package com.sckw.report.service;

import com.sckw.core.common.enums.enums.DictTypeEnum;
import com.sckw.core.model.constant.Global;
import com.sckw.core.model.constant.NumberConstant;
import com.sckw.core.model.page.PageResult;
import com.sckw.core.model.vo.TableBottom;
import com.sckw.core.model.vo.TableStatisticRes;
import com.sckw.core.model.vo.TableTop;
import com.sckw.core.utils.BeanUtils;
import com.sckw.core.utils.CollectionUtils;
import com.sckw.core.utils.DateUtils;
import com.sckw.core.utils.StringUtils;
import com.sckw.core.web.context.LoginUserHolder;
import com.sckw.excel.utils.DateUtil;
import com.sckw.mongo.model.SckwTradeOrder;
import com.sckw.report.enums.TOrderStatusEnum;
import com.sckw.report.service.param.*;
import com.sckw.report.service.vo.OrderListRes;
import com.sckw.report.service.vo.TradeOrderAppStatisticVO;
import com.sckw.system.api.RemoteSystemService;
import com.sckw.system.api.model.dto.res.SysDictResDto;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author zk
 * @desc 订单服务
 * @date 2023/7/10 0010
 */
@Service
@Slf4j
@AllArgsConstructor
public class KwOrderService {

    private final MongoTemplate mongoTemplate;

    @DubboReference(version = "1.0.0", group = "design", check = false)
    private RemoteSystemService remoteSystemService;

    /**
     * @desc: 贸易订单详情
     * @author: yzc
     * @date: 2023-07-14 9:03
     * @Param id:
     * @return: com.sckw.mongo.model.SckwTradeOrder
     */
    public SckwTradeOrder tradeOrderDetail(Long id) {
        Long entId = LoginUserHolder.getEntId();
        Query query = new Query();
        Criteria criteria = new Criteria();
        criteria.andOperator(Criteria.where("_id").is(id).and("delFlag").is(0));
        criteria.orOperator(Criteria.where("procureTopEntId").is(entId), Criteria.where("supplyTopEntId").is(entId));
        query.addCriteria(criteria);
        return mongoTemplate.findOne(query, SckwTradeOrder.class);
    }

    /**
     * @desc: 贸易订单列表分页查询
     * @author: yzc
     * @date: 2023-07-17 18:04
     * @Param params:
     * @return: com.sckw.core.model.page.PageResult
     */
    public PageResult tradeOrderSelect(TradeOrderListSelectParam params) {
        Criteria criteria = buildCriteria(params, false);
        Sort sort = Sort.by(Sort.Direction.DESC, "createTime");
        return getResult(criteria, sort, params.getPage(), params.getPageSize());
    }

