const system = require("../../../system");
const ServiceBase = require("../../sve.base")
const settings = require("../../../../config/settings")
class InvoiceService extends ServiceBase {
  constructor() {
    super("invoice", ServiceBase.getDaoName(InvoiceService));

    // this.merchantDao = system.getObject("db.merchant.merchantDao");
    // this.merchantsignedDao = system.getObject("db.merchant.merchantsignedDao");
    // this.merchantaccountDao = system.getObject("db.merchant.merchantaccountDao");
    // this.businessmenDao = system.getObject("db.order.businessmenDao");

    // this.merchanttradeDao = system.getObject("db.merchant.merchanttradeDao");
    // this.merchanttradeprocessDao = system.getObject("db.merchant.merchanttradeprocessDao");

    // this.restClient = system.getObject("util.restClient");
    // this.pushUtils = system.getObject("util.businessManager.pushUtils")
  }

  async apiCalcInvoice(pobj) {
    var merchantId = pobj.merchant_id;
    var signInfo = await this.merchantsignedDao.findOne({
      merchant_id: merchantId
    });
    var list = pobj.invoiceList;
    if(list.length > 10) {
      return system.getResult(null, "一次试算请求不能超过10条记录");
    }

    var result = {};
    for(var item of list) {
      var invoice = {
        merchantId: merchantId,
        businessmenCreditCode: item.businessmenCreditCode,
        invoiceAmt: item.invoiceAmt,
        invoiceTime: item.invoiceTime,
        type: item.type,
      };
      try {
        var rs = await this.calcInvoice(merchantId, invoice, signInfo);
        result[item.businessmenCreditCode] = {
          code : rs.code,
          msg: rs.msg || "",
          incomeTax: rs.incomeTax || 0,
          addedValueTax: rs.addedValueTax || 0,
          specialTax: rs.specialTax || 0,
          serviceTax: rs.serviceTax || 0,
          warning: rs.warning || "",
          monthAmt: rs.monthAmt || 0,
        }
      } catch (error) {
        result[item.businessmenCreditCode] = {
          code : 0,
          msg: "试算服务异常",
          incomeTax: 0,
          addedValueTax: 0,
          specialTax: 0,
          serviceTax: 0,
          warning: "",
          monthAmt: 0,
        }
      }
    }
    return system.getResultSuccess(result);
  }

  async apiSaveInvoice(pobj) {
    var merchantId = pobj.merchant_id;
    var signInfo = await this.merchantsignedDao.findOne({
      merchant_id: merchantId
    });
    var list = pobj.invoiceList;
    if(list.length > 10) {
      return system.getResult(null, "一次发票提交不能超过10条记录");
    }

    var merchant = await this.merchantDao.findById(merchantId);
    var result = {};
    for(var item of list) {
      var repeat = await this.dao.findOne({merchant_id: merchantId, applyNo: item.applyNo});
      if(repeat) {
        result[item.businessmenCreditCode] = {
          code: 0,
          msg: "发票【" + item.applyNo + "】申请号重复",
        }
        continue;
      }
      var invoice = {
        merchant_id: merchantId,
        applyNo: item.applyNo,
        businessmenCreditCode: item.businessmenCreditCode,
        invoiceAmt: item.invoiceAmt,
        invoiceTime: item.invoiceTime,
        type: item.type,
        settleImg: item.settleImg,

        merchantName: merchant.name,
        merchantTaxNo: merchant.taxNo,
        merchantInvoiceAddr: merchant.invoiceAddr,
        merchantInvoiceMobile: merchant.invoiceMobile,
        merchantAccountName: merchant.accountName,
        merchantAccountPublic: merchant.accountPublic,
      };

      try {
        var rs = await this.saveInvoice(invoice, signInfo);
        result[item.businessmenCreditCode] = {
          code: rs.code,
          msg: rs.msg || "",
        }
      } catch (error) {
        console.log(error.stack);
        var message = error.message || "";
        var msg;
        if(message == "1001") {
          msg = "账户余额不足";
        }

        if(message == "Validation error") {
          msg = "发票申请号" + item.applyNo + "】重复";
        }
        result[item.businessmenCreditCode] = {
          code: 0,
          msg: msg || "服务异常",
        }
      }
    }
    return system.getResultSuccess(result);
  }

