package cn.superdesk.uniorder.controller.invoice.customer;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import cn.superdesk.uniorder.common.bizScene.accounting.customer.AccountingScoreCustomerScene;
import cn.superdesk.uniorder.common.bizScene.invoice.customer.InvoiceApplyCustomerScene;
import cn.superdesk.uniorder.common.enums.accounting.customer.AccountingOrderCustomerAccountingStatusEnum;
import cn.superdesk.uniorder.common.enums.invoice.common.InvoiceTypeMoudelXModeEnum;
import cn.superdesk.uniorder.common.enums.invoice.customer.InvoiceApplyCustomerInvoiceProgressingStatusEnum;
import cn.superdesk.uniorder.common.exception.UnifiedOrderRuntimeException;
import cn.superdesk.uniorder.common.rest.response.R;
import cn.superdesk.uniorder.common.rest.response.ResponseResultOuterUtils;
import cn.superdesk.uniorder.controller.base.BaseController;
import cn.superdesk.uniorder.dao.entity.accounting.score.customer.AccountingScoreCustomer;
import cn.superdesk.uniorder.dao.entity.invoice.customer.InvoiceApply;
import cn.superdesk.uniorder.dto.param.invoice.customer.*;
import cn.superdesk.uniorder.dto.vo.invoice.customer.*;
import cn.superdesk.uniorder.dto.vo.thirdpart.szhtxx.electronicInvoice.SzhtxxElectronicInvoiceFptxxListItemVo;
import cn.superdesk.uniorder.dubbo.consumer.accounting.customer.AccountingScoreCustomerDubboConsumerService;
import cn.superdesk.uniorder.dubbo.consumer.invoice.customer.InvoiceApplyCustomerDubboConsumerService;
import cn.superdesk.uniorder.dubbo.consumer.invoice.customer.InvoiceApplyXGoodsDubboConsumerService;
import cn.superdesk.uniorder.dubbo.consumer.order.base.UnifiedOrderGoodsDubboConsumerService;
import cn.superdesk.uniorder.dubbo.consumer.organisation.SysEnterpriseDubboConsumerService;
import cn.superdesk.uniorder.dubbo.consumer.organisation.SysEnterpriseExtInvoiceDubboConsumerService;
import cn.superdesk.uniorder.dubbo.consumer.thirdpart.szhtxx.electronicInvoice.SzhtxxElectronicInvoiceFptxxDubboConsumerService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description: 积分订单 产生的 结算单 开票
 * @Author: linjinyu
 * @CreateDate: 7/1/20 11:37 AM
 * @UpdateUser: linjinyu
 * @UpdateDate: 7/1/20 11:37 AM
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Api(value = "积分结算-发票单", tags = {"积分结算-发票单"})
@Slf4j
@RestController
@RequestMapping("/invoice/apply/customer/score")
public class InvoiceApplyCustomerScoreController extends BaseController {

    @Autowired
    private InvoiceApplyCustomerDubboConsumerService invoiceApplyCustomerDubboConsumerService;
    @Autowired
    private InvoiceApplyXGoodsDubboConsumerService   invoiceApplyXGoodsDubboConsumerService;

    @Autowired
    private AccountingScoreCustomerDubboConsumerService accountingScoreCustomerDubboConsumerService;

    @Autowired
    private UnifiedOrderGoodsDubboConsumerService unifiedOrderGoodsDubboConsumerService;

    @Autowired
    private SysEnterpriseDubboConsumerService           sysEnterpriseDubboConsumerService;
    @Autowired
    private SysEnterpriseExtInvoiceDubboConsumerService sysEnterpriseExtInvoiceDubboConsumerService;

    /**************************************** 第三方 start ****************************************/

    @Autowired
    private SzhtxxElectronicInvoiceFptxxDubboConsumerService szhtxxElectronicInvoiceFptxxDubboConsumerService;


    @ApiOperation(value = "opList-积分结算-发票申请管理-积分结算2.0 已适配")
    @RequestMapping(value = "/findViewByPage", method = RequestMethod.POST)
    public R<List<InvoiceApplyCustomerPageVo>> findViewByPage(@RequestBody InvoiceApplyCustomerQueryCriteria criteria) {

        R<List<InvoiceApplyCustomerPageVo>> result = new R<>();

        log.info("\n\n\nfindViewByPage\nparams \n{}\ntoken  \n{}\n\n\n\n", JSONUtil.toJsonStr(criteria), getToken());

        result = invoiceApplyCustomerDubboConsumerService.findViewByPageFocusScore(
                criteria,
                criteria.getPageNumber(),
                criteria.getPageSize(),
                getToken()
        );

        return result;
    }