    /**
     * @desc: 获取分页结果
     * @author: yzc
     * @date: 2023-07-20 15:02
     * @Param criteria:
     * @Param sort:
     * @Param page:
     * @Param pageSize:
     * @return: com.sckw.core.model.page.PageResult
     */
    public PageResult getResult(Criteria criteria, Sort sort, Integer page, Integer pageSize) {
        Query query = new Query();
        query.addCriteria(criteria);
        long count = mongoTemplate.count(query, SckwTradeOrder.class);
        SpringDataPageAble pageAble = new SpringDataPageAble(page, pageSize, sort);
        query.with(pageAble);
        List<SckwTradeOrder> list = mongoTemplate.find(query, SckwTradeOrder.class);
        if (CollectionUtils.isEmpty(list)) {
            return PageResult.build(page, pageSize, count, Collections.emptyList());
        }
        Map<String, Map<String, String>> dict = remoteSystemService.queryDictByType(List.of(
                DictTypeEnum.TORDER_STATUS.getType(), DictTypeEnum.TRADE_TYPE.getType(), DictTypeEnum.DELIVERY_TYPE.getType(),
                DictTypeEnum.PICKUP_TYPE.getType(), DictTypeEnum.TORDER_SOURCE.getType()));
        Map<String, SysDictResDto> unitType = remoteSystemService.queryDictMapByType(DictTypeEnum.UNIT_TYPE.getType());
        Map<String, String> statusMap, tradeMap, deliveryMap, pickupMap, sourceMap;
        if (CollectionUtils.isNotEmpty(dict)) {
            statusMap = CollectionUtils.isNotEmpty(dict.get(DictTypeEnum.TORDER_STATUS.getType())) ?
                    dict.get(DictTypeEnum.TORDER_STATUS.getType()) : new HashMap<>(Global.NUMERICAL_SIXTEEN);
            tradeMap = CollectionUtils.isNotEmpty(dict.get(DictTypeEnum.TRADE_TYPE.getType())) ?
                    dict.get(DictTypeEnum.TRADE_TYPE.getType()) : new HashMap<>(Global.NUMERICAL_SIXTEEN);
            deliveryMap = CollectionUtils.isNotEmpty(dict.get(DictTypeEnum.DELIVERY_TYPE.getType())) ?
                    dict.get(DictTypeEnum.DELIVERY_TYPE.getType()) : new HashMap<>(Global.NUMERICAL_SIXTEEN);
            pickupMap = CollectionUtils.isNotEmpty(dict.get(DictTypeEnum.PICKUP_TYPE.getType())) ?
                    dict.get(DictTypeEnum.PICKUP_TYPE.getType()) : new HashMap<>(Global.NUMERICAL_SIXTEEN);
            sourceMap = CollectionUtils.isNotEmpty(dict.get(DictTypeEnum.TORDER_SOURCE.getType())) ?
                    dict.get(DictTypeEnum.TORDER_SOURCE.getType()) : new HashMap<>(Global.NUMERICAL_SIXTEEN);
        } else {
            statusMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
            tradeMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
            deliveryMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
            pickupMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
            sourceMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
        }
        List<OrderListRes> result = new ArrayList<>();
        list.forEach(e -> {
            BigDecimal actualAmount = Objects.isNull(e.getActualAmount()) ? BigDecimal.ZERO : BigDecimal.valueOf(e.getActualAmount());
            BigDecimal unitPrice = Objects.isNull(e.getUnitPrice()) ? BigDecimal.ZERO : BigDecimal.valueOf(e.getUnitPrice());
            OrderListRes order = BeanUtils.copyProperties(e, OrderListRes.class);
            String loadCityName = Objects.isNull(e.getLoadCityName()) ? "" : e.getLoadCityName();
            String unloadCityName = Objects.isNull(e.getUnloadCityName()) ? "" : e.getUnloadCityName();
            String loadDetailAddress = Objects.isNull(e.getLoadDetailAddress()) ? "" : e.getLoadDetailAddress();
            String unloadDetailAddress = Objects.isNull(e.getUnloadDetailAddress()) ? "" : e.getUnloadDetailAddress();
            order.setStatusLabel(statusMap.get(String.valueOf(e.getStatus())))
                    .setTradingLabel(tradeMap.get(e.getTrading()))
                    .setTrading(tradeMap.get(e.getTrading()))
                    .setDeliveryTypeLabel(deliveryMap.get(e.getDeliveryType()))
                    .setDeliveryType(deliveryMap.get(e.getDeliveryType()))
                    .setPickupTypeLabel(pickupMap.get(e.getPickupType()))
                    .setSourceLabel(sourceMap.get(e.getSource()))
                    .setSource(sourceMap.get(e.getSource()))
                    .setLoadDetailAddressInfo(loadCityName + loadDetailAddress)
                    .setUnloadDetailAddressInfo(unloadCityName + unloadDetailAddress)
                    .setUnitPrice(setScale(e.getUnitPrice()))
                    .setPrice(setScale(e.getPrice()))
                    .setUnit(e.getUnit())
                    .setUnitLabel(unitType == null ? e.getUnit() : (unitType.get(e.getUnit()) == null ? e.getUnit() : unitType.get(e.getUnit()).getLabel()))
                    .setAmount(setScale(e.getAmount()))
                    .setEntrustAmount(setScale(e.getEntrustAmount()))
                    .setActualAmount(setScale(e.getActualAmount()))
                    .setWaitEntrustAmount(setScale(getWaitEntrustAmount(e.getAmount(), e.getEntrustAmount())))
                    .setActualPrice(actualAmount.multiply(unitPrice).setScale(2, RoundingMode.HALF_UP));
            result.add(order);
        });
        return PageResult.build(page, pageSize, count, result);
    }