  async apiCancelInvoice(pobj) {
    try {
      var rs = await this.cancel(pobj.merchant_id, pobj.applyNo);
      if(rs.code == 1) {
        return system.getResultSuccess("success");
      }
      return system.getResult(null, rs.msg);
    } catch (error) {
      console.log(error.stack);
      return system.getResult(null, error.message == "1001" ? "账户解冻余额不足" : "服务错误");
    }
  }

  async testInvoiceAudit(pobj) {
    var invoice = await this.dao.findOne({merchant_id: pobj.merchant_id, applyNo: pobj.applyNo});
    var rs = await this.audit(invoice.id, pobj.isPass, pobj.remark);
    return system.getResultSuccess(rs);
  }

  async testKaipiao(pobj) {
    var invoice = await this.dao.findOne({merchant_id: pobj.merchant_id, applyNo: pobj.applyNo});
    var info = {
      id: invoice.id,
      invoiceNo: pobj.invoiceNo,
      invoiceTime: pobj.invoiceTime,
      invoiceImg: pobj.invoiceImg,
      payVoucher: pobj.payVoucher,

      isServiceTax: pobj.isServiceTax,
      isInomeTaX: pobj.isInomeTaX,
      isAddedValueTax: pobj.isAddedValueTax,
      isSpecialTax: pobj.isSpecialTax,
    }
    var rs = await this.kaipiao(info);
    return system.getResultSuccess(rs);
  }


