package com.gree.mall.miniapp.logic.material.parts;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.gree.mall.miniapp.bean.material.parts.OldRefundManageRecordBean;
import com.gree.mall.miniapp.bean.material.parts.PartsSalesOrderBean;
import com.gree.mall.miniapp.bean.material.parts.PartsSalesOrderItemBean;
import com.gree.mall.miniapp.bean.material.stock.WebsitStockDTO;
import com.gree.mall.miniapp.bean.material.stock.WorkerStockDTO;
import com.gree.mall.miniapp.bean.user.CurrentCompanyWechat;
import com.gree.mall.miniapp.commonmapper.MaterialMapper;
import com.gree.mall.miniapp.enums.IsEnum;
import com.gree.mall.miniapp.enums.IsYesNoEnum;
import com.gree.mall.miniapp.enums.PayTypeEnum;
import com.gree.mall.miniapp.enums.StateEnum;
import com.gree.mall.miniapp.enums.base.BaseEnum;
import com.gree.mall.miniapp.enums.material.*;
import com.gree.mall.miniapp.exception.RemoteServiceException;
import com.gree.mall.miniapp.logic.common.CommonLogic;
import com.gree.mall.miniapp.logic.material.stock.MaterialGoodsStockLogic;
import com.gree.mall.miniapp.plus.entity.*;
import com.gree.mall.miniapp.plus.service.*;
import io.jsonwebtoken.lang.Collections;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Slf4j
public class WebsitPartsSalesOrderLogic {

    @Resource
    WebsitPartsSalesService websitPartsSalesService;
    @Resource
    WebsitPartsSalesItemService websitPartsSalesItemService;
    @Resource
    MaterialGoodsStockLogic materialGoodsStockLogic;
    @Resource
    CommonLogic commonLogic;
    @Resource
    AdminWebsitService adminWebsitService;
    @Resource
    StorageService storageService;
    @Resource
    WebsitGoodsService websitGoodsService;
    @Resource
    WebsitPartsRefundConfigService websitPartsRefundConfigService;
    @Resource
    WebsitStockService websitStockService;
    @Resource
    MaterialConfigService materialConfigService;
    @Resource
    MaterialMapper materialMapper;
    @Resource
    WebsitSalesPayOrderService websitSalesPayOrderService;
    @Resource
    WebsitPartsWorkerCreditRecordService websitPartsWorkerCreditRecordService;

    public void handlePaySuccessMethod(WebsitSalesPayOrder order) throws Exception {
        // 更新配件销售单状态为已支付
        WebsitPartsSales partsSalesOrder = websitPartsSalesService.lambdaQuery()
                .eq(WebsitPartsSales::getId, order.getOrderId())
                .one();

        log.info("配件销售单状态：" + partsSalesOrder.getStatus());
        if (PartsOrderStatusEnum.SUBMIT.getKey().equals(partsSalesOrder.getStatus())) {
            // 销售单状态是提交状态执行
            partsSalesOrder.setPayType(order.getPayType())
                    .setPayFlag(PartsPayFlagEnum.PAY_NOT_TAKE.getKey())
                    .setStatus(PartsOrderStatusEnum.PAYED.getKey())
                    .setPayTime(order.getPayTime())
                    .setTransactionId(order.getTransactionId())
                    .setOpenid(order.getOpenid());


            List<WebsitPartsSalesItem> partsSalesOrderItems = websitPartsSalesItemService.lambdaQuery()
                    .eq(WebsitPartsSalesItem::getSalesId, order.getOrderId())
                    .list();

            if (!partsSalesOrder.getIsApply()) {
                PartsSalesOrderBean partsSalesOrderBean = new PartsSalesOrderBean();
                BeanUtils.copyProperties(partsSalesOrder, partsSalesOrderBean);
                List<PartsSalesOrderItemBean> partsSalesOrderItemBeanList = BeanUtil.copyToList(partsSalesOrderItems, PartsSalesOrderItemBean.class);

                partsSalesOrderBean.setItemList(partsSalesOrderItemBeanList);

                this.handleForwardWebsitAndWorkerStock(partsSalesOrderBean);
            }

            partsSalesOrder.updateById();
        }
    }

