浏览代码

广东接口变更相关

vian 5 年之前
父节点
当前提交
52aae461f7
共有 3 个文件被更改,包括 207 次插入26 次删除
  1. 74 1
      modules/pm/facade/pm_facade.js
  2. 5 4
      web/building_saas/main/js/views/mbzm_view.js
  3. 128 21
      web/over_write/js/guangdong_2018_import.js

+ 74 - 1
modules/pm/facade/pm_facade.js

@@ -2057,10 +2057,13 @@ async function importProject(importObj, userID, compilationID, overWriteUrl) {
                 }
             });
             featureLib.feature.push(...unmatched);
-            //设置工程专业的值为费用标准的值..
             featureLib.feature.forEach(f => {
+                //设置工程专业的值为费用标准的值..
                 if (f.key === 'engineering') {
                     f.value = data.property.feeStandardName;
+                } else if (f.key === 'projType' && !f.value) {
+                    const options = f.options && f.options.split('@') || [];
+                    f.value = options[0] || '';
                 }
             });
         }
@@ -2178,8 +2181,15 @@ async function setupStdData(tenderData) {
     //标准人材机code - 映射
     let stdGLJCodeMap = {};
     stdGLJs.forEach(stdGLJ => stdGLJCodeMap[stdGLJ.code] = stdGLJ);
+    // 取费ID-计算程序子目映射
+    const programIDCalculationMap = {};
     //更新定额数据
+    const toSetFakeProgramIDData = [];
     tenderData.ration.forEach(r => {
+        if (r.setFakeProgramID) {
+            toSetFakeProgramIDData.push(r);
+            delete r.setFakeProgramID;
+        }
         let stdRation = stdRationCodeMap[r.code];
         if (stdRation) {
             r.caption = stdRation.caption;
@@ -2199,7 +2209,70 @@ async function setupStdData(tenderData) {
             r.from = 'cpt';
             r.prefix = '补';
         }
+        if (r.calculationItems && r.calculationItems.length > 0 && !programIDCalculationMap[r.programID]) {
+            programIDCalculationMap[r.programID] = r.calculationItems;
+        }
+        delete r.calculationItems;
     });
+    // 更新计算程序
+    const newTemplates = [];
+    const calcFileID = tenderData.tender.property.calcProgramFile.ID;
+    let calcProgramFile = null;
+    if (Object.keys(programIDCalculationMap).length > 0) {
+        calcProgramFile = await calcProgramsModel.findOne({ ID: calcFileID }).lean();
+        if (calcProgramFile) {
+            for (const template of calcProgramFile.templates) {
+                const matched = programIDCalculationMap[template.ID];
+                if (!matched) {
+                    newTemplates.push(template);
+                    continue;
+                }
+                for (const newCalcItem of matched) {
+                    for (const oldCalcItem of template.calcItems) {
+                        if (newCalcItem.fieldName === oldCalcItem.fieldName &&
+                            !(newCalcItem.feeRate === 100 && !oldCalcItem.feeRateID && !oldCalcItem.feeRate)) {
+                                oldCalcItem.feeRate = newCalcItem.feeRate;
+                                oldCalcItem.feeRateID = null; // feeRateID优先级比较高,不赋为空的话为被覆盖
+                        }
+                    }
+                }
+                newTemplates.push(template);
+            }
+        }
+    }
+    // 增加假的计算程序
+    if (toSetFakeProgramIDData.length) {
+        if (!calcProgramFile) {
+            calcProgramFile = await calcProgramsModel.findOne({ ID: calcFileID }).lean();
+        }
+        if (calcProgramFile) {
+            const programIDTemplateMap = {};
+            const programIDNewTemplateMap = {};
+            calcProgramFile.templates.forEach(template => programIDTemplateMap[template.ID] = template);
+            let curID = calcProgramFile.templates.length + 1;
+            toSetFakeProgramIDData.forEach(r => {
+                const matchedNewTempate = programIDNewTemplateMap[r.programID];
+                if (matchedNewTempate) {
+                    r.programID = matchedNewTempate.ID;
+                    return;
+                }
+                const matched = programIDTemplateMap[r.programID];
+                if (matched) {
+                    const newData = {
+                        ID: curID++,
+                        name: `${matched.name}_1`,
+                        calcItems: []
+                    };
+                    newTemplates.push(newData);
+                    programIDNewTemplateMap[r.programID] = newData;
+                    r.programID = newData.ID;
+                }
+            });
+        }
+    }
+    if (newTemplates.length) {
+        await calcProgramsModel.update({ ID: calcFileID }, { $set: { templates: newTemplates } });
+    }
     //更新定额人材机数据
     tenderData.rationGLJ.forEach(rGLJ => {
         rGLJ.from = 'cpt';

+ 5 - 4
web/building_saas/main/js/views/mbzm_view.js

@@ -289,7 +289,7 @@ let mbzm_obj={
         if(rations.create.length > 0){
             serialNo = rations.create[rations.create.length -1].newData.serialNo + 1
         }
-        let n_ration = this.createNewRationData(data,newID,mainRation.data.ID,mainRation.data.billsItemID,serialNo,quantity,mainRation.data.libID);
+        let n_ration = this.createNewRationData(data,newID,mainRation.data.ID,mainRation.data.billsItemID,serialNo,quantity,mainRation.data.libID,false,mainRation.data.manageFeeRate);
         rations.create.push(n_ration);
         //处理其它兄弟节点的序号
         let br = projectObj.project.Ration.getBillsSortRation();
@@ -369,7 +369,7 @@ let mbzm_obj={
         let serialNo = 1;
         serialNo =  this.checkAndGetSerialNo(serialNo,billsID,rations);
         //先查看刚生成的定额中有没有相同父清单,有的话取最后的一个序列号加1
-        let n_ration = this.createNewRationData(data,newID,mainRation.data.ID,billsID,serialNo,quantity,mainRation.data.libID);
+        let n_ration = this.createNewRationData(data,newID,mainRation.data.ID,billsID,serialNo,quantity,mainRation.data.libID,false,mainRation.data.manageFeeRate);
         rations.create.push(n_ration);
     },
     createNewRationInFBFX:function (data,mainRation,quantity,rations,bills) {
@@ -384,7 +384,7 @@ let mbzm_obj={
             let newID =  uuid.v1();
             let serialNo = 1;
              serialNo =  this.checkAndGetSerialNo(serialNo,billsID,rations);
-            let n_ration = this.createNewRationData(data,newID,mainRation.data.ID,billsID,serialNo,quantity,mainRation.data.libID,true);
+            let n_ration = this.createNewRationData(data,newID,mainRation.data.ID,billsID,serialNo,quantity,mainRation.data.libID,true,mainRation.data.manageFeeRate);
             rations.create.push(n_ration);
         }
     },
@@ -418,13 +418,14 @@ let mbzm_obj={
         }
         return newData;
     },
-    createNewRationData:function (data,newID,referenceRationID,billsID,serialNo,quantity,libID,isFBFX) {
+    createNewRationData:function (data,newID,referenceRationID,billsID,serialNo,quantity,libID,isFBFX,manageFeeRate) {
         let newData = projectObj.project.Ration.getTempRationData(newID,billsID,serialNo,rationType.ration);
         newData.referenceRationID = referenceRationID;
         newData.quantity = quantity;
         newData.quantityEXP = gljUtil.isDef(data.coe) && data.coe != "0"?"MBGCL":quantity+"";
         //这里还要生成根据清单生成含量,父清单如果是刚自动生成的,其工程量为0,含量也为0
         newData.contain = projectObj.project.Ration.getContain(projectObj.project.mainTree.findNode(billsID),quantity);
+        newData.manageFeeRate = manageFeeRate;
         let temRation = this.getDefaultRationCreateData(newData,data.code,libID,isFBFX);
         return temRation;
     },

+ 128 - 21
web/over_write/js/guangdong_2018_import.js

@@ -200,6 +200,8 @@ const importXML = (() => {
         });
     }
     // 从xml对象中提取单位工程数据
+
+    // 额外新增的数据(文件里没有,需要额外生成)
     function extractTenders(sectionWorkSrc, xmlObjMap) {
         const unitWorks = arrayValue(sectionWorkSrc, ['UnitWorks']);
         return unitWorks.map(unitWorckSrc => {
@@ -220,6 +222,7 @@ const importXML = (() => {
                 csxm: extractCSXM(src),
                 other: extractOther(src),
                 tax: extractTax(src),
+                evalGLJFromOther: extractProvisionalMaterialEquipmentItem(src),
                 ...extractGLJSummary(src),
                 bidEvaluationSummary: extractBidEvaluationSummary(src)
             };
@@ -234,6 +237,29 @@ const importXML = (() => {
             value: getValue(src, ['_Value'])
         }));
         clearEmptyItems(featureData);
+        console.log(featureData);
+        // 特殊处理几个工程特征(有的文件AttrInfo中不包含一些工程特征)
+        const hasProjectType = featureData.some(item => item.dipName === '工程类型');
+        const hasScale = featureData.some(item => item.dipName === '建设规模');
+        const hasScaleUnit = featureData.some(item => item.dipName === '建设规模单位');
+        if (!hasProjectType) {
+            featureData.push({
+                dispName: '工程类型',
+                value: getValue(tenderSrc, ['_ProjectType'])
+            });
+        }
+        if (!hasScale) {
+            featureData.push({
+                dispName: '建设规模',
+                value: getValue(tenderSrc, ['_Scale'])
+            });
+        }
+        if (!hasScaleUnit) {
+            featureData.push({
+                dispName: '建设规模单位',
+                value: getValue(tenderSrc, ['_Unit'])
+            });
+        }
         return featureData;
 
         function clearEmptyItems(items) {
@@ -474,6 +500,46 @@ const importXML = (() => {
             }
             return rationType.ration;
         }
+        // 根据定额计算程序子目,获取量价类型
+        function getVolumePriceTypeByCalcItems(rationSrc) {
+            const calculationOfItems = arrayValue(rationSrc, ['UnitPriceCalculationOfItem']);
+            for (const item of calculationOfItems) {
+                const code = getValue(item, ['_Code']);
+                const total = +getValue(item, ['_Total']);
+                if (code === 'RGF' && total) {
+                    return { type: rationType.volumePrice, subType: 1 };
+                }
+                if (code === 'CLF' && total) {
+                    return { type: rationType.volumePrice, subType: 201 };
+                }
+                if (code === 'JXF' && total) {
+                    return { type: rationType.volumePrice, subType: 301 };
+                }
+            }
+            return null;
+        }
+        // 提取计算程序费率数据
+        function extractCalculationOfItems(rationSrc) {
+            // 需要提取费率的字段映射
+            const codeFiedNameMap = {
+                'RGF': 'labour',
+                'CLF': 'material',
+                'JXF': 'machine',
+                'GLF': 'manage',
+                'LR': 'profit',
+                'DJ': 'common',
+            };
+            const calculationOfItems = arrayValue(rationSrc, ['UnitPriceCalculationOfItem']);
+            const rst = [];
+            calculationOfItems.forEach(item => {
+                const fieldName = codeFiedNameMap[getValue(item, ['_Code'])];
+                const feeRate = +getValue(item, ['_Rate']);
+                if (fieldName && !isNaN(feeRate)) {
+                    rst.push({ fieldName, feeRate });
+                }
+            });
+            return rst;
+        }
         // 从定额的计算程序提取价格
         function getFeesFromCalculationOfItem(rationSrc) {
             const calculationOfItems = arrayValue(rationSrc, ['UnitPriceCalculationOfItem']);
@@ -487,7 +553,6 @@ const importXML = (() => {
                 'SBF': 'equipment',
                 'LR': 'profit',
                 //'DJ': 'common',定额本身已经有单价这个字段,不需要从这读取
-
             };
             calculationOfItems.forEach(item => {
                 const totalFee = +getValue(item, ['_Total']);
@@ -508,9 +573,13 @@ const importXML = (() => {
         }
         // TODO 目前无法确定定额的取费专业programID,暂时用专业类别Specialty
         function extractRation(rationSrc, jobContentText) {
+            // 需要处理定额编码如易达的某文件,定额编码有“E1-3-52*3”,需要截取“*”之前的作为定额编码
+            let code = getValue(rationSrc, ['_Number']);
+            const codeReg = /([^*]+)\*.*/;
+            code = code.replace(codeReg, '$1');
             const ration = {
                 serialNo: serialNo++,
-                code: getValue(rationSrc, ['_Number']),
+                code,
                 name: getValue(rationSrc, ['_Name']),
                 unit: getValue(rationSrc, ['_Unit']),
                 quantity: getValue(rationSrc, ['_Quantity']),
@@ -524,27 +593,20 @@ const importXML = (() => {
             const feesFromCalcItem = getFeesFromCalculationOfItem(rationSrc);
             ration.fees = mergeFees(fees, feesFromCalcItem);
             ration.rationGLJs = extractRationGLJs(rationSrc);
+            // 没有定额人材机则当作是增加费定额、同时导入后成为量价
+            if (!ration.rationGLJs.length) {
+                const typeData = getVolumePriceTypeByCalcItems(rationSrc);
+                if (typeData) {
+                    Object.assign(ration, typeData);
+                    ration.setFakeProgramID = true;
+                }
+            }
             ration.quantityDetails = extractQuantityDetails(rationSrc);
+            ration.calculationItems = extractCalculationOfItems(rationSrc);
             return ration;
         }
     }
     // 提取措施项目
-    /* function extractCSXM(tenderSrc) {
-        const csxmSrc = getValue(tenderSrc, ['Preliminaries']);
-        const fields = [['DivisionalWorks'], ['WorkElement']];
-        const fees = getFeesFromBasicCost(csxmSrc); // 措施项目的汇总价
-        const items = getItemsRecur(csxmSrc, fields, (itemSrc, curField) => {
-            if (curField[0] === fields[0][0]) {
-                return extractDivisionalWorks(itemSrc, billType.BILL);
-            } else {
-                return extractWorkElement(itemSrc, billType.BILL);
-            }
-        });
-        return {
-            fees,
-            items
-        };
-    } */
     function extractCSXM(tenderSrc) {
         const csxmSrc = getValue(tenderSrc, ['Preliminaries']);
         const fields = [['DivisionalWorks'], ['WorkElement']];
@@ -561,6 +623,21 @@ const importXML = (() => {
             items
         };
     }
+    // 提取额外的暂估材料表
+    // 除了人材机汇总中的is_evaluate = true的材料为暂估材料外,还需要处理ProvisionalMaterialEquipmentItem的数据
+    // 如易达的一些文件,ProvisionalMaterialEquipmentItem中存在人材机汇总没有的数据
+    function extractProvisionalMaterialEquipmentItem(tenderSrc) {
+        const evalGLJs = arrayValue(tenderSrc, ['Sundry', 'ProvisionalMaterialEquipment', 'ProvisionalMaterialEquipmentItem']);
+        return evalGLJs.map(glj => ({
+            code: getValue(glj, ['_Number']),
+            name: getValue(glj, ['_Name']),
+            unit: getValue(glj, ['_Unit']),
+            quantity: getValue(glj, ['_Quantity']),
+            market_price: getValue(glj, ['_Price']),
+            remark: getValue(glj, ['_Remark'])
+        }));
+
+    }
     // 提取其他项目
     function extractOther(tenderSrc) {
         const sundry = getValue(tenderSrc, ['Sundry']);
@@ -984,6 +1061,10 @@ const importXML = (() => {
             const fixedBillsFlag = getFlag(fixedBills);
             let preBills = billsTemplate.find(bills => bills.ParentID === fixedBills.ID && bills.NextSiblingID === -1);
             items.forEach(bills => {
+                // 特殊处理绿色施工,否则可能会重复导入(易达绿色施工安全防护措施费的code为AQWMSGF,feeCode为空)
+                if (bills.name === '绿色施工安全防护措施费' && bills.code === 'AQWMSGF') {
+                    bills.feeCode = 'AQWMSGF';
+                }
                 // 计日工需要特殊处理,兼容广联达的数据,广联达的计日工下的人工、材料、机械的费用字典不对,因此用名称匹配
                 let matched;
                 if (fixedBillsFlag === fixedFlag.DAYWORK) {
@@ -996,6 +1077,9 @@ const importXML = (() => {
                 }
                 if (matched) {
                     assignAttr(matched, bills, ['items'], true);
+                    if (commonUtil.isDef(bills.feeRate) && commonUtil.isDef(matched.feeRateID)) {
+                        delete matched.feeRateID; // 不清除的话,赋值过去的feeRate会被后端覆盖
+                    }
                     if (bills.items && bills.items.length) {
                         mergeitems(matched, bills.items);
                         //mergedBills.push(...mergeDataRecur(fixedBills, [bills]))    
@@ -1342,7 +1426,30 @@ const importXML = (() => {
         }
         // 转换暂估价材料
         function transformEvalSummary() {
-            const evalGLJList = tenderData.gljSummary
+            //evalGLJFromOther
+            const existMap = {};
+            const evalItems = [];
+            tenderData.gljSummary.forEach(glj => {
+                if (glj.is_evaluate) {
+                    existMap[glj.code] = true;
+                    evalItems.push(glj);
+                }
+            });
+            tenderData.evalGLJFromOther.forEach(glj => {
+                if (!existMap[glj.code]) {
+                    evalItems.push(glj);
+                }
+            });
+            const evalGLJList = evalItems.map(glj => {
+                const evalGLJ = {};
+                assignAttr(evalGLJ, glj, [
+                    'code', 'name', 'specs', 'unit', 'quantity', 'market_price',
+                    'originPlace', 'vender', 'remark'
+                ]);
+                evalGLJ.seq = evalGLJ.code;
+                return evalGLJ;
+            });
+            /* const evalGLJList = tenderData.gljSummary
                 .filter(glj => glj.is_evaluate)
                 .map(glj => {
                     const evalGLJ = {};
@@ -1352,7 +1459,7 @@ const importXML = (() => {
                     ]);
                     evalGLJ.seq = evalGLJ.code;
                     return evalGLJ;
-                });
+                }); */
             transformRelatedGLJList(evalGLJList, rst.evaluationList, 'is_evaluate');
         }
         // 生成单价文件
@@ -1382,7 +1489,7 @@ const importXML = (() => {
             ration: [],
             rationGLJ: [],
             rationCoe: [],
-            rationQuantityDetails: []
+            rationQuantityDetails: [],
         };
         billsData
             .filter(bills => bills.rations && bills.rations.length)