package cn.superdesk.uniorder.dubbo.provider.invoice.supplier;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.superdesk.uniorder.common.enums.invoice.InvoiceApplyAuditStatusEnum;
import cn.superdesk.uniorder.common.enums.invoice.supplier.*;
import cn.superdesk.uniorder.common.json.AnJsonUtils;
import cn.superdesk.uniorder.common.lamda.AnLamdaUtils;
import cn.superdesk.uniorder.common.numerical.AnBeanUtils;
import cn.superdesk.uniorder.common.numerical.AnConvertBeanUtil;
import cn.superdesk.uniorder.common.numerical.AnLongUtils;
import cn.superdesk.uniorder.common.rest.response.R;
import cn.superdesk.uniorder.common.security.dto.LoginSysUser;
import cn.superdesk.uniorder.dao.entity.base.UnifiedOrder;
import cn.superdesk.uniorder.dao.entity.invoice.common.InvoiceBankInfo;
import cn.superdesk.uniorder.dao.entity.invoice.common.InvoiceType;
import cn.superdesk.uniorder.dao.entity.invoice.supplier.InvoiceApplySupplier;
import cn.superdesk.uniorder.dao.entity.invoice.supplier.InvoiceApplySupplierXGoods;
import cn.superdesk.uniorder.dao.entity.sys.SysUser;
import cn.superdesk.uniorder.dao.entity.sys.notify.SysNotify;
import cn.superdesk.uniorder.dto.param.invoice.supplier.*;
import cn.superdesk.uniorder.dto.param.invoice.supplier.status.InvoiceApplySupplierOpCommonDimAccountingOrderForm;
import cn.superdesk.uniorder.dto.vo.invoice.supplier.*;
import cn.superdesk.uniorder.dto.vo.organisation.SysPlatformExtInvoiceVo;
import cn.superdesk.uniorder.dubbo.facade.invoice.supplier.DubboInvoiceApplySupplierService;
import cn.superdesk.uniorder.dubbo.facade.sys.notify.DubboSysNotifyService;
import cn.superdesk.uniorder.event.invoiceApplySupplierTrigger.InvoiceApplySupplierTriggerEventPublisher;
import cn.superdesk.uniorder.event.invoiceApplySupplierTrigger.TailUpdateInvoiceApplySupplierFieldSaleIsExportEvent;
import cn.superdesk.uniorder.service.order.base.UnifiedOrderService;
import cn.superdesk.uniorder.service.invoice.common.InvoiceBankInfoService;
import cn.superdesk.uniorder.service.invoice.common.InvoiceTypeService;
import cn.superdesk.uniorder.service.invoice.supplier.InvoiceApplySupplierExportExcelService;
import cn.superdesk.uniorder.service.invoice.supplier.InvoiceApplySupplierService;
import cn.superdesk.uniorder.service.invoice.supplier.InvoiceApplySupplierXGoodsService;
import cn.superdesk.uniorder.service.organisation.SysSupplierExtInvoiceService;
import cn.superdesk.uniorder.service.setting.UnifiedSnConfigService;
import cn.superdesk.uniorder.service.sys.SysUserService;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Service(version = "1.0.0", retries = -1, timeout = 10000)
public class DubboInvoiceApplySupplierServiceImpl implements DubboInvoiceApplySupplierService {

    @Autowired
    private InvoiceApplySupplierService       invoiceApplySupplierService;
    @Autowired
    private InvoiceApplySupplierXGoodsService invoiceApplySupplierXGoodsService;

    @Autowired
    private InvoiceApplySupplierExportExcelService invoiceApplySupplierExportExcelService;

    @Autowired
    private InvoiceApplySupplierTriggerEventPublisher invoiceApplySupplierTriggerEventPublisher;

    @Autowired
    private UnifiedSnConfigService unifiedSnConfigService;
    @Autowired
    private UnifiedOrderService    unifiedOrderService;

    @Autowired
    private SysSupplierExtInvoiceService sysSupplierExtInvoiceService;
    @Autowired
    private InvoiceBankInfoService       invoiceBankInfoService;
    @Autowired
    private InvoiceTypeService           invoiceTypeService;

    @Autowired
    private SysUserService sysUserService;

    /****************************************** 引用自身 Dubbo provider start ******************************************/

    @Reference(version = "1.0.0", timeout = 10000, retries = -1)
    private DubboSysNotifyService dubboSysNotifyService;

    /****************************************** 引用自身 Dubbo provider   end ******************************************/


    /****************************************** extends BaseService 部分 start ******************************************/

    @Override
    public void addObj(InvoiceApplySupplierParam param) {

        InvoiceApplySupplier invoiceApplySupplier = AnBeanUtils.copy(param, InvoiceApplySupplier.class);
        invoiceApplySupplierService.insertSelective(invoiceApplySupplier);

    }