    private void handleForwardWebsitAndWorkerStock(PartsSalesOrderBean partsSalesOrderBean) throws Exception {
        // 扣减网点库存
        List<WebsitStockDTO> websitStockDTOList = this.getWebsitStock(partsSalesOrderBean, DirectFlagEnum.SUB);
        materialGoodsStockLogic.handleWebsitStock(websitStockDTOList);

        if (DeliveryTypeEnum.EXPRESS.getValue().equals(partsSalesOrderBean.getDeliveryType())
                && BuyPeopleEnum.WORKER.getKey().equals(partsSalesOrderBean.getBuyPeople())) {
            // 如果是快递并且销售类型为“服务人员”的单，需要增加师傅在途库存
            // 增加师傅在途库存
            List<WorkerStockDTO> workerStockDTOList = this.getWorkerStock(partsSalesOrderBean,
                    PartsRefTypeEnum.SALES.getRemark(), null, PartsAttrEnum.WAY.getKey());

            materialGoodsStockLogic.handleWorkerStock(workerStockDTOList);
        }
    }

    public List<WebsitStockDTO> getWebsitStock(PartsSalesOrderBean partsSalesOrderBean, DirectFlagEnum directFlag){
        if(Collections.isEmpty(partsSalesOrderBean.getItemList())) {
            return null;
        }
        List<WebsitStockDTO> websitStockDTOList = new ArrayList<>();
        for(WebsitPartsSalesItem item : partsSalesOrderBean.getItemList()) {
            WebsitStockDTO websitStockDTO = new WebsitStockDTO();
            websitStockDTO.setCompanyWechatId(partsSalesOrderBean.getCompanyWechatId());
            websitStockDTO.setCompanyWechatName(partsSalesOrderBean.getCompanyWechatName());
            websitStockDTO.setWebsitId(partsSalesOrderBean.getWebsitId());
            websitStockDTO.setWebsitName(partsSalesOrderBean.getWebsitName());
            websitStockDTO.setSdate(new Date());
            websitStockDTO.setPartsWebsitId(item.getPartsWebsitId());
            websitStockDTO.setGoodsType(WebsitGoodsTypeEnum.P.toString());
            websitStockDTO.setGoodsId(item.getPartsNumber());
            websitStockDTO.setGoodsName(item.getPartsName());
            websitStockDTO.setMaterialGroupName(item.getMaterialGroupName());
            websitStockDTO.setPrice(item.getSalesPrice());
            websitStockDTO.setGoodsStockUnit(item.getGoodsStockUnit());
            websitStockDTO.setVoucherNo(partsSalesOrderBean.getId());
            websitStockDTO.setApplyNo(partsSalesOrderBean.getId());
            websitStockDTO.setRef(partsSalesOrderBean.getId());
            websitStockDTO.setRefType(PartsRefTypeEnum.SALES.getRemark());
            websitStockDTO.setObj(BaseEnum.keyToEnumNotNull(BuyPeopleEnum.class, partsSalesOrderBean.getBuyPeople()).getRemark());
            websitStockDTO.setPartsAttr(PartsAttrEnum.NEW.getKey());
            websitStockDTO.setChangeQty(item.getQty());
            websitStockDTO.setDirectFlag(directFlag.getKey());
            websitStockDTO.setRemark(partsSalesOrderBean.getRemark());
            websitStockDTO.setOperateBy(partsSalesOrderBean.getSubmitBy());
            websitStockDTO.setOperateTime(new Date());
            websitStockDTO.setStorageId(partsSalesOrderBean.getStorageId());
            websitStockDTOList.add(websitStockDTO);
        }
        return websitStockDTOList;
    }

