package com.zfire.mall.manager.logic.wallet;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.EnumUtil;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.utils.StringUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zfire.mall.manager.bean.CommonCountBean;
import com.zfire.mall.manager.bean.ExcelData;
import com.zfire.mall.manager.bean.ReceivableOrderBean;
import com.zfire.mall.manager.bean.admin.AdminUserCom;
import com.zfire.mall.manager.bean.k3.K3CustomerBean;
import com.zfire.mall.manager.bean.k3.KingDeeWalletVO;
import com.zfire.mall.manager.bean.k3.bill.OtherReceItemBean;
import com.zfire.mall.manager.bean.k3.bill.SyncK3OtherReceBean;
import com.zfire.mall.manager.bean.listV2.*;
import com.zfire.mall.manager.bean.listV2.dto.CustomerAmountDTO;
import com.zfire.mall.manager.bean.listV2.dto.ExamineZfireParamBean;
import com.zfire.mall.manager.bean.rece.ReceivableItemBean;
import com.zfire.mall.manager.bean.wallet.*;
import com.zfire.mall.manager.commonmapper.listV2.CommonCMapper;
import com.zfire.mall.manager.commonmapper.rece.ReceMapper;
import com.zfire.mall.manager.commonmapper.wallet.WalletCommonMapper;
import com.zfire.mall.manager.constant.Constant;
import com.zfire.mall.manager.constant.KingDeeCons;
import com.zfire.mall.manager.enums.ExamineStatusEnum;
import com.zfire.mall.manager.enums.WalletTypeEnum;
import com.zfire.mall.manager.exception.RemoteServiceException;
import com.zfire.mall.manager.helper.ResponseHelper;
import com.zfire.mall.manager.logic.admin.AdminUserLogic;
import com.zfire.mall.manager.logic.admin.AdminWebsitLogic;
import com.zfire.mall.manager.logic.common.CommonLogic;
import com.zfire.mall.manager.logic.k3.K3CustomerLogic;
import com.zfire.mall.manager.logic.k3.bill.K3OtherReceLogic;
import com.zfire.mall.manager.plus.entity.*;
import com.zfire.mall.manager.plus.service.*;
import com.zfire.mall.manager.zfire.bean.ZfireParamBean;
import com.zfire.mall.manager.zfire.util.FieldUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.stream.Collectors;

@Slf4j
@Service
public class WalletLogic {

    @Autowired
    WalletCommonMapper walletCommonMapper;
    @Autowired
    WalletRebateService walletRebateService;
    @Autowired
    WalletRebateSaleTypeService walletRebateSaleTypeService;
    @Autowired
    CustomerWalletService customerWalletService;
    @Autowired
    CustomerWalletRecordService customerWalletRecordService;
    @Autowired
    KingDeeWalletService kingDeeWalletService;
    @Autowired
    CustomerWalletTransferService customerWalletTransferService;
    @Autowired
    ReceivableOrderService receivableOrderService;
    @Autowired
    ReceivableOrderItemService receivableOrderItemService;
    @Autowired
    SaleTypeService saleTypeService;
    @Autowired
    CommonLogic commonLogic;
    @Autowired
    AdminUserLogic adminUserLogic;
    @Autowired
    RedisLockRegistry redisLockRegistry;
    @Autowired
    CustomerWalletCreditLogic customerWalletCreditLogic;
    @Autowired
    K3CustomerLogic k3CustomerLogic;
    @Autowired
    K3OtherReceLogic k3OtherReceLogic;
    @Autowired
    KingDeeCustomerService kingDeeCustomerService;
    @Autowired
    AdminWebsitLogic adminWebsitLogic;
    @Autowired
    CustomerWalletReconciliationService customerWalletReconciliationService;
    @Resource
    ReceMapper receMapper;
    @Autowired
    CommonCMapper commonCMapper;
    @Autowired
    RebateOrderLogic rebateOrderLogic;


    final List<String> GLB_BillTypeList = new ArrayList<String>(){
        {
            add(Constant.BILL_TYPE_SKDFS);
            add(Constant.BILL_TYPE_TKDFS);
            add(Constant.BILL_TYPE_FKDFS);
            add(Constant.BILL_TYPE_OFKD);
            add(Constant.BILLTYPE_FLD_ZR);
        }
    };

    final List<String> GLB_BILL_SOURCE = new ArrayList<String>(){
        {
            add("工程价差");
            add("仓储费");
            add("工程收差");
            add("运输费");
        }
    };


    /**
     * 返利钱包列表
     */
    public IPage<WalletRebateVO> listV2(ZfireParamBean zfireParamBean){
        zfireParamBean = FieldUtils.supplyParam(zfireParamBean);
        return commonCMapper.queryWalletRebate(new Page(zfireParamBean.getPageNum(),zfireParamBean.getPageSize()),zfireParamBean);
    }



    /**
     * 新增返利钱包
     * @param wallet
     */
    @Transactional
    public void add(WalletRebate wallet){
        Integer count = walletRebateService.lambdaQuery().eq(WalletRebate::getName, wallet.getName()).count();
        if(count > 0){
            throw new RemoteServiceException(wallet.getName()+"已存在");
        }
        AdminUserCom adminUser = commonLogic.getAdminUser();
        wallet.setAdminCompanyId(adminUser.getAdminCompanyId());
        wallet.insert();
        //初始化所有经销商的返利钱包
        this.initRebateByK3Customer();
    }

    /**
     * 修改返利钱包
     */
    public void update(WalletRebate wallet){
        Integer count = walletRebateService.lambdaQuery()
                .eq(WalletRebate::getName, wallet.getName())
                .ne(WalletRebate::getWalletRebateId,wallet.getWalletRebateId()).count();
        if(count > 0){
            throw new RemoteServiceException(wallet.getName()+"已存在");
        }
        wallet.updateById();
    }

    /**
     * 返利钱包销售类型-列表V2
     */
    public IPage<WalletSaleTypeRelaVO> listRebateSaleTypeV2(ZfireParamBean zfireParamBean){
        zfireParamBean = FieldUtils.supplyParam(zfireParamBean);
        IPage<WalletSaleTypeRelaVO> page = commonCMapper.queryWalletSaleType(new Page(zfireParamBean.getPageNum(), zfireParamBean.getPageSize()), zfireParamBean);
        return page;
    }


    /**
     * 返利钱包销售类型-列表
     */
    public IPage<RebateWalletSaleBean> listRebateSaleType(String name, String saleTypeCode,String saleTypeName, Boolean status, Integer pageNum, Integer pageSize){
        IPage<RebateWalletSaleBean> rebateWalletSaleBeanIPage = walletCommonMapper.
                queryRebateWalletSaleTypeList(new Page(pageNum, pageSize), name, saleTypeCode, saleTypeName, status);
        return rebateWalletSaleBeanIPage;
    }

    public ExcelData listRebateSaleTypeExport(List<RebateWalletSaleBean> list){
        String[] titles = new String[]{"销售类型编码","销售类型名称","返利类型","返利折扣比例","状态","创建人","创建时间"};
        List<List<Object>> rows = new ArrayList<>();

        for (RebateWalletSaleBean bean : list) {
            List<Object> row = new ArrayList<>();
            row.add(bean.getSaleTypeCode());
            row.add(bean.getSaleTypeName());
            row.add(bean.getName());
            row.add(bean.getRebateRate());
            row.add(bean.getStatus()?"已启用":"未启用");
            row.add(bean.getCreateBy());
            row.add(DateUtil.formatDate(bean.getCreateTime()));
            rows.add(row);
        }
        ExcelData excelData = new ExcelData();
        excelData.setRows(rows);
        excelData.setTitles(Arrays.asList(titles));
        return excelData;
    }

    /**
     * 新增返利钱包销售类型
     */
    @Transactional
    public void addRebateSaleType(WalletRebateSaleType walletRebateSaleType){
        Integer count = walletRebateSaleTypeService.lambdaQuery()
                .eq(WalletRebateSaleType::getWalletRebateId, walletRebateSaleType.getWalletRebateId())
                .eq(WalletRebateSaleType::getSaleTypeId, walletRebateSaleType.getSaleTypeId())
                .count();
        if(count > 0){
            throw new RemoteServiceException("请勿给返利钱包重复添加销售类型");
        }
        walletRebateSaleType.insert();
    }

    /**
     * 修改返利钱包销售类型
     */
    public void updateRebateSaleType(WalletRebateSaleType walletRebateSaleType){
        Integer count = walletRebateSaleTypeService.lambdaQuery()
                .eq(WalletRebateSaleType::getWalletRebateId, walletRebateSaleType.getWalletRebateId())
                .eq(WalletRebateSaleType::getSaleTypeId, walletRebateSaleType.getSaleTypeId())
                .ne(WalletRebateSaleType::getWalletRebateSaleTypeId,walletRebateSaleType.getWalletRebateSaleTypeId())
                .count();
        if(count > 0){
            throw new RemoteServiceException("请勿给返利钱包重复添加销售类型");
        }
        walletRebateSaleType.updateById();
    }

    /**
     * 返利钱包销售类型详情
     */
    public WalletRebateSaleType detailRebateSaleType(String walletRebateSaleTypeId){
        WalletRebateSaleType walletRebateSaleType = walletRebateSaleTypeService.getById(walletRebateSaleTypeId);
        return walletRebateSaleType;
    }

    /**
     * 删除返利钱包销售类型
     */
    public void deleteRebateSaleType(List<String> ids){
        walletRebateSaleTypeService.lambdaUpdate().in(WalletRebateSaleType::getWalletRebateSaleTypeId,ids).remove();
    }


    /**
     * 返利钱包详情
     */
    public WalletRebateBean detail(String id){
        WalletRebate wallet = walletRebateService.getById(id);
        WalletRebateBean bean = new WalletRebateBean();
        BeanUtils.copyProperties(wallet,bean);
        //查询钱包的销售类型
        List<WalletRebateSaleType> list1 = walletRebateSaleTypeService.lambdaQuery().eq(WalletRebateSaleType::getWalletRebateId, id).list();
        bean.setSaleTypes(list1);
        return bean;
    }

    /**
     * 现金钱包详情
     */
    public KingDeeWallet kingDeedetail(String id){
        KingDeeWallet wallet = kingDeeWalletService.getById(id);
        return wallet;
    }

    /**
     * 设置特定的返利钱包的比例
     */
    public void updateRate(String customerWalletId,BigDecimal rebateRate){
        CustomerWallet customerWallet = customerWalletService.getById(customerWalletId);
        if(customerWallet == null || !customerWallet.getType().equals(WalletTypeEnum.REBATE.getKey())){
            throw new RemoteServiceException("返利钱包不存在");
        }
        if(rebateRate.doubleValue() > 1 || rebateRate.doubleValue() < 0){
            throw new RemoteServiceException("返利钱包比例必须0-1之间");
        }
        //customerWallet.setRebateRate(rebateRate);
        customerWallet.updateById();
    }

