material_exponent.js 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  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. const materialConst = require('../const/material');
  11. const MaterialCalculator = require('../lib/material_calc');
  12. module.exports = app => {
  13. class MaterialExponent extends app.BaseService {
  14. /**
  15. * 构造函数
  16. *
  17. * @param {Object} ctx - egg全局变量
  18. * @return {void}
  19. */
  20. constructor(ctx) {
  21. super(ctx);
  22. this.tableName = 'material_exponent';
  23. }
  24. /**
  25. * 添加指数清单
  26. * @return {void}
  27. */
  28. async add() {
  29. if (!this.ctx.tender || !this.ctx.material) {
  30. throw '数据错误';
  31. }
  32. const transaction = await this.db.beginTransaction();
  33. try {
  34. const resultData = {};
  35. const newExponent = {
  36. tid: this.ctx.tender.id,
  37. mid: this.ctx.material.id,
  38. in_time: new Date(),
  39. };
  40. // 新增工料
  41. const result = await transaction.insert(this.tableName, newExponent);
  42. if (result.affectedRows !== 1) {
  43. throw '新增指数数据失败';
  44. }
  45. switch (this.ctx.material.exponentStatus) {
  46. case materialConst.exponent_status.shared_noNode:
  47. break;
  48. case materialConst.exponent_status.shared_node:
  49. case materialConst.exponent_status.self_noNode:
  50. case materialConst.exponent_status.self_node:
  51. await this.ctx.service.materialExponentShard.add(transaction, this.ctx.material, result.insertId);
  52. resultData.pushExponentShardData = await transaction.select(this.ctx.service.materialExponentShard.tableName, { where: { mid: this.ctx.material.id, me_id: result.insertId } });
  53. break;
  54. default: break;
  55. }
  56. await transaction.commit();
  57. resultData.info = await this.getDataById(result.insertId);
  58. return resultData;
  59. } catch (error) {
  60. console.log(error);
  61. await transaction.rollback();
  62. throw error;
  63. }
  64. }
  65. /**
  66. * 删除指数清单
  67. * @param {int} id 工料id
  68. * @return {void}
  69. */
  70. async del(id) {
  71. if (!this.ctx.tender || !this.ctx.material) {
  72. throw '数据错误';
  73. }
  74. // 判断t_type是否为费用,且存在quantity,m_spread值
  75. const transaction = await this.db.beginTransaction();
  76. try {
  77. const result = {};
  78. const info = {};
  79. const meInfo = await this.getDataById(id);
  80. await transaction.delete(this.tableName, { id });
  81. if (meInfo.weight_num === null) {
  82. await transaction.delete(this.ctx.service.materialExponentHistory.tableName, { mid: this.ctx.material.id, me_id: id });
  83. }
  84. switch (this.ctx.material.exponentStatus) {
  85. case materialConst.exponent_status.shared_noNode:
  86. result.ex_tp = this.ctx.material.ex_tp;
  87. result.ex_expr = this.ctx.material.ex_expr;
  88. if (meInfo.is_summary === materialConst.is_summary.yes) {
  89. // 金额发生变化,则重新计算本期金额
  90. [result.ex_tp, result.ex_tax_tp, result.ex_expr] = await this.calcMaterialExTp(transaction);
  91. }
  92. break;
  93. case materialConst.exponent_status.shared_node:
  94. await transaction.delete(this.ctx.service.materialExponentShard.tableName, { me_id: id });
  95. if (meInfo.is_summary === materialConst.is_summary.yes) {
  96. info.nodeList = await transaction.select(this.ctx.service.materialExponentNode.tableName, { where: { mid: this.ctx.material.id } });
  97. for (const node of info.nodeList) {
  98. await this.ctx.service.materialExponentShard.calcMaterialExTp(transaction, node.ex_calc ? JSON.parse(node.ex_calc) : null, this.ctx.material.id, null, node.id);
  99. }
  100. [result.ex_tp, result.ex_tax_tp] = await this.calcTpByMaterialExponentNode(transaction, this.ctx.material.id);
  101. result.exponentShardData = await transaction.select(this.ctx.service.materialExponentShard.tableName, {where: {mid: this.ctx.material.id}});
  102. result.nodeData = await transaction.select(this.ctx.service.materialExponentNode.tableName, {where: {mid: this.ctx.material.id}});
  103. }
  104. break;
  105. case materialConst.exponent_status.self_noNode:
  106. await transaction.delete(this.ctx.service.materialExponentShard.tableName, { me_id: id });
  107. if (meInfo.is_summary === materialConst.is_summary.yes) {
  108. info.materialStages = await transaction.select(this.ctx.service.materialStage.tableName, { where: { mid: this.ctx.material.id } });
  109. for (const ms of info.materialStages) {
  110. await this.ctx.service.materialExponentShard.calcMaterialExTp(transaction, ms.ex_calc ? JSON.parse(ms.ex_calc) : null, this.ctx.material.id, ms.id);
  111. }
  112. [result.ex_tp, result.ex_tax_tp] = await this.calcTpByMaterialStageExponent(transaction, this.ctx.material.id);
  113. result.exponentShardData = await transaction.select(this.ctx.service.materialExponentShard.tableName, { where: { mid: this.ctx.material.id } });
  114. result.stageData = await transaction.select(this.ctx.service.materialStage.tableName, { where: { mid: this.ctx.material.id } });
  115. }
  116. break;
  117. case materialConst.exponent_status.self_node:
  118. await transaction.delete(this.ctx.service.materialExponentShard.tableName, { me_id: id });
  119. if (meInfo.is_summary === materialConst.is_summary.yes) {
  120. info.materialStages = await transaction.select(this.ctx.service.materialStage.tableName, { where: { mid: this.ctx.material.id } });
  121. info.materialNodes = await transaction.select(this.ctx.service.materialExponentNode.tableName, { where: { mid: this.ctx.material.id } });
  122. for (const ms of info.materialStages) {
  123. const nodeList = this._.filter(info.materialNodes, { ms_id: ms.id });
  124. for (const node of nodeList) {
  125. await this.ctx.service.materialExponentShard.calcMaterialExTp(transaction, node.ex_calc ? JSON.parse(node.ex_calc) : null, this.ctx.material.id, null, node.id);
  126. }
  127. await this.ctx.service.materialExponentNode.calcStageExTpByNode(transaction, this.ctx.material.id, ms.id);
  128. }
  129. [result.ex_tp, result.ex_tax_tp] = await this.calcTpByMaterialStageExponent(transaction, this.ctx.material.id);
  130. result.exponentShardData = await transaction.select(this.ctx.service.materialExponentShard.tableName, { where: { mid: this.ctx.material.id } });
  131. result.stageData = await transaction.select(this.ctx.service.materialStage.tableName, { where: { mid: this.ctx.material.id } });
  132. result.nodeData = await transaction.select(this.ctx.service.materialExponentNode.tableName, { where: { mid: this.ctx.material.id } });
  133. }
  134. break;
  135. default: break;
  136. }
  137. await transaction.commit();
  138. return result;
  139. } catch (err) {
  140. await transaction.rollback();
  141. throw err;
  142. }
  143. }
  144. /**
  145. * 修改指数清单信息
  146. * @param {Object} data 工料内容
  147. * @return {void}
  148. */
  149. async save(data, ms_id = null, mn_id = null) {
  150. if (!this.ctx.tender || !this.ctx.material) {
  151. throw '数据错误';
  152. }
  153. delete data.in_time;
  154. // delete data.m_tp;
  155. // 判断是否可修改
  156. // 判断t_type是否为费用
  157. const transaction = await this.db.beginTransaction();
  158. try {
  159. const result = {};
  160. const info = {};
  161. switch (this.ctx.material.exponentStatus) {
  162. case materialConst.exponent_status.shared_noNode:
  163. await transaction.update(this.tableName, data);
  164. [result.ex_tp, result.ex_tax_tp, result.ex_expr] = await this.calcMaterialExTp(transaction);
  165. break;
  166. case materialConst.exponent_status.shared_node:
  167. if (!mn_id) {
  168. throw '分项参数有误';
  169. }
  170. [info.needUp, info.needCalc] = await this._updateOneExponentData(transaction, data, null, mn_id);
  171. await this.ctx.service.materialExponentShard.update(transaction, data, null, mn_id, info.needCalc);
  172. [result.ex_tp, result.ex_tax_tp] = await this.calcTpByMaterialExponentNode(transaction, this.ctx.material.id);
  173. if (info.needUp) {
  174. result.exponentData = await transaction.select(this.tableName, { where: { id: data.id } });
  175. }
  176. result.exponentShardData = await transaction.select(this.ctx.service.materialExponentShard.tableName, { where: { mid: this.ctx.material.id, mn_id, me_id: data.id } });
  177. result.nodeData = info.needCalc ? await transaction.select(this.ctx.service.materialExponentNode.tableName, { where: { mid: this.ctx.material.id } }) :
  178. await transaction.select(this.ctx.service.materialExponentNode.tableName, { where: { mid: this.ctx.material.id, id: mn_id } });
  179. break;
  180. case materialConst.exponent_status.self_noNode:
  181. if (!ms_id) {
  182. throw '期参数有误';
  183. }
  184. [info.needUp, info.needCalc] = await this._updateOneExponentData(transaction, data, ms_id);
  185. await this.ctx.service.materialExponentShard.update(transaction, data, ms_id, null, info.needCalc);
  186. [result.ex_tp, result.ex_tax_tp] = await this.calcTpByMaterialStageExponent(transaction, this.ctx.material.id);
  187. if (info.needUp) {
  188. result.exponentData = await transaction.select(this.tableName, { where: { id: data.id } });
  189. }
  190. result.exponentShardData = await transaction.select(this.ctx.service.materialExponentShard.tableName, { where: { mid: this.ctx.material.id, ms_id, me_id: data.id } });
  191. result.stageData = info.needCalc ? await transaction.select(this.ctx.service.materialStage.tableName, { where: { mid: this.ctx.material.id } }) :
  192. await transaction.select(this.ctx.service.materialStage.tableName, { where: { mid: this.ctx.material.id, id: ms_id } });
  193. break;
  194. case materialConst.exponent_status.self_node:
  195. if (!ms_id && !mn_id) {
  196. throw '参数有误';
  197. }
  198. [info.needUp, info.needCalc] = await this._updateOneExponentData(transaction, data, ms_id, mn_id);
  199. await this.ctx.service.materialExponentShard.update(transaction, data, ms_id, mn_id, info.needCalc);
  200. [result.ex_tp, result.ex_tax_tp] = await this.calcTpByMaterialStageExponent(transaction, this.ctx.material.id);
  201. if (info.needUp) {
  202. result.exponentData = await transaction.select(this.tableName, { where: { id: data.id } });
  203. }
  204. result.exponentShardData = await transaction.select(this.ctx.service.materialExponentShard.tableName, { where: { mid: this.ctx.material.id, ms_id, mn_id, me_id: data.id } });
  205. result.stageData = info.needCalc ? await transaction.select(this.ctx.service.materialStage.tableName, { where: { mid: this.ctx.material.id } }) :
  206. await transaction.select(this.ctx.service.materialStage.tableName, { where: { mid: this.ctx.material.id, id: ms_id } });
  207. result.nodeData = info.needCalc ? await transaction.select(this.ctx.service.materialExponentNode.tableName, { where: { mid: this.ctx.material.id } }) :
  208. await transaction.select(this.ctx.service.materialExponentNode.tableName, { where: { mid: this.ctx.material.id, id: mn_id } });
  209. break;
  210. default: break;
  211. }
  212. await transaction.commit();
  213. return result;
  214. } catch (err) {
  215. await transaction.rollback();
  216. throw err;
  217. }
  218. }
  219. async _updateOneExponentData(transaction, data, ms_id = null, mn_id = null) {
  220. // 当以下值和exponent值不相同时,需要同步更新最新的计算表达式和金额到stage表里,无需更新到exponentShard表
  221. const updateColsArray = ['symbol', 'symbol_desc', 'code', 'basic_price', 'is_summary', 'basic_times'];
  222. const updateCalcArray = ['weight_num', 'basic_price', 'is_summary'];
  223. let needCalc = false;
  224. let needUp = false;
  225. const meInfo = await this.getDataById(data.id);
  226. if (!meInfo) {
  227. throw '指数工料数据不存在';
  228. }
  229. const updateData = {};
  230. for (const uc of updateColsArray) {
  231. if (data[uc] !== undefined && data[uc] !== meInfo[uc]) {
  232. if (updateCalcArray.includes(uc)) {
  233. needCalc = true;
  234. }
  235. needUp = true;
  236. updateData[uc] = data[uc];
  237. }
  238. }
  239. // 判断updateData不为空时,不需要更新
  240. if (needUp) {
  241. updateData.id = data.id;
  242. await transaction.update(this.tableName, updateData);
  243. }
  244. if (needCalc) {
  245. if (mn_id) {
  246. await this.ctx.service.materialExponentShard.calcMaterialAllExTpByNode(transaction, this.ctx.material.id, mn_id);
  247. } else if (ms_id && !mn_id) {
  248. await this.ctx.service.materialExponentShard.calcMaterialAllExTpByStage(transaction, this.ctx.material.id, ms_id);
  249. }
  250. }
  251. return [needUp, needCalc];
  252. }
  253. /**
  254. * 复制粘贴指数清单
  255. * @param {Object} data 工料内容
  256. * @return {void}
  257. */
  258. async saveDatas(datas, ms_id = null, mn_id = null) {
  259. if (!this.ctx.tender || !this.ctx.material) {
  260. throw '数据错误';
  261. }
  262. // 判断是否可修改
  263. // 判断t_type是否为费用
  264. const transaction = await this.db.beginTransaction();
  265. try {
  266. const result = { ex_tp: this.ctx.material.ex_tp };
  267. const info = {};
  268. if (this.ctx.material.exponentStatus !== materialConst.exponent_status.shared_noNode) {
  269. info.meList = await transaction.select(this.tableName, { where: { id: this._.map(datas, 'id') } });
  270. }
  271. switch (this.ctx.material.exponentStatus) {
  272. case materialConst.exponent_status.shared_noNode:
  273. await transaction.updateRows(this.tableName, datas);
  274. [result.ex_tp, result.ex_tax_tp, result.ex_expr] = await this.calcMaterialExTp(transaction);
  275. result.exponentData = await transaction.select(this.tableName, { where: { id: this._.map(datas, 'id') } });
  276. break;
  277. case materialConst.exponent_status.shared_node:
  278. if (!mn_id) {
  279. throw '参数有误';
  280. }
  281. info.needCalc = await this._updateMoreExponentData(transaction, datas, result, info.meList, null, mn_id);
  282. if (info.needCalc) await this.ctx.service.materialExponentShard.calcMaterialAllExTpByNode(transaction, this.ctx.material.id);
  283. [result.ex_tp, result.ex_tax_tp] = await this.calcTpByMaterialExponentNode(transaction, this.ctx.material.id);
  284. result.nodeData = info.needCalc ? await transaction.select(this.ctx.service.materialExponentNode.tableName, { where: { mid: this.ctx.material.id } }) :
  285. await transaction.select(this.ctx.service.materialExponentNode.tableName, { where: { mid: this.ctx.material.id, id: mn_id } });
  286. break;
  287. case materialConst.exponent_status.self_noNode:
  288. if (!ms_id) {
  289. throw '参数有误';
  290. }
  291. info.needCalc = await this._updateMoreExponentData(transaction, datas, result, info.meList, ms_id, null);
  292. if (info.needCalc) await this.ctx.service.materialExponentShard.calcMaterialAllExTpByStage(transaction, this.ctx.material.id);
  293. [result.ex_tp, result.ex_tax_tp] = await this.calcTpByMaterialStageExponent(transaction, this.ctx.material.id);
  294. result.stageData = info.needCalc ? await transaction.select(this.ctx.service.materialStage.tableName, { where: { mid: this.ctx.material.id } }) :
  295. await transaction.select(this.ctx.service.materialStage.tableName, { where: { mid: this.ctx.material.id, id: ms_id } });
  296. break;
  297. case materialConst.exponent_status.self_node:
  298. if (!mn_id && !ms_id) {
  299. throw '参数有误';
  300. }
  301. info.needCalc = await this._updateMoreExponentData(transaction, datas, result, info.meList, null, mn_id);
  302. if (info.needCalc) await this.ctx.service.materialExponentShard.calcMaterialAllExTpByNode(transaction, this.ctx.material.id);
  303. [result.ex_tp, result.ex_tax_tp] = await this.calcTpByMaterialStageExponent(transaction, this.ctx.material.id);
  304. result.nodeData = info.needCalc ? await transaction.select(this.ctx.service.materialExponentNode.tableName, { where: { mid: this.ctx.material.id } }) :
  305. await transaction.select(this.ctx.service.materialExponentNode.tableName, { where: { mid: this.ctx.material.id, id: mn_id } });
  306. result.stageData = info.needCalc ? await transaction.select(this.ctx.service.materialStage.tableName, { where: { mid: this.ctx.material.id } }) :
  307. await transaction.select(this.ctx.service.materialStage.tableName, { where: { mid: this.ctx.material.id, id: ms_id } });
  308. break;
  309. default: break;
  310. }
  311. await transaction.commit();
  312. return result;
  313. } catch (err) {
  314. await transaction.rollback();
  315. throw err;
  316. }
  317. }
  318. async _updateMoreExponentData(transaction, datas, result, meList, ms_id = null, mn_id = null) {
  319. // 判断data值是否需要更新materialExponent和materialExponentShard
  320. const mesCondition = { me_id: this._.map(datas, 'id') };
  321. if (ms_id !== null) mesCondition.ms_id = ms_id;
  322. if (mn_id !== null) mesCondition.mn_id = mn_id;
  323. const mesList = await transaction.select(this.ctx.service.materialExponentShard.tableName, { where: mesCondition });
  324. const materialExponentColArray = ['symbol', 'symbol_desc', 'code', 'basic_price', 'is_summary', 'basic_times'];
  325. const materialExponentShardColArray = ['weight_num', 'm_price', 'remark'];
  326. const updateCalcArray = ['weight_num', 'basic_price', 'm_price', 'is_summary'];
  327. const updateMeArray = [];
  328. const udpateMseArray = [];
  329. let needCalc = false;
  330. for (const data of datas) {
  331. const meInfo = this._.find(meList, { id: data.id });
  332. const mseInfo = this._.find(mesList, { me_id: data.id });
  333. for (const uc of materialExponentColArray) {
  334. if (data[uc] !== undefined && data[uc] !== meInfo[uc]) {
  335. const updateMe = this._.find(updateMeArray, { id: meInfo.id });
  336. if (!updateMe) {
  337. const newUpdateMe = { id: meInfo.id };
  338. newUpdateMe[uc] = data[uc];
  339. updateMeArray.push(newUpdateMe);
  340. } else {
  341. updateMe[uc] = data[uc];
  342. }
  343. if (updateCalcArray.includes(uc)) {
  344. needCalc = true;
  345. }
  346. }
  347. }
  348. for (const uc of materialExponentShardColArray) {
  349. if (data[uc] !== undefined && data[uc] !== mseInfo[uc]) {
  350. const updateMse = this._.find(udpateMseArray, { id: mseInfo.id });
  351. if (!updateMse) {
  352. const newUpdateMse = { id: mseInfo.id };
  353. newUpdateMse[uc] = data[uc];
  354. udpateMseArray.push(newUpdateMse);
  355. } else {
  356. updateMse[uc] = data[uc];
  357. }
  358. if (updateCalcArray.includes(uc)) {
  359. needCalc = true;
  360. }
  361. }
  362. }
  363. }
  364. console.log(updateMeArray, udpateMseArray);
  365. if (updateMeArray.length > 0) {
  366. await transaction.updateRows(this.tableName, updateMeArray);
  367. result.exponentData = await transaction.select(this.tableName, { where: { id: this._.map(updateMeArray, 'id') } });
  368. }
  369. if (udpateMseArray.length > 0) {
  370. await transaction.updateRows(this.ctx.service.materialExponentShard.tableName, udpateMseArray);
  371. // const condition = mn_id ? { mid: this.ctx.material.id, mn_id } : { mid: this.ctx.material.id, ms_id };
  372. result.exponentShardData = await transaction.select(this.ctx.service.materialExponentShard.tableName, { where: { id: this._.map(udpateMseArray, 'id') } });
  373. }
  374. return needCalc;
  375. }
  376. /**
  377. * 旧数据补充定值和历史数据
  378. * @returns {Promise<void>}
  379. */
  380. async addOldData() {
  381. if (!this.ctx.tender || !this.ctx.material) {
  382. throw '数据错误';
  383. }
  384. const transaction = await this.db.beginTransaction();
  385. try {
  386. // 先获取第一期的mid
  387. const first_material = await this.ctx.service.material.getDataByCondition({
  388. tid: this.ctx.tender.id,
  389. order: 1,
  390. });
  391. const insert_data = {
  392. tid: this.ctx.tender.id,
  393. mid: first_material.id,
  394. type: materialConst.ex_type[0].value,
  395. symbol: 'X',
  396. symbol_desc: '非可调因子',
  397. code: 'A',
  398. weight_num: 0,
  399. is_summary: materialConst.is_summary.yes,
  400. in_time: new Date(),
  401. };
  402. const result = await transaction.insert(this.tableName, insert_data);
  403. // 获取所有期数据
  404. const materials = await this.ctx.service.material.getAllDataByCondition({ where: {
  405. tid: this.ctx.tender.id,
  406. } });
  407. // const qi_order = high_material.status === auditConst.status.uncheck || high_material.status === auditConst.status.checkNo ? high_material.order - 1 : high_material;
  408. // const qi_order = high_material.status === auditConst.status.uncheck || high_material.status === auditConst.status.checkNo ? high_material.order - 1 : high_material;
  409. const insert_history_data = [];
  410. const insert_stage_data = [];
  411. for (const m of materials) {
  412. if (m.is_stage_self && m.is_new_exponent) {
  413. const materialStages = await this.ctx.service.materialStage.getAllDataByCondition({ where: {
  414. tid: this.ctx.tender.id,
  415. mid: m.id,
  416. } });
  417. for (const ms of materialStages) {
  418. const one_stage_insert = {
  419. tid: this.ctx.tender.id,
  420. mid: m.id,
  421. ms_id: ms.id,
  422. me_id: result.insertId,
  423. type: materialConst.ex_type[0].value,
  424. };
  425. insert_stage_data.push(one_stage_insert);
  426. }
  427. } else {
  428. const one_insert = {
  429. tid: this.ctx.tender.id,
  430. mid: first_material.id,
  431. order: m.order,
  432. me_id: result.insertId,
  433. type: materialConst.ex_type[0].value,
  434. weight_num: 0,
  435. is_summary: materialConst.is_summary.yes,
  436. };
  437. insert_history_data.push(one_insert);
  438. }
  439. }
  440. // for (let i = 1; i <= qi_order; i++) {
  441. // const one_insert = {
  442. // tid: this.ctx.tender.id,
  443. // mid: first_material.id,
  444. // order: i,
  445. // me_id: result.insertId,
  446. // type: materialConst.ex_type[0].value,
  447. // weight_num: 0,
  448. // is_summary: materialConst.is_summary.yes,
  449. // };
  450. // insert_history_data.push(one_insert);
  451. // }
  452. if (insert_history_data.length > 0) await transaction.insert(this.ctx.service.materialExponentHistory.tableName, insert_history_data);
  453. if (insert_stage_data.length > 0) await transaction.insert(this.ctx.service.materialExponentShard.tableName, insert_stage_data);
  454. await transaction.commit();
  455. } catch (err) {
  456. console.log(err);
  457. await transaction.rollback();
  458. throw err;
  459. }
  460. }
  461. // 更改计算总指数金额并返回值和公式
  462. async calcMaterialExTp(transaction, ex_calc = (this.ctx.material.ex_calc ? JSON.parse(this.ctx.material.ex_calc) : null), mid = null, decimal = (this.ctx.material.exponent_decimal ? this.ctx.material.exponent_decimal : materialConst.exponent_decimal), rate = (this.ctx.material.rate ? this.ctx.material.exponent_rate : 10)) {
  463. let basic_calc = 0;
  464. // let basic_expr = 0;
  465. if (ex_calc) {
  466. for (const calc of ex_calc) {
  467. if (calc.select) {
  468. if (calc.code === 'zdy' && calc.result) {
  469. basic_calc = this.ctx.helper.add(basic_calc, calc.result);
  470. // basic_expr = calc.value;
  471. } else {
  472. basic_calc = this.ctx.helper.add(basic_calc, calc.value);
  473. // basic_expr = this.ctx.helper.add(basic_expr, calc.value);
  474. }
  475. }
  476. }
  477. }
  478. let expr = basic_calc + '*[';
  479. const exponentList = await transaction.select(this.tableName, { where: { tid: this.ctx.tender.id, is_summary: materialConst.is_summary.yes } });
  480. let sumByChange = 0;
  481. let constant = 0;
  482. for (const ex of exponentList) {
  483. if (ex.type === materialConst.ex_type[0].value) {
  484. constant = ex.weight_num ? ex.weight_num : 0;
  485. expr += constant.toString();
  486. } else if (ex.type === materialConst.ex_type[1].value) {
  487. const calc_num = ex.basic_price > 0 ? this.ctx.helper.mul(ex.weight_num, this.ctx.helper.div(ex.m_price, ex.basic_price)) : 0;
  488. const change = calc_num ? this.ctx.helper.round(calc_num, decimal.qty) : 0;
  489. // const change = ex.calc_num ? ex.calc_num : 0;
  490. expr = expr + (change !== 0 ? '+' + ex.weight_num.toString() + '*(' + ex.m_price.toString() + '/' + ex.basic_price.toString() + ')' : '');
  491. sumByChange = this.ctx.helper.add(sumByChange, change);
  492. }
  493. }
  494. expr += '-1]';
  495. expr = constant !== 0 ? expr : null;
  496. const ex_tp = constant !== 0 ? this.ctx.helper.round(this.ctx.helper.mul(basic_calc, this.ctx.helper.sub(this.ctx.helper.add(constant, sumByChange), 1)), decimal.tp) : null;
  497. const ex_tax_tp = ex_tp !== null ? this.ctx.helper.round(this.ctx.helper.mul(ex_tp, 1 + rate / 100), decimal.tp) : null;
  498. await transaction.update(this.ctx.service.material.tableName, {
  499. id: mid ? mid : this.ctx.material.id,
  500. ex_tp,
  501. ex_tax_tp,
  502. ex_expr: expr,
  503. ex_calc: JSON.stringify(ex_calc),
  504. });
  505. console.log(ex_tp, expr);
  506. if (!mid) {
  507. // 找出当前人并更新tp_data
  508. const tp_data = await this.ctx.service.materialAudit.getTpData(transaction, this.ctx.material.id);
  509. if (this.ctx.material.status === auditConst.status.uncheck || this.ctx.material.status === auditConst.status.checkNo) {
  510. await transaction.update(this.ctx.service.material.tableName, {
  511. id: this.ctx.material.id,
  512. tp_data: JSON.stringify(tp_data),
  513. });
  514. } else if (this.ctx.material.curAuditor) {
  515. await transaction.update(this.ctx.service.materialAudit.tableName, {
  516. id: this.ctx.material.curAuditor.id,
  517. tp_data: JSON.stringify(tp_data),
  518. });
  519. }
  520. }
  521. return [ex_tp, ex_tax_tp, expr];
  522. }
  523. /**
  524. * 更新新一期的现行价格指数,并返回指数总金额和公式
  525. * @param transaction
  526. * @param tid
  527. * @param mid
  528. * @returns {Promise<number>}
  529. */
  530. async updateNewMaterial(transaction, mid, ctx, stage_id, ex_calc, decimal, rate) {
  531. const stage_list = await ctx.service.stage.getStageMsgByStageId(stage_id);
  532. const calcBase = await ctx.service.stage.getMaterialCalcBase(stage_list, ctx.tender.info);
  533. const old_ex_calc = ex_calc ? JSON.parse(ex_calc) : null;
  534. const new_ex_calc = this._.cloneDeep(materialConst.ex_calc);
  535. for (const bq of new_ex_calc) {
  536. const calc = this._.find(calcBase, { code: bq.code }) || this._.find(calcBase, { code: 'bqwc' });
  537. const oldcalc = old_ex_calc ? this._.find(old_ex_calc, { code: bq.code }) : null;
  538. bq.value = calc.value;
  539. bq.select = oldcalc ? oldcalc.select : bq.select;
  540. }
  541. await this.calcMaterialExTp(transaction, new_ex_calc, mid, decimal, rate);
  542. return new_ex_calc;
  543. }
  544. async calcTpByMaterialExponentNode(transaction, mid) {
  545. // 汇总到material上
  546. const materialNodes = await transaction.select(this.ctx.service.materialExponentNode.tableName, { where: { mid } });
  547. let ex_tax_tp = 0;
  548. let total_ex_tp = 0;
  549. for (const ms of materialNodes) {
  550. ex_tax_tp = this.ctx.helper.add(ex_tax_tp, ms.ex_tax_tp);
  551. total_ex_tp = this.ctx.helper.add(total_ex_tp, ms.ex_tp || 0);
  552. }
  553. // if (updateTaxTps.length > 0) await transaction.updateRows(this.ctx.service.materialStage.tableName, updateTaxTps);
  554. await transaction.update(this.ctx.service.material.tableName, {
  555. id: mid,
  556. ex_tp: total_ex_tp,
  557. ex_tax_tp,
  558. });
  559. return [total_ex_tp, ex_tax_tp];
  560. }
  561. async calcTpByMaterialStageExponent(transaction, mid) {
  562. // 汇总到material上
  563. const materialStages = await transaction.select(this.ctx.service.materialStage.tableName, { where: { mid } });
  564. let ex_tax_tp = 0;
  565. let total_ex_tp = 0;
  566. for (const ms of materialStages) {
  567. ex_tax_tp = this.ctx.helper.add(ex_tax_tp, ms.ex_tax_tp);
  568. total_ex_tp = this.ctx.helper.add(total_ex_tp, ms.ex_tp || 0);
  569. }
  570. // if (updateTaxTps.length > 0) await transaction.updateRows(this.ctx.service.materialStage.tableName, updateTaxTps);
  571. await transaction.update(this.ctx.service.material.tableName, {
  572. id: mid,
  573. ex_tp: total_ex_tp,
  574. ex_tax_tp,
  575. });
  576. return [total_ex_tp, ex_tax_tp];
  577. }
  578. async resetDecimal(transaction, decimal) {
  579. const exponentList = await transaction.select(this.tableName, { where: { tid: this.ctx.tender.id } });
  580. const exponentShardList = await transaction.select(this.ctx.service.materialExponentShard.tableName, { where: { mid: this.ctx.material.id } });
  581. const updateArray = [];
  582. const updateStageArray = [];
  583. const upColArray = ['basic_price', 'm_price'];
  584. // const qtyColArray = ['calc_num'];
  585. for (const ex of exponentList) {
  586. for (const col of upColArray) {
  587. if (ex[col] && ex[col] !== this.ctx.helper.round(ex[col], decimal.up)) {
  588. const upex = this._.find(updateArray, { id: ex.id });
  589. if (upex) {
  590. upex[col] = this.ctx.helper.round(ex[col], decimal.up);
  591. } else {
  592. const insertEx = {
  593. id: ex.id,
  594. };
  595. insertEx[col] = this.ctx.helper.round(ex[col], decimal.up);
  596. updateArray.push(insertEx);
  597. }
  598. }
  599. }
  600. // for (const col of qtyColArray) {
  601. // if (ex[col] && ex[col] !== this.ctx.helper.round(ex[col], decimal.qty)) {
  602. // const upex = this._.find(updateArray, { id: ex.id });
  603. // if (upex) {
  604. // upex[col] = this.ctx.helper.round(ex[col], decimal.qty);
  605. // } else {
  606. // const insertEx = {
  607. // id: ex.id,
  608. // };
  609. // insertEx[col] = this.ctx.helper.round(ex[col], decimal.qty);
  610. // updateArray.push(insertEx);
  611. // }
  612. // }
  613. // }
  614. }
  615. for (const ex of exponentShardList) {
  616. if (ex.m_price && ex.m_price !== this.ctx.helper.round(ex.m_price, decimal.up)) {
  617. const insertEx = {
  618. id: ex.id,
  619. };
  620. insertEx.m_price = this.ctx.helper.round(ex.m_price, decimal.up);
  621. updateStageArray.push(insertEx);
  622. }
  623. }
  624. if (updateArray.length > 0) await transaction.updateRows(this.tableName, updateArray);
  625. if (updateStageArray.length > 0) await transaction.updateRows(this.ctx.service.materialExponentShard.tableName, updateStageArray);
  626. }
  627. }
  628. return MaterialExponent;
  629. };