    @ApiOperation(value = "op页面Head-积分结算-发票申请管理-积分结算2.0 已适配")
    @RequestMapping(value = "/findViewHeadData", method = RequestMethod.POST)
    public R<InvoiceApplyCustomerHeadDataVo> findViewHeadData(@RequestBody InvoiceApplyCustomerQueryCriteria criteria) {

        return ResponseResultOuterUtils.createSuccesResult("", invoiceApplyCustomerDubboConsumerService.findViewHeadDataFocusScore(criteria, getToken()));
    }

    /****************************************** 积分结算2.1 start ******************************************/


    @ApiOperation(value = "opList-积分结算-发票申请管理-积分结算2.1 已适配")
    @RequestMapping(value = "/findViewByPage/V2_1", method = RequestMethod.POST)
    public R<List<InvoiceApplyCustomerPageVo>> findViewByPageV2_1(@RequestBody InvoiceApplyCustomerQueryCriteriaV2_1 queryCriteria) {

        R<List<InvoiceApplyCustomerPageVo>> result = new R<>();

        log.info("\n\n\nfindViewByPage\nparams \n{}\ntoken  \n{}\n\n\n\n", JSONUtil.toJsonStr(queryCriteria), getToken());

        result = invoiceApplyCustomerDubboConsumerService.findViewByPageFocusScoreV2_1(queryCriteria, getToken());

        return result;
    }

    @ApiOperation(value = "op页面Head-积分结算-发票申请管理-积分结算2.1 已适配")
    @RequestMapping(value = "/findViewHeadData/V2_1", method = RequestMethod.POST)
    public R<InvoiceApplyCustomerHeadDataVoV2_1> findViewHeadDataV2_1(@RequestBody InvoiceApplyCustomerQueryCriteriaV2_1 queryCriteria) {

        return ResponseResultOuterUtils.createSuccesResult("", invoiceApplyCustomerDubboConsumerService.findViewHeadDataFocusScoreV2_1(queryCriteria, getToken()));
    }

    /****************************************** 积分结算2.1   end ******************************************/


    @ApiOperation(value = "op查看详情-积分结算-发票申请管理|发票管理-积分结算2.0 已适配")
    @RequestMapping(value = "/getDetail", method = RequestMethod.POST)
    public R<InvoiceApplyCustomerDetailDimCreditVo> opDetail(@RequestBody InvoiceApplyCustomerQueryCriteria criteria) {

        log.info("积分结算-发票申请管理-op 查看详情 params : \n{}", JSONUtil.toJsonStr(criteria));

        return ResponseResultOuterUtils.createSuccesResult("", invoiceApplyCustomerDubboConsumerService.getInvoiceApplyCustomerDetailDimCredit(criteria, getToken()));
    }

    @ApiOperation(value = "op查看详情-积分结算-发票申请管理|发票管理-积分结算2.1 已适配")
    @RequestMapping(value = "/getDetail/V2_1", method = RequestMethod.POST)
    public R<InvoiceApplyCustomerDetailDimCreditVoV2_1> opDetailV2_1(@RequestBody InvoiceApplyCustomerQueryCriteriaV2_1 criteria) {

        log.info("积分结算-发票申请管理-op 查看详情 params : \n{}", JSONUtil.toJsonStr(criteria));

        return ResponseResultOuterUtils.createSuccesResult(
                "",
                invoiceApplyCustomerDubboConsumerService.getInvoiceApplyCustomerDetailDimCreditV2_1(criteria, getToken())
        );
    }