    /**
     * 返利钱包列表
     */
    public IPage<WalletRebateBean> list(String name, Boolean status, Integer pageNo, Integer pageSize){
        AdminUserCom adminUser = commonLogic.getAdminUser();

        IPage page = walletRebateService.lambdaQuery()
                .in(CollectionUtils.isNotEmpty(adminUser.getAdminCompanyIds()), WalletRebate::getAdminCompanyId, adminUser.getAdminCompanyIds())
                .like(StringUtils.isNotEmpty(name),WalletRebate::getName,name)
                .eq(status != null,WalletRebate::getStatus,status)
                .orderByDesc(WalletRebate::getCreateTime)
                .page(new Page<>(pageNo, pageSize));

        List<WalletRebateBean> list = new ArrayList<>();
        for(Object o : page.getRecords()){
            WalletRebate rebate = (WalletRebate)o;
            WalletRebateBean bean = new WalletRebateBean();
            BeanUtils.copyProperties(rebate,bean);

            //查询钱包的销售类型
            List<WalletRebateSaleType> list1 = walletRebateSaleTypeService.lambdaQuery().eq(WalletRebateSaleType::getWalletRebateId, rebate.getWalletRebateId()).list();
            bean.setSaleTypes(list1);

            list.add(bean);
        }
        page.setRecords(list);
        return page;
    }


    /**
     * 钱包列表
     */
    public List<KingDeeWallet> list(String walletName){
        List<KingDeeWallet> list = kingDeeWalletService.lambdaQuery()
                .like(StringUtils.isNotEmpty(walletName),KingDeeWallet::getName,walletName)
                .list();
        return list;
    }

    //所有返利钱包
    public List<WalletRebate> queryWalletRebateList(){
        return walletRebateService.list();
    }


    public List<CustomerWallet> queryCustomerWalletByCustomerId(String customerId){
        List<CustomerWallet> list = customerWalletService.lambdaQuery().eq(CustomerWallet::getCustomerId, customerId).list();
        return list;
    }

    public CustomerWallet queryCustomerWallet(String customerId,String walletId){
        CustomerWallet one = customerWalletService.lambdaQuery()
                .eq(CustomerWallet::getCustomerId, customerId)
                .eq(CustomerWallet::getWalletRebateId, walletId).one();
        return one;
    }


    public CustomerWallet queryCustomerWalletById(String customerWalletId){
        return customerWalletService.getById(customerWalletId);
    }

    public List<CustomerWalletBean> queryWalletByCustomerId(String customerId,String type){
        return this.queryWalletByCustomerId(customerId,type,null);
    }

    /**
     * 经销商的钱包列表
     */
    public List<CustomerWalletBean> queryWalletByCustomerId(String customerId,String type,Boolean hasRecord){
        if(StringUtils.isEmpty(customerId)){
            return new ArrayList<>();
        }
        List<CustomerWalletBean> customerWalletBeans = walletCommonMapper
                .queryWalletByCustomerId(new Page(1,-1,false),customerId,type,hasRecord,null,null).getRecords();
        if(CollectionUtils.isEmpty(customerWalletBeans)){
            return new ArrayList<>();
        }
        List<WalletRebateSaleType> walletSaleTypes = walletRebateSaleTypeService.list();
        for(CustomerWalletBean bean : customerWalletBeans){
            List<WalletRebateSaleType> walletRebateSaleTypes = walletSaleTypes.stream()
                    .filter(v -> v.getWalletRebateId().equals(bean.getWalletRebateId()))
                    .collect(Collectors.toList());
            List<String> saleTypeIds = walletRebateSaleTypes.stream().map(WalletRebateSaleType::getSaleTypeId).collect(Collectors.toList());
            bean.setWalletRaleTypes(walletRebateSaleTypes);
            bean.setSaleTypeIds(saleTypeIds);
        }
        return customerWalletBeans;
    }

    /***
     * 组织数据
     */
    public ExcelData exportWalletCount(String customerNumber,String startCustomerId,String endCustomerId){

        List<String> titles = Arrays.asList("经销商编码", "经销商名称","钱包类型","钱包名称", "余额","已使用信用额度","可使用信用额度");
        List<List<Object>> rows = new ArrayList<>();
        List<WalletCountBean> itemBeans = walletCommonMapper.queryWalletByCustomerIdRange(startCustomerId,endCustomerId);
        List<WalletCountBean> countBeans = walletCommonMapper.queryWalletByCustomerIdRangeCount(startCustomerId,endCustomerId);
        Map<String, List<WalletCountBean>> groupByNum = itemBeans.stream().collect(Collectors.groupingBy(WalletCountBean::getCustomerNumber));
        for (Map.Entry<String, List<WalletCountBean>> entry: groupByNum.entrySet()) {
            String key = entry.getKey();
            List<WalletCountBean> entryUserList = entry.getValue();
            for(WalletCountBean  count:countBeans){
                if(key.equals(count.getCustomerNumber())){
                    if(count.getType().equals("COMMONLY")){
                        WalletCountBean bean = new WalletCountBean();
                        bean.setCustomerNumber("现金钱包合计:");
                        bean.setAmount(count.getAmountC().subtract(count.getUseCreditC()));
                        bean.setFreeCreditAmount(count.getFreeUseCreditC());
                        bean.setUsedCreditAmount(count.getUseCreditC());
                        entryUserList.add(bean);
                    }
                    if(count.getType().equals("REBATE")){
                        WalletCountBean bean = new WalletCountBean();
                        bean.setCustomerNumber("返利钱包合计:");
                        bean.setAmount(count.getAmountC());
                        entryUserList.add(bean);
                    }
                }
            }
        }

        for (Map.Entry<String, List<WalletCountBean>> entry: groupByNum.entrySet()) {
            List<WalletCountBean> entryList = entry.getValue();
                    for(WalletCountBean item :entryList){
                            List<Object> row = new ArrayList<>();
                            row.add(item.getCustomerNumber());
                            row.add(item.getCustomerName());
                            if(item.getType() != null && item.getType().equals("COMMONLY"))
                            { row.add("现金钱包"); }
                            else if(item.getType() != null && item.getType().equals("REBATE"))
                            { row.add("返利钱包"); }
                            else{
                                row.add("");
                            }
                            row.add(item.getWalletName());
                            row.add(item.getAmount().subtract(item.getUsedCreditAmount()));
                            row.add(item.getUsedCreditAmount());
                            row.add(item.getFreeCreditAmount());
                            rows.add(row);
                    }

        }

        ExcelData excelData = new ExcelData();
        excelData.setTitles(titles);
        excelData.setRows(rows);
        return excelData;

    }


    /**
     * 经销商的钱包列表
     */
    public IPage<CustomerWalletBean> queryWalletByCustomerId(String customerId,String type,Boolean hasRecord,
                                                             BigDecimal minFreeAmount,BigDecimal maxFreeAmount,Integer pageNum,Integer pageSize){
        IPage<CustomerWalletBean> customerWalletBeanIPage = walletCommonMapper
                .queryWalletByCustomerId(new Page(pageNum, pageSize), customerId,type,hasRecord,minFreeAmount,maxFreeAmount);
        return customerWalletBeanIPage;
    }



    /**
     * 经销商的钱包详情
     */
    public CustomerWalletBean queryWalletDetailByCustomerId(String customerWalletId){
        CustomerWalletBean customerWalletBean = walletCommonMapper.queryWalletDetailByCustomerId(customerWalletId);
        return customerWalletBean;
    }


    /**
     * 需要初始化经销商的返利钱包
     */
    public void initByAddUser(List<String> adminCompanyIds,String customerId){
        List<CustomerWallet> list1 = customerWalletService.lambdaQuery()
                .eq(CustomerWallet::getCustomerId, customerId)
                .eq(CustomerWallet::getType, WalletTypeEnum.REBATE.getKey()).list();

        List<String> walletIds = list1.stream().map(CustomerWallet::getWalletRebateId).collect(Collectors.toList());
        //1.初始化经销商的返利钱包
        List<WalletRebate> list = walletRebateService.lambdaQuery()
                .in(CollectionUtils.isNotEmpty(adminCompanyIds), WalletRebate::getAdminCompanyId, adminCompanyIds).list();
        if(list.size() > 0){
            K3CustomerBean detail = k3CustomerLogic.detail(customerId);
            for(WalletRebate walletRebate : list){
                if(walletIds.contains(walletRebate.getWalletRebateId())){
                    continue;
                }
                CustomerWallet customerWallet = new CustomerWallet();
                customerWallet.setCustomerId(customerId);
                customerWallet.setCustomerNumber(detail.getNumber());
                customerWallet.setCustomerName(detail.getName());
                customerWallet.setWalletRebateId(walletRebate.getWalletRebateId());
                customerWallet.setCustomerWalletName(walletRebate.getName());
                customerWallet.setType(WalletTypeEnum.REBATE.getKey());
                customerWallet.insert();
            }
        }
    }


    /**
     * 钱包绑定品类
     */
    public void bindMain(String id,Boolean isZr,Boolean isRebate){
        KingDeeWallet kingDeeWallet = kingDeeWalletService.getById(id);
        if(kingDeeWallet == null){
            throw new RemoteServiceException("钱包不存在");
        }
        kingDeeWallet.setIsZr(isZr);
        kingDeeWallet.setIsRebate(isRebate);
        kingDeeWallet.updateById();
    }


    /**
     * 对账列表v2
     */
    public IPage<CustomerWalletRecordVO> standingBookListV2(ZfireParamBean zfireParamBean){
        zfireParamBean = FieldUtils.supplyParam(zfireParamBean);
        IPage<CustomerWalletRecordVO> page = commonCMapper.queryCustomerWalletRecord(new Page(zfireParamBean.getPageNum(), zfireParamBean.getPageSize()), zfireParamBean);
        return page;
    }



    /**
     * 台账列表
     *  需要过滤 退货单，收款单 反审的数据
     */
    public IPage<CustomerWalletRecord> standingBookList(String customerId,String customerNumber,String customerName,String type,
                                                        String customerWalletId,String walletRebateId,String billNo,String enginRecordNo,
                                                        String startTime,String endTime,Boolean isReconciliation,String billType,String remark,
                                                        Integer pageNum,Integer pageSize){
        AdminUserCom adminUser = commonLogic.getAdminUser();

        //List<String> billTypes = Arrays.asList(Constant.BILL_TYPE_SKDFS, Constant.BILL_TYPE_SKDFS);

        IPage<CustomerWalletRecord> page = customerWalletRecordService.lambdaQuery()
              //  .ne(type != null && type.equals(WalletTypeEnum.REBATE.getKey()),CustomerWalletRecord::getAmount,0)
                .eq(StringUtils.isNotEmpty(customerId),CustomerWalletRecord::getCustomerId,customerId)
                .like(StringUtils.isNotEmpty(customerNumber),CustomerWalletRecord::getCustomerCode,customerNumber)
                .like(StringUtils.isNotEmpty(customerName),CustomerWalletRecord::getCustomerName,customerName)
                .eq(StringUtils.isNotEmpty(type), CustomerWalletRecord::getType, type)
                .eq(adminUser.getIsCustomer(),CustomerWalletRecord::getCustomerId,adminUser.getCustomerId())
                .eq(StringUtils.isNotEmpty(customerWalletId),CustomerWalletRecord::getCustomerWalletId,customerWalletId)
                .eq(StringUtils.isNotEmpty(walletRebateId), CustomerWalletRecord::getWalletRebateId, walletRebateId)
                .eq(null != isReconciliation,CustomerWalletRecord::getIsReconciliation,isReconciliation)
                .like(StringUtils.isNotEmpty(billNo), CustomerWalletRecord::getBillNo, billNo)
                .like(StringUtils.isNotEmpty(enginRecordNo),CustomerWalletRecord::getEnginRecordNo,enginRecordNo)
                .like(StringUtils.isNotEmpty(remark),CustomerWalletRecord::getRemark,remark)
                .eq(StringUtils.isNotEmpty(billType), CustomerWalletRecord::getBillType, billType)
         //       .notIn(CustomerWalletRecord::getBillType,billTypes)
                .between(StringUtils.isNotEmpty(startTime) && StringUtils.isNotEmpty(endTime), CustomerWalletRecord::getCreateTime, startTime, endTime+" 23:59:59")
                .orderByDesc(CustomerWalletRecord::getCreateTime,CustomerWalletRecord::getId)
                .page(new Page<>(pageNum, pageSize));
        return page;
    }





