stage_change.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. 'use strict';
  2. /**
  3. * 期 - 变更数据
  4. *
  5. * @author Mai
  6. * @date
  7. * @version
  8. */
  9. const defaultPid = -1; // 非pid
  10. const audit = require('../const/audit');
  11. module.exports = app => {
  12. class StageChange extends app.BaseService {
  13. /**
  14. * 构造函数
  15. *
  16. * @param {Object} ctx - egg全局变量
  17. * @return {void}
  18. */
  19. constructor(ctx) {
  20. super(ctx);
  21. this.tableName = 'stage_change';
  22. }
  23. /**
  24. * 查询 调用的变更令 最新数据
  25. * @param {Number} tid - 标段id
  26. * @param {Number} sid - 期id
  27. * @param {Number} lid - 台账节点id
  28. * @param {Number} pid - 部位明细id
  29. * @returns {Promise<*>}
  30. */
  31. async getLastestStageData(tid, sid, lid, pid) {
  32. const sql = 'SELECT c.* FROM ' + this.tableName + ' As c ' +
  33. ' INNER JOIN ( ' +
  34. ' SELECT MAX(`stimes`) As `stimes`, MAX(`sorder`) As `sorder`, `lid`, `pid`, `sid` From ' + this.tableName +
  35. ' WHERE tid = ? And sid = ? And lid = ? And pid = ?' +
  36. ' GROUP By `lid`, `pid`' +
  37. ' ) As m ' +
  38. ' ON c.stimes = m.stimes And c.sorder = m.sorder And c.lid = m.lid And c.pid = m.pid And c.`sid` = m.`sid`';
  39. const sqlParam = [tid, sid, lid, pid ? pid : -1];
  40. return await this.db.query(sql, sqlParam);
  41. }
  42. /**
  43. * 查询 调用的变更令 某轮 某人的数据
  44. * @param {Number} tid - 标段id
  45. * @param {Number} sid - 期id
  46. * @param {Number} times - 第几轮
  47. * @param {Number} order - 第几人
  48. * @param {Number} lid - 台账节点id
  49. * @param {Number} pid - 部位明细id
  50. * @returns {Promise<*>}
  51. */
  52. async getAuditorStageData(tid, sid, times, order, lid, pid) {
  53. const sql = 'SELECT c.* FROM ' + this.tableName + ' As c ' +
  54. ' INNER JOIN ( ' +
  55. ' SELECT MAX(`stimes`) As `stimes`, MAX(`sorder`) As `sorder`, `lid`, `pid`, `sid` From ' + this.tableName +
  56. ' WHERE tid = ? And sid = ? And (`stimes` < ? OR (`stimes` = ? AND `sorder` <= ?)) And lid = ? And pid = ?' +
  57. ' GROUP By `lid`, `pid`' +
  58. ' ) As m ' +
  59. ' ON c.stimes = m.stimes And c.sorder = m.sorder And c.lid = m.lid And c.pid = m.pid And c.`sid` = m.`sid`';
  60. const sqlParam = [tid, sid, times, times, order, lid, pid ? pid : -1];
  61. return await this.db.query(sql, sqlParam);
  62. }
  63. /**
  64. * 台账,调用变更令
  65. *
  66. * @param {Object} bills - 台账节点数据
  67. * @param {Array} changes - 调用的变更令
  68. * @returns {Promise<void>}
  69. */
  70. async billsChange(bills, changes) {
  71. const self = this;
  72. function getNewChange(cid, cbid, times, order, qty) {
  73. return {
  74. tid: self.ctx.tender.id,
  75. sid: self.ctx.stage.id,
  76. lid: bills.id,
  77. pid: -1,
  78. cid: cid,
  79. cbid: cbid,
  80. stimes: times,
  81. sorder: order,
  82. qty: qty
  83. }
  84. }
  85. const ledgerBills = await this.ctx.service.ledger.getDataById(bills.id);
  86. if (!ledgerBills || ledgerBills.tender_id !== this.ctx.tender.id) {
  87. throw '提交数据错误';
  88. }
  89. const precision = this.ctx.helper.findPrecision(this.ctx.tender.info.precision, ledgerBills.unit);
  90. // 获取原变更令
  91. const oldChanges = await this.getLastestStageData(this.ctx.tender.id, this.ctx.stage.id, bills.id, -1);
  92. // 获取更新数据
  93. const updateChanges = [], newChanges = [];
  94. let billsQty = 0;
  95. for (const oc of oldChanges) {
  96. const nc = this._.find(changes, {cid: oc.cid, cbid: oc.cbid});
  97. if (!nc || nc.qty !== oc.qty) {
  98. const qty = nc ? this.round(nc.qty, precision.value) : null;
  99. const change = getNewChange(oc.cid, oc.cbid, this.ctx.stage.curTimes, this.ctx.stage.curOrder, qty);
  100. billsQty = this.ctx.helper.add(billsQty, change.qty);
  101. if (oc.stimes === this.ctx.stage.curTimes && oc.sorder === this.ctx.stage.curOrder) {
  102. change.id = oc.id;
  103. updateChanges.push(change);
  104. } else {
  105. newChanges.push(change);
  106. }
  107. } else {
  108. billsQty = this.ctx.helper.add(billsQty, oc.qty);
  109. }
  110. }
  111. for (const c of changes) {
  112. const nc = this._.find(oldChanges, {cid: c.cid, cbid: c.cbid});
  113. if (!nc) {
  114. const change = getNewChange(c.cid, c.cbid, this.ctx.stage.curTimes, this.ctx.stage.curOrder, this.round(c.qty, precision.value));
  115. billsQty = this.ctx.helper.add(billsQty, change.qty);
  116. newChanges.push(change);
  117. }
  118. }
  119. // 更新数据
  120. const transaction = await this.db.beginTransaction();
  121. try {
  122. if (newChanges.length > 0) {
  123. await transaction.insert(this.tableName, newChanges);
  124. }
  125. for (const c of updateChanges) {
  126. await transaction.update(this.tableName, c);
  127. }
  128. const stageBills = await this.ctx.service.stageBills.getLastestStageData(this.ctx.tender.id, this.ctx.stage.id, bills.id);
  129. await this.ctx.service.stageBills.updateStageBillsQty(transaction, ledgerBills, stageBills, { qc_qty: billsQty });
  130. await transaction.commit();
  131. } catch (err) {
  132. await transaction.rollback();
  133. throw err;
  134. }
  135. const result = await this.ctx.service.stageBills.getLastestStageData(this.ctx.tender.id, this.ctx.stage.id, [bills.id]);
  136. return { bills: result };
  137. }
  138. /**
  139. * 部位明细,调用变更令
  140. *
  141. * @param {Object} pos - 部位明细数据
  142. * @param {Array} changes - 调用的变更令
  143. * @returns {Promise<{}>}
  144. */
  145. async posChange(pos, changes) {
  146. const self = this;
  147. function getNewChange(cid, cbid, times, order, qty) {
  148. return {
  149. tid: self.ctx.tender.id,
  150. sid: self.ctx.stage.id,
  151. lid: pos.lid,
  152. pid: pos.id,
  153. cid: cid,
  154. cbid: cbid,
  155. stimes: times,
  156. sorder: order,
  157. qty: qty
  158. }
  159. }
  160. const ledgerBills = await this.ctx.service.ledger.getDataById(pos.lid);
  161. if (!ledgerBills || ledgerBills.tender_id !== this.ctx.tender.id) {
  162. throw '提交数据错误';
  163. }
  164. const precision = this.ctx.helper.findPrecision(this.ctx.tender.info.precision, ledgerBills.unit);
  165. // 获取原变更令
  166. const oldChanges = await this.getLastestStageData(this.ctx.tender.id, this.ctx.stage.id, pos.lid, pos.id);
  167. const updateChanges = [], newChanges = [];
  168. let posQty = 0;
  169. for (const oc of oldChanges) {
  170. const nc = this._.find(changes, {cid: oc.cid, cbid: oc.cbid});
  171. if (!nc || nc.qty !== oc.qty) {
  172. const qty = nc ? this.round(nc.qty, precision.value) : null;
  173. const change = getNewChange(oc.cid, oc.cbid, this.ctx.stage.curTimes, this.ctx.stage.curOrder, qty);
  174. posQty = this.ctx.helper.add(posQty, change.qty);
  175. if (oc.stimes === this.ctx.stage.curTimes && oc.sorder === this.ctx.stage.curOrder) {
  176. change.id = oc.id;
  177. updateChanges.push(change);
  178. } else {
  179. newChanges.push(change);
  180. }
  181. } else {
  182. posQty = this.ctx.helper.add(posQty, oc.qty);
  183. }
  184. }
  185. for (const c of changes) {
  186. const nc = this._.find(oldChanges, {cid: c.cid, cbid: c.cbid});
  187. if (!nc) {
  188. const change = getNewChange(c.cid, c.cbid, this.ctx.stage.curTimes, this.ctx.stage.curOrder, this.round(c.qty, precision.value));
  189. posQty = this.ctx.helper.add(posQty, change.qty);
  190. newChanges.push(change);
  191. }
  192. }
  193. // 更新数据
  194. const transaction = await this.db.beginTransaction();
  195. try {
  196. if (newChanges.length > 0) {
  197. await transaction.insert(this.tableName, newChanges);
  198. }
  199. for (const c of updateChanges) {
  200. await transaction.update(this.tableName, c);
  201. }
  202. await this.ctx.service.stagePos.updateChangeQuantity(transaction, pos, posQty);
  203. await transaction.commit();
  204. } catch (err) {
  205. await transaction.rollback();
  206. throw err;
  207. }
  208. // 获取返回数据
  209. try {
  210. const data = {};
  211. data.bills = await this.ctx.service.stageBills.getLastestStageData(this.ctx.tender.id, this.ctx.stage.id, [pos.lid]);
  212. data.pos = await this.ctx.service.stagePos.getLastestStageData(this.ctx.tender.id, this.ctx.stage.id, [pos.id]);
  213. return data;
  214. } catch(err) {
  215. throw '获取数据错误,请刷新页面';
  216. }
  217. }
  218. /**
  219. * 获取 变更令 - 变更清单 使用情况
  220. * @param {Number} sid - 查询期id
  221. * @param {uuid} cid - 变更令id
  222. * @returns {Promise<void>}
  223. */
  224. async getUsedData(tid, cid) {
  225. const lastStage = await this.ctx.service.stage.getLastestStage(tid, true);
  226. let filter;
  227. if (lastStage.id === this.ctx.stage.id) {
  228. filter = this.db.format(' And (s.`order` < ? || (s.`order` = ? And sChange.`stimes` <= ? And sChange.`sorder` <= ?))',
  229. [lastStage.order, lastStage.order, this.ctx.stage.curTimes, this.ctx.stage.curOrder]);
  230. } else {
  231. if (lastStage.status === audit.stage.status.uncheck) {
  232. filter = 'And s.order < ' + lastStage.order;
  233. } else if (lastStage.status === audit.stage.status.checked) {
  234. filter = '';
  235. } else if (lastStage.status === audit.stage.status.checkNo) {
  236. filter = this.db.format(' And (s.`order` < ? || (s.`order` = ? And sChange.`stimes` <= ?))',
  237. [lastStage.order, lastStage.order, lastStage.times])
  238. } else {
  239. const curAuditor = await this.ctx.service.stageAudit.getCurAuditor(lastStage.id, lastStage.times);
  240. filter = this.db.format(' And (s.`order` < ? || (s.`order` = ? And sChange.`stimes` <= ? And sChange.`sorder` <= ?))',
  241. [lastStage.order, lastStage.order, lastStage.times, curAuditor.order - 1]);
  242. }
  243. }
  244. const sql = 'SELECT c.lid, c.pid, SUM(c.qty) as used_qty,' +
  245. ' cb.tid, cb.cid, cb.id, cb.code, cb.name, cb.unit, cb.unit_price, cb.detail, cb.samount' +
  246. ' FROM ' + this.ctx.service.changeAuditList.tableName + ' As cb' +
  247. ' LEFT JOIN ' + this.tableName + ' As c ON cb.id = c.cbid ' +
  248. ' INNER JOIN (' +
  249. ' SELECT MAX(`stimes`) As `stimes`, MAX(`sorder`) As `sorder`, `lid`, `pid`, `cbid`, sChange.`sid`, `cid` ' +
  250. ' FROM ' + this.tableName + ' As sChange' +
  251. ' LEFT JOIN ' + this.ctx.service.stage.tableName + ' As s ON sChange.sid = s.id' +
  252. ' WHERE sChange.tid = ? AND cid = ?' + filter +
  253. ' GROUP By `lid`, `pid`, `cbid`, sChange.`sid`' +
  254. ' ) As m' +
  255. ' ON c.stimes = m.stimes And c.sorder = m.sorder And c.`cbid` = m.`cbid` AND c.`sid` = m.`sid` And c.`cid` = m.`cid`' +
  256. ' WHERE cb.cid = ?' +
  257. ' GROUP By c.`cbid`';
  258. const sqlParam = [tid, cid, cid];
  259. return await this.db.query(sql, sqlParam);
  260. }
  261. /**
  262. * 获取 变更令 - 变更清单 当期使用情况
  263. * @param {Number} sid - 查询期id
  264. * @param {uuid} cid - 变更令id
  265. * @returns {Promise<*>}
  266. */
  267. async getStageUsedData(sid, cid) {
  268. const sql = 'SELECT c.*, ' +
  269. ' l.ledger_id As `ledger_id`, l.b_code As `l_code`, l.name As `l_name`, l.unit As `l_unit`, l.unit_price As `l_up`,' +
  270. ' l.deal_qty As `l_deal_qty`, l.deal_tp As `l_deal_tp`, l.quantity As `l_qty`, l.total_price As `l_tp`, ' +
  271. ' l.drawing_code As `l_drawing_code`, ' +
  272. ' p.name As `p_name`, p.drawing_code As `p_drawing_code`, p.`quantity` As `p_qty`' +
  273. ' FROM ' + this.tableName + ' As c ' +
  274. ' INNER JOIN ( ' +
  275. ' SELECT MAX(`stimes`) As `stimes`, MAX(`sorder`) As `sorder`, `lid`, `pid`, `cbid` From ' + this.tableName +
  276. ' WHERE sid = ? And cid = ?' +
  277. ' GROUP By `lid`, `pid`, `cbid`' +
  278. ' ) As m ' +
  279. ' ON c.stimes = m.stimes And c.sorder = m.sorder And c.lid = m.lid And c.pid = m.pid And c.cbid = m.cbid' +
  280. ' LEFT JOIN ' + this.ctx.service.ledger.tableName + ' As l ON c.lid = l.id' +
  281. ' LEFT JOIN ' + this.ctx.service.pos.tableName + ' As p ON c.pid = p.id';
  282. const sqlParam = [sid, cid];
  283. return await this.db.query(sql, sqlParam);
  284. }
  285. /**
  286. * 获取 本期 使用的变更令
  287. * @param sid
  288. * @returns {Promise<void>}
  289. */
  290. async getStageUsedChangeId(sid) {
  291. const sql = 'SELECT c.`cid` FROM ' + this.tableName + ' As c' +
  292. ' INNER JOIN (' +
  293. ' SELECT MAX(`stimes`) As `stimes`, MAX(`sorder`) As `sorder`, `lid`, `pid`, `cbid` From ' + this.tableName +
  294. ' WHERE sid = ? And not ISNULL(qty)' +
  295. ' GROUP By `lid`, `pid`, `cbid`' +
  296. ' ) As m' +
  297. ' ON c.stimes = m.stimes And c.sorder = m.sorder And c.lid = m.lid And c.pid = m.pid And c.cbid = m.cbid' +
  298. ' GROUP BY c.`cid`';
  299. const sqlParam = [sid];
  300. const result = await this.db.query(sql, sqlParam);
  301. return this._.map(result, 'cid');
  302. }
  303. }
  304. return StageChange;
  305. };