    @ApiOperation(value = "op变更抬头-积分结算-发票申请管理|发票管理-积分结算2.1 已适配")
    @RequestMapping(value = "/opModifyInvoiceTitle", method = RequestMethod.POST)
    public R<String> opModifyInvoiceTitle(@RequestBody InvoiceApplyCustomerOpModifyInvoiceTitleForm form) {

        log.info("积分结算-发票申请管理-op 查看详情 params : \n{}", JSONUtil.toJsonStr(form));

        InvoiceApply entity = invoiceApplyCustomerDubboConsumerService.findById(form.getInvoiceApplyId());

        if (ObjectUtil.isNull(entity)) {
            return ResponseResultOuterUtils.createErrorResult("500", "该开票申请不存在");
        }

        if (InvoiceApplyCustomerInvoiceProgressingStatusEnum.待开票.getKey().compareTo(entity.getInvoiceStatus()) != 0) {
            return ResponseResultOuterUtils.createErrorResult("500", "该开票申请状态发生变更,请返回检查");
        }

        List<Long> affectedAccountingOrderIds = invoiceApplyXGoodsDubboConsumerService.getAffectedAccountingOrderIdsByInvoiceApplyId(form.getInvoiceApplyId());

        List<AccountingScoreCustomer> affectedAccountingOrderList = accountingScoreCustomerDubboConsumerService.findByIds(affectedAccountingOrderIds);

        if (CollUtil.isEmpty(affectedAccountingOrderList)) {
            return ResponseResultOuterUtils.createErrorResult("500", "该对账单不存在");
        }

        for (AccountingScoreCustomer affected : affectedAccountingOrderList) {
            if (AccountingOrderCustomerAccountingStatusEnum.已确认.getKey().compareTo(affected.getAccountingStatus()) != 0) {
                return ResponseResultOuterUtils.createErrorResult("500", "该对账单状态发生变更,请返回检查");
            }
        }

        int ret = invoiceApplyCustomerDubboConsumerService.opModifyInvoiceTitle(form, getToken());

        if (ret == 0) {
            return ResponseResultOuterUtils.createErrorResult("500", "变更失败");
        } else {
            return ResponseResultOuterUtils.createSuccesResult("变更成功");
        }


    }

    @ApiOperation(value = "op开票备注1-积分结算-发票申请管理|发票管理-积分结算2.1 已适配")
    @RequestMapping(value = "/opSetRemark1", method = RequestMethod.POST)
    @ResponseBody
    public R<String> opSetRemark1(@RequestBody InvoiceApplyCustomerOpSetRemark2Form form) {


        InvoiceApply invoiceApply4SetRemark2 = new InvoiceApply();

        invoiceApply4SetRemark2.setId(form.getInvoiceApplyId());
        invoiceApply4SetRemark2.setRemark(form.getRemark());

        int ret = invoiceApplyCustomerDubboConsumerService.updateInvoiceApplyByPrimaryKeySelective(invoiceApply4SetRemark2);

        if (ret == 0) {
            return ResponseResultOuterUtils.createSuccesResult("开票备注失败");
        } else {
            return ResponseResultOuterUtils.createSuccesResult("开票备注成功");
        }
    }

    @ApiOperation(value = "op后台备注2-积分结算-发票申请管理|发票管理-积分结算2.1 已适配")
    @RequestMapping(value = "/opSetRemark2", method = RequestMethod.POST)
    @ResponseBody
    public R<String> opSetRemark2(@RequestBody InvoiceApplyCustomerOpSetRemark2Form form) {


        InvoiceApply invoiceApply4SetRemark2 = new InvoiceApply();

        invoiceApply4SetRemark2.setId(form.getInvoiceApplyId());
        invoiceApply4SetRemark2.setRemark2(form.getRemark());

        int ret = invoiceApplyCustomerDubboConsumerService.updateInvoiceApplyByPrimaryKeySelective(invoiceApply4SetRemark2);

        if (ret == 0) {
            return ResponseResultOuterUtils.createSuccesResult("后台备注失败");
        } else {
            return ResponseResultOuterUtils.createSuccesResult("后台备注成功");
        }
    }