    /**
     * @desc: 设置两位小数
     * @author: yzc
     * @date: 2023-09-26 10:11
     * @Param d:
     * @return: java.lang.BigDecimal
     */
    private BigDecimal setScale(Double d) {
        if (Objects.isNull(d) || BigDecimal.ZERO.compareTo(BigDecimal.valueOf(d)) == 0) {
            return NumberConstant.ZERO_TWO;
        }
        return BigDecimal.valueOf(d).setScale(2, RoundingMode.HALF_UP);
    }

    /**
     * @desc: 获取订单待分配运输量
     * @author: yzc
     * @date: 2023-08-25 10:32
     * @Param amount:
     * @Param entrustAmount:
     * @return: java.math.Double
     */
    private Double getWaitEntrustAmount(Double amount, Double entrustAmount) {
        if (Objects.isNull(amount) || Objects.isNull(entrustAmount)) {
            return amount;
        }
        return amount - entrustAmount;
    }

    /**
     * @desc: 组装Criteria
     * @author: yzc
     * @date: 2023-07-17 18:08
     * @Param params:
     * @Param isStatistic:
     * @return: org.springframework.data.mongodb.core.query.Criteria
     */
    private Criteria buildCriteria(TradeOrderListStatisticParam params, Boolean isStatistic) {
        Long entId = LoginUserHolder.getEntId();
        Long userId = LoginUserHolder.getUserId();
        String topEnt = Objects.equals(params.getOrderType(), 1) ? "procureTopEntId" : "supplyTopEntId";
        Criteria dataPermission = getDataPermissions(params.getOrderType());
        //订单状态
        Criteria statusCriteria;
        if (Objects.nonNull(params.getStatus()) && !isStatistic) {
            statusCriteria = new Criteria().and("status").is(params.getStatus());
            if (Objects.equals(params.getStatus(), 0)) {
                //草稿状态只能创建订单的人能看
                statusCriteria.and("createBy").is(userId);
            }
        } else {
            //非草稿状态or草稿状态且是当前人
            statusCriteria = new Criteria().orOperator(Criteria.where("status").ne(0),
                    new Criteria().andOperator(Criteria.where("status").is(0),
                            Criteria.where("createBy").is(userId)));
        }
        //匹配条件
        Criteria condition = new Criteria();
        condition.and("delFlag").is(0);
        //日期范围
        if (Objects.nonNull(params.getStartCreateTime()) && Objects.nonNull(params.getEndCreateTime())) {
            condition.and("createTime").gte(params.getStartCreateTime()).lte(params.getEndCreateTime());
        } else if (Objects.nonNull(params.getStartCreateTime())) {
            condition.and("createTime").gte(params.getStartCreateTime());
        } else if (Objects.nonNull(params.getEndCreateTime())) {
            condition.and("createTime").lte(params.getEndCreateTime());
        }
        //装卸货地址
        String loadCode = params.getShippingAddressCode();
        if (StringUtils.isNotBlank(loadCode)) {
            switch (params.getShippingAddressLevel()) {
                case 1 -> condition.and("loadCityCode")
                        .regex(Pattern.compile("^" + loadCode.substring(0, 2) + ".*$", Pattern.CASE_INSENSITIVE));
                case 2 -> condition.and("loadCityCode")
                        .regex(Pattern.compile("^" + loadCode.substring(0, 4) + ".*$", Pattern.CASE_INSENSITIVE));
                case 3 -> condition.and("loadCityCode").is(loadCode);
            }
        }
        String unloadCode = params.getUnloadingAddressCode();
        if (StringUtils.isNotBlank(unloadCode)) {
            switch (params.getUnloadingAddressLevel()) {
                case 1 -> condition.and("unloadCityCode")
                        .regex(Pattern.compile("^" + unloadCode.substring(0, 2) + ".*$", Pattern.CASE_INSENSITIVE));
                case 2 -> condition.and("unloadCityCode")
                        .regex(Pattern.compile("^" + unloadCode.substring(0, 4) + ".*$", Pattern.CASE_INSENSITIVE));
                case 3 -> condition.and("unloadCityCode").is(unloadCode);
            }
        }
        //提货方式
        if (StringUtils.isNotBlank(params.getPickupType())) {
            condition.and("pickupType").is(params.getPickupType());
        }
        //交易方式
        if (StringUtils.isNotBlank(params.getTrading())) {
            condition.and("trading").is(params.getTrading());
        }
        //交付类型
        if (StringUtils.isNotBlank(params.getDeliveryType())) {
            condition.and("deliveryType").is(params.getDeliveryType());
        }
        //下单方式
        if (StringUtils.isNotBlank(params.getSource())) {
            condition.and("source").is(params.getSource());
        }
        Criteria criteria = new Criteria().and(topEnt).is(entId);
        //关键字模糊匹配
        if (StringUtils.isNotBlank(params.getKeywords())) {
            Pattern pattern = Pattern.compile("^.*" + params.getKeywords() + ".*$", Pattern.CASE_INSENSITIVE);
            Criteria keywordsMatch = new Criteria().orOperator(
                    Criteria.where("tOrderNo").regex(pattern), Criteria.where("procureFirmName").regex(pattern),
                    Criteria.where("supplyFirmName").regex(pattern), Criteria.where("goodsName").regex(pattern));
            criteria.andOperator(dataPermission, statusCriteria, condition, keywordsMatch);
        } else {
            criteria.andOperator(dataPermission, statusCriteria, condition);
        }
        return criteria;
    }

