// 公路云

let isQG2018 = true;

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.COMMERCIAL_CONCRETE, gljType.COMMERCIAL_MORTAR], priceTypes.ptBasePrice, isTender);
  };
  rationCalcBases["定额设备费"] = function (node, isTender) {
    return calcTools.rationBaseFee(node, [gljType.EQUIPMENT], priceTypes.ptBasePrice, isTender);
  };
  rationCalcBases["定额外购砼构件费"] = function (node, isTender) {
    return calcTools.rationBaseFee(node, [gljType.PURCHASE_COMPONENT], priceTypes.ptBasePrice, isTender);
  };
  rationCalcBases["定额绿化苗木费"] = function (node, isTender) {
    return calcTools.rationBaseFee(node, [gljType.GREEN_SEEDLING], priceTypes.ptBasePrice, isTender);
  };
}

(function overwriteFeeTypes() {
  if (typeof cpFeeTypes == "undefined") return;
  cpFeeTypes = [
    {
      type: "marketLabour",
      name: "人工费",
    },
    {
      type: "marketMaterial",
      name: "材料费",
    },
    {
      type: "marketMachine",
      name: "施工机械使用费",
    },
    {
      type: "marketMachineLabour",
      name: "施工机械人工费",
    },
    {
      type: "marketEquipment",
      name: "设备购置费",
    },
    {
      type: "marketDirect",
      name: "直接费",
    },

    {
      type: "labour",
      name: "定额人工费",
    },
    {
      type: "material",
      name: "定额材料费",
    },
    {
      type: "machine",
      name: "定额施工机械使用费",
    },
    {
      type: "equipment",
      name: "定额设备费",
    },
    {
      type: "direct",
      name: "定额直接费",
    },

    {
      type: "measure",
      name: "措施费",
    },
    {
      type: "measure1",
      name: "措施费I",
    },
    {
      type: "measure2",
      name: "措施费II",
    },
    {
      type: "manage",
      name: "企业管理费",
    },
    {
      type: "force",
      name: "规费",
    },
    {
      type: "profit",
      name: "利润",
    },
    {
      type: "tax",
      name: "税金",
    },
    {
      type: "common",
      name: "建安费",
    },
    {
      type: "rationCommon",
      name: "定额建安费",
    },
  ];
})();

// 在新建分段的时候需要隐藏养护类别和费用标准
if (typeof $ !== "undefined") {
  // 后端也有引用这个文件，后端引用时$没有定义会报错
  $(document).ready(function () {
    $("#tender-engineering-group").hide();
    $("#tender-feeStandard-group").hide();
  });
}

//全国工地转移、综合里程费率值修改特殊处理
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 < 3) {
      //综合里程3km以内按3km算
      result.valueKey = "3";
      result.value = scMathUtil.roundForObj(value, getDecimal("feeRate")); //设置显示的节点值
    }
    return result;
  };
}

