瀏覽代碼

量价计算。

Chenshilong 7 年之前
父節點
當前提交
b1ee477019

+ 2 - 0
modules/main/models/ration.js

@@ -38,6 +38,8 @@ let rationSchema = new Schema({
     caption: String,
     unit: String,
     quantity: String, // Decimal
+    marketUnitFee: String,
+    marketTotalFee: String,
     isFromDetail:{type: Number,default:0},  //1 true 2 false
     programID: Number,
     adjustState: String,

+ 2 - 0
modules/volume_price/models/volume_price_model.js

@@ -30,6 +30,7 @@ class volumePriceModel extends baseModel {
             if(err){
                 callback(1, '', null);
             }else {
+                // console.log(JSON.stringify(datas));
                 callback(0, consts.projectConst.VOLUMEPRICE, datas);
             }
         })
@@ -39,6 +40,7 @@ class volumePriceModel extends baseModel {
         let funs = [];
 
         function saveOne(doc) {
+            // console.log('-----------------------------------------------------------------------------' + JSON.stringify(doc));
             return function (cb) {
                 switch (doc.updateType) {
                     case commonConsts.UT_UPDATE:

+ 6 - 0
modules/volume_price/models/volume_price_schema.js

@@ -20,12 +20,18 @@ let volumePriceSchema = new Schema({
     serialNo: Number,
     // 编号
     code: String,
+    // 量价类型:人工、材料、机械、主材、设备
+    type: String,
+    programID: Number,
     // 名称
     name: String,
     // 单位
     unit: String,
     // 数量
     quantity: Number,
+    marketUnitFee: String,
+    marketTotalFee: String,
+
     // 费用字段
     fees: [subSchema.feesSchema],
     // 是否删除

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

@@ -137,7 +137,7 @@ var TREE_SHEET_HELPER = {
                     cell.value(getFieldText2());
                 }
                 if (colSetting.data.cellType && Object.prototype.toString.apply(colSetting.data.cellType) !== "[object String]") {
-                    cell.cellType(colSetting.data.cellType);
+                    cell.cellType(colSetting.data.cellType(node));
                 }
                 if (colSetting.readOnly) {
                     if (Object.prototype.toString.apply(colSetting.readOnly) === "[object Function]") {

+ 16 - 8
test/tmp_data/test_ration_calc/ration_calc_base.js

@@ -42,42 +42,50 @@ let rationCalcBase = [
         'calcFun': 'base',
         'calcType': baseCalc,
         'gljTypes': [gljType.LABOUR]
-    },{
+    },
+    {
         'dispName': '定额基价材料费',
         'calcFun': 'base',
         'calcType': baseCalc,
         'gljTypes': [gljType.GENERAL_MATERIAL, gljType.CONCRETE, gljType.MORTAR, gljType.MIX_RATIO, gljType.COMMERCIAL_CONCRETE, gljType.COMMERCIAL_MORTAR]
-    },{
+    },
+    {
         'dispName': '定额基价机械费',
         'calcFun': 'base',
         'calcType': baseCalc,
         'gljTypes': [gljType.GENERAL_MACHINE]
-    },{
+    },
+    {
         'dispName': '定额基价机上人工费',
         'calcFun': 'base',
         'calcType': baseCalc,
         'gljTypes': [gljType.MACHINE_LABOUR]
-    },{
+    },
+    {
         'dispName': '人工费价差',
         'calcFun': 'diff',
         'calcType': diffCalc,
         'gljTypes': [gljType.LABOUR]
-    },{
+    },
+    {
         'dispName': '材料费价差',
         'calcFun': 'diff',
         'calcType': diffCalc,
         'gljTypes': [gljType.GENERAL_MATERIAL, gljType.CONCRETE, gljType.MORTAR, gljType.MIX_RATIO, gljType.COMMERCIAL_CONCRETE, gljType.COMMERCIAL_MORTAR]
-    },{
+    },
+    {
         'dispName': '机械费价差',
         'calcFun': 'diff',
         'calcType': diffCalc,
         'gljTypes': [gljType.GENERAL_MACHINE]
-    },{
+    },
+    {
         'dispName': '主材费',
         'calcFun': 'budget',
         'calcType': budgetCalc,
         'gljTypes': [gljType.MAIN_MATERIAL]
-    },{
+    },
+    {
         'dispName': '设备费',
         'calcFun': 'budget',
         'calcType': budgetCalc,

+ 87 - 75
web/building_saas/main/js/models/calc_program.js

@@ -255,74 +255,89 @@ let executeObj = {
     },
     base: function(calcBaseName) {
         let me = executeObj, rst = 0,
-            //base = getRationCalcBase(calcBaseName);
             base = me.calcBase[calcBaseName];
 
         if (base != null) {
-            let price = 0, aprice = 0, mprice = 0, tmpSum = 0, mdSum = 0;
-
             function isSubset(sub, arr){
-                // if(!(sub instanceof Array) || !(arr instanceof Array)) return false;
-                // if(sub.length > arr.length) return false;
                 for(var i = 0, len = sub.length; i < len; i++){
                     if(arr.indexOf(sub[i]) == -1) return false;
                 }
                 return true;
-            }
-
+            };
             // 机上人工费:多一层
-            if (isSubset(base.gljTypes, [gljType.MACHINE_LABOUR])) {
-                if (!me.treeNode.data.gljList) tmpSum = 0
-                else{
-                    for (let glj of me.treeNode.data.gljList) {
-                        if (glj.type == gljType.GENERAL_MACHINE) {
-                            // 获取机械组成物
-                            let mds = projectObj.project.composition.getCompositionByCode(glj.code);
-                            if (!mds) mds = [];
-                            for (let md of mds){
-                                if (base.gljTypes.indexOf(md.glj_type) >= 0) {
-                                    price = md["base_price"];
-                                    if (!price) price = 0;
-                                    mdSum = mdSum + (md["consumption"] * price).toDecimal(me.digit);
-                                    mdSum = (mdSum).toDecimal(me.digitDefault);
-                                }
-                            };
-                            tmpSum = tmpSum + (glj["quantity"] * mdSum).toDecimal(me.digitDefault);
-                            tmpSum = (tmpSum).toDecimal(me.digitDefault);
-                        }
+            function machineLabourFee() {
+                if (!me.treeNode.data.gljList) return 0;
+                let result = 0, mdSum = 0;
+                for (let glj of me.treeNode.data.gljList) {
+                    if (glj.type == gljType.GENERAL_MACHINE) {
+                        // 获取机械组成物
+                        let mds = projectObj.project.composition.getCompositionByCode(glj.code);
+                        if (!mds) mds = [];
+                        for (let md of mds){
+                            if (base.gljTypes.indexOf(md.glj_type) >= 0) {
+                                let q = md["consumption"] ? md["consumption"] : 0;
+                                let p = md["base_price"] ? md["base_price"] : 0;
+                                mdSum = mdSum + (q * p).toDecimal(me.digit);
+                                mdSum = (mdSum).toDecimal(me.digitDefault);
+                            }
+                        };
+                        result = result + (glj["quantity"] * mdSum).toDecimal(me.digitDefault);
+                        result = (result).toDecimal(me.digitDefault);
                     };
-                }
-            }else{
-                if (!me.treeNode.data.gljList) tmpSum = 0
-                else{
-                    for (let glj of me.treeNode.data.gljList) {
-                        if (base.gljTypes.indexOf(glj.type) >= 0) {
-                            if (base.calcType == baseCalc){ price = glj["basePrice"];}
-                            else if (base.calcType == adjustCalc){price = glj["adjustPrice"];}
-                            else if (base.calcType == budgetCalc){price = glj["marketPrice"];}
-                            else if (base.calcType == diffCalc){
-                                aprice = glj["adjustPrice"];
-                                if (!aprice) aprice = 0;
-                                mprice = glj["marketPrice"];
-                                if (!mprice) mprice = 0;
-                                price = mprice - aprice;
-                            };
-                            if (!price) price = 0;
-                            tmpSum = tmpSum + (glj["quantity"] * price).toDecimal(me.digitDefault);
-                            tmpSum = (tmpSum).toDecimal(me.digitDefault);
+                };
+                return result;
+            };
+            function commonGLJFee(){
+                if (!me.treeNode.data.gljList) return 0;
+                let result = 0;
+                for (let glj of me.treeNode.data.gljList) {
+                    let price = 0;
+                    if (base.gljTypes.indexOf(glj.type) >= 0) {
+                        if (base.calcType == baseCalc){ price = parseFloat(glj["basePrice"]);}
+                        else if (base.calcType == adjustCalc){price = parseFloat(glj["adjustPrice"]);}
+                        else if (base.calcType == budgetCalc){price = parseFloat(glj["marketPrice"]);}
+                        else if (base.calcType == diffCalc){
+                            let aprice = glj["adjustPrice"] ? glj["adjustPrice"] : 0;
+                            let mprice = glj["marketPrice"] ? glj["marketPrice"] : 0;
+                            price = (parseFloat(mprice) - parseFloat(aprice)).toDecimal(me.digitDefault);
                         };
+                        result = result + (glj["quantity"] * price).toDecimal(me.digitDefault);
+                        result = (result).toDecimal(me.digitDefault);
                     };
                 };
+                return result;
+            };
+            // 量价没有具体的工料机类型,但仍然要用定额的计算程序,所以要给计算基数直接指定。
+            function volumePriceFee() {
+                let result = 0;
+                if (
+                    ( me.treeNode.data.type === '人工' && base.dispName === '定额基价人工费') ||
+                    ( me.treeNode.data.type === '材料' && base.dispName === '定额基价材料费') ||
+                    ( me.treeNode.data.type === '机械' && base.dispName === '定额基价机械费') ||
+                    ( me.treeNode.data.type === '主材' && base.dispName === '主材费') ||
+                    ( me.treeNode.data.type === '设备' && base.dispName === '设备费')
+                ) result = me.treeNode.data.marketUnitFee;
+
+                return result;
             };
 
-            rst = (tmpSum).toDecimal(me.digitDefault);
+            if (me.treeNode.sourceType === projectObj.project.VolumePrice.getSourceType()){
+                rst = volumePriceFee();
+            }
+            else{
+                if (isSubset(base.gljTypes, [gljType.MACHINE_LABOUR]))
+                    rst = machineLabourFee()
+                else
+                    rst = commonGLJFee();
+            }
         };
 
         return rst;
     },
     HJ: function () {
         let me = this;
-        return me.treeNode.calcBaseValue;
+        let rst = me.treeNode.data.marketUnitFee ? me.treeNode.data.marketUnitFee : 0;
+        return rst;
     }
 };
 
@@ -524,7 +539,7 @@ class CalcProgram {
         };
     };
 
-    // 仅内部调用。注意:外部不能直接使用
+    // 仅内部调用。注意:外部不能直接使用,因为这里传入的树节点必须有一定的初始化。
     InnerCalc(treeNode){
         let me = this;
         let project = me.project;
@@ -605,14 +620,18 @@ class CalcProgram {
                     treeNode.data.programID = defaultBillTemplate.ID;
                 };
             }
-            else {
-                if (treeNode.sourceType === project.Ration.getSourceType()) {
-                    treeNode.data.gljList = project.ration_glj.getGljArrByRation(treeNode.data.ID);
-                }
-                else if (treeNode.sourceType === project.Bills.getSourceType()) {
-                    let rations = project.Ration.getBillsSortRation(treeNode.source.getID());
-                    treeNode.data.gljList = project.ration_glj.getGatherGljArrByRations(rations);
+            else if (treeNode.calcType == treeNodeCalcType.ctRationCalcProgram) {
+                let muf = treeNode.data.marketUnitFee ? treeNode.data.marketUnitFee : 0;
+                let q = treeNode.data.quantity ? treeNode.data.quantity : 0;
+                treeNode.data.marketTotalFee = (muf * q).toDecimal(me.digit);
+                treeNode.data.gljList = me.project.ration_glj.getGljArrByRation(treeNode.data.ID);
+                if (treeNode.data.programID == undefined){
+                    treeNode.data.programID = 1;
                 };
+            }
+            else if (treeNode.calcType == treeNodeCalcType.ctBillCalcProgram) {
+                let rations = project.Ration.getBillsSortRation(treeNode.source.getID());
+                treeNode.data.gljList = project.ration_glj.getGatherGljArrByRations(rations);
 
                 if (treeNode.data.programID == undefined){
                     treeNode.data.programID = 1;
@@ -652,35 +671,25 @@ class CalcProgram {
         let me = this;
 
         let isRation = treeNode.sourceType === me.project.Ration.getSourceType();
+        let isVolumePrice = treeNode.sourceType === me.project.VolumePrice.getSourceType();
         let isBill = treeNode.sourceType === me.project.Bills.getSourceType();
-        let isLeafBill = isBill && treeNode.source.children && treeNode.source.children.length === 0;
+        let isLeafBill = isBill && treeNode.source.children && treeNode.source.children.length === 0;   // 是清单且其下没有子清单
         let isBillPriceCalc = me.project.projSetting.billsCalcMode === billsPrice;
 
-        if (isRation)
-            treeNode.calcType = treeNodeCalcType.ctRationCalcProgram
+        if (isRation || isVolumePrice){
+            treeNode.calcType = treeNodeCalcType.ctRationCalcProgram;
+        }
         else if (isLeafBill) {
             if (treeNode.children && treeNode.children.length > 0){
                 me.calcLeafBillChildren(treeNode);
-                if (treeNode.children[0].sourceType == me.project.Ration.getSourceType()){
-                    if (isBillPriceCalc)                   // 清单单价计算模式下的叶子清单:取自己的计算程序ID,找到自己的计算程序计算
-                        treeNode.calcType = treeNodeCalcType.ctBillCalcProgram;
-                    else                                  // 前三种计算模式下的叶子清单:汇总定额的计算程序的费用类别
-                        treeNode.calcType = treeNodeCalcType.ctGatherRations;
-                }
-                else if (treeNode.children[0].sourceType == me.project.VolumePrice.getSourceType()){
-                    let value = 20000;
-                    // if (treeNode.data.feesIndex && treeNode.data.feesIndex.common && treeNode.data.feesIndex.common.unitFee != 0)
-                    //     value = treeNode.data.feesIndex.common.unitFee;
-                    treeNode.calcType = treeNodeCalcType.ctCalcBaseValue;
-                    treeNode.calcBaseValue = value;
-                };
+
+                if (isBillPriceCalc)                        // 清单单价计算模式下的叶子清单:取自己的计算程序ID,找到自己的计算程序计算
+                    treeNode.calcType = treeNodeCalcType.ctBillCalcProgram;
+                else                                        // 前三种计算模式下的叶子清单:汇总定额的计算程序的费用类别
+                    treeNode.calcType = treeNodeCalcType.ctGatherRations;
             }
             else{                                          // 公式计算
-                let value = 20000;
-                // if (treeNode.data.feesIndex && treeNode.data.feesIndex.common && treeNode.data.feesIndex.common.unitFee != 0)
-                //     value = treeNode.data.feesIndex.common.unitFee;
                 treeNode.calcType = treeNodeCalcType.ctCalcBaseValue;
-                treeNode.calcBaseValue = value;
             };
         }
         else if (isBill)                                 // 父清单:汇总子清单的费用类别
@@ -720,8 +729,11 @@ class CalcProgram {
                 let data = {
                     ID: node.data.ID,
                     projectID: me.project.ID(),
+                    type: node.data.type,
                     quantity: node.data.quantity,
                     programID: node.data.programID,
+                    marketUnitFee: node.data.marketUnitFee,
+                    marketTotalFee: node.data.marketTotalFee,
                     fees: node.data.fees
                 };
                 let newData = {'updateType': 'ut_update', 'updateData': data};

+ 17 - 1
web/building_saas/main/js/views/main_tree_col.js

@@ -10,7 +10,11 @@ let MainTreeCol = {
             } else if (node.sourceType === projectObj.project.Ration.getSourceType()) {
                 return '定';
             } else if (node.sourceType === projectObj.project.VolumePrice.getSourceType()) {
-                return '量';
+                if (node.data.type === '人工') return '量人'
+                else if (node.data.type === '材料') return '量材'
+                else if (node.data.type === '机械') return '量机'
+                else if (node.data.type === '主材') return '量主'
+                else if (node.data.type === '设备') return '量设';
             } else if (node.sourceType === projectObj.project.ration_glj.getSourceType()) {
                 return '主';
             }
@@ -23,6 +27,10 @@ let MainTreeCol = {
         }
     },
     readOnly: {
+        type: function (node){
+            return node.sourceType !== projectObj.project.VolumePrice.getSourceType();
+        },
+
         bills: function (node) {
             return node.sourceType === projectObj.project.Bills.getSourceType();
         },
@@ -81,6 +89,14 @@ let MainTreeCol = {
             var names = new GC.Spread.Sheets.CellTypes.ComboBox();
             names.items(projectObj.project.calcProgram.compiledTemplateNames);
             return names;
+        },
+
+        type: function (node) {
+            if (node.sourceType === projectObj.project.VolumePrice.getSourceType()) {
+                let VPType = new GC.Spread.Sheets.CellTypes.ComboBox();
+                VPType.items(["人工","材料","机械","主材","设备"]);
+                return VPType;
+            };
         }
      },
     getEvent: function (eventName) {

+ 16 - 24
web/building_saas/main/js/views/project_view.js

@@ -19,11 +19,7 @@ var projectObj = {
 
         // CSL.2017.07.25
         if (activeSubSheetIs(subSheetIndex.ssiCalcProgram)) {
-            if (node.sourceType === project.Bills.getSourceType() || node.sourceType === project.Ration.getSourceType()) {
-                calcProgramObj.showData(node);
-            } else {
-                calcProgramObj.clearData();
-            };
+            calcProgramObj.showData(node);
         };
         //zhong 2017-9-1 特征及内容
         if(pageCCOprObj.active){
@@ -267,27 +263,23 @@ var projectObj = {
         if (value !== calcFees.getFee(node.data, fieldName)) {
             if (fieldName === 'code') {
                 projectObj.updateCode(node, value);
-            } else if (fieldName === 'quantity' && project.quantity_detail.quantityEditChecking(value,node,fieldName)) {
-                if (value) {value = value.toDecimal(projectObj.project.Decimal.common.quantity);};
-                node.data.quantity = value;
-                node.changed = true;
-                project.calcProgram.calculate(node);
-                project.calcProgram.saveNode(node);
-                // projectObj.updateAndReCalculate(node, fieldName, value);
-            } else if (fieldName === 'feesIndex.common.unitFee') {
-                if (value) {value = value.toDecimal(projectObj.project.Decimal.common.unitFee);};
-                node.data.feesIndex.common.unitFee = value;
-                project.calcProgram.calculate(node);
-                project.calcProgram.saveNode(node);
-                // projectObj.updateAndReCalculate(node, fieldName, value);
-            } else if (fieldName === 'programID') {
-                node.data.programID = value;
+            }
+            else if(fieldName ==='feeRate'){
+                project.FeeRate.updateFeeRateFromBills(value,node,fieldName);
+            }
+            else if (fieldName === 'quantity' || fieldName === 'marketUnitFee' || fieldName === 'programID' || fieldName === 'type'){
+                if (fieldName === 'quantity' && project.quantity_detail.quantityEditChecking(value,node,fieldName)) {
+                    if (value) {value = value.toDecimal(projectObj.project.Decimal.common.quantity)};
+                } else if (fieldName === 'marketUnitFee') {
+                    if (value) {value = parseFloat(value).toDecimal(projectObj.project.Decimal.common.unitFee)};
+                };
+
                 node.changed = true;
+                node.data[fieldName] = value;
                 project.calcProgram.calculate(node);
                 project.calcProgram.saveNode(node);
-            } else if(fieldName ==='feeRate'){
-                project.FeeRate.updateFeeRateFromBills(value,node,fieldName);
-            }else {
+            }
+            else {
                 if (node.sourceType === project.Bills.getSourceType()) {
                     project.Bills.updateField(node.source, fieldName, value, true);
                 } else if (node.sourceType === project.Ration.getSourceType()) {
@@ -369,7 +361,7 @@ var projectObj = {
                     }
                     if (col.data.cellType && Object.prototype.toString.apply(col.data.cellType) === "[object String]") {
                         let getCellType = MainTreeCol.getEvent(col.data.cellType);
-                        col.data.cellType = getCellType();
+                        col.data.cellType = getCellType;
                     }
                     if (col.data.digit && Object.prototype.toString.apply(col.data.digit) === "[object String]") {
                         col.data.decimal = that.project.getDecimal(col.data.digit);

+ 1 - 5
web/building_saas/main/js/views/sub_view.js

@@ -92,11 +92,7 @@ $("#linkJSCX").click(function(){        // 计算程序
     if (!projectObj.mainController.tree.selected)
         projectObj.mainController.tree.selected = projectObj.mainController.tree.firstNode();
     let sel = projectObj.mainController.tree.selected;
-    if (sel.sourceType === projectObj.project.Bills.getSourceType() || sel.sourceType === projectObj.project.Ration.getSourceType()) {
-        calcProgramObj.showData(sel);
-    } else {
-        calcProgramObj.clearData();
-    };
+    calcProgramObj.showData(sel);
     gljOprObj.activeTab='#linkJSCX';
 });