  // 发票费用计算
  async calcInvoice(merchantId, invoice, signInfo) {
    var result = {
      code: 1,
      creditCode: invoice.businessmenCreditCode,
      msg: "success"
    };
    // 查询商户签约信息
    if (!signInfo) {
      signInfo = await this.merchantsignedDao.findOne({
        merchant_id: merchantId
      });
    }

    if (!signInfo) {
      result.code = 1;
      result.msg = "商户未签约";
      return result;
    }
    // 发票信息
    var invoiceType = invoice.type || 0; // 0专票 1普票
    var invoiceAmt = Number(invoice.invoiceAmt); // 开票金额分
    var invoiceTime = invoice.invoiceTime; // 开票时间
    var creditCode = invoice.businessmenCreditCode; // 社会统一信用代码

    // 服务费率
    var serviceRate = Number(signInfo.serviceRate || 0);
    var serviceTax = Number((invoiceAmt * serviceRate) / 100).toFixed(0) || 0;

    // 查询账户信息
    var account = await this.merchantaccountDao.findOne({
      channel_id: 0,
      merchant_id: merchantId,
    });
    result.accountId = account.id;

    if (account.available_amt < serviceTax) {
      result.code = 0;
      result.msg = "账户余额不足，请充值";
      return result;
    }

    // 验证发票
    var invoiceList = await this.dao.findMonthAmtByCreditCode(creditCode, invoice.invoiceTime, ['00']);
    if(invoiceList.length > 0) {
      result.code = 0;
      result.msg = "该商户发票编号【" + invoiceList[0].applyNo + "】正在申请中，请等待审核通过或者撤回才能再次申请";
      return result;
    }

    // 获取个体工商户信息
    var businessmen = await this.businessmenDao.findOne({
      creditCode: creditCode
    });
    // 查询个体户签约信息
    if (!businessmen) {
      result.code = 0;
      result.msg = "个体工商户不存在，请检查该商户的统一社会信用代码【" + creditCode + "】";
      return result;
    }
    result.businessmen = businessmen;

    // 计算当前个体工商户月开票总金额
    var totalAmt = Number(await this.dao.findAllAmtByCreditCode(creditCode, invoiceTime) || 0);

    // 未开户的，不计算，不扣款
    if (businessmen.isBank) {
      result.msg = "success";
      result.incomeTax = 0;
      result.addedValueTax = 0;
      result.specialTax = 0;
      result.serviceTax = serviceTax;
      return result;
    }

    if (totalAmt + invoiceAmt >= 500000000) {
      result.code = 0;
      result.msg = "本年度开票金额不允许超过500万";
      return result;
    }
    if (totalAmt + invoiceAmt >= 420000000) {
      result.warning = "年度总开票金额已达到" + system.f2y(totalAmt + invoiceAmt);
    }

    // 00开票申请 10已撤回 20审核驳回 30审核通过 40已开票 50已邮寄 60完税证明
    var monthList = await this.dao.findMonthAmtByCreditCode(creditCode, invoiceTime, ['00', '30', '40', '50', '60']);

    // 计算当月个税、增值税、附加税 累计金额
    var monthIcomeTax = 0;
    var monthAddedValueTax = 0;
    var monthSpecialTax = 0;
    var monthAmt = 0;

    for (var item of monthList) {
      monthAmt = monthAmt + Number(item.invoiceAmt);
      monthIcomeTax = monthIcomeTax + Number(item.incomeTax);
      monthAddedValueTax = monthAddedValueTax + Number(item.addedValueTax);
      monthSpecialTax = monthSpecialTax + Number(item.specialTax);
    }

    // 计算当前个税
    var taxLadder;
    var otherLadder;

    // 当前开票额 + 本月开票额
    var amt = invoiceAmt + monthAmt;

    if (invoiceType == '00') {
      taxLadder = this.getAmtLadder(invoiceAmt, JSON.parse(businessmen.commonTaxLadder));
      otherLadder = this.getAmtLadder(invoiceAmt, JSON.parse(businessmen.commonOtherLadder));
    } else {
      taxLadder = this.getAmtLadder(invoiceAmt, JSON.parse(businessmen.specialTaxLadder));
      otherLadder = this.getAmtLadder(invoiceAmt, JSON.parse(businessmen.specialOtherLadder));
    }

    var incomeRate = Number(taxLadder.rate || 0) / 100; // 个税税率
    var zengzhiRate = Number(otherLadder.zengzhiRate || 0) / 100; // 着呢格式税税率
    var fujiaRate = Number(otherLadder.fujiaRate || 0) / 100; // 附加税税率

    var xadd = 1 + zengzhiRate; // 1 + 增值税

    // 计算个税 ((当前开票额 + 本月开票额) * 个税 / (1 + 增值税)) - 本月个税总额
    result.incomeTax = ((amt * incomeRate / xadd) - monthIcomeTax).toFixed(0);
    // 计算增值税 ((当前开票额 + 本月开票额) * 增值税 / (1 + 增值税)) - 本月个税总额
    result.addedValueTax = ((amt * zengzhiRate / xadd) - monthAddedValueTax).toFixed(0);
    // 计算附加税
    result.specialTax = Number(result.addedValueTax * fujiaRate).toFixed(0);

    // 计算服务费
    result.serviceTax = Number((invoiceAmt * serviceRate) / 100).toFixed(0);
    // 本月已申请的开票金额
    result.monthAmt = monthAmt;

    // 验证账户金额是否可使用
    var totalfee = Number(result.incomeTax) + Number(result.addedValueTax) + Number(result.specialTax) + Number(result.serviceTax);
    if (totalfee > account.available_amt) {
      result.code = 0;
      result.msg = "账户余额不足，请充值";
      return result;
    }
    return result;
  }

