project_service.py 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961
  1. from dao.project_dao import *
  2. from dao.vendor_dao import getVendorDetailsDao
  3. from utils.error_log import insert_into_error_log
  4. from utils.UploadImage import uploadImagetoFolder
  5. from datetime import datetime
  6. from fpdf import FPDF
  7. import os
  8. import time
  9. from PyPDF2 import PdfFileMerger, PdfFileReader
  10. from utils.Email import sendEmail
  11. def addProjectService(files, data, app, mongo):
  12. queryResult = {}
  13. try:
  14. insert_doc = {
  15. 'id': '',
  16. 'user_id': '',
  17. 'project_name': '',
  18. 'intervention': '',
  19. 'project_type': '',
  20. 'mou_expiry': 0,
  21. 'quotations': [],
  22. 'amount':0,
  23. 'maintainence_amount_limit': False,
  24. 'amount_limit': False,
  25. 'req_exception':False,
  26. 'status': 'SAVED'
  27. }
  28. insert_doc['project_name'] = data['p_name'] # Project Name
  29. insert_doc['intervention'] = data['intervention'] # Intervention
  30. insert_doc['project_type'] = data['p_type'] # Project Type
  31. if data['id'] == '0':
  32. insert_doc['po_submitted'] = False
  33. insert_doc['created_on'] = int(datetime.now().timestamp() * 1000)
  34. else:
  35. insert_doc['updated_on'] = int(datetime.now().timestamp() * 1000)
  36. suffix = []
  37. for key in data:
  38. if key.startswith('v_name'):
  39. suffix.append(key[len('v_name'):])
  40. quotations = []
  41. # Upload quotations
  42. for value in suffix:
  43. append = False
  44. quote = {'v_name': '', 'exception': '', 'note': ''}
  45. if 'v_name' + str(value) in data and data['v_name' +
  46. str(value)] != '':
  47. append = True
  48. quote['v_name'] = data['v_name' + str(value)]
  49. if 'exception' + str(value) in data:
  50. quote['exception'] = True
  51. else:
  52. quote['exception'] = False
  53. if 'note' + str(value) in data:
  54. quote['note'] = data['note' + str(value)]
  55. if 'quote_file' + str(value) in files:
  56. quote_file = (files['quote_file' + str(value)])
  57. quotImageResponse = uploadImagetoFolder(
  58. quote_file, 'quote_' + str(value), app)
  59. if quotImageResponse['status'] == 'success':
  60. quote['quote_file'] = quotImageResponse['message']
  61. # quoteImageResponse=uploadImagetoFolder(quote_file,'QUOT_')
  62. if append == True:
  63. quotations.append(quote)
  64. insert_doc['quotations'] = quotations
  65. if 'mou_expiry' in data and data['mou_expiry'] != '':
  66. mou_expiry = data['mou_expiry'] # MOU Expiry
  67. insert_doc['mou_expiry'] = (int(
  68. datetime.strptime(str(mou_expiry),
  69. "%m/%d/%Y").strftime('%s'))) * 1000
  70. if 'id' in data:
  71. insert_doc['id'] = data['id']
  72. if 'user_id' in data:
  73. insert_doc['user_id'] = data['user_id']
  74. if 'maintainence_amount_limit' in data:
  75. insert_doc['maintainence_amount_limit'] = True
  76. if 'amount_limit' in data:
  77. insert_doc['amount_limit'] = True
  78. if 'req_exception' in data:
  79. insert_doc['req_exception'] = True
  80. if 'req_exception_note' in data:
  81. insert_doc['req_exception_note'] = data['req_exception_note']
  82. file_found=False
  83. # Upload MOU File
  84. if 'mou' in files:
  85. mou_file = files['mou']
  86. mouImageResponse = uploadImagetoFolder(mou_file, 'mou_', app)
  87. if mouImageResponse['status'] == 'success':
  88. file_found=True
  89. insert_doc['mou_file'] = mouImageResponse['message']
  90. # Upload Comparative Statement
  91. if 'comparative_statement' in files:
  92. comparative_statement_file = files['comparative_statement']
  93. compImageResponse = uploadImagetoFolder(comparative_statement_file,
  94. 'comparative_statement',
  95. app)
  96. if compImageResponse['status'] == 'success':
  97. insert_doc['comparative_statement'] = compImageResponse[
  98. 'message']
  99. # For Opex Donation
  100. if data['p_type'] == 'opex_donation':
  101. if 'registration_copy' in files:
  102. # Upload registration_copy
  103. registration_copy_file = files['registration_copy']
  104. regImageResponse = uploadImagetoFolder(registration_copy_file,
  105. 'reg_', app)
  106. if regImageResponse['status'] == 'success':
  107. insert_doc['registration_copy'] = regImageResponse[
  108. 'message']
  109. if 'deed_copy' in files:
  110. # Upload deed_copy
  111. deed_copy_file = files['deed_copy']
  112. deedImageResponse = uploadImagetoFolder(
  113. deed_copy_file, 'deed_', app)
  114. if deedImageResponse['status'] == 'success':
  115. insert_doc['deed_copy'] = deedImageResponse['message']
  116. if '80_g_copy' in files:
  117. # Upload 80_g_copy
  118. G80_file = files['80_g_copy']
  119. g80ImageResponse = uploadImagetoFolder(G80_file, '80g_', app)
  120. if g80ImageResponse['status'] == 'success':
  121. insert_doc['80g_copy'] = g80ImageResponse['message']
  122. if '12_a_copy' in files:
  123. # Upload 12_a_copy
  124. a12_file = files['12_a_copy']
  125. a12ImageResponse = uploadImagetoFolder(a12_file, '12a_', app)
  126. if a12ImageResponse['status'] == 'success':
  127. insert_doc['12a_copy'] = a12ImageResponse['message']
  128. if 'audit_sheet' in files:
  129. # Upload audit_sheet
  130. audit_sheet_file = files['audit_sheet']
  131. auditImageResponse = uploadImagetoFolder(
  132. audit_sheet_file, 'audit_', app)
  133. if auditImageResponse['status'] == 'success':
  134. insert_doc['audit_sheet'] = auditImageResponse['message']
  135. if 'board_resolution' in files:
  136. # Upload board_resolution
  137. board_resolution_file = files['board_resolution']
  138. boardImageResponse = uploadImagetoFolder(
  139. board_resolution_file, 'board_', app)
  140. if boardImageResponse['status'] == 'success':
  141. insert_doc['board_resolution'] = boardImageResponse[
  142. 'message']
  143. if 'donation_letter' in files:
  144. # Upload donation_letter
  145. donation_letter_file = files['donation_letter']
  146. donationImageResponse = uploadImagetoFolder(
  147. donation_letter_file, 'donation_', app)
  148. if donationImageResponse['status'] == 'success':
  149. insert_doc['donation_letter'] = donationImageResponse[
  150. 'message']
  151. if 'amount' in data:
  152. insert_doc['amount']=float(data['amount'])
  153. insert_into_db=True
  154. if insert_doc['req_exception']==False or float(insert_doc['amount'])>=25000 or float(insert_doc['amount'])>=100000:
  155. # Mou file and PO is mandatory
  156. if file_found==False or insert_doc['mou_expiry']==0:
  157. insert_into_db=False
  158. if insert_into_db==True:
  159. insertIntoProjectMaster(insert_doc, mongo)
  160. queryResult = {
  161. 'status': 'success',
  162. 'message': 'Requirement added successfully!'
  163. }
  164. else:
  165. queryResult = {
  166. 'status': 'failure',
  167. 'message': 'Mou file and expiry is mandatory!'
  168. }
  169. except Exception as err:
  170. queryResult = {'status': 'failure', 'message': 'Something went wrong!'}
  171. print(err)
  172. return queryResult
  173. def getProjectList(u_id, mongo): # Validate email id and password
  174. queryResult = []
  175. try:
  176. queryResult = getProjectListByUID(u_id, mongo)
  177. except Exception as err:
  178. # insert_into_error_log({'timestamp':int(datetime.now().timestamp()*1000),'type':'api','err':str(err),'function':'validateLogin'},mongo)
  179. queryResult = []
  180. return queryResult
  181. def getAllProjectList(mongo): # Validate email id and password
  182. queryResult = []
  183. try:
  184. queryResult = getAllProjectListDao(mongo)
  185. except Exception as err:
  186. queryResult = []
  187. return queryResult
  188. def getPOPendingLisForApprovals(u_id,mongo):
  189. queryResult = []
  190. try:
  191. queryResult = getPendingPOForApprovalDao(u_id, mongo)
  192. except Exception as err:
  193. queryResult = []
  194. return queryResult
  195. def getPOArchiveLisForApprovals(u_id,mongo):
  196. queryResult = []
  197. try:
  198. queryResult = getArchivePOForApprovalDao(u_id, mongo)
  199. except Exception as err:
  200. queryResult = []
  201. return queryResult
  202. def getProjectDetails(id, mongo): # Validate email id and password
  203. queryResult = []
  204. try:
  205. queryResult = getProjectDetailsDao(id, mongo)
  206. except Exception as err:
  207. # insert_into_error_log({'timestamp':int(datetime.now().timestamp()*1000),'type':'api','err':str(err),'function':'validateLogin'},mongo)
  208. queryResult = []
  209. return queryResult
  210. def submitProjectDetails(request_obj, mongo): # Submit Project
  211. queryResult = {}
  212. try:
  213. submitProjectDao(request_obj, mongo)
  214. queryResult = {
  215. 'status': 'success',
  216. 'message': 'Requirement submitted successfully!'
  217. }
  218. except Exception as err:
  219. # insert_into_error_log({'timestamp':int(datetime.now().timestamp()*1000),'type':'api','err':str(err),'function':'validateLogin'},mongo)
  220. queryResult = {'status': 'failure', 'message': 'Something went wrong!'}
  221. return queryResult
  222. def approveDeclinePOService(request_obj,mongo,app):
  223. queryResult={}
  224. try:
  225. update_obj={}
  226. flag=request_obj['status']
  227. po_details=getProjectDetailsDao(request_obj['po_id'],mongo)
  228. remark=request_obj["reason"]
  229. seniorId=request_obj['user_id']
  230. timestamp=int(datetime.now().timestamp())*1000
  231. approverName = ""
  232. approverLevel = ""
  233. approverId = ""
  234. approvalTrackLevel = ""
  235. for po in po_details:
  236. user_id=po['user_id']
  237. seniorLevel1=po['approval_track']['senior_level_1']
  238. seniorLevel2=po['approval_track']['senior_level_2']
  239. seniorLevel3=po['approval_track']['senior_level_3']
  240. # if senior id = senior level1
  241. if seniorLevel1["id"]==seniorId:
  242. approverName = seniorLevel1["name"]
  243. approverId = seniorLevel1["id"]
  244. approverLevel = seniorLevel1["level"]
  245. approvalTrackLevel = "senior_level_1"
  246. # If expense approved
  247. if flag=="APPROVED":
  248. if seniorLevel2["id"]=="NA":
  249. if seniorLevel3["id"]=="NA":
  250. update_obj["po_status"]=flag
  251. create_email(po,"APPROVED",approverName,approverLevel,mongo,app)
  252. else:
  253. update_obj["approval_track.senior_level_3.status"]= "PENDING"
  254. else:
  255. update_obj["approval_track.senior_level_2.status"]= "PENDING"
  256. # if senior id = senior level2
  257. if seniorLevel2["id"]==seniorId:
  258. approverName = seniorLevel2["name"]
  259. approverId = seniorLevel2["id"]
  260. approverLevel = seniorLevel2["level"]
  261. approvalTrackLevel = "senior_level_2"
  262. # If expense approved
  263. if flag=="APPROVED":
  264. if seniorLevel3["id"]=="NA":
  265. update_obj["po_status"]=flag
  266. create_email(po,"APPROVED",approverName,approverLevel,mongo,app)
  267. else:
  268. update_obj["approval_track.senior_level_3.status"]= "PENDING"
  269. # if senior id = senior level3
  270. if seniorLevel3["id"]==seniorId:
  271. approverName = seniorLevel3["name"]
  272. approverId = seniorLevel3["id"]
  273. approverLevel = seniorLevel3["level"]
  274. approvalTrackLevel = "senior_level_3"
  275. # If expense approved
  276. if flag=="APPROVED":
  277. update_obj["po_status"]=flag
  278. create_email(po,"APPROVED",approverName,approverLevel,mongo,app)
  279. update_obj["approval_track." + approvalTrackLevel + ".status"]=flag
  280. update_obj["approval_track." + approvalTrackLevel + ".info"]={"status":flag,"remark":remark,"updated_on":timestamp}
  281. # for disapproved
  282. if flag=="DECLINED":
  283. update_obj["po_status"]= "DECLINED"
  284. # Status Log
  285. approval_status={
  286. "user_id":user_id,
  287. "po_id":request_obj['po_id'],
  288. "timestamp":timestamp,
  289. "action":flag,
  290. "approver_name":approverName,
  291. "approver_level":approverLevel,
  292. "approver_id":approverId,
  293. "type":"approval",
  294. "remark":remark
  295. }
  296. # Update Purchase Order
  297. updatePurchaseOrderApprovalStatus(update_obj,request_obj['po_id'],mongo)
  298. # Insert into PO-status-log
  299. insertPOStatusLog(approval_status,mongo)
  300. queryResult = {
  301. 'status': 'success',
  302. 'message': 'Purchase Order '+flag+' successfully!'
  303. }
  304. except Exception as err:
  305. queryResult = {
  306. 'status': 'failure',
  307. 'message': 'Something went wrong!'
  308. }
  309. print(err)
  310. return queryResult
  311. def createPOService(data,app, mongo):
  312. queryResult = {}
  313. try:
  314. timestamp=int(datetime.now().timestamp())*1000
  315. total_amount = 0
  316. user_id=""
  317. insert_doc = {
  318. 'po_year': (str(time.strftime("%y", time.localtime())) + '-' +
  319. str(int(time.strftime("%y", time.localtime())) + 1)),
  320. 'po_status':'PENDING'
  321. }
  322. if 'id' in data and data['id'] != '0':
  323. project_id = data['id']
  324. order_id = ''
  325. suffix = []
  326. for key in data:
  327. if key.startswith('product_dec'):
  328. suffix.append(key[len('product_dec'):])
  329. od = []
  330. # Upload Order Details
  331. for value in suffix:
  332. append = False
  333. quote = {
  334. 'product_dec': '',
  335. 'product_qty': '',
  336. 'product_amount': '',
  337. 'product_gst': ''
  338. }
  339. if 'product_dec' + str(value) in data and data[
  340. 'product_dec' + str(value)] != '':
  341. append = True
  342. quote['product_dec'] = data['product_dec' + str(value)]
  343. if 'product_qty' + str(value) in data:
  344. quote['product_qty'] = int(data['product_qty' +
  345. str(value)])
  346. if 'product_amount' + str(value) in data:
  347. quote['product_amount'] = float(data['product_amount' +
  348. str(value)])
  349. if 'product_gst' + str(value) in data:
  350. quote['product_gst'] = float(data['product_gst' +
  351. str(value)])
  352. if append == True:
  353. od.append(quote)
  354. insert_doc['po_created_on'] = int(datetime.now().timestamp() *1000)
  355. insert_doc['od'] = od
  356. insert_doc['po_submitted'] = True
  357. if 'po_note' in data:
  358. insert_doc['po_note']=data['po_note']
  359. # if 'product_gst' in data:
  360. # insert_doc['po_gst'] = int(data['product_gst'])
  361. # if 'product_gst_amt' in data:
  362. # insert_doc['po_gst_amt'] = int(data['product_gst_amt'])
  363. if 'p_additional_charges' in data:
  364. insert_doc['po_additional_charges'] = float(data['p_additional_charges'])
  365. if 'product_total_amount' in data:
  366. insert_doc['po_total_amount'] = float(data['product_total_amount' ])
  367. total_amount += float(data['product_total_amount'])
  368. # Fetch product details
  369. project_details = getProjectDetailsDao(project_id, mongo)
  370. for project in project_details:
  371. order_id = project['intervention']+ '/'+ create_po_id(mongo)
  372. user_id = project['user_id']
  373. insert_doc['approval_track']=getApprovalTrack(total_amount,user_id,mongo)
  374. if 'vendors' in data and data['vendors'] != '':
  375. vendor_id = data['vendors'] # MOU Expiry
  376. insert_doc['vendor_id'] = vendor_id
  377. if 'po_reason' in data and data['po_reason'] != '':
  378. po_reason = data['po_reason'] # MOU Expiry
  379. insert_doc['po_reason'] = po_reason
  380. if 'MOP' in data and data['MOP'] != '':
  381. MOP = data['MOP'] # MOU Expiry
  382. insert_doc['MOP'] = MOP
  383. if 'amount_words' in data and data['amount_words'] != '':
  384. amount_words = data['amount_words'] # MOU Expiry
  385. insert_doc['amount_words'] = amount_words
  386. if 'po_mou_expiry' in data and data['po_mou_expiry'] != '':
  387. po_mou_expiry = data['po_mou_expiry'] # MOU Expiry
  388. insert_doc['po_mou_expiry'] = (int(
  389. datetime.strptime(str(po_mou_expiry),
  390. "%m/%d/%Y").strftime('%s'))) * 1000
  391. insert_doc['po_order_id'] = order_id
  392. updatePurchaseOrder(insert_doc, project_id, mongo)
  393. # Insert into PO-status-log
  394. insertPOStatusLog({
  395. "user_id":user_id,
  396. "po_id":project_id,
  397. "timestamp":timestamp,
  398. "action":"SUBMITTED"
  399. },mongo)
  400. createPoPdfService(project_id,app,mongo)
  401. queryResult = {
  402. 'status': 'success',
  403. 'message': 'Purchase order created successfully!'
  404. }
  405. else:
  406. queryResult = {
  407. 'status': 'failure',
  408. 'message': 'Something went wrong!'
  409. }
  410. except Exception as err:
  411. queryResult = {'status': 'failure', 'message': 'Something went wrong!'}
  412. print(err)
  413. return queryResult
  414. def createPoPdfService(p_id, app, mongo):
  415. queryResult = {}
  416. try:
  417. # fetch purchase order details
  418. purchase_order = getProjectDetailsDao(p_id, mongo)
  419. for order in purchase_order:
  420. if 'vendor_id' in order:
  421. vendor_id = order['vendor_id']
  422. # Get Vendor Details
  423. vendor_details = getVendorDetailsDao(vendor_id, mongo)
  424. for vendor_detail in vendor_details:
  425. createPDF(app, order, vendor_detail)
  426. except Exception as err:
  427. queryResult = {'status': 'failure', 'message': 'Something went wrong!'}
  428. print(err)
  429. def create_po_id(mongo):
  430. order_id = ''
  431. try:
  432. po_year = (str(time.strftime("%y", time.localtime())) + '-' +
  433. str(int(time.strftime("%y", time.localtime())) + 1))
  434. # get PO Year
  435. db_year = getPOYear(mongo)
  436. po_count = '01'
  437. for year_obj in db_year:
  438. if po_year == year_obj['year']:
  439. # Fetch total PO created ID
  440. po_count = getInserterdPoCount(po_year, mongo)
  441. po_count = str(po_count +
  442. 1) if po_count + 1 > 9 else '0' + str(po_count +
  443. 1)
  444. else:
  445. # insert new year object
  446. insertPOYear(po_year, mongo)
  447. order_id = (po_year + '/' + po_count)
  448. except Exception as err:
  449. print(err)
  450. return order_id
  451. def getPOStatusLogs(po_id,mongo,app):
  452. queryResult = []
  453. try:
  454. queryResult = getPOStatusLog(po_id, mongo)
  455. except Exception as err:
  456. queryResult = []
  457. return queryResult
  458. def getLastAssignedSenior(senior_obj):
  459. lastSeniorKey=''
  460. try:
  461. strToIntObj={int(k):v for k,v in senior_obj.items()}
  462. lastSeniorKey=strToIntObj[sorted(strToIntObj)[-1]]
  463. except Exception as err:
  464. print(err)
  465. return lastSeniorKey
  466. def vendorAcceptanceService(files, data, app, mongo):
  467. queryResult = {}
  468. timestamp=int(datetime.now().timestamp())*1000
  469. try:
  470. po_id=data['id']
  471. if po_id!="":
  472. updateDoc={'vendor_action':'DECLINED','vendor_acceptance':True}
  473. if 'vendor_action' in data:
  474. updateDoc['vendor_action']=data['vendor_action']
  475. # Upload Vendir Acceptance Proof
  476. if 'vendor_acceptance_proof' in files:
  477. vendor_acceptance_proof = files['vendor_acceptance_proof']
  478. vendorImageResponse = uploadImagetoFolder(vendor_acceptance_proof, 'po_vendor_accpt_', app)
  479. if vendorImageResponse['status'] == 'success':
  480. updateDoc['mou_file'] = vendorImageResponse['message']
  481. updatePurchaseOrderApprovalStatus(updateDoc,po_id, mongo)
  482. # Insert into PO-status-log
  483. insertPOStatusLog({
  484. "user_id":data['user_id'],
  485. "po_id":po_id,
  486. "timestamp":timestamp,
  487. "type":"vendor_acceptance",
  488. "action":updateDoc['vendor_action']
  489. },mongo)
  490. queryResult = {
  491. 'status': 'success',
  492. 'message': 'Status Updated Successfully!'
  493. }
  494. else:
  495. queryResult = {'status': 'failure', 'message': 'Invalid PO ID!'}
  496. except Exception as err:
  497. queryResult = {'status': 'failure', 'message': 'Something went wrong!'}
  498. print(err)
  499. return queryResult
  500. def getApprovalTrack(total_amount,user_id,mongo):
  501. approval_track = {"senior_level_1":{},"senior_level_2":{},"senior_level_3":{}}
  502. try:
  503. # Fetch user Details from user master
  504. user_list=getUserDetailsFromMaster(user_id,mongo)
  505. for user_obj in user_list:
  506. sernior_level="expense_senior_level_5000_"
  507. if total_amount>10000:
  508. sernior_level="expense_senior_level_25000_"
  509. senior_level_1_key=getLastAssignedSenior(user_obj[sernior_level+'I'])
  510. senior_level_1_name=user_obj[sernior_level+'I_name']
  511. senior_level_2_key=getLastAssignedSenior(user_obj[sernior_level+'II'])
  512. senior_level_2_name=user_obj[sernior_level+'II_name']
  513. senior_level_3_key=getLastAssignedSenior(user_obj[sernior_level+'III'])
  514. senior_level_3_name=user_obj[sernior_level+'III_name']
  515. approval_track['senior_level_1']={
  516. "level" : "Senior Level 1",
  517. "name" : senior_level_1_name,
  518. "id" : senior_level_1_key,
  519. "status" : "PENDING"
  520. }
  521. approval_track['senior_level_2']={
  522. "level" : "Senior Level 2",
  523. "name" : senior_level_2_name,
  524. "id" : senior_level_2_key,
  525. "status" : "NOT VISIBLE"
  526. }
  527. approval_track['senior_level_3']={
  528. "level" : "Senior Level 3",
  529. "name" : senior_level_3_name,
  530. "id" : senior_level_3_key,
  531. "status" : "NOT VISIBLE"
  532. }
  533. except Exception as err:
  534. print(err)
  535. return approval_track
  536. def getAllPOListService(mongo):
  537. queryResult = []
  538. try:
  539. queryResult = getPOList(mongo)
  540. except Exception as err:
  541. queryResult = []
  542. return queryResult
  543. class MyFPDF(FPDF):
  544. pass
  545. def createPDF(app, purchase_order, vendor_detail):
  546. try:
  547. order_id=""
  548. po_created_on=""
  549. po_note=""
  550. po_mou_expiry=""
  551. if 'po_order_id' in purchase_order:
  552. order_id=purchase_order['po_order_id']
  553. if 'po_created_on' in purchase_order:
  554. po_created_on=datetime.fromtimestamp(int(purchase_order['po_created_on'])/1000).strftime("%d %B, %Y")
  555. if 'po_note' in purchase_order:
  556. po_note=purchase_order['po_note']
  557. if 'po_mou_expiry' in purchase_order:
  558. po_mou_expiry=datetime.fromtimestamp(int(purchase_order['po_mou_expiry'])/1000).strftime("%d %B, %Y")
  559. authorised_by=""
  560. try:
  561. if "po_status" in purchase_order and purchase_order["po_status"]=="APPROVED" and 'approval_track' in purchase_order:
  562. if 'senior_level_1' in purchase_order['approval_track'] and purchase_order['approval_track']['senior_level_1']['status']=="APPROVED":
  563. authorised_by=purchase_order['approval_track']['senior_level_1']['name']
  564. if 'senior_level_2' in purchase_order['approval_track'] and purchase_order['approval_track']['senior_level_2']['status']=="APPROVED":
  565. authorised_by=purchase_order['approval_track']['senior_level_2']['name']
  566. if 'senior_level_3' in purchase_order['approval_track'] and purchase_order['approval_track']['senior_level_3']['status']=="APPROVED":
  567. authorised_by=purchase_order['approval_track']['senior_level_3']['name']
  568. except Exception as err:
  569. print(err)
  570. filepath = os.path.join(app.config['STATIC_IMG'], 'kef-logo.jpg')
  571. pdf = MyFPDF(orientation='P', unit='mm', format='Letter')
  572. # Effective page width, or just epw
  573. epw = pdf.w - 6 * pdf.l_margin
  574. pdf.set_left_margin(30)
  575. pdf.add_page()
  576. pdf.image(filepath, 70, 10, 70, 30)
  577. pdf.ln(30.00)
  578. pdf.set_font('Times', '', 11)
  579. pdf.multi_cell(epw, 3.81,
  580. '1st Floor, North Side, Ujagar Compound, Adjacent to Deonar Bus Depot, Off. Sion Trombay Road, Deonar, Mumbai 400 088',
  581. align='C' )
  582. # Set Header
  583. pdf.ln(15)
  584. pdf.set_font('Times', '', 18)
  585. pdf.cell(epw, 3.81, 'PURCHASE ORDER', align='C', border=0)
  586. pdf.ln(8.81)
  587. pdf.set_font('Times', 'U', 11)
  588. pdf.cell(epw, 3.81, 'PO REF:', border=0)
  589. pdf.set_xy(47.0, pdf.get_y())
  590. pdf.set_font('Times', '', 11)
  591. pdf.cell(epw, 3.81, order_id.upper(), border=0)
  592. pdf.ln(3.81)
  593. pdf.set_font('Times', 'U', 11)
  594. pdf.cell(epw, 3.81, 'DATE:', border=0)
  595. pdf.set_xy(43.0, pdf.get_y())
  596. pdf.set_font('Times', '', 11)
  597. pdf.cell(epw, 3.81, po_created_on.upper(), border=0)
  598. pdf.ln(3.81)
  599. pdf.set_font('Times', 'U', 11)
  600. pdf.cell(epw, 3.81, 'YOUR REF:', border=0)
  601. pdf.set_xy(52.0, pdf.get_y())
  602. pdf.set_font('Times', '', 11)
  603. pdf.cell(epw, 3.81, 'YOUR QUOTATION DATED '+po_mou_expiry.upper(), border=0)
  604. pdf.ln(3.81)
  605. pdf.set_font('Times', 'U', 11)
  606. pdf.multi_cell(epw, 3.81, 'BILLING ADDRESS: KOTAK EDUCATION FOUNDATION, GR FLOOR & 1 S T FLOOR UJAGAR COMPOUND, DEONAR, MUMBAI: 400088', border=0)
  607. # pdf.set_xy(67.0, pdf.get_y())
  608. # pdf.set_font('Times', '', 11)
  609. # pdf.cell(epw, 3.81,'',border=0)
  610. # pdf.ln(3.81)
  611. # pdf.cell(epw, 3.81, '', border=0)
  612. # pdf.ln(3.81)
  613. pdf.set_font('Times', 'U', 11)
  614. pdf.multi_cell(epw, 3.81, 'SHIP TO: KOTAK EDUCATION FOUNDATION, GR FLOOR & 1 S T FLOOR UJAGAR COMPOUND, DEONAR, MUMBAI: 400088', border=0)
  615. # pdf.set_xy(47.0, pdf.get_y())
  616. # pdf.set_font('Times', '', 11)
  617. # pdf.cell(epw, 3.81,'',border=0)
  618. # pdf.ln(3.81)
  619. # pdf.cell(epw, 3.81, '', border=0)
  620. pdf.ln(12.81)
  621. pdf.set_font('Times', 'BU', 11)
  622. pdf.cell(epw, 3.81, 'TO BE ISSUED TO:', border=0)
  623. pdf.ln(8.81)
  624. pdf.set_font('Times', 'U', 11)
  625. pdf.cell(epw, 3.81, 'VENDOR NAME:', border=0)
  626. pdf.set_xy(62.0, pdf.get_y())
  627. pdf.set_font('Times', '', 11)
  628. pdf.cell(epw, 3.81, vendor_detail['v_name'].upper(), border=0)
  629. pdf.ln(3.81)
  630. pdf.set_font('Times', 'U', 11)
  631. pdf.multi_cell(epw, 3.81, 'VENDOR ADDRESS: ' +vendor_detail['v_address'].upper(), border=0)
  632. pdf.set_font('Times', 'U', 11)
  633. pdf.cell(epw, 3.81, 'VENDOR CODE:', border=0)
  634. pdf.set_xy(60.0, pdf.get_y())
  635. pdf.set_font('Times', '', 11)
  636. pdf.cell(epw, 3.81, str(vendor_detail['v_code']), border=0)
  637. # pdf.set_xy(10.0, 120.0)
  638. pdf.ln(8.81)
  639. pdf.set_font('Times', '', 11)
  640. pdf.multi_cell(epw, 3.81,
  641. 'We hereby place this Purchase order on yourselves for supply of the following materials and delivery of the following services, as per terms and conditions given in this Purchase Order.',
  642. border=0)
  643. pdf.ln(8.81)
  644. # pdf.set_right_margin(30)
  645. pdf.set_font('Times', 'B', 11)
  646. pdf.cell(epw, 3.81, 'MATERIAL / SERVICES ORDER', align='C', border=0)
  647. pdf.ln(5.84)
  648. # Add table
  649. # Set column width to 1/4 of effective page width to distribute content
  650. # evenly across table and page
  651. col_width = epw / 6
  652. # Since we do not need to draw lines anymore, there is no need to separate
  653. # headers from data matrix.
  654. data = [['Sr no.', 'Product Description', 'Qty', 'Price','Gst','Amount']]
  655. if 'od' in purchase_order:
  656. i = 1
  657. for order in purchase_order['od']:
  658. data.append([
  659. i, order['product_dec'], order['product_qty'],
  660. order['product_amount'],order['product_gst'],(order['product_amount']*order['product_qty'])+order['product_gst']
  661. ])
  662. i += 1
  663. data.append(['', 'Additional Charges', '','', purchase_order['po_additional_charges']])
  664. # data.append(['', 'GST : '+ str(purchase_order['po_gst'])+'%', '','', purchase_order['po_gst_amt']])
  665. data.append(['', 'Total Amount', '','', purchase_order['po_total_amount']])
  666. # Text height is the same as current font size
  667. th = pdf.font_size
  668. pdf.set_font('Times', '', 11.0)
  669. i = 1
  670. # Here we add more padding by passing 2*th as height
  671. for row in data:
  672. ybefore=pdf.get_y()
  673. # pdf.set_xy(col_width, 2 * th)
  674. j=1
  675. cell_margin=0
  676. for datum in row:
  677. if i == 1:
  678. pdf.set_font('Times', 'B', 11.0)
  679. else:
  680. pdf.set_font('Times', '', 11.0)
  681. if j==2:
  682. pdf.multi_cell(68,3.81, str(datum),border=0)
  683. pdf.set_xy(cell_margin+(68)+pdf.l_margin, ybefore)
  684. cell_margin+=68
  685. else:
  686. pdf.multi_cell(22,3.81, str(datum),border=0)
  687. pdf.set_xy(cell_margin+(22)+pdf.l_margin, ybefore)
  688. cell_margin+=22
  689. j+=1
  690. # pdf.multi_cell(col_width, 2 * th, str(datum), border=1)
  691. # Enter data in colums
  692. # ybefore=pdf.get_y()
  693. i += 1
  694. pdf.ln(2 * 3.81)
  695. if 'intervention' in purchase_order and purchase_order['intervention']=='IT':
  696. pdf.ln(8.81)
  697. # pdf.set_right_margin(30)
  698. pdf.set_font('Times', 'B', 11)
  699. pdf.cell(epw, 3.81, 'DELIVERY TIMELINES', align='C', border=0)
  700. pdf.ln(5.84)
  701. col_width = epw / 7
  702. it_data = [['Particulars', 'Quantity', 'Location', 'Mode of delivery','Delivery Timelines','Remarks'],
  703. ['','','','','','',''],
  704. ['','','','','','',''],
  705. ['','','','','','','']]
  706. # Text height is the same as current font size
  707. th = pdf.font_size
  708. pdf.set_font('Times', '', 11.0)
  709. k = 1
  710. # Here we add more padding by passing 2*th as height
  711. for it_row in it_data:
  712. ybefore=pdf.get_y()
  713. # pdf.set_xy(col_width, 2 * th)
  714. j=1
  715. cell_margin=0
  716. for datum in it_row:
  717. if k == 1:
  718. pdf.set_font('Times', 'B', 11.0)
  719. else:
  720. pdf.set_font('Times', '', 11.0)
  721. if j==1:
  722. pdf.multi_cell(68,3.81, str(datum),border=0)
  723. pdf.set_xy(cell_margin+(68)+pdf.l_margin, ybefore)
  724. cell_margin+=68
  725. else:
  726. pdf.multi_cell(22,3.81, str(datum),border=0)
  727. pdf.set_xy(cell_margin+(22)+pdf.l_margin, ybefore)
  728. cell_margin+=22
  729. j+=1
  730. # pdf.multi_cell(col_width, 2 * th, str(datum), border=1)
  731. # Enter data in colums
  732. # ybefore=pdf.get_y()
  733. k += 1
  734. pdf.ln(2 * 3.81)
  735. pdf.set_font('Times', '', 11)
  736. # pdf.set_xy(10.0, 236.0)
  737. pdf.ln(3.81)
  738. pdf.cell(epw, 3.81,
  739. '*Note: '+po_note,
  740. border=0)
  741. pdf.ln(8.81)
  742. pdf.cell(epw, 3.81,'Authorised Signatory',border=0)
  743. pdf.ln(3.81)
  744. pdf.cell(epw, 3.81,authorised_by,border=0)
  745. # ======== Write File ==========
  746. pdf.output(os.path.join(app.config['PO_PDF'], purchase_order['id']+'.pdf'), 'F')
  747. # Call the PdfFileMerger
  748. mergedObject = PdfFileMerger()
  749. # I had 116 files in the folder that had to be merged into a single document
  750. # Loop through all of them and append their pages
  751. mergedObject.append(PdfFileReader(os.path.join(app.config['PO_PDF'], purchase_order['id']+'.pdf'), 'rb'))
  752. if 'intervention' in purchase_order and purchase_order['intervention']=='Nirmaan':
  753. mergedObject.append(PdfFileReader(os.path.join(app.config['PO_PDF'], 'infra_tc.pdf'), 'rb'))
  754. else:
  755. mergedObject.append(PdfFileReader(os.path.join(app.config['PO_PDF'], 'Formate-2-5.pdf'), 'rb'))
  756. # Write all the files into a file which is named as shown below
  757. mergedObject.write(os.path.join(app.config['PO_PDF'], purchase_order['id']+'.pdf'))
  758. except Exception as err:
  759. print(err)
  760. def create_email(po,status,approverName,approverLevel,mongo,app):
  761. try:
  762. # get user details
  763. users=getUserDetailsFromMaster(po['user_id'],mongo)
  764. vendor_name="______________"
  765. vendor_details=getVendorDetailsDao(po['vendor_id'],mongo)
  766. for vendor in vendor_details:
  767. vendor_name=vendor['v_name']
  768. for user in users:
  769. name=user['first_name']
  770. subject="PO approval & vendor acceptance"
  771. file_name=po['id']+'.pdf'
  772. pdf_attach=True
  773. body="Dear "+name+",<br /><br /> The PO of "+vendor_name+" vendor has been approved by your "+approverLevel +" <br />Kindly forward the attached PO for vendor acceptance, after approved by vendor, kindly take a screenshot & attached the same in vendor acceptance column for further processing."
  774. if 'official_email_id' in user and user['official_email_id']!="" and user['official_email_id']!="NA":
  775. reciever_email=user['official_email_id']
  776. sendEmail(file_name,reciever_email,body,pdf_attach,subject)
  777. except Exception as err:
  778. print(err)