    /**
     * /invoice/apply/customer/score/deleteInvoiceApply
     *
     * @return
     */
    @ApiOperation(value = "op撤销开票-积分结算-发票申请管理|发票管理")
    @RequestMapping(value = "/deleteInvoiceApply/{invoiceApplyId}", method = RequestMethod.POST)
    public R<String> opDelete(@PathVariable("invoiceApplyId") Long invoiceApplyId) {

        // 前端
//		(1)当前操作人拥有该功能操作权限;
//		(2)该开票申请的申请状态为"待开票";
//		满足以上两个条件,即正常显示,否则不显示;

//2.5.8.3.3.2 【确认撤销】
//(1)前端:此按钮需加5s防频繁点击,不重复提交内容;
//(2)服务端判断:
//·该对账单存在,若不存在,1.5s提示"该对账单不存在";
//·该对账单状态为"已确认",若对账单状态非"已确认",1.5s提示"该对账单状态发生变更,请返回检查";
//·该开票申请存在,若不存在,1.5s提示"该开票申请不存在";
//·该开票申请的申请状态为"待开票",若非"待开票",1.5s提示"该开票申请状态发生变更,请返回检查";
//
//满足以上条件,即确认撤销开票申请成功:
//·将该开票申请的所有订单流水数据释放回该对账单中,流水的申请状态变更为"未申请";
//·将该开票申请记录物理删除;
//·该对账单的申请状态"未申请/部分申请/全部申请",重新校验更新;
//·该对账单的更新人和更新时间更新为当前的操作人姓名及时间;
//·记录撤销和删除开票申请日志;---- 这个指什么日志 - 操作日志?
//·弹窗关闭,1.5s提示"撤销成功",列表数据更新;

        InvoiceApply invoiceApplyEntity = invoiceApplyCustomerDubboConsumerService.findById(invoiceApplyId);

        if (ObjectUtil.isNull(invoiceApplyEntity)) {
            return ResponseResultOuterUtils.createErrorResult("500", "该开票申请不存在");
        }

        if (InvoiceApplyCustomerInvoiceProgressingStatusEnum.待开票.getKey()
                .compareTo(invoiceApplyEntity.getInvoiceStatus()) != 0) {
            return ResponseResultOuterUtils.createErrorResult("500", "该开票申请状态发生变更,请返回检查");
        }

        List<Long> affectedAccountingOrderIds = invoiceApplyXGoodsDubboConsumerService
                .getAffectedAccountingOrderIdsByInvoiceApplyId(
                        invoiceApplyId
                );

        List<AccountingScoreCustomer> affectedAccountingOrderList = accountingScoreCustomerDubboConsumerService
                .findByIds(
                        affectedAccountingOrderIds
                );

        if (CollUtil.isEmpty(affectedAccountingOrderList)) {
            return ResponseResultOuterUtils.createErrorResult("500", "该对账单不存在");
        }

        for (AccountingScoreCustomer affected : affectedAccountingOrderList) {
            if (AccountingOrderCustomerAccountingStatusEnum.已确认.getKey()
                    .compareTo(affected.getAccountingStatus()) != 0) {
                return ResponseResultOuterUtils.createErrorResult("500", "该对账单状态发生变更,请返回检查");
            }
        }

        int ret = invoiceApplyCustomerDubboConsumerService.opDelete(invoiceApplyId, getToken());

        if (ret == 0) {
            return ResponseResultOuterUtils.createSuccesResult("撤销失败");
        } else {
            return ResponseResultOuterUtils.createSuccesResult("撤销成功");
        }
    }


    /**
     * 有空再梳理吧，先用这恶心的if else
     *
     * @param form
     * @return
     */
    @ApiOperation(value = "op重新开票Pre-积分结算-发票申请管理|发票管理-积分结算2.1 已适配")
    @RequestMapping(value = "/opAgainInvoiceApplyPre", method = RequestMethod.POST)
    @ResponseBody
    public R<SzhtxxElectronicInvoiceFptxxListItemVo> opAgainInvoiceApplyPre(@RequestBody InvoiceApplyCustomerOpAgainInvoiceApplyForm form) {

        InvoiceApply invoiceApplyEntity = invoiceApplyCustomerDubboConsumerService.findById(form.getInvoiceApplyId());

        if (ObjectUtil.isNull(invoiceApplyEntity)) {
            return ResponseResultOuterUtils.createErrorResult("500", "该开票申请不存在");
        }

        if (!ArrayUtil.contains(
                InvoiceApplyCustomerScene.statusV2_1_Array_InvoiceProgressingSceneStateCheck(),
                invoiceApplyEntity.getInvoiceStatus())
        ) {
            return ResponseResultOuterUtils.createErrorResult("500", "该开票申请状态发生变更，请返回检查");
        }

        List<Long> affectedAccountingOrderIds = invoiceApplyXGoodsDubboConsumerService.getAffectedAccountingOrderIdsByInvoiceApplyId(form.getInvoiceApplyId());

        List<AccountingScoreCustomer> affectedAccountingOrderList = accountingScoreCustomerDubboConsumerService.findByIds(affectedAccountingOrderIds);

        if (CollUtil.isEmpty(affectedAccountingOrderList)) {
            return ResponseResultOuterUtils.createErrorResult("500", "该对账单不存在");
        }

        for (AccountingScoreCustomer affected : affectedAccountingOrderList) {
            if (AccountingOrderCustomerAccountingStatusEnum.已确认.getKey().compareTo(affected.getAccountingStatus()) != 0) {
                return ResponseResultOuterUtils.createErrorResult("500", "该对账单状态发生变更,请返回检查");
            }
        }

        switch (InvoiceTypeMoudelXModeEnum.get(invoiceApplyEntity.getInvoiceMode())) {
            case 线下开票:
                int ret = invoiceApplyCustomerDubboConsumerService.opDelete(form.getInvoiceApplyId(), getToken());

                if (ret == 0) {
                    return ResponseResultOuterUtils.createSuccesResult("重开失败");
                } else {
                    return ResponseResultOuterUtils.createSuccesResult("重开成功");
                }

            case 深圳航信电子发票:

                SzhtxxElectronicInvoiceFptxxListItemVo fptxxListItemElectronicVo = szhtxxElectronicInvoiceFptxxDubboConsumerService.queryOneByFpqqlsh(form.getInvoiceApplySn(), getToken());

                if (ObjectUtil.isNull(fptxxListItemElectronicVo)) {
                    return ResponseResultOuterUtils.createErrorResult("500", "异常，无法匹配[金税盘发票]");
                } else {
                    return ResponseResultOuterUtils.createSuccesResult("", fptxxListItemElectronicVo);
                }

            case 深圳航信纸质发票:
                SzhtxxElectronicInvoiceFptxxListItemVo fptxxListItemPaperVo = szhtxxElectronicInvoiceFptxxDubboConsumerService.queryOneByFpqqlsh(form.getInvoiceApplySn(), getToken());

                if (ObjectUtil.isNull(fptxxListItemPaperVo)) {
                    return ResponseResultOuterUtils.createErrorResult("500", "异常，无法匹配[金税盘发票]");
                } else {
                    return ResponseResultOuterUtils.createSuccesResult("", fptxxListItemPaperVo);
                }

            default:
                return ResponseResultOuterUtils.createErrorResult("500", "异常，无法匹配[开票方式]");
        }
    }