  async saveInvoice(invoice, signInfo) {
    var result = {code: 1}
    if(!signInfo) {
      signInfo = await this.merchantsignedDao.findOne({
        merchant_id: invoice.merchant_id
      });
    }

    if (!signInfo) {
      result.code = 0;
      result.msg = "商户未签约";
      return result;
    }

    // 计算税费
    var taxResult = await this.calcInvoice(invoice.merchant_id, invoice, signInfo);
    if (taxResult.code === 0) {
      return taxResult;
    }

    // 试算费用
    invoice.tryIncomeTax = Number(taxResult.incomeTax || 0);
    invoice.tryAddedValueTax = Number(taxResult.addedValueTax || 0);
    invoice.tryServiceTax = Number(taxResult.serviceTax || 0);
    invoice.trySpecialTax = Number(taxResult.specialTax || 0);
    invoice.tryMonthAmt = Number(taxResult.monthAmt || 0);

    // 实际费用，因为试算时，都使用实际费用字段，所以这里先赋值，再审核时，再次计算再次赋值
    invoice.incomeTax = Number(taxResult.incomeTax || 0);
    invoice.addedValueTax = Number(taxResult.addedValueTax || 0);
    invoice.serviceTax = Number(taxResult.serviceTax || 0);
    invoice.specialTax = Number(taxResult.specialTax || 0);
    invoice.monthAmt = Number(taxResult.monthAmt || 0);

    invoice.businessmenName = taxResult.businessmen.name;
    invoice.businessmenCreditCode = taxResult.businessmen.creditCode;
    invoice.businessmenIsBank = taxResult.businessmen.isBank;
    invoice.businessmen_id = taxResult.businessmen.id;

    var accountId = taxResult.accountId;
    var totalfee = invoice.incomeTax + invoice.addedValueTax + invoice.serviceTax + invoice.specialTax;

    // 发票事务处理
    var self = this;
    var data = await self.db.transaction(async function (t) {
      // 创建发票
      invoice = await self.dao.create(invoice, t);

      // 冻结金额   TODO 测试事务回滚
      var rows = await self.merchantaccountDao.frozenAmt(accountId, totalfee, t);
      if (rows.length < 2 || rows[1] == 0) {
        // 账户余额不足
        throw new Error(1001);
      }
      // 查询账户额度
      var account = await self.merchantaccountDao.findOne({
        channel_id: 0,
        merchant_id: invoice.merchant_id,
      });
      var availableAmt = account.available_amt || 0;
      var frozen_amt = account.frozen_amt || 0;

      // 服务费冻结
      await self.doFrozenItem({
        invoice: invoice,
        accountId: accountId,
        amt: invoice.serviceTax,
        amtType: "00",
        busiType: "00",
        frozen: true,
      }, t);

      // 个税流水
      await self.doFrozenItem({
        invoice: invoice,
        accountId: accountId,
        amt: invoice.incomeTax,
        amtType: "10",
        busiType: "00",
        frozen: true,
      }, t);

      // 增值税流水
      await self.doFrozenItem({
        invoice: invoice,
        accountId: accountId,
        amt: invoice.addedValueTax,
        amtType: "20",
        busiType: "00",
        frozen: true,
      }, t);

      // 附加费流水 
      await self.doFrozenItem({
        invoice: invoice,
        accountId: accountId,
        amt: invoice.specialTax,
        amtType: "30",
        busiType: "00",
        frozen: true,
      }, t);
      return invoice;
    });

    result.code = 1;
    result.msg = "success";
    return result;
  }

  // 发票撤回
  async cancel(merchantId, applyNo) {
    var result = {
      code: 1
    };
    var invoice = await this.dao.findOne({
      merchant_id: merchantId,
      applyNo: applyNo
    });

    if (!invoice) {
      result.code = 1;
      result.msg = "发票不存在";
      return result;
    }

    if (invoice.invoiceStatus != '00') {
      var statusName = await this.dao.getInvoiceStatusName(invoice.invoiceStatus);
      result.code = 0;
      result.msg = "当前发票状态为【" + statusName + "】，不允许撤回，如需撤回请联系客户经理。";
      return result;
    }
    // 解冻冻结金额
    await this.unfreeze(invoice, "20", "10", "发票撤回解冻");
    result.msg = "success";
    return result;
  }

  // 发票审核
  async audit(id, isPass, auditRemark) {
    var result = {code: 1};
    var invoice = await this.dao.findById(id);
    if (!invoice) {
      result.code = 0;
      result.msg = "发票不存在";
      return result;
    }
    if (invoice.invoiceStatus != '00') {
      var statusName = await this.dao.getInvoiceStatusName(invoice.invoiceStatus);
      result.code = 0;
      result.msg = "当前发票状态为【" + statusName + "】，不可以审核。";
      return result;
    }

    if (isPass) {
      invoice.invoiceStatus = "30";
      invoice.auditRemark = auditRemark;
      await invoice.save();
    } else {
      // 解冻冻结金额
      await this.unfreeze(invoice, "30", "20", auditRemark);
    }

    // 推送审核信息
    var pushObj = {
      merchant_id: invoice.merchant_id,
      applyNo: invoice.applyNo,
      auditStatus: isPass ? 1 : 0,
      auditRemark: auditRemark,
    }
    this.pushUtils.push(invoice.merchant_id, "fapiaoshenhe", pushObj);

    result.code = 1;
    result.msg = "success";
    return result;
  }

