change_audit_list.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  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) {
  27. const sql = 'SELECT * FROM ?? WHERE `cid` = ? ORDER BY `lid` = "0", `id` asc';
  28. const sqlParam = [this.tableName, cid];
  29. return await this.db.query(sql, sqlParam);
  30. }
  31. /**
  32. * 添加空白变更清单
  33. * @return {void}
  34. */
  35. async add(data) {
  36. if (!this.ctx.tender || !this.ctx.change) {
  37. throw '数据错误';
  38. }
  39. const insertData = {
  40. tid: this.ctx.tender.id,
  41. cid: this.ctx.change.cid,
  42. lid: '0',
  43. code: '',
  44. name: '',
  45. bwmx: '',
  46. unit: '',
  47. unit_price: null,
  48. oamount: 0,
  49. camount: 0,
  50. samount: '',
  51. detail: '',
  52. spamount: 0,
  53. xmj_code: null,
  54. xmj_jldy: null,
  55. xmj_dwgc: null,
  56. xmj_fbgc: null,
  57. xmj_fxgc: null,
  58. gcl_id: '',
  59. };
  60. // 新增工料
  61. const result = await this.db.insert(this.tableName, insertData);
  62. if (result.affectedRows === 0) {
  63. throw '新增空白清单数据失败';
  64. }
  65. return await this.getDataById(result.insertId);
  66. }
  67. /**
  68. * 批量添加空白变更清单
  69. * @return {void}
  70. */
  71. async batchAdd(data) {
  72. if (!this.ctx.tender || !this.ctx.change) {
  73. throw '数据错误';
  74. }
  75. const num = data.num ? parseInt(data.num) : 0;
  76. if (num < 1 || num > 100) {
  77. throw '批量添加的空白清单数目不能小于1或大于100';
  78. }
  79. const insertArray = [];
  80. for (let i = 0; i < num; i++) {
  81. const insertData = {
  82. tid: this.ctx.tender.id,
  83. cid: this.ctx.change.cid,
  84. lid: '0',
  85. code: '',
  86. name: '',
  87. bwmx: '',
  88. unit: '',
  89. unit_price: null,
  90. oamount: 0,
  91. camount: 0,
  92. samount: '',
  93. detail: '',
  94. spamount: 0,
  95. xmj_code: null,
  96. xmj_jldy: null,
  97. xmj_dwgc: null,
  98. xmj_fbgc: null,
  99. xmj_fxgc: null,
  100. gcl_id: '',
  101. };
  102. insertArray.push(insertData);
  103. }
  104. // 新增工料
  105. const result = await this.db.insert(this.tableName, insertArray);
  106. if (result.affectedRows !== num) {
  107. throw '批量添加空白清单数据失败';
  108. }
  109. // 获取刚批量添加的所有list
  110. for (let j = 0; j < num; j++) {
  111. insertArray[j].id = result.insertId + j;
  112. }
  113. return insertArray;
  114. }
  115. /**
  116. * 删除变更清单
  117. * @param {int} id 清单id
  118. * @return {void}
  119. */
  120. async del(id) {
  121. if (!this.ctx.tender || !this.ctx.change) {
  122. throw '数据错误';
  123. }
  124. const transaction = await this.db.beginTransaction();
  125. try {
  126. // 判断是否可删
  127. await transaction.delete(this.tableName, { id });
  128. // 重新算变更令总额
  129. await this.calcCamountSum(transaction);
  130. await transaction.commit();
  131. return true;
  132. } catch (err) {
  133. await transaction.rollback();
  134. throw err;
  135. }
  136. }
  137. /**
  138. * 修改变更清单
  139. * @param {Object} data 工料内容
  140. * @param {int} order 期数
  141. * @return {void}
  142. */
  143. async save(data, order) {
  144. if (!this.ctx.tender || !this.ctx.change) {
  145. throw '数据错误';
  146. }
  147. const transaction = await this.db.beginTransaction();
  148. try {
  149. // const mb_id = data.mb_id;
  150. // delete data.mb_id;
  151. await transaction.update(this.tableName, data);
  152. // await this.calcQuantityByML(transaction, mb_id);
  153. await this.calcCamountSum(transaction);
  154. await transaction.commit();
  155. return true;
  156. } catch (err) {
  157. await transaction.rollback();
  158. throw err;
  159. }
  160. }
  161. /**
  162. * 修改变更清单 复制粘贴
  163. * @param {Object} datas 修改内容
  164. * @return {void}
  165. */
  166. async saveDatas(datas) {
  167. if (!this.ctx.tender || !this.ctx.change) {
  168. throw '数据错误';
  169. }
  170. // 判断是否可修改
  171. // 判断t_type是否为费用
  172. const transaction = await this.db.beginTransaction();
  173. try {
  174. // for (const data of datas) {
  175. // const mb_id = data.mb_id;
  176. // delete data.mb_id;
  177. // await transaction.update(this.tableName, data);
  178. // await this.calcQuantityByML(transaction, mb_id);
  179. // }
  180. await transaction.updateRows(this.tableName, datas);
  181. await this.calcCamountSum(transaction);
  182. await transaction.commit();
  183. return true;
  184. } catch (err) {
  185. await transaction.rollback();
  186. throw err;
  187. }
  188. }
  189. /**
  190. * 台账数据清单 重新选择
  191. * @param {Object} datas 内容
  192. * @return {void}
  193. */
  194. async saveLedgerListDatas(datas) {
  195. if (!this.ctx.tender || !this.ctx.change) {
  196. throw '数据错误';
  197. }
  198. // 判断是否可修改
  199. // 判断t_type是否为费用
  200. const transaction = await this.db.beginTransaction();
  201. try {
  202. const sql1 = 'SELECT a.* FROM ?? as b LEFT JOIN ?? as a ON b.cbid = a.id WHERE b.cid = ? GROUP BY b.cbid';
  203. const sqlParam1 = [this.ctx.service.stageChange.tableName, this.tableName, this.ctx.change.cid];
  204. const usedList = await transaction.query(sql1, sqlParam1);
  205. // 先删除原本的台账清单数据
  206. const sql = 'DELETE FROM ?? WHERE cid = ? and lid != "0"';
  207. const sqlParam = [this.tableName, this.ctx.change.cid];
  208. await transaction.query(sql, sqlParam);
  209. const insertDatas = [];
  210. for (const data of datas) {
  211. data.tid = this.ctx.tender.id;
  212. data.cid = this.ctx.change.cid;
  213. data.spamount = data.camount;
  214. data.samount = '';
  215. insertDatas.push(data);
  216. }
  217. if (insertDatas.length > 0) await transaction.insert(this.tableName, insertDatas);
  218. await this.calcCamountSum(transaction);
  219. // 更新stage_change和stage_change_final的cbid
  220. if (usedList.length > 0) {
  221. const updateList = [];
  222. const sql2 = 'SELECT * FROM ?? WHERE `cid` = ? AND `lid` != "0"';
  223. const sqlParam2 = [this.tableName, this.ctx.change.cid];
  224. const newList = await transaction.query(sql2, sqlParam2);
  225. // const newList = await transaction.select(this.tableName, { where: { cid: this.ctx.change.cid } });
  226. for (const used of usedList) {
  227. const newone = this._.find(newList, { code: used.code, lid: used.lid, gcl_id: used.gcl_id, bwmx: used.bwmx });
  228. if (newone) {
  229. updateList.push({
  230. row: {
  231. cbid: newone.id,
  232. },
  233. where: {
  234. cid: this.ctx.change.cid,
  235. cbid: used.id,
  236. },
  237. });
  238. }
  239. }
  240. if (updateList.length > 0) {
  241. await transaction.updateRows(this.ctx.service.stageChange.tableName, updateList);
  242. await transaction.updateRows(this.ctx.service.stageChangeFinal.tableName, updateList);
  243. }
  244. }
  245. await transaction.commit();
  246. return true;
  247. } catch (err) {
  248. await transaction.rollback();
  249. throw err;
  250. }
  251. }
  252. /**
  253. * 台账数据清单 清除部分并重新算原设计总金额
  254. * @param {Object} datas 内容
  255. * @return {void}
  256. */
  257. async removeLedgerListDatas(datas) {
  258. if (!this.ctx.tender || !this.ctx.change) {
  259. throw '数据错误';
  260. }
  261. // 判断是否可修改
  262. // 判断t_type是否为费用
  263. const transaction = await this.db.beginTransaction();
  264. try {
  265. // 先删除原本的台账清单数据
  266. // const sql = 'DELETE FROM ?? WHERE cid = ? and lid != "0"';
  267. // const sqlParam = [this.tableName, this.ctx.change.cid];
  268. // await transaction.query(sql, sqlParam);
  269. // const insertDatas = [];
  270. for (const data of datas) {
  271. // data.tid = this.ctx.tender.id;
  272. // data.cid = this.ctx.change.cid;
  273. // data.spamount = data.camount;
  274. // data.samount = '';
  275. // insertDatas.push(data);
  276. await transaction.delete(this.tableName, { id: data.id });
  277. }
  278. // if (insertDatas.length > 0) await transaction.insert(this.tableName, insertDatas);
  279. await this.calcCamountSum(transaction);
  280. await transaction.commit();
  281. return true;
  282. } catch (err) {
  283. await transaction.rollback();
  284. throw err;
  285. }
  286. }
  287. async calcCamountSum(transaction) {
  288. // const sql = 'SELECT SUM(ROUND(`camount`*`unit_price`, )) as total_price FROM ?? WHERE cid = ?';
  289. // const sqlParam = [this.tableName, this.change.cid];
  290. // const tp = await transaction.queryOne(sql, sqlParam);
  291. // 防止小数位不精确,采用取值计算
  292. const sql = 'SELECT unit_price, spamount FROM ?? WHERE cid = ?';
  293. const sqlParam = [this.tableName, this.ctx.change.cid];
  294. const changeList = await transaction.query(sql, sqlParam);
  295. let total_price = 0;
  296. const tp_decimal = this.ctx.change.tp_decimal ? this.ctx.change.tp_decimal : this.ctx.tender.info.decimal.tp;
  297. for (const cl of changeList) {
  298. total_price = this.ctx.helper.accAdd(total_price, this.ctx.helper.mul(cl.unit_price, cl.spamount, tp_decimal));
  299. }
  300. const updateData = {
  301. total_price,
  302. };
  303. const options = {
  304. where: {
  305. cid: this.ctx.change.cid,
  306. },
  307. };
  308. await transaction.update(this.ctx.service.change.tableName, updateData, options);
  309. }
  310. /**
  311. * 用户数据数量提交
  312. * @param {Object} data 内容
  313. * @return {void}
  314. */
  315. async saveAmountData(data) {
  316. if (!this.ctx.tender || !this.ctx.change) {
  317. throw '数据错误';
  318. }
  319. // 判断是否可修改
  320. // 判断t_type是否为费用
  321. const transaction = await this.db.beginTransaction();
  322. try {
  323. await transaction.update(this.tableName, data);
  324. await this.calcCamountSum(transaction);
  325. await transaction.commit();
  326. return true;
  327. } catch (err) {
  328. await transaction.rollback();
  329. throw err;
  330. }
  331. }
  332. async gatherBgBills(tid) {
  333. const sql = 'SELECT cb.code, cb.name, cb.unit, cb.unit_price, Round(Sum(cb.samount + 0), 6) as quantity' +
  334. ' FROM ' + this.tableName + ' cb' +
  335. ' LEFT JOIN ' + this.ctx.service.change.tableName + ' c ON cb.cid = c.cid' +
  336. ' WHERE cb.tid = ? and c.status = ?' +
  337. ' GROUP BY code, name, unit, unit_price';
  338. const param = [tid, audit.flow.status.checked];
  339. const result = await this.db.query(sql, param);
  340. for (const b of result) {
  341. b.total_price = this.ctx.helper.mul(b.unit_price, b.quantity, this.ctx.tender.info.decimal.tp);
  342. }
  343. return result;
  344. }
  345. /**
  346. * 报表用
  347. * Tony Kang
  348. * @param {tid} tid - 标段id
  349. * @return {void}
  350. */
  351. async getChangeAuditBills(tid) {
  352. const sql = 'SELECT cb.*' +
  353. ' FROM ' + this.tableName + ' cb' +
  354. ' LEFT JOIN ' + this.ctx.service.change.tableName + ' c ON cb.cid = c.cid' +
  355. ' WHERE c.tid = ? and c.status = 3' +
  356. ' ORDER BY cb.cid, cb.code';
  357. const param = [tid];
  358. const result = await this.db.query(sql, param);
  359. return result;
  360. }
  361. }
  362. return ChangeAuditList;
  363. };