|
@@ -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)
|