const ServiceBase = require("../../sve.base");
const system = require("../../../system");
const moment = require('moment')
/**
 * 交付商 提交的信息
 */
class IInvoiceService extends ServiceBase {
  constructor() {
    super("invoice", ServiceBase.getDaoName(IInvoiceService));
    let is = system.getObject("util.invoiceStatus");
    this.invoiceStatus = is.status;

    this.iinvoicesummaryinfoDao = system.getObject("db.invoice.iinvoicesummaryinfoDao");
    this.iinvoiceprocessDao = system.getObject("db.invoice.iinvoiceprocessDao");
    this.iinvoiceinforegDao = system.getObject("db.invoice.iinvoiceinforegDao");
    this.iinvoicedeliverDao = system.getObject("db.invoice.iinvoicedeliverDao");
    this.RULE_INVOICE_TYPE = ["10", '20', '30']; //发票类型
    this.RULE_BUSINESSMEN_TYPE = ['10', '20']; //销售方类型
    this.DEFAULT_PRODUCT_ID = "50020000"; //默认产品ID
    this.iproductDao = system.getObject("db.product.iproductDao");
    this.iprocessDao = system.getObject("db.product.iprocessDao");
    this.iproductprocessDao = system.getObject("db.product.iproductprocessDao");
  }

  /**
   * 发票申请
   * @param {*} params 
   */
  async invoiceApply(params) {
    if (!params.channel_id) {
      return system.getResult(null, `渠道ID不能为空`);
    }
    if (!params.apply_no) {
      return system.getResult(null, `发票申请编号不能为空`);
    }
    try {
      let invoiceExists = await this.dao.findByChannelAndApplyNo(this.trim(params.channel_id), this.trim(params.apply_no));
      if (invoiceExists.total != 0) {
        return system.getResult(null, `发票编号[${params.apply_no}]已存在`);
      }
    } catch (error) {
      console.log(error);
      return system.getResult(null, `系统错误 ${error}`);
    }

    if (this.RULE_INVOICE_TYPE.indexOf(this.trim(params.invoice_type)) == -1) {
      return system.getResult(null, `发票类型不存在`);
    }
    // if(!params.apply_time){
    //   return system.getResult(null,`发票申请时间错误`);
    // }
    // if (!params.invoice_content) {
    //   return system.getResult(null, `开票内容不能为空`);
    // }
    // if(!params.contract){
    //   return system.getResult(null,`合同不能为空`);
    // }

    let _invoice = {};
    _invoice.channel_id = this.trim(params.channel_id);
    _invoice.apply_no = this.trim(params.apply_no);
    _invoice.invoice_type = this.trim(params.invoice_type);
    _invoice.apply_time = this.trim(params.apply_time) || new Date();
    _invoice.invoice_amount = this.trim(params.invoice_amount) || 0;
    _invoice.invoice_content = this.trim(params.invoice_content) || "服务费";
    _invoice.contract = this.trim(params.contract) || "";
    _invoice.personal_invoice_tax = this.trim(params.personal_invoice_tax) || 0;
    _invoice.additional_tax = this.trim(params.additional_tax) || 0;
    _invoice.value_added_tax = this.trim(params.value_added_tax) || 0;
    _invoice.product_id = params.product_id || this.DEFAULT_PRODUCT_ID;
    if (!params.merchant_name) {
      return system.getResult(null, `购买方名称不能为空`);
    }
    if (!params.merchant_credit_code) {
      return system.getResult(null, `购买方社会统一信用代码不能为空`);
    }
    if (!params.merchant_addr) {
      return system.getResult(null, `购买方地址不能为空`);
    }
    if (!params.merchant_mobile) {
      return system.getResult(null, `购买方电话不能为空`);
    }
    if (!params.merchant_bank) {
      return system.getResult(null, `购买方开户行不能为空`);
    }
    if (!params.merchant_account) {
      return system.getResult(null, `购买方对公账户不能为空`);
    }
    _invoice.merchant_id = this.trim(params.merchant_id);
    _invoice.merchant_name = this.trim(params.merchant_name);
    _invoice.merchant_credit_code = this.trim(params.merchant_credit_code);
    _invoice.merchant_addr = this.trim(params.merchant_addr);
    _invoice.merchant_mobile = this.trim(params.merchant_mobile);
    _invoice.merchant_bank = this.trim(params.merchant_bank);
    _invoice.merchant_account = this.trim(params.merchant_account);

    if (!params.businessmen_name) {
      return system.getResult(null, `销售方名称不能为空`);
    }
    if (!params.businessmen_credit_code) {
      return system.getResult(null, `销售方社会统一信用代码不能为空`);
    }
    if (!params.businessmen_addr) {
      return system.getResult(null, `销售方地址不能为空`);
    }
    if (!params.businessmen_mobile) {
      return system.getResult(null, `销售方电话不能为空`);
    }
    // if (!params.businessmen_bank) {
    //   return system.getResult(null, `销售方开户行不能为空`);
    // }
    // if (!params.businessmen_account) {
    //   return system.getResult(null, `销售方对公账户不能为空`);
    // }
    if (this.RULE_BUSINESSMEN_TYPE.indexOf(this.trim(params.businessmen_type)) == -1) {
      return system.getResult(null, `销售方类型错误`);
    }
    _invoice.businessmen_type = this.trim(params.businessmen_type);
    _invoice.businessmen_id = this.trim(params.businessmen_id);
    _invoice.businessmen_credit_code = this.trim(params.businessmen_credit_code) || 0;
    _invoice.businessmen_name = this.trim(params.businessmen_name);
    _invoice.businessmen_addr = this.trim(params.businessmen_addr);
    _invoice.businessmen_mobile = this.trim(params.businessmen_mobile);
    _invoice.businessmen_bank = this.trim(params.businessmen_bank);
    _invoice.businessmen_account = this.trim(params.businessmen_account);

    _invoice.mail_to = this.trim(params.mail_to) || "";
    _invoice.mail_mobile = this.trim(params.mail_mobile) || "";
    _invoice.mail_addr = this.trim(params.mail_addr) || "";
    _invoice.saas_deliver_api = this.trim(params.saas_deliver_api) || "";

    try {

      let processList = await this.buildProcess(_invoice.product_id) || [];
      if (!processList || processList.length == 0) {
        return system.getResult(null, "产品流程未配置");
      }
      _invoice.status = processList[0].status;

      await this.db.transaction(async t => {
        _invoice = await this.dao.create(_invoice, t);
        await this.iinvoiceinforegDao.create({
          id: _invoice.id
        }, t);
        await this.iinvoicesummaryinfoDao.create({
          id: _invoice.id
        }, t);

        for (let process of processList) {
          process.invoice_id = _invoice.id;
        }
        await this.iinvoiceprocessDao.model.bulkCreate(processList, {
          transaction: t
        });
        //如果存在交付商信息这需要创建交付商记录
        if(params.deliver_id){
          let iinvoicedeliverProperty = {
            invoice_id:_invoice.id,
            deliver_id:params.deliver_id,
            deliver_name:params.deliverName,
            deliver_delive:0
          };
          let iinvoicedeliver = await this.iinvoicedeliverDao.create(iinvoicedeliverProperty, t);
          //将id和交付商商id回写到发票表种
          let _invoiceProperty = {
            id:_invoice.id,
            invoice_deliver_id:iinvoicedeliver.id,
            deliver_id:params.deliver_id
          }
          await this.dao.update(_invoiceProperty, t);
        }
      });
      return system.getResult(`success`);
    } catch (error) {
      console.log(error);
      return system.getResult(null, `系统错误`);
    }
  }

