contract_pay.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. 'use strict';
  2. /**
  3. * Created by EllisRan on 2020/3/3.
  4. */
  5. const BaseService = require('../base/base_service');
  6. const contractConst = require('../const/contract');
  7. const auditConst = require('../const/audit').contract;
  8. const auditType = require('../const/audit').auditType;
  9. module.exports = app => {
  10. class ContractPay extends BaseService {
  11. /**
  12. * 构造函数
  13. *
  14. * @param {Object} ctx - egg全局变量
  15. * @return {void}
  16. */
  17. constructor(ctx) {
  18. super(ctx);
  19. this.tableName = 'contract_pay';
  20. this.dataId = 'id';
  21. }
  22. async getPays(options, cid) {
  23. const sql = 'SELECT * FROM ?? WHERE ' + this.ctx.helper._getOptionsSql(options) + ' AND `cid` = ? ORDER BY `create_time` DESC';
  24. const sqlParams = [this.tableName, cid];
  25. const list = await this.db.query(sql, sqlParams);
  26. const pay_shenpi_status = this.ctx.contract_tender ? this.ctx.subProject.page_show.openContractPayTenderShenpi : this.ctx.subProject.page_show.openContractPaySubProjectShenpi;
  27. if (list.length > 0) {
  28. const userList = await this.ctx.service.projectAccount.getAllDataByCondition({ where: { id: list.map(item => item.uid) } });
  29. for (const l of list) {
  30. const userInfo = userList.find(item => item.id === l.uid);
  31. l.username = userInfo ? userInfo.name : '';
  32. l.files = await this.ctx.service.contractPayAtt.getAtt(l.id);
  33. if (pay_shenpi_status) {
  34. await this.ctx.service.contractSpAudit.loadUser(l);
  35. await this.ctx.service.contractSpAudit.loadAuditViewData(l);
  36. await this.ctx.service.contractSpAudit.checkShenpi(l);
  37. if (l.status !== auditConst.status.checked || !l.final_auditor_str) {
  38. l.curAuditors2 = await this.ctx.service.contractSpAudit.getAuditorsByStatus(l.cid, l.id, l.status, l.times);
  39. if (l.status === auditConst.status.checked && !l.final_auditor_str) {
  40. const final_auditor_str = l.curAuditors2[0].audit_type === auditType.key.common
  41. ? l.curAuditors2[0].name + (l.curAuditors2[0].role ? '-' + l.curAuditors2[0].role : '')
  42. : this.ctx.helper.transFormToChinese(l.curAuditors2[0].audit_order) + '审';
  43. await this.defaultUpdate({ final_auditor_str, id: l.id });
  44. l.final_auditor_str = final_auditor_str;
  45. }
  46. }
  47. }
  48. }
  49. }
  50. return list;
  51. }
  52. async add(options, cid, data) {
  53. const node = await this.ctx.service.contract.getDataById(cid);
  54. if (!node) {
  55. throw '合同不存在';
  56. }
  57. const transaction = await this.db.beginTransaction();
  58. try {
  59. const insertData = {
  60. spid: options.spid || null,
  61. tid: options.tid || null,
  62. contract_type: options.contract_type,
  63. cid,
  64. uid: this.ctx.session.sessionUser.accountId,
  65. pay_time: data.pay_time,
  66. used: data.used || '合同',
  67. pay_price: data.pay_price,
  68. debit_price: data.debit_price,
  69. yf_price: data.yf_price,
  70. sf_price: data.sf_price,
  71. pay_type: data.pay_type,
  72. remark: data.remark,
  73. create_time: new Date(),
  74. need_shenpi: options.spid ? this.ctx.subProject.page_show.openContractPaySubProjectShenpi : this.ctx.subProject.page_show.openContractPayTenderShenpi,
  75. };
  76. const result = await transaction.insert(this.tableName, insertData);
  77. await this.calcContract(transaction, node);
  78. await this.ctx.service.contractSpAudit.makeAudits(transaction, options, cid, result.insertId, this.ctx.session.sessionUser.accountId);
  79. await transaction.commit();
  80. } catch (err) {
  81. await transaction.rollback();
  82. throw err;
  83. }
  84. return { pays: await this.getPays(options, cid), node: { update: node } };
  85. }
  86. async save(options, cid, data) {
  87. if (!data.id) {
  88. throw '参数有误';
  89. }
  90. const node = await this.ctx.service.contract.getDataById(cid);
  91. if (!node) {
  92. throw '合同不存在';
  93. }
  94. const cpInfo = await this.getDataById(data.id);
  95. if (!cpInfo) {
  96. throw '合同' + contractConst.typeName[cpInfo.contract_type] + '不存在';
  97. }
  98. const transaction = await this.db.beginTransaction();
  99. try {
  100. await transaction.update(this.tableName, data);
  101. await this.calcContract(transaction, node);
  102. await transaction.commit();
  103. } catch (err) {
  104. await transaction.rollback();
  105. throw err;
  106. }
  107. return { pays: await this.getPays(options, cid), node: { update: node } };
  108. }
  109. async del(options, cid, cpid) {
  110. if (!cpid) {
  111. throw '参数有误';
  112. }
  113. const node = await this.ctx.service.contract.getDataById(cid);
  114. if (!node) {
  115. throw '合同不存在';
  116. }
  117. const cpInfo = await this.getDataById(cpid);
  118. if (!cpInfo) {
  119. throw '合同' + contractConst.typeName[cpInfo.contract_type] + '不存在';
  120. }
  121. if (cpInfo.fpcid) {
  122. throw '该合同' + contractConst.typeName[cpInfo.contract_type] + '关联了资金支付明细,不能删除';
  123. }
  124. const transaction = await this.db.beginTransaction();
  125. try {
  126. await transaction.delete(this.tableName, { id: cpid });
  127. // 删除合同附件
  128. const attList = await this.ctx.service.contractPayAtt.getAllDataByCondition({ where: { cpid } });
  129. await this.ctx.helper.delFiles(attList);
  130. await transaction.delete(this.ctx.service.contractPayAtt.tableName, { cpid });
  131. await transaction.delete(this.ctx.service.contractSpAudit.tableName, { cpid });
  132. await this.calcContract(transaction, node);
  133. await transaction.commit();
  134. } catch (err) {
  135. await transaction.rollback();
  136. throw err;
  137. }
  138. return { pays: await this.getPays(options, cid), node: { update: node } };
  139. }
  140. async calcContract(transaction, node) {
  141. const paysList = await transaction.query('SELECT * FROM ?? WHERE `cid` = ?', [this.tableName, node.id]);
  142. let pay_price = 0;
  143. let debit_price = 0;
  144. let yf_price = 0;
  145. let sf_price = 0;
  146. for (const l of paysList) {
  147. pay_price = this.ctx.helper.add(pay_price, l.pay_price);
  148. debit_price = this.ctx.helper.add(debit_price, l.debit_price);
  149. yf_price = this.ctx.helper.add(yf_price, l.yf_price);
  150. sf_price = this.ctx.helper.add(sf_price, l.sf_price);
  151. }
  152. node.pay_price = pay_price;
  153. node.debit_price = debit_price;
  154. node.yf_price = yf_price;
  155. node.sf_price = sf_price;
  156. node.exist_pay = paysList.length === 0 ? 0 : 1;
  157. await transaction.update(this.ctx.service.contract.tableName, node);
  158. }
  159. async createContractPays(transaction, fp, times, pays) {
  160. const addPays = [];
  161. const contracts = await transaction.select(this.ctx.service.contract.tableName, { where: { id: this._.uniq(this._.map(pays, 'cid')) } });
  162. for (const p of pays) {
  163. const contract = contracts.find(c => c.id === p.cid);
  164. if (contract) {
  165. addPays.push({
  166. spid: contract.spid || null,
  167. tid: contract.tid || null,
  168. contract_type: contract.contract_type,
  169. cid: p.cid,
  170. uid: fp.uid,
  171. fpid: fp.id,
  172. fpcid: p.id,
  173. pay_time: times,
  174. used: fp.used || '合同',
  175. pay_price: p.pay_price || 0,
  176. debit_price: 0,
  177. yf_price: p.pay_price || 0,
  178. sf_price: p.settle_price || 0,
  179. pay_type: p.pay_type || '',
  180. remark: '',
  181. create_time: times,
  182. status: auditConst.status.checked,
  183. times: 1,
  184. need_shenpi: contract.spid ? this.ctx.subProject.page_show.openContractPaySubProjectShenpi : this.ctx.subProject.page_show.openContractPayTenderShenpi,
  185. });
  186. }
  187. }
  188. if (addPays.length > 0) {
  189. const result = await transaction.insert(this.tableName, addPays);
  190. for (const c of contracts) {
  191. await this.calcContract(transaction, c);
  192. }
  193. // 获取刚批量添加的所有list
  194. for (let j = 0; j < addPays.length; j++) {
  195. addPays[j].id = result.insertId + j;
  196. }
  197. if (fp.auditors && fp.auditors.length > 0) {
  198. const addSpAudits = [];
  199. for (const p of addPays) {
  200. // 先push fp原报
  201. const ybAudit = {
  202. spid: p.spid,
  203. tid: p.tid,
  204. cid: p.cid,
  205. cpid: p.id,
  206. aid: fp.uid,
  207. order: 0,
  208. times: 1,
  209. status: auditConst.status.checked,
  210. audit_type: 1,
  211. audit_order: 0,
  212. opinion: '',
  213. };
  214. for (const a of fp.auditors) {
  215. if (a.order === 1) {
  216. ybAudit.begin_time = a.begin_time;
  217. ybAudit.end_time = a.begin_time;
  218. ybAudit.times = 1;
  219. addSpAudits.push(ybAudit);
  220. }
  221. addSpAudits.push({
  222. spid: p.spid,
  223. tid: p.tid,
  224. cid: p.cid,
  225. cpid: p.id,
  226. aid: a.aid,
  227. order: a.order,
  228. times: 1,
  229. status: a.status,
  230. audit_type: a.audit_type,
  231. audit_order: a.audit_order,
  232. begin_time: a.begin_time,
  233. end_time: a.end_time,
  234. opinion: a.opinion,
  235. });
  236. }
  237. }
  238. if (addSpAudits.length > 0) {
  239. await transaction.insert(this.ctx.service.contractSpAudit.tableName, addSpAudits);
  240. }
  241. }
  242. const commonJson = this.ctx.subProject.common_json ? JSON.parse(this.ctx.subProject.common_json) : {};
  243. const used = commonJson && commonJson.tender_contract_used ? commonJson.tender_contract_used : [];
  244. if (fp.used !== '合同' && !this._.includes(used, fp.used)) {
  245. used.push(fp.used);
  246. commonJson.tender_contract_used = used;
  247. await transaction.update(this.ctx.service.subProject.tableName, { id: this.ctx.subProject.id, common_json: JSON.stringify(commonJson) });
  248. }
  249. }
  250. }
  251. async removeContractPays(transaction, fpid, pays) {
  252. const contractPays = await transaction.select(this.tableName, { where: { fpid } });
  253. await transaction.delete(this.tableName, { fpid });
  254. // 删除合同附件, 删除审批人列表
  255. for (const p of contractPays) {
  256. // 删除合同附件
  257. const attList = await this.ctx.service.contractPayAtt.getAllDataByCondition({ where: { cpid: p.id } });
  258. await this.ctx.helper.delFiles(attList);
  259. await transaction.delete(this.ctx.service.contractPayAtt.tableName, { cpid: p.id });
  260. await transaction.delete(this.ctx.service.contractSpAudit.tableName, { cpid: p.id });
  261. }
  262. const contracts = await transaction.select(this.ctx.service.contract.tableName, { where: { id: this._.uniq(this._.map(pays, 'cid')) } });
  263. if (contracts.length > 0) {
  264. for (const c of contracts) {
  265. await this.calcContract(transaction, c);
  266. }
  267. }
  268. }
  269. }
  270. return ContractPay;
  271. };