project_service.py 36 KB

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