'use strict'; /** * * * @author Mai * @date * @version */ const Ledger = require('./ledger'); const splitChar = '-'; const mergeChar = ';'; class BillsPosConvert { constructor(ctx) { const self = this; this.ctx = ctx; this._ = this.ctx.helper._; this.tpFields = ['total_price', 'contract_tp', 'qc_tp', 'gather_tp', 'contract_pc_tp', 'qc_pc_tp', 'pc_tp', 'pre_contract_tp', 'pre_qc_tp', 'pre_gather_tp', 'end_contract_tp', 'end_qc_tp']; this.baseCalcFields = ['quantity', 'contract_qty', 'qc_qty', 'gather_qty', 'pre_contract_qty', 'pre_qc_qty', 'pre_gather_qty', 'end_contract_qty', 'end_qc_qty', 'end_gather_qty']; // mainData this.bpcTree = new Ledger.billsTree(this.ctx, { id: 'ledger_id', pid: 'ledger_pid', order: 'order', level: 'level', rootId: -1, keys: ['id', 'tender_id', 'ledger_id'], stageId: 'id', updateFields: ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp'], calcFields: [], }); this.bpcPos = new Ledger.pos({ id: 'id', ledgerId: 'lid', updateFields: ['contract_qty', 'qc_qty'], }); this.bpcChange = []; // reusltData this.resultTreeSetting = { id: 'ledger_id', pid: 'ledger_pid', order: 'order', level: 'level', rootId: -1, fullPath: 'full_path', }; this.resultTree = new Ledger.filterTree(this.ctx, this.resultTreeSetting); } // 加载基础数据 _loadLedgerData (ledger) { const self = this; // 加载树结构数据 this.bpcTree.loadDatas(ledger); } _loadPosData(pos) { this.bpcPos.loadDatas(pos); } loadData (ledger, pos, change) { this._loadLedgerData(ledger); this._loadPosData(pos); this.bpcChange = change; } _convertXmj(data) { const xmj = this.resultTree.addData(data, ['ledger_id', 'ledger_pid', 'order', 'level', 'tender_id', 'full_path', 'code', 'name', 'unit', 'dgn_qty1', 'dgn_qty2', 'drawing_code', 'postil', 'memo', 'gxby_status', 'dagl_status', 'gxby_url', 'dagl_url', 'ex_memo1', 'ex_memo2', 'ex_memo3']); return xmj; } // v1 _loadField(node, data, fields) { for (const prop in data) { if (fields.indexOf(prop) >= 0) node[prop] = data[prop]; } } // v2 _loadPosCalcFields(node, data) { const tpDecimal = this.ctx.tender.info.decimal.tp; node.quantity = this.ctx.helper.add(node.quantity, data.quantity); node.total_price = this.ctx.helper.add(node.total_price, this.ctx.helper.mul(node.unit_price, data.quantity, tpDecimal)); const org_price = node.org_price || node.unit_price; node.contract_qty = this.ctx.helper.add(node.contract_qty, data.contract_qty); node.contract_tp = this.ctx.helper.add(node.contract_tp, this.ctx.helper.mul(node.unit_price, data.contract_qty, tpDecimal)); node.qc_qty = this.ctx.helper.add(node.qc_qty, data.qc_qty); node.qc_tp = this.ctx.helper.add(node.qc_tp, this.ctx.helper.mul(node.unit_price, data.qc_qty, tpDecimal)); node.gather_qty = this.ctx.helper.add(node.gather_qty, data.gather_qty); node.pre_contract_qty = this.ctx.helper.add(node.pre_contract_qty, data.pre_contract_qty); node.pre_contract_tp = this.ctx.helper.add(node.pre_contract_tp, this.ctx.helper.mul(org_price, data.pre_contract_qty, tpDecimal)); node.pre_qc_qty = this.ctx.helper.add(node.pre_qc_qty, data.pre_qc_qty); node.pre_qc_tp = this.ctx.helper.add(node.pre_qc_tp, this.ctx.helper.mul(org_price, data.pre_qc_qty, tpDecimal)); node.pre_gather_qty = this.ctx.helper.add(node.pre_gather_qty, data.pre_gather_qty); node.real_qty = this.ctx.helper.add(node.real_qty, data.real_qty); node.qc_minus_qty = this.ctx.helper.add(node.qc_minus_qty, data.qc_minus_qty); node.pre_qc_minus_qty = this.ctx.helper.add(node.pre_qc_minus_qty, data.pre_qc_minus_qty); } _loadBillsCalcFields(node, data) { node.quantity = this.ctx.helper.add(node.quantity, data.quantity); node.total_price = this.ctx.helper.add(node.total_price, data.total_price); node.contract_qty = this.ctx.helper.add(node.contract_qty, data.contract_qty); node.contract_tp = this.ctx.helper.add(node.contract_tp, data.contract_tp); node.qc_qty = this.ctx.helper.add(node.qc_qty, data.qc_qty); node.qc_tp = this.ctx.helper.add(node.qc_tp, data.qc_tp); node.gather_qty = this.ctx.helper.add(node.gather_qty, data.gather_qty); node.gather_tp = this.ctx.helper.add(node.gather_tp, data.gather_tp); node.pre_contract_qty = this.ctx.helper.add(node.pre_contract_qty, data.pre_contract_qty); node.pre_contract_tp = this.ctx.helper.add(node.pre_contract_tp, data.pre_contract_tp); node.pre_qc_qty = this.ctx.helper.add(node.pre_qc_qty, data.pre_qc_qty); node.pre_qc_tp = this.ctx.helper.add(node.pre_qc_tp, data.pre_qc_tp); node.pre_gather_qty = this.ctx.helper.add(node.pre_gather_qty, data.pre_gather_qty); node.qc_minus_qty = this.ctx.helper.add(node.qc_minus_qty, data.qc_minus_qty); node.pre_qc_minus_qty = this.ctx.helper.add(node.pre_qc_minus_qty, data.pre_qc_minus_qty); } _convertGcl(node, xmj) { if (!xmj) return; if (!xmj.unitTree) { xmj.unitTree = new Ledger.filterGatherTree(this.ctx, this.resultTreeSetting); } const pos = this.bpcPos.getLedgerPos(node.id); if (pos && pos.length > 0) { for (const p of pos) { const posUnit = xmj.unitTree.addNode({pos_name: p.name, b_code: null, name: '', unit: null, unit_price: null, gxby_status: p.gxby_status, dagl_status: p.dagl_status, gxby_url: p.gxby_url, dagl_url: p.dagl_url}); if (p.drawing_code && posUnit.drawing_code.indexOf(p.drawing_code) < 0) posUnit.drawing_code.push(p.drawing_code); if (p.memo) posUnit.memo.push(p.memo); if (p.postil) posUnit.postil.push(p.postil); if (p.ex_memo1) posUnit.ex_memo1.push(p.ex_memo1); if (p.ex_memo2) posUnit.ex_memo2.push(p.ex_memo2); if (p.ex_memo3) posUnit.ex_memo3.push(p.ex_memo3); const gclUnit = xmj.unitTree.addNode({pos_name: '', b_code: node.b_code, name: node.name, unit: node.unit, unit_price: node.unit_price, org_price: node.org_price, }, posUnit); if (node.drawing_code && gclUnit.drawing_code.indexOf(node.drawing_code) < 0) gclUnit.drawing_code.push(node.drawing_code); if (node.memo) gclUnit.memo.push(node.memo); if (node.postil) gclUnit.postil.push(node.postil); if (node.ex_memo1) gclUnit.ex_memo1.push(node.ex_memo1); if (node.ex_memo2) gclUnit.ex_memo2.push(node.ex_memo2); if (node.ex_memo3) gclUnit.ex_memo3.push(node.ex_memo3); //loadField(gclUnit, p, baseCalcFields); this._loadPosCalcFields(gclUnit, p); if (!gclUnit.changes) gclUnit.changes = []; for (const c of this.bpcChange) { if (c.lid === node.id && c.pid === p.id && c.qty && c.qty !== 0) { gclUnit.changes.push(c); } } } } else { const unit = xmj.unitTree.addNode({ pos_name: '', b_code: node.b_code, name: node.name, unit: node.unit, unit_price: node.unit_price, org_price: node.org_price, }); if (node.drawing_code && unit.drawing_code.indexOf(node.drawing_code) < 0) unit.drawing_code.push(node.drawing_code); if (node.memo) unit.memo.push(node.memo); if (node.postil) unit.postil.push(node.postil); if (node.ex_memo1) unit.ex_memo1.push(node.ex_memo1); if (node.ex_memo2) unit.ex_memo2.push(node.ex_memo2); if (node.ex_memo3) unit.ex_memo3.push(node.ex_memo3); this._loadBillsCalcFields(unit, node); if (!unit.changes) unit.changes = []; for (const c of this.bpcChange) { if (c.lid === node.id && c.pid == -1 && c.qty && c.qty !== 0) { unit.changes.push(c); } } } } _recursiveConvertNode(nodes, xmj = null) { if (!nodes || !nodes instanceof Array || nodes.length === 0) return; for (const node of nodes) { if (node.b_code && node.b_code !== '') { if (!node.children || node.children.length === 0) { this._convertGcl(node, xmj); } this._recursiveConvertNode(node.children, xmj); } else { const curXmj = this._convertXmj(node); this._recursiveConvertNode(node.children, curXmj); if (!node.children || node.children.length === 0) { this._loadField(curXmj, node, this.tpFields); } } } } _calculateChild(child) { const tpDecimal = this.ctx.tender.info.decimal.tp; child.gather_qty = this.ctx.helper.add(child.contract_qty, child.qc_qty); child.pre_gather_qty = this.ctx.helper.add(child.pre_contract_qty, child.pre_qc_qty); child.end_contract_qty = this.ctx.helper.add(child.contract_qty, child.pre_contract_qty); child.end_qc_qty = this.ctx.helper.add(child.qc_qty, child.pre_qc_qty); child.end_gather_qty = this.ctx.helper.add(child.gather_qty, child.pre_gather_qty); child.estimate_qty = !this.ctx.helper.checkZero(child.real_qty) ? this.ctx.helper.sub(this.ctx.helper.sub(child.real_qty, child.quantity), child.end_qc_qty) : null; // v1 // child.total_price = this.ctx.helper.mul(child.unit_price, child.quantity, tpDecimal); // child.contract_tp = this.ctx.helper.mul(child.unit_price, child.contract_qty, tpDecimal); // child.qc_tp = this.ctx.helper.mul(child.unit_price, child.qc_qty, tpDecimal); // child.gather_tp = this.ctx.helper.mul(child.unit_price, child.gather_qty, tpDecimal); // child.pre_contract_tp = this.ctx.helper.mul(child.unit_price, child.pre_contract_qty, tpDecimal); // child.pre_qc_tp = this.ctx.helper.mul(child.unit_price, child.pre_qc_qty, tpDecimal); // child.pre_gather_tp = this.ctx.helper.mul(child.unit_price, child.pre_gather_qty, tpDecimal); // child.end_contract_tp = this.ctx.helper.mul(child.unit_price, child.end_contract_qty, tpDecimal); // child.end_qc_tp = this.ctx.helper.mul(child.unit_price, child.end_qc_qty, tpDecimal); // child.end_gather_tp = this.ctx.helper.mul(child.unit_price, child.end_gather_qty, tpDecimal); // v2 child.gather_tp = this.ctx.helper.add(child.contract_tp, child.qc_tp); child.pre_gather_tp = this.ctx.helper.add(child.pre_contract_tp, child.pre_qc_tp); child.end_contract_tp = this.ctx.helper.add(child.pre_contract_tp, child.contract_tp); child.end_qc_tp = this.ctx.helper.add(child.pre_qc_tp, child.qc_tp); child.end_gather_tp = this.ctx.helper.add(child.end_contract_tp, child.end_qc_tp); child.final_tp = this.ctx.helper.add(child.total_price, child.end_qc_tp); child.end_gather_percent = this.ctx.helper.mul(this.ctx.helper.div(child.end_gather_tp, child.final_tp, 4), 100); child.real_tp = this.ctx.helper.mul(child.real_qty, child.unit_price, tpDecimal); child.estimate_tp = this.ctx.helper.mul(child.estimate_qty, child.unit_price, tpDecimal); child.bgl_code = this.ctx.helper._.uniq(this.ctx.helper._.map(child.changes, 'c_code')).join(';'); // !#台账相关 child.end_qc_minus_qty = this.ctx.helper.add(child.pre_qc_minus_qty, child.qc_minus_qty); // 1#台账 child.final_1_qty = this.ctx.helper.add(child.end_qc_minus_qty, child.quantity); // 1#台账 = 台账+负变更 child.final_1_tp = this.ctx.helper.mul(child.unit_price, child.final_1_qty, tpDecimal); child.end_final_1_tp = this.ctx.helper.add(child.final_1_tp, child.end_qc_tp); child.end_final_1_percent = this.ctx.helper.mul(this.ctx.helper.div(child.end_gather_tp, child.end_final_1_tp, 4), 100); const priceDiff = child.org_price ? this.ctx.helper.sub(child.unit_price, child.org_price) : 0; if (priceDiff && (child.pre_contract_qty || child.pre_qc_qty)) { child.contract_pc_tp = this.ctx.helper.sub(this.ctx.helper.mul(child.unit_price, child.pre_contract_qty, this.ctx.tender.info.decimal.tp), child.pre_contract_tp); child.qc_pc_tp = this.ctx.helper.sub(this.ctx.helper.mul(child.unit_price, child.pre_qc_qty, this.ctx.tender.info.decimal.tp), child.pre_qc_tp); child.pc_tp = this.ctx.helper.add(child.contract_pc_tp, child.qc_pc_tp); child.gather_tp = this.ctx.helper.add(child.gather_tp, child.pc_tp); child.end_contract_tp = this.ctx.helper.add(child.end_contract_tp, child.contract_pc_tp); child.end_qc_tp = this.ctx.helper.add(child.end_qc_tp, child.qc_pc_tp); child.end_gather_tp = this.ctx.helper.add(child.end_contract_tp, child.end_qc_tp); } } _calculateNode(node, children) { for (const child of children) { node.total_price = this.ctx.helper.add(node.total_price, child.total_price); node.contract_tp = this.ctx.helper.add(node.contract_tp, child.contract_tp); node.qc_tp = this.ctx.helper.add(node.qc_tp, child.qc_tp); node.pc_tp = this.ctx.helper.add(node.pc_tp, child.pc_tp); node.gather_tp = this.ctx.helper.add(node.gather_tp, child.gather_tp); node.pre_contract_tp = this.ctx.helper.add(node.pre_contract_tp, child.pre_contract_tp); node.pre_qc_tp = this.ctx.helper.add(node.pre_qc_tp, child.pre_qc_tp); node.pre_gather_tp = this.ctx.helper.add(node.pre_gather_tp, child.pre_gather_tp); node.end_contract_tp = this.ctx.helper.add(node.end_contract_tp, child.end_contract_tp); node.end_qc_tp = this.ctx.helper.add(node.end_qc_tp, child.end_qc_tp); node.end_gather_tp = this.ctx.helper.add(node.end_gather_tp, child.end_gather_tp); node.real_tp = this.ctx.helper.add(node.real_tp, child.real_tp); node.estimate_tp = this.ctx.helper.add(node.estimate_tp, child.estimate_tp); node.final_1_tp = this.ctx.helper.add(node.final_1_tp, child.final_1_tp); } if (node.dgn_qty1) node.dgn_price = this.ctx.helper.div(node.total_price, node.dgn_qty1, this.ctx.tender.info.decimal.up); node.final_tp = this.ctx.helper.add(node.total_price, node.end_qc_tp); node.end_final_1_tp = this.ctx.helper.add(node.final_1_tp, node.end_qc_tp); node.end_gather_percent = this.ctx.helper.mul(this.ctx.helper.div(node.end_gather_tp, node.final_tp, 4), 100); node.end_final_1_percent = this.ctx.helper.mul(this.ctx.helper.div(node.end_gather_tp, node.end_final_1_tp, 4), 100); } _recursiveCalcUnitNodes(nodes) { if (!nodes || !nodes instanceof Array || nodes.length === 0) return; for (const node of nodes) { this._recursiveCalcUnitNodes(node.children); if (node.children && node.children.length > 0) { this._calculateNode(node, node.children); } else { this._calculateChild(node); } if (node.drawing_code && node.drawing_code.length > 0) node.drawing_code_merge = node.drawing_code.join(mergeChar); if (node.memo && node.memo.length > 0) node.memo_merge = node.memo.join(mergeChar); if (node.ex_memo1 && node.ex_memo1.length > 0) node.ex_memo1_merge = node.ex_memo1.join(mergeChar); if (node.ex_memo2 && node.ex_memo2.length > 0) node.ex_memo2_merge = node.ex_memo2.join(mergeChar); if (node.ex_memo3 && node.ex_memo3.length > 0) node.ex_memo3_merge = node.ex_memo3.join(mergeChar); if (node.postil && node.postil.length > 0) node.postil_merge = node.postil.join(mergeChar); } } _recursiveCalculateAndSort(nodes) { const self = this; if (!nodes || !nodes instanceof Array || nodes.length === 0) return; for (const node of nodes) { this._recursiveCalculateAndSort(node.children); if (node.unitTree) { node.unitTree.sortTreeNodeCustom(function (a, b) { if (a.b_code && a.b_code !== '') { return b.b_code && b.b_code !== '' ? self.ctx.helper.compareCode(a.b_code, b.b_code) : 1; } else { return b.b_code && b.b_code !== '' ? -1 : a.order - b.order; } }); this._recursiveCalcUnitNodes(node.unitTree.children); this._calculateNode(node, node.unitTree.children, this.tpFields); } else if (node.children && node.children.length > 0) { this._calculateNode(node, node.children, this.tpFields); } else { this._calculateChild(node); } } } _calculateAndSortResult() { this.resultTree.sortTreeNode(); this._recursiveCalculateAndSort(this.resultTree.children); } _generateCodeByWbsCode(wbsCode) { let needUpdate = false; for (const node of this.resultTree.nodes) { if (!node.unitTree) continue; let xmj = wbsCode.find(function (x) { return x.xmj_code === node.code; }); for (const unit of node.unitTree.nodes) { if (!unit.pos_name || unit.pos_name === '') continue; if (!xmj) { xmj = {xmj_code: node.code, pos: []}; wbsCode.push(xmj); needUpdate = true; } let index = xmj.pos.indexOf(unit.pos_name); if (index < 0) { unit.code = xmj.xmj_code + splitChar + (xmj.pos.length + 1); xmj.pos.push(unit.pos_name); needUpdate = true; } else { unit.code = xmj.xmj_code + splitChar + (index + 1); } } } return needUpdate; } _getResultData(filterFun) { const result = this.resultTree.getDefaultDatas(filterFun); for (const r of result) { if (r.unitTree) { r.unitTreeData = r.unitTree.getDefaultDatas(filterFun); delete r.unitTree; } } return result; } // 转换数据 convert(filter) { this._recursiveConvertNode(this.bpcTree.children); this._calculateAndSortResult(); this._generateCodeByWbsCode([]); switch (filter) { case 'cur': return this._getResultData(function (node) { for (const field of ['contract_tp', 'qc_tp', 'gather_tp', 'contract_pc_tp', 'qc_pc_tp', 'pc_tp']) { if (node[field]) { return false; } } return true; }); case 'end': return this._getResultData(function (node) { for (const field of ['end_contract_tp', 'end_qc_tp', 'end_gather_tp']) { if (node[field]) { return false; } } return true; }); default: return this._getResultData(); } } /** * 转换数据,会根据wbsCodeHis生成计量单元的code * 如果计量单元在wbsCodeHis中没有历史,则会更新传入的wbsCodeHis,并返回[result, true], 反之返回[result, false] * @param wbsCodeHis * @returns {*[]} */ convertByWbsCode(wbsCodeHis) { this._recursiveConvertNode(this.bpcTree.children); this._calculateAndSortResult(); const needUpdate = this._generateCodeByWbsCode(wbsCodeHis); return [this._getResultData(), needUpdate]; } } module.exports = BillsPosConvert;