|
@@ -28,6 +28,8 @@ const importXML = (() => {
|
|
|
//导入的文件类型,界面选的文件类型是生成项目的文件类型,这里的文件类型指的是,要导入文件的类型,
|
|
|
//导入文件类型不同,导入数据不同
|
|
|
let importFileKind = '';
|
|
|
+ // 投标文件和控制价文件是完全导入数据的
|
|
|
+ let isFullyImport = false;
|
|
|
// 文件类型
|
|
|
const FileKind = {
|
|
|
'6': 1, // 投标
|
|
@@ -65,10 +67,10 @@ const importXML = (() => {
|
|
|
// 默认、中间过程
|
|
|
PROCESS: 6
|
|
|
};
|
|
|
- // 根据上方精度要求得到的项目属性,小数位数的值
|
|
|
+ // 根据上方精度要求得到的项目属性,小数位数的值(定额工程量小数位数需求改成六位)
|
|
|
const tenderPropertyDecimal = {
|
|
|
bills: { unitPrice: Decimal.FEE, totalPrice: Decimal.FEE },
|
|
|
- ration: { quantity: Decimal.QUANTITY, unitPrice: Decimal.FEE, totalPrice: Decimal.FEE },
|
|
|
+ ration: { quantity: Decimal.PROCESS, unitPrice: Decimal.FEE, totalPrice: Decimal.FEE },
|
|
|
glj: { quantity: Decimal.GLJ, unitPriceHasMix: Decimal.FEE, unitPrice: Decimal.FEE },
|
|
|
feeRate: Decimal.RATE,
|
|
|
quantity_detail: 4,
|
|
@@ -97,6 +99,7 @@ const importXML = (() => {
|
|
|
const projectXMLObj = xmlObjMap['Project.xml'];
|
|
|
const projectSrc = getValue(projectXMLObj, ['ConstructionProject']);
|
|
|
importFileKind = FileKind[getValue(projectSrc, ['_FileKind'])]; // 标记当前导入的文件类型
|
|
|
+ isFullyImport = [FileKind.tender, FileKind.control].includes(importFileKind);
|
|
|
const rst = {
|
|
|
projType: projectType.Project,
|
|
|
name: getValue(projectSrc, ['_Name']),
|
|
@@ -107,7 +110,7 @@ const importXML = (() => {
|
|
|
basicInformation: extractBasicInfo(projectSrc)
|
|
|
};
|
|
|
countData.unitPriceCount = countData.projectGLJCount;
|
|
|
- if (importFileKind !== FileKind.tender) {
|
|
|
+ if (!isFullyImport) {
|
|
|
countData = {
|
|
|
projectCount: countData.projectCount,
|
|
|
unitPriceFileCount: countData.unitPriceFileCount
|
|
@@ -122,6 +125,7 @@ const importXML = (() => {
|
|
|
const bidderInfo = getValue(projectSrc, ['ConstructionInfo', 'BidderInfo']); // 投标信息
|
|
|
return [
|
|
|
{ key: 'projNum', value: getValue(projectSrc, ['_Number']) }, // 编码
|
|
|
+ { key: 'projectType', value: getValue(projectSrc, ['_ProjectType']) }, // 工程类型
|
|
|
{ key: 'projectCategory', value: getValue(projectSrc, ['_ProjectCategory']) }, // 工程类别
|
|
|
{ key: 'constructionType', value: getValue(projectSrc, ['_ConstructionType']) }, // 建设性质
|
|
|
{ key: 'regionalCategories', value: AreaKind[getValue(projectSrc, ['_AreaKind'])] }, // 地区类被
|
|
@@ -197,6 +201,8 @@ const importXML = (() => {
|
|
|
});
|
|
|
}
|
|
|
// 从xml对象中提取单位工程数据
|
|
|
+
|
|
|
+ // 额外新增的数据(文件里没有,需要额外生成)
|
|
|
function extractTenders(sectionWorkSrc, xmlObjMap) {
|
|
|
const unitWorks = arrayValue(sectionWorkSrc, ['UnitWorks']);
|
|
|
return unitWorks.map(unitWorckSrc => {
|
|
@@ -217,6 +223,7 @@ const importXML = (() => {
|
|
|
csxm: extractCSXM(src),
|
|
|
other: extractOther(src),
|
|
|
tax: extractTax(src),
|
|
|
+ evalGLJFromOther: extractProvisionalMaterialEquipmentItem(src),
|
|
|
...extractGLJSummary(src),
|
|
|
bidEvaluationSummary: extractBidEvaluationSummary(src)
|
|
|
};
|
|
@@ -231,6 +238,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) {
|
|
@@ -267,7 +297,7 @@ const importXML = (() => {
|
|
|
const feeRate = getValue(src, ['_Rate']);
|
|
|
item.feeRate = +feeRate !== 100 && feeRate || undefined;
|
|
|
}
|
|
|
- if (importFileKind !== FileKind.tender) {
|
|
|
+ if (!isFullyImport) {
|
|
|
delete item.feeRate
|
|
|
delete item.fees;
|
|
|
}
|
|
@@ -327,7 +357,7 @@ const importXML = (() => {
|
|
|
item.feeCode = FlagFeeCodeMap[fixedFlag.OTHER_MEASURE_FEE];
|
|
|
}
|
|
|
}
|
|
|
- if (importFileKind === FileKind.tender) {
|
|
|
+ if (isFullyImport) {
|
|
|
const summaryFees = getFeesFromBasicCost(divisionalSrc);
|
|
|
const fees = [{ fieldName: 'common', totalFee: getValue(divisionalSrc, ['_Total']), unitFee: getValue(divisionalSrc, ['_TechnicalAndEconomicIndex']) }];
|
|
|
item.fees = mergeFees(fees, summaryFees);
|
|
@@ -360,21 +390,19 @@ const importXML = (() => {
|
|
|
bills.feeRate = +feeRate !== 100 && feeRate || undefined;
|
|
|
}
|
|
|
// 投标和控制价,需要导入最高限价
|
|
|
- if ([FileKind.tender, FileKind.control].includes(importFileKind)) {
|
|
|
+ if (isFullyImport) {
|
|
|
const maxPrice = getValue(workElementSrc, ['_PriceHigh']);
|
|
|
//不为0才输出
|
|
|
if (maxPrice && maxPrice !== '0') {
|
|
|
bills.outPutMaxPrice = true;
|
|
|
bills.maxPrice = maxPrice;
|
|
|
}
|
|
|
- if (importFileKind === FileKind.tender) {
|
|
|
- const summaryFees = getFeesFromBasicCost(workElementSrc);
|
|
|
- const fees = [
|
|
|
- { fieldName: 'common', unitFee: getValue(workElementSrc, ['_Price']), totalFee: getValue(workElementSrc, ['_Total']) },
|
|
|
- { fieldName: 'equipment', unitFee: getValue(workElementSrc, ['_EquipmentPrice']) },
|
|
|
- ];
|
|
|
- bills.fees = mergeFees(fees, summaryFees);
|
|
|
- }
|
|
|
+ const summaryFees = getFeesFromBasicCost(workElementSrc);
|
|
|
+ const fees = [
|
|
|
+ { fieldName: 'common', unitFee: getValue(workElementSrc, ['_Price']), totalFee: getValue(workElementSrc, ['_Total']) },
|
|
|
+ { fieldName: 'equipment', unitFee: getValue(workElementSrc, ['_EquipmentPrice']) },
|
|
|
+ ];
|
|
|
+ bills.fees = mergeFees(fees, summaryFees);
|
|
|
}
|
|
|
return bills;
|
|
|
// 获取项目特征文本
|
|
@@ -436,7 +464,7 @@ const importXML = (() => {
|
|
|
}
|
|
|
// 提取定额
|
|
|
function extractRations(workElementSrc) {
|
|
|
- if (importFileKind !== FileKind.tender) {
|
|
|
+ if (!isFullyImport) {
|
|
|
return [];
|
|
|
}
|
|
|
// 正常情况下定额肯定是在WorkContent内的,但是也做定额不在WorkContent内的处理(外层定额)
|
|
@@ -473,6 +501,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']);
|
|
@@ -486,7 +554,6 @@ const importXML = (() => {
|
|
|
'SBF': 'equipment',
|
|
|
'LR': 'profit',
|
|
|
//'DJ': 'common',定额本身已经有单价这个字段,不需要从这读取
|
|
|
-
|
|
|
};
|
|
|
calculationOfItems.forEach(item => {
|
|
|
const totalFee = +getValue(item, ['_Total']);
|
|
@@ -507,9 +574,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']),
|
|
@@ -523,27 +594,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']];
|
|
@@ -560,6 +624,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']);
|
|
@@ -569,7 +648,7 @@ const importXML = (() => {
|
|
|
const sundryFees = [{ fieldName: 'common', totalFee: getValue(sundryCosts, ['_Total']) }];
|
|
|
const provisionalMaterialEquipment = getValue(sundry, ['ProvisionalMaterialEquipment']);
|
|
|
return {
|
|
|
- fees: importFileKind === FileKind.tender ? sundryFees : [],
|
|
|
+ fees: isFullyImport ? sundryFees : [],
|
|
|
sundryCosts: extractData(sundry, 'SundryCosts', [['SundryCostsGroup'], ['SundryCostsItem']]),
|
|
|
provisional: extractData(sundry, 'ProvisionalSums', [['ProvisionalSumsGroup'], ['ProvisionalSumsItem']]),
|
|
|
ProvisionalMaterialEquipment: {
|
|
@@ -591,7 +670,7 @@ const importXML = (() => {
|
|
|
if (isGroup) {
|
|
|
source = {
|
|
|
name: getValue(itemSrc, ['_Name']),
|
|
|
- fees: importFileKind === FileKind.tender ? [{ fieldName: 'common', totalFee: getValue(itemSrc, ['_Total']) }] : [],
|
|
|
+ fees: isFullyImport ? [{ fieldName: 'common', totalFee: getValue(itemSrc, ['_Total']) }] : [],
|
|
|
feeCode: getValue(itemSrc, ['_Code']),
|
|
|
remark: getValue(itemSrc, ['_Remark'])
|
|
|
};
|
|
@@ -602,7 +681,7 @@ const importXML = (() => {
|
|
|
unit: getValue(itemSrc, ['_Unit']),
|
|
|
calcBase: getValue(itemSrc, ['_QtyFormula']),
|
|
|
feeRate: +feeRate !== 100 && feeRate || undefined,
|
|
|
- fees: importFileKind === FileKind.tender ? [{ fieldName: 'common', unitFee: getValue(itemSrc, ['_Price']), totalFee: getValue(itemSrc, ['_Total']) }] : [],
|
|
|
+ fees: isFullyImport ? [{ fieldName: 'common', unitFee: getValue(itemSrc, ['_Price']), totalFee: getValue(itemSrc, ['_Total']) }] : [],
|
|
|
feeCode: getValue(itemSrc, ['_Code']),
|
|
|
remark: getValue(itemSrc, ['_Remark'])
|
|
|
};
|
|
@@ -616,7 +695,7 @@ const importXML = (() => {
|
|
|
function extractData(sundry, srcName, fields, groupExtendMap, itemExtendMap) {
|
|
|
const src = getValue(sundry, [srcName]);
|
|
|
return {
|
|
|
- fees: importFileKind === FileKind.tender ? [{ fieldName: 'common', totalFee: getValue(src, ['_Total']) }] : [],
|
|
|
+ fees: isFullyImport ? [{ fieldName: 'common', totalFee: getValue(src, ['_Total']) }] : [],
|
|
|
feeCode: getValue(src, ['_Code']),
|
|
|
items: extractItemsRecur(src, fields, (itemSrc, curField) => {
|
|
|
const groupExtend = groupExtendMap
|
|
@@ -652,7 +731,7 @@ const importXML = (() => {
|
|
|
name: getValue(src, ['_Name']),
|
|
|
calcBase: getValue(src, ['_QtyFormula']),
|
|
|
feeRate: +feeRate !== 100 && feeRate || undefined,
|
|
|
- fees: importFileKind === FileKind.tender ? [{ fieldName: 'common', totalFee: getValue(src, ['_Total']) }] : [],
|
|
|
+ fees: isFullyImport ? [{ fieldName: 'common', totalFee: getValue(src, ['_Total']) }] : [],
|
|
|
feeCode: getValue(src, ['_Code']),
|
|
|
remark: getValue(src, ['_Remark'])
|
|
|
};
|
|
@@ -661,15 +740,21 @@ const importXML = (() => {
|
|
|
|
|
|
// 供料方式
|
|
|
const Provider = {
|
|
|
- '1': commonConstants.supplyType.ZXCG,
|
|
|
- '2': commonConstants.supplyType.BFJG,
|
|
|
- '3': commonConstants.supplyType.WQJG
|
|
|
+ '1': commonConstants.supplyType.ZXCG, // 自行采购
|
|
|
+ '2': commonConstants.supplyType.JGCL, // 甲供材料
|
|
|
+ '3': commonConstants.supplyType.JDYG // 甲定乙供
|
|
|
};
|
|
|
|
|
|
+ // 获取原始编码
|
|
|
+ function getOriginalCode(code) {
|
|
|
+ //编码后面有-\d+的形式,去掉-\d+取前面的字符串作为原始代码
|
|
|
+ return code.replace(/(.*)-\d+$/, '$1');
|
|
|
+ }
|
|
|
+
|
|
|
// 提取人材机汇总相关(人材机汇总表、承包材料表)
|
|
|
function extractGLJSummary(tenderSrc) {
|
|
|
const initData = { gljSummary: [], differentiaSummary: [], exponentialSummary: [] };
|
|
|
- if (importFileKind !== FileKind.tender) {
|
|
|
+ if (!isFullyImport) {
|
|
|
return initData;
|
|
|
}
|
|
|
const taxType = getValue(tenderSrc, ['_TaxModel']); // 计税方式
|
|
@@ -687,11 +772,6 @@ const importXML = (() => {
|
|
|
return acc;
|
|
|
}, initData);
|
|
|
|
|
|
- // 获取原始编码
|
|
|
- function getOriginalCode(code) {
|
|
|
- //编码后面有-\d+的形式,去掉-\d+取前面的字符串作为原始代码
|
|
|
- return code.replace(/(.*)-\d+$/, '$1');
|
|
|
- }
|
|
|
// TODO (不靠谱) 获取人材机类型数据
|
|
|
// 导入的源文件没有细化区分人材机类型,这里只是暂时大概给个值。后续会在后端与标准人材机进行配对。也因此无法准确处理补充人材机
|
|
|
function getTypeData(gljSrc) {
|
|
@@ -743,6 +823,9 @@ const importXML = (() => {
|
|
|
function extractGLJ(gljSrc) {
|
|
|
countData.projectGLJCount++;
|
|
|
const code = getValue(gljSrc, ['_Number']);
|
|
|
+ /* if (code.includes('99450680')) {
|
|
|
+ debugger;
|
|
|
+ } */
|
|
|
return {
|
|
|
code,
|
|
|
original_code: getOriginalCode(code),
|
|
@@ -805,7 +888,7 @@ const importXML = (() => {
|
|
|
}
|
|
|
// 提取评标材料
|
|
|
function extractBidEvaluationSummary(tenderSrc) {
|
|
|
- if (importFileKind !== FileKind.tender) {
|
|
|
+ if (!isFullyImport) {
|
|
|
return [];
|
|
|
}
|
|
|
const srcList = arrayValue(tenderSrc, ['BidEvaluationMainMaterial']);
|
|
@@ -969,6 +1052,18 @@ const importXML = (() => {
|
|
|
mergeCSXM(tenderData.csxm);
|
|
|
mergeOther(tenderData.other);
|
|
|
mergeTax(tenderData.tax);
|
|
|
+ // 需要清空各种原因导入的父项的工程量
|
|
|
+ /* const parentMap = {};
|
|
|
+ mergedBills.forEach(bills => {
|
|
|
+ if (bills.ParentID !== -1) {
|
|
|
+ parentMap[bills.ParentID] = 1;
|
|
|
+ }
|
|
|
+ })
|
|
|
+ mergedBills.forEach(bills => {
|
|
|
+ if (parentMap[bills.ID] && commonUtil.isDef(bills.quantity)) {
|
|
|
+ delete bills.quantity;
|
|
|
+ }
|
|
|
+ }) */
|
|
|
return mergedBills;
|
|
|
|
|
|
// 合并清单数据
|
|
@@ -983,6 +1078,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) {
|
|
@@ -995,6 +1094,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]))
|
|
@@ -1122,7 +1224,8 @@ const importXML = (() => {
|
|
|
}
|
|
|
// 检查清单是否引用了自身,比如广联达导出文件中 材料保管费基数为CLBGF
|
|
|
function isCalcBaseCycle(bills) {
|
|
|
- return bills.calcBase.match(new RegExp(`\\b${bills.feeCode}\\b`)); // \b: 匹配前一个字符和后一个字符不全为\w的位置
|
|
|
+ const matched = bills.calcBase.match(new RegExp(`\\b${bills.feeCode}\\b`)); // \b: 匹配前一个字符和后一个字符不全为\w的位置
|
|
|
+ return !!(matched && matched[0]);
|
|
|
}
|
|
|
// 转换计算基数
|
|
|
// 1.有子项数据,则清空基数
|
|
@@ -1220,6 +1323,12 @@ const importXML = (() => {
|
|
|
const hasChild = billsData.some(data => data.ParentID === bills.ID);
|
|
|
let unitFee = getFee(bills.fees, ['common', 'unitFee']);
|
|
|
const totalFee = getFee(bills.fees, ['common', 'totalFee']);
|
|
|
+ // 如果费率为0、同时合价不为0,则需要清空计算基数和费率(当作数量单价的形式。易达某文件出现了费率为0、有金额且有基数的数据)
|
|
|
+ // 不这么处理的话,导入后造价计算,此清单金额算出来会是0
|
|
|
+ if (+bills.feeRate === 0 && +totalFee > 0) {
|
|
|
+ bills.calcBase = '';
|
|
|
+ bills.feeRate = null;
|
|
|
+ }
|
|
|
if (!hasChild && !parseFloat(unitFee) && totalFee && parseFloat(totalFee)) {
|
|
|
// 不存工程量
|
|
|
if (!bills.quantity || !parseFloat(bills.quantity)) {
|
|
@@ -1290,6 +1399,10 @@ const importXML = (() => {
|
|
|
projectGLJ.ratios.forEach(ratio => {
|
|
|
const matched = projectGLJMap[ratio.code];
|
|
|
ratio.code = matched.code;
|
|
|
+ // 为了后端匹配标准数据,如易达有组成物"99450680-0001"
|
|
|
+ // 项目人材机、单价文件根据original_code匹配上了标准人材机,修改了gljType等
|
|
|
+ // mixRatio根据code匹配标准数据匹配不上标准数据,因此type与项目人材机的type不同,导致组成物丢失
|
|
|
+ ratio.original_code = getOriginalCode(ratio.code);
|
|
|
ratio.projectGLJID = projectGLJ.id;
|
|
|
ratio.id = IDPlaceholder.ratio++;
|
|
|
ratio.unit_price_file_id = tenderData.property.unitPriceFile.id;
|
|
@@ -1340,7 +1453,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 = {};
|
|
@@ -1350,7 +1486,7 @@ const importXML = (() => {
|
|
|
]);
|
|
|
evalGLJ.seq = evalGLJ.code;
|
|
|
return evalGLJ;
|
|
|
- });
|
|
|
+ }); */
|
|
|
transformRelatedGLJList(evalGLJList, rst.evaluationList, 'is_evaluate');
|
|
|
}
|
|
|
// 生成单价文件
|
|
@@ -1380,7 +1516,7 @@ const importXML = (() => {
|
|
|
ration: [],
|
|
|
rationGLJ: [],
|
|
|
rationCoe: [],
|
|
|
- rationQuantityDetails: []
|
|
|
+ rationQuantityDetails: [],
|
|
|
};
|
|
|
billsData
|
|
|
.filter(bills => bills.rations && bills.rations.length)
|
|
@@ -1604,7 +1740,10 @@ const importXML = (() => {
|
|
|
throw '无有效数据';
|
|
|
}
|
|
|
const xmlObjMap = {};
|
|
|
+ // 导入易达的文件,经过unzipFile的decodeFileName,xml文件头部变成了<?xml version="1.0" encoding="utf-8"?>,需要将前面的乱码去除,否则DOMParser转换后是null
|
|
|
+ const reg = /.*<\?xml version="1.0" encoding="utf-8"\?>/i;
|
|
|
for (const fileName in fileMap) {
|
|
|
+ fileMap[fileName] = fileMap[fileName].replace(reg, '<?xml version="1.0" encoding="utf-8"?>');
|
|
|
// x2js转换xml使用了DomParser接口,会将一些字符实体进行转义。若不想被自动转义,则需要调用escapeXMLEntity
|
|
|
const xmlStr = escape ? util.escapeXMLEntity(fileMap[fileName]) : fileMap[fileName];
|
|
|
//将xml格式良好的字符串转换成对象
|