  async invoicePage(params) {
    params.currentPage = Number(params.currentPage || 1);
    params.pageSize = Number(params.pageSize || 10);
    params.startRow = Number((params.currentPage - 1) * params.pageSize);

    let total = await this.dao.countByParams(params);
    if (total == 0) {
      return system.getResult({
        count: 0,
        rows: []
      });
    }

    let list = await this.dao.pageByParams(params);
    if (list) {
      for (var item of list) {
        this.handleDate(item, ['updated_at', 'created_at', 'invoice_time'], 'YYYY-MM-DD HH:mm:ss');
      }
      //格式化产品
      await this.setDeliver(list);
      //格式化业务员
      await this.setStatus(list);
      for (let item of list) {
        if (item.red_status == 0) {
          item.red_status_name = "未红冲";
        } else if (item.red_status == 1) {
          item.red_status_name = '已经红冲';
        } else if (item.red_status == 2) {
          item.red_status_name = "红冲中";
        } else {
          item.red_status_name = "";
        }
      }
      await this.setProduct(list);
    }
    return system.getResultSuccess({
      count: total,
      rows: list
    });
  }

  /**
   * 格式化产品
   * @param {*} list
   */
  async setProduct(list) {
    let productIdList = [];
    for (let item of list) {
      if (item.product_id) {
        productIdList.push(item.product_id);
      }
    }
    if (!productIdList || productIdList.length === 0) {
      return;
    }
    let productMap = await this.iproductDao.mapByIds(productIdList);
    for (let item of list) {
      item.oproduct = productMap[item.product_id] || {}
    }
  }

