project_service.py 36 KB

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