'use strict'; /** * * * @author Mai * @date * @version */ const itemsPre = 'id_'; const BillsTree = require('./ledger').billsTree; const TreeUtils = require('./ledger').treeUtils; const auditConst = require('../const/audit'); class FinalTree extends BillsTree { constructor(ctx, setting) { super(ctx, setting); this._newId = 1; this.checkField = ['code', 'name']; } get newId() { return this._newId++; } loadNode(node, parent, loadFun) { if (node.b_code) return; const checkField = this.checkField; const siblings = parent ? parent.children : this.children; let cur = siblings.find(function (x) { for (const cf of checkField) { if (x[cf] !== node[cf]) return false; } return true; // return x.code === node.code && x.name === node.name; }); if (!cur) { cur = { children: [], code: node.code || '', name: node.name || '', unit: node.unit || '' }; const id = this.newId; cur[this.setting.id] = id; cur[this.setting.pid] = parent ? parent[this.setting.id] : this.setting.rootId; cur[this.setting.fullPath] = parent ? parent[this.setting.fullPath] + '-' + id : '' + id; cur[this.setting.level] = parent ? parent[this.setting.level] + 1 : 1; cur[this.setting.order] = siblings.length + 1; siblings.push(cur); this.datas.push(cur); } loadFun(cur, node); for (const c of node.children) { this.loadNode(c, cur, loadFun); } } loadTree(tree, loadFun) { for (const node of tree.children) { this.loadNode(node, null, loadFun); } } generateSortNodes() { const self = this; const addSortNode = function (node) { self.nodes.push(node); for (const c of node.children) { addSortNode(c); } }; this.nodes = []; for (const n of this.children) { addSortNode(n); } } afterLoad(fun) { for (const d of this.datas) { fun && fun(d); d.is_leaf = d.children.length === 0; d.expanded = true; d.visible = true; this.items[itemsPre + d[this.setting.id]] = d; } this.generateSortNodes(); } resortChildrenByCustom(fun) { for (const n of this.nodes) { if (n.children && n.children.length > 1) { n.children.sort(fun); n.children.forEach((x, y) => { x.order = y + 1; }); } } this.generateSortNodes(); } } class BudgetFinal { constructor (ctx) { this.ctx = ctx; this.budgetSetting = { id: 'tree_id', pid: 'tree_pid', order: 'order', level: 'level', rootId: -1, calcFields: ['total_price'] }; this.tenderSetting = { id: 'ledger_id', pid: 'ledger_pid', order: 'order', level: 'level', rootId: -1, calcFields: ['total_price', 'end_gather_tp', 'end_contract_tp', 'end_qc_tp', 'tz_qc_tp'] }; this.finalTree = new FinalTree(this.ctx, { id: 'id', pid: 'pid', order: 'order', level: 'level', fullPath: 'full_path', rootId: -1 }); } async _loadGu(budget) { const helper = this.ctx.helper; const gu = await this.ctx.service.budgetGu.getData(budget.id); const guTree = new BillsTree(this.ctx, { id: 'tree_id', pid: 'tree_pid', order: 'order', level: 'level', rootId: -1, calcFields: ['total_price'] }); guTree.loadDatas(gu); guTree.calculateAll(); this.finalTree.loadTree(guTree, function (cur, source) { cur.base = true; cur.gu_dgn_qty1 = helper.add(cur.gu_dgn_qty1, source.dgn_qty1); cur.gu_dgn_qty2 = helper.add(cur.gu_dgn_qty2, source.dgn_qty2); cur.gu_tp = helper.add(cur.gu_tp, source.total_price); }); } async _loadGai(budget) { const helper = this.ctx.helper; const gai = await this.ctx.service.budgetGai.getData(budget.id); const gaiTree = new BillsTree(this.ctx, { id: 'tree_id', pid: 'tree_pid', order: 'order', level: 'level', rootId: -1, calcFields: ['total_price'] }); gaiTree.loadDatas(gai); gaiTree.calculateAll(); this.finalTree.loadTree(gaiTree, function (cur, source) { cur.base = true; cur.gai_dgn_qty1 = helper.add(cur.gai_dgn_qty1, source.dgn_qty1); cur.gai_dgn_qty2 = helper.add(cur.gai_dgn_qty2, source.dgn_qty2); cur.gai_tp = helper.add(cur.gai_tp, source.total_price); }); } async _loadYu(budget) { const helper = this.ctx.helper; const yu = await this.ctx.service.budgetYu.getData(budget.id); const yuTree = new BillsTree(this.ctx, { id: 'tree_id', pid: 'tree_pid', order: 'order', level: 'level', rootId: -1, calcFields: ['total_price'] }); yuTree.loadDatas(yu); yuTree.calculateAll(); this.finalTree.loadTree(yuTree, function (cur, source) { cur.base = true; cur.yu_dgn_qty1 = helper.add(cur.yu_dgn_qty1, source.dgn_qty1); cur.yu_dgn_qty2 = helper.add(cur.yu_dgn_qty2, source.dgn_qty2); cur.yu_tp = helper.add(cur.yu_tp, source.total_price); }); } async _loadZb(budget) { const helper = this.ctx.helper; const zb = await this.ctx.service.budgetZb.getData(budget.id); const zbTree = new BillsTree(this.ctx, { id: 'tree_id', pid: 'tree_pid', order: 'order', level: 'level', rootId: -1, calcFields: ['total_price'] }); zbTree.loadDatas(zb); zbTree.calculateAll(); this.finalTree.loadTree(zbTree, function (cur, source) { cur.base = true; cur.zb_dgn_qty1 = helper.add(cur.zb_dgn_qty1, source.dgn_qty1); cur.zb_dgn_qty2 = helper.add(cur.zb_dgn_qty2, source.dgn_qty2); cur.zb_tp = helper.add(cur.zb_tp, source.total_price); }); } async _loadCtrl(budget) { const helper = this.ctx.helper; const ctrl = await this.ctx.service.budgetCtrl.getData(budget.id); const ctrlTree = new BillsTree(this.ctx, { id: 'tree_id', pid: 'tree_pid', order: 'order', level: 'level', rootId: -1, calcFields: ['total_price'] }); ctrlTree.loadDatas(ctrl); ctrlTree.calculateAll(); this.finalTree.loadTree(ctrlTree, function (cur, source) { cur.base = true; cur.ctrl_dgn_qty1 = helper.add(cur.ctrl_dgn_qty1, source.dgn_qty1); cur.ctrl_dgn_qty2 = helper.add(cur.ctrl_dgn_qty2, source.dgn_qty2); cur.ctrl_tp = helper.add(cur.ctrl_tp, source.total_price); }); } async _loadReal(budget) { const helper = this.ctx.helper; const real = await this.ctx.service.budgetReal.getData(budget.id); const realTree = new BillsTree(this.ctx, { id: 'tree_id', pid: 'tree_pid', order: 'order', level: 'level', rootId: -1, calcFields: ['total_price'] }); realTree.loadDatas(real); realTree.calculateAll(); this.finalTree.loadTree(realTree, function (cur, source) { cur.base = true; cur.real_dgn_qty1 = helper.add(cur.real_dgn_qty1, source.dgn_qty1); cur.real_dgn_qty2 = helper.add(cur.real_dgn_qty2, source.dgn_qty2); cur.real_tp = helper.add(cur.real_tp, source.total_price); }); } async _getValidStages(tenderId, sort = 'desc', checked = false) { const accountId = this.ctx.session.sessionUser.accountId; const condition = { tid: tenderId }; if (checked) condition.status = auditConst.stage.status.checked; const stages = await this.ctx.service.stage.getAllDataByCondition({ where: condition, orders: [['order', sort]] }); return stages.filter(s => { return s.status !== auditConst.stage.status.uncheck || s.user_id === accountId; }); } async _filterOrder(id, order, checked) { const stages = await this._getValidStages(id, 'desc', checked); const stage = this.ctx.helper._.find(stages, { order }); if (stage) await this.ctx.service.stage.doCheckStage(stage); return { type: 'stage', stage, filter: `第${order}期` }; } async _filterMonth(id, month, checked) { const stages = await this._getValidStages(id, 'desc', checked); const stage = this.ctx.helper._.find(stages, { s_time: month }); if (stage) await this.ctx.service.stage.doCheckStage(stage); return { type: 'stage', stage, filter: month }; } async _filterFinal(id, checked) { const stages = await this._getValidStages(id, 'desc', checked); const stage = stages[0]; if (stage) await this.ctx.service.stage.doCheckStage(stage); return { type: 'stage', stage, filter: stage ? `第${stage.order}期` : '' }; } async _filterCheckedFinal(id, checked) { const stages = await this._getValidStages(id, 'desc', checked); const checkedStages = stages.filter(x => { return x.status === status.checked; }); const stage = checkedStages[0]; if (stage && stage.status !== auditConst.stage.status.checked) await this.ctx.service.stage.doCheckStage(stage); return { type: 'stage', stage, filter: stage ? `第${stage.order}期` : '' }; } async _filterUnderMonth(id, month, checked) { const stages = await this._getValidStages(id, 'desc', checked); let stage = this.ctx.helper._.find(stages, { s_time: month }); if (!stage) { const checkTime = this.ctx.moment(month); for (const s of stages) { const rela_time = this.ctx.moment(s.s_time); if (rela_time.isBefore(checkTime)) { stage = s; break; } } } if (stage) await this.ctx.service.stage.doCheckStage(stage); return { type: 'stage', stage, filter: stage ? stage.s_time : '' }; } async _filterStage(tender, stageInfo) { switch(stageInfo.type) { case 'stage': return await this._filterOrder(tender, stageInfo.stage, stageInfo.checked); case 'month': return await this._filterMonth(tender, stageInfo.month, stageInfo.checked); case 'final': return await this._filterFinal(tender, stageInfo.checked); case 'checked-final': return await this._filterCheckedFinal(tender, stageInfo.checked); case 'under-month': return await this._filterUnderMonth(tender, stageInfo.month, stageInfo.checked); default: return await this._filterFinal(tender, stageInfo.checked); } } async _loadTender(id, stageInfo) { const helper = this.ctx.helper; const bills = await this.ctx.service.ledger.getFinalData(id, ['id', 'ledger_id', 'ledger_pid', 'level', 'order', 'full_path', 'is_leaf', 'code', 'b_code', 'name', 'unit', 'unit_price', 'dgn_qty1', 'dgn_qty2', 'total_price']); const dgnData = await this.ctx.service.stageBillsDgn.getDgnData(id); // 使用最新一期对比 const stageFilter = await this._filterStage(id, stageInfo); if (!stageFilter.stage) { helper.assignRelaData(bills, [ { data: dgnData, fields: ['deal_dgn_qty1', 'deal_dgn_qty2', 'c_dgn_qty1', 'c_dgn_qty2'], prefix: '', relaId: 'id' }, ]); this.final.tender_info.push({ id, stageCount: 0 }); } else if (stageFilter.stage.status === auditConst.stage.status.checked) { const finalBills = await this.ctx.service.stageBillsFinal.getFinalData({ id }, stageFilter.stage.order); helper.assignRelaData(bills, [ { data: finalBills, fields: ['contract_tp', 'qc_tp'], prefix: 'end_', relaId: 'lid' }, { data: dgnData, fields: ['deal_dgn_qty1', 'deal_dgn_qty2', 'c_dgn_qty1', 'c_dgn_qty2'], prefix: '', relaId: 'id' }, ]); bills.forEach(b => { b.end_gather_tp = helper.add(b.end_qc_tp, b.end_contract_tp); }); this.final.tender_info.push({ id, stageOrder: stageFilter.stage.order }); } else { const curBills = stageFilter.stage.readOnly ? await this.ctx.service.stageBills.getAuditorStageData2(id, stageFilter.stage.id, stageFilter.stage.curTimes, stageFilter.stage.curOrder) : await this.ctx.service.stageBills.getLastestStageData2(id, stageFilter.stage.id); const preBills = stageFilter.stage.preCheckedStage ? await this.ctx.service.stageBillsFinal.getFinalData({ id }, stageFilter.stage.preCheckedStage.order) : []; const bpcData = await this.ctx.service.stageBillsPc.getAllDataByCondition({ where: { sid: stageFilter.stage.id } }); helper.assignRelaData(bills, [ { data: curBills, fields: ['contract_tp', 'qc_tp'], prefix: '', relaId: 'lid' }, { data: preBills, fields: ['contract_tp', 'qc_tp'], prefix: 'pre_', relaId: 'lid' }, { data: dgnData, fields: ['deal_dgn_qty1', 'deal_dgn_qty2', 'c_dgn_qty1', 'c_dgn_qty2'], prefix: '', relaId: 'id' }, { data: bpcData, fields: ['contract_pc_tp', 'qc_pc_tp', 'pc_tp', 'org_price'], prefix: '', relaId: 'lid' }, ]); bills.forEach(b => { b.end_contract_tp = helper.sum([b.contract_tp, b.pre_contract_tp, b.contract_pc_tp]); b.end_qc_tp = helper.sum([b.qc_tp, b.pre_qc_tp, b.qc_pc_tp]); b.end_gather_tp = helper.sum([b.qc_tp, b.contract_tp, b.pre_qc_tp, b.pre_contract_tp, b.pc_tp]); }); this.final.tender_info.push({ id, stageOrder: stageFilter.stage.order, stageStatus: stageFilter.stage.status, stageFlow: stageFilter.stage.curTimes + '-' + stageFilter.stage.curOrder }); } const tree = new BillsTree(this.ctx, this.tenderSetting); tree.loadDatas(bills); const tenderInfo = await this.ctx.service.tenderInfo.getTenderInfo(id); const reCalcChange = await this.ctx.service.change.getReCalcChangeData(id, tenderInfo); TreeUtils.loadChangeData(tree, null, reCalcChange, tenderInfo, helper); tree.calculateAll(); this.finalTree.loadTree(tree, function (cur, source) { cur.total_price = helper.add(cur.total_price, source.total_price); cur.dgn_qty1 = helper.add(cur.dgn_qty1, source.dgn_qty1); cur.dgn_qty2 = helper.add(cur.dgn_qty2, source.dgn_qty2); cur.deal_dgn_qty1 = helper.add(cur.deal_dgn_qty1, source.deal_dgn_qty1); cur.deal_dgn_qty2 = helper.add(cur.deal_dgn_qty2, source.deal_dgn_qty2); cur.c_dgn_qty1 = helper.add(cur.c_dgn_qty1, source.c_dgn_qty1); cur.c_dgn_qty2 = helper.add(cur.c_dgn_qty2, source.c_dgn_qty2); cur.final_dgn_qty1 = helper.sum([cur.final_dgn_qty1, source.deal_dgn_qty1, source.c_dgn_qty1]); cur.final_dgn_qty2 = helper.sum([cur.final_dgn_qty2, source.deal_dgn_qty2, source.c_dgn_qty2]); cur.final_contract_tp = helper.add(cur.final_contract_tp, source.end_contract_tp); cur.final_qc_tp = helper.add(cur.final_qc_tp, source.end_qc_tp); cur.final_tp = helper.add(cur.final_tp, source.end_gather_tp); cur.tz_qc_qty = helper.add(cur.tz_qc_qty, source.tz_qc_qty); cur.tz_qc_tp = helper.add(cur.tz_qc_tp, source.tz_qc_tp); }); } async _loadDeal(deal, stage) { if (!deal || deal.length === 0) return; this.final.contract = deal; const helper = this.ctx.helper; const treeData = await this.ctx.service.contractTree.getAllDataByCondition({ where: { id: deal, spid: this.ctx.subProject.id, contract_type: 1 } }); const contractData = await this.ctx.service.contract.getAllDataByCondition({ where: { id: deal, spid: this.ctx.subProject.id, contract_type: 1 } }); const paySqlParam = []; const timeFilter = stage.type === 'under-month' ? `AND pay_time <= ? ` : ''; if (stage.type === 'under-month') { paySqlParam.push(this.ctx.moment(stage.month, 'YYYY-MM').endOf('month').format('YYYY-MM-DD HH:mm:ss')); } const checkedFilter = stage.checked && this.ctx.subProject.page_show.openContractPaySubProjectShenpi ? ' AND status = 3 ' : ''; const paySql = `SELECT cid, SUM(yf_price) AS yf_tp FROM ${this.ctx.service.contractPay.tableName}` + ` WHERE cid IN(${contractData.map(x => { return `'${x.id}'`}).join(', ')}) ` + timeFilter + checkedFilter + ' GROUP BY cid'; const contractPayData = await this.ctx.service.contractPay.db.query(paySql, paySqlParam); for (const c of contractData) { const cp = contractPayData.find(x => { return x.cid === c.id; }); c.yf_tp = cp ? cp.yf_tp || 0 : 0; } const tree = new BillsTree(this.ctx, { id: 'contract_id', pid: 'contract_pid', order: 'order', level: 'level', rootId: -1, calcFields: ['total_price', 'yf_tp'], calc: function (node, helper, decimal) {}, }); tree.loadDatas([...treeData, ...contractData]); tree.calculateAll(); this.finalTree.loadTree(tree, function (cur, source) { if (source.c_code) cur.code = source.c_code; cur.total_price = helper.add(cur.total_price, source.total_price); cur.final_contract_tp = helper.add(cur.final_contract_tp, source.yf_tp); cur.final_tp = helper.add(cur.final_tp, source.yf_tp); }); } async _afterLoad() { const helper = this.ctx.helper; const checkGaiExist = this.finalTree.datas.findIndex(x => { if (x.gai_tp || x.gai_dgn_qty1 || x.gai_dgn_qty2) return true; }) >= 0; this.finalTree.afterLoad(node => { node.dgn_price = helper.div(node.total_price, node.dgn_qty1, 2); node.dgn_qty = node.dgn_qty1 ? (node.dgn_qty2 ? node.dgn_qty1 + '/' + node.dgn_qty2 : node.dgn_qty1) : (node.dgn_qty2 ? '/' + node.dgn_qty2 : ''); node.gu_dgn_price = helper.div(node.gu_tp, node.gu_dgn_qty1, 2); node.gu_dgn_qty = node.gu_dgn_qty1 ? (node.gu_dgn_qty2 ? node.gu_dgn_qty1 + '/' + node.gu_dgn_qty2 : node.gu_dgn_qty1 + '') : (node.gu_dgn_qty2 ? '/' + node.gu_dgn_qty2 : ''); node.gai_dgn_price = helper.div(node.gai_tp, node.gai_dgn_qty1, 2); node.gai_dgn_qty = node.gai_dgn_qty1 ? (node.gai_dgn_qty2 ? node.gai_dgn_qty1 + '/' + node.gai_dgn_qty2 : node.gai_dgn_qty1 + '') : (node.gai_dgn_qty2 ? '/' + node.gai_dgn_qty2 : ''); node.yu_dgn_price = helper.div(node.yu_tp, node.yu_dgn_qty1, 2); node.yu_dgn_qty = node.yu_dgn_qty1 ? (node.yu_dgn_qty2 ? node.yu_dgn_qty1 + '/' + node.yu_dgn_qty2 : node.yu_dgn_qty1 + '') : (node.yu_dgn_qty2 ? '/' + node.yu_dgn_qty2 : ''); node.zb_dgn_price = helper.div(node.zb_tp, node.zb_dgn_qty1, 2); node.zb_dgn_qty = node.zb_dgn_qty1 ? (node.zb_dgn_qty2 ? node.zb_dgn_qty1 + '/' + node.zb_dgn_qty2 : node.zb_dgn_qty1 + '') : (node.zb_dgn_qty2 ? '/' + node.zb_dgn_qty2 : ''); node.ctrl_dgn_price = helper.div(node.ctrl_tp, node.ctrl_dgn_qty1, 2); node.ctrl_dgn_qty = node.ctrl_dgn_qty1 ? (node.ctrl_dgn_qty2 ? node.ctrl_dgn_qty1 + '/' + node.ctrl_dgn_qty2 : node.ctrl_dgn_qty1 + '') : (node.ctrl_dgn_qty2 ? '/' + node.ctrl_dgn_qty2 : ''); node.real_dgn_price = helper.div(node.real_tp, node.real_dgn_qty1, 2); node.real_dgn_qty = node.real_dgn_qty1 ? (node.real_dgn_qty2 ? node.real_dgn_qty1 + '/' + node.real_dgn_qty2 : node.real_dgn_qty1 + '') : (node.real_dgn_qty2 ? '/' + node.real_dgn_qty2 : ''); node.final_dgn_price = helper.div(node.final_tp, node.final_dgn_qty1, 2); node.final_dgn_qty = node.final_dgn_qty1 ? (node.final_dgn_qty2 ? node.final_dgn_qty1 + '/' + node.final_dgn_qty2 : node.final_dgn_qty1) : (node.final_dgn_qty2 ? '/' + node.final_dgn_qty2 : ''); if (checkGaiExist) { node.grow_dgn_qty1 = helper.mul(helper.div(helper.sub(node.final_dgn_qty1, node.gai_dgn_qty1), node.gai_dgn_qty1, 4), 100); node.grow_dgn_qty2 = helper.mul(helper.div(helper.sub(node.final_dgn_qty2, node.gai_dgn_qty2), node.gai_dgn_qty2, 4), 100); node.grow_dgn_qty = node.grow_dgn_qty1 ? (node.grow_dgn_qty2 ? node.grow_dgn_qty1 + '/' + node.grow_dgn_qty2 : node.grow_dgn_qty1) : (node.grow_dgn_qty2 ? '/' + node.grow_dgn_qty2 : ''); node.grow_tp = helper.mul(helper.div(helper.sub(node.final_tp, node.gai_tp), node.gai_tp, 4), 100); } else { node.grow_dgn_qty1 = helper.mul(helper.div(helper.sub(node.final_dgn_qty1, node.yu_dgn_qty1), node.yu_dgn_qty1, 4), 100); node.grow_dgn_qty2 = helper.mul(helper.div(helper.sub(node.final_dgn_qty2, node.yu_dgn_qty2), node.yu_dgn_qty2, 4), 100); node.grow_dgn_qty = node.grow_dgn_qty1 ? (node.grow_dgn_qty2 ? node.grow_dgn_qty1 + '/' + node.grow_dgn_qty2 : node.grow_dgn_qty1) : (node.grow_dgn_qty2 ? '/' + node.grow_dgn_qty2 : ''); node.grow_tp = helper.mul(helper.div(helper.sub(node.final_tp, node.yu_tp), node.yu_tp, 4), 100); } }); this.finalTree.resortChildrenByCustom(function (x, y) { const iCode = helper.compareCode(x.code, y.code); if (iCode) return iCode; if (!x.name) return -1; if (!y.name) return 1; return x.name.localeCompare(y.name); }); } getFinalData() { const data = [], ctx = this.ctx, bid = this.budget.id, final_id = this.final.id; this.finalTree.datas.forEach(x => { data.push({ id: ctx.app.uuid.v4(), bid, final_id, tree_id: x.id, tree_pid: x.pid, order: x.order, level: x.level, full_path: x.full_path, is_leaf: x.children && x.children.length > 0 ? 0 : 1, code: x.code || '', name: x.name || '', unit: x.unit || '', gu_dgn_qty1: x.gu_dgn_qty1 || 0, gu_dgn_qty2: x.gu_dgn_qty2 || 0, gu_dgn_qty: x.gu_dgn_qty || '', gu_dgn_price: x.gu_dgn_price || 0, gu_tp: x.gu_tp || 0, gai_dgn_qty1: x.gai_dgn_qty1 || 0, gai_dgn_qty2: x.gai_dgn_qty2 || 0, gai_dgn_qty: x.gai_dgn_qty || '', gai_dgn_price: x.gai_dgn_price || 0, gai_tp: x.gai_tp || 0, yu_dgn_qty1: x.yu_dgn_qty1 || 0, yu_dgn_qty2: x.yu_dgn_qty2 || 0, yu_dgn_qty: x.yu_dgn_qty || '', yu_dgn_price: x.yu_dgn_price || 0, yu_tp: x.yu_tp || 0, zb_dgn_qty1: x.zb_dgn_qty1 || 0, zb_dgn_qty2: x.zb_dgn_qty2 || 0, zb_dgn_qty: x.zb_dgn_qty || '', zb_dgn_price: x.zb_dgn_price || 0, zb_tp: x.zb_tp || 0, ctrl_dgn_qty1: x.ctrl_dgn_qty1 || 0, ctrl_dgn_qty2: x.ctrl_dgn_qty2 || 0, ctrl_dgn_qty: x.ctrl_dgn_qty || '', ctrl_dgn_price: x.ctrl_dgn_price || 0, ctrl_tp: x.ctrl_tp || 0, real_dgn_qty1: x.real_dgn_qty1 || 0, real_dgn_qty2: x.real_dgn_qty2 || 0, real_dgn_qty: x.real_dgn_qty || '', real_dgn_price: x.real_dgn_price || 0, real_tp: x.real_tp || 0, dgn_qty1: x.dgn_qty1 || 0, dgn_qty2: x.dgn_qty2 || 0, total_price: x.total_price || 0, dgn_price: x.dgn_price || 0, dgn_qty: x.dgn_qty || '', deal_dgn_qty1: x.deal_dgn_qty1 || 0, deal_dgn_qty2: x.deal_dgn_qty2 || 0, c_dgn_qty1: x.c_dgn_qty1 || 0, c_dgn_qty2: x.c_dgn_qty2 || 0, final_dgn_qty1: x.final_dgn_qty1 || 0, final_dgn_qty2: x.final_dgn_qty2 || 0, final_tp: x.final_tp || 0, final_contract_tp: x.final_contract_tp || 0, final_qc_tp: x.final_qc_tp || 0, final_dgn_price: x.final_dgn_price || 0, final_dgn_qty: x.final_dgn_qty || '', tz_qc_qty: x.tz_qc_qty || 0, tz_qc_tp: x.tz_qc_tp || 0, grow_dgn_qty1: x.grow_dgn_qty1 || 0, grow_dgn_qty2: x.grow_dgn_qty2 || 0, grow_dgn_qty: x.grow_dgn_qty || '', grow_tp: x.grow_tp || 0, }) }); return data; } async doFinal(budget, final, stage, contract) { this.budget = budget; this.final = final; this.finalTree.checkField = budget.final_type.split('_'); for (const t of final.tender) { await this._loadTender(t, stage); } await this._loadReal(budget); await this._loadCtrl(budget); await this._loadZb(budget); await this._loadYu(budget); await this._loadGai(budget); await this._loadGu(budget); await this._loadDeal(contract, stage); this._afterLoad(); return this.getFinalData(); } } module.exports = BudgetFinal;