// 清单基数
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: "DEJZAZGCF",
      fixedFlag: fixedFlag.CONSTRUCTION_INSTALL_FEE,
      filter: [
        /* fixedFlag.CONSTRUCTION_INSTALL_FEE */
      ],
      pick: true,
    },
    // 显示：仅清单固定类别是“安全生产费”行可显示
    "建筑安装工程费(不含安全生产费)": {
      base: "JZAZGCFBHSC",
      fixedFlag: null, // 防止触发循环计算
      filter: [fixedFlag.SAFE_COST],
      pick: true,
    },
    // 显示：仅清单固定类别是“工程建设其他费”部分可显示
    "建筑安装工程费(不含设备费)": {
      base: "JZAZGCFBHSB",
      fixedFlag: fixedFlag.CONSTRUCTION_INSTALL_FEE,
      filter: [fixedFlag.MAINTENANCE_EXPENSES],
      pick: true,
    },
    // 显示：仅清单固定类别是“工程建设其他费”部分可显示
    "定额建筑安装工程费(含定额设备购置费*40%)": {
      base: "DEJZAZGCFSBSS",
      fixedFlag: fixedFlag.CONSTRUCTION_INSTALL_FEE,
      filter: [fixedFlag.MAINTENANCE_EXPENSES],
      pick: true,
    },
    // 显示：仅清单固定类别是“工程建设其他费”可显示
    "定额建筑安装工程费(不含定额设备购置费、专项费用)": {
      base: "DEJZAZGCFBHSBZX",
      fixedFlag: null,
      filter: [
        /* fixedFlag.MAINTENANCE_EXPENSES */
      ],
      pick: true,
    },
    // 显示：仅清单固定类别是“施工场地建设费”的可显示
    施工场地建设费: {
      isProgressive: true,
      base: "SGCDJSF",
      // 虽然用到了定额建筑安装工程费一部分费用baseFee，但是是扣除了专项费用的。施工场地建设费清单为专项费用清单子项。
      // 当施工场地建设费清单使用此基数时，该清单的费用不会汇总到baseFee里，因此不会造成循环计算。如果fixedFlag设置成fixedFlag.CONSTRUCTION_INSTALL_FEE，则会造成循环计算
      fixedFlag: null,
      filter: [fixedFlag.CONSTRUCTION_PLANT_COST],
      pick: true,
    },
    // 显示：仅清单固定类别是“工程建设其他费”部分可显示
    "建设单位(业主)管理费": {
      isProgressive: true,
      base: "JSDWYZGLF",
      fixedFlag: fixedFlag.CONSTRUCTION_INSTALL_FEE,
      filter: [fixedFlag.MAINTENANCE_EXPENSES],
      pick: true,
    },
    // 显示：仅清单固定类别是“工程建设其他费”部分可显示
    建设项目信息化费: {
      isProgressive: true,
      base: "JSXMXXHF",
      fixedFlag: fixedFlag.CONSTRUCTION_INSTALL_FEE,
      filter: [fixedFlag.MAINTENANCE_EXPENSES],
      pick: true,
    },
    // 显示：仅清单固定类别是“工程建设其他费”部分可显示
    工程监理费: {
      isProgressive: true,
      base: "GCJLF",
      fixedFlag: fixedFlag.CONSTRUCTION_INSTALL_FEE,
      filter: [fixedFlag.MAINTENANCE_EXPENSES],
      pick: true,
    },
    // 显示：仅清单固定类别是“工程建设其他费”部分可显示
    设计文件审查费: {
      isProgressive: true,
      base: "SJWJSCF",
      fixedFlag: fixedFlag.CONSTRUCTION_INSTALL_FEE,
      filter: [fixedFlag.MAINTENANCE_EXPENSES],
      pick: true,
    },
    // 显示：仅清单固定类别是“工程建设其他费”部分可显示
    前期工作费: {
      isProgressive: true,
      base: "QQGZF",
      fixedFlag: fixedFlag.CONSTRUCTION_INSTALL_FEE,
      filter: [fixedFlag.MAINTENANCE_EXPENSES],
      pick: true,
    },
    // 显示：仅“价差预备费”可显示
    价差预备费: {
      base: "JCYBF",
      fixedFlag: fixedFlag.CONSTRUCTION_INSTALL_FEE,
      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: "YBZYHQDHJ",
      fixedFlag: null,
      filter: [fixedFlag.ONE_HUNDRED_BILLS],
      pick: true,
    },
    定额建筑安装工程费: {
      base: "DEJZAZGCF",
      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");
    },
    // 定额建筑安装工程费 算法：取“定额建筑安装工程费”的金额
    DEJZAZGCF(tender) {
      return cbTools.getBaseFee(fixedFlag.CONSTRUCTION_INSTALL_FEE, tender, "rationCommon");
    },
    // 建筑安装工程费(不含安全生产费) 算法：取固定类别是“建筑安装工程费”的“建安费”，扣除固定类别是“安全生产费”的“建安费”
    JZAZGCFBHSC(tender) {
      let baseFee = this["JZAZGCF"](tender);
      const safeFee = cbTools.getBaseFee(fixedFlag.SAFE_COST, tender, "common");
      return (baseFee - safeFee).toDecimal(decimalObj.bills.totalPrice);
    },
    // 建设安装工程费(不含设备费) 算法：取固定类别是“建筑安装工程费”的建安费。扣除设备的定额设备费。（全国造价云版中，没有固定的设备购置行，需要扣除所有类别是“设备”的金额，仅指设备行，不包括定额工料机的设备）
    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);
    },
    // 定额建筑安装工程费(含定额设备购置费*40%) 取固定类别是“建筑安装工程费”的定额建安费，扣除定额设备购置费*60%的定额设备费。
    DEJZAZGCFSBSS(tender) {
      let baseFee = this["DEJZAZGCF"](tender);
      const fixedNode = projectObj.project.mainTree.roots.find((node) => node.getFlag() === fixedFlag.CONSTRUCTION_INSTALL_FEE);
      const equipmentFee = cbTools.getEquipmentFee(fixedNode, tender, "equipment");
      baseFee = (baseFee - equipmentFee * 0.6).toDecimal(decimalObj.process);
      return baseFee.toDecimal(decimalObj.bills.totalPrice);
    },
    // 定额建筑安装工程费(不含定额设备购置费、专项费用) 算法：取固定类别是“建筑安装工程费”的定额建安费，扣除定额设备购置费和专项费用的建安费
    DEJZAZGCFBHSBZX(tender) {
      let baseFee = this["DEJZAZGCF"](tender);
      const fixedNode = projectObj.project.mainTree.roots.find((node) => node.getFlag() === fixedFlag.CONSTRUCTION_INSTALL_FEE);
      const equipmentFee = cbTools.getEquipmentFee(fixedNode, tender, "equipment");
      const specialFee = cbTools.getBaseFee(fixedFlag.SPECIAL_COST, tender, "rationCommon");
      const diffFee = (equipmentFee + specialFee).toDecimal(decimalObj.process);
      baseFee = (baseFee - diffFee).toDecimal(decimalObj.process);
      return baseFee.toDecimal(decimalObj.bills.totalPrice);
    },
    // 施工场地建设费 算法：按“定额建筑安装工程费”扣除专项费为基数，以累进办法计算
    // 【变更】：按【固定类别是“建筑安装工程费”的“定额建安费”，扣除固定类别是“专项费用”的“定额建安费”，扣除“设备”的“定额设备费”*60%】为基数，以累进办法计算
    SGCDJSF(tender) {
      let baseFee = this["DEJZAZGCF"](tender);
      const specialFee = cbTools.getBaseFee(fixedFlag.SPECIAL_COST, tender, "rationCommon");
      baseFee = (baseFee - specialFee).toDecimal(decimalObj.process);
      const fixedNode = projectObj.project.mainTree.roots.find((node) => node.getFlag() === fixedFlag.CONSTRUCTION_INSTALL_FEE);
      const equipmentFee = cbTools.getEquipmentFee(fixedNode, tender, "equipment");
      baseFee = (baseFee - equipmentFee * 0.6).toDecimal(decimalObj.process);
      if (!tender) {
        calcBase.baseProgressiveFee = baseFee;
      }
      return calculateUtil.getProgressiveFee(
        baseFee,
        "施工场地建设费",
        projectObj.project.property.progressiveInterval,
        decimalObj.bills.totalPrice,
        deficiency
      );
    },
    // 建设单位(业主)管理费 算法：按“定额建筑安装工程费”总和为基数，以累进办法计算
    // 【变更】：算法：按【固定类别是“建筑安装工程费”的“定额建安费”，扣除“设备”的“定额设备费”*60%】为基数，以累进办法计算。
    JSDWYZGLF(tender) {
      let baseFee = this["DEJZAZGCF"](tender);
      const fixedNode = projectObj.project.mainTree.roots.find((node) => node.getFlag() === fixedFlag.CONSTRUCTION_INSTALL_FEE);
      const equipmentFee = cbTools.getEquipmentFee(fixedNode, tender, "equipment");
      baseFee = (baseFee - equipmentFee * 0.6).toDecimal(decimalObj.process);
      if (!tender) {
        calcBase.baseProgressiveFee = baseFee;
      }
      return calculateUtil.getProgressiveFee(
        baseFee,
        "建设单位(业主)管理费",
        projectObj.project.property.progressiveInterval,
        decimalObj.bills.totalPrice,
        deficiency
      );
    },
    // 建设项目信息化费 算法：按“定额建筑安装工程费”总和为基数，以累进办法计算
    // 【变更】：算法：按【固定类别是“建筑安装工程费”的“定额建安费”，扣除“设备”的“定额设备费”*60%】为基数，以累进办法计算。
    JSXMXXHF(tender) {
      let baseFee = this["DEJZAZGCF"](tender);
      const fixedNode = projectObj.project.mainTree.roots.find((node) => node.getFlag() === fixedFlag.CONSTRUCTION_INSTALL_FEE);
      const equipmentFee = cbTools.getEquipmentFee(fixedNode, tender, "equipment");
      baseFee = (baseFee - equipmentFee * 0.6).toDecimal(decimalObj.process);
      if (!tender) {
        calcBase.baseProgressiveFee = baseFee;
      }
      return calculateUtil.getProgressiveFee(
        baseFee,
        "建设项目信息化费",
        projectObj.project.property.progressiveInterval,
        decimalObj.bills.totalPrice,
        deficiency
      );
    },
    // 工程监理费 算法：按“定额建筑安装工程费”总和为基数，以累进办法计算
    // 【变更】：算法：按【固定类别是“建筑安装工程费”的“定额建安费”，扣除“设备”的“定额设备费”*60%】为基数，以累进办法计算。
    GCJLF(tender) {
      let baseFee = this["DEJZAZGCF"](tender);
      const fixedNode = projectObj.project.mainTree.roots.find((node) => node.getFlag() === fixedFlag.CONSTRUCTION_INSTALL_FEE);
      const equipmentFee = cbTools.getEquipmentFee(fixedNode, tender, "equipment");
      baseFee = (baseFee - equipmentFee * 0.6).toDecimal(decimalObj.process);
      if (!tender) {
        calcBase.baseProgressiveFee = baseFee;
      }
      return calculateUtil.getProgressiveFee(baseFee, "工程监理费", projectObj.project.property.progressiveInterval, decimalObj.bills.totalPrice, deficiency);
    },
    // 设计文件审查费 算法：按“定额建筑安装工程费”总和为基数，以累进办法计算
    // 【变更】：算法：按【固定类别是“建筑安装工程费”的“定额建安费”，扣除“设备”的“定额设备费”*60%】为基数，以累进办法计算。
    SJWJSCF(tender) {
      let baseFee = this["DEJZAZGCF"](tender);
      const fixedNode = projectObj.project.mainTree.roots.find((node) => node.getFlag() === fixedFlag.CONSTRUCTION_INSTALL_FEE);
      const equipmentFee = cbTools.getEquipmentFee(fixedNode, tender, "equipment");
      baseFee = (baseFee - equipmentFee * 0.6).toDecimal(decimalObj.process);
      if (!tender) {
        calcBase.baseProgressiveFee = baseFee;
      }
      return calculateUtil.getProgressiveFee(
        baseFee,
        "设计文件审查费",
        projectObj.project.property.progressiveInterval,
        decimalObj.bills.totalPrice,
        deficiency
      );
    },
    // 前期工作费 算法：按“定额建筑安装工程费”总和为基数，以累进办法计算
    // 变更：【算法】：按【固定类别是“建筑安装工程费”的“定额建安费”，扣除“设备”的“定额设备费”*60%】为基数，以累进办法计算。
    QQGZF(tender) {
      let baseFee = this["DEJZAZGCF"](tender);
      const fixedNode = projectObj.project.mainTree.roots.find((node) => node.getFlag() === fixedFlag.CONSTRUCTION_INSTALL_FEE);
      const equipmentFee = cbTools.getEquipmentFee(fixedNode, tender, "equipment");
      baseFee = (baseFee - equipmentFee * 0.6).toDecimal(decimalObj.process);
      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章的清单使用，所以暂时不需要此判断)
    YBZYHQDHJ: 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);
    },
    // 清单项目基数：{定额建筑安装工程费} 算法：取清单固定类别是“第100章至700章清单”的定额建安费(其中定额设备费按40%计算，税金是全额计算。公路云默认要使用此算法)。
    // 显示：只有清单固定类别是“第100章清单总则”的部分可显示。
    DEJZAZGCF(tender) {
      const baseFee = cbTools.getBaseFee(fixedFlag.ONE_SEVEN_BILLS, tender, "rationCommon");
      const fixedNode = projectObj.project.mainTree.roots.find((node) => node.getFlag() === fixedFlag.ONE_SEVEN_BILLS);
      const equipmentFee = cbTools.getEquipmentFee(fixedNode, tender, "equipment");
      return (baseFee - equipmentFee * 0.6).toDecimal(decimalObj.bills.totalPrice);
    },
  };
}

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

  projectObj.getSaveProductionCostCode = function () {
    //公路云里18的清单范本安全生产费是102-3的；养护云里浙江养护的安全生产费是102-4。
    return "102-3";
  };
}

if (typeof module !== "undefined" && !module.nodeType) {
  module.exports = {
    progression,
    deficiency,
  };
}
