material_list.js 54 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048
  1. 'use strict';
  2. /**
  3. * 调差清单关联工料表 数据模型
  4. *
  5. * @author Mai
  6. * @date 2018/8/13
  7. * @version
  8. */
  9. const auditConst = require('../const/audit').material;
  10. module.exports = app => {
  11. class MaterialList extends app.BaseService {
  12. /**
  13. * 构造函数
  14. *
  15. * @param {Object} ctx - egg全局变量
  16. * @return {void}
  17. */
  18. constructor(ctx) {
  19. super(ctx);
  20. this.tableName = 'material_list';
  21. }
  22. /**
  23. * 添加工料清单关联
  24. * @return {void}
  25. */
  26. async add(data, ms_id = null) {
  27. if (!this.ctx.tender || !this.ctx.material) {
  28. throw '数据错误';
  29. }
  30. const list = [];
  31. for (const mb of data.mb_id) {
  32. const newLists = {
  33. tid: this.ctx.tender.id,
  34. order: this.ctx.material.order,
  35. mid: this.ctx.material.id,
  36. mb_id: mb,
  37. gcl_id: data.gcl_id,
  38. xmj_id: data.xmj_id,
  39. mx_id: data.mx_id,
  40. contract_qty: data.contract_qty,
  41. qc_qty: data.qc_qty,
  42. qc_minus_qty: data.qc_minus_qty,
  43. gather_qty: data.gather_qty,
  44. qty: data.qty || null,
  45. is_join: data.is_join,
  46. is_self: 1,
  47. ms_id: ms_id ? ms_id : null,
  48. in_time: new Date(),
  49. };
  50. list.push(newLists);
  51. }
  52. // 新增工料
  53. const result = await this.db.insert(this.tableName, list);
  54. if (result.affectedRows === 0) {
  55. throw '新增工料数据失败';
  56. }
  57. return await this.getMaterialData(this.ctx.tender.id, this.ctx.material.id);
  58. }
  59. /**
  60. * 删除工料清单关联
  61. * @param {int} id 工料id
  62. * @return {void}
  63. */
  64. async del(id, mb_id, ms_id = null) {
  65. if (!this.ctx.tender || !this.ctx.material) {
  66. throw '数据错误';
  67. }
  68. const transaction = await this.db.beginTransaction();
  69. try {
  70. // 判断是否可删
  71. await transaction.delete(this.tableName, { id });
  72. await this.calcQuantityByML(transaction, mb_id, ms_id);
  73. await transaction.commit();
  74. return true;
  75. } catch (err) {
  76. await transaction.rollback();
  77. throw err;
  78. }
  79. }
  80. /**
  81. * 修改工料清单关联信息
  82. * @param {Object} data 工料内容
  83. * @param {int} order 期数
  84. * @return {void}
  85. */
  86. async save(data, ms_id = null) {
  87. if (!this.ctx.tender || !this.ctx.material) {
  88. throw '数据错误';
  89. }
  90. const transaction = await this.db.beginTransaction();
  91. try {
  92. const mb_id = data.mb_id;
  93. delete data.mb_id;
  94. await transaction.update(this.tableName, data);
  95. await this.calcQuantityByML(transaction, mb_id, ms_id);
  96. await transaction.commit();
  97. return true;
  98. } catch (err) {
  99. await transaction.rollback();
  100. throw err;
  101. }
  102. }
  103. /**
  104. * 修改工料信息
  105. * @param {Object} data 工料内容
  106. * @return {void}
  107. */
  108. async saveDatas(datas, ms_id = null) {
  109. if (!this.ctx.tender || !this.ctx.material) {
  110. throw '数据错误';
  111. }
  112. // 判断是否可修改
  113. // 判断t_type是否为费用
  114. const transaction = await this.db.beginTransaction();
  115. try {
  116. for (const data of datas) {
  117. const mb_id = data.mb_id;
  118. delete data.mb_id;
  119. await transaction.update(this.tableName, data);
  120. await this.calcQuantityByML(transaction, mb_id, ms_id);
  121. }
  122. await transaction.commit();
  123. return true;
  124. } catch (err) {
  125. await transaction.rollback();
  126. throw err;
  127. }
  128. }
  129. /**
  130. * 应用工料清单到其它清单中
  131. * @return {void}
  132. */
  133. async addOther(data) {
  134. if (!this.ctx.tender || !this.ctx.material) {
  135. throw '数据错误';
  136. }
  137. const transaction = await this.db.beginTransaction();
  138. try {
  139. // 先删除addxmj里所有的清单工料再添加新工料,并重新计算每个工料的单价数量
  140. // 还要找出删除的工料,更新单价数量
  141. const list = [];
  142. const delList = [];
  143. const materialBills = data.materialBills;
  144. const mb_idList = [];
  145. for (const xmj of data.addXmj) {
  146. const mlList = await this.getAllDataByCondition({
  147. where: {
  148. mid: this.ctx.material.id,
  149. gcl_id: xmj.gcl_id,
  150. xmj_id: xmj.id,
  151. mx_id: xmj.mx_id,
  152. },
  153. });
  154. const mbIdList = this._.map(mlList, 'mb_id');
  155. mb_idList.push(...mbIdList);
  156. delList.push(...this._.map(mlList, 'id'));
  157. for (const mb of materialBills) {
  158. const newLists = {
  159. tid: this.ctx.tender.id,
  160. order: mb.order,
  161. mid: this.ctx.material.id,
  162. mb_id: mb.mb_id,
  163. gcl_id: xmj.gcl_id,
  164. xmj_id: xmj.id,
  165. mx_id: xmj.mx_id,
  166. gather_qty: xmj.gather_qty ? xmj.gather_qty : null,
  167. quantity: mb.quantity,
  168. expr: mb.expr,
  169. in_time: new Date(),
  170. };
  171. list.push(newLists);
  172. mb_idList.push(mb.mb_id);
  173. }
  174. }
  175. // 删除工料清单关联
  176. if (delList.length > 0) await transaction.delete(this.tableName, { id: delList });
  177. // 新增工料清单关联
  178. if (list.length > 0) {
  179. const result = await transaction.insert(this.tableName, list);
  180. if (result.affectedRows === 0) {
  181. throw '新增工料数据失败';
  182. }
  183. }
  184. // 重算工料和总金额
  185. const calcMBIdList = this._.uniq(mb_idList);
  186. if (calcMBIdList.length > 0) {
  187. for (const select of calcMBIdList) {
  188. await this.calcQuantityByML(transaction, select);
  189. }
  190. }
  191. // throw 'fail';
  192. // await this.calcQuantityByML(transaction, select.mb_id);
  193. await transaction.commit();
  194. return await this.getMaterialData(this.ctx.tender.id, this.ctx.material.id);
  195. } catch (err) {
  196. await transaction.rollback();
  197. throw err;
  198. }
  199. }
  200. /**
  201. * 修改material_bills的quantity值和计算本期金额
  202. * @param transaction
  203. * @param mb_id
  204. * @return {Promise<*>}
  205. */
  206. async calcQuantityByML(transaction, mb_id, ms_id = null, updateAllStage = '') {
  207. // 修改material_bills值
  208. const mbInfo = await this.ctx.service.materialBills.getDataById(mb_id);
  209. if (!mbInfo) {
  210. throw '不存在该工料';
  211. }
  212. let m_spread = mbInfo.m_spread;
  213. let updateId = mb_id;
  214. if (ms_id) {
  215. const msbInfo = await this.ctx.service.materialStageBills.getDataByCondition({ mid: this.ctx.material.id, mb_id, ms_id });
  216. m_spread = msbInfo.m_spread;
  217. updateId = msbInfo.id;
  218. }
  219. const newQuantity = await this.getMbQuantity(transaction, this.ctx.material.id, this.ctx.material.qty_source, this.ctx.material.decimal.qty, mb_id, ms_id);
  220. const newTp = this.ctx.helper.round(this.ctx.helper.mul(newQuantity, m_spread), this.ctx.material.decimal.tp);
  221. const updateData = {
  222. id: updateId,
  223. quantity: newQuantity,
  224. m_tp: newTp,
  225. m_tax_tp: this.ctx.helper.round(this.ctx.helper.mul(newTp, (1 + this.ctx.helper.div(mbInfo.m_tax, 100))), this.ctx.material.decimal.tp),
  226. };
  227. if (ms_id) {
  228. await transaction.update(this.ctx.service.materialStageBills.tableName, updateData);
  229. await this.ctx.service.materialStage.updateMtp(transaction, ms_id);
  230. if (updateAllStage === 'all') {
  231. const updateDatas = [];
  232. const updateMsIds = [];
  233. const msbList = await transaction.select(this.ctx.service.materialStageBills.tableName, { where: { mid: this.ctx.material.id, mb_id } });
  234. for (const msb of msbList) {
  235. if (msb.ms_id !== parseInt(ms_id)) {
  236. const newQuantity4 = await this.getMbQuantity(transaction, this.ctx.material.id, this.ctx.material.qty_source, this.ctx.material.decimal.qty, mb_id, msb.ms_id);
  237. const newTp4 = this.ctx.helper.round(this.ctx.helper.mul(newQuantity4, msb.m_spread), this.ctx.material.decimal.tp);
  238. const updateData4 = {
  239. id: msb.id,
  240. quantity: newQuantity4,
  241. m_tp: newTp4,
  242. m_tax_tp: this.ctx.helper.round(this.ctx.helper.mul(newTp4, (1 + this.ctx.helper.div(mbInfo.m_tax, 100))), this.ctx.material.decimal.tp),
  243. };
  244. updateDatas.push(updateData4);
  245. updateMsIds.push(msb.ms_id);
  246. }
  247. }
  248. if (updateDatas.length > 0) {
  249. await transaction.updateRows(this.ctx.service.materialStageBills.tableName, updateDatas);
  250. for (const msId of updateMsIds) {
  251. await this.ctx.service.materialStage.updateMtp(transaction, msId);
  252. }
  253. }
  254. }
  255. // 还要更新bills表的m_tp和m_tax_tp值
  256. const sql3 = 'SELECT SUM(`m_tp`) as total_price, SUM(IF(`m_tax_tp` is null, `m_tp`, `m_tax_tp`)) as tax_total_price FROM ' + this.ctx.service.materialStageBills.tableName + ' WHERE `tid` = ? AND `mid` = ? AND `mb_id` = ? AND `is_summary` = 1';
  257. const sqlParam3 = [this.ctx.tender.id, this.ctx.material.id, mb_id];
  258. const tp3 = await transaction.queryOne(sql3, sqlParam3);
  259. const updateBillsData = {
  260. id: mb_id,
  261. m_tp: tp3.total_price,
  262. m_tax_tp: tp3.tax_total_price,
  263. };
  264. await transaction.update(this.ctx.service.materialBills.tableName, updateBillsData);
  265. } else {
  266. await transaction.update(this.ctx.service.materialBills.tableName, updateData);
  267. }
  268. // 计算本期总金额
  269. const sql2 = 'SELECT SUM(`m_tp`) as total_price, SUM(IF(`m_tax_tp` is null, `m_tp`, `m_tax_tp`)) as tax_total_price FROM ' + this.ctx.service.materialBills.tableName + ' WHERE `tid` = ? AND `is_summary` = 1';
  270. const sqlParam2 = [this.ctx.tender.id];
  271. const tp = await transaction.queryOne(sql2, sqlParam2);
  272. console.log(tp);
  273. const updateData2 = {
  274. id: this.ctx.material.id,
  275. m_tp: tp.total_price,
  276. m_tax_tp: tp.tax_total_price,
  277. };
  278. // 计算建筑税价
  279. if (this.ctx.material.is_stage_self) {
  280. const materialStages = await transaction.select(this.ctx.service.materialStage.tableName, { where: { mid: this.ctx.material.id } });
  281. let rate_tp = 0;
  282. for (const ms of materialStages) {
  283. const ms_rate_tp = this.ctx.helper.round(this.ctx.helper.mul(ms.m_tp, 1 + this.ctx.material.rate / 100), this.ctx.material.decimal.tp);
  284. rate_tp = this.ctx.helper.add(rate_tp, ms_rate_tp);
  285. }
  286. updateData2.rate_tp = rate_tp;
  287. } else {
  288. updateData2.rate_tp = this.ctx.helper.round(this.ctx.helper.mul(tp.total_price, 1 + this.ctx.material.rate / 100), this.ctx.material.decimal.tp);
  289. }
  290. const result = await transaction.update(this.ctx.service.material.tableName, updateData2);
  291. // 找出当前人并更新tp_data
  292. const tp_data = await this.ctx.service.materialAudit.getTpData(transaction, this.ctx.material.id);
  293. if (this.ctx.material.status === auditConst.status.uncheck || this.ctx.material.status === auditConst.status.checkNo) {
  294. await transaction.update(this.ctx.service.material.tableName, {
  295. id: this.ctx.material.id,
  296. tp_data: JSON.stringify(tp_data),
  297. });
  298. } else if (this.ctx.material.curAuditor) {
  299. await transaction.update(this.ctx.service.materialAudit.tableName, {
  300. id: this.ctx.material.curAuditor.id,
  301. tp_data: JSON.stringify(tp_data),
  302. });
  303. }
  304. return result;
  305. }
  306. /**
  307. * 修改material_bills的quantity值和计算本期金额
  308. * @param transaction
  309. * @param mb_id
  310. * @return {Promise<*>}
  311. */
  312. async calcAllQuantityByML(transaction, mbIds) {
  313. const mbList = await transaction.select(this.ctx.service.materialBills.tableName, { where: { id: mbIds } });
  314. // 修改material_bills值
  315. for (const mbInfo of mbList) {
  316. if (!mbInfo) {
  317. throw '不存在该工料';
  318. }
  319. if (this.ctx.material.is_stage_self) {
  320. const updateDatas = [];
  321. const updateMsIds = [];
  322. const msbList = await transaction.select(this.ctx.service.materialStageBills.tableName, { where: { mid: this.ctx.material.id, mb_id: mbInfo.id } });
  323. for (const msb of msbList) {
  324. const newQuantity = await this.getMbQuantity(transaction, this.ctx.material.id, this.ctx.material.qty_source, this.ctx.material.decimal.qty, mbInfo.id, msb.ms_id);
  325. const newTp = this.ctx.helper.round(this.ctx.helper.mul(newQuantity, msb.m_spread), this.ctx.material.decimal.tp);
  326. const updateData = {
  327. id: msb.id,
  328. quantity: newQuantity,
  329. m_tp: newTp,
  330. m_tax_tp: this.ctx.helper.round(this.ctx.helper.mul(newTp, (1 + this.ctx.helper.div(mbInfo.m_tax, 100))), this.ctx.material.decimal.tp),
  331. };
  332. updateDatas.push(updateData);
  333. updateMsIds.push(msb.ms_id);
  334. }
  335. if (updateDatas.length > 0) {
  336. await transaction.updateRows(this.ctx.service.materialStageBills.tableName, updateDatas);
  337. for (const msId of updateMsIds) {
  338. await this.ctx.service.materialStage.updateMtp(transaction, msId);
  339. }
  340. }
  341. // 还要更新bills表的m_tp和m_tax_tp值
  342. const sql3 = 'SELECT SUM(`m_tp`) as total_price, SUM(IF(`m_tax_tp` is null, `m_tp`, `m_tax_tp`)) as tax_total_price FROM ' + this.ctx.service.materialStageBills.tableName + ' WHERE `tid` = ? AND `mid` = ? AND `mb_id` = ? AND `is_summary` = 1';
  343. const sqlParam3 = [this.ctx.tender.id, this.ctx.material.id, mbInfo.id];
  344. const tp3 = await transaction.queryOne(sql3, sqlParam3);
  345. const updateBillsData = {
  346. id: mbInfo.id,
  347. m_tp: tp3.total_price,
  348. m_tax_tp: tp3.tax_total_price,
  349. };
  350. await transaction.update(this.ctx.service.materialBills.tableName, updateBillsData);
  351. } else {
  352. const newQuantity = await this.getMbQuantity(transaction, this.ctx.material.id, this.ctx.material.qty_source, this.ctx.material.decimal.qty, mbInfo.id);
  353. const newTp = this.ctx.helper.round(this.ctx.helper.mul(newQuantity, mbInfo.m_spread), this.ctx.material.decimal.tp);
  354. const updateData = {
  355. id: mbInfo.id,
  356. quantity: newQuantity,
  357. m_tp: newTp,
  358. m_tax_tp: this.ctx.helper.round(this.ctx.helper.mul(newTp, (1 + this.ctx.helper.div(mbInfo.m_tax, 100))), this.ctx.material.decimal.tp),
  359. };
  360. await transaction.update(this.ctx.service.materialBills.tableName, updateData);
  361. }
  362. }
  363. // 计算本期总金额
  364. const sql2 = 'SELECT SUM(`m_tp`) as total_price, SUM(IF(`m_tax_tp` is null, `m_tp`, `m_tax_tp`)) as tax_total_price FROM ' + this.ctx.service.materialBills.tableName + ' WHERE `tid` = ? AND `is_summary` = 1';
  365. const sqlParam2 = [this.ctx.tender.id];
  366. const tp = await transaction.queryOne(sql2, sqlParam2);
  367. console.log(tp);
  368. const updateData2 = {
  369. id: this.ctx.material.id,
  370. m_tp: tp.total_price,
  371. m_tax_tp: tp.tax_total_price,
  372. };
  373. return await transaction.update(this.ctx.service.material.tableName, updateData2);
  374. }
  375. /**
  376. * 获取工料清单关联表
  377. * @param {int} tid 标段id
  378. * @param {Object} mid 期id
  379. * @return {void}
  380. */
  381. async getMaterialData(tid, mid) {
  382. const sql = 'SELECT ml.`id`, mb.`code`, mb.`name`, mb.`unit`, ml.`order`, ml.`contract_qty`, ml.`qc_qty`, ml.`qc_minus_qty`, ml.`gather_qty`, ml.`qty`, ml.`quantity`, ml.`expr`, ml.`mb_id`, ml.`gcl_id`, ml.`xmj_id`, ml.`mx_id`, ml.`ms_id`, ml.`tid`, ml.`mid`, mb.m_spread, ml.ms_id, ml.is_join' +
  383. ' FROM ' + this.tableName + ' as ml' +
  384. ' LEFT JOIN ' + this.ctx.service.materialBills.tableName + ' as mb' +
  385. ' ON ml.`mb_id` = mb.`id`' +
  386. ' WHERE ml.`tid` = ? AND ml.`mid` = ?';
  387. const sqlParam = [tid, mid];
  388. return await this.db.query(sql, sqlParam);
  389. }
  390. async getPreMaterialData(tid, mid) {
  391. const sql = 'SELECT ml.`id`, mb.`code`, mb.`name`, mb.`unit`, ml.`order`, ml.`quantity`, ml.`expr`, ml.`mb_id`, ml.`gcl_id`, ml.`xmj_id`, ml.`mx_id`, ml.`ms_id`, ml.`tid`, ml.`mid`, mbh.m_spread, ml.ms_id, ml.is_join' +
  392. ' FROM ' + this.tableName + ' as ml' +
  393. ' LEFT JOIN ' + this.ctx.service.materialBills.tableName + ' as mb ON ml.`mb_id` = mb.`id`' +
  394. ' LEFT JOIN ' + this.ctx.service.materialBillsHistory.tableName + ' as mbh ON ml.`mb_id` = mbh.`mb_id` and mbh.mid = ?' +
  395. ' WHERE ml.`tid` = ? AND ml.`mid` = ?';
  396. const sqlParam = [mid, tid, mid];
  397. return await this.db.query(sql, sqlParam);
  398. }
  399. async getMaterialStageData(tid, mid) {
  400. const sql = 'SELECT ml.`id`, mb.`code`, mb.`name`, mb.`unit`, ml.`order`, ml.`quantity`, ml.`expr`, msb.id AS mb_id, ml.`gcl_id`, ml.`xmj_id`, ml.`mx_id`, ml.`ms_id`, ml.`tid`, ml.`mid`, msb.m_spread, ml.ms_id, ms.sid, ms.order as s_order, ml.is_join' +
  401. ' FROM ' + this.tableName + ' as ml' +
  402. ' LEFT JOIN ' + this.ctx.service.materialBills.tableName + ' as mb ON ml.`mb_id` = mb.`id`' +
  403. ' LEFT JOIN ' + this.ctx.service.materialStageBills.tableName + ' as msb ON ml.mb_id = msb.mb_id AND ml.ms_id = msb.ms_id' +
  404. ' LEFT JOIN ' + this.ctx.service.materialStage.tableName + ' as ms ON ml.`ms_id` = ms.`id`' +
  405. ' WHERE ml.`tid` = ? AND ml.`mid` = ?';
  406. const sqlParam = [tid, mid];
  407. return await this.db.query(sql, sqlParam);
  408. }
  409. async getPreMaterialStageData(tid, mid) {
  410. const sql = 'SELECT ml.`id`, mb.`code`, mb.`name`, mb.`unit`, ml.`order`, ml.`quantity`, ml.`expr`, msb.id AS mb_id, ml.`gcl_id`, ml.`xmj_id`, ml.`mx_id`, ml.`ms_id`, ml.`tid`, ml.`mid`, msb.m_spread, ml.ms_id, ms.sid, ms.order as s_order, ml.is_join' +
  411. ' FROM ' + this.tableName + ' as ml' +
  412. ' LEFT JOIN ' + this.ctx.service.materialBills.tableName + ' as mb ON ml.`mb_id` = mb.`id`' +
  413. ' LEFT JOIN ' + this.ctx.service.materialStageBills.tableName + ' as msb ON ml.`mb_id` = msb.mb_id AND ml.ms_id = msb.ms_id And ml.mid = msb.mid' +
  414. ' LEFT JOIN ' + this.ctx.service.materialStage.tableName + ' as ms ON ml.`ms_id` = ms.`id`' +
  415. ' WHERE ml.`tid` = ? AND ml.`mid` = ?';
  416. const sqlParam = [tid, mid];
  417. return await this.db.query(sql, sqlParam);
  418. }
  419. /**
  420. * 复制上一期并生成新一期清单工料关联,计算新一期小计值
  421. * @param transaction
  422. * @param preMaterial
  423. * @param newMid
  424. * @return {Promise<void>}
  425. */
  426. async copyPreMaterialList(transaction, preMaterial, newMaterial) {
  427. const materialListData = await this.getAllDataByCondition({ where: { tid: this.ctx.tender.id, mid: preMaterial.id } });
  428. const copyMLArray = [];
  429. for (const ml of materialListData) {
  430. // 获取小计值
  431. let qtys = null;
  432. if (ml.mx_id !== null && ml.mx_id !== '') {
  433. qtys = await this.ctx.service.stagePos.getGatherQtyByMaterial(ml.tid, newMaterial.stage_id, ml.gcl_id, ml.mx_id);
  434. } else {
  435. qtys = await this.ctx.service.stageBills.getGatherQtyByMaterial(ml.tid, newMaterial.stage_id, ml.gcl_id);
  436. }
  437. const newMaterialList = {
  438. tid: ml.tid,
  439. order: ml.order,
  440. mid: newMaterial.id,
  441. mb_id: ml.mb_id,
  442. gcl_id: ml.gcl_id,
  443. xmj_id: ml.xmj_id,
  444. mx_id: ml.mx_id,
  445. contract_qty: qtys ? qtys.contract_qty : null,
  446. qc_qty: qtys ? qtys.qc_qty : null,
  447. qc_minus_qty: qtys ? qtys.qc_minus_qty : null,
  448. gather_qty: qtys ? qtys.gather_qty : null,
  449. quantity: ml.quantity,
  450. expr: ml.expr,
  451. is_join: ml.is_join,
  452. in_time: new Date(),
  453. };
  454. copyMLArray.push(newMaterialList);
  455. }
  456. return copyMLArray.length !== 0 ? await transaction.insert(this.tableName, copyMLArray) : true;
  457. }
  458. /**
  459. * 复制上一期并生成新一期清单工料关联,计算新一期小计值
  460. * @param transaction
  461. * @param preMaterial
  462. * @param newMid
  463. * @return {Promise<void>}
  464. */
  465. async copyPreMaterialList2(transaction, materialListData, materialSelfListData, notJoinList, newMaterial, materialStageData) {
  466. if (materialListData && materialListData.length > 0) {
  467. const copyMLArray = [];
  468. for (const ml of materialListData) {
  469. const is_join = this._.find(notJoinList, { gcl_id: ml.gcl_id, xmj_id: ml.xmj_id, mx_id: ml.mx_id, type: 1 });
  470. const is_change = this._.find(notJoinList, { gcl_id: ml.gcl_id, xmj_id: ml.xmj_id, mx_id: ml.mx_id, type: 2 });
  471. const newMaterialList = {
  472. tid: newMaterial.tid,
  473. order: ml.order,
  474. mid: newMaterial.id,
  475. mb_id: ml.mb_id,
  476. gcl_id: ml.gcl_id,
  477. xmj_id: ml.xmj_id,
  478. mx_id: ml.mx_id,
  479. contract_qty: ml.contract_qty,
  480. qc_qty: ml.qc_qty,
  481. qc_minus_qty: ml.qc_minus_qty,
  482. gather_qty: ml.gather_qty,
  483. quantity: ml.quantity ? ml.quantity : 0,
  484. expr: ml.expr ? ml.expr : '',
  485. is_join: is_join ? 0 : is_change ? 2 : 1,
  486. in_time: new Date(),
  487. };
  488. if (ml.sid) {
  489. const ms = this._.find(materialStageData, { sid: ml.sid });
  490. if (ms && ms.id) newMaterialList.ms_id = ms.id;
  491. }
  492. copyMLArray.push(newMaterialList);
  493. }
  494. if (copyMLArray.length !== 0) await transaction.insert(this.tableName, copyMLArray);
  495. }
  496. if (materialSelfListData && materialSelfListData.length > 0) {
  497. const copyMLArray2 = [];
  498. for (const ml of materialSelfListData) {
  499. const is_join = this._.find(notJoinList, { gcl_id: ml.gcl_id, xmj_id: ml.xmj_id, mx_id: ml.mx_id, type: 1 });
  500. const is_change = this._.find(notJoinList, { gcl_id: ml.gcl_id, xmj_id: ml.xmj_id, mx_id: ml.mx_id, type: 2 });
  501. const newMaterialList = {
  502. tid: newMaterial.tid,
  503. order: ml.order,
  504. mid: newMaterial.id,
  505. mb_id: ml.mb_id,
  506. gcl_id: ml.gcl_id,
  507. xmj_id: ml.xmj_id,
  508. mx_id: ml.mx_id,
  509. contract_qty: ml.contract_qty,
  510. qc_qty: ml.qc_qty,
  511. qc_minus_qty: ml.qc_minus_qty,
  512. gather_qty: ml.gather_qty,
  513. quantity: ml.quantity ? ml.quantity : 0,
  514. expr: ml.expr ? ml.expr : '',
  515. is_join: is_join ? 0 : is_change ? 2 : 1,
  516. is_self: 1,
  517. in_time: new Date(),
  518. };
  519. if (ml.sid) {
  520. const ms = this._.find(materialStageData, { sid: ml.sid });
  521. if (ms && ms.id) newMaterialList.ms_id = ms.id;
  522. }
  523. copyMLArray2.push(newMaterialList);
  524. }
  525. if (copyMLArray2.length !== 0) await transaction.insert(this.tableName, copyMLArray2);
  526. }
  527. }
  528. /**
  529. * 添加工料清单关联(多清单对应)
  530. * @return {void}
  531. */
  532. async adds(datas, checklist = false) {
  533. if (!this.ctx.tender || !this.ctx.material) {
  534. throw '数据错误';
  535. }
  536. const transaction = await this.db.beginTransaction();
  537. try {
  538. const list = [];
  539. const listGcl = [];
  540. const uplist = [];
  541. const uplistGcl = [];
  542. // const delList = [];
  543. // const mb_idList = [];
  544. const selfList = await transaction.select(this.ctx.service.materialListSelf.tableName, { where: { tid: this.ctx.tender.id, mid: this.ctx.material.id } });
  545. const oldGclList = await transaction.select(this.ctx.service.materialListGcl.tableName, { where: { tid: this.ctx.tender.id } });
  546. const oldMaterialList = await transaction.select(this.ctx.service.materialList.tableName, { where: { tid: this.ctx.tender.id, mid: this.ctx.material.id } });
  547. for (const xmj of datas.xmjs) {
  548. for (const mb of datas.mbIds) {
  549. // // 旧数据兼容问题,要去删除相同已存在的工料
  550. // const mlInfo = await this.getDataByCondition({
  551. // mid: this.ctx.material.id,
  552. // gcl_id: xmj.gcl_id,
  553. // xmj_id: xmj.xmj_id,
  554. // mx_id: xmj.mx_id ? xmj.mx_id : [null, ''],
  555. // mb_id: mb,
  556. // });
  557. // if (mlInfo) {
  558. // delList.push(mlInfo.id);
  559. // mb_idList.push(mb);
  560. // }
  561. const mbId = typeof mb === 'object' ? mb.id : mb;
  562. const quantity = typeof mb === 'object' ? mb.quantity : 0;
  563. if ((xmj.contract_qty || xmj.qc_qty || xmj.qc_minus_qty || xmj.gather_qty) && this._.findIndex(selfList, { gcl_id: xmj.gcl_id, xmj_id: xmj.xmj_id, mx_id: xmj.mx_id }) === -1) {
  564. const mlInfo = this._.find(oldMaterialList, { gcl_id: xmj.gcl_id, xmj_id: xmj.xmj_id, mx_id: xmj.mx_id, mb_id: mbId, ms_id: xmj.ms_id ? xmj.ms_id : null });
  565. if (mlInfo) {
  566. uplist.push({ id: mlInfo.id, quantity, expr: '' });
  567. } else {
  568. const newLists = {
  569. tid: this.ctx.tender.id,
  570. order: this.ctx.material.order,
  571. mid: this.ctx.material.id,
  572. mb_id: mbId,
  573. gcl_id: xmj.gcl_id,
  574. xmj_id: xmj.xmj_id,
  575. mx_id: xmj.mx_id,
  576. ms_id: xmj.ms_id ? xmj.ms_id : null,
  577. contract_qty: xmj.contract_qty,
  578. qc_qty: xmj.qc_qty,
  579. qc_minus_qty: xmj.qc_minus_qty,
  580. gather_qty: xmj.gather_qty,
  581. qty: xmj.qty || null,
  582. quantity,
  583. in_time: new Date(),
  584. is_join: xmj.is_join,
  585. };
  586. list.push(newLists);
  587. }
  588. }
  589. const gclIndex = this._.findIndex(oldGclList, { gcl_id: xmj.gcl_id, mb_id: mbId });
  590. if (gclIndex === -1 && this._.findIndex(listGcl, { gcl_id: xmj.gcl_id, mb_id: mbId }) === -1) {
  591. const newListGcl = {
  592. tid: this.ctx.tender.id,
  593. order: this.ctx.material.order,
  594. mid: this.ctx.material.id,
  595. mb_id: mbId,
  596. gcl_id: xmj.gcl_id,
  597. quantity,
  598. expr: '',
  599. };
  600. listGcl.push(newListGcl);
  601. } else if (gclIndex !== -1 && this._.findIndex(uplistGcl, { id: oldGclList[gclIndex].id }) === -1) {
  602. uplistGcl.push({
  603. id: oldGclList[gclIndex].id,
  604. expr: '',
  605. quantity,
  606. });
  607. }
  608. }
  609. }
  610. // 维护list_gcl表
  611. // 删除工料清单关联
  612. // if (delList.length > 0) await transaction.delete(this.tableName, { id: delList });
  613. // 新增工料清单关联
  614. if (list.length > 0) {
  615. await this.insertBigDatas(transaction, list);
  616. }
  617. if (listGcl.length > 0) {
  618. const result2 = await transaction.insert(this.ctx.service.materialListGcl.tableName, listGcl);
  619. if (result2.affectedRows === 0) {
  620. throw '新增工料关联数据失败';
  621. }
  622. }
  623. // 覆盖
  624. if (uplist.length > 0) {
  625. await transaction.updateRows(this.tableName, uplist);
  626. }
  627. if (uplistGcl.length > 0) {
  628. await transaction.updateRows(this.ctx.service.materialListGcl.tableName, uplistGcl);
  629. }
  630. if (checklist) {
  631. await this.ctx.service.materialChecklist.updateHadBills(transaction, checklist.id, checklist.had_bills);
  632. }
  633. // 重算工料和总金额
  634. // const calcMBIdList = this._.uniq(mb_idList);
  635. // if (calcMBIdList.length > 0) {
  636. // for (const select of calcMBIdList) {
  637. // await this.calcQuantityByML(transaction, select);
  638. // }
  639. // }
  640. if ((list.length > 0 || uplist.length > 0) && datas.export) {
  641. await this.calcAllQuantityByML(transaction, this._.map(datas.mbIds, 'id'));
  642. }
  643. await transaction.commit();
  644. const gclList = await this.ctx.service.materialListGcl.getAllDataByCondition({ where: { tid: this.ctx.tender.id } });
  645. return checklist ? gclList : {
  646. gclList,
  647. materialListData: await this.getMaterialData(this.ctx.tender.id, this.ctx.material.id),
  648. };
  649. } catch (err) {
  650. await transaction.rollback();
  651. throw err;
  652. }
  653. }
  654. async cover() {
  655. const transaction = await this.db.beginTransaction();
  656. try {
  657. await transaction.delete(this.tableName, { tid: this.ctx.tender.id, order: this.ctx.material.order, is_self: 0 });
  658. await transaction.delete(this.ctx.service.materialListGcl.tableName, { tid: this.ctx.tender.id, mid: this.ctx.material.id });
  659. await transaction.update(this.ctx.service.materialChecklist.tableName, { had_bills: 0 }, { where: { tid: this.ctx.tender.id, mid: this.ctx.material.id } });
  660. await transaction.commit();
  661. } catch (err) {
  662. await transaction.rollback();
  663. throw err;
  664. }
  665. }
  666. /**
  667. * 删除工料清单关联(多清单对应)
  668. * @param {int} id 工料id
  669. * @return {void}
  670. */
  671. async dels(datas, checklist = false, fromCheckList = false, ms_id = null) {
  672. if (!this.ctx.tender || !this.ctx.material) {
  673. throw '数据错误';
  674. }
  675. const transaction = await this.db.beginTransaction();
  676. try {
  677. // 判断是否可删
  678. const listGcl = [];
  679. for (const xmj of datas.xmjs) {
  680. await transaction.delete(this.tableName, { tid: this.ctx.tender.id, mid: this.ctx.material.id, mb_id: datas.mb_id, gcl_id: xmj.gcl_id, xmj_id: xmj.xmj_id, mx_id: xmj.mx_id, is_self: 0 });
  681. if (this._.indexOf(listGcl, xmj.gcl_id) === -1) {
  682. await transaction.delete(this.service.materialListGcl.tableName, { tid: this.ctx.tender.id, mid: this.ctx.material.id, mb_id: datas.mb_id, gcl_id: xmj.gcl_id });
  683. listGcl.push(xmj.gcl_id);
  684. }
  685. }
  686. // await transaction.delete(this.tableName, { id });
  687. await this.calcQuantityByML(transaction, datas.mb_id, ms_id, 'all');
  688. if (checklist) {
  689. await this.ctx.service.materialChecklist.updateHadBills(transaction, checklist.id, checklist.had_bills);
  690. }
  691. await transaction.commit();
  692. // console.log(datas);
  693. const gclList = await this.ctx.service.materialListGcl.getAllDataByCondition({ where: { tid: this.ctx.tender.id } });
  694. return fromCheckList ? gclList : {
  695. gclList,
  696. materialListData: await this.getMaterialData(this.ctx.tender.id, this.ctx.material.id),
  697. };
  698. } catch (err) {
  699. await transaction.rollback();
  700. throw err;
  701. }
  702. }
  703. /**
  704. * 修改工料清单关联信息(多清单对应)
  705. * @param {Object} data 工料内容
  706. * @param {int} order 期数
  707. * @return {void}
  708. */
  709. async saves(datas, checklist = false, ms_id = null) {
  710. if (!this.ctx.tender || !this.ctx.material) {
  711. throw '数据错误';
  712. }
  713. const transaction = await this.db.beginTransaction();
  714. try {
  715. const mb_id = datas.mb_id;
  716. const updateDatas = [];
  717. const updateListGcl = [];
  718. const listGcl = [];
  719. const selfList = await transaction.select(this.ctx.service.materialListSelf.tableName, { where: { tid: this.ctx.tender.id, mid: this.ctx.material.id } });
  720. for (const xmj of datas.xmjs) {
  721. if (this._.findIndex(selfList, { gcl_id: xmj.gcl_id, xmj_id: xmj.xmj_id, mx_id: xmj.mx_id }) === -1) {
  722. const udata = {
  723. row: {
  724. expr: datas.expr,
  725. quantity: datas.quantity,
  726. },
  727. where: {
  728. tid: this.ctx.tender.id,
  729. mid: this.ctx.material.id,
  730. mb_id,
  731. gcl_id: xmj.gcl_id,
  732. xmj_id: xmj.xmj_id,
  733. mx_id: xmj.mx_id,
  734. },
  735. };
  736. updateDatas.push(udata);
  737. }
  738. if (this._.indexOf(listGcl, xmj.gcl_id) === -1) {
  739. listGcl.push(xmj.gcl_id);
  740. updateListGcl.push({
  741. row: {
  742. expr: datas.expr,
  743. quantity: datas.quantity,
  744. },
  745. where: {
  746. tid: this.ctx.tender.id,
  747. // mid: this.ctx.material.id,
  748. mb_id,
  749. gcl_id: xmj.gcl_id,
  750. },
  751. });
  752. }
  753. }
  754. if (updateDatas.length > 0) await transaction.updateRows(this.tableName, updateDatas);
  755. if (updateListGcl.length > 0) await transaction.updateRows(this.service.materialListGcl.tableName, updateListGcl);
  756. await this.calcQuantityByML(transaction, mb_id, ms_id, 'all');
  757. await transaction.commit();
  758. const gclList = await this.ctx.service.materialListGcl.getAllDataByCondition({ where: { tid: this.ctx.tender.id } });
  759. return checklist ? gclList : {
  760. gclList,
  761. materialListData: await this.getMaterialData(this.ctx.tender.id, this.ctx.material.id),
  762. };
  763. } catch (err) {
  764. await transaction.rollback();
  765. throw err;
  766. }
  767. }
  768. /**
  769. * 复制粘贴多工料信息(多清单对应)
  770. * @param {Object} data 工料内容
  771. * @return {void}
  772. */
  773. async savePastes(datas, checklist = false, ms_id = null) {
  774. if (!this.ctx.tender || !this.ctx.material) {
  775. throw '数据错误';
  776. }
  777. // 判断是否可修改
  778. // 判断t_type是否为费用
  779. const transaction = await this.db.beginTransaction();
  780. try {
  781. const selfList = await transaction.select(this.ctx.service.materialListSelf.tableName, { where: { tid: this.ctx.tender.id, mid: this.ctx.material.id } });
  782. for (const data of datas.pasteData) {
  783. const updateDatas = [];
  784. const updateListGcl = [];
  785. const listGcl = [];
  786. for (const xmj of datas.xmjs) {
  787. if (this._.findIndex(selfList, { gcl_id: xmj.gcl_id, xmj_id: xmj.xmj_id, mx_id: xmj.mx_id }) === -1) {
  788. const udata = {
  789. row: {
  790. expr: data.expr,
  791. quantity: data.quantity,
  792. },
  793. where: {
  794. tid: this.ctx.tender.id,
  795. mid: this.ctx.material.id,
  796. mb_id: data.mb_id,
  797. gcl_id: xmj.gcl_id,
  798. xmj_id: xmj.xmj_id,
  799. mx_id: xmj.mx_id,
  800. },
  801. };
  802. updateDatas.push(udata);
  803. }
  804. if (this._.indexOf(listGcl, xmj.gcl_id) === -1) {
  805. listGcl.push(xmj.gcl_id);
  806. updateListGcl.push({
  807. row: {
  808. expr: data.expr,
  809. quantity: data.quantity,
  810. },
  811. where: {
  812. tid: this.ctx.tender.id,
  813. // mid: this.ctx.material.id,
  814. mb_id: data.mb_id,
  815. gcl_id: xmj.gcl_id,
  816. },
  817. });
  818. }
  819. }
  820. if (updateDatas.length > 0) await transaction.updateRows(this.tableName, updateDatas);
  821. if (updateListGcl.length > 0) await transaction.updateRows(this.service.materialListGcl.tableName, updateListGcl);
  822. await this.calcQuantityByML(transaction, data.mb_id, ms_id, 'all');
  823. }
  824. await transaction.commit();
  825. const gclList = await this.ctx.service.materialListGcl.getAllDataByCondition({ where: { tid: this.ctx.tender.id } });
  826. return checklist ? gclList : {
  827. gclList,
  828. materialListData: await this.getMaterialData(this.ctx.tender.id, this.ctx.material.id),
  829. };
  830. } catch (err) {
  831. await transaction.rollback();
  832. throw err;
  833. }
  834. }
  835. async saveQtyHistory(updateList) {
  836. if (!this.ctx.tender || !this.ctx.material) {
  837. throw '数据错误';
  838. }
  839. // 判断是否可修改
  840. // 判断t_type是否为费用
  841. const transaction = await this.db.beginTransaction();
  842. try {
  843. if (updateList.length > 0) await transaction.updateRows(this.tableName, updateList);
  844. await transaction.update(this.ctx.service.material.tableName, { id: this.ctx.material.id, is_new_qty: 1 });
  845. await transaction.commit();
  846. return {
  847. materialListData: await this.getMaterialData(this.ctx.tender.id, this.ctx.material.id)
  848. };
  849. } catch (err) {
  850. await transaction.rollback();
  851. throw err;
  852. }
  853. }
  854. async getMbQuantity(transaction, mid, qty_source, qty_decimal, mb_id, ms_id = null, needRound = 1) {
  855. // const msSql = ms_id ? ' AND `ms_id` = ' + ms_id : '';
  856. // const sql = `
  857. // SELECT
  858. // SUM(CASE WHEN is_join = 1 THEN ${this.ctx.helper.getQtySource(qty_source)} * quantity ELSE 0 END) AS quantity1,
  859. // SUM(CASE WHEN is_join = 2 THEN ${this.ctx.helper.getQtySource(qty_source, 1)} * quantity ELSE 0 END) AS quantity2
  860. // FROM ${this.tableName}
  861. // WHERE mid = ? AND mb_id = ?${msSql}
  862. // `;
  863. // const sqlParam = [mid, mb_id];
  864. // const result = await transaction.queryOne(sql, sqlParam);
  865. // const newQuantity = this.ctx.helper.add(result.quantity1, result.quantity2);
  866. // return needRound ? this.ctx.helper.round(newQuantity, qty_decimal) : newQuantity;
  867. const condition = { mid, mb_id };
  868. if (ms_id) condition.ms_id = ms_id;
  869. const list = await transaction.select(this.tableName, { where: condition });
  870. let quantity1 = 0;
  871. let quantity2 = 0;
  872. let qty = 0;
  873. for (const item of list) {
  874. if (item.qty !== null) {
  875. qty = this.ctx.helper.add(qty, this.ctx.helper.mul(item.qty, item.quantity));
  876. } else if (item.is_join === 1) {
  877. quantity1 = this.ctx.helper.add(quantity1, this.ctx.helper.mul(this.ctx.helper.getQtySourceValue(item, qty_source), item.quantity));
  878. } else if (item.is_join === 2) {
  879. quantity2 = this.ctx.helper.add(quantity2, this.ctx.helper.mul(this.ctx.helper.getQtySourceValue(item, qty_source, 1), item.quantity));
  880. }
  881. }
  882. const newQuantity = this.ctx.helper.sum([quantity1, quantity2, qty]);
  883. return needRound ? this.ctx.helper.round(newQuantity, qty_decimal) : newQuantity;
  884. }
  885. async makeMaterialList(data) {
  886. if (!data.mid) {
  887. throw '参数错误';
  888. }
  889. const transaction = await this.db.beginTransaction();
  890. try {
  891. const material = await this.ctx.service.material.getDataById(data.mid);
  892. const newCalcStage = material.is_stage_self ? (material.calc_stage ? material.calc_stage.split(',') : []) : data.stage_id;
  893. if (material.is_stage_self) newCalcStage.push(data.stage_id);
  894. const materialStages = material.is_stage_self ? await this.ctx.service.materialStage.getAllDataByCondition({ where: { mid: material.id } }) : [];
  895. const notJoinList = await this.ctx.service.materialListNotjoin.getAllDataByCondition({ where: { tid: this.ctx.tender.id, mid: material.id } });
  896. // 复制调差清单工料关联表
  897. // await this.ctx.service.materialList.copyPreMaterialList(transaction, preMaterial, newMaterial);
  898. await this.copyPreMaterialList2(transaction, data.material_list, [], notJoinList, material, materialStages);
  899. // 新增或删除list_gcl表
  900. await this.ctx.service.materialListGcl.insertOrDelGcl(transaction, data.insertGclList, data.removeGclList, material.id);
  901. // 修改本期应耗数量值和有效价差,需要剔除不参与调差的清单数据,并返回总金额
  902. const materials = await this.ctx.service.material.getAllDataByCondition({
  903. where: { tid: this.ctx.tender.id },
  904. order: ['order'],
  905. });
  906. const preMaterial = materials[materials.length - 2];
  907. if (material.is_stage_self) {
  908. await this.ctx.service.materialStageBills.insertMsBills(transaction, this.ctx.tender.id, material.id, this._.find(materialStages, { sid: parseInt(data.stage_id) }), JSON.parse(material.decimal), preMaterial.is_stage_self, material.qty_source, material.rate);
  909. if (!material.pre_exponent_node) await this.ctx.service.materialExponentShard.insertMsExponent(transaction, this.ctx.tender.id, material.id, this._.find(materialStages, { sid: parseInt(data.stage_id) }), preMaterial, JSON.parse(material.exponent_decimal), material.exponent_rate);
  910. await transaction.update(this.ctx.service.material.tableName, {
  911. id: material.id, calc_stage: newCalcStage.join(','),
  912. });
  913. } else {
  914. let m_tp = null;
  915. let m_tax_tp = null;
  916. let rate_tp = null;
  917. [m_tp, m_tax_tp, rate_tp] = await this.ctx.service.materialBills.updateNewMaterial(transaction, this.ctx.tender.id, material.id, this.ctx, material.stage_id, JSON.parse(material.decimal), preMaterial.is_stage_self, material.qty_source, material.rate);
  918. const updateMaterialData = {
  919. id: material.id,
  920. m_tp,
  921. m_tax_tp,
  922. rate_tp,
  923. calc_tp: 1,
  924. calc_stage: newCalcStage,
  925. };
  926. await transaction.update(this.ctx.service.material.tableName, updateMaterialData);
  927. }
  928. await transaction.commit();
  929. return true;
  930. } catch (err) {
  931. await transaction.rollback();
  932. throw err;
  933. }
  934. }
  935. async makeSelfList(data) {
  936. if (!data.mid) {
  937. throw '参数错误';
  938. }
  939. const transaction = await this.db.beginTransaction();
  940. try {
  941. const material = await this.ctx.service.material.getDataById(data.mid);
  942. const materialStages = material.is_stage_self ? await this.ctx.service.materialStage.getAllDataByCondition({ where: { mid: material.id } }) : [];
  943. const notJoinList = await this.ctx.service.materialListNotjoin.getAllDataByCondition({ where: { tid: this.ctx.tender.id, mid: material.id } });
  944. // 复制调差清单工料关联表
  945. // await this.ctx.service.materialList.copyPreMaterialList(transaction, preMaterial, newMaterial);
  946. await this.copyPreMaterialList2(transaction, [], data.material_self_list, notJoinList, material, materialStages);
  947. // 设置list_gcl表old=>new更新
  948. await this.ctx.service.materialListGcl.setNewOldData(transaction, this.ctx.tender.id);
  949. // 修改本期应耗数量值和有效价差,需要剔除不参与调差的清单数据,并返回总金额
  950. // 找出当前人并更新tp_data
  951. const tp_data = await this.ctx.service.materialAudit.getTpData(transaction, material.id, JSON.parse(material.decimal), JSON.parse(material.exponent_decimal));
  952. const updateMaterialData = {
  953. id: material.id,
  954. calc_tp: 1,
  955. tp_data: JSON.stringify(tp_data),
  956. };
  957. if (material.is_stage_self) {
  958. // 更新bill表和截止上期数据
  959. const materialDecimal = JSON.parse(material.decimal);
  960. const updateBillsData = [];
  961. const billsList = await transaction.select(this.ctx.service.materialBills.tableName, { where: { tid: this.ctx.tender.id } });
  962. const stageBillsDatas = await this.ctx.service.materialStageBills.getAllDataByCondition({ where: { tid: this.ctx.tender.id, mid: material.id } });
  963. for (const mb of billsList) {
  964. const [newmsg_spread, newm_spread] = await this.ctx.service.materialStageBills.getSpread(mb, null, materialDecimal.up);
  965. const newTp = this._.sumBy(stageBillsDatas, function(item) {
  966. return item.mb_id === mb.id ? item.m_tp : 0;
  967. });
  968. const oneBillsData = {
  969. id: mb.id,
  970. quantity: null,
  971. expr: null,
  972. msg_tp: null,
  973. msg_times: null,
  974. msg_spread: newmsg_spread,
  975. m_spread: newm_spread,
  976. origin: null,
  977. m_tp: newTp,
  978. pre_tp: mb.m_tp !== null ? this.ctx.helper.add(mb.pre_tp, mb.m_tp) : mb.pre_tp,
  979. m_tax_tp: this.ctx.helper.round(this.ctx.helper.mul(newTp, (1 + this.ctx.helper.div(mb.m_tax, 100))), materialDecimal.tp),
  980. tax_pre_tp: mb.m_tax_tp !== null ? this.ctx.helper.add(mb.tax_pre_tp, mb.m_tax_tp) : mb.tax_pre_tp,
  981. };
  982. updateBillsData.push(oneBillsData);
  983. }
  984. if (updateBillsData.length > 0) await transaction.updateRows(this.ctx.service.materialBills.tableName, updateBillsData);
  985. // 计算得出本期总金额
  986. let m_tp = 0;
  987. let m_tax_tp = 0;
  988. let rate_tp = 0;
  989. let ex_tp = 0;
  990. let ex_tax_tp = 0;
  991. for (const s of materialStages) {
  992. m_tp = this.ctx.helper.add(m_tp, s.m_tp);
  993. m_tax_tp = this.ctx.helper.add(m_tax_tp, s.m_tax_tp);
  994. const sRateTp = this.ctx.helper.round(this.ctx.helper.mul(s.m_tp, (1 + this.ctx.helper.div(material.rate, 100))), materialDecimal.tp);
  995. rate_tp = this.ctx.helper.add(rate_tp, sRateTp);
  996. ex_tp = this.ctx.helper.add(ex_tp, s.ex_tp);
  997. ex_tax_tp = this.ctx.helper.add(ex_tax_tp, s.ex_tax_tp);
  998. }
  999. updateMaterialData.m_tp = m_tp;
  1000. updateMaterialData.m_tax_tp = m_tax_tp;
  1001. updateMaterialData.rate_tp = rate_tp;
  1002. updateMaterialData.ex_tp = ex_tp;
  1003. updateMaterialData.ex_tax_tp = ex_tax_tp;
  1004. }
  1005. await transaction.update(this.ctx.service.material.tableName, updateMaterialData);
  1006. // 删除material_list表冗余数据,减少表数据量
  1007. await transaction.delete(this.tableName, { tid: this.ctx.tender.id, gather_qty: null, is_self: 0 });
  1008. await transaction.commit();
  1009. return true;
  1010. } catch (err) {
  1011. await transaction.rollback();
  1012. throw err;
  1013. }
  1014. }
  1015. }
  1016. return MaterialList;
  1017. };