Flask Example – Invoice Online App

Invoice Online App is a common need of small to large businesses. It allows the users or customers to login into their account and see the status of the invoices generated against their purchases. The Invoice Online App is for the Flask beginners who wish to use database to store the data and present it in the web application dynamically as per user action.

Invoice Online App-Basic Activities

In this sample project, we have user PostgreSQL to create and store the database tables. The following activities are implemented in the Invoice Online App-

  • User can login to open his dashboard to check the invoices generated against him
  • Dashboard presents all the invoice numbers as clickable links on left panel.
  • A User can click on any link presented Invoice/ Bill ID. The details of the selected Invoice are displayed in the right panel of the dashboard.
  • The user logs out from dashboard and he is taken back to the main page.

In this application we are using Session to maintain the username which is displayed in the dashboard.

Database- Invoice Online App

The app stores data in these four tables-

Users table
Items Table
Invoice Online App table
Invoice details table

PK indicated columns are Primary keys. FK indicated columns are Foreign Key

Login Page

The Login page asks user to enter login credentials. On correct user name and password user is taken to his invoice dashboard and all the invoices against him are displayed in the left panel.

login page

The Users model is used to match the user name and password with that stored in the users table. If match is not found, the dashboard displays error message of “Wrong credentials!”

login page with error

Dashboard

The dashboard displays the username of the user which can be clicked to logout of the invoice dashboard. When a user clicks any invoice number from the left panel, its invoice Number, Date of invoice, items purchased, item name, price, quantity purchased, item wise amount and total invoice amount are displayed.

dashboard

layout.html

<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
    <title>{% block title %}{% endblock %}</title>
</head>
<body>
	<div class="container">
	<div class="row" style="border-style:solid;padding:20px; text-align: right;">
		<b>{% block pagetitle %}{% endblock %}</b>
	</div>
	<div class="row">
	<div class="col-sm-1" style="border-right:groove;">
	{% block invoiceList %}{% endblock %}
	</div>
	<div class="col-sm" style="margin-top:5%">
	{% block content %}{% endblock %}
	</div>
	</div>
	
	<div class="row">
	<div id="footer" style="border-top:groove;">
        Copyright 2020 by CSVeda.com
    </div>
	</div>
	</div>
</body>
</html>

layout_reg.html

<!DOCTYPE html>
<html>
    <head>
        <title>{% block title %}{% endblock %}</title>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.3/css/bootstrap.min.css" integrity="sha384-Zug+QiDoJOrZ5t4lssLdxGhVrurbmBWopoEl+M6BdEfwnCJZtKxi1KgxUyJq13dy" crossorigin="anonymous">
    </head>
    <body>
	<div class="container">
		<div class="row"><div class="col-sm-12">
		<center><h3>Invoice System</h3></center>
		</div></div>
		<div class="row">
		<div class="col-sm-1" style="border-right:groove; ">
		{% block body %}
        {% endblock %}
		</div>
		<div class="col-sm" style="margin-top:5%">
		{% block content %}
		{% endblock %}
		</div>
		
		</div>
		
	</div>
	<div class="row" style="color:red; margin-left:50%">
		{% block errmsg %}
		{% endblock %}
	</div>
    </body>
</html>

application.py

from flask import Flask, render_template, jsonify, request, redirect, session
from models import *
from werkzeug.utils import secure_filename
folder_name="static"

app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "postgresql://postgres:username@localhost:5432/dbname"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"

db.init_app(app)
app.secret_key = 'anykeystring'


@app.route("/")
def index():
    return render_template("index.html")
    
@app.route("/dashboard",methods=["POST"])
def dashboard():
    unam = request.form.get("username")
    pwd = request.form.get("password")
    session['username']= unam
    ulist=Users.query.filter_by(username=unam).first()
    if ulist:
        uid=ulist.userid
        invList=Invoice.query.filter_by(userid=uid).all()
        return render_template("dashboard.html",uname=unam,invList=invList, invDet=[], invSel=[])
    else:  
        return render_template("index.html", msg='Wrong Credentials!!')
        
    
@app.route("/showInvoice/<int:invID>")
def showInvoice(invID):
    unam=session['username']
    ulist=Users.query.filter_by(username=unam).first()
    invList=Invoice.query.filter_by(userid=ulist.userid).all()
    invDet=InvoiceDet.query.filter_by(invoiceID=invID).all()
    invSel=Invoice.query.filter_by(invoiceID=invID).first()
    return render_template("dashboard.html",uname=unam,invList=invList, invDet=invDet, invSel=invSel)     