    @ApiOperation(value = "op重新开票-积分结算-发票申请管理|发票管理-积分结算2.1 已适配")
    @RequestMapping(value = "/opAgainInvoiceApply", method = RequestMethod.POST)
    @ResponseBody
    public R<String> opAgainInvoiceApply(@RequestBody InvoiceApplyCustomerOpAgainInvoiceApplyForm form) throws UnifiedOrderRuntimeException {

        InvoiceApply invoiceApplyCustomerEntity = invoiceApplyCustomerDubboConsumerService.findById(form.getInvoiceApplyId());

        if (ObjectUtil.isNull(invoiceApplyCustomerEntity)) {
            return ResponseResultOuterUtils.createErrorResult("500", "该开票申请不存在");
        }

        if (!ArrayUtil.contains(
                InvoiceApplyCustomerScene.statusV2_1_Array_InvoiceProgressingSceneStateCheck(),
                invoiceApplyCustomerEntity.getInvoiceStatus())
        ) {
            return ResponseResultOuterUtils.createErrorResult("500", "该开票申请状态发生变更，请返回检查");
        }

        List<Long> affectedAccountingOrderIds = invoiceApplyXGoodsDubboConsumerService.getAffectedAccountingOrderIdsByInvoiceApplyId(form.getInvoiceApplyId());

        List<AccountingScoreCustomer> affectedAccountingOrderList = accountingScoreCustomerDubboConsumerService.findByIds(affectedAccountingOrderIds);

        if (CollUtil.isEmpty(affectedAccountingOrderList)) {
            return ResponseResultOuterUtils.createErrorResult("500", "该对账单不存在");
        }

        for (AccountingScoreCustomer affected : affectedAccountingOrderList) {
            if (AccountingOrderCustomerAccountingStatusEnum.已确认.getKey().compareTo(affected.getAccountingStatus()) != 0) {
                return ResponseResultOuterUtils.createErrorResult("500", "该对账单状态发生变更,请返回检查");
            }
        }

        switch (InvoiceTypeMoudelXModeEnum.get(invoiceApplyCustomerEntity.getInvoiceMode())) {
            case 线下开票:
                int retOffLine = invoiceApplyCustomerDubboConsumerService.opDelete(form.getInvoiceApplyId(), getToken());

                if (retOffLine == 0) {
                    return ResponseResultOuterUtils.createSuccesResult("重开失败");
                } else {
                    return ResponseResultOuterUtils.createSuccesResult("重开成功");
                }
            case 深圳航信电子发票:

                //(2)该开票申请的开票方式为"深圳航信电子发票":
                //
                //①前端:
                //·重开原因不可为空,否则不允许提交,1.5s提示"请输入重开原因";
                //·是否红冲为"是"&原/红冲发票号不为空,否则不允许提交,1.5s提示"当前开票方式,请先红冲原发票后再重开";
                //·此按钮需加5s防频繁点击,不重复提交内容;
                //
                //②服务端判断:
                //·该对账单存在,若不存在,1.5s提示"该对账单不存在";
                //·该对账单状态为"已确认",若对账单状态非"已确认",1.5s提示"该对账单状态发生变更,请返回检查";
                //·该开票申请存在,若不存在,1.5s提示"该开票申请不存在";
                //·该开票申请的申请状态为"待领票/待寄票/待回款",若非"待领票/待寄票/待回款",1.5s提示"该开票申请状态发生变更,请返回检查";
                //
                //满足以上条件,即确认重开成功:
                //·将该开票申请的申请状态变更为"已红冲";
                //·同时解除该开票申请与原发票和红冲发票的开票申请数据的关系;
                //·重开原因记录到该开票申请的开票备注中;
                //·将该开票申请的所有订单流水数据释放回该对账单中,流水的申请状态变更为"未申请",流水的开票状态变更为"待开票";
                //·该对账单的申请状态"未申请/部分申请/全部申请",重新校验更新;
                //·该对账单的更新人和更新时间更新为当前的操作人姓名及时间;
                //·该开票申请的更新人和更新时间更新为当前的操作人姓名及时间;
                //·记录重开和删除开票申请日志;
                //·弹窗关闭,1.5s提示"重开成功",列表数据更新;

                SzhtxxElectronicInvoiceFptxxListItemVo fptxxListItemVo4SzhtxxElectronicInvoice = szhtxxElectronicInvoiceFptxxDubboConsumerService.queryOneByFpqqlsh(form.getInvoiceApplySn(), getToken());

                if (ObjectUtil.isNull(fptxxListItemVo4SzhtxxElectronicInvoice)) {
                    return ResponseResultOuterUtils.createErrorResult("500", "异常，无法匹配[金税盘发票]");
                }

                int retSzhtxxElectronicInvoice = invoiceApplyCustomerDubboConsumerService.opAgainSzhtxxElectronicInvoice(form, invoiceApplyCustomerEntity, fptxxListItemVo4SzhtxxElectronicInvoice, getToken());

                if (retSzhtxxElectronicInvoice == 0) {
                    return ResponseResultOuterUtils.createErrorResult("500", "重开失败");
                } else {
                    return ResponseResultOuterUtils.createSuccesResult("重开成功");
                }

            case 深圳航信纸质发票:
                //(2)该开票申请的开票方式为"深圳航信电子发票":
                //
                //①前端:
                //·重开原因不可为空,否则不允许提交,1.5s提示"请输入重开原因";
                //·是否红冲为"是"&原/红冲发票号不为空,否则不允许提交,1.5s提示"当前开票方式,请先红冲原发票后再重开";
                //·此按钮需加5s防频繁点击,不重复提交内容;
                //
                //②服务端判断:
                //·该对账单存在,若不存在,1.5s提示"该对账单不存在";
                //·该对账单状态为"已确认",若对账单状态非"已确认",1.5s提示"该对账单状态发生变更,请返回检查";
                //·该开票申请存在,若不存在,1.5s提示"该开票申请不存在";
                //·该开票申请的申请状态为"待领票/待寄票/待回款",若非"待领票/待寄票/待回款",1.5s提示"该开票申请状态发生变更,请返回检查";
                //
                //满足以上条件,即确认重开成功:
                //·将该开票申请的申请状态变更为"已红冲";
                //·同时解除该开票申请与原发票和红冲发票的开票申请数据的关系;
                //·重开原因记录到该开票申请的开票备注中;
                //·将该开票申请的所有订单流水数据释放回该对账单中,流水的申请状态变更为"未申请",流水的开票状态变更为"待开票";
                //·该对账单的申请状态"未申请/部分申请/全部申请",重新校验更新;
                //·该对账单的更新人和更新时间更新为当前的操作人姓名及时间;
                //·该开票申请的更新人和更新时间更新为当前的操作人姓名及时间;
                //·记录重开和删除开票申请日志;
                //·弹窗关闭,1.5s提示"重开成功",列表数据更新;

                SzhtxxElectronicInvoiceFptxxListItemVo fptxxListItemVo4SzhtxxPaperInvoice = szhtxxElectronicInvoiceFptxxDubboConsumerService.queryOneByFpqqlsh(form.getInvoiceApplySn(), getToken());

                if (ObjectUtil.isNull(fptxxListItemVo4SzhtxxPaperInvoice)) {
                    return ResponseResultOuterUtils.createErrorResult("500", "异常，无法匹配[金税盘发票]");
                }

                int retSzhtxxPaperInvoice = invoiceApplyCustomerDubboConsumerService.opAgainSzhtxxPaperInvoice(form, invoiceApplyCustomerEntity, fptxxListItemVo4SzhtxxPaperInvoice, getToken());

                if (retSzhtxxPaperInvoice == 0) {
                    return ResponseResultOuterUtils.createErrorResult("500", "重开失败");
                } else {
                    return ResponseResultOuterUtils.createSuccesResult("重开成功");
                }

            default:
                return ResponseResultOuterUtils.createErrorResult("500", "异常，无法匹配[开票方式]");
        }

    }


