Преглед изворни кода

混凝土替换,批量替换功能

zhangweicheng пре 6 година
родитељ
комит
39342584c5

+ 2 - 0
modules/all_models/ration_glj.js

@@ -19,6 +19,8 @@ var ration_glj = new Schema({
         index: true
     },
     rcode:String,
+    //新结构,计录替换前的工料机信息,对于混凝土,替换,计算等问题处理,替换时保存旧数据的5大项信息
+    mIndexObj: Schema.Types.Mixed,
     specs:String,
     unit:String,
     shortName:String,

+ 23 - 5
modules/ration_glj/facade/glj_calculate_facade.js

@@ -66,7 +66,7 @@ async function calculateQuantity(query,noNeedCal=null,refreshRationName = false)
              }
          }
          for(let glj of gljList){//先把混凝土,砂浆,配合比有自定义消耗的挑出来
-             if(gljUtil.isConcreteType(glj.type)&& !noCustomQuantiyt(glj)) await getMixRatioMap(glj,gljList,coeList,assList,mixRatioMap);
+             if(gljUtil.isConcreteType(glj.type)) await getMixRatioMap(glj,gljList,coeList,assList,mixRatioMap);
          }
         gljList = gljUtil.sortRationGLJ(gljList);
         for(let i =0;i<gljList.length;i++ ){
@@ -202,15 +202,33 @@ async function getMixRatioMap(glj,gljList,coeList,assList,mixRatioMap) {//生成
     let assCoeQuantity = await calcWhenNoCustomQuantiyt(decimal,glj,gljList,coeList,assList);//计算要用父工料机经过辅助子目换算后的量
     let unitPriceFileId = await ProjectModel.getUnitPriceFileId(glj.projectID);
     let connect_key = gljUtil.getIndex(glj);
-    let mixList =  await mixRatioModel.find({"unit_price_file_id":unitPriceFileId,'connect_key':connect_key})
+    let mixList =  await mixRatioModel.find({"unit_price_file_id":unitPriceFileId,'connect_key':connect_key});
     for(let m of mixList){
+        if(glj.createType ==  'replace'&& glj.mIndexObj){//如果是替换过的工料机,要造一条加的数据去补回下面的减数据
+            //与下面的减相对应,如果有没被引用子组成物工料机,会少一条加的数据,这样,那条没被引用的消耗量会被减为0
+            addToMixMap(m,mixRatioMap,glj.rationItemQuantity,0);
+        }
+        if(!noCustomQuantiyt(glj)) {//有自定义消耗量才做正常的计算处理
+            addToMixMap(m,mixRatioMap,glj.customQuantity,assCoeQuantity);
+        }
+    }
+    if(glj.createType ==  'replace' && glj.mIndexObj){//如果这条是替换过的混凝土,原来的组成物的消耗量还要减去替换前的混凝土得到的消耗量
+        let t_con_key = gljUtil.getIndex(glj.mIndexObj);
+        let tmixList = await mixRatioModel.find({"unit_price_file_id":unitPriceFileId,'connect_key':t_con_key});
+        for(let tm of tmixList ){
+            addToMixMap(tm,mixRatioMap,0,glj.rationItemQuantity);
+        }
+    }
+    function addToMixMap(m,map,cust,ass,isReplace = false) {
         let mkey = gljUtil.getIndex(m);
-        if(mixRatioMap[mkey]){
-            mixRatioMap[mkey].push({customQuantity:glj.customQuantity,assCoeQuantity:assCoeQuantity,consumption:m.consumption});
+        let pObj = {customQuantity:cust,assCoeQuantity:ass,consumption:m.consumption,isReplace:isReplace};
+        if(map[mkey]){
+            map[mkey].push(pObj);
         }else {
-            mixRatioMap[mkey] = [{customQuantity:glj.customQuantity,assCoeQuantity:assCoeQuantity,consumption:m.consumption}];
+            map[mkey] = [pObj];
         }
     }
+
 }
 
 

+ 49 - 37
modules/ration_glj/facade/ration_glj_facade.js

@@ -168,6 +168,7 @@ function createNewRecord(ration_glj) {
     newRecoed.GLJID = ration_glj.GLJID;
     newRecoed.rationID = ration_glj.rationID;
     newRecoed.rationItemQuantity = ration_glj.rationItemQuantity;
+    newRecoed.customQuantity = ration_glj.customQuantity;
     newRecoed.quantity = ration_glj.quantity;
     newRecoed.name = ration_glj.name;
     newRecoed.code = ration_glj.code;
@@ -733,7 +734,7 @@ function addMixRatioToRationGLJ(g,subList,newRecodes,GLJMap){
             unit:mr.unit,
             specs:mr.specs,
             from:mr.from,
-            createType:g.createType,
+            createType:'add',
             shortName:mr.unit_price.short_name,
             billsItemID:g.billsItemID,
             type:mr.type,
@@ -749,28 +750,40 @@ function addMixRatioToRationGLJ(g,subList,newRecodes,GLJMap){
 }
 
 async  function replaceGLJByData(data,compilation) {
-    let projectGljModel = new GLJListModel();
+    let projectGljModel = new GLJListModel(),newRecodes=[],deleteList=[];
     let [unitFileId,ext] = await  prepareExtData(data.projectID,compilation);
     let result = await projectGljModel.addList(getGLJSearchInfo(data),unitFileId,ext);
-    let typeString = result.type+'';
     data.projectGLJID = result.id;
-    //  CompositionGLJ=await this.getCompositionGLJByData(data,unitPriceFileId);
-    let [newRecodes,deleteList] = await replaceMixRatio(data,result,unitFileId);
-    let updateResult = await ration_glj.findOneAndUpdate({ID: data.ID, projectID: data.projectID}, data);//更新定额工料机
-    //组装回传数据
-    data.marketPrice = result.unit_price.market_price;
-    data.adjustPrice = result.unit_price.base_price;
-    data.basePrice = result.unit_price.base_price;
-    data.isAdd = result.unit_price.is_add;
-    if (typeString.startsWith("2")||typeString=='4'||typeString=='5') {//只有材料类型才显示是否暂估
-        data.isEstimate = result.is_evaluate;
-    }
-    if (result.hasOwnProperty('subList') && result.subList.length > 0) {
-        data.subList = getMixRatioShowDatas(result.subList);
+    if(data.toCommercial == true){//从混凝土改成商品混凝土,
+       let [contype,newR] =  await concreteTypeToCommercial(data);
+        newRecodes.push(newR);
+        data=contype;
+    }else {
+        let [newList,tdelList] = await replaceMixRatio(data,result,unitFileId);
+        newRecodes = newList;
+        deleteList = tdelList;
+        let updateResult = await ration_glj.findOneAndUpdate({ID: data.ID, projectID: data.projectID}, data);//更新定额工料机
     }
+
     return {data:data,newRecodes:newRecodes,deleteList:deleteList};
 }
 
+
+async function concreteTypeToCommercial(data) {
+   //旧的自定义消耗量改为0
+   let contype =  await ration_glj.findOneAndUpdate({ID: data.originalID}, {customQuantity:'0'});
+    //因为商品混凝土是没有组成物的,所以不用考虑组成物的情况
+    let new_glj =  createComercialConcreteData(data);
+    await ration_glj.create(new_glj);
+    return [contype,new_glj];
+}
+
+function createComercialConcreteData(data){
+    data.ID = uuidV1();
+    return createNewRecord(data);
+}
+
+
 async function replaceMixRatio(g,result,unitFileId){
     let newRecodes=[],deleteList = [];
     if(gljUtil.isConcreteType(g.type)||gljUtil.isCommercialConcreteType(g.type)){//混凝土大类,商品混凝土属于相同大类,替换前和替换后只判断一个就好了
@@ -823,14 +836,21 @@ async function replaceGLJ(data,compilation) {
 
 async function replaceMixRatioForMReplace(tasks,result,unitFileId) {
     let allNewRecodes = [],allDeleteList=[];
-    for(let t of tasks){
-        let tem = _.cloneDeep(t.updateOne.update);
-        tem.ID = t.updateOne.filter.ID;
-        tem.rationID = t.updateOne.filter.rationID;
-        delete t.updateOne.filter.rationID;
-        let [newRecodes,deleteList] = await replaceMixRatio(tem,result,unitFileId);
-        allNewRecodes = allNewRecodes.concat(newRecodes);
-        allDeleteList = allDeleteList.concat(deleteList);
+    for(let t of tasks){//要新增一条商品混凝土
+        if(t.insertOne){
+            t.insertOne.document.projectGLJID = result.id;
+            t.insertOne.document = createComercialConcreteData(t.insertOne.document);
+            allNewRecodes.push(t.insertOne.document);
+        }else if(t.updateOne&&t.updateOne.update.isConcrete == true){//过滤掉只更新自定义消耗量的task
+            let tem = _.cloneDeep(t.updateOne.update);
+            tem.ID = t.updateOne.filter.ID;
+            tem.rationID = t.updateOne.filter.rationID;
+            delete t.updateOne.filter.rationID;
+            delete t.updateOne.update.isConcrete;
+            let [newRecodes,deleteList] = await replaceMixRatio(tem,result,unitFileId);
+            allNewRecodes = allNewRecodes.concat(newRecodes);
+            allDeleteList = allDeleteList.concat(deleteList);
+        }
     }
     return {newRecodes:allNewRecodes,deleteList:allDeleteList}
 }
@@ -846,25 +866,17 @@ async function mReplaceGLJ(data,compilation) {
     newDoc.projectGLJID = result.id;
     let rationList = [];//await ration_glj.distinct('rationID', data.query);
     for(let t of data.tasks){
-        rationList.push(t.updateOne.filter.rationID);
-        t.updateOne.update.projectGLJID = result.id;//更新项目工料机ID
+        if(t.updateOne){
+            rationList.push(t.updateOne.filter.rationID);
+            if(t.updateOne.update.code) t.updateOne.update.projectGLJID = result.id;//如果是不是只修改自定义消耗的task,更新项目工料机ID
+        }
     }
-    if(gljUtil.isConcreteType(result.unit_price.type)) {
+    if(gljUtil.isConcreteType(result.unit_price.type)||gljUtil.isCommercialConcreteType(result.unit_price.type)) {
         mixResult = await replaceMixRatioForMReplace(data.tasks,result,unitFileId);
         noNeedCal = null;
     }
     await ration_glj.bulkWrite(data.tasks);
 
-    newDoc.marketPrice = result.unit_price.market_price;
-    newDoc.adjustPrice = result.unit_price.base_price;
-    newDoc.basePrice = result.unit_price.base_price;
-    newDoc.isAdd = result.unit_price.is_add;
-    if (typeString.startsWith("2")||typeString=='4'||typeString=='5') {//只有材料类型才显示是否暂估
-        newDoc.isEstimate = result.is_evaluate;
-    }
-    if (result.hasOwnProperty('subList') && result.subList.length > 0) {
-        newDoc.subList = getMixRatioShowDatas(result.subList);
-    }
     let [stateList,glj_result] = await changAdjustState(data, rationList,noNeedCal);
     data.doc = newDoc;
     mresult.data = data;

+ 4 - 0
public/web/gljUtil.js

@@ -326,6 +326,10 @@ let gljUtil = {
         let commercialType = [gljUtil.gljType.COMMERCIAL_CONCRETE,gljUtil.gljType.COMMERCIAL_MORTAR];//商品混凝土、商品砂浆
         return commercialType.indexOf(type)!=-1
     },
+    //是否从混凝土改成商品混凝土,并且混凝土的定额消耗量不为空,则原混凝土的自定义消耗改成0,插入一条新的商品混凝土自定义消耗量为原自定义或定额消耗
+    isAddCommercialForReplace:function (oldType,newType,rationItemQuantity) {
+        return gljUtil.isConcreteType(oldType)&&gljUtil.isCommercialConcreteType(newType)&&rationItemQuantity&&rationItemQuantity!='0';
+    },
     hasComposition:function (ration_glj,isRationType) {//判断是否有组成物,有则返回true   现在主材类型的工料机也有可能有组成物。
         let type = isRationType==true? ration_glj.subType:ration_glj.type;
         if(gljUtil.notEditType.indexOf(type)!=-1||type==gljType.MAIN_MATERIAL){

+ 34 - 43
web/building_saas/main/js/models/ration_glj.js

@@ -188,6 +188,7 @@ let ration_glj = {
             }
         };
         ration_glj.prototype.updateGLJNodeAfterReplace = function(data){
+            if(!data) return null;
             if (this.needShowToTree(data)) {//当替换的是主材或设备时,刷新对应的树节点
                 var node = this.findGLJNodeByID(data.ID);
                 if (node) {
@@ -799,7 +800,7 @@ let ration_glj = {
             let me = this;
             me.addAndDeleteDatas(result.newRecodes,result.deleteList);
             let list_index = _.findIndex(me.datas, {'ID': result.data.ID});
-            me.datas[list_index] = result.data;
+            if(result.data) me.datas[list_index] = result.data;
             me.refreshQuantityAfterCalResult(result.glj_result);
         };
 
@@ -817,9 +818,10 @@ let ration_glj = {
             if (oldData.createType===undefined || oldData.createType == 'normal') {// createTypel 默认是normal 只有是定额下带的工料机才需把类型改成替换,其它的保持不变
                 oldData.rcode = oldData.code;
                 oldData.createType = 'replace';
-            }
-            if(oldData.createType == 'replace' && oldData.rcode == glj.code){//如果原数据已经是替换过的,这次替换又恢复成原数据,则把类型改回来
-                oldData.createType = 'normal'
+                oldData.mIndexObj ={code:oldData.code,name:oldData.name,type:oldData.type,unit:oldData.unit,specs:oldData.specs};
+            }else if(oldData.createType == 'replace' && oldData.rcode == glj.code){//如果原数据已经是替换过的,这次替换又恢复成原数据,则把类型改回来
+                oldData.createType = 'normal';
+                oldData.mIndexObj = null;
             }
             oldData.GLJID = glj.ID;
             oldData.name = glj.name;
@@ -830,6 +832,7 @@ let ration_glj = {
             oldData.specs = glj.specs;
             oldData.model = glj.model;
             oldData.basePrice = glj.basePrice;
+            oldData.shortName=glj.shortName;
             oldData.marketPrice = glj.basePrice;
             oldData.repositoryId = glj.repositoryId;
             oldData.materialType = glj.materialType;
@@ -859,7 +862,17 @@ let ration_glj = {
             if (selectCode == gljOprObj.getIndex(oldData, gljKeyArray)) {
                 return callback(null);
             }
-            oldData = this.getReplaceDataByStd(oldData,glj);
+            //如果是从混凝土改成商品混凝土,并且混凝土的定额消耗量不为空,则原混凝土的自定义消耗改成0,插入一条新的商品混凝土自定义消耗量为原自定义或定额消耗
+            if(gljUtil.isAddCommercialForReplace(oldData.type,glj.gljType,oldData.rationItemQuantity)){
+                let originalID = oldData.ID;
+                let customQuantity = gljUtil.isDef(oldData.customQuantity)? oldData.customQuantity:oldData.rationItemQuantity;
+                oldData = this.getAddDataByStd(glj,oldData.rationID,oldData.billsItemID,oldData.projectID);
+                oldData.toCommercial=true;
+                oldData.originalID = originalID;
+                oldData.customQuantity = customQuantity;
+            }else {
+                oldData = this.getReplaceDataByStd(oldData,glj);
+            }
             $.bootstrapLoading.start();
             CommonAjax.post("/rationGlj/replaceGLJ", oldData, callback, function () {
                 $.bootstrapLoading.end();
@@ -867,7 +880,7 @@ let ration_glj = {
         };
 
         ration_glj.prototype.mReplaceGLJ = function (selectCode, oldData, callback) {
-            let allGLJ = gljOprObj.AllRecode,tasks = [],updateMap={};
+            let allGLJ = gljOprObj.AllRecode,tasks = [],updateMap={},doc = null;
             let oldIndex = gljOprObj.getIndex(oldData, gljKeyArray);
             let glj = _.find(allGLJ, function (item) {
                 let i_key = gljOprObj.getIndex(item, gljLibKeyArray);
@@ -882,50 +895,28 @@ let ration_glj = {
                 name: oldData.name,
                 unit: oldData.unit,
                 type: oldData.type
-            }
+            };
             if (oldData.specs && oldData.specs != '') {
                 query.specs = oldData.specs;
             }
-            let doc = {
-                GLJID: glj.ID,
-                createType: 'replace',
-                rationItemQuantity: 0,
-                name: glj.name,
-                code: glj.code,
-                original_code: glj.code,
-                unit: glj.unit,
-                specs: glj.specs,
-                type: glj.gljType,
-                model:glj.model,
-                basePrice: glj.basePrice,
-                marketPrice:glj.basePrice,
-                repositoryId: glj.repositoryId,
-                materialType: glj.materialType,   //三材类别
-                materialCoe: glj.materialCoe,
-                grossWeightCoe:glj.grossWeightCoe,
-                purchaseStorageRate:glj.purchaseStorageRate,
-                offSiteTransportLossRate:glj.offSiteTransportLossRate,
-                handlingLossRate:glj.handlingLossRate,
-                projectID: oldData.projectID
-            };
-            if (glj.hasOwnProperty("compilationId")) {
-                doc.from = "cpt";
-                if (glj.code.indexOf('-') != -1) {//这条工料机是用户通过修改包称、规格、型号等保存到补充工料机库的
-                    doc.original_code = glj.code.split('-')[0];//取-前的编号作为原始编号
-                }
-            } else {
-                doc.from = "std";
-            }
             for(let d of this.datas){//查询出所有需替换的工料机
                 let tem_index = gljOprObj.getIndex(d, gljKeyArray);
                 if(tem_index == oldIndex){
-                    let tem_doc = _.cloneDeep(doc);
-                    if(d.createType == 'replace'){
-                        tem_doc.rcode = d.rcode;
-                    }else if(d.createType == 'add'){//对于添加的类型,替换后还是添加类型
-                        tem_doc.createType = 'add';
+                    let tem_doc = {};
+                    //是否从混凝土改成商品混凝土,并且混凝土的定额消耗量不为空
+                    if(gljUtil.isAddCommercialForReplace(d.type,glj.gljType,d.rationItemQuantity)){
+                        tem_doc = {'customQuantity':'0'};
+                        //插入一条新的定额,这里的更新自定义消耗量操作由task完成了,不用像单条替换那样做标记,修改等
+                        let newDoc =  this.getAddDataByStd(glj,d.rationID,d.billsItemID,d.projectID);
+                        let customQuantity = gljUtil.isDef(d.customQuantity)? d.customQuantity:d.rationItemQuantity;
+                        newDoc.customQuantity = customQuantity;
+                        let tTask = {insertOne:{document: newDoc}};
+                        tasks.push(tTask);
+                        doc=newDoc//后台操作: 要根据nweDoc,插入项目工料机,修改insertOne里项目工料机ID,生成新的自身ID
                     }else {
-                        tem_doc.rcode = d.code
+                        tem_doc = this.getReplaceDataByStd(d,glj);
+                        if(gljUtil.isConcreteType(d.type)||gljUtil.isCommercialConcreteType(d.type)) tem_doc.isConcrete = true;//这里是在批量替换中有可能同时存在定额下的替换和添加的替换,对于添加的替换,要走替换混凝土的逻辑,定额下的替换又走另外的逻辑
+                        doc = tem_doc;
                     }
                     let task = {
                         updateOne:{

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

@@ -1214,7 +1214,7 @@ var gljOprObj = {
             _.forEach(project.ration_glj.datas, function (t) {
                 //     let t_index = me.getIndex(t, gljKeyArray);
                 if (updateMap[t.ID]) {
-                    me.updateProperty(t, data.doc);
+                    if(updateMap[t.ID].code)  me.updateProperty(t, data.doc);//说明这条不是只更新自定义消耗量的,才要更新项目工料机
                     me.updateProperty(t, updateMap[t.ID]);
                     if (project.ration_glj.needShowToTree(t)) {//如果是造价书中的树节点,则也须刷新
                         project.ration_glj.transferToNodeData(t);