    public List<WorkerStockDTO> getWorkerStock(PartsSalesOrderBean partsSalesOrderBean, String refType, String partsAttr1,
                                               String partsAttr2){
        if(Collections.isEmpty(partsSalesOrderBean.getItemList())) {
            return null;
        }
        List<WorkerStockDTO> workerStockDTOList = new ArrayList<>();

        for (WebsitPartsSalesItem item : partsSalesOrderBean.getItemList()) {
            if (StringUtils.isNotBlank(partsAttr1)) {
                WorkerStockDTO workerStockDTO = new WorkerStockDTO();
                workerStockDTO.setCompanyWechatId(partsSalesOrderBean.getCompanyWechatId());
                workerStockDTO.setCompanyWechatName(partsSalesOrderBean.getCompanyWechatName());
                workerStockDTO.setIdentity(item.getIdentity());
                workerStockDTO.setWorkerId(partsSalesOrderBean.getWorkerId());
                workerStockDTO.setWorkerName(partsSalesOrderBean.getWorkerName());
                workerStockDTO.setWebsitId(partsSalesOrderBean.getWebsitId());
                workerStockDTO.setWebsitName(partsSalesOrderBean.getWebsitName());
                workerStockDTO.setSdate(DateUtil.date());
                workerStockDTO.setPartsWebsitId(item.getPartsWebsitId());
                workerStockDTO.setGoodsType(WebsitGoodsTypeEnum.P.toString());
                workerStockDTO.setGoodsId(item.getPartsNumber());
                workerStockDTO.setGoodsName(item.getPartsName());
                workerStockDTO.setMaterialGroupName(item.getMaterialGroupName());
                workerStockDTO.setPrice(item.getSalesPrice());
                workerStockDTO.setGoodsStockUnit(item.getGoodsStockUnit());
                workerStockDTO.setRef(partsSalesOrderBean.getId());
                workerStockDTO.setRefType(refType);
                workerStockDTO.setPartsAttr(partsAttr1);
                workerStockDTO.setChangeQty(item.getQty());
                workerStockDTO.setDirectFlag(DirectFlagEnum.SUB.getKey());
                workerStockDTO.setRemark(partsSalesOrderBean.getRemark());
                workerStockDTO.setOperateBy(partsSalesOrderBean.getWorkerName());
                workerStockDTO.setOperateTime(DateUtil.date());
                workerStockDTOList.add(workerStockDTO);
            }
            if (StringUtils.isNotBlank(partsAttr2)) {
                WorkerStockDTO workerStockDTO = new WorkerStockDTO();
                workerStockDTO.setIdentity(item.getIdentity());
                workerStockDTO.setCompanyWechatId(partsSalesOrderBean.getCompanyWechatId());
                workerStockDTO.setCompanyWechatName(partsSalesOrderBean.getCompanyWechatName());
                workerStockDTO.setWorkerId(partsSalesOrderBean.getWorkerId());
                workerStockDTO.setWorkerName(partsSalesOrderBean.getWorkerName());
                workerStockDTO.setWebsitId(partsSalesOrderBean.getWebsitId());
                workerStockDTO.setWebsitName(partsSalesOrderBean.getWebsitName());
                workerStockDTO.setSdate(DateUtil.date());
                workerStockDTO.setPartsWebsitId(item.getPartsWebsitId());
                workerStockDTO.setGoodsType(WebsitGoodsTypeEnum.P.toString());
                workerStockDTO.setGoodsId(item.getPartsNumber());
                workerStockDTO.setGoodsName(item.getPartsName());
                workerStockDTO.setMaterialGroupName(item.getMaterialGroupName());
                workerStockDTO.setPrice(item.getSalesPrice());
                workerStockDTO.setGoodsStockUnit(item.getGoodsStockUnit());
                workerStockDTO.setRef(partsSalesOrderBean.getId());
                workerStockDTO.setRefType(refType);
                workerStockDTO.setPartsAttr(partsAttr2);
                workerStockDTO.setChangeQty(item.getQty());
                workerStockDTO.setDirectFlag(DirectFlagEnum.ADD.getKey());
                workerStockDTO.setRemark(partsSalesOrderBean.getRemark());
                workerStockDTO.setOperateBy(partsSalesOrderBean.getWorkerName());
                workerStockDTO.setOperateTime(DateUtil.date());
                workerStockDTOList.add(workerStockDTO);
            }
        }
        return workerStockDTOList;
    }

    @Transactional
    public void add(PartsSalesOrderBean partsSalesOrderBean) {
        CurrentCompanyWechat wechat = commonLogic.getCurrentCompanyWechat();
        partsSalesOrderBean.setCompanyWechatId(wechat.getCompanyWechatId())
                .setCompanyWechatName(wechat.getCompanyName());
        //一系列校验
        Map<String, Object> validateMap = this.validate(partsSalesOrderBean);
        if(validateMap.containsKey("isSuccess") && !Boolean.parseBoolean(validateMap.get("isSuccess").toString())) {
            throw new RemoteServiceException(validateMap.get("msg").toString());
        }
        //获取登录人昵称
        DateTime curDate = DateUtil.date();

        if (Objects.isNull(partsSalesOrderBean.getPayType())) {
            // 默认现金
            partsSalesOrderBean.setPayType(PayTypeEnum.CASH.getKey());
        }
        List<PartsSalesOrderItemBean> itemList = partsSalesOrderBean.getItemList();
        BigDecimal totalPrice = BigDecimal.ZERO;

        if (CollectionUtil.isEmpty(itemList)) {
            throw new RemoteServiceException("请选择配件");
        }

        for(WebsitPartsSalesItem partsSalesOrderItem : itemList) {
            partsSalesOrderItem.setTotalAmount(partsSalesOrderItem.getSalesPrice().multiply(partsSalesOrderItem.getQty())
                    .setScale(2, BigDecimal.ROUND_HALF_UP));
            totalPrice = totalPrice.add(partsSalesOrderItem.getTotalAmount());
        }

        // 记录总金额
        partsSalesOrderBean.setTotalAmount(totalPrice);
        partsSalesOrderBean.setWorkerId(wechat.getUser().getWorkerNumber());
        partsSalesOrderBean.setWorkerName(wechat.getUser().getNickName());
        partsSalesOrderBean.setStatus(PartsOrderStatusEnum.SAVE.getKey());
        // 生成订单号
        String sheetId = commonLogic.generateMaterialNo(wechat.getCompanyWechatId(), "PJ", PartsRefTypeEnum.SALES.getKey(), 13);
        partsSalesOrderBean.setId(sheetId);
        websitPartsSalesService.save(partsSalesOrderBean);
        websitPartsSalesService.lambdaUpdate()
                .set(WebsitPartsSales::getCreateBy, wechat.getUser().getNickName())
                .set(WebsitPartsSales::getUpdateBy, wechat.getUser().getNickName())
                .eq(WebsitPartsSales::getId, sheetId)
                .update();


        // 保存销售单明细
        List<WebsitPartsSalesItem> partsSalesOrderItems = this.createSalesOrderItem(partsSalesOrderBean, itemList);
        websitPartsSalesItemService.saveBatch(partsSalesOrderItems);
    }