    @Override
    public void updateObj(InvoiceApplySupplierParam param) {

        InvoiceApplySupplier invoiceApplySupplier = AnBeanUtils.copy(param, InvoiceApplySupplier.class);
        invoiceApplySupplierService.updateByPrimaryKeySelective(invoiceApplySupplier);
    }

    @Override
    public InvoiceApplySupplier updateObj(InvoiceApplySupplier update) {

        invoiceApplySupplierService.updateByPrimaryKeySelective(update);

        return update;
    }

    @Override
    public void deleteObj(Long id) {
        invoiceApplySupplierService.deleteObj(id);
    }

    @Override
    public InvoiceApplySupplier findById(Long id) {
        return invoiceApplySupplierService.findById(id);
    }

    @Override
    public List<InvoiceApplySupplier> findByIds(List<Long> invoiceApplyIds) {
        return invoiceApplySupplierService.findByIds(invoiceApplyIds);
    }

    @Override
    public List<InvoiceApplySupplier> findByAccountingOrderSn(String accountingOrderSn) {
        return invoiceApplySupplierService.findByAccountingOrderSn(accountingOrderSn);
    }

    @Override
    public PageInfo<InvoiceApplySupplier> findByPaging(Map<String, Object> conditions, Integer pageNun, Integer pageSize) {
        return invoiceApplySupplierService.findByPaging(conditions, pageNun, pageSize);
    }

    @Override
    public List<InvoiceApplySupplier> findAll(Map<String, Object> queryMap) {

        return invoiceApplySupplierService.findAll(queryMap);
    }

    /****************************************** extends BaseService 部分   end ******************************************/


    @Override
    public void addInvoiceApplySupplier(InvoiceApplySupplierParam param) {

        InvoiceApplySupplier invoiceApplySupplier = AnBeanUtils.copy(param, InvoiceApplySupplier.class);
        invoiceApplySupplierService.addInvoiceApplySupplier(invoiceApplySupplier);
    }

    @Override
    public void updateInvoiceApplySupplier(InvoiceApplySupplierParam param) {

        InvoiceApplySupplier invoiceApplySupplier = AnBeanUtils.copy(param, InvoiceApplySupplier.class);
        invoiceApplySupplierService.updateInvoiceApplySupplier(invoiceApplySupplier);
    }

    @Override
    public int updateInvoiceApplySupplierByPrimaryKeySelective(InvoiceApplySupplier entity) {
        return invoiceApplySupplierService.updateInvoiceApplySupplierByPrimaryKeySelective(entity);
    }

    @Override
    public void deleteInvoiceApplySupplier(Long id) {
        invoiceApplySupplierService.deleteInvoiceApplySupplier(id);
    }

    @Override
    public InvoiceApplySupplier findInvoiceApplySupplierById(Long id) {
        return invoiceApplySupplierService.findInvoiceApplySupplierById(id);
    }

    @Override
    public R<List<InvoiceApplySupplier>> pageQuery(Map<String, Object> conditions, int pageNun, int pageSize) {
        return invoiceApplySupplierService.pageQuery(conditions, pageNun, pageSize);
    }

    @Override
    public R<List<InvoiceApplySupplier>> pageQueryGenericParam(InvoiceApplySupplierQueryCriteria criteria) {
        return invoiceApplySupplierService.pageQueryGenericParam(criteria);
    }


    /****************************************** 重构前存在 start ******************************************/

    @Override
    public R<List<InvoiceApplySupplier>> getInvoiceApplySupplierList(Map<String, Object> params, int pageNum, int pageSize) {

        return invoiceApplySupplierService.queryInvoiceApplyList(params, pageNum, pageSize);
    }

    @Override
    public R<List<InvoiceApplySupplierPageVo>> getInvoiceApplySupplierPageVoList(InvoiceApplySupplierPageVoListQueryCriteria queryCriteria, LoginSysUser loginSysUser) {

        log.info("供应商结算->发票登记管理 params {}", JSONUtil.toJsonStr(queryCriteria));

        return invoiceApplySupplierService.queryInvoiceApplySupplierPageVoList(queryCriteria, loginSysUser);
    }

    @Override
    public InvoiceApplySupplierHeadVo getInvoiceApplyListHeadSum(Map<String, Object> params) {

        return invoiceApplySupplierService.getInvoiceApplyListHeadSum(params);
    }