    public AmountCountBean amountCount(String customerId, String customerNumber, String customerName, String type,
                                       String customerWalletId, String walletRebateId, String billNo,
                                       String startTime, String endTime, Boolean isReconciliation,String billType){
        AdminUserCom adminUser = commonLogic.getAdminUser();
        if(StringUtils.isNotEmpty(startTime) && StringUtils.isNotEmpty(endTime)){
            startTime = startTime.substring(0,10)+" 00:00:00";
            endTime = endTime.substring(0,10) + " 23:59:59";
        }

       return walletCommonMapper.amountCount(customerId, customerNumber, customerName, type, customerWalletId,
               walletRebateId, billNo, startTime, endTime,isReconciliation,adminUser.getIsCustomer(),billType);
    }


    /**
     * 返利单互转列表
     */
    public IPage<CustomerWalletTransferVO> transferListV2(ExamineZfireParamBean examineZfireParamBean){
        ZfireParamBean zfireParamBean = FieldUtils.supplyParam(examineZfireParamBean);

        AdminUserCom adminUser = commonLogic.getAdminUser();
        String customerId = adminUser.getIsCustomer()?adminUser.getCustomerId():null;

        IPage<CustomerWalletTransferVO> page = commonCMapper.queryCustomerWalletTransfer(new Page(examineZfireParamBean.getPageNum(),
                examineZfireParamBean.getPageSize()), zfireParamBean, examineZfireParamBean.getExamineStatus(),customerId);
        return page;
    }


    /**
     * 返利互转列表
     */
    public IPage<CustomerWalletTransfer> transferList(String id,String examineStatus,String walletName,String startTime,
                                                     String endTime,String customerName,Integer pageNum,Integer pageSize){
        AdminUserCom adminUser = commonLogic.getAdminUser();
        IPage<CustomerWalletTransfer> page = customerWalletTransferService.lambdaQuery()
                .like(StringUtils.isNotEmpty(id),CustomerWalletTransfer::getId, id)
                .like(StringUtils.isNotEmpty(customerName),CustomerWalletTransfer::getCustomerName, customerName)
                .eq(adminUser.getIsCustomer(),CustomerWalletTransfer::getCustomerId,adminUser.getCustomerId())
                .eq(StringUtils.isNotEmpty(examineStatus),CustomerWalletTransfer::getExamineStatus,examineStatus)
                .and(StringUtils.isNotEmpty(walletName), v ->
                        v.like(CustomerWalletTransfer::getInitiatorCustomerWalletName, walletName)
                                .or().like(CustomerWalletTransfer::getReceiverCustomerWalletName, walletName)
                )
                .between(StringUtils.isNotEmpty(startTime) && StringUtils.isNotEmpty(endTime), CustomerWalletTransfer::getApplyTime, startTime, endTime)
                .orderByDesc(CustomerWalletTransfer::getCreateTime)
                .page(new Page<>(pageNum, pageSize));
        return page;
    }

    /**
     * 返利互转列表 (统计) todo
     */
    public CommonCountBean transferListCount(String id, String examineStatus, String walletName, String startTime,
                                             String endTime,String customerName){
        AdminUserCom adminUser = commonLogic.getAdminUser();
        return new CommonCountBean();
    }


    /**
     * 返利互转详情
     * @param id
     * @return
     */
    public CustomerWalletTransfer transferDetail(String id){
        CustomerWalletTransfer bean = customerWalletTransferService.getById(id);
        return bean;
    }


    /**
     * 返利钱包转账
     * @param initiatorWalletRebateId
     * @param receiverWalletRebateId
     * @param amount
     * @return
     */
    @Transactional
    public void add(String initiatorWalletRebateId,String receiverWalletRebateId,BigDecimal amount,
                    String initiatorRemark,String receiverRemark,BigDecimal allowanceAmount,BigDecimal initiatorAmount,String remark) throws InterruptedException {
        AdminUserCom adminUser = commonLogic.getAdminUser();

        CustomerWalletBean customerWallet1 = this.queryWalletDetailByCustomerId(initiatorWalletRebateId);
        CustomerWalletBean customerWallet2 = this.queryWalletDetailByCustomerId(receiverWalletRebateId);

        rebateOrderLogic.checkNeedAck(customerWallet1.getCustomerWalletId());
        rebateOrderLogic.checkNeedAck(customerWallet2.getCustomerWalletId());

        if(customerWallet1 == null || customerWallet2 == null){
            throw new RemoteServiceException("钱包不存在");
        }
        if(!customerWallet1.getType().equals(WalletTypeEnum.REBATE.getKey())
                || !customerWallet2.getType().equals(WalletTypeEnum.REBATE.getKey())){
            throw new RemoteServiceException("非返利钱包不可申请");
        }
        if(customerWallet1.getAmount().doubleValue() < amount.doubleValue()){
            throw new RemoteServiceException(customerWallet1.getName() + "金额不够，无法转账");
        }

        if(allowanceAmount == null ){
            allowanceAmount = new BigDecimal(0);
        }
        if(amount == null ){
            amount = new BigDecimal(0);
        }

        if(initiatorAmount == null || initiatorAmount.doubleValue() > 0){
            throw new RemoteServiceException("发起方返利金额不能为空或为负数");
        }
        //取对应正数
        initiatorAmount = BigDecimal.valueOf(0).subtract(initiatorAmount);

        if(allowanceAmount.add(amount).doubleValue() !=  initiatorAmount.doubleValue()){
            throw new RemoteServiceException("发起方返利金额不等于接收方返利加折让金额");
        }

        String customerId1 = customerWallet1.getCustomerId();
        String customerId2 = customerWallet2.getCustomerId();
        //如果是经销商申请的，且不是自己的返利钱包，需要限制是同1个集团的
        if(adminUser.getIsCustomer() && !customerId1.equals(customerId2)){
            K3CustomerBean customer1 = k3CustomerLogic.detail(customerId1);
            K3CustomerBean customer2 = k3CustomerLogic.detail(customerId2);
//            if(!customer1.getIsGroupCompany() || !customer2.getIsGroupCompany()){
//                throw new RemoteServiceException("非相同集团的客户不可互转");
//            }
            if(!customer1.getParentId().equals(customer2.getParentId())){
                throw new RemoteServiceException("非相同集团的客户不可互转");
            }
        }


        CustomerWalletTransfer bean = new CustomerWalletTransfer();
        bean.setInitiatorCustomerWalletId(customerWallet1.getCustomerWalletId())
            .setInitiatorCustomerWalletName(customerWallet1.getName())
            .setReceiverCustomerWalletId(customerWallet2.getCustomerWalletId())
            .setReceiverCustomerWalletName(customerWallet2.getName())
            .setAmount(amount)
            .setAllowanceAmount(allowanceAmount)
            .setInitiatorAmount(initiatorAmount)
            .setType(customerWallet1.getType())
            .setCustomerId(adminUser.getCustomerId())
            .setTheTime(new Date())
            .setInitiatorRemark(initiatorRemark)
            .setReceiverRemark(receiverRemark)
            .setCustomerId(customerWallet1.getCustomerId())
            .setCustomerNumber(customerWallet1.getCustomerNumber())
            .setCustomerName(customerWallet1.getCustomerName())
            .setReceiverCustomerName(customerWallet2.getCustomerName())
            .setReceiverCustomerNumber(customerWallet2.getCustomerNumber())
            .setApplyTime(new Date())
                .setRemark(remark)
            .insert();

    }


    /**
     * 返利钱包转账
     * @param initiatorWalletRebateId
     * @param receiverWalletRebateId
     * @param amount
     * @return
     */
    @Transactional
    public void update(String id,String initiatorWalletRebateId,String receiverWalletRebateId,BigDecimal amount,
                       String initiatorRemark,String receiverRemark,String theTime,BigDecimal allowanceAmount,BigDecimal initiatorAmount,String remark){

        AdminUserCom adminUser = commonLogic.getAdminUser();

        CustomerWalletBean customerWallet1 = this.queryWalletDetailByCustomerId(initiatorWalletRebateId);
        CustomerWalletBean customerWallet2 = this.queryWalletDetailByCustomerId(receiverWalletRebateId);

        rebateOrderLogic.checkNeedAck(customerWallet1.getCustomerWalletId());
        rebateOrderLogic.checkNeedAck(customerWallet2.getCustomerWalletId());

        if(customerWallet1 == null || customerWallet2 == null){
            throw new RemoteServiceException("钱包不存在");
        }
        if(customerWallet1.getAmount().doubleValue() < amount.doubleValue()){
            throw new RemoteServiceException("金额不够，无法转账");
        }
        if(!customerWallet1.getType().equals(WalletTypeEnum.REBATE.getKey())
                || !customerWallet2.getType().equals(WalletTypeEnum.REBATE.getKey())){
            throw new RemoteServiceException("非返利钱包不可申请");
        }
        CustomerWalletTransfer bean = customerWalletTransferService.getById(id);
        if(!bean.getExamineStatus().equals(ExamineStatusEnum.SAVE.toString())){
            throw new RemoteServiceException("非保存状态，不可编辑");
        }

        if(amount == null ){
            amount = new BigDecimal(0);
        }
        if(allowanceAmount == null ){
            allowanceAmount = new BigDecimal(0);
        }

        if(initiatorAmount == null || initiatorAmount.doubleValue() > 0){
            throw new RemoteServiceException("发起方返利金额不能为空或为负数");
        }
        //取对应正数
        initiatorAmount = BigDecimal.valueOf(0).subtract(initiatorAmount);

        if(allowanceAmount.add(amount).doubleValue() !=  initiatorAmount.doubleValue()){
            throw new RemoteServiceException("发起方返利金额不等于接收方返利加折让金额");
        }

        String customerId1 = customerWallet1.getCustomerId();
        String customerId2 = customerWallet2.getCustomerId();
        //如果是经销商申请的，且不是自己的返利钱包，需要限制是同1个集团的
        if(adminUser.getIsCustomer() && !customerId1.equals(customerId2)){
            K3CustomerBean customer1 = k3CustomerLogic.detail(customerId1);
            K3CustomerBean customer2 = k3CustomerLogic.detail(customerId2);
            /*if(!customer1.getIsGroupCompany() || !customer2.getIsGroupCompany()){
                throw new RemoteServiceException("非相同集团的客户不可互转");
            }*/
            if(!customer1.getParentId().equals(customer2.getParentId())){
                throw new RemoteServiceException("非相同集团的客户不可互转");
            }
            bean.setCustomerName(customer1.getName());
            bean.setReceiverCustomerName(customer2.getName());
        }

        bean.setInitiatorCustomerWalletId(customerWallet1.getCustomerWalletId());
        bean.setInitiatorCustomerWalletName(customerWallet1.getName());
        bean.setReceiverCustomerWalletId(customerWallet2.getCustomerWalletId());
        bean.setReceiverCustomerWalletName(customerWallet2.getName());
        bean.setAmount(amount);
        bean.setAllowanceAmount(allowanceAmount);
        bean.setInitiatorAmount(initiatorAmount);
        bean.setType(customerWallet1.getType());
        bean.setCustomerId(customerWallet1.getCustomerId());
        bean.setInitiatorRemark(initiatorRemark);
        bean.setReceiverRemark(receiverRemark);
        bean.setCustomerId(customerWallet1.getCustomerId());
        bean.setCustomerNumber(customerWallet1.getCustomerNumber());
        bean.setReceiverCustomerNumber(customerWallet2.getCustomerNumber());
        bean.setApplyTime(new Date());
        if(StringUtils.isNotEmpty(theTime)) {
            bean.setTheTime(DateUtil.parseDateTime(theTime));
        }
        bean.setRemark(remark);
        bean.updateById();
    }

