// 清单基数
const progression = ['养护管理单位项目管理费', '工程监理费', '招标费'];
const deficiency = {};
if (typeof baseFigureMap !== 'undefined') {
  const { fixedFlag } = commonConstants;
  const budgetMap = {
      // 显示：除清单固定类别是“建筑安装工程费”的以外部分可显示。
      '建筑安装工程费': {
          base: 'JZAZGCF',
          fixedFlag: fixedFlag.CONSTRUCTION_INSTALL_FEE,
          filter: [fixedFlag.CONSTRUCTION_INSTALL_FEE],
          pick: false,
      },
      // 显示：除清单固定类别是“建筑安装工程费”的以外部分可显示。
      '指标建筑安装工程费': {
          base: 'ZBJZAZGCF',
          fixedFlag: fixedFlag.CONSTRUCTION_INSTALL_FEE,
          filter: [fixedFlag.CONSTRUCTION_INSTALL_FEE],
          pick: false,
      },
      // 显示：除“建筑安装工程费”以外部分可显示。
      '建筑安装工程费(不含设备费)': {
          base: 'JZAZGCFBHSB',
          fixedFlag: null,
          filter: [fixedFlag.CONSTRUCTION_INSTALL_FEE],
          pick: false,
      },
      // 显示：仅清单固定类别是“安全生产费”可显示。
      '建筑安装工程费(不含安全生产费)': {
          base: 'JZAZGCFBHSC',
          fixedFlag: null,
          filter: [fixedFlag.SAFE_COST],
          pick: true
      },
      // 显示：仅清单固定类别是“养护工程其他费用”部分可显示。
      '养护管理单位项目管理费': {
        isProgressive: true,
        base: 'YHGLDWXMGLF',
        fixedFlag: null,
        filter: [fixedFlag.MAINTENANCE_EXPENSES],
        pick: true,
    },
    // 显示：仅清单固定类别是“养护工程其他费用”部分可显示。
    '工程监理费': {
      isProgressive: true,
      base: 'GCJLF',
      fixedFlag: null,
      filter: [fixedFlag.MAINTENANCE_EXPENSES],
      pick: true,
    },
    // 显示：仅清单固定类别是“养护工程其他费用”部分可显示。
    '招标费': {
      isProgressive: true,
      base: 'ZBF',
      fixedFlag: null,
      filter: [fixedFlag.MAINTENANCE_EXPENSES],
      pick: true,
    },
    // 显示：仅“价差预备费”可显示
    '价差预备费': {
      base: 'JCYBF',
      fixedFlag: null,
      filter: [fixedFlag.SPREAD_BUDGET_FEE],
      pick: true,
    },
  };
  const boqMap = {
      //仅允许用于固定类别是“第100章至700章清单”以外的清单
      '各章清单合计': {
          base: 'GZQDHJ',
          fixedFlag: fixedFlag.ONE_SEVEN_BILLS,
          filter: [fixedFlag.ONE_SEVEN_BILLS],
          pick: false
      },
      //仅允许用于固定类别是“第100章至700章清单”以外的清单
      '专项暂定合计': {
          base: 'ZXZDHJ',
          fixedFlag: null,
          filter: [fixedFlag.ONE_SEVEN_BILLS],
          pick: false
      },
      /*
      *  清单固定行[第100章至700章清单]下的[第100章清单]需要允许清单可使用基数{100章以外合计}
      *  因此{100章以外合计}不设置关联的清单固定行
      * */
      //仅允许用于固定类别为“100章清单”引用
      '100章以外清单合计': {
          base: 'YBZYWQDHJ',
          fixedFlag: null,
          filter: [fixedFlag.ONE_HUNDRED_BILLS],
          pick: true
      }
  };
  baseFigureMap.budget = budgetMap;
  baseFigureMap.boq = boqMap;
}