  async kaipiao(info) {
    var result = {code : 1};
    var invoice = await this.dao.findById(info.id);
    if (!invoice) {
      result.code = 0;
      result.msg = "发票不存在";
      return result;
    }
    if (invoice.invoiceStatus != '30') {
      var statusName = await this.dao.getInvoiceStatusName(invoice.invoiceStatus);
      result.code = 0;
      result.msg = "当前发票状态为【" + statusName + "】，不可以开票。";
      return result;
    }

    var processMap = await this.merchanttradeprocessDao.findMapByInvoiceId(invoice.id);
    var account = await this.merchantaccountDao.findOne({
      channel_id: 0,
      merchant_id: invoice.merchant_id,
    });

    var self = this;
    await this.db.transaction(async function (t) {
      var updateParams = {
        invoiceStatus: "40",
        invoiceNo: info.invoiceNo,
        invoiceTime: info.invoiceTime,
        invoiceImg: info.invoiceImg,
        payVoucher: info.payVoucher,
        updated_at: new Date()
      }
      // 审核通过
      await self.dao.model.update(updateParams, {where: {id: invoice.id},transaction: t});
      if (invoice.businessmenIsBank) {
        return;
      }
      if (info.isServiceTax) {
        // 扣除服务费
        await self.cutpayment(account, invoice, processMap["00"], "00", t);
      }
      if (info.isInomeTaX) {
        // 扣除个税
        await self.cutpayment(account, invoice, processMap["10"], "10", t);
      }
      if (info.isAddedValueTax) {
        // 扣除增值税
        await self.cutpayment(account, invoice, processMap["20"], "20", t);
      }
      if (info.isSpecialTax) {
        // 扣除附加费
        await self.cutpayment(account, invoice, processMap["30"], "30", t);
      }
    });
    
    // 推送开票信息 TODO
    invoice = await this.dao.findById(info.id);
    var pushObj = {
      merchant_id: invoice.merchant_id,
      applyNo: invoice.applyNo,
      invoiceNo: info.invoiceNo,
      invoiceTime: info.invoiceTime,
      invoiceImg: info.invoiceImg,
      payVoucher: info.payVoucher,
    }
    this.pushUtils.push(invoice.merchant_id, "fapiaoshenhe", pushObj);
  }

  async toEmail(id, courierNo, courierImg) {
    var invoice = await this.dao.findById(info.id);
    if (!invoice) {
      result.code = 1;
      result.msg = "发票不存在";
      return result;
    }
    if (invoice.invoiceStatus != '40') {
      var statusName = await this.dao.getInvoiceStatusName(invoice.invoiceStatus);
      result.code = 1;
      result.msg = "当前发票状态为【" + statusName + "】，不可以创建邮寄进度。";
      return result;
    }
    invoice.courierNo = courierNo;
    invoice.courierImg = courierImg;
    invoice.invoiceStatus = "50";

    await invoice.save();

    // TODO 推送邮寄信息
    invoice = await this.dao.findById(info.id);

    var params = {
      merchant_id : invoice.merchant_id,//  商户id 
      courierNo: courierNo,     // 快递单号
      courierImg: courierImg,   //  快递交接单图片 
    }
    this.pushUtils.push(invoice.merchant_id, "fapiaoshenhe", params);
  }

