Professional Documents
Culture Documents
Online Deal Project Report
Online Deal Project Report
Engineering
NALANDA INSTITUTE OF TECHNOLOGY,
CHANDAKA, BHUBANESWAR
(Affiliated to Biju Patnaik University of Technology, Odisha)
Project Report
ON
“ONLINE DEAL”
PRITAM SHASANEE(1601297183)
PROJECT REPORT
ON
“ONLINE DEAL”
SUBMITTED BY:
RANJEET KUMAR (1601297127)
SHIV SAGAR (1601297129)
ABHISHEK KUMAR (1601297030)
PRITAM SHASANEE(1601297183)
In partial fulfillment for the award of the degree of
B.TECH
IN
COMPUTER SCIENCE AND ENGINEERING
NALANDA INSTITUTE OF
TECHNOLOGY, CHANDAKA,
BHUBANESWAR-754005 2020-20
Department of Computer Science and Engineering
NALANDA INSTITUTE OF TECHNOLOGY, CHANDAKA,
BHUBANESWAR-754005
2019-20
CERTIFICATE
Certified that this is a bonafide record of project work titled
“ONLINE DEAL”
Done By:
RANJEET KUMAR
SHIV SAGAR
ABHISHEK KUMAR
PRITAM SHASANEE
of VIII Semester computer science and engineering in the year 2020 in partial
fulfillment of the requirement for award of degree of bachelor of technology in
computer science and engineering of Biju Patnaik University of Technology .
DECLARATION
We Hereby Declare That This Project Prepared By Us and Entitled
As “Online Deal” Is Original and This Has Not Been Submitted To
Anywhere Else For the Award of Any Other Degree
Ranjeet Kumar
Shiv Sagar
Abhishek Kumar
Pritam Sashanee
ABSTRACT
Our project is Online Deal. This is a website which helps people to find and
buy all type of product on internet. It is useful in the way that it makes an
easier way to buy product online. Online Deal is an interactive e-commerce
solution providing users with an opportunity to buy any product. Online
Deal is the online platform which deals with all product of all fields.
INTRODUCTION 1
Types of E-Commerce websites 2
TITLE OF THE PROJECT “ ONLINE DEAL ” 3
BACKGROUND : 3
SCOPE OF THE PROJECT 3
SYSTEM MISSION 4
SYSTEM FUNCTIONS/RESPONSIBILITIES 4
OBJECTIVES OF THE PROJECT 4
PRODUCT FUNCTIONS 5
USER CHARACTERISTICS 5
SYSTEM FUNCTIONS/RESPONSIBILITIES 5
SYSTEM CONSTRAINTS 6
SYSTEM ANALYSIS 7
a) Problem Specification 7
b) Feasibility Study 7
c) System Requirements Specification 7
d) Existing System 7
SYSTEM REQUIREMENTS SPECIFICATION (SRS) 8
SYSTEM REQUIREMENT 11
1. SOFTWARE REQUIREMENT: 11
2. HARDWARE REQUIREMENT: 11
LITERATURE SURVEY 12
DJANGO MVC - MVT Pattern 13
SYSTEM DESIGN 18
1. UML Diagrams 18
2. Database Design 18
3. Dataflow Diagrams 18
4. E-R Diagrams 18
5. Database Tables 18
1. Dependency 22
2. Association 22
3. Generalization 22
4. Realization 22
1. Dependency: 22
2. Association: 22
3. Generalization: 23
DATABASE DESIGN 27
1. Physical DFD 27
2. Logical DFD 27
1. PHYSICAL DFD: 27
3. LOGICAL DFD: 27
SCREEN SHOTS 33
HOME: 33
SIGN UP: 34
LOGIN: 35
PASSWORD RESET: 36
PRODUCT DETAILS: 36
ORDER SUMMARY: 37
CHECKOUT FORM: 38
ADMIN LOGIN: 39
ADMIN DASHBOARD: 40
ADMIN USER: 41
ADMIN/ADD PRODUCT: 41
CODING 42
Front-end codes: 42
base.html 42
Back-end coding 78
Migrations 99
TESTING 104
1. Unit testing 105
2. Integrated testing 105
3. Validation testing 105
4. Output testing 105
5. System testing 105
6. User acceptance testing 105
Maintenance: 108
1) System Development Audit Controls 108
2) Programming Management Audit Controls 108
3) Security Management Audit Controls 108
4) Operations Management Audit Controls 108
5) Quality Management Audit Controls 108
6) Boundary Audit Controls 108
1) Task System Impact: 109
2) Programming managing audit control: 109
3) Security management audit control: 109
4) Operation management audit control: 110
5) Quality assurance management audit control: 110
6) Boundary audit control: 110
7) Output Audit controls: 111
PROJECT
DOCUMENTATION
INTRODUCTION
An e-Commerce website is an information technology method in
which trader, businesses/distributor/marketers can sell
products/services and the customer can purchase on that website
electronically by using internet on the mobile and computer.
It means an e-commerce website is an online shop.
e means electronic. Commerce mean business.
Website means the group of HTML web pages and that is
created to market/sell information/product/services.
In a bigger perspective, every website on the internet is the
e-Commerce Website. It can be the platform, it can be a marketplace, it
can be portal, it can be apps, it can be an entertainment website,
shopping website, online courses website and online degree college.
When you purchase a mobile phone /shoes/software/ flowers on
any website such as Amazon, Flipkart etc. and pay through
credit/debit card and then seller deliver the product through courier
or post mail on your location then it’s called e-commerce. In this
case, Flipkart is an online store website or an e-commerce website.
When you subscribe to watch a cricket match, movies, and
shows on any website such as hotstar through debit card and
credit card it is called e-commerce. And in this way, hotstar is a
digital and mobile entertainment e-commerce website.
When you rent or buy movies on YouTube and pay to watch by using
the mobile/computer and internet it’s called e-commerce. In this
method, you have used computer/mobile and internet through
electricity and visited youtube website to watch/buy/rent the movie
and paid through debit card/credit card/ net banking/payment wallet
etc. It means youtube is an eCommerce website in which you can
buy/watch/rent the latest movies and shows.
When you use Google Ads or Facebook Advertising etc. to
promote and advertise your products/services online and pay
Google and Facebook to use the services and platforms then it’s
e-commerce. In this case Google / Facebook etc. are e-commerce
companies that provide you platform and tools to advertise and
promote your business/products/services online.
When you launch your apps on the Google Play store, you pay
Google to use their platform to connect with your customers/target
audience then it’s e-commerce and google play store is an e-
1
Commerce platform in which apps developer or apps
launcher or owners have to pay Google. And all these
transactions are online. It’s e-commerce.
When you recharge your mobile phone/dish tv/internet data pack
by using the internet and the website such as paytm, mobiwiki,
JIO etc. and pay through debit/credit card, wallet, and net banking
then it’s e-commerce and PayTM, Mobiwiki, Jio apps or websites
are e-commerce websites. In which they are doing customers
recharge online and getting paid directly to their bank account.
When you purchase software as a service, platform as a
service, infrastructure as service for your business from
cloud computing service providers such as Alibaba,
Amazon web service, Microsoft, google cloud etc. on
their website then these are the e-commerce websites.
When you use internet banking then it is e-commerce. You pay
bills, transfer money, open RD/FD account, pay installments online,
pay for offline products from payment wallets etc. are e-commerce.
When political parties, government or
non-government organizations received funds or
donations online then it is e-commerce.
BACKGROUND :
Any system needs continuous evaluation to know the
merits and demerits of the system . Thus evaluation system
gives the scope of further improvement of the system . One of
the major sources of evaluation is end user/customer.
This is true for this system too. There should be a
continuous update of the information of the job details. Etc.
E-Commerce is forever.
E-commerce has tremendous prospects in future.
The tremendous popularity of using the e-commerce could never
have been realized before. In fact, e-commerce has become an
important tool of marketing in true sense of customer orientation.
The scope of e-commerce is widening, and today it offers
a strong support to the companies in providing the much
desired touch of concern. Future of e-commerce brings
exciting promises as expected from the experience of
limited users from a few companies in the top bracket.
3
SYSTEM MISSION
SYSTEM FUNCTIONS/RESPONSIBILITIES
PRODUCT FUNCTIONS
USER CHARACTERISTICS
Admin who wish to perform system administration
functions as well as serve as customers queries.
SYSTEM FUNCTIONS/RESPONSIBILITIES
SYSTEM CONSTRAINTS
Hardware Constraints
The system should work on most home
desktop ,laptop Computers and smart-phones.
Software Constraints
The system is designed to run on Firefox ,Google
chrome and Internet Explorer.
Communications Constraints
System must have access to the included
database.Other components of the Property IQ system
may require access to certain data and web services.
Operational Constraints
The system is limited by its operating server in terms of the
maximum number of users it can support at a given time.
6
Site Adaptation Constraints
The component will be adapted to the overarching
system at the conclusion of the system creation.
SYSTEM ANALYSIS
a) Problem Specification
b) Feasibility Study
c)System Requirements Specification
d) Existing System
PROBLEM SPECIFICATIOON
FEASIBILITY STUDY
TECHNICAL FEASIBILITY
7
and development of code in a cleaner fashion. Input validation code
attached to the user interface elements reduce the errors in data entry
to a greater extent and reduce errors in accounts maintenance.
Economical feasibility
Functional Requirements
Registration
Basket
Payment
Product management
8
Orders management
VAT and shipping costs
Registration
Basket
Payment
After filling in the order, the customer enters his/her credit card
number that travels along a channel solely accessible to the
bank. The bank checks the customer’s account and decides
whether or not to authorise the payment.
The operation takes a few moments. If approved, the bank performs the
transaction and transfers the payment to the account. If denied the user is
notified that the transaction cannot be completed and his order is cancelled.
Product management
9
Product management:
product code
category
subcategory
product name
description
image, zoom
sizes available
price in rupees
'pieces' in stock
From the back office of the site you can search and sort orders by:
Customer
order
status Date
10
payment
Discounts
Discounts and promotions are managed for a single product
or product category.
SYSTEM REQUIREMENT
1. SOFTWARE REQUIREMENT:
2. HARDWARE REQUIREMENT:
11
LITERATURE SURVEY
Introduction to django:
Django is a web development framework that assists in
building and maintaining quality web applications. Django
helps eliminate repetitive tasks making the development
process an easy and time saving experience. This tutorial
gives a complete understanding of Django.
12
Clean Design − Django strictly maintains a clean design
throughout its own code and makes it easy to follow
best web-development practices.
Advantages of Django
Here are few advantages of using Django which can be
listed out here −
13
The developer provides the Model, the view and the
template then just maps it to a URL and Django does
the magic to serve it to the user.
Installing Django is very easy, but the steps required for its
installation depends on your operating system. Since Python
is a platform-independent language, Django has one package
that works everywhere regardless of your operating system.
14
You have two ways of installing Django if you are running
Linux or Mac OS system −
Windows Installation
16
BASIC DJANGO
STRUCTURE
which
database
17
connectivity, which also can provide functionality to
compile Django in to a .war suitable for deployment.
Google App Engine includes support for Django version
1.x.x as one of the bundled frameworks.
SYSTEM DESIGN
1. UML Diagrams
2. Database Design
3. Dataflow Diagrams
4. E-R Diagrams
5. Database Tables
UML DIAGRAMS (unified modeling language)
UML is the international standard notation for object-oriented
analysis and design. The Object Management Group defines it. The heart of
object-oriented problem solving is the construction of a model. The
Class:
A class is a description of a set of objects that share the same attributes,
operations, relationships, and semantics. A class implements one or more
interfaces. Graphically a class is rendered as a rectangle, usually including
its name, attributes and operations, as shown below.
Login
Userid
Password
Verify()
Exit()
Interface:
An interface is a collection of operations that specify a
service of a class or component. An interface describes the
externally visible behavior of that element.
Graphically the interface is rendered as a circle together with its name.
ISpelling
19
Collaboration:
Collaboration defines interaction and is a society of roles and
other elements that work together to provide some cooperative
behavior that's bigger than the sum of all the elements.
Graphically, collaboration is rendered as an ellipse with dashed
lines, usually including only its name as shown below.
Chain of
Responsibility
Use Case:
Use case is a description of a set of sequence of actions that a system
performs that yields an observable result of value to a particular thing
in a model. Graphically, Use Case is rendered as an ellipse with dashed
lines, usually including only its name as shown below.
Place Order
Component:
Component is a physical and replaceable part of a system that conforms
to and provides the realization of a set of interfaces. Graphically, a
component is rendered as a rectangle with tabs, usually including only
its name, as shown below.
Home.aspx
Home.py
20
Node:
A Node is a physical element that exists at run time and represents
a computational resource, generally having at least some memory
and often, processing capability. Graphically, a node is rendered
as a cube, usually including only its name, as shown below.
Server
BEHAVIORAL THINGS:
Behavioural Things are the dynamic parts of UML models. These are
the verbs of a model, representing behaviour over time and space.
Interaction:
Display
State Machine:
A state machine is a behaviour that specifies the sequence of states
an object are an interaction goes through during its lifetime on
response to events, together with its responses to those events.
Graphically, a state is rendered as a rounded rectangle usually
including its name and its sub-states, if any, as shown below.
Waiting
21
GROUPING THINGS:
Grouping things are the organizational parts of the UML models.
These are the boxes into which a model can be decomposed.
Package:
general-purpose
mechanism for organizing
elements into groups.
ANNOTATIONAL THINGS:
An notational things are the explanatory parts of the UML models.
1. Dependency:
2. Association:
4. Realization:
DIAGRAMS IN UML:
Diagrams play a very important role in the UML. There are
nine kind of modeling diagrams as follows:
Use Case Diagram
Class Diagram
Object Diagram
Sequence Diagram
Collaboration Diagram
State Chart Diagram
Activity Diagram
Component Diagram
Deployment Diagram
CLASS DIAGRAM:
23
USE CASES DIAGRAM:
Use Case diagrams are one of the five diagrams in the UML for
modeling the dynamic aspects of systems(activity diagrams, sequence
diagrams, state chart diagrams and collaboration diagrams are the four
other kinds of diagrams in the UML for modeling the dynamic aspects
of systems). Use Case diagrams are central to modeling the behavior of
the system, a sub-system, or a class. Each one shows a set of use
cases and actors and relationships.
Common Properties:
A Use Case diagram is just a special kind of diagram and shares the
same common properties, as do all other diagrams- a name and
graphical contents that are a projection into the model. What
distinguishes a use case diagram from all other kinds of diagrams is its
particular content.
Contents
Use Case diagrams commonly contain:
Use Cases
Actors
Dependency, generalization, and association relationships
Like all other diagrams, use case diagrams may contain notes and
constraints. Use Case diagrams may also contain packages, which are
used to group elements of your model into larger chunks. Occasionally,
you will want to place instances of use cases in your diagrams, as well,
especially when you want to visualize a specific executing system.
INTERACTION DIAGRAMS
An Interaction diagram shows an interaction, consisting of a set of
objects and their relationships, including the messages that may be
dispatched among them. Interaction diagrams are used for modeling the
dynamic aspects of the system.
A sequence diagram is an interaction diagram that emphasizes the
time ordering of the messages. Graphically, a sequence diagram is a
table that shows objects arranged along the X-axis and messages,
ordered in increasing time, along the Y-axis and messages, ordered in
increasing time, along the Y-axis.
Interaction diagrams commonly contain:
Objects
Links
24
Messages
Like all other diagrams, interaction diagrams may contain
notes and constraints.
SEQUENCE DIAGRAMS:
A sequence diagram is an interaction diagram that emphasizes
the time ordering of the messages. Graphically, a sequence diagram
is a table that shows objects arranged along the X-axis and
messages, ordered in increasing time, along the Y-axis.Typically
you place the object that initiates the interaction at the left, and
increasingly more sub-routine objects to the right. This gives the
reader a clear visual cue to the flow of control over time.
Sequence diagrams have two interesting features:
Contents
Sequence diagrams commonly contains
Objects
Object Life Line
Focus of Control
ACTIVITY DIAGRAM
An Activity Diagram is essentially a flow chart showing
flow of control from activity to activity. They are used to
model the dynamic aspects of as system. They can also be
used to model the flow of an object as it moves from state
to state at different points in the flow of control.
25
An activity is an ongoing non-atomic execution with in a State
machine. Activities ultimately result in some action, which is
made up of executable atomic computations that result in a
change of state of distinguishes a use case diagram from all
other kinds of diagrams is its particular content.
Contents
Fork
26
DATABASE DESIGN
DATA-FLOW DIAGRAMS
CONTEXT DIAGRAM
3. LOGICAL DFD:
27
BASIC NOTATION:
The Basic Notation used to create a DFD's are as follows:
DATAFLOW:
Data move in a specific direction from an origin to a destination.
SOURCE:
External sources or destination of data, which may be People,
programs, organizations or other entities.
DATA STORE:
DESIGN:
Design is the first step in moving from problem domain to
the solution domain. Design is essentially the bridge
between requirements specification and the final solution.
The goal of design process is to produce a model or representation
of a system, which can be used later to build that system.
The produced model is called the "Design of the System". It
is plan for a solution for the system.
28
E-R DIAGRAM :
29
CONTEXT FLOW DIAGRAM:
Description: Context Flow Diagram gives us the complete details about
the inputs and outputs for a given system. In the above system the
main task is to identify a criminal face. So, the operator and eyewitness
are the inputs to our system and criminal face is desired output.
DEVELOPMENT MODEL
Customer Communication:
Tasks required establishing effective
communication between developer and customer.
Planning:
Tasks required defining resources, timelines, and
other project related information.
Risk analysis:
Tasks required to assess both technical and
management risks. Engineering: Tasks required building one
or more representations of the applications.
30
Customer Evaluation:
Tasks required obtaining customer feedback based on
evaluation of the software representations created during the
engineering stage and implemented during the installation stage.
Effort Cost
Estimation Estimation
Size
estimation
PERT controls time and costs during the project and also
facilitates finding the right balance between completing a project
on time and facilitates finding the right balance between
completing a project on time and completing it within the budget.
Gantt Chart:
A Gantt Chart, is perhaps the simplest of formal project management.
The Gantt Chart is used almost exclusively for scheduling purpose and
therefore controls only the time dimension of projects.
Gantt Charts are project control techniques that can be used for
several purpose, including scheduling, budgeting and resource planning.
A Gantt Chart is a bar chart, with each bar representing an
activities. The bars drawn against a time line. The length of each
bar is proportional to the length of time planned for the activity.
32
SCREEN SHOTS
HOME:
33
SIGN UP:
34
LOGIN:
35
PASSWORD RESET:
PRODUCT DETAILS:
36
ORDER SUMMARY:
37
CHECKOUT FORM:
38
ADMIN LOGIN:
39
ADMIN DASHBOARD:
40
ADMIN USER:
ADMIN/ADD PRODUCT:
41
CODING
Front-end codes:
base.html
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no">
<meta http-equiv="x-ua-compatible"
content="ie=edge"> <title>{% block head_title
%}{% endblock %}</title> {% block extra_head %}
{% endblock %}
<link rel="stylesheet"
href="https://use.fontawesome.com/releases/v5.8.1/css/all.c ss">
<link href="{% static 'css/bootstrap.min.css' %}"
rel="stylesheet"> <link href="{% static 'css/mdb.min.css' %}"
rel="stylesheet"> <link href="{% static 'css/style.min.css' %}"
rel="stylesheet"> <style type="text/css">
html,
body,
header,
.carousel {
height: 60vh;
}
html,
body,
header,
.carousel {
height: 100vh;
}
}
html,
42
body,
header,
.carousel {
height: 100vh;
}
}
</style>
</head>
{% include "navbar.html" %}
<body>
{% block content %}
{% endblock content %}
{% block extra_body %}
{% endblock %}
{% include "footer.html" %}
{% include "scripts.html" %}
{% block extra_scripts %}
{% endblock extra_scripts %}
</body>
</html>
home.html
{% extends "base.html" %}
43
{% block content %}
<main>
<div class="container">
<!--Navbar-->
<nav class="navbar navbar-expand-lg navbar-dark
mdb-color lighten-3 mt-3 mb-5">
</ul>
44
<!-- Links -->
<form class="form-inline">
<div class="md-form my-0">
<input class="form-control
mr-sm-
2" type="text" placeholder="Search"
aria-label="Search"> </div>
</form>
</div>
<!-- Collapsible content -->
</nav>
<!--/.Navbar-->
<div class="card">
<h4 class="font-weight-bold
blue-text"> <strong>Rs
{% if item.discount_price %}
{{ item.discount_price
}} {% else %}
{{ item.price }}
{% endif %}
</strong>
</h4>
</div>
</div>
</div>
{% endfor %}
</div>
</section>
<!--Section: Products v.3-->
<!--Pagination-->
{% if is_paginated %}
<nav class="d-flex justify-content-center wow
fadeIn"> <ul class="pagination pg-blue">
{% if page_obj.has_previous %}
<li class="page-item">
46
<a
page_obj.previous_page_number
class="page-
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-
link" href="?page={{ page_obj.next_page_number }}" aria-label="Next">
<span aria-hidden="true">»</span>
<span class="sr-only">Next</span>
</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
</div>
</main>
{% endblock content %}
navbar.html
{% load cart_template_tags %}
</div>
</nav>
Footer.html
<hr class="my-4">
<!--Copyright-->
<div class="footer-copyright py-3">
© 2020 Copyright:
<a href="" target="_blank">
OnlineDeal.com </a> </div>
<!--/.Copyright-->
</footer>
Product.html
50
{% extends "base.html" %}
{% block content %}
<!--Grid row-->
<div class="row wow fadeIn">
<!--Grid column-->
<div class="col-md-6 mb-4">
<img
src="https://mdbootstrap.com/img/Photos/Horizontal/E-commerce/Produ
cts/14.jpg" class="img-fluid" alt="">
<img src="{{ oject.get_absolute_url }}" class="img-fluid" alt="">
</div>
<!--Grid column-->
<!--Grid column-->
<div class="col-md-6 mb-4">
<!--Content-->
<div class="p-4">
<div class="mb-3">
<a href="">
<span class="badge
purple mr-
1">{{ object.get_category_display
}}</span> </a>
</div>
<p class="lead">
{% if object.discount_price %}
<span class="mr-1">
<del>Rs {{ object.price }}</del>
</span>
<span>Rs {{ object.discount_price
}}</span> {% else %}
51
<span>Rs {{ object.price }}</span>
{% endif %}
</p>
</form> {% endcomment %}
<a href="{{ object.get_add_to_cart_url }}"
class="btn btn-primary btn-md my-0 p">
Add to cart
<i class="fas fa-shopping-cart
ml-1"></i> </a>
<a href="{{ object.get_remove_from_cart_url }}"
class="btn btn-danger btn-md my-0 p">
Remove from cart
</a>
</div>
<!--Content-->
</div>
<!--Grid column-->
</div>
<!--Grid row-->
<hr>
<!--Grid row-->
52
<div class="row d-flex justify-content-center wow fadeIn">
<!--Grid column-->
<div class="col-md-6 text-center">
</div>
<!--Grid column-->
</div>
<!--Grid row-->
<!--Grid row-->
<div class="row wow fadeIn">
<!--Grid column-->
<div class="col-lg-4 col-md-12 mb-4">
<img
src="https://mdbootstrap.com/img/Photos/Horizontal/E-commerce/Produ
cts/11.jpg" class="img-fluid" alt="">
</div>
<!--Grid column-->
<!--Grid column-->
<div class="col-lg-4 col-md-6 mb-4">
<img
src="https://mdbootstrap.com/img/Photos/Horizontal/E-commerce/Produ
cts/12.jpg" class="img-fluid" alt="">
</div>
<!--Grid column-->
53
<!--Grid column-->
<div class="col-lg-4 col-md-6 mb-4">
<img
src="https://mdbootstrap.com/img/Photos/Horizontal/E-commerce/Produ
cts/13.jpg" class="img-fluid" alt="">
</div>
<!--Grid column-->
</div>
<!--Grid row-->
</div>
</main>
{% endblock content %}
order_summary.html
{% extends "base.html" %}
{% block content %}
<main>
<div class="container">
<div class="table-responsive
text-nowrap"> <h2>Order
Summary</h2>
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Item title</th>
<th scope="col">Price</th>
<th scope="col">Quantity</th>
<th scope="col">Total Item
Price</th> </tr>
</thead>
<tbody>
{% for order_item in object.items.all %}
<tr>
54
<th scope="row">{{ forloop.counter
}}</th> <td>{{ order_item.item.title
}}</td> <td>{{ order_item.item.price
}}</td> <td>
<a href="{% url
'core:remove-single-item-from-cart' order_item.item.slug
%}"><i
class="fas fa-minus
mr-2"></i></a> {{
order_item.quantity }}
<a href="{% url 'core:add-to-
cart' order_item.item.slug %}"><i
class="fas fa-plus ml-2"></i></a>
</td>
<td>
{% if order_item.item.discount_price %}
Rs {{ order_item.get_total_discount_item_price }}
<span class="badge badge-
primary">Saving Rs {{ order_item.get_amount_saved
}}</span> {% else %}
Rs {{ order_item.get_total_item_price
}} {% endif %}
<a style='color: red;' href="{% url
'core:remove-from-cart' order_item.item.slug %}">
<i class="fas fa-trash float-right"></i>
</a>
</td>
</tr>
{% empty %}
<tr>
<td colspan='5'>Your cart is empty</td>
</tr>
<tr>
<td colspan="5">
<a class='btn btn-primary float-
right' href='/'>Continue shopping</a>
</td>
</tr>
{% endfor %}
{% if object.coupon %}
<tr>
<td colspan="4"><b>Coupon</b></td>
55
<td><b>-Rs{{ object.coupon.amount
}}</b></td> </tr>
{% endif %}
{% if object.get_total %}
<tr>
<td colspan="4"><b>Order Total</b></td>
<td><b>Rs {{ object.get_total }}</b></td>
</tr>
<tr>
<td colspan="5">
<a class='btn btn-warning float-right ml-
2' href='/checkout/'>Proceed to checkout</a>
<a class='btn btn-primary float-
right' href='/'>Continue shopping</a>
</td>
</tr>
{% endif %}
</tbody>
</table>
</div>
</div>
</main>
{% endblock content %}
Order_snippet.html
<div class="col-md-12 mb-4">
<h4 class="d-flex justify-content-between align-items-center
mb-3"> <span class="text-muted">Your cart</span>
<span class="badge badge-secondary
badge-pill">{{ order.items.count }}</span>
</h4>
<ul class="list-group mb-3 z-depth-1">
{% for order_item in order.items.all %}
<li class="list-group-item d-flex
justify-content-between lh-condensed">
<div>
56
<h6 class="my-
0">{{ order_item.quantity }} x {{ order_item.item.title}}</h6>
<small class="text-
muted">{{ order_item.item.description}}</small>
</div>
<span class="text-
muted">Rs {{ order_item.get_final_price
}}</span> </li>
{% endfor %}
{% if order.coupon %}
<li class="list-group-item d-flex justify-content-between
bg-light"> <div class="text-success">
<h6 class="my-0">Promo code</h6>
<small>{{ order.coupon.code }}</small>
</div>
<span class="text-success">-${{ order.coupon.amount
}}</span> </li>
{% endif %}
<li class="list-group-item d-flex
justify-content-between"> <span>Total
(Rs)</span>
<strong>Rs {{ order.get_total
}}</strong> </li>
</ul>
{% if DISPLAY_COUPON_FORM %}
<form class="card p-2" action="{% url
'core:add-coupon' %}" method="POST">
{% csrf_token %}
<div class="input-group">
{{ couponform.code }}
<div class="input-group-append">
<button class="btn btn-secondary btn-md
waves-effect m-0" type="submit">Redeem</button>
</div>
</div>
</form>
{% endif %}
</div>
57
Checkout.hmtl
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<main >
<div class="container wow fadeIn">
<h2 class="my-5 h2 text-center">Checkout
form</h2> <div class="row">
<div class="col-md-8 mb-4">
<div class="card">
<form method="POST"
class="card-body"> {% csrf_token
%}
<h3>Shipping address</h3>
<div class='hideable_shipping_form'>
<div class="row">
<div class="col-lg-4 col-md-12 mb-4">
<label for="country">Country</label>
{{ form.shipping_country
}} <div
class="invalid-feedback"
> Please select a valid
country. </div>
58
</div>
<div class="col-lg-4 col-md-6 mb-4">
<label for="shipping_zip">Zip</label>
<input type='text' placeholder='Zip code'
id='shipping_zip' na me='shipping_zip' class='form-control' />
<div class="invalid-feedback">
Zip code required.
</div>
</div>
</div>
</div>
{% if default_shipping_address %}
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-
input" name="use_default_shipping" id="use_default_shipping">
<label class="custom-control-
label" for="use_default_shipping">Use default shipping address: {{ defa
ult_shipping_address.street_address|truncatechars:10 }}</label>
</div>
{% endif %}
<hr>
59
<h3>Billing address</h3>
<div class='hideable_billing_form'>
<div class="md-form mb-5">
<input type='text' placeholder='1234 Main St'
id='billing_addre ss' name='billing_address' class='form-control' />
<label for="billing_address"
class="">Address</label> </div>
<div class="row">
<div class="col-lg-4 col-md-12 mb-4">
<label for="country">Country</label>
{{ form.billing_country }}
<div class="invalid-feedback">
Please select a valid country.
</div>
</div>
</div>
60
<label class="custom-control-
label" for="set_default_billing">Save as default billing
address</label> </div>
</div>
{% if default_billing_address %}
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-
input" name="use_default_billing" id="use_default_billing">
<label class="custom-control-
label" for="use_default_billing">Use default billing address: {{ default_bi
lling_address.street_address|truncatechars:10 }}</label>
</div>
{% endif %}
<hr>
<h3>Payment option</h3>
<hr class="mb-4">
<button class="btn btn-primary
btn-lg btn-
block" type="submit">Continue to checkout</button>
</form>
</div>
</div>
61
<div class="col-md-4 mb-4">
{% include "order_snippet.html" %}
</div>
</div>
</div>
</main>
{% endblock content %}
{% block extra_scripts %}
<script>
var hideable_shipping_form = $('.hideable_shipping_form');
var hideable_billing_form = $('.hideable_billing_form');
var use_default_shipping =
document.querySelector("input[name=use_ default_shipping]");
var use_default_billing =
document.querySelector("input[name=use_def ault_billing]");
use_default_shipping.addEventListener('change',
function() { if (this.checked) {
hideable_shipping_form.hide();
} else {
hideable_shipping_form.show();
}
})
use_default_billing.addEventListener('change',
function() { if (this.checked) {
hideable_billing_form.hide();
} else {
hideable_billing_form.show();
}
})
</script>
{% endblock extra_scripts %}
62
Payment.html
{% extends "base.html" %}
{% block extra_head %}
<style>
#stripeBtnLabel {
font-family: "Helvetica Neue", Helvetica, sans-serif;
font-size: 16px;
font-variant: normal;
padding: 0;
margin: 0;
-webkit-font-smoothing: antialiased;
font-weight: 500;
display: block;
}
#stripeBtn {
border: none;
border-radius: 4px;
outline: none;
text-decoration: none;
color: #fff;
background: #32325d;
white-space: nowrap;
display: inline-block;
height: 40px;
line-height: 40px;
box-shadow: 0 4px 6px rgba(50, 50, 93, .11), 0 1px 3px rgba(0, 0, 0, .08);
border-radius: 4px;
font-size: 15px;
font-weight: 600;
letter-spacing: 0.025em;
text-decoration: none;
-webkit-transition: all 150ms ease;
transition: all 150ms ease;
float: left;
width: 100%
}
63
button:hover {
transform: translateY(-1px);
box-
shadow: 0 7px 14px rgba(50, 50, 93, .10), 0 3px 6px rgba(0, 0, 0, .08);
background-color: #43458b;
}
.stripe-form {
padding: 5px 30px;
}
#card-errors {
height: 20px;
padding: 4px 0;
color: #fa755a;
}
.stripe-form-row {
width: 100%;
float: left;
margin-top: 5px;
margin-bottom: 5px;
}
/**
* The CSS shown here will not be introduced in the
Quickstart guide, bu t shows
* how you can use CSS to style your Element's container.
*/
.StripeElement {
box-sizing: border-box;
height: 40px;
64
box-shadow: 0 1px 3px 0 #e6ebf1;
-webkit-transition: box-shadow 150ms ease;
transition: box-shadow 150ms ease;
}
.StripeElement--focus {
box-shadow: 0 1px 3px 0 #cfd7df;
}
.StripeElement--invalid {
border-color: #fa755a;
}
.StripeElement--webkit-autofill {
background-color: #fefde5 !important;
}
.current-card-form {
display: none;
}
</style>
{% endblock extra_head %}
{% block content %}
<main >
<div class="container wow fadeIn">
<div class="row">
<script src="https://js.stripe.com/v3/"></script>
{% if card %}
<div style="padding: 5px 30px;">
65
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-
input" name="use_default_card" id="use_default_card">
<label class="custom-control-
label" for="use_default_card">Use default card:
**** **** **** {{ card.last4 }}
<span>Exp: {{ card.exp_month }}/{{ card.exp_year }}</span></l
abel>
</div>
</div>
{% endif %}
<div class="current-card-form">
<form action="." method="post"
class="stripe-form"> {% csrf_token %}
<input type="hidden" name="use_default"
value="true"> <div class="stripe-form-row">
<button id="stripeBtn">Submit
Payment</button> </div>
<div id="card-errors"
role="alert"></div> </form>
</div>
<div class="new-card-form">
<form action="." method="post" class="stripe-form" id="stripe-
form">
{% csrf_token %}
<div class="stripe-form-row" id="creditCard">
<label for="card-element" id="stripeBtnLabel">
Credit or debit card
</label>
<div id="card-element" class="StripeElement StripeElement-
-
empty"><div class="__PrivateStripeElement" style="margin: 0px !import
ant; padding: 0px !important; border: none !important; display: block !i
mportant; background: transparent !important; position: relative !impor
tant; opacity: 1 !important;"><iframe frameborder="0" allowtransparenc
y="true" scrolling="no" name="__privateStripeFrame5" allowpaymentre
quest="true"
src="https://js.stripe.com/v3/elements-inner-card-19066928f2ed1ba3ff
ada645e45f5b50.html#style[base][color]=%233232
66
5d&style[base][fontFamily]=%22Helvetica+Neue%22%2C+Helvetica
%2C+sans-
serif&style[base][fontSmoothing]=antialiased&style[base][fon
tSize]=16px&style[base][::placeholder][color]=%23aab7c4&sty
le[invalid][color]=%23fa755a&style[invalid][iconColor]=%23fa755a
&componentName=card&wait=false&rtl=false&key
Mode=test&origin=https%3A%2F%2Fstripe.com&referrer=htt
ps%3A%2F%2Fstripe.com%2Fdocs%2Fstripe-
js&controllerId=__privateStripeController1" title="Secure payment
input frame" style="border: none !important; margin: 0px !important; p
adding: 0px !important; width: 1px !important; min-
width: 100% !important; overflow: hidden !important; display: block !im
portant; height: 19.2px;"></iframe><input class="__PrivateStripeElemen
t-input" aria-hidden="true" aria-label=" " autocomplete="false"
maxlength="1" style="border: none !imp ortant; display: block
!important; position: absolute !important; height: 1px !important;
top: 0px !important; left: 0px !important; padding: 0px !i mportant;
margin: 0px !important; width: 100% !important; opacity: 0 !i
mportant; background: transparent !important; pointer-
events: none !important; font-size: 16px
!important;"></div></div> </div>
<div class="stripe-form-row">
<button id="stripeBtn">Submit
Payment</button> </div>
<div class="stripe-form-row">
<div class="custom-control custom-checkbox">
<input type="checkbox"
class="custom-control-input" name="save"
id="save_card_info">
<label class="custom-control-
label" for="save_card_info">Save for future
purchases</label> </div>
</div>
<div id="card-errors"
role="alert"></div> </form>
</div>
</div>
</div>
{% include "order_snippet.html" %}
67
</div>
</div>
</main>
{% endblock content %}
{% block extra_scripts %}
stripe.createToken(card).then(function(result) {
if (result.error) {
// Inform the user if there was an error.
var errorElement =
document.getElementById('card-errors');
errorElement.textContent = result.error.message;
} else {
// Send the token to your server.
stripeTokenHandler(result.token);
}
});
});
</script>
{% endblock extra_scripts %}
Scrtips.html
{% load static %}
</script>
70
Signup.html
{% extends "account/base.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block content %}
<main>
<div class="container">
<section class="mb-4">
<div class="row wow fadeIn">
<div class='col-6 offset-3'>
<h1>{% trans "Sign Up" %}</h1>
<p>{% blocktrans %}Already have an account? Then please
<a hre f="{{ login_url }}">sign in</a>.{% endblocktrans %}</p>
<form class="signup" id="signup_form" method="post" action="{
% url 'account_signup'
%}"> {% csrf_token
%}
{{ form|crispy }}
{% if redirect_field_value %}
<input type="hidden" name="{{ redirect_field_name }}" value="{
{ redirect_field_value }}" />
{% endif %}
<button class='btn btn-
primary' type="submit">{% trans "Sign Up" %}
»</button> </form>
</div>
</div>
</section>
</div>
</main>
{% endblock %}
Signup_closed.html
{% extends "account/base.html" %}
71
{% load i18n %}
{% block content %}
<h1>{% trans "Sign Up Closed" %}</h1>
Login.html
{% extends "account/base.html" %}
{% load i18n %}
{% load account socialaccount %}
{% load crispy_forms_tags %}
{% block content %}
<main>
<div class="container">
<section class="mb-4">
<div class="row wow fadeIn">
<div class='col-6 offset-3'>
<h1>{% trans "Sign In" %}</h1>
{% get_providers as socialaccount_providers %}
{% if socialaccount_providers %}
<p>{% blocktrans with site.name as site_name %}Please sign in wit
h one
of your existing third party accounts. Or, <a href="{{
signup_url }}"> sign up</a>
for a {{ site_name }} account and sign in below:{% endblocktrans %}
</p>
<div class="socialaccount_ballot">
<ul class="socialaccount_providers">
72
{% include "socialaccount/snippets/provider_list.html"
with proc ess="login" %}
</ul>
</div>
{% include "socialaccount/snippets/login_extra.html" %}
{% else %}
<p>{% blocktrans %}If you have not created an account yet, then pl
ease
<a href="{{ signup_url }}">sign up</a> first.{% endblocktrans %}</p
>
{% endif %}
{% endblock %}
73
Logout.html
{% extends "account/base.html" %}
{% load i18n %}
{% block content %}
<main>
<div class="container">
<section class="mb-4">
<div class="row wow fadeIn">
<div class='col-6 offset-3'>
<h1>{% trans "Sign Out" %}</h1>
<p>{% trans 'Are you sure you want to sign out?'
%}</p> <form method="post" action="{% url
'account_logout' %}"> {% csrf_token %}
{% if redirect_field_value %}
<input type="hidden" name="{{ redirect_field_name }}" value="{
{ redirect_field_value }}"/>
{% endif %}
<button class='btn btn-
primary' type="submit">{% trans 'Sign Out'
%}</button> </form>
</div>
</div>
</section>
</div>
</main>
{% endblock %}
Password_change.html
{% extends "account/base.html" %}
{% load i18n %}
{% block content %}
<h1>{% trans "Change Password" %}</h1>
74
<form method="POST" action="{% url
'account_change_password' %}" class="password_change">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" name="action">{% trans "Change
Password" %}</button>
</form>
{% endblock %}
Password_reset_done.html
{% extends "account/base.html" %}
{% load i18n %}
{% load account %}
{% block content %}
<h1>{% trans "Password Reset" %}</h1>
{% if user.is_authenticated %}
{% include "account/snippets/already_logged_in.html"
%} {% endif %}
Password_reset_from_key_done.html
{% extends "account/base.html" %}
{% load i18n %}
{% block head_title %}{% trans "Change Password" %}{% endblock %}
{% block content %}
<h1>{% trans "Change Password" %}</h1>
75
<p>{% trans 'Your password is now
changed.' %}</p> {% endblock %}
Password_reset_from_key.html
{% extends "account/base.html" %}
{% load i18n %}
{% block head_title %}{% trans "Change Password" %}{% endblock %}
{% block content %}
<h1>{% if token_fail %}{% trans "Bad Token" %}{% else
%}{% trans "Ch ange Password" %}{% endif %}</h1>
{% if token_fail %}
{% url 'account_reset_password' as passwd_reset_url %}
<p>{% blocktrans %}The password reset link was invalid, possibly be
cause it has already been used. Please request a <a href="{{ passwd_res
et_url }}">new password reset</a>.{% endblocktrans %}</p>
{% else %}
{% if form %}
<form method="POST" action="{{
action_url }}"> {% csrf_token %}
{{ form.as_p }}
<input type="submit" name="action" value="{% trans
'change p assword' %}"/>
</form>
{% else %}
<p>{% trans 'Your password is now
changed.' %}</p> {% endif %}
{% endif %}
{% endblock %}
Password_reset.html
{% extends "account/base.html" %}
{% load i18n %}
{% load account %}
76
{% block content %}
Password_set.html
{% extends "account/base.html" %}
{% load i18n %}
{% block content %}
<h1>{% trans "Set Password" %}</h1>
app_name = 'core'
urlpatterns = [
path('', HomeView.as_view(), name='home'), path('checkout/',
CheckoutView.as_view(), name='checkout'),
path('order-summary/', OrderSummaryView.as_view(),
name='order-
summary'),
path('product/<slug>/', ItemDetailView.as_view(), name='product'),
path('add-to-cart/<slug>/', add_to_cart, name='add-to-cart'),
path('add-coupon/', AddCouponView.as_view(), name='add-coupon'),
path('remove-from-cart/<slug>/', remove_from_cart, name='remove-
from-cart'),
path('remove-item-from-
cart/<slug>/', remove_single_item_from_cart,
name='remove-single-item-from-cart'),
path('payment/<payment_option>/', PaymentView.as_view(),
name=' payment'),
78
path('request-
refund/', RequestRefundView.as_view(), name='request-refund')
]
Views.py
import random
import string
import stripe
stripe.api_key = settings.STRIPE_SECRET_KEY
def create_ref_code():
return ''.join(random.choices(string.ascii_lowercase +
string.digits, k=2 0))
def products(request):
context = {
'items': Item.objects.all()
}
return render(request, "products.html", context)
def is_valid_form(values):
valid = True
for field in values:
if field == '':
79
valid = False
return valid
class CheckoutView(View):
def get(self, *args, **kwargs):
try:
order = Order.objects.get(user=self.request.user, ordered=False)
form = CheckoutForm()
context = {
'form': form,
'couponform': CouponForm(),
'order': order,
'DISPLAY_COUPON_FORM': True
}
shipping_address_qs = Address.objects.filter(
user=self.request.user, address_type='S',
default=True
)
if shipping_address_qs.exists():
context.update(
{'default_shipping_address': shipping_address_qs[0]})
billing_address_qs = Address.objects.filter(
user=self.request.user, address_type='B',
default=True
)
if billing_address_qs.exists():
context.update(
{'default_billing_address': billing_address_qs[0]})
80
try:
order = Order.objects.get(user=self.request.user, ordered=False)
if form.is_valid():
use_default_shipping = form.cleaned_data.get(
'use_default_shipping')
if use_default_shipping:
print("Using the defualt shipping address")
address_qs = Address.objects.filter(
user=self.request.user,
address_type='S',
default=True
)
if address_qs.exists():
shipping_address = address_qs[0]
order.shipping_address = shipping_address
order.save()
else:
messages.info(
self.request, "No default shipping address available")
return redirect('core:checkout')
else:
print("User is entering a new shipping address")
shipping_address1 = form.cleaned_data.get(
'shipping_address')
shipping_address2 = form.cleaned_data.get(
'shipping_address2')
shipping_country = form.cleaned_data.get(
'shipping_country')
shipping_zip = form.cleaned_data.get('shipping_zip')
order.shipping_address =
shipping_address order.save()
set_default_shipping = form.cleaned_data.get(
'set_default_shipping')
if set_default_shipping:
shipping_address.default = True
shipping_address.save()
else:
messages.info(
self.request, "Please fill in the required shipping address
fields")
use_default_billing = form.cleaned_data.get(
'use_default_billing')
same_billing_address = form.cleaned_data.get(
'same_billing_address')
if same_billing_address:
billing_address = shipping_address
billing_address.pk = None
billing_address.save()
billing_address.address_type = 'B'
billing_address.save()
order.billing_address = billing_address
order.save()
elif use_default_billing:
print("Using the defualt billing address")
address_qs = Address.objects.filter(
user=self.request.user,
address_type='B',
default=True
)
if address_qs.exists():
billing_address = address_qs[0]
82
order.billing_address = billing_address
order.save()
else:
messages.info(
self.request, "No default billing address available")
return redirect('core:checkout')
else:
print("User is entering a new billing address")
billing_address1 = form.cleaned_data.get(
'billing_address')
billing_address2 = form.cleaned_data.get(
'billing_address2')
billing_country = form.cleaned_data.get(
'billing_country')
billing_zip = form.cleaned_data.get('billing_zip')
order.billing_address = billing_address
order.save()
set_default_billing = form.cleaned_data.get(
'set_default_billing')
if set_default_billing:
billing_address.default = True
billing_address.save()
else:
messages.info(
83
self.request, "Please fill in the required billing address fie
lds")
payment_option = form.cleaned_data.get('payment_option')
if payment_option == 'S':
return redirect('core:payment', payment_option='stripe')
elif payment_option == 'P':
return redirect('core:payment', payment_option='paypal')
else:
messages.warning(
self.request, "Invalid payment option selected")
return redirect('core:checkout')
except ObjectDoesNotExist:
messages.warning(self.request, "You do not have an active order")
return redirect("core:order-summary")
class PaymentView(View):
def get(self, *args, **kwargs):
order = Order.objects.get(user=self.request.user, ordered=False)
if order.billing_address:
context = {
'order': order,
'DISPLAY_COUPON_FORM': False
}
userprofile = self.request.user.userprofile
if userprofile.one_click_purchasing:
# fetch the users card list
cards = stripe.Customer.list_sources(
userprofile.stripe_customer_id,
limit=3,
object='card'
)
card_list = cards['data']
if len(card_list) > 0:
# update the context with the
default card context.update({
'card': card_list[0]
})
return render(self.request, "payment.html", context)
84
else:
messages.warning(
self.request, "You have not added a billing address")
return redirect("core:checkout")
if save:
if userprofile.stripe_customer_id != '' and
userprofile.stripe_cus tomer_id is not None:
customer = stripe.Customer.retrieve(
userprofile.stripe_customer_id)
customer.sources.create(source=token)
else:
customer = stripe.Customer.create(
email=self.request.user.email,
)
customer.sources.create(source=token)
userprofile.stripe_customer_id = customer['id']
userprofile.one_click_purchasing = True
userprofile.save()
try:
if use_default or save:
# charge the customer because we cannot charge
the token more than once
charge = stripe.Charge.create(
amount=amount, #
cents currency="usd",
85
customer=userprofile.stripe_customer_id
)
else:
# charge once off on the token
charge = stripe.Charge.create(
amount=amount, # cents
currency="usd",
source=token
)
order_items = order.items.all()
order_items.update(ordered=True)
for item in order_items:
item.save()
order.ordered = True
order.payment = payment
order.ref_code = create_ref_code()
order.save()
except stripe.error.CardError as e:
body = e.json_body
err = body.get('error', {})
messages.warning(self.request, f"{err.get('message')}")
return redirect("/")
except stripe.error.RateLimitError as e:
# Too many requests made to the API too quickly
86
messages.warning(self.request, "Rate limit error")
return redirect("/")
except stripe.error.InvalidRequestError as e:
# Invalid parameters were supplied to
Stripe's API print(e)
messages.warning(self.request, "Invalid
parameters") return redirect("/")
except stripe.error.AuthenticationError as e:
# Authentication with Stripe's API failed
# (maybe you changed API keys recently)
messages.warning(self.request, "Not
authenticated") return redirect("/")
except stripe.error.APIConnectionError as e:
# Network communication with Stripe
failed messages.warning(self.request,
"Network error") return redirect("/")
except stripe.error.StripeError as e:
# Display a very generic error to the user, and maybe send
# yourself an email
messages.warning(
self.request, "Something went wrong. You were not
charged. Please try again.")
return redirect("/")
except Exception as e:
# send an email to
ourselves
messages.warning(
self.request, "A serious error occurred. We have been notifed.
")
return redirect("/")
class HomeView(ListView):
model = Item
87
paginate_by = 16
template_name = "home.html"
class ItemDetailView(DetailView):
model = Item
template_name = "product.html"
@login_required
def add_to_cart(request, slug):
item = get_object_or_404(Item, slug=slug)
order_item, created =
OrderItem.objects.get_or_create( item=item,
user=request.user,
ordered=False
)
order_qs = Order.objects.filter(user=request.user, ordered=False)
if order_qs.exists():
order = order_qs[0]
# check if the order item is in the order
if order.items.filter(item__slug=item.slug).exists():
order_item.quantity += 1 order_item.save()
@login_required
def remove_from_cart(request, slug):
item = get_object_or_404(Item, slug=slug)
order_qs = Order.objects.filter(
user=request.user,
ordered=False
)
if order_qs.exists():
order = order_qs[0]
# check if the order item is in the order
if order.items.filter(item__slug=item.slug).exists():
order_item = OrderItem.objects.filter(
item=item,
user=request.user,
ordered=False
)[0]
order.items.remove(order_item)
order_item.delete()
messages.info(request, "This item was removed from your cart.")
return redirect("core:order-summary")
else:
messages.info(request, "This item was not in your cart")
return redirect("core:product", slug=slug)
else:
messages.info(request, "You do not have an active order")
return redirect("core:product", slug=slug)
@login_required
def remove_single_item_from_cart(request,
slug): item = get_ object_or_404(Item,
slug=slug) order_qs = Order.objects.filter(
user=request.user,
89
ordered=False
)
if order_qs.exists():
order = order_qs[0]
# check if the order item is in the order
if order.items.filter(item__slug=item.slug).exists():
order_item = OrderItem.objects.filter(
item=item,
user=request.user,
ordered=False
)[0]
if order_item.quantity > 1:
order_item.quantity -= 1
order_item.save()
else:
order.items.remove(order_item)
messages.info(request, "This item quantity was updated.")
return redirect("core:order-summary")
else:
messages.info(request, "This item was not in your cart")
return redirect("core:product", slug=slug)
else:
messages.info(request, "You do not have an active order")
return redirect("core:product", slug=slug)
class AddCouponView(View):
def post(self, *args, **kwargs):
form = CouponForm(self.request.POST or None)
if form.is_valid():
try:
code = form.cleaned_data.get('code')
order = Order.objects.get(
90
user=self.request.user, ordered=False)
order.coupon = get_coupon(self.request, code)
order.save()
messages.success(self.request, "Successfully added coupon")
return redirect("core:checkout")
except ObjectDoesNotExist:
messages.info(self.request, "You do not have an active order")
return redirect("core:checkout")
class RequestRefundView(View):
def get(self, *args, **kwargs):
form = RefundForm()
context = {
'form': form
}
return render(self.request, "request_refund.html", context)
except ObjectDoesNotExist:
91
messages.info(self.request, "This order does not exist.")
return redirect("core:request-refund")
Models.py
CATEGORY_CHOICES = (
('S', 'Shirt'),
('SW', 'Sport wear'),
('OW', 'Outwear')
)
LABEL_CHOICES = (
('P', 'primary'),
('S', 'secondary'),
('D', 'danger')
)
ADDRESS_CHOICES = (
('B', 'Billing'),
('S', 'Shipping'),
)
class UserProfile(models.Model):
user = models.OneToOneField(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
stripe_customer_id = models.CharField(max_length=50, blank=True, n
ull=True)
one_click_purchasing = models.BooleanField(default=False)
def __str__(self):
return self.user.username
class Item(models.Model):
92
title = models.CharField(max_length=100)
price = models.FloatField()
discount_price = models.FloatField(blank=True, null=True)
category = models.CharField(choices=CATEGORY_CHOICES,
max_lengt h=2)
label = models.CharField(choices=LABEL_CHOICES, max_length=1)
slug = models.SlugField()
description = models.TextField()
image = models.ImageField()
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("core:product",
kwargs={ 'slug': self.slug
})
def get_add_to_cart_url(self):
return reverse("core:add-to-cart",
kwargs={ 'slug': self.slug
})
def get_remove_from_cart_url(self):
return reverse("core:remove-from-cart",
kwargs={ 'slug': self.slug
})
class OrderItem(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
ordered = models.BooleanField(default=False)
item = models.ForeignKey(Item, on_delete=models.CASCADE)
quantity = models.IntegerField(default=1)
def __str__(self):
return f"{self.quantity} of {self.item.title}"
def get_total_item_price(self):
return self.quantity * self.item.price
93
def get_total_discount_item_price(self):
return self.quantity * self.item.discount_price
def get_amount_saved(self):
return self.get_total_item_price() -
self.get_total_discount_item_price()
def get_final_price(self):
if self.item.discount_price:
return self.get_total_discount_item_price()
return self.get_total_item_price()
class Order(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
ref_code = models.CharField(max_length=20, blank=True, null=True)
items = models.ManyToManyField(OrderItem)
start_date = models.DateTimeField(auto_now_add=True)
ordered_date = models.DateTimeField()
ordered = models.BooleanField(default=False)
shipping_address = models.ForeignKey(
'Address', related_name='shipping_address',
on_delete=models.SET _NULL, blank=True, null=True)
billing_address = models.ForeignKey(
'Address', related_name='billing_address',
on_delete=models.SET_N ULL, blank=True, null=True)
payment = models.ForeignKey(
'Payment', on_delete=models.SET_NULL, blank=True,
null=True) coupon = models.ForeignKey(
'Coupon', on_delete=models.SET_NULL, blank=True, null=True)
being_delivered = models.BooleanField(default=False)
received = models.BooleanField(default=False)
refund_requested = models.BooleanField(default=False)
refund_granted = models.BooleanField(default=False)
'''
1. Item added to cart
2. Adding a billing
address (Failed checkout)
94
3. Payment
(Preprocessing, processing, packaging etc.)
4. Being delivered
5. Received
6. Refunds
'''
def __str__(self):
return self.user.username
def get_total(self):
total = 0
for order_item in self.items.all():
total += order_item.get_final_price()
if self.coupon:
total -= self.coupon.amount
return total
class Address(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
street_address = models.CharField(max_length=100)
apartment_address = models.CharField(max_length=100)
country = CountryField(multiple=False)
zip = models.CharField(max_length=100)
address_type = models.CharField(max_length=1,
choices=ADDRESS_C HOICES)
default = models.BooleanField(default=False)
def __str__(self):
return self.user.username
class Meta:
verbose_name_plural = 'Addresses'
class Payment(models.Model):
stripe_charge_id = models.CharField(max_length=50) user
= models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.SET_NULL, blank=True, null=True)
amount = models.FloatField()
95
timestamp = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.user.username
class Coupon(models.Model):
code = models.CharField(max_length=15)
amount = models.FloatField()
def __str__(self):
return self.code
class Refund(models.Model):
order = models.ForeignKey(Order, on_delete=models.CASCADE)
reason = models.TextField()
accepted = models.BooleanField(default=False)
email = models.EmailField()
def __str__(self):
return f"{self.pk}"
post_save.connect(userprofile_receiver,
sender=settings.AUTH_USER_M ODEL)
Forms.py
PAYMENT_CHOICES = (
('S', 'Stripe'),
('P', 'PayPal')
)
96
class CheckoutForm(forms.Form):
shipping_address = forms.CharField(required=False)
shipping_address2 = forms.CharField(required=False)
shipping_country = CountryField(blank_label='(select
country)').formfi eld(
required=False,
widget=CountrySelectWidget(attrs={
'class': 'custom-select d-block w-100',
}))
shipping_zip = forms.CharField(required=False)
billing_address = forms.CharField(required=False)
billing_address2 = forms.CharField(required=False)
billing_country = CountryField(blank_label='(select country)').formfiel
d(
required=False,
widget=CountrySelectWidget(attrs={
'class': 'custom-select d-block w-100',
}))
billing_zip = forms.CharField(required=False)
same_billing_address = forms.BooleanField(required=False)
set_default_shipping = forms.BooleanField(required=False)
use_default_shipping = forms.BooleanField(required=False)
set_default_billing = forms.BooleanField(required=False)
use_default_billing = forms.BooleanField(required=False)
choices=PAYMENT_CHOICES)
class CouponForm(forms.Form):
code = forms.CharField(widget=forms.TextInput(attrs={
'class': 'form-control',
'placeholder': 'Promo code',
'aria-label': 'Recipient\'s username',
'aria-describedby': 'basic-addon2'
}))
class RefundForm(forms.Form):
ref_code = forms.CharField()
97
message = forms.CharField(widget=forms.Textarea(attrs={
'rows': 4
}))
email = forms.EmailField()
class PaymentForm(forms.Form):
stripeToken = forms.CharField(required=False)
save = forms.BooleanField(required=False)
use_default = forms.BooleanField(required=False)
Admin.py
class OrderAdmin(admin.ModelAdmin):
list_display = ['user',
'ordered',
'being_delivered',
'received',
'refund_requested',
'refund_granted',
'shipping_address',
'billing_address',
'payment',
'coupon'
]
list_display_links = [
'user',
'shipping_address',
'billing_address',
98
'payment',
'coupon'
]
list_filter = ['ordered',
'being_delivered',
'received',
'refund_requested',
'refund_granted']
search_fields = [
'user__username',
'ref_code'
]
actions = [make_refund_accepted]
class AddressAdmin(admin.ModelAdmin):
list_display = [
'user',
'street_address',
'apartment_address',
'country',
'zip',
'address_type',
'default'
]
list_filter = ['default', 'address_type', 'country']
search_fields = ['user', 'street_address', 'apartment_address', 'zip']
admin.site.register(Item)
admin.site.register(OrderItem)
admin.site.register(Order, OrderAdmin)
admin.site.register(Payment)
admin.site.register(Coupon)
admin.site.register(Refund)
admin.site.register(Address, AddressAdmin)
admin.site.register(UserProfile)
Migrations
_initial.py
99
from django.db import migrations, models
import django.db.models.deletion import
django_countries.fields
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Address',
fields=[
('id', models.AutoField(auto_created=True,
primary_key=True, s erialize=False, verbose_name='ID')),
('street_address', models.CharField(max_length=100)),
('apartment_address', models.CharField(max_length=100)),
('country', django_countries.fields.CountryField(max_length=2)),
('zip', models.CharField(max_length=100)),
('address_type', models.CharField(choices=[('B',
'Billing'), ('S', 'S hipping')], max_length=1)),
('default', models.BooleanField(default=False)),
('user', models.ForeignKey(on_delete=django.db.models.deleti
on.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='Coupon',
fields=[
('id', models.AutoField(auto_created=True,
primary_key=True, s erialize=False, verbose_name='ID')),
('code', models.CharField(max_length=15)),
('amount', models.FloatField()),
],
),
migrations.CreateModel(
name='Item',
100
fields=[
('id', models.AutoField(auto_created=True,
primary_key=True, s erialize=False, verbose_name='ID')),
('title', models.CharField(max_length=100)),
('price', models.FloatField()),
('discount_price', models.FloatField(blank=True, null=True)),
('category', models.CharField(choices=[('S', 'Shirt'), ('SW', 'Sport
wear'), ('OW', 'Outwear')], max_length=2)),
('label', models.CharField(choices=[('P', 'primary'), ('S',
'seconda ry'), ('D', 'danger')], max_length=1)),
('slug', models.SlugField()), ('description',
models.TextField()), ('image',
models.ImageField(upload_to='')),
],
),
migrations.CreateModel(
name='Order',
fields=[
('id', models.AutoField(auto_created=True,
primary_key=True, s erialize=False, verbose_name='ID')),
('ref_code', models.CharField(max_length=20)),
('start_date', models.DateTimeField(auto_now_add=True)),
('ordered_ date', models.DateTimeField()), ('ordered',
models.BooleanField(default=False)),
('being_delivered', models.BooleanField(default=False)),
('received', models.BooleanField(default=False)),
('refund_requested', models.BooleanField(default=False)),
('refund_granted', models.BooleanField(default=False)),
('billing_address', models.ForeignKey(blank=True,
null=True, on _delete=django.db.models.deletion.SET_NULL,
related_name='billing_a ddress', to='core.Address')),
('coupon', models.ForeignKey(blank=True, null=True,
on_delete =django.db.models.deletion.SET_NULL, to='core.Coupon')),
],
),
migrations.CreateModel(
name='Refund',
fields=[
('id', models.AutoField(auto_created=True,
primary_key=True, s erialize=False, verbose_name='ID')),
101
('reason', models.TextField()),
('accepted', models.BooleanField(default=False)),
('email', models.EmailField(max_length=254)),
('order', models.ForeignKey(on_delete=django.db.models.deleti
on.CASCADE, to='core.Order')),
],
),
migrations.CreateModel(
name='Payment',
fields=[
('id', models.AutoField(auto_created=True,
primary_key=True, s erialize=False, verbose_name='ID')),
('stripe_charge_id', models.CharField(max_length=50)),
('amount', models.FloatField()),
('timestamp', models.DateTimeField(auto_now_add=True)),
('user', models.ForeignKey(blank=True, null=True, on_delete=dj
ango.db.models.deletion.SET_NULL,
to=settings.AUTH_USER_MODEL)), ],
),
migrations.CreateModel(
name='OrderItem',
fields=[
('id', models.AutoField(auto_created=True,
primary_key=True, s erialize=False, verbose_name='ID')),
('ordered', models.BooleanField(default=False)),
('quantity', models.IntegerField(default=1)),
('item', models.ForeignKey(on_delete=django.db.models.deleti
on.CASCADE, to='core.Item')),
('user', models.ForeignKey(on_delete=django.db.models.deleti
on.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
migrations.AddField(
model_name='order',
name='items',
field=models.ManyToManyField(to='core.OrderItem'),
),
migrations.AddField(
model_name='order',
name='payment',
102
field=models.ForeignKey(blank=True, null=True,
on_delete=djang o.db.models.deletion.SET_NULL, to='core.Payment'),
),
migrations.AddField(
model_name='order',
name='shipping_address',
field=models.ForeignKey(blank=True, null=True,
on_delete=djang o.db.models.deletion.SET_NULL,
related_name='shipping_address', to=' core.Address'),
),
migrations.AddField(
model_name='order',
name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.C
ASCADE, to=settings.AUTH_USER_MODEL),
),
]
_userprofile.py
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('core', '0002_auto_20190616_2144'),
]
operations = [
migrations.CreateModel(
name='UserProfile',
fields=[
('id', models.AutoField(auto_created=True,
primary_key=True, s erialize=False, verbose_name='ID')),
('stripe_customer_id', models.CharField(blank=True,
max_lengt h=50, null=True)),
103
('one_click_purchasing', models.BooleanField()),
('user', models.OneToOneField(on_delete=django.db.models.d
eletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),]
TESTING
TEST CASE DESIGN
For testing to be successful, proper selection for test
cases is essential. There are two different types of approaches to
selection test cases-functional testing and structural testing.
The final output of the testing phase is the "test report" and the
"error report" The test report contains the set of test cases and the
result of executing the coding with these test cases. The error report
describes the errors encountered and the action to remove the error.
104
The basic levels of various testing techniques are :
1. Unit testing
2. Integrated testing
3. Validation testing
4. Output testing
5. System testing
6. User acceptance testing
UNIT TESTING:
INTEGRATED TESTING:
VALIDATION TESTING:
105
SYSTEM TESTING:
Here the entire software is tested. The reference document for this
process is the requirements document, and the goal is it see if the
software meets its requirements. This testing is intended to focus the
interface, functionally of the software to evaluate its compliance with
the specified requirements. The software constraints for executing
the project is: MS-DOS operating system and the hardware
constraints are Intel processor 1 GB and 64 MB RAM.
TEST PROCEDURES:
106
this is that if a test case detects an error in a large program, it
will be extremely difficult to pinpoint the source of the error.
107
used. By doing this, as parts of the system are developed, they are
tested and errors are detected as development proceeds. It should be
pointed out that we are concerned with the actual program envelopment
here, not the design method. The development can be bottom-up
approach even if the design was domain a top-down manner.
Maintenance:
In developing this project almost care is taken that all the
specifications given by the organization is included. It is
designed by using all the requirements in SRS. Extensive care
is taken while designing the user interface. This project is
highly user friendly and easy to use and maintain.
Future Scope
This project has been successfully tested, implemented and found to be
satisfactory with working. Finally I want to conclude that this is a user
friendly and scalable project, which can be used by any one. This can be
made much more user friendly by using any future technologies.
Auditing:
INFORMATION SYSTEM CONTROL & AUDITING
The system auditing Report shows how the system
is effective and efficient in achieving overall system
requirements. There are different phases of auditing an
information system. They are as follows:
1) System Development Audit Controls
2) Programming Management Audit Controls
3) Security Management Audit Controls
4) Operations Management Audit Controls
5) Quality Management Audit Controls
6) Boundary Audit Controls
109
Keeps the premises of the computer and back up store dry, cool. Avoid
smoking etc. in the premises.Use UPS to save from power fluctuations.
control the entry of personnel in to the premises of the computer and
back up store. Scan any data carrier from outside for viruses, worms
etc. maintain 2 copies of data to avoid unauthorized data modification.
SCREEN DESIGNS
Screen should be organized simply.
Captain should indicate nature of data to be entered.
Mention specified format for data entry fields.
Tab index should be in specific order.
Provide shortcut keys for skipping colors.
• Apply cool colors
• Use different but few colors for
effectiveness. Prompting and help
Prompt should be provided when there is a deviation.
Help should be provided on user request.
Communication Audit Controls.
Errors that occur On a communication line because of
attenuation, distortion or noise should be detected. Flow
control is needed to ensure swapping of nodes in a network.
Use encryption Techniques in data communication.
Database Audit Controls.
110
Data integrity is preserved. Design verification are
followed. Data normalization is effectively carried out.
IMPLEMENTATION:
The implementation is the final and important phase. It involves User
training, system testing and successful running of the developed
system. The users test the developed system when changes are
made according to the needs. The testing phase involves the testing
of the developed system using various kinds of data. An elaborate
testing of data is prepared and system is tested using the tests data.
CONCLUSION:
The "Online Deal" has been successfully completed. The goal of the
111
system is achieved and problems are solved. The package is
developed in a manner that it is user friendly and required
help is provided at different levels.
The project can be easily used in the process of decision
making. Different types of reports can be generated which
help the management to take correct decision and reduce the
time delay which automatically increases the company's work
standards as well as the economical state of the company.
This system never decreases the manpower but helps the development
of available manpower and optimizes the manpower by which company's
standards and capabilities can be scaled to higher dimensions.
https://docs.djangoproject.com/en/2.1/
https://www.tutorialspoint.com/
www.msdn.com
www.google.com
www.sglserver.com
https://getbootstrap.com/
BIBLIOGRAPHY
112
Python Crash Course, 2nd Edition: A Hands-On, Project-Based
Introduction to Programming
Book by Eric Matthes
autopep8==1.4.4
certifi==2019.3.9
chardet==3.0.4
defusedxml==0.6.0
Django==2.2.10
django-allauth==0.39.1
django-countries==5.3.3
django-crispy-forms==1.7.2
django-debug-toolbar==1.10.1
idna==2.8
oauthlib==3.0.1
pep8==1.7.1
Pillow==6.2.0
pycodestyle==2.5.0
python-decouple==3.1
python3-openid==3.1.0
pytz==2018.5
requests==2.21.0
requests-oauthlib==1.2.0
sqlparse==0.2.4
stripe==2.27.0
urllib3==1.24.2
*****************************
113