|  | @@ -151,7 +151,7 @@ let calcTools = {
 | 
	
		
			
				|  |  |          if (this.isRationCategory(treeNode)) {
 | 
	
		
			
				|  |  |              if (treeNode.data.type != rationType.volumePrice) {
 | 
	
		
			
				|  |  |                  treeNode.data.gljList = projectObj.project.ration_glj.getGljArrByRation(treeNode.data);
 | 
	
		
			
				|  |  | -            };
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          else if (this.isBill(treeNode)){
 | 
	
		
			
				|  |  |              let nodeQ = this.uiNodeQty(treeNode);
 | 
	
	
		
			
				|  | @@ -211,6 +211,16 @@ let calcTools = {
 | 
	
		
			
				|  |  |              treeNode.data.feesIndex[feeObj.fieldName].totalFee = feeObj.totalFee;
 | 
	
		
			
				|  |  |              treeNode.changed = true;
 | 
	
		
			
				|  |  |          };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if (treeNode.data.feesIndex[feeObj.fieldName].tenderUnitFee != feeObj.tenderUnitFee){
 | 
	
		
			
				|  |  | +            treeNode.data.feesIndex[feeObj.fieldName].tenderUnitFee = feeObj.tenderUnitFee;
 | 
	
		
			
				|  |  | +            treeNode.changed = true;
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if (treeNode.data.feesIndex[feeObj.fieldName].tenderTotalFee != feeObj.tenderTotalFee){
 | 
	
		
			
				|  |  | +            treeNode.data.feesIndex[feeObj.fieldName].tenderTotalFee = feeObj.tenderTotalFee;
 | 
	
		
			
				|  |  | +            treeNode.changed = true;
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  |      setFieldValue: function (treeNode, fieldName, value){
 | 
	
		
			
				|  |  |          if (fieldName.includes('feesIndex')){
 | 
	
	
		
			
				|  | @@ -245,31 +255,29 @@ let calcTools = {
 | 
	
		
			
				|  |  |          else
 | 
	
		
			
				|  |  |              return 0;
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    rationBaseFee: function (treeNode, gljTypes, priceType){
 | 
	
		
			
				|  |  | +    rationBaseFee: function (treeNode, gljTypes, priceType, isTender){
 | 
	
		
			
				|  |  |          if (!treeNode.data.gljList) return 0;
 | 
	
		
			
				|  |  |          let me = this, result = 0;
 | 
	
		
			
				|  |  |          let price = 0, temp = 0, temp2 = 0;
 | 
	
		
			
				|  |  |          for (let glj of treeNode.data.gljList) {
 | 
	
		
			
				|  |  |              if (gljTypes.indexOf(glj.type) >= 0) {
 | 
	
		
			
				|  |  | -/*                if (priceType == priceTypes.ptDiffPrice){
 | 
	
		
			
				|  |  | -                    let aprice = me.uiGLJPrice(glj["adjustPrice"]);
 | 
	
		
			
				|  |  | -                    let mprice = me.uiGLJPrice(glj["marketPrice"]);
 | 
	
		
			
				|  |  | -                    temp = (me.uiGLJQty(glj["quantity"]) * mprice).toDecimal(decimalObj.process) - (me.uiGLJQty(glj["quantity"]) * aprice).toDecimal(decimalObj.process);
 | 
	
		
			
				|  |  | -                    temp = temp.toDecimal(decimalObj.process);
 | 
	
		
			
				|  |  | -                }*/
 | 
	
		
			
				|  |  | +                calcTools.calcGLJTenderPrice(glj);
 | 
	
		
			
				|  |  | +                calcTools.calcGLJTenderQty(treeNode, glj);
 | 
	
		
			
				|  |  | +                let qty = isTender ? me.uiGLJQty(glj["tenderQuantity"]) : me.uiGLJQty(glj["quantity"]);
 | 
	
		
			
				|  |  | +                let mprice = isTender ? me.uiGLJPrice(glj["tenderPrice"]) : me.uiGLJPrice(glj["marketPrice"]);
 | 
	
		
			
				|  |  | +                let aprice = me.uiGLJPrice(glj["adjustPrice"]);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |                  if (priceType == priceTypes.ptDiffPrice){
 | 
	
		
			
				|  |  | -                    let aprice = me.uiGLJPrice(glj["adjustPrice"]);
 | 
	
		
			
				|  |  | -                    let mprice = me.uiGLJPrice(glj["marketPrice"]);
 | 
	
		
			
				|  |  |                      if (aprice != mprice){
 | 
	
		
			
				|  |  | -                        temp = (temp + (me.uiGLJQty(glj["quantity"]) * mprice).toDecimal(decimalObj.process)).toDecimal(decimalObj.process);
 | 
	
		
			
				|  |  | -                        temp2 = (temp2 + (me.uiGLJQty(glj["quantity"]) * aprice).toDecimal(decimalObj.process)).toDecimal(decimalObj.process);
 | 
	
		
			
				|  |  | +                        temp = (temp + (qty * mprice).toDecimal(decimalObj.process)).toDecimal(decimalObj.process);
 | 
	
		
			
				|  |  | +                        temp2 = (temp2 + (qty * aprice).toDecimal(decimalObj.process)).toDecimal(decimalObj.process);
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |                  else {
 | 
	
		
			
				|  |  |                      if (priceType == priceTypes.ptBasePrice){ price = me.uiGLJPrice(glj["basePrice"]);}
 | 
	
		
			
				|  |  | -                    else if (priceType == priceTypes.ptAdjustPrice){price = me.uiGLJPrice(glj["adjustPrice"]);}
 | 
	
		
			
				|  |  | -                    else if (priceType == priceTypes.ptMarketPrice){price = me.uiGLJPrice(glj["marketPrice"]);}
 | 
	
		
			
				|  |  | -                    temp = (me.uiGLJQty(glj["quantity"]) * price).toDecimal(decimalObj.process);
 | 
	
		
			
				|  |  | +                    else if (priceType == priceTypes.ptAdjustPrice){price = aprice;}
 | 
	
		
			
				|  |  | +                    else if (priceType == priceTypes.ptMarketPrice){price = mprice;}
 | 
	
		
			
				|  |  | +                    temp = (qty * price).toDecimal(decimalObj.process);
 | 
	
		
			
				|  |  |                      result = (result + temp).toDecimal(decimalObj.process);
 | 
	
		
			
				|  |  |                  };
 | 
	
		
			
				|  |  |              };
 | 
	
	
		
			
				|  | @@ -284,12 +292,19 @@ let calcTools = {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          return result;
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    machineLabourFee: function (gljArr) {
 | 
	
		
			
				|  |  | +    machineLabourFee: function (treeNode, gljArr, isTender) {
 | 
	
		
			
				|  |  |          if (!gljArr) return 0;
 | 
	
		
			
				|  |  |          let result = 0;
 | 
	
		
			
				|  |  |          for (let glj of gljArr) {
 | 
	
		
			
				|  |  |              if (glj.type == gljType.GENERAL_MACHINE) {
 | 
	
		
			
				|  |  | -                // 获取机械组成物
 | 
	
		
			
				|  |  | +                let gljQ;
 | 
	
		
			
				|  |  | +                if (isTender){
 | 
	
		
			
				|  |  | +                    calcTools.calcGLJTenderQty(treeNode, glj);
 | 
	
		
			
				|  |  | +                    gljQ = glj.tenderQuantity;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                else
 | 
	
		
			
				|  |  | +                    gljQ = glj.quantity;
 | 
	
		
			
				|  |  | +                // 获取机械组成物(调价不深入到组成物)
 | 
	
		
			
				|  |  |                  let mds = projectObj.project.composition.getCompositionByGLJ(glj);
 | 
	
		
			
				|  |  |                  if (!mds) mds = [];
 | 
	
		
			
				|  |  |                  let mdSum = 0;
 | 
	
	
		
			
				|  | @@ -301,16 +316,16 @@ let calcTools = {
 | 
	
		
			
				|  |  |                          mdSum = (mdSum).toDecimal(decimalObj.ration.unitPrice);
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  | -                result = result + (glj["quantity"] * mdSum).toDecimal(decimalObj.ration.unitPrice);
 | 
	
		
			
				|  |  | +                result = result + (gljQ * mdSum).toDecimal(decimalObj.ration.unitPrice);
 | 
	
		
			
				|  |  |                  result = (result).toDecimal(decimalObj.ration.unitPrice);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          return result;
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  |      // 总造价清单、叶子清单、定额的暂估费。父清单是汇总子清单的暂估费,走计算程序逻辑,不在这里。
 | 
	
		
			
				|  |  | -    estimateFee: function (treeNode, isBase = false){
 | 
	
		
			
				|  |  | +    estimateFee: function (treeNode, isBase, isTender){
 | 
	
		
			
				|  |  |          let me = this, sumU = 0, sumT = 0;
 | 
	
		
			
				|  |  | -        let nodeQ = me.uiNodeQty(treeNode);
 | 
	
		
			
				|  |  | +        let nodeQ = me.uiNodeQty(treeNode, isTender);
 | 
	
		
			
				|  |  |          let isGather = (projectObj.project.property.zanguCalcMode == zanguCalcType.gatherMaterial);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // 先汇总数量,再乘市场价。如果是叶子清单,进入这里的gljList中的材料,已经是同类材料跨定额汇总过的了。
 | 
	
	
		
			
				|  | @@ -443,7 +458,7 @@ let calcTools = {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          me.checkFeeField(treeNode, {'fieldName': 'estimate', 'unitFee': sumU, 'totalFee': sumT});
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    marketPriceToBase: function (treeNode, baseName) {
 | 
	
		
			
				|  |  | +    marketPriceToBase: function (treeNode, baseName, isTender) {
 | 
	
		
			
				|  |  |          if (treeNode.data.type != rationType.volumePrice && treeNode.data.type != rationType.gljRation) return;
 | 
	
		
			
				|  |  |          let result = 0, me = this;
 | 
	
		
			
				|  |  |          if (
 | 
	
	
		
			
				|  | @@ -468,7 +483,7 @@ let calcTools = {
 | 
	
		
			
				|  |  |                  'quantity': 1,
 | 
	
		
			
				|  |  |                  'type': treeNode.data.subType      // 注意:这里要取subType
 | 
	
		
			
				|  |  |              };
 | 
	
		
			
				|  |  | -            result = me.machineLabourFee([glj]);
 | 
	
		
			
				|  |  | +            result = me.machineLabourFee(treeNode, [glj], isTender);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          else if (
 | 
	
		
			
				|  |  |              (treeNode.data.type == rationType.gljRation) &&
 | 
	
	
		
			
				|  | @@ -482,7 +497,7 @@ let calcTools = {
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          return result;
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    partASupplyFee: function (treeNode, baseName) {
 | 
	
		
			
				|  |  | +    partASupplyFee: function (treeNode, baseName, isTender) {
 | 
	
		
			
				|  |  |          if (!treeNode.data.gljList) return 0;
 | 
	
		
			
				|  |  |          let projectGLJ = projectObj.project.projectGLJ;
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -536,16 +551,26 @@ let calcTools = {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          let sum = 0;
 | 
	
		
			
				|  |  |          for (let glj of treeNode.data.gljList){
 | 
	
		
			
				|  |  | +            let gljQ;
 | 
	
		
			
				|  |  | +            if (isTender){
 | 
	
		
			
				|  |  | +                calcTools.calcGLJTenderQty(treeNode, glj);
 | 
	
		
			
				|  |  | +                gljQ = glj.tenderQuantity;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            else
 | 
	
		
			
				|  |  | +                gljQ = glj.quantity;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |              let X = 1;    // 部分甲供系数(默认1,即完全甲供)
 | 
	
		
			
				|  |  |              let tempSGLJ = supplyGLJsIdx[glj.projectGLJID];
 | 
	
		
			
				|  |  |              // 当前材料是甲供材料:①普通 ②商品硂等不计组成物的母体材料
 | 
	
		
			
				|  |  |              if (tempSGLJ) {
 | 
	
		
			
				|  |  |                  // 处理部分甲供
 | 
	
		
			
				|  |  |                  if (baseName.includes('甲供') && (tempSGLJ.supply == supplyType.BFJG)){
 | 
	
		
			
				|  |  | -                    let Q = tempSGLJ.quantity ? tempSGLJ.quantity : 1;
 | 
	
		
			
				|  |  | +                    // let Q =  isTender ? tempSGLJ.tenderQuantity : tempSGLJ.quantity;
 | 
	
		
			
				|  |  | +                    let Q = tempSGLJ.quantity;
 | 
	
		
			
				|  |  | +                    Q = Q ? Q : 1;
 | 
	
		
			
				|  |  |                      X = tempSGLJ.supply_quantity / Q;
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  | -                sum = (sum + glj.basePrice * glj.quantity * X).toDecimal(decimalObj.process);
 | 
	
		
			
				|  |  | +                sum = (sum + glj.basePrice * gljQ * X).toDecimal(decimalObj.process);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |              else{   // 当前材料不是甲供材料
 | 
	
		
			
				|  |  |                  if (compT.includes(glj.type)) {   // 混凝土等。组成物的母体,母体如果有组成物,则母体无法作为甲供材料,无法设置,此时要看其组成物是否是甲供材料;母体如果没有组成物,则母体有可能成为甲供材料。
 | 
	
	
		
			
				|  | @@ -558,7 +583,7 @@ let calcTools = {
 | 
	
		
			
				|  |  |                                  if (baseName.includes('甲供') && (c.supply == supplyType.BFJG)){
 | 
	
		
			
				|  |  |                                      X = c.supplyX;
 | 
	
		
			
				|  |  |                                  };
 | 
	
		
			
				|  |  | -                                sum = (sum + c.basePrice * c.consumption * glj.quantity * X).toDecimal(decimalObj.process);
 | 
	
		
			
				|  |  | +                                sum = (sum + c.basePrice * c.consumption * gljQ * X).toDecimal(decimalObj.process);
 | 
	
		
			
				|  |  |                              }
 | 
	
		
			
				|  |  |                          }
 | 
	
		
			
				|  |  |                      };
 | 
	
	
		
			
				|  | @@ -639,6 +664,46 @@ let calcTools = {
 | 
	
		
			
				|  |  |      uiNodeQty: function (treeNode){
 | 
	
		
			
				|  |  |          return parseFloatPlus(treeNode.data.quantity).toDecimal(decimalObj.decimal("quantity", treeNode));
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | +    calcNodeTenderQty: function (treeNode){
 | 
	
		
			
				|  |  | +        let qCoe = (treeNode.data.rationQuantityCoe == undefined) ? 1 : treeNode.data.rationQuantityCoe;
 | 
	
		
			
				|  |  | +        treeNode.data.tenderQuantity = (this.uiNodeQty(treeNode) * qCoe).toDecimal(decimalObj.decimal("quantity", treeNode));
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    calcGLJTenderQty: function (treeNode, glj){
 | 
	
		
			
				|  |  | +        if (treeNode.data.quantityCoe == undefined){
 | 
	
		
			
				|  |  | +            glj.tenderQuantity = glj.quantity;
 | 
	
		
			
				|  |  | +            return;
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        let qCoe = 1;
 | 
	
		
			
				|  |  | +        if (gljType.LABOUR == glj.type){
 | 
	
		
			
				|  |  | +            if (treeNode.data.quantityCoe.labour)
 | 
	
		
			
				|  |  | +                qCoe = treeNode.data.quantityCoe.labour;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        else if (baseMaterialTypes.indexOf(glj.type)){
 | 
	
		
			
				|  |  | +            if (treeNode.data.quantityCoe.material)
 | 
	
		
			
				|  |  | +                qCoe = treeNode.data.quantityCoe.material;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        else if (baseMachineTypes.indexOf(glj.type)){
 | 
	
		
			
				|  |  | +            if (treeNode.data.quantityCoe.machine)
 | 
	
		
			
				|  |  | +                qCoe = treeNode.data.quantityCoe.machine;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        else if (gljType.MAIN_MATERIAL == glj.type){
 | 
	
		
			
				|  |  | +            if (treeNode.data.quantityCoe.main)
 | 
	
		
			
				|  |  | +                qCoe = treeNode.data.quantityCoe.main;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        else if (gljType.EQUIPMENT == glj.type){
 | 
	
		
			
				|  |  | +            if (treeNode.data.quantityCoe.equipment)
 | 
	
		
			
				|  |  | +                qCoe = treeNode.data.quantityCoe.equipment;
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        glj.tenderQuantity = (glj.quantity * qCoe).toDecimal(decimalObj.glj.quantity);
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    calcGLJTenderPrice: function (glj) {
 | 
	
		
			
				|  |  | +        let pCoe = 1;
 | 
	
		
			
				|  |  | +        if (projectObj.project.property.tenderSetting && projectObj.project.property.tenderSetting.gljPriceTenderCoe)
 | 
	
		
			
				|  |  | +            pCoe = projectObj.project.property.tenderSetting.gljPriceTenderCoe;
 | 
	
		
			
				|  |  | +        glj.tenderPrice = (glj.marketPrice * pCoe).toDecimal(decimalObj.glj.unitPrice);
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  |      // 界面显示的工料机价格,包括定额价、市场价等。参数 price 传入一个普通的价格数值即可。
 | 
	
		
			
				|  |  |      uiGLJPrice: function (price){
 | 
	
		
			
				|  |  |          if (price)
 | 
	
	
		
			
				|  | @@ -718,99 +783,109 @@ const calcBaseNames = {
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  const rationCalcBases = {
 | 
	
		
			
				|  |  | -    '定额基价人工费': function (node) {
 | 
	
		
			
				|  |  | -        return calcTools.rationBaseFee(node, [gljType.LABOUR], priceTypes.ptBasePrice);
 | 
	
		
			
				|  |  | +    '定额基价人工费': function (node, isTender) {
 | 
	
		
			
				|  |  | +        return calcTools.rationBaseFee(node, [gljType.LABOUR], priceTypes.ptBasePrice, isTender);
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    '定额基价材料费': function (node) {
 | 
	
		
			
				|  |  | -        return calcTools.rationBaseFee(node, baseMaterialTypes, priceTypes.ptBasePrice);
 | 
	
		
			
				|  |  | +    '定额基价材料费': function (node, isTender) {
 | 
	
		
			
				|  |  | +        return calcTools.rationBaseFee(node, baseMaterialTypes, priceTypes.ptBasePrice, isTender);
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    '定额基价机械费': function (node) {
 | 
	
		
			
				|  |  | -        return calcTools.rationBaseFee(node, [gljType.GENERAL_MACHINE], priceTypes.ptBasePrice);
 | 
	
		
			
				|  |  | +    '定额基价机械费': function (node, isTender) {
 | 
	
		
			
				|  |  | +        return calcTools.rationBaseFee(node, [gljType.GENERAL_MACHINE], priceTypes.ptBasePrice, isTender);
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    '定额基价机上人工费': function (node) {
 | 
	
		
			
				|  |  | -        return calcTools.machineLabourFee(node.data.gljList);
 | 
	
		
			
				|  |  | +    '定额基价机上人工费': function (node, isTender) {
 | 
	
		
			
				|  |  | +        return calcTools.machineLabourFee(node, node.data.gljList, isTender);
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    '人工费价差': function (node) {
 | 
	
		
			
				|  |  | -        return calcTools.rationBaseFee(node, [gljType.LABOUR], priceTypes.ptDiffPrice);
 | 
	
		
			
				|  |  | +    '人工费价差': function (node, isTender) {
 | 
	
		
			
				|  |  | +        return calcTools.rationBaseFee(node, [gljType.LABOUR], priceTypes.ptDiffPrice, isTender);
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    '材料费价差': function (node) {
 | 
	
		
			
				|  |  | -        return calcTools.rationBaseFee(node, baseMaterialTypes, priceTypes.ptDiffPrice);
 | 
	
		
			
				|  |  | +    '材料费价差': function (node, isTender) {
 | 
	
		
			
				|  |  | +        return calcTools.rationBaseFee(node, baseMaterialTypes, priceTypes.ptDiffPrice, isTender);
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    '机械费价差': function (node) {
 | 
	
		
			
				|  |  | -        return calcTools.rationBaseFee(node, [gljType.GENERAL_MACHINE], priceTypes.ptDiffPrice);
 | 
	
		
			
				|  |  | +    '机械费价差': function (node, isTender) {
 | 
	
		
			
				|  |  | +        return calcTools.rationBaseFee(node, [gljType.GENERAL_MACHINE], priceTypes.ptDiffPrice, isTender);
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    '主材费': function (node) {
 | 
	
		
			
				|  |  | -        return calcTools.rationBaseFee(node, [gljType.MAIN_MATERIAL], priceTypes.ptMarketPrice);
 | 
	
		
			
				|  |  | +    '主材费': function (node, isTender) {
 | 
	
		
			
				|  |  | +        return calcTools.rationBaseFee(node, [gljType.MAIN_MATERIAL], priceTypes.ptMarketPrice, isTender);
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    '设备费': function (node) {
 | 
	
		
			
				|  |  | -        return calcTools.rationBaseFee(node, [gljType.EQUIPMENT], priceTypes.ptMarketPrice);
 | 
	
		
			
				|  |  | +    '设备费': function (node, isTender) {
 | 
	
		
			
				|  |  | +        return calcTools.rationBaseFee(node, [gljType.EQUIPMENT], priceTypes.ptMarketPrice, isTender);
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    '人工工日': function (node) {
 | 
	
		
			
				|  |  | +    '人工工日': function (node, isTender) {
 | 
	
		
			
				|  |  |          if (!node.data.gljList) return 0;
 | 
	
		
			
				|  |  |          let rst = 0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        calcTools.uiNodeQty(node)
 | 
	
		
			
				|  |  |          for (let glj of node.data.gljList) {
 | 
	
		
			
				|  |  |              if (glj.type == gljType.LABOUR) {
 | 
	
		
			
				|  |  | -                rst = rst + (calcTools.uiGLJQty(glj["quantity"]) * calcTools.uiNodeQty(node)).toDecimal(decimalObj.process);
 | 
	
		
			
				|  |  | +                let gljQ;
 | 
	
		
			
				|  |  | +                if (isTender){
 | 
	
		
			
				|  |  | +                    calcTools.calcGLJTenderQty(node, glj);
 | 
	
		
			
				|  |  | +                    gljQ = glj.tenderQuantity;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                else
 | 
	
		
			
				|  |  | +                    gljQ = glj.quantity;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                rst = rst + (gljQ * calcTools.uiNodeQty(node)).toDecimal(decimalObj.process);
 | 
	
		
			
				|  |  |                  rst = rst.toDecimal(decimalObj.process);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          };
 | 
	
		
			
				|  |  |          return rst.toDecimal(decimalObj.glj.quantity);
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    '甲供定额基价人工费': function (node) {
 | 
	
		
			
				|  |  | -        return calcTools.partASupplyFee(node, calcBaseNames.JGDEJJRGF);
 | 
	
		
			
				|  |  | +    '甲供定额基价人工费': function (node, isTender) {
 | 
	
		
			
				|  |  | +        return calcTools.partASupplyFee(node, calcBaseNames.JGDEJJRGF, isTender);
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    '甲供定额基价材料费': function (node) {
 | 
	
		
			
				|  |  | -        return calcTools.partASupplyFee(node, calcBaseNames.JGDEJJCLF);
 | 
	
		
			
				|  |  | +    '甲供定额基价材料费': function (node, isTender) {
 | 
	
		
			
				|  |  | +        return calcTools.partASupplyFee(node, calcBaseNames.JGDEJJCLF, isTender);
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    '甲供定额基价机械费': function (node) {
 | 
	
		
			
				|  |  | -        return calcTools.partASupplyFee(node, calcBaseNames.JGDEJJJXF);
 | 
	
		
			
				|  |  | +    '甲供定额基价机械费': function (node, isTender) {
 | 
	
		
			
				|  |  | +        return calcTools.partASupplyFee(node, calcBaseNames.JGDEJJJXF, isTender);
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    '甲供主材费': function (node) {
 | 
	
		
			
				|  |  | -        return calcTools.partASupplyFee(node, calcBaseNames.JGZCF);
 | 
	
		
			
				|  |  | +    '甲供主材费': function (node, isTender) {
 | 
	
		
			
				|  |  | +        return calcTools.partASupplyFee(node, calcBaseNames.JGZCF, isTender);
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    '甲供设备费': function (node) {
 | 
	
		
			
				|  |  | -        return calcTools.partASupplyFee(node, calcBaseNames.JGSBF);
 | 
	
		
			
				|  |  | +    '甲供设备费': function (node, isTender) {
 | 
	
		
			
				|  |  | +        return calcTools.partASupplyFee(node, calcBaseNames.JGSBF, isTender);
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    '甲定定额基价人工费': function (node) {
 | 
	
		
			
				|  |  | -        return calcTools.partASupplyFee(node, calcBaseNames.JDDEJJRGF);
 | 
	
		
			
				|  |  | +    '甲定定额基价人工费': function (node, isTender) {
 | 
	
		
			
				|  |  | +        return calcTools.partASupplyFee(node, calcBaseNames.JDDEJJRGF, isTender);
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    '甲定定额基价材料费': function (node) {
 | 
	
		
			
				|  |  | -        return calcTools.partASupplyFee(node, calcBaseNames.JDDEJJCLF);
 | 
	
		
			
				|  |  | +    '甲定定额基价材料费': function (node, isTender) {
 | 
	
		
			
				|  |  | +        return calcTools.partASupplyFee(node, calcBaseNames.JDDEJJCLF, isTender);
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    '甲定定额基价机械费': function (node) {
 | 
	
		
			
				|  |  | -        return calcTools.partASupplyFee(node, calcBaseNames.JDDEJJJXF);
 | 
	
		
			
				|  |  | +    '甲定定额基价机械费': function (node, isTender) {
 | 
	
		
			
				|  |  | +        return calcTools.partASupplyFee(node, calcBaseNames.JDDEJJJXF, isTender);
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    '甲定主材费': function (node) {
 | 
	
		
			
				|  |  | -        return calcTools.partASupplyFee(node, calcBaseNames.JDZCF);
 | 
	
		
			
				|  |  | +    '甲定主材费': function (node, isTender) {
 | 
	
		
			
				|  |  | +        return calcTools.partASupplyFee(node, calcBaseNames.JDZCF, isTender);
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    '甲定设备费': function (node) {
 | 
	
		
			
				|  |  | -        return calcTools.partASupplyFee(node, calcBaseNames.JDSBF);
 | 
	
		
			
				|  |  | +    '甲定设备费': function (node, isTender) {
 | 
	
		
			
				|  |  | +        return calcTools.partASupplyFee(node, calcBaseNames.JDSBF, isTender);
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    '暂估材料费': function (node) {
 | 
	
		
			
				|  |  | -        return calcTools.estimateFee(node, true);
 | 
	
		
			
				|  |  | +    '暂估材料费': function (node, isTender) {
 | 
	
		
			
				|  |  | +        return calcTools.estimateFee(node, true, isTender);
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    '分包定额基价人工费': function (node) {
 | 
	
		
			
				|  |  | -        if (node.data.isSubcontract) return this.定额基价人工费(node)
 | 
	
		
			
				|  |  | +    '分包定额基价人工费': function (node, isTender) {
 | 
	
		
			
				|  |  | +        if (node.data.isSubcontract) return this.定额基价人工费(node, isTender)
 | 
	
		
			
				|  |  |          else return 0;
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    '分包定额基价材料费': function (node) {
 | 
	
		
			
				|  |  | -        if (node.data.isSubcontract) return this.定额基价材料费(node)
 | 
	
		
			
				|  |  | +    '分包定额基价材料费': function (node, isTender) {
 | 
	
		
			
				|  |  | +        if (node.data.isSubcontract) return this.定额基价材料费(node, isTender)
 | 
	
		
			
				|  |  |          else return 0;
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    '分包定额基价机械费': function (node) {
 | 
	
		
			
				|  |  | -        if (node.data.isSubcontract) return this.定额基价机械费(node)
 | 
	
		
			
				|  |  | +    '分包定额基价机械费': function (node, isTender) {
 | 
	
		
			
				|  |  | +        if (node.data.isSubcontract) return this.定额基价机械费(node, isTender)
 | 
	
		
			
				|  |  |          else return 0;
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    '分包主材费': function (node) {
 | 
	
		
			
				|  |  | -        if (node.data.isSubcontract) return this.主材费(node)
 | 
	
		
			
				|  |  | +    '分包主材费': function (node, isTender) {
 | 
	
		
			
				|  |  | +        if (node.data.isSubcontract) return this.主材费(node, isTender)
 | 
	
		
			
				|  |  |          else return 0;
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    '分包设备费': function (node) {
 | 
	
		
			
				|  |  | -        if (node.data.isSubcontract) return this.设备费(node)
 | 
	
		
			
				|  |  | +    '分包设备费': function (node, isTender) {
 | 
	
		
			
				|  |  | +        if (node.data.isSubcontract) return this.设备费(node, isTender)
 | 
	
		
			
				|  |  |          else return 0;
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    '分包人工工日': function (node) {
 | 
	
		
			
				|  |  | -        if (node.data.isSubcontract) return this.人工工日(node)
 | 
	
		
			
				|  |  | +    '分包人工工日': function (node, isTender) {
 | 
	
		
			
				|  |  | +        if (node.data.isSubcontract) return this.人工工日(node, isTender)
 | 
	
		
			
				|  |  |          else return 0;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  };
 | 
	
	
		
			
				|  | @@ -1004,14 +1079,18 @@ let analyzer = {
 | 
	
		
			
				|  |  |          });
 | 
	
		
			
				|  |  |          for (var i = 0; i < atIDArr.length; i++) {
 | 
	
		
			
				|  |  |              let patt = new RegExp(atIDArr[i]);
 | 
	
		
			
				|  |  | -            let val = `$CE.at(${IDArr[i]})`;
 | 
	
		
			
				|  |  | +            let val = `$CE.at(${IDArr[i]}, false)`;
 | 
	
		
			
				|  |  |              rst = rst.replace(patt, val);
 | 
	
		
			
				|  |  |          };
 | 
	
		
			
				|  |  |          rst = rst.replace(/\[/g, "$CE.base('");
 | 
	
		
			
				|  |  | -        rst = rst.replace(/\]/g, "')");
 | 
	
		
			
				|  |  | +        rst = rst.replace(/\]/g, "', false)");
 | 
	
		
			
				|  |  |          rst = rst.replace(/L/g, labourCoe);
 | 
	
		
			
				|  |  |          return rst;
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | +    getCompiledTenderExpr: function (compiledExpr) {
 | 
	
		
			
				|  |  | +        let rst = compiledExpr.replace(/false/g, "true");
 | 
	
		
			
				|  |  | +        return rst;
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  |      getStatement: function (expression, template) {
 | 
	
		
			
				|  |  |          let rst = expression;
 | 
	
		
			
				|  |  |          let atIDArr = analyzer.getAtIDArr(rst);
 | 
	
	
		
			
				|  | @@ -1108,25 +1187,25 @@ let executeObj = {
 | 
	
		
			
				|  |  |      template: null,
 | 
	
		
			
				|  |  |      tempCalcItem: null,
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    at: function(ID) {
 | 
	
		
			
				|  |  | -        let me = executeObj;
 | 
	
		
			
				|  |  | -        let rst = me.template.compiledCalcItems[ID].unitFee;
 | 
	
		
			
				|  |  | +    at: function(ID, isTender) {
 | 
	
		
			
				|  |  | +        let item = executeObj.template.compiledCalcItems[ID];
 | 
	
		
			
				|  |  | +        let rst = isTender ? item.tenderUnitFee : item.unitFee;
 | 
	
		
			
				|  |  |          rst = parseFloat(rst);
 | 
	
		
			
				|  |  |          return rst;
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    base: function(baseName) {
 | 
	
		
			
				|  |  | +    base: function(baseName, isTender) {
 | 
	
		
			
				|  |  |          let me = executeObj;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // 量价、工料机形式的定额, 要把自己的市场单价用于计算程序中的基数。
 | 
	
		
			
				|  |  |          if (calcTools.isVolumePrice(me.treeNode) || calcTools.isGljRation(me.treeNode))
 | 
	
		
			
				|  |  | -            return calcTools.marketPriceToBase(me.treeNode, baseName)
 | 
	
		
			
				|  |  | +            return calcTools.marketPriceToBase(me.treeNode, baseName, isTender)
 | 
	
		
			
				|  |  |          else{
 | 
	
		
			
				|  |  |              if (!rationCalcBases[baseName]){
 | 
	
		
			
				|  |  |                  hintBox.infoBox('系统提示', '定额基数“' + baseName + '”末定义,计算错误。 (模板 ' + me.template.ID + ',规则 ' + me.tempCalcItem.ID +')', 1);
 | 
	
		
			
				|  |  |                  return 0;
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |              else
 | 
	
		
			
				|  |  | -                return rationCalcBases[baseName](me.treeNode);
 | 
	
		
			
				|  |  | +                return rationCalcBases[baseName](me.treeNode, isTender);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  |      HJ: function () {
 | 
	
	
		
			
				|  | @@ -1613,10 +1692,16 @@ class CalcProgram {
 | 
	
		
			
				|  |  |                      if (calcItem.feeRate != undefined)
 | 
	
		
			
				|  |  |                          feeRate = parseFloat(calcItem.feeRate).toDecimal(decimalObj.feeRate);
 | 
	
		
			
				|  |  |                      // console.log(`[${calcItem.ID}]: ${calcItem.compiledExpr}`);   // for test.
 | 
	
		
			
				|  |  | -                    calcItem.unitFee = (eval(calcItem.compiledExpr) * feeRate * 0.01).toDecimal(decimalObj.decimal('unitPrice', treeNode));   // 如果eval()对清单树有影响,就换成小麦的Expression对象再试
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                    let q = calcTools.uiNodeQty(treeNode) ? calcTools.uiNodeQty(treeNode) : 0;
 | 
	
		
			
				|  |  | -                    calcItem.totalFee = (calcItem.unitFee * q).toDecimal(decimalObj.decimal('totalPrice', treeNode));
 | 
	
		
			
				|  |  | +                    calcItem.unitFee = (eval(calcItem.compiledExpr) * feeRate * 0.01).toDecimal(decimalObj.decimal('unitPrice', treeNode));
 | 
	
		
			
				|  |  | +                    calcItem.totalFee = (calcItem.unitFee * calcTools.uiNodeQty(treeNode)).toDecimal(decimalObj.decimal('totalPrice', treeNode));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                    if (isTender) {
 | 
	
		
			
				|  |  | +                        calcTools.calcNodeTenderQty(treeNode);
 | 
	
		
			
				|  |  | +                        let tExpr = analyzer.getCompiledTenderExpr(calcItem.compiledExpr);
 | 
	
		
			
				|  |  | +                        calcItem.tenderUnitFee = (eval(tExpr) * feeRate * 0.01).toDecimal(decimalObj.decimal('unitPrice', treeNode));
 | 
	
		
			
				|  |  | +                        calcItem.tenderTotalFee = (calcItem.tenderUnitFee * treeNode.data.tenderQuantity).toDecimal(decimalObj.decimal('totalPrice', treeNode));
 | 
	
		
			
				|  |  | +                    };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                      if (calcItem.fieldName) {
 | 
	
		
			
				|  |  |                          fnArr.push(calcItem.fieldName);
 | 
	
	
		
			
				|  | @@ -1634,22 +1719,22 @@ class CalcProgram {
 | 
	
		
			
				|  |  |      };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      // 计算本节点、所有父节点(默认,可选)、公式引用节点(默认,可选)。
 | 
	
		
			
				|  |  | -    calculate(treeNode, calcParents = true, calcFormulas = true){
 | 
	
		
			
				|  |  | +    calculate(treeNode, calcParents = true, calcFormulas = true, isTender = false){
 | 
	
		
			
				|  |  |          let me = this;
 | 
	
		
			
				|  |  |          let changedNodes = [];
 | 
	
		
			
				|  |  | -        me.innerCalc(treeNode, changedNodes);
 | 
	
		
			
				|  |  | +        me.innerCalc(treeNode, changedNodes, isTender);
 | 
	
		
			
				|  |  |          if (treeNode.changed) {
 | 
	
		
			
				|  |  |              // 计算父结点
 | 
	
		
			
				|  |  |              if (calcParents){
 | 
	
		
			
				|  |  |                  let curNode = treeNode.parent;
 | 
	
		
			
				|  |  |                  while (curNode){
 | 
	
		
			
				|  |  | -                    me.innerCalc(curNode, changedNodes);
 | 
	
		
			
				|  |  | +                    me.innerCalc(curNode, changedNodes, isTender);
 | 
	
		
			
				|  |  |                      curNode = curNode.parent;
 | 
	
		
			
				|  |  |                  };
 | 
	
		
			
				|  |  |              };
 | 
	
		
			
				|  |  |              // 父结点算完,再计算所有的公式结点(必须先算完父结点,再算公式结点)
 | 
	
		
			
				|  |  |              if (calcFormulas) {
 | 
	
		
			
				|  |  | -                me.calcFormulaNodes(changedNodes);
 | 
	
		
			
				|  |  | +                me.calcFormulaNodes(changedNodes, isTender);
 | 
	
		
			
				|  |  |              };
 | 
	
		
			
				|  |  |          };
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -1662,7 +1747,7 @@ class CalcProgram {
 | 
	
		
			
				|  |  |          calcAllType.catRations   计算所有定额、工料机形式的定额、量价,因为它们都走自己的计算程序 (改变人工系数、费率值、工料机单价时会用到)  不要用
 | 
	
		
			
				|  |  |          缺陷:calcAllType.catRations 参数情况不会计算父结点。(calcAllType.catBills 可以,因为清单的父结点也是清单会计算)
 | 
	
		
			
				|  |  |      */
 | 
	
		
			
				|  |  | -    calcAllNodes(calcType = calcAllType.catAll){
 | 
	
		
			
				|  |  | +    calcAllNodes(calcType = calcAllType.catAll, isTender){
 | 
	
		
			
				|  |  |          let me = this;
 | 
	
		
			
				|  |  |          let changedNodes = [];
 | 
	
		
			
				|  |  |          function calcNodes(nodes) {
 | 
	
	
		
			
				|  | @@ -1674,17 +1759,17 @@ class CalcProgram {
 | 
	
		
			
				|  |  |                  if (calcType == calcAllType.catAll || calcType == node.sourceType) {
 | 
	
		
			
				|  |  |                      node.calcType = calcTools.getCalcType(node);
 | 
	
		
			
				|  |  |                      if (node.calcType != treeNodeCalcType.ctCalcBaseValue)
 | 
	
		
			
				|  |  | -                        me.innerCalc(node, changedNodes);
 | 
	
		
			
				|  |  | +                        me.innerCalc(node, changedNodes, isTender);
 | 
	
		
			
				|  |  |                  };
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          };
 | 
	
		
			
				|  |  |          calcNodes(me.project.mainTree.roots);
 | 
	
		
			
				|  |  | -        me.calcFormulaNodes(changedNodes);
 | 
	
		
			
				|  |  | +        me.calcFormulaNodes(changedNodes, isTender);
 | 
	
		
			
				|  |  |          return changedNodes;
 | 
	
		
			
				|  |  |      };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      // 计算全部公式项。 (参数意义:将通过本方法后发生改变的节点存入changedArr中)
 | 
	
		
			
				|  |  | -    calcFormulaNodes(changedArr){
 | 
	
		
			
				|  |  | +    calcFormulaNodes(changedArr, isTender){
 | 
	
		
			
				|  |  |          let me = this;
 | 
	
		
			
				|  |  |          let formulaNodes = cbTools.getFormulaNodes(true);
 | 
	
		
			
				|  |  |          if (formulaNodes.length == 0) return;
 | 
	
	
		
			
				|  | @@ -1693,13 +1778,13 @@ class CalcProgram {
 | 
	
		
			
				|  |  |              projectObj.project.calcBase.calculate(formulaNode, true);
 | 
	
		
			
				|  |  |              if (projectObj.project.calcBase.success){
 | 
	
		
			
				|  |  |                  // 计算公式结点
 | 
	
		
			
				|  |  | -                me.innerCalc(formulaNode, changedArr);
 | 
	
		
			
				|  |  | +                me.innerCalc(formulaNode, changedArr, isTender);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                  // 计算父结点
 | 
	
		
			
				|  |  |                  if (formulaNode.changed){
 | 
	
		
			
				|  |  |                      let curNode = formulaNode.parent;
 | 
	
		
			
				|  |  |                      while (curNode){
 | 
	
		
			
				|  |  | -                        me.innerCalc(curNode, changedArr);
 | 
	
		
			
				|  |  | +                        me.innerCalc(curNode, changedArr, isTender);
 | 
	
		
			
				|  |  |                          curNode = curNode.parent;
 | 
	
		
			
				|  |  |                      };
 | 
	
		
			
				|  |  |                  };
 | 
	
	
		
			
				|  | @@ -1790,8 +1875,8 @@ class CalcProgram {
 | 
	
		
			
				|  |  |          this.calcNodesAndSave(billNodes, callback);
 | 
	
		
			
				|  |  |      };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    calcAllNodesAndSave(calcType = calcAllType.catAll, callback){
 | 
	
		
			
				|  |  | -        let changedNodes = this.calcAllNodes(calcType);
 | 
	
		
			
				|  |  | +    calcAllNodesAndSave(calcType = calcAllType.catAll, callback, isTender){
 | 
	
		
			
				|  |  | +        let changedNodes = this.calcAllNodes(calcType, isTender);
 | 
	
		
			
				|  |  |          this.saveNodes(changedNodes, callback);
 | 
	
		
			
				|  |  |      };
 | 
	
		
			
				|  |  |  
 |