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