1+ from flask import Flask , render_template , request , redirect , abort , flash , session ,url_for
2+ from werkzeug .exceptions import HTTPException
3+ from firebase import Firebase
4+ import json
5+ from datetime import datetime
6+ from db import products_collection , invoices_collection , users_collection
7+ from helper import *
8+ import os
9+
10+ app = Flask (__name__ )
11+ app .secret_key = os .environ ['APP_SECRET' ]
12+
13+ config = {
14+ "apiKey" : os .environ .get ("FIREBASE_APIKEY" ),
15+ "authDomain" : os .environ .get ("FIREBASE_AUTHDOMAIN" ),
16+ "databaseURL" : os .environ .get ("FIREBASE_DATABASEURL" ),
17+ "projectId" : os .environ .get ("FIREBASE_PROJECT_ID" ),
18+ "storageBucket" : os .environ .get ("FIREBASE_STORAGE_BUCKET" ),
19+ "messagingSenderId" : os .environ .get ("FIREBASE_MESSAGING_SENDER_ID" ),
20+ "appId" : os .environ .get ("FIREBASE_APP_ID" ),
21+ "measurementId" : os .environ .get ("FIREBASE_MEASUREMENT_ID" )
22+ }
23+
24+ firebase = Firebase (config )
25+ db = firebase .database ()
26+ auth = firebase .auth ()
27+
28+ exempted_endpoints = ['signup' ,'login' ,'static' ]
29+
30+ @app .route ("/signup" , methods = ['GET' ,'POST' ])
31+ def signup ():
32+ if request .method == 'POST' :
33+ name = request .form .get ("name" )
34+ username = request .form .get ("email" )
35+ password = request .form .get ("password" )
36+ repassword = request .form .get ("repassword" )
37+ user_details = {"name" : name ,"email" : username }
38+ if password == repassword :
39+ if len (password )>= 6 :
40+ try :
41+ _user_ = auth .create_user_with_email_and_password (username ,password )
42+ auth .send_email_verification (_user_ ['idToken' ])
43+ user_details ['merchant_id' ] = _user_ ['localId' ]
44+ users_collection .insert_one (user_details )
45+ return render_template ("success.html" )
46+ except Exception as e :
47+ return redirect (url_for ('login' ))
48+ else :
49+ flash ('Password is less than 6 characters!' )
50+ return redirect ("/signup" )
51+ else :
52+ flash ('Both Passwords do not match!' )
53+ return redirect ("/signup" )
54+ return render_template ("signup.html" )
55+
56+ @app .route ("/login" ,methods = ['GET' ,'POST' ] )
57+ def login ():
58+ if request .method == 'POST' :
59+ data = dict (request .form )
60+ email = data .get ("email" )
61+ password = data .get ("password" )
62+ user_details = users_collection .find_one ({"email" : email },{"_id" : 0 })
63+ if user_details :
64+ user = auth .sign_in_with_email_and_password (email ,password )
65+ access_token = user ['idToken' ]
66+ acc_info = auth .get_account_info (access_token )
67+ print (acc_info )
68+ if not acc_info .get ("users" )[0 ].get ("emailVerified" ):
69+ abort (500 ,{"message" : f"{ email } is not verified!" })
70+ user_details = users_collection .find_one ({"email" : email , "merchant_id" : user ['localId' ]},{"_id" : 0 })
71+ if user_details :
72+ session ['user' ] = user ['localId' ]
73+ return redirect ("/" )
74+ else :
75+ abort (500 ,{"message" : "Username or Password is Invalid!!" })
76+
77+ else :
78+ flash ("User doesn't exist!" )
79+ return redirect ("/login" )
80+ if 'user' in session :
81+ return redirect ("/" )
82+ return render_template ("login.html" )
83+
84+
85+ @app .route ("/" ,methods = ['GET' ,'POST' ])
86+ def start ():
87+ products = list (products_collection .find ({"merchant_id" : session .get ('user' )},{"_id" :0 ,"created_on" : 0 }))
88+ return render_template ("index.html" ,_products_ = json .dumps (products ))
89+
90+ @app .route ("/checkout" ,methods = ['POST' ])
91+ def checkout ():
92+ bill_data = dict (request .form )
93+ dt_string = datetime .now ()
94+ bill_data ['created_on' ] = dt_string
95+ bill_data ['merchant_id' ] = session .get ('user' )
96+ bill_data ['selected_products' ] = json .loads (bill_data ['selected_products' ])
97+ unavailable_items = []
98+ for product in bill_data ['selected_products' ]:
99+ item_id = product ['item_id' ]
100+ qty = int (product ['qty' ])
101+ product_details = products_collection .find_one ({"merchant_id" : session .get ('user' ),"item_id" : item_id })
102+ current_stock = product_details .get ("item_stock" )
103+ item_name = product_details .get ("name" )
104+ if int (current_stock )<= int (qty ):
105+ unavailable_items .append (item_name )
106+ if unavailable_items == []:
107+ for product in bill_data ['selected_products' ]:
108+ item_id = product ['item_id' ]
109+ qty = int (product ['qty' ])
110+ products_collection .update_one ({"merchant_id" :session .get ('user' ),"item_id" :item_id },{"$inc" :{"item_stock" : - qty }})
111+ # return bill_data
112+ bill_id = random_id (10 )
113+ if bill_data .get ("payment_status" ) == "paid" :
114+ bill_data ['amount_to_be_collected' ] = "0"
115+ bill_data ['bill_id' ] = bill_id
116+ invoices_collection .insert_one (bill_data )
117+ return redirect (f"/bill/{ bill_id } " )
118+ else :
119+ for item in unavailable_items :
120+ flash (f"{ item } is out of stock!" )
121+ return redirect ("/" )
122+
123+ @app .route ("/bill/<string:bill_key>" , methods = ['GET' ,'POST' ])
124+ def bill (bill_key ):
125+ if request .method == 'POST' :
126+ incoming_updates = dict (request .form )
127+ if incoming_updates ['payment_status' ] == 'paid' :
128+ incoming_updates ['amount_to_be_collected' ] = "0"
129+ incoming_updates ['paid_amount' ] = incoming_updates ['checkout_amount' ].replace ("," ,'' )
130+ elif incoming_updates ['payment_status' ] == 'unpaid' :
131+ incoming_updates ['amount_to_be_collected' ] = incoming_updates ['checkout_amount' ].replace ("," ,'' )
132+ incoming_updates ['paid_amount' ] = "0"
133+ invoices_collection .update_one ({"merchant_id" :session .get ('user' ),"bill_id" : bill_key },{"$set" :incoming_updates })
134+ return redirect (f"/bill/{ bill_key } " )
135+ try :
136+ bill_details = invoices_collection .find_one ({"merchant_id" : session .get ('user' ),"bill_id" : bill_key },{"_id" :0 ,"created_on" : 0 })
137+ except :
138+ bill_details = None
139+ if bill_details is not None :
140+ return render_template ("bill.html" ,bill_key = bill_key , bill_details = json .dumps (bill_details ),bill_details_json = bill_details )
141+ else :
142+ abort (404 ,
143+ {
144+ "message" : f"Bill with Bill ID '{ bill_key } ' doesn't exist"
145+ })
146+
147+ @app .route ("/products" , methods = ['GET' ,'POST' ])
148+ def products ():
149+ if request .method == 'POST' :
150+ item_data = dict (request .form )
151+ item_data ['item_stock' ] = int (item_data ['item_stock' ])
152+ dt_string = datetime .now ()
153+ item_data ['created_on' ] = dt_string
154+ item_data ['merchant_id' ] = session .get ('user' )
155+ item_data ['item_id' ] = random_id (10 )
156+ products_collection .insert_one (item_data )
157+ return redirect ("/products/0" )
158+ return redirect ('/products/0' )
159+
160+ @app .route ("/products/<int:page_index>" , methods = ['GET' ,'POST' ])
161+ def products_idx (page_index ):
162+ if request .method == "POST" :
163+ query = request .form .get ("search" )
164+ page_size = 10
165+ pipeline = [{"$match" :{"merchant_id" : session .get ('user' )}},{"$project" :{"_id" :0 }}]
166+ res = []
167+ products = list (products_collection .aggregate (pipeline ))
168+ for product in products :
169+ if query in product .get ("name" ).lower ():
170+ res .append (product )
171+ return render_template ("products.html" ,products = res ,total_pages = 0 ,page_size = page_size , page_index = 0 ,merchant_id = session .get ('user' ), handle_catch = handle_catch )
172+ page_size = 10
173+ pipeline = [{"$match" :{"merchant_id" : session .get ('user' )}},{"$project" :{"_id" :0 }},{'$skip' : int (page_index )* page_size }, {'$limit' : page_size }]
174+ products = products_collection .aggregate (pipeline )
175+ temp = len (list (products_collection .find ({"merchant_id" :session .get ("user" )},{"_id" :0 })))
176+ if temp % page_size == 0 :
177+ total_pages = temp // page_size
178+ else :
179+ total_pages = temp // page_size + 1
180+
181+ return render_template ("products.html" ,products = products ,total_pages = total_pages ,page_size = page_size , page_index = page_index ,merchant_id = session .get ('user' ), handle_catch = handle_catch )
182+
183+ @app .route ("/products/<string:merchant_id>/<string:item_id>/<string:page_index>" , methods = ['POST' ])
184+ def products_update (merchant_id , item_id ,page_index ):
185+ item_data = dict (request .form )
186+ item_data ['item_stock' ] = int (item_data ['item_stock' ] )
187+ products_collection .update_one ({"item_id" : item_id ,"merchant_id" : merchant_id },{"$set" :item_data })
188+ return redirect (f"/products/{ page_index } " )
189+
190+ @app .route ("/products_delete/<string:merchant_id>/<string:item_id>/<string:page_index>" , methods = ['POST' ])
191+ def products_delete (merchant_id , item_id ,page_index ):
192+ products_collection .delete_one ({"item_id" : item_id ,"merchant_id" : merchant_id })
193+ return redirect (f"/products/{ page_index } " )
194+
195+ @app .route ("/bills" , methods = ['GET' ,'POST' ])
196+ def bills_temp ():
197+ return redirect ("/bills/0" )
198+
199+ @app .route ("/bills/<int:page_index>" , methods = ['GET' ,'POST' ])
200+ def bills (page_index ):
201+ if request .method == "POST" :
202+ payment_status_filter = str (request .form .get ("payment_status" ))
203+ page_size = 10
204+ if payment_status_filter != "" :
205+ pipeline = [{"$match" :{"merchant_id" : session .get ('user' ),"payment_status" :payment_status_filter }},{"$project" :{"_id" :0 }}]
206+ else :
207+ return redirect ("/bills/0" )
208+ all_bills = list (invoices_collection .aggregate (pipeline ))
209+ return render_template ("bills.html" ,all_bills = all_bills ,total_pages = 0 ,page_size = page_size , page_index = 0 ,merchant_id = session .get ('user' ), handle_catch = handle_catch )
210+ page_size = 10
211+ pipeline = [{"$match" :{"merchant_id" : session .get ('user' )}},{"$project" :{"_id" :0 }},{'$skip' : int (page_index )* page_size }, {'$limit' : page_size }]
212+ all_bills = invoices_collection .aggregate (pipeline )
213+ temp = len (list (invoices_collection .find ({"merchant_id" :session .get ("user" )},{"_id" :0 })))
214+ if temp % page_size == 0 :
215+ total_pages = temp // page_size
216+ else :
217+ total_pages = temp // page_size + 1
218+
219+ # all_bills = invoices_collection.find({"merchant_id":session.get('user')},{"_id":0})
220+ return render_template ("bills.html" , all_bills = all_bills ,total_pages = total_pages ,page_index = page_index , page_size = page_size ,handle_catch = handle_catch )
221+
222+ @app .route ("/logout" , methods = ['GET' ,'POST' ])
223+ def logout ():
224+ session .pop ('user' )
225+ return redirect ("/login" )
226+
227+ @app .before_request
228+ def before_request_func ():
229+ if request .endpoint in exempted_endpoints :
230+ return
231+ if 'user' not in session :
232+ return redirect (url_for ('login' ))
233+
234+
235+ if __name__ == '__main__' :
236+ app .run (debug = True , port = 5000 )
0 commit comments