Browse Source

calc price and tender price

zhangweicheng 7 years ago
parent
commit
fdec855c24

+ 22 - 8
modules/main/facade/project_facade.js

@@ -10,8 +10,10 @@ let bill_model = require('../models/bills');
 let consts = require('../models/project_consts');
 let projectConsts = consts.projectConst;
 let ration_glj_model = mongoose.model('ration_glj');
+let project_glj_model = mongoose.model('glj_list');
 let ration_glj_facade = require("../../ration_glj/facade/ration_glj_facade");
 const uuidV1 = require('uuid/v1');
+const gljUtil = require('../../../public/gljUtil');
 
 module.exports = {
     markUpdateProject:markUpdateProject,
@@ -123,6 +125,9 @@ async function updateNodes(datas){
     let nodeGroups = _.groupBy(datas,'type');
     let rationTasks = [];
     let billTasks = [];
+    let rationGLJTasks = [];
+    let projectGLJTasks = [];
+    let projectTasks = [];
     let asyncTasks = [];
     for(let type in nodeGroups){
         for(let node of nodeGroups[type]){
@@ -130,25 +135,34 @@ async function updateNodes(datas){
                 billTasks.push(getTask(node));
             }else if(type == projectConsts.RATION){
                 rationTasks.push(getTask(node));
+            }else if(type == projectConsts.RATION_GLJ){
+                rationGLJTasks.push(getTask(node));
+            }else if(type == projectConsts.PROJECTGLJ){
+                projectGLJTasks.push(getTask(node,'id'));
+            }else if(type == projectConsts.PROJECT){
+                projectTasks.push(getTask(node));
             }
+
         }
     }
     rationTasks.length>0?asyncTasks.push(ration_model.model.bulkWrite(rationTasks)):'';
     billTasks.length>0?asyncTasks.push(bill_model.model.bulkWrite(billTasks)):"";
+    rationGLJTasks.length>0?asyncTasks.push(ration_glj_model.bulkWrite(rationGLJTasks)):"";
+    projectGLJTasks.length>0?asyncTasks.push(project_glj_model.bulkWrite(projectGLJTasks)):"";
+    projectTasks.length>0?asyncTasks.push(projectsModel.bulkWrite(projectTasks)):"";
     return  asyncTasks.length>0?await Promise.all(asyncTasks):"";
 
-    function getTask(node) {
+    function getTask(node,idFiled = 'ID') {
+
         let task={
             updateOne:{
-                filter:{
-                    //projectID: node.data.projectID, 现在复制项目也重新生成一个新的ID了,所以ID是唯一的
-                    ID: node.data.ID
-                    //deleteInfo: null
-                },
-                update :node.data
+                filter:{},
+                update :_.cloneDeep(node.data)
             }
         };
-       return task;
+        task.updateOne.filter[idFiled] = node.data[idFiled];//现在复制项目也重新生成一个新的ID了,所以ID是唯一的
+        delete task.updateOne.update[idFiled];//防止误操作
+        return task;
     }
 }
 

+ 1 - 0
modules/main/models/project_consts.js

@@ -2,6 +2,7 @@
  * Created by jimiz on 2017/4/18.
  */
 let projectConst = {
+    PROJECT: 'project',
     BILLS: 'bills',
     RATION: 'ration',
     GLJ: 'GLJ',

+ 26 - 1
public/gljUtil.js

@@ -10,9 +10,34 @@ let data = fs.readFileSync(__dirname + '/web/gljUtil.js', 'utf8', 'r');
 eval(data + ' ; gljNodeUtil = gljUtil; ');
 
 module.exports = {
-    calcProjectGLJQuantity :calcProjectGLJQuantity
+    calcProjectGLJQuantity :calcProjectGLJQuantity,
+    getGLJPrice:getGLJPrice,
+    calcPriceDiff:calcPriceDiff,
+    getMarketPrice:getMarketPrice,
+    getBasePrice:getBasePrice,
+    getAdjustPrice:getAdjustPrice
 };
 
 function calcProjectGLJQuantity(projectGLJDatas,rationGLJDatas,rationDatas,billsDatas,q_decimal) {
     gljNodeUtil.calcProjectGLJQuantity(projectGLJDatas,rationGLJDatas,rationDatas,billsDatas,q_decimal,_,scMathUtil);
+}
+
+function getGLJPrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio=false) {
+    return gljNodeUtil.getGLJPrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil);
+}
+
+function getMarketPrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio=false) {
+    return gljNodeUtil.getMarketPrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil);
+}
+
+function getBasePrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio=false) {
+    return gljNodeUtil.getBasePrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil);
+}
+
+function getAdjustPrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio=false,_,scMathUtil) {
+    return gljNodeUtil.getAdjustPrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil);
+}
+
+function calcPriceDiff(glj,calcOptions) {
+    gljNodeUtil.calcPriceDiff(glj,calcOptions);
 }

+ 141 - 8
public/web/gljUtil.js

@@ -2,13 +2,16 @@
  * Created by zhang on 2018/6/7.
  */
 