    private Map<String, Object> validate(PartsSalesOrderBean partsSalesOrderBean) {
        Map<String, Object> result = new HashMap<>();
        result.put("isSuccess" , Boolean.TRUE);

        if(StringUtils.isBlank(partsSalesOrderBean.getWebsitId())) {
            result.put("isSuccess", Boolean.FALSE);
            result.put("msg", "新增配件销售单失败，没有网点");
            return result;
        }

        if (StringUtils.isBlank(partsSalesOrderBean.getBuyPeople())) {
            result.put("isSuccess", Boolean.FALSE);
            result.put("msg", "请选择销售类型");
            return result;
        }

        if (BuyPeopleEnum.WORKER.getKey().equals(partsSalesOrderBean.getBuyPeople())) {
            if(StringUtils.isBlank(partsSalesOrderBean.getIdentity())) {
                result.put("isSuccess", Boolean.FALSE);
                result.put("msg", "新增配件销售单失败，服务人员身份证不能为空，请选择服务人员");
                return result;
            }
        }

        //获取申请类别
        if(StringUtils.isBlank(partsSalesOrderBean.getApplyCategory())) {
            result.put("isSuccess", Boolean.FALSE);
            result.put("msg", "新增配件销售单失败，请选择申请类别");
            return result;
        }

        // 获取对应网点
        AdminWebsit websit = adminWebsitService.getById(partsSalesOrderBean.getWebsitId());
        if (Objects.isNull(websit) || StringUtils.isBlank(websit.getPartsWebsitId())) {
            result.put("isSuccess", Boolean.FALSE);
            result.put("msg", "新增配件销售单失败，没有找到该网点" + partsSalesOrderBean.getWebsitId());
            return result;
        }
        partsSalesOrderBean.setWebsitName(websit.getName());
        partsSalesOrderBean.setPartsWebsitId(websit.getPartsWebsitId());

        if (StringUtils.isBlank(partsSalesOrderBean.getStorageId())) {
            final Storage storage = storageService.lambdaQuery()
                    .eq(Storage::getCompanyWechatId, partsSalesOrderBean.getCompanyWechatId())
                    .eq(Storage::getWebsitId, partsSalesOrderBean.getWebsitId())
                    .eq(Storage::getIsDefault, IsEnum.Y.getValue())
                    .one();
            partsSalesOrderBean.setStorageId(storage.getStorageId())
                    .setStorageName(storage.getStorageName());
        }

        if (Objects.isNull(partsSalesOrderBean.getApplyType())) {
            result.put("isSuccess", Boolean.FALSE);
            result.put("msg", "新增配件销售单失败，没有申请类型");
            return result;
        }
        if (Objects.isNull(partsSalesOrderBean.getDeliveryType())) {
            result.put("isSuccess", Boolean.FALSE);
            result.put("msg", "新增配件销售单失败，请先选择发货方式");
            return result;
        }
        if (Collections.isEmpty(partsSalesOrderBean.getItemList())) {
            result.put("isSuccess", Boolean.FALSE);
            result.put("msg", "新增配件销售单失败，没有配件明细信息");
            return result;
        }

        // 快递必填详细地址
        if (partsSalesOrderBean.getDeliveryType().equals(DeliveryTypeEnum.EXPRESS.getValue())
                && StringUtils.isBlank(partsSalesOrderBean.getAddr())) {
            result.put("isSuccess", Boolean.FALSE);
            result.put("msg", "新增配件销售单失败，请填写详细地址");
            return result;
        }
        //校验配件明细列表
        LinkedHashSet<String> partsNumbers = new LinkedHashSet<>();
        for(WebsitPartsSalesItem item : partsSalesOrderBean.getItemList()) {
            if(StringUtils.isEmpty(item.getPartsNumber())) {
                result.put("isSuccess", Boolean.FALSE);
                result.put("msg", "新增配件销售单失败，配件编码不能为空");
                return result;
            }
            if(Objects.isNull(item.getQty()) || Integer.parseInt(item.getQty().toString()) <= 0) {
                result.put("isSuccess", Boolean.FALSE);
                result.put("msg", "新增配件销售单失败，配件编码"+item.getPartsNumber() + "数量不能小于或等于0");
                return result;
            }
            item.setCompanyWechatId(partsSalesOrderBean.getCompanyWechatId())
                    .setWebsitId(partsSalesOrderBean.getWebsitId())
                    .setPartsWebsitId(partsSalesOrderBean.getPartsWebsitId());

            partsNumbers.add(item.getPartsNumber());
        }
        //根据配件编码查询对应的配件列表
        final List<WebsitGoods> partsList = websitGoodsService.lambdaQuery()
                .eq(WebsitGoods::getGoodsType, WebsitGoodsTypeEnum.P.toString())
                .eq(WebsitGoods::getNormType, NormTypeEnum.M.getKey())
                .in(WebsitGoods::getGoodsCode, partsNumbers)
                .eq(WebsitGoods::getStatus, StateEnum.ON.getKey())
                .list();

        if(Collections.isEmpty(partsList)) {
            result.put("isSuccess", Boolean.FALSE);
            result.put("msg", "新增配件销售单失败，系统找不到该配件配件编码: " + String.join(",", partsNumbers));
            return result;
        }
        final Map<String, WebsitGoods> partsMap = partsList.stream().collect(Collectors.toMap(WebsitGoods::getGoodsCode, Function.identity()));
        //检验每个配件明细是否在数据库里查到
        LinkedHashSet<String> notExsistisPartsNumbers = new LinkedHashSet<>();
        for(String partsNumber : partsNumbers) {
            if( !partsMap.containsKey(partsNumber) || Objects.isNull(partsMap.get(partsNumber))) {
                notExsistisPartsNumbers.add(partsNumber);
            }
        }
        if(!Collections.isEmpty(notExsistisPartsNumbers)) {
            result.put("isSuccess", Boolean.FALSE);
            result.put("msg", "新增配件销售单失败，以下配件配件编码不存在: "+String.join(",", notExsistisPartsNumbers));
            return result;
        }
        List<PartsSalesOrderItemBean> values = new ArrayList<>(partsSalesOrderBean.getItemList().stream()
                .collect(Collectors.toMap(PartsSalesOrderItemBean::getPartsNumber, Function.identity(), (key1, key2) -> {
                    key1.setQty(key1.getQty().add(key2.getQty()));
                    return key1;
                })).values());
        partsSalesOrderBean.getItemList().clear();
        partsSalesOrderBean.setItemList(values);

        if(CollectionUtil.isNotEmpty(partsSalesOrderBean.getItemList())) {
            WebsitPartsRefundConfig partsConfig = websitPartsRefundConfigService.lambdaQuery()
                    .eq(WebsitPartsRefundConfig::getCompanyWechatId, partsSalesOrderBean.getCompanyWechatId())
                    .eq(WebsitPartsRefundConfig::getIsDefault, Boolean.TRUE)
                    .one();

            //检查是否有可用库存
            final List<WebsitStock> partsWebsitStockList = websitStockService.lambdaQuery()
                    .in(WebsitStock::getGoodsId, partsNumbers)
                    .eq(WebsitStock::getGoodsType, WebsitGoodsTypeEnum.P.toString())
                    .eq(WebsitStock::getCompanyWechatId, partsSalesOrderBean.getCompanyWechatId())
                    .eq(WebsitStock::getWebsitId, partsSalesOrderBean.getWebsitId())
                    .list();

            for (WebsitPartsSalesItem item : partsSalesOrderBean.getItemList()) {
                if (!partsMap.containsKey(item.getPartsNumber()) || Objects.isNull(partsMap.get(item.getPartsNumber()))) {
                    continue;
                }
                if (StringUtils.isEmpty(item.getPartsWebsitId())) {
                    result.put("isSuccess", Boolean.FALSE);
                    result.put("msg", "配件网点编号不能为空");
                    break;
                }
                if (StringUtils.isEmpty(item.getPartsNumber())) {
                    result.put("isSuccess", Boolean.FALSE);
                    result.put("msg", "配件编号不能为空");
                    break;
                }
                // 非申请单检验配件网点库存是否大于0
                if (partsSalesOrderBean.getIsApply()) {
                    if (!partsWebsitStockList.stream().filter(o ->
                            item.getPartsWebsitId().equals(o.getPartsWebsitId())
                                    && item.getPartsNumber().equals(o.getGoodsId())
                    ).findAny().isPresent()) {
                        result.put("isSuccess", Boolean.FALSE);
                        result.put("msg", String.join("配件编号:", item.getPartsNumber(), ",在网点编号:", partsSalesOrderBean.getWebsitId(), "没有库存"));
                        break;
                    }
                    List<WebsitStock> stockList = partsWebsitStockList.stream().filter(o ->
                            item.getPartsWebsitId().equals(o.getPartsWebsitId())
                                    && item.getPartsNumber().equals(o.getGoodsId())
                    ).collect(Collectors.toList());
                    if (item.getQty().compareTo(stockList.get(0).getQty()) > 0) {
                        result.put("isSuccess", Boolean.FALSE);
                        result.put("msg", String.join("配件编号:", item.getPartsNumber(), ", 不能大于网点库存"));
                        break;
                    }
                    WebsitGoods parts = partsMap.get(item.getPartsNumber());
                    item.setWebsitId(partsSalesOrderBean.getWebsitId());
                    item.setPartsId(parts.getGoodsId());
                    item.setMaterialGroupName(parts.getMaterialGroupName());
                    item.setGoodsStockUnit(parts.getGoodsStockUnit());
                    item.setPartsWebsitId(stockList.get(0).getPartsWebsitId());
                    item.setPartsNumber(stockList.get(0).getGoodsId());
                    item.setMarketPrice(parts.getMarketPrice());
                    item.setExamineQty(item.getQty());
                    item.setSecondPrice(parts.getSecondPrice());
                    computeSalesPrice(partsConfig, parts, item, result);
                } else {
                    WebsitGoods parts = partsMap.get(item.getPartsNumber());
                    item.setWebsitId(partsSalesOrderBean.getWebsitId());
                    item.setPartsId(parts.getGoodsId());
                    item.setMaterialGroupName(parts.getMaterialGroupName());
                    item.setGoodsStockUnit(parts.getGoodsStockUnit());
                    item.setPartsWebsitId(partsSalesOrderBean.getPartsWebsitId());
                    item.setPartsNumber(parts.getGoodsCode());
                    item.setMarketPrice(parts.getMarketPrice());
                    item.setExamineQty(item.getQty());
                    item.setSecondPrice(parts.getSecondPrice());
                    computeSalesPrice(partsConfig, parts, item, result);
                }
            }
        }
        return result;
    }