    /**************************************** op申请开票-op一键分票 start ****************************************/

    /**
     * 对映 InvoiceApplyCustomerUnifiedController.opApplySelect
     * 积分结算2.1 返回添加订单方向与退单单号
     *
     * @param queryCriteria
     * @return
     */
    @ApiOperation(value = "申请开票-积分结算-对账单-op申请开票-积分结算2.1 已适配", notes = "积分结算2.1")
    @PostMapping("/invoiceApplySelect")
    public R<InvoiceApplyCustomerSelectScoreStruct> opApplySelect(@RequestBody InvoiceApplyCustomerQueryCriteria queryCriteria) {

        if (ObjectUtil.isNull(queryCriteria.getAccountingOrderId())) {
            return ResponseResultOuterUtils.createErrorResult("500", "参数错误,对账单Id号不能为空");
        }

        /****************************************** 传了反而是错 start ******************************************/

//		if (ObjectUtil.isNotNull(queryCriteria.getAccountingOrderSn())) {
//			return ResponseResultOuterUtils.createErrorResult("500", "参数错误,不支持对账单Sn号");
//		}

        return ResponseResultOuterUtils.createSuccesResult("", invoiceApplyCustomerDubboConsumerService.invoiceApplySelectFocusScoreDimCreditV2_1(queryCriteria, getToken()));
    }


