Bladeren bron

Merge branch 'master' of http://smartcost.f3322.net:3000/SmartCost/ConstructionCost

zhangweicheng 7 jaren geleden
bovenliggende
commit
94eabec7a0

+ 2 - 2
config/gulpConfig.js

@@ -83,8 +83,8 @@ module.exports = {
         'public/web/id_tree.js',
         'web/building_saas/main/js/models/cache_tree.js',
         'web/building_saas/main/js/calc/calc_fees.js',
-        'web/building_saas/main/js/calc/ration_calc.js',
-        'web/building_saas/main/js/calc/bills_calc.js',
+        // 'web/building_saas/main/js/calc/ration_calc.js',
+        // 'web/building_saas/main/js/calc/bills_calc.js',
         // 'public/calc_util.js',
         'public/web/tree_sheet/tree_sheet_controller.js',
         'public/web/tree_sheet/tree_sheet_helper.js',

+ 67 - 4
modules/complementary_glj_lib/models/gljModel.js

@@ -58,12 +58,34 @@ class GljDao {
         }
     }
     //获得用户的补充工料机和用户当前所在编办的标准工料机
-    getGljItems (stdGljLibId, userId, compilationId, callback){
+    async getGljItems (stdGljLibId, userId, compilationId, callback){
         let me = this;
         let rst = {stdGljs: [], complementaryGljs: []};
+        //批量获取异步
+       /* let functions = [];
+        let count = await stdGljModel.find({repositoryId: stdGljLibId, $or: [{deleted: null}, {deleted: false}]}).count();
+        let findCount = Math.ceil(count/500);
+        for(let i = 0, len = findCount; i < len; i++){
+            functions.push((function(flag) {
+                return function (cb) {
+                    stdGljModel.find({repositoryId: stdGljLibId, deleted: null}, cb).skip(flag).sort({ID: 1}).limit(500);
+                }
+            })(i*500));
+        }
+        async.parallel(functions,  function (err, results) {
+            if(err){
+                callback(err, null);
+            }
+            else{
+                for(let stdGljs of results){
+                    rst.stdGljs = rst.stdGljs.concat(stdGljs);
+                }
+                callback(0, rst);
+            }
+        });*/
         async.parallel([
-            function (cb) {
-                stdGljModel.find({repositoryId: stdGljLibId}, function (err, stdGljs) {
+           async function (cb) {
+               /* stdGljModel.find({repositoryId: stdGljLibId}, function (err, stdGljs) {
                     if(err){
                         cb(err);
                     }
@@ -72,7 +94,48 @@ class GljDao {
                         rst.stdGljs = stdGljs;
                         cb(null);
                     }
-                });
+                });*/
+               try{
+                   let stdGljs = [];
+                   let first = await stdGljModel.find({repositoryId: stdGljLibId}).sort({ID: 1}).limit(1);
+                   let count = await stdGljModel.find({repositoryId: stdGljLibId, $or: [{deleted: null}, {deleted: false}]}).count();
+                   let findCount = Math.ceil(count/500);
+                   let flag = first[0].ID;
+                   //let flag = 0;
+                   //批量获取,非skip
+                   for(let i = 0, len = findCount; i < len; i++){
+                       let tempStdGlj;
+                       if(i === 0){
+                           tempStdGlj = await stdGljModel.find({repositoryId: stdGljLibId, deleted: null, ID: {$gte: flag}}).sort({ID: 1}).limit(500);
+                           if(tempStdGlj.length > 0){
+                               flag = tempStdGlj[tempStdGlj.length - 1].ID;
+                           }
+                       }
+                       else {
+                           tempStdGlj = await stdGljModel.find({repositoryId: stdGljLibId, deleted: null, ID: {$gt: flag}}).sort({ID: 1}).limit(500);
+                           if(tempStdGlj.length > 0){
+                               flag = tempStdGlj[tempStdGlj.length - 1].ID;
+                           }
+                       }
+                       if(tempStdGlj){
+                           stdGljs = stdGljs.concat(tempStdGlj);
+                       }
+                   }
+               /*    for(let i = 0, len = findCount; i < len; i++){
+                       let tempStdGlj = await stdGljModel.find({repositoryId: stdGljLibId, deleted: null}).skip(flag).sort({ID: 1}).limit(500);
+                       if(tempStdGlj.length > 0){
+                           flag = flag + 500;
+                           stdGljs = stdGljs.concat(tempStdGlj);
+                       }
+                   }*/
+                   me.sortToNumber(stdGljs);
+                   rst.stdGljs = stdGljs;
+                   cb(null);
+               }
+               catch (err){
+                   cb(err);
+               }
+
             },
             function (cb) {
                 complementaryGljModel.find({userId: userId, compilationId: compilationId}, function (err, complementaryGljs) {

+ 1 - 0
modules/complementary_ration_lib/models/searchModel.js

@@ -57,6 +57,7 @@ class SearchDao{
             for(let i = 0, len = stdRations.length; i < len; i++){
                 stdRations[i]._doc.type = 'std';
             }
+            filter.userId = userId;
             let compleRations = await compleRationModel.find(filter);
             for(let i = 0, len = compleRations.length; i <len; i++){
                 compleRations[i]._doc.type = 'complementary';

+ 8 - 0
public/web/common_util.js

@@ -27,3 +27,11 @@ function mergeArr(arr1, arr2){
         };
     }
 };
+
+// 判断 sub 是否是 arr 的子数组。
+function isSubArr(sub, arr){
+    for(var i = 0, len = sub.length; i < len; i++){
+        if(arr.indexOf(sub[i]) == -1) return false;
+    }
+    return true;
+};

+ 1 - 1
web/building_saas/complementary_glj_lib/js/gljComponent.js

@@ -498,7 +498,7 @@ let gljComponentOprObj = {
         let me = gljComponentOprObj, gljBasePrc = 0;
         for(let i = 0; i < component.length; i++){
             let roundBasePrc = scMathUtil.roundTo(parseFloat(component[i].basePrice), -2);
-            gljBasePrc += scMathUtil.roundTo(roundBasePrc * parseFloat(component[i].consumeAmt), -2);
+            gljBasePrc = scMathUtil.roundTo(scMathUtil.roundTo(roundBasePrc * parseFloat(component[i].consumeAmt), -2) + gljBasePrc, -2);
         }
         return gljBasePrc;
     }

+ 2 - 2
web/building_saas/main/html/main.html

@@ -936,8 +936,8 @@
         <script type="text/javascript" src="/public/web/id_tree.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/models/cache_tree.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/calc/calc_fees.js"></script>
-        <script type="text/javascript" src="/web/building_saas/main/js/calc/ration_calc.js"></script>
-        <script type="text/javascript" src="/web/building_saas/main/js/calc/bills_calc.js"></script>
+        <!--<script type="text/javascript" src="/web/building_saas/main/js/calc/ration_calc.js"></script>-->
+        <!--<script type="text/javascript" src="/web/building_saas/main/js/calc/bills_calc.js"></script>-->
         <!--<script type="text/javascript" src="/public/calc_util.js"></script>-->
         <!-- Controller -->
         <script type="text/javascript" src="/public/web/tree_sheet/tree_sheet_controller.js"></script>

+ 12 - 12
web/building_saas/main/js/calc/bills_calc.js

@@ -5,14 +5,14 @@
 // const rationContent = 0, rationPrice = 1, rationPriceConverse = 2, billsPrice = 3;
 
 // sumTotalFeeFlag: sum(child.totalFee), totalFeeFlag: bills.quantity × bills.unitFee
-const sumTotalFeeFlag = 0, totalFeeFlag = 1;
+// 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;
+// const rationContentUnitFeeFlag = 0, averageQtyUnitFeeFlag = 1, billsPriceUnitFeeFlag = 2, converseUnitFeeFlag = 3;
 
-let rationContentCalcFields = [
+/*let rationContentCalcFields = [
     {'type': 'common', 'unitFeeFlag': rationContentUnitFeeFlag, 'totalFeeFlag': totalFeeFlag},
     {'type': 'labour', 'unitFeeFlag': rationContentUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
     {'type': 'material', 'unitFeeFlag': rationContentUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
@@ -35,9 +35,9 @@ let billsPriceCalcFields = [
     {'type': 'labour', 'unitFeeFlag': billsPriceUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
     {'type': 'material', 'unitFeeFlag': billsPriceUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
     {'type': 'machine', 'unitFeeFlag': billsPriceUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag}
-];
+];*/
 
-let nodeCalcObj = {
+/*let nodeCalcObj = {
     node: null,
     digit: 2,
     field: null,
@@ -98,9 +98,9 @@ let nodeCalcObj = {
             return 0;
         }
     }
-};
+};*/
 
-let baseCalcField = [
+/*let baseCalcField = [
     {
         ID: 1,
         // 序号
@@ -246,9 +246,9 @@ let baseCalcField = [
         // 备注
         memo: ''
     }
-];
+];*/
 
-class BillsCalcHelper {
+/*class BillsCalcHelper {
     constructor (project, calcFlag) {
         this.project = project;
         this.InitFields(project.calcFields);
@@ -269,12 +269,12 @@ class BillsCalcHelper {
 
         // 清单单价:套用定额计算程序
         // if (this.project.projSetting.billsCalcMode === billsPrice) {
-        if (this.project.property.billsCalcMode === leafBillGetFeeType.billsPrice) {
+/!*        if (this.project.property.billsCalcMode === leafBillGetFeeType.billsPrice) {
             rationCalcObj.calcGljs = this.getBillsGLjs(node);
             console.log(rationCalcObj.calcGljs);
             rationCalcObj.calcFields = rationCalcFields;
             virData = rationCalcObj.calculate();
-        }
+        }*!/
 
         for (let field of fields) {
             nodeCalcObj.field = field;
@@ -396,4 +396,4 @@ class BillsCalcHelper {
             field.tenderTotalFeeSplit = field.tenderTotalFee.split('.');
         }
     };
-}
+}*/

+ 9 - 11
web/building_saas/main/js/calc/ration_calc.js

@@ -96,15 +96,13 @@ let rationCalcFields = [
     }
 ];
 */
-"use strict";
+// let calcEvaluate = function (expr) {
+//     let exp = new Expression('');
+//     exp.Expression(expr);
+//     return exp.Evaluate();
+// }
 
-let calcEvaluate = function (expr) {
-    let exp = new Expression('');
-    exp.Expression(expr);
-    return exp.Evaluate();
-}
-
-let rationCalcFields = [
+/*let rationCalcFields = [
     {
         type: 'rationBaseLabour', code: "1.1.1", name: "定额基价人工费",
         dispExpr: "定额基价人工费", expression: "定额基价人工费", compiledExpr: "",
@@ -301,9 +299,9 @@ let rationCalcObj = {
         }
         return result;
     }
-};
+};*/
 
-class RationCalcHelper {
+/*class RationCalcHelper {
     constructor (project) {
         this.project = project;
     }
@@ -327,4 +325,4 @@ class RationCalcHelper {
             this.calculate(rationData);
         }
     };
-}
+}*/

+ 420 - 375
web/building_saas/main/js/models/calc_program.js

@@ -98,57 +98,8 @@ let defaultBillTemplate = {
     ]
 };*/
 
-const baseCalcType = {baseCalc: 0, adjustCalc: 1, budgetCalc: 2, diffCalc: 3,  offerCalc: 4};
-
-let rationCalcBase = [
-    {
-        'dispName': '定额基价人工费',
-        'calcType': baseCalcType.baseCalc,
-        'gljTypes': [gljType.LABOUR]
-    },
-    {
-        'dispName': '定额基价材料费',
-        'calcType': baseCalcType.baseCalc,
-        'gljTypes': [gljType.GENERAL_MATERIAL, gljType.CONCRETE, gljType.MORTAR, gljType.MIX_RATIO, gljType.COMMERCIAL_CONCRETE, gljType.COMMERCIAL_MORTAR]
-    },
-    {
-        'dispName': '定额基价机械费',
-        'calcType': baseCalcType.baseCalc,
-        'gljTypes': [gljType.GENERAL_MACHINE]
-    },
-    {
-        'dispName': '定额基价机上人工费',
-        'calcType': baseCalcType.baseCalc,
-        'gljTypes': [gljType.MACHINE_LABOUR]
-    },
-    {
-        'dispName': '人工费价差',
-        'calcType': baseCalcType.diffCalc,
-        'gljTypes': [gljType.LABOUR]
-    },
-    {
-        'dispName': '材料费价差',
-        'calcType': baseCalcType.diffCalc,
-        'gljTypes': [gljType.GENERAL_MATERIAL, gljType.CONCRETE, gljType.MORTAR, gljType.MIX_RATIO, gljType.COMMERCIAL_CONCRETE, gljType.COMMERCIAL_MORTAR]
-    },
-    {
-        'dispName': '机械费价差',
-        'calcType': baseCalcType.diffCalc,
-        'gljTypes': [gljType.GENERAL_MACHINE]
-    },
-    {
-        'dispName': '主材费',
-        'calcType': baseCalcType.budgetCalc,
-        'gljTypes': [gljType.MAIN_MATERIAL]
-    },
-    {
-        'dispName': '设备费',
-        'calcType': baseCalcType.budgetCalc,
-        'gljTypes': [gljType.EQUIPMENT]
-    }
-];
-
-let cpFeeTypes = [
+const priceTypes = {ptBasePrice: 1, ptAdjustPrice: 2, ptMarketPrice: 3, ptDiffPrice: 4};
+const cpFeeTypes = [
     {type: 'direct', name: '直接费'},
     {type: 'labour', name: '人工费'},
     {type: 'material', name: '材料费'},
@@ -165,10 +116,397 @@ let cpFeeTypes = [
     {type: 'adjustMachineLabour', name: '调整机上人工费'},
     {type: 'estimate', name: '暂估费'},
     {type: 'fee1', name: '甲供材料费'},
-    // 模拟用户新增
     {type: 'common', name: '工程造价'}
 ];
 
+let nodeTools = {
+    isBill: function(treeNode){
+        return treeNode.sourceType === ModuleNames.bills;
+    },
+    isLeafBill: function(treeNode){
+        return treeNode.sourceType === ModuleNames.bills &&
+            treeNode.source.children &&
+            treeNode.source.children.length === 0;
+    },
+    isNullBill: function (treeNode) {
+        return this.isLeafBill(treeNode) && (treeNode.children.length === 0) && (!treeNode.data.calcBase);
+    },
+    isTotalCostBill: function (treeNode) {
+        return treeNode.data.flagsIndex && treeNode.data.flagsIndex.fixed && treeNode.data.flagsIndex.fixed.flag &&
+            treeNode.data.flagsIndex.fixed.flag == fixedFlag.ENGINEERINGCOST;
+    },
+
+    isRationCategory: function(treeNode){
+        return treeNode.sourceType === ModuleNames.ration;
+    },
+    isRation: function(treeNode){
+        return treeNode.sourceType === ModuleNames.ration && treeNode.data.type === rationType.ration;
+    },
+    isVolumePrice: function (treeNode) {
+        return treeNode.sourceType === ModuleNames.ration && treeNode.data.type === rationType.volumePrice;
+    },
+    isGljRation: function (treeNode) {
+        return treeNode.sourceType === ModuleNames.ration && treeNode.data.type === rationType.gljRation;
+    },
+
+    initFees: function (treeNode){
+        if (!treeNode.data.fees) {
+            treeNode.data.fees = [];
+            treeNode.data.feesIndex = {};
+            treeNode.changed = true;
+        };
+    },
+    initFeeField: function (treeNode, fieldName){
+        this.initFees(treeNode);
+        if (!treeNode.data.feesIndex[fieldName]) {
+            let fee = {
+                'fieldName': fieldName,
+                'unitFee': 0,
+                'totalFee': 0,
+                'tenderUnitFee': 0,
+                'tenderTotalFee': 0
+            };
+            treeNode.data.fees.push(fee);
+            treeNode.data.feesIndex[fieldName] = fee;
+            treeNode.changed = true;
+        };
+    },
+    checkFeeField: function (treeNode, feeObj){
+        if (!feeObj) return;
+        if (feeObj.fieldName == '') return;
+
+        // 初始化前先拦截末定义的情况
+        if (!treeNode.data.feesIndex || !treeNode.data.feesIndex[feeObj.fieldName]){
+            if (feeObj.unitFee == 0 && feeObj.totalFee == 0) return;
+        }
+
+        this.initFeeField(treeNode, feeObj.fieldName);
+
+        if (treeNode.data.feesIndex[feeObj.fieldName].unitFee != feeObj.unitFee){
+            treeNode.data.feesIndex[feeObj.fieldName].unitFee = feeObj.unitFee;
+            treeNode.changed = true;
+        };
+
+        if (treeNode.data.feesIndex[feeObj.fieldName].totalFee != feeObj.totalFee){
+            treeNode.data.feesIndex[feeObj.fieldName].totalFee = feeObj.totalFee;
+            treeNode.changed = true;
+        };
+    },
+    initSummaryFee: function (treeNode){
+        if (!treeNode.data.summaryFees){
+            treeNode.data.summaryFees = {
+                totalFee: 0,
+                estimateFee: 0,
+                safetyFee: 0,
+                chargeFee: 0
+            };
+            treeNode.changed = true;
+        };
+    },
+    getCalcType: function (treeNode) {
+        if (this.isRationCategory(treeNode)){
+            return treeNodeCalcType.ctRationCalcProgram;
+        }
+        else if (this.isNullBill(treeNode)){
+            return treeNodeCalcType.ctNull;
+        }
+        else if (this.isLeafBill(treeNode)) {
+            if (treeNode.children && treeNode.children.length > 0){
+                // 清单单价计算模式下的叶子清单:取自己的计算程序ID,找到自己的计算程序计算。(汇总清单所有定额的工料机)
+                if (projectObj.project.property.billsCalcMode === leafBillGetFeeType.billsPrice)
+                    return treeNodeCalcType.ctBillCalcProgram;
+                else                                        // 前三种计算模式下的叶子清单:汇总定额的计算程序的费用类别
+                    return treeNodeCalcType.ctGatherRationsFees;
+            }
+            else{                                          // 公式计算
+                return treeNodeCalcType.ctCalcBaseValue;
+            };
+        }
+        else if (this.isBill(treeNode)) {                              // 父清单:汇总子清单的费用类别
+            return treeNodeCalcType.ctGatherBillsFees;
+        }
+        else {
+            return treeNodeCalcType.ctRationCalcProgram;
+        };
+    },
+
+    // 参数fieldName值: 'common.totalFee'、'equipment.unitFee'
+    getFee: function (treeNode, fieldName) {
+        let ns = fieldName.split(".");
+        if (ns.length != 2)
+            return 0
+        else if (treeNode.data.feesIndex[ns[0]] && treeNode.data.feesIndex[ns[0]][ns[1]])
+            return parseFloat(treeNode.data.feesIndex[ns[0]][ns[1]])
+        else
+            return 0;
+    },
+    getNodeByFlag: function (flag) {
+        let bill = cbTools.findBill(flag);
+        if (bill) return this.getNodeByID(bill.ID)
+        else return null;
+    },
+    getNodeByID: function (ID){
+        return cbTools.getNodeByID(ID);
+    }
+};
+
+let assistCalcer = {
+    // 界面显示的结点的工程量的数值。
+    uiQuantity: function (treeNode){
+        return parseFloatPlus(treeNode.data.quantity).toDecimal(decimalObj.decimal("quantity", treeNode));
+    },
+    // 界面显示的工料机价格,包括定额价、市场价等。参数 price 传入一个普通的价格数值即可。
+    uiGLJPrice: function (price){
+        if (price)
+            return parseFloat(price).toDecimal(decimalObj.glj.unitPrice)
+        else return 0;
+    },
+    // 界面显示的工料机数量。参数 quantity 传入一个普通的数量数值即可。
+    uiGLJQuantity: function (quantity){
+        if (quantity)
+            return parseFloat(quantity).toDecimal(decimalObj.glj.quantity)
+        else return 0;
+    },
+    rationBaseFee: function (treeNode, gljTypes, priceType){
+        if (!treeNode.data.gljList) return 0;
+        let result = 0;
+        let me = this;
+        for (let glj of treeNode.data.gljList) {
+            let price = 0, temp = 0;
+            if (gljTypes.indexOf(glj.type) >= 0) {
+                if (priceType == priceTypes.ptDiffPrice){
+                    let aprice = me.uiGLJPrice(glj["adjustPrice"]);
+                    let mprice = me.uiGLJPrice(glj["marketPrice"]);
+                    temp = (me.uiGLJQuantity(glj["quantity"]) * mprice).toDecimal(decimalObj.ration.unitPrice) - (me.uiGLJQuantity(glj["quantity"]) * aprice).toDecimal(decimalObj.ration.unitPrice);
+                    temp = temp.toDecimal(decimalObj.ration.unitPrice);
+                }
+                else {
+                    if (priceType == priceTypes.ptBasePrice){ price = me.uiGLJPrice(glj["basePrice"]);}
+                    else if (priceType == priceTypes.ptAdjustPrice){price = me.uiGLJPrice(glj["adjustPrice"]);}
+                    else if (priceType == priceTypes.ptMarketPrice){price = me.uiGLJPrice(glj["marketPrice"]);}
+                    temp = (me.uiGLJQuantity(glj["quantity"]) * price).toDecimal(decimalObj.ration.unitPrice);
+                };
+
+                result = (result + temp).toDecimal(decimalObj.ration.unitPrice);
+            };
+        };
+        return result;
+    },
+    machineLabourFee: function (gljArr) {
+        if (!gljArr) return 0;
+        let result = 0, mdSum = 0;
+        for (let glj of gljArr) {
+            if (glj.type == gljType.GENERAL_MACHINE) {
+                // 获取机械组成物
+                let mds = projectObj.project.composition.getCompositionByGLJ(glj);
+                if (!mds) mds = [];
+                for (let md of mds) {
+                    if (md.type == gljType.MACHINE_LABOUR) {
+                        let q = md["consumption"] ? md["consumption"] : 0;
+                        let p = md["basePrice"] ? md["basePrice"] : 0;
+                        mdSum = mdSum + (q * p).toDecimal(decimalObj.process);
+                        mdSum = (mdSum).toDecimal(decimalObj.process);
+                    }
+                }
+                result = result + (glj["quantity"] * mdSum).toDecimal(decimalObj.process);
+                result = (result).toDecimal(decimalObj.process);
+            }
+        }
+        return result;
+    },
+    estimateFee: function (treeNode, isBase = false){
+        let me = this, sumU = 0, sumT = 0;
+        // 父清单暂估费的汇总计算走计算程序逻辑,不在这里。
+        if (nodeTools.isTotalCostBill(treeNode)){
+            let nodes = projectObj.project.mainTree.roots;
+            for (let node of nodes){
+                if (nodeTools.isTotalCostBill(node)) break;
+                let eU = 0, eT = 0;
+                if (node.data.feesIndex && node.data.feesIndex.estimate){
+                    eU = node.data.feesIndex.estimate.unitFee;
+                    eT = node.data.feesIndex.estimate.totalFee;
+                }
+                else {
+                    eU = 0, eT = 0;
+                };
+                sumU = (sumU + parseFloatPlus(eU)).toDecimal(decimalObj.process);
+                sumT = (sumT + parseFloatPlus(eT)).toDecimal(decimalObj.process);
+            };
+            sumU = (sumU).toDecimal(decimalObj.bills.unitPrice);
+            sumT = (sumT).toDecimal(decimalObj.bills.totalPrice);
+        }
+        else{
+            if (!treeNode.data.gljList) return;
+            let GLJObjs = [];
+            for (let glj of treeNode.data.gljList) {
+                if (allMaterialTypes.indexOf(glj.type) >= 0) {
+                    if (glj.isEstimate){
+                        GLJObjs.push({code: glj.code, name: glj.name, specs: glj.specs, unit: glj.unit, type: glj.type,
+                            quantity: glj.quantity, marketPrice: glj.marketPrice});
+                    }
+                    else{   // 组成物
+                        if (compositionTypes.indexOf(glj.type) >= 0){
+                            let mds = projectObj.project.composition.getCompositionByGLJ(glj);
+                            if (!mds) mds = [];
+                            for (let md of mds){
+                                if (md.isEstimate){
+                                    let isExist = false;
+                                    let mdQ = (me.uiGLJQuantity(glj.quantity) * me.uiGLJQuantity(md.consumption)).toDecimal(decimalObj.process);
+
+                                    for (let obj of GLJObjs){
+                                        if (gljOprObj.getIndex(md, gljKeyArray) == gljOprObj.getIndex(obj, gljKeyArray)){
+                                            isExist = true;
+                                            obj.quantity = (me.uiGLJQuantity(obj.quantity) + mdQ).toDecimal(decimalObj.process);
+                                            break;
+                                        }
+                                    };
+                                    if (!isExist)
+                                        GLJObjs.push({code: md.code, name: md.name, specs: md.specs, unit: md.unit, type: md.type,
+                                            quantity: mdQ, marketPrice: md.marketPrice});
+                                }
+                            }
+                        }
+                    }
+                };
+            };
+
+            for (let obj of GLJObjs){
+                sumU = sumU + (me.uiGLJQuantity(obj.quantity) * me.uiGLJPrice(obj.marketPrice)).toDecimal(decimalObj.process);
+                sumU = sumU.toDecimal(decimalObj.process);
+
+                let q = (me.uiGLJQuantity(obj.quantity) * me.uiQuantity(treeNode)).toDecimal(decimalObj.process);
+                sumT = sumT + (q * me.uiGLJPrice(obj.marketPrice)).toDecimal(decimalObj.process);
+                sumT = sumT.toDecimal(decimalObj.process);
+            };
+            sumU = sumU.toDecimal(decimalObj.bills.unitPrice);
+            if (projectObj.project.property.zanguCalcMode == zanguCalcType.common){
+                sumT = (me.uiQuantity(treeNode) * sumU).toDecimal(decimalObj.bills.totalPrice);
+            }
+            else if (projectObj.project.property.zanguCalcMode == zanguCalcType.gatherMaterial){
+                sumT = sumT.toDecimal(decimalObj.bills.totalPrice);
+            };
+        };
+
+        if (isBase)
+            return sumU
+        else
+            nodeTools.checkFeeField(treeNode, {'fieldName': 'estimate', 'unitFee': sumU, 'totalFee': sumT});
+    },
+    marketPriceToBase: function (treeNode, baseName) {
+        if (treeNode.data.type != rationType.volumePrice && treeNode.data.type != rationType.gljRation) return;
+        let result = 0, me = this;
+        if (
+            (treeNode.data.subType === gljType.LABOUR && baseName === '定额基价人工费') ||
+            (baseMaterialTypes.includes(treeNode.data.subType) && baseName === '定额基价材料费') ||
+            (treeNode.data.subType === gljType.GENERAL_MACHINE && baseName === '定额基价机械费') ||
+            (treeNode.data.subType === gljType.MAIN_MATERIAL && baseName === '主材费') ||
+            (treeNode.data.subType === gljType.EQUIPMENT && baseName === '设备费')) {
+            if (treeNode.data.type == rationType.volumePrice)
+                result = treeNode.data.marketUnitFee ? parseFloat(treeNode.data.marketUnitFee).toDecimal(decimalObj.ration.unitPrice) : 0
+            else if (treeNode.data.type == rationType.gljRation)
+                result = treeNode.data.basePrice ? parseFloat(treeNode.data.basePrice).toDecimal(decimalObj.ration.unitPrice) : 0;
+        }
+        else if (treeNode.data.subType === gljType.GENERAL_MACHINE && baseName === '定额基价机上人工费') {
+            let glj = {
+                'code': treeNode.data.code,
+                'name': treeNode.data.name,
+                'specs': treeNode.data.specs,
+                'unit': treeNode.data.unit,
+                'quantity': 1,
+                'type': treeNode.data.subType      // 注意:这里要取subType
+            };
+            result = assistCalcer.machineLabourFee([glj]);
+        }
+        else if (
+            (treeNode.data.type == rationType.gljRation) &&
+            ((treeNode.data.subType === gljType.LABOUR && baseName === '人工费价差') ||
+            (baseMaterialTypes.includes(treeNode.data.subType) && baseName === '材料费价差') ||
+            (treeNode.data.subType === gljType.GENERAL_MACHINE && baseName === '机械费价差'))
+        ) {
+            let aprice = me.uiGLJPrice(treeNode.data.adjustPrice);
+            let mprice = me.uiGLJPrice(treeNode.data.marketUnitFee);
+            result = (mprice - aprice).toDecimal(decimalObj.ration.unitPrice);
+        }
+        return result;
+    }
+};
+
+const rationCalcBaser = {
+    '定额基价人工费': function (node) {
+        return assistCalcer.rationBaseFee(node, [gljType.LABOUR], priceTypes.ptBasePrice);
+    },
+    '定额基价材料费': function (node) {
+        return assistCalcer.rationBaseFee(node, baseMaterialTypes, priceTypes.ptBasePrice);
+    },
+    '定额基价机械费': function (node) {
+        return assistCalcer.rationBaseFee(node, [gljType.GENERAL_MACHINE], priceTypes.ptBasePrice);
+    },
+    '定额基价机上人工费': function (node) {
+        return assistCalcer.machineLabourFee(node.data.gljList);
+    },
+    '人工费价差': function (node) {
+        return assistCalcer.rationBaseFee(node, [gljType.LABOUR], priceTypes.ptDiffPrice);
+    },
+    '材料费价差': function (node) {
+        return assistCalcer.rationBaseFee(node, baseMaterialTypes, priceTypes.ptDiffPrice);
+    },
+    '机械费价差': function (node) {
+        return assistCalcer.rationBaseFee(node, [gljType.GENERAL_MACHINE], priceTypes.ptDiffPrice);
+    },
+    '主材费': function (node) {
+        return assistCalcer.rationBaseFee(node, [gljType.MAIN_MATERIAL], priceTypes.ptMarketPrice);
+    },
+    '设备费': function (node) {
+        return assistCalcer.rationBaseFee(node, [gljType.EQUIPMENT], priceTypes.ptMarketPrice);
+    },
+    '人工工日': function (node) {
+        if (!node.data.gljList) return 0;
+        let rst = 0;
+        for (let glj of node.data.gljList) {
+            if (glj.type == gljType.LABOUR) {
+                rst = rst + (assistCalcer.uiGLJQuantity(glj["quantity"]) * assistCalcer.uiQuantity(node)).toDecimal(decimalObj.process);
+                rst = rst.toDecimal(decimalObj.process);
+            }
+        };
+        return rst.toDecimal(decimalObj.glj.quantity);
+    },
+    '甲供定额基价人工费': function (node) {
+    },
+    '甲供定额基价材料费': function (node) {
+    },
+    '甲供定额基价机械费': function (node) {
+    },
+    '甲供主材费': function (node) {
+    },
+    '甲供设备费': function (node) {
+    },
+    '甲定定额基价人工费': function (node) {
+    },
+    '甲定定额基价材料费': function (node) {
+    },
+    '甲定定额基价机械费': function (node) {
+    },
+    '甲定主材费': function (node) {
+    },
+    '甲定设备费': function (node) {
+    },
+    '暂估材料费': function (node) {
+        return assistCalcer.estimateFee(node, true);
+    },
+    '分包定额基价人工费': function (node) {
+    },
+    '分包定额基价材料费': function (node) {
+    },
+    '分包定额基价机械费': function (node) {
+    },
+    '分包主材费': function (node) {
+    },
+    '分包设备费': function (node) {
+    },
+    '分包人工工日': function (node) {
+    }
+};
+
 let analyzer = {
     calcTemplate: null,
     success: true,
@@ -313,244 +651,38 @@ let analyzer = {
 let executeObj = {
     treeNode: null,
     template: null,
-    calcBase: null,
+    tempCalcItem: null,
 
     at: function(ID) {
-        let me = executeObj,
-            rst = 0;
-        rst = me.template.compiledCalcItems[ID].unitFee;
+        let me = executeObj;
+        let rst = me.template.compiledCalcItems[ID].unitFee;
         rst = parseFloat(rst);
         return rst;
     },
-    base: function(calcBaseName) {
-        let me = executeObj, rst = 0,
-            base = me.calcBase[calcBaseName];
-
-        if (base != null) {
-            function isSubset(sub, arr){
-                for(var i = 0, len = sub.length; i < len; i++){
-                    if(arr.indexOf(sub[i]) == -1) return false;
-                }
-                return true;
-            };
-            // 机上人工费:多一层
-            function machineLabourFee() {
-                if (!me.treeNode.data.gljList) return 0;
-                let result = 0, mdSum = 0;
-                for (let glj of me.treeNode.data.gljList) {
-                    if (glj.type == gljType.GENERAL_MACHINE) {
-                        // 获取机械组成物
-                        let mds = projectObj.project.composition.getCompositionByGLJ(glj);
-                        if (!mds) mds = [];
-                        for (let md of mds){
-                            if (base.gljTypes.indexOf(md.type) >= 0) {
-                                let q = md["consumption"] ? md["consumption"] : 0;
-                                let p = md["basePrice"] ? md["basePrice"] : 0;
-                                mdSum = mdSum + (q * p).toDecimal(decimalObj.process);
-                                mdSum = (mdSum).toDecimal(decimalObj.process);
-                            }
-                        };
-                        result = result + (glj["quantity"] * mdSum).toDecimal(decimalObj.process);
-                        result = (result).toDecimal(decimalObj.process);
-                    };
-                };
-                return result;
-            };
-            function commonGLJFee(){
-                if (!me.treeNode.data.gljList) return 0;
-                let result = 0;
-                for (let glj of me.treeNode.data.gljList) {
-                    let price = 0, temp = 0;
-                    if (base.gljTypes.indexOf(glj.type) >= 0) {
-                        if (base.calcType == baseCalcType.diffCalc){
-                            let aprice = glj["adjustPrice"] ? glj["adjustPrice"] : 0;
-                            aprice = parseFloat(aprice);
-                            let mprice = glj["marketPrice"] ? glj["marketPrice"] : 0;
-                            mprice = parseFloat(mprice);
-                            temp = (glj["quantity"] * mprice).toDecimal(decimalObj.ration.unitPrice) - (glj["quantity"] * aprice).toDecimal(decimalObj.ration.unitPrice);
-                            temp = temp.toDecimal(decimalObj.ration.unitPrice);
-                        }
-                        else {
-                            if (base.calcType == baseCalcType.baseCalc){ price = parseFloat(glj["basePrice"]);}
-                            else if (base.calcType == baseCalcType.adjustCalc){price = parseFloat(glj["adjustPrice"]);}
-                            else if (base.calcType == baseCalcType.budgetCalc){price = parseFloat(glj["marketPrice"]);}
-                            temp = (glj["quantity"] * price).toDecimal(decimalObj.ration.unitPrice);
-                        };
-
-                        result = (result + temp).toDecimal(decimalObj.ration.unitPrice);
-                    };
-                };
-                return result;
-            };
-            // 量价、工料机形式的定额, 要把自己的市场单价用于计算程序中的基数。
-            function marketPriceToBase() {
-                let result = 0;
-                if (
-                    ( me.treeNode.data.subType === gljType.LABOUR && base.dispName === '定额基价人工费') ||
-                    ( baseMaterialTypes.includes(me.treeNode.data.subType) && base.dispName === '定额基价材料费') ||
-                    ( me.treeNode.data.subType === gljType.GENERAL_MACHINE && base.dispName === '定额基价机械费') ||
-                    ( me.treeNode.data.subType === gljType.MAIN_MATERIAL && base.dispName === '主材费') ||
-                    ( me.treeNode.data.subType === gljType.EQUIPMENT && base.dispName === '设备费')
-                ) result = me.treeNode.data.marketUnitFee ? me.treeNode.data.marketUnitFee : 0;
-
-                return result;
-            };
+    base: function(baseName) {
+        let me = executeObj;
 
-            if (me.treeNode.data.type == rationType.volumePrice || me.treeNode.data.type == rationType.gljRation){
-                rst = marketPriceToBase();
-            }
-            else{
-                if (isSubset(base.gljTypes, [gljType.MACHINE_LABOUR]))
-                    rst = machineLabourFee()
-                else
-                    rst = commonGLJFee();
+        // 量价、工料机形式的定额, 要把自己的市场单价用于计算程序中的基数。
+        if (me.treeNode.data.type == rationType.volumePrice || me.treeNode.data.type == rationType.gljRation)
+            return assistCalcer.marketPriceToBase(me.treeNode, baseName)
+        else{
+            if (!rationCalcBaser[baseName]){
+                alert('定额基数“' + baseName + '”末定义,计算错误。 (模板 ' + me.template.ID + ',规则 ' + me.tempCalcItem.ID +')');
+                return 0;
             }
-        };
-
-        return rst;
+            else
+                return rationCalcBaser[baseName](me.treeNode);
+        }
     },
     HJ: function () {
         let me = this;
         let p = me.treeNode.data.calcBaseValue ? me.treeNode.data.calcBaseValue : 0;
-        let q = nodeTools.uiQuantity(me.treeNode) ? nodeTools.uiQuantity(me.treeNode) : 1;
+        let q = assistCalcer.uiQuantity(me.treeNode) ? assistCalcer.uiQuantity(me.treeNode) : 1;
         let u = (p / q).toDecimal(decimalObj.decimal('unitPrice', me.treeNode));
         return u;
     }
 };
 
-let nodeTools = {
-    isBill: function(treeNode){
-        return treeNode.sourceType === ModuleNames.bills;
-    },
-    isLeafBill: function(treeNode){
-        return treeNode.sourceType === ModuleNames.bills &&
-            treeNode.source.children &&
-            treeNode.source.children.length === 0;
-    },
-    isNullBill: function (treeNode) {
-        return this.isLeafBill(treeNode) && (treeNode.children.length === 0) && (!treeNode.data.calcBase);
-    },
-    isTotalCostBill: function (treeNode) {
-        return treeNode.data.flagsIndex && treeNode.data.flagsIndex.fixed && treeNode.data.flagsIndex.fixed.flag &&
-            treeNode.data.flagsIndex.fixed.flag == fixedFlag.ENGINEERINGCOST;
-    },
-
-    isRationCategory: function(treeNode){
-        return treeNode.sourceType === ModuleNames.ration;
-    },
-    isRation: function(treeNode){
-        return treeNode.sourceType === ModuleNames.ration && treeNode.data.type === rationType.ration;
-    },
-    isVolumePrice: function (treeNode) {
-        return treeNode.sourceType === ModuleNames.ration && treeNode.data.type === rationType.volumePrice;
-    },
-    isGljRation: function (treeNode) {
-        return treeNode.sourceType === ModuleNames.ration && treeNode.data.type === rationType.gljRation;
-    },
-
-    initFees(treeNode){
-        if (!treeNode.data.fees) {
-            treeNode.data.fees = [];
-            treeNode.data.feesIndex = {};
-            treeNode.changed = true;
-        };
-    },
-    initFeeField(treeNode, fieldName){
-        this.initFees(treeNode);
-        if (!treeNode.data.feesIndex[fieldName]) {
-            let fee = {
-                'fieldName': fieldName,
-                'unitFee': 0,
-                'totalFee': 0,
-                'tenderUnitFee': 0,
-                'tenderTotalFee': 0
-            };
-            treeNode.data.fees.push(fee);
-            treeNode.data.feesIndex[fieldName] = fee;
-            treeNode.changed = true;
-        };
-    },
-    checkFeeField(treeNode, feeObj){
-        if (!feeObj) return;
-        if (feeObj.fieldName == '') return;
-
-        // 初始化前先拦截末定义的情况
-        if (!treeNode.data.feesIndex || !treeNode.data.feesIndex[feeObj.fieldName]){
-            if (feeObj.unitFee == 0 && feeObj.totalFee == 0) return;
-        }
-
-        this.initFeeField(treeNode, feeObj.fieldName);
-
-        if (treeNode.data.feesIndex[feeObj.fieldName].unitFee != feeObj.unitFee){
-            treeNode.data.feesIndex[feeObj.fieldName].unitFee = feeObj.unitFee;
-            treeNode.changed = true;
-        };
-
-        if (treeNode.data.feesIndex[feeObj.fieldName].totalFee != feeObj.totalFee){
-            treeNode.data.feesIndex[feeObj.fieldName].totalFee = feeObj.totalFee;
-            treeNode.changed = true;
-        };
-    },
-    initSummaryFee(treeNode){
-        if (!treeNode.data.summaryFees){
-            treeNode.data.summaryFees = {
-                totalFee: 0,
-                estimateFee: 0,
-                safetyFee: 0,
-                chargeFee: 0
-            };
-            treeNode.changed = true;
-        };
-    },
-    getCalcType(treeNode) {
-        if (this.isRationCategory(treeNode)){
-            return treeNodeCalcType.ctRationCalcProgram;
-        }
-        else if (this.isNullBill(treeNode)){
-            return treeNodeCalcType.ctNull;
-        }
-        else if (this.isLeafBill(treeNode)) {
-            if (treeNode.children && treeNode.children.length > 0){
-                // 清单单价计算模式下的叶子清单:取自己的计算程序ID,找到自己的计算程序计算。(汇总清单所有定额的工料机)
-                if (projectObj.project.property.billsCalcMode === leafBillGetFeeType.billsPrice)
-                    return treeNodeCalcType.ctBillCalcProgram;
-                else                                        // 前三种计算模式下的叶子清单:汇总定额的计算程序的费用类别
-                    return treeNodeCalcType.ctGatherRationsFees;
-            }
-            else{                                          // 公式计算
-                return treeNodeCalcType.ctCalcBaseValue;
-            };
-        }
-        else if (this.isBill(treeNode)) {                              // 父清单:汇总子清单的费用类别
-            return treeNodeCalcType.ctGatherBillsFees;
-        }
-        else {
-            return treeNodeCalcType.ctRationCalcProgram;
-        };
-    },
-    uiQuantity(treeNode){
-        return parseFloatPlus(treeNode.data.quantity).toDecimal(decimalObj.decimal("quantity", treeNode));
-    },
-
-    getFee(treeNode, fieldName) {    // fieldName: 'common.totalFee'、'equipment.unitFee'
-        let ns = fieldName.split(".");
-        if (ns.length != 2)
-            return 0
-        else if (treeNode.data.feesIndex[ns[0]] && treeNode.data.feesIndex[ns[0]][ns[1]])
-            return parseFloat(treeNode.data.feesIndex[ns[0]][ns[1]])
-        else
-            return 0;
-    },
-    getNodeByFlag(flag) {
-         let bill = cbTools.findBill(flag);
-         if (bill) return this.getNodeByID(bill.ID)
-         else return null;
-    },
-    getNodeByID(ID){
-        return cbTools.getNodeByID(ID);
-    }
-};
-
 class CalcProgram {
     constructor(project){
         let me = this;
@@ -593,7 +725,7 @@ class CalcProgram {
         me.feeRates = this.project.FeeRate.datas.rates;
         me.labourCoes = this.project.labourCoe.datas.coes;
         me.feeTypes = cpFeeTypes;
-        me.calcBases = rationCalcBase;
+        // me.calcBases = rationCalcBase;
         me.templates = this.project.calcProgram.datas.templates;
 
         // me.templates.push(defaultBillTemplate);
@@ -630,9 +762,9 @@ class CalcProgram {
             me.compiledFeeTypeNames.push(ft.name);
         }
 
-        for (let cb of me.calcBases) {
+/*        for (let cb of me.calcBases) {
             me.compiledCalcBases[cb.dispName] = cb;         // 中文预编译,可靠性有待验证
-        }
+        }*/
     };
 
     compileTemplate(template){
@@ -816,83 +948,6 @@ class CalcProgram {
             return ['labour', 'material', 'machine', 'mainMaterial', 'equipment'].indexOf(type) > -1;
         };
 
-        // 计算暂估费用
-        function calcEstimateFee(treeNode){
-            let sumU = 0, sumT = 0;
-
-            if (nodeTools.isTotalCostBill(treeNode)){
-                let nodes = projectObj.project.mainTree.roots;
-                for (let node of nodes){
-                    if (nodeTools.isTotalCostBill(node)) break;
-                    let eU = 0, eT = 0;
-                    if (node.data.feesIndex && node.data.feesIndex.estimate){
-                        eU = node.data.feesIndex.estimate.unitFee;
-                        eT = node.data.feesIndex.estimate.totalFee;
-                    }
-                    else {
-                        eU = 0, eT = 0;
-                    };
-                    sumU = (sumU + parseFloatPlus(eU)).toDecimal(decimalObj.process);
-                    sumT = (sumT + parseFloatPlus(eT)).toDecimal(decimalObj.process);
-                };
-                sumU = (sumU).toDecimal(decimalObj.bills.unitPrice);
-                sumT = (sumT).toDecimal(decimalObj.bills.totalPrice);
-            }
-            else{
-                if (!treeNode.data.gljList) return;
-                let GLJObjs = [];
-                for (let glj of treeNode.data.gljList) {
-                    if (allMaterialTypes.indexOf(glj.type) >= 0) {
-                        if (glj.isEstimate){
-                            GLJObjs.push({code: glj.code, name: glj.name, specs: glj.specs, unit: glj.unit, type: glj.type,
-                                quantity: glj.quantity, marketPrice: glj.marketPrice});
-                        }
-                        else{   // 组成物
-                            if (compositionTypes.indexOf(glj.type) >= 0){
-                                let mds = projectObj.project.composition.getCompositionByGLJ(glj);
-                                if (!mds) mds = [];
-                                for (let md of mds){
-                                    if (md.isEstimate){
-                                        let isExist = false;
-                                        let mdQ = (parseFloatPlus(glj.quantity) * parseFloatPlus(md.consumption)).toDecimal(decimalObj.process);
-
-                                        for (let obj of GLJObjs){
-                                            if (gljOprObj.getIndex(md, gljKeyArray) == gljOprObj.getIndex(obj, gljKeyArray)){
-                                                isExist = true;
-                                                obj.quantity = (parseFloatPlus(obj.quantity) + mdQ).toDecimal(decimalObj.process);
-                                                break;
-                                            }
-                                        };
-                                        if (!isExist)
-                                            GLJObjs.push({code: md.code, name: md.name, specs: md.specs, unit: md.unit, type: md.type,
-                                                quantity: mdQ, marketPrice: md.marketPrice});
-                                    }
-                                }
-                            }
-                        }
-                    };
-                };
-
-                for (let obj of GLJObjs){
-                    sumU = sumU + (parseFloatPlus(obj.quantity) * parseFloatPlus(obj.marketPrice)).toDecimal(decimalObj.process);
-                    sumU = sumU.toDecimal(decimalObj.process);
-
-                    let q = (parseFloatPlus(obj.quantity) * parseFloatPlus(treeNode.data.quantity)).toDecimal(decimalObj.process);
-                    sumT = sumT + (q * parseFloatPlus(obj.marketPrice)).toDecimal(decimalObj.process);
-                    sumT = sumT.toDecimal(decimalObj.process);
-                };
-                sumU = sumU.toDecimal(decimalObj.bills.unitPrice);
-                if (projectObj.project.property.zanguCalcMode == zanguCalcType.common){
-                    sumT = (nodeTools.uiQuantity(treeNode) * sumU).toDecimal(decimalObj.bills.totalPrice);
-                }
-                else if (projectObj.project.property.zanguCalcMode == zanguCalcType.gatherMaterial){
-                    sumT = sumT.toDecimal(decimalObj.bills.totalPrice);
-                };
-            };
-
-            nodeTools.checkFeeField(treeNode, {'fieldName': 'estimate', 'unitFee': sumU, 'totalFee': sumT});
-        };
-
         // 删掉多余的费用。例如:从其它计算方式切换到公式计算方式,会多出其它的费(不光是common)
         function deleteUselessFees(treeNode, fieldNameArr){
             if (fieldNameArr){   // 用于计算程序没有绑定的费用类别,不要同步到清单,而清单因为以前计算过该类别又有值,需删除。如切换取费类别,旧费要清掉。
@@ -944,9 +999,9 @@ class CalcProgram {
                 }
                 else if (treeNode.calcType == treeNodeCalcType.ctGatherRationsFees){     // 这里的算法要配合冷姐姐的神图才能看懂^_^
                     let sum_rtf = 0, sum_rttf = 0;
-                    let bq = nodeTools.uiQuantity(treeNode) ? nodeTools.uiQuantity(treeNode) : 1;
+                    let bq = assistCalcer.uiQuantity(treeNode) ? assistCalcer.uiQuantity(treeNode) : 1;
                     for (let node of nodes) {
-                        let rq = nodeTools.uiQuantity(node) ? nodeTools.uiQuantity(node) : 0;
+                        let rq = assistCalcer.uiQuantity(node) ? assistCalcer.uiQuantity(node) : 0;
                         let ruf = 0, rtuf = 0, rtf = 0, rttf = 0;
                         if (node.data.feesIndex && node.data.feesIndex[ft.type]) {
                             ruf = parseFloat(node.data.feesIndex[ft.type].unitFee);
@@ -1025,7 +1080,7 @@ class CalcProgram {
             }
 
             let f = treeNode.data.feeRate ? treeNode.data.feeRate : 100;
-            let q = nodeTools.uiQuantity(treeNode) ? nodeTools.uiQuantity(treeNode) : 1;
+            let q = assistCalcer.uiQuantity(treeNode) ? assistCalcer.uiQuantity(treeNode) : 1;
             let b = treeNode.data.calcBaseValue ? treeNode.data.calcBaseValue : 0;
             let uf = (b * f * q / 100).toDecimal(decimalObj.bills.unitPrice);
             let tuf = uf;
@@ -1037,7 +1092,7 @@ class CalcProgram {
             // 总造价清单还要做单项工程、建设项目的四大项金额汇总
             if (nodeTools.isTotalCostBill(treeNode)){
                 // 公式叶子清单没有暂估费,但总造价清单除外。
-                calcEstimateFee(treeNode);
+                assistCalcer.estimateFee(treeNode);
                 nodeTools.initSummaryFee(treeNode);
                 treeNode.data.summaryFees.totalFee = tf;
                 treeNode.data.summaryFees.estimateFee = nodeTools.getFee(treeNode, 'estimate.totalFee');
@@ -1054,7 +1109,7 @@ class CalcProgram {
                 if (treeNode.data.type == rationType.volumePrice){
                     delete treeNode.data.gljList;
                     let muf = treeNode.data.marketUnitFee ? treeNode.data.marketUnitFee : 0;
-                    let q = nodeTools.uiQuantity(treeNode) ? nodeTools.uiQuantity(treeNode) : 0;
+                    let q = assistCalcer.uiQuantity(treeNode) ? assistCalcer.uiQuantity(treeNode) : 0;
                     treeNode.data.marketTotalFee = (muf * q).toDecimal(decimalObj.ration.totalPrice);
                 }
                 else if (treeNode.data.type == rationType.gljRation){
@@ -1063,7 +1118,7 @@ class CalcProgram {
                 else{
                     treeNode.data.gljList = me.project.ration_glj.getGljArrByRation(treeNode.data.ID);
                     // 计算程序里没有暂估费的计算规则,会漏掉,所以这里要专门算。
-                    calcEstimateFee(treeNode);
+                    assistCalcer.estimateFee(treeNode);
                     fnArr.push('estimate');
                 };
 
@@ -1080,7 +1135,7 @@ class CalcProgram {
                 }
 
                 // 叶子清单自己的计算程序计算,其暂估费也要汇总算。
-                calcEstimateFee(treeNode);
+                assistCalcer.estimateFee(treeNode);
                 fnArr.push('estimate');
             };
 
@@ -1091,16 +1146,16 @@ class CalcProgram {
                 let $CE = executeObj;
                 $CE.treeNode = treeNode;
                 $CE.template = template;
-                $CE.calcBase = me.compiledCalcBases;
 
                 nodeTools.initFees(treeNode);
 
                 for (let idx of template.compiledSeq) {
                     let calcItem = template.calcItems[idx];
+                    $CE.tempCalcItem = calcItem;
                     let feeRate = parseFloatPlus(calcItem.feeRate) ? parseFloatPlus(calcItem.feeRate).toDecimal(decimalObj.feeRate) : 100;  // 100%
                     calcItem.unitFee = (eval(calcItem.compiledExpr) * feeRate * 0.01).toDecimal(decimalObj.decimal('unitPrice', treeNode));   // 如果eval()对清单树有影响,就换成小麦的Expression对象再试
 
-                    let q = nodeTools.uiQuantity(treeNode) ? nodeTools.uiQuantity(treeNode) : 0;
+                    let q = assistCalcer.uiQuantity(treeNode) ? assistCalcer.uiQuantity(treeNode) : 0;
                     calcItem.totalFee = (calcItem.unitFee * q).toDecimal(decimalObj.decimal('totalPrice', treeNode));
 
                     if (calcItem.fieldName) {
@@ -1243,6 +1298,7 @@ class CalcProgram {
         let changedNodes = this.calculate(treeNode);
         this.saveNodes(changedNodes);
     };
+
     calcAllNodesAndSave(calcType = calcAllType.catAll){
         let changedNodes = this.calcAllNodes(calcType);
         this.saveNodes(changedNodes);
@@ -1255,17 +1311,6 @@ class CalcProgram {
         let rst = 0;
 
         function calcNodes(nodes) {
-            /*for (let node of nodes) {
-                if (node.children.length > 0) {
-                    calcNodes(node.children);
-                }
-                else{
-                    if (!excludeNodes.includes(node) && node.sourceType != ModuleNames.ration_glj) {
-                        rst = (rst + nodeTools.getFee(node, 'common.totalFee')).toDecimal(decimalObj.bills.totalPrice);
-                    };
-                }
-            }*/
-
             for (let node of nodes) {
                 if (!excludeNodes.includes(node)){
                     if (node.children.length > 0) {
@@ -1283,4 +1328,4 @@ class CalcProgram {
         calcNodes(me.project.mainTree.roots);
         return rst;
     };
-}
+};

+ 5 - 0
web/building_saas/main/js/views/glj_view_contextMenu.js

@@ -197,7 +197,10 @@ var gljContextMenu = {
 
 function getGLJData(actionType) {
     $('#actionType').val(actionType);
+    $.bootstrapLoading.start();
+    console.log(+new Date());
     projectObj.project.ration_glj.getGLJData(function (result) {
+        console.log(+new Date());
         zTreeHelper.createTree(result.datas.treeData, gljOprObj.gljTreeSetting, "gljTree", gljOprObj);
         gljOprObj.stdGLJ=result.datas.stdGLJ;
         gljOprObj.complementaryGLJs=result.datas.complementaryGLJs;
@@ -205,6 +208,8 @@ function getGLJData(actionType) {
         gljOprObj.distTypeTree=gljOprObj.getComboData(result.datas.distTypeTree);
         $('#modalCon').width($(window).width()*0.5);
         $("input[name='glj']").get(0).checked=true;
+        $.bootstrapLoading.end();
+        console.log(+new Date());
         $("#glj_tree_div").modal({show:true});
     })
 }

+ 1 - 1
web/building_saas/main/js/views/main_tree_col.js

@@ -25,7 +25,7 @@ let MainTreeCol = {
           if(node.sourceType === projectObj.project.ration_glj.getSourceType()){
               return gljOprObj.getTotalQuantity(node.data);
           }else {
-              return nodeTools.uiQuantity(node)?nodeTools.uiQuantity(node):null;
+              return assistCalcer.uiQuantity(node)?assistCalcer.uiQuantity(node):null;
           }
         },
         // CSL, 2017-11-28

+ 8 - 47
web/building_saas/main/js/views/project_view.js

@@ -31,6 +31,11 @@ var projectObj = {
                 pageCCOprObj.clearData();
             }
         }
+
+        // for test interface.  CSLAAAAA
+/*        node.data.gljList = project.ration_glj.getGljArrByRation(node.data.ID);
+        let bname = '暂估材料费';
+        alert(bname + ': ' + rationCalcBaser[bname](node));*/
     },
     refreshBaseActn: function (tree) {
         let setButtonValid = function (valid, btn) {
@@ -180,50 +185,6 @@ var projectObj = {
             return this.checkCommonField(editingText, colSetting);
         }
     },
-    /*updateAndReCalculate: function (node, fieldName, value) {
-        let project = projectObj.project, calc = new BillsCalcHelper(project), nodes = [];
-        let getNodes = function (node) {
-            let cur = node, nodes = [];
-            while (cur) {
-                nodes.push(cur);
-                cur = cur.parent;
-            }
-            return nodes;
-        }
-        if (value) {
-            value = value.toDecimal(projectObj.project.Decimal.common.quantity);
-        }
-        if (node.sourceType === projectObj.project.Bills.getSourceType()) {
-            calcFees.setFee(node.data, fieldName, value);
-            calc.calcNode(node, true);
-            nodes = getNodes(node);
-            project.Bills.updateNodes(nodes, true);
-        }
-        else if (node.sourceType === projectObj.project.VolumePrice.getSourceType()) {
-            project.beginUpdate('VolumePrice_QuantityChange');
-            project.VolumePrice.updateField(node.source, fieldName, value, false);
-            calc.calcNode(node.parent, true);
-            nodes = getNodes(node.parent);
-            project.Bills.updateNodes(nodes, false);
-            project.endUpdate();
-            nodes.push(node);
-        }
-        else if (node.sourceType === projectObj.project.Ration.getSourceType()) {
-            project.beginUpdate('Ration_QuantityChange');
-            calcFees.setFee(node.data, fieldName, value);
-            node.data.gljList = project.ration_glj.getGljArrByRation(node.data.ID);
-            // calcProgram.calculate的传参必须是cacheNode类型,故无法将计算放在Ration模块中。
-            project.calcProgram.calculate(node);
-            project.Ration.updateRation(node.source, false);    // 加入待存储队列
-            calc.calcNode(node.parent, true);       //
-            nodes = getNodes(node.parent);
-            project.Bills.updateNodes(nodes, false);
-            project.endUpdate();
-            nodes.push(node);
-        }
-        this.mainController.refreshTreeNode(nodes, false);
-        calc = null;
-    },*/
     updateBillsCode: function (node, value) {
         let project = projectObj.project;
         let stdMatchCode, formatCode, matchs;
@@ -1112,8 +1073,8 @@ $('#property_ok').click(function () {
             bills: bills
         },
 
-        reCalcBills= false,
-        reCalcRations= false;
+        reCalcBills = false,
+        reCalcRations = false;
 
     let b = parseInt($("input[name='calcFlag']:checked").val());
     if (b !== project.property.billsCalcMode) {
@@ -1126,7 +1087,7 @@ $('#property_ok').click(function () {
     if (zg !== project.property.zanguCalcMode) {
         properties['property.zanguCalcMode'] = zg;
         project.property.zanguCalcMode = zg;
-        reCalcBills = true;
+        reCalcRations = true;
     };
 
     //基本信息