    private void computeSalesPrice(WebsitPartsRefundConfig partsConfig, WebsitGoods parts, WebsitPartsSalesItem item, Map<String, Object> result) {
        final MaterialConfig materialConfig = materialConfigService.lambdaQuery()
                .eq(MaterialConfig::getCompanyWechatId, partsConfig.getCompanyWechatId())
                .one();
        switch (Optional.ofNullable(parts.getPartType()).orElse("")) {
            case "":
                result.put("isSuccess", Boolean.FALSE);
                result.put("msg", "配件类型不能为空");
                break;
            case "空调":
                item.setSalesPrice(item.getMarketPrice().multiply(materialConfig.getPriceRate1()).setScale(2, BigDecimal.ROUND_HALF_UP));
                break;
            case "冰箱":
                item.setSalesPrice(item.getMarketPrice().multiply(materialConfig.getPriceRate2()).setScale(2, BigDecimal.ROUND_HALF_UP));
                break;
            case "生活电器":
                item.setSalesPrice(item.getMarketPrice().multiply(materialConfig.getPriceRate3()).setScale(2, BigDecimal.ROUND_HALF_UP));
                break;
            default:
                item.setSalesPrice(item.getMarketPrice().multiply(new BigDecimal("1.2")).setScale(2, BigDecimal.ROUND_HALF_UP));
                break;
        }
    }