    /**
     * 积分结算2.0 整改 mark by linjinyu at 20211118
     * 积分结算2.0 TODO 添加开票方式 mark by linjinyu at 20220223
     *
     * @return
     */
    @Deprecated
    @ApiOperation(value = "一键分票-积分结算-对账单-op申请开票-op一键分票 -积分结算2.0 已适配", notes = "积分结算2.0")
    @PostMapping("/invoiceApply")
    public R opApply(@RequestBody InvoiceApplyFocusScoreOpApplyForm form) {

        log.info("客户结算 > 发票申请管理 > op 申请开票 -> 编辑页面 op 提交 params: \n{}", JSONUtil.toJsonStr(form));

        return invoiceApplyCustomerDubboConsumerService.opInvoiceApplyCustomerFocusScore(form, getToken());
    }

    @ApiOperation(value = "一键分票-积分结算-对账单-op申请开票-op一键分票 -积分结算2.1 已适配", notes = "积分结算2.1")
    @PostMapping("/invoiceApply/v2_1")
    public R<InvoiceApplyFocusScoreOpApplyReportV2_1> opApplyV2_1(@RequestBody InvoiceApplyFocusScoreOpApplyFormV2_1 form) {

        log.info("客户结算 > 发票申请管理 > op 申请开票 -> 编辑页面 op 提交 params: \n{}", JSONUtil.toJsonStr(form));

        /****************************************  start ****************************************/

        R<String> checkUpResponse = opApplyCheckUpV2_1(form);
        if ("500".equals(checkUpResponse.getCode())) {
            return ResponseResultOuterUtils.createErrorResult(checkUpResponse.getCode(), checkUpResponse.getMessage());
        }

        /****************************************    end ****************************************/

        return invoiceApplyCustomerDubboConsumerService.opInvoiceApplyCustomerFocusScoreV2_1(form, getToken());
    }

