Sfoglia il codice sorgente

逼近:按目标价调整定额工程量 模式下有Bug

chenshilong 4 anni fa
parent
commit
f04a1fd416

+ 66 - 50
web/building_saas/main/js/models/calc_program.js

@@ -1081,12 +1081,23 @@
      return projectObj.project.property.valuationType == 'ration';
    },
 
-   getTenderCalcType: function () {
+   getTenderTypeStr: function () {
      let tenderSetting = projectObj.project.property.tenderSetting;
      let ct = tenderSetting && tenderSetting.calcPriceOption ? tenderSetting.calcPriceOption : "priceBase_RCJ";
      if (ct == 'priceBase') ct = 'priceBase_RCJ'; // 兼容旧项目
      return ct;
    },
+   getTenderType: function () {
+     let rst;
+     let sOption = calcTools.getTenderTypeStr();
+     if (sOption == 'coeBase')
+       rst = tenderTypes.ttCalc
+     else if (sOption == 'priceBase_RCJ')
+       rst = tenderTypes.ttReverseGLJ
+     else if (sOption == 'priceBase_ZM')
+       rst = tenderTypes.ttReverseRation;
+     return rst;
+   },
    getProgramArray: function () {
     let array = [];
     for (let p of projectObj.project.calcProgram.datas.templates) {
@@ -1094,7 +1105,7 @@
     }
     return array;
   },
-  getCodeForBlock: function(node){
+   getCodeForBlock: function(node){
     let code = node.data.code;
     if (calcTools.isBillProject()){
         let tempNode = node;
@@ -1105,12 +1116,19 @@
     };
     return code;
   },
-  getCodeFromBlock: function(block){
+   getCodeFromBlock: function(block){
     let code = '';
     let i = block.data.nodeName.indexOf(' ');
     if (i != -1) code = block.data.nodeName.slice(0, i);
     return code;
-  }
+  },
+   // 取树结点的调价系数。
+   getCoe: function (node, tender) {
+     if (tender == tenderTypes.ttReverseGLJ)
+       return (calcTools.isVP_or_GLJR(node)) ? node.data.rationQuantityCoe : node.data.quantityCoe.labour
+     else if (tender == tenderTypes.ttReverseRation)
+       return node.data.rationQuantityCoe;
+   }
  };
 
  let rationCalcBases = {
@@ -2600,7 +2618,7 @@
    };
 
    // 反向调价逼近
-   reverseTenderApproach(callback){
+   reverseTenderApproach(callback, tender){
      let me = this;
 
      let G_DIGIT = 0.01;      // 系数调整步距(0.1最终结果误差大。0.001目标金额与逼前金额差距大时无法有效逼近)
@@ -2609,11 +2627,6 @@
      let diffProp = 0.0001;   // 计算模式=2(速度优先)时有效。 计算可接受的差值D。差值D = 根结点金额 * diffProp
      let isTest = true;       // 测试
 
-     // 取树结点的调价系数。
-     function getCoe(node){
-       return (calcTools.isVP_or_GLJR(node)) ? node.data.rationQuantityCoe : node.data.quantityCoe.labour;
-     }
-
      // 按指定的比例获取可接受的差值:如目标金额的万分之一。
      function getPropV(node){
        let v = parseFloat((node.data.targetTotalFee * diffProp).toFixed(0));   // node.data.feesIndex.common.totalFee
@@ -2634,7 +2647,7 @@
          // 量价还是要参与,因为它贡献了金额,如果它的金额比重很大,它退出了,会导致其它结点过调。
          // if (calcTools.isRationCategory(node) && (!calcTools.isVP_or_GLJR(node))){
          if (calcTools.isRationCategory(node)){
-           let coe = getCoe(node);
+           let coe = calcTools.getCoe(node, tender);
            if (coe!= 0) {
              let diff = Math.abs(node.data.feesIndex.common.tenderTotalFee - node.data.feesIndex.common.totalFee);
              node.data.tender_diffValuePerCoe  = (diff * G_DIGIT / coe).toDecimal(decimalObj.process);
@@ -2683,22 +2696,29 @@
          return {type: 2, node: undefined, nodeIdx: -1};    // arr 被清空了
 
        let d = (v > 0) ? -G_DIGIT : G_DIGIT;
-       let coe = getCoe(closeNode);
+       let coe = calcTools.getCoe(closeNode, tender);
        if ((coe + d) < 0)
          return {type: 3, node: obj.node, nodeIdx: obj.idx};  // 再调的话,系数就变负数了,过调
 
-       if (calcTools.isVP_or_GLJR(closeNode)){
+       if (tender == tenderTypes.ttReverseRation){
          closeNode.data.tender_previousCoe = closeNode.data.rationQuantityCoe;  // tender_previousCoe: 上一次的调整系数,用于撤回
          closeNode.data.rationQuantityCoe = (closeNode.data.rationQuantityCoe + d).toDecimal(decimalObj.process);
        }
-       else {
-         closeNode.data.tender_previousCoe = closeNode.data.quantityCoe.labour;
-         closeNode.data.quantityCoe.labour = (closeNode.data.quantityCoe.labour + d).toDecimal(decimalObj.process)
-         closeNode.data.quantityCoe.material = (closeNode.data.quantityCoe.material + d).toDecimal(decimalObj.process)
-         closeNode.data.quantityCoe.machine = (closeNode.data.quantityCoe.machine + d).toDecimal(decimalObj.process)
-         closeNode.data.quantityCoe.main = (closeNode.data.quantityCoe.main + d).toDecimal(decimalObj.process)
-         closeNode.data.quantityCoe.equipment = (closeNode.data.quantityCoe.equipment + d).toDecimal(decimalObj.process)
-       };
+       else if (tender == tenderTypes.ttReverseGLJ){
+         if (calcTools.isVP_or_GLJR(closeNode)){
+           closeNode.data.tender_previousCoe = closeNode.data.rationQuantityCoe;
+           closeNode.data.rationQuantityCoe = (closeNode.data.rationQuantityCoe + d).toDecimal(decimalObj.process);
+         }
+         else {
+           closeNode.data.tender_previousCoe = closeNode.data.quantityCoe.labour;
+           closeNode.data.quantityCoe.labour = (closeNode.data.quantityCoe.labour + d).toDecimal(decimalObj.process)
+           closeNode.data.quantityCoe.material = (closeNode.data.quantityCoe.material + d).toDecimal(decimalObj.process)
+           closeNode.data.quantityCoe.machine = (closeNode.data.quantityCoe.machine + d).toDecimal(decimalObj.process)
+           closeNode.data.quantityCoe.main = (closeNode.data.quantityCoe.main + d).toDecimal(decimalObj.process)
+           closeNode.data.quantityCoe.equipment = (closeNode.data.quantityCoe.equipment + d).toDecimal(decimalObj.process)
+         };
+       }
+
        me.calculate(closeNode, true, true, tenderTypes.ttCalc);
        return {type: 1, node: obj.node, nodeIdx: obj.idx};
      }
@@ -2707,16 +2727,21 @@
      function undoLastApproach(obj){
        let closeNode = obj.node;
        let coe = closeNode.data.tender_previousCoe;
-       if (calcTools.isVP_or_GLJR(closeNode)){
+       if (tender == tenderTypes.ttReverseRation){
          closeNode.data.rationQuantityCoe = coe
+       } else if (tender == tenderTypes.ttReverseGLJ){
+         if (calcTools.isVP_or_GLJR(closeNode)){
+           closeNode.data.rationQuantityCoe = coe
+         }
+         else {
+           closeNode.data.quantityCoe.labour = coe
+           closeNode.data.quantityCoe.material = coe
+           closeNode.data.quantityCoe.machine = coe
+           closeNode.data.quantityCoe.main = coe
+           closeNode.data.quantityCoe.equipment = coe
+         };
        }
-       else {
-         closeNode.data.quantityCoe.labour = coe
-         closeNode.data.quantityCoe.material = coe
-         closeNode.data.quantityCoe.machine = coe
-         closeNode.data.quantityCoe.main = coe
-         closeNode.data.quantityCoe.equipment = coe
-       };
+
        me.calculate(closeNode, true, true, tenderTypes.ttCalc);
        if (isTest) {
          let _sp = `        `;   // 保留空格,打印对齐
@@ -2731,11 +2756,13 @@
      let d1 = getRootDiff();
 
      if (isTest){
-       let tq = root.data.feesIndex.common.totalFee;
-       let mb = root.data.targetTotalFee;
-       let bbj = root.data.feesIndex.common.tenderTotalFee;
-       let ms = (calcModel == 2) ? `速度优先(0~${propV})` : "精度优先";
-       console.log(`调前${tq}|目标${mb}|调后无逼近${bbj}|差值${d1}|${ms}`);
+       let _tq = `调前${root.data.feesIndex.common.totalFee}`;
+       let _mb = `目标${root.data.targetTotalFee}`;
+       let _wbj = `调后无逼近${root.data.feesIndex.common.tenderTotalFee}`;
+       let _cz = `差值${d1}`;
+       let _js = `轮${times} 系数步距${G_DIGIT}`;
+       let _yx = (calcModel == 2) ? `速度优先(差比${diffProp} 差域0~${propV})` : "精度优先";
+       console.log(`${_tq}|${_mb}|${_wbj}|${_cz}|${_yx}|${_js}`);
      }
 
      // 多轮逼进
@@ -2757,10 +2784,11 @@
        let d2 = getRootDiff();
 
        if (isTest){
+         let _time = `【第 ${i} 轮】调整`;
          let _node = `[行${obj.node.data.tender_rowNo} 索引${obj.nodeIdx}]`;
-         let _coe = `${obj.node.data.tender_previousCoe} → ${getCoe(obj.node)}`;
+         let _coe = `${obj.node.data.tender_previousCoe} → ${calcTools.getCoe(obj.node, tender)}`;
          let _d = `差值${d1} → ${d2}`;
-         console.log(`【第 ${i} 轮】调整${_node} ${_coe},${_d}`);
+         console.log(`${_time}${_node} ${_coe},${_d}`);
        }
 
        if (Math.abs(d2) > Math.abs(d1)){    // 逼近后差值反而变大,证明此轮调节不合适,回退一步,并将结点从列表清除
@@ -2815,20 +2843,8 @@
    };
 
    doTenderCalc(callback) {
-     function getTenderType(){
-       let rst;
-       let sOption = calcTools.getTenderCalcType();
-       if (sOption == 'coeBase')
-         rst = tenderTypes.ttCalc
-       else if (sOption == 'priceBase_RCJ')
-         rst = tenderTypes.ttReverseGLJ
-       else if (sOption == 'priceBase_ZM')
-         rst = tenderTypes.ttReverseRation;
-       return rst;
-     };
-
      $.bootstrapLoading.start();
-     let tender = getTenderType();
+     let tender = calcTools.getTenderType();
      if (tender == tenderTypes.ttReverseGLJ || tender == tenderTypes.ttReverseRation) {
        // 调价计算必须依赖调价树。
        if (!tender_obj.tenderTree){
@@ -2841,7 +2857,7 @@
        this.prepareForDistribute(tender_obj.tenderTree.roots[0]);
        this.distributeTargetTotalFee(tender_obj.tenderTree.roots[0]);
        this.calcAllNodes(calcAllType.catAll, tender);    // 先全局反算:得到每定额的coe、基础调后金额(误差大,需逼近)
-       this.reverseTenderApproach(callback);             // 逼近上述基础调后金额
+       this.reverseTenderApproach(callback, tender);     // 逼近上述基础调后金额
      }
 
      // 全局正算(用的是主树,无需调价树)

+ 1 - 1
web/building_saas/main/js/views/tender_price_view.js

@@ -429,7 +429,7 @@ let tender_obj={
         let tenderSetting = projectObj.project.property.tenderSetting;
         let gljPriceTenderCoe = tenderSetting && tenderSetting.gljPriceTenderCoe?tenderSetting.gljPriceTenderCoe:1;
         let showTenderFields = tenderSetting && tenderSetting.showTenderFields?tenderSetting.showTenderFields:false;
-        let calcPriceOption = calcTools.getTenderCalcType();
+        let calcPriceOption = calcTools.getTenderTypeStr();
         $('#calcPriceOption').val(calcPriceOption);
         $('#gljPriceTenderCoe').val(gljPriceTenderCoe);
         $('#cbShowTenderFields').prop("checked", showTenderFields);