Browse Source

算法调整,树结构计算。

Chenshilong 7 years ago
parent
commit
ac3cc252a3

+ 5 - 9
public/calc_util.js

@@ -79,7 +79,7 @@ let executeObj = {
     },
     HJ: function () {
         let me = this;
-        return me.treeNode.data.baseTotalPrice;
+        return me.treeNode.calcBaseValue;
     }
 };
 
@@ -428,12 +428,10 @@ class Calculation {
         let project = projectObj.project;
 
         // 汇总定额或子清单的费用类别
-        if (treeNode.data.gatherType != undefined){
-            if (treeNode.sourceType != project.Bills.getSourceType()) return;
-
+        if (treeNode.calcType == treeNodeCalcType.ctGatherRations || treeNode.calcType == treeNodeCalcType.ctGatherBills){
             me.initFees(treeNode);
 
-            let objsArr = (treeNode.data.gatherType === CP_GatherType.rations) ? project.Ration.getRationsByNode(treeNode) : treeNode.children;
+            let objsArr = (treeNode.calcType == treeNodeCalcType.ctGatherRations) ? project.Ration.getRationsByNode(treeNode) : treeNode.children;
             let rst = [];
             for (let ft of feeType) {
                 let ftObj = {};
@@ -441,7 +439,7 @@ class Calculation {
                 ftObj.name = ft.name;
                 let uf = 0, tf = 0, tuf = 0, ttf = 0;
                 for (let item of objsArr) {
-                    let data = (treeNode.data.gatherType === CP_GatherType.rations) ? item : item.data;
+                    let data = (treeNode.calcType == treeNodeCalcType.ctGatherRations) ? item : item.data;
                     if (data.feesIndex && data.feesIndex[ft.type]) {
                         uf = (uf + parseFloat(data.feesIndex[ft.type].unitFee)).toDecimal(me.digitDefault);
                         tf = (tf + parseFloat(data.feesIndex[ft.type].totalFee)).toDecimal(me.digitDefault);
@@ -462,9 +460,7 @@ class Calculation {
         }
         else{
             // 叶子清单的缺省计算程序需要提供总金额作为计算基数(不需要工料机),然后每条按比例(费率)计算,不需要工料机明细。
-            if (treeNode.data.baseTotalPrice != undefined){
-                if (treeNode.sourceType != project.Bills.getSourceType()) return;
-
+            if (treeNode.calcType == treeNodeCalcType.ctCalcBaseValue){
                 delete treeNode.data.gljList;
 
                 if (treeNode.data.programID == undefined){

+ 57 - 58
web/building_saas/main/js/models/calc_program.js

@@ -99,6 +99,8 @@ let defaultBillTemplate = {
     ]
 };
 
+
+
 class CalcProgram {
     constructor(project){
         this.project = project;
@@ -144,83 +146,80 @@ class CalcProgram {
         };
     };
 
-    calculate(treeNode){
+    // 计算本节点(默认同时递归计算所有父节点,可选)
+    calculate(treeNode, calcParents = true){
         let me = this;
 
-        me.calc.calculate(treeNode);
-
-        // 还原,防止出现混乱影响下次计算
-        delete treeNode.data.baseTotalPrice;
-        delete treeNode.data.gatherType;
-
-        // 存储、刷新本结点、所有父结点
-        if (treeNode.changed) {
-            me.saveAndCalcParents(treeNode);
-            delete treeNode.changed;
-        };
-    };
-
-    saveAndCalcParents(treeNode) {
-        if (treeNode.parent) {
-            projectObj.converseCalculateBills(treeNode.parent);
-        };
-
-        let data = {ID: treeNode.data.ID, projectID: projectObj.project.ID(), fees: treeNode.data.fees};
-        let newDta = {'updateType': 'ut_update', 'updateData': data};
-        let newDataArr = [];
-        newDataArr.push(newDta);
-        projectObj.project.pushNow('', treeNode.sourceType, newDataArr);
-        projectObj.mainController.refreshTreeNode([treeNode]);
-    };
-
-    getCalcDatas(treeNode){
-        let me = this;
-        let rst = [];
         let isRation = treeNode.sourceType === me.project.Ration.getSourceType();
         let isBill = treeNode.sourceType === me.project.Bills.getSourceType();
         let isLeafBill = isBill && treeNode.source.children && treeNode.source.children.length === 0;
         let isBillPriceCalc = me.project.projSetting.billsCalcMode === billsPrice;
 
-        if (isRation) {
-            //
-        }
+        if (isRation)
+            treeNode.calcType = treeNodeCalcType.ctRationCalcProgram
         else if (isLeafBill) {
-            let ct = '';
             if (treeNode.children && treeNode.children.length > 0){
                 if (treeNode.children[0].sourceType == me.project.Ration.getSourceType()){
-                    ct = childrenType.ration;
+                    if (isBillPriceCalc)                   // 清单单价计算模式下的叶子清单:取自己的计算程序ID,找到自己的计算程序计算
+                        treeNode.calcType = treeNodeCalcType.ctBillCalcProgram;
+                    else                                  // 前三种计算模式下的叶子清单:汇总定额的计算程序的费用类别
+                        treeNode.calcType = treeNodeCalcType.ctGatherRations;
                 }
                 else if (treeNode.children[0].sourceType == me.project.VolumePrice.getSourceType()){
-                    ct = childrenType.volumePrice;
+                    let value = 20000;
+                    // if (treeNode.data.feesIndex && treeNode.data.feesIndex.common && treeNode.data.feesIndex.common.unitFee != 0)
+                    //     value = treeNode.data.feesIndex.common.unitFee;
+                    treeNode.calcType = treeNodeCalcType.ctCalcBaseValue;
+                    treeNode.calcBaseValue = value;
                 };
             }
-            else{
-                ct = childrenType.formula;
+            else{                                          // 公式计算
+                let value = 20000;
+                // if (treeNode.data.feesIndex && treeNode.data.feesIndex.common && treeNode.data.feesIndex.common.unitFee != 0)
+                //     value = treeNode.data.feesIndex.common.unitFee;
+                treeNode.calcType = treeNodeCalcType.ctCalcBaseValue;
+                treeNode.calcBaseValue = value;
             };
+        }
+        else if (isBill)                                 // 父清单:汇总子清单的费用类别
+            treeNode.calcType = treeNodeCalcType.ctGatherBills;
 
-            if (ct == childrenType.ration){
-                if (isBillPriceCalc){                   // 清单单价计算模式下的叶子清单:取自己的计算程序ID,找到自己的计算程序计算
+        me.calc.calculate(treeNode);
 
-                }
-                else{                                   // 前三种计算模式下的叶子清单:汇总定额的计算程序的费用类别
-                    treeNode.data.gatherType = CP_GatherType.rations;
+        // 计算所有父结点
+        if (treeNode.changed && calcParents && treeNode.parent) {
+            me.calculate(treeNode.parent);
+        };
+    };
+
+    // 存储、刷新本节点(默认存储刷新所有父节点,可选)
+    saveNode(treeNode, saveParent = true) {
+        if (!treeNode.changed) return;
+
+        let newDataArr = [], nodesArr = [];
+        let project = projectObj.project;
+
+        project.beginUpdate('');
+        let curNode = treeNode;
+        while (curNode) {
+            if (curNode.changed){
+                let data = {
+                    ID: curNode.data.ID,
+                    projectID: projectObj.project.ID(),
+                    quantity: curNode.data.quantity,
+                    fees: curNode.data.fees
                 };
-            }
-            else if (ct == childrenType.volumePrice){
-                let totalPrice = 10000;
-                treeNode.data.baseTotalPrice = totalPrice;
-            }
-            else if (ct == childrenType.formula){
-                let totalPrice = 20000;
-                treeNode.data.baseTotalPrice = totalPrice;
+                let newDta = {'updateType': 'ut_update', 'updateData': data};
+                newDataArr.push(newDta);
+                nodesArr.push(curNode);
+                project.push(curNode.sourceType, newDataArr);
             };
-        }
-        else if (isBill){                                   // 父清单:汇总子清单的费用类别
-            treeNode.data.gatherType = CP_GatherType.bills;
+            if (saveParent) curNode = curNode.parent
+            else break;
         };
+        project.endUpdate();
 
-        me.calculate(treeNode);
-        rst = treeNode.data.calcTemplate.calcItems;
-        return rst;
-    }
+        for (let node of nodesArr){delete node.changed;};
+        projectObj.mainController.refreshTreeNode(nodesArr);
+    };
 }

+ 6 - 10
web/building_saas/main/js/models/main_consts.js

@@ -36,14 +36,10 @@ const CP_Col_Width = {          // 多处计算程序界面的列宽统一设置
     totalFee: 90
 };
 
-const CP_GatherType = {
-    rations: 'rations',
-    bills: 'bills'
-};
-
-const childrenType = {
-    ration: 'ration',
-    bill: 'bill',
-    volumePrice: 'volumePrice',
-    formula: 'formula'
+treeNodeCalcType = {
+    ctRationCalcProgram: 1,
+    ctBillCalcProgram: 2,
+    ctGatherRations: 3,
+    ctGatherBills: 4,
+    ctCalcBaseValue: 5
 };

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

@@ -228,7 +228,9 @@ let calcProgramObj = {
     showData: function (treeNode) {
         var me = this;
         me.treeNode = treeNode;
-        me.datas = projectObj.project.calcProgram.getCalcDatas(treeNode);
+        projectObj.project.calcProgram.calculate(treeNode);
+        projectObj.project.calcProgram.saveNode(treeNode);
+        me.datas = treeNode.data.calcTemplate.calcItems;
         sheetCommonObj.initSheet(me.sheet, me.setting, me.datas.length);
         sheetCommonObj.showData(me.sheet, me.setting, me.datas);
 

+ 4 - 1
web/building_saas/main/js/views/project_view.js

@@ -258,7 +258,10 @@ var projectObj = {
             if (fieldName === 'code') {
                 projectObj.updateCode(node, value);
             } else if (fieldName === 'quantity' && project.quantity_detail.quantityEditChecking(value,node,fieldName)) {
-                projectObj.updateAndReCalculate(node, fieldName, value);
+                node.data.quantity = value;
+                project.calcProgram.calculate(node);
+                project.calcProgram.saveNode(node);
+                // projectObj.updateAndReCalculate(node, fieldName, value);
             } else if (fieldName === 'feesIndex.common.unitFee') {
                 projectObj.updateAndReCalculate(node, fieldName, value);
             } else if(fieldName ==='feeRate'){