· 4 years ago · Apr 13, 2021, 07:14 AM
1from fastapi import Depends, FastAPI, HTTPException, Body, Form, UploadFile
2from fastapi.middleware.cors import CORSMiddleware
3from models import db, rr_db, pillarr_db, UserActivityModel, SaveConfigModel, AddTriggerModel, TriggerOutputModel, \
4 FAQModel, CBUserModel
5from datetime import datetime, timedelta
6from collections import Counter
7import pymongo
8from bson.objectid import ObjectId
9from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
10import hashlib
11import jwt
12from dateutil.tz import gettz
13import mysql.connector
14from mysql.connector import errorcode
15import requests
16import smtplib
17import ssl
18from email.mime.text import MIMEText
19from email.mime.multipart import MIMEMultipart
20import json
21from fastapi.responses import Response
22import gspread
23from oauth2client.service_account import ServiceAccountCredentials
24
25app = FastAPI()
26oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
27
28origins = [
29 "http://192.168.2.64:8000", "*",
30 "http://0.0.0.0"
31]
32
33quickoKey_01 = "key_live_U2TkwpOSyXsxGxgAsLLx2972paSHWhPw"
34quickoKey_02 = "secret_live_EWOqYnYW4xnvsciZvkqNNj3ygHh9rfQW"
35quicko_api_version = "3.3"
36
37app.add_middleware(
38 CORSMiddleware,
39 allow_origins=origins,
40 allow_credentials=True,
41 allow_methods=["*"],
42 allow_headers=["*"],
43)
44
45investmentAmount = 1000
46
47statusNameToID = {}
48statusIdToName = {}
49stockIdToSymbol = {}
50stockSymbolToID = {}
51stockIdToSector = {}
52sectorIdToName = {}
53branchIdToName = {}
54stockIdToFincode = {}
55fincodeToStockID = {}
56sectorIdToBFSI = {}
57stockIdToInNifty = {}
58
59stagingModeActive = True
60
61completeDataBank = list(db.data_bank.find())
62
63allStatus = ["Strong Buy", "Buy", "Caution Buy", "Hold", "Exit", "NA"]
64
65# uvicorn main:app --reload --host 0.0.0.0
66
67# On Startup
68###########################################
69
70branchRes = list(db.branch.find())
71secRes = list(db.sectors_list.find().sort("sector_name", pymongo.ASCENDING))
72for resItem in secRes:
73 sectorIdToName[resItem["_id"]] = resItem["sector_name"]
74 sectorIdToBFSI[resItem["_id"]] = resItem["is_bfsi"]
75
76for statusItem in allStatus:
77 res = db.stock_status.find_one({"stock_status": statusItem})
78 statusNameToID[statusItem] = res["_id"]
79 statusIdToName[res["_id"]] = statusItem
80
81stockDataList = list(db.stock_list.find())
82for xItem in stockDataList:
83 stockIdToSymbol[xItem["_id"]] = xItem["stock_symbol"]
84 stockSymbolToID[xItem["stock_symbol"]] = xItem["_id"]
85 stockIdToSector[xItem["_id"]] = xItem["stock_sector"]
86 fincodeToStockID[xItem["stock_fincode"]] = xItem["_id"]
87 stockIdToFincode[xItem["_id"]] = xItem["stock_fincode"]
88 stockIdToInNifty[xItem["_id"]] = xItem["in_nifty"]
89
90for bItem in branchRes:
91 branchIdToName[bItem["_id"]] = bItem["branch"]
92
93
94# ##############################################################################
95
96
97def connectToStagingDB():
98 try:
99 mydb = mysql.connector.connect(
100 database="stagingr_dev",
101 host="staging.researchandranking.com",
102 user="stagingr",
103 password='KkG@VP3R34S8zXB'
104 )
105 except mysql.connector.Error as err:
106 if err.errno == errorcode.ER_ACCESS_DENIED_ERROR:
107 print("Something is wrong with your user name or password")
108 elif err.errno == errorcode.ER_BAD_DB_ERROR:
109 print("Database does not exist")
110 else:
111 print(err)
112 else:
113 return mydb
114
115
116def getLastEntryDate(input_date):
117 myDateVal = datetime.strptime(input_date, '%Y-%m-%d')
118 switcher = {
119 "Saturday": myDateVal,
120 "Sunday": (myDateVal - timedelta(1)),
121 "Monday": (myDateVal - timedelta(2)),
122 "Tuesday": (myDateVal - timedelta(3)),
123 "Wednesday": (myDateVal - timedelta(4)),
124 "Thursday": (myDateVal - timedelta(5)),
125 "Friday": (myDateVal - timedelta(6))
126 }
127 resultDate = switcher.get(myDateVal.strftime('%A')) # "21-12-2012"
128 return resultDate
129
130
131def getFirstLiveDate(input_date):
132 myConn = connectToStagingDB()
133 myCursor = myConn.cursor()
134 myCommand = 'SELECT MIN(date) FROM rnr_v2_selected_company_closing WHERE date >= "' + input_date + '"'
135 myCursor.execute(myCommand)
136 queryResult = myCursor.fetchall()
137
138 myDateVal = str(queryResult[0][0])
139 myDateVal = datetime.strptime(myDateVal, "%Y-%m-%d")
140 myConn.close()
141
142 return myDateVal
143
144
145def getLastLiveDate(input_date):
146 myConn = connectToStagingDB()
147 myCursor = myConn.cursor()
148 myCommand = 'SELECT MAX(date) FROM rnr_v2_selected_company_closing WHERE date <= "' + input_date + '"'
149 myCursor.execute(myCommand)
150 queryResult = myCursor.fetchall()
151
152 myDateVal = str(queryResult[0][0])
153 myDateVal = datetime.strptime(myDateVal, "%Y-%m-%d")
154 myConn.close()
155
156 return myDateVal
157
158
159def getTodayDate():
160 return datetime.now(tz=gettz('Asia/Kolkata'))
161
162
163def hashMyPass(myPass):
164 hPass = hashlib.sha256(myPass.encode())
165 return hPass.hexdigest()
166
167
168def generateToken(username):
169 encoded_jwt = jwt.encode({"username": username, "timestamp": str(getTodayDate())}, "Mpo@5in5$", algorithm="HS256")
170 return str(encoded_jwt)
171
172
173# ===========================================
174@app.post("/login")
175def login(form_data: OAuth2PasswordRequestForm = Depends(),
176 device_token: str = Form(...)):
177 userNameInLower = str(form_data.username).lower()
178 if '@' in userNameInLower:
179 loginType = 'Email'
180 existCount = db.users.count_documents({'email': userNameInLower})
181 else:
182 loginType = 'Username'
183 existCount = db.users.count_documents({'username': userNameInLower})
184
185 if existCount == 0:
186 return {"status": False, "message": loginType + " does not exist."}
187 else:
188 userData = db.users.find_one({loginType.lower(): userNameInLower})
189 hashedPass = hashMyPass(form_data.password)
190 if hashedPass.lower() == str(userData['password_hash']).lower():
191
192 if device_token != "NA":
193 db.users.find_one_and_update({'_id': userData["_id"]}, {'$addToSet': {'device_token': device_token}},
194 upsert=True)
195
196 resultData = {}
197 resultData["username"] = userData['username']
198 resultData["full_name"] = userData['full_name']
199 resultData["email"] = userData['email']
200 resultData["mobile"] = userData['mobile']
201 resultData["branch"] = branchIdToName[userData['branch']]
202 resultData["admin"] = userData['admin']
203
204 try:
205 resultData["token"] = userData['token']
206 except:
207 token = generateToken(form_data.username)
208 newValues = {"$set": {"token": token}}
209 db.users.update_one({"_id": userData["_id"]}, newValues)
210 resultData["token"] = token
211
212 return {"status": True, "result": resultData}
213
214 else:
215 return {"status": False, "message": "Incorrect password. Please try again."}
216
217
218@app.get('/dashboardCards')
219def dashboardCards(token: str = Depends(oauth2_scheme)):
220 authCount = db.users.count_documents({"token": token})
221 if authCount == 0:
222 raise HTTPException(status_code=401, detail="Unauthorized Request.")
223
224 dateObj = getTodayDate()
225 end_date = dateObj.strftime("%Y-%m-%d")
226
227 lastEntryDate = getLastEntryDate(end_date)
228 lastLiveDate = getLastLiveDate(end_date)
229
230 itsWeekendBois = lastLiveDate < lastEntryDate
231
232 arrivalCounter = Counter()
233 removalCounter = Counter()
234
235 compInStatusCounter = Counter()
236 statusReturnsCounter = Counter()
237
238 transitionRecords = list(db.status_transitions.find({"datetime_entry": lastEntryDate}))
239
240 for item in transitionRecords:
241 arrivalCounter[statusIdToName[item["to_status"]]] += 1
242 removalCounter[statusIdToName[item["from_status"]]] += 1
243
244 compToLiveClosing = {}
245
246 if not itsWeekendBois:
247 myConn = connectToStagingDB()
248 myCursor = myConn.cursor()
249 myCommand = 'SELECT fincode, close FROM rnr_v2_selected_company_closing ' \
250 'WHERE date = "' + lastLiveDate.strftime("%Y-%m-%d") + '"'
251 myCursor.execute(myCommand)
252 queryResult = myCursor.fetchall()
253 for item in queryResult:
254 compToLiveClosing[fincodeToStockID[item[0]]] = item[1]
255 myConn.close()
256
257 dataBankOnEndDate = list(db.data_bank.find({"datetime_entry": lastEntryDate}))
258 for item in dataBankOnEndDate:
259 compInStatusCounter[statusIdToName[item["stock_status"]]] += 1
260 if not itsWeekendBois:
261 sharesBought = investmentAmount / item["close"]
262 myReturns = sharesBought * compToLiveClosing[item["stock"]]
263 statusReturnsCounter[statusIdToName[item["stock_status"]]] += myReturns
264
265 resultDict = {}
266
267 for myStatus in compInStatusCounter:
268 myData = {}
269 if itsWeekendBois:
270 performance = 0
271 else:
272 totalInvest = compInStatusCounter[myStatus] * investmentAmount
273 performance = round((statusReturnsCounter[myStatus] - totalInvest) * 100 / totalInvest, 2)
274
275 myData["count"] = compInStatusCounter[myStatus]
276 myData["performance"] = performance
277 myData["newAdd"] = arrivalCounter[myStatus]
278 myData["newRem"] = removalCounter[myStatus]
279
280 resultDict[myStatus] = myData
281
282 toDate = lastLiveDate
283 if toDate < lastEntryDate:
284 toDate = lastEntryDate
285
286 return {'result': {
287 "from_date": lastEntryDate.strftime("%Y-%m-%d"),
288 "to_date": toDate.strftime("%Y-%m-%d"),
289 "strong_buy": resultDict["Strong Buy"],
290 "buy": resultDict["Buy"],
291 "caution_buy": resultDict["Caution Buy"],
292 "hold": resultDict["Hold"],
293 "exit": resultDict["Exit"],
294 "na": resultDict["NA"]
295 }}
296
297
298@app.post('/snapshotByStatusInRange')
299def snapshotByStatusInRange(token: str = Depends(oauth2_scheme),
300 stock_status: str = Body(..., embed=True)):
301 authCount = db.users.count_documents({"token": token})
302 if authCount == 0:
303 raise HTTPException(status_code=401, detail="Unauthorized Request.")
304
305 myResponse = db.snapshot_by_status.find_one({"stock_status": statusNameToID[stock_status]})["response"]
306
307 return {"from_date": "2020-01-04",
308 "to_date": getLastEntryDate(getTodayDate().strftime("%Y-%m-%d")).strftime("%Y-%m-%d"),
309 'result': myResponse}
310
311
312@app.post('/arrivalsAndRemovals')
313def arrivalsAndRemovals(token: str = Depends(oauth2_scheme),
314 stock_status: str = Body(..., embed=True)):
315 authCount = db.users.count_documents({"token": token})
316 if authCount == 0:
317 raise HTTPException(status_code=401, detail="Unauthorized Request.")
318
319 myResponse = db.stock_arrivals_removals.find_one(
320 {"stock_status": statusNameToID[stock_status]})
321 result = myResponse["response"]
322
323 return result
324
325
326@app.post('/momentumFundaInStatus')
327def momentumFundaInStatus(token: str = Depends(oauth2_scheme),
328 stock_status: str = Body(..., embed=True),
329 is_filtered: bool = Body(..., embed=True)):
330 authCount = db.users.count_documents({"token": token})
331 if authCount == 0:
332 raise HTTPException(status_code=401, detail="Unauthorized Request.")
333
334 myResponse = db.stock_momentum_funda_table.find_one(
335 {"stock_status": statusNameToID[stock_status], "is_filtered": is_filtered})
336 result = myResponse["response"]
337
338 return {
339 "to_date": getLastLiveDate(getTodayDate().strftime("%Y-%m-%d")).strftime("%Y-%m-%d"),
340 "result": result}
341
342
343@app.post('/stockOverview')
344def stockOverview(token: str = Depends(oauth2_scheme),
345 stock_symbol: str = Body(..., embed=True)):
346 authCount = db.users.count_documents({"token": token})
347 if authCount == 0:
348 raise HTTPException(status_code=401, detail="Unauthorized Request.")
349
350 dateObj = getTodayDate()
351 live_date = dateObj.strftime("%Y-%m-%d")
352
353 myConn = connectToStagingDB()
354 myCursor = myConn.cursor()
355
356 lastEntryDate = getLastEntryDate(live_date)
357 stock_symbol = stock_symbol
358 stockData = db.stock_list.find_one({"stock_symbol": stock_symbol})
359
360 myCommand = 'SELECT fincode, open, close, low, high, volume, date FROM rnr_v2_selected_company_closing ' \
361 'WHERE ' \
362 'fincode = ' + str(stockIdToFincode[stockData["_id"]]) + ' AND ' \
363 'date >= "' + stockData[
364 "listing_date"].strftime("%Y-%m-%d") + '" ORDER BY date ASC'
365
366 myCursor.execute(myCommand)
367 queryResult = myCursor.fetchall()
368
369 latestData = db.data_bank.find_one({"stock": stockData["_id"],
370 "datetime_entry": lastEntryDate})
371
372 dateValRSI = "NA"
373 if latestData["rsi_div"] == "Bearish":
374 try:
375 dateValRSI = datetime.strptime(latestData["bearish_div_date"], "%d-%m-%Y").strftime("%d %b %Y")
376 except:
377 pass
378 elif latestData["rsi_div"] == "Bullish":
379 try:
380 dateValRSI = datetime.strptime(latestData["bullish_div_date"], "%d-%m-%Y").strftime("%d %b %Y")
381 except:
382 pass
383
384 try:
385 dateValWMA = datetime.strptime(latestData["cmp_wma_close_date"], "%d-%m-%Y").strftime("%d %b %Y")
386 except:
387 dateValWMA = "NA"
388
389 try:
390 dateValDMA = datetime.strptime(latestData["cmp_dma_close_date"], "%d-%m-%Y").strftime("%d %b %Y")
391 except:
392 dateValDMA = "NA"
393
394 try:
395 dateValCO = datetime.strptime(latestData["co_50_10_date"], "%d-%m-%Y").strftime("%d %b %Y")
396 except:
397 dateValCO = "NA"
398
399 stockInfo = {
400 "stock_name": stockData["stock_name"],
401 "stock_symbol": stock_symbol,
402 "stock_sector": sectorIdToName[stockData["stock_sector"]],
403 "is_bfsi": sectorIdToBFSI[stockData["stock_sector"]],
404 "status": statusIdToName[latestData["stock_status"]],
405 "wma_100": str(latestData["cmp_vs_wma"]).title(),
406 "dma_200": str(latestData["cmp_vs_dma"]).title(),
407 "momentum": latestData["momentum_status"],
408 "co_50_10": latestData["co_50_10_status"],
409 "rsi_div": latestData["rsi_div"],
410 "date_wma": dateValWMA,
411 "date_dma": dateValDMA,
412 "date_crossover": dateValCO,
413 "date_rsi": dateValRSI
414 }
415
416 transitionHistory = []
417 transitionResponse = list(db.status_transitions.find({"stock": stockData["_id"]}).sort(
418 "datetime_entry", pymongo.DESCENDING))
419
420 for item in transitionResponse:
421 data = {}
422 data["from_status"] = statusIdToName[item["from_status"]]
423 data["to_status"] = statusIdToName[item["to_status"]]
424 data["date"] = item["datetime_entry"].strftime('%Y-%m-%d')
425
426 transitionHistory.append(data)
427
428 candlestickData = []
429 for item in queryResult:
430 data = []
431 data.append(item[6])
432 data.append(item[1])
433 data.append(item[2])
434 data.append(item[3])
435 data.append(item[4])
436 data.append(item[5])
437
438 candlestickData.append(data)
439
440 myConn.close()
441
442 return {"stockInfo": stockInfo, "transitionHistory": transitionHistory, "candlestickData": candlestickData}
443
444
445@app.post('/triggerOutput')
446def triggerOutput(token: str = Depends(oauth2_scheme),
447 start_date: str = Body(..., embed=True),
448 end_date: str = Body(..., embed=True)):
449 authCount = db.users.count_documents({"token": token})
450 if authCount == 0:
451 raise HTTPException(status_code=401, detail="Unauthorized Request.")
452
453 tagIdToName = {}
454 temp = db.trigger_tags.find()
455 for item in temp:
456 tagIdToName[item["_id"]] = item["name"]
457
458 if start_date == "" or end_date == "":
459 res = list(db.trigger_output.find())
460 else:
461 startVal = datetime.strptime(start_date, "%Y-%m-%d")
462 endVal = datetime.strptime(end_date, "%Y-%m-%d")
463 res = list(db.trigger_output.find({"generated_on": {"$lte": endVal, "$gte": startVal}}).sort(
464 "generated_on", pymongo.DESCENDING))
465
466 resultList = []
467 for item in res:
468 data = {}
469
470 data["id"] = str(item["_id"])
471 data["statement"] = item["statement"]
472 data["tag"] = item["tag"]
473 data["generated_on"] = item["generated_on"].strftime("%Y-%m-%d")
474 data["headers"] = item["headers"]
475 data["data"] = item["data"]
476 resultList.append(TriggerOutputModel(**data))
477
478 return {"result": resultList}
479
480
481@app.get('/getConfigs')
482def getConfigs(token: str = Depends(oauth2_scheme)):
483 authCount = db.users.count_documents({"token": token})
484 if authCount == 0:
485 raise HTTPException(status_code=401, detail="Unauthorized Request.")
486
487 myRes = list(db.config.find().sort("index", pymongo.ASCENDING))
488 bfsi_indicators = []
489 non_bfsi_indicators = []
490 sectoral_momentum = {}
491
492 for item in myRes:
493 if item["type"] == "fundamental_indicators":
494 data = {}
495 data["_id"] = str(item["_id"])
496 data["indicator_name"] = item["indicator_name"]
497 data["indicator_comparator"] = item["indicator_comparator"]
498 data["indicator_value"] = item["indicator_value"]
499 data["indicator_value_postfix"] = item["indicator_value_postfix"]
500
501 if item["for_bfsi"]:
502 bfsi_indicators.append(data)
503 else:
504 non_bfsi_indicators.append(data)
505
506 elif item["type"] == "sectoral_momentum":
507 sectoral_momentum["momentum_upward_alloc"] = item["momentum_upward_alloc"]
508 sectoral_momentum["momentum_downward_alloc"] = item["momentum_downward_alloc"]
509 sectoral_momentum["upward_sector_1"] = statusIdToName[item["upward_sector_1"]]
510 sectoral_momentum["upward_sector_2"] = statusIdToName[item["upward_sector_2"]]
511 sectoral_momentum["downward_sector_1"] = statusIdToName[item["downward_sector_1"]]
512 sectoral_momentum["downward_sector_2"] = statusIdToName[item["downward_sector_2"]]
513
514 return {"result": {"non_bfsi_indicators": non_bfsi_indicators, "bfsi_indicators": bfsi_indicators,
515 "sectoral_momentum": sectoral_momentum}}
516
517
518@app.get('/getFundamentals')
519def getFundamentals(token: str = Depends(oauth2_scheme)):
520 authCount = db.users.count_documents({"token": token})
521 if authCount == 0:
522 raise HTTPException(status_code=401, detail="Unauthorized Request.")
523
524 myRes = list(db.config.find({"type": "fundamental_indicators"}).sort("index", pymongo.ASCENDING))
525 bfsi_indicators = []
526 non_bfsi_indicators = []
527 groupColorDict = {1: "#ffe79f", 2: "#dae1ff", 3: "#f0d0f3"}
528
529 for item in myRes:
530 data = {}
531
532 if item["indicator_comparator"] == "Above":
533 minMaxStr = " (Min)"
534 else:
535 minMaxStr = " (Max)"
536
537 data["indicator_name"] = item["indicator_name"] + minMaxStr
538 data["indicator_value"] = '{0:g}'.format(item["indicator_value"]) + item["indicator_value_postfix"]
539 data["indicator_color"] = groupColorDict[item["indicator_group"]]
540
541 if item["for_bfsi"]:
542 bfsi_indicators.append(data)
543 else:
544 non_bfsi_indicators.append(data)
545
546 return {"result": {"score": "7/10", "non_bfsi_indicators": non_bfsi_indicators, "bfsi_indicators": bfsi_indicators}}
547
548
549@app.post('/stockFundamentals')
550def stockFundamentals(token: str = Depends(oauth2_scheme),
551 stock_symbol: str = Body(..., embed=True)):
552 authCount = db.users.count_documents({"token": token})
553 if authCount == 0:
554 raise HTTPException(status_code=401, detail="Unauthorized Request.")
555
556 isBfsi = sectorIdToBFSI[stockIdToSector[stockSymbolToID[stock_symbol]]]
557
558 stockRes = db.stock_fundamental_bank.find_one({"stock": stockSymbolToID[stock_symbol]})
559 myRes = list(
560 db.config.find({"type": "fundamental_indicators", "for_bfsi": isBfsi}).sort("index", pymongo.ASCENDING))
561 fundamental_indicators = []
562
563 totalPoints = 0
564 for item in myRes:
565 data = {}
566 groupColor = "#EF5350"
567
568 if item["indicator_comparator"] == "Above":
569 if stockRes[item["fundaKey"]] >= item["indicator_value"]:
570 totalPoints += 1
571 groupColor = "#26A69A"
572 else:
573 if stockRes[item["fundaKey"]] <= item["indicator_value"]:
574 totalPoints += 1
575 groupColor = "#26A69A"
576
577 data["indicator_name"] = item["indicator_name"]
578 data["indicator_value"] = '{0:g}'.format(stockRes[item["fundaKey"]]) + item["indicator_value_postfix"]
579 data["indicator_color"] = groupColor
580
581 fundamental_indicators.append(data)
582
583 score = str(totalPoints) + "/10"
584
585 return {"result": {"score": score, "fundamental_indicators": fundamental_indicators}}
586
587
588@app.post('/stockDrawdown')
589def stockDrawdown(token: str = Depends(oauth2_scheme),
590 start_date: str = Body(..., embed=True),
591 end_date: str = Body(..., embed=True),
592 stock_symbol: str = Body(..., embed=True)):
593 authCount = db.users.count_documents({"token": token})
594 if authCount == 0:
595 raise HTTPException(status_code=401, detail="Unauthorized Request.")
596
597 myConn = connectToStagingDB()
598 myCursor = myConn.cursor()
599
600 myEndDate = getLastLiveDate(end_date)
601 if start_date == end_date:
602 myStartDate = getLastEntryDate(start_date)
603 else:
604 myStartDate = getLastLiveDate(start_date)
605
606 if myStartDate > myEndDate:
607 lastEntryData = db.data_bank.find_one({"stock": stockSymbolToID[stock_symbol], "datetime_entry": myStartDate})
608
609 drawdown = 0
610 troughRate = lastEntryData["close"]
611 troughDate = myStartDate.strftime('%Y-%m-%d')
612 peakRate = lastEntryData["close"]
613 peakDate = myStartDate.strftime('%Y-%m-%d')
614
615 else:
616
617 myCommand = 'SELECT date, close FROM rnr_v2_selected_company_closing ' \
618 'WHERE ' \
619 'fincode = ' + str(stockIdToFincode[stockSymbolToID[stock_symbol]]) + \
620 ' and date BETWEEN "' + myStartDate.strftime("%Y-%m-%d") + \
621 '" AND "' + myEndDate.strftime("%Y-%m-%d") + '"' + \
622 ' ORDER BY close DESC, date DESC LIMIT 1'
623
624 myCursor.execute(myCommand)
625 queryResult = myCursor.fetchone()
626
627 peakRate = queryResult[1]
628 peakDate = str(queryResult[0])
629
630 myCommand = 'SELECT date, close FROM rnr_v2_selected_company_closing ' \
631 'WHERE ' \
632 'fincode = ' + str(stockIdToFincode[stockSymbolToID[stock_symbol]]) + \
633 ' and date BETWEEN "' + peakDate + \
634 '" AND "' + myEndDate.strftime("%Y-%m-%d") + '"' + \
635 ' ORDER BY close ASC, date DESC LIMIT 1'
636
637 myCursor.execute(myCommand)
638 queryResult = myCursor.fetchone()
639
640 troughRate = queryResult[1]
641 troughDate = str(queryResult[0])
642
643 try:
644 drawdown = round((peakRate - troughRate) * 100 / peakRate, 2)
645 except:
646 drawdown = 0
647
648 myConn.close()
649
650 return {"result": {"drawdown": drawdown,
651 "troughRate": troughRate,
652 "troughDate": troughDate,
653 "peakRate": peakRate,
654 "peakDate": peakDate}}
655
656
657@app.get('/triggerList')
658def triggerList(token: str = Depends(oauth2_scheme)):
659 authCount = db.users.count_documents({"token": token})
660 if authCount == 0:
661 raise HTTPException(status_code=401, detail="Unauthorized Request.")
662
663 statusNameToKey = {}
664 statusNameToKey["Strong Buy"] = "strongBuy"
665 statusNameToKey["Buy"] = "buy"
666 statusNameToKey["Caution Buy"] = "cautionBuy"
667 statusNameToKey["Hold"] = "hold"
668 statusNameToKey["Exit"] = "exit"
669 statusNameToKey["NA"] = "na"
670
671 tagIdToKey = {}
672 tagIdToName = {}
673 temp = db.trigger_tags.find()
674 for item in temp:
675 tagIdToKey[item["_id"]] = item["key"]
676 tagIdToName[item["_id"]] = item["name"]
677
678 res = list(db.trigger_saved.find({"is_visible": True}).sort("created_on", pymongo.DESCENDING))
679 resultList = []
680 for item in res:
681 data = {}
682
683 data["id"] = str(item["_id"])
684 data["statement"] = item["statement"]
685 data["tag"] = tagIdToName[item["tag"]]
686 data["created_on"] = item["created_on"]
687 data["created_by"] = item["created_by"]
688 data["is_active"] = item["is_active"]
689
690 subData = {}
691 subData["trigger_list"] = tagIdToKey[item["tag"]]
692
693 if data["tag"] == "Stock Entry":
694 subData["trigger_to"] = statusNameToKey[statusIdToName[item["trigger_to"]]]
695
696 elif data["tag"] == "Transition":
697 subData["trigger_from"] = statusNameToKey[statusIdToName[item["trigger_from"]]]
698 subData["trigger_to"] = statusNameToKey[statusIdToName[item["trigger_to"]]]
699
700 elif data["tag"] == "Drawdown":
701 subData["trigger_comparator"] = item["trigger_comparator"]
702 subData["trigger_drawdown"] = item["trigger_drawdown"]
703 subData["trigger_frequency"] = item["trigger_frequency"]
704
705 elif data["tag"] == "Performance":
706 subData["trigger_comparator"] = item["trigger_comparator"]
707 subData["trigger_performance"] = item["trigger_performance"]
708 subData["trigger_frequency"] = item["trigger_frequency"]
709
710 elif data["tag"] == "Performers":
711 subData["trigger_rank"] = item["trigger_rank"]
712 subData["trigger_limit"] = item["trigger_limit"]
713 subData["trigger_frequency"] = item["trigger_frequency"]
714
715 elif data["tag"] == "Sectoral Momentum":
716 subData["trigger_momentum"] = item["trigger_momentum"]
717 subData["trigger_frequency"] = item["trigger_frequency"]
718
719 data["data"] = subData
720
721 tempData = dict()
722 tempData["EmailType"] = list()
723 tempData["WhatsappType"] = list()
724
725 for actionItem in item["email_list"]:
726 tempData["EmailType"].append({"email": actionItem})
727 for actionItem in item["mobile_list"]:
728 tempData["WhatsappType"].append({"phone": actionItem})
729
730 data["action_type"] = tempData
731
732 resultList.append(data)
733
734 return {"result": resultList}
735
736
737@app.post('/saveTrigger')
738def saveTrigger(requestBody: AddTriggerModel,
739 token: str = Depends(oauth2_scheme)):
740 authRes = list(db.users.find({"token": token}))
741 if len(authRes) == 0:
742 raise HTTPException(status_code=401, detail="Unauthorized Request.")
743
744 createdByName = authRes[0]["full_name"]
745
746 statusKeyToID = {}
747 triggerKeyToID = {}
748 statusKeyToDisplay = {"strongBuy": "Strong Buy", "buy": "Buy", "cautionBuy": "Caution Buy", "hold": "Hold",
749 "exit": "Exit", "na": "NA"}
750 frequencyKeyToDisplay = {"weekly": "last week.",
751 "monthly": "last month.",
752 "quarterly": "last quarter.",
753 "half_yearly": "last 6 months.",
754 "Yearly": "last year."}
755 comparatorKeyToDisplay = {"less_than": "less than", "greater_than": "greater than"}
756 momentumKeyToDisplay = {"upward": "an Upward Momentum", "downward": "a Downward Momentum"}
757
758 tempStatus = db.stock_status.find()
759 for item in tempStatus:
760 statusKeyToID[item["key"]] = item["_id"]
761
762 allTags = db.trigger_tags.find()
763 for item in allTags:
764 triggerKeyToID[item["key"]] = item["_id"]
765
766 triggerData = requestBody.triggerList
767
768 triggerTag = triggerData["trigger_list"]
769 subData = {}
770 todayDate = getTodayDate()
771
772 subData["tag"] = triggerKeyToID[triggerData["trigger_list"]]
773 subData["is_active"] = True
774 subData["is_visible"] = True
775 subData["created_on"] = todayDate
776 subData["created_by"] = createdByName
777
778 if triggerTag == "stockEntry":
779 subData["trigger_to"] = statusKeyToID[triggerData["trigger_to"]]
780 subData["statement"] = "Give me stocks which has entered the " + statusKeyToDisplay[
781 triggerData["trigger_to"]] + " section."
782
783 elif triggerTag == "transition":
784 subData["trigger_from"] = statusKeyToID[triggerData["trigger_from"]]
785 subData["trigger_to"] = statusKeyToID[triggerData["trigger_to"]]
786 subData["statement"] = "Give me stocks which has moved from " + statusKeyToDisplay[
787 triggerData["trigger_from"]] + " to " + statusKeyToDisplay[
788 triggerData["trigger_to"]] + " section."
789
790 elif triggerTag == "drawdown":
791 subData["trigger_comparator"] = triggerData["trigger_comparator"]
792 subData["trigger_drawdown"] = triggerData["trigger_drawdown"]
793 subData["trigger_frequency"] = triggerData["trigger_frequency"]
794 subData[
795 "statement"] = "Give me stocks which has a Drawdown " + comparatorKeyToDisplay[
796 triggerData["trigger_comparator"]] + " " + str(triggerData[
797 "trigger_drawdown"]) + "% since " + \
798 frequencyKeyToDisplay[
799 triggerData["trigger_frequency"]]
800
801 elif triggerTag == "performance":
802 subData["trigger_comparator"] = triggerData["trigger_comparator"]
803 subData["trigger_performance"] = triggerData["trigger_performance"]
804 subData["trigger_frequency"] = triggerData["trigger_frequency"]
805 subData[
806 "statement"] = "Give me stocks which has a Performance " + comparatorKeyToDisplay[
807 triggerData["trigger_comparator"]] + " " + str(triggerData[
808 "trigger_performance"]) + "% since " + \
809 frequencyKeyToDisplay[
810 triggerData["trigger_frequency"]]
811
812 elif triggerTag == "performers":
813 subData["trigger_rank"] = triggerData["trigger_rank"]
814 subData["trigger_limit"] = triggerData["trigger_limit"]
815 subData["trigger_frequency"] = triggerData["trigger_frequency"]
816 subData[
817 "statement"] = "Give me " + triggerData["trigger_rank"] + " " + str(triggerData[
818 "trigger_limit"]) + " Performers since " + \
819 frequencyKeyToDisplay[
820 triggerData["trigger_frequency"]]
821
822 elif triggerTag == "sectoralMomentum":
823 subData["trigger_momentum"] = triggerData["trigger_momentum"]
824 subData["trigger_frequency"] = triggerData["trigger_frequency"]
825 subData["statement"] = "Give me Sectors which has " + momentumKeyToDisplay[
826 triggerData["trigger_momentum"]] + " since " + frequencyKeyToDisplay[
827 triggerData["trigger_frequency"]]
828
829 email_list = []
830 mobile_list = []
831
832 for item in requestBody.action_type["EmailType"]:
833 myData = {}
834 myData["_id"] = item["_id"]
835 myData["full_name"] = item["full_name"]
836 myData["email"] = item["email"]
837 myData["selected"] = item["selected"]
838
839 email_list.append(myData)
840
841 for item in requestBody.action_type["WhatsappType"]:
842 myData = {}
843 myData["_id"] = item["_id"]
844 myData["full_name"] = item["full_name"]
845 myData["mobile"] = item["mobile"]
846 myData["selected"] = item["selected"]
847
848 mobile_list.append(myData)
849
850 subData["email_list"] = email_list
851 subData["mobile_list"] = mobile_list
852
853 if triggerData["id"] != "":
854 newValues = {"$set": {"is_active": False, "is_visible": False}}
855 db.trigger_saved.update_one({"_id": ObjectId(triggerData["id"])}, newValues)
856
857 db.trigger_saved.insert_one(subData)
858
859 return {"result": "Trigger saved successfully."}
860
861
862@app.post('/toggleTrigger')
863def toggleTrigger(token: str = Depends(oauth2_scheme),
864 trigger_status: bool = Body(..., embed=True),
865 trigger_id: str = Body(..., embed=True)):
866 authCount = db.users.count_documents({"token": token})
867 if authCount == 0:
868 raise HTTPException(status_code=401, detail="Unauthorized Request.")
869
870 newValues = {"$set": {"is_active": trigger_status}}
871 db.trigger_saved.update_one({"_id": ObjectId(trigger_id)}, newValues)
872
873 if trigger_status:
874 resultStr = "Trigger activated successfully!"
875 else:
876 resultStr = "Trigger deactivated successfully!"
877
878 return {"result": resultStr}
879
880
881@app.post('/deleteTrigger')
882def deleteTrigger(token: str = Depends(oauth2_scheme),
883 trigger_id: str = Body(..., embed=True)):
884 authCount = db.users.count_documents({"token": token})
885 if authCount == 0:
886 raise HTTPException(status_code=401, detail="Unauthorized Request.")
887
888 newValues = {"$set": {"is_active": False, "is_visible": False}}
889 db.trigger_saved.update_one({"_id": ObjectId(trigger_id)}, newValues)
890
891 return {"result": "Trigger deleted successfully!"}
892
893
894@app.post('/saveConfigs')
895def saveConfigs(requestBody: SaveConfigModel,
896 token: str = Depends(oauth2_scheme)):
897 authCount = db.users.count_documents({"token": token})
898 if authCount == 0:
899 raise HTTPException(status_code=401, detail="Unauthorized Request.")
900
901 for item in requestBody.non_bfsi_indicators:
902 myId = item["_id"]
903 myComparator = item["indicator_comparator"]
904 myValue = item["indicator_value"]
905
906 newData = {"$set": {"indicator_comparator": myComparator,
907 "indicator_value": myValue}}
908 db.config.update_one({"_id": ObjectId(myId)}, newData)
909
910 for item in requestBody.bfsi_indicators:
911 myId = item["_id"]
912 myComparator = item["indicator_comparator"]
913 myValue = item["indicator_value"]
914
915 newData = {"$set": {"indicator_comparator": myComparator,
916 "indicator_value": myValue}}
917 db.config.update_one({"_id": ObjectId(myId)}, newData)
918
919 sectoralData = {}
920 sectoralData["momentum_upward_alloc"] = requestBody.sectoral_momentum["momentum_upward_alloc"]
921 sectoralData["momentum_downward_alloc"] = requestBody.sectoral_momentum["momentum_downward_alloc"]
922 sectoralData["upward_sector_1"] = statusNameToID[requestBody.sectoral_momentum["upward_sector_1"]]
923 sectoralData["upward_sector_2"] = statusNameToID[requestBody.sectoral_momentum["upward_sector_2"]]
924 sectoralData["downward_sector_1"] = statusNameToID[requestBody.sectoral_momentum["downward_sector_1"]]
925 sectoralData["downward_sector_2"] = statusNameToID[requestBody.sectoral_momentum["downward_sector_2"]]
926 sectoralData["type"] = "sectoral_momentum"
927
928 db.config.replace_one({"type": "sectoral_momentum"}, sectoralData)
929
930 return {"result": "Configurations Updated Successfully"}
931
932
933@app.post('/getActionList')
934def getActionList(item_id: str = Body(..., embed=True),
935 token: str = Depends(oauth2_scheme)):
936 authCount = db.users.count_documents({"token": token})
937 if authCount == 0:
938 raise HTTPException(status_code=401, detail="Unauthorized Request.")
939
940 if item_id == "":
941 res = list(db.users.find())
942 resultData = {}
943 resultData["EmailType"] = list()
944 resultData["WhatsappType"] = list()
945
946 for item in res:
947 emailData = {}
948 phoneData = {}
949
950 emailData["_id"] = str(item["_id"])
951 emailData["full_name"] = item["full_name"]
952 emailData["email"] = item["email"]
953 emailData["selected"] = False
954
955 phoneData["_id"] = str(item["_id"])
956 phoneData["full_name"] = item["full_name"]
957 phoneData["mobile"] = item["mobile"]
958 phoneData["selected"] = False
959
960 resultData["EmailType"].append(emailData)
961 resultData["WhatsappType"].append(phoneData)
962 else:
963 res = db.trigger_saved.find_one({"_id": ObjectId(item_id)})
964 resultData = {}
965 resultData["EmailType"] = list()
966 resultData["WhatsappType"] = list()
967
968 for item in res["email_list"]:
969 emailData = {}
970 emailData["_id"] = str(item["_id"])
971 emailData["full_name"] = item["full_name"]
972 emailData["email"] = item["email"]
973 emailData["selected"] = item["selected"]
974 resultData["EmailType"].append(emailData)
975
976 for item in res["mobile_list"]:
977 phoneData = {}
978 phoneData["_id"] = str(item["_id"])
979 phoneData["full_name"] = item["full_name"]
980 phoneData["mobile"] = item["mobile"]
981 phoneData["selected"] = item["selected"]
982 resultData["WhatsappType"].append(phoneData)
983
984 return {"result": resultData}
985
986
987@app.get('/getCompanyList')
988def getCompanyList(token: str = Depends(oauth2_scheme)):
989 authCount = db.users.count_documents({"token": token})
990 if authCount == 0:
991 raise HTTPException(status_code=401, detail="Unauthorized Request.")
992
993 compRes = list(db.stock_list.find().sort("stock_symbol", pymongo.ASCENDING))
994 resultList = []
995 for item in compRes:
996 resultList.append(item["stock_symbol"])
997
998 return {"result": resultList}
999
1000
1001@app.post('/addPrintRecord')
1002def addPrintRecord(page_info: str = Body(..., embed=True),
1003 token: str = Depends(oauth2_scheme)):
1004 authRes = list(db.users.find({"token": token}))
1005 if len(authRes) == 0:
1006 raise HTTPException(status_code=401, detail="Unauthorized Request.")
1007
1008 userID = authRes[0]["_id"]
1009 data = {}
1010 data["user"] = userID
1011 data["page_info"] = page_info
1012 data["print_time"] = getTodayDate()
1013
1014 db.printscreen_attempts.insert_one(data)
1015
1016 return {"result": "Record saved!"}
1017
1018
1019@app.post('/sectoralBreakup')
1020def sectoralBreakup(token: str = Depends(oauth2_scheme),
1021 stock_status: str = Body(..., embed=True),
1022 start_date: str = Body(..., embed=True),
1023 end_date: str = Body(..., embed=True)):
1024 authCount = db.users.count_documents({"token": token})
1025 if authCount == 0:
1026 raise HTTPException(status_code=401, detail="Unauthorized Request.")
1027
1028 startDateVal = getLastEntryDate(start_date)
1029 lastEntryDate = getLastEntryDate(end_date)
1030 recordsInDuration = list(db.data_bank.find({"datetime_entry": {"$gte": startDateVal, "$lte": lastEntryDate},
1031 "stock_status": statusNameToID[stock_status]}))
1032
1033 alreadyAddedComp = set()
1034 sectorCount = Counter()
1035 for record in recordsInDuration:
1036 if record["stock"] in alreadyAddedComp:
1037 pass
1038 else:
1039 sectorCount[sectorIdToName[stockIdToSector[record["stock"]]]] += 1
1040 alreadyAddedComp.add(record["stock"])
1041
1042 resultList = []
1043
1044 for keys in sectorCount:
1045 data = {"name": keys, "value": sectorCount[keys]}
1046 resultList.append(data)
1047
1048 endDateStr = lastEntryDate.strftime('%Y-%m-%d')
1049
1050 return {"last_updated": endDateStr, "result": resultList}
1051
1052
1053@app.post('/sectoralPerformanceLive')
1054def sectoralPerformanceLive(token: str = Depends(oauth2_scheme),
1055 stock_status: str = Body(..., embed=True)):
1056 authCount = db.users.count_documents({"token": token})
1057 if authCount == 0:
1058 raise HTTPException(status_code=401, detail="Unauthorized Request.")
1059
1060 myResponse = db.periodic_sectoral_performance.find_one(
1061 {"stock_status": statusNameToID[stock_status], "period": "live"})["response"]
1062
1063 result = myResponse["result"]
1064
1065 lastEntryDate = getLastEntryDate(getTodayDate().strftime("%Y-%m-%d"))
1066 lastLiveDate = getLastLiveDate(getTodayDate().strftime("%Y-%m-%d"))
1067
1068 toDate = lastLiveDate
1069 if toDate < lastEntryDate:
1070 toDate = lastEntryDate
1071
1072 return {"from_date": lastEntryDate,
1073 "to_date": toDate,
1074 "result": result}
1075
1076
1077@app.post('/stocksPerformanceLive')
1078def stocksPerformanceLive(token: str = Depends(oauth2_scheme),
1079 stock_status: str = Body(..., embed=True)):
1080 authCount = db.users.count_documents({"token": token})
1081 if authCount == 0:
1082 raise HTTPException(status_code=401, detail="Unauthorized Request.")
1083
1084 myResponse = db.periodic_stock_performance.find_one(
1085 {"stock_status": statusNameToID[stock_status], "period": "live"})["response"]
1086
1087 result = myResponse["result"]
1088
1089 lastEntryDate = getLastEntryDate(getTodayDate().strftime("%Y-%m-%d"))
1090 lastLiveDate = getLastLiveDate(getTodayDate().strftime("%Y-%m-%d"))
1091
1092 toDate = lastLiveDate
1093 if toDate < lastEntryDate:
1094 toDate = lastEntryDate
1095
1096 return {"from_date": lastEntryDate,
1097 "to_date": toDate,
1098 "result": result}
1099
1100
1101@app.post('/sectoralDrawdownLive')
1102def sectoralDrawdownLive(token: str = Depends(oauth2_scheme),
1103 stock_status: str = Body(..., embed=True)):
1104 authCount = db.users.count_documents({"token": token})
1105 if authCount == 0:
1106 raise HTTPException(status_code=401, detail="Unauthorized Request.")
1107
1108 myResponse = db.periodic_sectoral_drawdown.find_one(
1109 {"stock_status": statusNameToID[stock_status], "period": "live"})["response"]
1110
1111 result = myResponse["result"]
1112
1113 lastEntryDate = getLastEntryDate(getTodayDate().strftime("%Y-%m-%d"))
1114 lastLiveDate = getLastLiveDate(getTodayDate().strftime("%Y-%m-%d"))
1115
1116 toDate = lastLiveDate
1117 if toDate < lastEntryDate:
1118 toDate = lastEntryDate
1119
1120 return {"from_date": lastEntryDate,
1121 "to_date": toDate,
1122 "result": result}
1123
1124
1125@app.post('/stocksDrawdownLive')
1126def stocksDrawdownLive(token: str = Depends(oauth2_scheme),
1127 stock_status: str = Body(..., embed=True)):
1128 authCount = db.users.count_documents({"token": token})
1129 if authCount == 0:
1130 raise HTTPException(status_code=401, detail="Unauthorized Request.")
1131
1132 myResponse = db.periodic_stock_drawdown.find_one(
1133 {"stock_status": statusNameToID[stock_status], "period": "live"})["response"]
1134
1135 result = myResponse["result"]
1136
1137 lastEntryDate = getLastEntryDate(getTodayDate().strftime("%Y-%m-%d"))
1138 lastLiveDate = getLastLiveDate(getTodayDate().strftime("%Y-%m-%d"))
1139
1140 toDate = lastLiveDate
1141 if toDate < lastEntryDate:
1142 toDate = lastEntryDate
1143
1144 return {"from_date": lastEntryDate,
1145 "to_date": toDate,
1146 "result": result}
1147
1148
1149@app.post('/sectoralPerformancePeriodic')
1150def sectoralPerformancePeriodic(token: str = Depends(oauth2_scheme),
1151 stock_status: str = Body(..., embed=True),
1152 period: str = Body(..., embed=True)):
1153 authCount = db.users.count_documents({"token": token})
1154 if authCount == 0:
1155 raise HTTPException(status_code=401, detail="Unauthorized Request.")
1156
1157 myResponse = db.periodic_sectoral_performance.find_one(
1158 {"stock_status": statusNameToID[stock_status], "period": period})["response"]
1159
1160 last_updated = myResponse["last_updated"]
1161 result = myResponse["result"]
1162
1163 return {"last_updated": last_updated, "result": result}
1164
1165
1166@app.post('/sectoralDrawdownPeriodic')
1167def sectoralDrawdownPeriodic(token: str = Depends(oauth2_scheme),
1168 stock_status: str = Body(..., embed=True),
1169 period: str = Body(..., embed=True)):
1170 authCount = db.users.count_documents({"token": token})
1171 if authCount == 0:
1172 raise HTTPException(status_code=401, detail="Unauthorized Request.")
1173
1174 myResponse = db.periodic_sectoral_drawdown.find_one(
1175 {"stock_status": statusNameToID[stock_status], "period": period})["response"]
1176
1177 last_updated = myResponse["last_updated"]
1178 result = myResponse["result"]
1179
1180 return {"last_updated": last_updated, "result": result}
1181
1182
1183@app.post('/stocksDrawdownPeriodic')
1184def stocksDrawdownPeriodic(token: str = Depends(oauth2_scheme),
1185 stock_status: str = Body(..., embed=True),
1186 period: str = Body(..., embed=True)):
1187 authCount = db.users.count_documents({"token": token})
1188 if authCount == 0:
1189 raise HTTPException(status_code=401, detail="Unauthorized Request.")
1190
1191 myResponse = db.periodic_stock_drawdown.find_one(
1192 {"stock_status": statusNameToID[stock_status], "period": period})["response"]
1193
1194 last_updated = myResponse["last_updated"]
1195 result = myResponse["result"]
1196
1197 return {"last_updated": last_updated, "result": result}
1198
1199
1200@app.post('/stocksPerformancePeriodic')
1201def stocksPerformancePeriodic(token: str = Depends(oauth2_scheme),
1202 stock_status: str = Body(..., embed=True),
1203 period: str = Body(..., embed=True)):
1204 authCount = db.users.count_documents({"token": token})
1205 if authCount == 0:
1206 raise HTTPException(status_code=401, detail="Unauthorized Request.")
1207
1208 myResponse = db.periodic_stock_performance.find_one(
1209 {"stock_status": statusNameToID[stock_status], "period": period})["response"]
1210
1211 last_updated = myResponse["last_updated"]
1212 result = myResponse["result"]
1213
1214 return {"last_updated": last_updated, "result": result}
1215
1216
1217@app.post('/momSectorPerformance')
1218def momSectorPerformance(token: str = Depends(oauth2_scheme),
1219 stock_status: str = Body(..., embed=True)):
1220 authCount = db.users.count_documents({"token": token})
1221 if authCount == 0:
1222 raise HTTPException(status_code=401, detail="Unauthorized Request.")
1223
1224 myResponse = db.month_on_month_sectoral_performance.find_one(
1225 {"stock_status": statusNameToID[stock_status]})
1226 result = myResponse["response"]
1227
1228 return {"result": result}
1229
1230
1231@app.post('/statusVsNiftyIndex')
1232def statusVsNiftyIndex(token: str = Depends(oauth2_scheme),
1233 stock_status: str = Body(..., embed=True),
1234 period: str = Body(..., embed=True)):
1235 authCount = db.users.count_documents({"token": token})
1236 if authCount == 0:
1237 raise HTTPException(status_code=401, detail="Unauthorized Request.")
1238
1239 myResponse = db.status_vs_nifty_index.find_one(
1240 {"stock_status": statusNameToID[stock_status],
1241 "period": period})
1242
1243 last_updated = getLastLiveDate(getTodayDate().strftime("%Y-%m-%d")).strftime("%Y-%m-%d")
1244 result = myResponse["response"]
1245
1246 return {"last_updated": last_updated, "result": result}
1247
1248
1249##################################################
1250##################################################
1251
1252@app.post("/trackActivity")
1253def trackActivity(requestBody: UserActivityModel,
1254 token: str = Depends(oauth2_scheme)):
1255 myList = requestBody.activity_logs
1256
1257 user_data = pillarr_db.rr_pillarr_users.find_one({"token": token})
1258 myUserId = user_data["_id"]
1259 newList = []
1260
1261 for item in myList:
1262 existCount = pillarr_db.rr_pillarr_user_activity.count({"user_id": myUserId, "start_time": item["start_time"]})
1263 if existCount == 0:
1264 item["user_id"] = myUserId
1265 newList.append(item)
1266
1267 if len(newList) > 0:
1268 try:
1269 pillarr_db.rr_pillarr_user_activity.insert_many(newList)
1270 except:
1271 return {"status": False}
1272
1273 for item in myList:
1274 try:
1275 item.pop("_id")
1276 except:
1277 pass
1278 try:
1279 item.pop("user_id")
1280 except:
1281 pass
1282
1283 return {"status": True, "data": myList}
1284
1285
1286@app.get("/getTeamStatus")
1287def getTeamStatus():
1288 teamIdToName = {}
1289 teamLeaderToUsers = {}
1290
1291 myRes = pillarr_db.rr_pillarr_teams.find()
1292 for item in myRes:
1293 teamIdToName[item["team_leader"]] = item["team_name"]
1294
1295 teamIdToName["0"] = "Unmapped Users"
1296 allUsers = pillarr_db.rr_pillarr_users.find()
1297
1298 finalData = []
1299 unmappedEntry = 0
1300
1301 for item in allUsers:
1302 try:
1303 leadId = item["team_leader"]
1304 except:
1305 leadId = "0"
1306
1307 if leadId not in teamLeaderToUsers:
1308 teamLeaderToUsers[leadId] = []
1309 teamLeaderToUsers[leadId].append(item)
1310
1311 for key in teamLeaderToUsers:
1312 myRes = teamLeaderToUsers[key]
1313 activeUsers = []
1314 inactiveUsers = []
1315
1316 for item in myRes:
1317 try:
1318 if item["demoWatched"]:
1319 activeUsers.append(item["email"])
1320 else:
1321 inactiveUsers.append(item["email"])
1322 except:
1323 inactiveUsers.append(item["email"])
1324
1325 data = {}
1326 data["team_name"] = teamIdToName[key]
1327 data["count_total_users"] = len(activeUsers) + len(inactiveUsers)
1328 data["count_active_users"] = len(activeUsers)
1329 data["count_inactive_users"] = len(inactiveUsers)
1330 data["list_active_users"] = activeUsers
1331 data["list_inactive_users"] = inactiveUsers
1332
1333 if key == "0":
1334 unmappedEntry = data
1335 else:
1336 finalData.append(data)
1337
1338 finalData.append(unmappedEntry)
1339
1340 return {"result": finalData}
1341
1342
1343@app.get("/getCountryList")
1344def getCountryList():
1345 myRes = rr_db.country_list.find()
1346 finalData = []
1347 for item in myRes:
1348 data = {}
1349 data["country"] = item["country"]
1350 data["country_code"] = item["country_code"]
1351 finalData.append(data)
1352
1353 return {"result": finalData}
1354
1355
1356async def insertPanVerifyResponse(panResponse):
1357 myConn = connectToStagingDB()
1358 myCursor = myConn.cursor()
1359 myCommand = 'insert into rnr_v2_pan_verify_attempts VALUES ("' + str(panResponse) + '", "' + str(
1360 getTodayDate()) + '")'
1361 myCursor.execute(myCommand)
1362 myConn.commit()
1363 myConn.close()
1364
1365
1366@app.post("/quickoPanVerify")
1367async def quickoPanVerify(pan: str = Form(...)):
1368 tokenResponse = requests.post("https://api.quicko.com/authenticate", headers={'x-api-key': quickoKey_01,
1369 'x-api-secret': quickoKey_02,
1370 'x-api-version': quicko_api_version})
1371 access_token = tokenResponse.json()["access_token"]
1372
1373 panResponse = requests.get("https://api.quicko.com/pans/" + pan + "/verify",
1374 params={'consent': "Y",
1375 'reason': "testing"},
1376 headers={
1377 'Authorization': access_token,
1378 'x-api-key': quickoKey_01,
1379 'x-api-version': quicko_api_version
1380 })
1381
1382 panResponse = panResponse.json()
1383 await insertPanVerifyResponse(panResponse)
1384
1385 return panResponse
1386
1387
1388@app.get('/niftyOverviewReport')
1389async def niftyOverviewReport(token: str = Depends(oauth2_scheme)):
1390 authUser = db.users.find_one({"token": token})
1391 if authUser is None:
1392 raise HTTPException(status_code=401, detail="Unauthorized Request.")
1393
1394 receiptEmail = authUser["email"]
1395 smtp_server = "smtp.gmail.com"
1396 port = 587 # For starttls
1397 sender_email = "rrpy.mail01@gmail.com"
1398 password = "Ecpl1234"
1399
1400 lastEntryText = getLastEntryDate(
1401 getTodayDate().strftime("%Y-%m-%d")).strftime(
1402 "%d %b %Y")
1403 message = MIMEMultipart("alternative")
1404 message["Subject"] = "[Alphabet] Stocks Classification - " + lastEntryText
1405 message["From"] = sender_email
1406 message["To"] = receiptEmail
1407
1408 msg = "Please find the spreadsheet containing a list of all " \
1409 "stocks along with their Technical Indicators and Stock Status as of " + lastEntryText + " below:<br>" + \
1410 "https://docs.google.com/spreadsheets/d/1kccpdc5HJbiO3Dz-TOPAtV-X3f80PGWuB0aVcjrf0XQ"
1411
1412 mailContent = MIMEText(msg, "html")
1413 message.attach(mailContent)
1414 # Create a secure SSL context
1415 context = ssl.create_default_context()
1416
1417 # Try to log in to server and send email
1418 try:
1419 server = smtplib.SMTP(smtp_server, port)
1420 server.starttls(context=context) # Secure the connection
1421 server.login(sender_email, password)
1422 server.sendmail(sender_email, receiptEmail, message.as_string())
1423
1424 server.quit()
1425 except Exception as e:
1426 # Print any error messages to stdout
1427 print(e)
1428
1429 return {
1430 "result": "A report has been generated and an email has been sent to " + receiptEmail + \
1431 " containing access to the spreadsheet."}
1432
1433
1434@app.post("/newRiskProfile")
1435def newRiskProfile(email: str = Form(...)):
1436 finalData = []
1437 questionIdToStatement = {}
1438 answerIdToStatement = {}
1439
1440 if stagingModeActive:
1441 myConn = connectToStagingDB()
1442 else:
1443 myConn = connectToStagingDB()
1444
1445 myCursor = myConn.cursor()
1446 myCommand = 'select qid, question from rr_ob_risk_profile_questions'
1447 myCursor.execute(myCommand)
1448 queryResult = myCursor.fetchall()
1449 for item in queryResult:
1450 questionIdToStatement[item[0]] = item[1]
1451
1452 myCommand = 'select option_id, answer from rr_ob_risk_profile_answer'
1453 myCursor.execute(myCommand)
1454 queryResult = myCursor.fetchall()
1455 for item in queryResult:
1456 answerIdToStatement[item[0]] = item[1]
1457
1458 myCommand = 'SELECT lead_id, answers_selected FROM rr_ob_user_portfolio ' \
1459 'where lead_id = (SELECT lead_id FROM rr_ob_users where customer_email_id = "' + email + '")'
1460 myCursor.execute(myCommand)
1461 queryResult = myCursor.fetchone()
1462 myJson = json.loads(queryResult[1])
1463 for item in myJson:
1464 data = {}
1465 data["id"] = item["qid"]
1466 data["question"] = questionIdToStatement[item["qid"]]
1467 data["answer"] = answerIdToStatement[item["option_id"]]
1468
1469 finalData.append(data)
1470
1471 myConn.close()
1472
1473 return {"status": True, "reports": finalData}
1474
1475
1476@app.get("/dailyClosing")
1477def dailyClosing():
1478 myRes = list(rr_db.final_closing.find())
1479 finalData = []
1480 for item in myRes:
1481 data = {}
1482 data['symbol'] = item['symbol']
1483 data['close'] = item['close']
1484 finalData.append(data)
1485
1486 return finalData
1487
1488
1489@app.post("/toggleServerMode")
1490def toggleServerMode(stagingMode: bool = Form(...)):
1491 global stagingModeActive
1492 stagingModeActive = stagingMode
1493 if stagingModeActive:
1494 result = "SQL Table switched to Staging."
1495 else:
1496 result = "SQL Table switched to Live."
1497
1498 return {"result": result}
1499
1500
1501@app.post("/fetchAssessmentResult")
1502def fetchAssessmentResult(email: str = Body(..., embed=True)):
1503 userData = pillarr_db.rr_pillarr_users.find_one({"email": email})
1504 if userData is None:
1505 return {"status": False, "message": "User does not exist"}
1506
1507 else:
1508 finalResult = []
1509
1510 user_id = userData["_id"]
1511 totalQuestions = 0
1512 totalCorrect = 0
1513 questionToCorrectAnswer = {}
1514 answerIdToStatement = {}
1515
1516 allAnswers = list(pillarr_db.rr_pillarr_questions_options.find())
1517 for item in allAnswers:
1518 answerIdToStatement[item["_id"]] = item["option_data"]
1519 if item["is_correct"]:
1520 questionToCorrectAnswer[item["question_id"]] = item["_id"]
1521
1522 allQuestionList = []
1523 questionsRes = list(
1524 pillarr_db.rr_pillarr_quiz_questions.find({"module_category_id": ObjectId('605c06647449302a74c4515b')}))
1525 allQuestionList.extend(questionsRes)
1526 questionsRes = list(
1527 pillarr_db.rr_pillarr_quiz_questions.find({"module_category_id": ObjectId('605c06727449302a74c4515c')}))
1528 allQuestionList.extend(questionsRes)
1529 questionsRes = list(
1530 pillarr_db.rr_pillarr_quiz_questions.find({"module_category_id": ObjectId('605c06977449302a74c4515d')}))
1531 allQuestionList.extend(questionsRes)
1532 questionsRes = list(
1533 pillarr_db.rr_pillarr_quiz_questions.find({"module_category_id": ObjectId('605c07187449302a74c4515e')}))
1534 allQuestionList.extend(questionsRes)
1535
1536 totalQuestions = len(allQuestionList)
1537 for item in allQuestionList:
1538 data = {}
1539 data["question"] = item["question"]
1540 data["attempted"] = False
1541 data["answers"] = []
1542 correctAnswer = questionToCorrectAnswer[item["_id"]]
1543 data["answers"].append({"statement": answerIdToStatement[correctAnswer], "color": "#43A047"})
1544
1545 userResponse = pillarr_db.rr_pillarr_quiz_given_by_users.find_one({"user_id": user_id,
1546 "question_id": item["_id"]})
1547
1548 if userResponse is not None:
1549 if "question_response_id" in userResponse:
1550 data["attempted"] = True
1551 if userResponse["question_response_id"] == correctAnswer:
1552 totalCorrect += 1
1553 else:
1554 data["answers"].append({"statement": answerIdToStatement[userResponse["question_response_id"]],
1555 "color": "#e53935"})
1556
1557 finalResult.append(data)
1558
1559 return {"status": True, "totalQuestions": totalQuestions, "totalCorrect": totalCorrect, "result": finalResult}
1560
1561
1562@app.post("/_upload")
1563async def _upload(saCode: str = Form(...),
1564 requestId: str = Form(...),
1565 docNo: str = Form(...),
1566 hash: str = Form(...),
1567 docType: str = Form(...),
1568 pageNo: str = Form(...),
1569 rectangle: str = Form(...),
1570 reason: str = Form(...),
1571 file1: UploadFile = Form(...)):
1572 data = {}
1573 data["saCode"] = saCode
1574 data["requestId"] = requestId
1575 data["docNo"] = docNo
1576 data["hash"] = hash
1577 data["docType"] = docType
1578 data["pageNo"] = pageNo
1579 data["rectangle"] = rectangle
1580 data["reason"] = reason
1581 fileName = file1.filename
1582 file1 = await readFile(file1)
1583
1584 myRequest = requests.post("https://prod.aadhaarbridge.com/api/_upload",
1585 data=data,
1586 files={"file1": (fileName, file1, 'application/pdf')},
1587 headers={'Accept-Encoding': "1"})
1588 myResponse = myRequest.json()
1589
1590 return myResponse
1591
1592
1593def readFile(file):
1594 return file.read()
1595
1596
1597@app.post("/_init")
1598async def _init(saCode: str = Form(...),
1599 api: str = Form(...),
1600 requestId: str = Form(...),
1601 timeStamp: str = Form(...),
1602 purpose: str = Form(...),
1603 otp: str = Form(...),
1604 hash: str = Form(...),
1605 fingerPrint: str = Form(...),
1606 iris: str = Form(...),
1607 channel: str = Form(...),
1608 successUrl: str = Form(...),
1609 failureUrl: str = Form(...)):
1610 data = {}
1611 data["saCode"] = saCode
1612 data["api"] = api
1613 data["requestId"] = requestId
1614 data["timeStamp"] = timeStamp
1615 data["purpose"] = purpose
1616 data["otp"] = otp
1617 data["hash"] = hash
1618 data["fingerPrint"] = fingerPrint
1619 data["iris"] = iris
1620 data["channel"] = channel
1621 data["successUrl"] = successUrl
1622 data["failureUrl"] = failureUrl
1623
1624 myRequest = requests.post("https://prod.aadhaarbridge.com/api/_init",
1625 data=data,
1626 headers={'Accept-Encoding': "1"},
1627 allow_redirects=False)
1628 myCode = myRequest.status_code
1629 myHeaders = myRequest.headers
1630
1631 return Response(status_code=myCode, headers=dict(myHeaders))
1632
1633
1634@app.get("/fetchCustomerComplaints")
1635def fetchCustomerComplaints():
1636 myScope = ['https://spreadsheets.google.com/feeds', 'https://www.googleapis.com/auth/drive']
1637 myCreds = ServiceAccountCredentials.from_json_keyfile_name('my_creds.json', myScope)
1638
1639 client = gspread.authorize(myCreds)
1640 sheet = client.open('CustomerComplaints')
1641 sheet_instance = sheet.get_worksheet(0)
1642 finalData = []
1643 allRecords = sheet_instance.get_all_records()
1644 for item in allRecords:
1645 data = {}
1646 data["month_beginning"] = item['At the beginning of the month']
1647 data["month_received"] = item['Received during the month']
1648 data["month_resolved"] = item['Resolved during the month']
1649 data["month_pending"] = item['Pending at the end of month']
1650 data["pending_reason"] = item['Reasons for pendency']
1651
1652 finalData.append(data)
1653
1654 return finalData
1655
1656
1657@app.post("/saveFAQ")
1658def saveFAQ(requestBody: FAQModel):
1659 sectionID = requestBody.section_id
1660
1661 myConn = connectToStagingDB()
1662 myCursor = myConn.cursor()
1663 if sectionID == 0:
1664 myCommand = 'select section_id, section_name from rnr_cb_section_master where section_name = "' + str(
1665 requestBody.section_name) + '"'
1666 myCursor.execute(myCommand)
1667 sqlResult = myCursor.fetchone()
1668
1669 if sqlResult is None:
1670 myCommand = 'INSERT into rnr_cb_section_master (section_name) VALUES ("' + str(
1671 requestBody.section_name) + '")'
1672 myCursor.execute(myCommand)
1673 myCommand = 'select section_id, section_name from rnr_cb_section_master where section_name = "' + str(
1674 requestBody.section_name) + '"'
1675 myCursor.execute(myCommand)
1676 sqlResult = myCursor.fetchone()
1677 sectionID = sqlResult[0]
1678 else:
1679 sectionID = sqlResult[0]
1680
1681 myCommand = 'SELECT faq_id from rnr_cb_faq_bank ORDER BY faq_id DESC LIMIT 1'
1682 myCursor.execute(myCommand)
1683 sqlResult = myCursor.fetchone()
1684 if sqlResult is None:
1685 faqID = 1
1686 else:
1687 faqID = sqlResult[0] + 1
1688
1689 finalResult = []
1690 for item in requestBody.selected_products:
1691 finalResult.append((item, requestBody.faq_question, requestBody.faq_answer, sectionID, faqID))
1692
1693 insertCommand = "INSERT INTO rnr_cb_faq_bank" \
1694 "(product_id, question" \
1695 ", answer, section_id, faq_id) " \
1696 "VALUES" \
1697 "(%s, %s, %s, %s, %s)"
1698
1699 myCursor.executemany(insertCommand, finalResult)
1700
1701 return {"result": "FAQ Record inserted."}
1702
1703
1704@app.get("/getFAQ/{product_id}")
1705def faqSections(product_id: int):
1706 finalData = []
1707 productIdToName = {}
1708 sectionIdToName = {}
1709
1710 myConn = connectToStagingDB()
1711 myCursor = myConn.cursor()
1712
1713 myCommand = 'SELECT product_id, product_name from rnr_cb_product_master'
1714 myCursor.execute(myCommand)
1715 sqlResult = list(myCursor.fetchall())
1716 for item in sqlResult:
1717 productIdToName[item[0]] = item[1]
1718
1719 myCommand = 'SELECT section_id, section_name from rnr_cb_section_master'
1720 myCursor.execute(myCommand)
1721 sqlResult = list(myCursor.fetchall())
1722 for item in sqlResult:
1723 sectionIdToName[item[0]] = item[1]
1724
1725 myCommand = 'SELECT faq_id, product_id, question, answer, section_id from rnr_cb_faq_bank where product_id = ' + str(
1726 product_id)
1727 myCursor.execute(myCommand)
1728 sqlResult = list(myCursor.fetchall())
1729 for item in sqlResult:
1730 data = {}
1731 data["faq_id"] = item[0]
1732 data["product_id"] = item[1]
1733 data["question"] = item[2]
1734 data["answer"] = item[3]
1735 data["section_id"] = item[4]
1736 data["product_name"] = productIdToName[item[1]]
1737 data["section_name"] = sectionIdToName[item[4]]
1738 finalData.append(data)
1739
1740 return {"result": finalData}
1741
1742
1743@app.post("/createUserCB")
1744def createUserCB(requestBody: CBUserModel):
1745 myConn = connectToStagingDB()
1746 myCursor = myConn.cursor()
1747
1748 # No Validations for now (internal API)
1749
1750 myCommand = 'INSERT INTO rnr_cb_users (username, full_name, email, password_hash, mobile)' \
1751 'VALUES(%s, %s, %s, %s, %s)'
1752 passHash = hashMyPass(requestBody.password)
1753 userData = (requestBody.username.lower(), requestBody.full_name, requestBody.email.lower(), passHash.lower(),
1754 requestBody.mobile)
1755
1756 myCursor.execute(myCommand, userData)
1757
1758 return {"result": "User created"}
1759
1760
1761@app.post("/loginCB")
1762def loginCB(form_data: OAuth2PasswordRequestForm = Depends()):
1763 myConn = connectToStagingDB()
1764 myCursor = myConn.cursor()
1765
1766 userNameInLower = str(form_data.username).lower()
1767 if '@' in userNameInLower:
1768 loginType = 'Email'
1769 else:
1770 loginType = 'Username'
1771
1772 myCommand = 'SELECT username, full_name, email, password_hash, mobile, token from rnr_cb_users where ' \
1773 + loginType.lower() + ' = "' + userNameInLower + '"'
1774 myCursor.execute(myCommand)
1775 sqlResult = myCursor.fetchone()
1776
1777 if sqlResult is None:
1778 return {"status": False, "message": loginType + " does not exist."}
1779 else:
1780 hashedPass = hashMyPass(form_data.password)
1781 if hashedPass.lower() == sqlResult[3].lower():
1782
1783 resultData = {}
1784 resultData["username"] = sqlResult[0]
1785 resultData["full_name"] = sqlResult[1]
1786 resultData["email"] = sqlResult[2]
1787 resultData["mobile"] = sqlResult[4]
1788
1789 try:
1790 resultData["token"] = sqlResult[5]
1791 genToken = resultData["token"] == ""
1792
1793 except:
1794 genToken = True
1795
1796 if genToken:
1797 token = generateToken(form_data.username)
1798 myCommand = 'UPDATE rnr_cb_users SET token = "' + token + '" where email = "' + sqlResult[2] + '"'
1799 myCursor.execute(myCommand)
1800 resultData["token"] = token
1801
1802 return {"status": True, "result": resultData}
1803
1804 else:
1805 return {"status": False, "message": "Incorrect password. Please try again."}
1806
1807
1808@app.post("/sectionsForProducts")
1809def sectionsForProducts(product_id: list = Body(..., embed=True)):
1810 finalData = []
1811 myConn = connectToStagingDB()
1812 myCursor = myConn.cursor()
1813
1814 myCommand = 'SELECT section_id, product_id from rnr_cb_faq_bank where product_id in (' + ", ".join(
1815 str(myId) for myId in product_id) + ')'
1816
1817 myCursor.execute(myCommand)
1818 sqlResult = list(myCursor.fetchall())
1819 allSections = 0
1820 productToSectionList = {}
1821
1822 for item in sqlResult:
1823 if item[1] not in productToSectionList:
1824 productToSectionList[item[1]] = []
1825 productToSectionList[item[1]].append(item[0])
1826
1827 for item in productToSectionList:
1828 if allSections == 0:
1829 allSections = productToSectionList[item]
1830 else:
1831 allSections = set(allSections).intersection(productToSectionList[item])
1832
1833 myCommand = 'SELECT section_id, section_name from rnr_cb_section_master where section_id in (' + ", ".join(
1834 str(myId) for myId in allSections) + ')'
1835
1836 myCursor.execute(myCommand)
1837 sqlResult = list(myCursor.fetchall())
1838 for item in sqlResult:
1839 data = {}
1840 data["section_id"] = item[0]
1841 data["section_name"] = item[1]
1842 finalData.append(data)
1843
1844 return {"result": finalData}
1845
1846
1847@app.post("/faqList")
1848def faqList(product_id: list = Body(..., embed=True),
1849 section_id: int = Body(..., embed=True)):
1850 finalData = []
1851 myConn = connectToStagingDB()
1852 myCursor = myConn.cursor()
1853
1854 myCommand = 'SELECT faq_id, product_id, question, answer from rnr_cb_faq_bank where product_id in (' + ", ".join(
1855 str(myId) for myId in product_id) + ') AND section_id = ' + str(section_id)
1856
1857 myCursor.execute(myCommand)
1858 sqlResult = list(myCursor.fetchall())
1859 allFAQ = 0
1860 productToFAQList = {}
1861 faqIdToQuestion = {}
1862 faqIdToAnswer = {}
1863
1864 for item in sqlResult:
1865 faqIdToQuestion[item[0]] = item[2]
1866 faqIdToAnswer[item[0]] = item[3]
1867 if item[1] not in productToFAQList:
1868 productToFAQList[item[1]] = []
1869 productToFAQList[item[1]].append(item[0])
1870
1871 for item in productToFAQList:
1872 if allFAQ == 0:
1873 allFAQ = productToFAQList[item]
1874 else:
1875 allFAQ = set(allFAQ).intersection(productToFAQList[item])
1876
1877 for item in allFAQ:
1878 data = {}
1879 data["faq_id"] = item
1880 data["faq_question"] = faqIdToQuestion[item]
1881 data["faq_answer"] = faqIdToAnswer[item]
1882 finalData.append(data)
1883
1884 return {"result": finalData}
1885
1886
1887@app.post("/deleteFAQ")
1888def deleteFAQ(product_id: list = Body(..., embed=True),
1889 faq_id: int = Body(..., embed=True)):
1890 myConn = connectToStagingDB()
1891 myCursor = myConn.cursor()
1892
1893 myCommand = 'delete from rnr_cb_faq_bank where product_id in (' + ", ".join(
1894 str(myId) for myId in product_id) + ') AND faq_id = ' + str(faq_id)
1895
1896 myCursor.execute(myCommand)
1897
1898 return {"result": "FAQ Entry deleted."}
1899
1900
1901@app.post("/deleteSection")
1902def deleteSection(section_id: int = Body(..., embed=True)):
1903 myConn = connectToStagingDB()
1904 myCursor = myConn.cursor()
1905
1906 myCommand = 'delete from rnr_cb_faq_bank where section_id = ' + str(section_id)
1907 myCursor.execute(myCommand)
1908
1909 myCommand = 'delete from rnr_cb_section_master where section_id = ' + str(section_id)
1910 myCursor.execute(myCommand)
1911
1912 return {"result": "FAQ section deleted."}
1913
1914
1915@app.post("/updateFAQ")
1916def updateFAQ(product_id: list = Body(..., embed=True),
1917 faq_id: int = Body(..., embed=True),
1918 faq_question: str = Body(..., embed=True),
1919 faq_answer: str = Body(..., embed=True),
1920 section_id: int = Body(..., embed=True)):
1921 myConn = connectToStagingDB()
1922 myCursor = myConn.cursor()
1923
1924 for item in product_id:
1925 myCommand = 'UPDATE rnr_cb_faq_bank ' \
1926 'set question = "' + faq_question + '", answer = "' + faq_answer + '", section_id = ' + str(
1927 section_id) + \
1928 ' WHERE faq_id =' + str(faq_id) + ' AND product_id = ' + str(item)
1929 myCursor.execute(myCommand)
1930
1931 return {"result": "FAQ entries updated."}
1932
1933
1934@app.post("/addFAQSection")
1935def addFAQSection(section_name: str = Body(..., embed=True)):
1936 myConn = connectToStagingDB()
1937 myCursor = myConn.cursor()
1938
1939 myCommand = 'select section_id, section_name from rnr_cb_section_master where section_name = "' + section_name + '"'
1940 myCursor.execute(myCommand)
1941 sqlResult = myCursor.fetchone()
1942 if sqlResult is None:
1943 myCommand = 'INSERT into rnr_cb_section_master (section_name) VALUES ("' + section_name + '")'
1944 myCursor.execute(myCommand)
1945 myCommand = 'select section_id, section_name from rnr_cb_section_master where section_name = "' + section_name + '"'
1946 myCursor.execute(myCommand)
1947 sqlResult = myCursor.fetchone()
1948
1949 resultMessage = "New FAQ section added."
1950 else:
1951 resultMessage = "Section already exists."
1952
1953 return {"result": {"message": resultMessage, "section_id": sqlResult[0]}}
1954
1955
1956@app.get("/allFaqSections")
1957def allFaqSections():
1958 finalData = []
1959 myConn = connectToStagingDB()
1960 myCursor = myConn.cursor()
1961 myCommand = 'SELECT section_id, section_name from rnr_cb_section_master'
1962 myCursor.execute(myCommand)
1963 sqlResult = list(myCursor.fetchall())
1964 for item in sqlResult:
1965 data = {}
1966 data["section_id"] = item[0]
1967 data["section_name"] = item[1]
1968 finalData.append(data)
1969
1970 return {"result": finalData}
1971