rptCustomData.js 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975
  1. 'use strict';
  2. /**
  3. * 定制报表 注意不做任何混用,也不做任何继承
  4. *
  5. * @author Mai
  6. * @date
  7. * @version
  8. */
  9. const auditConst = require('../const/audit');
  10. const Ledger = require('./ledger');
  11. const mergeChar = ';';
  12. /**
  13. * 季华项目 定制报表
  14. * 汇总表,流水汇总2个标段(N个),汇总到期,每期汇总3个人的数据(3个),工程量清单流水表,并根据截至本期变更令使用情况筛选
  15. *
  16. * 借用 通用汇总标段选的界面
  17. * 故配置可与汇总标段选择相同
  18. *
  19. * define: {
  20. * "title": "请选择汇总的标段", "type": "month/final/checked-final/stage",
  21. * "defaultCompare": [1, 2, 3], // 结果按序 rn_qty, rn_tp
  22. * "match": { "quality": [2, 3], "qty": "<0" }, // class根据变更类型过滤,qty根据数量过滤
  23. * "merge": true,
  24. * }
  25. * defaultCompare为默认选择的审批人,0为原报,1-N为1-N审
  26. * match为保留的类型
  27. * 如需要用户选择审批人,则应配置selectCompare(目前不可用,不可配置,如需使用,则需要额外界面),为后期可能的变动预留
  28. *
  29. */
  30. class jhHelper {
  31. constructor (ctx) {
  32. this.ctx = ctx;
  33. this.result = [];
  34. }
  35. async _getValidStages(tenderId) {
  36. const stages = await this.ctx.service.stage.db.select(this.ctx.service.stage.tableName, {
  37. where: { tid: tenderId },
  38. orders: [['order', 'desc']],
  39. });
  40. if (stages.length !== 0) {
  41. const lastStage = stages[0];
  42. if (lastStage.status === auditConst.stage.status.uncheck && lastStage.user_id !== this.ctx.session.sessionUser.accountId) {
  43. stages.splice(0, 1);
  44. }
  45. }
  46. return stages;
  47. }
  48. async _getCheckedStages(tenderId) {
  49. const stages = await this.db.select(this.ctx.service.stage.tableName, {
  50. where: { tid: tenderId },
  51. orders: [['order', 'desc']],
  52. });
  53. if (stages.length !== 0) {
  54. const lastStage = stages[0];
  55. if (lastStage.status !== auditConst.stage.status.checked) {
  56. stages.splice(0, 1);
  57. }
  58. }
  59. return stages;
  60. }
  61. /**
  62. * 查询本期所有变更明细
  63. * @param tid
  64. * @param sid
  65. * @returns {Promise<void>}
  66. */
  67. async getCurChangeDetailData(tid, sid) {
  68. const sql = 'SELECT sc.*, c.type As c_type, c.class As c_class, c.quality As c_quality FROM ' + this.ctx.service.stageChange.tableName + ' sc' +
  69. ' Left Join ' + this.ctx.service.change.tableName + ' c ON sc.cid = c.cid' +
  70. ' WHERE sc.tid = ? and sc.sid = ?';
  71. return await this.ctx.service.stageChange.db.query(sql, [tid, sid]);
  72. }
  73. async getPreChangeDetailData(tid, sOrder) {
  74. const sql = 'SELECT sc.*, c.type As c_type, c.class As c_class, c.quality As c_quality FROM ' + this.ctx.service.stageChangeFinal.tableName + ' sc' +
  75. ' Left Join ' + this.ctx.service.change.tableName + ' c ON sc.cid = c.cid' +
  76. ' Left Join ' + this.ctx.service.stage.tableName + ' s ON sc.sid = s.id' +
  77. ' WHERE sc.tid = ? and s.order < ?';
  78. return await this.ctx.service.stageChangeFinal.db.query(sql, [tid, sOrder]);
  79. }
  80. getLastestAuditors(auditors) {
  81. const index = {};
  82. for (const auditor of auditors) {
  83. if (!index[auditor.aid] || auditor.order > index[auditor.aid].order) index[auditor.aid] = auditor;
  84. }
  85. const result = [];
  86. for (const i in index) {
  87. result.push(index[i]);
  88. }
  89. result.sort((x, y) => { return x.order - y.order; });
  90. return result;
  91. }
  92. _loadChangeDetail(billsIndex, changeDetail, gsDefine, prefix) {
  93. for (const cd of changeDetail) {
  94. if (!cd.qty) continue;
  95. let match = false;
  96. for (const m of gsDefine.match) {
  97. if (m.quality === cd.c_quality && ((m.minus && cd.qty < 0) || (!m.minus && cd.qty > 0))) match = true;
  98. }
  99. if (!match) continue;
  100. const bills = billsIndex[cd.lid];
  101. if (!bills) continue;
  102. if (!bills[prefix + 'cd']) bills[prefix + 'cd'] = [];
  103. bills[prefix + 'cd'].push(cd);
  104. if (cd.pid) {
  105. const pos = bills.pos.find(x => {return x.id === cd.pid});
  106. if (pos) {
  107. if (!pos[prefix + 'cd']) pos[prefix + 'cd'] = [];
  108. pos[prefix + 'cd'].push(cd);
  109. }
  110. }
  111. }
  112. }
  113. _loadMergeResult(bills, prefixes, decimal) {
  114. const rst = {
  115. id: bills.id,
  116. tid: bills.tender_id,
  117. b_code: bills.b_code,
  118. name: bills.name,
  119. unit: bills.unit,
  120. unit_price: bills.unit_price
  121. };
  122. if (bills.pos && bills.pos.length > 0) {
  123. for (const p of bills.pos) {
  124. let gather = false;
  125. if (p.pre_cd && p.pre_cd.length > 0) gather = true;
  126. for (const prefix of prefixes) {
  127. if (p[prefix + 'cd'] && p[prefix + 'cd'].length > 0) gather = true;
  128. }
  129. if (gather) {
  130. rst.qc_qty = this.ctx.helper.add(rst.qc_qty, p.qc_qty);
  131. rst.pre_qc_qty = this.ctx.helper.add(rst.pre_qc_qty, p.pre_qc_qty);
  132. rst.end_qc_qty = this.ctx.helper.add(rst.end_qc_qty, p.end_qc_qty);
  133. for (const prefix of prefixes) {
  134. rst[prefix + 'qc_qty'] = this.ctx.helper.add(rst[prefix + 'qc_qty'], p[prefix + 'qc_qty']);
  135. }
  136. }
  137. }
  138. rst.qc_tp = this.ctx.helper.mul(rst.unit_price, rst.qc_qty, decimal.tp);
  139. rst.pre_qc_tp = this.ctx.helper.mul(rst.unit_price, rst.pre_qc_qty, decimal.tp);
  140. rst.end_qc_tp = this.ctx.helper.add(rst.pre_qc_tp, rst.qc_tp);
  141. for (const prefix of prefixes) {
  142. rst[prefix + 'qc_tp'] = this.ctx.helper.mul(rst.unit_price, rst[prefix + 'qc_qty'], decimal.tp);
  143. }
  144. } else {
  145. rst.qc_qty = bills.qc_qty;
  146. rst.qc_tp = bills.qc_tp;
  147. rst.pre_qc_qty = bills.pre_qc_qty;
  148. rst.pre_qc_tp = bills.pre_qc_tp;
  149. rst.end_qc_qty = bills.end_qc_qty;
  150. rst.end_qc_tp = bills.end_qc_tp;
  151. for (const prefix of prefixes) {
  152. rst[prefix + 'qc_qty'] = bills[prefix + 'qc_qty'];
  153. rst[prefix + 'qc_tp'] = bills[prefix + 'qc_tp'];
  154. }
  155. }
  156. this.result.push(rst);
  157. }
  158. _loadResult(bills, prefixes, decimal) {
  159. if (bills.pos) {
  160. for (const p of bills.pos) {
  161. let load = false;
  162. if (p.pre_cd && p.pre_cd.length > 0) load = true;
  163. for (const prefix of prefixes) {
  164. if (p[prefix + 'cd'] && p[prefix + 'cd'].length > 0) load = true;
  165. }
  166. if (!load) continue;
  167. const rst = {
  168. b_code: bills.b_code,
  169. name: bills.name,
  170. unit: bills.unit,
  171. unit_price: bills.unit_price,
  172. };
  173. rst.qc_qty = p.qc_qty;
  174. rst.qc_tp = this.ctx.helper.mul(bills.unit_price, p.qc_qty, decimal.tp);
  175. rst.pre_qc_qty = p.pre_qc_qty;
  176. rst.pre_qc_tp = this.ctx.helper.mul(bills.unit_price, p.pre_qc_qty, decimal.tp);
  177. rst.end_qc_qty = p.end_qc_qty;
  178. rst.end_qc_tp = this.ctx.helper.add(rst.qc_tp, p.pre_qc_tp);
  179. for (const prefix of prefixes) {
  180. rst[prefix + 'qc_qty'] = p[prefix + 'qc_qty'];
  181. rst[prefix + 'qc_tp'] = this.ctx.helper.mul(bills.unit_price, p[prefix + 'qc_qty'], decimal.tp);
  182. }
  183. this.result.push(rst);
  184. }
  185. } else {
  186. const rst = {
  187. b_code: bills.b_code,
  188. name: bills.name,
  189. unit: bills.unit,
  190. unit_price: bills.unit_price,
  191. };
  192. rst.qc_qty = bills.qc_qty;
  193. rst.qc_tp = bills.qc_tp;
  194. rst.pre_qc_qty = bills.pre_qc_qty;
  195. rst.pre_qc_tp = bills.pre_qc_tp;
  196. rst.end_qc_qty = bills.end_qc_qty;
  197. rst.end_qc_tp = bills.end_qc_tp;
  198. for (const prefix of prefixes) {
  199. rst[prefix + 'qc_qty'] = bills[prefix + 'qc_qty'];
  200. rst[prefix + 'qc_tp'] = bills[prefix + 'qc_tp'];
  201. }
  202. this.result.push(rst);
  203. }
  204. }
  205. _generateResult(billsData, gsDefine, decimal) {
  206. for (const bills of billsData) {
  207. let load = false;
  208. if (bills.pre_cd && bills.pre_cd.length > 0) load = true;
  209. for (const dc of gsDefine.defaultCompare) {
  210. if (bills['r' + dc + '_cd'] && bills['r' + dc + '_cd'].length > 0) load = true;
  211. }
  212. if (!load) continue;
  213. gsDefine.merge ? this._loadMergeResult(bills, this.prefixes, decimal) : this._loadResult(bills, this.prefixes, decimal);
  214. }
  215. }
  216. async _loadStageBillsData(tender, stage, gsDefine, auditors, filterGcl = true) {
  217. const helper = this.ctx.helper;
  218. // 加载截止上期/本期
  219. let billsData = await this.ctx.service.ledger.getData(tender.id);
  220. if (filterGcl) billsData = billsData.filter(x => { return x.b_code && x.is_leaf });
  221. const curStage = await this.ctx.service.stageBills.getLastestStageData2(tender.id, stage.id);
  222. const preStage = stage.preCheckedStage ? await this.ctx.service.stageBillsFinal.getFinalData(tender, stage.preCheckedStage.order) : [];
  223. const loadData = [
  224. { data: curStage, fields: this.billsQueryField, prefix: '', relaId: 'lid' },
  225. { data: preStage, fields: this.billsQueryField, prefix: 'pre_', relaId: 'lid' }
  226. ];
  227. for (const dc of gsDefine.defaultCompare) {
  228. const auditor = auditors[dc];
  229. if (!auditor) continue;
  230. const auditorStage = await this.ctx.service.stageBills.getAuditorStageData2(tender.id, stage.id, auditor.times, auditor.order);
  231. loadData.push({ data: auditorStage, fields: this.billsQueryField, prefix: `r${dc}_`, relaId: 'lid' });
  232. }
  233. helper.assignRelaData(billsData, loadData);
  234. return billsData;
  235. }
  236. async _loadStagePosData(tender, stage, gsDefine, auditors) {
  237. const helper = this.ctx.helper;
  238. const posData = await this.ctx.service.pos.getPosData({tid: tender.id});
  239. const curStage = await this.ctx.service.stagePos.getLastestStageData2(tender.id, stage.id);
  240. const preStage = stage.preCheckedStage ? await this.ctx.service.stagePosFinal.getFinalData(tender, stage.preCheckedStage.order) : [];
  241. const loadData = [
  242. { data: curStage, fields: ['qc_qty'], prefix: '', relaId: 'pid' },
  243. { data: preStage, fields: ['qc_qty'], prefix: 'pre_', relaId: 'pid' }
  244. ];
  245. for (const dc of gsDefine.defaultCompare) {
  246. const auditor = auditors[dc];
  247. if (!auditor) continue;
  248. const auditorStage = await this.ctx.service.stagePos.getAuditorStageData2(tender.id, stage.id, auditor.times, auditor.order);
  249. loadData.push({ data: auditorStage, fields: ['qc_qty'], prefix: `r${dc}_`, relaId: 'pid' });
  250. }
  251. helper.assignRelaData(posData, loadData);
  252. return posData;
  253. }
  254. async _gatherStageData(tender, stage, gsDefine) {
  255. if (!stage) return;
  256. const helper = this.ctx.helper;
  257. await this.ctx.service.stage.doCheckStage(stage);
  258. const auditors = this.getLastestAuditors(stage.auditors);
  259. const user = await this.ctx.service.projectAccount.getDataById(stage.user_id);
  260. auditors.unshift({
  261. aid: user.id, name: user.name, company: user.company, role: user.role,
  262. times: stage.curTimes, order: 0
  263. });
  264. const billsData = await this._loadStageBillsData(tender, stage, gsDefine, auditors);
  265. // 计算截止本期
  266. billsData.forEach(x => {
  267. x.end_qc_qty = helper.add(x.qc_qty, x.pre_qc_qty);
  268. x.end_qc_tp = helper.add(x.qc_tp, x.pre_qc_tp);
  269. });
  270. const posData = await this._loadStagePosData(tender, stage, gsDefine, auditors);
  271. posData.forEach(x => {
  272. x.end_qc_qty = helper.add(x.qc_qty, x.pre_qc_qty);
  273. });
  274. // 创建索引
  275. const billsIndex = {};
  276. for (const b of billsData) {
  277. billsIndex[b.id] = b;
  278. b.pos = posData.filter(x => { return x.lid === b.id; });
  279. }
  280. // 查询比较人数据
  281. this.prefixes = [];
  282. const stageChangeDetail = await this.getCurChangeDetailData(tender.id, stage.id);
  283. this.ctx.helper.saveBufferFile(JSON.stringify(stageChangeDetail, '', '\t'), this.ctx.app.baseDir + '/temp.json');
  284. for (const dc of gsDefine.defaultCompare) {
  285. if (!auditors[dc]) continue;
  286. const scd = helper.filterTimesOrderData(stageChangeDetail, ['lid', 'pid', 'cbid', 'no_value'], 'stimes', 'sorder', auditors[dc].times, auditors[dc].order);
  287. this._loadChangeDetail(billsIndex, scd, gsDefine, `r${dc}_`);
  288. this.prefixes.push(`r${dc}_`);
  289. }
  290. const finalChangeData = await this.getPreChangeDetailData(tender.id, stage.order);
  291. this._loadChangeDetail(billsIndex, finalChangeData, gsDefine, 'pre_');
  292. this._generateResult(billsData, gsDefine, tender.info.decimal);
  293. }
  294. async _gatherStageBillsData(tender, stage, gsDefine) {
  295. if (!stage) return;
  296. const helper = this.ctx.helper;
  297. await this.ctx.service.stage.doCheckStage(stage);
  298. const auditors = this.getLastestAuditors(stage.auditors);
  299. const user = await this.ctx.service.projectAccount.getDataById(stage.user_id);
  300. auditors.unshift({
  301. aid: user.id, name: user.name, company: user.company, role: user.role,
  302. times: stage.curTimes, order: 0
  303. });
  304. const billsData = await this._loadStageBillsData(tender, stage, gsDefine, auditors, false);
  305. const billsTree = new Ledger.billsTree(this.ctx, {
  306. id: 'ledger_id',
  307. pid: 'ledger_pid',
  308. order: 'order',
  309. level: 'level',
  310. rootId: -1,
  311. keys: ['id', 'ledger_id'],
  312. stageId: 'id',
  313. calcFields: ['deal_tp', 'total_price', 'contract_tp', 'qc_tp', 'gather_tp', 'pre_contract_tp', 'pre_qc_tp', 'pre_gather_tp'],
  314. calc: function (node) {
  315. if (node.children && node.children.length === 0) {
  316. node.pre_gather_qty = helper.add(node.pre_contract_qty, node.pre_qc_qty);
  317. node.gather_qty = helper.add(node.contract_qty, node.qc_qty);
  318. node.end_contract_qty = helper.add(node.pre_contract_qty, node.contract_qty);
  319. node.end_qc_qty = helper.add(node.pre_qc_qty, node.qc_qty);
  320. node.end_gather_qty = helper.add(node.pre_gather_qty, node.gather_qty);
  321. }
  322. node.pre_gather_tp = helper.add(node.pre_contract_tp, node.pre_qc_tp);
  323. node.gather_tp = helper.add(node.contract_tp, node.qc_tp);
  324. node.end_contract_tp = helper.add(node.pre_contract_tp, node.contract_tp);
  325. node.end_qc_tp = helper.add(node.pre_qc_tp, node.qc_tp);
  326. node.end_gather_tp = helper.add(node.pre_gather_tp, node.gather_tp);
  327. for (const dc of gsDefine.defaultCompare) {
  328. const prefix = `r${dc}_`;
  329. node[prefix + 'gather_qty'] = helper.add(node[prefix + 'contract_qty'], node[prefix + 'qc_qty']);
  330. node[prefix + 'gather_tp'] = helper.add(node[prefix + 'contract_tp'], node[prefix + 'qc_tp']);
  331. }
  332. }
  333. });
  334. billsTree.loadDatas(billsData);
  335. billsTree.calculateAll();
  336. this.resultTree.loadGatherTree(billsTree, function (gatherNode, sourceNode) {
  337. gatherNode.s_qty = helper.add(gatherNode.s_qty, sourceNode.quantity);
  338. gatherNode.s_tp = helper.add(gatherNode.s_tp, sourceNode.total_price);
  339. gatherNode.s_dgn_qty1 = helper.add(gatherNode.s_dgn_qty1, sourceNode.dgn_qty1);
  340. gatherNode.s_dgn_qty2 = helper.add(gatherNode.s_dgn_qty2, sourceNode.dgn_qty2);
  341. gatherNode.s_contract_qty = helper.add(gatherNode.s_contract_qty, sourceNode.contract_qty);
  342. gatherNode.s_contract_tp = helper.add(gatherNode.s_contract_tp, sourceNode.contract_tp);
  343. gatherNode.s_qc_qty = helper.add(gatherNode.s_qc_qty, sourceNode.qc_qty);
  344. gatherNode.s_qc_tp = helper.add(gatherNode.s_qc_tp, sourceNode.qc_tp);
  345. gatherNode.s_gather_qty = helper.add(gatherNode.s_gather_qty, sourceNode.gather_qty);
  346. gatherNode.s_gather_tp = helper.add(gatherNode.s_gather_tp, sourceNode.gather_tp);
  347. gatherNode.s_pre_contract_qty = helper.add(gatherNode.s_pre_contract_qty, sourceNode.pre_contract_qty);
  348. gatherNode.s_pre_contract_tp = helper.add(gatherNode.s_pre_contract_tp, sourceNode.pre_contract_tp);
  349. gatherNode.s_pre_qc_qty = helper.add(gatherNode.s_pre_qc_qty, sourceNode.pre_qc_qty);
  350. gatherNode.s_pre_qc_tp = helper.add(gatherNode.s_pre_qc_tp, sourceNode.pre_qc_tp);
  351. gatherNode.s_pre_gather_qty = helper.add(gatherNode.s_pre_gather_qty, sourceNode.pre_gather_qty);
  352. gatherNode.s_pre_gather_tp = helper.add(gatherNode.s_pre_gather_tp, sourceNode.pre_gather_tp);
  353. gatherNode.s_end_contract_qty = helper.add(gatherNode.s_end_contract_qty, sourceNode.end_contract_qty);
  354. gatherNode.s_end_contract_tp = helper.add(gatherNode.s_end_contract_tp, sourceNode.end_contract_tp);
  355. gatherNode.s_end_qc_qty = helper.add(gatherNode.s_end_qc_qty, sourceNode.end_qc_qty);
  356. gatherNode.s_end_qc_tp = helper.add(gatherNode.s_end_qc_tp, sourceNode.end_qc_tp);
  357. gatherNode.s_end_gather_qty = helper.add(gatherNode.s_end_gather_qty, sourceNode.end_gather_qty);
  358. gatherNode.s_end_gather_tp = helper.add(gatherNode.s_end_gather_tp, sourceNode.end_gather_tp);
  359. for (const dc of gsDefine.defaultCompare) {
  360. const prefix = `r${dc}_`;
  361. gatherNode[prefix + 'contract_qty'] = helper.add(gatherNode[prefix + 'contract_qty'], sourceNode[prefix + 'contract_qty']);
  362. gatherNode[prefix + 'contract_tp'] = helper.add(gatherNode[prefix + 'contract_tp'], sourceNode[prefix + 'contract_tp']);
  363. gatherNode[prefix + 'qc_qty'] = helper.add(gatherNode[prefix + 'qc_qty'], sourceNode[prefix + 'qc_qty']);
  364. gatherNode[prefix + 'qc_tp'] = helper.add(gatherNode[prefix + 'qc_tp'], sourceNode[prefix + 'qc_tp']);
  365. gatherNode[prefix + 'gather_qty'] = helper.add(gatherNode[prefix + 'gather_qty'], sourceNode[prefix + 'gather_qty']);
  366. gatherNode[prefix + 'gather_tp'] = helper.add(gatherNode[prefix + 'gather_tp'], sourceNode[prefix + 'gather_tp']);
  367. }
  368. });
  369. }
  370. async _gatherMonthData(tender, month, defaultCompare, fun) {
  371. const stages = await this._getValidStages(tender.id);
  372. const stage = this.ctx.helper._.find(stages, {s_time: month});
  373. await fun.call(this, tender, stage, defaultCompare);
  374. }
  375. async _gatherFinalData(tender, defaultCompare, fun) {
  376. const stages = await this._getValidStages(tender.id);
  377. await fun.call(this, tender, stages[0], defaultCompare);
  378. }
  379. async _gatherCheckedFinalData(tender, defaultCompare, fun) {
  380. const stages = await this._getCheckedStages(tender.id);
  381. await fun.call(this, tender, stages[0], defaultCompare);
  382. }
  383. async _gatherIndexData(tender, index, defaultCompare, fun) {
  384. const stages = await this._getValidStages(tender.id);
  385. const stage = this.ctx.helper._.find(stages, {order: index});
  386. await fun.call(this, tender, stage, defaultCompare);
  387. }
  388. /**
  389. *
  390. * @param {Array} memFieldKeys 报表添加的指标字段
  391. * @param {object} gsDefine
  392. * @param {object} gsCustom
  393. * @returns {Promise<Array>}
  394. */
  395. async gather(memFieldKeys, gsDefine, gsCustom) {
  396. this.billsQueryField = ['qc_qty', 'qc_tp'];
  397. if (!gsDefine || !gsDefine.enable) return [];
  398. if (!gsCustom || !gsCustom.tenders || gsCustom.tenders.length === 0) return [];
  399. const gsSetting = JSON.parse(gsDefine.setting);
  400. if (!gsSetting.defaultCompare || !gsSetting.match) return[];
  401. for (const t of gsCustom.tenders) {
  402. const tender = await this.ctx.service.tender.getCheckTender(t.tid);
  403. switch (gsSetting.type) {
  404. case 'month':
  405. await this._gatherMonthData(tender, gsCustom.month, gsSetting, this._gatherStageData);
  406. break;
  407. case 'final':
  408. await this._gatherFinalData(tender, gsSetting, this._gatherStageData);
  409. break;
  410. case 'checked-final':
  411. await this._gatherCheckedFinalData(tender, gsSetting, this._gatherStageData);
  412. break;
  413. case 'stage':
  414. await this._gatherIndexData(tender, gsCustom.stage, gsSetting, this._gatherStageData);
  415. break;
  416. default: throw '未知汇总类型';
  417. }
  418. }
  419. const helper = this.ctx.helper;
  420. // 排序
  421. this.result.sort((x, y) => { return helper.compareCode(x.b_code, y.b_code); });
  422. return this.result;
  423. }
  424. async convert(tid, sid, memFieldKeys, option) {
  425. this.billsQueryField = ['qc_qty', 'qc_tp'];
  426. if (!option) return [];
  427. const setting = JSON.parse(option);
  428. if (!setting || !setting.defaultCompare) return [];
  429. const tender = await this.ctx.service.tender.getCheckTender(tid);
  430. const stage = await this.ctx.service.stage.getDataById(sid);
  431. await this._gatherStageData(tender, stage, setting);
  432. const helper = this.ctx.helper;
  433. // 排序
  434. this.result.sort((x, y) => { return helper.compareCode(x.b_code, y.b_code); });
  435. return this.result;
  436. }
  437. async gatherBills(memFieldKeys, gsDefine, gsCustom) {
  438. if (!gsDefine || !gsDefine.enable) return [];
  439. if (!gsCustom || !gsCustom.tenders || gsCustom.tenders.length === 0) return [];
  440. const gsSetting = JSON.parse(gsDefine.setting);
  441. if (!gsSetting.defaultCompare) return [];
  442. this.billsQueryField = ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp'];
  443. this.resultTree = new Ledger.gatherTree(this.ctx, {
  444. id: 'id',
  445. pid: 'pid',
  446. order: 'order',
  447. level: 'level',
  448. rootId: -1
  449. });
  450. for (const t of gsCustom.tenders) {
  451. const tender = await this.ctx.service.tender.getCheckTender(t.tid);
  452. switch (gsSetting.type) {
  453. case 'month':
  454. await this._gatherMonthData(tender, gsCustom.month, gsSetting, this._gatherStageBillsData);
  455. break;
  456. case 'final':
  457. await this._gatherFinalData(tender, gsSetting, this._gatherStageBillsData);
  458. break;
  459. case 'checked-final':
  460. await this._gatherCheckedFinalData(tender, gsSetting, this._gatherStageBillsData);
  461. break;
  462. case 'stage':
  463. await this._gatherIndexData(tender, gsCustom.stage, gsSetting, this._gatherStageBillsData);
  464. break;
  465. default: throw '未知汇总类型';
  466. }
  467. }
  468. this.resultTree.generateSortNodes();
  469. return this.resultTree.getDefaultDatas();
  470. }
  471. }
  472. /**
  473. * 奉建项目 定制报表
  474. * 变更过程管理表
  475. * 汇总工程量清单(区分正负变更)
  476. */
  477. class fjHelper {
  478. constructor (ctx) {
  479. this.ctx = ctx;
  480. }
  481. async _getStageBillsData(tid, sid) {
  482. const helper = this.ctx.helper;
  483. const billsData = this.ctx.stage.ledgerHis
  484. ? await this.ctx.helper.loadLedgerDataFromOss(this.ctx.stage.ledgerHis.bills_file)
  485. : await this.ctx.service.ledger.getData(this.ctx.tender.id);
  486. const preStage = this.ctx.stage.preCheckedStage ? await this.ctx.service.stageBillsFinal.getFinalData(this.ctx.tender, this.ctx.stage.preCheckedStage.order) : [];
  487. const curStage = this.ctx.stage.readOnly
  488. ? await this.ctx.service.stageBills.getAuditorStageData2(tid, this.ctx.stage.id, this.ctx.stage.curTimes, this.ctx.stage.curOrder)
  489. : await this.ctx.service.stageBills.getLastestStageData2(tid, this.ctx.stage.id);
  490. const bpcStage = await this.ctx.service.stageBillsPc.getAllDataByCondition({ where: { sid: this.ctx.stage.id } });
  491. this.ctx.helper.assignRelaData(billsData, [
  492. { data: curStage, fields: ['qc_qty', 'qc_tp', 'qc_minus_qty'], prefix: '', relaId: 'lid' },
  493. { data: preStage, fields: ['qc_qty', 'qc_tp', 'qc_minus_qty'], prefix: 'pre_', relaId: 'lid' },
  494. { data: bpcStage, fields: ['contract_pc_tp', 'qc_pc_tp', 'pc_tp', 'org_price'], prefix: '', relaId: 'lid' },
  495. ]);
  496. billsData.forEach(node => {
  497. node.end_qc_qty = helper.add(node.pre_qc_qty, node.qc_qty);
  498. node.end_qc_tp = helper.sum([node.pre_qc_tp, node.qc_tp, node.qc_pc_tp]);
  499. node.final_qty = helper.add(node.quantity, node.end_qc_qty);
  500. node.final_tp = helper.add(node.total_price, node.end_qc_tp);
  501. });
  502. return billsData;
  503. }
  504. async _getStageImportChangeData(tid, sid) {
  505. const sql = 'SELECT sic.*, l.b_code, l.name, l.unit, l.unit_price, l.quantity, l.total_price' +
  506. ' FROM ' + this.ctx.service.stageImportChange.tableName + ' sic ' +
  507. ' LEFT JOIN (SELECT * FROM ' + this.ctx.service.ledger.tableName + ' WHERE tender_id = ? AND is_leaf) AS l ON sic.lid = l.id' +
  508. ' WHERE sic.tid = ? AND sic.sid <= ?';
  509. return await this.ctx.app.mysql.query(sql, [tid, tid, sid]);
  510. }
  511. convertChangeProgress(data, sid) {
  512. const helper = this.ctx.helper, tpDecimal = this.ctx.tender.info.decimal.tp;
  513. const bills = [];
  514. for (const d of data) {
  515. let b = bills.find(x => {
  516. return x.b_code === d.b_code && x.name === d.name && x.unit === d.unit && x.unit_price === d.unit_price;
  517. });
  518. if (!b) {
  519. b = { b_code: d.b_code, name: d.name, unit: d.unit, unit_price: d.unit_price, ledgerSource: [] };
  520. bills.push(b);
  521. }
  522. const ls = b.ledgerSource.find(x => { return x.lid === d.lid; });
  523. if (!ls) b.ledgerSource.push({lid: d.lid, quantity: d.quantity, total_price: d.total_price });
  524. const field = (d.sid < sid ? 'pre_' : '') + (d.rela_qty > 0 ? 'positive_' : 'negative_') + 'qc_qty';
  525. b[field] = this.ctx.helper.add(b[field], d.rela_qty);
  526. }
  527. bills.sort((a, b) => { return helper.compareCode(a.b_code, b.b_code); });
  528. const result = [];
  529. for (const b of bills) {
  530. b.pre_positive_qc_tp = helper.mul(b.unit_price, b.pre_positive_qc_qty, tpDecimal);
  531. b.pre_negative_qc_tp = helper.mul(b.unit_price, b.pre_negative_qc_qty, tpDecimal);
  532. b.positive_qc_tp = helper.mul(b.unit_price, b.positive_qc_qty, tpDecimal);
  533. b.negative_qc_tp = helper.mul(b.unit_price, b.negative_qc_qty, tpDecimal);
  534. b.end_positive_qc_qty = helper.add(b.pre_positive_qc_qty, b.positive_qc_qty);
  535. b.end_positive_qc_tp = helper.add(b.pre_positive_qc_tp, b.positive_qc_tp);
  536. b.end_negative_qc_qty = helper.add(b.pre_negative_qc_qty, b.negative_qc_qty);
  537. b.end_negative_qc_tp = helper.add(b.pre_negative_qc_tp, b.negative_qc_tp);
  538. b.final_qty = helper.add(b.quantity, helper.add(b.end_positive_qc_qty, b.end_negative_qc_qty));
  539. b.final_qty = helper.add(b.total_price, helper.add(b.end_positive_qc_tp, b.end_negative_qc_tp));
  540. result.push({
  541. b_code: b.b_code, name: b.name, unit: b.unit, unit_price: b.unit_price,
  542. quantity: b.quantity, total_price: b.total_price,
  543. pre_qc_qty: b.pre_positive_qc_qty, pre_qc_tp: b.pre_positive_qc_tp,
  544. qc_qty: b.positive_qc_qty, qc_tp: b.positive_qc_tp,
  545. end_qc_qty: b.end_positive_qc_qty, end_qc_tp: b.end_positive_qc_tp,
  546. final_qty: b.final_qty, final_tp: b.final_tp,
  547. minus: 0,
  548. });
  549. result.push({
  550. b_code: b.b_code, name: b.name, unit: b.unit, unit_price: b.unit_price,
  551. quantity: b.quantity, total_price: b.total_price,
  552. pre_qc_qty: b.pre_negative_qc_tp, pre_qc_tp: b.pre_negative_qc_tp,
  553. qc_qty: b.negative_qc_qty, qc_tp: b.negative_qc_tp,
  554. end_qc_qty: b.end_negative_qc_qty, end_qc_tp: b.end_negative_qc_tp,
  555. final_qty: b.final_qty, final_tp: b.final_tp,
  556. minus: 1,
  557. });
  558. }
  559. return result;
  560. }
  561. convertChangeProgress1(stageBills, stageImportChange, sid) {
  562. const helper = this.ctx.helper, tpDecimal = this.ctx.tender.info.decimal.tp;
  563. const bills = [];
  564. for (const sb of stageBills) {
  565. if (!sb.b_code) continue;
  566. let b = bills.find(x => { return x.b_code === sb.b_code && x.name === sb.name && x.unit === sb.unit && x.unit_price === sb.unit_price; });
  567. if (!b) {
  568. b = { b_code: sb.b_code, name: sb.name, unit: sb.unit, unit_price: sb.unit_price, org_price: sb.org_price, ledgerSource: [] };
  569. bills.push(b);
  570. }
  571. const ls = b.ledgerSource.find(x => { return x.lid === sb.lid; });
  572. if (!ls) b.ledgerSource.push({
  573. lid: sb.id,
  574. quantity: sb.quantity, total_price: sb.total_price,
  575. final_qty: sb.final_qty, final_tp: sb.final_tp,
  576. });
  577. }
  578. bills.sort((a, b) => { return helper.compareCode(a.b_code, b.b_code); });
  579. for (const d of stageImportChange) {
  580. const b = bills.find(x => { return x.ledgerSource.findIndex(y => { return y.lid === d.lid; }) >= 0; });
  581. if (!b) continue;
  582. const field = (d.sid < sid ? 'pre_' : '') + (d.rela_qty > 0 ? 'positive_' : 'negative_') + 'qc_qty';
  583. const minusField = (d.sid < sid ? 'pre_c_' : 'c_') + (d.rela_minus > 0 ? 'minus_' : '') + 'qc_qty';
  584. b[field] = this.ctx.helper.add(b[field], d.rela_qty);
  585. b[minusField] = this.ctx.helper.add(b[minusField], d.rela_qty);
  586. }
  587. const result = [], changeSum = {};
  588. for (const b of bills) {
  589. b.quantity = helper.sum(b.ledgerSource.map(x => { return x.quantity; }));
  590. b.total_price = helper.sum(b.ledgerSource.map(x => { return x.total_price; }));
  591. b.final_qty = helper.sum(b.ledgerSource.map(x => { return x.final_qty; }));
  592. b.final_tp = helper.sum(b.ledgerSource.map(x => { return x.final_tp; }));
  593. if (b.org_price) {
  594. b.pre_positive_qc_tp = helper.mul(b.org_price, b.pre_positive_qc_qty, tpDecimal);
  595. b.pre_negative_qc_tp = helper.mul(b.org_price, b.pre_negative_qc_qty, tpDecimal);
  596. b.positive_qc_pc_tp = helper.sub(helper.mul(b.unit_price, b.pre_positive_qc_qty, tpDecimal), b.pre_positive_qc_tp);
  597. b.negative_qc_pc_tp = helper.sub(helper.mul(b.unit_price, b.pre_negative_qc_qty, tpDecimal), b.pre_negative_qc_tp);
  598. } else {
  599. b.pre_positive_qc_tp = helper.mul(b.unit_price, b.pre_positive_qc_qty, tpDecimal);
  600. b.pre_negative_qc_tp = helper.mul(b.unit_price, b.pre_negative_qc_qty, tpDecimal);
  601. b.positive_qc_pc_tp = 0;
  602. b.negative_qc_pc_tp = 0;
  603. }
  604. b.positive_qc_tp = helper.mul(b.unit_price, b.positive_qc_qty, tpDecimal);
  605. b.negative_qc_tp = helper.mul(b.unit_price, b.negative_qc_qty, tpDecimal);
  606. b.end_positive_qc_qty = helper.add(b.pre_positive_qc_qty, b.positive_qc_qty);
  607. b.end_positive_qc_tp = helper.add(helper.add(b.pre_positive_qc_tp, b.positive_qc_tp), b.positive_qc_pc_tp);
  608. b.end_negative_qc_qty = helper.add(b.pre_negative_qc_qty, b.negative_qc_qty);
  609. b.end_negative_qc_tp = helper.add(helper.add(b.pre_negative_qc_tp, b.negative_qc_tp), b.negative_qc_pc_tp);
  610. if (b.org_price) {
  611. b.pre_c_qc_tp = helper.mul(b.org_price, b.pre_c_qc_qty, tpDecimal);
  612. b.pre_c_minus_qc_tp = helper.mul(b.org_price, b.pre_c_minus_qc_qty, tpDecimal);
  613. b.c_qc_pc_tp = helper.sub(helper.mul(b.unit_price, b.pre_c_qc_qty, tpDecimal), b.pre_c_qc_tp);
  614. b.c_minus_qc_pc_tp = helper.sub(helper.mul(b.unit_price, b.pre_c_minus_qc_qty, tpDecimal), b.pre_c_minus_qc_tp);
  615. } else {
  616. b.pre_c_qc_tp = helper.mul(b.unit_price, b.pre_c_qc_qty, tpDecimal);
  617. b.pre_c_minus_qc_tp = helper.mul(b.unit_price, b.pre_c_minus_qc_qty, tpDecimal);
  618. b.c_positive_qc_pc_tp = 0;
  619. b.c_negative_qc_pc_tp = 0;
  620. }
  621. b.c_qc_tp = helper.mul(b.unit_price, b.c_qc_qty, tpDecimal);
  622. b.c_minus_qc_tp = helper.mul(b.unit_price, b.c_minus_qc_qty, tpDecimal);
  623. b.end_c_qc_qty = helper.add(b.pre_c_qc_qty, b.c_qc_qty);
  624. b.end_c_qc_tp = helper.add(helper.add(b.pre_c_qc_tp, b.c_qc_tp), b.c_qc_pc_tp);
  625. b.end_c_minus_qc_qty = helper.add(b.pre_c_minus_qc_qty, b.c_minus_qc_qty);
  626. b.end_c_minus_qc_tp = helper.add(helper.add(b.pre_c_minus_qc_tp, b.c_minus_qc_tp), b.c_minus_qc_pc_tp);
  627. // 统计合计
  628. changeSum.pre_c_tp = helper.add(changeSum.pre_c_tp, b.pre_c_qc_tp);
  629. changeSum.c_tp = helper.add(changeSum.c_tp, b.c_qc_tp);
  630. changeSum.c_pc_tp = helper.add(changeSum.c_pc_tp, b.c_qc_pc_tp);
  631. changeSum.end_c_tp = helper.add(changeSum.end_c_tp, b.end_c_qc_tp);
  632. changeSum.pre_c_minus_tp = helper.add(changeSum.pre_c_minus_tp, b.pre_c_minus_qc_tp);
  633. changeSum.c_minus_tp = helper.add(changeSum.c_minus_tp, b.c_minus_qc_tp);
  634. changeSum.c_minus_pc_tp = helper.add(changeSum.c_minus_pc_tp, b.c_minus_qc_pc_tp);
  635. changeSum.end_c_minus_tp = helper.add(changeSum.end_c_minus_tp, b.end_c_minus_qc_tp);
  636. result.push({
  637. b_code: b.b_code, name: b.name, unit: b.unit, unit_price: b.unit_price,
  638. quantity: b.quantity, total_price: b.total_price,
  639. pre_qc_qty: b.pre_positive_qc_qty, pre_qc_tp: b.pre_positive_qc_tp,
  640. qc_qty: b.positive_qc_qty, qc_tp: b.positive_qc_tp, qc_pc_tp: b.positive_qc_pc_tp,
  641. end_qc_qty: b.end_positive_qc_qty, end_qc_tp: b.end_positive_qc_tp,
  642. final_qty: b.final_qty, final_tp: b.final_tp,
  643. minus: 0,
  644. });
  645. result.push({
  646. b_code: b.b_code, name: b.name, unit: b.unit, unit_price: b.unit_price,
  647. quantity: b.quantity, total_price: b.total_price,
  648. pre_qc_qty: b.pre_negative_qc_qty, pre_qc_tp: b.pre_negative_qc_tp,
  649. qc_qty: b.negative_qc_qty, qc_tp: b.negative_qc_tp, qc_pc_tp: b.negative_qc_pc_tp,
  650. end_qc_qty: b.end_negative_qc_qty, end_qc_tp: b.end_negative_qc_tp,
  651. final_qty: b.final_qty, final_tp: b.final_tp,
  652. minus: 1,
  653. });
  654. }
  655. return { mem_fj_change_progress: result, mem_fj_change_sum: [changeSum] };
  656. }
  657. async getChangeProgressData(tid, sid) {
  658. await this.ctx.service.stage.checkStage(sid);
  659. const stageBills = await this._getStageBillsData(tid, sid);
  660. const stageImportChange = await this._getStageImportChangeData(tid, sid);
  661. return this.convertChangeProgress1(stageBills, stageImportChange, sid);
  662. }
  663. }
  664. /**
  665. * 华晶项目 定制报表
  666. * 台账复核表:根据【台账顺序】列出所有清单、计量单元及明细、附属工程量及明细
  667. */
  668. class huajingHelper {
  669. constructor(ctx) {
  670. this.ctx = ctx;
  671. this.dataType = { jl: '计量', fs: '附属' };
  672. }
  673. async loadLedgerData(tid) {
  674. this.ledger = new Ledger.billsTree(this.ctx, {
  675. id: 'ledger_id',
  676. pid: 'ledger_pid',
  677. order: 'order',
  678. level: 'level',
  679. rootId: -1,
  680. keys: ['id', 'tender_id', 'ledger_id'],
  681. stageId: 'id',
  682. calcFields: [],
  683. calc: function (node, helper, decimal) {},
  684. });
  685. const ledgerData = await this.ctx.service.ledger.getData(tid);
  686. const ledgerExtraData = await this.ctx.service.ledgerExtra.getAllDataByCondition({ where: { tid } });
  687. this.ctx.helper.assignRelaData(ledgerData, [
  688. { data: ledgerExtraData, fields: ['calc_template'], prefix: '', relaId: 'id' },
  689. ]);
  690. this.ledger.loadDatas(ledgerData);
  691. this.pos = new Ledger.pos({ id: 'id', ledgerId: 'lid' });
  692. const posData = await this.ctx.service.pos.getAllDataByCondition({ where: { tid }});
  693. this.pos.loadDatas(posData);
  694. this.posCalcDetail = new Ledger.pos({ id: 'id', ledgerId: 'pid', orderField: 'pcd_order' });
  695. const posCalcDetailData = await this.ctx.service.posCalcDetail.getAllDataByCondition({ where: { tid } });
  696. this.posCalcDetail.loadDatas(posCalcDetailData);
  697. this.ancGcl = new Ledger.pos({ id: 'id', ledgerId: 'pid', orderField: 'g_order' });
  698. const ancGclData = await this.ctx.service.ancillaryGcl.getAllDataByCondition({ where: { tid } });
  699. this.ancGcl.loadDatas(ancGclData);
  700. this.ancGclDetail = new Ledger.pos({ id: 'id', ledgerId: 'ag_id', orderField: 'agd_order' });
  701. const ancGclDetailData = await this.ctx.service.ancillaryGclDetail.getAllDataByCondition({ where: { tid } });
  702. this.ancGclDetail.loadDatas(ancGclDetailData);
  703. this.calcTemplate = await this.ctx.service.calcTmpl.getAllTemplateDetail(this.ctx.session.sessionProject.id, 'posCalc');
  704. }
  705. CheckPeg(text) {
  706. const pegReg = /[a-zA-Z]*[kK][0-9]+[++][0-9]{3}([.][0-9]+)?/;
  707. return pegReg.test(text);
  708. }
  709. getPegNode(node) {
  710. if (node) {
  711. if (this.CheckPeg(node.name)) {
  712. return node;
  713. } else {
  714. const parent = this.ledger.getParent(node);
  715. return parent ? this.getPegNode(parent) : null;
  716. }
  717. }
  718. }
  719. getNodeByLevel(node, level) {
  720. let cur = node;
  721. while (cur && cur.level > level) {
  722. cur = this.ledger.getParent(cur);
  723. }
  724. return cur;
  725. }
  726. getDwgc(peg, xmj) {
  727. if (peg) {
  728. return peg.name;
  729. } else {
  730. const node = this.getNodeByLevel(xmj, 2);
  731. return node ? node.name : '';
  732. }
  733. }
  734. getFbgc(peg, xmj) {
  735. if (peg && peg.id !== xmj.id) {
  736. const node = this.getNodeByLevel(xmj, peg.level + 1);
  737. return node ? node.name : '';
  738. } else {
  739. const node = this.getNodeByLevel(xmj, 3);
  740. return node ? node.name : '';
  741. }
  742. }
  743. getFxgc (peg, xmj) {
  744. if (!peg) {
  745. const node = this.getNodeByLevel(xmj, 4);
  746. return node ? node.name : '';
  747. } else if (peg.id === xmj.id) {
  748. if (xmj.level > 4) {
  749. let value = '';
  750. for (let level = 4; level < xmj.level; level++) {
  751. const node = this.getNodeByLevel(xmj, level);
  752. value = value === '' ? node.name : value + mergeChar + node.name;
  753. }
  754. return value;
  755. } else {
  756. return '';
  757. }
  758. } else {
  759. if (peg.level + 2 < xmj.level) {
  760. let value = '';
  761. for (let level = peg.level + 2; level < xmj.level; level++) {
  762. const node = this.getNodeByLevel(xmj, level);
  763. value = value === '' ? node.name : value + mergeChar + node.name;
  764. }
  765. return value;
  766. } else {
  767. return '';
  768. }
  769. }
  770. }
  771. newCacheLeafXmj(leafXmj) {
  772. const peg = this.getPegNode(leafXmj);
  773. const cacheLX = {
  774. id: leafXmj.id,
  775. code: leafXmj.code,
  776. jldy: leafXmj.name,
  777. fbgc: this.getFbgc(peg, leafXmj),
  778. fxgc: this.getFxgc(peg, leafXmj),
  779. dwgc: this.getDwgc(peg, leafXmj),
  780. drawing_code: leafXmj.drawing_code,
  781. };
  782. this.leafXmjs.push(cacheLX);
  783. return cacheLX;
  784. }
  785. getCacheLeafXmj(leafXmj) {
  786. if (!this.leafXmjs) this.leafXmjs = [];
  787. const cacheLX = this.leafXmjs.find(lx => { return lx.id === leafXmj.id; });
  788. if (!cacheLX) {
  789. return this.newCacheLeafXmj(leafXmj);
  790. } else {
  791. return cacheLX;
  792. }
  793. }
  794. convertCalcHeader(target, calcTemplate) {
  795. for (const [i, col] of calcTemplate.col_set.entries()) {
  796. target['detail_' + i] = col.title + (col.unit ? `(${col.unit})` : '');
  797. }
  798. }
  799. convertCalcData(target, source, calcTemplate) {
  800. for (const [i, col] of calcTemplate.col_set.entries()) {
  801. target['detail_' + i] = source[col.field];
  802. }
  803. }
  804. convertAncGclDetail(gclBaseData, pos, ancGcl, details, calcTemplate) {
  805. const calc = [];
  806. for (const d of details) {
  807. calc.push(d.qty);
  808. const dData = {
  809. ...gclBaseData,
  810. pos_id: pos.id, pos_name: pos.name,
  811. anc_gcl_id: ancGcl.id, anc_gcl_name: ancGcl.name,
  812. anc_gcl_detail_id: d.id, data_type: this.dataType.fs,
  813. };
  814. this.convertCalcData(dData, d, calcTemplate);
  815. this.ledgerCheckData.push(dData);
  816. }
  817. return calc.join('+');
  818. }
  819. convertAncGcl(gclBaseData, pos, ancGcl) {
  820. for (const ag of ancGcl) {
  821. const agData = {
  822. ...gclBaseData,
  823. pos_id: pos.id, pos_name: pos.name,
  824. anc_gcl_id: ag.id, anc_gcl_name: ancGcl.name, quantity: ag.quantity, data_type: this.dataType.fs,
  825. };
  826. const calcTemplate = this.calcTemplate.find(x => { return x.id === ag.calc_template; });
  827. this.ledgerCheckData.push(agData);
  828. const details = this.ancGclDetail.getLedgerPos(ag.id);
  829. if (calcTemplate) this.convertCalcHeader(agData, calcTemplate);
  830. if (calcTemplate && details && details.length > 0) {
  831. agData.expr = this.convertAncGclDetail(gclBaseData, pos, ag, details, calcTemplate);
  832. } else {
  833. agData.expr = ag.expr;
  834. }
  835. }
  836. }
  837. convertPosCalcDetail(gclBaseData, pos, details, calcTemplate) {
  838. const calc = [];
  839. for (const d of details) {
  840. calc.push(d.qty);
  841. const dData = {
  842. ...gclBaseData,
  843. pos_id: pos.id, pos_name: pos.name,
  844. pos_calc_detail_id: d.id, data_type: this.dataType.jl,
  845. };
  846. this.convertCalcData(dData, d, calcTemplate);
  847. this.ledgerCheckData.push(dData);
  848. }
  849. return calc.join('+');
  850. }
  851. convertPosRange(gclBaseData, posRange, calcTemplate) {
  852. const calc = [];
  853. for (const p of posRange) {
  854. calc.push(p.sgfh_qty);
  855. const posData = {
  856. ...gclBaseData,
  857. pos_id: p.id, pos_name: p.name, quantity: p.sgfh_qty, data_type: this.dataType.jl,
  858. };
  859. this.ledgerCheckData.push(posData);
  860. const details = this.posCalcDetail.getLedgerPos(p.id);
  861. if (calcTemplate) this.convertCalcHeader(posData, calcTemplate);
  862. if (calcTemplate && details && details.length > 0) {
  863. posData.expr = this.convertPosCalcDetail(gclBaseData, p, details, calcTemplate);
  864. } else {
  865. posData.expr = p.sgfh_expr;
  866. }
  867. const ancGcl = this.ancGcl.getLedgerPos(p.id);
  868. if (ancGcl && ancGcl.length > 0) this.convertAncGcl(gclBaseData, p, ancGcl);
  869. }
  870. return calc.join('+');
  871. }
  872. convertGclNode(node, leafXmj) {
  873. const cacheLeafXmj = this.getCacheLeafXmj(leafXmj);
  874. const posRange = this.pos.getLedgerPos(node.id);
  875. const gclBaseData = {
  876. id: node.id, tid: node.tender_id, leaf_xmj_id: leafXmj.id,
  877. b_code: node.b_code, name: node.name, unit: node.unit, unit_price: node.unit_price,
  878. drawing_code: node.drawing_code,
  879. g_jldy: cacheLeafXmj.jldy, g_fbgc: cacheLeafXmj.fbgc, g_fxgc: cacheLeafXmj.fxgc, g_dwgc: cacheLeafXmj.dwgc, g_bwmx: cacheLeafXmj.bwmx,
  880. };
  881. const gclData = { ...gclBaseData, quantity: node.sgfh_qty, data_type: this.dataType.jl } ;
  882. this.ledgerCheckData.push(gclData);
  883. if (posRange && posRange.length > 0) {
  884. const calcTemplate = node.calc_template ? this.calcTemplate.find(x => { return x.id === node.calc_template; }) : null;
  885. gclData.expr = this.convertPosRange(gclBaseData, posRange, calcTemplate);
  886. } else {
  887. gclData.expr = node.sgfh_expr;
  888. }
  889. }
  890. recursiveConvertLedgerCheckData(nodes, leafXmj) {
  891. for (const node of nodes) {
  892. if (node.b_code) {
  893. if (node.children.length > 0) {
  894. this.recursiveConvertLedgerCheckData(node.children, leafXmj);
  895. } else {
  896. this.convertGclNode(node, leafXmj);
  897. }
  898. } else if (node.children.length > 0) {
  899. this.recursiveConvertLedgerCheckData(node.children, node);
  900. }
  901. }
  902. }
  903. async getLedgerCheckData(tid) {
  904. await this.ctx.service.tender.checkTender(tid);
  905. await this.loadLedgerData(tid);
  906. this.ledgerCheckData = [];
  907. this.recursiveConvertLedgerCheckData(this.ledger.children, null);
  908. return this.ledgerCheckData;
  909. }
  910. }
  911. module.exports = {
  912. jhHelper,
  913. fjHelper,
  914. huajingHelper,
  915. };