    /**
     * @desc: 数据权限组装
     * @author: yzc
     * @date: 2023-09-08 18:02
     * @Param orderType:
     * @return: org.springframework.data.mongodb.core.query.Criteria
     */
    private Criteria getDataPermissions(Integer orderType) {
        Long entId = LoginUserHolder.getEntId();
        Integer isMain = LoginUserHolder.getIsMain();
        List<Long> authUserIdList = LoginUserHolder.getAuthUserIdList();
        //数据权限
        String topEnt = Objects.equals(orderType, 1) ? "procureTopEntId" : "supplyTopEntId";
        String contactsId = Objects.equals(orderType, 1) ? "procureContactsId" : "supplyContactsId";
        Criteria criteria1, criteria2;
        if (Objects.equals(isMain, 0)) {
            criteria1 = new Criteria().andOperator(Criteria.where("ent_id").is(entId),
                    Criteria.where("create_by").in(authUserIdList));
            criteria2 = new Criteria().andOperator(Criteria.where(topEnt).is(entId),
                    Criteria.where(contactsId).in(authUserIdList));
        } else {
            criteria1 = new Criteria().andOperator(Criteria.where("ent_id").is(entId));
            criteria2 = new Criteria().andOperator(Criteria.where(topEnt).is(entId));
        }
        return new Criteria().orOperator(criteria1, criteria2);
    }

    /**
     * @desc: 贸易订单列表统计查询
     * @author: yzc
     * @date: 2023-07-17 18:05
     * @Param params:
     * @return: com.sckw.core.model.vo.TableStatisticRes
     */
    public TableStatisticRes tradeOrderStatistic(TradeOrderListStatisticParam params) {
        Criteria criteria = buildCriteria(params, true);
        return getTableStatistic(criteria, TOrderStatusEnum.getSortList());
    }