    private List<WebsitPartsSalesItem> createSalesOrderItem(PartsSalesOrderBean partsSalesOrderBean, List<PartsSalesOrderItemBean> itemList) {
        List<WebsitPartsSalesItem> partsSalesOrderItems = new ArrayList<>();
        final List<WebsitStock> websitStocks = websitStockService.lambdaQuery()
                .eq(WebsitStock::getCompanyWechatId, partsSalesOrderBean.getCompanyWechatId())
                .eq(WebsitStock::getWebsitId, partsSalesOrderBean.getWebsitId())
                .eq(WebsitStock::getStorageId, partsSalesOrderBean.getStorageId())
                .eq(WebsitStock::getGoodsType, WebsitGoodsTypeEnum.P.toString())
                .in(WebsitStock::getGoodsId, itemList.stream().map(PartsSalesOrderItemBean::getPartsNumber).collect(Collectors.toList()))
                .list();
        if (CollectionUtil.isNotEmpty(websitStocks)) {
            final Map<String, WebsitStock> stockMap = websitStocks.stream()
                    .collect(Collectors.toMap(WebsitStock::getGoodsId, Function.identity()));
            for (PartsSalesOrderItemBean salesItem : itemList) {
                final WebsitStock stock = stockMap.get(salesItem.getPartsNumber());
                if (Objects.nonNull(stock) && salesItem.getQty().compareTo(stock.getQty()) > 0) {
                    throw new RemoteServiceException(salesItem.getPartsName() + " 销售数量不能大于库存数量");
                }
                salesItem.setStockQty(stock.getQty());
            }
        }
        for(PartsSalesOrderItemBean partsSalesOrderItemBean : itemList) {
            WebsitPartsSalesItem partsSalesOrderItem = new WebsitPartsSalesItem();
            BeanUtils.copyProperties(partsSalesOrderItemBean, partsSalesOrderItem);
            partsSalesOrderItem.setSalesId(partsSalesOrderBean.getId())
                    .setWebsitId(partsSalesOrderBean.getWebsitId())
                    .setIdentity(partsSalesOrderBean.getIdentity());
            partsSalesOrderItems.add(partsSalesOrderItem);
        }
        return partsSalesOrderItems;
    }

