Browse Source

信息价功能

zhangweicheng 4 years ago
parent
commit
09619ee8ea

+ 1 - 0
modules/all_models/unit_price.js

@@ -47,6 +47,7 @@ let modelSchema = {
     unit_price_file_id: {type: Number, index: true},
     // 对应标准库工料机id
     glj_id: Number,
+    priceFrom:String,//价格来源
     //是否新增1为是,0为否
     is_add:{
         type: Number,

+ 3 - 2
modules/glj/models/unit_price_model.js

@@ -262,7 +262,8 @@ class UnitPriceModel extends BaseModel {
 
     async updateUnitPrice(data){
         //查找并更新单价
-        let doc={},newValueMap={};
+        let newValueMap={};
+        let doc = data.udoc?data.udoc:{};
         doc[data.field]=data.newval;
         newValueMap[data.id]=doc;
         let unitPrice = await this.db.findAndModify({id:data.id,unit_price_file_id:data.unit_price_file_id},doc);
@@ -379,7 +380,7 @@ class UnitPriceModel extends BaseModel {
                 filter:condition,
                 update:doc
             }
-        };
+          };
         return task
 }
 

+ 5 - 0
modules/main/controllers/info_price_controller.js

@@ -14,6 +14,11 @@ let controller = {
       let data = req.body.data;
       data = JSON.parse(data);
       return await info_price_facade.getDataByCondition(data,req.session.sessionCompilation);
+    },
+    mutiApplyInfoPrice:async function (req){
+      let data = req.body.data;
+      data = JSON.parse(data);
+      return await info_price_facade.mutiApplyInfoPrice(data,req.session.sessionCompilation);
     }
 };
 

+ 39 - 5
modules/main/facade/info_price_facade.js

@@ -3,23 +3,29 @@
  */
 module.exports={
   getOptions,
-  getDataByCondition
+  getDataByCondition,
+  mutiApplyInfoPrice
 };
 
 const mongoose = require('mongoose');
 let infoLibModel = mongoose.model("std_price_info_lib");
 let infoItemsModel = mongoose.model("std_price_info_items");
+let infoAreasModel = mongoose.model("std_price_info_areas");
+let unitPriceModel = mongoose.model("unit_price"); 
 let _ = require("lodash");
+let gljUtil = require('../../../public/web/gljUtil');
+const scMathUtil = require('../../../public/scMathUtil').getUtil();
 async function getOptions(data,compilation){//data 是预留对象,暂时不用
   let compilationID = compilation._id;
   let areaMap={};
-  let areas= [];
   let periodMap={};
+  let areas =await infoAreasModel.find({"compilationID":compilationID}).lean();
+
   let libList = await infoLibModel.find({"compilationID":compilationID}).lean();
   for(let l of libList){
-    for(let area of l.areas){
-      if(!areaMap[area]) areas.push(area);
-    }
+    // for(let area of l.areas){
+    //   if(!areaMap[area]) areas.push(area);
+    // }
     //2020-05
     let periodArray = l.period.split("-");
     periodMap[periodArray[0]]?periodMap[periodArray[0]].push(periodArray[1]):periodMap[periodArray[0]]=[periodArray[1]]
@@ -45,3 +51,31 @@ async function getDataByCondition(data,compilation){
   result.items = await infoItemsModel.find(data.condition).lean().sort({"_id":1}).limit(50);
   return result;
 }
+
+async function mutiApplyInfoPrice(data,compilation){
+  data.condition["compilationID"] = compilation._id;
+  let infoPrices = await infoItemsModel.find(data.condition).lean();
+  let tasks = [];
+  let projectGLJMap = {};
+  for(let info of infoPrices){
+    let index = gljUtil.getIndex(info,["name","specs","unit"]);
+    if(data.pgljMap[index]){
+      for(let obj of data.pgljMap[index]){
+        let infoPrice = gljUtil.getInfoMarketPrice(info,data.taxType);
+        infoPrice = scMathUtil.roundToString(infoPrice,data.decimal);
+        let doc = {'market_price':infoPrice,'priceFrom':data.priceFrom};
+        let task = {
+          updateOne:{
+              filter:{'id':obj.unitPriceID},
+              update:doc
+          }
+        };
+        tasks.push(task);
+        projectGLJMap[obj.pgljID] = {index:obj.fullIndex,doc:doc};
+      }  
+    }
+  }
+  if(tasks.length > 0) await unitPriceModel.bulkWrite(tasks);
+  return projectGLJMap;
+}
+

+ 1 - 0
modules/main/routes/info_price_route.js

@@ -8,6 +8,7 @@ module.exports = function (app) {
     let infoController = require('../controllers/info_price_controller');
     infoRouter.post('/getOptions', infoController.action);
     infoRouter.post('/getDataByCondition', infoController.action);
+    infoRouter.post('/mutiApplyInfoPrice', infoController.action);
 
     app.use('/infoPrice', infoRouter);
 };

+ 15 - 2
public/web/gljUtil.js

@@ -273,7 +273,7 @@ let gljUtil = {
         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,decimal)), -decimal);