    /**
     * @desc: 列表统计
     * @author: yzc
     * @date: 2023-09-14 14:18
     * @Param criteria:
     * @Param enums:
     * @return: com.sckw.core.model.vo.TableStatisticRes
     */
    public TableStatisticRes getTableStatistic(Criteria criteria, List<TOrderStatusEnum> enums) {
        TableStatisticRes res = new TableStatisticRes();
        Aggregation aggregation = Aggregation.newAggregation(
                Aggregation.match(criteria),
                Aggregation.group("status").count().as("total"),
                Aggregation.project("total").and("value").previousOperation()
        );
        AggregationResults<TableTop> aggregate = mongoTemplate
                .aggregate(aggregation, SckwTradeOrder.class, TableTop.class);
        List<TableTop> tableTops = aggregate.getMappedResults();
        Map<Integer, Integer> map = new HashMap<>(Global.NUMERICAL_SIXTEEN);
        if (CollectionUtils.isNotEmpty(tableTops)) {
            map = tableTops.stream().collect(Collectors.toMap
                    (TableTop::getValue, TableTop::getTotal, (k1, k2) -> k2));
        }
        List<TableTop> list = new ArrayList<>();
        int count = 0;
        for (TOrderStatusEnum e : enums) {
            Integer value = e.getCode();
            int total = Objects.isNull(map.get(value)) ? 0 : map.get(value);
            TableTop tableTop = new TableTop();
            tableTop.setName(e.getMsg()).setValue(value).setTotal(total);
            list.add(tableTop);
            count = count + total;
        }
        TableTop all = new TableTop();
        all.setName("全部").setTotal(count);
        list.add(0, all);
        TableBottom tableBottom = new TableBottom();
        tableBottom.setTotal(count);
        res.setTableTops(list).setTableBottom(tableBottom);
        return res;
    }

    /**
     * @desc: app主界面贸易订单统计
     * @author: yzc
     * @date: 2023-08-21 17:39
     * @Param params:
     * @return: java.util.List<com.sckw.report.service.vo.TradeOrderAppStatisticVO>
     */
    public List<TradeOrderAppStatisticVO> appStatistic(TradeOrderAppStatisticParam params) {
        Long entId = LoginUserHolder.getEntId();
        String topEnt = Objects.equals(params.getOrderType(), 1) ? "procureTopEntId" : "supplyTopEntId";
        List<Integer> status = Arrays.asList(1, 4, 5, 7);
        Criteria criteria = new Criteria();
        criteria.and(topEnt).is(entId).and("status").in(status).and("delFlag").is(0);
        Criteria dataPermissions = getDataPermissions(params.getOrderType());
        criteria.andOperator(dataPermissions);
        Aggregation aggregation = Aggregation.newAggregation(
                Aggregation.match(criteria),
                Aggregation.group("status").count().as("total"),
                Aggregation.project("total").and("value").previousOperation()
        );
        AggregationResults<TradeOrderAppStatisticVO> aggregate = mongoTemplate
                .aggregate(aggregation, SckwTradeOrder.class, TradeOrderAppStatisticVO.class);
        List<TradeOrderAppStatisticVO> tableTops = aggregate.getMappedResults();
        Map<Integer, Integer> map = new HashMap<>(Global.NUMERICAL_SIXTEEN);
        if (CollectionUtils.isNotEmpty(tableTops)) {
            map = tableTops.stream().collect(Collectors.toMap
                    (TradeOrderAppStatisticVO::getValue, TradeOrderAppStatisticVO::getTotal, (k1, k2) -> k2));
        }
        List<TradeOrderAppStatisticVO> statistics = new ArrayList<>();
        for (Integer e : status) {
            int total = Objects.isNull(map.get(e)) ? 0 : map.get(e);
            TradeOrderAppStatisticVO statistic = new TradeOrderAppStatisticVO();
            statistic.setValue(e).setTotal(total);
            statistics.add(statistic);
        }
        return statistics;
    }

    /**
     * @desc: 贸易订单列表导出
     * @author: yzc
     * @date: 2023-07-17 18:05
     * @Param params:
     * @return: java.util.List<com.sckw.report.service.param.TradeOrderListExport>
     */
    public List<TradeOrderListExport> export(TradeOrderListExportParam params) {
        Query query = new Query();
        if (StringUtils.isNotBlank(params.getIds())) {
            List<Long> ids = StringUtils.splitStrToList(params.getIds(), ",", Long.class);
            Long entId = LoginUserHolder.getEntId();
            Criteria criteria = new Criteria();
            String topEnt = Objects.equals(params.getOrderType(), 1) ? "procureTopEntId" : "supplyTopEntId";
            criteria.and("_id").in(ids).and(topEnt).is(entId).and("delFlag").is(0);
            query.addCriteria(criteria);
        } else {
            query.addCriteria(buildCriteria(params, false));
        }
        query.with(Sort.by(Sort.Order.desc("createTime")));
        return getExportResult(query);
    }

