contract_pay.js 14 KB

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