  async taxCertificate(info) {
    // taxNo: DataTypes.STRING(64),
    // taxTime: DataTypes.DATE,
    // taxVoucher: DataTypes.STRING(300),

    if (!invoice) {
      result.code = 1;
      result.msg = "发票不存在";
      return result;
    }
    if (invoice.invoiceStatus != '50') {
      var statusName = await this.dao.getInvoiceStatusName(invoice.invoiceStatus);
      result.code = 1;
      result.msg = "当前发票状态为【" + statusName + "】，不可以创建完税证明。";
      return result;
    }

    var processMap = await this.merchanttradeprocessDao.findMapByInvoiceId(invoiceId);
    var account = await this.merchantaccountDao.findOne({
      channel_id: 0,
      merchant_id: merchantId,
    });

    await this.db.transaction(async function (t) {
      var updateParams = {
        invoiceStatus: "50",
        taxNo: info.taxNo,
        taxTime: info.taxTime,
        taxVoucher: info.taxVoucher,
        updated_at: new Date()
      }
      // 审核通过
      await self.dao.model.update(updateParams, {where: {id: invoice.id},transaction: t});
      if (invoice.businessmenIsBank) {
        return;
      }
      if (info.isServiceTax) {
        // 扣除服务费
        await self.cutpayment(account, invoice, processMap["00"], "00", t);
      }
      if (info.isInomeTaX) {
        // 扣除个税
        await self.cutpayment(account, invoice, processMap["10"], "10", t);
      }
      if (info.isAddedValueTax) {
        // 扣除增值税
        await self.cutpayment(account, invoice, processMap["20"], "20", t);
      }
      if (info.isSpecialTax) {
        // 扣除附加费
        await self.cutpayment(account, invoice, processMap["30"], "30", t);
      }
      // 这里可以检查一下，当前发票冻结流水全部解冻
      var list = await self.merchanttradeprocessDao.findUnComplete(invoice.id);
      for(var item of list) {
        if(item.amt == 0) {
          await self.cutpayment(account, invoice, [item], item.amtType, t);
        } else {
          throw new Error(1002);
        }
      }
    });
  }

  // 解冻扣款操作
  async cutpayment(account, invoice, processList, amtType, t) {
    for(var item of processList) {
      if(!item.complete && (item.busiType == '00')) {
        // 账户解冻扣款
        var rows = await this.merchantaccountDao.cutpayment(account.id, item.amt, t);
        if(rows == 0) {
          throw new Error(1001);
        }
        // 解冻扣款流水
        var unfreezeObj = {
          merchant_id: item.merchant_id,
          invoice_id: item.invoice_id,
          amt: item.amt,
          busiType: "10",
          amtType: amtType,
        };
        await this.merchanttradeprocessDao.create(unfreezeObj, t);
        await this.merchanttradeprocessDao.model.update({complete: true}, {where: {id: item.id},transaction: t});
      }
    }
  }

  async doAuditPass(invoice, auditRemark) {
    // 计算税费
    var taxResult = await this.calcInvoice(invoice.merchant_id, invoice);
    var processMap = await this.merchanttradeprocessDao.findMapByInvoiceId(invoiceId);

    // 服务费
    var serviceTax = self.cloneProcessObj(processMap, "00", busiType);
    // 个税
    var incomeTax = self.cloneProcessObj(processMap, "10", busiType);
    // 增值费
    var addedValueTax = self.cloneProcessObj(processMap, "20", busiType);
    // 附加费
    var specialTax = self.cloneProcessObj(processMap, "30", busiType);

    // 计算费用差
    var serviceTaxDiff = Number(taxResult.serviceTax || 0) - Number(serviceTax.amt);
    var incomeTaxDiff = Number(taxResult.incomeTax || 0) - Number(incomeTax.amt);
    var addedValueTaxDiff = Number(taxResult.addedValueTax || 0) - Number(addedValueTax.amt);
    var specialTax = Number(taxResult.specialTax || 0) - Number(specialTax.amt);
    var account = await this.merchantaccountDao.findOne({
      channel_id: 0,
      merchant_id: merchantId,
    });

    var self = this;
    await this.db.transaction(async function (t) {
      // 审核通过
      await self.dao.model.update({
        invoiceStatus: "30",
        updated_at: new Date(),
        auditRemark: auditRemark || ""
      }, {
        where: {
          id: invoice.id
        },
        transaction: t
      });

      if (invoice.businessmenIsBank) {
        return;
      }
      var rows = 0;
      if (serviceTaxDiff != 0) {
        await self.doProcessItem({
          invoice: invoice,
          amt: serviceTaxDiff,
          amtType: "00",
          busiType: serviceTaxDiff > 0 ? "40" : "50",
        }, t);
      }

      if (incomeTaxDiff != 0) {
        await self.doProcessItem({
          invoice: invoice,
          amt: incomeTaxDiff,
          amtType: "10",
          busiType: incomeTaxDiff > 0 ? "40" : "50",
        }, t);
      }

      if (addedValueTax != 0) {
        await self.doProcessItem({
          invoice: invoice,
          amt: addedValueTax,
          amtType: "20",
          busiType: addedValueTax > 0 ? "40" : "50",
        }, t);

      }

      if (specialTax != 0) {
        await self.doProcessItem({
          invoice: invoice,
          amt: specialTax,
          amtType: "30",
          busiType: specialTax > 0 ? "40" : "50",
        }, t);
      }
    });
  }