+
+
+
 let gljUtil = {
     calcProjectGLJQuantity:function (projectGLJDatas,rationGLJDatas,rationDatas,billsDatas,q_decimal,_,scMathUtil) {
         let project_gljs = projectGLJDatas.gljList;
         let mixRatioMap = projectGLJDatas.mixRatioMap;
         let rations = rationDatas;
         let rationMap = _.indexBy(rations,'ID');
-        let quantityMap={},changeArray=[];
+        let quantityMap={};
         let rationGljGroup = _.groupBy(rationGLJDatas,'projectGLJID');
         let [billIDs,tech_billIDS] = this.getSubdivisionAndTechBillsLeavesID(billsDatas);//分别取分部分项和技术措施项目的所有叶子清单ID
         for(let pglj of project_gljs ){
@@ -82,9 +85,9 @@ let gljUtil = {
         return result;
     },
     getSubdivisionAndTechBillsLeavesID:function (billsDatas) {//分别取分部分项和技术措施项目的所有叶子清单ID
-       /* if(projectObj){//存在,说明在前端调用
+        if(projectObj){//存在,说明在前端调用
             return [projectObj.project.Bills.getSubdivisionProjectLeavesID(),projectObj.project.Bills.getTechLeavesID()];
-        }*/
+        }
         let parentMap ={};
         let subdivisionBillID  = null,techBillID = null,sIDs = [],tIDS = [];
         for(let b of billsDatas){
@@ -116,11 +119,110 @@ let gljUtil = {
                     }
                 }
             }
-
         }
-
-
-
+    },
+    getGLJPrice:function (glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio=false,_,scMathUtil) {
+        let result = {};
+        result.marketPrice = this.getMarketPrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil);
+        if(this.calcPriceDiff(glj,calcOptions)==true){//计取价差
+            result.basePrice = this.getBasePrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil);
+            result.adjustPrice = this.getAdjustPrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil);
+        }else {//不计价差
+            result.basePrice = result.marketPrice;
+            result.adjustPrice = result.marketPrice;
+        }
+        return result;
+    },
+    getMarketPrice:function (glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil) {
+        let price_decimal = decimalObj.glj.unitPrice;
+        let quantity_decimal = decimalObj.glj.quantity;
+        let process_decimal = decimalObj.process;
+        if (this.notEditType.indexOf(glj.unit_price.type)!=-1&&glj.ratio_data.length>0) {//对于混凝土、配合比、砂浆、机械台班等有组成物的材料,价格需根据组成物计算得出。
+            let p =0;
+            for(let ratio of glj.ratio_data){
+                let tem =  _.find(projectGLJDatas.gljList,{
+                    'code': ratio.code,
+                    'name': ratio.name,
+                    'specs':ratio.specs,
+                    'type': ratio.type,
+                    'unit': ratio.unit
+                });
+                if(tem){
+                    let priceData=this.getGLJPrice(tem,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,true,_,scMathUtil);
+                    p+=scMathUtil.roundForObj(priceData.marketPrice*scMathUtil.roundForObj(ratio.consumption,quantity_decimal),process_decimal);
+                }
+            }
+            return scMathUtil.roundForObj(p,price_decimal);
+        }else {
+            let tem_decimal = isRadio==true?process_decimal:price_decimal;
+            return scMathUtil.roundForObj(glj.unit_price.market_price,tem_decimal);
+        }
+    },
+    getBasePrice:function (glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil) {
+        let price_decimal = decimalObj.glj.unitPrice;
+        let quantity_decimal = decimalObj.glj.quantity;
+        let process_decimal = decimalObj.process;
+        if (this.notEditType.indexOf(glj.unit_price.type)!=-1&&glj.ratio_data.length>0) {//对于混凝土、配合比、砂浆、机械台班等有组成物的材料,价格需根据组成物计算得出。
+            let p =0;
+            for(let ratio of glj.ratio_data){
+                let tem =  _.find( projectGLJDatas.gljList,{
+                    'code': ratio.code,
+                    'name': ratio.name,
+                    'specs':ratio.specs,
+                    'type': ratio.type,
+                    'unit': ratio.unit
+                });
+                if(tem){
+                    let priceData=this.getGLJPrice(tem,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,true,_,scMathUtil);
+                    p+=scMathUtil.roundForObj(priceData.basePrice*scMathUtil.roundForObj(ratio.consumption,quantity_decimal),process_decimal);
+                }
+            }
+            return scMathUtil.roundForObj(p,price_decimal);
+        }else {
+            let tem_decimal = isRadio==true?process_decimal:price_decimal;
+            return scMathUtil.roundForObj(glj.unit_price.base_price,tem_decimal);
+        }
+    },
+    getAdjustPrice:function (glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio=false,_,scMathUtil) {
+        let decimal = decimalObj.glj.unitPrice;
+        let quantity_decimal =  decimalObj.glj.quantity;
+        let process_decimal = decimalObj.process;
+        let  tem_decimal = isRadio==true?process_decimal:decimal;
+        if (glj.unit_price.type == this.gljType.LABOUR || glj.unit_price.type == this.gljType.MACHINE_LABOUR) {//人工、机上人工,调整价根据定额价*调整系数计算得出。
+            let labour = _.find(labourCoeDatas.coes,{'ID':glj.adjCoe});
+            let coe = labour && labour.coe ? labour.coe : 1;
+            return scMathUtil.roundTo(parseFloat(coe * scMathUtil.roundForObj(glj.unit_price.base_price,tem_decimal)), -tem_decimal);
+        } else if (notEditType.indexOf(glj.unit_price.type)!=-1&&glj.ratio_data.length>0) {//对于混凝土、配合比、砂浆、机械台班,调整价根据组成物计算得出。
+            let p =0;
+            for(let ratio of glj.ratio_data){
+                let tem =  _.find( projectGLJDatas.gljList,{
+                    'code': ratio.code,
+                    'name': ratio.name,
+                    'specs':ratio.specs,
+                    'type': ratio.type,
+                    'unit': ratio.unit
+                })
+                if(tem){
+                    let priceData=this.getGLJPrice(tem,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,true,_,scMathUtil);
+                    p+=scMathUtil.roundForObj(priceData.adjustPrice*scMathUtil.roundForObj(ratio.consumption,quantity_decimal),process_decimal);
+                }
+            }
+            return scMathUtil.roundForObj(p,decimal);
+        } else {//对于其他普通材料等,无调整系数,调整价=定额价。
+            return glj.unit_price.base_price
+        }
+    },
+    calcPriceDiff:function (glj,calcOptions) {
+        if(glj.is_evaluate==1){//先按是否暂估判断
+            return calcOptions.calc_est;
+        }
+        if(glj.type==gljType.MAIN_MATERIAL||glj.type==gljType.EQUIPMENT){//再判断是否是主材和设备
+            return calcOptions.calc_main;
+        }
+        if(glj.unit_price.is_add==1){//再判断是否新增
+            return calcOptions.calc_add;
+        }
+        return true;
     },
     isFlag : function (v) {
         return this.isDef(v.flagsIndex) && this.isDef(v.flagsIndex.fixed) && this.isDef(v.flagsIndex.fixed.flag);
@@ -146,5 +248,36 @@ let gljUtil = {
         MEASURE: 2,
         // 施工技术措施项目
         CONSTRUCTION_TECH: 3
-    }
+    },
+    gljType : {
+        // 人工
+        LABOUR: 1,
+        // ==============材料类型=================
+        // 普通材料
+        GENERAL_MATERIAL: 201,
+        // 混凝土
+        CONCRETE: 202,
+        // 砂浆
+        MORTAR: 203,
+        // 配合比
+        MIX_RATIO: 204,
+        // 商品混凝土
+        COMMERCIAL_CONCRETE: 205,
+        // 商品砂浆
+        COMMERCIAL_MORTAR: 206,
+        // ==============材料类型=================
+        // ==============机械类型=================
+        // 机械台班
+        GENERAL_MACHINE: 301,
+        // 机械组成物
+        MACHINE_COMPOSITION: 302,
+        // 机上人工
+        MACHINE_LABOUR: 303,
+        // ==============机械类型=================
+        // 主材
+        MAIN_MATERIAL: 4,
+        // 设备
+        EQUIPMENT: 5
+    },
+     notEditType : [202, 203,204, 301, 4],
 }

