Browse Source

bills calculate

MaiXinRong 8 years ago
parent
commit
07e632aab3

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

@@ -13,7 +13,7 @@ class baseModel {
      * @param fields
      * @returns {Promise|Array|{index: number, input: string}}
      */
-    getQueryData(query, fields) {
+    getQueryData (query, fields) {
         return this.model.find(query, fields).exec();
     };
 

+ 1 - 1
package.json

@@ -27,6 +27,6 @@
     "uuid": "^3.1.0"
   },
   "scripts": {
-    "start": "nodemon server.js"
+    "start": "C:\\Users\\mai\\AppData\\Roaming\\npm\\babel-node.cmd server.js"
   }
 }

+ 16 - 16
public/web/tree_sheet/tree_sheet_helper.js

@@ -68,21 +68,21 @@ var TREE_SHEET_HELPER = {
                 var iRow = node.serialNo();
                 var cell = sheet.getCell(iRow, iCol, GC.Spread.Sheets.SheetArea.viewport);
 
-                var getFieldText = function () {
-                    var fields = colSetting.data.field.split('.');
-                    var validField = fields.reduce(function (field1, field2) {
-                        if (eval('node.data.' + field1)) {
-                            return field1 + '.' + field2
-                        } else {
-                            return field1;
-                        }
-                    });
-                    if (eval('node.data.' + validField)) {
-                        return eval('node.data.' + validField);
-                    } else {
-                        return '';
-                    }
-                };
+                // var getFieldText = function () {
+                //     var fields = colSetting.data.field.split('.');
+                //     var validField = fields.reduce(function (field1, field2) {
+                //         if (eval('node.data.' + field1)) {
+                //             return field1 + '.' + field2
+                //         } else {
+                //             return field1;
+                //         }
+                //     });
+                //     if (eval('node.data.' + validField)) {
+                //         return eval('node.data.' + validField);
+                //     } else {
+                //         return '';
+                //     }
+                // };
                 var getFieldText2 = function () {
                     var fields = colSetting.data.field.split('.'), iField, data = node.data;
                     for (iField = 0; iField < fields.length; iField++) {
@@ -261,4 +261,4 @@ var TREE_SHEET_HELPER = {
             TREE_SHEET_HELPER.refreshNodesVisible(tree.roots, sheet, true);
         });
     }
-};
+};

+ 65 - 5
test/tmp_data/bills_grid_setting.js

