package com.ghy.web.controller.order;

import com.ghy.common.core.controller.BaseController;
import com.ghy.common.core.domain.AjaxResult;
import com.ghy.common.enums.*;
import com.ghy.common.utils.StringUtils;
import com.ghy.customer.domain.Customer;
import com.ghy.customer.domain.CustomerAddress;
import com.ghy.customer.service.CustomerAddressService;
import com.ghy.customer.service.CustomerService;
import com.ghy.goods.domain.DeptGoodsCategory;
import com.ghy.goods.domain.Goods;
import com.ghy.goods.domain.GoodsStandard;
import com.ghy.goods.request.AppGoodsRequest;
import com.ghy.goods.service.DeptGoodsCategoryService;
import com.ghy.goods.service.GoodsService;
import com.ghy.goods.service.GoodsStandardService;
import com.ghy.order.domain.*;
import com.ghy.order.request.AppOrderAssignRequest;
import com.ghy.order.request.AppOrderRequest;
import com.ghy.order.request.SysOrderAssignRequest;
import com.ghy.order.service.*;
import com.ghy.payment.domain.FinancialChangeRecord;
import com.ghy.payment.domain.FinancialDetail;
import com.ghy.payment.domain.FinancialMaster;
import com.ghy.payment.domain.OrderTimeoutRecord;
import com.ghy.payment.service.FinancialChangeRecordService;
import com.ghy.payment.service.FinancialDetailService;
import com.ghy.payment.service.FinancialMasterService;
import com.ghy.payment.service.OrderFineRecordService;
import com.ghy.system.domain.SysArea;
import com.ghy.system.service.ISysAreaService;
import com.ghy.system.service.IWxMsgService;
import com.ghy.web.pojo.vo.*;
import com.ghy.worker.domain.Worker;
import com.ghy.worker.domain.WorkerCertification;
import com.ghy.worker.service.IWorkerCertificationService;
import com.ghy.worker.service.WorkerService;
import com.huifu.adapay.core.exception.BaseAdaPayException;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author clunt
 * 下单接口
 */
@Controller
@RequestMapping("/order")
public class OrderController extends BaseController {

    @Resource
    private CustomerService customerService;
    @Resource
    private GoodsService goodsService;
    @Resource
    private DeptGoodsCategoryService deptGoodsCategoryService;
    @Resource
    private WorkerService workerService;
    @Resource
    private OrderMasterService orderMasterService;
    @Resource
    private OrderDetailService orderDetailService;
    @Resource
    private OrderGoodsService orderGoodsService;
    @Resource
    private FinancialMasterService financialMasterService;
    @Resource
    private FinancialDetailService financialDetailService;
    @Resource
    private GoodsStandardService goodsStandardService;
    @Resource
    private CustomerAddressService addressService;
    @Resource
    private ISysAreaService sysAreaService;
    @Resource
    private OrderFineRecordService orderFineRecordService;
    @Resource
    private FinancialChangeRecordService financialChangeRecordService;
    @Resource
    private IWorkerCertificationService workerCertificationService;
    @Resource
    private IAfterServiceRecordService afterServiceRecordService;
    @Resource
    private OrderBehaviorService orderBehaviorService;
    @Resource
    private IWxMsgService wxMsgService;