+ 12 - 5
web/building_saas/main/html/tender_price.html

@@ -1,17 +1,24 @@
 <div class="toolsbar px-1">
     <div class="btn-toolbar py-1">
-        <div class="input-group input-group-sm mr-2" style="width:220px">
+
+        <select class="form-control mr-2" style="width: auto; font-size: .875rem" id="calcPriceOption">
+            <option value="coeBase">根据调整系数计算报价</option>
+            <option value="priceBase" >根据报价计算调整系数</option>
+        </select>
+
+        <div class="input-group input-group-sm mr-2" style="width:240px">
             <div class="input-group-prepend">
                 <span class="input-group-text" id="inputGroup-sizing-sm">工料机单价调整系数</span>
             </div>
-            <input type="number" step="0.1" class="form-control" placeholder="请输入系数" value="1">
+            <input id = 'gljPriceTenderCoe' type="number" step="0.1" class="form-control" placeholder="请输入系数" value="1">
         </div>
         <div class="btn-group mr-2">
-            <button type="button" class="btn btn-outline-primary btn-sm">反调消耗</button>
+            <button type="button" class="btn btn-outline-primary btn-sm" id = "tenderGLJQuantity">调整人材机消耗</button>
+            <button type="button" class="btn btn-outline-primary btn-sm" id = "tenderRationQuantity">调整子目工程量</button>
            <!-- <button type="button" class="btn btn-outline-primary btn-sm">反调单价</button>-->
-            <button type="button" class="btn btn-outline-primary btn-sm">正向调价</button>
+            <button type="button" class="btn btn-outline-primary btn-sm" id = "tenderPrice">调价计算</button>
         </div>
-        <button type="button" class="btn btn-outline-danger btn-sm">清空调价</button>
+        <button type="button" class="btn btn-outline-danger btn-sm" id = "cleanTender">清空调价</button>
     </div>
 </div>
 <div class="container-fluid">

+ 1 - 0
web/building_saas/main/js/models/main_consts.js