  // 处理冻结、解冻流水
  async doFrozenItem(params, t) {
    var invoice = params.invoice;
    var amt = params.amt;
    var accountId = params.accountId;
    var amtType = params.amtType;
    var busiType = params.busiType;
    var frozen = params.frozen;
    if (amt > 0) {
      var rows ;
      if(frozen) {
        rows = await this.merchantaccountDao.frozenAmt(accountId, amt, t);
      } else {
        rows = await this.merchantaccountDao.unFrozenAmt(accountId, amt, t);
      }
      if (rows.length < 2 || rows[1] == 0) {
        // 账户余额不足
        throw new Error(1001);
      }
    }
    var account = await this.merchantaccountDao.findOne({id: accountId}, t);
    // 个税
    await this.merchanttradeprocessDao.create({
      merchant_id: invoice.merchant_id,
      invoice_id: invoice.id,
      amt: amt,
      available_amt: account.available_amt,
      frozen_amt: account.frozen_amt,
      busiType: busiType,
      amtType: amtType,
    }, t);
  }

  // 解冻退款
  async unfreeze(invoice, busiType, invoiceStatus, remark) {
    var processMap = await this.merchanttradeprocessDao.findMapByInvoiceId(invoice.id);

    // 查询账户信息
    var account = await this.merchantaccountDao.findOne({
      channel_id: 0,
      merchant_id: invoice.merchant_id,
    });

    var self = this;
    // 撤回冻结金额
    await this.db.transaction(async function (t) {
      if(!invoice.businessmenIsBank) {
        // 服务费
        var serviceTax = self.cloneProcessObj(processMap, "00", busiType);
        // 解冻
        await self.doFrozenItem({
          invoice: invoice,
          accountId: account.id,
          amt: serviceTax.amt,
          amtType: "00",
          busiType: "20",
          frozen: false,
        }, t);

        // 个税
        var incomeTax = self.cloneProcessObj(processMap, "10", busiType);
        // 解冻
        await self.doFrozenItem({
          invoice: invoice,
          accountId: account.id,
          amt: incomeTax.amt,
          amtType: "10",
          busiType: "20",
          frozen: false,
        }, t);

        // 增值费
        var addedValueTax = self.cloneProcessObj(processMap, "20", busiType);
        // 解冻
        await self.doFrozenItem({
          invoice: invoice,
          accountId: account.id,
          amt: addedValueTax.amt,
          amtType: "20",
          busiType: "20",
          frozen: false,
        }, t);

        // 附加费
        var specialTax = self.cloneProcessObj(processMap, "30", busiType);
        // 解冻
        await self.doFrozenItem({
          invoice: invoice,
          accountId: account.id,
          amt: addedValueTax.amt,
          amtType: "30",
          busiType: "20",
          frozen: false,
        }, t);
      }

      // 发票状态修改
      await self.dao.model.update({invoiceStatus: invoiceStatus, updated_at:new Date(), auditRemark: (remark || "")}, {where:{id:invoice.id}, transaction:t});
    });
  }

  cloneProcessObj(processMap, amtType, busiType) {
    var list = processMap[amtType];
    // 判断解冻扣款
    if (list.length > 1) {
      // 服务费冻结已被处理，不可撤回发票
      throw new Error(amtType);
    }
    var item = list[0];
    return {
      merchant_id: item.merchant_id,
      invoice_id: item.invoice_id,
      amt: item.amt,
      busiType: busiType,
      amtType: amtType,
    };
  }

  getAmtLadder(amt, ladders) {
    if (!ladders) {
      return {};
    }

    for (var ladder of ladders) {
      var min = Number(ladder.minValue);
      var max = Number(ladder.maxValue);
      if (amt >= min && amt < max) {
        return ladder;
      }
    }
    return {};
  }
}
  module.exports = InvoiceService;
  // var task=new UserService();
  // task.getUserStatisticGroupByApp().then(function(result){
  //   console.log((result));
  // }).catch(function(e){
  //   console.log(e);
  // });