@app.route("/logout")
def logout():
    return render_template("index.html")

models.py

import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()
   
class Invoice(db.Model):
    __tablename__="invoice_tbl"
    invoiceID = db.Column(db.Integer, primary_key=True)
    invoiceDate =db.Column(db.DateTime, nullable=False)
    totAmt =db.Column(db.Float, nullable=False)
    discount =db.Column(db.Float, nullable=False)
    taxAmt = db.Column(db.Float, nullable=True)
    netAmt =db.Column(db.Float, nullable=False)  
    userid = db.Column(db.Integer, nullable=True) 
    
      
class InvoiceDet(db.Model):
    __tablename__="invoiceDet_tbl"
    invoiceID = db.Column(db.Integer, primary_key=True)
    ItemID =db.Column(db.Integer, db.ForeignKey("Items_tbl.itemID"), primary_key=True)
    itemQty =db.Column(db.Integer, nullable=False)
    item_discount =db.Column(db.Integer, nullable=False)
    itemAmt = db.Column(db.Float, nullable=True)
    item = db.relationship("Items", backref="item", lazy=True)
         
         
class Users(db.Model):
    __tablename__="usertbl"
    userid = db.Column(db.Integer, primary_key=True)
    username =db.Column(db.String, nullable=False)
    password =db.Column(db.String, nullable=False)
           
class Items(db.Model):
    __tablename__="Items_tbl"
    itemID = db.Column(db.Integer, primary_key=True)
    itemDesc =db.Column(db.String, nullable=False)
    itemPrice =db.Column(db.Float, nullable=False)           

index.html

{% extends "layout_reg.html" %}

{% block title %}
    Invoice System!
{% endblock %}

{% block content %}
 	<form action="{{ url_for('dashboard')}}" method="post"> 
	<div class="form-group row">
    <div class="form-group mx-sm-3 mb-2">
    <label for="username" class="sr-only">User Name</label>
    <input type="text" class="form-control" name="username" placeholder="User Name">
  </div>
	<div class="form-group mx-sm-3 mb-2">
    <label for="inputPassword2" class="sr-only">Password</label>
    <input type="password" class="form-control" name="password" placeholder="Password">
  </div>
  <button type="submit" class="btn btn-primary mb-2">Confirm identity</button>
  
</form>
{% endblock %}
{% block errmsg %}
{{msg}}
{% endblock %}

dashboard.html

{% extends "layout.html" %}

{% block title %}
    User Dashboard!
{% endblock %}

{% block pagetitle %}
    <b><a href={{url_for('logout')}}>logout {{uname}}!</a></b>
{% endblock %}

{% block invoiceList %}
<B> Your Bills</B><br><br>
{% for l in invList%}
	<a href="{{url_for('showInvoice', invID=l.invoiceID)}}">{{l.invoiceID}}</a></br>
{%endfor%}
{% endblock %}

{% block content %}
<b>
Invoice ID : {{invSel.invoiceID}} <br>
Invoice Date : {{invSel.invoiceDate}} </b>	
<table class="table">
	
	<TH>
	<TD><b>Item ID</b></TD>
	<TD><b>Item Desc</b></TD>
	<TD><b>Item Price</b></TD>
	<TD><b>Item Quantity</b></TD>
	<TD><b>Discount on Item</b></TD>
	<TD><b>Item Amount</b></TD>
	<TD></TD>
	</TH>
	{% for inv in invDet %}
	<TR>
	<TD></TD>
	<TD>{{inv.ItemID}}</TD>
	<TD>{{inv.item.itemDesc}}</TD>
	<TD>{{inv.item.itemPrice}}</TD>
	<TD>{{inv.itemQty}}</TD>
	<TD>{{inv.item_discount}}</TD>
	<TD>{{inv.itemAmt}}</TD>
	</TR>
	{% endfor %}
	<TR>
	<TD></TD>
	<TD></TD>
	<TD></TD>
	<TD></TD>
	<TD></TD>
	<TD><b>Total Amount Payable :</TD>
	<TD> {{invSel.netAmt}} </b></TD>
	</TR>
</table>
{% endblock %}

In this sample flask project on Invoice Online App, we have used session to maintain user name in ‘username’ session variable to display it across the app’s pages. This is a very basic example which can be enhanced by improving its look and feel. We have truly not focused on its visual aspect, though we used bootstrap!! You can start from here to know how to create a Flask App

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *