Browse Source

Merge branch 'master' of http://smartcost.f3322.net:3000/SmartCost/ConstructionCost

zhongzewei 7 years ago
parent
commit
935e79f5b7
32 changed files with 662 additions and 235 deletions
  1. 1 0
      config/gulpConfig.js
  2. BIN
      lib/jquery-ui/images/ui-icons_444444_256x240.png
  3. BIN
      lib/jquery-ui/images/ui-icons_555555_256x240.png
  4. BIN
      lib/jquery-ui/images/ui-icons_777620_256x240.png
  5. BIN
      lib/jquery-ui/images/ui-icons_777777_256x240.png
  6. BIN
      lib/jquery-ui/images/ui-icons_cc0000_256x240.png
  7. BIN
      lib/jquery-ui/images/ui-icons_ffffff_256x240.png
  8. 4 3
      modules/all_models/bills.js
  9. 5 0
      modules/all_models/ration.js
  10. 1 3
      modules/all_schemas/bills_sub_schemas.js
  11. 22 8
      modules/main/facade/project_facade.js
  12. 1 0
      modules/main/models/project_consts.js
  13. 3 2
      modules/pm/models/project_property_template.js
  14. 37 4
      modules/reports/util/rpt_construct_data_util.js
  15. 43 0
      public/gljUtil.js
  16. 284 0
      public/web/gljUtil.js
  17. 1 1
      public/web/rpt_value_define.js
  18. 9 3
      public/web/sheet/sheet_common.js
  19. 1 0
      public/web/tree_sheet/tree_sheet_helper.js
  20. 1 1
      test/unit/reports/test_tpl_09_1.js
  21. 2 1
      test/unit/reports/test_tpl_11.js
  22. 2 1
      web/building_saas/js/global.js
  23. 12 5
      web/building_saas/main/html/tender_price.html
  24. 12 8
      web/building_saas/main/js/models/calc_program.js
  25. 1 0
      web/building_saas/main/js/models/main_consts.js
  26. 24 164
      web/building_saas/main/js/models/project_glj.js
  27. 5 1
      web/building_saas/main/js/models/ration_glj.js
  28. 8 18
      web/building_saas/main/js/views/glj_view.js
  29. 1 1
      web/building_saas/main/js/views/project_glj_view.js
  30. 0 1
      web/building_saas/main/js/views/project_view.js
  31. 181 10
      web/building_saas/main/js/views/tender_price_view.js
  32. 1 0
      web/common/html/header.html

+ 1 - 0
config/gulpConfig.js

@@ -11,6 +11,7 @@ module.exports = {
         'lib/bootstrap/bootstrap.min.js',
         'web/building_saas/js/*.js',
         'public/web/scMathUtil.js',
+        'public/web/gljUtil.js',
         'public/web/PerfectLoad.js',
         'lib/lodash/lodash.js',
     ],

BIN
lib/jquery-ui/images/ui-icons_444444_256x240.png


BIN
lib/jquery-ui/images/ui-icons_555555_256x240.png


BIN
lib/jquery-ui/images/ui-icons_777620_256x240.png


BIN
lib/jquery-ui/images/ui-icons_777777_256x240.png


BIN
lib/jquery-ui/images/ui-icons_cc0000_256x240.png


BIN
lib/jquery-ui/images/ui-icons_ffffff_256x240.png


+ 4 - 3
modules/all_models/bills.js

