change_audit_list.js 63 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234
  1. 'use strict';
  2. /**
  3. *
  4. *
  5. * @author Mai
  6. * @date 2018/8/14
  7. * @version
  8. */
  9. const audit = require('../const/audit');
  10. module.exports = app => {
  11. class ChangeAuditList extends app.BaseService {
  12. /**
  13. * 构造函数
  14. *
  15. * @param {Object} ctx - egg全局变量
  16. * @return {void}
  17. */
  18. constructor(ctx) {
  19. super(ctx);
  20. this.tableName = 'change_audit_list';
  21. }
  22. /**
  23. * 取出变更令清单列表,并按台账清单在前,空白清单在后排序
  24. * @return {void}
  25. */
  26. async getList(cid, order_by = this.ctx.change.order_by) {
  27. if (order_by) {
  28. return await this.getAllDataByCondition({ where: { cid }, orders: [['order', 'asc']] });
  29. }
  30. const sql = 'SELECT * FROM ?? WHERE `cid` = ? ORDER BY `lid` = "0", `id` asc';
  31. const sqlParam = [this.tableName, cid];
  32. const result = await this.db.query(sql, sqlParam);
  33. return this._.orderBy(result, ['order'], ['asc']);
  34. }
  35. /**
  36. * 移除清单时,同步其后清单order
  37. * @param transaction - 事务
  38. * @param {Number} cid - 变更cid
  39. * @param {Number} order - order之后的
  40. * @return {Promise<*>}
  41. * @private
  42. */
  43. async _syncOrder(transaction, cid, order, selfOperate = '-', num = 1) {
  44. this.initSqlBuilder();
  45. this.sqlBuilder.setAndWhere('cid', {
  46. value: this.db.escape(cid),
  47. operate: '=',
  48. });
  49. this.sqlBuilder.setAndWhere('order', {
  50. value: order,
  51. operate: '>=',
  52. });
  53. this.sqlBuilder.setUpdateData('order', {
  54. value: num,
  55. selfOperate,
  56. });
  57. const [sql, sqlParam] = this.sqlBuilder.build(this.tableName, 'update');
  58. const data = await transaction.query(sql, sqlParam);
  59. return data;
  60. }
  61. /**
  62. * 添加空白变更清单
  63. * @return {void}
  64. */
  65. async add(data, delimit = 100) {
  66. if (!this.ctx.tender || !this.ctx.change) {
  67. throw '数据错误';
  68. }
  69. const transaction = await this.db.beginTransaction();
  70. try {
  71. let order = null;
  72. if (this.ctx.change.order_by) {
  73. if (data) {
  74. order = parseInt(data) + 1;
  75. // order以下的清单+1
  76. await this._syncOrder(transaction, this.ctx.change.cid, order, '+');
  77. } else {
  78. order = await this.count({ cid: this.ctx.change.cid });
  79. order = order ? order + 1 : 1;
  80. }
  81. }
  82. const insertData = {
  83. tid: this.ctx.tender.id,
  84. cid: this.ctx.change.cid,
  85. lid: '0',
  86. code: '',
  87. name: '',
  88. bwmx: '',
  89. unit: '',
  90. unit_price: null,
  91. oamount: 0,
  92. oamount2: 0,
  93. camount: 0,
  94. camount_expr: '',
  95. samount: '',
  96. detail: '',
  97. spamount: 0,
  98. xmj_code: null,
  99. xmj_jldy: null,
  100. xmj_dwgc: null,
  101. xmj_fbgc: null,
  102. xmj_fxgc: null,
  103. gcl_id: '',
  104. mx_id: '',
  105. order,
  106. is_valuation: 1,
  107. delimit,
  108. };
  109. // 新增工料
  110. const result = await transaction.insert(this.tableName, insertData);
  111. if (result.affectedRows === 0) {
  112. throw '新增空白清单数据失败';
  113. }
  114. await transaction.commit();
  115. return await this.getDataById(result.insertId);
  116. } catch (err) {
  117. await transaction.rollback();
  118. throw err;
  119. }
  120. }
  121. /**
  122. * 添加台账清单(从新增部位页新增)
  123. * @return {void}
  124. */
  125. async adds(datas, delimit = 100) {
  126. if (!this.ctx.tender || !this.ctx.change) {
  127. throw '数据错误';
  128. }
  129. const transaction = await this.db.beginTransaction();
  130. try {
  131. let order = null;
  132. if (this.ctx.change.order_by) {
  133. const data = this.ctx.change.order_site ? await this.getDataById(this.ctx.change.order_site) : null;
  134. if (data) {
  135. order = parseInt(data.order) + 1;
  136. // order以下的清单+1
  137. await this._syncOrder(transaction, this.ctx.change.cid, order, '+');
  138. } else {
  139. order = await this._getMaxOrder(this.ctx.change.cid);
  140. order = order ? order + 1 : 1;
  141. }
  142. }
  143. const insertData = [];
  144. for (const d of datas) {
  145. d.tid = this.ctx.tender.id;
  146. d.cid = this.ctx.change.cid;
  147. d.spamount = d.spamount || null;
  148. d.detail = d.detail || '';
  149. d.samount = d.samount || '';
  150. d.delimit = delimit;
  151. d.order = order ? order : null;
  152. order = order ? order + 1 : null;
  153. insertData.push(d);
  154. }
  155. // 新增工料
  156. const result = await transaction.insert(this.tableName, insertData);
  157. if (result.affectedRows === 0) {
  158. throw '添加清单数据失败';
  159. }
  160. await transaction.commit();
  161. return true;
  162. } catch (err) {
  163. await transaction.rollback();
  164. throw err;
  165. }
  166. }
  167. /**
  168. * 批量添加空白变更清单
  169. * @return {void}
  170. */
  171. async batchAdd(data, delimit = 100) {
  172. if (!this.ctx.tender || !this.ctx.change) {
  173. throw '数据错误';
  174. }
  175. const transaction = await this.db.beginTransaction();
  176. try {
  177. const num = data.num ? parseInt(data.num) : 0;
  178. if (num < 1 || num > 100) {
  179. throw '批量添加的空白清单数目不能小于1或大于100';
  180. }
  181. let order = null;
  182. if (this.ctx.change.order_by) {
  183. if (data) {
  184. order = parseInt(data.postData) + 1;
  185. // order以下的清单+1
  186. await this._syncOrder(transaction, this.ctx.change.cid, order, '+', num);
  187. } else {
  188. order = await this._getMaxOrder(this.ctx.change.cid);
  189. order = order ? order + 1 : 1;
  190. }
  191. }
  192. const insertArray = [];
  193. for (let i = 0; i < num; i++) {
  194. const insertData = {
  195. tid: this.ctx.tender.id,
  196. cid: this.ctx.change.cid,
  197. lid: '0',
  198. code: '',
  199. name: '',
  200. bwmx: '',
  201. unit: '',
  202. unit_price: null,
  203. oamount: 0,
  204. oamount2: 0,
  205. camount: 0,
  206. camount_expr: '',
  207. samount: '',
  208. detail: '',
  209. spamount: 0,
  210. xmj_code: null,
  211. xmj_jldy: null,
  212. xmj_dwgc: null,
  213. xmj_fbgc: null,
  214. xmj_fxgc: null,
  215. gcl_id: '',
  216. mx_id: '',
  217. order: order ? order + i : null,
  218. is_valuation: 1,
  219. delimit,
  220. };
  221. insertArray.push(insertData);
  222. }
  223. // 新增工料
  224. const result = await transaction.insert(this.tableName, insertArray);
  225. if (result.affectedRows !== num) {
  226. throw '批量添加空白清单数据失败';
  227. }
  228. await transaction.commit();
  229. // // 获取刚批量添加的所有list
  230. // for (let j = 0; j < num; j++) {
  231. // insertArray[j].id = result.insertId + j;
  232. // }
  233. // return insertArray;
  234. return await this.getList(this.ctx.change.cid);
  235. } catch (err) {
  236. await transaction.rollback();
  237. throw err;
  238. }
  239. }
  240. async _getMaxOrder(cid) {
  241. const sql = 'SELECT MAX(`order`) AS `order` FROM ?? WHERE cid = ?';
  242. const sqlParams = [this.tableName, cid];
  243. const result = await this.db.queryOne(sql, sqlParams);
  244. return result ? result.order : 0;
  245. }
  246. /**
  247. * 删除变更清单
  248. * @param {int} id 清单id
  249. * @return {void}
  250. */
  251. async del(data) {
  252. if (!this.ctx.tender || !this.ctx.change) {
  253. throw '数据错误';
  254. }
  255. const transaction = await this.db.beginTransaction();
  256. try {
  257. // 判断是否可删
  258. await transaction.delete(this.tableName, { id: data.ids });
  259. // // order以下的清单-1
  260. if (this.ctx.change.order_by && data.postData) {
  261. await this._syncOrder(transaction, this.ctx.change.cid, data.postData, '-', data.delLength ? data.delLength : data.ids.length);
  262. }
  263. // 重新算变更令总额
  264. await this.calcCamountSum(transaction);
  265. await transaction.commit();
  266. return true;
  267. } catch (err) {
  268. await transaction.rollback();
  269. throw err;
  270. }
  271. }
  272. async dels(data) {
  273. if (!this.ctx.tender || !this.ctx.change) {
  274. throw '数据错误';
  275. }
  276. const transaction = await this.db.beginTransaction();
  277. try {
  278. // 判断是否存在调用,存在则报错
  279. const delList = await this.getAllDataByCondition({ where: { id: data.ids } });
  280. const sql1 = 'SELECT a.* FROM ?? as b LEFT JOIN ?? as a ON b.cbid = a.id WHERE b.cid = ? AND b.id in (' + this.ctx.helper.getInArrStrSqlFilter(data.ids) + ') GROUP BY b.cbid';
  281. const sqlParam1 = [this.ctx.service.stageChange.tableName, this.tableName, this.ctx.change.cid];
  282. const usedList = await transaction.query(sql1, sqlParam1);
  283. if (usedList.length > 0) {
  284. throw '清单已被调用,不可删除';
  285. }
  286. await transaction.delete(this.tableName, { id: data.ids });
  287. // // order以下的清单-1
  288. if (this.ctx.change.order_by) {
  289. const postData = this.ctx.change.order_site ? await this.getDataById(this.ctx.change.order_site) : null;
  290. await this._syncOrder(transaction, this.ctx.change.cid, (postData ? postData.order : null), '-', data.ids.length);
  291. }
  292. // 重新算变更令总额
  293. await this.calcCamountSum(transaction);
  294. await transaction.commit();
  295. return true;
  296. } catch (err) {
  297. await transaction.rollback();
  298. throw err;
  299. }
  300. }
  301. /**
  302. * 修改变更清单
  303. * @param {Object} data 工料内容
  304. * @param {int} order 期数
  305. * @return {void}
  306. */
  307. async save(data) {
  308. if (!this.ctx.tender || !this.ctx.change) {
  309. throw '数据错误';
  310. }
  311. const transaction = await this.db.beginTransaction();
  312. try {
  313. // const mb_id = data.mb_id;
  314. // delete data.mb_id;
  315. await transaction.update(this.tableName, data);
  316. // await this.calcQuantityByML(transaction, mb_id);
  317. await this.calcCamountSum(transaction);
  318. await transaction.commit();
  319. return true;
  320. } catch (err) {
  321. await transaction.rollback();
  322. throw err;
  323. }
  324. }
  325. /**
  326. * 修改变更清单 复制粘贴
  327. * @param {Object} datas 修改内容
  328. * @return {void}
  329. */
  330. async saveDatas(datas) {
  331. if (!this.ctx.tender || !this.ctx.change) {
  332. throw '数据错误';
  333. }
  334. // 判断是否可修改
  335. // 判断t_type是否为费用
  336. const transaction = await this.db.beginTransaction();
  337. try {
  338. // for (const data of datas) {
  339. // const mb_id = data.mb_id;
  340. // delete data.mb_id;
  341. // await transaction.update(this.tableName, data);
  342. // await this.calcQuantityByML(transaction, mb_id);
  343. // }
  344. await transaction.updateRows(this.tableName, datas);
  345. await this.calcCamountSum(transaction);
  346. await transaction.commit();
  347. return true;
  348. } catch (err) {
  349. await transaction.rollback();
  350. throw err;
  351. }
  352. }
  353. /**
  354. * 台账数据清单 重新选择
  355. * @param {Object} datas 内容
  356. * @return {void}
  357. */
  358. async saveLedgerListDatas(datas, data = null, order_by = this.ctx.change.order_by) {
  359. if (!this.ctx.tender || !this.ctx.change) {
  360. throw '数据错误';
  361. }
  362. // 判断是否可修改
  363. // 判断t_type是否为费用
  364. const transaction = await this.db.beginTransaction();
  365. try {
  366. let usedList = [];
  367. let order = null;
  368. if (order_by) {
  369. if (data) {
  370. order = parseInt(data) + 1;
  371. // order以下的清单+1
  372. await this._syncOrder(transaction, this.ctx.change.cid, order, '+', datas.length);
  373. } else {
  374. order = await this.count({ cid: this.ctx.change.cid });
  375. order = order ? order + 1 : 1;
  376. }
  377. } else {
  378. const sql1 = 'SELECT a.* FROM ?? as b LEFT JOIN ?? as a ON b.cbid = a.id WHERE b.cid = ? GROUP BY b.cbid';
  379. const sqlParam1 = [this.ctx.service.stageChange.tableName, this.tableName, this.ctx.change.cid];
  380. usedList = await transaction.query(sql1, sqlParam1);
  381. // 先删除原本的台账清单数据
  382. const sql = 'DELETE FROM ?? WHERE cid = ? and lid != "0"';
  383. const sqlParam = [this.tableName, this.ctx.change.cid];
  384. await transaction.query(sql, sqlParam);
  385. }
  386. const insertDatas = [];
  387. for (const data of datas) {
  388. data.tid = this.ctx.tender.id;
  389. data.cid = this.ctx.change.cid;
  390. data.spamount = data.camount;
  391. data.samount = '';
  392. data.order = order ? order : null;
  393. order = order ? order + 1 : null;
  394. insertDatas.push(data);
  395. }
  396. if (insertDatas.length > 0) await this.insertBigDatas(transaction, insertDatas);
  397. await this.calcCamountSum(transaction);
  398. if (!order_by) {
  399. // 更新stage_change和stage_change_final的cbid
  400. if (usedList.length > 0) {
  401. const updateList = [];
  402. const sql2 = 'SELECT * FROM ?? WHERE `cid` = ? AND `lid` != "0"';
  403. const sqlParam2 = [this.tableName, this.ctx.change.cid];
  404. const newList = await transaction.query(sql2, sqlParam2);
  405. // const newList = await transaction.select(this.tableName, { where: { cid: this.ctx.change.cid } });
  406. for (const used of usedList) {
  407. const findFilter = { lid: used.lid, gcl_id: used.gcl_id, bwmx: used.bwmx };
  408. if (used.mx_id) findFilter.mx_id = used.mx_id;
  409. const newone = this._.find(newList, findFilter);
  410. if (newone) {
  411. updateList.push({
  412. row: {
  413. cbid: newone.id,
  414. },
  415. where: {
  416. cid: this.ctx.change.cid,
  417. cbid: used.id,
  418. },
  419. });
  420. }
  421. }
  422. if (updateList.length > 0) {
  423. await transaction.updateRows(this.ctx.service.stageChange.tableName, updateList);
  424. await transaction.updateRows(this.ctx.service.stageChangeFinal.tableName, updateList);
  425. }
  426. }
  427. }
  428. await transaction.commit();
  429. return true;
  430. } catch (err) {
  431. await transaction.rollback();
  432. throw err;
  433. }
  434. }
  435. /**
  436. * 台账数据清单 清除部分并重新算原设计总金额
  437. * @param {Object} datas 内容
  438. * @return {void}
  439. */
  440. async removeLedgerListDatas(datas) {
  441. if (!this.ctx.tender || !this.ctx.change) {
  442. throw '数据错误';
  443. }
  444. // 判断是否可修改
  445. // 判断t_type是否为费用
  446. const transaction = await this.db.beginTransaction();
  447. try {
  448. // 先删除原本的台账清单数据
  449. // const sql = 'DELETE FROM ?? WHERE cid = ? and lid != "0"';
  450. // const sqlParam = [this.tableName, this.ctx.change.cid];
  451. // await transaction.query(sql, sqlParam);
  452. // const insertDatas = [];
  453. for (const data of datas) {
  454. // data.tid = this.ctx.tender.id;
  455. // data.cid = this.ctx.change.cid;
  456. // data.spamount = data.camount;
  457. // data.samount = '';
  458. // insertDatas.push(data);
  459. await transaction.delete(this.tableName, { id: data.id });
  460. }
  461. // if (insertDatas.length > 0) await transaction.insert(this.tableName, insertDatas);
  462. await this.calcCamountSum(transaction);
  463. await transaction.commit();
  464. return true;
  465. } catch (err) {
  466. await transaction.rollback();
  467. throw err;
  468. }
  469. }
  470. async calcCamountSum(transaction, updateTpDecimal = false, change = this.ctx.change) {
  471. // const sql = 'SELECT SUM(ROUND(`camount`*`unit_price`, )) as total_price FROM ?? WHERE cid = ?';
  472. // const sqlParam = [this.tableName, this.change.cid];
  473. // const tp = await transaction.queryOne(sql, sqlParam);
  474. // 防止小数位不精确,采用取值计算
  475. const sql = 'SELECT unit_price, spamount, is_valuation, gcl_id, unit FROM ?? WHERE cid = ?';
  476. const sqlParam = [this.tableName, change.cid];
  477. const changeList = await transaction.query(sql, sqlParam);
  478. let total_price = 0;
  479. let positive_tp = 0;
  480. let negative_tp = 0;
  481. let valuation_tp = 0;
  482. let unvaluation_tp = 0;
  483. const tp_decimal = change.tp_decimal ? change.tp_decimal : this.ctx.tender.info.decimal.tp;
  484. const up_decimal = change.up_decimal ? change.up_decimal : this.ctx.tender.info.decimal.up;
  485. const gclChangeList = this._.uniq(this._.map(changeList, 'gcl_id'));
  486. for (const g of gclChangeList) {
  487. if (g) {
  488. const list = this._.filter(changeList, { gcl_id: g });
  489. let spamount = 0;
  490. let valuation_amount = 0;
  491. let unvaluation_amount = 0;
  492. let unitPrice = 0;
  493. for (const cl of list) {
  494. if (cl.spamount) {
  495. spamount = this.ctx.helper.add(spamount, cl.spamount);
  496. unitPrice = cl.unit_price;
  497. if (cl.is_valuation) {
  498. valuation_amount = this.ctx.helper.add(valuation_amount, cl.spamount);
  499. } else {
  500. unvaluation_amount = this.ctx.helper.add(unvaluation_amount, cl.spamount);
  501. }
  502. const posOrNePrice = this.ctx.helper.mul(cl.spamount, this.ctx.helper.round(cl.unit_price, up_decimal), tp_decimal);
  503. if (posOrNePrice >= 0) {
  504. positive_tp = this.ctx.helper.add(positive_tp, posOrNePrice);
  505. } else {
  506. negative_tp = this.ctx.helper.add(negative_tp, posOrNePrice);
  507. }
  508. }
  509. }
  510. const price = this.ctx.helper.mul(spamount, this.ctx.helper.round(unitPrice, up_decimal), tp_decimal);
  511. const valuation_price = this.ctx.helper.mul(valuation_amount, this.ctx.helper.round(unitPrice, up_decimal), tp_decimal) || 0;
  512. const unvaluation_price = this.ctx.helper.mul(unvaluation_amount, this.ctx.helper.round(unitPrice, up_decimal), tp_decimal) || 0;
  513. valuation_tp = this.ctx.helper.add(valuation_tp, valuation_price);
  514. unvaluation_tp = this.ctx.helper.add(unvaluation_tp, unvaluation_price);
  515. total_price = this.ctx.helper.add(total_price, price);
  516. // if (price >= 0) {
  517. // positive_tp = this.ctx.helper.accAdd(positive_tp, price);
  518. // } else {
  519. // negative_tp = this.ctx.helper.accAdd(negative_tp, price);
  520. // }
  521. } else {
  522. const list = this._.filter(changeList, { gcl_id: g });
  523. for (const cl of list) {
  524. const price = this.ctx.helper.mul(this.ctx.helper.round(cl.unit_price, up_decimal), cl.spamount, tp_decimal);
  525. total_price = this.ctx.helper.add(total_price, price);
  526. if (price >= 0) {
  527. positive_tp = this.ctx.helper.add(positive_tp, price);
  528. } else {
  529. negative_tp = this.ctx.helper.add(negative_tp, price);
  530. }
  531. if (cl.is_valuation) {
  532. valuation_tp = this.ctx.helper.add(valuation_tp, price);
  533. } else {
  534. unvaluation_tp = this.ctx.helper.add(unvaluation_tp, price);
  535. }
  536. }
  537. }
  538. }
  539. const updateData = {
  540. total_price,
  541. positive_tp,
  542. negative_tp,
  543. valuation_tp,
  544. unvaluation_tp,
  545. };
  546. if (updateTpDecimal) {
  547. updateData.tp_decimal = tp_decimal;
  548. updateData.up_decimal = up_decimal;
  549. }
  550. const options = {
  551. where: {
  552. cid: change.cid,
  553. },
  554. };
  555. await transaction.update(this.ctx.service.change.tableName, updateData, options);
  556. }
  557. /**
  558. * 用户数据数量提交
  559. * @param {Object} data 内容
  560. * @return {void}
  561. */
  562. async saveAmountData(data) {
  563. if (!this.ctx.tender || !this.ctx.change) {
  564. throw '数据错误';
  565. }
  566. // 判断是否可修改
  567. // 判断t_type是否为费用
  568. const transaction = await this.db.beginTransaction();
  569. try {
  570. await transaction.update(this.tableName, data);
  571. await this.calcCamountSum(transaction);
  572. await transaction.commit();
  573. return true;
  574. } catch (err) {
  575. await transaction.rollback();
  576. throw err;
  577. }
  578. }
  579. async gatherBgBills(tid) {
  580. const sql = 'SELECT cb.code, cb.name, cb.unit, cb.unit_price, Round(Sum(cb.samount + 0), 6) as quantity' +
  581. ' FROM ' + this.tableName + ' cb' +
  582. ' LEFT JOIN ' + this.ctx.service.change.tableName + ' c ON cb.cid = c.cid' +
  583. ' WHERE cb.tid = ? and c.status = ?' +
  584. ' GROUP BY code, name, unit, unit_price';
  585. const param = [tid, audit.flow.status.checked];
  586. const result = await this.db.query(sql, param);
  587. for (const b of result) {
  588. b.total_price = this.ctx.helper.mul(b.unit_price, b.quantity, this.ctx.tender.info.decimal.tp);
  589. }
  590. return result;
  591. }
  592. /**
  593. * 报表用
  594. * Tony Kang
  595. * @param {tid} tid - 标段id
  596. * @return {void}
  597. */
  598. async getChangeAuditBills(tid, onlyChecked) {
  599. const sql = 'SELECT cb.*' +
  600. ' FROM ' + this.tableName + ' cb' +
  601. ' LEFT JOIN ' + this.ctx.service.change.tableName + ' c ON cb.cid = c.cid' +
  602. ' WHERE c.tid = ? ' + (onlyChecked ? 'and c.status = 3' : '') +
  603. ' ORDER BY cb.cid, cb.code';
  604. const param = [tid];
  605. const result = await this.db.query(sql, param);
  606. return result;
  607. }
  608. /**
  609. * 删除变更清单(form 变更新增部位页)
  610. * Tony Kang
  611. * @param {String} transaction - 队列
  612. * @param {String} tid - 标段id
  613. * @param {Array} ids - id列表
  614. * @param {String} column - id所属字段
  615. * @param {String} mx_id - mx_id为空列删除
  616. * @return {void}
  617. */
  618. async deleteDataByRevise(transaction, tid, ids, column = 'gcl_id', mx_id = 'hello') {
  619. if (ids.length > 0) {
  620. const addSql = mx_id === '' ? ' AND (`mx_id` is NULL OR `mx_id` = "")' : '';
  621. const sql = 'SELECT `cid` FROM ?? WHERE `tid` = ? AND ' + column + ' in (' + this.ctx.helper.getInArrStrSqlFilter(ids) + ')' + addSql + ' GROUP BY `cid`';
  622. const params = [this.tableName, tid];
  623. const changes = await transaction.query(sql, params);
  624. if (changes.length > 0) {
  625. const delData = {
  626. tid,
  627. };
  628. delData[column] = ids;
  629. await transaction.delete(this.tableName, delData);
  630. for (const c of changes) {
  631. // 重算选了此清单的变更令已变更金额
  632. await this.calcCamountSum(transaction, false, c);
  633. }
  634. }
  635. }
  636. }
  637. /**
  638. * 修改变更清单(form 变更新增部位页台账子节点清单编号编辑)
  639. * Tony Kang
  640. * @param {String} transaction - 队列
  641. * @param {String} tid - 标段id
  642. * @param {Array} datas - 更新列表
  643. * @param {String} column - id所属字段
  644. * @return {void}
  645. */
  646. async updateDataByReviseLedger(transaction, tid, datas, column = 'gcl_id') {
  647. if (datas.length > 0) {
  648. const ids = this._.map(datas, 'id');
  649. const sql = 'SELECT ' + column + ' FROM ?? WHERE `tid` = ? AND ' + column + ' in (' + this.ctx.helper.getInArrStrSqlFilter(ids) + ') GROUP BY ' + column;
  650. const params = [this.tableName, tid];
  651. const changeAuditLists = await transaction.query(sql, params);
  652. if (changeAuditLists.length > 0) {
  653. const updateArr = [];
  654. const cidList = [];
  655. for (const ca of changeAuditLists) {
  656. const d = this._.find(datas, { id: ca[column] });
  657. if (d.id) {
  658. const changePosNum = await transaction.count(this.ctx.service.changePos.tableName, { lid: d.id });
  659. const updateCol = {};
  660. if (column === 'gcl_id' && d.b_code) updateCol.code = d.b_code;
  661. if (column === 'gcl_id' && d.quantity !== undefined && changePosNum === 0) updateCol.oamount = d.quantity ? d.quantity : 0;
  662. if (column === 'gcl_id' && d.unit_price !== undefined) updateCol.unit_price = d.unit_price ? d.unit_price : 0;
  663. if (column === 'gcl_id' && d.unit !== undefined) updateCol.unit = d.unit;
  664. if (column === 'gcl_id' && d.name !== undefined) updateCol.name = d.name;
  665. if (d.b_code !== undefined && d.b_code === null) {
  666. // 清单升级成了项目节,故删除变更已有的此清单,并找出需要重新计算的变更令
  667. const sql = 'SELECT `cid` FROM ?? WHERE `tid` = ? AND ' + column + ' = ? GROUP BY `cid`';
  668. const params = [this.tableName, tid, d.id];
  669. const changes = await transaction.query(sql, params);
  670. for (const c of changes) {
  671. if (this._.indexOf(cidList, c.cid) === -1) {
  672. cidList.push(c.cid);
  673. }
  674. }
  675. const delData = {
  676. tid,
  677. };
  678. delData[column] = d.id;
  679. await transaction.delete(this.tableName, delData);
  680. } else {
  681. const options = {
  682. row: {},
  683. where: {},
  684. };
  685. options.row = updateCol;
  686. options.where[column] = d.id;
  687. if (!this._.isEmpty(options.row)) updateArr.push(options);
  688. if (updateCol.unit !== undefined || updateCol.unit_price !== undefined) {
  689. const sql = 'SELECT `cid` FROM ?? WHERE `tid` = ? AND ' + column + ' = ? GROUP BY `cid`';
  690. const params = [this.tableName, tid, d.id];
  691. const changes = await transaction.query(sql, params);
  692. for (const c of changes) {
  693. if (this._.indexOf(cidList, c.cid) === -1) {
  694. cidList.push(c.cid);
  695. }
  696. }
  697. }
  698. }
  699. }
  700. }
  701. if (updateArr.length > 0) await transaction.updateRows(this.tableName, updateArr);
  702. if (cidList.length > 0) {
  703. for (const c of cidList) {
  704. await this.calcCamountSum(transaction, false, c);
  705. }
  706. }
  707. }
  708. // 针对项目节更新可能对清单影响判断,修正变更清单项目节编号,细目,单位工程,分部分项工程数据
  709. for (const data of datas) {
  710. const select = await transaction.get(this.ctx.service.changeLedger.tableName, { id: data.id });
  711. if (select && select.is_leaf === 0) {
  712. const lists = await this.ctx.service.changeLedger.getDataByFullPath(this.ctx.service.changeLedger.tableName, tid, select.full_path + '%', transaction);
  713. const childLists = this._.filter(lists, { level: select.level + 1 }); // 细目or项目节编号更新
  714. if (childLists.length > 0) {
  715. const d = { xmj_code: '', xmj_jldy: '' };
  716. if (select.code !== null) {
  717. d.xmj_code = select.code;
  718. d.xmj_jldy = select.name;
  719. } else {
  720. // 再找出上一个项目节节点并更新
  721. this.newBills = false;
  722. const parents = await this.ctx.service.changeLedger.getDataByKid(tid, select.ledger_pid);
  723. d.xmj_code = parents.code;
  724. d.xmj_jldy = parents.name;
  725. }
  726. for (const cl of childLists) {
  727. await transaction.update(this.tableName, { xmj_code: d.xmj_code, xmj_jldy: d.xmj_jldy }, { where: { tid, gcl_id: cl.id } });
  728. }
  729. }
  730. if (select.code !== null && data.name !== undefined) { // 名称修改则可能影响几个数据
  731. const secondChildLists = this._.filter(lists, { level: select.level + 2 }); // 分项工程更新
  732. const thirdChildLists = this._.filter(lists, { level: select.level + 3 }); // 分部工程更新
  733. const fourthChildLists = this._.filter(lists, { level: select.level + 4 }); // 单位工程更新
  734. if (secondChildLists.length > 0) {
  735. for (const sl of secondChildLists) {
  736. await transaction.update(this.tableName, { xmj_fxgc: select.name }, { where: { tid, gcl_id: sl.id } });
  737. }
  738. }
  739. if (thirdChildLists.length > 0) {
  740. for (const tl of thirdChildLists) {
  741. await transaction.update(this.tableName, { xmj_fbgc: select.name }, { where: { tid, gcl_id: tl.id } });
  742. }
  743. }
  744. if (fourthChildLists.length > 0 && select.level === 2) {
  745. for (const fl of fourthChildLists) {
  746. await transaction.update(this.tableName, { xmj_dwgc: select.name }, { where: { tid, gcl_id: fl.id } });
  747. }
  748. }
  749. }
  750. }
  751. }
  752. }
  753. }
  754. /**
  755. * 修改变更清单(form 变更新增部位页台账节点清单编号升降级)
  756. * Tony Kang
  757. * @param {String} transaction - 队列
  758. * @param {String} tid - 标段id
  759. * @param {Array} datas - 更新列表
  760. * @param {String} column - id所属字段
  761. * @return {void}
  762. */
  763. async updateDataByReviseLedgerUpDownLevel(transaction, tid, datas, column = 'gcl_id') {
  764. if (datas.length > 0) {
  765. console.log(datas);
  766. // const ids = this._.map(datas, 'id');
  767. // const sql = 'SELECT ' + column + ' FROM ?? WHERE `tid` = ? AND ' + column + ' in (' + this.ctx.helper.getInArrStrSqlFilter(ids) + ') GROUP BY ' + column;
  768. // const params = [this.tableName, tid];
  769. // const changeAuditLists = await transaction.query(sql, params);
  770. // if (changeAuditLists.length > 0) {
  771. // const updateArr = [];
  772. // const cidList = [];
  773. // for (const ca of changeAuditLists) {
  774. // const d = this._.find(datas, { id: ca[column] });
  775. // console.log(d);
  776. // if (d.id) {
  777. // const changePosNum = await transaction.count(this.ctx.service.changePos.tableName, { lid: d.id });
  778. // const updateCol = {};
  779. // if (column === 'gcl_id' && d.b_code !== undefined) updateCol.code = d.b_code;
  780. // if (column === 'gcl_id' && d.sgfh_qty !== undefined && changePosNum === 0) updateCol.oamount = d.sgfh_qty ? d.sgfh_qty : 0;
  781. // if (column === 'gcl_id' && d.unit_price !== undefined) updateCol.unit_price = d.unit_price ? d.unit_price : 0;
  782. // if (column === 'gcl_id' && d.unit !== undefined) updateCol.unit = d.unit;
  783. // if (column === 'gcl_id' && d.name !== undefined) updateCol.name = d.name;
  784. // if (d.code !== undefined && d.b_code === null) {
  785. // // 清单升级成了项目节,故删除变更已有的此清单,并找出需要重新计算的变更令
  786. // const sql = 'SELECT `cid` FROM ?? WHERE `tid` = ? AND ' + column + ' = ? GROUP BY `cid`';
  787. // const params = [this.tableName, tid, d.id];
  788. // const changes = await transaction.query(sql, params);
  789. // for (const c of changes) {
  790. // if (this._.indexOf(cidList, c.cid) === -1) {
  791. // cidList.push(c.cid);
  792. // }
  793. // }
  794. // const delData = {
  795. // tid,
  796. // };
  797. // delData[column] = d.id;
  798. // console.log(delData);
  799. // await transaction.delete(this.tableName, delData);
  800. // } else {
  801. // const options = {
  802. // row: {},
  803. // where: {},
  804. // };
  805. // options.row = updateCol;
  806. // options.where[column] = d.id;
  807. // if (!this._.isEmpty(options.row)) updateArr.push(options);
  808. // if (updateCol.unit !== undefined || updateCol.unit_price !== undefined) {
  809. // const sql = 'SELECT `cid` FROM ?? WHERE `tid` = ? AND ' + column + ' = ? GROUP BY `cid`';
  810. // const params = [this.tableName, tid, d.id];
  811. // const changes = await transaction.query(sql, params);
  812. // for (const c of changes) {
  813. // if (this._.indexOf(cidList, c.cid) === -1) {
  814. // cidList.push(c.cid);
  815. // }
  816. // }
  817. // }
  818. // }
  819. // }
  820. // }
  821. // console.log(updateArr, cidList);
  822. // if (updateArr.length > 0) await transaction.updateRows(this.tableName, updateArr);
  823. // if (cidList.length > 0) {
  824. // for (const c of cidList) {
  825. // await this.reCalcTp(transaction, c);
  826. // }
  827. // }
  828. // }
  829. // 针对项目节更新可能对清单影响判断,修正变更清单项目节编号,细目,单位工程,分部分项工程数据
  830. // for (const data of datas) {
  831. // const select = await transaction.get(this.ctx.service.changeLedger.tableName, { id: data.id });
  832. // console.log(select);
  833. // if (select && select.is_leaf === 0) {
  834. // const lists = await this.ctx.service.changeLedger.getDataByFullPath(this.ctx.service.changeLedger.tableName, tid, select.full_path + '%', transaction);
  835. // const childLists = this._.filter(lists, { level: select.level + 1 }); // 细目or项目节编号更新
  836. // if (childLists.length > 0) {
  837. // const d = { xmj_code: '', xmj_jldy: '' };
  838. // if (select.code !== null) {
  839. // d.xmj_code = select.code;
  840. // d.xmj_jldy = select.name;
  841. // } else {
  842. // // 再找出上一个项目节节点并更新
  843. // this.newBills = false;
  844. // const parents = await this.ctx.service.changeLedger.getDataByKid(tid, select.ledger_pid);
  845. // console.log('hello :', parents);
  846. // d.xmj_code = parents.code;
  847. // d.xmj_jldy = parents.name;
  848. // }
  849. // for (const cl of childLists) {
  850. // await transaction.update(this.tableName, { xmj_code: d.xmj_code, xmj_jldy: d.xmj_jldy }, { where: { tid, gcl_id: cl.id } });
  851. // }
  852. // }
  853. // if (select.code !== null && data.name !== undefined) { // 名称修改则可能影响几个数据
  854. // const secondChildLists = this._.filter(lists, { level: select.level + 2 }); // 分项工程更新
  855. // const thirdChildLists = this._.filter(lists, { level: select.level + 3 }); // 分部工程更新
  856. // const fourthChildLists = this._.filter(lists, { level: select.level + 4 }); // 单位工程更新
  857. // if (secondChildLists.length > 0) {
  858. // for (const sl of secondChildLists) {
  859. // await transaction.update(this.tableName, { xmj_fxgc: select.name }, { where: { tid, gcl_id: sl.id } });
  860. // }
  861. // }
  862. // if (thirdChildLists.length > 0) {
  863. // for (const tl of thirdChildLists) {
  864. // await transaction.update(this.tableName, { xmj_fbgc: select.name }, { where: { tid, gcl_id: tl.id } });
  865. // }
  866. // }
  867. // if (fourthChildLists.length > 0) {
  868. // for (const fl of fourthChildLists) {
  869. // await transaction.update(this.tableName, { xmj_dwgc: select.name }, { where: { tid, gcl_id: fl.id } });
  870. // }
  871. // }
  872. // }
  873. // }
  874. // }
  875. }
  876. }
  877. /**
  878. * 修改变更清单(form 变更新增部位页计量单元编辑)
  879. * Tony Kang
  880. * @param {String} transaction - 队列
  881. * @param {String} tid - 标段id
  882. * @param {Array} datas - 更新列表
  883. * @param {String} column - id所属字段
  884. * @return {void}
  885. */
  886. async updateDataByRevisePos(transaction, tid, datas, column = 'mx_id') {
  887. if (datas.length > 0) {
  888. const ids = this._.map(datas, 'id');
  889. const sql = 'SELECT ' + column + ' FROM ?? WHERE `tid` = ? AND ' + column + ' in (' + this.ctx.helper.getInArrStrSqlFilter(ids) + ') GROUP BY ' + column;
  890. const params = [this.tableName, tid];
  891. const changeAuditLists = await transaction.query(sql, params);
  892. if (changeAuditLists.length > 0) {
  893. const updateArr = [];
  894. for (const ca of changeAuditLists) {
  895. const d = this._.find(datas, { id: ca[column] });
  896. if (d.id) {
  897. const updateCol = {};
  898. if (column === 'mx_id' && d.name !== undefined) updateCol.bwmx = d.name;
  899. if (column === 'mx_id' && d.quantity !== undefined) updateCol.oamount = d.quantity ? d.quantity : 0;
  900. if (column === 'mx_id' && d.quantity === undefined &&
  901. ((d.sgfh_expr && d.sgfh_expr === '') || (d.sjcl_expr && d.sjcl_expr === '') || (d.qtcl_expr && d.qtcl_expr === ''))) updateCol.oamount = 0;
  902. const options = {
  903. row: {},
  904. where: {},
  905. };
  906. options.row = updateCol;
  907. options.where[column] = d.id;
  908. // if (!this._.isEmpty(updateCol)) await transaction.update(this.tableName, updateCol, options);
  909. if (!this._.isEmpty(options.row)) updateArr.push(options);
  910. }
  911. }
  912. if (updateArr.length > 0) await transaction.updateRows(this.tableName, updateArr);
  913. }
  914. }
  915. }
  916. /**
  917. * 重算变更令总金额(变更新增部位设置时使用)
  918. * @param {String} transaction - 队列
  919. * @param {String} cid - 变更令id
  920. */
  921. async reCalcTp(transaction, cid) {
  922. const change = await transaction.get(this.ctx.service.change.tableName, { cid });
  923. let count = '';
  924. if (change.status === audit.change.status.uncheck || change.status === audit.change.status.checkNo || change.status === audit.change.status.revise) {
  925. count = '`camount`';
  926. } else if (change.status === audit.change.status.checking || change.status === audit.change.status.checkNoPre) {
  927. count = '`spamount`';
  928. }
  929. if (count) {
  930. const sql = 'SELECT `unit_price`, ' + count + ' as `count` FROM ?? WHERE `cid` = ?';
  931. const params = [this.tableName, change.cid];
  932. const caLists = await transaction.query(sql, params);
  933. let tp = 0;
  934. const tpUnit = change.tp_decimal ? change.tp_decimal : this.ctx.tender.info.decimal.tp;
  935. for (const ca of caLists) {
  936. const catp = this.ctx.helper.round(this.ctx.helper.mul(ca.unit_price, ca.count), tpUnit);
  937. tp = this.ctx.helper.add(tp, catp);
  938. }
  939. console.log(tp);
  940. if (tp !== change.total_price) {
  941. const options = {
  942. where: {
  943. cid: change.cid,
  944. },
  945. };
  946. const change_update = {
  947. total_price: tp,
  948. };
  949. await transaction.update(this.ctx.service.change.tableName, change_update, options);
  950. }
  951. }
  952. }
  953. async updateToLedger(transaction, tid, cid) {
  954. // 找出本条变更属于新增部位的数据
  955. const allList = await transaction.select(this.tableName, { where: { tid, cid } });
  956. const result = [];
  957. const result2 = [];
  958. for (const l of allList) {
  959. const changeLedgerInfo = await transaction.get(this.ctx.service.changeLedger.tableName, { id: l.gcl_id });
  960. if (changeLedgerInfo && this._.findIndex(result, { id: l.gcl_id }) === -1) {
  961. result.push(changeLedgerInfo);
  962. }
  963. const changePosInfo = await transaction.get(this.ctx.service.changePos.tableName, { id: l.mx_id });
  964. if (changePosInfo) {
  965. result2.push(changePosInfo);
  966. }
  967. }
  968. // const sql = 'SELECT a.* FROM ?? a LEFT JOIN ?? b ON a.id = b.gcl_id WHERE b.tid = ? AND b.cid = ? GROUP BY a.id';
  969. // const sqlParam = [this.ctx.service.changeLedger.tableName, this.tableName, tid, cid];
  970. // const result = await transaction.query(sql, sqlParam);
  971. // const sql2 = 'SELECT a.* FROM ?? a LEFT JOIN ?? b ON a.id = b.mx_id WHERE b.tid = ? AND b.cid = ?';
  972. // const sqlParam2 = [this.ctx.service.changePos.tableName, this.tableName, tid, cid];
  973. // const result2 = await transaction.query(sql2, sqlParam2);
  974. if (result.length > 0 || result2.length > 0) {
  975. const changeLedgerGclIdList = this._.map(result, 'id');
  976. const changeLedgerIdList = this._.uniq(this._.map(result, 'ledger_pid'));// 父节点集合
  977. const needUpdateLedgerList = [];// 找出需要更新的原台账清单的id
  978. const needUpdateChangeLedgerList = [];// 找出需要更新的新台账清单的id
  979. const tpDecimal = this.ctx.tender.info.decimal.tp;
  980. // 要更新的ledger节点,数量及总数
  981. for (const data of result2) {
  982. if (this._.indexOf(changeLedgerGclIdList, data.lid) === -1) {
  983. const info = this._.find(needUpdateLedgerList, { id: data.lid });
  984. if (info) {
  985. info.sgfh_qty = this.ctx.helper.add(info.sgfh_qty, data.sgfh_qty);
  986. info.sjcl_qty = this.ctx.helper.add(info.sjcl_qty, data.sjcl_qty);
  987. info.qtcl_qty = this.ctx.helper.add(info.qtcl_qty, data.qtcl_qty);
  988. info.quantity = this.ctx.helper.add(info.quantity, data.quantity);
  989. info.ex_qty1 = this.ctx.helper.add(info.ex_qty1, data.ex_qty1);
  990. } else {
  991. needUpdateLedgerList.push({ id: data.lid, sgfh_qty: data.sgfh_qty, sjcl_qty: data.sjcl_qty, qtcl_qty: data.qtcl_qty, quantity: data.quantity, ex_qty1: data.ex_qty1 });
  992. }
  993. } else {
  994. const info = this._.find(needUpdateChangeLedgerList, { id: data.lid });
  995. if (info) {
  996. info.sgfh_qty = this.ctx.helper.add(info.sgfh_qty, data.sgfh_qty);
  997. info.sjcl_qty = this.ctx.helper.add(info.sjcl_qty, data.sjcl_qty);
  998. info.qtcl_qty = this.ctx.helper.add(info.qtcl_qty, data.qtcl_qty);
  999. info.quantity = this.ctx.helper.add(info.quantity, data.quantity);
  1000. info.ex_qty1 = this.ctx.helper.add(info.ex_qty1, data.ex_qty1);
  1001. } else {
  1002. needUpdateChangeLedgerList.push({ id: data.lid, sgfh_qty: data.sgfh_qty, sjcl_qty: data.sjcl_qty, qtcl_qty: data.qtcl_qty, quantity: data.quantity, ex_qty1: data.ex_qty1 });
  1003. }
  1004. }
  1005. }
  1006. // 更新到result上
  1007. if (needUpdateChangeLedgerList.length > 0) {
  1008. for (const nucl of needUpdateChangeLedgerList) {
  1009. const now = this._.find(result, { id: nucl.id });
  1010. now.sgfh_qty = nucl.sgfh_qty;
  1011. now.sjcl_qty = nucl.sjcl_qty;
  1012. now.qtcl_qty = nucl.qtcl_qty;
  1013. now.quantity = nucl.quantity;
  1014. now.sgfh_tp = this.ctx.helper.mul(now.sgfh_qty, now.unit_price, tpDecimal);
  1015. now.sjcl_tp = this.ctx.helper.mul(now.sjcl_qty, now.unit_price, tpDecimal);
  1016. now.qtcl_tp = this.ctx.helper.mul(now.qtcl_qty, now.unit_price, tpDecimal);
  1017. now.total_price = this.ctx.helper.mul(now.quantity, now.unit_price, tpDecimal);
  1018. now.ex_qty1 = nucl.ex_qty1;
  1019. now.ex_tp1 = this.ctx.helper.mul(now.ex_qty1, now.unit_price, tpDecimal);
  1020. }
  1021. }
  1022. // 更新到ledger上
  1023. if (needUpdateLedgerList.length > 0) {
  1024. for (const nul of needUpdateLedgerList) {
  1025. const ledgerInfo = await this.ctx.service.ledger.getDataById(nul.id);
  1026. ledgerInfo.sgfh_qty = this.ctx.helper.add(ledgerInfo.sgfh_qty, nul.sgfh_qty);
  1027. ledgerInfo.sjcl_qty = this.ctx.helper.add(ledgerInfo.sjcl_qty, nul.sjcl_qty);
  1028. ledgerInfo.qtcl_qty = this.ctx.helper.add(ledgerInfo.qtcl_qty, nul.qtcl_qty);
  1029. ledgerInfo.quantity = this.ctx.helper.add(ledgerInfo.quantity, nul.quantity);
  1030. ledgerInfo.sgfh_tp = this.ctx.helper.mul(ledgerInfo.sgfh_qty, ledgerInfo.unit_price, tpDecimal);
  1031. ledgerInfo.sjcl_tp = this.ctx.helper.mul(ledgerInfo.sjcl_qty, ledgerInfo.unit_price, tpDecimal);
  1032. ledgerInfo.qtcl_tp = this.ctx.helper.mul(ledgerInfo.qtcl_qty, ledgerInfo.unit_price, tpDecimal);
  1033. ledgerInfo.total_price = this.ctx.helper.mul(ledgerInfo.quantity, ledgerInfo.unit_price, tpDecimal);
  1034. ledgerInfo.ex_qty1 = this.ctx.helper.add(ledgerInfo.ex_qty1, nul.ex_qty1);
  1035. ledgerInfo.ex_tp1 = this.ctx.helper.mul(ledgerInfo.ex_qty1, ledgerInfo.unit_price, tpDecimal);
  1036. await transaction.update(this.ctx.service.ledger.tableName, ledgerInfo);
  1037. }
  1038. }
  1039. // 找出所有新增的父节点并插入到result中
  1040. for (const r of changeLedgerIdList) {
  1041. await this._findParents(transaction, tid, r, result);
  1042. }
  1043. // 插入到计量单元表,并删除变更的计量单元数据, 插入清单表,并删除变更的清单表
  1044. await this._insertByChangeRevise(transaction, tid, cid, result, result2);
  1045. // 更新标段总金额
  1046. const sumSql = 'SELECT Sum(total_price) As total_price, Sum(deal_tp) As deal_tp' +
  1047. ' FROM ' + this.ctx.service.ledger.tableName + this.ctx.helper.whereSql({ tender_id: tid });
  1048. const sum = await transaction.queryOne(sumSql);
  1049. await transaction.update(this.ctx.service.tender.tableName, {
  1050. id: tid,
  1051. total_price: sum.total_price,
  1052. deal_tp: sum.deal_tp,
  1053. });
  1054. // 清除修订及台账的maxLid缓存,防止树结构混乱
  1055. await this.ctx.service.reviseBills._removeCacheMaxLid(tid);
  1056. await this.ctx.service.ledger._removeCacheMaxLid(tid);
  1057. }
  1058. }
  1059. async _findParents(transaction, tid, id, result) {
  1060. const info = await transaction.get(this.ctx.service.changeLedger.tableName, { tender_id: tid, ledger_id: id });
  1061. if (info && this._.findIndex(result, { ledger_id: info.ledger_id }) === -1) {
  1062. result.push(info);
  1063. await this._findParents(transaction, tid, info.ledger_pid, result);
  1064. } else {
  1065. return;
  1066. }
  1067. }
  1068. async _insertByChangeRevise(transaction, tid, cid, ledgerList, posList) {
  1069. if (ledgerList.length > 0) {
  1070. const insertLedgerArr = [];
  1071. for (const l of ledgerList) {
  1072. const insertL = [
  1073. l.id, l.code, l.b_code, l.name, l.unit, l.source, l.remark, l.ledger_id,
  1074. l.ledger_pid, l.level, l.order, l.full_path, l.is_leaf, l.quantity, l.total_price,
  1075. l.unit_price, l.drawing_code, l.memo, l.features, l.dgn_qty1, l.dgn_qty2, l.deal_qty, l.deal_tp,
  1076. l.sgfh_qty, l.sgfh_tp, l.sjcl_qty, l.sjcl_tp, l.qtcl_qty, l.qtcl_tp, l.node_type, l.crid, l.ccid,
  1077. l.tender_id, l.sgfh_expr, l.sjcl_expr, l.qtcl_expr, l.check_calc,
  1078. l.ex_memo1, l.ex_memo2, l.ex_memo3,
  1079. l.ex_qty1, l.ex_tp1,
  1080. ];
  1081. insertLedgerArr.push('(' + this.ctx.helper.getInArrStrSqlFilter(insertL) + ')');
  1082. await transaction.delete(this.ctx.service.changeLedger.tableName, { id: l.id });
  1083. // 日志添加
  1084. await transaction.insert(this.ctx.service.changeReviseLog.tableName, { tid, cid, lid: l.id, name: l.name ? l.name : (l.code ? l.code : ''), create_time: new Date() });
  1085. }
  1086. const bSql = 'Insert Into ' +
  1087. this.ctx.service.ledger.tableName +
  1088. ' (id, code, b_code, name, unit, source, remark, ledger_id, ledger_pid, level, `order`, full_path, is_leaf,' +
  1089. ' quantity, total_price, unit_price, drawing_code, memo, features, dgn_qty1, dgn_qty2, deal_qty, deal_tp,' +
  1090. ' sgfh_qty, sgfh_tp, sjcl_qty, sjcl_tp, qtcl_qty, qtcl_tp, node_type, crid, ccid, tender_id,' +
  1091. ' sgfh_expr, sjcl_expr, qtcl_expr, check_calc,' +
  1092. ' ex_memo1, ex_memo2, ex_memo3, ex_qty1, ex_tp1) VALUES ' + insertLedgerArr.join(',') + ';';
  1093. await transaction.query(bSql, []);
  1094. }
  1095. if (posList.length > 0) {
  1096. const insertPosArr = [];
  1097. for (const p of posList) {
  1098. const insertp = [
  1099. p.id, p.tid, p.lid, p.name, p.drawing_code, p.quantity, p.add_stage, p.add_stage_order, p.add_times,
  1100. p.add_user, p.sgfh_qty, p.sjcl_qty, p.qtcl_qty, p.crid, p.ccid, p.porder, p.position,
  1101. p.sgfh_expr, p.sjcl_expr, p.qtcl_expr, p.real_qty,
  1102. p.ex_memo1, p.ex_memo2, p.ex_memo3, p.ex_qty1,
  1103. ];
  1104. insertPosArr.push('(' + this.ctx.helper.getInArrStrSqlFilter(insertp) + ')');
  1105. await transaction.delete(this.ctx.service.changePos.tableName, { id: p.id });
  1106. // 日志添加
  1107. await transaction.insert(this.ctx.service.changeReviseLog.tableName, { tid, cid, pid: p.id, name: p.name, create_time: new Date() });
  1108. }
  1109. const pSql =
  1110. 'Insert Into ' +
  1111. this.ctx.service.pos.tableName +
  1112. ' (id, tid, lid, name, drawing_code, quantity, add_stage, add_stage_order, add_times, add_user,' +
  1113. ' sgfh_qty, sjcl_qty, qtcl_qty, crid, ccid, porder, position, ' +
  1114. ' sgfh_expr, sjcl_expr, qtcl_expr, real_qty,' +
  1115. ' ex_memo1, ex_memo2, ex_memo3, ex_qty1) VALUES ' + insertPosArr.join(',') + ';';
  1116. await transaction.query(pSql, []);
  1117. }
  1118. }
  1119. async checkedChangeBills(tid) {
  1120. const DefaultDecimal = this.ctx.tender.info.decimal.tp;
  1121. const sql = 'SELECT cal.*, c.tp_decimal FROM ' + this.ctx.service.changeAuditList.tableName + ' cal LEFT JOIN ' + this.ctx.service.change.tableName + ' c on cal.cid = c.cid where c.tid = ? and c.valid and c.status = ?';
  1122. const changeBills = await this.db.query(sql, [tid, audit.flow.status.checked]);
  1123. changeBills.forEach(x => {
  1124. x.tp_decimal = x.tp_decimal !== 0 ? x.tp_decimal : DefaultDecimal
  1125. });
  1126. return changeBills;
  1127. }
  1128. /**
  1129. * 交换两个清单的顺序
  1130. * @param {Number} id1 - 工料1的id
  1131. * @param {Number} id2 - 工料2的id
  1132. * @returns {Promise<void>}
  1133. */
  1134. async changeOrder(datas) {
  1135. if (!this.ctx.tender || !this.ctx.change) {
  1136. throw '数据错误';
  1137. }
  1138. // const bill1 = await this.getDataByCondition({ tid: this.ctx.tender.id, id: id1 });
  1139. // const bill2 = await this.getDataByCondition({ tid: this.ctx.tender.id, id: id2 });
  1140. // if (!bill1 || !bill2) {
  1141. // throw '数据错误';
  1142. // }
  1143. const transaction = await this.db.beginTransaction();
  1144. try {
  1145. // const order = bill1.order;
  1146. // bill1.order = bill2.order;
  1147. // bill2.order = order;
  1148. // await transaction.update(this.tableName, { id: bill1.id, order: bill1.order });
  1149. // await transaction.update(this.tableName, { id: bill2.id, order: bill2.order });
  1150. await transaction.updateRows(this.tableName, datas);
  1151. await transaction.commit();
  1152. return true;
  1153. } catch (err) {
  1154. await transaction.rollback();
  1155. throw err;
  1156. }
  1157. }
  1158. async setAllValuation(cid, ids, is_valuation) {
  1159. return await this.db.update(this.tableName, { is_valuation }, {
  1160. where: {
  1161. cid,
  1162. id: ids,
  1163. },
  1164. });
  1165. }
  1166. async getBillsSum(tid) {
  1167. const sql = 'SELECT gcl_id, Sum(qc_qty) AS qc_qty, Sum(qc_tp) AS qc_tp, Sum(qc_minus_qty) AS qc_minus_qty, Sum(qc_minus_tp) AS qc_minus_tp' +
  1168. ' FROM(' +
  1169. ' SELECT cal.gcl_id, Sum(cal.checked_amount) AS qc_qty, Sum(cal.checked_price) AS qc_tp, 0 As qc_minus_qty, 0 As qc_minus_tp' +
  1170. ` FROM ${this.tableName} cal LEFT JOIN ${this.ctx.service.change.tableName} c ON cal.cid = c.cid` +
  1171. ' WHERE c.tid = ? AND c.valid AND c.status = ? AND cal.is_valuation' +
  1172. ' GROUP BY cal.gcl_id' +
  1173. ' UNION ALL ' +
  1174. ' SELECT cal.gcl_id, 0 As qc_qty, 0 As qc_tp, Sum(cal.checked_amount) AS qc_minus_qty, Sum(cal.checked_price) AS qc_minus_tp' +
  1175. ` FROM ${this.tableName} cal LEFT JOIN ${this.ctx.service.change.tableName} c ON cal.cid = c.cid` +
  1176. ' WHERE c.tid = ? AND c.valid AND c.status = ? AND not cal.is_valuation' +
  1177. ' GROUP BY cal.gcl_id) As TEMP' +
  1178. ' GROUP BY gcl_id';
  1179. return await this.db.query(sql, [tid, audit.flow.status.checked, tid, audit.flow.status.checked]);
  1180. }
  1181. async getPosSum(tid) {
  1182. const sql = 'SELECT mx_id, Sum(qc_qty) AS qc_qty, Sum(qc_minus_qty) AS qc_minus_qty' +
  1183. ' FROM(' +
  1184. ' SELECT cal.mx_id, Sum(cal.checked_amount) AS qc_qty, 0 As qc_minus_qty' +
  1185. ` FROM ${this.tableName} cal LEFT JOIN ${this.ctx.service.change.tableName} c ON cal.cid = c.cid` +
  1186. ' WHERE c.tid = ? AND c.valid AND c.status = ? AND cal.is_valuation' +
  1187. ' GROUP BY cal.mx_id' +
  1188. ' UNION ALL ' +
  1189. ' SELECT cal.mx_id, 0 As qc_qty, Sum(cal.checked_amount) AS qc_minus_qty' +
  1190. ` FROM ${this.tableName} cal LEFT JOIN ${this.ctx.service.change.tableName} c ON cal.cid = c.cid` +
  1191. ' WHERE c.tid = ? AND c.valid AND c.status = ? AND not cal.is_valuation' +
  1192. ' GROUP BY cal.mx_id) As TEMP' +
  1193. ' GROUP BY mx_id';
  1194. return await this.db.query(sql, [tid, audit.flow.status.checked, tid, audit.flow.status.checked]);
  1195. }
  1196. }
  1197. return ChangeAuditList;
  1198. };