if (typeof baseFigureTemplate !== 'undefined') {
  const { fixedFlag } = commonConstants;
  baseFigureTemplate.budget = {
      // 建筑安装工程费 算法：取清单固定类别是“建筑安装工程费”的金额。
      JZAZGCF(tender) {
          return cbTools.getBaseFee(fixedFlag.CONSTRUCTION_INSTALL_FEE, tender, 'common');
      },
      // 指标建筑安装工程费 算法：取清单固定类别是“建筑安装工程费”的指标建安费。
      ZBJZAZGCF(tender) {
          return cbTools.getBaseFee(fixedFlag.CONSTRUCTION_INSTALL_FEE, tender, 'rationCommon');
      },
      // 建筑安装工程费(不含设备费) 算法：取清单固定类别是“建筑安装工程费”的金额，扣除设备购置。
      JZAZGCFBHSB(tender) {
        let baseFee = this['JZAZGCF'](tender);
        const fixedNode = projectObj.project.mainTree.roots.find(node => node.getFlag() === fixedFlag.CONSTRUCTION_INSTALL_FEE);
        const equipmentFee = cbTools.getEquipmentFee(fixedNode, tender);
        baseFee = (baseFee - equipmentFee).toDecimal(decimalObj.process);
        return baseFee.toDecimal(decimalObj.bills.totalPrice);
      },
      // 建筑安装工程费(不含安全生产费) 算法：取清单固定类别是“建筑安装工程费”的金额，扣除“安全生产费”的金额。
      JZAZGCFBHSC(tender) {
          return cbTools.getFeeWithDeduction(fixedFlag.CONSTRUCTION_INSTALL_FEE, [fixedFlag.SAFE_COST], tender, 'common');
      },
      // 养护管理单位项目管理费 算法：按“指标建筑安装工程费”为基数，以累进办法计算。
      YHGLDWXMGLF(tender) {
          const baseFee = this['ZBJZAZGCF'](tender);
          if (!tender) {
              calcBase.baseProgressiveFee = baseFee;
          }
          return calculateUtil.getProgressiveFee(baseFee, '养护管理单位项目管理费', projectObj.project.property.progressiveInterval, decimalObj.bills.totalPrice, deficiency);
      },
      // 工程监理费 算法：按“指标建筑安装工程费”为基数，以累进办法计算。
      GCJLF(tender) {
          const baseFee = this['ZBJZAZGCF'](tender);
          if (!tender) {
              calcBase.baseProgressiveFee = baseFee;
          }
          return calculateUtil.getProgressiveFee(baseFee, '工程监理费', projectObj.project.property.progressiveInterval, decimalObj.bills.totalPrice, deficiency);
      },
      // 招标费 算法：按“指标建筑安装工程费”为基数，以累进办法计算。
      ZBF(tender) {
          const baseFee = this['ZBJZAZGCF'](tender);
          if (!tender) {
              calcBase.baseProgressiveFee = baseFee;
          }
          return calculateUtil.getProgressiveFee(baseFee, '招标费', projectObj.project.property.progressiveInterval, decimalObj.bills.totalPrice, deficiency);
      },
      /*  价差预备费 算法：以建筑安装工程费为基数，按设计文件编制年始至养护项目工程竣工年终的年数和年工程造价增涨率计算。
          价差预备费 P * [(1+i)^(n-1) -1]
          P——建筑安装工程费总额（元）；
          i——年工程造价增涨率（%）；
          n——设计文件编制年至养护项目开工年+养护项目建设期限（年）。
      */
      JCYBF(tender) {
          //建筑安装工程费作为基数
          const installFee = this['JZAZGCF'](tender);
          //年造价增涨
          const costGrowthRate = calcBase.project.property.costGrowthRate
              ? calcBase.project.property.costGrowthRate
              : 0;
          //增涨计费年限
          const growthPeriod = projectObj.project.property.growthPeriod
              ? calcBase.project.property.growthPeriod
              : 0;
          //= P * [(1+i)^(n-1) -1]
          return (installFee * (Math.pow(1 + costGrowthRate, growthPeriod - 1) - 1)).toDecimal(decimalObj.bills.totalPrice);
      }

  };

  baseFigureTemplate.boq = {
      //{各章清单合计}
      // 取清单固定类别是“第100章至700章清单”的金额
      'GZQDHJ': function (tender) {
          return cbTools.getBaseFee(calcBase.fixedFlag.ONE_SEVEN_BILLS, tender, 'common');
      },
      //{专项暂定合计}
      // 第100章至700章清单行的暂估合价
      'ZXZDHJ': function (tender) {
          return cbTools.getBaseFee(calcBase.fixedFlag.ONE_SEVEN_BILLS, tender, 'estimate');
      },
      //{100章以外清单合计}
      // 取清单固定清单[第100章至700章清单]的金额，但扣除清单100章下的金额。
      // 如果是固定清单[第100章至700章清单]下100章以外清单引用此基数，要排除自身(目前只允许100章的清单使用，所以暂时不需要此判断)
      'YBZYWQDHJ': function (tender) {
          let oneToSeven = cbTools.findNodeByFlag(fixedFlag.ONE_SEVEN_BILLS);
          if (!oneToSeven) {
              return 0;
          }
          //100-700章固定节点的所有子节点
          let allChildren = [];
          function getChildren(nodes) {
              allChildren = allChildren.concat(nodes);
              for (let node of nodes) {
                  if (node.children.length > 0) {
                      getChildren(node.children);
                  }
              }
          }
          getChildren(oneToSeven.children);
          //扣除的节点：100章的节点[100-200)
          let deductNodes = allChildren.filter(cbTools.withingOneHundred);
          //计算金额
          let fullFeeField = tender ? 'common.tenderTotalFee' : 'common.totalFee';
          return projectObj.project.calcProgram.getTotalFee([oneToSeven], deductNodes, fullFeeField).toDecimal(decimalObj.bills.totalPrice);
      }
  };
}