    public PartsSalesOrderBean loadSalesOrderById(String id) {
        WebsitPartsSales partsSalesOrder = websitPartsSalesService.getById(id);

        if(Objects.isNull(partsSalesOrder)) {
            throw new RemoteServiceException("获取配件销售单失败") ;
        }

        PartsSalesOrderBean partsSalesOrderBean = new PartsSalesOrderBean();
        BeanUtils.copyProperties(partsSalesOrder, partsSalesOrderBean, PartsSalesOrderBean.class);
        List<PartsSalesOrderItemBean> itemList = materialMapper.selectItemBySalesOrderId(partsSalesOrderBean.getId());
        partsSalesOrderBean.setItemList(Collections.isEmpty(itemList) ? null : itemList);
        List<WebsitSalesPayOrder> payList = websitSalesPayOrderService.lambdaQuery()
                .eq(WebsitSalesPayOrder::getCompanyWechatId, partsSalesOrder.getCompanyWechatId())
                .eq(WebsitSalesPayOrder::getPayFlag, IsYesNoEnum.YES.getKey())
                .eq(WebsitSalesPayOrder::getOrderId, partsSalesOrderBean.getId())
                .list();
        List<WebsitSalesPayOrder> allPayList = websitSalesPayOrderService.lambdaQuery()
                .eq(WebsitSalesPayOrder::getCompanyWechatId, partsSalesOrder.getCompanyWechatId())
                .eq(WebsitSalesPayOrder::getOrderId, partsSalesOrderBean.getId())
                .list();

        partsSalesOrderBean.setPayList(payList);
        partsSalesOrderBean.setAllPayList(allPayList);

        // 配件使用记录
        List<OldRefundManageRecordBean> oldRefundManageRecordBeans = materialMapper.queryOldRefundRecordById(partsSalesOrder.getId());
        partsSalesOrderBean.setOldRefundManageRecordBeanList(oldRefundManageRecordBeans);


        return partsSalesOrderBean;
    }

    public Object submit(String id) {
        CurrentCompanyWechat wechat = commonLogic.getCurrentCompanyWechat();
        PartsSalesOrderBean partsSalesOrderBean = loadSalesOrderById(id);
        if(Objects.isNull(partsSalesOrderBean)) {
            throw new RemoteServiceException("配件单提交失败，销售单信息不能为空") ;
        }
        if(!partsSalesOrderBean.getStatus().equals(PartsOrderStatusEnum.SAVE.getKey())) {
            throw new RemoteServiceException("该配件销售单已提交，不能重复提交");
        }
        // 先保存一下页面信息，再提交状态

        // 更新状态为1-已提交
        partsSalesOrderBean.setStatus(PartsOrderStatusEnum.SUBMIT.getKey());
        partsSalesOrderBean.setSubmitBy(wechat.getUser().getNickName());
        partsSalesOrderBean.setSubmitTime(DateUtil.date());

        websitPartsSalesService.saveOrUpdate(partsSalesOrderBean);
        return loadSalesOrderById(id);
    }

