Просмотр исходного кода

Merge branch '1.0.0_online' of http://192.168.1.41:3000/SmartCost/ConstructionCost into 1.0.0_online

TonyKang 6 лет назад
Родитель
Сommit
d41c4255c7

+ 4 - 1
modules/all_models/compleRation_ration.js

@@ -24,7 +24,10 @@ const compleRationAssItemSchema = new Schema({
     decimal: Number,
     carryBit: String,
     minValue: String,
-    maxValue: String
+    maxValue: String,
+    paramName:String,//参数名称
+    param:String,//参数
+    thirdRationCode:String//第三定额
 }, { _id: false });
 
 //定额安装增加费用

+ 5 - 1
modules/all_models/ration.js

@@ -17,7 +17,11 @@ var rationAssItemSchema = mongoose.Schema({
     carryBit: String,
     minValue: String,
     maxValue: String,
-    isAdjust:Number //0不调整,1调整
+    paramName:String,//参数名称
+    param:String,//参数
+    thirdRationCode:String,//第三定额
+    isAdjust:Number,//0不调整,1调整
+    groupList:[Schema.Types.Mixed]//当有分组的时候用这个
 }, { _id: false });
 
 // 定额、量价、工料机定额 合并存储

+ 4 - 1
modules/all_models/stdRation_ration.js

@@ -19,7 +19,10 @@ const rationAssItemSchema = new Schema({
     decimal: Number,
     carryBit: String,
     minValue: String,
-    maxValue: String
+    maxValue: String,
+    paramName:String,//参数名称
+    param:String,//参数
+    thirdRationCode:String//第三定额
 }, { _id: false });
 
 //定额安装增加费用

+ 10 - 3
modules/main/facade/ration_facade.js

