Amago Final Report PDF
Amago Final Report PDF
Faculty Advisor:
ECE Department
Summer, 2019
Letter of Transmittal
8th September 2019,
To
Dr. K. M. A. Salam
Professor & Chair,
Department of Electrical and Computer Engineering
North South University, Dhaka
Dear Sir,
With due respect, we would like to submit our Capstone Project Report on “Amago: A
Cloud Based Produce Market for Independent Farmers, Grocers and Retailers” as a part
of our BSc program. The report deals with introducing an online digital market for Agricultural
trade. This project was very valuable to us as it helped us gain experience from implementing
software in the practical field and apply it in real life. We tried to make the most of our
1
We will be highly obliged if you kindly receive this report and provide your valuable judgment.
It would be our immense pleasure if you find this report useful and informative to have an
Sincerely Yours,
.........................................................
Abir Rahman
ECE Department
North South University, Bangladesh
........................................................
Jawad Aziz Khan
ECE Department
North South University, Bangladesh
.........................................................
Ishfaq Zaman
ECE Department
North South University, Bangladesh
2
APPROVAL
Abir Rahman (ID #1530412042), Jawad Aziz Khan (ID #1530457042) and Ishfaq Zaman
(ID #1530173642) from the Electrical and Computer Engineering Department of North South
University, have worked together on the Senior Design Project titled “Amago: A Cloud Based
Produce Market for Independent Farmers, Grocers and Retailers” under the supervision
of Dr. Mohammad Monirujjaman Khan as partial fulfillment of the requirement for the
Supervisor’s Signature
…………………………………….
Dhaka, Bangladesh.
Chairman’s Signature
…………………………………….
Dr. K. M. A. Salam
Professor & Chair
Dhaka, Bangladesh.
3
Declaration
This is to certify that this Project is our original work. No part of this work has been submitted
elsewhere partially or fully for the award of any other degree or diploma. Any material
1. Abir Rahman
ID 1530412042
_________________
ID 1530457042
_________________
3. Ishfaq Zaman
ID 1530173642
_________________
4
ACKNOWLEDGMENT
First of all, we wish to express our gratitude to the Almighty for giving us the strength to
The capstone project program is very helpful to bridge the gap between the theoretical
knowledge and real life experience as part of our Bachelor of Science (BSc) program. This
report has been designed to have a practical experience through the theoretical understanding.
We also acknowledge our profound sense of gratitude to all the teachers who have been
instrumental in providing us the technical knowledge and moral support to complete the project
It is imperative to show our appreciation for our honorable faculty member Dr. Mohammad
Monirujjaman Khan for his undivided attention and help to achieve this milestone. Also, our
gratefulness is divine to the North South University, ECE department for providing us a course
such as CSE 499 in which we could really work on this project and materialize it the way we
We thank our friends and family for their moral support to carve out this project and always
5
Table of Contents
Index Chapters Page no.
Abstract 10
Chapter 1: Overview 11
1.1 Introduction 12
1.5 Summary 13
2.1 Introduction 15
2.5 Summary 17
3.1 Introduction 19
3.4 Summary 21
4.1 Introduction 23
4.3 Summary 26
5.1 Introduction 28
6
5.2 Step-by-Step Framework Design 28
5.3 Summary 29
6.1 Introduction 31
6.3 Summary 33
7.1 Introduction 35
7.5 Summary 39
8.1 Introduction 41
8.3 Summary 41
9.1 Introduction 43
9.5 Sustainability 44
9.6 Summary 45
10.2 US Standard 47
10.3 EU Standard 47
10.4 Summary 48
7
11.1 Introduction 50
11.3 Summary 52
Bibliography 55
Appendix 56
List of Figures 92
8
Organization of the Report
Chapter 1 : Overview | This chapter provides an overview of the complete project idea.
Chapter 2 : Related Works | This chapter talks about similar and current works done and the
proposed solution.
Chapter 3: System Architecture | This chapter highlights the complete technical architecture
of the system.
Chapter 4 : Software Design | This chapter goes in depth into the design of the android and web
applications.
Chapter 5 : System Framework | This chapter highlights the database and server application
design
Chapter 6: Skills Obtained | This chapter talks about the skills that were need to be acquired
before and during the duration of the project
Chapter 7: Working Sheets | This chapter talks about the work timeline and procedures,
feasibility study and sustainability.
Chapter 8: Future Works | This chapter talks about what future work extensions can be done.
Chapter 9: Design Impact | This chapter highlights the social, economical and environmental
impacts of the project.
Chapter 10: Compliance with Standards | This chapter talks about how the project maintains
major industry standards.
Chapter 11: Results | This chapter talks about the project results achieved.
9
Abstract
Bangladesh suffers from fluctuating prices of produce due to several factors, such as
transport costs, seasonal supply demand changes, forced price inflation by stocking goods
when demand is high and many more. Each of these factors is a unique problem but some of
the solutions to these problems are data driven. Amago is a digital produce market platform
that aims to eliminate inefficient, unfair and unprofitable segments of the country’s existing
pipeline of the agricultural trade. The optimization of calculated minimal waste crop yield is a
data problem where supply and demand data should be leveraged for prediction that our
proposed system could potentially solve. Another point of inflection where profits are unfairly
lower are for the farmers when sold to the unregulated middle men. Thus the Amago Platform
has been proposed as a better solution for a digital future. The Amago Platform consists of 3
main components that we have implemented successfully - the Server and Application Layer
that handles data and queries, the Android app for farmers to post their harvests for sale, and
the Web Client for grocers and retailers who would buy from the posted harvests. The platform
will serve as a digital open marketplace for both parties and optimizations can be introduced
10
Chapter 1
Overview
11
1.1 Introduction
Bangladesh suffers from fluctuating prices of produce due to several factors, such as
transport costs, seasonal supply demand changes, forced price inflation by stocking goods
when demand is high and many more. Each of these factors is a unique problem but some of
the solutions to these problems are data driven. Amago is a digital produce market platform
that aims to eliminate inefficient, unfair and unprofitable segments of the country’s existing
pipeline of the agricultural trade. The optimization of calculated minimal waste crop yield is a
data problem where supply and demand data should be leveraged for prediction that our
proposed system could potentially solve. Another point of inflection where profits are unfairly
lower are for the farmers when sold to the unregulated middle men. Thus the Amago platform
quickly accumulate produce directly from the farmers based on market demand and ship them
Farmers will post a sell request through an android application. Our system will process
these requests and accumulate the produce until reaching maximum storage capacity. Retailers
will be able to order through an online web interface, once an order is received it will be directly
shipped to their specified store/outlet. The optimisation objective of the platform is to minimise
12
1.3 Purpose of Project
The purpose of the Amago Platform project is to replace or at least augment the manual,
inefficient, unregulated, unfair and unprofitable pipeline of the current agricultural trade to
better help the economy grow and to provide an attainable future for the producers to scale up
their business and move up in the social ladder. As of now, the fresh produce changes hands
multiple times on the way to the urbans from the farmlands and each time the price of the
produce increases in price while the corrupt middlemen take a part of the cut. But the real
problem is the fact that the farmers are nevertheless underpaid at the end of the day.
facilitate trade among farmers, producers and grocers, retailers so that both parties can buy and
sell at fair government set prices and help the agricultural economy grow.
1.5 Summary
13
Amago is a digital cloud based produce market that aims to help the agricultural
economy by connecting farmers to grocers such that both can trade at acceptable prices and
profit. The platform is meant to be used by laymen and accommodates them thusly by design.
14
Chapter 2
Related Works
15
2.1 Introduction
Currently there exists no such solution in the market. Studies show that there are several
challenges that have affected the agricultural industry over the years, this includes climate
change, inefficient use of water and fertilizers, pests, lack of quality seeds, unfair pricing and
insufficient investment in research [1]. There are multiple emerging agro-tech startups that are
for farmers. Farmers can sign up to work for designated farms. These farms are then advertised
for sponsorship by the platform. The sponsor and farmer share the profit from the farm giving
information. Their digital service "Golden Paddy" consist of a web/android application and a
On July 2019, ACI launched ‘Fosholi’ an android app which aims to create an
high quality agricultural data and services from the app. Fosholi offers intelligent information
and advisory services to local crop farmers for free. Fosholi will help farmers by providing
16
information on crop suitability, modern agronomic technology and practice, pest and disease
alerts and weather forecasts. Thus, it will improve farmers’ decision making and farming
productivity and ensure the overarching national goal of sustainable food and nutrition security.
"Plantix" is an Android based farming assistant tool. It provides crop health checking
through the use of computer vision, connects farmers to scientists, experienced farmers and
plant experts.
Ifarmer is an investment platform for farmers and mostly focus on livestock rearing.
Currently providing no option for crop farming. Nor do they provide any solution to connecting
"Impact Terra" and "Plantix" simply is a “Farming Assistant” Tool that provides tips
ACI Foshli while promising to provide data and logistical solutions to farmers does not
client that will digitally connect the aforementioned users in a produce marketplace, similar to
17
modern e-commerce services. The platform aims to own multiple warehouses in
geographically lucrative location where farmers can opt to store their produce and sell it
directly to uban retail markets. Logistical support is also provided through our service. The
ability to store produce allow farmers to take their time and sell crops at a higher rate. Therefore
the platform provides a higher chance of profitability for farmers automatically incentivising
them to use it. The lack of intermediary agents allow for lower prices for both sides in this b2b
model.
2.5 Summary
While there are many Agriculture related applications most provide a supportive role.
No current solution exists in the market that addresses our concern. Amago therefore is filling
18
Chapter 3
System Architecture
19
3.1 Introduction
The Amago Platform is an online service and thus would require a backend and
frontend system with a suitable communication protocol to successfully function and keep it’s
operations active. It would also require a database and accompanying management system to
store it’s user data. In this section, we discuss the technology, underlying structure of the
system and design principles that have gone into making this project tangible.
the NodeJS Server with the Application Layer, and the Frontend Android App plus the Web
Client. The database stores all the user’s necessary information in tuple form. Only necessary
information like Name, ID, Phone number, PIN and Location are stored. The Application Layer
handles the queries sent to the database dynamically as endpoint URLs are called by the
frontend client applications. The Server and Application Layer is written in Javascript and uses
handling the server logic and communications with the server and clients easier. They are
scalable and is proudly touted as being able to take large network traffic load and still maintain
20
3.3 System Design
The proposed system will operate using a PostgreSQL Relational Database System.
The database will log user account details, transaction requests, inventory and geolocation data.
The backend will be managed using a Node framework called ExpressJS and queries will be
managed by the Sequelize framework. The robust ExpressJS framework is used to create APIs
that is used for communicating with the server through an Android app/Web interface. Whereas
Sequelize is a database bridging manager that handles queries written in Javascript then
dynamically and efficiently translates it for the PostgreSQL hosted database. A diagram of the
21
Responses to queries are sent back as a JSON entity code. Such responses are very easy
to parse and manipulate within the application and is also capable of handling large quantities
of data entities, hence the decision to use it as the medium of data being communicated between
the client and server. Given below is an example of a JSON response, an element from a JSON
Array of the produce from a particular (farmer) user, note the user is denoted by the ‘userID’
The integer itemType is parsed and displayed by using a lookup string array that
contains a list of all the names of the produce available for the farmers to harvest. This list is
also queried from the database if needed or a local copy is maintained on both the Android app
3.4 Summary
The system was designed with stability and scalability in mind with regards to using
modern application, server and web technologies. Efficiency and atomicity of the transactions
is also to be preserved with the system designed. Overall a holistic component approach was
22
Chapter 4
Software Design
23
4.1 Introduction
For the completion of the Platform, 2 frontend applications needed to be developed -
an Android App for the farmers and a Web Client for Grocers. The two applications were
developed separately but while following the Server Application Layer’s endpoints and
constraints. The Application Layer was also developed with API endpoints for handling
Web Client
Our retail clients will be provided with a web interface. The web client is written in
their needs.
Website
24
Android:
The Android app, its API frameworks and the UX will follow Google's "Material”
design principles. Standard software patterns and Object Oriented design was considered
during the development of the app. It was done in a Linux Android Studio environment and
tested on a Virtual Device running Android 5.0. The app was laid out such that non tech savvy
farmers will be able to use it based on its easy operations and simple atomic functions.
Another significant way farmers can better use the app with minimum difficulty is by making
the entire interface of the app fully in Bangla. This is done with a dynamic locale management
system and is maintained by cross translating every possible string used in the interface in a
The UI surrounding the text is designed with ‘user look flow’ in mind and buttons given large
welcoming shapes and colors. The UI design was kept simple minimalistic and large such that
even laymen and farmers who are not very tech-savvy would be capable of using the app
25
without difficulty or much training. Text is displayed at a highly readable 24dp and colors are
Figure 4.3: Screenshot of the Login, Registration and Main Harvest pages of the Amago
Sell requests and Harvest posts through our app are displayed on the main home page
in a vertical linear view, with each operation and item segmented as a card. Each operation
reloads the home page and calls the server for an updated list of harvests and sell requests. Sell
requests are coupled with a status integer denoting the stage of the harvest and the
corresponding card is changed to reflect it. For example when a harvest is accepted for delivery,
the card can display an icon of a truck, the recipient’s name and location.
Farmers’ login credentials are sent to the server API via the Retrofit framework.
Retrofit is a high level third party Android framework dependency that makes sending and
processing HTTP Requests vastly convenient, concise and streamlined. This is done by
handling all GET and POST operations like regular functions from within Android and passed
to the Retrofit Interface class to run. Retrofit functions need to be declared in the Interface class
26
along with it’s required fields. For example, for a ‘login’ POST request the only fields needed
would be the phone number and the PIN. The interface function declaration looks something
like:
@FormUrlEncoded
@POST("api/auth/login")
Call<ResponseBody> Login(
@Field("phone") String phonenumber,
@Field("password") String pinnumber
);
After declaration of the interface it is only a matter of calling the function, sending the
necessary parameters and parsing any responses sent from the server. The return type of the
4.3 Summary
Implementation standards designed by Google were followed for the Android app
whilst also accommodating Bangla for farmer usage and accessibility. The Retrofit API was
very useful in building the app since it made endpoint calls extremely easy. The Web client
27
Chapter 5
System Framework
28
5.1 Introduction
This chapter provides an overview of the database design and server application
design.
One of the major goals of this project was to make sure that the system was designed
to be scalable and efficient. Following industry standards, we had started with our database.
We choose to go with a relational database, based on the fact that our system would be
storing lots of data. Being able to run high level queries were an important aspect. The
database relation diagram given in fig 5.1 shows how we planned our design. We tried to
make query faster by trying to stick to an integer based system, considering integers take less
time to sort. Our design also allows for complex joins that would create some interesting
work when working with data. We’ve tried to create as little redundancy as possible.
The application server design was based on the MVC or model view controller
architecture. We have API routes and web routes all handling the validation and handling of
29
input and output ports. All routing was done using expressJS framework because of its fast
build cycle and the fact that it does all the json parsing for us and no extra code needs to be
written.
There are specific controllers that contain all the logic and validations required for
example say registration. The controllers are designed to be modular so that down the line
they can be updated. We have tried to make the system secure and hassle free by using json
web tokens for authentication and seamless login. The json web tokens provide a unique
hashed code that is only decrypted using a secret key set by us. Hashed information is so
secure that, neither can the user nor the developers know how to decrypt it. Additionally there
were small handy utility middlewares such as loggers and uuid code generators.
One of the major frameworks we used was Sequelize to help create models of the
database for easy query. We used the native sequelize queries for most use cases but also
used raw SQL queries for more advanced tasks. The server was hosted on heroku to help our
development team collaborate real time and this also made testing remotely easier.
5.3 Summary
To conclude, the system was designed to be fast, efficient and scalable. Starting from
the database design to application server design, all of it was done after hours of research and
30
Chapter 6
Skills Obtained
31
6.1 Introduction
This project required us to design a full end to end product solution complete with a
RDMS database, server backend, web front end and android application. We therefore received
engineering practices.
javascript server framework, express web development framework, sequelize a custom ORM
for SQL queries, json web tokens, embedded javascript template engine, HTML, CSS and
Postgresql. During the start of the project timeline we spent a significant amount of time
learning node.js and express.js frameworks. We had chosen these stacks based on their high
performance and fast code cycles. Amongst all our members, we were experienced in
programming so it was fairly easy to get started with javascript. There was a small learning
curve to understanding how the express framework utilized routing protocols for APIs. We had
created our database on postgresql and used the sequelize framework as an ORM to help
maintain relations more easily. We learned how to create sequelize models and also learned
how to make simple queries using the model syntax that sequelize provided. However, later
down the line, we discovered that we were unable to do certain complex table queries using
sequelize but luckily we were able to query the tables manually with raw SQL queries.
Having prior android application development experience, we were able to jump into
production very fast however, our previous experiences were unpleasant due to the way android
studio handled API calls. Previously we had to write numerous lines of code to handle API
32
posts and requests inclusive of the manual parsing of data, however this time we spent some
time learning about ‘retrofit’. Retrofit is an open source type safe HTTP client for android and
java. Time invested in learning retrofit’s implementation saved us a lot of time during the final
stages of the production timeline. Lastly, on top of the basics of HTML and CSS we had to
learn integrating EJS pr embedded javascript template engine to help us setup the web
application. Using ejs was a time constrained decision because due to lack of time, this was the
Technology Reasoning
Java and Android Java is a performant and widely known scalable application
Studio programming language. It has automated memory management and
taking advantage of features is much more streamlined as it is
Object Oriented. Android Studio is the platform where the app is to
be implemented which allows fast prototyping, API handling and
debugging.
HTML, CSS, HTML is the world standard for building smooth simple but
Javascript aesthetically pleasing frontend web interfaces. CSS allows for
animations and styling while JS lets functions and business logic run
in the background of the site and is a highly readable and scalable
tool.
Python Python is enriched with many powerful statistical testing and machine
learning libraries. These libraries will be used extensively when
implementing our statistical testing platform and machine learning
model for demand prediction.
6.3 Summary
33
All in all, over the course of the project time period, we learned and implemented
several industry standard technologies. We can now call ourselves ‘experienced’ in these fields
and similar tasks would take almost half the time to accomplish.
34
Chapter 7
Working Sheets
35
7.1 Introduction
In this chapter, we observe the entire work structure, meaning how the scheduling was
maintained throughout the developmental phase. We shall also see the financial foundation of
this project and furthermore the feasibility study will also be discussed.
The project development was conducted in a number of phases. They were planned as
follows:
Development methodology used was Agile. Each cycle was be around 2 weeks long.
In each cycle the development team updated the product with major features. A three member
Phase 1: Research
● This phase was dedicated to researching the technological factors to be used and the
market research to collect vital data about the implications of the product.
● Delivered: Research material and datasets to progress to building the AI model for the
platform.
● This phase oversaw the preparation of the minimal viable product (MVP). This
includes the UI/UX, frontend and backend development. All the sections was
● Delivered: At the end of this phase, a useable platform was provided which included a
acceptable state.
36
Phase 3: Performance optimization
optimization of the website and backend services were done to a critical extent.
● Deliverable: At the end of this phase, the platform was tuned and optimized for the
● This phase concerned the end user experience. Testing of the platform was done in this
phase, starting from user testing to internal code tests to make sure the system is easily
● Deliverable: At the end of this phase a final report was published stating the progress
of the project.
Month
Major Milestones 1 2 3 4 5 6 7 8
37
Requirement
Analysis
Market Research
and Data
Collection
Backend system
development
Android App
development
Web Services
Feedback and UI
Changes
Final Report
to minimize costs. Fortunately, one of our team members already owned powerful enough
hardware to perform data analysis. We utilized ‘heroku’ to deploy our database, application
server and retail website. Using heroku helped us cut costs down and not compromise on
38
performance. Overall, there were almost no costs involved in the production of the platform
to be considered:
Technical feasibility
If we consider the technology stack used to build the ‘Amago’ platform, it can be seen
that these are very modern technologies and have large community support. The technology is
easy to learn and upgrading should also be easy. The system is built to be modular, so that it
can be easily upgraded and maintained. Integration of new technology is also possible with
Most of the frontend and backend portions of the project can be built with open source
tools that are highly well documented. System requirements for our application server and
android application are very minimal, hence end users won’t have to bear high computational
costs. The technology stack was chosen with thought to make sure that scalability is a major
option. Our system can currently handle upto approx. 3000 concurrent users with ease. This
Economic feasibility
The ‘Amago’ platform itself does not require a lot of money to be developed, however putting
the system in the hands of users and operational costs are massive. A big chunk of investment
is needed to bring the service to the market and initially requires a lot of training sessions to
39
teach our target group of farmers how to use the application and how it may benefit them. All
digital aspects of the project are financially feasible but physical aspects of it are not.
7.5 Summary
To conclude, we discussed the scheduling processes of the development of ‘Amago’
and additionally talked about the feasibility options of the complete system, starting from
production to market.
40
Chapter 8
Future Work
41
8.1 Introduction
In this chapter we discuss the future of our project including how we plan to improve
the system and what new features we might add down the line.
We plan on leveraging the large data that the system will amass if users join the
platform. We plan to apply machine learning to make sensible understanding of all that data.
We also plan to introduce new features such as farmer support and automated warehouse
management tools. Computer vision models can also be used to help farmers identify crop
8.3 Summary
This chapter has described the possible future applications of the design. But there are
a lot of possibilities with the designed system. The system may need some research for different
applications, though the principle of the designed system will remain as it is, mostly data driven
future is expected.
42
Chapter 9
Design Impact
43
9.1 Introduction
This section talks about the design impacts of the ‘Amago’ platform. Topics range from
Environmental impacts can include utilization of arable land and since most of the
inventory will be done digitally, there will be significantly less use of physical paper. Overall
● Farmers are expected to receive fair pricing on their production as ‘Amago’ plans to
● Farmers can stay connected to the market more easily as vital supply demand
● Help farmers modernize their processes and bring new innovative technologies to them
● Help farmers export their products abroad by trying to create a direct channel for them
to operate.
● Create a fair pricing and regulation standard for the drivers of long haul deliveries.
44
9.4 Social Impact
● ‘Amago’ hopes to uplift farming as a profession, by helping farmers earn more and
showing that it is a well respected lifestyle. These people feed us and we would go
9.5 Sustainability
Initially, the project requires funding from investors. The initial funding will be used to fund
the development phase and a portion of the marketing. Our sustainable business model would
be to charge a 2% (subject to change) flat service charge on the overall order. However, we do
not plan to solely rely on this but rather utilize the data we collect over time to create some
platform that connects suppliers to retailers in the most efficient way possible but with time as
we grow our database with information regarding supply, demand and crop yields, we would
be able to diversify into providing market analysis. Not only this, the farmer application can be
used to collect vital information about the farmers land and crops, which can be later processed
to help farmers obtain higher crop yields based on crop optimization. The farmer application
can also work as an information hub for farmers providing advice, a marketplace for farmers
As mentioned earlier, the project has a high potential for income generation. Initially
revenue will be generated on a flat 2%(subject to change) service charge added on top of each
transaction. A real life assumption can be made, a seller ‘A’ wants to sell 1 tonne of onions at
wholesale price (100 kg = 1562 BDT, set by the ministry of agriculture), therefor total of 15620
BDT. If you add logistics on top of this, then an approximate addition of 5000 BDT(subject
45
to location), and the total becomes 20620 BDT. Amago takes 2% of this, which is about 413
BDT, so the total price retailers pay is 21032 BDT. Assuming Amago initiated 500 of such
onion orders, then we make approximately 206500 BDT. This amount is only for one particular
After the initial investment, it will take some time to familiarize the product to the
market and might not be making any profit. However, in the long run, profit will hopefully be
made. To reach a profitable state, more research and development would be needed and this
The instant benefit of the project will be enjoyed by the farmers and logistic personnel.
But down the line it would have a massive impact on the way retailers buy produce. Farm to
retail procedure would be structured and tracked leaving no place for bad quality produce to
make it to shelves. Research and development will be done based on the data acquired to help
9.6 Summary
This chapter has covered the different types of impacts that our system offers and those
has been described and discussed. From the above given impacts we can conclude that our
46
Chapter 10
47
10.1 Introduction
In this section we discuss the consistency of our task with diverse standards. There are
a few distinct standards, amongst which the IEEE standards, US standards and European
There are a few distinct guidelines put forward by IEEE Standards affiliation. The
majority of them however are not material for our framework. We have included idea of
operation as for the IEEE standard. A conference paper has additionally been submitted and
affirmed by IEEE standards entitled "Amago: A Cloud Based Produce Market for
Independent Farmers, Grocers and Retailers" that points our work on this task.
ANSI recommends that copyrighted software should only be included for informational
believes that the use of software in standards should be avoided to the extent possible, ANSI
recognizes that there may be circumstances in which inclusion of some software, provided
could include: ·
● Schema examples;
48
● Data structure definitions;
purposes.
Our project has been established based on the above ANSI principles and it completely
in accordance with. These standards have been put without hesitation so as to control things,
guarantee well-being and ensure there are no well-being dangers to the use of distinctive
segments. It is imperatively essential to maintain these measures and we have done as such
49
Chapter 11
Results
50
11.1 Introduction
This chapter of the report contains the results that we achieved throughout the course of using
this system.
industry standards, we were able to design a dynamic and flexile backend which made
frontend and android development relatively smooth. We found that using Node.js as our
primary application server technology would triumph over using raw PHP as it provides
much higher scalability due to its asynchronous network command execution. This enables it
to handle much higher user traffic compared to PHP. We created an API based server side
application that made future expansion and upgrades and development easy. Planning took a
major portion of the project timeline because of the extensive scale of the project. The
flexible backend allowed us to implement granular APIs to meet the needs of our Android
application and web interface. We were able to design an android app which is able to
connect wholesalers or independent farmers to urban retailers along with storing accurate
logs of transactions and inventory of its users. The UI of the android app is kept simplistic
and intuitive with complete bangla localization to make it easy to use by our target
demographic.
Additionally to all this, we were able to collect data regarding sales of agricultural
products to apply a low level data analysis and prediction models. The idea of this was to
create a feedback system to help farmers and retailers both understand the market better and
act accordingly. However due to time constraints we were not able to implement the feedback
system into our core code. However we played around with the data we collected and found
interesting outputs.
51
Figure 11.1: Data Analysis Graphs on Pricing
52
Figure 11.2: Data Analysis Graphs on Harvest
11.3 Summary
This chapter has covered the different types of results that we have managed to obtain
53
Chapter 12
Conclusion
54
We designed a concept application that intends to use technology to streamline the
logistical and communication challenges faced in the agricultural industry of our country. It
highlights the features farmer and retailer users can take advantage of and emphasizes the
The proposed solution will truly count as innovation since nothing like this has been
implemented before in Bangladesh. Innovation in the agriculture sector has not been scaled
using digital technology and hence provides a perfect opportunity for the ‘Amago’ platform to
thrive. Production to Retail management in terms of agriculture goods has not been done
before. Not only that but management of production yields and logistics has also not been done
before at a significant scale. Prediction models for supply and demand will also be a new
introduction to the market. These technologies can change the playing field for the good of the
From the beginning of developing this system, our main goal was to develop a fully
functional state of the art system which could cater to the masses and it would become a
tremendous commercial entity. Our focus was not only to finish the project in due time but to
design this system in such a way that it would genuinely be useful in the real world. We wish
55
Bibliography
[3] iFarmer.Asia, an impact tech startup for innovative online platform which enables
https://ifarmer.asia/
[4] Impact Terra. AgroTech Startup with Finance and Farmer Consultancy.
https://www.impactterra.com/
https://plantix.net/en
56
Appendix
Android Code
57
AmagoItem.java
package com.sks.amago;
import com.google.gson.annotations.SerializedName;
import java.util.Calendar;
@SerializedName("sellerName")
private String sellerName;
@SerializedName("itemStatus")
private int itemStatus;
itemStatus = 2;
dateHarvested = GetDateTaken();
}
public AmagoItem(int id, int n, int w, int p, String sn, int is){
uniqueID = id;
itemID = n;
itemPrice = p;
itemAmount = w;
sellerName = sn;
58
itemStatus = is;
dateHarvested = GetDateTaken();
}
LanguageSelect.java
package com.sks.amago;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
59
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;
import com.sks.amago.Helper.LocaleHelper;
import java.util.Locale;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_language_select);
radioLangGroup = findViewById(R.id.radiogroupLang);
btnOK = findViewById(R.id.button_langok);
textLang = findViewById(R.id.textView2);
SharedPreferences sharedPrefs =
getSharedPreferences("com.sks.amago.userprefs", MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPrefs.edit();
editor.putBoolean("firsttime", false);
editor.apply();
Toast.makeText(this,
lang+" Selected", Toast.LENGTH_SHORT).show();
if (lang.equalsIgnoreCase(" English")) {
updateView("en");
Locale locale = new Locale("en");
Configuration config =
getBaseContext().getResources().getConfiguration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
}
60
else {
updateView("bn");
Locale locale = new Locale("bn");
Configuration config =
getBaseContext().getResources().getConfiguration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
}
startActivity(new Intent(LanguageSelect.this, IntroSlider.class));
}
Register.java
package com.sks.amago;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.sks.amago.Retrofit.RetrofitClient;
import java.io.IOException;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
EditText editTextFullnamereg;
EditText editTextPhoneNumreg;
EditText editTextPINreg;
61
Button buttonSignup;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
editTextFullnamereg = findViewById(R.id.editText_fullnamereg);
editTextPhoneNumreg = findViewById(R.id.editText_phonereg);
editTextPINreg = findViewById(R.id.editText_PINreg);
buttonSignup = findViewById(R.id.button_signupreg);
if (!fullname.isEmpty()) {
if (phonenum.length() == 11) {
if (pinnumber.length() >= 4) {
SharedPreferences sharedPrefs =
getSharedPreferences("com.sks.amago.userprefs", MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPrefs.edit();
editor.putString("amagoPIN", pinnumber);
editor.putString("amagoPhone", phonenum);
editor.putString("amagoFullname", fullname);
editor.apply();
Toast.makeText(this, "Saved!\n" + phonenum + " "
+ pinnumber, Toast.LENGTH_LONG).show();
Call<ResponseBody> apicall =
RetrofitClient.getRetrofitInstance()
.getAPICalls().Register(fullname, pinnumber,
phonenum);
apicall.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call,
Response<ResponseBody> response) {
try {
String s = response.body().string();
Toast.makeText(Register.this, s,
Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
}
}
62
@Override
public void onFailure(Call<ResponseBody> call,
Throwable t) {
Toast.makeText(Register.this, t.getMessage(),
Toast.LENGTH_LONG).show();
}
});
this.finish();
} else editTextPINreg.setError("! " +
getString(R.string.needpin) + " !");
} else editTextPhoneNumreg.setError("! " +
getString(R.string.needphnum) + " !");
} else editTextFullnamereg.setError("! " +
getString(R.string.needname) + " !");
}
}
Login.java
package com.sks.amago;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.sks.amago.Helper.LocaleHelper;
import com.sks.amago.Retrofit.RetrofitClient;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import io.paperdb.Paper;
63
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
TextView amagotext;
EditText editTextPhone;
EditText editTextPIN;
Button buttonLogin;
Button buttonSignin;
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(LocaleHelper.onAttach(newBase, "en"));
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
sharedPrefs = getSharedPreferences("com.sks.amago.userprefs",
MODE_PRIVATE);
firsttime = sharedPrefs.getBoolean("firsttime", true);
if(firsttime){
Intent intent = new Intent(Login.this, LanguageSelect.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
}
64
username = sharedPrefs.getString("utoken",
"tokennotsetpleaselogin");
CheckCurrentToken(utoken);
amagotext = findViewById(R.id.textView);
editTextPhone = findViewById(R.id.editText_phone);
editTextPIN = findViewById(R.id.editText_PIN);
buttonLogin = findViewById(R.id.button_login);
buttonSignin = findViewById(R.id.button_signup);
}
public void GotoMain(View view) {
SharedPreferences sharedPrefs =
getSharedPreferences("com.sks.amago.userprefs", MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPrefs.edit();
editor.putString("utoken", tokencheck);
editor.apply();
65
Log.i("LOGIN SAVE TOKEN","Token Saved to Local:
"+tokencheck);
CheckCurrentToken(tokencheck);
}
catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Toast.makeText(Login.this, t.getMessage() +" "+
getString(R.string.crednotmatch), Toast.LENGTH_LONG).show();
}
});
SharedPreferences sharedPrefs =
getSharedPreferences("com.sks.amago.userprefs", MODE_PRIVATE);
66
SharedPreferences.Editor editor =
sharedPrefs.edit();
editor.putString("userid", userid);
editor.putString("username", username);
editor.apply();
}
else {
Toast.makeText(Login.this, "Fail:
"+tokenresponsecode+" "+getString(R.string.crednotmatch),
Toast.LENGTH_LONG).show();
Log.i("RESPONSE TOKEN FAIL",tokencheck+"
"+tokenresponsecode);
}
}
catch (IOException | JSONException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Toast.makeText(Login.this, t.getMessage(),
Toast.LENGTH_LONG).show();
}
});
}
CallsInterface.java
package com.sks.amago.Retrofit;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.Field;
67
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.POST;
import retrofit2.http.Path;
@FormUrlEncoded
@POST("api/users/register")
Call<ResponseBody> Register(
@Field("username") String fullname,
@Field("password") String pinnumber,
@Field("phone") String phonenumber
);
@FormUrlEncoded
@POST("api/auth/login")
Call<ResponseBody> Login(
@Field("phone") String phonenumber,
@Field("password") String pinnumber
);
@POST("api/auth/current")
Call<ResponseBody> CheckToken(
@Header("Authorization") String utoken
);
@GET("api/harvest/getHarvest/{id}")
Call<ResponseBody> GetHarvest(@Path("id") String id);
@FormUrlEncoded
@POST("api/harvest/postHarvest")
Call<ResponseBody> PostHarvest(
@Field("userID") String userid,
@Field("itemType") int itemType,
@Field("amount") int amount
);
@FormUrlEncoded
@POST("api/harvest/sellHarvest")
Call<ResponseBody> SellHarvest(
@Field("id") int itemid,
@Field("status") int status,
@Field("price") int price
);
}
68
MainActivity.java
Server Code
server.js
69
server.use(express.static(__dirname + '/public'));
// DB config
const db = require('./config/database');
// DB Connection
/*
! Connected to amagoProduction DB server
*/
db.authenticate()
.then(() => console.log('Database connected...'))
.catch(err => console.log('Error: ' + err));
/*
//Retail webapp routes
server.get('/register', (req, res) => {
res.render('register', { name: 'Register for a retail account' });
});
70
phone: req.body.phone,
password: req.body.inputPassword
};
console.log(register);
res.render('login');
//res.render('home',{
// userValue : student,
// topicHead : 'Student Form'
});
*/
//use routes
server.use('/api/users', users);
server.use('/api/auth', auth);
server.use('/api/harvest', harvest);
server.use('/api/item', item);
server.use('/api/sellRequest', sellReq);
server.use('/', retailUtils);
server.use('/', retailUsers);
server.use('/', retailAuth);
server.use('/', retailDashboard);
api/user.js
const express = require('express');
const uuid = require('uuid');
const moment = require('moment');
const router = express.Router();
const bcrypt = require('bcryptjs');
71
userID: req.params.id
}
})
.then(resultID => res.json(resultID))
.catch(err => console.log(err))
);
72
});
/*
! Need to check if the user already exists in DB
! and handle accordingly
*/
});
module.exports = router;
api/auth.js
const express = require('express');
const router = express.Router();
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
73
return res.status(404).json({ msg: ' not a registered user' });
}
//Sign Token
jwt.sign(
payload,
keys.secretOrKey,
{ expiresIn: 3060 },
(err, token) => {
res.json({
token: 'Bearer ' + token
});
}
);
} else {
// Passwords don't match
return res.status(400).json({ msg: 'Incorrect Password' });
}
});
})
.catch(err => console.log(err))
);
74
module.exports = router;
api/harvest.js
const express = require('express');
const router = express.Router();
const moment = require('moment');
75
router.post('/postHarvest', (req, res) => {
const newHarvset = {
userID: req.body.userID,
itemType: req.body.itemType,
amount: req.body.amount,
status: '1',
createdAt: moment().format(),
updatedAt: moment().format()
};
module.exports = router;
jwtMiddleware.js
// FORMAT OF TOKEN
// Authorization: Bearer <access_token>
// Verify Token
module.exports = function verifyToken(req, res, next) {
// Get auth header value
const bearerHeader = req.headers['authorization'];
//const bearerHeader = req.headers('authorization');
// Check if bearer is undefined
if (typeof bearerHeader !== 'undefined') {
// Split at the space
const bearer = bearerHeader.split(' ');
// Get token from array
const bearerToken = bearer[1];
// Set the token
req.token = bearerToken;
// Next middleware
next();
} else {
// Forbidden
76
res.sendStatus(403);
}
};
registrationValidator.js
const Validator = require("validator");
const isEmpty = require("./is-empty");
module.exports = function validateRegisterInput(data) {
let errors = {};
data.name = !isEmpty(data.name) ? data.name : "";
data.email = !isEmpty(data.email) ? data.email : "";
data.role = !isEmpty(data.role) ? data.role : "";
data.password = !isEmpty(data.password) ? data.password : "";
data.password2 = !isEmpty(data.password2) ? data.password2 : "";
if (Validator.isEmpty(data.name)) {
errors.name = "Name field is required";
}
if (Validator.isEmpty(data.email)) {
errors.email = "Email field is required";
}
if (!Validator.isEmail(data.email)) {
errors.email = "Email is invalid";
}
if (Validator.isEmpty(data.role)) {
errors.role = "Role is required";
}
if (Validator.isEmpty(data.password)) {
errors.password = "Password field is required";
}
if (Validator.isEmpty(data.password2)) {
errors.password2 = "Confirm Password field is required";
}
77
if (!Validator.equals(data.password, data.password2)) {
errors.password2 = "Passwords must match";
}
return {
errors,
isValid: isEmpty(errors)
};
};
loginValidator.js
const Validator = require("validator");
const isEmpty = require("./is-empty");
if (!Validator.isEmail(data.email)) {
errors.email = "Email is invalid";
}
if (Validator.isEmpty(data.email)) {
errors.email = "Email field is required";
}
// if (Validator.isEmpty(data.role)) {
// errors.role = 'Role is required';
// }
if (Validator.isEmpty(data.password)) {
errors.password = "Password field is required";
}
return {
errors,
isValid: isEmpty(errors)
};
};
78
Website Code
Login.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<meta name="description" content="" />
<meta name="author" content="" />
<title>Amago - Login</title>
<link rel="icon" type="image/ico" href="img/amagoLogo.png" />
<body class="bg-dark">
</ul>
</nav>
<div class="container">
79
<div class="card card-login mx-auto mt-5">
<div class="card-header">Login</div>
<div class="card-body">
<form id="login" method="POST" action="/login">
<div class="form-group">
<div class="form-label-group">
<input
type="phone"
id="phone"
name="phone"
class="form-control"
placeholder="Phone number"
required="required"
autofocus="autofocus"
/>
<label for="phone">Phone number</label>
</div>
</div>
<div class="form-group">
<div class="form-label-group">
<input
type="password"
id="inputPassword"
name="inputPassword"
class="form-control"
placeholder="Password"
required="required"
/>
<label for="inputPassword">Password</label>
</div>
</div>
<div class="form-group">
<div class="checkbox">
<label>
<input type="checkbox" value="remember-me" />
Remember Password
</label>
</div>
</div>
<div>
<button
type="submit"
class="btn btn-primary btn-block"
value="Login"
>
Login
</button>
</div>
</form>
<div class="text-center">
80
<% if(typeof msg != 'undefined')
{ %> <h3><%= msg %></h3> <%}
%>
<a class="d-block small mt-3" href="register"
>Register an Account</a
>
<a class="d-block small" href="forgot-password"
>Forgot Password?</a
>
</div>
</div>
</div>
Registation.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<meta name="description" content="" />
<meta name="author" content="" />
<title>Amago- Register</title>
<link rel="icon" type="image/ico" href="img/amagoLogo.png" />
81
<!-- Custom styles for this template-->
<link href="/css/sb-admin.css" rel="stylesheet" />
</head>
<body class="bg-dark">
<nav class="navbar navbar-expand navbar-dark bg-navlight static-top">
<a class="navbar-brand mr-1" href="home"
><img src="img/amago.png" position="center" width="70" height="40"
/></a>
82
<div class="form-label-group">
<input
type="phone"
id="phone"
name="phone"
class="form-control"
placeholder="Phone Number"
required="required"
/>
<label for="phone">Phone Number</label>
</div>
</div>
<div class="form-group">
<div class="form-row">
<div class="col-md-6">
<div class="form-label-group">
<input
type="password"
id="inputPassword"
name="inputPassword"
class="form-control"
placeholder="Password"
required="required"
/>
<label for="inputPassword">Password</label>
</div>
</div>
<div class="col-md-6">
<div class="form-label-group">
<input
type="password"
id="confirmPassword"
name="confirmPassword"
class="form-control"
placeholder="Confirm password"
required="required"
/>
<label for="confirmPassword">Confirm password</label>
</div>
</div>
</div>
</div>
<div>
<button
type="submit"
class="btn btn-primary btn-block"
value="Register"
>
Register
</button>
83
</div>
</form>
<div class="text-center">
<a class="d-block small mt-3" href="login">Login Page</a>
<a class="d-block small" href="forgot-password.html"
>Forgot Password?</a
>
</div>
</div>
</div>
</div>
Index.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<meta name="description" content="" />
<meta name="author" content="" />
<title>Amago - Dashboard</title>
<link rel="icon" type="image/ico" href="img/amagoLogo.png" />
84
/>
<body id="page-top"
<h1>Logged in as : <%= data.id %></h1>
<nav class="navbar navbar-expand bg-navlight bg-dark static-top">
<a class="navbar-brand mr-1" href="index"
><a class="navbar-brand mr-1" href="home"
><img
src="img/amago.png"
position="center"
width="70"
height="40"/></a
></a>
<button
class="btn btn-link btn-sm text-white order-1 order-sm-0"
id="sidebarToggle"
href="#"
>
<i class="fas fa-bars"></i>
</button>
85
<a
class="nav-link dropdown-toggle"
href="#"
id="alertsDropdown"
role="button"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>
<i class="fas fa-bell fa-fw"></i>
<span class="badge badge-danger">9+</span>
</a>
<div
class="dropdown-menu dropdown-menu-right"
aria-labelledby="alertsDropdown"
>
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</li>
<li class="nav-item dropdown no-arrow mx-1">
<a
class="nav-link dropdown-toggle"
href="#"
id="messagesDropdown"
role="button"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>
<i class="fas fa-envelope fa-fw"></i>
<span class="badge badge-danger">7</span>
</a>
<div
class="dropdown-menu dropdown-menu-right"
aria-labelledby="messagesDropdown"
>
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</li>
<li class="nav-item dropdown no-arrow">
<a
class="nav-link dropdown-toggle"
href="#"
id="userDropdown"
86
role="button"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>
<i class="fas fa-user-circle fa-fw"></i>
</a>
<div
class="dropdown-menu dropdown-menu-right"
aria-labelledby="userDropdown"
>
<a class="dropdown-item" href="#">Settings</a>
<a class="dropdown-item" href="#">Activity Log</a>
<div class="dropdown-divider"></div>
<a
class="dropdown-item"
href="login"
data-toggle="modal"
data-target="#logoutModal"
>Logout</a
>
</div>
</li>
</ul>
</nav>
<div id="wrapper">
<!-- Sidebar -->
<ul class="sidebar navbar-nav">
<li class="nav-item active">
<a class="nav-link" href="index.html">
<i class="fas fa-fw fa-tachometer-alt"></i>
<span>Dashboard</span>
</a>
</li>
<li class="nav-item dropdown">
<a
class="nav-link dropdown-toggle"
href="#"
id="pagesDropdown"
role="button"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>
<i class="fas fa-fw fa-folder"></i>
<span>Inventory</span>
</a>
<div class="dropdown-menu" aria-labelledby="pagesDropdown">
<h6 class="dropdown-header">Login Screens:</h6>
87
<a class="dropdown-item" href="login">Login</a>
<a class="dropdown-item" href="register">Register</a>
<a class="dropdown-item" href="forgot-password">Forgot
Password</a>
<div class="dropdown-divider"></div>
<h6 class="dropdown-header">Other Pages:</h6>
<a class="dropdown-item" href="404">404 Page</a>
<a class="dropdown-item" href="blank">Blank Page</a>
</div>
</li>
<li class="nav-item">
<a class="nav-link" href="charts">
<i class="fas fa-fw fa-chart-area"></i>
<span>Reports</span></a
>
</li>
<li class="nav-item">
<a class="nav-link" href="tables">
<i class="fas fa-fw fa-table"></i>
<span>Transactions</span></a
>
</li>
</ul>
<div id="content-wrapper">
<div class="container-fluid">
<!-- Breadcrumbs-->
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="#">Dashboard</a>
</li>
<li class="breadcrumb-item active">Overview</li>
</ol>
88
</a>
</div>
</div>
<div class="col-xl-3 col-sm-6 mb-3">
<div class="card text-white bg-warning o-hidden h-100">
<div class="card-body">
<div class="card-body-icon">
<i class="fas fa-fw fa-list"></i>
</div>
<div class="mr-5">11 New Tasks!</div>
</div>
<a class="card-footer text-white clearfix small z-1"
href="#">
<span class="float-left">View Details</span>
<span class="float-right">
<i class="fas fa-angle-right"></i>
</span>
</a>
</div>
</div>
<div class="col-xl-3 col-sm-6 mb-3">
<div class="card text-white bg-success o-hidden h-100">
<div class="card-body">
<div class="card-body-icon">
<i class="fas fa-fw fa-shopping-cart"></i>
</div>
<div class="mr-5">123 New Orders!</div>
</div>
<a class="card-footer text-white clearfix small z-1"
href="#">
<span class="float-left">View Details</span>
<span class="float-right">
<i class="fas fa-angle-right"></i>
</span>
</a>
</div>
</div>
<div class="col-xl-3 col-sm-6 mb-3">
<div class="card text-white bg-danger o-hidden h-100">
<div class="card-body">
<div class="card-body-icon">
<i class="fas fa-fw fa-life-ring"></i>
</div>
<div class="mr-5">13 New Tickets!</div>
</div>
<a class="card-footer text-white clearfix small z-1"
href="#">
<span class="float-left">View Details</span>
<span class="float-right">
<i class="fas fa-angle-right"></i>
89
</span>
</a>
</div>
</div>
</div>
</tbody>
</table>
</div>
90
</div>
<div class="card-footer small text-muted">
Updated yesterday at 11:59 PM
</div>
</div>
<!-- Area Chart Example-->
<div class="card mb-3">
<div class="card-header">
<i class="fas fa-chart-area"></i>
Purchase History
</div>
<div class="card-body">
<canvas id="myAreaChart" width="100%" height="30"></canvas>
</div>
<div class="card-footer small text-muted">
Updated yesterday at 11:59 PM
</div>
</div>
</div>
<!-- /.container-fluid -->
91
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Ready to
Leave?</h5>
<button
class="close"
type="button"
data-dismiss="modal"
aria-label="Close"
>
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
Select "Logout" below if you are ready to end your current
session.
</div>
<div class="modal-footer">
<button
class="btn btn-secondary"
type="button"
data-dismiss="modal"
>
Cancel
</button>
<a class="btn btn-primary" href="login">Logout</a>
</div>
</div>
</div>
</div>
92
</button>
</div>
<div class="modal-body">
Are you sure you want to buy this item?
</div>
<div class="modal-footer">
<button
class="btn btn-secondary"
type="button"
data-dismiss="modal"
>
Cancel
</button>
<a class="btn btn-primary" type="submit"
href="blank">Purchase</a>
</div>
</div>
</div>
</div>
List of Figures
93
Figure no. Figure Caption Page no.
94