  async setDeliver(list) {
    if (!list || list.length == 0) {
      return;
    }

    let ids = [];
    for (let item of list) {
      item.invoice_deliver = {};
      if (!item.invoice_deliver_id) {
        continue;
      }
      ids.push(item.invoice_deliver_id)
    }
    if (!ids || ids.length === 0) {
      return;
    }

    let map = await this.iinvoicedeliverDao.findMapByIds(ids);
    for (let item of list) {
      item.invoice_deliver = map[item.invoice_deliver_id] || {};
    }
  }

  /**
   * 处理状态数据
   * @param list
   * @returns {Promise<void>}
   */
  async setStatus(list) {
    let ids = [];
    let statuses = [];
    for (let item of list) {
      ids.push(item.id);
      statuses.push(item.status);
    }

    if (!ids || ids.length === 0 || !statuses || statuses.length === 0) {
      return;
    }

    let map = await this.iinvoiceprocessDao.mapByInvoiceIdsAndStatus(ids, statuses);
    for (let item of list) {
      let key = item.id + "_" + item.status;
      let v = map[key] || {};
      item.status_name = v.name;
      item.name1 = v.name1;
      item.name2 = v.name2;
      item.name3 = v.name3;
      item.name4 = v.name4;
      item.next_status = JSON.parse(v.next_status || "[]");
    }
    console.log(list);
  }

  /**
   * 构建产品流程对象
   * @param productPid
   * @param chooseProductIds
   * @returns {Promise<void>}
   */
  async buildProcess(productPid) {
    productPid = productPid || 50010000;
    // 查询产品流程
    let productProcessList = await this.iproductprocessDao.byProductPid(productPid);
    if (!productProcessList || productProcessList.length == 0) {
      return [];
    }

    let invoiceProcessList = [];
    // 批量查流程
    let processMap = await this.iprocessDao.mapAll();

    for (let productProcess of productProcessList) {
      // 风还钻该处理每一个子项流程 变为 订单流程对象
      let process = processMap[productProcess.process_id];
      let nextArr = this.trim(productProcess.next_status).split(",");
      let nextStatus = [];
      for (let nextId of nextArr) {
        nextId = Number(nextId || 0);
        let nextObj = processMap[nextId];
        if (!nextObj) {
          continue;
        }
        nextStatus.push({
          next_status: nextObj.status,
          next_name: nextObj.name
        });
      }

      let orderProcess = {
        product_id: productPid,
        name: process.name,
        status: process.status,
        func: productProcess.func,
        next_status: JSON.stringify(nextStatus),
        name1: productProcess.name1,
        name2: productProcess.name2,
        name3: productProcess.name3,
        name4: productProcess.name4,
        sort: productProcess.sort,
        autoIncrement: true
      };
      invoiceProcessList.push(orderProcess);
    }

    return invoiceProcessList;
  }

  /**
   * 根据ID查询发票详细信息
   * @param {*} params 
   */
  async queryInvoice(params) {
    if (!params.id) {
      return system.getResult(null, `参数错误 ID不能为空`);
    }
    try {
      let _invoice = await this.dao.getById(this.trim(params.id));
      if (!_invoice) {
        return system.getResult(null, `发票不存在`);
      }
      this.handleDate(_invoice, ['invoice_time', 'apply_time', 'updated_at', 'created_at'], 'YYYY-MM-DD HH:mm:ss');
      _invoice.invoice_amount = system.f2y(_invoice.invoice_amount);
      _invoice.personal_invoice_tax = system.f2y(_invoice.personal_invoice_tax);
      _invoice.additional_tax = system.f2y(_invoice.additional_tax);
      _invoice.value_added_tax = system.f2y(_invoice.value_added_tax);
      let _invoiceinforeg = await this.iinvoiceinforegDao.getById(this.trim(params.id)) || {};
      this.handleDate(_invoiceinforeg, ['updated_at', 'created_at'], 'YYYY-MM-DD HH:mm:ss');
      let _invoicedeliver = await this.iinvoicedeliverDao.getById(_invoice.invoice_deliver_id) || {};
      this.handleDate(_invoicedeliver, ['updated_at', 'created_at'], 'YYYY-MM-DD HH:mm:ss');
      _invoicedeliver.deliver_delive = system.f2y(_invoicedeliver.deliver_delive);
      let _invoicesummaryinfo = await this.iinvoicesummaryinfoDao.getById(this.trim(params.id));
      _invoicesummaryinfo.summary = JSON.parse(_invoicesummaryinfo.summary);
      this.handleDate(_invoicesummaryinfo, ['invoice_time', 'updated_at', 'created_at'], 'YYYY-MM-DD HH:mm:ss');

      _invoice.invoiceinforeg = _invoiceinforeg;
      _invoice.invoicedeliver = _invoicedeliver;
      _invoice.invoicesummaryinfo = _invoicesummaryinfo;

      _invoice.status_name = await this.iprocessDao.queryInvoiceStatusName(_invoice.status);
      return system.getResult(_invoice);
    } catch (error) {
      console.log(error);
      return system.getResult(null, `系统错误 错误信息${error}`);
    }
  }