    /**
     * @param invoiceApplySupplierId
     * @param loginSysUser
     * @return
     */
    @Override
    public InvoiceApplySupplierDetailDimGoodsVo getInvoiceApplySupplierDetailByInvoiceApplySupplierId(/* 发票申请Id */Long invoiceApplySupplierId, LoginSysUser loginSysUser) {

        InvoiceApplySupplier invoiceApplySupplier = invoiceApplySupplierService.findById(invoiceApplySupplierId);

        InvoiceApplySupplierDetailDimGoodsVo vo = AnConvertBeanUtil.copyBean(invoiceApplySupplier, InvoiceApplySupplierDetailDimGoodsVo.class);

        /****************************************** part1 start ******************************************/
        // 处理 sysPlatformExtInvoiceId 不为0的情况
        if (ObjectUtil.isNotNull(vo)
                && ObjectUtil.isNotNull(vo.getSysPlatformExtInvoiceId())
                && vo.getSysPlatformExtInvoiceId().compareTo(0L) != 0) {
            vo.setSysPlatformExtInvoiceSnapshotEntity(AnJsonUtils.toObject(vo.getSysPlatformExtInvoiceSnapshot(), SysPlatformExtInvoiceVo.class));
        }

        /****************************************** part2 start ******************************************/

        List<Long> sysUserIds = new ArrayList<>();

        if (ObjectUtil.isNotNull(vo.getApplyUserId())) {
            sysUserIds.add(vo.getApplyUserId());
        }
        if (ObjectUtil.isNotNull(vo.getAuditUserId())) {
            sysUserIds.add(vo.getAuditUserId());
        }
        if (ObjectUtil.isNotNull(vo.getInvoiceProgressingUserId())) {
            sysUserIds.add(vo.getInvoiceProgressingUserId());
        }
        if (ObjectUtil.isNotNull(vo.getMakeInvoiceUserId())) {
            sysUserIds.add(vo.getMakeInvoiceUserId());
        }
        if (ObjectUtil.isNotNull(vo.getReceiveInvoiceUserId())) {
            sysUserIds.add(vo.getReceiveInvoiceUserId());
        }
        if (ObjectUtil.isNotNull(vo.getMailTickUserId())) {
            sysUserIds.add(vo.getMailTickUserId());
        }
        if (ObjectUtil.isNotNull(vo.getPayoffAccountUserId())) {
            sysUserIds.add(vo.getPayoffAccountUserId());
        }

        Map<Long, SysUser>     sysUserMap     = sysUserService.convertSysUserIds2MapSysUserId2Entity(sysUserIds);
        Map<Long, InvoiceType> invoiceTypeMap = invoiceTypeService.convertToMapFieldId2Entity();

        // 补 状态名称
        vo.setAuditStatusName(InvoiceApplyAuditStatusEnum.getDesc(vo.getAuditStatus()));
        vo.setInvoiceProgressingStatusName(InvoiceApplySupplierInvoiceProgressingStatusEnum.getDesc(vo.getInvoiceStatus()));
        vo.setMakeInvoiceStatusName(InvoiceApplySupplierMakeInvoiceStatusEnum.getDesc(vo.getMakeInvoiceStatus()));
        vo.setReceiveInvoiceStatusName(InvoiceApplySupplierReceiveInvoiceStatusEnum.getDesc(vo.getReceiveInvoiceStatus()));
        vo.setMailTickStatusName(InvoiceApplySupplierMailTickStatusEnum.getDesc(vo.getMailTickStatus()));
        vo.setPayoffAccountStatusName(InvoiceApplySupplierPayOffAccountStatusEnum.getDesc(vo.getPayoffAccountStatus()));

        // 补 人员信息
        if (sysUserMap.get(vo.getApplyUserId()) != null) {
            vo.setApplyUserName(sysUserMap.get(vo.getApplyUserId()).getFullname());
        }
        if (sysUserMap.get(vo.getAuditUserId()) != null) {
            vo.setAuditUserName(sysUserMap.get(vo.getAuditUserId()).getFullname());
        }
        if (sysUserMap.get(vo.getInvoiceProgressingUserId()) != null) {
            vo.setInvoiceProgressingUserName(sysUserMap.get(vo.getInvoiceProgressingUserId()).getFullname());
        }
        if (sysUserMap.get(vo.getMakeInvoiceUserId()) != null) {
            vo.setMakeInvoiceUserName(sysUserMap.get(vo.getMakeInvoiceUserId()).getFullname());
        }
        if (sysUserMap.get(vo.getReceiveInvoiceUserId()) != null) {
            vo.setReceiveInvoiceUserName(sysUserMap.get(vo.getReceiveInvoiceUserId()).getFullname());
        }
        if (sysUserMap.get(vo.getMailTickUserId()) != null) {
            vo.setMailTickUserName(sysUserMap.get(vo.getMailTickUserId()).getFullname());
        }
        if (sysUserMap.get(vo.getPayoffAccountUserId()) != null) {
            vo.setPayoffAccountUserName(sysUserMap.get(vo.getPayoffAccountUserId()).getFullname());
        }

        // 补 发票种类
        if (invoiceTypeMap.get(AnLongUtils.getLong(vo.getInvoiceType())) != null) {
            vo.setInvoiceTypeName(invoiceTypeMap.get(AnLongUtils.getLong(vo.getInvoiceType())).getTypeName());
        }


        /****************************************** 供应商结算2.0 详情 这个明细可以不要,改为导出excel start ******************************************/


        List<InvoiceApplySupplierDetailDimGoodsItemVo> innerGoodsList = invoiceApplySupplierXGoodsService.getInvoiceApplySupplierDetailInnerGoodsList(
                InvoiceApplySupplierOpDetailInnerGoodsListQueryCriteria
                        .builder()
                        .invoiceApplySn(invoiceApplySupplier.getInvoiceApplySn())
                        .build()
        );

        vo.setGoods(innerGoodsList);

        /****************************************** 供应商结算2.0 详情 这个明细可以不要,改为导出excel   end ******************************************/

        return vo;
    }