@@ -2,6 +2,7 @@
  * Created by jimiz on 2017/4/19.
  */
 const ModuleNames = {
+    project:'project',
     bills: 'bills',
     ration: 'ration',
     GLJ: 'GLJ',

+ 24 - 164
web/building_saas/main/js/models/project_glj.js

@@ -594,92 +594,29 @@ ProjectGLJ.prototype.setAdjustPrice = function (glj) {
 }
 
 ProjectGLJ.prototype.getAdjustPrice = function (glj,isRadio) {
-    GLJTypeConst = this.datas.constData.GLJTypeConst !== undefined ? JSON.parse(this.datas.constData.GLJTypeConst) : GLJTypeConst;
-    let decimal = getDecimal("glj.unitPrice");
-    let quantity_decimal = getDecimal("glj.quantity");
-    let process_decimal = getDecimal("process");
-    let  tem_decimal = isRadio==true?process_decimal:decimal;
-    if (glj.unit_price.type == GLJTypeConst.LABOUR || glj.unit_price.type == GLJTypeConst.MACHINE_LABOUR) {//人工、机上人工,调整价根据定额价*调整系数计算得出。
-        let labour = projectObj.project.calcProgram.compiledLabourCoes[glj.adjCoe];
-        //let labour=1;
-        let coe = labour && labour.coe ? labour.coe : 1;
-        return scMathUtil.roundTo(parseFloat(coe * scMathUtil.roundForObj(glj.unit_price.base_price,tem_decimal)), -tem_decimal);
-    } else if (notEditType.indexOf(glj.unit_price.type)!=-1&&glj.ratio_data.length>0) {//对于混凝土、配合比、砂浆、机械台班,调整价根据组成物计算得出。
-        let p =0;
-        for(let ratio of glj.ratio_data){
-           let tem =  _.find( projectObj.project.projectGLJ.datas.gljList,{
-               'code': ratio.code,
-               'name': ratio.name,
-               'specs':ratio.specs,
-               'type': ratio.type,
-               'unit': ratio.unit
-           })
-            if(tem){
-                let priceData={};
-                gljOprObj.setGLJPrice(priceData,tem,true);
-                p+=scMathUtil.roundForObj(priceData.adjustPrice*scMathUtil.roundForObj(ratio.consumption,quantity_decimal),process_decimal);
-            }
-        }
-        return scMathUtil.roundForObj(p,decimal);
-    } else {//对于其他普通材料等,无调整系数,调整价=定额价。
-        return glj.unit_price.base_price
-    }
+    let proGLJ =  projectObj.project.projectGLJ;
+    let calcOptions=projectInfoObj.projectInfo.property.calcOptions;
+    let decimalObj = projectInfoObj.projectInfo.property.decimal;
+    let labourCoeDatas =  projectObj.project.labourCoe.datas;
+    return gljUtil.getAdjustPrice(glj,proGLJ.datas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil);
 };
 
 ProjectGLJ.prototype.getBasePrice = function(glj,isRadio){
-    let price_decimal = getDecimal("glj.unitPrice");
-    let quantity_decimal = getDecimal("glj.quantity");
-    let process_decimal = getDecimal("process");
-    if (notEditType.indexOf(glj.unit_price.type)!=-1&&glj.ratio_data.length>0) {//对于混凝土、配合比、砂浆、机械台班等有组成物的材料,价格需根据组成物计算得出。
-        let p =0;
-        for(let ratio of glj.ratio_data){
-            let tem =  _.find( projectObj.project.projectGLJ.datas.gljList,{
-                'code': ratio.code,
-                'name': ratio.name,
-                'specs':ratio.specs,
-                'type': ratio.type,
-                'unit': ratio.unit
-            });
-            if(tem){
-                let priceData={};
-                gljOprObj.setGLJPrice(priceData,tem,true);
-                p+=scMathUtil.roundForObj(priceData.basePrice*scMathUtil.roundForObj(ratio.consumption,quantity_decimal),process_decimal);
-            }
-        }
-        return scMathUtil.roundForObj(p,price_decimal);
-    }else {
-        let tem_decimal = isRadio==true?process_decimal:price_decimal;
-        return scMathUtil.roundForObj(glj.unit_price.base_price,tem_decimal);
-    }
+    let proGLJ =  projectObj.project.projectGLJ;
+    let calcOptions=projectInfoObj.projectInfo.property.calcOptions;
+    let decimalObj = projectInfoObj.projectInfo.property.decimal;
+    let labourCoeDatas =  projectObj.project.labourCoe.datas;
+    return gljUtil.getBasePrice(glj,proGLJ.datas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil);
 };
 
 
 ProjectGLJ.prototype.getMarketPrice = function (glj,isRadio) {
-    let price_decimal = getDecimal("glj.unitPrice");
-    let quantity_decimal = getDecimal("glj.quantity");
-    let process_decimal = getDecimal("process");
-    if (notEditType.indexOf(glj.unit_price.type)!=-1&&glj.ratio_data.length>0) {//对于混凝土、配合比、砂浆、机械台班等有组成物的材料,价格需根据组成物计算得出。
-        let p =0;
-        for(let ratio of glj.ratio_data){
-            let tem =  _.find( projectObj.project.projectGLJ.datas.gljList,{
-                'code': ratio.code,
-                'name': ratio.name,
-                'specs':ratio.specs,
-                'type': ratio.type,
-                'unit': ratio.unit
-            });
-            if(tem){
-                let priceData={};
-                gljOprObj.setGLJPrice(priceData,tem,true);
-                p+=scMathUtil.roundForObj(priceData.marketPrice*scMathUtil.roundForObj(ratio.consumption,quantity_decimal),process_decimal);
-            }
-        }
-        return scMathUtil.roundForObj(p,price_decimal);
-    }else {
-        let tem_decimal = isRadio==true?process_decimal:price_decimal;
-        return scMathUtil.roundForObj(glj.unit_price.market_price,tem_decimal);
-    }
-}
+    let proGLJ =  projectObj.project.projectGLJ;
+    let calcOptions=projectInfoObj.projectInfo.property.calcOptions;
+    let decimalObj = projectInfoObj.projectInfo.property.decimal;
+    let labourCoeDatas =  projectObj.project.labourCoe.datas;
+    return gljUtil.getMarketPrice(glj,proGLJ.datas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil);
+};
 
 ProjectGLJ.prototype.isEstimateType = function(type){
     let typeString = type + "";
@@ -696,42 +633,13 @@ ProjectGLJ.prototype.getShortNameByID = function (ID) {
 
 ProjectGLJ.prototype.calcQuantity  = function (init=false){
     let project_gljs = this.datas.gljList;
-    let mixRatioConnectData = this.datas.mixRatioConnectData;
-    let mixRatioMap = this.datas.mixRatioMap;
-    let rations = projectObj.project.Ration.datas;
-    let rationMap = _.indexBy(rations,'ID');
-    let quantityMap={},changeArray=[];
-    let rationGljGroup = _.groupBy(projectObj.project.ration_glj.datas,'projectGLJID')
-    let q_decimal = getDecimal("glj.quantity");
-    for(let pglj of project_gljs ){
-        let pg_index = gljOprObj.getIndex(pglj,gljKeyArray);
-        pglj.subdivisionQuantity = 0;
-        pglj.techQuantity = 0;
-        pglj.quantity = 0;
-        let gljGroup = rationGljGroup[pglj.id]?rationGljGroup[pglj.id]:[];//定额工料机没有,有可能是定额类型的工料机
-        let result = this.getQuantityPerGLJ(gljGroup,rations,rationMap,pglj,quantityMap);
-        pglj.subdivisionQuantity = result.subdivisionQuantity;
-        pglj.techQuantity = result.techQuantity;
-        pglj.quantity = result.quantity;
-        quantityMap[pg_index] = pglj;
-    }
-    //计算做为组成物的消耗量
-    for(let pkey in mixRatioMap){
-        let mixRatioList = mixRatioMap[pkey];
-        for(let m of mixRatioList){
-            let m_index = gljOprObj.getIndex(m,gljKeyArray);
-            let m_glj = quantityMap[m_index];
-            let p_glj = quantityMap[pkey];
-            if(m_glj&&p_glj){
-                let quantity = scMathUtil.roundForObj(p_glj.quantity*parseFloat(m.consumption),q_decimal);
-                let techQuantity = scMathUtil.roundForObj(p_glj.techQuantity*parseFloat(m.consumption),q_decimal);
-                let subdivisionQuantity = scMathUtil.roundForObj(p_glj.subdivisionQuantity*parseFloat(m.consumption),q_decimal);
-                m_glj.quantity =  scMathUtil.roundForObj(m_glj.quantity+quantity,q_decimal);
-                m_glj.techQuantity =  scMathUtil.roundForObj(m_glj.techQuantity+techQuantity,q_decimal);
-                m_glj.subdivisionQuantity =  scMathUtil.roundForObj(m_glj.subdivisionQuantity+subdivisionQuantity,q_decimal);
-            }
-        }
-    }
+    let changeArray=[];
+    let rationGLJDatas = projectObj.project.ration_glj.datas;
+    let rationDatas = projectObj.project.Ration.datas;
+    let billsDatas = projectObj.project.Bills.datas;
+
+    gljUtil.calcProjectGLJQuantity(this.datas,rationGLJDatas,rationDatas,billsDatas,getDecimal("glj.quantity"),_,scMathUtil);
+
     if(init == true || this.quantityChangeMap == null){//如果是初始化,建立一个映射表
         this.quantityChangeMap = {};
         for(let pglj of project_gljs){
@@ -751,52 +659,4 @@ ProjectGLJ.prototype.calcQuantity  = function (init=false){
         }
     }
     changeArray.length > 0 && projectGljObject.calcPartASupplyFeeByProjectGLJs ?projectGljObject.calcPartASupplyFeeByProjectGLJs(changeArray):'';
-
-
-
-};
-
-ProjectGLJ.prototype.getQuantityPerGLJ = function (ration_glj_list,rations,rationMap,pglj) {
-    let billIDs =   projectObj.project.Bills.getSubdivisionProjectLeavesID();//取分部分项上的所有叶子清单ID
-    let tech_billIDS =  projectObj.project.Bills.getTechLeavesID();//取所有技术措施项目叶子清单IDs
-    let mixRatioMap = this.datas.mixRatioMap;
-    let q_decimal = getDecimal("glj.quantity");
-    let result={};
-    let quantity_sum=0;//工料机汇总消耗量
-    let sum = 0;//分部分项总消耗量
-    let tech_sum = 0;//技术措施总消耗量
-    for(let rg of ration_glj_list){
-            let tem_ration = rationMap[rg.rationID];
-            let r_quantity = tem_ration?scMathUtil.roundForObj(tem_ration.quantity,q_decimal):0;
-            let glj_quantity = scMathUtil.roundForObj(rg.quantity, q_decimal);
-            if(!r_quantity){
-                continue;
-            }
-            let total = scMathUtil.roundForObj(glj_quantity*r_quantity, q_decimal);
-            quantity_sum = scMathUtil.roundForObj(quantity_sum+total,q_decimal);
-            if(_.includes(billIDs,rg.billsItemID)){//计算分部分项
-                sum = scMathUtil.roundForObj(sum+total,q_decimal);
-            }
-            if(_.includes(tech_billIDS,rg.billsItemID)){//计算技术措施项目消耗量
-                tech_sum = scMathUtil.roundForObj(tech_sum+total,q_decimal);
-            }
-    }
-    for(let ra of rations){//计算定额类型工料机的消耗量
-        if(ra.type == rationType.gljRation&&ra.projectGLJID===pglj.id){
-            let r_quantity = scMathUtil.roundForObj(ra.quantity,q_decimal);
-            r_quantity = r_quantity?r_quantity:0;
-            quantity_sum = scMathUtil.roundForObj(quantity_sum+r_quantity,q_decimal);
-            if(_.includes(billIDs,ra.billsItemID)){//计算分部分项
-                sum = scMathUtil.roundForObj(sum+r_quantity,q_decimal);
-            }
-            if(_.includes(tech_billIDS,ra.billsItemID)){//计算技术措施项目消耗量
-                tech_sum = scMathUtil.roundForObj(tech_sum+r_quantity,q_decimal);
-            }
-        }
-
-    }
-    result.subdivisionQuantity = sum;
-    result.techQuantity = tech_sum;
-    result.quantity = quantity_sum;
-    return result;
-} 
+};

+ 8 - 18
web/building_saas/main/js/views/glj_view.js

@@ -744,15 +744,14 @@ var gljOprObj = {
     },
     setGLJPrice:function (data,glj,isRadio = false) {//isRadio 标记是否算组成物的价格
         let proGLJ =  projectObj.project.projectGLJ;
+        let calcOptions=projectInfoObj.projectInfo.property.calcOptions;
+        let decimalObj = projectInfoObj.projectInfo.property.decimal;
+        let labourCoeDatas =  projectObj.project.labourCoe.datas;
         glj = glj?glj:_.find(proGLJ.datas.gljList, {'id': data.projectGLJID});
-        data.marketPrice = proGLJ.getMarketPrice(glj,isRadio);
-        if(this.calcPriceDiff(glj)==true) {//计取价差
-            data.basePrice = proGLJ.getBasePrice(glj,isRadio);
-            data.adjustPrice = proGLJ.getAdjustPrice(glj,isRadio);
-        }else {//不计价差
-            data.basePrice = proGLJ.getMarketPrice(glj,isRadio);
-            data.adjustPrice = proGLJ.getMarketPrice(glj,isRadio);
-        }
+        let result = gljUtil.getGLJPrice(glj,proGLJ.datas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil);
+        data.marketPrice = result.marketPrice;
+        data.basePrice =  result.basePrice;
+        data.adjustPrice = result.adjustPrice;
         return data;
 
     },
@@ -767,16 +766,7 @@ var gljOprObj = {
     },
     calcPriceDiff:function (glj) {
         let calcOptions=projectInfoObj.projectInfo.property.calcOptions;
-        if(glj.is_evaluate==1){//先按是否暂估判断
-            return calcOptions.calc_est;
-        }
-        if(glj.type==gljType.MAIN_MATERIAL||glj.type==gljType.EQUIPMENT){//再判断是否是主材和设备
-            return calcOptions.calc_main;
-        }
-        if(glj.unit_price.is_add==1){//再判断是否新增
-            return calcOptions.calc_add;
-        }
-        return true;
+        return gljUtil.calcPriceDiff(glj,calcOptions);
     },
     getIndex(obj, pops){
         let t_index = '';

+ 1 - 1
web/building_saas/main/js/views/project_glj_view.js

@@ -794,7 +794,7 @@ projectGljObject={
                       projectObj.mainController.refreshTreeNode(projectObj.project.mainTree.roots);
                   });
               }
-        };
+        }
     }
 };
 

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

