'use strict'; /** * * * @author Zhong * @date 2019/3/15 * @version */ /* * 数据标准接口 * 导出符合标准接口要求的xml * */ const XMLStandard = (function () { //属性类型 const TYPE = { DATE: 1, //日期类型YYYY-MM-DD DATE_TIME: 2, //日期类型YYY-MM-DDTHH:mm:ss INT: 3, //整数类型 DECIMAL: 4, //数值类型,不限制小数位数 NUM2: 5, //数值类型2:最多两位小数 BOOL: 6 //布尔型 }; const WHITE_SPACE = { COLLAPSE: 1 //移除所有空白字符(换行、回车、空格以及制表符会被替换为空格,开头和结尾的空格会被移除,而多个连续的空格会被缩减为一个单一的空格) }; /* * 标准文件中的约束(唯一性) * path为'.//'时,路径为:当前上下文中一级或多级深度 * path为'a/b'时,路径为: 当前上下文a节点下节点b * */ const CONSTRAINTS = { //建设项目上下文的约束 PROJECT: [ {path: './/', selector: '单项工程', field: '编号'}, //建设项目下所有单项工程,编号唯一 {path: './/', selector: '单位工程', field: '编号'}, //建设项目下所有单位工程,编号唯一 ], //单位工程上下文的约束 TENDER: [ {path: './/', selector: '清单项目', field: '项目编码'}, //单位工程下所有清单项目,项目编码唯一 {path: './/', selector: '公式计算措施项', field: '序号'}, //单位工程下所有公式措施项,序号唯一 {path: './/', selector: '人材机', field: '代码'}, //单位工程下所有人材机,代码唯一 {path: './/', selector: '暂列金额明细', field: '编号'}, //单位工程下所有暂列金额明细,编号唯一 {path: './/', selector: '专业工程暂估明细', field: '编号'}, //单位工程下所有专业工程暂估明细,编号唯一 {path: './/', selector: '总承包服务费费用项', field: '编号'}, //单位工程下所有总承包服务费费用项,编号唯一 {path: '其他项目清单/计日工/人工', selector: '计日工项目', field: '编号'}, //单位工程/其他项目清单/计日工/人工下所有计日工项目,编号唯一 {path: '其他项目清单/计日工/材料', selector: '计日工项目', field: '编号'}, //单位工程/其他项目清单/计日工/材料下所有计日工项目,编号唯一 {path: '其他项目清单/计日工/施工机械', selector: '计日工项目', field: '编号'}, //单位工程/其他项目清单/计日工/施工机械下所有计日工项目,编号唯一 {path: './/', selector: '其他列项', field: '序号'}, //单位工程下所有其他列项,序号唯一 {path: './/', selector: '费用项', field: '序号'}, //单位工程下所有费用项,序号唯一 ] }; /* * 唯一性约束检查 * 无法在创建节点时就检查,需要形成完整的数据后检查 * @param{Object}element(节点) {Array}constraints(约束数据) * */ /* * 检查 * 创建节点时检查节点的数据 * 1.长度限制minLen,maxLen * 2.值的限制,固定范围:enumeration * @param {Array}datas(需要检查的属性数据) * @return {Array}没通过的属性 * */ function check(datas) { let rst = []; let dateReg = /([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8])))/; for (let data of datas) { data.value = typeof data.value === 'undefined' || data.value === null ? '' : data.value.toString(); if (data.whiteSpace && data.whiteSpace === WHITE_SPACE.COLLAPSE) { data.value = data.value.replace(/[\r,\n,\t]/g, ' '); data.value = data.value.trim(); data.value = data.value.replace(/\s{1,}/g, ' '); } if (!data.value && !data.minLen && !data.enumeration) { //值为空,且没有限制最小字符数,且没有限制值,则跳过 continue; } if (data.minLen && data.value.length < data.minLen){ rst.push(`“${data.name}”字符数不可小于${data.minLen}个`); } else if (data.maxLen && data.value.length > data.maxLen) { rst.push(`“${data.name}”字符数不可大于${data.maxLen}个`); } else if (data.enumeration && !data.enumeration.includes(data.value)) { rst.push(`“${data.name}”只能从“${data.enumeration.join(';')}”中选择`); } else if (data.type && data.type === TYPE.DATE && !dateReg.test(data.value)) { rst.push(`“${data.name}”日期格式必须是YYYY-MM-DD`); } else if (data.type && data.type === TYPE.INT && !Number.isInteger(parseFloat(data.value))) { rst.push(`“${data.name}”必须为整数`); } else if (data.type && data.type === TYPE.DECIMAL && isNaN(parseFloat(data.value))) { rst.push(`“${data.name}”必须为数值`) } else if (data.type && data.type === TYPE.NUM2) { let v = parseFloat(data.value); if (isNaN(v)) { rst.push(`“${data.name}”必须为数值`); } else if (data.value.split('.')[1].length > 2){ rst.push(`“${data.name}”小数位数不得多于两位`); } } else if (data.type && data.type === TYPE.BOOL && !['true', 'false'].includes(data.value.toString())) { } } return rst; } //从fees数组中获取相关费用 function getFee(fees, feeFields) { let fields = feeFields.split('.'); let fee = fees.find(data => data.feeName === fields[0]); if (fee) { return 0; } return fee[fields[1]] || 0; } //造成导出失败 let failList = []; /* * 定义不设置一个Node方法统一进入的原因:模板化比较直观,不分开定义节点的话,调用传参也很麻烦而且不直观。 * 一个节点对应一个构造方法,方便其他版本开发、接收的人看起来更直观 * @param {String}name(节点名) {Array}attrs(节点属性数据) * @return {void} * */ function element(name, attrs) { this.element = name; this.attrs = attrs; this.children = []; this.fail = check(attrs); for (let fail of this.fail) { failList.push(`${name}-${fail}`); } } //根据字段获取基本信息、工程特征 function getValueByKey(data, key) { for (let d of data) { if (d.key === key) { return d.value; } if (d.items && d.items.length > 0) { let findData = d.items.find(x => x.key === key); if (findData) { return findData.value; } } } return ''; } //建设项目定义 //source:来源数据 function Project(source) { let attrs = [ {name: '项目编号', value: getValueByKey(source.basicInformation, 'projNumber'), minLen: 1, maxLen: 255, whiteSpace: WHITE_SPACE.COLLAPSE}, {name: '项目名称', value: source.name, minLen: 1, maxLen: 255, whiteSpace: WHITE_SPACE.COLLAPSE}, {name: '建设单位', value: getValueByKey(source.basicInformation, 'constructionUnit')}, {name: '标准版本号', value: '3.2.2'}, {name: '标准名称', value: '重庆造价软件数据交换标准(清单计价)'}, {name: '文件类型', value: getValueByKey(source.basicInformation, 'fileKind'), enumeration: ['招标', '投标', '控制价', '结算', '其他']}, {name: '计税方法', value: 'todo'}, ]; element.call(this, '标段', attrs); } //项目信息定义 function ProjectInfo(source) { let attrs = [ {name: '工程规模', value: getValueByKey(source.basicInformation, 'projectScale')}, {name: '工程所在地', value: getValueByKey(source.basicInformation, 'projLocation')}, {name: '工程地址', value: getValueByKey(source.basicInformation, 'projAddress')}, {name: '施工单位', value: getValueByKey(source.basicInformation, 'buildingUnit')}, {name: '编制单位', value: getValueByKey(source.basicInformation, 'establishmentUnit')}, {name: '审核单位', value: getValueByKey(source.basicInformation, 'auditUnit')}, {name: '编制人', value: getValueByKey(source.basicInformation, 'buildingUnitAuthor')}, {name: '审核人', value: 'todo'}, {name: '开工日期', value: getValueByKey(source.basicInformation, 'commencementDate'), type: TYPE.DATE}, {name: '竣工日期', value: getValueByKey(source.basicInformation, 'completionDate'), type: TYPE.DATE}, {name: '编制日期', value: getValueByKey(source.basicInformation, 'establishDate'), type: TYPE.DATE}, {name: '审核日期', value: getValueByKey(source.basicInformation, 'auditDate'), type: TYPE.DATE}, {name: '材料价格期', value: getValueByKey(source.basicInformation, 'materialPricePeriod')}, {name: '合同价类型', value: getValueByKey(source.basicInformation, 'contractPriceType')}, ]; element.call(this, '项目信息', attrs); } //招标信息定义 function BiddingInfo(source) { let attrs = [ {name: '招标代理机构', value: getValueByKey(source.basicInformation, 'tenderingAgency')}, {name: '造价工程师', value: getValueByKey(source.basicInformation, 'tenderCostEngineer')}, {name: '造价工程师注册证号', value: getValueByKey(source.basicInformation, 'tenderCostEngineerNo')}, {name: '招标工期', value: getValueByKey(source.basicInformation, 'tenderPeriod'), type: TYPE.INT}, {name: '控制总价', value: source.summaryInfo.engineeringCost, type: TYPE.NUM2}, ]; element.call(this, '招标信息', attrs); } //投标信息定义 function BidInfo(source) { let attrs = [ {name: '投标人', value: getValueByKey(source.basicInformation, 'bidder')}, {name: '造价工程师', value: getValueByKey(source.basicInformation, 'bidCostEngineer')}, {name: '造价工程师注册证号', value: getValueByKey(source.basicInformation, 'bidCostEngineerNo')}, {name: '项目经理', value: getValueByKey(source.basicInformation, 'projectManager')}, {name: '投标工期', value: getValueByKey(source.basicInformation, 'biddingPeriod')}, {name: '投标保证金', value: getValueByKey(source.basicInformation, 'biddingMargin'), type: TYPE.NUM2}, {name: '质量承诺', value: getValueByKey(source.basicInformation, 'qualityCommitment')}, {name: '担保类型', value: getValueByKey(source.basicInformation, 'guaranteeType')}, {name: '投标总价', value: source.summaryInfo.engineeringCost, type: TYPE.NUM2}, ]; element.call(this, '投标信息', attrs); } //编制说明定义 function CompilationIllustration(source) { let attrs = [ {name: '内容', value: source.compilationIllustration}, ]; element.call(this, '编制说明', attrs); } //系统信息定义 function SystemInfo(source) { let attrs = [ {name: 'ID1', value: source.softInfo}, {name: 'ID2', value: ''}, {name: '生成时间', value: source.generatedTime, type: TYPE.DATE_TIME}, ]; element.call(this, '系统信息', attrs); } //费用构成定义 function FeeFrom(summaryInfo) { let attrs = [ {name: '工程费合计', value: summaryInfo.engineeringCost, type: TYPE.NUM2}, {name: '分部分项清单合计', value: summaryInfo.subEngineering, type: TYPE.NUM2}, {name: '措施项目清单合计', value: summaryInfo.measure, type: TYPE.NUM2}, {name: '安全文明施工专项费', value: summaryInfo.safetyConstruction, type: TYPE.NUM2}, {name: '其他项目清单合计', value: summaryInfo.other, type: TYPE.NUM2}, {name: '规费', value: summaryInfo.charge, type: TYPE.NUM2}, {name: '税金', value: summaryInfo.tax, type: TYPE.NUM2}, ]; element.call(this, '费用构成', attrs); } //单项工程定义 function engineering(source) { let attrs = [ {name: '编号', value: source.code, minLen: 1, maxLen: 255}, {name: '名称', value: source.name, minLen: 1, maxLen: 255}, {name: '金额', value: source.summaryInfo.engineeringCost, type: TYPE.NUM2}, ]; element.call(this, '单项工程', attrs); } //单位工程定义 function tender(source) { const TAX = { 1: '一般计税', 2: '简易计税' }; let attrs = [ {name: '编号', value: source.code, minLen: 1, maxLen: 255}, {name: '名称', value: source.name, minLen: 1, maxLen: 255}, {name: '专业', value: source.property.engineering}, {name: '金额', value: source.summaryInfo.engineeringCost, type: TYPE.NUM2}, {name: '定额库编码', value: source.property.defaultRationLibCode}, {name: '计税方法', value: TAX[source.property.taxType]}, ]; } //工程特征定义 function engFeature(source) { let attrs = [ {name: '建筑分类', value: source.feature.buildingClass, }, {name: '工程分类', value: source.feature.projClass, }, {name: '建设规模', value: 'todo', }, {name: '工程类别', value: source.basicInformation.projectCategory} //取建设项目的工程类别 ]; element.call(this, '工程特征', attrs); } //特征项定义 function featureItem(feature) { let attrs = [ {name: '编码', value: ''}, {name: '名称', value: feature.dispName}, {name: '内容', value: feature.value}, ]; element.call(this, '特征项', attrs); } //单位工程费汇总定义 function tenderFeeSummary() { element.call(this, '单位工程费汇总', []); } //计价程序费用行定义 function dxfyRow(source) { let attrs = [ {name: '序号', value: source.code}, {name: '行代号', value: source.rowCode}, {name: '项目名称', value: source.name}, {name: '计算基础表达式', value: source.calcBase}, {name: '计算基础说明', value: source.calcBaseAnnotation}, {name: '费率', value: source.feeRate}, {name: '金额', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2}, {name: '其中暂估价', value: getFee(source.fees, 'estimate.totalFee'), type: TYPE.NUM2}, {name: '费用类别', value: source.feeType, type: TYPE.INT}, {name: '备注', value: source.remark}, ]; element.call(this, '计价程序费用行', attrs); } //分部分项清单 function fbfxBills() { element.call(this, '分部分项清单', []); } //清单分部定义 function fbBills(source) { let attrs = [ {name: '编号', value: source.code, maxLen: 20}, {name: '名称', value: source.name, minLen: 1, maxLen: 255}, {name: '金额', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2}, {name: '其中暂估价', value: getFee(source.fees, 'estimate.totalFee')}, {name: '备注', value: source.remark} ]; element.call(this, '清单分部', attrs); } //清单项目定义 function fxbills(source) { let attrs = [ {name: '项目编码', value: source.code, minLen: 1, maxLen: 20}, {name: '项目名称', value: source.name, minLen: 1, maxLen: 500}, {name: '单位', value: source.unit, minLen: 1, maxLen: 20}, {name: '工程量', value: source.quantity, type: TYPE.DECIMAL}, {name: '综合单价', value: getFee(source.fees, 'common.unitFee'), type: TYPE.DECIMAL}, {name: '综合合价', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2}, {name: '其中暂估价', value: getFee(source.fees, 'estimate.totalFee'), type: TYPE.NUM2}, {name: '主要清单标志', value: source.mainBills, type: TYPE.BOOL}, {name: '暂估清单标志', value: source.isEstimate, type: TYPE.BOOL}, {name: '备注', value: source.remark}, ]; element.call(this, '清单项目', attrs); } //项目特征定义 function itemCharacter() { element.call(this, '项目特征', []); } //特征定义 function feature(source) { let attrs = [ {name: '特征名称', value: source.name}, {name: '特征描述', value: source.value}, ]; element.call(this, '特征', attrs); } //工程内容定义 function jobContent() { element.call(this, '工程内容', []); } //内容定义 function content(content) { let attrs = [ {name: '内容', value: content} ]; element.call(this, '内容', attrs); } //组价内容定义 function priceContent() { element.call(this, '组价内容', []); } //定额子目定义 function ration(source) { let attrs = [ {name: '定额编号', value: source.viewCode, minLen: 1, maxLen: 80}, {name: '项目名称', value: source.viewCode, minLen: 1, maxLen: 255}, {name: '单位', value: source.unit, minLen: 1, maxLen: 20}, {name: '定额库编码', value: source.libCode}, {name: '原始定额编号', value: source.code, minLen: 1, maxLen: 80}, {name: '子目类型', value: source.code, type: TYPE.INT, enumeration: [0, 1, 2, 3, 4, 5, 6]}, {name: '工程量', value: source.quantity, type: TYPE.DECIMAL}, {name: '工程量计算式', value: source.quantityEXP}, {name: '定额单价', value: getFee(source.fees, 'rationUnitPrice.unitFee'), type: TYPE.DECIMAL}, {name: '定额合价', value: getFee(source.fees, 'rationUnitPrice.totalFee'), type: TYPE.NUM2}, {name: '综合单价', value: getFee(source.fees, 'common.unitFee'), type: TYPE.DECIMAL}, {name: '综合合价', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2}, {name: '单价构成文件ID', value: 0, type: TYPE.INT}, //todo {name: '分包标志', value: source.isSubcontract, type: TYPE.BOOL}, {name: '备注', value: source.remark} ]; element.call(this, '定额子目', attrs); } //工料分析定义 function gljAnalyze() { element.call(this, '工料分析', []); } //人材机含量定义 function gljContent(source) { let attrs = [ {name: '人材机代码', value: source.code, minLen: 1, maxLen: 20}, {name: '消耗量', value: source.quantity, type: TYPE.DECIMAL}, {name: '总消耗量', value: source.totalQuantity, type: TYPE.DECIMAL}, {name: '数量计算方式', value: 1, type: TYPE.INT}, ]; element.call(this, '人材机含量', attrs); } //费用组成 function feeContent(source) { let attrs = [ {name: '基价人工费单价', value: getFee(source.fees, 'labour.unitFee'), type: TYPE.DECIMAL}, {name: '基价人工费合价', value: getFee(source.fees, 'labour.totalFee'), type: TYPE.NUM2}, {name: '定额人工基价调整单价', value: 0, type: TYPE.DECIMAL}, //调整价目前只有08有,默认设置成0 {name: '定额人工基价调整合价', value: 0, type: TYPE.NUM2}, {name: '基价材料费单价', value: getFee(source.fees, 'material.unitFee'), type: TYPE.DECIMAL}, {name: '基价材料费合价', value: getFee(source.fees, 'material.totalFee'), type: TYPE.NUM2}, {name: '基价机械费单价', value: getFee(source.fees, 'machine.unitFee'), type: TYPE.DECIMAL}, {name: '基价机械费合价', value: getFee(source.fees, 'machine.totalFee'), type: TYPE.NUM2}, {name: '定额机上人工基价调整单价', value: 0, type: TYPE.DECIMAL}, {name: '定额机上人工基价调整合价', value: 0, type: TYPE.NUM2}, {name: '未计材料单价', value: getFee(source.fees, 'unratedMaterial.unitFee'), type: TYPE.DECIMAL}, {name: '未计材料合价', value: getFee(source.fees, 'unratedMaterial.totalFee'), type: TYPE.NUM2}, {name: '人材机价差单价', value: getFee(source.fees, 'gljDiff.unitFee'), type: TYPE.DECIMAL}, //人材机价差通过人工、材料、机械价差相加得出 {name: '人材机价差合价', value: getFee(source.fees, 'gljDiff.totalFee'), type: TYPE.NUM2}, {name: '暂估材料单价', value: getFee(source.fees, 'estimate.unitFee'), type: TYPE.DECIMAL}, {name: '暂估材料合价', value: getFee(source.fees, 'estimate.totalFee'), type: TYPE.NUM2}, {name: '管理费单价', value: getFee(source.fees, 'manage.unitFee'), type: TYPE.DECIMAL}, {name: '管理费合价', value: getFee(source.fees, 'manage.totalFee'), type: TYPE.NUM2}, {name: '利润单价', value: getFee(source.fees, 'profit.unitFee'), type: TYPE.DECIMAL}, {name: '利润合价', value: getFee(source.fees, 'profit.totalFee'), type: TYPE.NUM2}, {name: '风险单价', value: getFee(source.fees, 'risk.unitFee'), type: TYPE.DECIMAL}, //重庆08叫风险费 重庆18叫一般风险费 {name: '风险合价', value: getFee(source.fees, 'risk.totalFee'), type: TYPE.NUM2}, {name: '一般风险单价', value: getFee(source.fees, 'risk.unitFee'), type: TYPE.DECIMAL}, {name: '一般风险合价', value: getFee(source.fees, 'risk.totalFee'), type: TYPE.NUM2}, {name: '其他风险单价', value: getFee(source.fees, 'otherRisk.unitFee'), type: TYPE.DECIMAL}, {name: '其他风险合价', value: getFee(source.fees, 'otherRisk.totalFee'), type: TYPE.NUM2}, ]; element.call(this, '费用组成', attrs); } //措施项目清单定义 function csxmBills(source) { let attrs = [ {name: '金额', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2}, {name: '其中暂估价', value: getFee(source.fees, 'estimate.totalFee'), type: TYPE.NUM2}, ]; element.call(this, '措施项目清单', attrs); } //组织措施清单定义 function zzcsBills(source) { let attrs = [ {name: '金额', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2}, ]; element.call(this, '组织措施清单', attrs); } //组织措施分类定义 function zzcsClass(source) { let attrs = [ {name: '编码', value: source.code, maxLen: 20}, {name: '名称', value: source.name, minLen: 1, maxLen: 255}, {name: '金额', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2}, {name: '备注', value: source.remark} ]; element.call(this, '组织措施分类', attrs); } //公式计算措施项 function formulaCalcMeasure(source) { let attrs = [ {name: '序号', value: source.code, minLen: 1, maxLen:20}, {name: '名称', value: source.name, minLen: 1, maxLen: 255}, {name: '计算基础表达式', value: source.calcBase}, {name: '计算基础说明', value: source.calcBaseAnnotation}, {name: '费率', value: source.feeRate}, {name: '金额', value: getFee(source.fees, 'common.totalFee')}, {name: '金额', value: getFee(source.fees, 'common.totalFee')}, {name: '暂估价标志', value: getFee(source.fees, 'common.totalFee')}, {name: '备注', value: source.remark}, {name: '费用类别', value: source.feeType, enumeration: [120201, 1204, 10041, 1206]}, ] } //技术措施清单定义 function jscsBills(source) { let attrs = [ {name: '技术措施清单', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2}, {name: '其中暂估价', value: getFee(source.fees, 'estimate.totalFee'), type: TYPE.NUM2}, ]; element.call(this, '技术措施清单', attrs); } //技术措施分类 function jscsClass(source) { let attrs = [ {name: '编号', value: source.code}, {name: '名称', value: source.name}, {name: '金额', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2}, {name: '其中暂估价', value: getFee(source.fees, 'estimate.totalFee'), type: TYPE.DECIMAL}, ]; element.call(this, '技术措施分类', attrs); } //其他项目清单定义 function otherBills() { element.call(this, '其他项目清单', []); } //暂列金额定义 function provisional(source) { let attrs = [ {name: '金额', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2} ]; element.call(this, '暂列金额', attrs); } //暂列金额明细定义 function provisionalDetail(source) { let attrs = [ {name: '编号', value: source.code, minLen: 1, maxLen: 20, whiteSpace: WHITE_SPACE.COLLAPSE}, {name: '项目名称', value: source.name, minLen: 1, maxLen: 255, whiteSpace: WHITE_SPACE.COLLAPSE}, {name: '计量单位', value: source.unit, maxLen: 20}, {name: '金额', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2}, {name: '备注', value: source.remark} ]; element.call(this, '暂列金额明细', attrs); } //专业工程暂估价定义 function engineeringEstimate(source) { let attrs = [ {name: '金额', value: getFee(source.fees, 'common.totalFee')} ]; element.call(this, '专业工程暂估价', attrs); } //专业工程暂估明细定义 function engineeringEstimateDetail(source) { let attrs = [ {name: '编号', value: source.code, minLen: 1, maxLen: 20, whiteSpace: WHITE_SPACE.COLLAPSE}, {name: '工程名称', value: source.name, minLen: 1, maxLen: 255, whiteSpace: WHITE_SPACE.COLLAPSE}, {name: '工程内容', value: 'todo', maxLen: 2000}, //todo {name: '金额', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2}, {name: '备注', value: source.remark} ]; element.call(this, '专业工程暂估明细', attrs); } //计日工定义 function dayWork(source) { let attrs = [ {name: '金额', value: getFee(source.fees, 'common.totalFee')} ]; element.call(this, '', attrs); } //人工定义 function labour() { element.call(this, '人工', []); } //计日工项目定义 function dayWorkItem(source) { let attrs = [ {name: '编号', value: source.code, minLen: 1, maxLen: 20, whiteSpace: WHITE_SPACE.COLLAPSE}, {name: '名称', value: source.name, minLen: 1, maxLen: 255, whiteSpace: WHITE_SPACE.COLLAPSE}, {name: '单位', value: source.unit, minLen: 1, maxLen: 20, whiteSpace: WHITE_SPACE.COLLAPSE}, {name: '数量', value: source.quantity, type: TYPE.DECIMAL}, {name: '综合单价', value: source.quantity, type: TYPE.DECIMAL}, {name: '综合合价', value: source.quantity, type: TYPE.NUM2}, {name: '备注', value: source.remark} ]; element.call(this, '计日工项目', attrs); } //材料定义 function material() { element.call(this, '材料', []); } //施工机械定义 function machine() { element.call(this, '施工机械', []); } //总承包服务费定义 function turnKeyContract(source) { let attrs = [ {name: '金额', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2} ]; element.call(this, '总承包服务费', attrs); } //总承包服务费分类定义 function turnKeyContractClass(source) { let attrs = [ {name:'编号', value: source.code, minLen: 1, maxLen: 20, whiteSpace: WHITE_SPACE.COLLAPSE}, {name:'名称', value: source.name, minLen: 1, maxLen: 255, whiteSpace: WHITE_SPACE.COLLAPSE}, {name:'备注', value: source.remark} ]; element.call(this, '总承包服务费分类', attrs); } //总承包服务费费用项定义 function turnKeyContractItem(source) { let attrs = [ {name: '编号', value: source.code, minLen: 1, maxLen: 20, whiteSpace: WHITE_SPACE.COLLAPSE}, {name: '工程名称', value: source.name, minLen: 1, maxLen: 255, whiteSpace: WHITE_SPACE.COLLAPSE}, {name: '计算基础', value: 0, type: TYPE.DECIMAL}, //todo {name: '服务内容', value: '', maxLen: 255}, //todo {name: '费率', value: source.feeRate, type: TYPE.DECIMAL}, {name: '金额', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2}, {name: '备注', value: source.remark} ]; element.call(this, '总承包服务费费用项', attrs); } //其他定义 function other(source) { let attrs = [ {name: '金额', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2} ]; element.call(this, '其他', attrs); } //其他列项定义 function otherItem(source) { let attrs = [ {name: '序号', value: source.code, minLen: 1, maxLen: 20, whiteSpace: WHITE_SPACE.COLLAPSE}, {name: '名称', value: source.name, minLen: 1, maxLen: 255, whiteSpace: WHITE_SPACE.COLLAPSE}, {name: '计算基础', value: source.calcBase, maxLen: 255}, {name: '费率', value: source.feeRate, type: TYPE.DECIMAL}, {name: '金额', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2}, {name: '不计入合价标志', value: source.isEstimate, type: TYPE.BOOL}, {name: '备注', value: source.remark, maxLen: 255} ]; element.call(this, '其他列项', attrs); } //规费和税金清单定义 function chargeTaxBills() { element.call(this, '规费和税金清单', []); } //费用项定义 function feeItem(source) { let attrs = [ {name: '序号', value: source.code, minLen: 1, maxLen: 20, whiteSpace: WHITE_SPACE.COLLAPSE}, {name: '行代号', value: source.rowCode, maxLen: 20}, {name: '名称', value: source.name, minLen: 1, maxLen: 255, whiteSpace: WHITE_SPACE.COLLAPSE}, {name: '计算基础表达式', value: source.calcBase, maxLen: 255}, {name: '计算基础说明', value: source.calcBaseAnnotation, maxLen: 255}, {name: '费率', value: source.feeRate, type: TYPE.DECIMAL}, {name: '金额', value: getFee(source.fees, 'common.totalFee'), type: TYPE.NUM2}, {name: '费用类别', value: source.feeType, enumeration: [800, 900, 9001, 9002, 9003]}, {name: '备注', value: source.remark, maxLen: 255} ] } //人材机汇总定义 function gljSummary() { element.call(this, '人材机汇总', []); } //人材机定义 function glj(source) { let attrs = [ {name: '代码', value: source.code, minLen: 1, maxLen: 20, whiteSpace: WHITE_SPACE.COLLAPSE}, {name: '名称', value: source.name, minLen: 1, maxLen: 255, whiteSpace: WHITE_SPACE.COLLAPSE}, {name: '规格', value: source.spec, maxLen: 255}, {name: '单位', value: source.unit, minLen: 1, maxLen: 20, whiteSpace: WHITE_SPACE.COLLAPSE}, {name: '原始代码', value: source.code, minLen: 1, maxLen: 20, whiteSpace: WHITE_SPACE.COLLAPSE}, {name: '费用类别', value: source.feeType, enumeration: [1, 2, 3, 4]}, {name: '配比类别', value: '', type: TYPE.INT}, //todo {name: '主要材料类别', value: '', type: TYPE.INT}, //todo {name: '主要材料单位系数', value: '', type: TYPE.DECIMAL}, //todo {name: '材料耗用类型', value: '', type: TYPE.INT}, //todo {name: '供货方式', value: '', type: TYPE.INT}, //todo {name: '暂估材料标志', value: !!source.is_evaluate, type: TYPE.BOOL}, {name: '不计税设备标志', value: !!source.is_adjust_price, type: TYPE.BOOL}, //todo {name: '单价不从明细汇总标志', value: !!source.excludeRatio, type: TYPE.BOOL}, //todo {name: '定额价', value: source.basePrice, type: TYPE.DECIMAL}, {name: '定额价调整', value: '', type: TYPE.DECIMAL}, //todo {name: '市场价', value: source.marketPrice, type: TYPE.DECIMAL}, {name: '数量', value: source.quantity, type: TYPE.DECIMAL}, {name: '产地', value: source.originPlace, maxLen: 255}, {name: '厂家', value: source.vender, maxLen: 255}, {name: '质量等级', value: source.qualityGrace, maxLen: 255}, {name: '品牌', value: source.brand, maxLen: 255}, {name: '备注', value: source.quantity, maxLen: 255}, ]; element.call(this, '人材机', attrs); } //人材机配比定义 function gljRatio(source) { let attrs = [ {name: '明细材料代码', value: source.code, minLen: 1, maxLen: 20, whiteSpace: WHITE_SPACE.COLLAPSE}, {name: '数量', value: source.quantity, type: TYPE.DECIMAL} ]; element.call(this, '人材机配比', attrs); } return function (granularity) { this.GRANULARITY = { PROJECT: 1, //导出建设项目 ENGINEERING: 2, //导出单项工程 TENDER: 3 //导出单位工程 }; //默认导出建设项目 if (!granularity || ![1, 2, 3].includes(granularity)) { granularity = this.GRANULARITY.PROJECT; } this.failList = failList; this.granularity = granularity; //目前的数据 let curData = null; //唯一性约束 let contraints = {}; async function loadProject(tenderID) { //拉取标段数据:建设项目、单项工程、单位工程数据 let projectData = await ajaxPost('/pm/api/getProjectByGranularity', {user_id: userID, tenderID: tenderID, granularity: granularity}); if (!projectData) { throw '获取项目数据错误'; } //标段 let project = curData = new Project({basicInformation: projectData.property.basicInformation, name: projectData.name}); //项目信息 let projectInfo = new ProjectInfo({basicInformation: projectData.property.basicInformation}); project.children.push(projectInfo); //招标信息 let biddingInfo = new BiddingInfo({basicInformation: projectData.property.basicInformation, summaryInfo: projectData.summaryInfo[projectData.ID]}); projectInfo.children.push(biddingInfo); //投标信息 let bidInfo = new BidInfo({basicInformation: projectData.property.basicInformation, summaryInfo: projectData.summaryInfo[projectData.ID]}); projectInfo.children.push(bidInfo); //编制说明 let compilationIll = new CompilationIllustration({compilationIllustration: projectData.property.compilationIllustration}); project.children.push(compilationIll); //系统信息 let generatedTime = moment(Date.now()).format('YYYY-MM-DDTHH:mm:ss'), sysInfoSource = {softInfo: projectData.softInfo, generatedTime}, sysInfo = new SystemInfo(sysInfoSource); project.children.push(sysInfo); //费用构成 let feeForm = new FeeFrom(projectData.summaryInfo[projectData.ID]); project.children.push(feeForm); } /* * 加载数据 * */ this.loadData = async function(tenderID) { await loadProject(tenderID); return curData; }; /* * 转换数据,将数据转换成可被导出成xml的结构 * {element: '标段', attrs: [{name: '属性1', value: 't'}], children: [...]} to * {'标段': {...}, '_属性1': t} * */ /* * 导出数据 * */ this.toXml = function () { } } })();