@@ -618,11 +618,18 @@ async function setEmptyRation(projectID,rationID){
 function createRationAss(std) {
     let  rationAssList = [];//生成辅助定额
     if(std.hasOwnProperty('rationAssList')&&std.rationAssList.length>0){
-        for(let i=0;i<std.rationAssList.length;i++){
-            let ass = std.rationAssList[i];
+        let assGroup =  _.groupBy(std.rationAssList,'name');
+        for(let key in assGroup){
+            let assList = assGroup[key];
+            let ass = assList[0];
             ass._doc.actualValue = ass.stdValue;
-            if(_.isString(ass._doc.assistCode)) ass._doc.assistCode = ass._doc.assistCode.replace("\n","");
             ass._doc.isAdjust = 0;
+            if(_.isString(ass._doc.assistCode)) ass._doc.assistCode = ass._doc.assistCode.replace("\n","");
+            if(_.isString(ass._doc.thirdRationCode)) ass._doc.thirdRationCode = ass._doc.thirdRationCode.replace("\n","");
+            if(assList.length > 1){
+                ass._doc.groupList = JSON.parse(JSON.stringify(assList))  ;
+                ass._doc.maxValue = assList[assList.length-1]._doc.maxValue;
+            }
             rationAssList.push(ass);
         }
     }

+ 53 - 6
modules/ration_glj/facade/glj_calculate_facade.js

@@ -56,14 +56,29 @@ async function calculateQuantity(query,noNeedCal,refreshRationName = false){
              return null;
          }
          if(impactRation._doc.hasOwnProperty("rationAssList")&&impactRation.rationAssList.length>0){
+             let temTimes = [];
+             let thirdRationCodes=[];
              for(let i=0;i<impactRation.rationAssList.length;i++){
                  let times = calculateTimes(impactRation.rationAssList[i]);
                  if(times!=0){
+                     let thirdRationCode = impactRation.rationAssList[i].thirdRationCode;
+                     if(thirdRationCode && thirdRationCode !=''){
+                         temTimes.push(times);
+                         thirdRationCodes.push(thirdRationCode)
+                     }
                      assRation = await  std_ration_lib_ration_items.findOne({rationRepId:impactRation.libID,code:impactRation.rationAssList[i].assistCode});
                      assList.push({times:times,assRation:assRation});
                      adjustState.push({index:stateSeq.ass,content:impactRation.rationAssList[i].name+" "+impactRation.rationAssList[i].actualValue+" : +"+impactRation.rationAssList[i].assistCode+"x"+times});
                  }
              }
+             if(temTimes.length == 2 &&thirdRationCodes[0] == thirdRationCodes[1] ){ //说明有第三定额
+                 let times_t = temTimes[0] * temTimes[1];
+                 let tration =  await  std_ration_lib_ration_items.findOne({rationRepId:impactRation.libID,code:thirdRationCodes[0]});
+                 if(tration){
+                     assList.push({times:times_t,assRation:tration});
+                     adjustState.push({index:stateSeq.ass,content:"+"+thirdRationCodes[0]+"x"+times_t});
+                 }
+             }
          }
          gljList = sortRationGLJ(gljList);
          for(let i =0;i<gljList.length;i++ ){
@@ -102,12 +117,26 @@ function quantityUpdateCheck(glj,r) {//检查,有改变的才更新
 
 function generateRationName(ration,gljList) {
     let caption = ration.caption ? ration.caption:ration.name;
-    if(ration.rationAssList && ration.rationAssList.length > 0){
-        let ass = ration.rationAssList[0];
-        if( ass.isAdjust == 1 && ass.actualValue != null && ass.actualValue != undefined ){
-            caption =  caption.replace('%s',ass.actualValue);
-        }else {
-            caption =  caption.replace('%s',ass.stdValue);//没勾选的时候要恢复成标准值
+    let replaceList = [];
+    if(ration.rationAssList && ration.rationAssList.length > 0){//这里要处理第三定额和多辅助定额的情况
+        let isThird = ration.rationAssList.length == 2 && ration.rationAssList[0].thirdRationCode&&ration.rationAssList[0].thirdRationCode!='';//说明有第三定额的情况
+        let adjustMatch = "",notAdjust="";
+        for(let ass of ration.rationAssList){
+            let tem = "";
+            if( ass.isAdjust == 1 && ass.actualValue != null && ass.actualValue != undefined ){
+                tem = ass.actualValue;
+                adjustMatch = tem;
+            }else {
+                tem = ass.stdValue;
+                notAdjust = tem;
+            }
+            if(isThird) replaceList.push(tem);
+        }
+        if(replaceList.length == 0){
+            adjustMatch!=""?replaceList.push(adjustMatch):replaceList.push(notAdjust);
+        }
+        for(let r of replaceList){
+            caption =  caption.replace('%s',r);
         }
     }
     let reNameList = [];
@@ -293,6 +322,22 @@ function getContent(coes) {
 
 }
 
+function prepareAss(assList) {//处理辅助定额,支持多个辅助定额的情况
+    for(let a of assList){
+        if(a.groupList && a.groupList.length > 1){//组里有多个定额的情况
+            let newList = _.sortByAll(a.groupList,['param']);//先按参数排序
+            for(let n of newList){
+                if(a.actualValue > n.stdValue && a.actualValue <= parseFloat(n.param)){//落在中间,则用组里的这条定额
+                    a._doc.param = n.param;
+                    a._doc.paramName = n.paramName;
+                    a._doc.assistCode = n.assistCode;
+                    break;
+                }
+            }
+        }
+    }
+}
+
 function calculateTimes(ass){
     if(ass.isAdjust == 0) return 0;//打勾辅助定额才计算
     let times =(ass.actualValue-ass.stdValue)/ass.stepValue;
@@ -305,6 +350,8 @@ function calculateTimes(ass){
         times = _.round(times,ass.decimal);
     }else if (ass.carryBit=='进一'){
         times =_.ceil(times,ass.decimal);
+    }else if(ass.carryBit == '舍一'){
+        times = _.floor(times,ass.decimal);
     }
     if(r){
         times=times*-1;

+ 13 - 3
modules/templates/controllers/bills_template_controller.js

@@ -35,10 +35,20 @@ module.exports = {
         });
     },
     getNeedfulTemplate: async function (req, res) {
-        let data = JSON.parse(req.body.data);
+        let data = JSON.parse(req.body.data),
+            allTemplateLibIDs = data.allTemplateLibIDs;
         try {
-            let needfulDatas = await BillsTemplateData.getNeedfulTemplate(data.templateLibID);
-            callback(req, res, 0, 'succes', needfulDatas);
+            let task = [];
+            for (let templateLibID of allTemplateLibIDs) {
+                task.push(BillsTemplateData.getNeedfulTemplate(templateLibID));
+            }
+            let needfulDatas = await Promise.all(task);
+            let mapping = {};
+            needfulDatas.forEach((data, index) => {
+                let curLibID = allTemplateLibIDs[index];
+                mapping[curLibID] = data;
+            });
+            callback(req, res, 0, 'succes', mapping);
         } catch (err) {
             console.log(err);
             callback(req, res, 1, err, null);

+ 1 - 1
public/web/tree_sheet/tree_sheet_helper.js

@@ -195,7 +195,7 @@ var TREE_SHEET_HELPER = {
                 if(colSetting.data.autoHeight == true){
                     colSetting.setAutoHeight(cell,node);
                 }
-                if(colSetting.editChecking&&colSetting.editChecking(node)){
+                if(colSetting.editChecking&&colSetting.editChecking(node,colSetting.data.field)){
                     cell.locked(true);
                 }else if (colSetting.readOnly) {
                     if(typeof projectReadOnly !== 'undefined' && projectReadOnly){

+ 2 - 2
web/building_saas/main/html/main.html

@@ -75,7 +75,7 @@
                 <li class="nav-item"><a data-toggle="tab" href="#project_glj" id="tab_project_glj" data-name="tab_project_glj" role="tab">人材机汇总</a></li>
                 <li class="nav-item"><a data-toggle="tab" href="#fee_rates" id="tab_fee_rate" role="tab" >费率</a></li>
                 <li class="nav-item"><a data-toggle="tab" href="#calc_program_manage" id="tab_calc_program_manage" role="tab" style="display:none">总计算程序</a></li>
-                <li class="nav-item"><a data-toggle="tab" href="#tender_price" id="tab_tender_price" role="tab">调价</a></li>
+                <li class="nav-item"><a data-toggle="tab" href="#tender_price" id="tab_tender_price" role="tab" style="display:none">调价</a></li>
                 <li class="nav-item"><a data-toggle="tab" href="#reports" role="tab" id="tab_report" onclick="rptTplObj.iniPage();">报表</a></li>
                 <li class="nav-item"><a data-toggle="tab" href="#index" id="tab_index" role="tab" style="display:none">指标信息</a></li>
             </ul>
@@ -166,7 +166,7 @@
                               <a class="nav-link px-3 right-nav-link"  href="javascript:void(0)" id = 'locateTab' relaPanel="#locate">查找定位</a>
                           </li>-->
                           <li class="nav-item">
-                              <a class="nav-link px-1 right-nav-link" href="javascript:void(0)" id = 'stdBillsGuidanceTab' relaPanel="#zy">清单</a>
+                              <a class="nav-link px-1 right-nav-link" href="javascript:void(0)" id = 'stdBillsGuidanceTab' relaPanel="#zy">标准清单</a>
                           </li>
                          <!-- <li class="nav-item">
                               <a class="nav-link px-3" href="javascript:void(0)" id = 'stdBillsTab' relaPanel="#qd">清单规则</a>

+ 1 - 1
web/building_saas/main/js/controllers/block_controller.js

@@ -552,7 +552,7 @@ let BlockController = {
             let newID = uuid.v1(); //新的清单ID
             billsIDMap[temData.ID] = newID;
             temData.ID = newID; //新的清单ID
-            if(temData.billsLibId && temData.billsLibId!="" && temData.code.length == 12){//是从清单库来的
+            if(temData.code.length == 12){//是从清单库来的  //temData.billsLibId && temData.billsLibId!=""    2019-09-03  修改需求,不做清单库ID判断
                 let value = temData.code.substr(0,9);
                 if (value&&value.length === 9) {//&& /^[\d]+$/.test(value) 去掉全数字判断    07-31 zhang
                     temData.code = me.newFormatCode(value);

+ 13 - 7
web/building_saas/main/js/models/calc_program.js

@@ -578,15 +578,21 @@ let calcTools = {
             sumU = undefined;
         }
         else if (me.isLeafBill(treeNode)){
-            if (isGather){
-                me.getGLJList(treeNode, false);
-                sumT = eTFee();
+            if (projectObj.project.Bills.isEngineerEst(treeNode)){
+                sumT = treeNode.data.feesIndex['common'].totalFee;
+                sumU = treeNode.data.feesIndex['common'].unitFee;
             }
-            else
-                sumT = eTFeeByChildren();
+            else{
+                if (isGather){
+                    me.getGLJList(treeNode, false);
+                    sumT = eTFee();
+                }
+                else
+                    sumT = eTFeeByChildren();
 
-            let q = nodeQ ? nodeQ : 1;
-            sumU = (sumT / q).toDecimal(decimalObj.bills.totalPrice);
+                let q = nodeQ ? nodeQ : 1;
+                sumU = (sumT / q).toDecimal(decimalObj.bills.totalPrice);
+            }
         }
         else if (me.isRationCategory(treeNode)){
             me.getGLJList(treeNode, false);

+ 29 - 11
web/building_saas/main/js/models/exportStandardInterface.js

@@ -238,16 +238,34 @@ const XMLStandard = (function () {
             XML_EXPORT_BASE.Element.call(this, '系统信息', attrs);
         }
         //费用构成定义
+        /*
+         * 1.投标文件时:
+         * 在标段下,则取建设项目对应汇总数值;是在单项工程,则取单项工程对应汇总数值。
+         * 2.招标文件时,全部取0。
+         * 3.控制价文件时,分部分项清单合计、措施项目清单合计、其他项目清单合计、计日工合计、总承包服务费合计、签证索赔合计、规费、税金,均取0;其他按项目中汇总数据取值。
+         * */
         function FeeFrom(summaryInfo) {
+            let tenderKind = _config.EXPORT_KIND.Tender,
+                controlKind = _config.EXPORT_KIND.Control;
             let attrs = [
-                {name: '工程费合计', value: exportKind === _config.EXPORT_KIND.Tender ? summaryInfo.engineeringCost : '0', required: true, type: _config.TYPE.NUM2},
+                {name: '工程费合计',
+                    value: [tenderKind, controlKind].includes(exportKind) ? summaryInfo.engineeringCost : '0',
+                    required: true, type: _config.TYPE.NUM2},
                 {name: '分部分项清单合计', value: exportKind === _config.EXPORT_KIND.Tender ? summaryInfo.subEngineering : '0', required: true, type: _config.TYPE.NUM2},
                 {name: '措施项目清单合计', value: exportKind === _config.EXPORT_KIND.Tender ? summaryInfo.measure : '0', required: true, type: _config.TYPE.NUM2},
-                {name: '安全文明施工专项费', value: exportKind === _config.EXPORT_KIND.Tender ? summaryInfo.safetyConstruction : '0', required: true, type: _config.TYPE.NUM2},
+                {name: '安全文明施工专项费',
+                    value: [tenderKind, controlKind].includes(exportKind) ? summaryInfo.safetyConstruction : '0',
+                    required: true, type: _config.TYPE.NUM2},
                 {name: '其他项目清单合计', value: exportKind === _config.EXPORT_KIND.Tender ? summaryInfo.other : '0', required: true, type: _config.TYPE.NUM2},
-                {name: '暂列金额合计', value: exportKind === _config.EXPORT_KIND.Tender ? summaryInfo.provisional : '0', type: _config.TYPE.NUM2},
-                {name: '材料暂估价合计', value: exportKind === _config.EXPORT_KIND.Tender ? summaryInfo.materialProvisional : '0', type: _config.TYPE.NUM2},
-                {name: '专业工程暂估价合计', value: exportKind === _config.EXPORT_KIND.Tender ? summaryInfo.engineeringEstimate : '0', type: _config.TYPE.NUM2},
+                {name: '暂列金额合计',
+                    value: [tenderKind, controlKind].includes(exportKind) ? summaryInfo.provisional : '0',
+                    type: _config.TYPE.NUM2},
+                {name: '材料暂估价合计',
+                    value: [tenderKind, controlKind].includes(exportKind) ? summaryInfo.materialProvisional : '0',
+                    type: _config.TYPE.NUM2},
+                {name: '专业工程暂估价合计',
+                    value: [tenderKind, controlKind].includes(exportKind) ? summaryInfo.engineeringEstimate : '0',
+                    type: _config.TYPE.NUM2},
                 {name: '计日工合计', value: exportKind === _config.EXPORT_KIND.Tender ? summaryInfo.daywork : '0', type: _config.TYPE.NUM2},
                 {name: '总承包服务费合计', value: exportKind === _config.EXPORT_KIND.Tender ? summaryInfo.turnKeyContract : '0', type: _config.TYPE.NUM2},
                 {name: '签证索赔合计', value: exportKind === _config.EXPORT_KIND.Tender ? summaryInfo.claimVisa : '0', type: _config.TYPE.NUM2},
@@ -1185,7 +1203,7 @@ const XMLStandard = (function () {
                     code: node.data.code,
                     rowCode: `F${serialNo}`,
                     name: node.data.name,
-                    calcBase: _util.transformCalcBase(detail, node, {CalcBaseMap, FlagCalcBaseMap}),
+                    calcBase: _util.transformCalcBase(exportKind, detail, node, {CalcBaseMap, FlagCalcBaseMap}),
                     feeRate: _util.hasValue(node.data.feeRate) ? node.data.feeRate : 100,
                     fees: node.data.fees,
                     feeType: FEE_TYPE[flag] || FEE_TYPE['0'],
@@ -1499,7 +1517,7 @@ const XMLStandard = (function () {
                             row: detail.mainTree.nodes[detail.mainTree.prefix + node.data.ID].serialNo() + 1,
                             code: node.data.code,
                             name: node.data.name,
-                            calcBase: _util.transformCalcBase(detail, node, {CalcBaseMap, FlagCalcBaseMap}),
+                            calcBase: _util.transformCalcBase(exportKind, detail, node, {CalcBaseMap, FlagCalcBaseMap}),
                             feeRate: _util.hasValue(node.data.feeRate) ? node.data.feeRate : 100,
                             fees: node.data.fees,
                             remark: node.data.remark,
@@ -1618,7 +1636,7 @@ const XMLStandard = (function () {
             let claimNode = detail.Bills.tree.items.find(node => node.getFlag() === fixedFlag.CLAIM);
             if (claimNode && claimNode.children.length > 0) {   //必须要有子项才能显示索赔计价汇总元素
                 let claimEle = new XML_EXPORT_BASE.Element('索赔计价汇总', [
-                    {name: '金额', value: exportKind === _config.EXPORT_KIND.Tender ? _util.getFee(claimNode.data.fees, 'common.totalFee') : '0'}]);
+                    {name: '金额', value: _util.getFee(claimNode.data.fees, 'common.totalFee')}]);
                 for (let n of claimNode.children) {
                     claimEle.children.push(new ClaimVisaFeeItem(n.data));
                 }
@@ -1628,7 +1646,7 @@ const XMLStandard = (function () {
             let visaNode = detail.Bills.tree.items.find(node => node.getFlag() === fixedFlag.VISA);
             if (visaNode && visaNode.children.length > 0) {     //必须要有子项才能显示现场签证计价汇总元素
                 let visaEle = new XML_EXPORT_BASE.Element('现场签证计价汇总', [
-                    {name: '金额', value: exportKind === _config.EXPORT_KIND.Tender ? _util.getFee(visaNode.data.fees, 'common.totalFee') : '0'}
+                    {name: '金额', value: _util.getFee(visaNode.data.fees, 'common.totalFee')}
                 ]);
                 for (let n of visaNode.children) {
                     visaEle.children.push(new ClaimVisaFeeItem(n.data));
@@ -1772,7 +1790,7 @@ const XMLStandard = (function () {
                         row: detail.mainTree.nodes[detail.mainTree.prefix + node.data.ID].serialNo() + 1,
                         code: node.data.code,
                         name: node.data.name,
-                        calcBase: _util.transformCalcBase(detail, node, {CalcBaseMap, FlagCalcBaseMap}),
+                        calcBase: _util.transformCalcBase(exportKind, detail, node, {CalcBaseMap, FlagCalcBaseMap}),
                         feeRate: _util.hasValue(node.data.feeRate) ? node.data.feeRate : 100,
                         commonTotalFee: totalFee,
                         notSummary: belongFlag && belongFlag === fixedFlag.MATERIAL_PROVISIONAL,   //不计入合价,只有材料(工程设备)暂估价固定节点
@@ -1823,7 +1841,7 @@ const XMLStandard = (function () {
                     code: node.data.code,
                     rowCode: `F${serialNo}`,
                     name: node.data.name,
-                    calcBase: _util.transformCalcBase(detail, node, {CalcBaseMap, FlagCalcBaseMap}),
+                    calcBase: _util.transformCalcBase(exportKind, detail, node, {CalcBaseMap, FlagCalcBaseMap}),
                     feeRate: _util.hasValue(node.data.feeRate) ? node.data.feeRate : 100,
                     fees: node.data.fees,
                     feeType: feeType,

+ 17 - 8
web/building_saas/main/js/models/exportStdInterfaceBase.js

@@ -41,7 +41,7 @@ const XML_EXPORT_BASE = (() => {
         coe: 'priceCoe' // 价格指数调整法
     };
     // 加载数据间隔,减少服务器压力
-    const TIMEOUT_TIME = 200;
+    const TIMEOUT_TIME = 400;
     // 导出粒度
     const GRANULARITY = {
         PROJECT: 1,         //导出建设项目
@@ -493,11 +493,11 @@ const XML_EXPORT_BASE = (() => {
         return await entryFunc(userID, exportKind, projectData);
     }
 
-    //转换基数表达式
-    //1.有子项,则取固定清单对应基数
-    //2.无子项,有基数,a.优先转换为行代号(不可自身) b.不能转换为行代号则找对应字典
-    //3.基数中有无法转换的,设为金额
-    function transformCalcBase(tenderDetail, node, {CalcBaseMap, FlagCalcBaseMap}) {
+    // 转换基数表达式
+    // 1.有子项,则取固定清单对应基数
+    // 2.无子项,有基数,a.优先转换为行代号(不可自身) b.不能转换为行代号则找对应字典
+    // 3.基数中有无法转换的,根据导出类型决定
+    function transformCalcBase(exportKind, tenderDetail, node, {CalcBaseMap, FlagCalcBaseMap}) {
         let expr = node.data.calcBase || '';
         if (node.children.length) {
             let flag = node.getFlag();
@@ -537,9 +537,18 @@ const XML_EXPORT_BASE = (() => {
                 }
                 expr = expr.replace(new RegExp(base, 'g'), rowCode);
             });
-            //不合法 返回金额
+            //不合法
+            // 在我们软件中的基数无法找到映射代号的情况下
+            // 导出招标、控制价时,基数为空
+            // 导出投标时,基数=综合合价/费率
             if (illegal) {
-                return getFee(node.data.fees, 'common.totalFee');
+                if (exportKind === EXPORT_KIND.Bid || exportKind === EXPORT_KIND.Control) {
+                    return '';
+                } else {
+                    let totalFee = getFee(node.data.fees, 'common.totalFee'),
+                        feeRate = node.data.feeRate;
+                    return feeRate && !isNaN(feeRate) ? scMathUtil.roundTo(totalFee/feeRate, -2) : totalFee
+                }
             }
             return expr;
         }

+ 46 - 20
web/building_saas/main/js/models/importStandardInterface.js

@@ -379,9 +379,10 @@ const ImportXML = (() => {
                 let obj = {
                     rowCode: getValue(itemSrc, ['_行代号']),
                     name: getValue(itemSrc, ['_项目名称']),
+                    calcBase: getValue(itemSrc, ['_计算基础表达式'])
                 };
                 if (importFileKind === FileKind.tender) {
-                    obj.calcBase = getValue(itemSrc, ['_计算基础表达式']);
+                    // obj.calcBase = getValue(itemSrc, ['_计算基础表达式']);
                     obj.feeRate = getValue(itemSrc, ['_费率']);
                     obj.fees = [{fieldName: 'common', totalFee: getValue(itemSrc, ['_金额']) || '0'}];
                 }
@@ -495,8 +496,8 @@ const ImportXML = (() => {
             function featureAndContentText(features, contents) {
                 let textArr = [];
                 // 项目特征
+                textArr.push('[项目特征]');
                 if (features.length) {
-                    textArr.push('[项目特征]');
                     textArr.push(...features.map(feature => {
                         //若不存在特征描述,同时特征名称中含有“:”,则直接返回特征名称 (广联达招标文件中,特征名称包含了特征名:值)
                         if (!feature.eigenvalue && /[\:,:]/.test(feature.name)) {
@@ -507,10 +508,10 @@ const ImportXML = (() => {
                     }));
                 }
                 // 工作内容
+                textArr.push('[工作内容]');
                 if (textArr.length) {
-                    textArr.push('[工作内容]');
+                    textArr.push(...contents.map(content => content.name));
                 }
-                textArr.push(...contents.map(content => content.name));
                 return textArr.join('\n');
             }
         }
@@ -812,13 +813,13 @@ const ImportXML = (() => {
                 }
                 return obj;
             })};
+            provisional.fees = [{fieldName: 'common', totalFee: getValue(otherSrc, ['暂列金额', '_金额']) || '0'}];
+            engineeringPro.fees = [{fieldName: 'common', totalFee: getValue(otherSrc, ['专业工程暂估价', '_金额']) || '0'}];
+            claim.fees = [{fieldName: 'common', totalFee: getValue(otherSrc, ['索赔计价汇总', '_金额']) || '0'}];
+            visa.fees = [{fieldName: 'common', totalFee: getValue(otherSrc, ['现场签证计价汇总', '_金额']) || '0'}];
             if (importFileKind === FileKind.tender) {
-                provisional.fees = [{fieldName: 'common', totalFee: getValue(otherSrc, ['暂列金额', '_金额']) || '0'}];
-                engineeringPro.fees = [{fieldName: 'common', totalFee: getValue(otherSrc, ['专业工程暂估价', '_金额']) || '0'}];
                 dayWork.fees = [{fieldName: 'common', totalFee: getValue(otherSrc, ['计日工', '_金额']) || '0'}];
                 service.fees = [{fieldName: 'common', totalFee: getValue(otherSrc, ['总承包服务费', '_金额']) || '0'}];
-                claim.fees = [{fieldName: 'common', totalFee: getValue(otherSrc, ['索赔计价汇总', '_金额']) || '0'}];
-                visa.fees = [{fieldName: 'common', totalFee: getValue(otherSrc, ['现场签证计价汇总', '_金额']) || '0'}];
                 others.fees = [{fieldName: 'common', totalFee: getValue(otherSrc, ['其他', '_金额']) || '0'}];
             }
             return {provisional, engineeringPro, dayWork, service, claim, visa, others};
@@ -1023,6 +1024,7 @@ const ImportXML = (() => {
                         name: feeBills.name,
                         rowCode: feeBills.rowCode,
                         feeRate: feeBills.feeRate,
+                        calcBase: feeBills.calcBase,
                     };
                     if (importFileKind === FileKind.tender) {
                         //subTaxData.rowCode = feeBills.rowCode;
@@ -1033,7 +1035,7 @@ const ImportXML = (() => {
                     }
                     needfulTemplate.push(subTaxData);
                     preSubTax = subTaxData;
-                } else {    //匹配固定项
+                } else {
                     let isMatched = false;
                     //匹配固定项
                     for (let match of toMatches) {
@@ -1061,7 +1063,13 @@ const ImportXML = (() => {
                             continue;
                         }
                         isMatched = true;
-                        findBills.calcBase = feeBills.calcBase;
+                        // 文件有基数则导入基数,没有则用模板的基数
+                        if (feeBills.calcBase) {
+                            findBills.calcBase = feeBills.calcBase;
+                        } else {
+                            // 用了模板的基数,基数无视基数验证
+                            findBills.ignoreValidator = true;
+                        }
                         findBills.feeRate = feeBills.feeRate;
                         findBills.rowCode = feeBills.rowCode;
                         //后台配置的feeRateID优先级比feeRate高,导入数据有费率值时,需要清空这个配置
@@ -1161,7 +1169,9 @@ const ImportXML = (() => {
             function updateZZCSItem(org, tar) {
                 for(let [k, v] of Object.entries(tar)) {
                     // 如果匹配到的清单自身已有固定ID,不更新固定ID
-                    if (k === 'flags' && Array.isArray(tar.flags) && tar.flags.length) {
+                    // 如果目标清单没有基数,模板清单基数不更新
+                    if ((k === 'flags' && Array.isArray(tar.flags) && tar.flags.length) ||
+                        (k === 'calcBase' && !tar.calcBase)) {
                         continue;
                     }
                     org[k] = v;
@@ -1291,7 +1301,7 @@ const ImportXML = (() => {
             JSCS_JXF: '{技术措施项目定额施工机具使用费}',
             JSCS_ZCF: '{技术措施项目主材费}',
             JSCS_GR: '{技术措施项目人工工日}',
-            JZMZ: '{建筑面积}',
+            JZMJ: '{建筑面积}',
             RCJJC: '{人材机价差}',
             RGJC: '{人工价差}',
             CLJC: '{材料价差}',
@@ -1325,7 +1335,7 @@ const ImportXML = (() => {
                 }
             });
             for (let bills of billsData) {
-                if (!bills.calcBase) {
+                if (!bills.calcBase || bills.ignoreValidator) {
                     continue;
                 }
                 let sub = billsData.find(data => data.ParentID === bills.ID);
@@ -1335,6 +1345,9 @@ const ImportXML = (() => {
                     bills.feeRate = '';
                     continue;
                 }
+                if (typeof bills.calcBase !== 'string') {
+                    bills.calcBase = String(bills.calcBase);
+                }
                 //提取基数
                 bills.calcBase = bills.calcBase.replace(/\s/g, '');
                 let bases = bills.calcBase.split(/[\+\-\*\/]/g);
@@ -1417,6 +1430,18 @@ const ImportXML = (() => {
                 shareInfo: [],
                 engs: []
             };
+            // 所有的清单模板库ID
+            let allTemplateLibIDs = [];
+            xmlObj.engs.forEach(eng => {
+                eng.tenders.forEach(tender => {
+                    let templateLibID = tender.property.templateLibID;
+                    if (!allTemplateLibIDs.includes(templateLibID)) {
+                        allTemplateLibIDs.push(templateLibID);
+                    }
+                });
+            });
+            // 模板映射:{[templateLibID]: data}
+            let templateMapping = await ajaxPost('/template/bills/api/getNeedfulTemplate', {allTemplateLibIDs});
             for (let i = 0; i < xmlObj.engs.length; i++) {
                 let curEng = xmlObj.engs[i],
                     preEng = postConstructData.engs[i - 1];
@@ -1448,7 +1473,8 @@ const ImportXML = (() => {
                         preTender.tender.NextSiblingID = curTender.ID;
                     }
                     //提取详细数据
-                    let postTenderData = await transformTender(curTender, IDPlaceholder);
+                    let needfulTemplate = _.cloneDeep(templateMapping[curTender.property.templateLibID]);
+                    let postTenderData = await transformTender(curTender, IDPlaceholder, needfulTemplate);
                     postTenderData.tender.property.rootProjectID = postConstructData.ID;
                     postEngData.tenders.push(postTenderData);
                 }
@@ -1458,8 +1484,8 @@ const ImportXML = (() => {
         };
 
         //转换单位工程的数据(直接可插入数据库的数据),返回{tender: {}, bills: [], ration: [], rationGLJ: [], projectGLJ: [], unitPrice: [], mixRatio: []}
-        async function transformTender(tenderData, IDPlaceholder) {
-            let detailData = await transformBills(tenderData, IDPlaceholder);
+        async function transformTender(tenderData, IDPlaceholder, needfulTemplate) {
+            let detailData = await transformBills(tenderData, IDPlaceholder, needfulTemplate);
             //提取需要插入的单位工程数据
             let tender = {
                 ID: tenderData.ID,
@@ -1481,10 +1507,7 @@ const ImportXML = (() => {
             return detailData;
         }
         //转换清单数据
-        async function transformBills(tenderData, IDPlaceholder) {
-            //获取清单模板数据
-            let needfulTemplate = await ajaxPost('/template/bills/api/getNeedfulTemplate',
-                {templateLibID: tenderData.property.templateLibID});
+        async function transformBills(tenderData, IDPlaceholder, needfulTemplate) {
             //处理单位工程费用汇总的清单,这一部分没有靠谱的规则,特殊处理。
             setupFeeSummary(tenderData.feeSummary, needfulTemplate);
             //处理添加清单数据
@@ -1516,6 +1539,9 @@ const ImportXML = (() => {
                 tenderData.gljSummary.forEach(pGLJ => {
                     pGLJ.project_id = tenderData.ID;
                     pGLJ.id = IDPlaceholder.projectGLJ++;
+                    // 如果人材机数据的类型为空,默认设置成201先,具体需要后台匹配
+                    pGLJ.type = pGLJ.type || 201;
+                    pGLJ.shortName = pGLJ.shortName || '材';
                     //gljCodeMap[pGLJ.code] = pGLJ;
                     projectGLJMap[pGLJ.customCode] = pGLJ;
                     projectGLJMap[pGLJ.original_code] = pGLJ;

+ 0 - 1
web/building_saas/main/js/views/billsElf.js

@@ -197,7 +197,6 @@ const BillsSub = (function() {
         }
         $('#qdjlTools').show();
         // 库名称、清单子菜单名称动态显示
-        $('#stdBillsGuidanceTab').text(libText);
         $('#linkQDJL').text(libText);
         // 监听按钮事件
         bindListener();

+ 4 - 3
web/building_saas/main/js/views/calc_base_view.js

@@ -172,14 +172,14 @@ let calcBaseView = {
         return this.billsCBClass.ALL;
     },
 
-    initCalctor: function (type) {//type = bills、ration
+    initCalctor: function (type,field) {//type = bills、ration
         let me = calcBaseView;
         let showDatas;
         me.inputExpr = $('#calcBaseExp');
         me.curType = type;
         if (type === me.type.bills) {
             //锁定的清单不显示
-            if(projectObj.project.isBillsLocked() && projectObj.project.withinBillsLocked(projectObj.project.mainTree.selected)){
+            if( MainTreeCol.lockBillChecking(projectObj.project.mainTree.selected,field)){
                 return;
             }
             //显示清单基数分类
@@ -356,7 +356,8 @@ let calcBaseView = {
         calcBaseView.confirmBtn.attr('toggle', 'calcBase');
         changeCalcBaseFeeRate('calcBase');
         $('#tabCalcBase').tab('show');
-        calcBaseView.initCalctor(type);
+        let field = projectObj.mainController.setting.cols[hitinfo.col].data.field;
+        calcBaseView.initCalctor(type,field);
     }
 };
 

+ 2 - 2
web/building_saas/main/js/views/fee_rate_view.js

@@ -478,9 +478,9 @@ var feeRateObject={
         return new FeeRateEditCellType();
     },
     showSelectModal:function (hitinfo) {
-        //锁定的清单不显示
         let project = projectObj.project;
-        if(project.isBillsLocked() && project.withinBillsLocked(project.mainTree.selected)){
+        let field = projectObj.mainController.setting.cols[hitinfo.col].data.field;
+        if(MainTreeCol.lockBillChecking(project.mainTree.selected,field)){ //锁定的清单不显示
             return;
         }
         //$("#fee_rate_tree").modal({show:true});

+ 9 - 3
web/building_saas/main/js/views/main_tree_col.js

@@ -419,15 +419,21 @@ let MainTreeCol = {
         //仅“分部分项工程”或“施工技术措施项目”下的分部、分项、补项、清单可编辑
         return ((Bills.isFBFX(node)||Bills.isTechMeasure(node))&&node.sourceType == ModuleNames.bills)
     },
-    editChecking:function(node){
-        if(node.sourceType==projectObj.project.Bills.getSourceType()&&projectObj.project.isBillsLocked()&&projectObj.project.withinBillsLocked(node)){
-            return true;
+    editChecking:function(node,field){
+        if(node.sourceType==projectObj.project.Bills.getSourceType()){
+            return MainTreeCol.lockBillChecking(node,field)
         }
         if(gljOprObj.isInstallationNode(node)){//如果是通过安装增加费自动生成的,都是只读类型
             return true;
         }
         return false;
     },
+    lockBillChecking:function (node,field) {//true就是不可编辑,被锁定
+        if(projectObj.project.isBillsLocked()&&projectObj.project.withinBillsLocked(node)){
+            return (field == "feesIndex.common.unitFee"||field=="feesIndex.common.totalFee"||field=="calcBase"||field=="feeRate")?false:true;// 锁定状态下,除了综合单价、综合合价、计算基数、费率这个几,其它的都不能编辑
+        }
+        return false
+    },
     setAutoHeight:function (cell,node) {//设置自动行高
         cell.wordWrap(MainTreeCol.needAutoFit(node));
     },

+ 2 - 1
web/building_saas/main/js/views/project_property_projFeature.js

@@ -107,7 +107,8 @@ let projFeatureView = {
             me.initTree(sheet, true, datas);
             sheet.setFormatter(-1, 1, '@');
             //兼容旧数据
-            let compatLockedKeys = ['engineering'],
+            // org: compatLockedKeys = ['engineering']
+            let compatLockedKeys = [],
                 compatNumKeys = [
                     'buildingArea',
                     'basementBuildingArea',

+ 2 - 1
web/building_saas/main/js/views/project_view.js

@@ -2008,7 +2008,8 @@ var projectObj = {
         calcBaseView.confirmBtn.attr('toggle', 'commonTotalFee');
         changeCalcBaseFeeRate('commonTotalFee');
         $('#tabCalcBase').tab('show');
-        calcBaseView.initCalctor('bills');
+        let field = projectObj.mainController.setting.cols[hitinfo.col].data.field;
+        calcBaseView.initCalctor('bills',field);
         feeRateObject.showSelectModal(hitinfo);
     },
     selectColAndFocus :function (newNode,field = 'code') {//选中单元格并设置焦点

+ 1 - 2
web/building_saas/pm/js/pm_import.js

@@ -442,12 +442,10 @@ const importView = (() => {
                 if (sameDepthProjs.find(node => node.data.name === xmlObj.name)) {
                     xmlObj.name += `(${moment(Date.now()).format('YYYY-MM-DD HH:mm:ss')})`;
                 }
-                //console.log(xmlObj);
                 $('#importInterface').modal('hide');
                 pr.start('导入文件', '正在生成文件,请稍候……');
                 let importData = await importXML.transformData(xmlObj);
                 let blob = new Blob([JSON.stringify(importData)], {type: 'text/plain;charset=utf-8'});
-                console.log(blob);
                 let formData = new FormData();
                 formData.append('file', blob);
                 $.ajax({
@@ -477,6 +475,7 @@ const importView = (() => {
                     STATE.importing = false;
                 }, 500);
                 pr.end();
+                console.log(err);
                 alert(err);
             }
         });