|
@@ -3,92 +3,6 @@
|
|
|
* 计算程序。所有定额、清单、父清单的计算都从此入。
|
|
|
*/
|
|
|
|
|
|
-/* 新版GLD 取消了默认清单模板,所以这里废弃。先留着,预防不时之需。
|
|
|
-let defaultBillTemplate = {
|
|
|
- ID: 15,
|
|
|
- name: "清单公式",
|
|
|
- calcItems: [
|
|
|
- {
|
|
|
- ID: 1,
|
|
|
- code: "1",
|
|
|
- name: "定额直接费",
|
|
|
- dispExpr: "F2+F3+F4",
|
|
|
- statement: "人工费+材料费+机械费",
|
|
|
- feeRate: null,
|
|
|
- memo: ''
|
|
|
- },
|
|
|
- {
|
|
|
- ID: 2,
|
|
|
- code: "1.1",
|
|
|
- name: "人工费",
|
|
|
- dispExpr: "HJ",
|
|
|
- statement: "合计",
|
|
|
- feeRate: 50,
|
|
|
- fieldName: 'labour',
|
|
|
- memo: ''
|
|
|
- },
|
|
|
- {
|
|
|
- ID: 3,
|
|
|
- code: "1.2",
|
|
|
- name: "材料费",
|
|
|
- dispExpr: "HJ",
|
|
|
- statement: "合计",
|
|
|
- feeRate: 30,
|
|
|
- fieldName: 'material',
|
|
|
- memo: ''
|
|
|
- },
|
|
|
- {
|
|
|
- ID: 4,
|
|
|
- code: "1.3",
|
|
|
- name: "机械费",
|
|
|
- dispExpr: "HJ",
|
|
|
- statement: "合计",
|
|
|
- feeRate: 20,
|
|
|
- fieldName: 'machine',
|
|
|
- memo: ''
|
|
|
- },
|
|
|
- {
|
|
|
- ID: 5,
|
|
|
- code: "2",
|
|
|
- name: "企业管理费",
|
|
|
- dispExpr: "F1",
|
|
|
- statement: "定额直接费",
|
|
|
- feeRate: null,
|
|
|
- fieldName: 'manage',
|
|
|
- memo: ''
|
|
|
- },
|
|
|
- {
|
|
|
- ID: 6,
|
|
|
- code: "3",
|
|
|
- name: "利润",
|
|
|
- dispExpr: "F1",
|
|
|
- statement: "定额直接费",
|
|
|
- feeRate: null,
|
|
|
- fieldName: 'profit',
|
|
|
- memo: ''
|
|
|
- },
|
|
|
- {
|
|
|
- ID: 7,
|
|
|
- code: "4",
|
|
|
- name: "风险费用",
|
|
|
- dispExpr: "F1",
|
|
|
- statement: "定额直接费",
|
|
|
- feeRate: null,
|
|
|
- fieldName: 'risk',
|
|
|
- memo: ''
|
|
|
- },
|
|
|
- {
|
|
|
- ID: 8,
|
|
|
- code: "5",
|
|
|
- name: "综合单价",
|
|
|
- dispExpr: "F1+F5+F6+F7",
|
|
|
- statement: "定额直接费+企业管理费+利润+风险费用",
|
|
|
- feeRate: null,
|
|
|
- fieldName: 'common',
|
|
|
- memo: ''
|
|
|
- }
|
|
|
- ]
|
|
|
-};*/
|
|
|
let calcTools = {
|
|
|
getNodeByFlag: function (flag) {
|
|
|
let bill = cbTools.findBill(flag);
|
|
@@ -284,7 +198,7 @@ let calcTools = {
|
|
|
if (!feeObj) return;
|
|
|
if (feeObj.fieldName == '') return;
|
|
|
|
|
|
- // 初始化前先拦截末定义的情况
|
|
|
+ // 初始化前,先拦截属性末定义、又要给该属性赋0的情况
|
|
|
if (!treeNode.data.feesIndex || !treeNode.data.feesIndex[feeObj.fieldName]){
|
|
|
if (feeObj.unitFee == 0 && feeObj.totalFee == 0 && feeObj.tenderUnitFee == 0 && feeObj.tenderTotalFee == 0) return;
|
|
|
}
|
|
@@ -1126,12 +1040,14 @@ let calcTools = {
|
|
|
}
|
|
|
return totalFee > maxPrice;
|
|
|
},
|
|
|
+
|
|
|
getTenderCalcType: function () {
|
|
|
let tenderSetting = projectObj.project.property.tenderSetting;
|
|
|
let ct = tenderSetting && tenderSetting.calcPriceOption? tenderSetting.calcPriceOption : "coeBase";
|
|
|
if (ct == 'priceBase') ct = 'priceBase_RCJ'; // 兼容旧项目
|
|
|
return ct;
|
|
|
}
|
|
|
+
|
|
|
};
|
|
|
|
|
|
let rationCalcBases = {
|
|
@@ -1372,8 +1288,8 @@ let analyzer = {
|
|
|
for (let base of arrBase){
|
|
|
let baseName = base.slice(1, -1);
|
|
|
if (!rationCalcBases[baseName]){
|
|
|
- analyzer.error = `定额基数${hintBox.font('[' +baseName + ']')}末定义!`;
|
|
|
- // hintBox.infoBox('错误提示', `定额基数${hintBox.font('[' +baseName + ']')}末定义!`, 1);
|
|
|
+ analyzer.error = `定额基数${hintBox.font('[' +baseName + ']')}未定义!`;
|
|
|
+ // hintBox.infoBox('错误提示', `定额基数${hintBox.font('[' +baseName + ']')}未定义!`, 1);
|
|
|
return false;
|
|
|
}
|
|
|
};
|
|
@@ -1587,7 +1503,7 @@ let executeObj = {
|
|
|
return calcTools.marketPriceToBase(me.treeNode, baseName, isTender)
|
|
|
else{
|
|
|
if (!rationCalcBases[baseName]){
|
|
|
- hintBox.infoBox('系统提示', '定额基数“' + baseName + '”末定义,计算错误。 (模板 ' + me.template.ID + ',规则 ' + me.tempCalcItem.ID +')', 1);
|
|
|
+ hintBox.infoBox('系统提示', '定额基数“' + baseName + '”未定义,计算错误。 (模板 ' + me.template.ID + ',规则 ' + me.tempCalcItem.ID +')', 1);
|
|
|
return 0;
|
|
|
}
|
|
|
else
|
|
@@ -1641,7 +1557,7 @@ class CalcProgram {
|
|
|
me.compiledFeeTypeMaps = {};
|
|
|
me.compiledFeeTypeNames = [];
|
|
|
me.compiledCalcBases = {};
|
|
|
- // me.saveForReports = [];
|
|
|
+
|
|
|
|
|
|
me.feeRates = this.project.FeeRate.datas.rates;
|
|
|
me.labourCoes = this.project.labourCoe.datas.coes;
|
|
@@ -1656,19 +1572,6 @@ class CalcProgram {
|
|
|
for (let t of me.templates){
|
|
|
me.compileTemplate(t);
|
|
|
};
|
|
|
-
|
|
|
-
|
|
|
- // 存储费率临时数据,报表用。
|
|
|
- // if (isInit && me.saveForReports.length > 0){
|
|
|
- // let saveDatas = {};
|
|
|
- // saveDatas.projectID = projectObj.project.projectInfo.ID;
|
|
|
- // saveDatas.calcItems = me.saveForReports;
|
|
|
- // CommonAjax.post('/calcProgram/saveCalcItems', saveDatas, function (result) {
|
|
|
- // if (result){
|
|
|
- // me.saveForReports = [];
|
|
|
- // };
|
|
|
- // });
|
|
|
- // };
|
|
|
};
|
|
|
|
|
|
compilePublics(){
|
|
@@ -1805,275 +1708,276 @@ class CalcProgram {
|
|
|
};
|
|
|
};
|
|
|
|
|
|
+ // 删掉多余的费用。例如:①切换取费类别 ②从其它计算方式(有很多费)切换到公式计算方式(只需要common费),多出来的费要删除。
|
|
|
+ // 如果指定了保留字段,则按用户指定的来。如果没指定保留字段,则按默认的来:总造价清单只留common, estimate两个费用类别。其它公式清单只留common。
|
|
|
+ deleteUselessFees(treeNode, fieldNameArr){
|
|
|
+ if (!(treeNode.data.fees && treeNode.data.fees.length > 0)) return;
|
|
|
+ let keeps = fieldNameArr ? fieldNameArr : [];
|
|
|
+ // 这两个默认是要保留的
|
|
|
+ if (!keeps.includes('common')) keeps.push('common');
|
|
|
+ if (!keeps.includes('estimate')) keeps.push('estimate');
|
|
|
+
|
|
|
+ for (let i = 0; i < treeNode.data.fees.length; i++) {
|
|
|
+ if (!keeps.includes(treeNode.data.fees[i].fieldName)) {
|
|
|
+ delete treeNode.data.feesIndex[treeNode.data.fees[i].fieldName];
|
|
|
+ treeNode.data.fees.splice(i, 1);
|
|
|
+ treeNode.changed = true;
|
|
|
+ }
|
|
|
+ };
|
|
|
+ };
|
|
|
+
|
|
|
+ // 不能直接删除该属性,否则无法冲掉库中已存储的值。下同。
|
|
|
+ deleteProperties (treeNode, propNamesArr){
|
|
|
+ for (let pn of propNamesArr){
|
|
|
+ if (treeNode.data[pn]){
|
|
|
+ treeNode.data[pn] = null;
|
|
|
+ treeNode.changed = true;
|
|
|
+ }
|
|
|
+ };
|
|
|
+ };
|
|
|
+
|
|
|
// 只计算treeNode自身。changedArr: 外部传来的一个数组,专门存储发生变动的节点。
|
|
|
innerCalc(treeNode, changedArr, tenderType){
|
|
|
+ if (treeNode.sourceType === ModuleNames.ration_glj) return; // 仅用作树节点显示的工料机不能参与计算。
|
|
|
+
|
|
|
let me = this;
|
|
|
- // 仅用作树节点显示的工料机不能参与计算。
|
|
|
- if (treeNode.sourceType === ModuleNames.ration_glj) return;
|
|
|
//设置定额工料机映射表
|
|
|
me.setRationMap();
|
|
|
+
|
|
|
treeNode.calcType = calcTools.getCalcType(treeNode);
|
|
|
- let nQ = calcTools.uiNodeQty(treeNode);
|
|
|
- let nTQ = calcTools.uiNodeTenderQty(treeNode);
|
|
|
|
|
|
- function isBaseFeeType(type){
|
|
|
- return ['labour', 'material', 'machine', 'mainMaterial', 'equipment'].indexOf(type) > -1;
|
|
|
- };
|
|
|
+ // 父清单汇总子清单的费用类别
|
|
|
+ if (treeNode.calcType == treeNodeCalcType.ctGatherBillsFees)
|
|
|
+ me.innerCalcBill(treeNode, 2)
|
|
|
+ // 叶子清单汇总定额的费用类别
|
|
|
+ else if (treeNode.calcType == treeNodeCalcType.ctGatherRationsFees)
|
|
|
+ me.innerCalcBill(treeNode, 1)
|
|
|
+ // 叶子清单:公式计算
|
|
|
+ else if (treeNode.calcType == treeNodeCalcType.ctCalcBaseValue)
|
|
|
+ me.innerCalcBillExpr(treeNode)
|
|
|
+ // 叶子清单:手工修改单价或金额(无定额、无公式计算,什么都没有时)。
|
|
|
+ else if (treeNode.calcType == treeNodeCalcType.ctNull)
|
|
|
+ me.innerCalcBillCustom(treeNode)
|
|
|
+ // 定额:计算程序
|
|
|
+ else
|
|
|
+ me.innerCalcRation(treeNode, tender);
|
|
|
|
|
|
- // 不能直接删除该属性,否则无法冲掉库中已存储的值。下同。
|
|
|
- function deleteProperties (treeNode, propNamesArr){
|
|
|
- for (let pn of propNamesArr){
|
|
|
- if (treeNode.data[pn]){
|
|
|
- treeNode.data[pn] = null;
|
|
|
- treeNode.changed = true;
|
|
|
- }
|
|
|
- };
|
|
|
- };
|
|
|
+ if (!calcTools.isTotalCostBill(treeNode)) // 已在上面的分支中计算过
|
|
|
+ calcTools.estimateFee(treeNode);
|
|
|
|
|
|
- // 删掉多余的费用。例如:①切换取费类别 ②从其它计算方式(有很多费)切换到公式计算方式(只需要common费),多出来的费要删除。
|
|
|
- // 如果指定了保留字段,则按用户指定的来。如果没指定保留字段,则按默认的来:总造价清单只留common, estimate两个费用类别。其它公式清单只留common。
|
|
|
- function deleteUselessFees(treeNode, fieldNameArr){
|
|
|
- if (!(treeNode.data.fees && treeNode.data.fees.length > 0)) return;
|
|
|
- let keeps = fieldNameArr ? fieldNameArr : [];
|
|
|
- // 这两个默认是要保留的
|
|
|
- if (!keeps.includes('common')) keeps.push('common');
|
|
|
- if (!keeps.includes('estimate')) keeps.push('estimate');
|
|
|
+ if (treeNode.changed && !changedArr.includes(treeNode)) changedArr.push(treeNode);
|
|
|
+ };
|
|
|
|
|
|
- for (let i = 0; i < treeNode.data.fees.length; i++) {
|
|
|
- if (!keeps.includes(treeNode.data.fees[i].fieldName)) {
|
|
|
- delete treeNode.data.feesIndex[treeNode.data.fees[i].fieldName];
|
|
|
- treeNode.data.fees.splice(i, 1);
|
|
|
- treeNode.changed = true;
|
|
|
- }
|
|
|
- };
|
|
|
+ // 清单部分抽取出来,供分摊清单公用。commonCalcType:1 叶子清单汇总定额的费用类别; 2 父清单汇总子清单的费用类别。3: 分摊:叶子清单汇总定额的费用类别。
|
|
|
+ innerCalcBill(treeNode, commonCalcType, tender = tenderTypes.ttCalc){
|
|
|
+ let me = this;
|
|
|
+ treeNode.data.programID = null;
|
|
|
+ calcTools.initFees(treeNode);
|
|
|
+
|
|
|
+ let nodes = [];
|
|
|
+ if (commonCalcType == 1){
|
|
|
+ calcTools.getGLJList(treeNode, true);
|
|
|
+ nodes = me.project.Ration.getRationNodes(treeNode);
|
|
|
+ }
|
|
|
+ else if (commonCalcType == 2)
|
|
|
+ nodes = treeNode.children
|
|
|
+ else if (commonCalcType == 3)
|
|
|
+ nodes = treeNode.children;
|
|
|
+
|
|
|
+ function isBaseFeeType(type){
|
|
|
+ return ['labour', 'material', 'machine', 'mainMaterial', 'equipment'].indexOf(type) > -1;
|
|
|
};
|
|
|
|
|
|
- // 叶子清单汇总定额、父清单汇总子清单的费用类别
|
|
|
- if (treeNode.calcType == treeNodeCalcType.ctGatherBillsFees || treeNode.calcType == treeNodeCalcType.ctGatherRationsFees){
|
|
|
- treeNode.data.programID = null;
|
|
|
- calcTools.initFees(treeNode);
|
|
|
+ let rst = [];
|
|
|
+ for (let ft of cpFeeTypes) {
|
|
|
+ let ftObj = {};
|
|
|
+ ftObj.fieldName = ft.type;
|
|
|
+ ftObj.name = ft.name;
|
|
|
+ let buf = 0, btf = 0, btuf = 0, bttf = 0;
|
|
|
|
|
|
- let nodes = [];
|
|
|
- if (treeNode.calcType == treeNodeCalcType.ctGatherRationsFees){
|
|
|
- calcTools.getGLJList(treeNode, true);
|
|
|
- nodes = me.project.Ration.getRationNodes(treeNode);
|
|
|
- } else { //固定清单材料(工程设备)暂估价比较特殊,不进行父项汇总(需求)
|
|
|
- nodes = me.project.Bills.getGatherNodes(treeNode);
|
|
|
+ let nQ = calcTools.uiNodeQty(treeNode);
|
|
|
+ let nTQ = calcTools.uiNodeTenderQty(treeNode);
|
|
|
+ let bq = nQ ? nQ : 1;
|
|
|
+ let btq = nTQ ? nTQ : 1;
|
|
|
+
|
|
|
+ if (commonCalcType == 2){
|
|
|
+ for (let node of nodes) {
|
|
|
+ if (node.data.feesIndex && node.data.feesIndex[ft.type]) {
|
|
|
+ btf = (btf + parseFloatPlus(node.data.feesIndex[ft.type].totalFee)).toDecimal(decimalObj.process);
|
|
|
+ bttf = (bttf + parseFloatPlus(node.data.feesIndex[ft.type].tenderTotalFee)).toDecimal(decimalObj.process);
|
|
|
+ };
|
|
|
+ };
|
|
|
}
|
|
|
- //else nodes = treeNode.children;
|
|
|
-
|
|
|
- let rst = [];
|
|
|
- for (let ft of cpFeeTypes) {
|
|
|
- let ftObj = {};
|
|
|
- ftObj.fieldName = ft.type;
|
|
|
- ftObj.name = ft.name;
|
|
|
- let buf = 0, btf = 0, btuf = 0, bttf = 0;
|
|
|
- let bq = nQ ? nQ : 1;
|
|
|
- let btq = nTQ ? nTQ : 1;
|
|
|
-
|
|
|
- if (treeNode.calcType == treeNodeCalcType.ctGatherBillsFees){
|
|
|
- for (let node of nodes) {
|
|
|
- if (node.data.feesIndex && node.data.feesIndex[ft.type]) { // 父清单不要汇总综合单价。
|
|
|
- btf = (btf + parseFloatPlus(node.data.feesIndex[ft.type].totalFee)).toDecimal(decimalObj.process);
|
|
|
- bttf = (bttf + parseFloatPlus(node.data.feesIndex[ft.type].tenderTotalFee)).toDecimal(decimalObj.process);
|
|
|
- };
|
|
|
+ else if ((commonCalcType == 1) || (commonCalcType == 3)){
|
|
|
+ let sum_rtf = 0, sum_rttf = 0;
|
|
|
+ for (let node of nodes) {
|
|
|
+ let ruf = 0, rtuf = 0, rtf = 0, rttf = 0;
|
|
|
+ if (node.data.feesIndex && node.data.feesIndex[ft.type]) {
|
|
|
+ ruf = parseFloatPlus(node.data.feesIndex[ft.type].unitFee).toDecimal(decimalObj.bills.unitPrice);
|
|
|
+ rtuf = parseFloatPlus(node.data.feesIndex[ft.type].tenderUnitFee).toDecimal(decimalObj.bills.unitPrice);
|
|
|
+ rtf = parseFloatPlus(node.data.feesIndex[ft.type].totalFee).toDecimal(decimalObj.bills.totalPrice);
|
|
|
+ rttf = parseFloatPlus(node.data.feesIndex[ft.type].tenderTotalFee).toDecimal(decimalObj.bills.totalPrice);
|
|
|
};
|
|
|
- }
|
|
|
- else if (treeNode.calcType == treeNodeCalcType.ctGatherRationsFees){ // 这里的算法要配合冷姐姐的神图才能看懂^_^
|
|
|
- let sum_rtf = 0, sum_rttf = 0;
|
|
|
- for (let node of nodes) {
|
|
|
- let ruf = 0, rtuf = 0, rtf = 0, rttf = 0;
|
|
|
- if (node.data.feesIndex && node.data.feesIndex[ft.type]) {
|
|
|
- ruf = parseFloatPlus(node.data.feesIndex[ft.type].unitFee).toDecimal(decimalObj.bills.unitPrice);
|
|
|
- rtuf = parseFloatPlus(node.data.feesIndex[ft.type].tenderUnitFee).toDecimal(decimalObj.bills.unitPrice);
|
|
|
- rtf = parseFloatPlus(node.data.feesIndex[ft.type].totalFee).toDecimal(decimalObj.bills.totalPrice);
|
|
|
- rttf = parseFloatPlus(node.data.feesIndex[ft.type].tenderTotalFee).toDecimal(decimalObj.bills.totalPrice);
|
|
|
- };
|
|
|
- // 取费方式为子目含量,清单行/列的XX单价应 =ROUND( ∑ROUND(定额XX单价*含量,清单单价精度),清单单价精度)
|
|
|
- if (me.project.property.billsCalcMode === leafBillGetFeeType.rationContent) {
|
|
|
- buf = (buf + (ruf * parseFloatPlus(node.data.contain)).toDecimal(decimalObj.bills.unitPrice)).toDecimal(decimalObj.process);
|
|
|
- node.data.tenderContaion = (node.data.tenderQuantity / bq).toDecimal(decimalObj.process);
|
|
|
- btuf = (btuf + (rtuf * parseFloatPlus(node.data.tenderContaion)).toDecimal(decimalObj.bills.unitPrice)).toDecimal(decimalObj.process);
|
|
|
- };
|
|
|
- sum_rtf = (sum_rtf + rtf).toDecimal(decimalObj.process);
|
|
|
- sum_rttf = (sum_rttf + rttf).toDecimal(decimalObj.process);
|
|
|
+ // 取费方式为子目含量,清单行/列的XX单价应 =ROUND( ∑ROUND(定额XX单价*含量,清单单价精度),清单单价精度)
|
|
|
+ if (me.project.property.billsCalcMode === leafBillGetFeeType.rationContent) {
|
|
|
+ buf = (buf + (ruf * parseFloatPlus(node.data.contain)).toDecimal(decimalObj.bills.unitPrice)).toDecimal(decimalObj.process);
|
|
|
+ node.data.tenderContaion = (node.data.tenderQuantity / bq).toDecimal(decimalObj.process);
|
|
|
+ btuf = (btuf + (rtuf * parseFloatPlus(node.data.tenderContaion)).toDecimal(decimalObj.bills.unitPrice)).toDecimal(decimalObj.process);
|
|
|
};
|
|
|
+ sum_rtf = (sum_rtf + rtf).toDecimal(decimalObj.process);
|
|
|
+ sum_rttf = (sum_rttf + rttf).toDecimal(decimalObj.process);
|
|
|
+ };
|
|
|
|
|
|
- if (me.project.property.billsCalcMode == leafBillGetFeeType.rationPriceConverse ||
|
|
|
- me.project.property.billsCalcMode == leafBillGetFeeType.rationPrice) {
|
|
|
- buf = (sum_rtf / bq).toDecimal(decimalObj.process);
|
|
|
- btuf = (sum_rttf / btq).toDecimal(decimalObj.process);
|
|
|
- };
|
|
|
- if (isBaseFeeType(ft.type) ||
|
|
|
- (me.project.property.billsCalcMode === leafBillGetFeeType.rationPrice && ft.type == "common")){
|
|
|
- btf = sum_rtf;
|
|
|
- bttf = sum_rttf;
|
|
|
- }
|
|
|
- else{
|
|
|
- btf = (buf.toDecimal(decimalObj.bills.unitPrice) * bq).toDecimal(decimalObj.process);
|
|
|
- bttf = (btuf.toDecimal(decimalObj.bills.unitPrice) * btq).toDecimal(decimalObj.process);
|
|
|
- };
|
|
|
+ if (me.project.property.billsCalcMode == leafBillGetFeeType.rationPriceConverse ||
|
|
|
+ me.project.property.billsCalcMode == leafBillGetFeeType.rationPrice) {
|
|
|
+ buf = (sum_rtf / bq).toDecimal(decimalObj.process);
|
|
|
+ btuf = (sum_rttf / btq).toDecimal(decimalObj.process);
|
|
|
};
|
|
|
+ if (isBaseFeeType(ft.type) ||
|
|
|
+ (me.project.property.billsCalcMode === leafBillGetFeeType.rationPrice && ft.type == "common")){
|
|
|
+ btf = sum_rtf;
|
|
|
+ bttf = sum_rttf;
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ btf = (buf.toDecimal(decimalObj.bills.unitPrice) * bq).toDecimal(decimalObj.process);
|
|
|
+ bttf = (btuf.toDecimal(decimalObj.bills.unitPrice) * btq).toDecimal(decimalObj.process);
|
|
|
+ };
|
|
|
+ };
|
|
|
|
|
|
- ftObj.totalFee = btf.toDecimal(decimalObj.bills.totalPrice);
|
|
|
- ftObj.tenderTotalFee = bttf.toDecimal(decimalObj.bills.totalPrice);
|
|
|
- ftObj.unitFee = buf.toDecimal(decimalObj.bills.unitPrice);
|
|
|
- ftObj.tenderUnitFee = btuf.toDecimal(decimalObj.bills.unitPrice);
|
|
|
+ ftObj.totalFee = btf.toDecimal(decimalObj.bills.totalPrice);
|
|
|
+ ftObj.tenderTotalFee = bttf.toDecimal(decimalObj.bills.totalPrice);
|
|
|
+ ftObj.unitFee = buf.toDecimal(decimalObj.bills.unitPrice);
|
|
|
+ ftObj.tenderUnitFee = btuf.toDecimal(decimalObj.bills.unitPrice);
|
|
|
|
|
|
- calcTools.checkFeeField(treeNode, ftObj);
|
|
|
+ calcTools.checkFeeField(treeNode, ftObj);
|
|
|
|
|
|
- rst.push(ftObj);
|
|
|
- };
|
|
|
- treeNode.data.calcTemplate = {"calcItems": rst};
|
|
|
+ rst.push(ftObj);
|
|
|
+ };
|
|
|
+ treeNode.data.calcTemplate = {"calcItems": rst};
|
|
|
+ };
|
|
|
+
|
|
|
+ innerCalcBillExpr(treeNode){
|
|
|
+ delete treeNode.data.gljList;
|
|
|
+ let me = this;
|
|
|
+ me.deleteProperties(treeNode, ['programID']);
|
|
|
+ me.deleteUselessFees(treeNode, ['common', 'rationCommon']);
|
|
|
+
|
|
|
+ let nQ = calcTools.uiNodeQty(treeNode);
|
|
|
+ let nTQ = calcTools.uiNodeTenderQty(treeNode);
|
|
|
+ let f = calcTools.getFeeRateByNode(treeNode);
|
|
|
+ let b = treeNode.data.calcBaseValue ? treeNode.data.calcBaseValue : 0;
|
|
|
+ let tb = treeNode.data.tenderCalcBaseValue ? treeNode.data.tenderCalcBaseValue : 0;
|
|
|
+ let q = nQ ? nQ : 1;
|
|
|
+ let tq = nTQ ? nTQ : 1;
|
|
|
+ let uf = (b * f * 0.01 / q).toDecimal(decimalObj.bills.unitPrice);
|
|
|
+ let tuf = (tb * f * 0.01 / tq).toDecimal(decimalObj.bills.unitPrice);
|
|
|
+ let tf = (me.project.property.billsCalcMode === leafBillGetFeeType.rationPrice) ? (b * f / 100) : (uf * q);
|
|
|
+ tf = tf.toDecimal(decimalObj.bills.totalPrice);
|
|
|
+ let ttf = (me.project.property.billsCalcMode === leafBillGetFeeType.rationPrice) ? (tb * f / 100) : (tuf * tq);
|
|
|
+ ttf = ttf.toDecimal(decimalObj.bills.totalPrice);
|
|
|
+
|
|
|
+ calcTools.checkFeeField(treeNode, {'fieldName': 'common', 'unitFee': uf, 'totalFee': tf, 'tenderUnitFee': tuf, 'tenderTotalFee': ttf});
|
|
|
+
|
|
|
+ // 总造价清单还要做单项工程、建设项目的四大项金额汇总
|
|
|
+ if (calcTools.isTotalCostBill(treeNode)){
|
|
|
+ // 公式叶子清单没有暂估费,但总造价清单除外。
|
|
|
+ calcTools.estimateFee(treeNode);
|
|
|
+ calcTools.initSummaryFee(treeNode);
|
|
|
+ treeNode.data.summaryFees.totalFee = tf;
|
|
|
+ treeNode.data.summaryFees.estimateFee = calcTools.getFee(treeNode, 'estimate.totalFee');
|
|
|
+ treeNode.data.summaryFees.safetyFee = calcTools.getFee(calcTools.getNodeByFlag(fixedFlag.SAFETY_CONSTRUCTION), 'common.totalFee');
|
|
|
+ treeNode.data.summaryFees.chargeFee = calcTools.getFee(calcTools.getNodeByFlag(fixedFlag.CHARGE), 'common.totalFee');
|
|
|
}
|
|
|
- // 叶子清单无子结点、无公式计算(啥都没有时)
|
|
|
- else if (treeNode.calcType == treeNodeCalcType.ctNull){
|
|
|
- delete treeNode.data.gljList;
|
|
|
- deleteProperties(treeNode, ['calcBase', 'calcBaseValue', 'tenderCalcBaseValue', 'programID']);
|
|
|
- deleteUselessFees(treeNode, ['rationCommon']);
|
|
|
- // 不能直接删除该属性,否则无法冲掉库中已存储的值。下同。
|
|
|
-/* if (treeNode.data.calcBase){
|
|
|
- treeNode.data.calcBase = null;
|
|
|
- treeNode.changed = true;
|
|
|
- }
|
|
|
|
|
|
- if (treeNode.data.calcBaseValue){
|
|
|
- treeNode.data.calcBaseValue = null;
|
|
|
- treeNode.changed = true;
|
|
|
- }
|
|
|
+ treeNode.data.calcTemplate = {"calcItems": []};
|
|
|
+ };
|
|
|
|
|
|
- if (treeNode.data.tenderCalcBaseValue){
|
|
|
- treeNode.data.tenderCalcBaseValue = null;
|
|
|
+ innerCalcBillCustom(treeNode){
|
|
|
+ let me = this;
|
|
|
+ delete treeNode.data.gljList;
|
|
|
+ me.deleteProperties(treeNode, ['calcBase', 'calcBaseValue', 'tenderCalcBaseValue', 'programID']);
|
|
|
+ me.deleteUselessFees(treeNode, ['rationCommon']);
|
|
|
+
|
|
|
+ // 2017-09-27 需求改了,除了第 1 、 2.2部分以外,都可以手工修改综合单价、综合合价并参与计算
|
|
|
+ // 在没有公式的情况下可以手工修改综合单价并参与计算
|
|
|
+ if(calcTools.canCalcToTalFeeByOwn(treeNode)){
|
|
|
+ if (treeNode.data.feesIndex && treeNode.data.feesIndex.common){
|
|
|
+ let ftObj = {fieldName: 'common'};
|
|
|
+ let nQ = calcTools.uiNodeQty(treeNode);
|
|
|
+ let nTQ = calcTools.uiNodeTenderQty(treeNode);
|
|
|
+ ftObj.unitFee = parseFloatPlus(treeNode.data.feesIndex.common.unitFee);
|
|
|
+ ftObj.totalFee = (ftObj.unitFee * nQ).toDecimal(decimalObj.bills.totalPrice);
|
|
|
+ ftObj.tenderUnitFee = ftObj.unitFee;
|
|
|
+ ftObj.tenderTotalFee = (ftObj.tenderUnitFee * nTQ).toDecimal(decimalObj.bills.totalPrice);
|
|
|
+ calcTools.checkFeeField(treeNode, ftObj);
|
|
|
+ }
|
|
|
+ } else{
|
|
|
+ if (treeNode.data.fees && treeNode.data.fees.length > 0){
|
|
|
+ treeNode.data.fees = null;
|
|
|
+ treeNode.data.feesIndex = null;
|
|
|
treeNode.changed = true;
|
|
|
}
|
|
|
+ };
|
|
|
|
|
|
- if (treeNode.data.programID) {
|
|
|
- treeNode.data.programID = null;
|
|
|
- treeNode.changed = true;
|
|
|
- };*/
|
|
|
-
|
|
|
- // 第1、2部分以外的叶子清单在没有公式的情况下可以手工修改综合单价并参与计算。
|
|
|
- // 2017-09-27 需求改了,除了第 1 、 2.2部分以外,都可以手工修改综合单价、综合合价并参与计算
|
|
|
- //if(!calcTools.isFBFX(treeNode) && !calcTools.isTechMeasure(treeNode)){ // if(!calcTools.isInheritFrom(treeNode, [fixedFlag.SUB_ENGINERRING, fixedFlag.MEASURE]))
|
|
|
- // 在没有公式的情况下可以手工修改综合单价并参与计算
|
|
|
- if(calcTools.canCalcToTalFeeByOwn(treeNode)){
|
|
|
- if (treeNode.data.feesIndex && treeNode.data.feesIndex.common){
|
|
|
- let ftObj = {};
|
|
|
- ftObj.fieldName = 'common';
|
|
|
- ftObj.unitFee = parseFloatPlus(treeNode.data.feesIndex.common.unitFee);
|
|
|
- ftObj.totalFee = (ftObj.unitFee * nQ).toDecimal(decimalObj.bills.totalPrice);
|
|
|
- ftObj.tenderUnitFee = ftObj.unitFee;
|
|
|
- ftObj.tenderTotalFee = (ftObj.tenderUnitFee * nTQ).toDecimal(decimalObj.bills.totalPrice);
|
|
|
- calcTools.checkFeeField(treeNode, ftObj);
|
|
|
- }
|
|
|
- } else{
|
|
|
- if (treeNode.data.fees && treeNode.data.fees.length > 0){
|
|
|
- treeNode.data.fees = null;
|
|
|
- treeNode.data.feesIndex = null;
|
|
|
+ treeNode.data.calcTemplate = {"calcItems": []};
|
|
|
+ };
|
|
|
+
|
|
|
+ // 定额部分抽取出来,供分摊定额公用。
|
|
|
+ innerCalcRation(treeNode, tenderType = tenderTypes.ttCalc){
|
|
|
+ let me = this;
|
|
|
+ let fnArr = [];
|
|
|
+ calcTools.getGLJList(treeNode, true);
|
|
|
+
|
|
|
+ if (treeNode.calcType == treeNodeCalcType.ctRationCalcProgram) {
|
|
|
+ // 量价、工料机类型的定额要求"市场合价"
|
|
|
+ if (calcTools.isVP_or_GLJR(treeNode)){
|
|
|
+ let u = treeNode.data.marketUnitFee ? treeNode.data.marketUnitFee : 0;
|
|
|
+ let nQ = calcTools.uiNodeQty(treeNode);
|
|
|
+ let t = (u * nQ).toDecimal(decimalObj.ration.totalPrice);
|
|
|
+ if (treeNode.data.marketTotalFee != t){
|
|
|
+ treeNode.data.marketTotalFee = t;
|
|
|
treeNode.changed = true;
|
|
|
- }
|
|
|
+ } ;
|
|
|
};
|
|
|
+ };
|
|
|
|
|
|
- treeNode.data.calcTemplate = {"calcItems": []};
|
|
|
- }
|
|
|
- // 叶子清单公式计算
|
|
|
- else if (treeNode.calcType == treeNodeCalcType.ctCalcBaseValue){
|
|
|
- delete treeNode.data.gljList;
|
|
|
+ let template = me.compiledTemplates[treeNode.data.programID];
|
|
|
+ treeNode.data.calcTemplate = template;
|
|
|
|
|
|
- if (treeNode.data.programID) {
|
|
|
- treeNode.data.programID = null;
|
|
|
- treeNode.changed = true;
|
|
|
- }
|
|
|
- let f = calcTools.getFeeRateByNode(treeNode);
|
|
|
- let b = treeNode.data.calcBaseValue ? treeNode.data.calcBaseValue : 0;
|
|
|
- let tb = treeNode.data.tenderCalcBaseValue ? treeNode.data.tenderCalcBaseValue : 0;
|
|
|
- let q = nQ ? nQ : 1;
|
|
|
- let tq = nTQ ? nTQ : 1;
|
|
|
- let uf = (b * f * 0.01 / q).toDecimal(decimalObj.bills.unitPrice);
|
|
|
- let tuf = (tb * f * 0.01 / tq).toDecimal(decimalObj.bills.unitPrice);
|
|
|
- let tf = (me.project.property.billsCalcMode === leafBillGetFeeType.rationPrice) ? (b * f / 100) : (uf * q);
|
|
|
- tf = tf.toDecimal(decimalObj.bills.totalPrice);
|
|
|
- let ttf = (me.project.property.billsCalcMode === leafBillGetFeeType.rationPrice) ? (tb * f / 100) : (tuf * tq);
|
|
|
- ttf = ttf.toDecimal(decimalObj.bills.totalPrice);
|
|
|
- deleteUselessFees(treeNode);
|
|
|
- calcTools.checkFeeField(treeNode, {'fieldName': 'common', 'unitFee': uf, 'totalFee': tf, 'tenderUnitFee': tuf, 'tenderTotalFee': ttf});
|
|
|
-
|
|
|
- // 总造价清单还要做单项工程、建设项目的四大项金额汇总
|
|
|
- if (calcTools.isTotalCostBill(treeNode)){
|
|
|
- // 公式叶子清单没有暂估费,但总造价清单除外。
|
|
|
- calcTools.estimateFee(treeNode);
|
|
|
- calcTools.initSummaryFee(treeNode);
|
|
|
- treeNode.data.summaryFees.totalFee = tf;
|
|
|
- treeNode.data.summaryFees.estimateFee = calcTools.getFee(treeNode, 'estimate.totalFee');
|
|
|
- treeNode.data.summaryFees.safetyFee = calcTools.getFee(calcTools.getNodeByFlag(fixedFlag.SAFETY_CONSTRUCTION), 'common.totalFee');
|
|
|
- treeNode.data.summaryFees.chargeFee = calcTools.getFee(calcTools.getNodeByFlag(fixedFlag.CHARGE), 'common.totalFee');
|
|
|
- }
|
|
|
+ if (treeNode && template && template.hasCompiled) {//2018-08-27 空行的时候,取费专业为空,template也为空,加入template非空判断
|
|
|
+ let $CE = executeObj;
|
|
|
+ $CE.treeNode = treeNode;
|
|
|
+ $CE.template = template;
|
|
|
|
|
|
- treeNode.data.calcTemplate = {"calcItems": []};
|
|
|
- }
|
|
|
- // 定额或叶子清单自己的计算程序计算
|
|
|
- else{
|
|
|
- let fnArr = [];
|
|
|
- calcTools.getGLJList(treeNode, true);
|
|
|
+ calcTools.initFees(treeNode);
|
|
|
|
|
|
- if (treeNode.calcType == treeNodeCalcType.ctRationCalcProgram) {
|
|
|
- // 量价、工料机类型的定额要求市场合价
|
|
|
- if (calcTools.isVP_or_GLJR(treeNode)){
|
|
|
- let muf = treeNode.data.marketUnitFee ? treeNode.data.marketUnitFee : 0;
|
|
|
- let mtf = (muf * nQ).toDecimal(decimalObj.ration.totalPrice);
|
|
|
- if (treeNode.data.marketTotalFee != mtf){
|
|
|
- treeNode.data.marketTotalFee = mtf;
|
|
|
- treeNode.changed = true;
|
|
|
- };
|
|
|
+ for (let idx of template.compiledSeq) {
|
|
|
+ let calcItem = template.calcItems[idx];
|
|
|
+ $CE.tempCalcItem = calcItem;
|
|
|
+ let feeRate = 100; // 100%
|
|
|
+ if (calcItem.feeRate != undefined)
|
|
|
+ feeRate = parseFloat(calcItem.feeRate).toDecimal(decimalObj.feeRate);
|
|
|
+
|
|
|
+ calcItem.unitFee = (eval(calcItem.compiledExpr) * feeRate * 0.01).toDecimal(decimalObj.decimal('unitPrice', treeNode));
|
|
|
+ calcItem.totalFee = (calcItem.unitFee * calcTools.uiNodeQty(treeNode)).toDecimal(decimalObj.decimal('totalPrice', treeNode));
|
|
|
+
|
|
|
+ let tExpr = analyzer.getCompiledTenderExpr(calcItem.compiledExpr);
|
|
|
+ calcItem.tenderUnitFee = (eval(tExpr) * feeRate * 0.01).toDecimal(decimalObj.decimal('unitPrice', treeNode));
|
|
|
+ calcItem.tenderTotalFee = (calcItem.tenderUnitFee * treeNode.data.tenderQuantity).toDecimal(decimalObj.decimal('totalPrice', treeNode));
|
|
|
+
|
|
|
+ if (calcItem.fieldName) {
|
|
|
+ fnArr.push(calcItem.fieldName);
|
|
|
+ calcTools.checkFeeField(treeNode, calcItem);
|
|
|
};
|
|
|
};
|
|
|
- // 2018-08-27 zhang 插入空定额的时候,取费专业也为空
|
|
|
- // if (treeNode.data.programID == undefined) treeNode.data.programID = projectObj.project.projectInfo.property.engineering;
|
|
|
- let template = me.compiledTemplates[treeNode.data.programID];
|
|
|
- treeNode.data.calcTemplate = template;
|
|
|
-
|
|
|
- if (treeNode && template && template.hasCompiled) {//2018-08-27 空行的时候,取费专业为空,template也为空,加入template非空判断
|
|
|
- let $CE = executeObj;
|
|
|
- $CE.treeNode = treeNode;
|
|
|
- $CE.template = template;
|
|
|
-
|
|
|
- calcTools.initFees(treeNode);
|
|
|
-
|
|
|
- for (let idx of template.compiledSeq) {
|
|
|
- let calcItem = template.calcItems[idx];
|
|
|
- $CE.tempCalcItem = calcItem;
|
|
|
- let feeRate = 100; // 100%
|
|
|
- if (calcItem.feeRate != undefined)
|
|
|
- feeRate = parseFloat(calcItem.feeRate).toDecimal(decimalObj.feeRate);
|
|
|
- // console.log(`[${calcItem.ID}]: ${calcItem.compiledExpr}`); // for test.
|
|
|
-
|
|
|
- calcItem.unitFee = (eval(calcItem.compiledExpr) * feeRate * 0.01).toDecimal(decimalObj.decimal('unitPrice', treeNode));
|
|
|
- calcItem.totalFee = (calcItem.unitFee * calcTools.uiNodeQty(treeNode)).toDecimal(decimalObj.decimal('totalPrice', treeNode));
|
|
|
-
|
|
|
- // if (tenderType == tenderTypes.ttCalc) {
|
|
|
- let tExpr = analyzer.getCompiledTenderExpr(calcItem.compiledExpr);
|
|
|
- calcItem.tenderUnitFee = (eval(tExpr) * feeRate * 0.01).toDecimal(decimalObj.decimal('unitPrice', treeNode));
|
|
|
- calcItem.tenderTotalFee = (calcItem.tenderUnitFee * treeNode.data.tenderQuantity).toDecimal(decimalObj.decimal('totalPrice', treeNode));
|
|
|
- // };
|
|
|
-
|
|
|
- if (calcItem.fieldName) {
|
|
|
- fnArr.push(calcItem.fieldName);
|
|
|
- calcTools.checkFeeField(treeNode, calcItem);
|
|
|
- };
|
|
|
- };
|
|
|
|
|
|
- if (tenderType == tenderTypes.ttReverseRation || tenderType == tenderTypes.ttReverseGLJ)
|
|
|
- this.calcTenderReverse(treeNode, tenderType);
|
|
|
+ if (tenderType == tenderTypes.ttReverseRation || tenderType == tenderTypes.ttReverseGLJ)
|
|
|
+ this.calcTenderReverse(treeNode, tenderType);
|
|
|
|
|
|
- deleteUselessFees(treeNode, fnArr);
|
|
|
- };
|
|
|
+ me.deleteUselessFees(treeNode, fnArr);
|
|
|
};
|
|
|
-
|
|
|
- if (!calcTools.isTotalCostBill(treeNode)) // 已在上面的分支中计算过
|
|
|
- calcTools.estimateFee(treeNode);
|
|
|
-
|
|
|
- if (treeNode.changed && !changedArr.includes(treeNode)) changedArr.push(treeNode);
|
|
|
};
|
|
|
+
|
|
|
// 存储、刷新零散的多个结点。
|
|
|
saveNodes(treeNodes, callback){
|
|
|
if (treeNodes.length < 1) {
|
|
@@ -2100,8 +2004,6 @@ class CalcProgram {
|
|
|
$.bootstrapLoading.start();
|
|
|
let startTime = +new Date();
|
|
|
me.project.updateNodes(dataArr, function (data) {
|
|
|
- let endShowTime = +new Date();
|
|
|
- console.log(`保存所需时间——${endShowTime - startTime}`);
|
|
|
me.rationMap = null;
|
|
|
me.pgljMap = null;
|
|
|
if(callback){
|
|
@@ -2139,10 +2041,11 @@ class CalcProgram {
|
|
|
|
|
|
return changedNodes;
|
|
|
};
|
|
|
- // 计算并保存本节点及所有会被影响到的节点。
|
|
|
+ // 计算并保存一个树节点。(修改一个树节点,实际上要计算和保存的是一批树结点:层层父结点、被其它结点(的公式)引用的公式结点)
|
|
|
calcAndSave(treeNode, callback, tender){
|
|
|
- let changedNodes = this.calculate(treeNode, true, true, tender);
|
|
|
- this.saveNodes(changedNodes, callback);
|
|
|
+ this.calcNodesAndSave([treeNode],callback,tender);
|
|
|
+ /* let changedNodes = this.calculate(treeNode, true, true, tender); 统一调用相同的方法
|
|
|
+ this.saveNodes(changedNodes, callback);*/
|
|
|
};
|
|
|
|
|
|
/* 计算所有树结点(分3种情况),并返回发生变动的零散的多个树结点。参数取值如下:
|
|
@@ -2161,6 +2064,7 @@ class CalcProgram {
|
|
|
if (node.children.length > 0) {
|
|
|
calcNodes(node.children);
|
|
|
};
|
|
|
+
|
|
|
if (calcType == calcAllType.catAll || calcType == node.sourceType) {
|
|
|
node.calcType = calcTools.getCalcType(node);
|
|
|
if (node.calcType != treeNodeCalcType.ctCalcBaseValue)
|