@@ -646,7 +646,6 @@ var projectObj = {
                 });
                 let startShowTime = +new Date();
                 that.mainController = TREE_SHEET_CONTROLLER.createNew(that.project.mainTree, that.mainSpread.getActiveSheet(), that.project.projSetting.mainGridSetting);
-
                 that.mainController.showTreeData();
                 let endShowTime = +new Date();
                 console.log(`show data时间——${endShowTime - startShowTime}`);

+ 181 - 10
web/building_saas/main/js/views/tender_price_view.js

@@ -9,26 +9,27 @@ let tender_obj={
     tenderController:null,
     tenderSetting:{
         header:[
-            {headerName: "项目编码", headerWidth: 170, dataCode: "code", dataType: "String",spanRows: [2]},
-            {headerName: "类别", headerWidth: 50, dataCode: "subType", dataType: "String",spanRows: [2]},
+            {headerName: "项目编码", headerWidth: 170, dataCode: "code", dataType: "String",spanRows: [2],getText:'getText.code'},
+            {headerName: "类别", headerWidth: 50, dataCode: "subType", hAlign: "center", dataType: "String",spanRows: [2],getText:'getText.subType'},
             {headerName: "项目名称", headerWidth: 200, dataCode: "name",showHint:true, hAlign: "left", dataType: "String",spanRows: [2]},
-            {headerName: "计量\n单位", headerWidth: 120, dataCode: "unit", hAlign: "center", dataType: "String",spanRows: [2]},
+            {headerName: "计量\n单位", headerWidth: 60, dataCode: "unit", hAlign: "center", dataType: "String",spanRows: [2]},
             {headerName: "工程量", headerWidth: 120, dataCode: "basePrice", hAlign: "right", dataType: "Number",validator:"number",spanRows: [2]},
             {headerName: "不调价", headerWidth: 55, dataCode: "is_adjust_price", hAlign: "center", cellType : "checkBox",dataType: "Number",spanRows: [2]},
             {headerName: ["初始报价","综合单价"], headerWidth: 80, dataCode: "feesIndex.common.unitFee", hAlign: "right", dataType: "Number",validator:"number",spanCols : [2,1]},
             {headerName: ["","综合合价"], headerWidth: 80, dataCode: "feesIndex.common.totalFee", hAlign: "right", dataType: "Number",validator:"number",spanCols : [0,1]},
-            {headerName: ["反向目标","综合单价"], headerWidth: 80, dataCode: "feesIndex.common.targetUnitFee", hAlign: "right", dataType: "Number",validator:"number",spanCols : [2,1]},
-            {headerName: ["","综合合价"], headerWidth: 80, dataCode: "feesIndex.common.targetTotalFee", hAlign: "right", dataType: "Number",validator:"number",spanCols : [0,1]},
+            {headerName: ["目标造价","综合单价"], headerWidth: 80, dataCode: "targetUnitFee", hAlign: "right", dataType: "Number",validator:"number",spanCols : [2,1]},
+            {headerName: ["","综合合价"], headerWidth: 80, dataCode: "targetTotalFee", hAlign: "right", dataType: "Number",validator:"number",spanCols : [0,1]},
             {headerName: ["调整后报价","综合单价"], headerWidth: 80, dataCode: "feesIndex.common.tenderUnitFee", hAlign: "right", dataType: "Number",validator:"number",spanCols : [2,1]},
             {headerName: ["","综合合价"], headerWidth: 80, dataCode: "feesIndex.common.tenderTotalFee", hAlign: "right", dataType: "Number",validator:"number",spanCols : [0,1]},
             {headerName: ["消耗量调整系数","人工"], headerWidth: 80, dataCode: "quantityCoe.labour", hAlign: "right", dataType: "Number",validator:"number",spanCols : [5,1]},
             {headerName: ["","材料"], headerWidth: 80, dataCode: "quantityCoe.material", hAlign: "right", dataType: "Number",validator:"number",spanCols : [0,1]},
             {headerName: ["","机械"], headerWidth: 80, dataCode: "quantityCoe.machine", hAlign: "right", dataType: "Number",validator:"number",spanCols : [0,1]},
             {headerName: ["","主材"], headerWidth: 80, dataCode: "quantityCoe.main", hAlign: "right", dataType: "Number",validator:"number",spanCols : [0,1]},
-            {headerName: ["","设备"], headerWidth: 80, dataCode: "quantityCoe.equipment", hAlign: "right", dataType: "Number",validator:"number",spanCols : [0,1]}
+            {headerName: ["","设备"], headerWidth: 80, dataCode: "quantityCoe.equipment", hAlign: "right", dataType: "Number",validator:"number",spanCols : [0,1]},
+            {headerName: "子目工程量\n调整系数", headerWidth: 100, dataCode: "rationQuantityCoe", hAlign: "center", dataType: "Number",spanRows: [2],validator:"number"}
         ],
         view: {
-            lockColumns: [0,1,2,3,4,5,6,7,10,11]
+            lockColumns: [0,1,2,3,4,6,7,10,11]
         }
     },
     tenderTreeSetting:{
@@ -48,10 +49,13 @@ let tender_obj={
         TREE_SHEET_HELPER.initSetting($('#tenderSpread')[0], this.tenderTreeSetting );
         this.tenderTreeSetting.setAutoFitRow = MainTreeCol.getEvent("setAutoFitRow");
         this.tenderController = TREE_SHEET_CONTROLLER.createNew(this.tenderTree, this.tenderSheet, this.tenderTreeSetting);
+        this.tenderSheet.bind(GC.Spread.Sheets.Events.ValueChanged, this.onSheetValueChange);
+        this.tenderSheet.bind(GC.Spread.Sheets.Events.EditStarting,this.onEditStarting);
+
        // this.tenderController.bind(TREE_SHEET_CONTROLLER.eventName.treeSelectedChanged, this.onSelectionChange);
     },
     createTenderTreeSetting:function () {
-       return sheetCommonObj.transferToTreeSetting(this.tenderSetting,this.tenderTreeSetting);
+       return sheetCommonObj.transferToTreeSetting(this.tenderSetting,this.tenderTreeSetting,MainTreeCol);
     },
     showTenderData:function () {
         let me = this;
@@ -61,6 +65,7 @@ let tender_obj={
             createTenderNode(r,null,null);
         }
         me.tenderTree.sortTreeItems();
+        this.tenderSheet.setRowCount(0);
         me.tenderController.showTreeData();
 
         function createTenderNode(mainNode,parent,next) {
@@ -78,11 +83,153 @@ let tender_obj={
                 return newNode;
             }
         }
-    }
+    },
+    onSheetValueChange : function (sender,args) {
+        let me = tender_obj, row = args.row, col = args.col;
+        let node = me.tenderTree.items[row];
+        let dataCode = me.tenderSetting.header[col].dataCode;
+        let value = args.newValue;
+        let updateData = {type:node.sourceType,data:{'ID' : node.data.ID}};
+        let datas = [],nodes = [];
 
-};
+        if (value&&!projectGljObject.checkData(col,me.tenderSetting,value)) {
+            setTimeout(function () {//为了不与click事件冲突
+                alert('输入的数据类型不对,请重新输入!');
+            },200);
+            updateData = null;
+        }
+        if(dataCode == 'is_adjust_price'){//不调价,修改父项后,子项也跟着更新
+            if(value == true){
+                value = 1;
+            }else if(value == false){
+                value = 0;
+            }
+            me.updateChildrenValue(node,dataCode,value,datas,nodes);
+        }
+        if(updateData&&dataCode.indexOf("Coe") != -1 ){//如果是调整系统项,级联更新子项
+            value = scMathUtil.roundForObj(value,getDecimal('process'));
+            me.updateChildrenValue(node,dataCode,value,datas,nodes);
+        }
+
+
+        //在目标造价综合单价中输入数值,按项目属性中的清单单价精度取舍,并清空当前行的目标造价综合合价
+        if(dataCode == 'targetUnitFee'){
+            value = scMathUtil.roundForObj(value,getDecimal('unitPrice',node));
+            updateData?updateData.data["targetTotalFee"] = null:'';
+        }
+        if(dataCode == 'targetTotalFee'){
+            value = scMathUtil.roundForObj(value,getDecimal('totalPrice',node));
+            updateData?updateData.data["targetUnitFee"] = null:'';
+        }
+        if(updateData){
+            updateData.data[dataCode] = value;
+            datas.push(updateData);
+        }
+        nodes.push(node);
+        me.updateTenderData(datas,function () {
+            me.tenderController.refreshTreeNode(nodes, false);
+        });
+
+    },
+    updateChildrenValue:function (node,dataCode,value,datas,nodes) {
+         if(node.children.length > 0){
+            for(let c of node.children){
+                let updateData = {type:c.sourceType,data:{'ID' : c.data.ID}};
+                updateData.data[dataCode] = value;
+                datas.push(updateData);
+                nodes.push(c);
+                this.updateChildrenValue(c,dataCode,value,datas,nodes);
+            }
+         }
+
+    },
+
+    updateTenderData:function (datas,callback) {
+        let me = tender_obj;
+        if(datas.length <= 0){
+            callback?callback():'';
+            return;
+        }
+        $.bootstrapLoading.start();
+        projectObj.project.updateNodes(datas,function () {
+            for(let d of datas){
+                let temObj = null;
+                if(d.type == ModuleNames.bills || d.type == ModuleNames.ration){
+                    let temNode = me.tenderTree.findNode(d.data.ID);
+                    temObj = temNode?temNode.data:null;
+                }else if(d.type == ModuleNames.project){
+                    temObj = projectInfoObj.projectInfo;
+                }
+                if(temObj){
+                    for(let key in d.data){
+                        if(key == 'ID' || key == 'id'){
+                            continue;
+                        }
+                        _.set(temObj,key,d.data[key]);
+                    }
+                }
+            }
+            callback?callback():'';
+            $.bootstrapLoading.end();
+        })
+    },
 
 
+    onEditStarting:function (sender,args) {
+        let me = tender_obj, row = args.row, col = args.col;
+        if(me.editChecking(row,col) == false){
+            args.cancel = true;
+        }
+
+    },
+    editChecking:function (row,col) {//return false表示不能编辑
+        let me = tender_obj;
+        let dataCode = me.tenderSetting.header[col].dataCode;
+        let lockColumns = me.tenderSetting.view.lockColumns;
+
+        if(lockColumns.indexOf(col)!= -1){
+            return false;
+        }
+        if(dataCode == 'is_adjust_price'){
+            return false;
+        }
+        if(row >=  me.tenderTree.items.length){
+            return false;
+        }
+        if(dataCode == 'targetUnitFee' || dataCode == 'targetTotalFee'){
+            if($('#calcPriceOption').val() == 'coeBase'){//下拉按钮显示为“根据调整系数计算报价”时,目标造价(综合单价、综合合价) ,灰显,只读。
+                return false;
+            }else if(me.tenderTree.items[row].data.is_adjust_price === 1){//下拉按钮显示为“根据报价计算调整系数”时,打勾了不调价,目标造价(综合单价、综合合价)只读。
+                return false;
+            }
+        }
+        if(dataCode.indexOf('Coe') != -1){//如果是调整系数列
+            if($('#calcPriceOption').val() =='priceBase'){//下拉按钮显示为“根据报价计算调整系数”时,只读。
+                return false;
+            }else if(me.tenderTree.items[row].data.is_adjust_price === 1){//打勾了不调价,只读。
+                return false;
+            }
+        }
+        return true;
+    },
+    initPageContent : function () {
+        let tenderSetting = projectObj.project.property.tenderSetting;
+        let calcPriceOption = tenderSetting && tenderSetting.calcPriceOption? tenderSetting.calcPriceOption :"coeBase";
+        let gljPriceTenderCoe = tenderSetting && tenderSetting.gljPriceTenderCoe?tenderSetting.gljPriceTenderCoe:1;
+        $('#calcPriceOption').val(calcPriceOption);
+        $('#gljPriceTenderCoe').val(gljPriceTenderCoe);
+        if(calcPriceOption == 'coeBase'){
+            $('#tenderPrice').removeAttr("disabled");
+            $('#tenderGLJQuantity').attr("disabled",true);
+            $('#tenderRationQuantity').attr("disabled",true);
+        }else {
+            $('#tenderPrice').attr("disabled",true);
+            $('#tenderGLJQuantity').removeAttr("disabled");
+            $('#tenderRationQuantity').removeAttr("disabled");
+        }
+        //gljPriceTenderCoe
+    }
+};
 
 $(function () {
     $('#tab_tender_price').on('shown.bs.tab', function (e) {
@@ -94,8 +241,32 @@ $(function () {
         autoFlashHeight();
         tender_obj.tenderSpread.refresh();
         tender_obj.showTenderData();
+        tender_obj.initPageContent();
+    });
+
+    $('#tenderGLJQuantity').bind('click',function () {
+        console.log($('#gljPriceTenderCoe').val()) ;
+    });
+
+    $('#calcPriceOption').change(function(){
+        let me = tender_obj;
+        let newVal = $(this).val();
+        let updateData = {type:ModuleNames.project,data:{'ID' : projectObj.project.ID(),'property.tenderSetting.calcPriceOption':newVal}};
+        me.updateTenderData([updateData],function () {
+            me.initPageContent();
+        });
     });
 
+    $('#gljPriceTenderCoe').change(function(){
+        let me = tender_obj;
+        let process = getDecimal('process');
+        var newVal = $(this).val();
+        process = scMathUtil.roundForObj(newVal,process);
+        let updateData = {type:ModuleNames.project,data:{'ID' : projectObj.project.ID(),'property.tenderSetting.gljPriceTenderCoe':process}};
+        me.updateTenderData([updateData],function () {
+            me.initPageContent();
+        });
+    })
 
 
 });

+ 1 - 0
web/common/html/header.html

@@ -92,6 +92,7 @@
 <script type="text/javascript" src="/web/building_saas/js/moment.min.js"></script>
 <script type="text/javascript" src="/web/building_saas/js/message.js"></script>
 <script type="text/javascript" src="/public/web/scMathUtil.js"></script>
+<script type="text/javascript" src="/public/web/gljUtil.js"></script>
 <script type="text/javascript" src="/public/web/PerfectLoad.js"></script>
 <script type="text/javascript" src="/lib/lodash/lodash.js"></script>
 <!-- endinject -->