Forráskód Böngészése

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

zhongzewei 7 éve
szülő
commit
d3dca09cab

+ 1 - 1
modules/main/models/bills.js

@@ -23,7 +23,7 @@ let billsSchema = new Schema({
     chapterID: Number,
     code: String,
     fullCode: String,
-    type:Number,
+    type:{type: Number,default:4},//1 :大项费用 2:分部 3分项 4清单
     isAdd:{type: Number,default:0},//1 true 0 false是否新增
     name: String,
     unit: String,

+ 1 - 1
modules/pm/models/templates/bills_template_model.js

@@ -39,7 +39,7 @@ class BillsTemplateModel extends BaseModel {
      */
     async getTemplateDataForNewProj (valuationId, engineering) {
         // 筛选字段
-        let field = {_id: 0, ID: 1, ParentID: 1, NextSiblingID: 1, code: 1, name: 1, unit: 1, flags: 1};
+        let field = {_id: 0, ID: 1, ParentID: 1, NextSiblingID: 1, code: 1, name: 1, unit: 1, flags: 1,type:1};
         let data = await this.findDataByCondition({valuationId: valuationId, engineering: engineering}, field, false);
 
         return data === null ? [] : data;

+ 2 - 1
modules/pm/models/templates/schemas/bills_template.js

@@ -30,7 +30,8 @@ let BillsTemplateSchema = {
     // 所属计价ID
     valuationId: String,
     // 工程专业
-    engineering: Number
+    engineering: Number,
+    type:Number
 };
 
 let model = mongoose.model(collectionName, new Schema(BillsTemplateSchema, {versionKey: false, collection: collectionName}));

+ 4 - 2
web/building_saas/main/js/models/bills.js

@@ -169,11 +169,12 @@ var Bills = {
             this.datas.push(newData);
             return this.tree.insertByData(newData,parentId, nextSiblingId);
         };
-        bills.prototype.insertBills = function (parentId, nextSiblingId) {//是否是用户新增的
+        bills.prototype.insertBills = function (parentId, nextSiblingId) {
             var insertData = this.tree.getInsertData(parentId, nextSiblingId);
             var that = this, newData = null;
             insertData.forEach(function (data) {
                 if (data.type === idTree.updateType.new) {
+                    data.data.type = billType.BILL;
                     newData = data.data;
                 }
             });
@@ -182,7 +183,7 @@ var Bills = {
             //project.pushNow('insertBills', ModuleNames.bills, tools.coverseTreeUpdateData(insertData));
 
             this.datas.push(newData);
-            return this.tree.insert(parentId, nextSiblingId);
+            return this.tree.insertByData(newData,parentId, nextSiblingId);
         };
         bills.prototype.insertStdBills = function (parentId, nextSiblingId, stdBillsData) {
             var insertData = this.tree.getInsertData(parentId, nextSiblingId);
@@ -202,6 +203,7 @@ var Bills = {
                     data.data.jobContentText = stdBillsData.jobContentText;
                     data.data.itemCharacterText = stdBillsData.itemCharacterText;
                     data.data.programID = stdBillsData.engineering;
+                    data.data.type = billType.BILL;//插入清单类型
                     //zhong
                     newData = data.data;
                 }

+ 0 - 2
web/building_saas/main/js/models/calc_base.js

@@ -606,8 +606,6 @@ let calcBase = {
             me.success = true;
             node.data.calcBase = exp;
             node.data.calcBaseValue = parseFloat(calcBaseValue).toDecimal(decimalObj.decimal('totalPrice', node));
-           /* me.project.calcProgram.calculate(node);
-            me.project.calcProgram.saveNode(node);*/
         }
         catch (err){
             alert(me.errMsg);

+ 167 - 142
web/building_saas/main/js/models/calc_program.js

@@ -6,7 +6,8 @@
  *  用到费率的规则必须有feeRateID属性,当有该属性时,会自动显示费率值。
  */
 
-/*let defaultBillTemplate = {
+/*  新版GLD 取消了默认清单模板,所以这里废弃。先留着,预防不时之需。
+let defaultBillTemplate = {
     ID: 15,
     name: "清单公式",
     calcItems: [
@@ -430,26 +431,74 @@ let treeNodeTools = {
         return nodes;
     },
 
-    isRation: function(treeNode){
-        return treeNode.sourceType === ModuleNames.ration && treeNode.data.type === rationType.ration;
+    isBill: function(treeNode){
+        return treeNode.sourceType === ModuleNames.bills;
     },
-
     isLeafBill: function(treeNode){
-        return treeNode.sourceType === projectObj.project.Bills.getSourceType() &&
+        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);
     },
 
+    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;
+    },
+
+    initFeeField(treeNode, fieldName){
+        if (!treeNode.data.fees) {
+            treeNode.data.fees = [];
+            treeNode.data.feesIndex = {};
+        };
+        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;
+        };
+    },
+
+    getCalcType(treeNode) {
+        if (this.isRationCategory(treeNode)){
+            return treeNodeCalcType.ctRationCalcProgram;
+        }
+        else if (this.isNullBill(treeNode)){
+            return treeNodeCalcType.ctCommonUnitFee;
+        }
+        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;
+        };
     }
 };
 
@@ -461,15 +510,18 @@ class CalcProgram {
         project.registerModule(ModuleNames.calc_program, me);
     };
 
+    // 兼容Project框架方法
     getSourceType () {
         return ModuleNames.calc_program;
     };
 
+    // 兼容Project框架方法
     loadData (datas) {
         this.datas = datas;
         this.compileAllTemps();
     };
 
+    // 兼容Project框架方法
     doAfterUpdate (err, data) {
         if(!err){
             $.bootstrapLoading.end();
@@ -648,28 +700,62 @@ class CalcProgram {
         };
     };
 
-    initFeeField(treeNode, fieldName){
-        if (!treeNode.data.fees) {
-            treeNode.data.fees = [];
-            treeNode.data.feesIndex = {};
+    // 存储、刷新零散的多个结点。
+    saveNodes(treeNodes){
+        if (treeNodes.length < 1) return;
+
+        let me = this;
+
+        me.project.beginUpdate('');
+        for (let node of treeNodes){
+            if (node.changed){
+                let data = {
+                    ID: node.data.ID,
+                    projectID: me.project.ID(),
+                    /*  subType、quantity、calcBase、programID、marketUnitFee等等字段较为特殊,它们的改变一定会触发计算并导致计算
+                    结果的变化,从而引发保存动作。将这些字段放在该位置跟计算结果一起保存,可减少前端跟后端的通讯频率。              */
+                    subType: node.data.subType,
+                    quantity: node.data.quantity,
+                    calcBase: node.data.calcBase,
+                    calcBaseValue: node.data.calcBaseValue,
+                    programID: node.data.programID,
+                    marketUnitFee: node.data.marketUnitFee,
+                    marketTotalFee: node.data.marketTotalFee,
+                    fees: node.data.fees,
+                    isFromDetail:node.data.isFromDetail,
+                    feeRate: node.data.feeRate,
+                    feeRateID: node.data.feeRateID,
+                    contain:node.data.contain,
+                    quantityEXP:node.data.quantityEXP
+                };
+                if(node.sourceType==ModuleNames.ration && node.data.type==rationType.gljRation){//定额类型的工料机做特殊处理
+                    data.code=node.data.code;
+                    data.projectGLJID = node.data.projectGLJID;
+                    delete data.marketUnitFee;
+                }
+
+                let newData = {'updateType': 'ut_update', 'updateData': data};
+                me.project.push(node.sourceType, [newData]);
+            }
         };
-        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;
+        me.project.endUpdate();
+
+        for (let node of treeNodes){delete node.changed};
+        projectObj.mainController.refreshTreeNode(treeNodes);
+
+        if (activeSubSheetIs(subSheetIndex.ssiCalcProgram)) {
+            calcProgramObj.showData(me.project.mainTree.selected, false);
         };
     };
 
-  // 仅内部调用。注意:外部不能直接使用,因为这里传入的树节点必须有一定的初始化。
-    InnerCalc(treeNode){
+    // 只计算treeNode自身。changedArr: 外部传来的一个数组,专门存储发生变动的节点
+    innerCalc(treeNode, changedArr){
         let me = this;
-        let project = me.project;
+        // 仅用作树节点显示的工料机不能参与计算。
+        if (treeNode.sourceType === me.project.ration_glj.getSourceType()) return;
+
+        treeNode.calcType = treeNodeTools.getCalcType(treeNode);
+        // if (treeNode.calcType == treeNodeCalcType.ctCalcBaseValue) return;
 
         function initFees(treeNode){
             if (!treeNode.data.fees) {
@@ -711,12 +797,13 @@ class CalcProgram {
             return ['labour', 'material', 'machine', 'mainMaterial', 'equipment'].indexOf(type) > -1;
         };
 
-        // 汇总定额或子清单的费用类别
-        if (treeNode.calcType == treeNodeCalcType.ctGatherRationsFees || treeNode.calcType == treeNodeCalcType.ctGatherBillsFees){
+        // 父清单汇总子项(定额或子清单)的费用类别
+        if (treeNode.calcType == treeNodeCalcType.ctGatherRationsFees ||
+            treeNode.calcType == treeNodeCalcType.ctGatherBillsFees){
             treeNode.data.programID = null;
             initFees(treeNode);
 
-            let objsArr = (treeNode.calcType == treeNodeCalcType.ctGatherRationsFees) ? project.Ration.getRationsByNode(treeNode) : treeNode.children;
+            let objsArr = (treeNode.calcType == treeNodeCalcType.ctGatherRationsFees) ? me.project.Ration.getRationsByNode(treeNode) : treeNode.children;
             let rst = [];
             for (let ft of cpFeeTypes) {
                 let ftObj = {};
@@ -798,7 +885,7 @@ class CalcProgram {
 
             delete treeNode.data.fees;    // 直接删掉再新增,不用一个个费判断更新,效率更高。
             delete treeNode.data.feesIndex;
-            me.initFeeField(treeNode, 'common');
+            treeNodeTools.initFeeField(treeNode, 'common');
             treeNode.data.feesIndex.common.unitFee = uf.toDecimal(decimalObj.bills.unitPrice);
             treeNode.data.feesIndex.common.totalFee = tf.toDecimal(decimalObj.bills.totalPrice);
             treeNode.data.feesIndex.common.tenderUnitFee = tuf.toDecimal(decimalObj.bills.unitPrice);
@@ -806,13 +893,12 @@ class CalcProgram {
             treeNode.changed = true;
             treeNode.data.calcTemplate = {"calcItems": []};
         }
-        // 叶子清单的计算基数计算
+        // 叶子清单公式计算
         else if (treeNode.calcType == treeNodeCalcType.ctCalcBaseValue){
             delete treeNode.data.gljList;
             if (treeNode.data.programID) treeNode.data.programID = null;
 
             let f = treeNode.data.feeRate ? treeNode.data.feeRate : 100;
-            // let q = treeNode.data.quantity ? treeNode.data.quantity : 0;
             if (!treeNode.data.quantity) treeNode.data.quantity = 1;
             let q = treeNode.data.quantity;
             let b = treeNode.data.calcBaseValue ? treeNode.data.calcBaseValue : 0;
@@ -823,7 +909,7 @@ class CalcProgram {
 
             delete treeNode.data.fees;    // 直接删掉再新增,不用一个个费判断更新,效率更高。
             delete treeNode.data.feesIndex;
-            me.initFeeField(treeNode, 'common');
+            treeNodeTools.initFeeField(treeNode, 'common');
             treeNode.data.feesIndex.common.unitFee = uf;
             treeNode.data.feesIndex.common.totalFee = tf;
             treeNode.data.feesIndex.common.tenderUnitFee = tuf;
@@ -831,7 +917,7 @@ class CalcProgram {
             treeNode.changed = true;
             treeNode.data.calcTemplate = {"calcItems": []};
         }
-        // 定额或清单自己的计算程序计算
+        // 定额或叶子清单自己的计算程序计算
         else{
             if (treeNode.calcType == treeNodeCalcType.ctRationCalcProgram) {
                 if (treeNode.data.type == rationType.volumePrice){
@@ -852,10 +938,9 @@ class CalcProgram {
                 };
             }
             else if (treeNode.calcType == treeNodeCalcType.ctBillCalcProgram) {
-                let rations = project.Ration.getBillsSortRation(treeNode.source.getID());
-                treeNode.data.gljList = project.ration_glj.getGatherGljArrByRations(rations);
+                let rations = me.project.Ration.getBillsSortRation(treeNode.source.getID());
+                treeNode.data.gljList = me.project.ration_glj.getGatherGljArrByRations(rations);
 
-                // if (treeNode.data.programID == undefined || treeNode.data.programID == defaultBillTemplate.ID){
                 if (treeNode.data.programID == undefined){
                     treeNode.data.programID = projectInfoObj.projectInfo.property.engineering;
                 }
@@ -889,104 +974,32 @@ class CalcProgram {
                 };
             }
         };
-    };
-
-    // 计算本节点(默认同时递归计算所有父节点,可选)
-    calculate(treeNode, calcParents = true){
-        let me = this;
-        if (treeNode.sourceType === me.project.ration_glj.getSourceType()) return;     // 仅用作树节点显示的工料机不能参与计算。
-        let isRation = treeNode.sourceType === me.project.Ration.getSourceType();
-        let isBill = treeNode.sourceType === me.project.Bills.getSourceType();
 
-        if (isRation){
-            treeNode.calcType = treeNodeCalcType.ctRationCalcProgram;
-        }
-        else  if (treeNodeTools.isNullBill(treeNode)){
-            treeNode.calcType = treeNodeCalcType.ctCommonUnitFee;
-        }
-        else if (treeNodeTools.isLeafBill(treeNode)) {
-            if (treeNode.children && treeNode.children.length > 0){
-                // 清单单价计算模式下的叶子清单:取自己的计算程序ID,找到自己的计算程序计算。(汇总清单所有定额的工料机)
-                if (me.project.property.billsCalcMode === leafBillGetFeeType.billsPrice)
-                    treeNode.calcType = treeNodeCalcType.ctBillCalcProgram;
-                else                                        // 前三种计算模式下的叶子清单:汇总定额的计算程序的费用类别
-                    treeNode.calcType = treeNodeCalcType.ctGatherRationsFees;
-            }
-            else{                                          // 公式计算
-                treeNode.calcType = treeNodeCalcType.ctCalcBaseValue;
-            };
-        }
-        else if (isBill)                                 // 父清单:汇总子清单的费用类别
-            treeNode.calcType = treeNodeCalcType.ctGatherBillsFees;
-
-        me.InnerCalc(treeNode);
-
-        // 计算所有父结点
-        if (treeNode.changed && calcParents && treeNode.parent) {
-            me.calculate(treeNode.parent);
-        };
+        if (treeNode.changed && !changedArr.includes(treeNode)) changedArr.push(treeNode);
     };
 
-    // 存储、刷新本节点(默认存储刷新所有父节点,可选)
-    saveNode(treeNode, saveParents = true) {
-        if (!treeNode.changed) return;
+    // 计算本节点、所有父节点(默认,可选)、公式引用节点。
+    calculate(treeNode, calcParents = true){
         let me = this;
-        let nodesArr = [];
-        let curNode = treeNode;
-        while (curNode) {
-            if (curNode.changed){nodesArr.push(curNode)};
-            if (saveParents) curNode = curNode.parent
-            else break;
-        };
-        me.saveNodes(nodesArr);
-    };
-
-    // 存储、刷新零散的多个树结点
-    saveNodes(treeNodes){
-        if (treeNodes.length < 1) return;
+        let changedNodes = [];
 
-        let me = this;
+        me.innerCalc(treeNode, changedNodes);
 
-        me.project.beginUpdate('');
-        for (let node of treeNodes){
-            if (node.changed){
-                let data = {
-                    ID: node.data.ID,
-                    projectID: me.project.ID(),
-                    /*  subType、quantity、calcBase、programID、marketUnitFee等等字段较为特殊,它们的改变一定会触发计算并导致计算
-                    结果的变化,从而引发保存动作。将这些字段放在该位置跟计算结果一起保存,可减少前端跟后端的通讯频率。              */
-                    subType: node.data.subType,
-                    quantity: node.data.quantity,
-                    calcBase: node.data.calcBase,
-                    calcBaseValue: node.data.calcBaseValue,
-                    programID: node.data.programID,
-                    marketUnitFee: node.data.marketUnitFee,
-                    marketTotalFee: node.data.marketTotalFee,
-                    fees: node.data.fees,
-                    isFromDetail:node.data.isFromDetail,
-                    feeRate: node.data.feeRate,
-                    feeRateID: node.data.feeRateID,
-                    contain:node.data.contain,
-                    quantityEXP:node.data.quantityEXP
+        if (treeNode.changed) {
+            // 计算父结点
+            if (calcParents){
+                let curNode = treeNode.parent;
+                while (curNode){
+                    me.innerCalc(curNode, changedNodes);
+                    curNode = curNode.parent;
                 };
-                if(node.sourceType==ModuleNames.ration && node.data.type==rationType.gljRation){//定额类型的工料机做特殊处理
-                    data.code=node.data.code;
-                    data.projectGLJID = node.data.projectGLJID;
-                    delete data.marketUnitFee;
-                }
+            };
 
-                let newData = {'updateType': 'ut_update', 'updateData': data};
-                me.project.push(node.sourceType, [newData]);
-            }
+            // 父结点算完,再计算所有的公式结点(必须先算完父结点,再算公式结点)
+            me.calcFormulaNodes(changedNodes);
         };
-        me.project.endUpdate();
-
-        for (let node of treeNodes){delete node.changed};
-        projectObj.mainController.refreshTreeNode(treeNodes);
 
-        if (activeSubSheetIs(subSheetIndex.ssiCalcProgram)) {
-            calcProgramObj.showData(me.project.mainTree.selected, false);
-        };
+        return changedNodes;
     };
 
     /* 计算所有树结点(分3种情况),并返回发生变动的零散的多个树结点。
@@ -1016,20 +1029,30 @@ class CalcProgram {
         return changedNodes;
     };
 
-    // 计算全部公式项
-    calcFormulaNodes(){
-        let nodes = treeNodeTools.getFormulaNodes();
-        if (nodes.length == 0) return;
-        for (let node of nodes){
-              this.calcFormulaNode(node);
+    // 计算全部公式项。 (参数意义:将通过本方法后发生改变的节点存入changedNodesArr中)
+    calcFormulaNodes(changedArr){
+        let me = this;
+        let formulaNodes = treeNodeTools.getFormulaNodes();
+        if (formulaNodes.length == 0) return;
+        for (let formulaNode of formulaNodes){
+            formulaNode.data.userCalcBase = formulaNode.data.calcBase;    // 这句不该出现,projectObj.project.calcBase中要改进。
+            projectObj.project.calcBase.calculate(formulaNode, true);
+            if (projectObj.project.calcBase.success){
+                // 计算公式结点
+                me.innerCalc(formulaNode, changedArr);
+
+                // 计算父结点
+                if (formulaNode.changed){
+                    let curNode = formulaNode.parent;
+                    while (curNode){
+                        me.innerCalc(curNode, changedArr);
+                        curNode = curNode.parent;
+                    };
+                };
+            };
         };
     };
 
-    // 计算公式项。(它一定是叶子结点,它的父结点一定没有公式)
-    calcFormulaNode(treeNode){
-        // do
-    };
-
     // 计算叶子清单下的所有子结点(如定额、量价、工料机定额等), 并计算自身和所有父结点。最后打包存储。
     calcLeafAndSave(treeNode){
         let me = this;
@@ -1056,22 +1079,24 @@ class CalcProgram {
     calcRationsAndSave(rationNodes){
         let me = this, leafBills = [], changedNodes = [];
         for (let node of rationNodes) {
-            me.calculate(node, false);
-            if (node.changed) changedNodes.push(node);
+            me.innerCalc(node, changedNodes);
             let leafBill = node.parent;
-            if (leafBill && leafBills.indexOf(leafBill) < 0) leafBills.push(leafBill);      // 多条定额同属一条叶子清单时,避免叶子清单重复计算
+            // 多条定额同属一条叶子清单时,避免叶子清单重复计算
+            if (leafBill && leafBills.indexOf(leafBill) < 0) leafBills.push(leafBill);
         };
 
         for (let node of leafBills){
             me.calculate(node);
-            let cur = node;
-            while (cur) {
-                if (cur.changed && changedNodes.indexOf(cur) < 0) changedNodes.push(cur);
-                cur = cur.parent;
-            };
         };
 
         me.saveNodes(changedNodes);
     };
 
+    // 计算并保存指定的一个树节点。修改一个树节点,实际上要计算和保存的是一批树结点:层层父结点、被其它结点(的公式)引用的公式结点。
+    // 这个方法实际上封装了calculate()和saveNodes()两个方法,主要目的是为了外部调用方便,少写一点累赘代码。
+    calcAndSave(treeNode){
+        let changedNodes = this.calculate(treeNode);
+        this.saveNodes(changedNodes);
+    };
+
 }

+ 1 - 2
web/building_saas/main/js/models/fee_rate.js

@@ -348,8 +348,7 @@ var FeeRate = {
                     var rate =me.getFeeRateByID(bill.feeRateID);
                     var data=me.getfbUpdateData(rate,bill,fee_value,value);
                     if(data==null){//只更改清单的值的情况下,由计算程序更新
-                        project.calcProgram.calculate(node);
-                        project.calcProgram.saveNode(node);
+                        project.calcProgram.calcAndSave(node);
                     }
                     this.setFeeRateToBill(data,function (result) {
                         if(data.hasOwnProperty('feeRate')){

+ 1 - 0
web/building_saas/main/js/models/main_consts.js

@@ -174,6 +174,7 @@ const fixedFlag = {
 };
 
 const gljKeyArray =['code','name','specs','unit','type'];
+const rationKeyArray =['code','name','specs','unit','subType'];
 const gljLibKeyArray =['code', 'name', 'specs', 'unit', 'gljType'];
 const billType ={
     DXFY:1,//大项费用

+ 1 - 2
web/building_saas/main/js/models/project_glj.js

@@ -217,8 +217,7 @@ ProjectGLJ.prototype.updateGLJProperty = function (node, updateField, newval) {
         //触发计算并更新节点信息
         node.changed = true;
         projectObj.project.projectGLJ.loadData(function () {
-            projectObj.project.calcProgram.calculate(node);
-            projectObj.project.calcProgram.saveNode(node);
+            projectObj.project.calcProgram.calcAndSave(node);
             $.bootstrapLoading.end();
         });//重新加载项目工料机数据
         //上面两步都是异步操作,这句应该是要等上面两步做完了再执行的

+ 2 - 4
web/building_saas/main/js/models/quantity_detail.js

@@ -587,8 +587,7 @@ var quantity_detail = {
                 project.calcProgram.calcRationsAndSave(needUpdateChildren);
             }else {
                 node.changed = true;
-                project.calcProgram.calculate(node);
-                project.calcProgram.saveNode(node);
+                project.calcProgram.calcAndSave(node);
             }
             if(gljNodes.length>0){
                 projectObj.mainController.refreshTreeNode(gljNodes);
@@ -607,8 +606,7 @@ var quantity_detail = {
             value = scMathUtil.roundForObj(value,decimalObj.decimal("quantity",node))
             node.data.quantity=value;
             node.changed = true;
-            project.calcProgram.calculate(node);
-            project.calcProgram.saveNode(node);
+            project.calcProgram.calcAndSave(node);
             projectObj.mainController.refreshTreeNode(node.children);//刷新子工料机总消耗量
             gljOprObj.showRationGLJSheetData();
         };

+ 1 - 2
web/building_saas/main/js/models/ration.js

@@ -408,8 +408,7 @@ var Ration = {
             node.data.quantity=scMathUtil.roundForObj(billQuantity*contain,getDecimal("quantity"),node);
             node.data.quantity = projectObj.project.quantity_detail.autoTransformQuantity(node.data.quantity,node);//按单位做转换
             node.changed = true;
-            project.calcProgram.calculate(node);
-            project.calcProgram.saveNode(node);
+            project.calcProgram.calcAndSave(node);
             projectObj.mainController.refreshTreeNode(node.children);//刷新子工料机树节点总消耗量
         };
         

+ 2 - 4
web/building_saas/main/js/models/ration_glj.js

@@ -119,8 +119,7 @@ var ration_glj = {
             me.addToMainTree(neRecodes);
             let node = project.mainTree.selected;
             project.projectGLJ.loadData(function () {
-                project.calcProgram.calculate(node);
-                project.calcProgram.saveNode(node);
+                project.calcProgram.calcAndSave(node);
                 if (activeSubSheetIs(subSheetIndex.ssiCalcProgram)) {
                     calcProgramObj.showData(node, false);
                 };
@@ -750,8 +749,7 @@ var ration_glj = {
         ration_glj.prototype.reCalcWhenGLJChange = function (ration_glj) {//当改变定额工料机时,重新计算定额以及期父节点
             let node = this.findRationNodeByID(ration_glj.rationID);
             if (node) {
-                project.calcProgram.calculate(node);
-                project.calcProgram.saveNode(node);
+                project.calcProgram.calcAndSave(node);
             }
         };
         return new ration_glj(project);

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

@@ -136,7 +136,7 @@ let calcBaseView = {
         }
         me.buildSheet();
         let baseObj = projectObj.project.calcBase.getBaseByClass(node);
-        console.log(baseObj);
+        // console.log(baseObj);
         me.showData(me.toViewData(baseObj));
 
     },

+ 1 - 2
web/building_saas/main/js/views/calc_program_view.js

@@ -43,8 +43,7 @@ let calcProgramObj = {
         var me = this;
         me.treeNode = treeNode;
         if (needCalc){
-            projectObj.project.calcProgram.calculate(treeNode);
-            projectObj.project.calcProgram.saveNode(treeNode);
+            projectObj.project.calcProgram.calcAndSave(treeNode);
         };
         me.datas = treeNode.data.calcTemplate ? treeNode.data.calcTemplate.calcItems : [];
         sheetCommonObj.initSheet(me.sheet, me.setting, me.datas.length);

+ 1 - 2
web/building_saas/main/js/views/fee_rate_view.js

@@ -652,8 +652,7 @@ var feeRateObject={
             selected.data.feeRateID=rate.ID.toString();
             selected.data.feeRate=scMathUtil.roundToString(rate.rate,getDecimal("feeRate"));
             selected.changed = true;
-            projectObj.project.calcProgram.calculate(selected);
-            projectObj.project.calcProgram.saveNode(selected);
+            projectObj.project.calcProgram.calcAndSave(selected);
             //projectObj.mainController.refreshTreeNode([selected]);
             $("#fee_rate_tree").modal('hide');
         });

+ 39 - 9
web/building_saas/main/js/views/glj_view.js

@@ -686,6 +686,11 @@ var gljOprObj = {
                 this.showRationAssData(node);
                 isShow = true;
             }
+            if(node.sourceType == ModuleNames.ration_glj){
+
+                isShow = true;
+            }
+
             this.showQuantityDetailData(node);
         } else {
             this.selectedNodeId = null;
@@ -700,6 +705,29 @@ var gljOprObj = {
         }
         //   $('#dropdown').hide();
     },
+    showMixRatio:function (node) {//显示组成物到定额工料机
+        let mixRatioMap = projectObj.project.projectGLJ.datas.mixRatioMap;
+        let projectGljs = projectObj.project.projectGLJ.datas.gljList;
+        let indexArray =node.getSourceType()==ModuleNames.ration?rationKeyArray:gljKeyArray;
+        let connect_index = this.getIndex(node.data,indexArray);
+        let gljList=[];
+        if(mixRatioMap[connect_index]){ //说明是有组成物的类型
+            gljList =  this.getMixRationShowDatas(mixRatioMap[connect_index], projectGljs);
+        }
+        if(gljList.length>0){//计算总消耗量
+            if(node.getSourceType()==ModuleNames.ration){
+                this.calcMixRationTotalQuantity(gljList,node.data.quantity);
+            }else {
+               let totalQuantity = this.getTotalQuantity(node.data);
+               this.calcMixRationTotalQuantity(gljList,totalQuantity)
+            }
+        }
+        this.sheetData = gljList;
+        this.sheet.setRowCount(0);
+        this.sheetData = sortRationGLJ(this.sheetData);
+        sheetCommonObj.showData(this.sheet, this.setting, this.sheetData);
+    },
+
     showRationGLJData: function (node) {
         var gljList = [];
         var ration_glj = projectObj.project.ration_glj;
@@ -775,14 +803,18 @@ var gljOprObj = {
             glj.quantity = scMathUtil.roundForObj(glj.quantity, getDecimal("glj.quantity"));
             glj.totalQuantity = scMathUtil.roundToString(quantity * glj.quantity, getDecimal("glj.quantity"));
             if (glj.hasOwnProperty('subList')) {//需要计算glj下挂的组成物的总消耗量
-                for (let subG of glj.subList) {
-                    subG.rationItemQuantity = scMathUtil.roundForObj(subG.rationItemQuantity, getDecimal("glj.quantity"));
-                    subG.totalQuantity = scMathUtil.roundToString(subG.rationItemQuantity * glj.totalQuantity, getDecimal("glj.quantity"));
-                }
+                this.calcMixRationTotalQuantity(glj.subList,glj.totalQuantity);
             }
             return  glj.totalQuantity;
         }
     },
+    calcMixRationTotalQuantity(mList,pTotal){ //计算组成物的总消耗量
+        for (let subG of mList) {
+            subG.rationItemQuantity = scMathUtil.roundForObj(subG.rationItemQuantity, getDecimal("glj.quantity"));
+            subG.totalQuantity = scMathUtil.roundToString(subG.rationItemQuantity * pTotal, getDecimal("glj.quantity"));
+        }
+    },
+
     addMixRatioToShow: function () {
         var newList = [];
         _.remove(this.sheetData, {'isMixRatio': true});
@@ -808,7 +840,7 @@ var gljOprObj = {
                     }
                     ration_gljs[i].isAdd = glj.unit_price.is_add;
                     ration_gljs[i]=this.setGLJPrice(ration_gljs[i],glj);//设置工料机价格
-                    var connect_index = this.getIndex(glj, gljKeyArray)
+                    var connect_index = this.getIndex(glj, gljKeyArray);
                     if (mixRatioMap.hasOwnProperty(connect_index)) {
                         var mixRatios = this.getMixRationShowDatas(mixRatioMap[connect_index], projectGljs);
                         ration_gljs[i].subList = mixRatios;
@@ -1235,8 +1267,7 @@ var gljOprObj = {
                     gljOprObj.showRationGLJSheetData();
                     project.ration_glj.addToMainTree(result.showData);
                     project.projectGLJ.loadData(function () {
-                        project.calcProgram.calculate(selected);
-                        project.calcProgram.saveNode(selected);
+                        project.calcProgram.calcAndSave(selected);
                         projectObj.mainController.refreshTreeNode([selected]);
                         $.bootstrapLoading.end();
                     });
@@ -1278,8 +1309,7 @@ var gljOprObj = {
                 selected.data.adjustState = result.adjustState;
                 project.projectGLJ.loadData(function () {//加载完项目工料机再计算
                     projectObj.mainController.refreshTreeNode(nodes);
-                    project.calcProgram.calculate(selected);
-                    project.calcProgram.saveNode(selected);
+                    project.calcProgram.calcAndSave(selected);
                 });
             }
             $.bootstrapLoading.end();

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

@@ -257,8 +257,7 @@ var projectObj = {
         } else if (node.sourceType === project.Ration.getSourceType()) {
             this.updateRationCode(node, value);  // 新套定额适合实时计算
             // 这里因异步问题暂时缺少工料机价格。该过程移到:ration_glj.js的refreshAfterSave方法中。
-            /*project.calcProgram.calculate(node);
-            project.calcProgram.saveNode(node);
+            /*project.calcProgram.calcAndSave(node);
             if (activeSubSheetIs(subSheetIndex.ssiCalcProgram)) {
                 calcProgramObj.showData(node, false);
             };*/
@@ -304,12 +303,11 @@ var projectObj = {
                 };
                 node.changed = true;
                 if (fieldName == 'feesIndex.common.unitFee'){
-                    project.calcProgram.initFeeField(node, 'common');
+                    treeNodeTools.initFeeField(node, 'common');
                     node.data.feesIndex.common.unitFee = value;
                 }
                 else node.data[fieldName] = value;
-                project.calcProgram.calculate(node);
-                project.calcProgram.saveNode(node);
+                project.calcProgram.calcAndSave(node);
                 gljOprObj.showRationGLJSheetData();
             }
             else {
@@ -559,7 +557,10 @@ var projectObj = {
                     },
                     callback: function (key, opt) {
                         if(project.mainTree.selected.data.type == billType.DXFY){
-
+                            if(project.mainTree.selected.data.calcBase&&project.mainTree.selected.data.calcBase!=""){
+                                alert("当前有基数计算不能插入子项。");
+                                return;
+                            }
                         }
                         ProjectController.addBills(project, controller);
                     },
@@ -660,8 +661,7 @@ var projectObj = {
             this.project.Bills.updateNodes(nodes, true);
             calc = null;
         }*/
-        projectObj.project.calcProgram.calculate(node);
-        projectObj.project.calcProgram.saveNode(node);
+        projectObj.project.calcProgram.calcAndSave(node);
     },
     // 计算全部清单
 /*    calculateAll: function () {