+            return scMathUtil.roundForObj(parseFloat(coe * scMathUtil.roundForObj(glj.unit_price.base_price,decimal)), decimal);
         } else if (this.notEditType.indexOf(glj.unit_price.type)!=-1&&glj.ratio_data.length>0) {//对于混凝土、配合比、砂浆、机械台班,调整价根据组成物计算得出。
             let p =0;
             for(let ratio of glj.ratio_data){
@@ -612,7 +612,16 @@ let gljUtil = {
           }, 'code']);
       }
       return jsonData
-  },
+    },
+    getInfoMarketPrice:function (info,taxType) {
+      //1: 一般计税 2: 简易计税
+      let fieldArray=['noTaxPrice'];//一般计税 - 不含税价 || 简易计税 - 含税价
+      taxType == "1" ? fieldArray.push("taxPrice"):fieldArray.unshift("taxPrice");
+      //一个放后面,一个放前面
+      let infoPrice = info[fieldArray[0]];
+      if(!this.isDef(infoPrice)) infoPrice= info[fieldArray[1]];//信息价只有一个价格(含税价/不含税价),则不分计税方式,套用仅有的价格。
+      return parseFloat(infoPrice);
+    },      
     fixedFlag : {
         // 分部分项工程
         SUB_ENGINERRING: 1,
@@ -665,4 +674,8 @@ let gljUtil = {
     hasCompMaterial:[202, 203, 204],//有组成物的材料
     hasCompMachine:[301],//有组成物的机械
     machineComposition:[302,303]//可以做为机械组成物的类型
+}
+
+if(typeof module !== 'undefined'){
+  module.exports = gljUtil;
 }

+ 7 - 8
public/web/scMathUtil.js

@@ -173,21 +173,20 @@ let scMathUtil = {
     roundForObj:function(obj,decimal){
         let me = this;
         let value;
+        if(obj === undefined || obj === null) return 0;
+        let n = Math.pow(10,decimal);
         if(me.isNumber(obj)){
-            value = me.roundTo(obj,-decimal)
+          value = Math.round(obj * n) / n;
+          //value = me.roundTo(obj,-decimal)
         }else {
-            value = me.roundTo(Number(obj),-decimal);
+          value = Math.round(Number(obj) * n) / n;
+          //value = me.roundTo(Number(obj),-decimal);
         }
         return value
     },
     roundToString:function(obj,decimal){
         let me = this;
-        let value;
-        if(me.isNumber(obj)){
-            value = me.roundTo(obj,-decimal)
-        }else {
-            value = me.roundTo(Number(obj),-decimal);
-        }
+        let value = me.roundForObj(obj,decimal);
         return value.toFixed(decimal);
     },
     isNumOrFormula:function (text) {

+ 1 - 1
public/web/socket/connection.js

@@ -80,7 +80,7 @@ socketObject = {
         socket.on('handleAvatarList', function ({ editingUsers }) {
             projectInfoObj.handleAvatarList(editingUsers);
         });
-        SHARE_TO.permissionChangeListener();
+        if(typeof SHARE_TO !== 'undefined') SHARE_TO.permissionChangeListener();
 
         //=============================================================================================
         //项目管理页面接收消息部分

+ 4 - 0
web/building_saas/css/custom.css

@@ -502,3 +502,7 @@ margin-right: 100px !important;
 .menu-input:focus {
   outline: none;
 }
+
+.info-checkbox {
+  margin-right: 20px;
+}

+ 90 - 0
web/building_saas/glj/html/project_glj.html

@@ -363,4 +363,94 @@
             </div>
         </div>
     </div>
+</div>
+
+<!--弹出 信息价单位换算窗口-->
+<div class="modal fade" id="infoPriceCoeDiv" data-backdrop="static">
+  <div class="modal-dialog" role="document">
+      <div class="modal-content">
+          <div class="modal-header">
+              <h5 class="modal-title">单位换算</h5>
+              <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                  <span aria-hidden="true">&times;</span>
+              </button>
+          </div>
+          <div class="modal-body">
+              <!-- <div class="form-group">
+                  <label id = "assistProductionLabel">辅助生产间接费费率(%)</label>
+                  <input class="form-control" id="assistProductionFeeRate" value="">
+              </div> -->
+              <input type="hidden" id="infoRow" value="">
+              <fieldset class="form-group"  style="border:1px solid #b3b3b3;padding: 15px">
+                <legend class="legend" ></legend>
+                <label>材料名称:</label><label id="applyGLJName">钢筋</label><br>
+                <label  >单位:</label><label id="applyGLJUnit">t</label>=&nbsp;<input id="infoPriceCoe" type="number" class="form-control form-control-sm" style="display:inline;width: 200px;" value="">&nbsp;<label id="applyInfoUnit" >m3</label>
+            </fieldset>
+          </div>
+          <div class="modal-footer">
+              <button type="button" class="btn btn-primary" id="infoPriceCoeConfirm">确定</button>
+              <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+          </div>
+      </div>
+  </div>
+</div>
+
+
+<!--弹出批量套用窗口-->
+<div class="modal fade" id="mutiApplyInfoPriceDiv" data-backdrop="static">
+  <div class="modal-dialog" role="document">
+      <div class="modal-content">
+          <div class="modal-header">
+              <h5 class="modal-title">批量套用信息价</h5>
+              <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                  <span aria-hidden="true">&times;</span>
+              </button>
+          </div>
+          <div class="modal-body" style="padding: 0;">
+            <fieldset class="form-group" style="padding: 1rem;">
+              <h5>套用条件</h5>   
+              <label class="form-check-label info-checkbox">
+                  <input class="" type="checkbox" checked disabled>
+                  名称
+              </label>
+              <label class="form-check-label info-checkbox">
+                  <input class="" type="checkbox" checked disabled>
+                  规格型号
+              </label>
+              <label class="form-check-label info-checkbox">
+                  <input class="" type="checkbox" checked disabled>
+                  单位
+              </label> 
+          </fieldset>
+
+          <fieldset class="form-group" style="border-top:1px solid #ccc;padding: 1rem;">
+            <h5>套用类别</h5>   
+            <label class="form-check-label info-checkbox">
+                <input class="info_apply_type" id="info_label" value="1" type="checkbox" checked >
+                人工
+            </label>
+            <label class="form-check-label info-checkbox">
+                <input class="info_apply_type" id="info_material" value="2" type="checkbox" checked >
+                材料
+            </label>
+            <label class="form-check-label info-checkbox">
+                <input class="info_apply_type" id="info_machine" value="3" type="checkbox" checked >
+                机械
+            </label> 
+            <label class="form-check-label info-checkbox">
+              <input class="info_apply_type"  id="info_main" value="4" type="checkbox" checked >
+              主材
+            </label>
+            <label class="form-check-label info-checkbox">
+                <input class="info_apply_type" id="info_equipment" value="5" type="checkbox" checked >
+                设备
+            </label> 
+        </fieldset>
+          </div>
+          <div class="modal-footer">
+              <button type="button" class="btn btn-primary" data-dismiss="modal" id="mutiApplyinfoPriceConfirm">确定</button>
+              <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+          </div>
+      </div>
+  </div>
 </div>

+ 56 - 19
web/building_saas/main/js/models/project_glj.js

@@ -203,10 +203,10 @@ ProjectGLJ.prototype.loadCacheData = function (resort) {
 
 ProjectGLJ.prototype.updatePriceFromRG = function (recode, updateField, newval,callback) {
     if (updateField == 'marketPrice') {
-        this.updatePrice(recode, "market_price", newval,"rg",callback);
+        this.updatePrice(recode, "market_price", newval,"rg",null,callback);
     }
     if (updateField == 'basePrice') {
-        this.updatePrice(recode, "base_price", newval,"rg",callback);
+        this.updatePrice(recode, "base_price", newval,"rg",null,callback);
     }
 };
 
@@ -290,37 +290,46 @@ ProjectGLJ.prototype.getPriceDecimal = function (glj) {//价格的小数位数
 
 };
 
-ProjectGLJ.prototype.updatePrice = function (recode, updateField, newval,from,cb) {
+ProjectGLJ.prototype.doAfterPriceChange=function(gljs){
+    //更新回传的父节点项目工料机价格
+
+    projectGljObject.refreshDataSheet(true);//更新工料机汇总缓存和显示
+    gljOprObj.showRationGLJSheetData();
+    let nodes = this.getImpactRationNodes(gljs);//取到因为改变工料机价格而受影响的定额
+    projectObj.project.calcProgram.calcNodesAndSave(nodes, async function () {
+        await OVER_HEIGHT.reCalcOverHeightFee();
+        await itemIncreaseFeeObj.calcItemIncreaseFeeByNodes(nodes);
+    });//触发计算程序
+    projectGljObject.onUnitFileChange(gljs);
+}
+
+
+ProjectGLJ.prototype.updatePrice = function (recode, updateField, newval,from,tdoc,cb) {
     let me = this;
     let projectGljs = this.datas.gljList;
     let pgljID = from=="rg"?recode.projectGLJID:recode.id;//和定额工料机统一接口,项目工料机ID取值不一样
     let glj = _.find(projectGljs, {'id': pgljID});
+    let udoc = tdoc?tdoc:{"priceFrom":""};//20200728 新增价格来源,默认为空
     if (glj) {
         if(glj.unit_price[updateField] == newval){
             return;
         }
         newval = scMathUtil.roundForObj(newval,this.getPriceDecimal(glj));
         let data = {id: glj.unit_price.id, field: updateField, newval: newval,project_id:glj.project_id,unit_price_file_id:glj.unit_price.unit_price_file_id};
+        if(updateField == 'market_price') data.udoc=udoc;
         let callback = function (data) {
             if (updateField == 'base_price') {
                 glj.unit_price.base_price = newval;
                 me.setAdjustPrice(glj);
             } else {
                 glj.unit_price.market_price = newval;
+                gljUtil.setProperty(glj.unit_price,udoc);
             }
             //更新回传的父节点项目工料机价格
-           let gljs = me.getProjectGLJs(data);
-          //  me.refreshRationGLJPrice(glj);//刷新定额工料机列表的记录
-            projectObj.project.projectGLJ.loadCacheData();//更新工料机汇总缓存和显示
-            gljOprObj.showRationGLJSheetData();
-            me.refreshTreeNodePriceIfNeed(glj);//刷新造价书中主树上的定额工料机;
+            let gljs = me.getProjectGLJs(data);
             gljs.push(glj);
-            let nodes = me.getImpactRationNodes(gljs);//取到因为改变工料机价格而受影响的定额
-            projectObj.project.calcProgram.calcNodesAndSave(nodes, async function () {
-                await OVER_HEIGHT.reCalcOverHeightFee();
-                await itemIncreaseFeeObj.calcItemIncreaseFeeByNodes(nodes);
-            });//触发计算程序
-            projectGljObject.onUnitFileChange(data);
+            me.refreshTreeNodePriceIfNeed(glj);//刷新造价书中主树上的定额工料机;
+            projectObj.project.projectGLJ.doAfterPriceChange(gljs);//更新工料机汇总缓存和显示
             if(cb){
                 cb(gljs);
             }
@@ -382,6 +391,38 @@ ProjectGLJ.prototype.batchUpdateGLJProperty = function (updateMap,callback) {
 
 };
 
+ProjectGLJ.prototype.mutiApplyInfoPrice = async function(pgljMap,condition,priceFrom) {
+  try {
+    $.bootstrapLoading.start();
+    let taxType = projectObj.project.property.taxType;
+    let projectGLJMap = await ajaxPost("/infoPrice/mutiApplyInfoPrice",{pgljMap:pgljMap,condition:condition,taxType:taxType,decimal:getDecimal('glj.unitPrice'),priceFrom:priceFrom});
+    let parentKeyMap = {};
+    let gljs = [];
+    if(!_.isEmpty(projectGLJMap)){
+      for(let id in projectGLJMap){//先整理出受影响的父工料机
+        let mixRatioKey = projectGLJMap[id].index;
+        let parentArray = this.datas.mixRatioConnectData[mixRatioKey];
+        if(!parentArray) continue;
+        for(pk of parentArray){
+          parentKeyMap[pk] = true;
+        }
+      }
+      for(let glj of this.datas.gljList){
+        if(projectGLJMap[glj.id]){
+          gljUtil.setProperty(glj.unit_price,projectGLJMap[glj.id].doc);
+          gljs.push(glj);
+        }else if(parentKeyMap[gljUtil.getIndex(glj)]){
+          gljs.push(glj);
+        }
+      }
+      this.doAfterPriceChange(gljs);
+    }
+  } catch (error) {
+    console.log(error);
+  }
+  $.bootstrapLoading.end();
+}
+
 ProjectGLJ.prototype.batchUpdatePrice = function (changeInfo,sheetName,callback) {
     let me = this;
     let projectGljs = me.datas.gljList;
@@ -408,7 +449,6 @@ ProjectGLJ.prototype.batchUpdatePrice = function (changeInfo,sheetName,callback)
             }
         }
     }
-    console.log(updateData);
     if(updateData.length > 0){
         $.bootstrapLoading.start();
         CommonAjax.post("/glj/batchUpdatePrices", updateData, function (result) {
@@ -429,10 +469,7 @@ ProjectGLJ.prototype.batchUpdatePrice = function (changeInfo,sheetName,callback)
             }
             let pgljs = me.getProjectGLJs(parentData);
             gljs = gljs.concat(pgljs);
-            let nodes = me.getImpactRationNodes(gljs);//取到因为改变工料机价格而受影响的定额
-            projectObj.project.calcProgram.calcNodesAndSave(nodes);//触发计算程序
-            gljOprObj.showRationGLJSheetData();
-            projectGljObject.onUnitFileChange(gljs);
+            me.doAfterPriceChange(gljs);
             if(callback){
                 callback(gljs);
             }

+ 3 - 3
web/building_saas/main/js/views/config_material_view.js

@@ -496,7 +496,7 @@ let configMaterialObj = {
                     alert("当前材料市场价已被锁定,修改请先返回人材机汇总界面解除锁定。");
                     return me.showBidMaterialDatas();
                 }
-                return projectObj.project.projectGLJ.updatePrice(bid,dataCode,value,'rg', projectGljObject.refreshViewsData);
+                return projectObj.project.projectGLJ.updatePrice(bid,dataCode,value,'rg', null,projectGljObject.refreshViewsData);
             }
             value =  scMathUtil.roundToString(value,getDecimal('glj.unitPrice'));
         }
@@ -540,7 +540,7 @@ let configMaterialObj = {
             if(dataCode=='marketPrice'){
                 dataCode = 'market_price';
                 if(recode.is_related){//关联的情况下,直接修改工料机价格 暂时不支持批量修改
-                    return projectObj.project.projectGLJ.updatePrice(recode,dataCode,value,'rg', projectGljObject.refreshViewsData);
+                    return projectObj.project.projectGLJ.updatePrice(recode,dataCode,value,'rg',null,projectGljObject.refreshViewsData);
                 }
             }else {
                 let tem = updateMap[recode.ID]?updateMap[recode.ID]:{};
@@ -572,7 +572,7 @@ let configMaterialObj = {
         if(dataCode == 'marketPrice'){
             dataCode = 'market_price';
             if(evaluate.is_related){//关联的情况下,直接修改工料机价格
-                return projectObj.project.projectGLJ.updatePrice(evaluate,dataCode,value,'rg', projectGljObject.refreshViewsData);
+                return projectObj.project.projectGLJ.updatePrice(evaluate,dataCode,value,'rg',null,projectGljObject.refreshViewsData);
             }
         }
         if(value && dataCode === 'quantity'){//修改数量需做4舍5入

+ 4 - 1
web/building_saas/main/js/views/glj_col.js

@@ -43,6 +43,7 @@ let gljCol = {
             {headerName: "单位", headerWidth: 45, dataCode: "unit", hAlign: "center", dataType: "String",spanRows: [2]},
             {headerName: "类型", headerWidth: 45, dataCode: "short_name", hAlign: "center", dataType: "String",spanRows: [2]},
             {headerName: "市场价", headerWidth: 70, dataCode: "marketPrice", hAlign: "right", dataType: "Number",validator:"number",spanRows: [2]},//,decimalField:"glj.unitPrice"
+            {headerName: "价格来源", headerWidth: 90, dataCode: "priceFrom", dataType: "String",spanRows: [2]},
             {headerName: "税率", headerWidth: 70, dataCode: "taxRate", hAlign: "right", dataType: "Number",validator:"number",spanRows: [2]},//,decimalField:"glj.unitPrice"
             {headerName: "调整价", headerWidth: 70, dataCode: "adjustPrice", hAlign: "right", dataType: "Number",spanRows: [2]},//,decimalField:"glj.unitPrice"
             {headerName: "定额价", headerWidth: 70, dataCode: "basePrice", hAlign: "right", dataType: "Number",validator:"number",spanRows: [2]},//decimalField:'glj.unitPrice',
@@ -67,8 +68,10 @@ let gljCol = {
             {headerName: ["","总消耗量"], headerWidth: 90, dataCode: "tenderQuantity", hAlign: "right", dataType: "Number",decimalField:'glj.quantity',spanCols: [0,1], visible: false}
         ],
         view: {
-            lockColumns: ["code","name","specs","unit","short_name","tenderPrice","adjustPrice","quantity","tenderQuantity"]
+            lockColumns: ["code","name","specs","unit","short_name","tenderPrice","adjustPrice","quantity","tenderQuantity","priceFrom"]
         },
+        autoFit:true,
+        fitRow:['priceFrom'],
         frozenCols:4,
         headRows:2,
         getStyle:function (data,row,activeRow) {

+ 4 - 0
web/building_saas/main/js/views/glj_view.js

@@ -689,6 +689,8 @@ var gljOprObj = {
         return codeMap;
     },
     initRationTree: function (init,codeMap) {
+        this.sheet.suspendPaint();
+        this.sheet.suspendEvent();
         this.sheet.setRowCount(this.sheetData.length >30?this.sheetData.length:30);
         for (var i = 0; i < this.sheetData.length; i++) {
             let options = this.getCodeOptions(this.sheetData[i],codeMap);
@@ -700,6 +702,8 @@ var gljOprObj = {
                 }
             }
         }
+        this.sheet.resumeEvent();
+        this.sheet.resumePaint();
     },
     getCodeOptions:function (recode,codeMap) {
         let options = [];

+ 2 - 2
web/building_saas/main/js/views/material_adjust_view.js

@@ -110,7 +110,7 @@ let materialAdjustObj = {
             if(dataCode=='marketPrice'){
                 dataCode = 'market_price';
                 if(recode.is_related){//关联的情况下,直接修改工料机价格
-                    return projectGLJ.updatePrice(recode,dataCode,value,'rg', projectGljObject.refreshViewsData);
+                    return projectGLJ.updatePrice(recode,dataCode,value,'rg',null, projectGljObject.refreshViewsData);
                 }
             }else {
                 let tem = updateMap[recode.ID]?updateMap[recode.ID]:{};
@@ -157,7 +157,7 @@ let materialAdjustObj = {
                 return me.refreshSheetDatas();
             }
             if(evaluate.is_related){//关联的情况下,直接修改工料机价格
-                return projectObj.project.projectGLJ.updatePrice(evaluate,dataCode,value,'rg', projectGljObject.refreshViewsData);
+                return projectObj.project.projectGLJ.updatePrice(evaluate,dataCode,value,'rg',null, projectGljObject.refreshViewsData);
             }
         }
         if(dataCode == "standardPrice") value = scMathUtil.roundForObj(value,getDecimal('glj.unitPrice'))+"";

+ 166 - 33
web/building_saas/main/js/views/project_glj_view.js

@@ -15,10 +15,11 @@ let projectGljObject={
     mixRatioSetting:{},
     infoPriceSetting:{
       header:[
-        {headerName: "材料名称", headerWidth: 360, dataCode: "name", dataType: "String"},
-        {headerName: "规格型号", headerWidth: 240, dataCode: "specs", hAlign: "left", dataType: "String"},
+        {headerName: "材料名称", headerWidth: 320, dataCode: "name", dataType: "String"},
+        {headerName: "规格型号", headerWidth: 200, dataCode: "specs", hAlign: "left", dataType: "String"},
         {headerName: "单位", headerWidth: 50, dataCode: "unit", dataType: "String",hAlign: "center"},
-        {headerName: "含税市场价", headerWidth: 160, dataCode: "taxPrice", hAlign: "right", dataType: "Number",validator:"number"}//,decimalField:"glj.unitPrice"
+        {headerName: "含税市场价", headerWidth: 100, dataCode: "taxPrice", hAlign: "right", dataType: "Number",validator:"number"},
+        {headerName: "不含税市场价", headerWidth: 100, dataCode: "noTaxPrice", hAlign: "right", dataType: "Number",validator:"number"}//,decimalField:"glj.unitPrice"
     ],
     view: {
         lockColumns: [0,1,2,3,4]//,
@@ -83,10 +84,16 @@ let projectGljObject={
       this.infoPriceSheet = this.infoPriceSpread .getSheet(0);
       this.initSheet(this.infoPriceSheet,this.infoPriceSetting);
       this.infoPriceSheet.bind(GC.Spread.Sheets.Events.TopRowChanged, _.debounce(this.onInfoTopRowChanged, 100));
+      this.infoPriceSheet.bind(GC.Spread.Sheets.Events.CellDoubleClick, this.onInfoPriceDoubleClick);
       this.infoPriceSheet.name('infoPriceSheet');
       this.infoPriceSheet.setRowCount(0);
-
       this.getInfoPriceOptions();
+      
+      if(projectReadOnly){
+        disableSpread(this.infoPriceSpread);
+      }else{
+        this.initInfoPriceRightClick();
+      }
     },
     initSpreads:function(){
         if(this.projectGljSpread==null) this.initProjectGljSpread();
@@ -455,6 +462,9 @@ let projectGljObject={
       $("#tab_zaojiashu").click();
       locateObject.locateNode(record.ID);
     },
+    onInfoPriceDoubleClick:function name(sender,args) {
+      projectGljObject.preApplyInfoPrice(args.row);
+    },
     onProjectGljSelectionChange:function (sender, args) {
         let me = projectGljObject;
         let newSel = args.newSelections[0];
@@ -568,10 +578,9 @@ let projectGljObject={
         }
         me.batchUpdateGLJProperty(propertyCells,sheetName,function () {
             //价格属于单价文件表,如果与项目工料机的其它属性一起的话计算起来会比较复杂,同时出现价格与其它属性一起更新的情况也会比较少;
-            projectGLJ.batchUpdatePrice(priceCells,sheetName,function (impactList) {
-                me.refreshBySheetName(sheetName);
-                gljOprObj.refreshView();
-            });
+            projectGLJ.batchUpdatePrice(priceCells,sheetName);
+            //me.refreshBySheetName(sheetName); 2020-07-27  改在projectGLJ里统一刷新了
+             //gljOprObj.refreshView();
         });
     },
     refreshBySheetName:function (sheetName) {
@@ -669,6 +678,7 @@ let projectGljObject={
     },
     showProjectGljData:function () {
         if(!this.projectGljSpread) return;
+        let me = this;
         this.projectGljSpread.setActiveSheetIndex(0);
         let sel = this.projectGljSheet.getSelections()[0];
         let oldData = sel.row<this.projectGljSheetData.length?this.projectGljSheetData[sel.row]:"";
@@ -680,10 +690,12 @@ let projectGljObject={
             projectGljSheetData.push(this.getSheetDataByGLJ(glj));
         }
         this.projectGljSheetData = projectGljSheetData;
-        sheetCommonObj.showData(this.projectGljSheet, this.projectGljSetting,this.projectGljSheetData);
-        this.projectGljSheet.setRowCount(this.projectGljSheetData.length);
-        sel.row = oldData?_.findIndex(this.projectGljSheetData,{'id':oldData.id}):'';
-        this.projectGljSheet.setSelection(sel.row==-1?0:sel.row,sel.col,sel.rowCount,sel.colCount);
+        sheetCommonObj.showData(this.projectGljSheet, this.projectGljSetting,this.projectGljSheetData,null,function(){
+          me.projectGljSheet.setRowCount(me.projectGljSheetData.length);
+          sel.row = oldData?_.findIndex(me.projectGljSheetData,{'id':oldData.id}):-1;
+          me.projectGljSheet.setSelection(sel.row==-1?0:sel.row,sel.col,sel.rowCount,sel.colCount);
+        });
+       
     },
     showMaterialTreeData:function () {
         this.projectGljSpread.setActiveSheetIndex(1);
@@ -740,20 +752,22 @@ let projectGljObject={
         if(me.displayType == filterType.ZGCL || me.displayType == filterType.PBCL) return configMaterialObj.refreshSheetDatas();
         me.refreshDataSheet();
     },
-    refreshDataSheet:function () {
+    refreshDataSheet:function (refresh) {//refresh = true 的时候不用更新表头信息
         let me = projectGljObject;
-        let quantityCol = _.findIndex(me.projectGljSetting.header,function (header) {
+        if(!refresh){
+          let quantityCol = _.findIndex(me.projectGljSetting.header,function (header) {
             return header.dataCode ==  'quantity'|| header.dataCode == 'techQuantity' || header.dataCode =='subdivisionQuantity';
-        });
-        if(me.displayType == filterType.FBFX){//分部分项人材机,将“总消耗量”替换显示为“分部分项总消耗量”。
-            me.projectGljSetting.header[quantityCol].dataCode = 'subdivisionQuantity';
-            me.projectGljSheet.setValue(0, quantityCol, "分部分项总消耗量", GC.Spread.Sheets.SheetArea.colHeader);
-        }else if(me.displayType == filterType.TECH) {//措施项目人材机,将“总消耗量”替换显示为“措施项目总消耗量”。
-            me.projectGljSetting.header[quantityCol].dataCode = 'techQuantity';
-            me.projectGljSheet.setValue(0, quantityCol, "措施项目总消耗量", GC.Spread.Sheets.SheetArea.colHeader);
-        }else {
-            me.projectGljSetting.header[quantityCol].dataCode = 'quantity';
-            me.projectGljSheet.setValue(0, quantityCol, "总消耗量", GC.Spread.Sheets.SheetArea.colHeader);
+          });
+          if(me.displayType == filterType.FBFX){//分部分项人材机,将“总消耗量”替换显示为“分部分项总消耗量”。
+              me.projectGljSetting.header[quantityCol].dataCode = 'subdivisionQuantity';
+              me.projectGljSheet.setValue(0, quantityCol, "分部分项总消耗量", GC.Spread.Sheets.SheetArea.colHeader);
+          }else if(me.displayType == filterType.TECH) {//措施项目人材机,将“总消耗量”替换显示为“措施项目总消耗量”。
+              me.projectGljSetting.header[quantityCol].dataCode = 'techQuantity';
+              me.projectGljSheet.setValue(0, quantityCol, "措施项目总消耗量", GC.Spread.Sheets.SheetArea.colHeader);
+          }else {
+              me.projectGljSetting.header[quantityCol].dataCode = 'quantity';
+              me.projectGljSheet.setValue(0, quantityCol, "总消耗量", GC.Spread.Sheets.SheetArea.colHeader);
+          }
         }
         if(me.displayType == filterType.SCHZ){//三材汇总树节点
             me.showMaterialTreeData();
@@ -909,6 +923,7 @@ let projectGljObject={
             qualityGrace:glj.qualityGrace,
             brand:glj.brand,
             unitPriceID:glj.unit_price.id,
+            priceFrom:glj.unit_price.priceFrom,
             remark:glj.remark
         };
         gljOprObj.setGLJPrice(data,glj);
@@ -1116,11 +1131,10 @@ let projectGljObject={
                     projectObj.mainController.refreshTreeNode(projectObj.project.mainTree.roots);
                 });
             }
-            gljOprObj.refreshView();
         };
         if(dataCode=='basePrice'||dataCode=='marketPrice'){//修改市场价和修改定额价时需要重新记算很多受影响的树节点,现在改成与定字额工料机那里调相同的方法。
             let editField = dataCode === 'basePrice'?"base_price":"market_price";
-            projectObj.project.projectGLJ.updatePrice(recode,editField,value,'pg',callback);
+            projectObj.project.projectGLJ.updatePrice(recode,editField,value,'pg',null,callback);
         }else {
             let extend = {};
             // 如果是供货方式则需要处理数据
@@ -1204,6 +1218,30 @@ let projectGljObject={
       }
       return data;
     },
+    initInfoPriceRightClick:function(){
+      let me = this;
+      $.contextMenu({
+        selector: '#info_price_sheet',
+        build: function ($trigger, e) {
+            me.rightClickTarget = SheetDataHelper.safeRightClickSelection($trigger, e, me.infoPriceSpread);
+            return me.rightClickTarget.hitTestType === GC.Spread.Sheets.SheetArea.viewport ||
+                me.rightClickTarget.hitTestType === GC.Spread.Sheets.SheetArea.rowHeader;
+        },
+        items: {
+            "apply": {
+                name: "确认套用(或双快速套用)",
+                icon: 'fa-sign-in',
+                disabled: function () {
+                    return me.rightClickTarget.row === undefined;
+                },
+                callback: function (key, opt) {
+                    let row = me.rightClickTarget.row;
+                     me.preApplyInfoPrice(row);
+                }
+            }
+        }
+      });
+    },
     initRightClick : function() {
         let activeSheet = this.mixRatioSheet;
         let me = this;
@@ -1302,15 +1340,20 @@ let projectGljObject={
     getInfoPriceOptions:async function(){
       let options =await ajaxPost("/infoPrice/getOptions",{});
       this.infoPriceOptions=options;
-      this.createSelectOptions($("#info_area"),options.areas);
+      this.createSelectOptions($("#info_area"),options.areas,true);
       let years = _.keysIn(options.periodMap);
       this.createSelectOptions($("#info_year"),_.sortBy(years));   
     },
-    createSelectOptions:function(ele,opts){
+    createSelectOptions:function(ele,opts,isArea){
       ele.empty();
       let str = `<option value=""></option>`;
       for(let o of opts){
-        str +=`<option value="${o}">${o}</option>`
+        if(isArea == true){
+          str +=`<option value="${o.ID}">${o.name}</option>`
+        }else{
+          str +=`<option value="${o}">${o}</option>`
+        }
+        
       }
       ele.html(str);
     },
@@ -1332,14 +1375,14 @@ let projectGljObject={
     searchInfoPrice:async function(objectID){
       let year = $('#info_year').val();
       let month =  $('#info_month').val();
-      let area = $('#info_area').val();
+      let areaID = $('#info_area').val();
       let keyWord = $('#info_search_name').val();
       let me = projectGljObject;
       try {
-        if(year !="" && month!="" && area!="") {
+        if(year !="" && month!="" && areaID!="") {
           let condition = {
             period:year+"-"+month,
-            area:area
+            areaID:areaID
           }
           let data ={condition:condition};
           if(keyWord !="")  data.keyWord = keyWord;
@@ -1356,8 +1399,48 @@ let projectGljObject={
         }
       } catch (error) {
         console.log(error) 
-      }
+      }      
+    },
+    preApplyInfoPrice:function (row) {
+        let info = this.infoPriceData[row];
+        let projectGLJData = this.getProjectGLJSelected();
+        if (projectGLJData.ratio_data  && projectGLJData.ratio_data.length > 0)  return ;
+        let marketPrice = this.getInfoMarketPrice(info);
+        if(projectGLJData.unit == info.unit){
+          this.applyInfoPrice(projectGLJData,marketPrice,1);
+        }else if(_.includes(["t","kg"],projectGLJData.unit)&&_.includes(["t","kg"],info.unit)){
+          //遇到t和kg之间的转换,默认处理:1t=1000kg,不弹换算窗口
+          let coeMap={"t":1,"kg":1000};
+          let coe = coeMap[info.unit]/coeMap[projectGLJData.unit];
+          this.applyInfoPrice(projectGLJData,marketPrice,coe);
+        }else{//弹出单位转换窗口
+          $("#infoRow").val(row);
+          $("#applyGLJName").text(projectGLJData.name);
+          $("#applyGLJUnit").text(projectGLJData.unit);
+          $("#infoPriceCoe").val("");
+          $("#applyInfoUnit").text(info.unit);
+          $("#infoPriceCoeDiv").modal('show')
+        }
+    },
+    applyInfoPrice:function (projectGLJData,price,coe) {
+      let priceFrom= me.getPriceFrom();
+      projectObj.project.projectGLJ.updatePrice(projectGLJData,"market_price",price*coe,'pg',{"priceFrom":priceFrom});
       
+    },
+    getPriceFrom:function(){
+      let area = "";
+      for(let o of this.infoPriceOptions.areas){
+        if(o.ID == $("#info_area").val()){
+          area = o.name;
+          break;
+        }
+      }
+      return  `${area}信息价(${$("#info_year").val()}${$("#info_month").val()})`;
+    },
+
+    getInfoMarketPrice:function (info) {
+      let taxType = projectObj.project.property.taxType;//1: 一般计税 2: 简易计税
+      return gljUtil.getInfoMarketPrice(info,taxType); 
     }
 };
 
@@ -1741,8 +1824,58 @@ $(function () {
         projectGljObject.searchInfoPrice();
       }
     });
+
     $('#info_search_btn').on('click', function (e) {
       projectGljObject.searchInfoPrice();
     });
 
+    $('#infoPriceCoeConfirm').on('click', function (e) {
+      let me = projectGljObject;
+      let infoPriceCoe = $("#infoPriceCoe").val();
+      if(infoPriceCoe==="") return alert("请输入单位转换值!");
+      if(!(/^\d+(\.\d+)?$/.test(infoPriceCoe))) return alert("请输入数字!");
+      $("#infoPriceCoeDiv").modal('hide');
+      let pojectGLJData = me.getProjectGLJSelected();
+      let info=me.infoPriceData[parseInt($("#infoRow").val())];
+      let marketPrice = me.getInfoMarketPrice(info);
+      me.applyInfoPrice(pojectGLJData,marketPrice,parseFloat(infoPriceCoe));
+    });
+
+    $('#muti_apply_info').on('click', function (e) {
+      let year = $('#info_year').val();
+      let month =  $('#info_month').val();
+      let areaID = $('#info_area').val();
+      if(year !="" && month!="" && areaID!=""){
+        $("#mutiApplyInfoPriceDiv").modal("show");
+      }  
+    });
+    $('#mutiApplyinfoPriceConfirm').on('click', function (e) {
+      let typeMap= {};
+      let pgljMap = {};
+      let year = $('#info_year').val();
+      let month =  $('#info_month').val();
+      let areaID = $('#info_area').val();
+      for(let e of $(".info_apply_type")){
+        if($(e).prop('checked') == true){
+          typeMap[$(e).val()] = true;
+        }
+      }
+      for(let pglj of projectGljObject.projectGljSheetData){
+        if(pglj.ratio_data  && pglj.ratio_data.length > 0) continue; //有组成物时跳过
+        let typeString = pglj.type +"";
+        if(typeMap[typeString.charAt(0)]){
+          let index = gljUtil.getIndex(pglj,["name","specs","unit"]);
+          let obj = {pgljID:pglj.id,unitPriceID:pglj.unitPriceID,fullIndex:gljUtil.getIndex(pglj)};
+          pgljMap[index]?pgljMap[index].push(obj):pgljMap[index]=[obj];//考虑到只用三个去匹配会有重复的工料机,所以这里用数组
+        }
+      }
+      if(_.isEmpty(pgljMap)) return;
+      let condition = {
+        period:year+"-"+month,
+        areaID:areaID
+      }
+      let priceFrom = projectGljObject.getPriceFrom();
+      projectObj.project.projectGLJ.mutiApplyInfoPrice(pgljMap,condition,priceFrom);
+      
+    });
 });