  /**
   * 更新记账
   * @param {*} params 
   */
  async uploadDetailSve(params) {
    if (!params.id) {
      return system.getResult(null, `参数错误 发票ID 不能为空`);
    }
    try {
      let _invoice = await this.dao.model.findOne({
        where: {
          id: this.trim(params.id)
        }
      });
      if (!_invoice) {
        return system.getResult(null, `发票不存在`);
      }
      _invoice.bookkeeping = 1;
      _invoice.save();
      return system.getResultSuccess();
    } catch (error) {
      console.log(error);
      return system.getResult(null, `系统错误`);
    }
  }

  /**
   * 计算累计金额
   * @param {*} params 
   */
  async accumulatedAmount(params) {
    if (!params.credit_code) {
      return system.getResult(null, `参数错误 统一社会信用代码不能为空`);
    }
    if (!params.invoiced_time) {
      return system.getResult(null, `参数错误 开票时间不能为空`);
    }
    //计算增值税附加税 的时间
    let addValueTime = this.accumulatedTime(params.add_value_up_type, params.invoiced_time);
    //计算个税的时间
    let taxTime = this.accumulatedTime(params.tax_up_type, params.invoiced_time);
    try {
      let addValueRes = await this.dao.accumulatedAddValueAmountByTime(params.credit_code,addValueTime.beginTime, addValueTime.endTime) || {};
      let taxValueRes = await this.dao.accumulatedTaxAmountByTime(params.credit_code,taxTime.beginTime, taxTime.endTime) || {};
      return system.getResult({
        addValueRes,
        taxValueRes
      });
    } catch (error) {
      console.log(error);
      return system.getResult(null, `系统错误`);
    }
  }

  //计算时间  1：月 2：季度
  accumulatedTime(type, invoiced_time) {
    let currentTime = moment(invoiced_time);
    let beginTime = null,
      endTime = null,
      year = currentTime.year(),
      _month = currentTime.month() + 1,
      month = _month<10?"0"+_month:_month,
      date = null;
    if (type == 1) {
      date = "01";
      let maxDate = moment(`${year}-${month}`, "YYYY-MM").daysInMonth();
      beginTime = `${year}-${month}-${date} 00:00:00`;
      endTime = `${year}-${month}-${maxDate} 23:59:59`
    }
    if (type == 2) {
      //获取当前是第几季度
      let currentQuarter = currentTime.quarter();
      //季度开始的时间
      beginTime = moment(moment(year + '-01-01').toDate()).quarter(currentQuarter).format('YYYY-MM-DD HH:mm:ss');
      let endMonth = 3 * parseInt(currentQuarter) //当季度最后一个月
      /* 对月数进行格式化 */
      if (endMonth < 10)
        endMonth = '0' + endMonth
      else
        endMonth += ''
      let endMonthDays = moment(year + '-' + endMonth).daysInMonth(); // 末尾月天数
      endTime = year + '-' + endMonth + '-' + endMonthDays +  " 23:59:59"; //完整年月日整合
    }
    return {
      beginTime,
      endTime
    };
  }

  /**
   * 根据销售方统一社会信用代码查询发票
   * @param params
   * @returns {Promise<void>}
   */
  async invoiceBycreditCode(params){
    if (!params.credit_code_array || params.credit_code_array.length == 0) {
      return system.getResult(null, `参数错误 统一社会信用代码格式不正确`);
    }
    try{

      params.currentPage = Number(params.currentPage || 1);
      params.pageSize = Number(params.pageSize || 10);
      params.startRow = Number((params.currentPage - 1) * params.pageSize);

      let totalRes = await this.dao.countByParamsBycreditCode(params);
      if (totalRes.count == 0) {
        return system.getResult({
          count: 0,
          rows: []
        });
      }

      let list = await this.dao.invoiceBycreditCode(params);
      if(!list || list.length==0){
        return system.getResult([]);
      }
      for (let item of list) {
        this.handleDate(item, [ 'created_at', 'invoice_time'], 'YYYY-MM-DD HH:mm:ss');
        if(item.status=="1060"){
          item.status_name = "已完成";
        }
        item.invoice_amount = system.f2y(item.invoice_amount);
      }
      return system.getResult({count:totalRes.count,rows:list});
    }catch (e) {
      console.log(e);
      return system.getResult(null, `系统错误`);
    }
  }
}
module.exports = IInvoiceService;
