Quellcode durchsuchen

Merge branch 'master' of http://192.168.1.12:3000/SmartCost/ConstructionCost

TonyKang vor 7 Jahren
Ursprung
Commit
652238f28a

+ 87 - 62
public/calc_util.js

@@ -1,14 +1,14 @@
 /**
  * Created by Tony on 2017/6/21.
+ * Modified by CSL, 2017-08-01
  */
+
 let executeObj = {
-    calculation : null,
     ration: null,
-    feeRate: null,
     at: function(ID) {
         let me = executeObj,
             rst = 0;
-        rst = me.calculation.compileAssistantObj[ID].unitFee;
+        rst = me.ration.data.calcTemplate.compiledTemplate[ID].unitFee;
         rst = parseFloat(rst);
         return rst;
     },
@@ -31,31 +31,26 @@ let executeObj = {
             rst = tmpSum;
         };
         return rst;
-    },
-    fee: function(feeID) {
-        let me = executeObj, rst = 0;
-        if (me.compiledFeeRateFile["fee_" + feeID]) rst = me.compiledFeeRateFile["fee_" + feeID].rate;
-        return rst;
-    },
-    factor: function(factorCode) {
+    }
+/*    factor: function(factorID) {
         let me = executeObj;
-        let rst = 0.89; //暂时固定输出,测试用
+        let rst = 7.77;
         return rst;
-    }
+    }*/
 };
 
 class Calculation {
-    init(calcTemplate, feeRate){
+/*    init(template, feeRates){
         let me = this;
-        me.calcTemplate = calcTemplate;
-        me.feeRate = feeRate;
+        me.template = template;
+        me.feeRates = feeRates;
         me.hasCompiled = false;
-    };
+    };*/
 
-    compile(){
+    compile(template, feeRates, labourCoes){
         let me = this;
-        me.hasCompiled = false;
-        me.errs = [];
+        template.hasCompiled = false;
+        template.errs = [];
 
         let private_extract_ID = function(str, idx){
             let rst = '', lBracket = 0, rBracket = 0, firstIdx = idx, lastIdx = 0;
@@ -86,100 +81,130 @@ class Calculation {
             while (idx >= 0) {
                 let ID = private_extract_ID(item.expression, idx);
                 if (ID.length > 0) {
-                    let subItem = me.compileAssistantObj[ID];
+                    let subItem = template.compiledTemplate[ID];
                     if (subItem) {
                         if (subItem.ID !== item.ID) {
-                            private_parse_ref(subItem, me.compileAssistantObj[ID + "_idx"]);
+                            private_parse_ref(subItem, template.compiledTemplate[ID + "_idx"]);
                         } else {
-                            me.errs.push("There exists the self refer ID: " + ID);
+                            template.errs.push("There exists the self refer ID: " + ID);
                         }
                     } else {
-                        me.errs.push("There exists the invalid ID by which could not find the item: " + ID);
+                        template.errs.push("There exists the invalid ID by which could not find the item: " + ID);
                         console.log('invalid ID: ' + ID);
                     }
                 }
                 idx = item.expression.indexOf('@(', idx + ID.length + 3);
             }
-            if (me.calcTemplate.compiledSeq.indexOf(itemIdx) < 0) {
-                me.calcTemplate.compiledSeq.push(itemIdx);
+            if (template.compiledSeq.indexOf(itemIdx) < 0) {
+                template.compiledSeq.push(itemIdx);
             }
         };
         let private_setup_seq = function(item, itemIdx){
-            if (me.calcTemplate.compiledSeq.indexOf(itemIdx) < 0) {
+            if (template.compiledSeq.indexOf(itemIdx) < 0) {
                 private_parse_ref(item, itemIdx);
             }
         };
         let private_compile_items = function() {
-            for (let idx of me.calcTemplate.compiledSeq) {
-                let item = me.calcTemplate.calcItems[idx];
+            for (let idx of template.compiledSeq) {
+                let item = template.calcItems[idx];
                 item.compiledExpr = item.expression.split('@(').join('$CE.at(');
                 item.compiledExpr = item.compiledExpr.split('base(').join('$CE.base(');
-                item.compiledExpr = item.compiledExpr.split('fee(').join('$CE.fee(');
-                item.compiledExpr = item.compiledExpr.split('factor(').join('$CE.factor(');
+                //item.compiledExpr = item.compiledExpr.split('rate(').join('$CE.rate(');
+                //item.compiledExpr = item.compiledExpr.split('factor(').join('$CE.factor(');
+                if (item.labourCoeID){
+                    let lc = me.compiledLabourCoes["LabourCoe_" + item.labourCoeID].coe;
+                    item.dispExpr = item.dispExpr.replace(/L/gi, lc.toString());
+                    item.compiledExpr = item.compiledExpr.replace(/L/gi, lc.toString());
+                }
             }
         };
-        let private_comile_feeFile = function() {
-            if (me.feeRate) {
-                me.compiledFee = {};
-                for (let fee of me.feeRate) {
-                    me.compiledFee["fee_" + fee.ID] = fee;
+        let private_compile_feeFile = function() {
+            if (feeRates) {
+                me.compiledFeeRate = {};
+                for (let rate of feeRates) {
+                    me.compiledFeeRate["feeRate_" + rate.ID] = rate;
+                }
+            }
+        };
+        let private_compile_labourCoeFile = function() {
+            if (labourCoes) {
+                me.compiledLabourCoes = {};
+                for (let coe of labourCoes) {
+                    me.compiledLabourCoes["LabourCoe_" + coe.ID] = coe;
                 }
             }
         };
 
-        if (me.calcTemplate && me.calcTemplate.calcItems && me.calcTemplate.calcItems.length > 0) {
-            me.calcTemplate.compiledSeq = [];
-            me.compileAssistantObj = {};
+        if (template && template.calcItems && template.calcItems.length > 0) {
+            template.compiledSeq = [];
+            template.compiledTemplate = {};
             //1. first round -> prepare
-            private_comile_feeFile();
-            for (let i = 0; i < me.calcTemplate.calcItems.length; i++) {
-                let item = me.calcTemplate.calcItems[i];
-                me.compileAssistantObj[item.ID] = item;
-                me.compileAssistantObj[item.ID + "_idx"] = i;
+            private_compile_feeFile();
+            private_compile_labourCoeFile();
+            for (let i = 0; i < template.calcItems.length; i++) {
+                let item = template.calcItems[i];
+                template.compiledTemplate[item.ID] = item;
+                template.compiledTemplate[item.ID + "_idx"] = i;
             }
             //2. second round -> go!
-            for (let i = 0; i < me.calcTemplate.calcItems.length; i++) {
-                private_setup_seq(me.calcTemplate.calcItems[i], i);
+            for (let i = 0; i < template.calcItems.length; i++) {
+                private_setup_seq(template.calcItems[i], i);
             }
-            if (me.errs.length == 0) {
+            if (template.errs.length == 0) {
                 private_compile_items();
-                if (me.errs.length == 0) me.hasCompiled = true;
+                template.hasCompiled = true;
             } else {
-                console.log('errors: ' + me.errs.toString());
+                console.log('errors: ' + template.errs.toString());
             }
         }
     };
+
     calculate($RATION){         // 参数$RATION也可以是清单
         let me = this;
-        if ($RATION && me.hasCompiled) {
+        let template = $RATION.data.calcTemplate;
+
+        if ($RATION && template.hasCompiled) {
             let $CE = executeObj;
             $CE.ration = $RATION;
-            $CE.calculation = me;
-            $CE.feeRate = me.feeRate;
-            $CE.compiledFeeRateFile = me.compiledFee;
 
             if (!$RATION.fees) {
                 $RATION.fees = [];
                 $RATION.feesIndex = {};
             };
 
-            for (let idx of me.calcTemplate.compiledSeq) {
-                let calcItem = me.calcTemplate.calcItems[idx];
+            for (let idx of template.compiledSeq) {
+                let calcItem = template.calcItems[idx];
 
-                // 这两项用于界面显示。
-                calcItem.unitFee = eval(calcItem.compiledExpr);   // AAAAA 如果eval()对清单树有影响,就换成小麦的Expression对象再试
-                calcItem.totalFee = calcItem.unitFee * 3;     // AAAAA 测试值,因目前定额无数量(保存不上) $RATION.data.Quantity
+                let feeRate = 100;    // 100%
+                // 下面三项用于界面显示。
+                if (calcItem.feeRateID) {
+                    feeRate = me.compiledFeeRate["feeRate_" + calcItem.feeRateID].rate;
+                    calcItem.feeRate = feeRate;
+                };
+                calcItem.unitFee = eval(calcItem.compiledExpr) * feeRate * 0.01;   // 如果eval()对清单树有影响,就换成小麦的Expression对象再试
+                calcItem.totalFee = calcItem.unitFee * 3;     // AAAAAA 测试值,因目前定额无数量(保存不上) $RATION.data.Quantity
 
                 // 费用同步到定额
                 // 引入小麦的字段检测后,快速切换定额出现计算卡顿现象,过多的循环造成。这里把她的代码拆出来,减少微循环。
-                if (!$RATION.feesIndex[calcItem.type]){
-                    calcFees.addFee($RATION, calcItem.type);
-                };
-                $RATION.feesIndex[calcItem.type].unitFee = calcItem.unitFee;
-                $RATION.feesIndex[calcItem.type].totalFee = calcItem.totalFee;
+                if (!$RATION.feesIndex[calcItem.fieldName]){
+                    let fee = {
+                        'fieldName': calcItem.fieldName,
+                        'unitFee': calcItem.unitFee,
+                        'totalFee': calcItem.totalFee,
+                        'tenderUnitFee': 0,
+                        'tenderTotalFee': 0
+                    };
+                    $RATION.fees.push(fee);
+                    $RATION.feesIndex[calcItem.fieldName] = fee;
+                }
+                else{
+                    $RATION.feesIndex[calcItem.fieldName].unitFee = calcItem.unitFee;
+                    $RATION.feesIndex[calcItem.fieldName].totalFee = calcItem.totalFee;
+                }
             }
         }
     }
 }
 
+
 //module.exports = new calculation();

+ 25 - 0
public/web/sheet/sheet_data_helper.js

@@ -97,7 +97,32 @@ var SheetDataHelper = {
             sheet.setStyle(-1, iCol, SheetDataHelper.getSheetCellStyle(colSetting));
             datas.forEach(function (data, iRow) {
                 var cell = sheet.getCell(iRow, iCol, GC.Spread.Sheets.SheetArea.viewport);
+                var getFieldText2 = function () {
+                    var fields = colSetting.data.field.split('.'), iField, value = data;
+                    for (iField = 0; iField < fields.length; iField++) {
+                        if (value[fields[iField]]) {
+                            value = value[fields[iField]];
+                        } else {
+                            return '';
+                        }
+                    }
+                    return value;
+                };
                 cell.value(data[colSetting.data.field]);
+                if (colSetting.data.getText) {
+                    cell.value(colSetting.data.getText(data));
+                } else {
+                    cell.value(getFieldText2());
+                }
+                if (colSetting.readOnly) {
+                    if (Object.prototype.toString.apply(colSetting.readOnly) === "[object Function]") {
+                        cell.locked(colSetting.readOnly(node));
+                    } else {
+                        cell.locked(true);
+                    }
+                } else {
+                    cell.locked(false);
+                }
             });
         });
 

+ 3 - 0
public/web/tree_sheet/tree_sheet_helper.js

@@ -11,6 +11,9 @@ var TREE_SHEET_HELPER = {
         style.hAlign = setting.data.hAlign;
         style.vAlign = setting.data.vAlign;
         style.wordWrap = setting.data.wordWrap;
+        if (setting.data.formatter) {
+            style.formatter = setting.data.formatter;
+        }
         return style;
     },
     loadSheetHeader: function (setting, sheet) {

+ 14 - 9
test/tmp_data/bills_grid_setting.js

@@ -316,7 +316,7 @@ var BillsGridSetting ={
         },
         {
             "width":80,
-            "readOnly":false,
+            "readOnly":'readOnly.billsParent',
             "head":{
                 "titleNames":[
                     "工程量"
@@ -341,7 +341,8 @@ var BillsGridSetting ={
                 "field":"quantity",
                 "vAlign":1,
                 "hAlign":2,
-                "font":"Arial"
+                "font":"Arial",
+                "digit": 'common.quantity'
             }
         },
         {
@@ -376,7 +377,7 @@ var BillsGridSetting ={
         },
         {
             "width":120,
-            "readOnly":'readOnly.volumePrice',
+            "readOnly":'readOnly.forCalcBase',
             "head":{
                 "titleNames":[
                     "计算基数"
@@ -436,7 +437,7 @@ var BillsGridSetting ={
         },
         {
             "width":80,
-            "readOnly":false,
+            "readOnly":'readOnly.ration',
             "head":{
                 "titleNames":[
                     "综合单价"
@@ -461,12 +462,13 @@ var BillsGridSetting ={
                 "field":"feesIndex.common.unitFee",
                 "vAlign":1,
                 "hAlign":2,
-                "font":"Arial"
+                "font":"Arial",
+                "digit": 'common.unitFee'
             }
         },
         {
             "width":80,
-            "readOnly":false,
+            "readOnly":'readOnly.ration',
             "head":{
                 "titleNames":[
                     "综合合价"
@@ -491,7 +493,8 @@ var BillsGridSetting ={
                 "field":"feesIndex.common.totalFee",
                 "vAlign":1,
                 "hAlign":2,
-                "font":"Arial"
+                "font":"Arial",
+                "digit": 'common.totalFee'
             }
         },
         {
@@ -521,7 +524,8 @@ var BillsGridSetting ={
                 "field":"feesIndex.zangu.unitFee",
                 "vAlign":1,
                 "hAlign":2,
-                "font":"Arial"
+                "font":"Arial",
+                "digit": 'common.unitFee'
             }
         },
         {
@@ -551,7 +555,8 @@ var BillsGridSetting ={
                 "field":"feesIndex.zangu.totalFee",
                 "vAlign":1,
                 "hAlign":2,
-                "font":"Arial"
+                "font":"Arial",
+                "digit": 'common.totalFee'
             }
         },
         {

+ 1 - 1
web/building_saas/css/main.css

@@ -234,7 +234,7 @@ body {
     }
 }
 .bottom-content .tab-content .main-data-bottom{
-    height: 200px;
+    height: 400px;
     overflow: auto;
 }
 .bottom-content .tab-content .ovf-hidden{

+ 1 - 0
web/building_saas/main/html/main.html

@@ -525,6 +525,7 @@
     <script type="text/javascript" src="/web/building_saas/main/js/views/std_ration_lib.js"></script>
     <script type="text/javascript" src="/web/building_saas/main/js/models/quantity_detail.js"></script>
     <script type="text/javascript" src="/web/building_saas/main/js/views/glj_view_contextMenu.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/views/calc_program_view.js"></script>
     <!-- reports -->
     <script type="text/javascript" src="/public/web/treeDataHelper.js"></script>
     <script type="text/javascript" src="/public/web/ztree_common.js"></script>

+ 6 - 7
web/building_saas/main/js/calc/bills_calc.js

@@ -220,7 +220,6 @@ class BillsCalcHelper {
     constructor (project, CalcFlag) {
         this.project = project;
         this.CalcFlag = CalcFlag;
-        this.digit = 2;
         switch (this.CalcFlag) {
             case rationContent:
                 this.calcField = rationContentCalcFields;
@@ -250,7 +249,7 @@ class BillsCalcHelper {
     };
     calcRationLeaf (node, fields) {
         nodeCalcObj.node = node;
-        nodeCalcObj.digit = this.digit;
+        nodeCalcObj.digit = this.project.Decimal.unitFee;
         calcFees.checkFields(node.data, fields);
         let nodeCalc = nodeCalcObj, virData= null;
 
@@ -266,10 +265,10 @@ class BillsCalcHelper {
             nodeCalcObj.field = field;
             switch (field.unitFeeFlag) {
                 case rationContentUnitFeeFlag:
-                    node.data.feesIndex[field.type].unitFee = nodeCalcObj.rationContentUnitFee().toDecimal(this.digit);
+                    node.data.feesIndex[field.type].unitFee = nodeCalcObj.rationContentUnitFee().toDecimal(this.project.Decimal.common.unitFee);
                     break;
                 case averageQtyUnitFeeFlag:
-                    node.data.feesIndex[field.type].unitFee = nodeCalcObj.averageQty().toDecimal(this.digit);
+                    node.data.feesIndex[field.type].unitFee = nodeCalcObj.averageQty().toDecimal(this.project.Decimal.common.unitFee);
                     break;
                  case billsPriceUnitFeeFlag:
                      node.data.feesIndex[field.type].unitFee = virData[field.type];
@@ -279,10 +278,10 @@ class BillsCalcHelper {
             }
             switch (field.totalFeeFlag) {
                 case sumTotalFeeFlag:
-                    node.data.feesIndex[field.type].totalFee = nodeCalcObj.sumTotalFee().toDecimal(this.digit);
+                    node.data.feesIndex[field.type].totalFee = nodeCalcObj.sumTotalFee().toDecimal(this.project.Decimal.common.totalFee);
                     break;
                 case totalFeeFlag:
-                    node.data.feesIndex[field.type].totalFee = nodeCalcObj.totalFee().toDecimal(this.digit);
+                    node.data.feesIndex[field.type].totalFee = nodeCalcObj.totalFee().toDecimal(this.project.Decimal.common.totalFee);
                     break;
                 default:
                     node.data.feesIndex[field.type].totalFee = 0;
@@ -297,7 +296,7 @@ class BillsCalcHelper {
         calcFees.checkFields(node.data, fields);
         for (let field of fields) {
             nodeCalcObj.field = field;
-            node.data.feesIndex[field.type].totalFee = nodeCalcObj.sumTotalFee().toDecimal(this.digit);
+            node.data.feesIndex[field.type].totalFee = nodeCalcObj.sumTotalFee().toDecimal(this.project.Decimal.common.totalFee);
         }
     };
     calcNodes (nodes) {

+ 2 - 2
web/building_saas/main/js/calc/calc_fees.js

@@ -83,9 +83,9 @@ let calcFees = {
                 }
             } else {
                 if (i == fields.length - 1) {
-                    valueField[fields[i]] = {};
-                } else {
                     valueField[fields[i]] = value;
+                } else {
+                    valueField[fields[i]] = {};
                 };
             }
         }

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

@@ -178,7 +178,6 @@ var Bills = {
             return this.tree.delete(node);
         };
 
-
         bills.prototype.upMoveBills = function (node) {
             var upMoveData = node.getUpMoveData();
             project.pushNow('upMoveBills', this.getSourceType(), tools.coverseTreeUpdateData(upMoveData, this.project.ID()));
@@ -202,7 +201,29 @@ var Bills = {
             project.pushNow('downLevelBills', [this.getSourceType()], [tools.coverseTreeUpdateData(downLevelData, this.project.ID())]);
 
             return node.downLevel();
-        }
+        };
+
+        bills.prototype.updateField = function (node, field, newValue) {
+            calcFees.setFee(node.data, field, newValue);
+            let updateData = [];
+            let data = {'ID': node.getID(), 'projectID': this.project.ID()};
+            if (field === 'quantity') {
+                data[field] = newValue;
+                // to do Calculate
+                if (node.data.fees) {
+                    data.fees = node.data.fees;
+                }
+            } else if (field === 'feesIndex.common.unitFee') {
+                // to do Calculate
+                if (node.data.fees) {
+                    data.fees = node.data.fees;
+                }
+            } else {
+                data[field] = newValue;
+            }
+            updateData.push({'updateType': 'ut_update', 'updateData': data});
+            this.project.pushNow('updateBills', this.getSourceType(), updateData);
+        };
 
         return new bills(project);
     }

+ 23 - 1
web/building_saas/main/js/models/project.js

@@ -74,6 +74,13 @@ var PROJECT = {
             this.quantity_detail = quantity_detail.createNew(this);
             this.FeeRate = FeeRate.createNew(this);
             this.VolumePrice = VolumePrice.createNew(this);
+            this.Decimal = {
+                common: {
+                    quantity: 3,
+                    unitFee: 2,
+                    totalFee: 2
+                }
+            };
 
             this.masterField = {ration: 'billsItemID', volumePrice: 'billsItemID'};
         };
@@ -90,7 +97,22 @@ var PROJECT = {
 
         project.prototype.projCounter = function () {
             return tools.projCounter;
-        }
+        };
+        project.prototype.getDecimal = function (fullName) {
+            let names = fullName.split('.'), decimal = this.Decimal;
+            for (let name of names) {
+                if (decimal[name]) {
+                    decimal = decimal[name];
+                } else {
+                    return null;
+                }
+            }
+            if (Object.prototype.toString.apply(decimal) === '[object Number]') {
+                return decimal;
+            } else {
+                return null;
+            }
+        };
 
         project.prototype.loadMainTree = function () {
             var that = this;

+ 22 - 0
web/building_saas/main/js/models/ration.js

@@ -229,6 +229,28 @@ var Ration = {
             ration2.serialNo = preSerialNo;
         };
 
+        ration.prototype.updateField = function (ration, field, newValue) {
+            calcFees.setFee(ration, field, newValue);
+            let updateData = [];
+            let data = {'ID': ration.ID, 'projectID': this.project.ID()};
+            if (field === 'quantity') {
+                data[field] = newValue;
+                // to do Calculate
+                if (ration.fees) {
+                    data.fees = ration.fees;
+                }
+            } else if (field === 'feesIndex.common.unitFee') {
+                // to do Calculate
+                if (ration.fees) {
+                    data.fees = ration.fees;
+                }
+            } else {
+                data[field] = newValue;
+            }
+            updateData.push({'updateType': 'ut_update', 'updateData': data});
+            this.project.pushNow('updateBills', this.getSourceType(), updateData);
+        };
+
         return new ration(project);
     }
 };

+ 344 - 201
web/building_saas/main/js/models/ration_program.js

@@ -2,7 +2,207 @@
  * Created by CSL on 2017-07-19.
  */
 
-let calcFeeRate = [
+// dispExpr: F8*(L-1); expression: "@('8') * (L-1)";
+// 说明:F后跟行号,L替换人工系数值,@后跟ID。用到L的规则必须有labourCoeID属性(反过来不要求),
+// 用到费率的规则必须有feeRateID属性,当有该属性时,会自动显示费率值。
+let calcTemplates = [
+    {
+        ID: 1,
+        name: "重庆2015",
+        calcItems: [
+            {
+                ID: "1",
+                code: "1",
+                name: "基价直接工程费",
+                fieldName: "baseDirect",
+                dispExpr: "F2+F5+F6+F10",
+                expression: "@('2') + @('5') + @('6') + @('10')",
+                compiledExpr: "",
+                statement: "基价人工费+基价材料费+基价机械费+未计价材料费"
+            },
+            {
+                ID: "2",
+                code: "1.1",
+                name: "基价人工费",
+                fieldName: "baseLabour",
+                dispExpr: "F3+F4",
+                expression: "@('3') + @('4')",
+                compiledExpr: "",
+                statement: "定额基价人工费+定额人工单价(基价)调整"
+            },
+            {
+                ID: "3",
+                code: "1.1.1",
+                name: "定额基价人工费",
+                fieldName: "rationBaseLabour",
+                dispExpr: "[定额基价人工费]",
+                expression: "base('定额基价人工费').toFixed(2)",
+                compiledExpr: "",
+                statement: "定额基价人工费"
+            },
+            {
+                ID: "4",
+                code: "1.1.2",
+                name: "定额人工单价(基价)调整",
+                fieldName: "rationLabourFixed",
+                dispExpr: "F3*(L-1)",
+                expression: "@('3') * (L-1)",
+                labourCoeID: 2,
+                compiledExpr: "",
+                statement: "定额基价人工费*[定额人工单价(基价)调整系数-1]",
+                memo: "渝建发(2013)51"
+            },
+            {
+                ID: "5",
+                code: "1.2",
+                name: "基价材料费",
+                fieldName: "baseMaterial",
+                dispExpr: "[定额基价材料费]",
+                expression: "base('定额基价材料费')",
+                compiledExpr: "",
+                statement: "定额基价材料费"
+            },
+            {
+                ID: "6",
+                code: "1.3",
+                name: "基价机械费",
+                fieldName: "baseMachine",
+                dispExpr: "F7+F9",
+                expression: "@('7') + @('9')",
+                compiledExpr: "",
+                statement: "定额基价机械费+定额机上人工单价(基价)调整"
+            },
+            {
+                ID: "7",
+                code: "1.3.1",
+                name: "定额基价机械费",
+                fieldName: "rationBaseMachine",
+                dispExpr: "[定额基价机械费]",
+                expression: "base('定额基价机械费')",
+                compiledExpr: "",
+                statement: "定额基价机械费"
+            },
+            {
+                ID: "8",
+                code: "1.3.1.1",
+                name: "其中:定额基价机上人工费",
+                fieldName: "rationBaseMachineLabour",
+                dispExpr: "[定额基价机上人工费]",
+                expression: "base('定额基价机上人工费')",
+                compiledExpr: "",
+                statement: "定额基价机上人工费"
+            },
+            {
+                ID: "9",
+                code: "1.3.2",
+                name: "定额机上人工单价(基价)调整",
+                fieldName: "rationBaseMachineLabourFixed",
+                dispExpr: "F8*(L-1)",
+                expression: "@('8') * (L-1)",
+                labourCoeID: 11,
+                compiledExpr: "",
+                statement: "定额基价机上人工费*[定额机上人工单价(基价)调整系数-1]"
+            },
+            {
+                ID: "10",
+                code: "1.4",
+                name: "未计价材料费",
+                fieldName: "unPriceMaterial",
+                dispExpr: "[主材费]+[设备费]",
+                expression: "base('主材费') + base('设备费')",
+                compiledExpr: "",
+                statement: "主材费+设备费"
+            },
+            {
+                ID: "11",
+                code: "2",
+                name: "企业管理费",
+                fieldName: "manageFee",
+                dispExpr: "F3",
+                feeRateID: 3,
+                expression: "@('3')",
+                compiledExpr: "",
+                statement: "定额基价人工费",
+                memo: "渝建发[2014]27号"
+            },
+            {
+                ID: "12",
+                code: "3",
+                name: "利润",
+                fieldName: "profit",
+                dispExpr: "F3",
+                feeRateID: 4,
+                expression: "@('3')",
+                compiledExpr: "",
+                statement: "定额基价人工费"
+            },
+            {
+                ID: "13",
+                code: "4",
+                name: "风险因素",
+                fieldName: "risk",
+                dispExpr: "F3",
+                feeRateID: 5,
+                expression: "@('3')",
+                compiledExpr: "",
+                statement: "定额基价人工费",
+                memo: "同定额包干费"
+            },
+            {
+                ID: "14",
+                code: "5",
+                name: "人材机价差",
+                fieldName: "lmmDiff",
+                dispExpr: "F15+F16+F17",
+                expression: "@('15') + @('16') + @('17')",
+                compiledExpr: "",
+                statement: "人工费价差+材料费价差+机械费价差"
+            },
+            {
+                ID: "15",
+                code: "5.1",
+                name: "人工费价差",
+                fieldName: "labourDiff",
+                dispExpr: "[人工费价差]",
+                expression: "base('市场价格人工费') - base('定额基价人工费(调整后)')",
+                compiledExpr: "",
+                statement: "市场价格人工费-调整后的定额人工费(基价)"
+            },
+            {
+                ID: "16",
+                code: "5.2",
+                name: "材料费价差",
+                fieldName: "materialDiff",
+                dispExpr: "[材料费价差]",
+                expression: "base('市场价格材料费') - base('定额基价材料费(调整后)')",
+                compiledExpr: "",
+                statement: "市场价格材料费-定额基价材料费"
+            },
+            {
+                ID: "17",
+                code: "5.3",
+                name: "机械费价差",
+                fieldName: "machineDiff",
+                dispExpr: "[机械费价差]",
+                expression: "base('市场价格机械费') - base('定额基价机械费(调整后)')",
+                compiledExpr: "",
+                statement: "市场价格机械费-调整后的定额基价机械费(基价)"
+            },
+            {
+                ID: "18",
+                code: "6",
+                name: "综合单价",
+                fieldName: "common",
+                dispExpr: "F1+F11+F12+F13+F14",
+                expression: "@('1') + @('11') + @('12') + @('13') + @('14')",
+                compiledExpr: "",
+                statement: "基价直接工程费+企业管理费+利润+风险因素+人材机价差"
+            }
+        ]
+    }
+];
+
+let calcFeeRates = [
     {
         "ID" : 1,
         "ParentID" : null,
@@ -215,211 +415,154 @@ let calcFeeRate = [
     }
 ];
 
-let calcTemplate = {
-    calType: 3,
-    calTypeName: "测试用_重庆",
-    compiledSeq: [],
-    calcItems: [
-        {
-            ID: "1",
-            code: "1",
-            name: "基价直接工程费",
-            type: "baseDirect",
-            dispExpr: "F2+F5+F6+F10",
-            expression: "@('2') + @('5') + @('6') + @('10')",
-            compiledExpr: "",
-            statement: "基价人工费+基价材料费+基价机械费+未计价材料费"
-        },
-        {
-            ID: "2",
-            code: "1.1",
-            name: "基价人工费",
-            type: "baseLabour",
-            dispExpr: "F3+F4",
-            expression: "@('3') + @('4')",
-            compiledExpr: "",
-            statement: "定额基价人工费+定额人工单价(基价)调整"
-        },
-        {
-            ID: "3",
-            code: "1.1.1",
-            name: "定额基价人工费",
-            type: "rationBaseLabour",
-            dispExpr: "[定额基价人工费]",
-            expression: "base('定额基价人工费').toFixed(2)",
-            compiledExpr: "",
-            statement: "定额基价人工费"
-        },
-        {
-            ID: "4",
-            code: "1.1.2",
-            name: "定额人工单价(基价)调整",
-            type: "rationLabourFixed",
-            dispExpr: "F3*(1.89-1)",
-            expression: "@('3') * (1.89-1)",
-            compiledExpr: "",
-            statement: "定额基价人工费*[定额人工单价(基价)调整系数-1]",
-            memo: "渝建发(2013)51"
-        },
-        {
-            ID: "5",
-            code: "1.2",
-            name: "基价材料费",
-            type: "baseMaterial",
-            dispExpr: "[定额基价材料费]",
-            expression: "base('定额基价材料费')",
-            compiledExpr: "",
-            statement: "定额基价材料费"
-        },
-        {
-            ID: "6",
-            code: "1.3",
-            name: "基价机械费",
-            type: "baseMachine",
-            dispExpr: "F7+F9",
-            expression: "@('7') + @('9')",
-            compiledExpr: "",
-            statement: "定额基价机械费+定额机上人工单价(基价)调整"
-        },
-        {
-            ID: "7",
-            code: "1.3.1",
-            name: "定额基价机械费",
-            type: "rationBaseMachine",
-            dispExpr: "[定额基价机械费]",
-            expression: "base('定额基价机械费')",
-            compiledExpr: "",
-            statement: "定额基价机械费"
-        },
-        {
-            ID: "8",
-            code: "1.3.1.1",
-            name: "其中:定额基价机上人工费",
-            type: "rationBaseMachineLabour",
-            dispExpr: "[定额基价机上人工费]",
-            expression: "base('定额基价机上人工费')",
-            compiledExpr: "",
-            statement: "定额基价机上人工费"
-        },
-        {
-            ID: "9",
-            code: "1.3.2",
-            name: "定额机上人工单价(基价)调整",
-            type: "rationBaseMachineLabourFixed",
-            dispExpr: "F8*(1.89-1)",
-            expression: "@('8') * (1.89-1)",
-            compiledExpr: "",
-            statement: "定额基价机上人工费*[定额机上人工单价(基价)调整系数-1]"
-        },
-        {
-            ID: "10",
-            code: "1.4",
-            name: "未计价材料费",
-            type: "unPriceMaterial",
-            dispExpr: "[主材费]+[设备费]",
-            expression: "base('主材费') + base('设备费')",
-            compiledExpr: "",
-            statement: "主材费+设备费"
-        },
-        {
-            ID: "11",
-            code: "2",
-            name: "企业管理费",
-            type: "manageFee",
-            dispExpr: "F3",
-            feeRate: 8.21,
-            expression: "@('3')*8.21 / 100",
-            compiledExpr: "",
-            statement: "定额基价人工费",
-            memo: "渝建发[2014]27号"
-        },
-        {
-            ID: "12",
-            code: "3",
-            name: "利润",
-            type: "profit",
-            dispExpr: "F3",
-            feeRate: 6.5,
-            expression: "@('3')*6.5 / 100",
-            compiledExpr: "",
-            statement: "定额基价人工费"
-        },
-        {
-            ID: "13",
-            code: "4",
-            name: "风险因素",
-            type: "risk",
-            dispExpr: "F3",
-            feeRate: 3,
-            expression: "@('3')*3 / 100",
-            compiledExpr: "",
-            statement: "定额基价人工费",
-            memo: "同定额包干费"
-        },
-        {
-            ID: "14",
-            code: "5",
-            name: "人材机价差",
-            type: "lmmDiff",
-            dispExpr: "F15+F16+F17",
-            expression: "@('15') + @('16') + @('17')",
-            compiledExpr: "",
-            statement: "人工费价差+材料费价差+机械费价差"
-        },
-        {
-            ID: "15",
-            code: "5.1",
-            name: "人工费价差",
-            type: "labourDiff",
-            dispExpr: "[人工费价差]",
-            expression: "base('市场价格人工费') - base('定额基价人工费(调整后)')",
-            compiledExpr: "",
-            statement: "市场价格人工费-调整后的定额人工费(基价)"
-        },
-        {
-            ID: "16",
-            code: "5.2",
-            name: "材料费价差",
-            type: "materialDiff",
-            dispExpr: "[材料费价差]",
-            expression: "base('市场价格材料费') - base('定额基价材料费(调整后)')",
-            compiledExpr: "",
-            statement: "市场价格材料费-定额基价材料费"
-        },
-        {
-            ID: "17",
-            code: "5.3",
-            name: "机械费价差",
-            type: "machineDiff",
-            dispExpr: "[机械费价差]",
-            expression: "base('市场价格机械费') - base('定额基价机械费(调整后)')",
-            compiledExpr: "",
-            statement: "市场价格机械费-调整后的定额基价机械费(基价)"
-        },
-        {
-            ID: "18",
-            code: "6",
-            name: "综合单价",
-            type: "common",
-            dispExpr: "F1+F11+F12+F13+F14",
-            expression: "@('1') + @('11') + @('12') + @('13') + @('14')",
-            compiledExpr: "",
-            statement: "基价直接工程费+企业管理费+利润+风险因素+人材机价差"
-        }
-    ]
-};
+let calcLabourCoes = [
+    {
+        "ID" : 1,
+        "ParentID" : null,
+        "name" : "2006概算定额",
+        "coe" : null
+    },
+    {
+        "ID" : 2,
+        "ParentID" : 1,
+        "name" : "土石方人工",
+        "coe" : 2.94
+    },
+    {
+        "ID" : 3,
+        "ParentID" : 1,
+        "name" : "建筑、市政、维修人工",
+        "coe" : 2.84
+    },
+    {
+        "ID" : 4,
+        "ParentID" : 1,
+        "name" : "装饰人工",
+        "coe" : 1
+    },
+    {
+        "ID" : 5,
+        "ParentID" : 1,
+        "name" : "安装、机械人工",
+        "coe" :2.58
+    },
+    {
+        "ID" : 6,
+        "ParentID" : 1,
+        "name" : "仿古、园林绿化人工",
+        "coe" :1
+    },
+    {
+        "ID" : 7,
+        "ParentID" : 1,
+        "name" : "盾构用工",
+        "coe" :1
+    },
+    {
+        "ID" : 8,
+        "ParentID" : null,
+        "name" : "2008计价定额",
+        "coe" :null
+    },
+    {
+        "ID" : 9,
+        "ParentID" : 8,
+        "name" : "土石方人工",
+        "coe" : 2.41
+    },
+    {
+        "ID" : 10,
+        "ParentID" : 8,
+        "name" : "建筑、市政、维修人工",
+        "coe" : 2.48
+    },
+    {
+        "ID" : 11,
+        "ParentID" : 8,
+        "name" : "装饰人工",
+        "coe" : 3.04
+    },
+    {
+        "ID" : 12,
+        "ParentID" : 8,
+        "name" : "安装、机械人工",
+        "coe" :2.39
+    },
+    {
+        "ID" : 13,
+        "ParentID" : 8,
+        "name" : "仿古、园林绿化人工",
+        "coe" :2.39
+    },
+    {
+        "ID" : 14,
+        "ParentID" : 8,
+        "name" : "盾构用工",
+        "coe" :1
+    },
+    {
+        "ID" : 15,
+        "ParentID" : null,
+        "name" : "2011轨道定额",
+        "coe" :null
+    },
+    {
+        "ID" : 16,
+        "ParentID" : 15,
+        "name" : "土石方人工",
+        "coe" : 1.51
+    },
+    {
+        "ID" : 17,
+        "ParentID" : 15,
+        "name" : "建筑、市政、维修人工",
+        "coe" : 1.55
+    },
+    {
+        "ID" : 18,
+        "ParentID" : 15,
+        "name" : "装饰人工",
+        "coe" : 1
+    },
+    {
+        "ID" : 19,
+        "ParentID" : 15,
+        "name" : "安装、机械人工",
+        "coe" :1.49
+    },
+    {
+        "ID" : 20,
+        "ParentID" : 15,
+        "name" : "仿古、园林绿化人工",
+        "coe" :1
+    },
+    {
+        "ID" : 21,
+        "ParentID" : 15,
+        "name" : "盾构用工",
+        "coe" :1.49
+    }
+];
 
-class RationCalc {
+class RationProgram {
     constructor(project){
         this.project = project;
+        this.calc = new Calculation();
     };
 
-    calculate(ration){
-        ration.data.gljList = projectObj.project.ration_glj.getGljArrByRation(ration.data.ID);
+    compileAllTemps(){
+       for (let calcTemplate of calcTemplates){
+           this.calc.compile(calcTemplate, calcFeeRates, calcLabourCoes);
+       };
+    };
 
-        let calc = new Calculation();
-        calc.init(calcTemplate, calcFeeRate);
-        calc.compile();
-        calc.calculate(ration);
+    compile(calcTemplate){
+       this.calc.compile(calcTemplate, calcFeeRates, calcLabourCoes);
+    };
+
+    calculate(ration){
+        ration.data.gljList = this.project.ration_glj.getGljArrByRation(ration.data.ID);
+        ration.data.calcTemplate = calcTemplates[0];  // AAAAAA = getCalcTemplate($RATION.calcTemplateID);
+        this.calc.calculate(ration);
     };
 }

+ 8 - 8
web/building_saas/main/js/models/volume_price.js

@@ -145,25 +145,25 @@ var VolumePrice = {
                 if (!calcFees.findFee(volumePrice, 'common')) {
                     calcFees.addFee(volumePrice, 'common');
                 }
-                volumePrice.feesIndex.common.totalFee = (volumePrice.feesIndex.common.unitFee * volumePrice.quantity).toDecimal(2);
+                volumePrice.feesIndex.common.totalFee = (volumePrice.feesIndex.common.unitFee * volumePrice.quantity).toDecimal(tools.owner.Decimal.common.totalFee);
                 volumePrice.needRefresh = true;
             }
             updateField(volumePrice, field, newValue) {
                 calcFees.setFee(volumePrice, field, newValue);
                 let updateData = [];
-                if (field === 'quantity' || field === 'feesIndex.common.unitFee') {
-                    let data = {'ID': volumePrice.ID, 'projectID': this.getProject().ID()};
+                let data = {'ID': volumePrice.ID, 'projectID': this.getProject().ID()};
+                if (field === 'quantity') {
                     data[field] = newValue;
                     this.calculate(volumePrice);
                     data.fees = volumePrice.fees;
-                    updateData.push({'updateType': 'ut_update', 'updateData': data});
-                    tools.owner.pushNow('updateVolumePrice', this.getSourceType(), updateData);
+                } else if (field === 'feesIndex.common.unitFee') {
+                    this.calculate(volumePrice);
+                    data.fees = volumePrice.fees;
                 } else {
-                    let data = {'ID': volumePrice.ID, 'projectID': this.getProject().ID()};
                     data[field] = newValue;
-                    updateData.push({'updateType': 'ut_update', 'updateData': data});
-                    tools.owner.pushNow('updateVolumePrice', this.getSourceType(), updateData);
                 }
+                updateData.push({'updateType': 'ut_update', 'updateData': data});
+                tools.owner.pushNow('updateVolumePrice', this.getSourceType(), updateData);
             }
         }
 

+ 210 - 0
web/building_saas/main/js/views/calc_program_view.js

@@ -0,0 +1,210 @@
+/**
+ * Created by Mai on 2017/7/28.
+ */
+
+let calcProgramSetting ={
+    "emptyRows":0,
+    "headRows":1,
+    "headRowHeight":[
+        35
+    ],
+    "cols":[
+        {
+            "width":75,
+            "readOnly": true,
+            "head":{
+                "titleNames":["序号"],
+                "spanCols":[1],
+                "spanRows":[1],
+                "vAlign":[1],
+                "hAlign":[1],
+                "font":["Arial"]
+            },
+            "data":{
+                "field":"serialNo",
+                "vAlign":1,
+                "hAlign":1,
+                "font":"Arial"
+            }
+        },
+        {
+            "width":75,
+            "readOnly": false,
+            "head":{
+                "titleNames":["费用代号"],
+                "spanCols":[1],
+                "spanRows":[1],
+                "vAlign":[1],
+                "hAlign":[1],
+                "font":["Arial"]
+            },
+            "data":{
+                "field":"code",
+                "vAlign":1,
+                "hAlign":0,
+                "font":"Arial"
+            }
+        },
+        {
+            "width":200,
+            "readOnly":false,
+            "head":{
+                "titleNames":["名称"],
+                "spanCols":[1],
+                "spanRows":[1],
+                "vAlign":[1],
+                "hAlign":[1],
+                "font":["Arial"]
+            },
+            "data":{
+                "field":"name",
+                "vAlign":1,
+                "hAlign":0,
+                "font":"Arial"
+            }
+        },
+        {
+            "width":280,
+            "readOnly":false,
+            "head":{
+                "titleNames":["计算基数"],
+                "spanCols":[1],
+                "spanRows":[1],
+                "vAlign":[1],
+                "hAlign":[1],
+                "font":["Arial"]
+            },
+            "data":{
+                "field":"dispExpr",
+                "vAlign":1,
+                "hAlign":0,
+                "font":"Arial"
+            }
+        },
+        {
+            "width":220,
+            "readOnly":false,
+            "head":{
+                "titleNames":["基数说明"],
+                "spanCols":[1],
+                "spanRows":[1],
+                "vAlign":[1],
+                "hAlign":[1],
+                "font":["Arial"]
+            },
+            "data":{
+                "field":"statement",
+                "vAlign":1,
+                "hAlign":0,
+                "font":"Arial"
+            }
+        },
+        {
+            "width":80,
+            "readOnly": false,
+            "head":{
+                "titleNames":["费率"],
+                "spanCols":[1],
+                "spanRows":[1],
+                "vAlign":[1],
+                "hAlign":[1],
+                "font":["Arial"]
+            },
+            "data":{
+                "field":"feeRate",
+                "vAlign":1,
+                "hAlign":2,
+                "font":"Arial"
+            }
+        },
+        {
+            "width": 100,
+            "readOnly":true,
+            "head":{
+                "titleNames":["单价"],
+                "spanCols":[1],
+                "spanRows":[1],
+                "vAlign":[1],
+                "hAlign":[1],
+                "font":["Arial"]
+            },
+            "data":{
+                "field":"unitFee",
+                "vAlign":1,
+                "hAlign":2,
+                "font":"Arial"
+            }
+        },
+        {
+            "width":100,
+            "readOnly":true,
+            "head":{
+                "titleNames":["合价"],
+                "spanCols":[1],
+                "spanRows":[1],
+                "vAlign":[1],
+                "hAlign":[1],
+                "font":["Arial"]
+            },
+            "data":{
+                "field":"totalFee",
+                "vAlign":1,
+                "hAlign":2,
+                "font":"Arial"
+            }
+        },
+        {
+            "width":80,
+            "readOnly": true,
+            "head":{
+                "titleNames":["费用类别"],
+                "spanCols":[1],
+                "spanRows":[1],
+                "vAlign":[1],
+                "hAlign":[1],
+                "font":["Arial"]
+            },
+            "data":{
+                "field":"type",
+                "vAlign":1,
+                "hAlign":0,
+                "font":"Arial",
+                "getText": function (record) {
+                    if (record.type) {
+                        for (let ft of feeType) {
+                            if (ft.type === record.type) {
+                                return ft.name;
+                            }
+                        }
+                    }
+                    return '';
+                }
+            }
+        },
+        {
+            "width":120,
+            "readOnly":false,
+            "head":{
+                "titleNames":["备注"],
+                "spanCols":[1],
+                "spanRows":[1],
+                "vAlign":[1],
+                "hAlign":[1],
+                "font":["Arial"]
+            },
+            "data":{
+                "field":"memo",
+                "vAlign":1,
+                "hAlign":0,
+                "font":"Arial"
+            }
+        }
+    ]
+};
+
+let calcProgramObj = {
+    showBillsCalcProgram: function (node, calcProgram, sheet) {
+        SheetDataHelper.loadSheetHeader(calcProgramSetting, sheet);
+        SheetDataHelper.loadSheetData(calcProgramSetting, sheet, calcProgram);
+    }
+};

+ 40 - 0
web/building_saas/main/js/views/main_tree_col.js

@@ -17,8 +17,30 @@ let MainTreeCol = {
         }
     },
     readOnly: {
+        bills: function (node) {
+            return node.sourceType === projectObj.project.Bills.getSourceType();
+        },
+        ration: function (node) {
+            return node.sourceType === projectObj.project.Ration.getSourceType();
+        },
         volumePrice: function (node) {
             return node.sourceType === projectObj.project.VolumePrice.getSourceType();
+        },
+        non_bills: function (node) {
+            return node.sourceType !== projectObj.project.Bills.getSourceType();
+        },
+        non_ration: function (node) {
+            return node.sourceType !== projectObj.project.Ration.getSourceType();
+        },
+        non_volumePrice: function (node) {
+            return node.sourceType !== projectObj.project.Ration.getSourceType();
+        },
+        billsParent: function (node) {
+            return node.sourceType === projectObj.project.Bills.getSourceType() && node.source.children.length > 0;
+        },
+        forCalcBase: function (node) {
+            // to do according to billsParentType
+            return MainTreeCol.readOnly.billsParent && MainTreeCol.readOnly.non_bills;
         }
     },
     getEvent: function (eventName) {
@@ -36,5 +58,23 @@ let MainTreeCol = {
         } else {
             return event;
         }
+    },
+    getNumberFormatter: function (digit) {
+        switch (digit) {
+            case 1:
+                return '0.#';
+            case 2:
+                return '0.##';
+            case 3:
+                return '0.###';
+            case 4:
+                return '0.####';
+            case 5:
+                return '0.#####';
+            case 6:
+                return '0.######';
+            default:
+                return '0.##';
+        }
     }
 }

+ 58 - 11
web/building_saas/main/js/views/project_view.js

@@ -7,25 +7,66 @@ var projectObj = {
     mainSpread: null,
     mainController: null,
     gljSpreed:null,
+    checkCommonField: function (editingText, colSetting) {
+        let value;
+        if (colSetting.data.decimal) {
+            value = Number(editingText);
+            if (number_util.isNumber(value)) {
+                value = value.toDecimal(colSetting.data.decimal);
+            } else {
+                value = null;
+                alert('当前输入的数据类型不正确,请重新输入。');
+            }
+        } else {
+            value = editingText;
+        }
+        return value;
+    },
+    checkQuantityField: function (editingText, colSetting) {
+        let value = Number(editingText);
+        if (!value) {
+            try {
+                let exp = new Expression('');
+                exp.Expression(editingText);
+                value = Number(exp.Evaluate());
+            } catch (error) {
+                value = null;
+            }
+        }
+        if (value) {
+            value = value.toDecimal(colSetting.data.decimal);
+        } else {
+            value = null;
+            alert('当前输入的数据类型不正确,请重新输入。');
+        }
+        return value;
+    },
+    checkSpreadEditingText: function (editingText, colSetting) {
+        if (colSetting.data.field === 'quantity') {
+            return this.checkQuantityField(editingText, colSetting);
+        } else {
+            return this.checkCommonField(editingText, colSetting);
+        }
+    },
     mainSpreadEditEnded: function (sender, info) {
         let project = projectObj.project;
         let node = project.mainTree.items[info.row];
         let colSetting = projectObj.mainController.setting.cols[info.col];
         let fieldName = projectObj.mainController.setting.cols[info.col].data.field;
+        let value = projectObj.checkSpreadEditingText(info.editingText, colSetting);
         if (colSetting.data.wordWrap) {
             info.sheet.autoFitRow(info.row);
         }
-        if (node.sourceType === project.Bills.getSourceType()) {
-
-        } else if (node.sourceType === project.Ration.getSourceType()) {
-
-        } else if (node.sourceType === project.VolumePrice.getSourceType()) {
-            project.VolumePrice.updateField(node.source, fieldName, info.editingText);
-            if (node.source.needRefresh) {
-                projectObj.mainController.refreshTreeNode([node]);
-                node.source.needRefresh = false;
+        if (value && value != calcFees.getFee(node.data, fieldName)) {
+            if (node.sourceType === project.Bills.getSourceType()) {
+                project.Bills.updateField(node.source, fieldName, value);
+            } else if (node.sourceType === project.Ration.getSourceType()) {
+                project.Ration.updateField(node.source, fieldName, value);
+            } else if (node.sourceType === project.VolumePrice.getSourceType()) {
+                project.VolumePrice.updateField(node.source, fieldName, value);
             }
-        };
+        }
+        projectObj.mainController.refreshTreeNode([node]);
     },
     checkMainSpread: function () {
         if (!this.mainSpread) {
@@ -51,6 +92,10 @@ var projectObj = {
                     if (col.readOnly && Object.prototype.toString.apply(col.readOnly) === "[object String]") {
                         col.readOnly = MainTreeCol.getEvent(col.readOnly);
                     }
+                    if (col.data.digit && Object.prototype.toString.apply(col.data.digit) === "[object String]") {
+                        col.data.decimal = that.project.getDecimal(col.data.digit);
+                        col.data.formatter = MainTreeCol.getNumberFormatter(col.data.decimal);
+                    }
                 });
                 that.mainController = TREE_SHEET_CONTROLLER.createNew(that.project.mainTree, that.mainSpread.getActiveSheet(), BillsGridSetting);
                 that.mainController.showTreeData();
@@ -104,7 +149,7 @@ var projectObj = {
                     // CSL.2017.07.25
                     if (SubActiveSheetNameIs('JSCX')) {
                         if (node.sourceType === that.project.Bills.getSourceType()) {
-                            rationCalcView.clearData();
+                            calcProgramObj.showBillsCalcProgram(node.source, baseCalcField, rationCalcView.sheet);
                         } else if (node.sourceType==='ration') {
                             rationCalcView.showData(node);
                         } else {
@@ -121,6 +166,8 @@ var projectObj = {
 
             }
         });
+        this.rationProgram = new RationProgram(this.project);
+        this.rationProgram.compileAllTemps();
     },
     loadMainSpreadContextMenu: function () {
         var project = this.project, spread = this.mainSpread, controller = this.mainController;

+ 2 - 4
web/building_saas/main/js/views/ration_calc_view.js

@@ -32,10 +32,8 @@ let rationCalcView = {
     showData: function (ration) {
         var me = this;
         me.ration = ration;
-        let rationCalc = new RationCalc(projectObj.project);
-        rationCalc.calculate(me.ration);
-
-        me.datas = calcTemplate.calcItems;   // AAAAAAAAA
+        projectObj.rationProgram.calculate(me.ration);
+        me.datas = me.ration.data.calcTemplate.calcItems;
         sheetCommonObj.showData(me.sheet, me.setting, me.datas);
     },
 

+ 6 - 4
web/building_saas/main/js/views/sub_view.js

@@ -60,12 +60,14 @@ $("#linkJSCX").click(function(){        // 计算程序
     subSpread.setActiveSheetIndex(4);
     rationCalcView.initSheet(subSpread.getSheet(4));
     let sel = projectObj.mainController.tree.selected;
-    if (sel != null && sel.sourceType == 'ration'){
+
+    if (sel.sourceType === projectObj.project.Bills.getSourceType()) {
+        calcProgramObj.showBillsCalcProgram(sel.source, baseCalcField, rationCalcView.sheet);
+    } else if (sel.sourceType==='ration') {
         rationCalcView.showData(sel);
-    }
-    else{
+    } else {
         rationCalcView.clearData();
-    };
+    }
 });
 
 $("#linkFXSM").click(function(){