@@ -4,12 +4,72 @@
 var BillsGridSetting ={
     "emptyRows":3,
     "headRows":1,
-    "treeCol": 0,
+    "treeCol": 2,
     "headRowHeight":[
         47
     ],
     "cols":[
         {
+            "width":50,
+            "readOnly":false,
+            "head":{
+                "titleNames":[
+                    "ID"
+                ],
+                "spanCols":[
+                    1
+                ],
+                "spanRows":[
+                    1
+                ],
+                "vAlign":[
+                    1
+                ],
+                "hAlign":[
+                    1
+                ],
+                "font":[
+                    "Comic Sans MS"
+                ]
+            },
+            "data":{
+                "field":"ID",
+                "vAlign":1,
+                "hAlign":0,
+                "font":"Arial"
+            }
+        },
+        {
+            "width":50,
+            "readOnly":false,
+            "head":{
+                "titleNames":[
+                    "serialNo"
+                ],
+                "spanCols":[
+                    1
+                ],
+                "spanRows":[
+                    1
+                ],
+                "vAlign":[
+                    1
+                ],
+                "hAlign":[
+                    1
+                ],
+                "font":[
+                    "Comic Sans MS"
+                ]
+            },
+            "data":{
+                "field":"serialNo",
+                "vAlign":1,
+                "hAlign":0,
+                "font":"Arial"
+            }
+        },
+        {
             "width":150,
             "readOnly":false,
             "head":{
@@ -456,7 +516,7 @@ var BillsGridSetting ={
                 ]
             },
             "data":{
-                "field":"feeIndex.common.unitFee",
+                "field":"feesIndex.common.unitFee",
                 "vAlign":1,
                 "hAlign":2,
                 "font":"Arial"
@@ -486,7 +546,7 @@ var BillsGridSetting ={
                 ]
             },
             "data":{
-                "field":"feeIndex.common.totalFee",
+                "field":"feesIndex.common.totalFee",
                 "vAlign":1,
                 "hAlign":2,
                 "font":"Arial"
@@ -516,7 +576,7 @@ var BillsGridSetting ={
                 ]
             },
             "data":{
-                "field":"feeIndex.zangu.unitFee",
+                "field":"feesIndex.zangu.unitFee",
                 "vAlign":1,
                 "hAlign":2,
                 "font":"Arial"
@@ -546,7 +606,7 @@ var BillsGridSetting ={
                 ]
             },
             "data":{
-                "field":"feeIndex.zangu.totalFee",
+                "field":"feesIndex.zangu.totalFee",
                 "vAlign":1,
                 "hAlign":2,
                 "font":"Arial"

File diff suppressed because it is too large
+ 0 - 62761
test/tmp_data/data_15690.js


File diff suppressed because it is too large
+ 0 - 41073
test/tmp_data/drawing_data_10268.js


File diff suppressed because it is too large
+ 62761 - 0
test/tmp_data/test_bills_calc/bills_data_15690.js


+ 676 - 0
test/tmp_data/test_bills_calc/bills_grid_setting_test_calc.js

@@ -0,0 +1,676 @@
+/**
+ * Created by Mai on 2017/4/1.
+ */
+var BillsGridSetting ={
+    "emptyRows":3,
+    "headRows":1,
+    "treeCol": 1,
+    "headRowHeight":[
+        47
+    ],
+    "cols":[
+        {
+            "width":50,
+            "readOnly":false,
+            "head":{
+                "titleNames":[
+                    "ID"
+                ],
+                "spanCols":[
+                    1
+                ],
+                "spanRows":[
+                    1
+                ],
+                "vAlign":[
+                    1
+                ],
+                "hAlign":[
+                    1
+                ],
+                "font":[
+                    "Comic Sans MS"
+                ]
+            },
+            "data":{
+                "field":"ID",
+                "vAlign":1,
+                "hAlign":0,
+                "font":"Arial"
+            }
+        },
+        {
+            "width":300,
+            "readOnly":false,
+            "head":{
+                "titleNames":[
+                    "项目编码"
+                ],
+                "spanCols":[
+                    1
+                ],
+                "spanRows":[
+                    1
+                ],
+                "vAlign":[
+                    1
+                ],
+                "hAlign":[
+                    1
+                ],
+                "font":[
+                    "Comic Sans MS"
+                ]
+            },
+            "data":{
+                "field":"code",
+                "vAlign":1,
+                "hAlign":0,
+                "font":"Arial"
+            }
+        },
+        {
+            "width":50,
+            "readOnly":false,
+            "head":{
+                "titleNames":[
+                    "类别"
+                ],
+                "spanCols":[
+                    1
+                ],
+                "spanRows":[
+                    1
+                ],
+                "vAlign":[
+                    1
+                ],
+                "hAlign":[
+                    1
+                ],
+                "font":[
+                    "Arial"
+                ]
+            },
+            "data":{
+                "field":"type",
+                "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":40,
+            "readOnly":false,
+            "head":{
+                "titleNames":[
+                    "计量\n单位"
+                ],
+                "spanCols":[
+                    1
+                ],
+                "spanRows":[
+                    1
+                ],
+                "vAlign":[
+                    1
+                ],
+                "hAlign":[
+                    1
+                ],
+                "font":[
+                    "Arial"
+                ],
+                "wordWrap":[
+                    true
+                ]
+            },
+            "data":{
+                "field":"unit",
+                "vAlign":1,
+                "hAlign":1,
+                "font":"Arial"
+            }
+        },
+        {
+            "width":80,
+            "readOnly":false,
+            "head":{
+                "titleNames":[
+                    "取费专业"
+                ],
+                "spanCols":[
+                    1
+                ],
+                "spanRows":[
+                    1
+                ],
+                "vAlign":[
+                    1
+                ],
+                "hAlign":[
+                    1
+                ],
+                "font":[
+                    "Arial"
+                ]
+            },
+            "data":{
+                "field":"",
+                "vAlign":1,
+                "hAlign":0,
+                "font":"Arial"
+            }
+        },
+        {
+            "width":120,
+            "readOnly":false,
+            "head":{
+                "titleNames":[
+                    "工程量计算规则"
+                ],
+                "spanCols":[
+                    1
+                ],
+                "spanRows":[
+                    1
+                ],
+                "vAlign":[
+                    1
+                ],
+                "hAlign":[
+                    1
+                ],
+                "font":[
+                    "Arial"
+                ]
+            },
+            "data":{
+                "field":"programID",
+                "vAlign":1,
+                "hAlign":0,
+                "font":"Arial"
+            }
+        },
+        {
+            "width":80,
+            "readOnly":false,
+            "head":{
+                "titleNames":[
+                    "工程量"
+                ],
+                "spanCols":[
+                    1
+                ],
+                "spanRows":[
+                    1
+                ],
+                "vAlign":[
+                    1
+                ],
+                "hAlign":[
+                    1
+                ],
+                "font":[
+                    "Arial"
+                ]
+            },
+            "data":{
+                "field":"quantity",
+                "vAlign":1,
+                "hAlign":2,
+                "font":"Arial"
+            }
+        },
+        {
+            "width":80,
+            "readOnly":false,
+            "head":{
+                "titleNames":[
+                    "含量"
+                ],
+                "spanCols":[
+                    1
+                ],
+                "spanRows":[
+                    1
+                ],
+                "vAlign":[
+                    1
+                ],
+                "hAlign":[
+                    1
+                ],
+                "font":[
+                    "Arial"
+                ]
+            },
+            "data":{
+                "field":"",
+                "vAlign":1,
+                "hAlign":0,
+                "font":"Arial"
+            }
+        },
+        {
+            "width":120,
+            "readOnly":false,
+            "head":{
+                "titleNames":[
+                    "计算基数"
+                ],
+                "spanCols":[
+                    1
+                ],
+                "spanRows":[
+                    1
+                ],
+                "vAlign":[
+                    1
+                ],
+                "hAlign":[
+                    1
+                ],
+                "font":[
+                    "Arial"
+                ]
+            },
+            "data":{
+                "field":"",
+                "vAlign":1,
+                "hAlign":0,
+                "font":"Arial"
+            }
+        },
+        {
+            "width":80,
+            "readOnly":false,
+            "head":{
+                "titleNames":[
+                    "费率(%)"
+                ],
+                "spanCols":[
+                    1
+                ],
+                "spanRows":[
+                    1
+                ],
+                "vAlign":[
+                    1
+                ],
+                "hAlign":[
+                    1
+                ],
+                "font":[
+                    "Arial"
+                ]
+            },
+            "data":{
+                "field":"",
+                "vAlign":1,
+                "hAlign":0,
+                "font":"Arial"
+            }
+        },
+        {
+            "width":80,
+            "readOnly":false,
+            "head":{
+                "titleNames":[
+                    "综合单价"
+                ],
+                "spanCols":[
+                    1
+                ],
+                "spanRows":[
+                    1
+                ],
+                "vAlign":[
+                    1
+                ],
+                "hAlign":[
+                    1
+                ],
+                "font":[
+                    "Arial"
+                ]
+            },
+            "data":{
+                "field":"feesIndex.common.unitFee",
+                "vAlign":1,
+                "hAlign":2,
+                "font":"Arial"
+            }
+        },
+        {
+            "width":80,
+            "readOnly":false,
+            "head":{
+                "titleNames":[
+                    "综合合价"
+                ],
+                "spanCols":[
+                    1
+                ],
+                "spanRows":[
+                    1
+                ],
+                "vAlign":[
+                    1
+                ],
+                "hAlign":[
+                    1
+                ],
+                "font":[
+                    "Arial"
+                ]
+            },
+            "data":{
+                "field":"feesIndex.common.totalFee",
+                "vAlign":1,
+                "hAlign":2,
+                "font":"Arial"
+            }
+        },
+        {
+            "width":80,
+            "readOnly":false,
+            "head":{
+                "titleNames":[
+                    "人工单价"
+                ],
+                "spanCols":[
+                    1
+                ],
+                "spanRows":[
+                    1
+                ],
+                "vAlign":[
+                    1
+                ],
+                "hAlign":[
+                    1
+                ],
+                "font":[
+                    "Arial"
+                ]
+            },
+            "data":{
+                "field":"feesIndex.labour.unitFee",
+                "vAlign":1,
+                "hAlign":2,
+                "font":"Arial"
+            }
+        },
+        {
+            "width":80,
+            "readOnly":false,
+            "head":{
+                "titleNames":[
+                    "人工合价"
+                ],
+                "spanCols":[
+                    1
+                ],
+                "spanRows":[
+                    1
+                ],
+                "vAlign":[
+                    1
+                ],
+                "hAlign":[
+                    1
+                ],
+                "font":[
+                    "Arial"
+                ]
+            },
+            "data":{
+                "field":"feesIndex.labour.totalFee",
+                "vAlign":1,
+                "hAlign":2,
+                "font":"Arial"
+            }
+        },
+        {
+            "width":80,
+            "readOnly":false,
+            "head":{
+                "titleNames":[
+                    "机械费单价"
+                ],
+                "spanCols":[
+                    1
+                ],
+                "spanRows":[
+                    1
+                ],
+                "vAlign":[
+                    1
+                ],
+                "hAlign":[
+                    1
+                ],
+                "font":[
+                    "Arial"
+                ]
+            },
+            "data":{
+                "field":"feesIndex.machine.unitFee",
+                "vAlign":1,
+                "hAlign":2,
+                "font":"Arial"
+            }
+        },
+        {
+            "width":80,
+            "readOnly":false,
+            "head":{
+                "titleNames":[
+                    "机械费合价"
+                ],
+                "spanCols":[
+                    1
+                ],
+                "spanRows":[
+                    1
+                ],
+                "vAlign":[
+                    1
+                ],
+                "hAlign":[
+                    1
+                ],
+                "font":[
+                    "Arial"
+                ]
+            },
+            "data":{
+                "field":"feesIndex.machine.totalFee",
+                "vAlign":1,
+                "hAlign":2,
+                "font":"Arial"
+            }
+        },
+        {
+            "width":80,
+            "readOnly":false,
+            "head":{
+                "titleNames":[
+                    "材料费单价"
+                ],
+                "spanCols":[
+                    1
+                ],
+                "spanRows":[
+                    1
+                ],
+                "vAlign":[
+                    1
+                ],
+                "hAlign":[
+                    1
+                ],
+                "font":[
+                    "Arial"
+                ]
+            },
+            "data":{
+                "field":"feesIndex.material.unitFee",
+                "vAlign":1,
+                "hAlign":2,
+                "font":"Arial"
+            }
+        },
+        {
+            "width":80,
+            "readOnly":false,
+            "head":{
+                "titleNames":[
+                    "材料费合价"
+                ],
+                "spanCols":[
+                    1
+                ],
+                "spanRows":[
+                    1
+                ],
+                "vAlign":[
+                    1
+                ],
+                "hAlign":[
+                    1
+                ],
+                "font":[
+                    "Arial"
+                ]
+            },
+            "data":{
+                "field":"feesIndex.material.totalFee",
+                "vAlign":1,
+                "hAlign":2,
+                "font":"Arial"
+            }
+        },
+        {
+            "width":80,
+            "readOnly":false,
+            "head":{
+                "titleNames":[
+                    "暂估单价"
+                ],
+                "spanCols":[
+                    1
+                ],
+                "spanRows":[
+                    1
+                ],
+                "vAlign":[
+                    1
+                ],
+                "hAlign":[
+                    1
+                ],
+                "font":[
+                    "Arial"
+                ]
+            },
+            "data":{
+                "field":"feesIndex.zangu.unitFee",
+                "vAlign":1,
+                "hAlign":2,
+                "font":"Arial"
+            }
+        },
+        {
+            "width":80,
+            "readOnly":false,
+            "head":{
+                "titleNames":[
+                    "暂估合价"
+                ],
+                "spanCols":[
+                    1
+                ],
+                "spanRows":[
+                    1
+                ],
+                "vAlign":[
+                    1
+                ],
+                "hAlign":[
+                    1
+                ],
+                "font":[
+                    "Arial"
+                ]
+            },
+            "data":{
+                "field":"feesIndex.zangu.totalFee",
+                "vAlign":1,
+                "hAlign":2,
+                "font":"Arial"
+            }
+        },
+        {
+            "width":120,
+            "readOnly":false,
+            "head":{
+                "titleNames":[
+                    "备注"
+                ],
+                "spanCols":[
+                    1
+                ],
+                "spanRows":[
+                    1
+                ],
+                "vAlign":[
+                    1
+                ],
+                "hAlign":[
+                    1
+                ],
+                "font":[
+                    "Arial"
+                ]
+            },
+            "data":{
+                "field":"",
+                "vAlign":1,
+                "hAlign":0,
+                "font":"Arial"
+            }
+        }
+    ]
+};

File diff suppressed because it is too large
+ 92413 - 0
test/tmp_data/test_bills_calc/drawing_data_10268.js


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

@@ -490,12 +490,16 @@
 
     <script type="text/javascript" src="/public/web/id_tree.js"></script>
     <script type="text/javascript" src="/web/building_saas/main/js/models/cache_tree.js"></script>
+    <script type="text/javascript" src="/web/building_saas/main/js/models/bills_calc.js"></script>
     <!-- Controller -->
     <script type="text/javascript" src="/public/web/tree_sheet/tree_sheet_controller.js"></script>
     <script type="text/javascript" src="/public/web/tree_sheet/tree_sheet_helper.js"></script>
     <script type="text/javascript" src="/public/web/sheet/sheet_data_helper.js"></script>
     <!-- Test Data -->
     <script type="text/javascript" src="/test/tmp_data/bills_grid_setting.js"></script>
+    <!--<script type="text/javascript" src="/test/tmp_data/test_bills_calc/bills_grid_setting_test_calc.js"></script>
+    <script type="text/javascript" src="/test/tmp_data/test_bills_calc/bills_data_15690.js"></script>
+    <script type="text/javascript" src="/test/tmp_data/test_bills_calc/drawing_data_10268.js"></script>-->
     <!-- view -->
     <script type="text/javascript" src="/web/building_saas/main/js/views/project_info.js"></script>
     <script type="text/javascript" src="/web/building_saas/main/js/views/project_view.js"></script>

+ 11 - 0
web/building_saas/main/js/controllers/project_controller.js

@@ -67,5 +67,16 @@ ProjectController = {
 
             this.syncDisplayNewNode(sheetController, newNode);
         }
+    },
+    calculateAll: function (project, sheetController, CalcType) {
+        let date1 = new Date();
+        let calc = new BillsCalc(project, CalcType);
+        calc.calcAll();
+        calc = null;
+        let date2 = new Date();
+        console.log(date2 - date1);
+        sheetController.showTreeData();
+        let date3 = new Date();
+        console.log(date3 - date1);
     }
 }

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

@@ -71,16 +71,16 @@ var Bills = {
             this.datas = datas;
             // generate Fees & Flags Index, For View & Calculate
             this.datas.forEach(function (data) {
-                data.FeesIndex = {};
+                data.feesIndex = {};
                 if (data.fees) {
                     data.fees.forEach(function (fee) {
-                        data.FeesIndex[fee.fieldName] = fee;
+                        data.feesIndex[fee.fieldName] = fee;
                     });
                 }
-                data.FlagsIndex = {};
+                data.flagsIndex = {};
                 if (data.flags) {
                     data.flags.forEach(function (flag) {
-                        data.FlagsIndex[flag.fieldName] = flag;
+                        data.flagsIndex[flag.fieldName] = flag;
                     });
                 }
             });

+ 225 - 0
web/building_saas/main/js/models/bills_calc.js

@@ -0,0 +1,225 @@
+/**
+ * Created by Mai on 2017/7/5.
+ */
+
+const rationContent = 0, rationPrice = 1, rationPriceConverse = 2, billsPrice = 3;
+
+const sumTotalFeeFlag = 0, totalFeeFlag = 1;
+const rationContentUnitFeeFlag = 0, averageQtyUnitFeeFlag = 1, billsPriceUnitFeeFlag = 2;
+
+let rationContentCalcFields = [
+    {'type': 'common', 'unitFeeFlag': rationContentUnitFeeFlag, 'totalFeeFlag': totalFeeFlag},
+    {'type': 'labour', 'unitFeeFlag': rationContentUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
+    {'type': 'material', 'unitFeeFlag': rationContentUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
+    {'type': 'machine', 'unitFeeFlag': rationContentUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
+];
+let rationPriceCalcFields = [
+    {'type': 'common', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': totalFeeFlag},
+    {'type': 'labour', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
+    {'type': 'material', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
+    {'type': 'machine', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
+];
+let rationPriceConverseCalcFields = [
+    {'type': 'common', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
+    {'type': 'labour', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
+    {'type': 'material', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
+    {'type': 'machine', 'unitFeeFlag': averageQtyUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
+];
+let billsPriceCalcFields = [
+    {'type': 'common', 'unitFeeFlag': billsPriceUnitFeeFlag, 'totalFeeFlag': totalFeeFlag},
+    {'type': 'labour', 'unitFeeFlag': billsPriceUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
+    {'type': 'material', 'unitFeeFlag': billsPriceUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
+    {'type': 'machine', 'unitFeeFlag': billsPriceUnitFeeFlag, 'totalFeeFlag': sumTotalFeeFlag},
+];
+
+Number.prototype.toDecimal = function (ADigit) {
+    return parseFloat(this.toFixed(ADigit));
+};
+
+let nodeCalcObj = {
+    node: null,
+    digit: 2,
+    field: null,
+    findFee: function (fieldName) {
+        if (!this.node.data.fees) {
+            this.node.data.fees = [];
+        }
+        for (let fee of this.node.data.fees) {
+            if (fee.fieldName === fieldName) {
+                return fee;
+            }
+        }
+        return null;
+    },
+    AddFee: function (fieldName) {
+        let fee = {
+            'fieldName': fieldName,
+            'unitFee': 0,
+            'totalFee': 0,
+            'tenderUnitFee': 0,
+            'tenderTotalFee': 0
+        };
+        this.node.data.fees.push(fee);
+        this.node.data.feesIndex[fieldName] = fee;
+    },
+    checkFields: function (fields) {
+        for (let field of fields) {
+            if (!this.findFee(field.type)) {
+                this.AddFee(field.type);
+            }
+        }
+    },
+    getFee: function (data, fullField) {
+        let fields = fullField.split('.'), value = data;
+        for (let field of fields) {
+            if (value[field]) {
+                value = value[field];
+            } else {
+                return 0;
+            }
+        }
+        return value;
+    },
+    getFeeSplit: function (data, fullFields) {
+        let value = data;
+        for (let field of fullFields) {
+            if (value[field]) {
+                value = value[field];
+            } else {
+                return 0;
+            }
+        }
+        return value;
+    },
+    sumTotalFee: function() {
+        let result = 0, child;
+        for (child of this.node.children) {
+            result += this.getFee(child.data, this.field.totalFee);
+            //result += child.data.feesIndex[this.field.type].totalFee;
+            //result += this.getFeeSplit(child.data, this.field.totalFeeSplit);
+        }
+        return result;
+    },
+    averageQty: function() {
+        let result = 0, child, qty;
+        result = this.sumTotalFee(this.field);
+        qty = this.getFee(this.node.data, 'quantity');
+        if (qty !== 0) {
+            result = result / qty;
+        }
+        return result;
+    },
+    totalFee: function () {
+        return this.getFee(this.node.data, this.field.unitFee) * this.getFee(this.node.data, 'quantity');
+        //return this.node.data.feesIndex[this.field.type].unitFee * this.node.data.quantity;
+        //return this.getFeeSplit(this.node.data, this.field.unitFeeSplit) * this.getFee(this.node.data, 'quantity');
+    },
+    rationContentUnitFee: function () {
+        let result = 0, child, qty = this.getFee(this.node.data, 'quantity');
+        if (qty === 0) {
+            qty = 1;
+        }
+        for (child of this.node.children) {
+            result += (this.getFee(child.data, this.field.unitFee) * this.getFee(child.data, 'quantity') / qty).toDecimal(this.digit);
+            //result += (child.data.feesIndex[this.field.type].unitFee * child.data.quantity / qty).toDecimal(this.digit);
+            //result += (this.getFeeSplit(child.data, this.field.unitFeeSplit) * this.getFee(child.data, 'quantity') / qty).toDecimal(this.digit);
+        }
+        return result;
+    }
+};
+
+class BillsCalc {
+    constructor (project, CalcFlag) {
+        this.project = project;
+        this.CalcFlag = CalcFlag;
+        this.digit = 2;
+        switch (this.CalcFlag) {
+            case rationContent:
+                this.calcFieldName = rationContentCalcFields;
+                break;
+            case rationPrice:
+                this.calcFieldName = rationPriceCalcFields;
+                break;
+            case rationPriceConverse:
+                this.calcFieldName = rationPriceConverseCalcFields;
+                break;
+            case billsPrice:
+                this.calcFieldName = billsPriceCalcFields;
+                break;
+            default:
+                this.calcFieldName = [];
+        }
+        this.InitFields(this.calcFieldName);
+    };
+
+    calcLeaf (node, fields) {
+        nodeCalcObj.node = node;
+        nodeCalcObj.digit = this.digit;
+        nodeCalcObj.checkFields(fields);
+        let nodeCalc = nodeCalcObj;
+        for (let field of fields) {
+            nodeCalcObj.field = field;
+            switch (field.unitFeeFlag) {
+                case rationContentUnitFeeFlag:
+                    node.data.feesIndex[field.type].unitFee = nodeCalcObj.rationContentUnitFee().toDecimal(this.digit);
+                    break;
+                case averageQtyUnitFeeFlag:
+                    node.data.feesIndex[field.type].unitFee = nodeCalcObj.averageQty().toDecimal(this.digit);
+                    break;
+                // to do billsPriceUnitFeeFlag(套用定额计算程序)
+                // case billsPriceUnitFeeFlag:
+                //     break;
+                default:
+                    node.data.feesIndex[field.type].unitFee = 0;
+            }
+            switch (field.totalFeeFlag) {
+                case sumTotalFeeFlag:
+                    node.data.feesIndex[field.type].totalFee = nodeCalcObj.sumTotalFee().toDecimal(this.digit);
+                    break;
+                case totalFeeFlag:
+                    node.data.feesIndex[field.type].totalFee = nodeCalcObj.totalFee().toDecimal(this.digit);
+                    break;
+                default:
+                    node.data.feesIndex[field.type].totalFee = 0;
+            }
+        }
+    };
+    calcParent (node, fields) {
+        nodeCalcObj.node = node;
+        nodeCalcObj.checkFields(fields);
+        for (let field of fields) {
+            nodeCalcObj.field = field;
+            node.data.feesIndex[field.type].totalFee = nodeCalcObj.sumTotalFee().toDecimal(this.digit);
+        }
+    };
+    calcNodes (nodes) {
+        for (let node of nodes) {
+            if (node.sourceType !== this.project.Bills.getSourceType()) {
+                return;
+            }
+
+            if (node.source.children.length > 0) {
+                this.calcNodes(node.children);
+                this.calcParent(node, this.calcFieldName);
+            } else {
+                this.calcLeaf(node, this.calcFieldName);
+            }
+        }
+    };
+    calcAll () {
+        this.calcNodes(this.project.mainTree.roots);
+    };
+    InitFields (fields) {
+        for (let field of fields) {
+            if (field.unitFee) return;
+            field.unitFee = 'feesIndex.' + field.type + '.unitFee';
+            field.unitFeeSplit = field.unitFee.split('.');
+            field.totalFee = 'feesIndex.' + field.type + '.totalFee';
+            field.totalFeeSplit = field.totalFee.split('.');
+            field.tenderUnitFee = 'feesIndex.'+ field.type + '.tenderUnitFee';
+            field.tenderUnitFeeSplit = field.tenderUnitFee.split('.');
+            field.tenderTotalFee = 'feesIndex.' + field.type + '.tenderTotalFee';
+            field.tenderTotalFeeSplit = field.tenderTotalFee.split('.');
+        }
+    }
+}

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

@@ -152,6 +152,8 @@ var PROJECT = {
                 success: function (result) {
                     if (!result.error) {
                         tools.doAfterLoad(result.data, callback);
+                        // for test calc
+                        //tools.doAfterLoad([{moduleName: 'bills', data: BillsData}, {'moduleName': 'ration', data: DrawingData}], callback);
                     } else {
                         alert('error: ' + result.message);
                         callback(result.error);

+ 4 - 5
web/building_saas/main/js/models/ration.js

@@ -38,13 +38,13 @@ var Ration = {
             this.datas = datas;
             // generate Fees & Flags Index,For View & Calculate
             this.datas.forEach(function (data) {
-                data.FeesIndex = {};
+                data.feesIndex = {};
                 data.fees.forEach(function (fee) {
-                    data.FeesIndex[fee.fieldName] = fee;
+                    data.feesIndex[fee.fieldName] = fee;
                 });
-                data.FlagsIndex = {};
+                data.flagsIndex = {};
                 data.flags.forEach(function (flag) {
-                    data.FlagsIndex[flag.fieldName] = flag;
+                    data.flagsIndex[flag.fieldName] = flag;
                 });
                 that.maxRationID(data.ID);
             });
@@ -102,7 +102,6 @@ var Ration = {
             var br = this.getBillsSortRation(billsID);
             this.project.pushNow('insertRation', [this.getSourceType(), this.project.projCounter()],
                 [this.getInsertRationData(billsID, preRation), this.getCounterData()]);
-            //this.project.pushNow('insertRation', [this.getSourceType()], [this.getInsertRationData(billsID, preRation)]);
 
             var newRation = null;
             if (preRation) {

+ 35 - 10
web/building_saas/main/js/views/project_view.js

@@ -23,6 +23,9 @@ var projectObj = {
         this.project = PROJECT.createNew(scUrlUtil.GetQueryString('project'), userID);
         this.project.loadDatas(function (err) {
             if (!err) {
+                BillsGridSetting.cols.forEach(function (col) {
+                    col.data.splitFields = col.data.field.split('.');
+                });
                 that.mainController = TREE_SHEET_CONTROLLER.createNew(that.project.mainTree, that.mainSpread.getActiveSheet(), BillsGridSetting);
                 that.mainController.showTreeData();
                 that.mainController.bind('refreshBaseActn', function (tree) {
@@ -47,7 +50,6 @@ var projectObj = {
 
 
                 that.mainController.bind(TREE_SHEET_CONTROLLER.eventName.treeSelectedChanged, function (node) {
-                    console.log(projectObj.project);
                     gljOprObj.showDataIfRationSelect(node);
                 });
 
@@ -129,7 +131,31 @@ var projectObj = {
                                 controller.delete();
                             };
                         }
-
+                    }
+                },
+                "spr2":'--------',
+                "calculateAll_RationContent": {
+                    name: '造价计算(子目含量取费)',
+                    callback: function () {
+                        ProjectController.calculateAll(project, controller, rationContent);
+                    }
+                },
+                "calculateAll_RationPrice": {
+                    name: '造价计算(子目单价取费)',
+                    callback: function () {
+                        ProjectController.calculateAll(project, controller, rationPrice);
+                    }
+                },
+                "calculateAll_RationPriceConverse": {
+                    name: '造价计算(子目单价取费-反算)',
+                    callback: function () {
+                        ProjectController.calculateAll(project, controller, rationPriceConverse);
+                    }
+                },
+                "calculateAll_BillsPrice": {
+                    name: '造价计算(清单单价取费)',
+                    callback: function () {
+                        ProjectController.calculateAll(project, controller, billsPrice);
                     }
                 }
             }
@@ -184,14 +210,14 @@ $('#upMove').click(function () {
     var controller = projectObj.mainController, project = projectObj.project;
     var selected = controller.tree.selected, pre, preSerialNo;
 
+    if (selected.sourceType === project.Bills.getSourceType()) {
+        project.Bills.upMoveBills(selected.source);
+        controller.upMove();
+    } else if (selected.sourceType === project.Ration.getSourceType()) {
+        project.Ration.changePos(selected.source, selected.preSibling.source);
+        controller.upMove();
+    }
     if (selected) {
-        if (selected.sourceType === project.Bills.getSourceType()) {
-            project.Bills.upMoveBills(selected.source);
-            controller.upMove();
-        } else if (selected.sourceType === project.Ration.getSourceType()) {
-            project.Ration.changePos(selected.source, selected.preSibling.source);
-            controller.upMove();
-        }
     }
 });
 $('#downMove').click(function () {
@@ -208,4 +234,3 @@ $('#downMove').click(function () {
         }
     }
 });
-