    /**
     * 返利钱包转账-提审
     */
    @Transactional
    public void walletTransferApplyExamine(String id) throws InterruptedException {
        CustomerWalletTransfer customerWalletTransfer = customerWalletTransferService.getById(id);
        if(customerWalletTransfer == null){
            throw new RemoteServiceException("提审失败");
        }
        if(!customerWalletTransfer.getExamineStatus().equals(ExamineStatusEnum.SAVE.toString())){
            throw new RemoteServiceException("不可提审非保存状态的单");
        }
        customerWalletTransfer.setApplyTime(new Date());
        customerWalletTransfer.setExamineStatus(ExamineStatusEnum.WAIT.toString());
        customerWalletTransfer.updateById();

        if(customerWalletTransfer.getInitiatorAmount() == null){
            throw new RemoteServiceException("发起方金额为空，请重新编辑再提审。");
        }
        //提审 扣减 发起方钱
        CustomerWalletAmountBean customerWalletAmountBean = new CustomerWalletAmountBean(customerWalletTransfer.getInitiatorCustomerWalletId(), customerWalletTransfer.getInitiatorAmount(),
                customerWalletTransfer.getInitiatorRemark(), "返利钱包互转", customerWalletTransfer.getTheTime(), customerWalletTransfer.getId(), 1,"sub");
        this.doWalletAmount(customerWalletAmountBean);
    }

    /**
     * 返利钱包转账-取消
     */
    @Transactional
    public void transferCancel(String id) throws InterruptedException {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        CustomerWalletTransfer customerWalletTransfer = customerWalletTransferService.getById(id);
        if(customerWalletTransfer == null){
            throw new RemoteServiceException("取消失败");
        }
        if(!customerWalletTransfer.getExamineStatus().equals(ExamineStatusEnum.WAIT.toString())){
            throw new RemoteServiceException("不可取消非待审核状态的单");
        }
        if(adminUser.getIsCustomer()){
            throw new RemoteServiceException("暂无权限操作");
        }
        customerWalletTransfer.setCancelBy(adminUser.getNickName());
        customerWalletTransfer.setCancelTime(new Date());
        customerWalletTransfer.setExamineStatus(ExamineStatusEnum.SAVE.toString());
        customerWalletTransfer.updateById();

        //取消 返还 发起方钱包金额
        CustomerWalletAmountBean customerWalletAmountBean = new CustomerWalletAmountBean(customerWalletTransfer.getInitiatorCustomerWalletId(), customerWalletTransfer.getInitiatorAmount(),
                customerWalletTransfer.getInitiatorRemark(), "返利钱包互转取消-退回", customerWalletTransfer.getTheTime(), customerWalletTransfer.getId(), 1,"add");
        this.doWalletAmount(customerWalletAmountBean);
    }



    /**
     * 审核
     * @param id
     * @param examineStatus
     * @param remark
     * @throws InterruptedException
     */
    @Transactional
    public void walletTransferExamine(String id,String examineStatus,String remark) throws InterruptedException {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        CustomerWalletTransfer customerWalletTransfer = customerWalletTransferService.getById(id);
        if(customerWalletTransfer == null){
            throw new RemoteServiceException("审核失败");
        }
        if(!customerWalletTransfer.getExamineStatus().equals(ExamineStatusEnum.WAIT.toString())
                && !customerWalletTransfer.getExamineStatus().equals(ExamineStatusEnum.OK_ONE.toString())){
            throw new RemoteServiceException("非待审批状态不可审批");
        }
        if(adminUser.getIsCustomer()){
            throw new RemoteServiceException("暂无权限操作");
        }
//        if(adminUser.getIsCw() && !customerWalletTransfer.getExamineStatus().equals(ExamineStatusEnum.WAIT.toString())){
//            throw new RemoteServiceException("无法审核");
//        }
        List<CustomerWalletAmountBean> customerWalletAmountBeans = new ArrayList<>();
       // examineStatus.equals(ExamineStatusEnum.FAIL.toString())?ExamineStatusEnum.SAVE.toString():examineStatus;
        customerWalletTransfer.setExamineStatus(ExamineStatusEnum.FAIL.toString().equals(examineStatus)? ExamineStatusEnum.REJECT.toString() : examineStatus);
        customerWalletTransfer.setExamineTime(new Date());
        customerWalletTransfer.setExamineBy(adminUser.getNickName());
        //如果审核不通过，需要返回发起方的钱
        if(customerWalletTransfer.getInitiatorAmount() == null){
            throw new RemoteServiceException("数据异常,发起方金额为空");
        }
        if(examineStatus.equals(ExamineStatusEnum.FAIL.toString())){
            customerWalletAmountBeans.add(new CustomerWalletAmountBean(customerWalletTransfer.getInitiatorCustomerWalletId(),customerWalletTransfer.getInitiatorAmount(),customerWalletTransfer.getInitiatorRemark()
                    ,"返利钱包互转审核驳回-退回金额",customerWalletTransfer.getTheTime(),customerWalletTransfer.getId(),1,"add"));

        } else {
            //customerWalletTransfer.setSecondExamineBy(adminUser.getNickName());
            customerWalletTransfer.setSecondExamineRemark(remark);
            customerWalletTransfer.setSecondExamineTime(new Date());
            //审核通过将钱给到接收方
            if(examineStatus.equals(ExamineStatusEnum.OK.toString())){
                if(customerWalletTransfer.getAmount().doubleValue() > 0){
                    customerWalletAmountBeans.add(new CustomerWalletAmountBean(customerWalletTransfer.getReceiverCustomerWalletId(),customerWalletTransfer.getAmount(),customerWalletTransfer.getReceiverRemark()
                            ,"返利钱包互转通过",customerWalletTransfer.getTheTime(),customerWalletTransfer.getId(),1,customerWalletTransfer.getAllowanceAmount(),null,null,"add"));
                } else if(customerWalletTransfer.getAmount().compareTo(BigDecimal.ZERO) == 0 ){
                    //返利金额为 0 时只记录台账
                    CustomerWallet customerWallet = customerWalletService.getById(customerWalletTransfer.getReceiverCustomerWalletId());
                    this.saveCustomerWalletRecord(customerWallet,customerWalletTransfer.getAmount(),customerWalletTransfer.getReceiverRemark(),"返利钱包互转通过",customerWalletTransfer.getTheTime(),customerWalletTransfer.getId(),1,"IN",customerWalletTransfer.getAllowanceAmount(),null,null);
                }

            }
        }

        this.doWalletAmount(customerWalletAmountBeans);
        customerWalletTransfer.updateById();
    }