    /**
     * 可派单商品数量
     */
    @PostMapping("/can/assign")
    @ResponseBody
    public AjaxResult canAssign(@RequestBody AppOrderAssignRequest request) {
        try {
            // 找出原单的数量
            List<OrderGoods> orderGoodsList = orderGoodsService.selectByOrderMasterId(request.getOrderMasterId());
            // 找出原单关联的细单的商品数量
            List<OrderDetail> orderDetailList = orderDetailService.selectByOrderMasterId(request.getOrderMasterId());
            for (OrderDetail orderDetail : orderDetailList) {
                // 子单数量
                List<OrderGoods> orderDetailGoodsList = orderGoodsService.selectByOrderDetailId(orderDetail.getId());

                // 计算剩余未分配的商品数量
                for (OrderGoods detailGoods : orderDetailGoodsList) {
                    for (OrderGoods masterGoods : orderGoodsList) {
                        if (Objects.equals(masterGoods.getGoodsStandardId(), detailGoods.getGoodsStandardId())) {
                            masterGoods.setGoodsNum(masterGoods.getGoodsNum() - detailGoods.getGoodsNum());
                        }
                    }
                }
            }
            //计算新单的数量
            return AjaxResult.success(orderGoodsList);
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 后台批量下单
     */
    @PostMapping("/sys/order")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult sysOrder(@RequestBody SysOrderAssignRequest request) {
        request.setGoodsDeptCategoryId(request.getCategory4());
        List<Long> ids = new ArrayList<>();
        ids.add(request.getCategory1());
        ids.add(request.getCategory2());
        ids.add(request.getCategory3());
        ids.add(request.getCategory4());

        DeptGoodsCategory deptGoodsCategory = deptGoodsCategoryService.get(request.getGoodsDeptCategoryId());
        OrderTemplateGoods orderTemplateGoods = new OrderTemplateGoods();
        orderTemplateGoods.setGoodsName(request.getGoodsBrand() + " " + deptGoodsCategory.getGoodsCategoryName());
        orderTemplateGoods.setDeptGoodsCategoryIds(ids);
        orderTemplateGoods.setDeptGoodsCategoryNames(Arrays.asList(orderTemplateGoods.getGoodsName()));
        request.setGoods(Arrays.asList(orderTemplateGoods));
        String goodsBrand = request.getGoodsBrand();
        Long deptId = getSysUser().getDeptId();
        List<OrderTemplateGoods> goodsList = request.getGoods();
        // 订单总价 不能小于0
        BigDecimal orderPrice = BigDecimal.valueOf(request.getPrice()).max(BigDecimal.ZERO);
        // 商品单价
        BigDecimal goodsPrice = orderPrice.divide(BigDecimal.valueOf(goodsList.size()), RoundingMode.HALF_UP);
        // 累计商品价格 用来处理商品单价除不尽的情况
        BigDecimal goodsPriceAccumulative = BigDecimal.ZERO;
        int goodsNum = 0;
        // 新增商品 -- 商品不关联师傅,状态为不展示在商城页面
        for (OrderTemplateGoods good : goodsList) {
            List<Long> dgcIds = good.getDeptGoodsCategoryIds();
            List<String> dgcNames = good.getDeptGoodsCategoryNames();
            // 商品的4级类要完整
            Assert.isTrue(dgcIds != null && dgcIds.size() == 4, "商品类型不正确");
            Goods goods = new Goods();
            goods.setDeptId(deptId);
            goods.setGoodsName(goodsBrand + ' ' + good.getGoodsName());
            goods.setGoodsImgUrl(request.getImageUrl());
            goods.setGoodsVideoUrl(request.getVideoUrl());
            goods.setDeptGoodsCategoryId(dgcIds.get(2));
            goods.setDeptGoodsCategoryName(dgcNames.get(0));
            goods.setStatus(1);

            GoodsStandard standard = new GoodsStandard();
            standard.setGoodsStandardName(good.getGoodsName());
            standard.setDeptGoodsCategoryId(dgcIds.get(3));
            standard.setGoodsCategoryName(dgcNames.get(0));
            if ((++goodsNum) == (goodsList.size() - 1)) {
                standard.setGoodsPrice(orderPrice.subtract(goodsPriceAccumulative));
            } else {
                standard.setGoodsPrice(goodsPrice);
                goodsPriceAccumulative = goodsPriceAccumulative.add(goodsPrice);
            }

            goodsService.insertGoods(goods);
            standard.setGoodsId(goods.getGoodsId());
            standard.setExtMoney(BigDecimal.ZERO);
            standard.setGoodsNum(999);
            standard.setSaleNum(0);
            goodsStandardService.save(Collections.singletonList(standard));

            // 生成主单
            OrderMaster orderMaster = new OrderMaster();
            orderMaster.setDeptId(deptId);
            orderMaster.setCode(orderMasterService.createOrderCode());
            orderMaster.setOrderType(0);
            orderMaster.setOrderStatus(OrderStatus.RECEIVE.code());
            orderMaster.setAddressId(request.getAddressId());
            orderMaster.setPayStatus(PayStatus.WAIT_PAY.getCode());
            orderMaster.setCreateTime(new Date());
            orderMaster.setWorkerId(goods.getWorkerId());
            orderMaster.setGoodsId(goods.getGoodsId());
            orderMasterService.insertOrderMaster(orderMaster);
            Assert.notNull(orderMaster.getId(), "OrderMaster.id is null!");

            // 生成财务主单
            FinancialMaster financialMaster = new FinancialMaster(financialMasterService.createCode(), deptId,
                    orderMaster.getId(), orderMaster.getCode(), standard.getGoodsPrice(), BigDecimal.ZERO, standard.getGoodsPrice());
            financialMaster.setServerMoney(financialMaster.getTotalMoney());
            financialMasterService.insertFinancialMaster(financialMaster);
            Assert.notNull(financialMaster.getId(), "FinancialMaster.id is null!");

            // 生成提成类子财务单
            createDeptFinancialDetail(standard, deptId, financialMaster);

            // 生成商品订单
            OrderGoods orderGoods = new OrderGoods(orderMaster.getId(), standard.getGoodsStandardId(),
                    standard.getGoodsStandardName(), good.getNumber(), 0);
            orderGoodsService.insertOrderGoods(orderGoods);

        }

        // 选择消费者(消费者类型为渠道商、不需要) --

        // 生成消费者下单地址

        // 生成主单

        // 生成财务单

        // 生成财务细单 -- 平台扣点、提成
        return AjaxResult.success("下单成功");
    }

    /**
     * 平台下单时生成子财务单的方法
     * 只有平台扣点和截流扣点
     *
     * @param goodsStandard   商品
     * @param deptId          企业ID
     * @param financialMaster 主财务单
     */
    private void createDeptFinancialDetail(GoodsStandard goodsStandard, Long deptId, FinancialMaster financialMaster) {
        // 平台
        BigDecimal deptMoney = BigDecimal.ZERO;
        // 截流扣点
        BigDecimal specialMoney = BigDecimal.ZERO;
        // 服务金额
        BigDecimal serverMoney = financialMaster.getServerMoney();
        // 扣点设置类目
        DeptGoodsCategory deptGoodsCategory = deptGoodsCategoryService.get(goodsStandard.getDeptGoodsCategoryId());
        // 平台扣点 = 平台金额 + 商品单价 * 扣点比例
        deptMoney = deptMoney.add(deptGoodsCategory.getDeptMoney())
                .add(goodsStandard.getGoodsPrice().multiply(BigDecimal.valueOf(Double.parseDouble(deptGoodsCategory.getDeptRate()))));
        // 截流扣点 = 截流金额 + 商品单价 * 扣点比例
        specialMoney = specialMoney.add(deptGoodsCategory.getRetainMoney())
                .add(goodsStandard.getGoodsPrice().multiply(BigDecimal.valueOf(Double.parseDouble(deptGoodsCategory.getRetainRate()))));
        // 平台扣点记录
        FinancialDetail deptDetail = new FinancialDetail(deptId, financialDetailService.createCode(),
                financialMaster.getId(), financialMaster.getCode(), deptMoney, FinancialDetailType.PLATFORM_FEE.getCode(), null);
        financialDetailService.insertFinancialDetail(deptDetail);
        // 剩余服务金额
        serverMoney = serverMoney.subtract(deptMoney);

        // 截流扣点记录
        FinancialDetail retainDetail = new FinancialDetail(deptId, financialDetailService.createCode(),
                financialMaster.getId(), financialMaster.getCode(), specialMoney, FinancialDetailType.PLATFORM_FEE.getCode(), null);
        financialDetailService.insertFinancialDetail(retainDetail);
        // 剩余服务金额
        serverMoney = serverMoney.subtract(specialMoney);

        FinancialMaster fmUpdate = new FinancialMaster();
        fmUpdate.setId(financialMaster.getId());
        fmUpdate.setServerMoney(serverMoney);
        financialMasterService.updateFinancialMaster(financialMaster);
    }

    /**
     * 分配订单
     */
    @PostMapping("/assign")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult assign(@RequestBody AppOrderAssignRequest request) throws BaseAdaPayException {
        logger.info("分配订单请求参数:{}", request);
        OrderMaster om = orderMasterService.selectById(request.getOrderMasterId());
        Assert.notNull(om, "订单不存在");
        FinancialMaster fm = financialMasterService.selectByOrderMasterId(om.getId());
        Assert.notNull(fm, "找不到对应的订单");
        // 派单师傅
        Worker assignWorker = workerService.selectById(om.getWorkerId());
        Assert.notNull(assignWorker, "找不到师傅信息");
        // 接单师傅
        Worker acceptWorker = workerService.selectById(request.getWorkerId());
        Assert.notNull(acceptWorker, "查询接单师傅信息失败");

        // 校验接单师傅和派单师傅是不是同一个Team
        if (om.getWorkerId().equals(request.getWorkerId())) {
            // 自己接单 子单金额=0
            request.setTotalPay(BigDecimal.ZERO);
        } else {
            if (fm.getServerMoney().compareTo(request.getTotalPay()) < 0) {
                logger.warn("派单金额[{}]大于订单总金额[{}]", request.getTotalPay(), fm.getServerMoney());
                return AjaxResult.error("派单金额不能大于订单总金额");
            }
            boolean checkInTeam = workerService.checkInTeam(assignWorker.getWorkerId(), acceptWorker.getWorkerId());
            Assert.isTrue(checkInTeam, "接单师傅不在本团队");
        }

        // 创建子订单
        OrderDetail od = new OrderDetail();
        od.setDeptId(om.getDeptId());
        od.setCode(orderDetailService.createCode());
        od.setOrderMasterId(om.getId());
        od.setOrderMasterCode(om.getCode());
        od.setCustomerId(om.getCustomerId());
        od.setOrderType(om.getOrderType());
        od.setOrderStatus(request.getWorkerId().equals(om.getWorkerId()) ? OrderStatus.GOING.code() : OrderStatus.RECEIVE.code());
        od.setWorkerId(request.getWorkerId());
        od.setRevTime(om.getRevTime());
        od.setExpectTimeStart(om.getExpectTimeStart());
        od.setExpectTimeEnd(om.getExpectTimeEnd());
        orderDetailService.insertOrderDetail(od);

        // 批量生成订单商品
        request.getGoodsList().forEach(goods -> {
            // 查询规格信息
            GoodsStandard goodsStandard = goodsStandardService.selectById(goods.getGoodsStandardId());
            OrderGoods orderGoods = new OrderGoods();
            orderGoods.setGoodsStandardId(goods.getGoodsStandardId());
            orderGoods.setGoodsNum(goods.getNum());
            orderGoods.setGoodsName(goodsStandard.getGoodsStandardName());
            orderGoods.setOrderDetailId(od.getId());
            orderGoods.setServerGoodsNum(0);
            orderGoodsService.insertOrderGoods(orderGoods);
        });


        //为接单师傅生成子财务单
        FinancialDetail fd = new FinancialDetail(fm.getDeptId(), financialDetailService.createCode(), fm.getId(),
                fm.getCode(), od.getId(), od.getCode(), request.getTotalPay(), FinancialDetailType.ORDER_FEE.getCode(), acceptWorker.getWorkerId(),
                fm.getPayType(), fm.getPayStatus(), fm.getPayTime());
        financialDetailService.insertFinancialDetail(fd);

        if (!BigDecimal.ZERO.equals(request.getTotalPay())) {
            // 更新财务主单服务金额
            FinancialMaster fm2up = new FinancialMaster();
            fm2up.setId(fm.getId());
            fm2up.setServerMoney(fm.getServerMoney().subtract(request.getTotalPay()));
            financialMasterService.updateFinancialMaster(fm2up);
        }

        // 保存订单操作记录
        OrderBehavior orderBehavior = new OrderBehavior().setOrderMasterId(om.getId()).setOrderMasterCode(om.getCode())
                .setWorkerId(assignWorker.getWorkerId()).setWorkerName(assignWorker.getName()).setBehavior(OrderBehaviorEnum.ASSIGN_ORDER);
        orderBehaviorService.insert(orderBehavior);

        // 更新主订单
        OrderMaster om2up = new OrderMaster();
        // 判断是否全部派完
        if (orderMasterService.isAllAssign(om.getId())) {
            om2up.setId(om.getId());
            Set<Long> workIds = orderDetailService.selectByOrderMasterId(om.getId()).stream().map(OrderDetail::getWorkerId).collect(Collectors.toSet());
            if (workIds.size() == 1 && workIds.contains(om.getWorkerId())) {
                // 派完单 并且只有自己接单
                om2up.setHasDispatchedAll(1);
                om2up.setOrderStatus(OrderStatus.GOING.code());
            } else {
                // 派完单 但是有其他师傅接单
                om2up.setHasDispatchedAll(0);
                om2up.setOrderStatus(OrderStatus.RECEIVE.code());
            }
        } else {
            // 未派完单
            om2up.setHasDispatchedAll(0);
        }
        orderMasterService.updateOrderMaster(om2up);

        // 通知师傅新订单
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("thing1", "新订单通知");
            params.put("thing5", "收到师傅派单,请及时处理!");
            wxMsgService.sendWxMsg(acceptWorker.getOpenId(), WxMsgEnum.ORDER_PLAN, params);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return AjaxResult.success();
    }

    @PostMapping("/server/app")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult appOrder(@RequestBody AppOrderRequest appOrderRequest) throws ParseException {
        // 校验用户信息
        Customer customer = customerService.selectByCustomerId(appOrderRequest.getCustomerId());
        if (StringUtils.isNull(customer)) {
            return AjaxResult.error("用户不存在!");
        }
        List<AppGoodsRequest> appGoodsList = appOrderRequest.getGoodsList();
        // 校验商品信息(库存)
        boolean flag = goodsService.checkStore(appGoodsList);
        if (!flag) {
            return AjaxResult.error("库存不足!");
        }
        // 计算商品费用
        BigDecimal totalPay = goodsService.calculate(appGoodsList);
        // 所有商品的ID
        Set<Long> goodsStandardIds = appGoodsList.stream().map(AppGoodsRequest::getGoodsStandardId).collect(Collectors.toSet());
        // 所有商品
        List<GoodsStandard> goodsList = goodsStandardService.selectByIds(goodsStandardIds);
        // 商品所属师傅
        Goods goods = goodsService.selectById(goodsList.get(0).getGoodsId());
        // 师傅信息
        Worker worker = workerService.selectById(goods.getWorkerId());
        // 商户ID
        Long deptId = appOrderRequest.getDeptId();
        Assert.notNull(deptId, "deptId is null!");

        // 生成主单
        OrderMaster orderMaster = new OrderMaster();
        orderMaster.setDeptId(deptId);
        orderMaster.setCode(orderMasterService.createOrderCode());
        orderMaster.setOrderType(0);
        orderMaster.setPayType(appOrderRequest.getPayType());
        orderMaster.setOrderStatus(OrderStatus.RECEIVE.code());
        orderMaster.setCustomerId(appOrderRequest.getCustomerId());
        orderMaster.setAddressId(appOrderRequest.getAddressId());
        orderMaster.setPayStatus(PayStatus.WAIT_PAY.getCode());
        orderMaster.setCreateTime(new Date());
        orderMaster.setWorkerId(goods.getWorkerId());
        orderMaster.setGoodsId(appOrderRequest.getGoodsId());
//        orderMaster.setRevTime(DateUtils.parseDate(appOrderRequest.getServerTime(), com.ghy.common.utils.DateUtils.YYYY_MM_DD_HH_MM_SS));
        orderMaster.setRemark(appOrderRequest.getRemark());
        orderMaster.setExpectTimeStart(DateUtils.parseDate(appOrderRequest.getExpectTimeStart(), com.ghy.common.utils.DateUtils.YYYY_MM_DD_HH_MM_SS));
        orderMaster.setExpectTimeEnd(DateUtils.parseDate(appOrderRequest.getExpectTimeEnd(), com.ghy.common.utils.DateUtils.YYYY_MM_DD_HH_MM_SS));
        orderMasterService.insertOrderMaster(orderMaster);
        Assert.notNull(orderMaster.getId(), "OrderMaster.id is null!");

        // TODO 优惠金额不知道咋算 暂时先给0
        BigDecimal discountMoney = BigDecimal.ZERO;
        BigDecimal payMoney = totalPay.subtract(discountMoney);

        // 当实付金额payType<=0时 使payType=BigDecimal.ZERO
        payMoney = BigDecimal.ZERO.max(payMoney);

        // 生成财务主单
        FinancialMaster financialMaster = new FinancialMaster(financialMasterService.createCode(), deptId,
                orderMaster.getId(), orderMaster.getCode(), totalPay, discountMoney, payMoney);
        financialMaster.setServerMoney(financialMaster.getTotalMoney());
        financialMasterService.insertFinancialMaster(financialMaster);
        Assert.notNull(financialMaster.getId(), "FinancialMaster.id is null!");


//      createFinancialDetail(goodsList.get(0).getDeptGoodsCategoryId(), deptId, customer, payMoney, financialMaster);

        //生成财务子单
        createFinancialDetail(appGoodsList, deptId, customer, payMoney, financialMaster);

        // 生成商品订单
        Map<Long, GoodsStandard> goodsMap = goodsList.stream().filter(Objects::nonNull)
                .collect(Collectors.toMap(GoodsStandard::getGoodsStandardId, x -> x));
        for (AppGoodsRequest appGoods : appGoodsList) {
            GoodsStandard goodsStandard = goodsMap.get(appGoods.getGoodsStandardId());
            OrderGoods orderGoods = new OrderGoods(orderMaster.getId(), goodsStandard.getGoodsStandardId(),
                    goodsStandard.getGoodsStandardName(), appGoods.getNum(), 0);
            orderGoodsService.insertOrderGoods(orderGoods);
        }
        // 通知师傅新订单
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("character_string22", orderMaster.getCode());
            params.put("thing19", customer.getName());
            params.put("time1", com.ghy.common.utils.DateUtils.parseDateToStr("yyyy年MM月dd日 HH:mm", new Date()));
            params.put("thing5", "有新订单,请及时处理!");
            wxMsgService.sendWxMsg(worker.getOpenId(), WxMsgEnum.NEW_ORDER, params);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return AjaxResult.success(orderMaster);
    }

    private void createFinancialDetail(List<AppGoodsRequest> appGoodsList, Long deptId, Customer customer, BigDecimal serverMoney, FinancialMaster financialMaster) {
        // 平台
        BigDecimal deptMoney = BigDecimal.ZERO;
        // 一级分销
        BigDecimal oneMoney = BigDecimal.ZERO;
        // 二级分销
        BigDecimal twoMoney = BigDecimal.ZERO;
        // 三级分销
        BigDecimal threeMoney = BigDecimal.ZERO;
        // 截流扣点
        BigDecimal specialMoney = BigDecimal.ZERO;
        for (AppGoodsRequest goodsRequest : appGoodsList) {
            // 商品规格-提成额
            GoodsStandard goodsStandard = goodsStandardService.selectById(goodsRequest.getGoodsStandardId());
            // 扣点设置类目
            DeptGoodsCategory deptGoodsCategory = deptGoodsCategoryService.get(goodsStandard.getDeptGoodsCategoryId());
            for (int index = 0; index < goodsRequest.getNum(); index++) {
                // 一级分销 = 商品单价 * 扣点比例
                oneMoney = oneMoney
                        .add(goodsStandard.getGoodsPrice().multiply(BigDecimal.valueOf(Double.parseDouble(deptGoodsCategory.getOneRate()))));
                // 二级分销 = 商品单价 * 扣点比例
                twoMoney = twoMoney.add(goodsStandard.getGoodsPrice().multiply(BigDecimal.valueOf(Double.parseDouble(deptGoodsCategory.getTwoRate()))));
                // 三级分销 = 提成额 + 商品单价 * 扣点比例
                threeMoney = threeMoney.add(goodsStandard.getExtMoney())
                        .add(goodsStandard.getGoodsPrice().multiply(BigDecimal.valueOf(Double.parseDouble(deptGoodsCategory.getThreeRate()))));
                // 平台扣点 = 平台金额 + 商品单价 * 扣点比例
                deptMoney = deptMoney.add(deptGoodsCategory.getDeptMoney())
                        .add(goodsStandard.getGoodsPrice().multiply(BigDecimal.valueOf(Double.parseDouble(deptGoodsCategory.getDeptRate()))));
                // 截流扣点 = 截流金额 + 商品单价 * 扣点比例
                specialMoney = specialMoney.add(deptGoodsCategory.getRetainMoney())
                        .add(goodsStandard.getGoodsPrice().multiply(BigDecimal.valueOf(Double.parseDouble(deptGoodsCategory.getRetainRate()))));
            }
        }
        // 平台扣点记录
        FinancialDetail deptDetail = new FinancialDetail(deptId, financialDetailService.createCode(),
                financialMaster.getId(), financialMaster.getCode(), deptMoney, FinancialDetailType.PLATFORM_FEE.getCode(), null);
        financialDetailService.insertFinancialDetail(deptDetail);

        // 剩余服务金额
        serverMoney = serverMoney.subtract(deptMoney);

        // 截流扣点记录
        FinancialDetail retainDetail = new FinancialDetail(deptId, financialDetailService.createCode(),
                financialMaster.getId(), financialMaster.getCode(), specialMoney, FinancialDetailType.PLATFORM_FEE.getCode(), null);
        financialDetailService.insertFinancialDetail(retainDetail);

        // 剩余服务金额
        serverMoney = serverMoney.subtract(specialMoney);

        // 分销扣点记录
        Long customerPlaceId = customer.getCustomerPlace();
        // 一级分销
        if (customerPlaceId != null) {
            FinancialDetail financialDetail = new FinancialDetail(deptId, financialDetailService.createCode(),
                    financialMaster.getId(), financialMaster.getCode(), threeMoney, FinancialDetailType.PLACE_FEE.getCode(), customerPlaceId);
            financialDetailService.insertFinancialDetail(financialDetail);

            // 剩余服务金额
            serverMoney = serverMoney.subtract(threeMoney);
        } else {
            oneMoney = oneMoney.add(threeMoney);
        }

        // 二级分销
        Long parentCustomerPlaceId = customer.getParentCustomerPlace();
        if (parentCustomerPlaceId != null) {
            FinancialDetail financialDetail = new FinancialDetail(deptId, financialDetailService.createCode(),
                    financialMaster.getId(), financialMaster.getCode(), twoMoney, FinancialDetailType.PLACE_FEE.getCode(), parentCustomerPlaceId);
            financialDetailService.insertFinancialDetail(financialDetail);

            // 剩余服务金额
            serverMoney = serverMoney.subtract(twoMoney);
        } else {
            oneMoney = oneMoney.add(twoMoney);
        }

        // 平台分销
        FinancialDetail financialDetail = new FinancialDetail(deptId, financialDetailService.createCode(),
                financialMaster.getId(), financialMaster.getCode(), oneMoney, FinancialDetailType.PLACE_FEE.getCode(), null);
        financialDetailService.insertFinancialDetail(financialDetail);

        // 剩余服务金额
        serverMoney = serverMoney.subtract(oneMoney);

        financialMaster.setServerMoney(serverMoney);
        financialMasterService.updateFinancialMaster(financialMaster);
    }

    /**
     * 生成财务子单
     *
     * @param deptGoodsCategoryId 商品类目id
     * @param deptId              商户ID
     * @param customer            消费者
     * @param payMoney            实付金额
     * @param financialMaster     财务主单
     */
    private void createFinancialDetail(Long deptGoodsCategoryId, Long deptId, Customer customer, BigDecimal payMoney, FinancialMaster financialMaster) {
        // 是否为0元购 是的话下面就不用多级分销了
        if (BigDecimal.ZERO.compareTo(payMoney) == 0) {
            return;
        }

        /* 1 平台服务服务费 */
        DeptGoodsCategory deptGoodsCategory = deptGoodsCategoryService.get(deptGoodsCategoryId);
        BigDecimal deptRate = new BigDecimal(deptGoodsCategory.getDeptRate());
        BigDecimal deptMoney = deptGoodsCategory.getDeptMoney();

        BigDecimal deptTotal = payMoney.multiply(deptRate).add(deptMoney);

        FinancialDetail deptDetail = new FinancialDetail(deptId, financialDetailService.createCode(),
                financialMaster.getId(), financialMaster.getCode(), deptTotal, FinancialDetailType.PLATFORM_FEE.getCode(), null);
        financialDetailService.insertFinancialDetail(deptDetail);

        /* 2 截留扣点 */
        BigDecimal retainRate = new BigDecimal(deptGoodsCategory.getRetainRate());
        BigDecimal retainMoney = deptGoodsCategory.getRetainMoney();

        BigDecimal retainTotal = payMoney.multiply(retainRate).add(retainMoney);

        FinancialDetail retainDetail = new FinancialDetail(deptId, financialDetailService.createCode(),
                financialMaster.getId(), financialMaster.getCode(), retainTotal, FinancialDetailType.PLATFORM_FEE.getCode(), null);
        financialDetailService.insertFinancialDetail(retainDetail);

        /* 3 分销扣点 */
        BigDecimal deptPlaceTotal = BigDecimal.ZERO;

        Long customerPlaceId = customer.getCustomerPlace();
        BigDecimal onePlaceMoney = payMoney.multiply(new BigDecimal(deptGoodsCategory.getOneRate()));
        BigDecimal twoPlaceMoney = payMoney.multiply(new BigDecimal(deptGoodsCategory.getTwoRate()));
        BigDecimal threePlaceMoney = payMoney.multiply(new BigDecimal(deptGoodsCategory.getThreeRate()));

        // 一级分销
        if (customerPlaceId != null) {
            FinancialDetail financialDetail = new FinancialDetail(deptId, financialDetailService.createCode(),
                    financialMaster.getId(), financialMaster.getCode(), onePlaceMoney, FinancialDetailType.PLACE_FEE.getCode(), customerPlaceId);
            financialDetailService.insertFinancialDetail(financialDetail);
        } else {
            deptPlaceTotal = deptPlaceTotal.add(onePlaceMoney);
        }

        // 二级分销
        Long parentCustomerPlaceId = customer.getParentCustomerPlace();
        if (parentCustomerPlaceId != null) {
            FinancialDetail financialDetail = new FinancialDetail(deptId, financialDetailService.createCode(),
                    financialMaster.getId(), financialMaster.getCode(), twoPlaceMoney, FinancialDetailType.PLACE_FEE.getCode(), parentCustomerPlaceId);
            financialDetailService.insertFinancialDetail(financialDetail);
        } else {
            deptPlaceTotal = deptPlaceTotal.add(twoPlaceMoney);
        }

        // 平台分销
        deptPlaceTotal = deptPlaceTotal.add(threePlaceMoney);
        FinancialDetail financialDetail = new FinancialDetail(deptId, financialDetailService.createCode(),
                financialMaster.getId(), financialMaster.getCode(), deptPlaceTotal, FinancialDetailType.PLACE_FEE.getCode(), null);
        financialDetailService.insertFinancialDetail(financialDetail);

        // 更新订单服务金额
        financialMaster.setServerMoney(financialMaster.getServerMoney().subtract(deptTotal)
                .subtract(retainTotal).subtract(deptPlaceTotal));
        financialMasterService.updateFinancialMaster(financialMaster);
    }

    /**
     * 订单统计
     */
    @PostMapping("/app/statistics")
    @ResponseBody
    public AjaxResult orderStatistics(@RequestBody OrderStatisticsRequest request) {
        OrderStatisticsResponse response = new OrderStatisticsResponse();

        try {
            OrderMaster orderMaster = new OrderMaster();
            orderMaster.setOrderStatus(OrderStatus.RECEIVE.code());
            orderMaster.setWorkerId(request.getWorkerId());
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setOrderStatus(OrderStatus.RECEIVE.code());
            orderDetail.setWorkerId(request.getWorkerId());
            orderDetail.setShelveStatus(0);
            Long newMasterOrderCount = orderMasterService.countOrderMasterList(orderMaster);
            Long newDetailOrderCount = orderDetailService.countOrderDetailList(orderDetail);
            // 统计新订单的单量
            response.setNewOrderNum(newMasterOrderCount + newDetailOrderCount);
            // 统计未排的单量
            orderMaster.setOrderStatus(OrderStatus.PLAIN.code());
            // 如果查询的是未约未排状态，只查询未全部派完的主单
            orderMaster.setHasDispatchedAll(0);
            orderDetail.setOrderStatus(OrderStatus.PLAIN.code());
            Long planMasterOrderCount = orderMasterService.countOrderMasterList(orderMaster);
            Long planDetailOrderCount = orderDetailService.countOrderDetailList(orderDetail);
            response.setPlanOrderNum(planMasterOrderCount + planDetailOrderCount);
            orderMaster.setHasDispatchedAll(null);
            // 统计待上门单量
            orderDetail.setOrderStatus(OrderStatus.GOING.code());
            response.setWaitServOrderNum(orderDetailService.countOrderDetailList(orderDetail));
            // 统计服务中单量
            orderDetail.setOrderStatus(OrderStatus.SERVER.code());
            response.setServingOrderNum(orderDetailService.countOrderDetailList(orderDetail));
            // 统计待确认单量
            orderDetail.setOrderStatus(null);
            orderDetail.setOrderStatusList(new ArrayList<Integer>() {{
                add(4);
                add(5);
            }});
            orderDetail.setWorkFinishTimeExisted(true);
            orderDetail.setDrawCashStatusList(new ArrayList<Integer>() {{
                add(0);
                add(1);
            }});
            response.setWaitSureOrderNum(orderDetailService.countOrderDetailList(orderDetail));
            orderDetail.setOrderStatusList(null);
            // 统计已完成子单量
            orderDetail.setOrderStatus(OrderStatus.FINISH.code());
            orderDetail.setDrawCashStatusList(new ArrayList<Integer>() {{
                add(2);
            }});
            response.setFinishedOrderNum(orderDetailService.countOrderDetailList(orderDetail));
            orderDetail.setWorkFinishTimeExisted(false);
            orderDetail.setDrawCashStatusList(null);
            // 统计已完成主单量
            orderMaster.setOrderStatus(OrderStatus.FINISH.code());
            response.setFinishedMasterOrderNum(orderMasterService.countOrderMasterList(orderMaster));
            // 统计监控单量
            orderMaster.setOrderStatus(null);
            orderMaster.setIsMonitoredOrder(true);
            response.setMonitoredOrderNum(orderMasterService.countOrderMasterList(orderMaster));
            orderMaster.setIsMonitoredOrder(false);
            // 统计搁置单量
            OrderDetail orderDetail1 = new OrderDetail();
            orderDetail1.setWorkerId(request.getWorkerId());
            orderDetail1.setShelveStatus(1);
            response.setShelvedOrderNum(orderDetailService.countOrderDetailList(orderDetail1));
            // 统计售后中单量
            OrderListRequest orderListRequest = new OrderListRequest();
            orderListRequest.setWorkerId(request.getWorkerId());
            orderListRequest.setIsMonitoredOrder(true);
            orderListRequest.setAllSelfAssigned(0);
            AjaxResult afterListRes = this.appMixAfterList(orderListRequest);
            List<AfterServiceRecord> afterList = (List<AfterServiceRecord>) afterListRes.get("data");
            response.setAfterListNum(afterList.size());
            // 统计超时单量
            orderListRequest = new OrderListRequest();
            orderListRequest.setIsOverTime(true);
            orderListRequest.setWorkerId(request.getWorkerId());
            orderListRequest.setIsMonitoredOrder(true);
            orderListRequest.setAllSelfAssigned(0);
            AjaxResult overTimeRes = this.appMixOrderList(orderListRequest);
            List<OrderListResponse> overTimeList = (List) overTimeRes.get("data");
            response.setOverTimeOrderNum(overTimeList.size());
            // 统计今日单量
            LocalDateTime today = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
            orderDetail.setOrderStatus(OrderStatus.GOING.code());
            orderDetail.setExpectTimeStart(Date.from(today.atZone(ZoneId.systemDefault()).toInstant()));
            today = LocalDateTime.of(LocalDate.now(), LocalTime.MAX);
            orderDetail.setExpectTimeEnd(Date.from(today.atZone(ZoneId.systemDefault()).toInstant()));
            response.setTodayOrderNum(orderDetailService.countOrderDetailList(orderDetail));
            // 统计明日单量
            LocalDateTime tomorrow = LocalDateTime.of(LocalDate.now().plusDays(1), LocalTime.MIN);
            orderDetail.setOrderStatus(OrderStatus.GOING.code());
            orderDetail.setExpectTimeStart(Date.from(tomorrow.atZone(ZoneId.systemDefault()).toInstant()));
            tomorrow = LocalDateTime.of(LocalDate.now().plusDays(1), LocalTime.MAX);
            orderDetail.setExpectTimeEnd(Date.from(tomorrow.atZone(ZoneId.systemDefault()).toInstant()));
            response.setTomorrowOrderNum(orderDetailService.countOrderDetailList(orderDetail));
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(ExceptionUtils.getStackTrace(e));
            return AjaxResult.error(e.getMessage());
        }

        return AjaxResult.success(response);
    }

    /**
     * 查询主单子单的混合列表，根据预约时间倒序排列，请求参数中的师傅id不能为空
     */
    @PostMapping("/app/mix/order/list")
    @ResponseBody
    public AjaxResult appMixOrderList(@RequestBody OrderListRequest orderListRequest) {
        List<OrderListResponse> orderListResponses = new ArrayList<>();

        // 校验参数
        Assert.notNull(orderListRequest.getWorkerId(), "师傅id不能为空");

        // 查询子单
        OrderDetail orderDetailReq = new OrderDetail();
        BeanUtils.copyProperties(orderListRequest, orderDetailReq);
        List<OrderListResponse> detailList = this.getDetailList(orderDetailReq);
        orderListResponses.addAll(detailList);

        // 查询主单
        OrderMaster orderMasterReq = new OrderMaster();
        BeanUtils.copyProperties(orderListRequest, orderMasterReq);
        List<OrderListResponse> masterList = this.getMasterList(orderMasterReq);
        // 超时查询需要排除同个师傅的主单子单同时出现
        if (orderListRequest.getIsOverTime() != null && orderListRequest.getIsOverTime()) {
            // 需要排除同个师傅的主单子单同时出现
            List<OrderListResponse> filteredMasterList = new ArrayList<OrderListResponse>();
            for (OrderListResponse master : masterList) {
                boolean isKeep = false;
                // 查询该主单下所有售后中的子单
                OrderDetail detailAfterListOfMasterQry = new OrderDetail();
                detailAfterListOfMasterQry.setOrderMasterCode(master.getOrderMasterCode());
                List<OrderListResponse> detailListOfMasters = this.getDetailList(detailAfterListOfMasterQry);
                for (OrderListResponse detailListOfMaster : detailListOfMasters) {
                    if (!detailListOfMaster.getWorkerId().equals(orderListRequest.getWorkerId())) {
                        isKeep = true;
                        break;
                    }
                }
                if (isKeep) {
                    filteredMasterList.add(master);
                }
            }
            orderListResponses.addAll(filteredMasterList);
        } else {
            orderListResponses.addAll(masterList);
        }

        // 根据预约时间倒序排列
        Collections.sort(orderListResponses, new Comparator<OrderListResponse>() {
            @Override
            public int compare(OrderListResponse o1, OrderListResponse o2) {
                return o1.getExpectTimeStart().compareTo(o2.getExpectTimeStart());
            }
        });

        return AjaxResult.success(orderListResponses);
    }

    @PostMapping("/app/mix/after/list")
    @ResponseBody
    public AjaxResult appMixAfterList(@RequestBody OrderListRequest orderListRequest) {
        List<OrderListResponse> orderListResponses = new ArrayList<>();

        // 校验参数
        Assert.notNull(orderListRequest.getWorkerId(), "师傅id不能为空");

        // 查询子单
        OrderDetail orderDetailReq = new OrderDetail();
        BeanUtils.copyProperties(orderListRequest, orderDetailReq);
        List<OrderListResponse> detailList = this.getDetailAfterList(orderDetailReq);
        orderListResponses.addAll(detailList);

        // 查询主单
        OrderMaster orderMasterReq = new OrderMaster();
        BeanUtils.copyProperties(orderListRequest, orderMasterReq);
        List<OrderListResponse> masterList = this.getMasterAfterList(orderMasterReq);
        // 需要排除同个师傅的主单子单同时出现
        List<OrderListResponse> filteredMasterList = new ArrayList<OrderListResponse>();
        for (OrderListResponse master : masterList) {
            boolean isKeep = false;
            // 查询该主单下所有售后中的子单
            OrderDetail detailAfterListOfMasterQry = new OrderDetail();
            detailAfterListOfMasterQry.setOrderMasterCode(master.getOrderMasterCode());
            List<OrderListResponse> detailAfterListOfMasters = this.getDetailAfterList(detailAfterListOfMasterQry);
            for (OrderListResponse detailAfterListOfMaster : detailAfterListOfMasters) {
                if (!detailAfterListOfMaster.getWorkerId().equals(orderListRequest.getWorkerId())) {
                    isKeep = true;
                    break;
                }
            }
            if (isKeep) {
                filteredMasterList.add(master);
            }
        }
        orderListResponses.addAll(filteredMasterList);

        // 根据预约时间倒序排列
        Collections.sort(orderListResponses, new Comparator<OrderListResponse>() {
            @Override
            public int compare(OrderListResponse o1, OrderListResponse o2) {
                return o1.getExpectTimeStart().compareTo(o2.getExpectTimeStart());
            }
        });

        return AjaxResult.success(orderListResponses);
    }

    public List<OrderListResponse> getMasterAfterList(OrderMaster orderMaster) {

        // 查所有售后的单
        AfterServiceRecord afterServiceRecord = new AfterServiceRecord();
        afterServiceRecord.setExcludeAfterServiceFinished(Boolean.TRUE);
        List<AfterServiceRecord> afterServiceRecordList = afterServiceRecordService.selectAfterServiceRecordList(afterServiceRecord);
        // 踢重后的子单ids
        List<Long> detailIds = afterServiceRecordList.stream().map(AfterServiceRecord::getOrderDetailId).distinct().collect(Collectors.toList());
        StringBuilder orderDetailIds = new StringBuilder();
        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setCustomerId(orderMaster.getCustomerId());
        orderDetail.setDeptId(orderMaster.getDeptId());
        detailIds.forEach(id -> {
            orderDetailIds.append(id).append(",");
        });
        String ids = orderDetailIds.toString();
        if (StringUtils.isNotEmpty(ids)) {
            orderDetail.setOrderDetailIds(ids.substring(0, ids.length() - 1));
        } else {
            orderDetail.setOrderDetailIds("0");
        }
        // 所有售后的子单
        List<OrderDetail> orderDetailList = orderDetailService.selectOrderDetailList(orderDetail);
        StringBuilder orderMasterIds = new StringBuilder();
        orderDetailList.stream().map(OrderDetail::getOrderMasterId).distinct()
                .collect(Collectors.toList()).forEach(id -> {
                    orderMasterIds.append(id).append(",");
                });
        String orderIds = orderMasterIds.toString();
        if (StringUtils.isNotEmpty(orderIds)) {
            orderMaster.setOrderMasterIds(orderIds.substring(0, orderIds.length() - 1));
        } else {
            orderMaster.setOrderMasterIds("0");
        }

        List<OrderListResponse> orderListResponses = new ArrayList<>();
        List<OrderMaster> list = orderMasterService.selectOrderMasterList(orderMaster);
        list.forEach(master -> {
            //子单
            List<OrderDetail> detailList = orderDetailService.selectByOrderMasterId(master.getId());

            // 初始化属性
            OrderListResponse orderListResponse = new OrderListResponse();
            List<OrderStandard> standardList = new ArrayList<>();

            // 师傅信息
            Worker worker = master.getWorkerId() != null ? workerService.selectById(master.getWorkerId()) : null;

            // 消费者信息
//            Customer customer = customerService.selectByCustomerId(master.getCustomerId());

            // 商品规格及信息
            List<OrderGoods> orderStandardList = orderGoodsService.selectByOrderMasterId(master.getId());

            // 商品信息
            GoodsStandard goodsStandard = goodsStandardService.selectById(orderStandardList.get(0).getGoodsStandardId());

            Goods goods = goodsService.selectById(goodsStandard.getGoodsId());

            // 财务信息
            FinancialMaster financialMaster = financialMasterService.selectByOrderMasterId(master.getId());
            BigDecimal totalPayMoney = financialMaster.getPayMoney();
//            BigDecimal totalChangeMoney = new BigDecimal(0);
//            for (OrderDetail detail: detailList) {
//                // 查询子单加价记录
//                FinancialChangeRecord changeRecordQry = new FinancialChangeRecord();
//                changeRecordQry.setOrderDetailId(detail.getId());
//                List<FinancialChangeRecord> financialChangeRecords = financialChangeRecordService.selectFinancialChangeRecordList(changeRecordQry);
//                if (CollectionUtils.isNotEmpty(financialChangeRecords)) {
//                    totalChangeMoney = totalChangeMoney.add(financialChangeRecords.get(0).getChangeMoney());
//                }
//            }
//            totalPayMoney = totalPayMoney.add(totalChangeMoney);

            // 地址信息
            CustomerAddress customerAddress = addressService.selectByCustomerAddressId(master.getAddressId());
            SysArea sysArea = sysAreaService.selectById(customerAddress.getCountryId());
            String completeAddress = sysArea.getMergerName().replaceAll(",", "") + customerAddress.getAddress();

            // 查询是否超时
            List<OrderTimeoutRecord> timeoutRecords = new ArrayList<>();
            // 查询售后记录
            List<AfterServiceRecord> afterServiceRecords = new ArrayList<>();
            List<OrderDetail> detailOrderList = orderDetailService.selectByOrderMasterId(master.getId());
            detailOrderList.stream().forEach(detail -> {
                OrderTimeoutRecord timeoutRecord = orderFineRecordService.selectByDetailIdAndStatus(detail.getId(), detail.getOrderStatus());
                if (timeoutRecord != null) {
                    timeoutRecords.add(timeoutRecord);
                }

                AfterServiceRecord afterServiceRecordQry = new AfterServiceRecord();
                afterServiceRecordQry.setOrderDetailId(detail.getId());
                List<AfterServiceRecord> records = afterServiceRecordService.selectAfterServiceRecordList(afterServiceRecordQry);
                afterServiceRecords.addAll(records);
            });

            for (OrderGoods orderGoods : orderStandardList) {
                OrderStandard orderStandard = new OrderStandard();
                orderStandard.setStandardName(orderGoods.getGoodsName());
                orderStandard.setStandardNum(orderGoods.getGoodsNum());
                standardList.add(orderStandard);
            }

            // 编辑返回属性
            orderListResponse.setOrderMasterId(master.getId());
            orderListResponse.setGoodsName(goods.getGoodsName());
            orderListResponse.setGoodsLogoUrl(goods.getGoodsImgUrl());
            orderListResponse.setDiscountMoney(financialMaster.getDiscountMoney());
            orderListResponse.setTotalMoney(financialMaster.getTotalMoney());
            orderListResponse.setPayMoney(totalPayMoney);
//            orderListResponse.setChangeMoney(totalChangeMoney);
            orderListResponse.setWorkerName(worker == null ? "" : worker.getName());
            orderListResponse.setWorkerPhone(worker == null ? "" : worker.getPhone());
            orderListResponse.setCustomerName(customerAddress.getName());
            orderListResponse.setCustomerPhone(customerAddress.getPhone());
            orderListResponse.setServerTime(master.getRevTime());
            orderListResponse.setExpectTimeStart(master.getExpectTimeStart());
            orderListResponse.setExpectTimeEnd(master.getExpectTimeEnd());
            orderListResponse.setExpectTimeStartFront(master.getExpectTimeStart());
            orderListResponse.setExpectTimeEndFront(master.getExpectTimeEnd());
            orderListResponse.setOrderStatus(master.getOrderStatus());
            orderListResponse.setPayStatus(master.getPayStatus());
            orderListResponse.setPayType(master.getPayType());
            orderListResponse.setOrderMasterCode(master.getCode());
            orderListResponse.setStandardList(standardList);
            orderListResponse.setAddress(completeAddress);
            orderListResponse.setRemark(goods.getRemark());
            orderListResponse.setCustomerRemark(master.getRemark());
            orderListResponse.setOrderTimeoutRecords(timeoutRecords);
            orderListResponse.setAfterServiceRecordList(afterServiceRecords);
            orderListResponses.add(orderListResponse);

        });
        return orderListResponses;
    }

    public List<OrderListResponse> getDetailAfterList(OrderDetail orderDetail) {
        AfterServiceRecord afterServiceRecord = new AfterServiceRecord();
        afterServiceRecord.setExcludeAfterServiceFinished(Boolean.TRUE);
        List<AfterServiceRecord> afterServiceRecordList = afterServiceRecordService.selectAfterServiceRecordList(afterServiceRecord);
        Map<Long, List<AfterServiceRecord>> detailRecordMap = afterServiceRecordList.stream().collect(Collectors.groupingBy(record -> record.getOrderDetailId()));
        // 踢重后的子单ids
        List<Long> detailIds = afterServiceRecordList.stream().map(AfterServiceRecord::getOrderDetailId).distinct().collect(Collectors.toList());
        StringBuilder orderDetailIds = new StringBuilder();
        detailIds.forEach(id -> {
            orderDetailIds.append(id).append(",");
        });
        String ids = orderDetailIds.toString();
        if (StringUtils.isNotEmpty(ids)) {
            orderDetail.setOrderDetailIds(ids.substring(0, ids.length() - 1));
        } else {
            orderDetail.setOrderDetailIds("0");
        }
        List<OrderListResponse> orderListResponses = new ArrayList<>();
        List<OrderDetail> list = orderDetailService.selectOrderDetailList(orderDetail);
        list.forEach(detail -> {

            // 主单信息
            OrderMaster orderMaster = orderMasterService.selectById(detail.getOrderMasterId());
            // 初始化属性
            OrderListResponse orderListResponse = new OrderListResponse();
            List<OrderStandard> standardList = new ArrayList<>();

            // 师傅信息
            Worker worker = workerService.selectById(detail.getWorkerId());
            WorkerCertification workerRealInfo = null;
            String workerName = "";
            if (worker != null) {
                // 师傅实名信息
                workerRealInfo = workerCertificationService.selectByWorkerId(orderMaster.getWorkerId());
                workerName = workerRealInfo == null ? worker.getName() : workerRealInfo.getName();
            }

            // 消费者信息
//            Customer customer = customerService.selectByCustomerId(detail.getCustomerId());

            // 商品规格及信息
            List<OrderGoods> orderStandardList = orderGoodsService.selectByOrderDetailId(detail.getId());

            // 商品信息
            GoodsStandard goodsStandard = goodsStandardService.selectById(orderStandardList.get(0).getGoodsStandardId());

            Goods goods = goodsService.selectById(goodsStandard.getGoodsId());

            // 财务信息
            FinancialDetail financialDetail = financialDetailService.selectByOrderDetailId(detail.getId());
            BigDecimal detailPayMoney = financialDetail.getPayMoney();

            // 查询子单加价记录
            FinancialChangeRecord financialChangeRecord = financialChangeRecordService.selectNotPayRecordByDetailId(detail.getId());
            BigDecimal changeMoney = financialChangeRecord == null ? BigDecimal.ZERO : financialChangeRecord.getChangeMoney();

            // 地址信息
            CustomerAddress customerAddress = addressService.selectByCustomerAddressId(orderMaster.getAddressId());
            SysArea sysArea = sysAreaService.selectById(customerAddress.getCountryId());
            String completeAddress = sysArea.getMergerName().replaceAll(",", "") + customerAddress.getAddress();

            for (OrderGoods orderGoods : orderStandardList) {
                OrderStandard orderStandard = new OrderStandard();
                orderStandard.setStandardName(orderGoods.getGoodsName());
                orderStandard.setStandardNum(orderGoods.getGoodsNum());
                orderStandard.setServerNum(orderGoods.getServerGoodsNum());
                orderStandard.setFinishTime(orderGoods.getFinishTime());
                orderStandard.setWaitServerNum(orderGoods.getGoodsNum() - orderGoods.getServerGoodsNum());
                standardList.add(orderStandard);
            }

            // 查询是否超时
            OrderTimeoutRecord orderTimeoutRecord = orderFineRecordService.selectByDetailIdAndStatus(detail.getId(), detail.getOrderStatus());
            Boolean isOverTime = orderTimeoutRecord != null;

            if (this.checkIsOnlyServer(orderMaster.getId(), detail.getWorkerId())) {
                FinancialMaster financialMaster = financialMasterService.selectByOrderMasterId(detail.getOrderMasterId());
                BigDecimal workerFee = financialMaster.getPayMoney();
                List<FinancialDetail> financialDetailList = financialDetailService.selectByFinancialMasterId(financialMaster.getId());
                for (FinancialDetail param : financialDetailList) {
                    if (!detail.getWorkerId().equals(param.getPayeeId())) {
                        workerFee = workerFee.subtract(param.getPayMoney());
                    }
                }
                orderListResponse.setPayMoney(workerFee);
                orderListResponse.setIsOnlyServ(Boolean.TRUE);
            } else {
                orderListResponse.setPayMoney(detailPayMoney);
                orderListResponse.setIsOnlyServ(Boolean.FALSE);
            }


            // 编辑返回属性
            orderListResponse.setOrderDetailId(detail.getId());
            orderListResponse.setOrderDetailCode(detail.getCode());
            orderListResponse.setOrderMasterId(detail.getOrderMasterId());
            orderListResponse.setOrderMasterCode(detail.getOrderMasterCode());
            orderListResponse.setGoodsName(goods.getGoodsName());
            orderListResponse.setGoodsLogoUrl(goods.getGoodsImgUrl());
            orderListResponse.setDiscountMoney(financialDetail.getDiscountMoney());
            orderListResponse.setTotalMoney(financialDetail.getTotalMoney());
            orderListResponse.setWorkerId(detail.getWorkerId());
            orderListResponse.setWorkerName(workerName);
            orderListResponse.setWorkerPhone(worker == null ? "" : worker.getPhone());
            orderListResponse.setCustomerName(customerAddress.getName());
            orderListResponse.setCustomerPhone(customerAddress.getPhone());
            orderListResponse.setOrderStatus(detail.getOrderStatus());
            orderListResponse.setPayStatus(orderMaster.getPayStatus());
            orderListResponse.setPayType(orderMaster.getPayType());
            orderListResponse.setStandardList(standardList);
            orderListResponse.setAddress(completeAddress);
            orderListResponse.setServerTime(detail.getRevTime());
            orderListResponse.setExpectTimeStart(detail.getExpectTimeStart());
            orderListResponse.setExpectTimeEnd(detail.getExpectTimeEnd());
            orderListResponse.setExpectTimeStartFront(detail.getExpectTimeStart());
            orderListResponse.setExpectTimeEndFront(detail.getExpectTimeEnd());
            orderListResponse.setWorkBeginTime(detail.getWorkBeginTime());
            orderListResponse.setWorkFinishTime(detail.getWorkFinishTime());
            orderListResponse.setRemark(goods.getRemark());
            orderListResponse.setCustomerRemark(orderMaster.getRemark());
            orderListResponse.setOrderType(detail.getOrderType());
            orderListResponse.setIsOverTime(isOverTime);
            orderListResponse.setAfterServiceRecordList(detailRecordMap.get(detail.getId()));
            orderListResponse.setChangeMoney(changeMoney);
            orderListResponses.add(orderListResponse);
        });
        return orderListResponses;
    }

    public List<OrderListResponse> getMasterList(OrderMaster orderMaster) {
        List<OrderListResponse> orderListResponses = new ArrayList<>();
        // 如果查询的是未约未排状态，只查询未全部派完的主单
        if (orderMaster.getOrderStatus() != null && OrderStatus.PLAIN.code() == orderMaster.getOrderStatus()) {
            orderMaster.setHasDispatchedAll(0);
        }
        List<OrderMaster> list = orderMasterService.selectOrderMasterList(orderMaster);
        for (OrderMaster master : list) {// 初始化属性
            OrderListResponse orderListResponse = new OrderListResponse();
            List<OrderStandard> standardList = new ArrayList<>();
            // 查询所有子单
            List<OrderDetail> orderDetails = orderDetailService.selectByOrderMasterId(master.getId());
            List<Long> orderDetailIds = orderDetails.stream().map(OrderDetail::getId).collect(Collectors.toList());

            // 师傅信息
            Worker worker = master.getWorkerId() != null ? workerService.selectById(master.getWorkerId()) : null;

            // 消费者信息
//            Customer customer = customerService.selectByCustomerId(master.getCustomerId());

            // 商品规格及信息
            List<OrderGoods> orderStandardList = orderGoodsService.selectByOrderMasterId(master.getId());

            // 商品信息
            GoodsStandard goodsStandard = goodsStandardService.selectById(orderStandardList.get(0).getGoodsStandardId());

            Goods goods = goodsService.selectById(goodsStandard.getGoodsId());

            // 财务信息
            FinancialMaster financialMaster = financialMasterService.selectByOrderMasterId(master.getId());

            // 查询加价价格
            BigDecimal changeMoney = BigDecimal.ZERO;
            List<FinancialChangeRecord> changeRecords = financialChangeRecordService.selectByDetailIds(StringUtils.join(orderDetailIds, ","));
            for (FinancialChangeRecord changeRecord : changeRecords) {
                if (PayStatus.WAIT_PAY.getCode().equals(changeRecord.getPayStatus())) {
                    changeMoney = changeMoney.add(changeRecord.getChangeMoney());
                }
            }

            // 地址信息
            CustomerAddress customerAddress = addressService.selectByCustomerAddressId(master.getAddressId());
            SysArea sysArea = sysAreaService.selectById(customerAddress.getCountryId());
            String completeAddress = sysArea.getMergerName().replaceAll(",", "") + customerAddress.getAddress();

            // 查询是否超时
            List<OrderTimeoutRecord> timeoutRecords = new ArrayList<>();
            // 查询售后记录
            List<AfterServiceRecord> afterServiceRecords = new ArrayList<>();
            List<OrderDetail> detailOrderList = orderDetailService.selectByOrderMasterId(master.getId());
            detailOrderList.stream().forEach(detail -> {
                OrderTimeoutRecord timeoutRecord = orderFineRecordService.selectByDetailIdAndStatus(detail.getId(), detail.getOrderStatus());
                if (timeoutRecord != null) {
                    timeoutRecords.add(timeoutRecord);
                }

                AfterServiceRecord afterServiceRecordQry = new AfterServiceRecord();
                afterServiceRecordQry.setOrderDetailId(detail.getId());
                List<AfterServiceRecord> records = afterServiceRecordService.selectAfterServiceRecordList(afterServiceRecordQry);
                afterServiceRecords.addAll(records);
            });
            if (Boolean.TRUE.equals(orderMaster.getIsOverTime()) && timeoutRecords.size() == 0) {
                continue;
            }

            for (OrderGoods orderGoods : orderStandardList) {
                OrderStandard orderStandard = new OrderStandard();
                orderStandard.setStandardName(orderGoods.getGoodsName());
                orderStandard.setStandardNum(orderGoods.getGoodsNum());
                standardList.add(orderStandard);
            }

            // 编辑返回属性
            orderListResponse.setOrderMasterId(master.getId());
            orderListResponse.setGoodsName(goods.getGoodsName());
            orderListResponse.setGoodsLogoUrl(goods.getGoodsImgUrl());
            orderListResponse.setDiscountMoney(financialMaster.getDiscountMoney());
            orderListResponse.setTotalMoney(financialMaster.getTotalMoney());
            orderListResponse.setPayMoney(financialMaster.getPayMoney());
            orderListResponse.setWorkerName(worker == null ? "" : worker.getName());
            orderListResponse.setWorkerPhone(worker == null ? "" : worker.getPhone());
            orderListResponse.setCustomerName(customerAddress.getName());
            orderListResponse.setCustomerPhone(customerAddress.getPhone());
            orderListResponse.setServerTime(master.getRevTime());
            orderListResponse.setExpectTimeStart(master.getExpectTimeStart());
            orderListResponse.setExpectTimeEnd(master.getExpectTimeEnd());
            orderListResponse.setExpectTimeStartFront(master.getExpectTimeStart());
            orderListResponse.setExpectTimeEndFront(master.getExpectTimeEnd());
            orderListResponse.setOrderStatus(master.getOrderStatus());
            orderListResponse.setPayStatus(master.getPayStatus());
            orderListResponse.setPayType(master.getPayType());
            orderListResponse.setOrderMasterCode(master.getCode());
            orderListResponse.setStandardList(standardList);
            orderListResponse.setAddress(completeAddress);
            orderListResponse.setRemark(goods.getRemark());
            orderListResponse.setCustomerRemark(master.getRemark());
            orderListResponse.setOrderTimeoutRecords(timeoutRecords);
            orderListResponse.setChangeMoney(changeMoney);
            orderListResponse.setServerMoney(financialMaster.getServerMoney());
            orderListResponse.setAfterServiceRecordList(afterServiceRecords);
            orderListResponses.add(orderListResponse);

        }
        return orderListResponses;
    }

    public List<OrderListResponse> getDetailList(OrderDetail orderDetail) {
        List<OrderListResponse> orderListResponses = new ArrayList<>();
        List<OrderDetail> list = orderDetailService.selectOrderDetailList(orderDetail);
        for (OrderDetail detail : list) {// 主单信息
            OrderMaster orderMaster = orderMasterService.selectById(detail.getOrderMasterId());
            // 初始化属性
            OrderListResponse orderListResponse = new OrderListResponse();
            List<OrderStandard> standardList = new ArrayList<>();

            // 师傅信息
            Worker worker = workerService.selectById(detail.getWorkerId());

            // 消费者信息
//            Customer customer = customerService.selectByCustomerId(detail.getCustomerId());

            // 商品规格及信息
            List<OrderGoods> orderStandardList = orderGoodsService.selectByOrderDetailId(detail.getId());

            // 商品信息
            GoodsStandard goodsStandard = goodsStandardService.selectById(orderStandardList.get(0).getGoodsStandardId());

            Goods goods = goodsService.selectById(goodsStandard.getGoodsId());

            // 财务信息
            FinancialDetail financialDetail = financialDetailService.selectByOrderDetailId(detail.getId());

            // 查询子单加价记录
            FinancialChangeRecord financialChangeRecord = financialChangeRecordService.selectNotPayRecordByDetailId(detail.getId());
            BigDecimal changeMoney = financialChangeRecord == null ? BigDecimal.ZERO : financialChangeRecord.getChangeMoney();

            // 地址信息
            CustomerAddress customerAddress = addressService.selectByCustomerAddressId(orderMaster.getAddressId());
            SysArea sysArea = sysAreaService.selectById(customerAddress.getCountryId());
            String completeAddress = sysArea.getMergerName().replaceAll(",", "") + customerAddress.getAddress();

            for (OrderGoods orderGoods : orderStandardList) {
                OrderStandard orderStandard = new OrderStandard();
                orderStandard.setStandardName(orderGoods.getGoodsName());
                orderStandard.setStandardNum(orderGoods.getGoodsNum());
                orderStandard.setServerNum(orderGoods.getServerGoodsNum());
                orderStandard.setFinishTime(orderGoods.getFinishTime());
                orderStandard.setWaitServerNum(orderGoods.getGoodsNum() - orderGoods.getServerGoodsNum());
                standardList.add(orderStandard);
            }

            // 查询是否超时
            OrderTimeoutRecord orderTimeoutRecord = orderFineRecordService.selectByDetailIdAndStatus(detail.getId(), detail.getOrderStatus());
            Boolean isOverTime = orderTimeoutRecord != null;
            if (Boolean.TRUE.equals(orderDetail.getIsOverTime()) && !isOverTime) {
                continue;
            }

            // 售后记录
//            AfterServiceRecord afterServiceRecord = new AfterServiceRecord();
//            afterServiceRecord.setOrderDetailId(detail.getId());
//            List<AfterServiceRecord> afterServiceRecordList  =afterServiceRecordService.selectAfterServiceRecordList(afterServiceRecord);

            // 编辑返回属性
            orderListResponse.setOrderDetailId(detail.getId());
            orderListResponse.setOrderDetailCode(detail.getCode());
            orderListResponse.setOrderMasterId(detail.getOrderMasterId());
            orderListResponse.setOrderMasterCode(detail.getOrderMasterCode());
            orderListResponse.setGoodsName(goods.getGoodsName());
            orderListResponse.setGoodsLogoUrl(goods.getGoodsImgUrl());
            orderListResponse.setDiscountMoney(financialDetail.getDiscountMoney());
            orderListResponse.setTotalMoney(financialDetail.getTotalMoney());
            orderListResponse.setPayMoney(financialDetail.getPayMoney());
            orderListResponse.setWorkerName(worker.getName());
            orderListResponse.setWorkerPhone(worker.getPhone());
            orderListResponse.setWorkerId(detail.getWorkerId());
            orderListResponse.setCustomerName(customerAddress.getName());
            orderListResponse.setCustomerPhone(customerAddress.getPhone());
            orderListResponse.setOrderStatus(detail.getOrderStatus());
            orderListResponse.setPayStatus(orderMaster.getPayStatus());
            orderListResponse.setPayType(orderMaster.getPayType());
            orderListResponse.setStandardList(standardList);
            orderListResponse.setAddress(completeAddress);
            orderListResponse.setServerTime(detail.getRevTime());
            orderListResponse.setExpectTimeStart(detail.getExpectTimeStart());
            orderListResponse.setExpectTimeEnd(detail.getExpectTimeEnd());
            orderListResponse.setExpectTimeStartFront(detail.getExpectTimeStart());
            orderListResponse.setExpectTimeEndFront(detail.getExpectTimeEnd());
            orderListResponse.setWorkBeginTime(detail.getWorkBeginTime());
            orderListResponse.setWorkFinishTime(detail.getWorkFinishTime());
            orderListResponse.setClockInLocation(detail.getClockInLocation());
            orderListResponse.setRemark(goods.getRemark());
            orderListResponse.setCustomerRemark(orderMaster.getRemark());
            orderListResponse.setOrderType(detail.getOrderType());
            orderListResponse.setIsOverTime(isOverTime);
            orderListResponse.setChangeMoney(changeMoney);
//            orderListResponse.setAfterServiceRecordList(afterServiceRecordList);
            orderListResponses.add(orderListResponse);
        }
        return orderListResponses;
    }

    private boolean checkIsOnlyServer(Long orderMasterId, Long workId) {
        // 找出原单的数量
        List<OrderGoods> orderGoodsList = orderGoodsService.selectByOrderMasterId(orderMasterId);
        // 找出原单关联的细单的商品数量
        List<OrderDetail> orderDetailList = orderDetailService.selectByOrderMasterId(orderMasterId);
        for (OrderDetail detail : orderDetailList) {
            // 非一个师傅接单
            if (!workId.equals(detail.getWorkerId())) {
                return false;
            }
            // 子单数量
            List<OrderGoods> orderDetailGoodsList = orderGoodsService.selectByOrderDetailId(detail.getId());
            // 计算剩余未分配的商品数量
            for (OrderGoods detailGoods : orderDetailGoodsList) {
                for (OrderGoods masterGoods : orderGoodsList) {
                    if (Objects.equals(masterGoods.getGoodsStandardId(), detailGoods.getGoodsStandardId())) {
                        masterGoods.setGoodsNum(masterGoods.getGoodsNum() - detailGoods.getGoodsNum());
                    }
                }
            }
        }
        // 有单派完.
        for (OrderGoods orderGoods : orderGoodsList) {
            if (orderGoods.getGoodsNum() > 0) {
                return false;
            }
        }
        return true;
    }
}