    /**
     * 师傅app端确认提货
     * @param id
     * @throws RemoteServiceException
     */
    @Transactional
    public void workerConfirmDelivery(String id) throws Exception {
        PartsSalesOrderBean partsSalesOrderBean = loadSalesOrderById(id);
        if(Objects.isNull(partsSalesOrderBean)) {
            throw new RemoteServiceException("配件单提交失败，单号=" + id) ;
        }
        if(!PartsOrderStatusEnum.PAYED.getKey().equals(partsSalesOrderBean.getStatus())) {
            throw new RemoteServiceException("非已支付状态，不能提货");
        }
        DateTime curDate = DateUtil.date();
        partsSalesOrderBean.setWorkerConfirmDate(curDate);
        if(Objects.nonNull(partsSalesOrderBean.getWebsitConfirmDate())) {
			 /* 网点确认时间不为空，说明网点已确认，则除了更新师傅确认时间之外，
			    还需要更新订单状态为已完成，流程结束时间，更新审核人，审核时间和pushFlag标志位;
			    同时还需要增加师傅库存.
			  */
            partsSalesOrderBean.setStatus(PartsOrderStatusEnum.END.getKey());
            partsSalesOrderBean.setEndTime(curDate);
            partsSalesOrderBean.setExamineBy(partsSalesOrderBean.getWorkerName());
            partsSalesOrderBean.setExamineTime(curDate);
            partsSalesOrderBean.setPushFlag(PartsPushFlagEnum.SALES.toString());
            partsSalesOrderBean.setPayFlag(PartsPayFlagEnum.PAY_TAKE.getKey());
            // 师傅在途库存转移到新件库存
            List<WorkerStockDTO> workerWayStockDTOList = this.getWorkerStock(partsSalesOrderBean, PartsRefTypeEnum.SALES.getRemark(),
                    PartsAttrEnum.WAY.getKey(), PartsAttrEnum.NEW.getKey());
            materialGoodsStockLogic.handleWorkerStock(workerWayStockDTOList);

            this.updateSalesItem(partsSalesOrderBean);
        }
        websitPartsSalesService.updateById(partsSalesOrderBean);
    }

    /**
     * 更新销售明细的信息
     * @param partsSalesOrderBean
     */
    private void updateSalesItem(PartsSalesOrderBean partsSalesOrderBean) {
        if(CollectionUtil.isNotEmpty(partsSalesOrderBean.getItemList())) {
            List<WebsitPartsSalesItem> itemList = new ArrayList<>();
            List<WebsitPartsWorkerCreditRecord> recordList = new ArrayList<>();
            for(PartsSalesOrderItemBean itemBean : partsSalesOrderBean.getItemList()) {
                itemBean.setPushFlag(partsSalesOrderBean.getPushFlag());
                itemBean.setExamineTime(partsSalesOrderBean.getExamineTime());
                if (partsSalesOrderBean.getPayType().equals(PayTypeEnum.CASH.getKey())) {
                    itemBean.setRefundAmountMode(PayTypeEnum.CASH.getKey());
                } else if (partsSalesOrderBean.getPayType().equals(PayTypeEnum.CREDIT.getKey())) {
                    itemBean.setRefundAmountMode(PayTypeEnum.CREDIT.getKey());

                    recordList.add(new WebsitPartsWorkerCreditRecord()
                            .setId("PC" + IdWorker.getIdStr())
                            .setCompanyWechatId(partsSalesOrderBean.getCompanyWechatId())
                            .setCompanyWechatName(partsSalesOrderBean.getCompanyWechatName())
                            .setWebsitId(partsSalesOrderBean.getWebsitId())
                            .setWebsitName(partsSalesOrderBean.getWebsitName())
                            .setMobile(partsSalesOrderBean.getMobile())
                            .setSalesId(partsSalesOrderBean.getId())
                            .setSalesItemId(itemBean.getId())
                            .setPartsNumber(itemBean.getPartsNumber())
                            .setPartsName(itemBean.getPartsName())
                            .setSalesPrice(itemBean.getSalesPrice())
                            .setMarketPrice(itemBean.getMarketPrice())
                            .setSecondPrice(itemBean.getSecondPrice())
                            .setQty(itemBean.getQty())
                            .setTotalAmount(itemBean.getTotalAmount())
                            .setCreditStatus(Boolean.FALSE)
                            .setRecAmountMode(itemBean.getRefundAmountMode())
                    );
                } else {
                    itemBean.setRefundAmountMode(PayTypeEnum.WECHAT.getKey());
                }
                itemList.add(itemBean);
            }
            websitPartsSalesItemService.saveOrUpdateBatch(itemList);
            if (CollectionUtil.isNotEmpty(recordList)) {
                websitPartsWorkerCreditRecordService.saveBatch(recordList);
            }
        }
    }
}