    /**
     * @desc: 获取导出结果
     * @author: yzc
     * @date: 2023-09-14 14:41
     * @Param query:
     * @return: java.util.List<com.sckw.report.service.param.TradeOrderListExport>
     */
    public List<TradeOrderListExport> getExportResult(Query query) {
        List<SckwTradeOrder> orders = mongoTemplate.find(query, SckwTradeOrder.class);
        if (CollectionUtils.isEmpty(orders)) {
            return Collections.emptyList();
        }
        Map<String, Map<String, String>> dict = remoteSystemService.queryDictByType(List.of(
                DictTypeEnum.TORDER_STATUS.getType(), DictTypeEnum.PICKUP_TYPE.getType(), DictTypeEnum.DELIVERY_TYPE.getType(),
                DictTypeEnum.TORDER_SOURCE.getType(), DictTypeEnum.TRADE_TYPE.getType()));
        Map<String, String> statusMap, pickupMap, deliveryMap, sourceMap, tradeMap;
        if (CollectionUtils.isNotEmpty(dict)) {
            statusMap = CollectionUtils.isNotEmpty(dict.get(DictTypeEnum.TORDER_STATUS.getType())) ?
                    dict.get(DictTypeEnum.TORDER_STATUS.getType()) : new HashMap<>(Global.NUMERICAL_SIXTEEN);
            pickupMap = CollectionUtils.isNotEmpty(dict.get(DictTypeEnum.PICKUP_TYPE.getType())) ?
                    dict.get(DictTypeEnum.PICKUP_TYPE.getType()) : new HashMap<>(Global.NUMERICAL_SIXTEEN);
            deliveryMap = CollectionUtils.isNotEmpty(dict.get(DictTypeEnum.DELIVERY_TYPE.getType())) ?
                    dict.get(DictTypeEnum.DELIVERY_TYPE.getType()) : new HashMap<>(Global.NUMERICAL_SIXTEEN);
            sourceMap = CollectionUtils.isNotEmpty(dict.get(DictTypeEnum.TORDER_SOURCE.getType())) ?
                    dict.get(DictTypeEnum.TORDER_SOURCE.getType()) : new HashMap<>(Global.NUMERICAL_SIXTEEN);
            tradeMap = CollectionUtils.isNotEmpty(dict.get(DictTypeEnum.TRADE_TYPE.getType())) ?
                    dict.get(DictTypeEnum.TRADE_TYPE.getType()) : new HashMap<>(Global.NUMERICAL_SIXTEEN);
        } else {
            statusMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
            pickupMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
            deliveryMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
            sourceMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
            tradeMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
        }
        List<TradeOrderListExport> list = new ArrayList<>();
        orders.forEach(e -> {
            Double waitEntrustAmount = getWaitEntrustAmount(e.getAmount(), e.getEntrustAmount());
            String loadCityName = Objects.isNull(e.getLoadCityName()) ? "" : e.getLoadCityName();
            String loadDetailAddress = Objects.isNull(e.getLoadDetailAddress()) ? "" : e.getLoadDetailAddress();
            String unloadCityName = Objects.isNull(e.getUnloadCityName()) ? "" : e.getUnloadCityName();
            String unloadDetailAddress = Objects.isNull(e.getUnloadDetailAddress()) ? "" : e.getUnloadDetailAddress();
            TradeOrderListExport export = BeanUtils.copyProperties(e, TradeOrderListExport.class);
            export.setStatus(statusMap.get(String.valueOf(e.getStatus())))
                    .setUnitPrice(String.valueOf(setScale(e.getUnitPrice())))
                    .setAmount(String.valueOf(setScale(e.getAmount())))
                    .setPrice(String.valueOf(setScale(e.getPrice())))
                    .setEntrustAmount(String.valueOf(setScale(e.getEntrustAmount())))
                    .setActualAmount(String.valueOf(setScale(e.getActualAmount())))
                    .setWaitEntrustAmount(String.valueOf(setScale(waitEntrustAmount)))
                    .setPickupType(pickupMap.get(e.getPickupType()))
                    .setDeliveryType(deliveryMap.get(e.getDeliveryType()))
                    .setSource(sourceMap.get(e.getSource()))
                    .setTrading(tradeMap.get(e.getTrading()))
                    .setLoadDetailAddressInfo(loadCityName + loadDetailAddress)
                    .setUnloadDetailAddressInfo(unloadCityName + unloadDetailAddress)
                    .setStartTime(Objects.isNull(e.getStartTime()) ? null : DateUtils.format(e.getStartTime(), DateUtils.DATE_PATTERN))
                    .setEndTime(Objects.isNull(e.getEndTime()) ? null : DateUtils.format(e.getEndTime(), DateUtils.DATE_PATTERN))
                    .setCreateTime(DateUtil.getDateTime(e.getCreateTime()));
            list.add(export);
        });
        return list;
    }