function overwriteRationCalcBases() {
    if (typeof rationCalcBases == 'undefined') return;
    for (let key in rationCalcBases) delete rationCalcBases[key];

    rationCalcBases['人工费'] = function (node, isTender) {
        return calcTools.rationBaseFee(node, [gljType.LABOUR], priceTypes.ptMarketPrice, isTender);
    };
    rationCalcBases['材料费'] = function (node, isTender) {
        return calcTools.rationBaseFee(node, baseMaterialTypes, priceTypes.ptMarketPrice, isTender);
    };
    rationCalcBases['施工机械使用费'] = function (node, isTender) {
        return calcTools.rationBaseFee(node, baseMachineTypes, priceTypes.ptMarketPrice, isTender);
    };
    rationCalcBases['施工机械人工费'] = function (node, isTender) {
        return calcTools.machineDetailFee(node, node.data.gljList, [], gljType.MACHINE_LABOUR, isTender);
    };
    rationCalcBases['设备购置费'] = function (node, isTender) {
        return calcTools.rationBaseFee(node, [gljType.EQUIPMENT], priceTypes.ptMarketPrice, isTender);
    };
    rationCalcBases['指标人工费'] = function (node, isTender) {
        return calcTools.rationBaseFee(node, [gljType.LABOUR], priceTypes.ptBasePrice, isTender);
    };
    rationCalcBases['指标材料费'] = function (node, isTender) {
        return calcTools.rationBaseFee(node, baseMaterialTypes, priceTypes.ptBasePrice, isTender);
    };
    rationCalcBases['指标施工机械使用费'] = function (node, isTender) {
        return calcTools.rationBaseFee(node, baseMachineTypes, priceTypes.ptBasePrice, isTender);
    };
    rationCalcBases['指标设备购置费'] = function (node, isTender) {
        return calcTools.rationBaseFee(node, [gljType.EQUIPMENT], priceTypes.ptBasePrice, isTender);
    };
};

if (typeof projectObj !== 'undefined') {
    projectObj.isInsertEquipmentVisable = function (selected) {
        return true;   //广西不管是预算或者工程量清单，都是显示
    }
  }

if (typeof feeRateObject !== 'undefined') {
    feeRateObject.feeRateSpecialHandle = function (subRate, value) {
        let result = {};
        if (subRate.name == "工地转移(km)" && value && value < 50) {//工地转移50km以内按50km算
            result.valueKey = "50";
            result.value = scMathUtil.roundForObj(value, getDecimal("feeRate"));//设置显示的节点值
        }
        if (subRate.name == "施工进出场(km)" && value && value < 5) {//施工进出场5km以内按5km算
            result.valueKey = "5";
            result.value = scMathUtil.roundForObj(value, getDecimal("feeRate"));//设置显示的节点值
        }
        return result;
    }
}

(function overwriteFeeTypes() {
    if (typeof cpFeeTypes == 'undefined') return;
    cpFeeTypes = [
        { type: 'marketDirect', name: '直接费' },
        { type: 'marketLabour', name: '人工费' },
        { type: 'marketMaterial', name: '材料费' },
        { type: 'marketMachine', name: '施工机械使用费' },
        { type: 'marketMachineLabour', name: '施工机械人工费' },
        { type: 'marketEquipment', name: '设备购置费' },
        { type: 'labour', name: '指标人工费' },
        { type: 'material', name: '指标材料费' },
        { type: 'machine', name: '指标施工机械使用费' },
        { type: 'equipment', name: '指标设备购置费' },
        { type: 'direct', name: '指标直接费' },
        { type: 'measure', name: '措施费' },
        { type: 'manage', name: '企业管理费' },
        { type: 'force', name: '规费' },
        { type: 'profit', name: '利润' },
        { type: 'tax', name: '税金' },
        { type: 'common', name: '建安费' },
        { type: 'rationCommon', name: '指标建安费' }
    ];
})();