    @Override
    public List<InvoiceApplySupplierSelectGoodsVo> getStatementOfAccountGoodsListByAccountingOrderSn(String accountingOrderSn) {
        return invoiceApplySupplierService.getStatementOfAccountGoodsListByAccountingOrderSn(accountingOrderSn);
    }

    @Override
    public List<InvoiceApplySupplierSelectGoodsVo> getStatementOfAccountGoodsListBySysUnifiedOrderGoodsIds(String accountingOrderSn, List<Long> processSysUnifiedOrderGoodsIds) {
        return invoiceApplySupplierService.getStatementOfAccountGoodsListBySysUnifiedOrderGoodsIds(accountingOrderSn, processSysUnifiedOrderGoodsIds);
    }

    /****************************************** 开票申请 start ******************************************/
    @Override
    public List<InvoiceApplySupplierSelectGoodsVo> invoiceApplySelectFocusUnified(String accountingOrderSn) {
        return invoiceApplySupplierService.invoiceApplySelectFocusUnified(accountingOrderSn);
    }

    @Override
    public InvoiceApplySupplier opInvoiceApply(InvoiceApplySupplierOpApplyForm invoiceApplySupplierOpApplyForm, LoginSysUser loginSysUser) {


        String invoiceApplySn = unifiedSnConfigService.getSupplierInvoiceApplySnBySnowflake();

        InvoiceApplySupplier invoiceApplySupplierEntity = new InvoiceApplySupplier();

        /****************************************** 发票信息部分 start ******************************************/

        invoiceApplySupplierEntity.setAccountingOrderId(invoiceApplySupplierOpApplyForm.getAccountingOrderId());
        invoiceApplySupplierEntity.setAccountingOrderSn(invoiceApplySupplierOpApplyForm.getAccountingOrderSn());

        // AccountingOrderTypeDimEnum
        invoiceApplySupplierEntity.setAccountingOrderType(invoiceApplySupplierOpApplyForm.getAccountingOrderType());
        // AccountingOrderDimCreateByEnum
        invoiceApplySupplierEntity.setDimCreateBy(invoiceApplySupplierOpApplyForm.getDimCreateBy());

        invoiceApplySupplierEntity.setInvoiceApplySn(invoiceApplySn);
        invoiceApplySupplierEntity.setInvoiceType(invoiceApplySupplierOpApplyForm.getInvoiceType());
        invoiceApplySupplierEntity.setInvoiceTitle(invoiceApplySupplierOpApplyForm.getInvoiceTitle());

        invoiceApplySupplierEntity.setTaxRate(invoiceApplySupplierOpApplyForm.getTaxRate());

        // 兼容做法 供应商|商户 发票抬头信息
//		if (ObjectUtil.isNotNull(invoiceApplySupplierOpApplyForm.getSysSupplierExtInvoiceId())) {
//			invoiceApplySupplierEntity.setSysSupplierExtInvoiceId(invoiceApplySupplierOpApplyForm.getSysSupplierExtInvoiceId());
//			SysSupplierExtInvoice sysSupplierExtInvoice = sysSupplierExtInvoiceService.findSysSupplierExtInvoiceById(invoiceApplySupplierOpApplyForm.getSysSupplierExtInvoiceId());
//			if (ObjectUtil.isNotNull(sysSupplierExtInvoice)) {
//				invoiceApplySupplierEntity.setSysSupplierExtInvoiceSnapshot(JSONUtil.toJsonStr(sysSupplierExtInvoice));
//			}
//
//		} else {
//			invoiceApplySupplierEntity.setSysSupplierExtInvoiceId(0L);
//		}

        invoiceApplySupplierEntity.setSysSupplierExtInvoiceId(0L);

        // 兼容做法 平台方作为付款方 发票抬头信息
        if (ObjectUtil.isNotNull(invoiceApplySupplierOpApplyForm.getSysPlatformExtInvoiceId())) {
            invoiceApplySupplierEntity.setSysPlatformExtInvoiceId(invoiceApplySupplierOpApplyForm.getSysPlatformExtInvoiceId());
            InvoiceBankInfo sysPlatformExtInvoice = invoiceBankInfoService.getInvoiceBankInfoById(invoiceApplySupplierOpApplyForm.getSysPlatformExtInvoiceId());
            if (ObjectUtil.isNotNull(sysPlatformExtInvoice)) {
                invoiceApplySupplierEntity.setSysPlatformExtInvoiceSnapshot(JSONUtil.toJsonStr(sysPlatformExtInvoice));
            }

        } else {
            invoiceApplySupplierEntity.setSysPlatformExtInvoiceId(0L);
        }


        /****************************************** 发票申请部分 start ******************************************/
        if (invoiceApplySupplierOpApplyForm.getApplyTime() != null) {
            //保留集采的申请时间
            invoiceApplySupplierEntity.setApplyTime(invoiceApplySupplierOpApplyForm.getApplyTime());
        } else {
            invoiceApplySupplierEntity.setApplyTime(DateUtil.date());
        }
        invoiceApplySupplierEntity.setApplyUserId(loginSysUser.getSysUserId());
        invoiceApplySupplierEntity.setApplyUserName(loginSysUser.getSysUserName());

        /****************************************** 发票申请审核部分 start ******************************************/

        invoiceApplySupplierEntity.setAuditStatus(InvoiceApplyAuditStatusEnum.未审核.getKey());

        /****************************************** 开票进展部分 start ******************************************/

        invoiceApplySupplierEntity.setInvoiceStatus(InvoiceApplySupplierInvoiceProgressingStatusEnum.待开票.getKey());
        invoiceApplySupplierEntity.setInvoiceTitle(invoiceApplySupplierOpApplyForm.getInvoiceTitle());
        invoiceApplySupplierEntity.setInvoiceType(invoiceApplySupplierOpApplyForm.getInvoiceType());

        /****************************************** 开票登记部分 start ******************************************/

        invoiceApplySupplierEntity.setMakeInvoiceStatus(InvoiceApplySupplierMakeInvoiceStatusEnum.未开票.getKey());

        /****************************************** 寄票登记部分 start ******************************************/

        invoiceApplySupplierEntity.setMailTickStatus(InvoiceApplySupplierMailTickStatusEnum.未邮寄.getKey());

        /****************************************** 收票登记部分 start ******************************************/

        invoiceApplySupplierEntity.setReceiveInvoiceStatus(InvoiceApplySupplierReceiveInvoiceStatusEnum.未收票.getKey());

        /****************************************** 付款登记部分 start ******************************************/

        invoiceApplySupplierEntity.setPayoffAccountStatus(InvoiceApplySupplierPayOffAccountStatusEnum.待付款.getKey());

        invoiceApplySupplierEntity.setRemark(invoiceApplySupplierOpApplyForm.getRemark());

//        // 前端传过来 UnifiedOrderGoodsIds
//        List<Long> processSysUnifiedOrderGoodsIds = SuperdeskStringUtils.stringArrayConvertToLongList(invoiceApplyParams.getIds(), ",");
//
//        log.info("\nopInvoiceApply {}: \n\n\n\n{}\n\n\n\n", processSysUnifiedOrderGoodsIds.size(), JsonUtils.toJson(processSysUnifiedOrderGoodsIds));
//
//        List<InvoiceApplySupplierSelectGoodsVo> invoiceApplySupplierSelectGoodsVoList = unifiedSupplierInvService.getStatementOfAccountGoodsListBySysUnifiedOrderGoodsIds(processSysUnifiedOrderGoodsIds);
//
//        log.info("\nopInvoiceApply {} 转换后", invoiceApplySupplierSelectGoodsVoList.size());

        /****************************************** 重构 start ******************************************/

        List<InvoiceApplySupplierSelectGoodsVo> invoiceApplySupplierSelectGoodsVoList = new ArrayList<>();


        List<InvoiceApplySupplierOpApplyFormItem> packageList = invoiceApplySupplierOpApplyForm.getPackageList();
//		List<InvoiceApplySupplierOpAddParamsPackage> packageList = AnJsonUtils.toList(invoiceApplySupplierOpApplyForm.getJsonStr(), InvoiceApplySupplierOpAddParamsPackage.class);
        log.info("供应商 创建对账单 包体 {}", JSONUtil.toJsonStr(packageList));


        /**
         * String 对账单Sn List<Long> UnifiedOrderGoodsIds
         */
        Map<String, List<Long>> processAccountingOrderList = packageList.parallelStream()
                .collect(Collectors.groupingBy(InvoiceApplySupplierOpApplyFormItem::getAccountingOrderSn, Collectors.mapping(InvoiceApplySupplierOpApplyFormItem::getUnifiedOrderGoodsId, Collectors.toList())));

        for (Map.Entry<String, List<Long>> _entry : processAccountingOrderList.entrySet()) {

            List<InvoiceApplySupplierSelectGoodsVo> sampleData = invoiceApplySupplierService.getStatementOfAccountGoodsListBySysUnifiedOrderGoodsIds(_entry.getKey(), _entry.getValue());

            if (CollUtil.isNotEmpty(sampleData)) {
                invoiceApplySupplierSelectGoodsVoList.addAll(sampleData);
            }
        }

        /****************************************** 重构   end ******************************************/


        // 标记 他们是一伙的
//        // 订单数量
//        Map<String, String> orderQuantity = new HashMap<>();
//        // 订单金额
//        BigDecimal orderAmount = BigDecimal.ZERO;

        List<InvoiceApplySupplierXGoods> invoiceApplyXGoodsProcessList = new ArrayList<>();

        for (InvoiceApplySupplierSelectGoodsVo invoiceApplySupplierSelectGoodsVo : invoiceApplySupplierSelectGoodsVoList) {

            InvoiceApplySupplierXGoods invoiceApplySupplierXGoodsItem = new InvoiceApplySupplierXGoods();

//			invoiceApplySupplierXGoodsItem.setAccountingOrderId(invoiceApplySupplierSelectGoodsVo.getAccountingOrderId());
            invoiceApplySupplierXGoodsItem.setAccountingOrderId(invoiceApplySupplierOpApplyForm.getAccountingOrderId());
            invoiceApplySupplierXGoodsItem.setAccountingOrderSn(invoiceApplySupplierSelectGoodsVo.getAccountingOrderSn());

            invoiceApplySupplierXGoodsItem.setAccountingOrderType(invoiceApplySupplierEntity.getAccountingOrderType());
            invoiceApplySupplierXGoodsItem.setDimCreateBy(invoiceApplySupplierEntity.getDimCreateBy());

//			invoiceApplySupplierXGoodsItem.setInvoiceApplyId(invoiceApplySupplierEntity.getId());
            invoiceApplySupplierXGoodsItem.setInvoiceApplySn(invoiceApplySupplierEntity.getInvoiceApplySn());

//			invoiceApplySupplierXGoodsItem.setUnifiedOrderId(invoiceApplySupplierSelectGoodsVo);
            invoiceApplySupplierXGoodsItem.setOrderSn(invoiceApplySupplierSelectGoodsVo.getOrderSn());

            invoiceApplySupplierXGoodsItem.setUnifiedOrderGoodsId(invoiceApplySupplierSelectGoodsVo.getUnifiedOrderGoodsId());
            invoiceApplySupplierXGoodsItem.setGoodsId(invoiceApplySupplierSelectGoodsVo.getGoodsId());

            invoiceApplySupplierXGoodsItem.setBackStatus(InvoiceApplySupplierItemPayOffStatusEnum.待付款.getKey());

            // 标记 他们是一伙的
//            if (!orderQuantity.containsKey(unifiedInvGoodsVo.getOrderSn())) {
//                orderQuantity.put(unifiedInvGoodsVo.getOrderSn(), unifiedInvGoodsVo.getOrderSn());
//            }
//
//            orderAmount = orderAmount.add(new BigDecimal(unifiedInvGoodsVo.getCostPrice().multiply(new BigDecimal(unifiedInvGoodsVo.getQuantity())).toString()));

            invoiceApplyXGoodsProcessList.add(invoiceApplySupplierXGoodsItem);
        }


        // 统计修正 mark by linjinyu 20201105
        /****************************************** 统计 start ******************************************/

        // 标记 他们是一伙的
//        invoiceApplyEntity.setOrderAmount(orderAmount);
//        invoiceApplyEntity.setOrderQuantity(orderQuantity.size());

        Long accountingOrderSnCount = invoiceApplySupplierSelectGoodsVoList.stream().filter(AnLamdaUtils.distinctByKey(o -> o.getAccountingOrderSn())).map(o -> o.getAccountingOrderSn()).collect(Collectors.counting());
        Long orderSnCount           = invoiceApplySupplierSelectGoodsVoList.stream().filter(AnLamdaUtils.distinctByKey(o -> o.getOrderSn())).map(o -> o.getOrderSn()).collect(Collectors.counting());
        Long goodsQuantity          = invoiceApplySupplierSelectGoodsVoList.stream().map(o -> o.getUnifiedOrderGoodsId()).collect(Collectors.counting());
        Long goodsItemQuantity      = invoiceApplySupplierSelectGoodsVoList.stream().map(o -> o.getQuantity()).collect(Collectors.counting());

        BigDecimal goodsAmount = invoiceApplySupplierSelectGoodsVoList
                .stream()
                .map(item -> item.getPrice() == null ? BigDecimal.ZERO : item.getPrice().multiply(new BigDecimal(item.getQuantity())))
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal goodsCostAmount = invoiceApplySupplierSelectGoodsVoList
                .stream()
                .map(item -> item.getCostPrice() == null ? BigDecimal.ZERO : item.getCostPrice().multiply(new BigDecimal(item.getQuantity())))
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        invoiceApplySupplierEntity.setInvoiceApplyAmount(goodsCostAmount);

        invoiceApplySupplierEntity.setAccountingOrderQuantity(accountingOrderSnCount.intValue());
        invoiceApplySupplierEntity.setOrderQuantity(orderSnCount.intValue());
        invoiceApplySupplierEntity.setOrderAmount(goodsCostAmount);
        invoiceApplySupplierEntity.setGoodsAmount(goodsAmount);
        invoiceApplySupplierEntity.setGoodsCostAmount(goodsCostAmount);
        invoiceApplySupplierEntity.setGoodsQuantity(goodsQuantity.intValue());
        invoiceApplySupplierEntity.setGoodsItemQuantity(goodsItemQuantity.intValue());


        /****************************************** 统计   end ******************************************/

        UnifiedOrder sampleUnifiedOrderEntity = unifiedOrderService.findByOrderSn(invoiceApplyXGoodsProcessList.get(0).getOrderSn());
        invoiceApplySupplierEntity.setSaleId(sampleUnifiedOrderEntity.getSaleId());
        invoiceApplySupplierEntity.setSaleName(sampleUnifiedOrderEntity.getSaleName());
        /**
         * 20220516 订单来源处理
         */
        if (StringUtils.isNotBlank(invoiceApplySupplierOpApplyForm.getSourceFrom())) {
            invoiceApplySupplierEntity.setSourceFrom(invoiceApplySupplierOpApplyForm.getSourceFrom());
        }
        if (StringUtils.isNotBlank(invoiceApplySupplierOpApplyForm.getServiceNo())) {
            invoiceApplySupplierEntity.setServiceNo(invoiceApplySupplierOpApplyForm.getServiceNo());
        }

        return invoiceApplySupplierService.opInvoiceApply(invoiceApplySupplierEntity, invoiceApplyXGoodsProcessList);
    }