    // 有空再把这检验的美化一下，变得优雅一些
    private R<String> opApplyCheckUpV2_1(InvoiceApplyFocusScoreOpApplyFormV2_1 form) {

        // 【2. 积分结算-2.1 对账单-2.1.1 “申请开票”页面-已整理-20220406-前端待验证-20220425】
        // https://www.tapd.cn/33003868/prong/stories/view/1133003868001004180
        //   2.1.1.2.2 服务端判断
        //   （1）该对账单存在，否则不允许一键分票，1.5s提示“该对账单不存在，请返回检查”；
        //   （2）该对账单状态为“已确认”，否则不允许一键分票，1.5s“该对账单状态发生变更，请返回检查”；
        //   （3）该对账单申请状态为“未申请/部分申请”，否则不允许一键分票，1.5s提示“该对账单申请状态发生变更，请返回检查”；
        //   （4）该对账单“已选”开票数据数量≥1，否则不允许一键分票，1.5s提示“已选的开票数据不能为空，请选择”；
        //   （5）由于数据量大，暂不对每条流水结算状态及申请状态检查；
        //   （6）若服务端存在其他必要性判断可自补充判断；

        AccountingScoreCustomer accountingScoreCustomerEntity = accountingScoreCustomerDubboConsumerService.findByAccountingOrderSn(form.getAccountingOrderSn());

        if (ObjectUtil.isNull(accountingScoreCustomerEntity)) {
            return ResponseResultOuterUtils.createErrorResult("500", "该对账单不存在,请返回检查");
        }

        if (AccountingOrderCustomerAccountingStatusEnum.已确认.getKey().compareTo(accountingScoreCustomerEntity.getAccountingStatus()) != 0) {
            return ResponseResultOuterUtils.createErrorResult("500", "该对账单状态发生变更,请返回检查");
        }

        if (!ArrayUtil.contains(
                AccountingScoreCustomerScene.statusV2_1_Array_InvoiceApplyStatusCheck(),
                accountingScoreCustomerEntity.getInvoiceStatus())
        ) {
            return ResponseResultOuterUtils.createErrorResult("500", "该对账单申请状态发生变更，请返回检查");
        }

        if (CollUtil.isEmpty(form.getCreditSelected())) {
            return ResponseResultOuterUtils.createErrorResult("500", "已选的开票数据不能为空，请选择");
        }

        return ResponseResultOuterUtils.createSuccesResult("");
    }

    /**************************************** op申请开票-op一键分票 start ****************************************/


    /**
     * 客户结算-发票申请管理-op row 审核 (申请开票) 按扭 同意 拒绝
     * /invoice/apply/customer/score/audit
     * <p>
     * 弃用
     * 【开发中 202107151422 积分结算2.0优化需求(保留现有的银行流水和收款核销模块)】 https://www.tapd.cn/33003868/prong/stories/view/1133003868001002470
     * 需求7:发票申请管理优化
     * ② 隐藏发票申请管理列表的字段:审核状态、审核人、审核时间
     * ③ 隐藏查询栏:审核状态下拉查询
     * ④ 隐藏发票申请管理列表操作按钮:同意、拒绝
     *
     * @return
     */
    @Deprecated
    @ApiOperation(value = "积分结算-发票申请管理-op row 审核向按扭 同意 拒绝 - 积分结算2.0后弃用")
    @PostMapping("/audit")
    public R opAudit() {

        Map<String, Object> params = new HashMap<>();

        params.put("id", getString("id"));
        params.put("auditStatus", getInteger("auditStatus"));

        log.info("客户结算-发票申请管理-op row 审核 (申请开票) 按扭 同意 拒绝 params : \n{}", JSONUtil.toJsonStr(params));

        invoiceApplyCustomerDubboConsumerService.opAudit(params, getToken());

        return new R();
    }


    /**
     * 客户结算-发票申请管理-op 开票登记
     * TODO 标记 可以共用
     * /invoice/apply/customer/score/invoiceRegister
     *
     * @return
     */
    @Deprecated
    @ApiOperation(value = "积分结算-发票申请管理-op 开票登记 - 积分结算2.0后弃用")
    @PostMapping("/invoiceRegister")
    public R opRegister() {

        Map<String, Object> params = new HashMap<>();

        /**
         * 发票申请Id
         */
        params.put("id", getString("id"));
        /**
         * 开票日期 手动填写
         */
        params.put("datestr", getString("datestr"));
        /**
         * 发票号
         */
        params.put("invoiceNumber", getString("invoiceNumber"));

        invoiceApplyCustomerDubboConsumerService.opRegister(params, getToken());

        return new R();
    }
}