    /**
     * @desc: 贸易订单对账单分页列表查询
     * @author: yzc
     * @date: 2023-07-20 15:03
     * @Param params:
     * @return: com.sckw.core.model.page.PageResult
     */
    public PageResult tradeOrderStatementList(TradeOrderStatementList params) {
        Long entId = LoginUserHolder.getEntId();
        Criteria criteria = new Criteria();
        String topEnt = Objects.equals(params.getOrderType(), 1) ? "procureTopEntId" : "supplyTopEntId";
        criteria.and(topEnt).is(entId).and("status").is(TOrderStatusEnum.FINISHED.getCode())
                .and("associateStatement").ne(1).and("delFlag").is(0);
        //排除订单ids
        if (StringUtils.isNotBlank(params.getExcludeIds())) {
            List<Long> ids = StringUtils.splitStrToList(params.getExcludeIds(), ",", Long.class);
            criteria.and("_id").nin(ids);
        }
        //采购企业
        if (Objects.nonNull(params.getProcureEntId())) {
            criteria.and("procureEntId").is(params.getProcureEntId());
        }
        //交易方式
        if (StringUtils.isNotBlank(params.getTrading())) {
            criteria.and("trading").is(params.getTrading());
        }
        //计划开始时间
        if (Objects.nonNull(params.getStartTime())) {
            criteria.and("startTime").gte(params.getStartTime());
        }
        //计划结束时间
        if (Objects.nonNull(params.getEndTime())) {
            criteria.and("endTime").lte(params.getEndTime());
        }
        //商品税率
        if (Objects.nonNull(params.getGoodsTaxRate())) {
            criteria.and("goodsTaxRate").is(params.getGoodsTaxRate());
        }
        //商品名称
        if (StringUtils.isNotBlank(params.getGoodsName())) {
            Pattern pattern = Pattern.compile("^.*" + params.getGoodsName() + ".*$", Pattern.CASE_INSENSITIVE);
            criteria.and("goodsName").regex(pattern);
        }
        Sort sort = Sort.by(Sort.Direction.DESC, "createTime");
        return getResult(criteria, sort, params.getPage(), params.getPageSize());
    }

    /**
     * @desc: 合同关联订单列表
     * @author: yzc
     * @date: 2023-07-27 17:05
     * @Param params:
     * @return: com.sckw.core.model.page.PageResult
     */
    public PageResult tradeOrderContractList(TradeOrderContractParam params) {
        Long entId = LoginUserHolder.getEntId();
        Criteria criteria = new Criteria();
        String topEnt = Objects.equals(params.getOrderType(), 1) ? "procureTopEntId" : "supplyTopEntId";
        List<Long> ids = StringUtils.splitStrToList(params.getContractIds(), ",", Long.class);
        criteria.and("contractId").in(ids).and(topEnt).is(entId).and("delFlag").is(0);
        Sort sort = Sort.by(Sort.Direction.DESC, "contractId", "createTime");
        return getResult(criteria, sort, params.getPage(), params.getPageSize());
    }

}
