package cn.superdesk.uniorder.service.thirdpart.qchjc.account.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.superdesk.uniorder.common.HttpUtil;
import cn.superdesk.uniorder.common.enums.accounting.AccountingOrderBackAccountStatusEnum;
import cn.superdesk.uniorder.common.enums.accounting.customer.AccountingOrderCustomerAccountingStatusEnum;
import cn.superdesk.uniorder.common.enums.accounting.supplier.AccountingOrderSupplierAccountingStatusEnum;
import cn.superdesk.uniorder.common.enums.common.*;
import cn.superdesk.uniorder.common.enums.invoice.supplier.InvoiceApplySupplierInvoiceProgressingStatusEnum;
import cn.superdesk.uniorder.common.enums.invoice.supplier.InvoiceApplySupplierMakeInvoiceStatusEnum;
import cn.superdesk.uniorder.common.enums.invoice.supplier.InvoiceApplySupplierReceiveInvoiceStatusEnum;
import cn.superdesk.uniorder.common.enums.order.UnifiedOrderCreditBackAccountStatusEnum;
import cn.superdesk.uniorder.common.enums.order.UnifiedOrderCreditInvoiceApplyStatusEnum;
import cn.superdesk.uniorder.common.enums.order.UnifiedOrderCreditInvoiceMakeStatusEnum;
import cn.superdesk.uniorder.common.enums.order.UnifiedOrderCreditTypeDefaultEnum;
import cn.superdesk.uniorder.common.enums.thirdpart.qchjc.QchjcOrgEnum;
import cn.superdesk.uniorder.common.enums.thirdpart.qchjc.QchjcStorageStatusEnum;
import cn.superdesk.uniorder.common.exception.OpenApiException;
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.AnCollectionUtils;
import cn.superdesk.uniorder.common.numerical.AnStringUtils;
import cn.superdesk.uniorder.common.rest.response.R;
import cn.superdesk.uniorder.common.security.JwtUtil;
import cn.superdesk.uniorder.common.security.dto.LoginSysUser;
import cn.superdesk.uniorder.dao.entity.accounting.unified.supplier.AccountingUnifiedSupplier;
import cn.superdesk.uniorder.dao.entity.base.*;
import cn.superdesk.uniorder.dao.entity.invoice.common.InvoiceBankInfo;
import cn.superdesk.uniorder.dao.entity.invoice.supplier.InvoiceApplySupplier;
import cn.superdesk.uniorder.dao.entity.sys.SysUser;
import cn.superdesk.uniorder.dao.entity.thirdpart.qchjc.accounting.*;
import cn.superdesk.uniorder.dao.entity.thirdpart.qchjc.invoice.QchjcInvoiceApplySupplierEntity;
import cn.superdesk.uniorder.dao.entity.thirdpart.qchjc.invoice.QchjcInvoiceApplySupplierEntityExample;
import cn.superdesk.uniorder.dao.entity.thirdpart.qchjc.organisation.QchjcEnterpriseEntity;
import cn.superdesk.uniorder.dao.entity.thirdpart.qchjc.organisation.QchjcSupplierEntity;
import cn.superdesk.uniorder.dao.entity.thirdpart.qchjc.organisation.QchjcSupplierEntityExample;
import cn.superdesk.uniorder.dao.mapper.base.*;
import cn.superdesk.uniorder.dao.mapper.organisation.UnifiedSupplierMapperEx;
import cn.superdesk.uniorder.dao.mapper.thirdpart.qchjc.accounting.*;
import cn.superdesk.uniorder.dao.mapper.thirdpart.qchjc.invoice.QchjcInvoiceApplySupplierEntityMapper;
import cn.superdesk.uniorder.dao.mapper.thirdpart.qchjc.organisation.QchjcEnterpriseEntityMapper;
import cn.superdesk.uniorder.dao.mapper.thirdpart.qchjc.organisation.QchjcSupplierEntityMapper;
import cn.superdesk.uniorder.dto.param.accounting.qchjc.QchjcSupplierAccountingListRequest;
import cn.superdesk.uniorder.dto.param.accounting.unified.supplier.AccountingUnifiedSupplierCreateParamDimGoodsSelected;
import cn.superdesk.uniorder.dto.param.accounting.unified.supplier.AccountingUnifiedSupplierOpCreateParamDimGoods;
import cn.superdesk.uniorder.dto.param.invoice.supplier.InvoiceApplySupplierOpApplyForm;
import cn.superdesk.uniorder.dto.param.invoice.supplier.InvoiceApplySupplierOpApplyFormItem;
import cn.superdesk.uniorder.dto.param.invoice.supplier.status.InvoiceApplySupplierOpCommonDimAccountingOrderForm;
import cn.superdesk.uniorder.dto.param.invoice.supplier.status.InvoiceApplySupplierOpCommonDimAccountingOrderItem;
import cn.superdesk.uniorder.dto.param.setting.UnifiedServicePartGoodsTransportParam;
import cn.superdesk.uniorder.dto.param.thirdpart.qchjc.accounting.QchjcAccountingUnifiedSupplierParam;
import cn.superdesk.uniorder.dto.param.thirdpart.qchjc.accounting.QchjcOrderGoodsParam;
import cn.superdesk.uniorder.dto.param.thirdpart.qchjc.accounting.QchjcOrderParam;
import cn.superdesk.uniorder.dto.param.thirdpart.qchjc.accounting.QchjcSupplierStorageParam;
import cn.superdesk.uniorder.dto.param.thirdpart.qchjc.api.QchjcResponse;
import cn.superdesk.uniorder.dto.param.thirdpart.qchjc.api.supplier.QchjcSupplierCancelStatementParam;
import cn.superdesk.uniorder.dto.param.thirdpart.qchjc.api.supplier.QchjcSupplierPaymentStatusSyncParam;
import cn.superdesk.uniorder.dto.param.thirdpart.qchjc.api.supplier.QchjcSupplierReceiveInvoiceStatusParam;
import cn.superdesk.uniorder.dto.param.thirdpart.qchjc.invoice.QchjcSupplierInoviceApplyParam;
import cn.superdesk.uniorder.dto.vo.organisation.UnifiedSupplierVo;
import cn.superdesk.uniorder.dto.vo.thirdpart.qchjc.accounting.QchjcAccountingUnifiedSupplierVo;
import cn.superdesk.uniorder.dto.vo.thirdpart.qchjc.accounting.QchjcOrderGoodsVo;
import cn.superdesk.uniorder.dto.vo.thirdpart.qchjc.accounting.QchjcOrderVo;
import cn.superdesk.uniorder.dto.vo.thirdpart.qchjc.invoice.QchjcInvoiceSupplierApplyVo;
import cn.superdesk.uniorder.service.accounting.unified.supplier.AccountingUnifiedSupplierService;
import cn.superdesk.uniorder.service.order.base.CommonOrderProcessService;
import cn.superdesk.uniorder.service.order.base.CommonOrderTransportProcessService;
import cn.superdesk.uniorder.service.invoice.supplier.InvoiceApplySupplierFieldPayoffAccountStatusService;
import cn.superdesk.uniorder.service.invoice.supplier.InvoiceApplySupplierService;
import cn.superdesk.uniorder.service.setting.UnifiedServiceService;
import cn.superdesk.uniorder.service.sys.SysUserService;
import cn.superdesk.uniorder.service.thirdpart.qchjc.account.QchjcSupplierStatementService;
import cn.superdesk.uniorder.service.thirdpart.qchjc.log.QchjcLogService;
import com.alibaba.fastjson2.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * @author xc
 * @description
 * @date 2022/4/1 18:36
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class QchjcSupplierStatementServiceImpl implements QchjcSupplierStatementService {

    private final QchjcAccountingUnifiedSupplierEntityMapper qchAccountingUnifiedSupplierEntityMapper;
    private final QchjcUserEntityMapper                      qchjcUserEntityMapper;
    private final SysUserService                             sysUserService;
    private final QchjcOrderGoodsEntityMapper qchOrderGoodsEntityMapper;
    private final QchjcOrderEntityMapper                     qchOrderEntityMapper;
    private final QchjcSupplierEntityMapper                  qchjcSupplierEntityMaper;
    private final CommonOrderTransportProcessService         commonOrderTransportProcessService;
    private final CommonOrderProcessService                  commonOrderProcessService;
    private final UnifiedOrderMapper                         unifiedOrderMapper;
    private final UnifiedOrderCreditMapper                   unifiedOrderCreditMapper;
    private final UnifiedOrderCreditMapperEx unifiedOrderCreditMapperEx;
    private final UnifiedOrderGoodsMapper                    unifiedOrderGoodsMapper;
    private final UnifiedOrderGoodsMapperEx unifiedOrderGoodsMapperEx;
    private final QchjcSupplierBackAccountEntityMapper                qchjcSupplierBackAccountEntityMapper;
    private final InvoiceApplySupplierService                         invoiceApplySupplierService;
    private final QchjcInvoiceApplySupplierEntityMapper               qchjcInvoiceApplySupplierEntityMapper;
    private final AccountingUnifiedSupplierService                    accountingUnifiedSupplierService;
    private final InvoiceApplySupplierFieldPayoffAccountStatusService invoiceApplySupplierFieldPayoffAccountStatusService;
    private final QchjcEnterpriseEntityMapper                         qchjcEnterpriseEntityMapper;

    private final QchjcLogService       qchjcLogService;
    private final UnifiedServiceService unifiedServiceService;

    private final UnifiedSupplierMapperEx unifiedSupplierMapperEx;

    @Value(value = "${qchjc.domain}")
    private String  domain;
    @Value(value = "${qchjc.supplier.receiveInvoiceStatusSyncApi}")
    private String  supplierReceiveInvoiceStatusSyncApi;
    @Value(value = "${qchjc.supplier.paymentStatusSyncApi}")
    private String  paymentStatusSyncApi;
    @Value(value = "${qchjc.supplier.statementCancelApi}")
    private String  statementCancelApi;
    @Value(value = "${qchjc.push.enable}")
    private boolean pushEnabled;

    @Override
    public int insertSelective(QchjcAccountingUnifiedSupplierEntity qchjcAccountingUnifiedSupplierEntity) {
        return qchAccountingUnifiedSupplierEntityMapper.insertSelective(qchjcAccountingUnifiedSupplierEntity);
    }

    @Override
    public int updateByPrimaryKeySelective(QchjcAccountingUnifiedSupplierEntity qchjcAccountingUnifiedSupplierEntity) {
        return qchAccountingUnifiedSupplierEntityMapper.updateByPrimaryKeySelective(qchjcAccountingUnifiedSupplierEntity);
    }

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

    @Override
    public QchjcAccountingUnifiedSupplierEntity findById(Long id) {
        return null;
    }

    @Override
    public List<QchjcAccountingUnifiedSupplierEntity> findAll(Map<String, Object> queryMap) {
        return null;
    }

    @Override
    public PageInfo<QchjcAccountingUnifiedSupplierEntity> findByPaging(Map<String, Object> params, Integer pageNo, Integer pageSize) {
        return null;
    }

    /**
     * 接收集采供应商对账单数据
     *
     * @param data
     * @throws OpenApiException
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void receive(String data) throws OpenApiException {

        QchjcAccountingUnifiedSupplierParam param = AnJsonUtils.toObject(data, QchjcAccountingUnifiedSupplierParam.class);

        //校验参数
        String                     sellerSupplierId           = param.getSellerSupplierId();
        QchjcSupplierEntityExample qchjcSupplierEntityExample = new QchjcSupplierEntityExample();
        qchjcSupplierEntityExample.createCriteria().andSupplierIdEqualTo(sellerSupplierId);
        List<QchjcSupplierEntity> qchjcSupplierEntities = qchjcSupplierEntityMaper.selectByExample(qchjcSupplierEntityExample);
        if (CollectionUtils.isEmpty(qchjcSupplierEntities) || null == qchjcSupplierEntities.get(0)) {
            throw new OpenApiException(500, "供应商ID在供应商数据库中不存在，请先同步供应商");
        }

        QchjcAccountingUnifiedSupplierEntityExample supplierEntityExample = new QchjcAccountingUnifiedSupplierEntityExample();
        supplierEntityExample.createCriteria()
                .andAccountingOrderSnEqualTo(param.getAccountingOrderSn());
        List<QchjcAccountingUnifiedSupplierEntity> list   = qchAccountingUnifiedSupplierEntityMapper.selectByExample(supplierEntityExample);
        QchjcAccountingUnifiedSupplierEntity       origin = null;

        if (CollectionUtils.isNotEmpty(list)) {
            origin = list.get(0);
            if (QchjcStorageStatusEnum.PROCESSING.getStatus().equals(origin.getStorageStatus())
                    || QchjcStorageStatusEnum.SUCCESS.getStatus().equals(origin.getStorageStatus())) {
                throw new OpenApiException(500, "该对账单已存在，处于入库中或入库成功，请勿重复推送对账单");
            }
        }

        //1.保存操作人员信息
        handleUser(param);
        //2.保存商品、订单信息
        Integer count = handleGoodsAndOrder(param, origin);
        //3.保存对账单主体信息
        param.setOrderGoodsCount(count);
        handleSupplierStatement(param, origin);
    }


    /**
     * 集采-获取待入库状态供应商对账单集合
     *
     * @return
     */
    @Override
    public QchjcAccountingUnifiedSupplierVo getTodoList(Long id) {
        return qchAccountingUnifiedSupplierEntityMapper.getTodoList(id);

    }

    @Override
    public QchjcAccountingUnifiedSupplierEntity selectByPrimaryKey(Long id) {
        return qchAccountingUnifiedSupplierEntityMapper.selectByPrimaryKey(id);
    }

    /**
     * 供应商对账单状态同步 集采 -> 结算中心
     *
     * @param toJSONString
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void syncStatus(String toJSONString) {
        QchjcSupplierBackAccountEntity entity = AnJsonUtils.toObject(toJSONString, QchjcSupplierBackAccountEntity.class);
        //数据库留存一份
        entity.setSyncTime(DateUtil.date());
        qchjcSupplierBackAccountEntityMapper.insertSelective(entity);

        if (entity.getBackAccountStatus() != 2) {
            throw new OpenApiException(500, "只接收全部付款");
        }
        String                               accountingOrderSn                    = entity.getAccountingOrderSn();
        QchjcAccountingUnifiedSupplierEntity qchjcAccountingUnifiedSupplierEntity = qchAccountingUnifiedSupplierEntityMapper.selectByAccountingOrderSn(accountingOrderSn);
        if (qchjcAccountingUnifiedSupplierEntity == null) {
            throw new OpenApiException(500, "对账单信息未同步，请先同步对账单");
        }


        //调用统一订单方法更新供应商对账单付款状态处理
        AccountingUnifiedSupplier accountingUnifiedSupplier = accountingUnifiedSupplierService.findByAccountingOrderSn(accountingOrderSn);
        if (accountingUnifiedSupplier == null) {
            throw new OpenApiException(500, "该对账单不存在，请检查");
        }
        //对账单已取消
        if (AccountingOrderSupplierAccountingStatusEnum.已取消.getKey().equals(accountingUnifiedSupplier.getAccountingStatus())) {
            throw new OpenApiException(500, "该对账单已取消，请检查");
        }
        //查询数据库中的开票申请
        List<InvoiceApplySupplier> entitysExistDb = invoiceApplySupplierService.findByAccountingOrderSn(accountingOrderSn);
        if (CollectionUtils.isEmpty(entitysExistDb)) {
            throw new OpenApiException(500, "数据异常，对账单下没有开票申请");
        }
        //过滤掉已作废的开票申请
        List<InvoiceApplySupplier> collect = entitysExistDb.stream().filter(i -> !InvoiceApplySupplierInvoiceProgressingStatusEnum.已作废.getKey().equals(i.getInvoiceStatus())).collect(Collectors.toList());

        if (CollectionUtils.isEmpty(collect)) {
            throw new OpenApiException(500, "该对账单非回款流程节点，请检查");
        }

        //判断是否有处于非待付款节点的开票申请
        List<InvoiceApplySupplier> inconformity = collect.stream().filter(i -> !InvoiceApplySupplierInvoiceProgressingStatusEnum.待付款.getKey().equals(i.getInvoiceStatus())).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(inconformity)) {
            throw new OpenApiException(500, "该对账单非回款流程节点，请检查");
        }
        //所有待回款节点的开票申请
        List<InvoiceApplySupplier> conformity = entitysExistDb.stream().filter(i -> InvoiceApplySupplierInvoiceProgressingStatusEnum.待付款.getKey().equals(i.getInvoiceStatus())).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(conformity)) {
            throw new OpenApiException(500, "该对账单非回款流程节点，请检查");
        }

        try {
            //处理用户
            handle(entity.getBackAccountUserId(), entity.getBackAccountUserName());

            InvoiceApplySupplierOpCommonDimAccountingOrderForm form = new InvoiceApplySupplierOpCommonDimAccountingOrderForm();
            form.setAccountingOrderId(accountingUnifiedSupplier.getId());
            form.setAccountingOrderSn(accountingOrderSn);
            form.setOutSaleId(accountingUnifiedSupplier.getSaleId());
            form.setOutSaleName(accountingUnifiedSupplier.getSaleName());
            form.setReason(entity.getRemark());
            List<InvoiceApplySupplierOpCommonDimAccountingOrderItem> invoiceApplySupplierList = new ArrayList<>();
            //构造表单参数 - 待回款的开票申请
            for (InvoiceApplySupplier invoiceApplySupplier : conformity) {
                InvoiceApplySupplierOpCommonDimAccountingOrderItem item = new InvoiceApplySupplierOpCommonDimAccountingOrderItem();
                item.setInvoiceApplyId(invoiceApplySupplier.getId());
                item.setInvoiceApplySn(invoiceApplySupplier.getInvoiceApplySn());
                invoiceApplySupplierList.add(item);
            }
            form.setInvoiceApplySupplierList(invoiceApplySupplierList);
            Long         unifiedId = qchjcUserEntityMapper.selectByOutId(entity.getBackAccountUserId()).getUnifiedId();
            LoginSysUser login     = LoginSysUser.builder().sysUserId(unifiedId).sysUserName(entity.getBackAccountUserName()).build();
            invoiceApplySupplierFieldPayoffAccountStatusService.opComplete(conformity, form, login);
        } catch (Exception e) {
            log.info("结算中心供应商回款状态同步失败，对账单编号：{},异常信息 : {}", accountingOrderSn, e.getLocalizedMessage());
            throw new OpenApiException(500, "结算中心供应商回款状态同步失败");
        }
        //更新中间表状态
        qchjcAccountingUnifiedSupplierEntity.setBackAccountStatus(AccountingOrderBackAccountStatusEnum.全部回款.getKey());//已付款
        qchjcAccountingUnifiedSupplierEntity.setUpdateTime(entity.getBackAccountTime());
        qchjcAccountingUnifiedSupplierEntity.setUpdateUserId(entity.getBackAccountUserId());
        qchjcAccountingUnifiedSupplierEntity.setUpdateUserName(entity.getBackAccountUserName());
        qchAccountingUnifiedSupplierEntityMapper.updateByPrimaryKeySelective(qchjcAccountingUnifiedSupplierEntity);
    }

    /**
     * 供应商收票状态同步 结算中心 -> 集采
     *
     * @param param
     * @return
     */
    @Override
    @Async
    public void receiveInvoiceStatusSync(QchjcSupplierReceiveInvoiceStatusParam param) {
        if (!pushEnabled) {
            //推送未启用
            return;
        }
        log.info("供应商收票状态同步 结算中心 -> 集采,param:{}", JSON.toJSONString(param));
        String                               accountingSn = param.getReconciliationSupplierCode();
        QchjcAccountingUnifiedSupplierEntity entity       = qchAccountingUnifiedSupplierEntityMapper.selectByAccountingOrderSn(accountingSn);
        if (entity == null) {
            return;
        }
        if (AccountingOrderSupplierAccountingStatusEnum.已取消.getKey().equals(entity.getReceiveInvoiceStatus())) {
            return;
        }
        QchjcResponse response = null;
        try {
            String result = HttpUtil.post(JSON.toJSONString(param), domain + supplierReceiveInvoiceStatusSyncApi);
            log.info("供应商收票状态同步 结算中心 -> 集采，参数：{}，返回结果：{}", JSON.toJSONString(param), result);
            response = JSON.parseObject(result, QchjcResponse.class);
        } catch (Exception e) {
            log.info("供应商收票状态同步 结算中心 -> 集采，参数：{}，异常：{}", JSON.toJSONString(param), e.getMessage());
            response = QchjcResponse.builder()
                    .success(false)
                    .resultMessage("供应商收票状态同步异常")
                    .build();
        } finally {
            if (response != null) {
                qchjcLogService.record(response.isSuccess() ? 1 : 0, "供应商收票状态推送", JSON.toJSONString(param), JSON.toJSONString(response));
            }
        }


        //中间表处理
        entity.setReceiveInvoiceStatus(InvoiceApplySupplierReceiveInvoiceStatusEnum.已收票.getKey());//已收票
        entity.setUpdateUserId(param.getOperatorId());
        entity.setUpdateUserName(param.getOperatorName());
        entity.setUpdateTime(DateUtil.date());
        qchAccountingUnifiedSupplierEntityMapper.updateByPrimaryKeySelective(entity);

        //保存发票号
        Map<String, String> invoiceNumberMap = param.getInvoiceNumberMap();
        if (invoiceNumberMap != null && !invoiceNumberMap.isEmpty()) {
            for (Map.Entry<String, String> entry : invoiceNumberMap.entrySet()) {
                String                                 key                                    = entry.getKey();//开票申请编号
                String                                 value                                  = entry.getValue();//发票号,多个用`,`分隔
                QchjcInvoiceApplySupplierEntityExample qchjcInvoiceApplySupplierEntityExample = new QchjcInvoiceApplySupplierEntityExample();
                qchjcInvoiceApplySupplierEntityExample.createCriteria().andInvoiceApplySnEqualTo(key);
                List<QchjcInvoiceApplySupplierEntity> qchjcInvoiceApplySupplierEntities = qchjcInvoiceApplySupplierEntityMapper.selectByExample(qchjcInvoiceApplySupplierEntityExample);
                if (CollectionUtils.isNotEmpty(qchjcInvoiceApplySupplierEntities)) {
                    QchjcInvoiceApplySupplierEntity qchjcInvoiceApplySupplierEntity = qchjcInvoiceApplySupplierEntities.get(0);
                    String                          invoiceNumber                   = qchjcInvoiceApplySupplierEntity.getInvoiceNumber();
                    if (StringUtils.isNotBlank(invoiceNumber)) {
                        if (!invoiceNumber.contains(value)) {
                            value = invoiceNumber + "," + value;
                            qchjcInvoiceApplySupplierEntity.setInvoiceNumber(value);
                        }
                    } else {
                        qchjcInvoiceApplySupplierEntity.setInvoiceNumber(value);
                    }
                    qchjcInvoiceApplySupplierEntityMapper.updateByPrimaryKeySelective(qchjcInvoiceApplySupplierEntity);
                }
            }
        }
    }

    /**
     * 供应商对账单付款状态同步 结算中心 -> 集采
     *
     * @param param
     * @return
     */
    @Override
    @Async
    public void paymentStatusSync(QchjcSupplierPaymentStatusSyncParam param) {
        if (!pushEnabled) {
            //推送未启用
            return;
        }
        log.info("供应商对账单付款状态同步 结算中心 -> 集采，参数：{}", JSON.toJSONString(param));
        String                               accountingSn = param.getReconciliationSupplierCode();
        QchjcAccountingUnifiedSupplierEntity entity       = qchAccountingUnifiedSupplierEntityMapper.selectByAccountingOrderSn(accountingSn);
        if (entity == null) {
            return;
        }
        if (AccountingOrderSupplierAccountingStatusEnum.已取消.getKey().equals(entity.getAccountingStatus())) {
            return;
        }
        QchjcResponse response = null;
        try {
            String result = HttpUtil.post(JSON.toJSONString(param), domain + paymentStatusSyncApi);
            log.info("供应商对账单付款状态同步 结算中心 -> 集采，参数：{}，返回结果：{}", JSON.toJSONString(param), result);
            response = JSON.parseObject(result, QchjcResponse.class);
        } catch (Exception e) {
            log.info("供应商对账单付款状态同步 结算中心 -> 集采，参数：{}，异常：{}", JSON.toJSONString(param), e.getMessage());
            response = QchjcResponse.builder()
                    .success(false)
                    .resultMessage("供应商对账单付款状态同步异常")
                    .build();
        } finally {
            if (response != null) {
                qchjcLogService.record(response.isSuccess() ? 1 : 0, "供应商对账单付款状态推送", JSON.toJSONString(param), JSON.toJSONString(response));
            }
        }
        //中间表处理
        entity.setBackAccountStatus(AccountingOrderBackAccountStatusEnum.全部回款.getKey());
        entity.setUpdateUserId(param.getOperatorId());
        entity.setUpdateUserName(param.getOperatorName());
        entity.setUpdateTime(DateUtil.date());
        qchAccountingUnifiedSupplierEntityMapper.updateByPrimaryKeySelective(entity);
    }

    /**
     * 供应商对账单作废接口 结算中心 -> 集采
     *
     * @param param
     * @return
     */
    @Override
    @Async
    public void statementCancelSync(QchjcSupplierCancelStatementParam param) {
        if (!pushEnabled) {
            //推送未启用
            return;
        }
        log.info("结算中心 调用 集采 供应商对账单作废接口，参数：{}", JSON.toJSONString(param));
        String                               accountingSn = param.getReconciliationSupplierCode();
        QchjcAccountingUnifiedSupplierEntity entity       = qchAccountingUnifiedSupplierEntityMapper.selectByAccountingOrderSn(accountingSn);
        if (entity == null) {
            return;
        }
        QchjcResponse response = null;
        try {
            String result = HttpUtil.post(JSON.toJSONString(param), domain + statementCancelApi);
            log.info("供应商对账单作废接口 结算中心 -> 集采，参数：{}，返回结果：{}", JSON.toJSONString(param), result);
            response = JSON.parseObject(result, QchjcResponse.class);
        } catch (Exception e) {
            log.info("供应商对账单作废接口 结算中心 -> 集采，参数：{}，异常：{}", JSON.toJSONString(param), e.getMessage());
            response = QchjcResponse.builder()
                    .success(false)
                    .resultMessage("供应商对账单作废同步异常")
                    .build();
        } finally {
            if (response != null) {
                qchjcLogService.record(response.isSuccess() ? 1 : 0, "供应商对账单作废接口推送", JSON.toJSONString(param), JSON.toJSONString(response));
            }
        }
        //中间表处理
        entity.setAccountingStatus(AccountingOrderCustomerAccountingStatusEnum.已取消.getKey());
        entity.setUpdateUserId(param.getOperatorId());
        entity.setUpdateUserName(param.getOperatorName());
        entity.setUpdateTime(DateUtil.date());
        qchAccountingUnifiedSupplierEntityMapper.updateByPrimaryKeySelective(entity);


        /**
         * 20220609 取消订单、商品中间表中和对账单的关联关系
         */
        QchjcOrderEntityExample qchjcOrderEntityExample = new QchjcOrderEntityExample();
        //根据采购单位对账单sn字段把对账单与订单的关联关系取消
        qchjcOrderEntityExample.createCriteria().andCustomerAccountingOrderSnEqualTo(param.getReconciliationSupplierCode());
        QchjcOrderEntity qchjcOrderEntity = new QchjcOrderEntity();
        qchjcOrderEntity.setSupplierAccountingOrderSn("");
        qchOrderEntityMapper.updateByExampleSelective(qchjcOrderEntity, qchjcOrderEntityExample);
        //根据采购单位对账单sn字段把对账单与商品的关联关系 & 发票单的关联取消 & 供应商对账状态改为未对账
        QchjcOrderGoodsEntityExample updateOrderGoodsExample = new QchjcOrderGoodsEntityExample();
        updateOrderGoodsExample.createCriteria().andSupplierAccountingOrderSnEqualTo(param.getReconciliationSupplierCode());
        QchjcOrderGoodsEntity qchjcOrderGoodsEntity = new QchjcOrderGoodsEntity();
        qchjcOrderGoodsEntity.setSupplierAccountingOrderSn("");
        qchjcOrderGoodsEntity.setQchSupplierInvoiceApplyId(0L);
        qchjcOrderGoodsEntity.setAccountingStateSupplier(CommonAccountingStateEnum.未对账.getKey());
        qchOrderGoodsEntityMapper.updateByExampleSelective(qchjcOrderGoodsEntity, updateOrderGoodsExample);

    }

    /**
     * 供应商对账单入库统一订单
     *
     * @param todoId
     */
    @Override
    public QchjcSupplierStorageParam doSaveDetail(Long todoId) {
        QchjcAccountingUnifiedSupplierVo vo = getTodoList(todoId);
        //校验发票单数量，如果不匹配则跳过任务
        Integer                                invoiceCount                           = vo.getInvoiceCount();
        QchjcInvoiceApplySupplierEntityExample qchjcInvoiceApplySupplierEntityExample = new QchjcInvoiceApplySupplierEntityExample();
        qchjcInvoiceApplySupplierEntityExample.createCriteria()
                .andAccountingOrderSnEqualTo(vo.getAccountingOrderSn());
        //查询对账单对应的发票单
        List<QchjcInvoiceApplySupplierEntity> qchjcInvoiceApplySupplierEntities = qchjcInvoiceApplySupplierEntityMapper.selectByExample(qchjcInvoiceApplySupplierEntityExample);
        if (CollectionUtils.isEmpty(qchjcInvoiceApplySupplierEntities) || qchjcInvoiceApplySupplierEntities.size() != invoiceCount) {
            log.info("对账单编号：{}，发票单共应 : {} 条， 已同步：{}条，任务跳过", vo.getAccountingOrderSn(), invoiceCount, qchjcInvoiceApplySupplierEntities.size());
            return null;
        }
        //判断对账单是否重复入库
//        AccountingUnifiedSupplier byAccountingOrderSn = accountingUnifiedSupplierService.findByAccountingOrderSn(vo.getAccountingOrderSn());
//        if (byAccountingOrderSn != null) {
//            log.info("该对账单已存在，请勿重复入库，accountingOrderSn : {}", vo.getAccountingOrderSn());
//            return null;
//        }

        log.info("集采-供应商对账单入库，param : {}", JSON.toJSONString(vo));
        /**
         * step_1 对账单明细数据构造
         */


        //未对账商品集合 -> 对应前端页面勾选的所有未对账商品，用于生成对账单的表单参数
        List<AccountingUnifiedSupplierCreateParamDimGoodsSelected> goodsSelected = new ArrayList<>();

        for (QchjcOrderVo qchjcOrderVo : vo.getOrderSelected()) {
            //处理订单
            UnifiedOrder unifiedOrderEntity = new UnifiedOrder();
            //集采订单vo转换为统一订单实体
            convertQchOrderParam2Entity(qchjcOrderVo, unifiedOrderEntity);
            //处理商品
            List<UnifiedOrderGoods>            processUnifiedOrderGoodsList = new ArrayList<>();
            List<QchjcOrderGoodsVo>            orderGoodsSelected           = qchjcOrderVo.getOrderGoodsSelected();
            List<Predicate<QchjcOrderGoodsVo>> predicates                   = new ArrayList<>();
            predicates.add(r -> null != r.getSellingPrice() && r.getSellingPrice().compareTo(BigDecimal.ZERO) > 0);
            predicates.add(r -> null != r.getCostPrice() && r.getCostPrice().compareTo(BigDecimal.ZERO) > 0);
            List<QchjcOrderGoodsVo> scoreOrderGoodsReceiveParamFilterList = AnLamdaUtils.filters(orderGoodsSelected, predicates);
            if (CollectionUtils.isEmpty(scoreOrderGoodsReceiveParamFilterList)) {
                log.info("scoreOrderGoodsReceiveParamFilterList is empty, orderSn : {}", qchjcOrderVo.getOrderSn());
                throw new OpenApiException(500, "过滤后商品列表为空，入库失败");
            }
            //订单商品vo转换为统一订单商品实体,并构造流水
            List<UnifiedOrderCredit> processUnifiedOrderCreditList = new ArrayList<>();
            scoreOrderGoodsReceiveParamFilterList.forEach(goodsVo -> {
                //转为商品实体
                UnifiedOrderGoods unifiedOrderGoods = new UnifiedOrderGoods();
                convertQchOrderGoodsVo2Entity(goodsVo, unifiedOrderGoods);
                unifiedOrderGoods.setOrderSn(unifiedOrderEntity.getOrderSn());
                unifiedOrderGoods.setQchjcGoodsId(goodsVo.getId());
                processUnifiedOrderGoodsList.add(unifiedOrderGoods);
                //构造流水
                UnifiedOrderCredit scoreOrderCredit = new UnifiedOrderCredit();
                convertQchOrderGoods2CreditEntity(goodsVo, scoreOrderCredit, qchjcOrderVo);
                scoreOrderCredit.setOrderSn(unifiedOrderEntity.getOrderSn());
                scoreOrderCredit.setQchGoodsId(goodsVo.getId());
                processUnifiedOrderCreditList.add(scoreOrderCredit);
            });


            commonOrderProcessService.processOrderAmount(unifiedOrderEntity, processUnifiedOrderGoodsList, AnStringUtils.getUUID());


            //流水、商品、订单入库
            // 没有商品 没有流水 不保存订单数据
            if (AnCollectionUtils.isNotEmpty(processUnifiedOrderGoodsList)) {

                //订单
                UnifiedOrderExample unifiedOrderExample = new UnifiedOrderExample();
                unifiedOrderExample.createCriteria().andOrderSnEqualTo(unifiedOrderEntity.getOrderSn());
                List<UnifiedOrder> unifiedOrders = unifiedOrderMapper.selectByExample(unifiedOrderExample);
                UnifiedOrder unifiedOrder = null;
                if (CollectionUtils.isNotEmpty(unifiedOrders) && (unifiedOrder = unifiedOrders.get(0)) != null) {
                    /**
                     * 订单已存在，加行锁 再行处理
                     */
                    unifiedOrder = unifiedOrderMapper.selectByPrimaryKeyForUpdate(unifiedOrder.getId());
                    //判断订单下的商品是否存在已过账，如果已经对过账，则不允许再次对账
                    UnifiedOrderGoodsExample unifiedOrderGoodsExample = new UnifiedOrderGoodsExample();
                    unifiedOrderGoodsExample.createCriteria().andOrderSnEqualTo(unifiedOrder.getOrderSn())
                                    .andAccountingStateSupplierEqualTo(CommonAccountingStateEnum.已对账.getKey());
                    List<UnifiedOrderGoods> alreadyAccounting = unifiedOrderGoodsMapper.selectByExample(unifiedOrderGoodsExample);
                    if (CollUtil.isNotEmpty(alreadyAccounting)) {
                        throw new OpenApiException(500, "订单sn:" +unifiedOrder.getOrderSn()+ "存在已对账商品，不允许重复对账");
                    }
                    /**
                     * 更新订单表，商品，流水数据，这里用了福利的重推单做法
                     * public UnifiedOrderIssuesFlowingParam kafkaScoreOrderReceive(ScoreOrderReceiveParam receiveParam)
                     */

                    /**
                     * 重推订单处理
                     *
                     * 这里用已有的订单覆盖采购单位对账标志，因为下一步要进行供应商对账单创建，采购单位对账单状态保持不变，供应商为未对账
                     */
                    unifiedOrderEntity.setId(unifiedOrder.getId());
                    unifiedOrderEntity.setUpdateTime(DateUtil.date());
                    unifiedOrderEntity.setAccountingStateCustomer(unifiedOrder.getAccountingStateCustomer());
                    unifiedOrderMapper.updateByPrimaryKeySelective(unifiedOrderEntity);
                    //把统一订单id更新到中间表
                    QchjcOrderEntity qchjcOrderEntity = new QchjcOrderEntity();
                    qchjcOrderEntity.setId(qchjcOrderVo.getId());
                    qchjcOrderEntity.setUnifiedId(unifiedOrderEntity.getId());
                    qchOrderEntityMapper.updateByPrimaryKeySelective(qchjcOrderEntity);

                    /**
                     * 最终入库的商品数据和流水数据
                     */
                    List<UnifiedOrderGoods> finalUnifiedOrderGoodsList = new ArrayList<>();
                    List<UnifiedOrderCredit> finalUnifiedOrderCreditList = new ArrayList<>();


                    /**
                     * 重推商品处理
                     */
                    processUnifiedOrderGoodsFromQchjc(unifiedOrderEntity, processUnifiedOrderGoodsList,finalUnifiedOrderGoodsList);
                    /**
                     * 重推流水处理
                     */
                    processUnifiedOrderCreditFromQchjc(unifiedOrderEntity, processUnifiedOrderCreditList,finalUnifiedOrderCreditList);

                    //id类字段回写到中间表
                    for (UnifiedOrderGoods unifiedOrderGoods : finalUnifiedOrderGoodsList) {
                        Long id = unifiedOrderGoods.getId();//统一订单商品id
                        Long qchjcGoodsId = unifiedOrderGoods.getQchjcGoodsId();//中间表商品id
                        //更新中间表商品id
                        QchjcOrderGoodsEntity qchjcOrderGoodsEntity = qchOrderGoodsEntityMapper.selectByPrimaryKey(qchjcGoodsId);
                        qchjcOrderGoodsEntity.setUnifiedId(id);
                        qchjcOrderGoodsEntity.setUnifiedOrderId(unifiedOrderEntity.getId());
                        qchjcOrderGoodsEntity.setAccountingStateSupplier(CommonAccountingStateEnum.已对账.getKey());
                        qchOrderGoodsEntityMapper.updateByPrimaryKeySelective(qchjcOrderGoodsEntity);

                        //构造未对账商品param
                        AccountingUnifiedSupplierCreateParamDimGoodsSelected param = new AccountingUnifiedSupplierCreateParamDimGoodsSelected();
                        param.setGoodsId(unifiedOrderGoods.getGoodsId());
                        param.setUnifiedOrderId(unifiedOrderEntity.getId());
                        param.setUnifiedOrderGoodsId(id);
                        goodsSelected.add(param);

                    }
                    for (UnifiedOrderCredit unifiedOrderCredit : finalUnifiedOrderCreditList) {
                        finalUnifiedOrderGoodsList.forEach(unifiedOrderGoods -> {
                            if (unifiedOrderGoods.getQchjcGoodsId().equals(unifiedOrderCredit.getQchGoodsId())) {
                                Long qchjcGoodsId = unifiedOrderGoods.getQchjcGoodsId();
                                //把统一订单流水id更新到商品中间表
                                QchjcOrderGoodsEntity qchjcOrderGoodsEntity = qchOrderGoodsEntityMapper.selectByPrimaryKey(qchjcGoodsId);
                                qchjcOrderGoodsEntity.setUnifiedCreditId(unifiedOrderCredit.getId());
                                qchOrderGoodsEntityMapper.updateByPrimaryKeySelective(qchjcOrderGoodsEntity);
                            }
                        });
                    }

                }
                /** 新推送的订单 */
                else {

                    //订单
                    unifiedOrderMapper.insertSelective(unifiedOrderEntity);
                    //把统一订单id更新到中间表
                    QchjcOrderEntity qchjcOrderEntity = new QchjcOrderEntity();
                    qchjcOrderEntity.setId(qchjcOrderVo.getId());
                    qchjcOrderEntity.setUnifiedId(unifiedOrderEntity.getId());
                    qchOrderEntityMapper.updateByPrimaryKeySelective(qchjcOrderEntity);
                    //商品
                    for (UnifiedOrderGoods unifiedOrderGoods : processUnifiedOrderGoodsList) {
                        unifiedOrderGoodsMapper.insert(unifiedOrderGoods);
                        Long id = unifiedOrderGoods.getId();//统一订单商品id
                        Long qchjcGoodsId = unifiedOrderGoods.getQchjcGoodsId();//中间表商品id
                        //更新中间表商品id
                        QchjcOrderGoodsEntity qchjcOrderGoodsEntity = qchOrderGoodsEntityMapper.selectByPrimaryKey(qchjcGoodsId);
                        qchjcOrderGoodsEntity.setUnifiedId(id);
                        qchjcOrderGoodsEntity.setUnifiedOrderId(unifiedOrderEntity.getId());
                        qchjcOrderGoodsEntity.setAccountingStateSupplier(CommonAccountingStateEnum.已对账.getKey());
                        qchOrderGoodsEntityMapper.updateByPrimaryKeySelective(qchjcOrderGoodsEntity);
                        //构造未对账商品param
                        AccountingUnifiedSupplierCreateParamDimGoodsSelected param = new AccountingUnifiedSupplierCreateParamDimGoodsSelected();
                        param.setGoodsId(unifiedOrderGoods.getGoodsId());
                        param.setUnifiedOrderId(unifiedOrderEntity.getId());
                        param.setUnifiedOrderGoodsId(id);
                        goodsSelected.add(param);
                    }
                    //流水
                    for (UnifiedOrderCredit unifiedOrderCredit : processUnifiedOrderCreditList) {
                        unifiedOrderCreditMapper.insert(unifiedOrderCredit);
                        processUnifiedOrderGoodsList.forEach(unifiedOrderGoods -> {
                            if (unifiedOrderGoods.getQchjcGoodsId().equals(unifiedOrderCredit.getQchGoodsId())) {
                                Long qchjcGoodsId = unifiedOrderGoods.getQchjcGoodsId();
                                //把统一订单流水id更新到商品中间表
                                QchjcOrderGoodsEntity qchjcOrderGoodsEntity = qchOrderGoodsEntityMapper.selectByPrimaryKey(qchjcGoodsId);
                                qchjcOrderGoodsEntity.setUnifiedCreditId(unifiedOrderCredit.getId());
                                qchOrderGoodsEntityMapper.updateByPrimaryKeySelective(qchjcOrderGoodsEntity);
                            }
                        });
                    }
                }
            }
        }

        /**
         * step_2 构造表单参数，对账单入库
         */
        AccountingUnifiedSupplierOpCreateParamDimGoods formParam = new AccountingUnifiedSupplierOpCreateParamDimGoods();
        //formParam.setJcRebateAmount(vo.getRebateAmount());//集采对账单返点金额
        formParam.setJcAccountingOrderSn(vo.getAccountingOrderSn());//集采原始对账单号
        //formParam.setJcUnAccountingAmount(vo.getJcUnAccountingAmount());//集采不对账金额
        formParam.setGoodsSelected(goodsSelected);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        formParam.setStartTime(format.format(vo.getStartTime()));
        formParam.setEndTime(format.format(vo.getEndTime()));
        formParam.setJcStatementCreateTime(vo.getCreateTime());
        formParam.setSourceFrom(CommonSourceFromEnum.企业商城_侨城汇.getSourceFromCode());//订单来源

        formParam.setServiceNo(CommonServiceNoEnum.企业商城_侨城汇.getServiceNo());//增加服务编码 标识来源
        LoginSysUser    loginUser       = new LoginSysUser();
        QchjcUserEntity qchjcUserEntity = qchjcUserEntityMapper.selectByOutId(vo.getCreateUserId());
        loginUser.setSysUserId(qchjcUserEntity.getUnifiedId());
        loginUser.setSysUserName(qchjcUserEntity.getUserName());

        return QchjcSupplierStorageParam.builder()
                .formParam(formParam)
                .loginUser(loginUser)
                //.xGoodsList(xGoodsList)
                .build();

    }
    /**
     * 集采重推供应商账单 流水处理
     * @param unifiedOrderEntity
     * @param processUnifiedOrderCreditList
     */
    private void processUnifiedOrderCreditFromQchjc(UnifiedOrder unifiedOrderEntity, List<UnifiedOrderCredit> processUnifiedOrderCreditList, List<UnifiedOrderCredit> finalUnifiedOrderCreditList) {
        UnifiedOrderCreditExample          orderCreditExample4SaveOrUpdate  = new UnifiedOrderCreditExample();
        orderCreditExample4SaveOrUpdate.createCriteria().andOrderSnEqualTo(unifiedOrderEntity.getOrderSn());

        List<UnifiedOrderCredit> existsDatabaseUnifiedOrderCreditList = unifiedOrderCreditMapper.selectByExample(orderCreditExample4SaveOrUpdate);

        log.info("\n\n\nOrderCredit: \n已存在数据 : \n{}\n过来的数据 : \n{}\n\n\n",
                AnJsonUtils.toJson(existsDatabaseUnifiedOrderCreditList),
                AnJsonUtils.toJson(processUnifiedOrderCreditList)
        );


        for (UnifiedOrderCredit processOrderCredit : processUnifiedOrderCreditList) {

            // 新过来的数据在老的是不是存在
            List<UnifiedOrderCredit> findByManyOrderCreditList          = null;

            // 查询条件 如果 goods_id 为 0 条数大于 1 是会有问题 0 默认只有运费 , 如果 附件与赠品过来的情况 就会有问题,具体的问题再写吧
            List<Predicate<UnifiedOrderCredit>> predicatesByMany = new ArrayList<>();
            // 20201016 add start 从数据上看,是会有可能 同样的 orderId 不同的 orderSn
            predicatesByMany.add(
                    r -> r.getOrderSn().equals(processOrderCredit.getOrderSn())
                            && r.getOrderId().equals(processOrderCredit.getOrderId())
                            && r.getGoodsId().equals(processOrderCredit.getGoodsId())
                            && r.getCreditType().equals(processOrderCredit.getCreditType())
                            && r.getCreditName().equals(processOrderCredit.getCreditName())
                            && r.getBalance().compareTo(processOrderCredit.getBalance()) == 0
                            && r.getBatchs().equals(processOrderCredit.getBatchs())
            );
            // 20201016 add end
            // 新过来的数据在老的是不是存在
            findByManyOrderCreditList = AnLamdaUtils.filters(existsDatabaseUnifiedOrderCreditList, predicatesByMany);


            if (CollectionUtils.isNotEmpty(findByManyOrderCreditList)) {

                UnifiedOrderCredit findedOrderCredit = findByManyOrderCreditList.get(0);

                overWriteCreditField(processOrderCredit, findedOrderCredit);

                findedOrderCredit.setUpdateUserId(3L);
                findedOrderCredit.setUpdateTime(DateUtil.date());

                finalUnifiedOrderCreditList.add(findedOrderCredit);
            }
            // 两种情况都不存 才会作为新数据插入
            else {
                finalUnifiedOrderCreditList.add(processOrderCredit);
            }

            unifiedOrderCreditMapper.deleteByExample(orderCreditExample4SaveOrUpdate);
            for (UnifiedOrderCredit unifiedOrderCredit : finalUnifiedOrderCreditList) {
                if (unifiedOrderCredit.getId() == null || unifiedOrderCredit.getId() == 0) {
                    unifiedOrderCreditMapper.insertSelective(unifiedOrderCredit);
                }else {
                    unifiedOrderCreditMapperEx.insertSelectiveWithoutReturnId(unifiedOrderCredit);
                }
            }
        }
    }
    /**
     * 集采重推账单 流水处理
     * @param processOrderCredit
     * @param findedOrderCredit
     */
    private void overWriteCreditField(UnifiedOrderCredit processOrderCredit, UnifiedOrderCredit findedOrderCredit) {
        findedOrderCredit.setOrderSn(processOrderCredit.getOrderSn());

        findedOrderCredit.setCreditType(processOrderCredit.getCreditType());
        findedOrderCredit.setCreditName(processOrderCredit.getCreditName());
        findedOrderCredit.setOutSnapshotOrderCreditId(processOrderCredit.getOutSnapshotOrderCreditId());
        findedOrderCredit.setGoodsId(processOrderCredit.getGoodsId());
        findedOrderCredit.setDailyAccountType(processOrderCredit.getDailyAccountType());
        findedOrderCredit.setBatchs(processOrderCredit.getBatchs());
        findedOrderCredit.setBalance(processOrderCredit.getBalance());
        findedOrderCredit.setEnterpriseId(processOrderCredit.getEnterpriseId());
        findedOrderCredit.setMemberId(processOrderCredit.getMemberId());
        findedOrderCredit.setPayStatus(processOrderCredit.getPayStatus());
        findedOrderCredit.setPayType(processOrderCredit.getPayType());
        // 供应商对账单标志位
        findedOrderCredit.setCreditLockingSupplier(CommonAccountingLockingEnum.正常.getKey());
        findedOrderCredit.setAccountingStateSupplier(CommonAccountingStateEnum.未对账.getKey());

        findedOrderCredit.setQchGoodsId(processOrderCredit.getQchGoodsId());
    }

    private void processUnifiedOrderGoodsFromQchjc(UnifiedOrder unifiedOrderEntity, List<UnifiedOrderGoods> processUnifiedOrderGoodsList, List<UnifiedOrderGoods> finalUnifiedOrderGoodsList) {
        UnifiedOrderGoodsExample          orderGoodsExample4SaveOrUpdate  = new UnifiedOrderGoodsExample();
        orderGoodsExample4SaveOrUpdate.createCriteria().andOrderSnEqualTo(unifiedOrderEntity.getOrderSn());
        //结算中心数据库中已存在的商品
        List<UnifiedOrderGoods> existsUnifiedOrderGoodsList = unifiedOrderGoodsMapper.selectByExample(orderGoodsExample4SaveOrUpdate);
        log.info("\n\n\nOrderGoods: \n已存在数据 : \n{}\n过来的数据 : \n{}\n\n\n",
                AnJsonUtils.toJson(existsUnifiedOrderGoodsList),
                AnJsonUtils.toJson(processUnifiedOrderGoodsList)
        );


        // 拿着过来的数据 去 查 数据库的
        for (UnifiedOrderGoods processOrderGoods : processUnifiedOrderGoodsList) {

            // 查询数据库中是否存在
            UnifiedOrderGoodsExample unifiedOrderGoodsExample = new UnifiedOrderGoodsExample();
            unifiedOrderGoodsExample.createCriteria().andOrderSnEqualTo(unifiedOrderEntity.getOrderSn())
                    .andOutSnapshotOrderGoodsIdEqualTo(processOrderGoods.getOutSnapshotOrderGoodsId());
            List<UnifiedOrderGoods> findByOutSnapshotIdOrderGoodsList = unifiedOrderGoodsMapper.selectByExample(unifiedOrderGoodsExample);


            //如果该商品已存在，则更新该商品数据
            if (CollectionUtils.isNotEmpty(findByOutSnapshotIdOrderGoodsList)) {
                UnifiedOrderGoods findedBySnapshotIdOrderGoods = findByOutSnapshotIdOrderGoodsList.get(0);

                overWriteGoodsField(processOrderGoods, findedBySnapshotIdOrderGoods);
                finalUnifiedOrderGoodsList.add(findedBySnapshotIdOrderGoods);
            } else {
                finalUnifiedOrderGoodsList.add(processOrderGoods);
            }
        }
        // 删除后重新插入数据
        unifiedOrderGoodsMapper.deleteByExample(orderGoodsExample4SaveOrUpdate);
        for (UnifiedOrderGoods unifiedOrderGoods : finalUnifiedOrderGoodsList) {
            if (unifiedOrderGoods.getId() == null || unifiedOrderGoods.getId() == 0) {
                unifiedOrderGoodsMapper.insertSelective(unifiedOrderGoods);
            } else {
                unifiedOrderGoodsMapperEx.insertSelectiveWithoutReturnId(unifiedOrderGoods);
            }
        }
        //unifiedOrderGoodsMapperEx.insertBatch(finalUnifiedOrderGoodsList);

        log.info("\n\n\n\nOrderGoods Final:\n{}\n\n\n\n", AnJsonUtils.toJson(finalUnifiedOrderGoodsList));
    }

    /**
     * 集采重推供应商账单 商品覆写处理
     * @param processOrderGoods
     * @param findedBySnapshotIdOrderGoods
     */
    private void overWriteGoodsField(UnifiedOrderGoods processOrderGoods, UnifiedOrderGoods findedBySnapshotIdOrderGoods) {

        findedBySnapshotIdOrderGoods.setOrderSn(processOrderGoods.getOrderSn());

        //供应商对账标志位改为未对账
        findedBySnapshotIdOrderGoods.setGoodsLockingSupplier(CommonAccountingLockingEnum.正常.getKey());
        findedBySnapshotIdOrderGoods.setAccountingStateSupplier(CommonAccountingStateEnum.未对账.getKey());

        findedBySnapshotIdOrderGoods.setGoodsName(processOrderGoods.getGoodsName());
        findedBySnapshotIdOrderGoods.setGoodsAlias(processOrderGoods.getGoodsAlias());

        findedBySnapshotIdOrderGoods.setGoodsId(processOrderGoods.getGoodsId());
        findedBySnapshotIdOrderGoods.setOutSnapshotOrderGoodsId(processOrderGoods.getOutSnapshotOrderGoodsId());

        findedBySnapshotIdOrderGoods.setQuantity(processOrderGoods.getQuantity());
        findedBySnapshotIdOrderGoods.setUnit(StrUtil.isBlank(processOrderGoods.getUnit()) ? CommonOrderGoodsUnitEnum.项.getDesc() : processOrderGoods.getUnit());
        findedBySnapshotIdOrderGoods.setPrice(processOrderGoods.getPrice());
        findedBySnapshotIdOrderGoods.setCostPrice(processOrderGoods.getCostPrice());

        findedBySnapshotIdOrderGoods.setGoodsParams(processOrderGoods.getGoodsParams());

        //findedBySnapshotIdOrderGoods.setFiscalCode(processOrderGoods.getFiscalCode());
        //findedBySnapshotIdOrderGoods.setTaxCode(processOrderGoods.getTaxCode());
        //findedBySnapshotIdOrderGoods.setTaxRate(processOrderGoods.getTaxRate());

        // 商户税率
        //findedBySnapshotIdOrderGoods.setMerchTaxId(processOrderGoods.getMerchTaxId());
        findedBySnapshotIdOrderGoods.setMerchTaxCode(processOrderGoods.getMerchTaxCode());
        findedBySnapshotIdOrderGoods.setMerchTaxRate(processOrderGoods.getMerchTaxRate());

        // 平台税率
        //findedBySnapshotIdOrderGoods.setOperationTaxId(processOrderGoods.getOperationTaxId());
        findedBySnapshotIdOrderGoods.setOperationTaxCode(processOrderGoods.getOperationTaxCode());
        findedBySnapshotIdOrderGoods.setOperationTaxRate(processOrderGoods.getOperationTaxRate());

        //findedBySnapshotIdOrderGoods.setCateIdLv1(processOrderGoods.getCateIdLv1());
        //findedBySnapshotIdOrderGoods.setCateIdLv1(processOrderGoods.getCateIdLv2());
        //findedBySnapshotIdOrderGoods.setCateIdLv3(processOrderGoods.getCateIdLv3());

        findedBySnapshotIdOrderGoods.setCateNameLv1(processOrderGoods.getCateNameLv1());
        findedBySnapshotIdOrderGoods.setCateNameLv2(processOrderGoods.getCateNameLv2());
        findedBySnapshotIdOrderGoods.setCateNameLv3(processOrderGoods.getCateNameLv3());

        findedBySnapshotIdOrderGoods.setSelfOption(processOrderGoods.getSelfOption() == null ? "" : processOrderGoods.getSelfOption());

        findedBySnapshotIdOrderGoods.setGoodsType(processOrderGoods.getGoodsType());


        findedBySnapshotIdOrderGoods.setUpdateTime(DateUtil.date());
        findedBySnapshotIdOrderGoods.setUpdateUserId(1L);

        findedBySnapshotIdOrderGoods.setQchjcGoodsId(processOrderGoods.getQchjcGoodsId());
    }

    @Override
    public void recordFailLog(QchjcAccountingUnifiedSupplierEntity entity, String toJSONString) {
        entity.setStorageStatus(QchjcStorageStatusEnum.FAIL.getStatus());
        entity.setStorageTime(DateUtil.date());
        entity.setStorageReason(toJSONString);
        qchAccountingUnifiedSupplierEntityMapper.updateByPrimaryKeySelective(entity);
    }

    @Override
    public List<QchjcInvoiceApplySupplierEntity> selectSupplierInvoiceByAccountingOrderSn(String accountingOrderSn) {
        QchjcInvoiceApplySupplierEntityExample qchjcInvoiceApplySupplierEntityExample = new QchjcInvoiceApplySupplierEntityExample();
        qchjcInvoiceApplySupplierEntityExample.createCriteria().andAccountingOrderSnEqualTo(accountingOrderSn);
        return qchjcInvoiceApplySupplierEntityMapper.selectByExample(qchjcInvoiceApplySupplierEntityExample);
    }

    @Override
    public QchjcSupplierInoviceApplyParam assembleSupplierInvoiceApplyParam(QchjcInvoiceApplySupplierEntity qchjcInvoiceApplySupplierEntity, AccountingUnifiedSupplier accountingUnifiedSupplier, InvoiceBankInfo invoiceBankInfo, QchjcAccountingUnifiedSupplierEntity qchjcAccountingUnifiedSupplierEntity) {
        InvoiceApplySupplierOpApplyForm           form        = new InvoiceApplySupplierOpApplyForm();
        List<InvoiceApplySupplierOpApplyFormItem> packageList = new ArrayList<>();
        form.setAccountingOrderId(accountingUnifiedSupplier.getId());//对账单id
        form.setAccountingOrderSn(accountingUnifiedSupplier.getAccountingOrderSn());//对账单编号
        form.setInvoiceType(qchjcInvoiceApplySupplierEntity.getInvoiceType());//发票类型
        form.setRemark(qchjcInvoiceApplySupplierEntity.getRemark());//备注
        form.setInvoiceTitle(invoiceBankInfo.getCompanyName());//抬头
        form.setSysPlatformExtInvoiceId(invoiceBankInfo.getId());//系统平台抬头id
        form.setSourceFrom(CommonSourceFromEnum.企业商城_侨城汇.getSourceFromCode());//订单来源
        form.setServiceNo(CommonServiceNoEnum.企业商城_侨城汇.getServiceNo());
        form.setApplyTime(qchjcInvoiceApplySupplierEntity.getApplyTime());//申请时间，取集采的时间，发票单下的开票申请都固定为这个时间，不然前端页面合并单元格会乱序
        //form.setJcRebateAmount(qchjcInvoiceApplySupplierEntity.getRebateAmount());//集采发票单返点金额
        //form.setJcRealAmount(qchjcInvoiceApplySupplierEntity.getRealAmount());//集采发票单实际金额
        //form.setJcUnAccountAmount(qchjcInvoiceApplySupplierEntity.getJcUnAccountingAmount());//集采发票单不对账金额

        //查询发票单下所有商品
        List<QchjcOrderGoodsEntity> qchjcOrderGoodsEntities = qchOrderGoodsEntityMapper.selectByInvoiceSupplierApplyId(qchjcInvoiceApplySupplierEntity.getId());
        if (CollectionUtils.isEmpty(qchjcOrderGoodsEntities)) {
            log.error("发票单下没有商品，发票单id：{}", qchjcInvoiceApplySupplierEntity.getId());
            throw new OpenApiException(500, "发票单下没有商品");
        }
        /**
         * 判断该发票单下的所有商品的商户税率是否一致
         */
        Map<BigDecimal, List<QchjcOrderGoodsEntity>> collect = qchjcOrderGoodsEntities.stream().collect(Collectors.groupingBy(QchjcOrderGoodsEntity::getMerchTaxRate));
        if (collect.size() > 1) {
            throw new OpenApiException(500, "供应商发票单下商品税率不一致");
        }
        for (QchjcOrderGoodsEntity qchjcOrderGoodsEntity : qchjcOrderGoodsEntities) {
            InvoiceApplySupplierOpApplyFormItem param = new InvoiceApplySupplierOpApplyFormItem();
            param.setAccountingOrderSn(accountingUnifiedSupplier.getAccountingOrderSn());//对账单编号
            param.setUnifiedOrderGoodsId(qchjcOrderGoodsEntity.getUnifiedId());//统一订单商品id
            packageList.add(param);
        }
        form.setPackageList(packageList);
        form.setTaxRate(qchjcOrderGoodsEntities.get(0).getMerchTaxRate().toString());//供应商发票单的明细是同税率

        LoginSysUser invoiceLoginUser = new LoginSysUser();
        invoiceLoginUser.setSysUserName(qchjcInvoiceApplySupplierEntity.getApplyUserName());
        QchjcUserEntity qchjcUserEntity1 = qchjcUserEntityMapper.selectByOutId(qchjcInvoiceApplySupplierEntity.getApplyUserId());
        invoiceLoginUser.setSysUserId(qchjcUserEntity1.getUnifiedId());
        return QchjcSupplierInoviceApplyParam.builder()
                .form(form)
                .invoiceLoginUser(invoiceLoginUser).build();
    }

    @Override
    public void saveSupplierInvoiceApplyByPrimaryKeySelective(QchjcInvoiceApplySupplierEntity qchjcInvoiceApplySupplierEntity) {
        qchjcInvoiceApplySupplierEntityMapper.updateByPrimaryKeySelective(qchjcInvoiceApplySupplierEntity);
    }

    @Override
    public R<List<UnifiedSupplierVo>> getSupplierList() {
        return new R<>(unifiedSupplierMapperEx.getSupplierList());
    }


    /**
     * web 企业商城账单 修改备注
     * @param id
     * @param remark
     * @param token
     * @return
     */
    @Override
    public R<String> remark(Long id, String remark, String token) {
        QchjcAccountingUnifiedSupplierEntity qchjcAccountingUnifiedSupplierEntity = qchAccountingUnifiedSupplierEntityMapper.selectByPrimaryKey(id);
        if (qchjcAccountingUnifiedSupplierEntity == null) {
            return new R<>("500", "未查询到对应的记录", false);
        }
        qchjcAccountingUnifiedSupplierEntity.setRemark(remark);
        qchjcAccountingUnifiedSupplierEntity.setUpdateTime(DateUtil.date());

        LoginSysUser loginSysUser = JwtUtil.getLoginSysUser(token);
        qchjcAccountingUnifiedSupplierEntity.setUpdateUserId(loginSysUser.getSysUserId().toString());
        qchjcAccountingUnifiedSupplierEntity.setUpdateUserName(loginSysUser.getFullName());
        qchAccountingUnifiedSupplierEntityMapper.updateByPrimaryKeySelective(qchjcAccountingUnifiedSupplierEntity);
        return new R<>("200", "更新成功", true);
    }

    @Override
    public R<List<QchjcAccountingUnifiedSupplierVo>> queryQchjcSupplierStatementList(QchjcSupplierAccountingListRequest request) {
        PageHelper.startPage(request.getPageNumber(), request.getPageSize());
        List<QchjcAccountingUnifiedSupplierVo>     qchjcAccountingUnifiedSupplierVos = qchAccountingUnifiedSupplierEntityMapper.queryQchjcCustomerStatementList(request);
        PageInfo<QchjcAccountingUnifiedSupplierVo> page                              = new PageInfo<>(qchjcAccountingUnifiedSupplierVos);
        return new R<List<QchjcAccountingUnifiedSupplierVo>>(page.getPageNum(), page.getPageSize(), (int) page.getTotal(), qchjcAccountingUnifiedSupplierVos);
    }

    @Override
    public R<QchjcAccountingUnifiedSupplierVo> getQchjcSupplierStatementById(Long id) {

        QchjcAccountingUnifiedSupplierEntity qchjcAccountingUnifiedSupplierEntity = qchAccountingUnifiedSupplierEntityMapper.selectByPrimaryKey(id);
        if (qchjcAccountingUnifiedSupplierEntity == null) {
            return new R<>("500", "未查询到对应的记录", false);
        }
        //对账单主体信息
        QchjcAccountingUnifiedSupplierVo vo = qchAccountingUnifiedSupplierEntityMapper.queryQchjcSupplierStatementVoById(id);
        //发票单信息
        List<QchjcInvoiceSupplierApplyVo> invoiceApplyVoList = qchjcInvoiceApplySupplierEntityMapper.queryQchjcInvoiceApplySupplierVoListByAccountingOrderSn(vo.getAccountingOrderSn());

        vo.setInvoiceSupplierApplyList(invoiceApplyVoList);
        return new R<>(vo);


    }

    @Override
    public List<Long> getTodoIdList() {
        return qchAccountingUnifiedSupplierEntityMapper.getTodoIdList();
    }

    /**
     * 商品vo转换为统一订单流水实体
     *
     * @param vo
     * @param unifiedOrderCreditEntity
     * @param qchjcOrderVo
     */
    private void convertQchOrderGoods2CreditEntity(QchjcOrderGoodsVo vo, UnifiedOrderCredit unifiedOrderCreditEntity, QchjcOrderVo qchjcOrderVo) {
        unifiedOrderCreditEntity.setDirection(vo.getDirection());
        //unifiedOrderCreditEntity.setOutSnapshotOrderCreditId(scoreOrderCreditReceiveParam.getOrderCreditId());

        unifiedOrderCreditEntity.setOrderId(qchjcOrderVo.getId());
        /**
         * goods_id用集采的
         */
        unifiedOrderCreditEntity.setGoodsId(Long.parseLong(vo.getGoodsId()));

        unifiedOrderCreditEntity.setCreditType(UnifiedOrderCreditTypeDefaultEnum.积分支付.getKey());
        unifiedOrderCreditEntity.setCreditName(UnifiedOrderCreditTypeDefaultEnum.积分支付.getDesc());

        /* 积分变动类型(1充值 2消费 3退款) */
        unifiedOrderCreditEntity.setDailyAccountType(vo.getDirection() == 1 ? 2 : 3);//1-正单 -1退单 ，对应2消费，3退款
        unifiedOrderCreditEntity.setBatchs(CommonServiceNoEnum.企业商城_侨城汇.getServiceNo());//固定值
        if (vo.getDirection() == 1) {
            unifiedOrderCreditEntity.setBalance(vo.getSellingPrice().multiply(new BigDecimal(vo.getQuantity())));
        } else {
            unifiedOrderCreditEntity.setBalance(vo.getSellingPrice().multiply(new BigDecimal(vo.getQuantity())).negate());
        }

        // TODO 要检查
        QchjcEnterpriseEntity qchjcEnterpriseEntity = qchjcEnterpriseEntityMapper.selectByOutId(qchjcOrderVo.getPurchaseVirtId());
        if (qchjcEnterpriseEntity != null) {
            unifiedOrderCreditEntity.setEnterpriseId(qchjcEnterpriseEntity.getId());//所属企业（买家）取中间表id，非统一订单企业表自增id
        } else {
            unifiedOrderCreditEntity.setEnterpriseId(0L);
        }
        QchjcUserEntity qchjcUser = qchjcUserEntityMapper.selectByOutId(qchjcOrderVo.getPurchaseUserId());
        if (qchjcUser != null) {
            unifiedOrderCreditEntity.setMemberId(qchjcUser.getUnifiedId());//买家id
        } else {
            unifiedOrderCreditEntity.setMemberId(0L);
        }

        unifiedOrderCreditEntity.setPayStatus(1);//固定已支付
        unifiedOrderCreditEntity.setPayType(qchjcOrderVo.getPayType());

        unifiedOrderCreditEntity.setCreditLockingCustomer(CommonAccountingLockingEnum.正常.getKey());
        unifiedOrderCreditEntity.setCreditLockingSupplier(CommonAccountingLockingEnum.正常.getKey());

        unifiedOrderCreditEntity.setAccountingStateCustomer(CommonAccountingStateEnum.不对账.getKey());
        unifiedOrderCreditEntity.setAccountingStateSupplier(CommonAccountingStateEnum.未对账.getKey());

        unifiedOrderCreditEntity.setInvoiceApplyStatus(UnifiedOrderCreditInvoiceApplyStatusEnum.待申请.getKey());
        unifiedOrderCreditEntity.setInvoiceMakeStatus(UnifiedOrderCreditInvoiceMakeStatusEnum.待开票.getKey());
        unifiedOrderCreditEntity.setBackStatus(UnifiedOrderCreditBackAccountStatusEnum.未回款.getKey());


        unifiedOrderCreditEntity.setCreateTime(qchjcOrderVo.getCreateTime());
        QchjcUserEntity qchjcCreateUserEntity = qchjcUserEntityMapper.selectByOutId(qchjcOrderVo.getCreateUserId());
        if (qchjcCreateUserEntity != null) {
            unifiedOrderCreditEntity.setCreateUserId(qchjcCreateUserEntity.getUnifiedId());
        }
        unifiedOrderCreditEntity.setUpdateTime(qchjcOrderVo.getUpdateTime());
        QchjcUserEntity qchjcUpdateUserEntity = qchjcUserEntityMapper.selectByOutId(qchjcOrderVo.getUpdateUserId());
        if (qchjcUpdateUserEntity != null) {
            unifiedOrderCreditEntity.setUpdateUserId(qchjcUpdateUserEntity.getUnifiedId());
        }

    }

    /**
     * 集采商品vo转换为统一订单商品实体
     *
     * @param vo
     * @param unifiedOrderGoods
     */
    private void convertQchOrderGoodsVo2Entity(QchjcOrderGoodsVo vo, UnifiedOrderGoods unifiedOrderGoods) {
        if (CommonOrderGoodsTypeEnum.运费.getKey().equals(vo.getGoodsType())) {
            UnifiedServicePartGoodsTransportParam defaultGoodsTransport = unifiedServiceService.getUnifiedServicePartGoodsTransport(CommonServiceNoEnum.企业商城_侨城汇.getServiceNo());

            //运费处理，集采的运费为双向结算
            unifiedOrderGoods.setOrderSn(vo.getOrderSn());
            unifiedOrderGoods.setGoodsLockingCustomer(CommonAccountingLockingEnum.正常.getKey());
            unifiedOrderGoods.setGoodsLockingSupplier(CommonAccountingLockingEnum.正常.getKey());
            /**
             * 20220425 对账状态标志位增加集采未对账 集采已对账
             */
            unifiedOrderGoods.setAccountingStateCustomer(CommonAccountingStateEnum.不对账.getKey());
            unifiedOrderGoods.setAccountingStateSupplier(CommonAccountingStateEnum.未对账.getKey());

            unifiedOrderGoods.setGoodsType(CommonOrderGoodsTypeEnum.运费.getKey());
            unifiedOrderGoods.setDirection(CommonDirectionEnum.正向.getKey());

            /**
             * goods_id用集采的
             */
            unifiedOrderGoods.setGoodsId(Long.parseLong(vo.getGoodsId()));
            unifiedOrderGoods.setOutSnapshotOrderGoodsId(Long.parseLong(vo.getOutSnapshotOrderGoodsId()));

            unifiedOrderGoods.setGoodsName(CommonOrderGoodsIdEnum.运费.getDesc());
            unifiedOrderGoods.setUnit(CommonOrderGoodsUnitEnum.项.getDesc());

            unifiedOrderGoods.setQuantity(1);
            unifiedOrderGoods.setPrice(vo.getSellingPrice());
            unifiedOrderGoods.setCostPrice(vo.getCostPrice());

//			defaultGoodsTransport
            unifiedOrderGoods.setFiscalCode(defaultGoodsTransport.getGoodsTransportFiscalCode());
            unifiedOrderGoods.setTaxCode(defaultGoodsTransport.getGoodsTransportTaxCode());
            unifiedOrderGoods.setTaxRate(defaultGoodsTransport.getGoodsTransportTaxRate());

            // 商户税率
            unifiedOrderGoods.setMerchTaxId(0L);
            unifiedOrderGoods.setMerchTaxCode(vo.getMerchTaxCode());
            unifiedOrderGoods.setMerchTaxRate(vo.getMerchTaxRate());

            // 平台税率
            unifiedOrderGoods.setOperationTaxId(0L);
            unifiedOrderGoods.setOperationTaxCode(vo.getOperationTaxCode());
            unifiedOrderGoods.setOperationTaxRate(vo.getOperationTaxRate());

            unifiedOrderGoods.setCreateTime(DateUtil.date());
            unifiedOrderGoods.setCreateUserId(1L);
            unifiedOrderGoods.setUpdateTime(DateUtil.date());
            unifiedOrderGoods.setUpdateUserId(1L);

        } else {
            unifiedOrderGoods.setGoodsType(vo.getGoodsType());//商品类型
            unifiedOrderGoods.setDirection(vo.getDirection());//商品方向

            unifiedOrderGoods.setGoodsLockingCustomer(CommonAccountingLockingEnum.正常.getKey());
            unifiedOrderGoods.setGoodsLockingSupplier(CommonAccountingLockingEnum.正常.getKey());

            /**
             * 20220425 对账状态标志位增加集采未对账 集采已对账
             */
            unifiedOrderGoods.setAccountingStateCustomer(CommonAccountingStateEnum.不对账.getKey());
            unifiedOrderGoods.setAccountingStateSupplier(CommonAccountingStateEnum.未对账.getKey());
            /**
             * goods_id用集采的
             */
            unifiedOrderGoods.setGoodsId(Long.parseLong(vo.getGoodsId()));
            unifiedOrderGoods.setOutSnapshotOrderGoodsId(Long.parseLong(vo.getOutSnapshotOrderGoodsId()));

            unifiedOrderGoods.setGoodsName(vo.getGoodsName());
            unifiedOrderGoods.setQuantity(vo.getQuantity());
            unifiedOrderGoods.setUnit(StrUtil.isBlank(vo.getUnit()) ? CommonOrderGoodsUnitEnum.项.getDesc() : vo.getUnit());
            unifiedOrderGoods.setPrice(vo.getSellingPrice());
            // add costprice 成本价
            unifiedOrderGoods.setCostPrice(vo.getCostPrice());

            unifiedOrderGoods.setGoodsParams(vo.getGoodsParams());//商品参数

            unifiedOrderGoods.setSelfOption(vo.getSelfOption() == null ? "" : vo.getSelfOption());

            /************************************** update by linjinjy 20200727 20200723_林志鹏_税率,退款格式.docx 将要弃用 20210413 mark by linjinyu **************************************/

            //unifiedOrderGoods.setFiscalCode(vo.getFiscalCode());
            //unifiedOrderGoods.setTaxCode(vo.getTaxCode());
            //unifiedOrderGoods.setTaxRate(vo.getTaxRate());

            /************************************** update by linjinjy 20200727 20200723_林志鹏_税率,退款格式.docx 将要弃用 20210413 mark by linjinyu **************************************/


            /****************************************** 税率修改 20210413 mark by linjinyu start ******************************************/

            // 商户税率
            //unifiedOrderGoods.setMerchTaxId(vo.getMerchTaxId());
            unifiedOrderGoods.setMerchTaxCode(vo.getMerchTaxCode());
            unifiedOrderGoods.setMerchTaxRate(vo.getMerchTaxRate());

            // 平台税率
            //unifiedOrderGoods.setOperationTaxId(vo.getOperationTaxId());
            unifiedOrderGoods.setOperationTaxCode(vo.getOperationTaxCode());
            unifiedOrderGoods.setOperationTaxRate(vo.getOperationTaxRate());

            /****************************************** 税率修改 20210413 mark by linjinyu   end ******************************************/


            // 弃 20200904 by linjinyu
            /************************************** update by linjinjy 20200810 20200729_林志鹏_税率,退款格式.docx **************************************/

//		scoreOrderGoodsEntity.setCateName(scoreOrderGoodsReceiveParam.getCateName());

            /************************************** update by linjinjy 20200810 20200729_林志鹏_税率,退款格式.docx **************************************/


            /****************************************** 三级分类 20200904 by linjinyu 20200904_林志鹏_三极分类 ******************************************/

            //unifiedOrderGoods.setCateIdLv1(vo.getCateIdLv1());
            //unifiedOrderGoods.setCateIdLv2(vo.getCateIdLv2());
            //unifiedOrderGoods.setCateIdLv3(vo.getCateIdLv3());
            unifiedOrderGoods.setCateNameLv1(vo.getCateNameLv1());
            unifiedOrderGoods.setCateNameLv2(vo.getCateNameLv2());
            unifiedOrderGoods.setCateNameLv3(vo.getCateNameLv3());

            /****************************************** 三级分类 20200904 by linjinyu 20200904_林志鹏_三极分类 ******************************************/


            unifiedOrderGoods.setCreateTime(DateUtil.date());
            // TODO 写死
            unifiedOrderGoods.setCreateUserId(1L);
            unifiedOrderGoods.setUpdateTime(DateUtil.date());
            // TODO 写死
            unifiedOrderGoods.setUpdateUserId(1L);
        }
    }

    /**
     * 集采订单vo转换为统一订单实体
     *
     * @param vo
     * @param unifiedOrderEntity
     */
    private void convertQchOrderParam2Entity(QchjcOrderVo vo, UnifiedOrder unifiedOrderEntity) {
        unifiedOrderEntity.setOrderType(vo.getOrderType());//正单/退单
        unifiedOrderEntity.setOrderSn(vo.getOrderSn());//订单编号
        unifiedOrderEntity.setOrderSnOutTrade(vo.getOrderSn());//外部订单号

        unifiedOrderEntity.setServiceNo(CommonServiceNoEnum.企业商城_侨城汇.getServiceNo());//服务编号，固定值
        unifiedOrderEntity.setServiceName(CommonServiceNoEnum.企业商城_侨城汇.getServiceName());

        unifiedOrderEntity.setProjectId(QchjcOrgEnum.CUSTOMER.getOrgId());//项目ID 固定值
        unifiedOrderEntity.setProjectName(QchjcOrgEnum.CUSTOMER.getServiceNoName());//项目名称 固定值
        QchjcEnterpriseEntity qchjcEnterpriseEntity = qchjcEnterpriseEntityMapper.selectByOutId(vo.getPurchaseVirtId());
        if (qchjcEnterpriseEntity != null) {
            unifiedOrderEntity.setPurchaseVirtId(qchjcEnterpriseEntity.getId());//采购单位ID，中间表id，集采id统一+10万
            unifiedOrderEntity.setPurchaseVirtName(vo.getPurchaseVirtName());//采购单位名称
        } else {
            unifiedOrderEntity.setPurchaseVirtId(0L);//采购单位ID，中间表id，集采id统一+10万
            unifiedOrderEntity.setPurchaseVirtName(vo.getPurchaseVirtName());//采购单位名称
        }

        unifiedOrderEntity.setPurchaseDepartmentName(vo.getPurchaseDepartmentName());//采购单位部门名称

        QchjcUserEntity qchjcUserEntity1 = qchjcUserEntityMapper.selectByOutId(vo.getPurchaseUserId());
        if (qchjcUserEntity1 != null) {
            unifiedOrderEntity.setPurchaseUserId(qchjcUserEntity1.getUnifiedId());//采购单位用户ID
        } else {
            unifiedOrderEntity.setPurchaseUserId(0L);//采购单位用户ID
        }
        unifiedOrderEntity.setPurchaseUserName(vo.getPurchaseUserName());//采购单位用户名称
        unifiedOrderEntity.setPurchasePhone(vo.getPurchasePhone());//采购单位用户电话
        QchjcSupplierEntity qchjcSupplierEntity = qchjcSupplierEntityMaper.selectByOutId(vo.getSupplierId());
        if (qchjcSupplierEntity != null) {
            unifiedOrderEntity.setSaleId(qchjcSupplierEntity.getId());//销售单位ID,中间表id，集采id统一+10万
        } else {
            unifiedOrderEntity.setSaleId(0L);//销售单位ID,中间表id，集采id统一+10万
        }
        unifiedOrderEntity.setSaleName(vo.getSupplierName());//销售单位名称

        // 商城 dispatchPrice + grprice = price scoreOrderReceiveParam.getPrice()
        unifiedOrderEntity.setAmount(vo.getOrderAmount());//订单金额
        unifiedOrderEntity.setCostAmount(vo.getOrderCostAmount());//订单成本金额
        /**
         * 20220425修改 集采运费已经拆成商品，运费都填0
         */
        unifiedOrderEntity.setTransportAmount(BigDecimal.ZERO);//运费
        unifiedOrderEntity.setTransportMerchantAssumeAmount(BigDecimal.ZERO);//运费商品承担金额


        // TODO mark by linjinyu at 2022-07-22 10:28:33 - 统一修正 支付方式 支付状态 订单状态 都不定义 start

//        unifiedOrderEntity.setOrderState(vo.getOrderState());//订单状态
//        unifiedOrderEntity.setOrderStateName(vo.getOrderStateName());//订单状态名称
//        unifiedOrderEntity.setPayType(vo.getPayType());
//        unifiedOrderEntity.setPayState(2); // TODO 写死

        unifiedOrderEntity.setOrderState(vo.getOrderState());
        unifiedOrderEntity.setOrderStateName(vo.getOrderStateName());

        unifiedOrderEntity.setPayType(vo.getPayType());
        unifiedOrderEntity.setPayTypeName(vo.getPayTypeName());

        unifiedOrderEntity.setPayState(ObjectUtil.isNull(vo.getPayState()) ? 2 : vo.getPayState());
        unifiedOrderEntity.setPayStateName(vo.getPayStateName());

        // TODO mark by linjinyu at 2022-07-22 10:28:33 - 统一修正 支付方式 支付状态 订单状态 都不定义   end


        unifiedOrderEntity.setCompletState(vo.getCompletState());//订单完成状态

        unifiedOrderEntity.setOrderLockingCustomer(CommonAccountingLockingEnum.正常.getKey());
        unifiedOrderEntity.setOrderLockingSupplier(CommonAccountingLockingEnum.正常.getKey());

        /**
         * 20220425 对账状态标志位增加集采未对账 集采已对账
         */
        unifiedOrderEntity.setAccountingStateCustomer(CommonAccountingStateEnum.不对账.getKey());
        unifiedOrderEntity.setAccountingStateSupplier(CommonAccountingStateEnum.未对账.getKey());



        // TODO 写死
        unifiedOrderEntity.setSettlementType(2);
        // TODO 写死
        unifiedOrderEntity.setAppraiseState(2);
        // TODO 写死
        unifiedOrderEntity.setSourceChannel(1);

        unifiedOrderEntity.setOtherParams(vo.getOtherParams());//其他参数

        QchjcUserEntity qchjcUserEntity = qchjcUserEntityMapper.selectByOutId(vo.getCreateUserId());
        // 这个是可以用于记录 谁创建的 20200611
        if (qchjcUserEntity != null) {
            unifiedOrderEntity.setCreateUserId(qchjcUserEntity.getUnifiedId());
        } else {
            unifiedOrderEntity.setCreateUserId(0L);
        }
        unifiedOrderEntity.setCreateTime(vo.getCreateTime());

        unifiedOrderEntity.setPayTime(vo.getPayTime());
        unifiedOrderEntity.setSendTime(vo.getSendTime());
        unifiedOrderEntity.setFinishTime(vo.getFinishTime());

        // TODO 结算时间逻辑 添加 mark by linjinyu at 20211112
        // |---- 1. kafka 正向通道,触发点 订单已完成 产生 结算时间(订单完成时间填充) right
        // |---- 2. kafka 负向通道,解发点 退单已完成 解锁正负单时 产生结算时间(退单完成时间填充)
        // |---- 3. 供应商结算 未对账商品 list 逻辑 不变(没说明) 看样子是 加了个 结算时间 筛选逻辑
        //if (UnifiedOrderCompletStateEnum.已完成.getKey().equals(unifiedOrderEntity.getCompletState())
        //        && ObjectUtil.isNotNull(unifiedOrderEntity.getFinishTime())) {
        //unifiedOrderEntity.setAccountingTime(unifiedOrderEntity.getFinishTime());
        unifiedOrderEntity.setAccountingTime(vo.getAccountingTime());//结算时间
        //}


        // TODO 写死
        unifiedOrderEntity.setUserType("2");
        // TODO 写死
        unifiedOrderEntity.setUserName("系统");

        unifiedOrderEntity.setUpdateTime(vo.getUpdateTime());

        QchjcUserEntity updateUser = qchjcUserEntityMapper.selectByOutId(vo.getUpdateUserId());
        if (updateUser != null) {
            unifiedOrderEntity.setUpdateUserId(updateUser.getUnifiedId());
        } else {
            unifiedOrderEntity.setUpdateUserId(0L);
        }
        // 原本代码也是注释了
//		unifiedOrderEntity.setRecUserId();
        unifiedOrderEntity.setRecUserName(vo.getRecUserName());
        unifiedOrderEntity.setRecUserPhone(vo.getRecUserPhone());
        unifiedOrderEntity.setRecAddress(vo.getRecAddress());


        unifiedOrderEntity.setExpress(vo.getExpress());
        unifiedOrderEntity.setExpressCompany(vo.getExpressCompany());
        unifiedOrderEntity.setExpressSn(vo.getExpressSn());


        unifiedOrderEntity.setRemarks(vo.getRemarks());
    }


    /**
     * 保存供应商对账单主体信息
     *
     * @param param
     * @param origin
     */
    private void handleSupplierStatement(QchjcAccountingUnifiedSupplierParam param, QchjcAccountingUnifiedSupplierEntity origin) {
        if (origin != null) {
            //重复推送的对账单信息，更新
            QchjcAccountingUnifiedSupplierEntity copy = getQchjcAccountingUnifiedSupplierEntity(AnBeanUtils.copy(param, origin), param);
            copy.setSyncTime(new Date());
            copy.setStorageStatus(QchjcStorageStatusEnum.TODO.getStatus());//重新推送的对账单改为待入库状态
            copy.setStorageReason("重新推送");
            qchAccountingUnifiedSupplierEntityMapper.updateByPrimaryKeySelective(copy);
        } else {
            //新增
            QchjcAccountingUnifiedSupplierEntity accountingUnifiedSupplierEntity = getQchjcAccountingUnifiedSupplierEntity(AnBeanUtils.copy(param, QchjcAccountingUnifiedSupplierEntity.class), param);
            qchAccountingUnifiedSupplierEntityMapper.insertSelective(accountingUnifiedSupplierEntity);
        }

    }

    private QchjcAccountingUnifiedSupplierEntity getQchjcAccountingUnifiedSupplierEntity(QchjcAccountingUnifiedSupplierEntity param, QchjcAccountingUnifiedSupplierParam param1) {
        QchjcAccountingUnifiedSupplierEntity copy = param;
        copy.setSyncTime(DateUtil.date());//同步时间
        copy.setInvoiceStatus(InvoiceApplySupplierMakeInvoiceStatusEnum.已开票.getKey());
        copy.setSaleId(param1.getSellerSupplierId());
        copy.setSaleName(param1.getSellerSupplierName());
        copy.setAccountingOrderAmount(param1.getAccountingAmount());
        return copy;
    }

    /**
     * 保存对账单的订单、商品明细
     *
     * @param param
     * @param origin
     */
    private Integer handleGoodsAndOrder(QchjcAccountingUnifiedSupplierParam param, QchjcAccountingUnifiedSupplierEntity origin) {
        Integer count = 0;
        //修改已有的商品，订单信息，新增不存在的订单和商品 需要注意并发问题
        List<QchjcOrderParam> orderSelected = param.getOrderSelected();

        String accountingOrderSn = param.getAccountingOrderSn();
        for (QchjcOrderParam orderParam : orderSelected) {
            QchjcOrderEntityExample qchjcOrderEntityExample = new QchjcOrderEntityExample();
            qchjcOrderEntityExample.createCriteria().andOrderSnEqualTo(orderParam.getOrderSn());
            List<QchjcOrderEntity> qchjcOrderEntities = qchOrderEntityMapper.selectByExample(qchjcOrderEntityExample);
            if (CollectionUtils.isNotEmpty(qchjcOrderEntities) && qchjcOrderEntities.get(0) != null) {
                QchjcOrderEntity qchjcOrderEntity = qchjcOrderEntities.get(0);
                //订单已存在,修改订单信息和商品信息，订单表加行锁
                QchjcOrderEntity orderEntity = qchOrderEntityMapper.selectByIdForUpdate(qchjcOrderEntity.getId());
                QchjcOrderEntity order = convertQchParam2QchEntity(orderParam, orderEntity, accountingOrderSn);
                qchOrderEntityMapper.updateByPrimaryKeySelective(order);

                //修改订单商品明细，存在的商品修改，不存在的商品新增
                List<QchjcOrderGoodsParam> orderGoodsSelected = orderParam.getOrderGoodsSelected();
                for (QchjcOrderGoodsParam qchjcOrderGoodsParam : orderGoodsSelected) {
                    QchjcOrderGoodsEntityExample qchjcOrderGoodsEntityExample = new QchjcOrderGoodsEntityExample();
                    qchjcOrderGoodsEntityExample.createCriteria().andOrderSnEqualTo(orderParam.getOrderSn())
                            .andOutSnapshotOrderGoodsIdEqualTo(qchjcOrderGoodsParam.getOutSnapshotOrderGoodsId());
                    List<QchjcOrderGoodsEntity> qchjcOrderGoodsEntities = qchOrderGoodsEntityMapper.selectByExample(qchjcOrderGoodsEntityExample);
                    if (CollectionUtils.isNotEmpty(qchjcOrderGoodsEntities) && qchjcOrderGoodsEntities.get(0) != null) {
                        QchjcOrderGoodsEntity qchjcOrderGoodsEntity = qchjcOrderGoodsEntities.get(0);
                        // 校验是否重复推送的商品
                        if(CommonAccountingStateEnum.已对账.getKey().equals(qchjcOrderGoodsEntity.getAccountingStateSupplier())) {
                            throw new OpenApiException(500, "订单" + orderParam.getOrderSn() + "已对账，所属对账单编号为：" + qchjcOrderGoodsEntity.getSupplierAccountingOrderSn() + ",不能重复对账");
                        }
                        //商品已存在，修改商品信息
                        qchjcOrderGoodsEntity = convertQchGoodsParam2Entity(qchjcOrderGoodsParam, qchjcOrderGoodsEntity,accountingOrderSn, qchjcOrderGoodsParam.getOrderSn());
                        qchOrderGoodsEntityMapper.updateByPrimaryKeySelective(qchjcOrderGoodsEntity);
                    } else {
                        //商品不存在，新增商品
                        QchjcOrderGoodsEntity orderGoods = convertQchGoodsParam2Entity(qchjcOrderGoodsParam, null,accountingOrderSn, qchjcOrderGoodsParam.getOrderSn());
                        qchOrderGoodsEntityMapper.insertSelective(orderGoods);
                    }
                    count += 1;
                }

                //todo 删除表里已经存在，但是新推送参数中不存在的商品 ?
                //List<String> collect = orderGoodsSelected.stream().map(QchjcOrderGoodsParam::getOutSnapshotOrderGoodsId).collect(Collectors.toList());
                //QchjcOrderGoodsEntityExample qchjcOrderGoodsEntityExample = new QchjcOrderGoodsEntityExample();
                //qchjcOrderGoodsEntityExample.createCriteria().andOrderSnEqualTo(orderParam.getOrderSn())
                //        .andOutSnapshotOrderGoodsIdNotIn(collect);
                //qchOrderGoodsEntityMapper.deleteByExample(qchjcOrderGoodsEntityExample);


            } else {
                //订单不存在，新增
                QchjcOrderEntity order = convertQchParam2QchEntity(orderParam, null, accountingOrderSn);
                qchOrderEntityMapper.insertSelective(order);
                //新增商品
                List<QchjcOrderGoodsParam> orderGoodsSelected = orderParam.getOrderGoodsSelected();
                String orderSn = orderParam.getOrderSn();
                //遍历保存商品
                for (QchjcOrderGoodsParam goodsParam : orderGoodsSelected) {
                    QchjcOrderGoodsEntity orderGoods = convertQchGoodsParam2Entity(goodsParam, null,accountingOrderSn, orderSn);
                    qchOrderGoodsEntityMapper.insertSelective(orderGoods);
                    count += 1;
                }
            }
        }
        return count;
    }

    private QchjcOrderGoodsEntity convertQchGoodsParam2Entity(QchjcOrderGoodsParam qchjcOrderGoodsParam, QchjcOrderGoodsEntity qchjcOrderGoodsEntity, String accountingOrderSn, String orderSn) {
        if (qchjcOrderGoodsEntity == null) {
            qchjcOrderGoodsEntity = AnBeanUtils.copy(qchjcOrderGoodsParam, QchjcOrderGoodsEntity.class);
        }else {
            qchjcOrderGoodsEntity = AnBeanUtils.copy(qchjcOrderGoodsParam, qchjcOrderGoodsEntity);
        }
        qchjcOrderGoodsEntity.setOrderSn(orderSn);
        qchjcOrderGoodsEntity.setSyncTime(DateUtil.date());
        qchjcOrderGoodsEntity.setSupplierAccountingOrderSn(accountingOrderSn);
        return qchjcOrderGoodsEntity;
    }

    private QchjcOrderEntity convertQchParam2QchEntity(QchjcOrderParam orderParam, QchjcOrderEntity orderEntity, String accountingOrderSn) {
        if (orderEntity == null) {
            orderEntity = AnBeanUtils.copy(orderParam, QchjcOrderEntity.class);
        }else {
            orderEntity = AnBeanUtils.copy(orderParam, orderEntity);
        }
        //orderEntity.setAccountingOrderSn(accountingOrderSn);
        orderEntity.setSupplierAccountingOrderSn(accountingOrderSn);
        orderEntity.setSyncTime(DateUtil.date());
        orderEntity.setServiceNo(CommonServiceNoEnum.企业商城_侨城汇.getServiceNo());
        orderEntity.setAmount(orderParam.getOrderAmount());
        orderEntity.setSaleId(orderParam.getSupplierId());
        orderEntity.setSaleName(orderParam.getSupplierName());
        orderEntity.setCostAmount(orderParam.getOrderCostAmount());
        orderEntity.setTransportAmount(orderParam.getTransportAmount());
        orderEntity.setTransportMerchantAssumeAmount(orderParam.getTransportMerchantAssumeAmount());
        return orderEntity;
    }

    /**
     * 外部用户入库统一订单，保存映射关系
     *
     * @param param
     */
    private void handleUser(QchjcAccountingUnifiedSupplierParam param) {
        String createUserId   = param.getCreateUserId();
        String createUserName = param.getCreateUserName();
        String updateUserId   = param.getUpdateUserId();
        String updateUserName = param.getUpdateUserName();

        handle(createUserId, createUserName);
        handle(updateUserId, updateUserName);
    }

    private void handle(String userId, String userName) {
        QchjcUserEntityExample example = new QchjcUserEntityExample();
        example.createCriteria()
                .andOutIdEqualTo(userId);
        List<QchjcUserEntity> creator = qchjcUserEntityMapper.selectByExample(example);
        QchjcUserEntity       createUser;
        if (CollectionUtils.isEmpty(creator) || null == creator.get(0)) {
            createUser = QchjcUserEntity.builder()
                    .outId(userId)
                    .userName(userName).build();
            qchjcUserEntityMapper.insertSelective(createUser);
        } else {
            createUser = creator.get(0);
        }
        if (createUser.getUnifiedId() == null) {
            //用户入库统一订单
            SysUser sysUser4Qchjc = sysUserService.createSysUser4Qchjc(userId, userName);
            if (sysUser4Qchjc == null) {
                createUser.setStorageStatus(QchjcStorageStatusEnum.FAIL.getStatus());
                qchjcUserEntityMapper.updateByPrimaryKeySelective(createUser);
                throw new OpenApiException(500, "同步失败,用户入库异常");
            }
            //保存统一订单用户id
            createUser.setUnifiedId(sysUser4Qchjc.getId());
            createUser.setStorageStatus(QchjcStorageStatusEnum.SUCCESS.getStatus());
            createUser.setStorageTime(DateUtil.date());
            qchjcUserEntityMapper.updateByPrimaryKeySelective(createUser);
        }
    }
}
