/** * Created by Mai on 2017/7/5. */ const rationContent = 0, rationPrice = 1, rationPriceConverse = 2, billsPrice = 3; // sumTotalFeeFlag: sum(child.totalFee), totalFeeFlag: bills.quantity × bills.unitFee const sumTotalFeeFlag = 0, totalFeeFlag = 1; // rationContentUnitFeeFlag: sum(child.unitFee * child.quantity / bills.quantity) // averageQtyUnitFeeFlag: sum(child.totalFee/bills.quantity) // billsPriceUnitFeeFlag: 根据定额计算程序 // converseUnitFeeFalg: bills.totalFee / bills.quantity const rationContentUnitFeeFlag = 0, averageQtyUnitFeeFlag = 1, billsPriceUnitFeeFlag = 2, converseUnitFeeFlag = 3; let rationContentCalcFields = [ {'type': 'common', 'unitFeeFlag': rationContentUnitFeeFlag, 'totalFeeFlag': totalFeeFlag}, {'type': 'labour', 'unitFeeFlag': rationContentUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag}, {'type': 'material', 'unitFeeFlag': rationContentUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag}, {'type': 'machine', 'unitFeeFlag': rationContentUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag} ]; let rationPriceCalcFields = [ {'type': 'common', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': totalFeeFlag}, {'type': 'labour', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag}, {'type': 'material', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag}, {'type': 'machine', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag} ]; let rationPriceConverseCalcFields = [ {'type': 'common', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag}, {'type': 'labour', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag}, {'type': 'material', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag}, {'type': 'machine', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag} ]; let billsPriceCalcFields = [ {'type': 'common', 'unitFeeFlag': billsPriceUnitFeeFlag, 'totalFeeFlag': totalFeeFlag}, {'type': 'labour', 'unitFeeFlag': billsPriceUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag}, {'type': 'material', 'unitFeeFlag': billsPriceUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag}, {'type': 'machine', 'unitFeeFlag': billsPriceUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag} ]; let nodeCalcObj = { node: null, digit: 2, field: null, getFee: calcFees.getFee, sumTotalFee: function() { let result = 0, child; for (child of this.node.children) { let value = this.getFee(child.data, this.field.totalFee); if (Object.prototype.toString.apply(value) === "[object String]") { value = parseFloat(value); } result += value; } return result; }, averageQty: function() { let result = 0, child, qty; result = this.sumTotalFee(this.field); qty = this.getFee(this.node.data, 'quantity'); if (Object.prototype.toString.apply(qty) === "[object String]") { qty = parseFloat(qty); } if (qty !== 0) { result = result / qty; } return result; }, totalFee: function () { return this.getFee(this.node.data, this.field.unitFee) * this.getFee(this.node.data, 'quantity'); }, rationContentUnitFee: function () { let result = 0, child, qty = this.getFee(this.node.data, 'quantity'); if (Object.prototype.toString.apply(qty) === "[object String]") { qty = parseFloat(qty); } if (qty === 0) { qty = 1; } for (child of this.node.children) { let childUnitFee = this.getFee(child.data, this.field.unitFee); if (Object.prototype.toString.apply(childUnitFee) === "[object String]") { childUnitFee = parseFloat(childUnitFee); } let childQuantity = this.getFee(child.data, 'quantity'); if (Object.prototype.toString.apply(childQuantity) === "[object String]") { childQuantity = parseFloat(childQuantity); } result += (childUnitFee * childQuantity / qty).toDecimal(this.digit); } return result; }, converseUnitFee: function (digit) { let totalFee = this.sumTotalFee().toDecimal(digit); let qty = this.getFee(this.node.data, 'quantity'); if (qty !== 0){ return totalFee / qty; } else { return 0; } } }; let baseCalcField = [ { ID: 1, // 序号 serialNo: '一', // 费用代号 code: "A", // 名称 name: "定额直接费", // 计算基数 dispExpr: "A1+A2+A3", // 基数说明 statement: "人工费+材料费+机械费", // 费率 feeRate: null, // 费用类别 type: 'RationDirect', // 备注 memo: '' }, { ID: 2, // 序号 serialNo: '1', // 费用代号 code: "A1", // 名称 name: "人工费", // 计算基数 dispExpr: "H_J", // 基数说明 statement: "合计", // 费率 feeRate: 0, // 费用类别 type: 'labour', // 备注 memo: '' }, { ID: 3, // 序号 serialNo: '2', // 费用代号 code: "A2", // 名称 name: "材料费", // 计算基数 dispExpr: "H_J", // 基数说明 statement: "合计", // 费率 feeRate: 100, // 费用类别 type: 'material', // 备注 memo: '' }, { ID: 4, // 序号 serialNo: '3', // 费用代号 code: "A3", // 名称 name: "机械费", // 计算基数 dispExpr: "H_J", // 基数说明 statement: "合计", // 费率 feeRate: 0, // 费用类别 type: 'machine', // 备注 memo: '' }, { ID: 5, // 序号 serialNo: '二', // 费用代号 code: "A4", // 名称 name: "管理费", // 计算基数 dispExpr: "A", // 基数说明 statement: "定额直接费", // 费率 feeRate: 0, // 费用类别 type: 'management', // 备注 memo: '' }, { ID: 6, // 序号 serialNo: '三', // 费用代号 code: "B", // 名称 name: "利润", // 计算基数 dispExpr: "A", // 基数说明 statement: "定额直接费", // 费率 feeRate: 0, // 费用类别 type: 'profit', // 备注 memo: '' }, { ID: 7, // 序号 serialNo: '四', // 费用代号 code: "C", // 名称 name: "风险费用", // 计算基数 dispExpr: "", // 基数说明 statement: "", // 费率 feeRate: null, // 费用类别 type: 'risk', // 备注 memo: '' }, { ID: 8, // 序号 serialNo: '', // 费用代号 code: "", // 名称 name: "综合单价", // 计算基数 dispExpr: "A+B", // 基数说明 statement: "定额直接费+利润", // 费率 feeRate: NaN, // 费用类别 type: 'common', // 备注 memo: '' } ]; class BillsCalcHelper { constructor (project, calcFlag) { this.project = project; this.InitFields(project.calcFields); }; getBillsGLjs (node) { let rations = this.project.Ration.getBillsSortRation(node.source.getID()); let gljs = this.project.ration_glj.getGatherGljArrByRations(rations); for (let glj of gljs) { glj.quantity = (glj.quantity / calcFees.getFee(node.data, 'quantity')).toDecimal(4); } return gljs; }; calcRationLeaf (node, fields, isIncre) { nodeCalcObj.node = node; nodeCalcObj.digit = this.project.Decimal.common.unitFee; calcFees.checkFields(node.data, fields); let nodeCalc = nodeCalcObj, virData= null, decimal = this.project.Decimal; // 清单单价:套用定额计算程序 // if (this.project.calcFlag === billsPrice) { if (this.project.projSetting.billsCalcMode === billsPrice) { rationCalcObj.calcGljs = this.getBillsGLjs(node); console.log(rationCalcObj.calcGljs); rationCalcObj.calcFields = rationCalcFields; virData = rationCalcObj.calculate(); } for (let field of fields) { nodeCalcObj.field = field; switch (field.unitFeeFlag) { case rationContentUnitFeeFlag: node.data.feesIndex[field.type].unitFee = nodeCalcObj.rationContentUnitFee().toDecimal(decimal.common.unitFee); break; case averageQtyUnitFeeFlag: node.data.feesIndex[field.type].unitFee = nodeCalcObj.averageQty().toDecimal(decimal.common.unitFee); break; case billsPriceUnitFeeFlag: node.data.feesIndex[field.type].unitFee = virData[field.type]; break; case converseUnitFeeFlag: node.data.feesIndex[field.type].unitFee = nodeCalcObj.converseUnitFee(decimal.common.totalFee).toDecimal(decimal.common.unitFee); break; default: node.data.feesIndex[field.type].unitFee = 0; } let value = 0; switch (field.totalFeeFlag) { case sumTotalFeeFlag: value = nodeCalcObj.sumTotalFee().toDecimal(decimal.common.totalFee); break; case totalFeeFlag: value = nodeCalcObj.totalFee().toDecimal(decimal.common.totalFee); break; default: value = 0; } this.setTotalFee(node, field, value, isIncre); } }; calcVolumePriceLeaf (node, fields, isIncre) { let total = 0; for (let child of node.children) { total += calcFees.getFee(child.data, 'feesIndex.common.totalFee'); } }; calcParent (node, fields, isIncre) { nodeCalcObj.node = node; calcFees.checkFields(node.data, fields); for (let field of fields) { nodeCalcObj.field = field; let value = nodeCalcObj.sumTotalFee().toDecimal(this.project.Decimal.common.totalFee); this.setTotalFee(node, field, value, isIncre); } }; clearFeeFields(node, fields, isIncre) { for (let field of fields) { node.data.feesIndex[field.type].unitFee = 0; this.setTotalFee(node, field, 0, isIncre); } } calcNode(node, isIncre) { if (node.source.children.length > 0) { this.calcParent(node, this.project.calcFields, isIncre); } else { if (node.children.length > 0) { if (node.firstChild().sourceType === this.project.Ration.getSourceType()) { this.calcRationLeaf(node, this.project.calcFields, isIncre); } else { this.calcVolumePriceLeaf(node, this.project.calcFields, isIncre); } } else { this.clearFeeFields(node, this.project.calcFields, isIncre); } } }; calcNodes (nodes) { for (let node of nodes) { if (node.sourceType !== this.project.Bills.getSourceType()) { return; } if (node.source.children.length > 0) { this.calcNodes(node.children); } this.calcNode(node); } }; updateParent (parent, field, Incre) { if (parent && parent.sourceType === this.project.Bills.getSourceType()) { calcFees.checkFields(parent.data, [field]); parent.data.feesIndex[field.type].totalFee = (parent.data.feesIndex[field.type].totalFee + Incre).toDecimal(this.project.Decimal.common.totalFee); parent.data.feesIndex[field.type].unitFee = 0; // AAAAA 临时补上,使存储 unitFee.toFixed(2) 时不出错 this.updateParent(parent.parent, field, Incre); } }; setTotalFee (node, field, value, isIncre) { if (isIncre) { let incre = value - node.data.feesIndex[field.type].totalFee; node.data.feesIndex[field.type].totalFee = value; node.data.feesIndex[field.type].unitFee = 0; // AAAAA 临时补上,使存储 unitFee.toFixed(2) 时不出错 this.updateParent(node.parent, field, incre); } else { node.data.feesIndex[field.type].totalFee = value; node.data.feesIndex[field.type].unitFee = 0; // AAAAA 临时补上,使存储 unitFee.toFixed(2) 时不出错 } }; converseCalc (node) { if (node && node.sourceType === this.project.Bills.getSourceType()) { this.calcNode(node); this.converseCalc(node.parent); } }; calcAll () { this.calcNodes(this.project.mainTree.roots); }; InitFields (fields) { for (let field of fields) { if (field.unitFee) return; field.unitFee = 'feesIndex.' + field.type + '.unitFee'; field.unitFeeSplit = field.unitFee.split('.'); field.totalFee = 'feesIndex.' + field.type + '.totalFee'; field.totalFeeSplit = field.totalFee.split('.'); field.tenderUnitFee = 'feesIndex.'+ field.type + '.tenderUnitFee'; field.tenderUnitFeeSplit = field.tenderUnitFee.split('.'); field.tenderTotalFee = 'feesIndex.' + field.type + '.tenderTotalFee'; field.tenderTotalFeeSplit = field.tenderTotalFee.split('.'); } }; }