chenshilong 7 years ago
parent
commit
66a2131aec

+ 70 - 157
web/building_saas/main/js/models/calc_program.js

@@ -553,7 +553,6 @@ const rationCalcBases = {
 
 let analyzer = {
     calcTemplate: null,
-    success: true,
 
     standard: function(expr){
         let str = expr;
@@ -587,47 +586,59 @@ let analyzer = {
     isCycleCalc: function (expr) {     // @5+@6  这里已经是ID引用
         let me = this;
         
-        function checkCycle() {
-            
-        }
-        let atIDArr = me.getAtIDArr(expr);
-        for (let atID of atIDArr){
-            let ID = atID.slice(1);
-            let item = me.calcTemplate.compiledCalcItems[ID];
-            let expression = item.expression;
-            if (expression.includes(atID)) return false;
-
+        function isCycle(nodeExpr) {
+            let atIDArr = me.getAtIDArr(nodeExpr);
+            for (let atID of atIDArr){
+                let ID = atID.slice(1);
+                let item = me.calcTemplate.compiledCalcItems[ID];
+                if (item.expression.includes(atID)) {
+                    return true;
+                }
+                else {
+                    isCycle(item.expression);
+                }
+            };
+            return false;
         };
+
+        return isCycle(expr);
     },
-    isLegal: function (expr) {
+    isLegal: function (expr) {   // 调用前必须先标准化
         let me = this;
-        let stdExpr = me.standard(expr);
 
         let invalidChars = /[^0-9\u4e00-\u9fa5\+\-\*\/\(\)\.\[\]F%]/g;
-        if (invalidChars.test(stdExpr)){
+        if (invalidChars.test(expr)){
             alert('表达式中含有无效的字符!');
             return false;
         };
 
         let pattCn = new RegExp(/[\u4E00-\u9FA5]+/gi);
-        let arrCn = stdExpr.match(pattCn);
+        let arrCn = expr.match(pattCn);
         let pattBase = new RegExp(/\[[\u4E00-\u9FA5]+\]/gi);
-        let arrBase = stdExpr.match(pattBase);
+        let arrBase = expr.match(pattBase);
         if (arrCn.length != arrBase.length){
-            alert('定额基数必须用“[]”括起来!');
+            for (let cn of arrCn){
+                let tempBase = `[${cn}]`;
+                  if (!arrBase.includes(tempBase)){
+                      alert(`定额基数“${cn}”必须用中括号[]括起来!`);
+                      return false;
+                  }
+            };
+            // 这里要加一个保险。因为上面的 for 循环在“主材费 + [主材费]” 情况下有Bug
+            alert('定额基数必须用中括号[]括起来!');
             return false;
         };
 
         for (let base of arrBase){
             let baseName = base.slice(1, -1);
             if (!rationCalcBases[baseName]){
-                alert('定额基数“' + baseName + '”末定义!');
+                alert('定额基数 [' + baseName + '] 末定义!');
                 return false;
             }
         };
 
         // 行引用检测、行引用转ID引用
-        let arrF = me.getFArr(stdExpr);
+        let arrF = me.getFArr(expr);
         for (let F of arrF){
             let num = F.slice(1);
             if (num > me.calcTemplate.calcItems.length){
@@ -636,140 +647,28 @@ let analyzer = {
             };
             let id = me.getFID(F);
             let fn = new RegExp(F, "g");
-            stdExpr = stdExpr.replace(fn, '@' + id);
+            expr = expr.replace(fn, `@('${id}')`);
         };
 
         // 循环计算
-        if (me.isCycleCalc(stdExpr)){
+        if (me.isCycleCalc(expr)){
             alert('表达式中有循环计算!');
             return false;
         }
-    },
-    analyzeCalcBase: function(expr){
-        // 前提:必须无空格、无特殊符号
-        function getCalcBase(expr){
-            let base = '',
-                iPos1 = -1, iPos2 = -1;
-            for (let i = 0; i < expr.length; i++) {
-                if (expr[i] === '['){
-                    iPos1 = i;
-                }
-                else if (iPos1 != -1 && expr[i]===']'){
-                    iPos2 = i;
-                };
-
-                if (iPos1 != -1 && iPos2 != -1){
-                    base = expr.slice(iPos1, iPos2 + 1);
-                    break;
-                }
-            };
-            return base;
-        };
-        function calcBaseToIDExpr(base){
-            /*// for test. 公路模式,基数到ID
-            let id = -1;
-            if (base == '[人工费]'){
-                id = 111;
-            }
-            else if (base == '[材料费]'){
-                id = 222;
-            }
-            else if (base == '[机械费]'){
-                id = 333;
-            }
-            else id = "错误";
-
-            return "@('" + id + "')";*/
-            let baseValue = base.slice(1, -1);
-            return "base('" + baseValue + "')";
-        };
-
-        while (expr.indexOf('[') > 0) {
-            let base = getCalcBase(expr);
-            let id = calcBaseToIDExpr(base);
-            let baseValue = base.slice(1, -1);   // []会给下面的正则带来干扰,这里去掉
-            var pattBase =new RegExp(baseValue, "g");
-            expr = expr.replace(pattBase, id);
-            expr = expr.replace(/\[base\('/g, "base('");      // [@('       [base('
-            expr = expr.replace(/'\)\]/g, "')");        // ')]
-        };
-
-        return expr;
-    },
-
-    analyzeLineRef: function(expr){
-        let me = this;
-        function isOperator(char){
-            var operator = "+-*/()";
-            return operator.indexOf(char) > -1;
-        };
-        function lineNumToID(lineNum){
-            if (lineNum > me.calcTemplate.calcItems.length){
-                me.success = false;
-                return '越界';
-            }
-            else{
-                let id = me.calcTemplate.calcItems[lineNum - 1].ID;
-                return id;
-            }
-        };
-        // 前提:必须无空格、无特殊符号、标准大写F
-        function getSection(expr){
-            let section = '',
-                iPos1 = -1, iPos2 = -1;
-            for (let i = 0; i < expr.length; i++) {
-                if (expr[i] === 'F'){
-                    iPos1 = i;
-                }
-                else if (iPos1 != -1 && isOperator(expr[i])){
-                    iPos2 = i;
-                }
-                else if (iPos1 != -1 && i == expr.length - 1){
-                    iPos2 = i + 1;
-
-                };
-                if (iPos1 != -1 && iPos2 != -1){
-                    section = expr.slice(iPos1, iPos2);
-                    break;
-                }
-            };
-            return section;
-        };
-        function sectionToIDExpr(section){
-            if (section){
-                let lineNum = section.slice(1);
-                if (isNaN(lineNum)){
-                    me.success = false;
-                    return '错误';      // 这里的返回提示不能加上section,因为会无限循环
-                }
-                else
-                    return "@('" + lineNumToID(lineNum) + "')";
-            }
-            else return '';
-        };
 
-        while (expr.indexOf('F') > 0) {
-            let sec = getSection(expr);
-            let id = sectionToIDExpr(sec);
-            var pattSec =new RegExp(sec, "g");
-            expr = expr.replace(pattSec, id);
-        };
-        return expr;
+        return true;
     },
-
     analyzeUserExpr: function(calcTemplate, calcItem){
         let me = this;
         me.calcTemplate = calcTemplate;
         let expr = calcItem.dispExpr;
-        // 标准化:处理特殊字符、中文符号、大小写
         expr = me.standard(expr);
         calcItem.dispExpr = expr;
-        // 先换掉计算基数
-        expr = me.analyzeCalcBase(expr);
-        // 再换掉行引用
-        expr = me.analyzeLineRef(expr);
-        calcItem.expression = expr;
-        return me.success;
+        if (me.isLegal(expr)){
+            calcItem.expression = expr;
+            return true;
+        }else
+            return false;
     }
 };
 
@@ -1079,10 +978,12 @@ class CalcProgram {
             let nodes = (treeNode.calcType == treeNodeCalcType.ctGatherBillsFees) ? treeNode.children : me.project.Ration.getRationNodes(treeNode);
             let rst = [];
             for (let ft of cpFeeTypes) {
+                let isEstimate = ft.name == '暂估费';
                 let ftObj = {};
                 ftObj.fieldName = ft.type;
                 ftObj.name = ft.name;
                 let buf = 0, btf = 0, btuf = 0, bttf = 0;
+                let bq = calcTools.uiNodeQty(treeNode) ? calcTools.uiNodeQty(treeNode) : 1;
 
                 if (treeNode.calcType == treeNodeCalcType.ctGatherBillsFees){
                     for (let node of nodes) {
@@ -1097,7 +998,6 @@ class CalcProgram {
                 }
                 else if (treeNode.calcType == treeNodeCalcType.ctGatherRationsFees){     // 这里的算法要配合冷姐姐的神图才能看懂^_^
                     let sum_rtf = 0, sum_rttf = 0;
-                    let bq = calcTools.uiNodeQty(treeNode) ? calcTools.uiNodeQty(treeNode) : 1;
                     for (let node of nodes) {
                         let rq = calcTools.uiNodeQty(node) ? calcTools.uiNodeQty(node) : 0;
                         let ruf = 0, rtuf = 0, rtf = 0, rttf = 0;
@@ -1108,33 +1008,46 @@ class CalcProgram {
                             rttf = parseFloat(node.data.feesIndex[ft.type].tenderTotalFee);
                         };
                         if (me.project.property.billsCalcMode === leafBillGetFeeType.rationContent) {
-                            buf = (buf + (ruf * rq / bq).toDecimal(decimalObj.process)).toDecimal(decimalObj.process);
-                            btuf = (btuf + (rtuf * rq / bq).toDecimal(decimalObj.process)).toDecimal(decimalObj.process);
+                            buf = (buf + (ruf * rq / bq).toDecimal(decimalObj.bills.unitFee)).toDecimal(decimalObj.bills.unitFee);
+                            btuf = (btuf + (rtuf * rq / bq).toDecimal(decimalObj.bills.unitFee)).toDecimal(decimalObj.bills.unitFee);
                         };
                         sum_rtf = (sum_rtf + rtf).toDecimal(decimalObj.process);
                         sum_rttf = (sum_rttf + rttf).toDecimal(decimalObj.process);
                     };
-
-                    if (me.project.property.billsCalcMode == leafBillGetFeeType.rationPriceConverse ||
-                        me.project.property.billsCalcMode == leafBillGetFeeType.rationPrice) {
-                        buf = (sum_rtf / bq).toDecimal(decimalObj.process);
-                        btuf = (sum_rttf / bq).toDecimal(decimalObj.process);
-                    };
-                    if (isBaseFeeType(ft.type) ||
-                        (me.project.property.billsCalcMode === leafBillGetFeeType.rationPrice && ft.type == "common")){
+                    if (isEstimate){
                         btf = sum_rtf;
                         bttf = sum_rttf;
-                    }
-                    else{
-                        btf = (buf.toDecimal(decimalObj.bills.unitPrice) * bq).toDecimal(decimalObj.process);
-                        bttf = (btuf.toDecimal(decimalObj.bills.unitPrice) * bq).toDecimal(decimalObj.process);
+                    }else{
+                        if (me.project.property.billsCalcMode == leafBillGetFeeType.rationPriceConverse ||
+                            me.project.property.billsCalcMode == leafBillGetFeeType.rationPrice) {
+                            buf = (sum_rtf / bq).toDecimal(decimalObj.process);
+                            btuf = (sum_rttf / bq).toDecimal(decimalObj.process);
+                        };
+                        if (isBaseFeeType(ft.type) ||
+                            (me.project.property.billsCalcMode === leafBillGetFeeType.rationPrice && ft.type == "common")){
+                            btf = sum_rtf;
+                            bttf = sum_rttf;
+                        }
+                        else{
+                            btf = (buf.toDecimal(decimalObj.bills.unitPrice) * bq).toDecimal(decimalObj.process);
+                            bttf = (btuf.toDecimal(decimalObj.bills.unitPrice) * bq).toDecimal(decimalObj.process);
+                        };
                     };
                 };
 
-                ftObj.unitFee = buf.toDecimal(decimalObj.bills.unitPrice);
                 ftObj.totalFee = btf.toDecimal(decimalObj.bills.totalPrice);
-                ftObj.tenderUnitFee = btuf.toDecimal(decimalObj.bills.unitPrice);
                 ftObj.tenderTotalFee = bttf.toDecimal(decimalObj.bills.totalPrice);
+                if (isEstimate){
+                    if (treeNode.calcType == treeNodeCalcType.ctGatherRationsFees){
+                        ftObj.unitFee = (ftObj.totalFee / bq).toDecimal(decimalObj.bills.unitPrice);
+                        ftObj.tenderUnitFee = (ftObj.tenderTotalFee / bq).toDecimal(decimalObj.bills.unitPrice);
+                    }
+                }
+                else{
+                    ftObj.unitFee = buf.toDecimal(decimalObj.bills.unitPrice);
+                    ftObj.tenderUnitFee = btuf.toDecimal(decimalObj.bills.unitPrice);
+                }
+
                 calcTools.checkFeeField(treeNode, ftObj);
 
                 rst.push(ftObj);
@@ -1413,7 +1326,7 @@ class CalcProgram {
                     }
                     else{
                         if (node.sourceType != ModuleNames.ration_glj) {
-                            rst = (rst + calcTools.getFee(node, 'common.totalFee')).toDecimal(decimalObj.bills.totalPrice);
+                            rst = (rst + calcTools.getFee(node, 'common.totalFee')).toDecimal(decimalObj.decimal("totalPrice", node));
                         };
                     }
                 }

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

@@ -16,8 +16,6 @@ var projectObj = {
         let project = projectObj.project;
         subViewObj.loadComments(node);
         gljOprObj.showDataIfRationSelect(node);
-
-        // CSL.2017.07.25
         if (activeSubSheetIs(subSheetIndex.ssiCalcProgram)) {
             calcProgramObj.showData(node);
         };
@@ -37,6 +35,15 @@ var projectObj = {
         node.data.isSubcontract = true;
         let bname = '分包人工工日';
         alert(bname + ': ' + rationCalcBases[bname](node));*/
+
+/*        let value = projectObj.project.calcProgram.getBeforeTaxTotalFee([node]);
+        alert('前四项累计值排除当前选中项:' + value);*/
+
+/*        let t = projectObj.project.calcProgram.compiledTemplates[node.data.programID];
+        let c = t.calcItems[7];
+        c.dispExpr = '[定额基价人工费] + [定额基价材料费]  + F6 + [主材费]';
+        let rst = analyzer.analyzeUserExpr(t, c);
+        alert(`${rst}: ` + JSON.stringify(c));*/
     },
     refreshBaseActn: function (tree) {
         let setButtonValid = function (valid, btn) {
@@ -426,13 +433,6 @@ var projectObj = {
                 const autoHeight = that.project.property.displaySetting !== undefined ?
                     that.project.property.displaySetting.autoHeight : false;
                 that.project.projSetting.mainGridSetting.cols.forEach(function (col) {
-                    // for test.  后端没有绑定,暂时写死用于测试。
-/*                    if (col.data.field == '' && col.head.titleNames[0] == "取费专业") {
-                        col.data.field = 'programID';
-                        col.data.getText = 'getText.calcProgramName';
-                        col.data.cellType = 'cellType.calcProgramName';
-                    };*/
-
                     col.data.splitFields = col.data.field.split('.');
                     if (col.data.getText && Object.prototype.toString.apply(col.data.getText) === "[object String]") {
                         col.data.getText = MainTreeCol.getEvent(col.data.getText);