    /**
     * 生成经销商的现金钱包
     * @param customerId
     */
    public void initByK3Customer(String customerId){
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.LOCK_WALLET + customerId);
        try {
            if(!obtain.tryLock(10,TimeUnit.SECONDS)){
                throw new RemoteServiceException("系统繁忙，请稍后再试");
            }
            walletCommonMapper.initCustomerWallet(customerId);
        } catch (Exception e) {
            log.error("初始化经销商钱包失败",e);
        } finally {
            obtain.unlock();
        }
    }

    /**
     * 生成经销商的返利钱包
     */
    public void initRebateByK3Customer(){
        walletCommonMapper.initCustomerWallet2();
    }


    /**
     * 其他应收单V2-列表
     */
    public IPage<ReceivableItemVO> otherReceListV2(ExamineZfireParamBean examineZfireParamBean){
        AdminUserCom adminUser = commonLogic.getAdminUser();
        String customerNumber = adminUser.getIsCustomer() ? adminUser.getCustomerNumber() : "";
        ZfireParamBean zfireParamBean = FieldUtils.supplyParam(examineZfireParamBean);
        IPage<ReceivableItemVO> receivableItemVOIPage = commonCMapper.queryReceivableItem(new Page(zfireParamBean.getPageNum(), zfireParamBean.getPageSize()), zfireParamBean, examineZfireParamBean.getExamineStatus(),customerNumber);
        return receivableItemVOIPage;
    }


    /**
     * 其他应收单-列表
     */
    public IPage<ReceivableItemBean> otherReceList(String source, String code, String userName,String examineBy,
                                                   String examineStatus, String startTime, String endTime, Integer pageNum, Integer pageSize){
        AdminUserCom adminUser = commonLogic.getAdminUser();
        String customerNumber = adminUser.getIsCustomer() ? adminUser.getCustomerNumber() : "";
        return  receMapper.list(new Page<>(pageNum, pageSize),source,code,userName, examineBy,examineStatus, startTime, endTime,customerNumber);
    }

    /**
     * 其他应收单-详情
     */
    public ReceivableOrderBean otherReceDetail(String id){
        ReceivableOrder receivableOrder = receivableOrderService.getById(id);
        ReceivableOrderBean bean = new ReceivableOrderBean();
        BeanUtils.copyProperties(receivableOrder,bean);
        //明细
        List<ReceivableOrderItem> list = receivableOrderItemService.lambdaQuery()
                .eq(ReceivableOrderItem::getReceivableOrderId, id).list();
        bean.setItems(list);
        return bean;
    }

    /**
     * 其他应收单-关闭
     */
    @Transactional
    public void close(String id) throws InterruptedException {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        if(adminUser.getIsCustomer()){
            throw new RemoteServiceException("暂无权限");
        }
        ReceivableOrder receivableOrder = receivableOrderService.getById(id);
        if(GLB_BILL_SOURCE.contains(receivableOrder.getSource())){
            throw new RemoteServiceException("不可关闭同步金蝶的其他应收单");
        }
        //先弃审
        if(receivableOrder.getExamineStatus().equals(ExamineStatusEnum.OK.getKey())) {
            this.abandon(id, true);
        }

        receivableOrder.setExamineStatus(ExamineStatusEnum.CLOSE.getKey());
        receivableOrder.updateById();
    }

    /**
     * 其他应收单-新增
     */
    @Transactional
    public ResponseHelper addOtherRece(ReceivableOrderBean receivableOrderBean){
        AdminUserCom adminUser = commonLogic.getAdminUser();
        receivableOrderBean.setId(IdWorker.getIdStr());
        List<ReceivableOrderItem> items = receivableOrderBean.getItems();
        if(CollectionUtils.isEmpty(items)){
            throw new RemoteServiceException("请填写明细");
        }
        BigDecimal totalAmount = new BigDecimal(0);
        List<String> customerList = new ArrayList<>();
        for(ReceivableOrderItem item : items){
            KingDeeWallet kingDeeWallet = kingDeeWalletService.getById(item.getWalletId());
            if(kingDeeWallet == null){
                throw new RemoteServiceException("现金钱包不存在");
            }

            if(GLB_BILL_SOURCE.contains(receivableOrderBean.getSource())){
                if(item.getTotalAmount().doubleValue() < 0 ){
                    throw new RemoteServiceException("金额请填写大于0的数字");
                }
            }


            //查询 钱包余额
            CustomerWallet customerWallet = customerWalletService.getById(item.getCustomerWalletId());
            if(!receivableOrderBean.getIsContinue() && item.getTotalAmount().doubleValue() > 0
                    && customerWallet.getFreeCreditAmount().add(customerWallet.getAmount()).doubleValue() < item.getTotalAmount().doubleValue()){
                customerList.add(item.getCustomerName());
            }

            item.setCustomerWalletName(kingDeeWallet.getName());
            totalAmount = item.getTotalAmount().add(totalAmount);
            item.setReceivableOrderId(receivableOrderBean.getId());
        }

        if(null != customerList && customerList.size() > 0){
            return ResponseHelper.success(201,customerList,"success");
        }

        //保存第一条数据展示在列表
        if(null != items){
            receivableOrderBean.setUserName(items.get(0).getCustomerName());
            receivableOrderBean.setCustomerNumber(items.get(0).getCustomerNumber());
        }

        receivableOrderBean.setExamineStatus(ExamineStatusEnum.SAVE.toString());
        receivableOrderBean.setCode(receivableOrderBean.getId());
        receivableOrderBean.setTotalAmount(totalAmount);
        //保存往来单位
        receivableOrderBean.setTheTime(new Date());
        receivableOrderBean.setUserType(KingDeeCons.CUSTOMER_INFO);


        receivableOrderService.save(receivableOrderBean);
        //新增明细
        receivableOrderItemService.saveBatch(receivableOrderBean.getItems());
        return  ResponseHelper.success();
    }


    /**
     * 其他应收单-(收差同步) 新增
     */
    @Transactional
    public void syncOtherRece(ReceivableOrderBean receivableOrderBean) throws InterruptedException {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        receivableOrderBean.setId(IdWorker.getIdStr());
        List<ReceivableOrderItem> items = receivableOrderBean.getItems();
        if(CollectionUtils.isEmpty(items)){
            throw new RemoteServiceException("请填写明细");
        }
        BigDecimal totalAmount = new BigDecimal(0);
        for(ReceivableOrderItem item : items){
            item.setCustomerWalletName(item.getCustomerName());
            totalAmount = item.getTotalAmount().add(totalAmount);
            KingDeeCustomer kingDeeCustomer = kingDeeCustomerService.lambdaQuery()
                    .eq(KingDeeCustomer::getNumber,item.getCustomerNumber()).one();
            //todo 未绑定销售部门 默认设置301
            item.setDepartmentId(kingDeeCustomer.getSaleDeptNumber() == null ? "301" : kingDeeCustomer.getSaleDeptNumber() );
            item.setIncomeDept(kingDeeCustomer.getSaleDeptNumber() == null ? "301" : kingDeeCustomer.getSaleDeptNumber() );
            item.setReceivableOrderId(receivableOrderBean.getId());
        }
        //设置状态审核通过
        receivableOrderBean.setExamineStatus(ExamineStatusEnum.OK.toString());
        receivableOrderBean.setCode(receivableOrderBean.getId());
        receivableOrderBean.setTotalAmount(totalAmount);
        //保存往来单位
        receivableOrderBean.setTheTime(new Date());
        receivableOrderBean.setUserType(KingDeeCons.CUSTOMER_INFO);
        receivableOrderBean.setUserName(receivableOrderBean.getUserName());
        receivableOrderBean.setExamineTime(new Date());
        receivableOrderBean.setExamineBy(adminUser.getNickName());

        receivableOrderService.save(receivableOrderBean);
        receivableOrderItemService.saveBatch(receivableOrderBean.getItems());

        List<CustomerWalletAmountBean> beans = new ArrayList<>();
        for(ReceivableOrderItem item : items){
            beans.add( new CustomerWalletAmountBean(item.getCustomerWalletId(),item.getTotalAmount(),"",
                    Constant.BILL_TYPE_OFKD,receivableOrderBean.getTheTime(),receivableOrderBean.getId(),1,"sub"));

        }
       this.doWalletAmount(beans);

        //同步金蝶
        ResponseHelper result =  this.syncK3OtherBill(receivableOrderBean);
        if(result.getCode() == ResponseHelper.ResponseCode_COMMON){
            throw new RemoteServiceException(result.getMessage());
        }


    }

    /**
     * 同步金蝶数据
     * @param receivableOrderBean
     */
    public ResponseHelper syncK3OtherBill(ReceivableOrderBean receivableOrderBean){

        List<SyncK3OtherReceBean> syncOBillList = new ArrayList<>();
        for(ReceivableOrderItem roi:receivableOrderBean.getItems()){
            SyncK3OtherReceBean syncOBill = new SyncK3OtherReceBean();
            KingDeeWallet wallet = kingDeeWalletService.getById(roi.getWalletId());
            //币别 人民币
            syncOBill.setAmountType(Constant.K3_AMOUNT_TYPE_RMB);
            syncOBill.setBillNo(roi.getId());
            syncOBill.setTheTime(DateUtil.formatDate(receivableOrderBean.getTheTime()));
            syncOBill.setUserNameType(receivableOrderBean.getUserType());
            syncOBill.setEndTime(DateUtil.formatDate(receivableOrderBean.getEndTime()));
            syncOBill.setJudgeTime(DateUtil.formatDate(receivableOrderBean.getEndTime()));

            OtherReceItemBean otherReceItemBean = new OtherReceItemBean();
            otherReceItemBean.setDepartmentId(roi.getDepartmentId());
            otherReceItemBean.setProjectCode(roi.getProjectCode());
            otherReceItemBean.setInvoiceType(roi.getInvoiceType());
//            KingDeeWallet wallet = kingDeeWalletService.getById(roi.getWalletId());
//            otherReceItemBean.setWalletId(wallet.getNumber());
            otherReceItemBean.setWalletId(wallet.getNumber());
            otherReceItemBean.setTotalAmount(roi.getTotalAmount());
            otherReceItemBean.setAfterTaxAmount(roi.getAfterTaxAmount());
            otherReceItemBean.setRemark(roi.getRemark());
            otherReceItemBean.setTax(roi.getTax());
            otherReceItemBean.setTaxRate(roi.getTaxRate());
            otherReceItemBean.setLastAmount(roi.getTotalAmount());
            otherReceItemBean.setIncomeDept(roi.getIncomeDept());
            // 每条item数据生成一条数据
           // otherReceItemBeanList.clear();
            List<OtherReceItemBean> otherReceItemBeanList = new ArrayList<>();
            otherReceItemBeanList.add(otherReceItemBean);

            syncOBill.setUserName(roi.getCustomerNumber());
            syncOBill.setSaleDept(roi.getDepartmentId());
            syncOBill.setItems(otherReceItemBeanList);
            syncOBillList.add(syncOBill);
        }
        return  k3OtherReceLogic.syncOtherBillData(syncOBillList);
    }

    /**
     * 其他应收单-修改
     */
    public void updateOtherRece(ReceivableOrderBean receivableOrderBean){
        if(!receivableOrderBean.getExamineStatus().equals(ExamineStatusEnum.SAVE.toString())){
            throw new RemoteServiceException("非保存状态不可修改");
        }

        List<ReceivableOrderItem> items = receivableOrderBean.getItems();
        BigDecimal totalAmount = new BigDecimal(0);
        for(ReceivableOrderItem item : items){
            totalAmount = item.getTotalAmount().add(totalAmount);
            item.setReceivableOrderId(receivableOrderBean.getId());
        }
        receivableOrderBean.setTotalAmount(totalAmount);

        //根据钱包覆盖相关信息
        String customerWalletId = receivableOrderBean.getItems().get(0).getCustomerWalletId();
        CustomerWallet customerWallet = customerWalletService.getById(customerWalletId);
        receivableOrderBean.setCustomerNumber(customerWallet.getCustomerNumber());

        receivableOrderBean.getItems().forEach(v -> v.setCustomerNumber(customerWallet.getCustomerNumber())
                .setCustomerName(customerWallet.getCustomerName()));

        receivableOrderService.updateById(receivableOrderBean);
        receivableOrderItemService.saveOrUpdateBatch(receivableOrderBean.getItems());


    }

    /**
     * 其他应收单-提审
     */
    public void applyExamineOtherRece(String id){
        ReceivableOrder receivableOrder = receivableOrderService.getById(id);
        if( !receivableOrder.getExamineStatus().equals(ExamineStatusEnum.SAVE.toString())){
            throw new RemoteServiceException("非保存状态不可提审");
        }
        receivableOrder.setExamineStatus(ExamineStatusEnum.WAIT.toString());
        receivableOrder.updateById();
    }

    /**
     * 其他应收单-审核
     */
    @Transactional
    public void examineOtherRece(String id,String examineStatus,String examineRemark) throws InterruptedException {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        ReceivableOrder receivableOrder = receivableOrderService.getById(id);

        if(!receivableOrder.getExamineStatus().equals(ExamineStatusEnum.WAIT.toString())){
            throw new RemoteServiceException("非待审核状态不可审核");
        }
        if(adminUser.getIsCustomer()){
            throw new RemoteServiceException("暂无权限操作");
        }
        receivableOrder.setExamineStatus(examineStatus);
        receivableOrder.setExamineRemark(examineRemark);
        receivableOrder.setExamineTime(new Date());
        receivableOrder.setExamineBy(adminUser.getNickName());
        receivableOrder.updateById();

        if(ExamineStatusEnum.OK.toString().equals(examineStatus)){
            //需要扣钱 todo
            List<ReceivableOrderItem> list = receivableOrderItemService.lambdaQuery()
                    .eq(ReceivableOrderItem::getReceivableOrderId, id).list();

            //新使用方式
            List<CustomerWalletAmountBean> beans = new ArrayList<>();

            for(ReceivableOrderItem item : list){
                if(item.getTotalAmount().doubleValue() < 0){
                    BigDecimal amount = BigDecimal.valueOf(0).subtract(item.getTotalAmount());
                    beans.add( new CustomerWalletAmountBean(item.getCustomerWalletId(),amount,item.getRemark(),
                            Constant.BILL_TYPE_OFKD,receivableOrder.getTheTime(),receivableOrder.getId(),getFlag(receivableOrder.getSource()),"add"));
                }else{
                    beans.add( new CustomerWalletAmountBean(item.getCustomerWalletId(),item.getTotalAmount(),item.getRemark(),
                            Constant.BILL_TYPE_OFKD,receivableOrder.getTheTime(),receivableOrder.getId(),getFlag(receivableOrder.getSource()),"sub"));
                }

            }
          this.doWalletAmount(beans);

            //同步金蝶
            if(GLB_BILL_SOURCE.contains(receivableOrder.getSource())){
                ReceivableOrderBean receivableOrderBean = new ReceivableOrderBean();
                BeanUtils.copyProperties(receivableOrder,receivableOrderBean);
                receivableOrderBean.setItems(list);
                ResponseHelper result =  this.syncK3OtherBill(receivableOrderBean);
                if(result.getCode() == ResponseHelper.ResponseCode_COMMON){
                    throw new RemoteServiceException(result.getMessage());
                }
            }

        }
    }

    /**
     *
     * @param amount 金额
     * @param rate 税率 13 : 13%
     * @return
     */
    BigDecimal calculateRate(BigDecimal amount,BigDecimal rate){
        if(null == amount || null == rate ){
            return  new BigDecimal(0);
        }
        BigDecimal rateAmount = amount.divide(BigDecimal.valueOf(100)).multiply(rate);
        return amount.add(rateAmount).setScale(2,BigDecimal.ROUND_HALF_UP);
    }

    Integer getFlag(String source){
        // 工程押金对应-押金列  保证金对应-保证金列  价差/仓储费对应-预付货款
        if("工程价差".equals(source) || "仓储费".equals(source)){
            return 1;
        }
        if("工程押金".equals(source) ){
            return 4;
        }
        if("保证金".equals(source)){
            return 5;
        }
        return null;
    }


    /**
     * 其他应收单-弃审
     */
    @Transactional
    public void abandon(String id, boolean isClose) throws InterruptedException {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        ReceivableOrder receivableOrder = receivableOrderService.getById(id);
        if( !receivableOrder.getExamineStatus().equals(ExamineStatusEnum.OK.toString())){
            throw new RemoteServiceException("非审核通过状态不可弃审");
        }
        if(adminUser.getIsCustomer()){
            throw new RemoteServiceException("暂无权限操作");
        }
        receivableOrder.setExamineStatus(ExamineStatusEnum.SAVE.toString());
        receivableOrder.updateById();
        List<ReceivableOrderItem> list = receivableOrderItemService.lambdaQuery()
                .eq(ReceivableOrderItem::getReceivableOrderId, id).list();
        //todo （批量弃审） 废弃金蝶的单据
        if(GLB_BILL_SOURCE.contains(receivableOrder.getSource())) {
            for(ReceivableOrderItem item:list){
                k3OtherReceLogic.unAuditByBillNo(item.getId());
            }
        }

        //新使用方式
        List<CustomerWalletAmountBean> beans = new ArrayList<>();
        for(ReceivableOrderItem item : list){
            if(item.getTotalAmount().doubleValue() < 0){
                BigDecimal amount = BigDecimal.valueOf(0).subtract(item.getTotalAmount());
                beans.add( new CustomerWalletAmountBean(item.getCustomerWalletId(),amount,"",
                        Constant.BILL_TYPE_OFKD + "-弃审",receivableOrder.getTheTime(),receivableOrder.getId(),getFlag(receivableOrder.getSource()),"sub"));
            }else {
                if (!isClose) {
                    beans.add(new CustomerWalletAmountBean(item.getCustomerWalletId(), item.getTotalAmount(), "",
                            Constant.BILL_TYPE_OFKD + "-弃审", receivableOrder.getTheTime(), receivableOrder.getId(), getFlag(receivableOrder.getSource()), "add"));
                } else if (item.getWalletId().equals("62a150816fabe7")) {
                    beans.add(new CustomerWalletAmountBean(item.getCustomerWalletId(), item.getTotalAmount(), "",
                            Constant.BILL_TYPE_OFKD + "-弃审", receivableOrder.getTheTime(), receivableOrder.getId(), getFlag(receivableOrder.getSource()), "add"));
                }
            }

        }
        if (CollectionUtil.isNotEmpty(beans))
            this.doWalletAmount(beans);

    }


    /**
     * 批量修改钱包金额，同单据多个钱包的每个钱包只需要锁1次
     * @param list
     * @throws InterruptedException
     */
    public void doWalletAmount(List<CustomerWalletAmountBean> list) throws InterruptedException {
        if(CollectionUtils.isEmpty(list)){
            return;
        }
        list = list.stream().filter(v -> v != null && StringUtils.isNotEmpty(v.getCustomerWalletId())).collect(Collectors.toList());
        List<String> customerWalletIds = list.stream().filter(v -> v != null).map(CustomerWalletAmountBean::getCustomerWalletId).distinct().collect(Collectors.toList());
        log.info("【钱包金额处理】customerWalletIds:{}",JSONObject.toJSONString(customerWalletIds));
        for(String customerWalletId : customerWalletIds){
            Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.LOCK_WALLET + customerWalletId);
            if(!obtain.tryLock(10,TimeUnit.SECONDS)){
                throw new RemoteServiceException("钱包已冻结:"+customerWalletId);
            }
            try{
                List<CustomerWalletAmountBean> customerWalletAmountBeans = list.stream().filter(v -> v.getCustomerWalletId().equals(customerWalletId)).collect(Collectors.toList());
                //根据类型升序排序：add，sub   来控制钱包的金额先加再扣减
                customerWalletAmountBeans.sort(Comparator.comparing(CustomerWalletAmountBean::getType));
                //开始处理
                for(CustomerWalletAmountBean bean : customerWalletAmountBeans) {
                    CustomerWallet customerWallet = walletCommonMapper.getCustomerWalletByIdForUpdate(customerWalletId);
                    bean.setCustomerWallet(customerWallet);
                    if(bean.getType().equals("add")) {
                        this.addWalletAmount(customerWallet, bean.getAmount(), bean.getRemark(), bean.getBillType(), bean.getTheTime(), bean.getBillNo(),
                                bean.getFlag(), bean.getAllowanceAmount(), bean.getWithholdAmount());
                    }else{
                        this.subWalletAmount(customerWallet,bean.getAmount(),bean.getRemark(),bean.getBillType(),bean.getTheTime(),bean.getBillNo(),
                                bean.getFlag(),bean.getAllowanceAmount(),bean.getWithholdAmount());
                    }
                }
            }finally {
                this.txCallUnlock(obtain);
                //obtain.unlock();
            }
        }
    }

    public void doWalletAmount(CustomerWalletAmountBean bean) throws InterruptedException {
        //this.doWalletAmount(Arrays.asList(bean));
        List<CustomerWalletAmountBean> list = new ArrayList<>();
        list.add(bean);
        this.doWalletAmount(list);
    }


    private void addWalletAmount(CustomerWallet customerWallet, BigDecimal amount,String remark,String billType,
                                Date theTime,String billNo,Integer flag,BigDecimal allowanceAmount,BigDecimal withholdAmount) throws InterruptedException {

        if(customerWallet == null){
            throw new RemoteServiceException("调取钱包失败，请稍后再试");
        }
        if(amount.doubleValue() < 0){
            throw new RemoteServiceException("钱包不可添加负数");
        }
        //现金钱包
        if(customerWallet.getType().equals(WalletTypeEnum.COMMONLY.getKey())) {
            //1.先还信用额度
            BigDecimal sub = customerWallet.getUsedCreditAmount().subtract(amount);
            if (sub.doubleValue() > 0) {
                //已使用的信用额度 比 加的钱 大
                customerWallet.setUsedCreditAmount(sub);
                customerWallet.setFreeCreditAmount(customerWallet.getFreeCreditAmount().add(amount));
            } else {
                //已使用的信用额度 比 加的钱 小
                customerWallet.setFreeCreditAmount(customerWallet.getFreeCreditAmount().add(customerWallet.getUsedCreditAmount()));
                customerWallet.setAmount(customerWallet.getAmount().subtract(sub));//负负得正
                customerWallet.setUsedCreditAmount(BigDecimal.valueOf(0));
            }
            customerWallet.updateById();
        }else{
            //返利钱包
            customerWallet.setAmount(customerWallet.getAmount().add(amount));
            customerWallet.updateById();
        }
        //记录流水
        this.saveCustomerWalletRecord(customerWallet,amount,remark,billType,theTime,billNo,flag,"IN",allowanceAmount,withholdAmount,billNo);
    }


    /**
     * 钱包余额-扣除
     * @param amount 金额
     * @param remark 说明
     * @param billType 单据类型
     * @param theTime 单据日期
     * @param billNo 单据号
     * @param flag 1=预付货款 2=订单占款 3=支付货款 4=押金 5=工程保证金 6=其他暂扣款
     * @param allowanceAmount  折让金额
     * @param withholdAmount  暂扣返利
     * @throws InterruptedException
     */
    private void subWalletAmount(CustomerWallet customerWallet,BigDecimal amount,String remark,String billType,
                                Date theTime,String billNo,Integer flag,BigDecimal allowanceAmount,BigDecimal withholdAmount) throws InterruptedException {

            if(amount.doubleValue() < 0){
                throw new RemoteServiceException("钱包不可扣除负数");
            }
            if(customerWallet == null){
                throw new RemoteServiceException("调取钱包失败，请稍后再试");
            }
            //反审收款单和退款单，允许钱包负数
            if(! GLB_BillTypeList.contains(billType)) {
                if (customerWallet.getFreeCreditAmount().add(customerWallet.getAmount()).doubleValue() < amount.doubleValue()) {
                    //返利钱包可能是负数，如果此时需要扣返利金额0元，则不需要拦截
                    if((customerWallet.getType().equals(WalletTypeEnum.REBATE.getKey()) && amount.doubleValue() != 0)
                            ||  customerWallet.getType().equals(WalletTypeEnum.COMMONLY.getKey())) {
                        throw new RemoteServiceException("操作失败，"+customerWallet.getCustomerName()
                                +"钱包:【" + customerWallet.getCustomerWalletName()
                                + "】当前额度:"+customerWallet.getFreeCreditAmount().add(customerWallet.getAmount())+",需要额度:"+amount+"。可使用金额不足");
                    }
                }
            }else {
                //被反审的收款单或者退款单，直接删除，并将他后面的台账的余额减掉金额
                this.deleteCustomerWalletRecordByK3ReceiverId(billNo);
            }

            //处理钱包逻辑
            //现金钱包
            if(customerWallet.getType().equals(WalletTypeEnum.COMMONLY.getKey())) {
                if (customerWallet.getAmount().subtract(amount).doubleValue() > 0) {
                    customerWallet.setAmount(customerWallet.getAmount().subtract(amount));
                } else {
                    BigDecimal sub = customerWallet.getAmount().subtract(amount);
                    customerWallet.setAmount(sub);
                }
                customerWallet.updateById();
            }else{
                //返利钱包
                if(!Constant.BILLTYPE_FLD_ZR.equals(billType)){
                    if(customerWallet.getAmount().doubleValue() < amount.doubleValue() && amount.doubleValue() != 0){
                        throw new RemoteServiceException("返利钱包可扣除金额不足");
                    }
                }

                customerWallet.setAmount(customerWallet.getAmount().subtract(amount));
                customerWallet.updateById();
            }
            //记录流水
            this.saveCustomerWalletRecord(customerWallet,amount,remark,billType,theTime,billNo,flag,"OUT",allowanceAmount,withholdAmount,null);
    }



    public void txCallUnlock(Lock obtain){
        //事务提交完成后才释放锁,此方法禁止执行mysql相关操作,否则将导致重大问题。
        if(TransactionSynchronizationManager.isActualTransactionActive()) {
            TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
                @Override
                public void afterCompletion(int status) {

                    if(TransactionSynchronization.STATUS_COMMITTED == status){
                        log.info("=========【钱包】======事务提交==============");
                    }else if(TransactionSynchronization.STATUS_ROLLED_BACK == status){
                        log.info("========【钱包】=========事务回滚============");
                    }

                    obtain.unlock();
                }
            });
        }else{
            log.info("【钱包】====没有事务===释放锁");
            obtain.unlock();
        }
    }


    /**
     * 台账流水
     * @param customerWallet 钱包
     * @param amount 金额
     * @param remark 摘要
     * @param billType 单据类型
     * @param theTime 单据日期
     * @param billNo 单据号
     * @param flag 1=预付货款 2=订单占款 3=支付货款 4=押金 5=工程保证金 6=其他暂扣款
     * @param amountType IN = 入账  OUT = 出账
     */
    public void saveCustomerWalletRecord(CustomerWallet customerWallet,BigDecimal amount,String remark,String billType,Date theTime,String billNo,Integer flag,String amountType){
        //记录流水
        this.saveCustomerWalletRecord(customerWallet,amount,remark,billType,theTime,billNo,flag,amountType,null,null,null);
    }

    /**
     * 台账流水
     * @param customerWallet 钱包
     * @param amount 金额
     * @param remark 摘要
     * @param billType 单据类型
     * @param theTime 单据日期
     * @param billNo 单据号
     * @param flag 1=预付货款 2=订单占款 3=支付货款 4=押金 5=工程保证金 6=其他暂扣款
     * @param amountType IN = 入账  OUT = 出账'
     * @param allowanceAmount 折让金额
     * @param withholdAmount 暂扣返利
     */
    public void saveCustomerWalletRecord(CustomerWallet customerWallet,BigDecimal amount,String remark,String billType,
                                          Date theTime,String billNo,Integer flag,String amountType,BigDecimal allowanceAmount,BigDecimal withholdAmount,String k3ReceiptId){
        //记录流水
        CustomerWalletRecord customerWalletRecord = new CustomerWalletRecord();
        customerWalletRecord.setCustomerWalletId(customerWallet.getCustomerWalletId());
        customerWalletRecord.setWalletName(customerWallet.getCustomerWalletName());
        customerWalletRecord.setType(customerWallet.getType());
        customerWalletRecord.setBillType(billType);
        customerWalletRecord.setTheTime(theTime);
        //工程单可能存在  单据号|工程登录编号   这种billNo
        if(StringUtils.isNotEmpty(billNo) && billNo.indexOf("|") > -1) {
            customerWalletRecord.setBillNo((billNo.split("\\|"))[0]);
            customerWalletRecord.setEnginRecordNo((billNo.split("\\|"))[1]);
        }else{
            //退货单可能存在  单据号&   这种billNo
            if(StringUtils.isNotEmpty(billNo) && billNo.indexOf("&") > -1) {
                customerWalletRecord.setBillNo(billNo.split("&")[0]);
                customerWalletRecord.setInvoiceId(billNo);
            }else {
                customerWalletRecord.setBillNo(billNo);
            }
        }

        customerWalletRecord.setCustomerId(customerWallet.getCustomerId());
        customerWalletRecord.setCustomerCode(customerWallet.getCustomerNumber());
        customerWalletRecord.setCustomerName(customerWallet.getCustomerName());
        customerWalletRecord.setAmountType(amountType);
        customerWalletRecord.setLastAmount(customerWallet.getAmount());
        customerWalletRecord.setAmount(amount);
        customerWalletRecord.setBalanceAmount(customerWallet.getAmount().subtract(customerWallet.getUsedCreditAmount()));
        customerWalletRecord.setRemark(remark);
        customerWalletRecord.setWalletRebateId(customerWallet.getWalletRebateId());
        customerWalletRecord.setMonth(new SimpleDateFormat("yyyy-MM").format(new Date()));
        customerWalletRecord.setFlag(flag);
        if(null != allowanceAmount){
            customerWalletRecord.setAllowanceAmount(allowanceAmount);
        }
        if(null != withholdAmount){
            customerWalletRecord.setWithholdAmount(withholdAmount);
        }
        if(StringUtils.isNotEmpty(k3ReceiptId)){
            customerWalletRecord.setK3ReceiptId(k3ReceiptId);
        }
        //如果是返利单 都记录到收入
        if(null != billType && Constant.BILLTYPE_FLD_ZR.equals(billType)){
            customerWalletRecord.setAmountType("IN");
            customerWalletRecord.setAmount(BigDecimal.valueOf(0).subtract(amount));
        }
        customerWalletRecord.insert();
    }

    public void deleteCustomerWalletRecord(String billNo){
        //customerWalletRecordService.lambdaUpdate().eq(CustomerWalletRecord::getBillNo,billNo).remove();
    }

    public void deleteCustomerWalletRecordByK3ReceiverId(String k3ReceiptId){
//        List<CustomerWalletRecord> customerWalletRecords = customerWalletRecordService.lambdaQuery().eq(CustomerWalletRecord::getK3ReceiptId, k3ReceiptId).list();
//        if(customerWalletRecords.size() == 0){
//            log.error("【删除台账】暂无数据删除:{}",k3ReceiptId);
//            return;
//        }
//        CustomerWalletRecord customerWalletRecord = customerWalletRecords.get(0);

    }

    /**
     * 删除
     */
    @Transactional
    public void deleteOther(List<String> ids) {
        List<String> delItems = new ArrayList<>();
        List<String> cahngeIds = new ArrayList<>();
        for (String id : ids) {
            ReceivableOrderItem item1 = receivableOrderItemService.getById(id);
            ReceivableOrder order = receivableOrderService.getById(item1.getReceivableOrderId());
            if (!order.getExamineStatus().equals(ExamineStatusEnum.OK.toString())) {
                delItems.add(id);
                cahngeIds.add(item1.getReceivableOrderId());
            }
        }
        //删除可删除的数据
        if(delItems.size() == 0){
            throw new RemoteServiceException("暂无可删除的数据");
        }

        receivableOrderItemService.lambdaUpdate().in(ReceivableOrderItem::getId, delItems).remove();
        //删除后查询
        List<String> delIds = new ArrayList<>();
        for(String cId:cahngeIds){
            List<ReceivableOrderItem> items = receivableOrderItemService.lambdaQuery().eq(ReceivableOrderItem::getReceivableOrderId,cId).list();
            //删除 没有明细的数据
            if(items.size() == 0){
                delIds.add(cId);
                continue;
            }

            //修改删除的明细
            ReceivableOrder order = receivableOrderService.getById(cId);
            BigDecimal totalAmount = new BigDecimal(0);
            for(ReceivableOrderItem item : items){
                totalAmount = totalAmount.add(item.getTotalAmount());
            }
            order.setTotalAmount(totalAmount);
            order.updateById();
        }

        if(delIds.size() > 0){
            receivableOrderService.lambdaUpdate().eq( ReceivableOrder::getId,delIds).remove();
        }

    }

    /**
     * 导出钱包数据
     */
    public ExcelData customerWalletExportData(List<CustomerWalletBean> list){
        List<String> titles = Arrays.asList("经销商编码", "经销商名称", "总信用额度","可用信用额度","关联钱包");
        List<List<Object>> rows = new ArrayList<>();
        for(CustomerWalletBean bean : list){
            List<Object> row = new ArrayList<>();
            row.add(bean.getCustomerNumber());
            row.add(bean.getCustomerName());
            row.add(bean.getFreeCreditAmount().add(bean.getUsedCreditAmount()));
            row.add(bean.getFreeCreditAmount());
            row.add(bean.getCustomerWalletName());
            rows.add(row);
        }
        ExcelData excelData = new ExcelData();
        excelData.setTitles(titles);
        excelData.setRows(rows);
        return excelData;
    }


    /**
     * 其他应收单-列表(导出)
     */
    public ExcelData otherReceListExport(List<ReceivableItemBean> receivableOrders){
        String[] titles = new String[]{"单据类型","单据来源","单据编码","业务日期","往来单位类型", "往来单位", "币别","总金额","单据状态","费用项目名称","审核人","审核时间"};
        List<List<Object>> rows = new ArrayList<>();
        for (ReceivableItemBean receivableOrder : receivableOrders) {
            List<Object> row = new ArrayList<>();
            row.add(receivableOrder.getBillType());
            row.add(receivableOrder.getSource());
            row.add(receivableOrder.getCode());
            row.add(DateUtil.formatDate(receivableOrder.getTheTime()));
            row.add("客户");
            row.add(receivableOrder.getUserName());
            row.add(receivableOrder.getAmountType());
            row.add(receivableOrder.getItemAmount());
//            row.add(ExamineStatusEnum.valueOf(receivableOrder.getExamineStatus()).getMsg());
            row.add(EnumUtil.getNameFieldMap(ExamineStatusEnum.class, "value").get(receivableOrder.getExamineStatus()));
            row.add(receivableOrder.getProjectName());
            row.add(receivableOrder.getExamineBy());
            row.add(DateUtil.formatDateTime(receivableOrder.getExamineTime()));
            rows.add(row);
        }
        ExcelData excelData = new ExcelData();
        excelData.setRows(rows);
        excelData.setTitles(Arrays.asList(titles));
        return excelData;
    }

    /**
     * 经销商余额汇总导出
     * @return
     */
    public ExcelData countTotalExport(List<CustomerTotalAmountExportBean> list){
        String[] titles = new String[]{"经销商编码","经销商名称","类型","名称","钱包对应业务","预付货款","订单占款","支付货款","押金","保证金","其他暂扣款","余额"};
        List<List<Object>> rows = new ArrayList<>();

        for (CustomerTotalAmountExportBean bean : list) {
            List<Object> row = new ArrayList<>();
            row.add(bean.getCustomerNumber());
            row.add(bean.getCustomerName());
//            row.add(WalletTypeEnum.valueOf(bean.getType()).getMsg());
            row.add(EnumUtil.getNameFieldMap(WalletTypeEnum.class, "value").get(bean.getType()));
            row.add(bean.getCustomerWalletName());
            row.add(bean.getServiceName());
            row.add(bean.getAmount1());
            row.add(bean.getAmount2());
            row.add(bean.getAmount3());
            row.add(bean.getAmount4());
            row.add(bean.getAmount5());
            row.add(bean.getAmount6());
            row.add(bean.getAmount());
            rows.add(row);
        }
        ExcelData excelData = new ExcelData();
        excelData.setRows(rows);
        excelData.setTitles(Arrays.asList(titles));
        return excelData;
    }

    @Transactional
    public void standingBookLCheck(List<String> ids){
        AdminUserCom adminUser = commonLogic.getAdminUser();
        customerWalletRecordService.lambdaUpdate()
            .set(CustomerWalletRecord::getIsReconciliation,true)
            .set(CustomerWalletRecord::getExamineTime,new Date())
            .set(CustomerWalletRecord::getCheckBy,adminUser.getNickName())
            .in(CustomerWalletRecord::getId,ids)
            .update();
    }

    @Transactional
    public void reconciliateCheck(List<String> ids){
        AdminUserCom adminUser = commonLogic.getAdminUser();
        customerWalletReconciliationService.lambdaUpdate()
                .set(CustomerWalletReconciliation::getCheckBy,adminUser.getNickName())
                .set(CustomerWalletReconciliation::getIsReconciliation,true)
                .in(CollectionUtils.isNotEmpty(ids),CustomerWalletReconciliation::getId,ids)
                .update();
    }

    public ExcelData standingBookExport(List<CustomerWalletRecord> customerWalletRecords ,String type){
        ExcelData excelData = new ExcelData();
        if("COMMONLY".equals(type)){
            String[] titles = new String[]{"单据日期","单据类型","单据号","工程登录编号","钱包","客户编码","客户名称","摘要", "预付货款",
                    "订单占款","支付货款","押金","工程保证金","其他暂扣款","账户余额"};
            List<List<Object>> rows = new ArrayList<>();

            for (CustomerWalletRecord c : customerWalletRecords) {

                BigDecimal amount = c.getAmountType().equals("IN")? c.getAmount() : BigDecimal.valueOf(0).subtract(c.getAmount());

                List<Object> row = new ArrayList<>();
                row.add(DateUtil.formatDate(c.getTheTime()));
                row.add(c.getBillType());
                row.add(c.getBillNo());
                row.add(c.getEnginRecordNo());
                row.add(c.getWalletName());
                row.add(c.getCustomerCode());
                row.add(c.getCustomerName());
                row.add(c.getRemark());
                row.add(null != c.getFlag() && c.getFlag() == 1 ? amount : "0");
                row.add(null != c.getFlag() && c.getFlag() == 2 ? amount : "0");
                row.add(null != c.getFlag() && c.getFlag() == 3 ? amount : "0");
                row.add(null != c.getFlag() && c.getFlag() == 4 ? amount : "0");
                row.add(null != c.getFlag() && c.getFlag() == 5 ? amount : "0");
                row.add(null != c.getFlag() && c.getFlag() == 6 ? amount : "0");
                row.add(c.getBalanceAmount());
                rows.add(row);
            }
            excelData.setRows(rows);
            excelData.setTitles(Arrays.asList(titles));
        } else if("REBATE".equals(type)) {
            String[] titles = new String[]{"客户编码","客户名称","单据日期","审核日期","单据类型", "单据号","工程登录编号",
                    "返利类型","摘要","收入","支出","暂扣返利","结存"};
            List<List<Object>> rows = new ArrayList<>();

            for (CustomerWalletRecord c : customerWalletRecords) {
                List<Object> row = new ArrayList<>();
                row.add(c.getCustomerCode());
                row.add(c.getCustomerName());
                row.add(DateUtil.formatDate(c.getTheTime()));
                row.add(DateUtil.formatDate(c.getExamineTime()));
                row.add(c.getBillType());
                row.add(c.getBillNo());
                row.add(c.getEnginRecordNo());
                row.add(c.getWalletName());
                row.add(c.getRemark());
                row.add(c.getAmountType().equals("IN") ? c.getAmount() : "-");
                row.add(c.getAmountType().equals("OUT") ? c.getAmount() : "-");
                row.add(c.getWithholdAmount());
                row.add(c.getBalanceAmount());
                rows.add(row);
            }
            excelData.setRows(rows);
            excelData.setTitles(Arrays.asList(titles));

        }else {
            String[] titles = new String[]{"月份","对账状态","客户编码","客户名称","部门", "现金钱包类型",
                    "单据类型","单据号","工程登录编号","单据日期","收付款金额","发货金额","备注"};
            List<List<Object>> rows = new ArrayList<>();

            for (CustomerWalletRecord c : customerWalletRecords) {
                List<Object> row = new ArrayList<>();
                row.add(c.getMonth());
                row.add(c.getIsReconciliation() ? "已对账":"未对账");
                row.add(c.getCustomerCode());
                row.add(c.getCustomerName());
                row.add("");
                row.add(c.getWalletName());
                row.add(c.getBillType());
                row.add(c.getBillNo());
                row.add(c.getEnginRecordNo());
                row.add(DateUtil.formatDate(c.getTheTime()));
                row.add(c.getAmount());
                row.add("");
                row.add(c.getRemark());
                rows.add(row);
            }
            excelData.setRows(rows);
            excelData.setTitles(Arrays.asList(titles));
        }

        return excelData;
    }

    public List<Map<String, Object>> queryCustomerTotalAmount(String customerNumber,String customerName,String area,String walletId){
        List<String> websitIds = null;
        if(StringUtils.isNotEmpty(area)){
            websitIds = adminWebsitLogic.getAllAdminWebsitIds(area);
        }
        IPage<Map<String, Object>> mapIPage = walletCommonMapper.queryCustomerTotalAmount(new Page(1, 100), customerNumber, customerName, websitIds, walletId);
        return mapIPage.getRecords();
    }


    public List<CustomerTotalAmountExportBean> queryCustomerTotalAmountExport(String customerNumber,String customerName,String area,String walletId,Boolean byCustomer){
        List<String> websitIds = null;
        if(StringUtils.isNotEmpty(area)){
            websitIds = adminWebsitLogic.getAllAdminWebsitIds(area);
        }
        return walletCommonMapper.queryCustomerTotalAmountExport(customerNumber,customerName,websitIds,walletId,byCustomer);
    }


    public List<Map<String, Object>> queryTotalAmount(String websitId,String type){
        List<String> websitIds = null;
        if(StringUtils.isNotEmpty(websitId)){
            websitIds = adminWebsitLogic.getAllAdminWebsitIds(websitId);
        }
        return  walletCommonMapper.queryTotalAmount(websitIds,type);
    }


    public IPage<CustomerWalletReconciliation> reconciliationList(String customerId,String customerNumber,String customerName,String type,
                                                        String customerWalletId,String walletRebateId, Integer pageNum,Integer pageSize,Boolean isReconciliation){
        AdminUserCom adminUser = commonLogic.getAdminUser();
        IPage<CustomerWalletReconciliation> page = customerWalletReconciliationService.lambdaQuery()
                .eq(StringUtils.isNotEmpty(customerId),CustomerWalletReconciliation::getCustomerId,customerId)
                .like(StringUtils.isNotEmpty(customerNumber),CustomerWalletReconciliation::getCustomerCode,customerNumber)
                .like(StringUtils.isNotEmpty(customerName),CustomerWalletReconciliation::getCustomerName,customerName)
                .eq(StringUtils.isNotEmpty(type), CustomerWalletReconciliation::getType, type)
                .eq(adminUser.getIsCustomer(),CustomerWalletReconciliation::getCustomerId,adminUser.getCustomerId())
                .eq(StringUtils.isNotEmpty(walletRebateId), CustomerWalletReconciliation::getWalletRebateId, walletRebateId)
                .eq(StringUtils.isNotEmpty(customerWalletId), CustomerWalletReconciliation::getCustomerWalletId, customerWalletId)
                .eq(null != isReconciliation,CustomerWalletReconciliation::getIsReconciliation,isReconciliation)
                .orderByDesc(CustomerWalletReconciliation::getMonth)
                .page(new Page<>(pageNum, pageSize));
        return page;
    }

    @Transactional
    public void generateMonthReconciliate(String month,String type){
        //todo 总余额
        if("COMMONLY".equals(type)){
            List<CustomerCountMonthBean>  list = walletCommonMapper.queryCommonlyMonthCount(month);
            if(list.size() >0){
                //生成前删除
                customerWalletReconciliationService.lambdaUpdate().eq(CustomerWalletReconciliation::getMonth,month).eq(CustomerWalletReconciliation::getType,type).remove();
                List<CustomerWalletReconciliation> saveList = new ArrayList<>();
                 for(CustomerCountMonthBean bean:list){
                     CustomerWalletReconciliation m = new CustomerWalletReconciliation();
                     m.setCustomerId(bean.getCustomerId());
                     m.setCustomerName(bean.getCustomerName());
                     m.setCustomerCode(bean.getCustomerNumber());
                     m.setMonth(bean.getMonth());
                     m.setDepositFee(bean.getOrderDate());
                     m.setPreFee(bean.getPreCount());
                     m.setOrderFee(bean.getOrderCOunt());
                     m.setPayFee(bean.getPayCount());
                     m.setProjectFee(bean.getProjectCount());
                     m.setOtherFee(bean.getOtherCount());
                 }
                customerWalletReconciliationService.saveBatch(saveList);
            }
        }else{
            List<CustomerCountMonthBean>  list = walletCommonMapper.queryrebateMonthCount(month);
            if(list.size() >0){
                //生成前删除
                customerWalletReconciliationService.lambdaUpdate().eq(CustomerWalletReconciliation::getMonth,month).eq(CustomerWalletReconciliation::getType,type).remove();
                List<CustomerWalletReconciliation> saveList = new ArrayList<>();
                for(CustomerCountMonthBean bean:list){
                    CustomerWalletReconciliation m = new CustomerWalletReconciliation();
                    m.setCustomerId(bean.getCustomerId());
                    m.setCustomerName(bean.getCustomerName());
                    m.setCustomerCode(bean.getCustomerNumber());
                    m.setMonth(bean.getMonth());
                    m.setRebateInFee(bean.getInCount());
                    m.setRebateOutFee(bean.getOutCount());
                    m.setAllowanceAmount(bean.getAllowanceCount());
                    m.setWithholdAmount(bean.getWithholdCount());
                }
                customerWalletReconciliationService.saveBatch(saveList);
            }

        }

    }


    /**
     * 所有钱包(现金，返利) 列表
     * @return
     */
    public List<WalletListBean> allWalletList(){
        //现金钱包
        List<KingDeeWallet> list = kingDeeWalletService.lambdaQuery().eq(KingDeeWallet::getForbidStatus,"A").list();
        //返利钱包
        List<WalletRebate> list2 = walletRebateService.lambdaQuery().eq(WalletRebate::getStatus, true).list();

        List<WalletListBean> allList = new ArrayList<>();
        for(KingDeeWallet bean : list){
            WalletListBean wallet = new WalletListBean();
            wallet.setWalletId(bean.getId());
            wallet.setWalletName(bean.getName());
            wallet.setWalletType(1);
            allList.add(wallet);
        }

        for(WalletRebate bean : list2){
            WalletListBean wallet = new WalletListBean();
            wallet.setWalletId(bean.getWalletRebateId());
            wallet.setWalletName(bean.getName());
            wallet.setWalletType(2);
            allList.add(wallet);
        }
        return allList;

    }


    public void cancelApplyOtherRece(String id) {
        ReceivableOrder receivableOrder = receivableOrderService.getById(id);
        if( !receivableOrder.getExamineStatus().equals(ExamineStatusEnum.WAIT.toString())){
            throw new RemoteServiceException("非提审状态不可撤销提审");
        }
        receivableOrder.setExamineStatus(ExamineStatusEnum.SAVE.toString());
        receivableOrder.updateById();
    }


    /**
     * 经销商历史钱包余额
     * @param customerAmountDTO
     * @return
     */
    public IPage<CustomerWalletAmountVO> historyAmountList(CustomerAmountDTO customerAmountDTO){
        ZfireParamBean zfireParamBean = FieldUtils.supplyParam(customerAmountDTO);
        IPage<CustomerWalletAmountVO> page = commonCMapper
                .queryCustomerWalletAmountList(new Page(zfireParamBean.getPageNum(), zfireParamBean.getPageSize()),zfireParamBean, customerAmountDTO.getTime());
        return page;
    }


    public void addWallet(KingDeeWallet kingDeeWallet) {
        if (StringUtils.isEmpty(kingDeeWallet.getNumber()))
            throw new RemoteServiceException("钱包编码不能为空");

        if (kingDeeWalletService.lambdaQuery().eq(KingDeeWallet::getNumber,kingDeeWallet.getNumber()).count() > 0) {
            throw new RemoteServiceException("钱包编码存在");
        }

        if (kingDeeWalletService.lambdaQuery().eq(KingDeeWallet::getName,kingDeeWallet.getName()).count() > 0) {
            throw new RemoteServiceException("钱包名称存在");
        }
        kingDeeWallet.insert();

        walletCommonMapper.initCustomerWallet(null);
    }

    public void updateWallet(KingDeeWallet kingDeeWallet) {

        if (kingDeeWalletService.lambdaQuery().eq(KingDeeWallet::getNumber,kingDeeWallet.getNumber())
                .ne(KingDeeWallet::getId,kingDeeWallet.getId()).count() > 0) {
            throw new RemoteServiceException("钱包编码存在");
        }

        if (kingDeeWalletService.lambdaQuery().eq(KingDeeWallet::getName,kingDeeWallet.getName())
                .ne(KingDeeWallet::getId,kingDeeWallet.getId()).count() > 0) {
            throw new RemoteServiceException("钱包名称存在");
        }
        kingDeeWallet.updateById();

    }

    public IPage<KingDeeWalletVO> v2ListPage(ZfireParamBean zfireParamBean) {
        zfireParamBean = FieldUtils.supplyParam(zfireParamBean);
        return receMapper.walletV2(new Page(zfireParamBean.getPageNum(), zfireParamBean.getPageSize()), zfireParamBean);
    }
}