    /****************************************** 开票申请   end ******************************************/


    @Override
    public String opPhysicsDelete(InvoiceApplySupplier entity, LoginSysUser loginSysUser) {

        return invoiceApplySupplierService.opPhysicsDelete(entity, loginSysUser);
    }

    @Override
    public String opBecomeInvalid(InvoiceApplySupplier entity, LoginSysUser loginSysUser) {

        return invoiceApplySupplierService.opBecomeInvalid(entity, loginSysUser);
    }

    @Override
    public String opBecomeInvalid(List<InvoiceApplySupplier> entitys, InvoiceApplySupplierOpCommonDimAccountingOrderForm form, LoginSysUser loginSysUser) {

        return invoiceApplySupplierService.opBecomeInvalid(entitys, form, loginSysUser);
    }


    @Override
    public void patchInvoiceApplyFieldStatistics() {
        invoiceApplySupplierService.patchInvoiceApplyFieldStatistics();
    }

    /****************************************** 开票申请页面 导出数据 start ******************************************/


    private static Map<Integer, Function<List<InvoiceApplySupplierDetailDimGoodsItemVo>, SysNotify>> modeOfExportExcelInvoiceApplySupplierFocusScoreDimGoods = new HashMap<>();


    public String exportExcelInvoiceApplySupplierFocusScoreDimGoods(InvoiceApplySupplierPageVoListQueryCriteria queryCriteria, LoginSysUser loginSysUser) {

        // 初始化
        // 侨城汇
        //	|---- 1. 搜索框 条件 结算集
        //	|---- 2. 搜索框 条件 结算集 后 界面上 勾选 要以 开票申请编号 分 sheet 分合并前 合并后
        //	|---- 3. 搜索框 条件 结算集 后 界面上 勾选 要以 开票申请编号 分 sheet 财务专用
        modeOfExportExcelInvoiceApplySupplierFocusScoreDimGoods.put(1, (resultList) -> invoiceApplySupplierExportExcelService.exportExcelInvoiceApplySupplierFocusScoreDimGoodsMode1(resultList));
        modeOfExportExcelInvoiceApplySupplierFocusScoreDimGoods.put(2, (resultList) -> invoiceApplySupplierExportExcelService.exportExcelInvoiceApplySupplierFocusScoreDimGoodsMode2(resultList));
        modeOfExportExcelInvoiceApplySupplierFocusScoreDimGoods.put(3, (resultList) -> invoiceApplySupplierExportExcelService.exportExcelInvoiceApplySupplierFocusScoreDimGoodsMode3(resultList));

        // 异步操作 包裹 mark by linjinyu at 20210317
        log.info("\n异步操作 包裹 外层 exportExcelInvoiceApplySupplierFocusScoreDimGoods params: \n{}", JSONUtil.toJsonStr(queryCriteria));

        /****************************************** 合并 invoiceApplyId start ******************************************/

        List<Long> queryInvoiceApplyIds = new ArrayList<>();
        if (ObjectUtil.isNotNull(queryCriteria.getInvoiceApplyId())) {
            queryInvoiceApplyIds.add(queryCriteria.getInvoiceApplyId());
        }
        if (CollUtil.isNotEmpty(queryCriteria.getInvoiceApplyIds())) {
            queryInvoiceApplyIds.addAll(queryCriteria.getInvoiceApplyIds());
        }

        if (CollUtil.isEmpty(queryInvoiceApplyIds)) {

            log.info("queryInvoiceApplyIds => {}", JSONUtil.toJsonStr(queryInvoiceApplyIds));
            return "参数未指定,任务未能执行...";
        }

        if (ObjectUtil.isEmpty(queryCriteria.getMode())) {
            return "参数未指定,任务未能执行...";
        } else {

            Integer[] modes = {1, 2, 3};
            if (!ArrayUtil.contains(modes, queryCriteria.getMode())) {
                return "非法参数,任务未能执行...";
            }
        }

        CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {

            try {

                log.info("\n异步操作 包裹 内层 exportExcelInvoiceApplySupplierFocusScoreDimGoods params: \n{}", JSONUtil.toJsonStr(queryCriteria));


                // 三步走 mark by linjinyu at 20210317
                // 1. 数据
                // 2. 生成excel
                // 3. 通知
                List<InvoiceApplySupplierDetailDimGoodsItemVo> resultList = invoiceApplySupplierXGoodsService
                        .getInvoiceApplySupplierDetailInnerGoodsList(
                                InvoiceApplySupplierOpDetailInnerGoodsListQueryCriteria
                                        .builder()
                                        .invoiceApplyIdSelect(queryInvoiceApplyIds)
                                        .build()
                        );

                invoiceApplySupplierExportExcelService.qchNeed20210922(resultList);

                // 处理张雪的一个写都写不好的弱智逻辑 群里确认了 原话 按照我写的规则来就行了 20211210
//				发票申请管理操作按钮:"勾选导出报表(合并前后的备注字段取值都需要处理)/导出开票数据"导出数据的备注取值规则
//				规则:
//				1、取申请开票时输入的备注字段
//				2、当备注内容为空时默认显示该发票对应的对账单编号,若是备注有内容则显示备注内容和对账单编号

                resultList.forEach(item -> {
                    if (StrUtil.isNotBlank(queryCriteria.getRemark())) {

                        item.setRemark(queryCriteria.getRemark() + "&" + item.getAccountingOrderSn());
//						item.setRemarkRule(criteria.getRemark());
                    } else {
                        item.setRemark(item.getAccountingOrderSn());
//						item.setRemarkRule(item.getAccountingOrderSn());
                    }
                });

                SysNotify sysNotify = modeOfExportExcelInvoiceApplySupplierFocusScoreDimGoods.get(queryCriteria.getMode()).apply(resultList);

                sysNotify.setRemark(queryCriteria.getRemark());

                // 通知
                dubboSysNotifyService.notifyExportExcelInvoiceApplyFocusScoreDimCredit(sysNotify, loginSysUser);

                // 商户是否导出 0-未导出;1-已导出;-供应商结算2.0 private Integer saleIsExport; saleIsExport++
                invoiceApplySupplierTriggerEventPublisher.triggerTailUpdateInvoiceApplySupplierFieldSaleIsExport(
                        TailUpdateInvoiceApplySupplierFieldSaleIsExportEvent.builder()
                                .loginSysUser(loginSysUser)
                                .queryInvoiceApplyIds(queryInvoiceApplyIds)
                                .build()
                );

            } catch (Exception e2) {
                log.error("\n异步操作 包裹 内层 exportExcelInvoiceApplySupplierFocusScoreDimGoods{} -> 执行 异常:{}", JSONUtil.toJsonStr(queryCriteria), e2);
            }
        });

        return "导出任务已经接收,正在处理中...";
    }


    /****************************************** 开票申请页面 导出数据   end ******************************************/


}