@@ -42,9 +42,8 @@ let billsSchema = new Schema({
     isTender_Labour: Boolean,
     isTender_Material: Boolean,
     isTender_Machine: Boolean,
-    tenderTargetPrice: String, // Decimal
-    tenderTargetUnitPrice: String, // Decimal
-    tenderTargetUnitPrice: String, // Decimal
+    targetUnitFee:String,//目标单价
+    targetTotalFee:String,//目标合价
     //工作内容//zhong 2017-8-31
     jobContentText: String, //清单工作内容列显示文本, 减少第一次拉数据时的循环次数
     jobContent: [subSchema.jobContentSchema],
@@ -57,6 +56,8 @@ let billsSchema = new Schema({
     flags: [subSchema.flagsSchema],
     //消耗量调整系数字段
     quantityCoe:subSchema.quantityCoeSchema,
+    //子目工程量调整系数
+    rationQuantityCoe:String,
     // 不调价
     is_adjust_price: {type: Number,default: 0},
     installationKey:String,//用来记录安装增加费的关联字段

+ 5 - 0
modules/all_models/ration.js

@@ -38,8 +38,13 @@ let rationSchema = new Schema({
     fees: [subSchema.feesSchema],
     //消耗量调整系数字段
     quantityCoe:subSchema.quantityCoeSchema,
+    //子目工程量调整系数
+    rationQuantityCoe:String,
+    tenderQuantity:String,//调整后工程量
     // 不调价
     is_adjust_price: {type: Number,default: 0},
+    targetUnitFee:String,//目标单价
+    targetTotalFee:String,//目标合价
     deleteInfo: deleteSchema,
     type: Number,                               // 1 定额、2 量价、3 工料机定额
     subType: Number,                            // 子类型:1人工、201材料、301机械、4主材、5设备

+ 1 - 3
modules/all_schemas/bills_sub_schemas.js

@@ -10,9 +10,7 @@ var feesSchema = new Schema({
     unitFee: String, // Decimal. 单价
     totalFee: String, // Decimal. 合价
     tenderUnitFee: String, // Decimal. 调价后单价
-    tenderTotalFee: String, // Decimal. 调价后合价
-    targetUnitFee:String,//目标单价
-    targetTotalFee:String//目标合价
+    tenderTotalFee: String // Decimal. 调价后合价
 });
 
 // 标记字段

+ 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',

+ 3 - 2
modules/pm/models/project_property_template.js

@@ -17,10 +17,11 @@ const displaySetting = {
     billsAutoHeight:true,
     rationAutoHeight:false,
     disPlayMainMaterial:true
-}
+};
 
 const tenderSetting = {
-    gljPriceTenderCoe:1 //工料机单价调整系数
+    gljPriceTenderCoe:1, //工料机单价调整系数
+    calcPriceOption:'coeBase'//根据调整系数计算报价
 };
 
 const calcOptions={

+ 37 - 4
modules/reports/util/rpt_construct_data_util.js

@@ -457,6 +457,28 @@ function filterData(sourceData, handleCfg, prjData) {
         let compRst = true;
         let curComparePrjData = null;
         let startIdx = 0;
+        let private_ref_join = function(refKey, targetDataKey, targetPropertyKey) {
+            let rst = null, objDataArr = null;
+            curComparePrjData = getModuleDataByKey(prjData, targetDataKey);
+            try {
+                if (curComparePrjData !== null) {
+                    if (targetDataKey === "projectGLJ") {
+                        objDataArr = curComparePrjData.data.gljList;
+                    } else {
+                        objDataArr = curComparePrjData.data;
+                    }
+                    for (let dtl of objDataArr) {
+                        if (item[refKey] === dtl[targetPropertyKey]) {
+                            rst = dtl;
+                            break;
+                        }
+                    }
+                }
+            } finally {
+                curComparePrjData = null;
+            }
+            return rst;
+        };
         for (let cfg of filterCfg[JV.PROP_FILTER_KEYS]) {
             if (cfg[JV.PROP_FILTER_COMPARE_VAL]) {
                 //比较key值
@@ -464,10 +486,21 @@ function filterData(sourceData, handleCfg, prjData) {
                 if (keys.length > 1) {
                     let lastObj = item;
                     for (let i = 0; i < keys.length - 1; i++) {
-                        lastObj = item[keys[i]];
-                        if (!(lastObj)) {
-                            compRst = false;
-                            break;
+                        if (keys[i].indexOf("ref_join(") === 0) {
+                            let params = keys[i].slice(9, keys[i].length - 1).split(",");
+                            if (params.length === 3) {
+                                lastObj = private_ref_join(params[0], params[1], params[2]);
+                            }
+                            if (!(lastObj)) {
+                                compRst = false;
+                                break;
+                            }
+                        } else {
+                            lastObj = item[keys[i]];
+                            if (!(lastObj)) {
+                                compRst = false;
+                                break;
+                            }
                         }
                     }
                     if (lastObj) {

+ 43 - 0
public/gljUtil.js

@@ -0,0 +1,43 @@
+/**
+ * Created by zhang on 2018/6/7.
+ */
+import fs from 'fs';
+let _= require('lodash');
+const scMathUtil = require('./scMathUtil').getUtil();
+
+let gljNodeUtil = null;
+let data = fs.readFileSync(__dirname + '/web/gljUtil.js', 'utf8', 'r');
+eval(data + ' ; gljNodeUtil = gljUtil; ');
+
+module.exports = {
+    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);
+}

+ 284 - 0
public/web/gljUtil.js

@@ -0,0 +1,284 @@
+/**
+ * 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={};
+        let rationGljGroup = _.groupBy(rationGLJDatas,'projectGLJID');
+        let IDarray =  this.getSubdivisionAndTechBillsLeavesID(billsDatas);//分别取分部分项和技术措施项目的所有叶子清单ID
+        let billIDs = IDarray[0],tech_billIDS = IDarray[1];
+        for(let pglj of project_gljs ){
+            let pg_index = this.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,billIDs,tech_billIDS,q_decimal,_,scMathUtil);
+            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);
+                }
+            }
+        }
+    },
+    getQuantityPerGLJ : function (ration_glj_list,rations,rationMap,pglj,billIDs,tech_billIDS,q_decimal,_,scMathUtil) {
+        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;
+    },
+    getSubdivisionAndTechBillsLeavesID:function (billsDatas) {//分别取分部分项和技术措施项目的所有叶子清单ID
+        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){
+            if(parentMap[b.ParentID]){
+                parentMap[b.ParentID].push(b);
+            }else {
+                parentMap[b.ParentID]= [b];
+            }
+            if(this.isFlag(b)&&b.flagsIndex.fixed.flag==this.fixedFlag.SUB_ENGINERRING) {
+                subdivisionBillID = b.ID;
+            }
+            if(this.isFlag(b)&&b.flagsIndex.fixed.flag==this.fixedFlag.CONSTRUCTION_TECH){
+                techBillID = b.ID;
+            }
+        }
+
+        getLeaveIDs(subdivisionBillID,parentMap,sIDs);
+        getLeaveIDs(techBillID,parentMap,tIDS);
+        return [sIDs,tIDS];
+
+        function getLeaveIDs(ID,parentM,leaveIDs) {
+            if(parentM[ID] && parentM[ID].length > 0){
+                let children  =  parentM[ID];
+                for(let c of children){
+                    if(parentM[c.ID]){
+                        getLeaveIDs(c.ID,parentM,leaveIDs);
+                    }else {
+                        leaveIDs.push(c.ID);
+                    }
+                }
+            }
+        }
+    },
+    getGLJPrice:function (glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,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,_,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);
+    }
+    ,
+    isDef:function (v) {
+        return v !== undefined && v !== null;
+    },
+    getIndex(obj, pops){
+        let t_index = '';
+        let k_arr = [];
+        for (let p of pops) {
+            let tmpK = (obj[p] == undefined || obj[p] == null || obj[p] == '') ? 'null' : obj[p];
+            k_arr.push(tmpK);
+        }
+        t_index = k_arr.join("|-|");
+        return t_index;
+    },
+    fixedFlag : {
+        // 分部分项工程
+        SUB_ENGINERRING: 1,
+        // 措施项目
+        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],
+}

+ 1 - 1
public/web/rpt_value_define.js

@@ -189,7 +189,7 @@ const JV = {
     PROP_SEG_GRP_IDX: "segGrpRecStartIdx",
     PROP_PRE_ADD_GRP_REC_INFO: "preAddPageGrpInfo",
     PROP_INSERTED_GRP_REC: "insertedGrpRecAmt",
-    PROP_GRP_LINES: "me.group_lines_amt",
+    PROP_GRP_LINES: "group_lines_amt",
 
     RUN_TYPE_BEFORE_PAGING: "before_paging",
     RUN_TYPE_BEFORE_OUTPUT: "before_output",

+ 9 - 3
public/web/sheet/sheet_common.js

@@ -462,7 +462,7 @@ var sheetCommonObj = {
         }
         return pasteText.join('\n');
     },
-    transferToTreeSetting:function(setting,treeSetting){
+    transferToTreeSetting:function(setting,treeSetting,treeCol){
         for(let h of setting.header){
             treeSetting.cols.push(getSettingCol(h))
         }
@@ -501,12 +501,18 @@ var sheetCommonObj = {
                 let decimal = getDecimal(header.decimalField);
                 col.formatter = getFormatter(decimal);
             }
-            col.readOnly = function (node) {
+            if(header.getText && treeCol){
+                col.data.getText = treeCol.getEvent(header.getText);
+            }
+
+
+
+            /*col.readOnly = function (node) {
                 if(node.data.ParentID == -1 || node.data.id == 'GJ'){//三材类别项不能编辑)
                     return true;
                 }
                 return false;
-            };
+            };*/
             return col;
         }
         function getCellType(header) {

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

@@ -83,6 +83,7 @@ var TREE_SHEET_HELPER = {
 
         sheet.options.protectionOptions = option;
         sheet.options.isProtected = true;
+        sheet.options.allowCellOverflow = false;
     },
     massOperationSheet: function (sheet, Operation) {
         sheet.suspendPaint();

+ 1 - 1
test/unit/reports/test_tpl_09_1.js

@@ -59,7 +59,7 @@ test('测试 - 测试模板啦: ', function (t) {
         rptTplDataFacade.prepareProjectData(userId_Dft, demoPrjId, filter, function (err, msg, rawDataObj) {
             if (!err) {
                 try {
-                    // fsUtil.writeObjToFile(rawDataObj, "D:/GitHome/ConstructionCost/tmp/rptTplRawDataObject_建筑09-1表.jsp");
+                    fsUtil.writeObjToFile(rawDataObj, "D:/GitHome/ConstructionCost/tmp/rptTplRawDataObject_建筑09-1表.jsp");
                     let tplData = rptDataUtil.assembleData(rawDataObj);
                     // fsUtil.writeObjToFile(tplData, "D:/GitHome/ConstructionCost/tmp/rptTplAssembledData_建筑09-1表.jsp");
                     //it's time to build the report!!!

+ 2 - 1
test/unit/reports/test_tpl_11.js

@@ -26,7 +26,8 @@ cfgCacheUtil.setupDftCache();
 let fsUtil = require("../../../public/fsUtil");
 
 let demoPrjId = - 1;
-let demoRptId = 247, pagesize = "A4";
+//let demoRptId = 247, pagesize = "A4";
+let demoRptId = 281, pagesize = "A4"; //281: 11-2
 
 // let userId_Leng = "59cdf14a0034a1000ba52b97"; //小冷User Id 换成_id了 QQ号
 let userId_Leng = "5acac1e885bf55000bd055ba"; //小冷User Id2

+ 2 - 1
web/building_saas/js/global.js

@@ -123,4 +123,5 @@ function getFeeIndex(fees) {
         }
     }
     return feesIndex;
-}
+}
+

+ 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">

+ 12 - 8
web/building_saas/main/js/models/calc_program.js

@@ -419,8 +419,10 @@ let calcTools = {
             sumU = undefined;
         }
         else if (me.isLeafBill(treeNode)){
-            if (isGather)
-                sumT = eTFee()
+            if (isGather){
+                me.getGLJList(treeNode, false);
+                sumT = eTFee();
+            }
             else
                 sumT = eTFeeByChildren();
 
@@ -428,6 +430,8 @@ let calcTools = {
             sumU = (sumT / q).toDecimal(decimalObj.bills.totalPrice);
         }
         else if (me.isRationCategory(treeNode)){
+            me.getGLJList(treeNode, false);
+
             sumU = eUFee();
             if (isBase) return sumU;
 
@@ -1387,7 +1391,7 @@ class CalcProgram {
     };
 
     // 只计算treeNode自身。changedArr: 外部传来的一个数组,专门存储发生变动的节点。
-    innerCalc(treeNode, changedArr){
+    innerCalc(treeNode, changedArr, isTender = false){
         let me = this;
         // 仅用作树节点显示的工料机不能参与计算。
         if (treeNode.sourceType === ModuleNames.ration_glj) return;
@@ -1623,10 +1627,8 @@ class CalcProgram {
             };
         };
 
-        if (!calcTools.isTotalCostBill(treeNode)){   // 已在上面的分支中计算过
-            calcTools.getGLJList(treeNode, false);
+        if (!calcTools.isTotalCostBill(treeNode))  // 已在上面的分支中计算过
             calcTools.estimateFee(treeNode);
-        }
 
         if (treeNode.changed && !changedArr.includes(treeNode)) changedArr.push(treeNode);
     };
@@ -1669,8 +1671,10 @@ class CalcProgram {
                     calcNodes(node.children);
                 };
 
-                if ((calcType == calcAllType.catAll || calcType == node.sourceType) && node.calcType != treeNodeCalcType.ctCalcBaseValue) {
-                    me.innerCalc(node, changedNodes);
+                if (calcType == calcAllType.catAll || calcType == node.sourceType) {
+                    node.calcType = calcTools.getCalcType(node);
+                    if (node.calcType != treeNodeCalcType.ctCalcBaseValue)
+                        me.innerCalc(node, changedNodes);
                 };
             }
         };

+ 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;
-} 
+};

+ 5 - 1
web/building_saas/main/js/models/ration_glj.js

@@ -50,7 +50,11 @@ var ration_glj = {
             }
             else{
                 let result = this.datas.filter(function (data) {
-                    return data.rationID === ration.ID;
+                    if(data.rationID === ration.ID){
+                        gljOprObj.getTotalQuantity(data, ration);
+                        return true;
+                    }
+                    return false;
                 })
                 result = gljOprObj.combineWithProjectGlj(result);
                 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 -->