package cn.iocoder.yudao.module.tickets.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.common.RecordTypeEnum;
import cn.iocoder.yudao.common.RepairRoleEnum;
import cn.iocoder.yudao.common.SoStatusEnum;
import cn.iocoder.yudao.common.SystemEnum;
import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.base.entity.RepairWorker;
import cn.iocoder.yudao.module.base.service.RepairRecordsService;
import cn.iocoder.yudao.module.base.service.RepairWorkerService;
import cn.iocoder.yudao.module.conf.entity.BaseType;
import cn.iocoder.yudao.module.conf.service.BaseTypeService;
import cn.iocoder.yudao.module.custom.entity.CustomerMain;
import cn.iocoder.yudao.module.custom.service.CustomerMainService;
import cn.iocoder.yudao.module.project.entity.RepairWares;
import cn.iocoder.yudao.module.project.service.RepairWaresService;
import cn.iocoder.yudao.module.stockOperate.entity.DlRepairSoi;
import cn.iocoder.yudao.module.stockOperate.mapper.DlRepairSoMapper;
import cn.iocoder.yudao.module.stockOperate.service.DlRepairSoService;
import cn.iocoder.yudao.module.stockOperate.service.DlRepairSoiService;
import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
import cn.iocoder.yudao.module.system.api.permission.RoleApi;
import cn.iocoder.yudao.module.system.api.permission.dto.RoleReqDTO;
import cn.iocoder.yudao.module.tickets.entity.DlRepairTickets;
import cn.iocoder.yudao.module.tickets.entity.DlRepairTitem;
import cn.iocoder.yudao.module.tickets.entity.DlTicketWares;
import cn.iocoder.yudao.module.tickets.entity.DlTwItem;
import cn.iocoder.yudao.module.tickets.mapper.DlTicketWaresMapper;
import cn.iocoder.yudao.module.tickets.service.DlRepairTicketsService;
import cn.iocoder.yudao.module.tickets.service.DlRepairTitemService;
import cn.iocoder.yudao.module.tickets.service.DlTicketWaresService;
import cn.iocoder.yudao.module.tickets.service.DlTwItemService;
import cn.iocoder.yudao.module.tickets.vo.DlTicketWaresReqVO;
import cn.iocoder.yudao.module.tickets.vo.DlTicketWaresRespVO;
import cn.iocoder.yudao.module.tickets.vo.DlTwItemRespVO;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

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

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;

/**
 * 针对表【dl_ticket_wares(工单配件申请/退回表)】的数据库操作Service实现
 *
 * @author 小李
 * @date 11:56 2024/10/15
 **/
@Service
public class DlTicketWaresServiceImpl extends ServiceImpl<DlTicketWaresMapper, DlTicketWares> implements DlTicketWaresService {


    @Resource
    private DlTwItemService twItemService;

    @Resource
    @Lazy
    private DlRepairTicketsService repairTicketsService;

    @Resource
    @Lazy
    private RepairWorkerService repairWorkerService;

    @Resource
    @Lazy
    private DlRepairTitemService repairTitemService;

    @Resource
    @Lazy
    private DlRepairSoService repairSoService;

    @Resource
    @Lazy
    private DlRepairSoiService repairSoiService;

    @Resource
    @Lazy
    private RepairWaresService repairWaresService;

    @Resource
    @Lazy
    private DlRepairSoMapper dlRepairSoMapper;

    @Resource
    @Lazy
    private RoleApi roleApi;

    @Resource
    @Lazy
    private PermissionApi permissionApi;
    @Resource
    private RepairRecordsService repairRecordsService;

    @Resource
    private CustomerMainService customerMainService;

    @Resource
    private BaseTypeService baseTypeService;

    /**
     * 分页查询
     *
     * @param reqVO 请求对象
     * @author 小李
     * @date 12:01 2024/10/15
     **/
    @Override
    public IPage<DlTicketWares> getPage(DlTicketWaresReqVO reqVO, Page<DlTicketWares> page) {
        // 确认查看者身份
        String userRoleCode = repairTicketsService.getUserRole();
        if (userRoleCode.equals(RepairRoleEnum.ADMIN.getCode()) || userRoleCode.equals(RepairRoleEnum.INSPECTION.getCode())) {
            //维修管理员和总检，看所有数据
        } else if (userRoleCode.equals(RepairRoleEnum.ADVISOR.getCode())) {
            //服务顾问--暂时看所有的配件申请单
//            reqVO.setAdviserId(SecurityFrameworkUtils.getLoginUserId());
        } else if (userRoleCode.equals(RepairRoleEnum.REPAIR_STAFF.getCode())) {
            //维修工，进一步判断是否是班组长
            boolean ifLeader = repairWorkerService.getIfLeader();
            if (ifLeader) {
                //班组长，看本班组所有数据
                RepairWorker one = repairWorkerService.getOne(new LambdaQueryWrapper<RepairWorker>().eq(RepairWorker::getUserId, SecurityFrameworkUtils.getLoginUserId()));
                // 查自己班组的员工信息
                List<RepairWorker> list = repairWorkerService.list(new LambdaQueryWrapper<RepairWorker>().eq(RepairWorker::getWorkType, one.getWorkType()));
                // 所有的员工信息
                List<Long> userIds = list.stream().map(RepairWorker::getUserId).collect(Collectors.toList());
                reqVO.setUserIds(userIds);
            } else {
                //普通维修工
                reqVO.setUserIds(Collections.singletonList(SecurityFrameworkUtils.getLoginUserId()));
            }
        } else if (userRoleCode.equals(RepairRoleEnum.WAREHOUSE.getCode())) {
            // 维修仓库管理员
            reqVO.setUserRole(5);
        } else {
            return null;
        }
        return baseMapper.getPage(reqVO, page);
    }

    /**
     * 查询当前工单下的配件申请单
     *
     * @param reqVO DlTicketWaresReqVO
     * @return java.util.List<cn.iocoder.yudao.module.tickets.entity.DlTicketWares>
     * @author PQZ
     * @date 13:44 2024/10/19
     **/
    @Override
    public List<DlTicketWares> listByTicket(DlTicketWaresReqVO reqVO) {
        // 确认查看者身份
        String userRoleCode = repairTicketsService.getUserRole();
        List<DlTicketWares> result = new ArrayList<>();
        //维修业务管理员、总检、服务顾问均可以进行审批
        if (userRoleCode.equals(RepairRoleEnum.ADMIN.getCode()) || userRoleCode.equals(RepairRoleEnum.INSPECTION.getCode()) || userRoleCode.equals(RepairRoleEnum.ADVISOR.getCode())) {
            LambdaQueryWrapper<DlTicketWares> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(DlTicketWares::getTicketId, reqVO.getTicketId());
            if (null != reqVO.getStatus()) {
                lambdaQueryWrapper.eq(DlTicketWares::getStatus, reqVO.getStatus());
            }
            result = list(lambdaQueryWrapper);
        }
        return result;
    }

    /**
     * 新增、修改
     *
     * @param respVO 请求对象
     * @author 小李
     * @date 12:14 2024/10/15
     **/
    @Override
    @DSTransactional
    public void updateTicketWares(DlTicketWaresRespVO respVO) {

        // 新增、修改主表
        DlTicketWares ticketWares = BeanUtil.toBean(respVO, DlTicketWares.class);
        /*
            设置信息
         */
        // 用户信息
        DlRepairTickets tickets = repairTicketsService.getById(ticketWares.getTicketId());
        CustomerMain customerMain = customerMainService.getById(tickets.getUserId());
        ticketWares.setUserId(customerMain.getUserId());
        ticketWares.setUserName(customerMain.getCusName());
        ticketWares.setUserMobile(customerMain.getPhoneNumber());
        // 车辆信息
        ticketWares.setCarId(tickets.getCarId());
        ticketWares.setLicenseNumber(tickets.getCarNo());
        // 发起人信息
        RepairWorker worker = repairWorkerService.getOne(new LambdaQueryWrapper<RepairWorker>().eq(RepairWorker::getUserId, SecurityFrameworkUtils.getLoginUserId()));
        ticketWares.setRepairId(worker.getUserId());
        ticketWares.setRepairName(worker.getUserName());
        ticketWares.setRepairWork(worker.getWorkType());
        // 服务顾问信息
        ticketWares.setAdviserId(Long.valueOf(tickets.getAdviserId()));
        ticketWares.setAdviserName(tickets.getAdviserName());

        // 图片
        if (ObjectUtil.isNotEmpty(respVO.getImages())){
            ticketWares.setImages(respVO.getImages());
        }
        baseMapper.insertOrUpdate(ticketWares);

        // 新增、修改子表
        if (CollectionUtil.isNotEmpty(respVO.getItems())){
            List<DlTwItem> list = respVO.getItems().stream()
                    .map(item -> {
                        DlTwItem twItem = BeanUtil.toBean(item, DlTwItem.class);
                        twItem.setTwId(ticketWares.getId());
                        twItem.setWaresStatus("");
                        twItem.setWaresAlreadyCount(0);
                        //非仓管添加
                        twItem.setIfHouseAdd(false);
                        twItem.setAddUserId(SecurityFrameworkUtils.getLoginUserId());
                        twItem.setAddUserName(SecurityFrameworkUtils.getLoginUserNickname());
                        return twItem;
                    }).collect(Collectors.toList());
            if (CollectionUtil.isEmpty(list)) {
                throw exception0(500, "配件列表为空");
            }
            twItemService.saveOrUpdateBatch(list);
        }

        // 通知对应的维修服务顾问和总检
        // 维修服务顾问即创建工单时选的是谁
        repairWorkerService.sentMessage(SystemEnum.REPAIR.getCode(),Long.valueOf(tickets.getAdviserId()), "您有新的配件申请单需要审核");
        // 总检查角色包含总检的员工
        // 取这个角色的角色信息
        RoleReqDTO roleInfo = roleApi.getRoleInfo(RepairRoleEnum.INSPECTION.getCode());
        // 通过角色信息查有这个角色的人
        List<Long> ids = permissionApi.getUserIdByRoleId(roleInfo.getId());
        // 发通知
        if (CollectionUtil.isNotEmpty(ids)) {
            ids.forEach(id -> repairWorkerService.sentMessage(SystemEnum.REPAIR.getCode(),id, "您有新的配件申请单需要审核"));
        }

        // 更新工单主表时间
        if (ObjectUtil.isNotEmpty(respVO.getTicketId())){
            repairTicketsService.refreshUpdateTime(respVO.getTicketId());
        }
    }

    /**
     * 删除
     *
     * @param id id
     * @author 小李
     * @date 12:21 2024/10/15
     **/
    @Override
    @DSTransactional
    public void removeTicketWares(String id) {
        // 更新工单主表时间
        DlTicketWares ticketWares = baseMapper.selectById(id);
        if (ObjectUtil.isNotEmpty(ticketWares) && ObjectUtil.isNotEmpty(ticketWares.getTicketId())){
            repairTicketsService.refreshUpdateTime(ticketWares.getTicketId());
        }
        // 删除主表
        baseMapper.deleteById(id);
        // 删除子表
        twItemService.remove(new LambdaQueryWrapper<DlTwItem>().eq(DlTwItem::getTwId, id));
    }

    /**
     * 审核
     *
     * @param respVO 请求对象
     * @author 小李
     * @date 21:15 2024/10/15
     **/
    @Override
    @DSTransactional
    public void auditTicketWares(DlTicketWaresRespVO respVO) {
        // 取出前端传的单据状态，这里是前端传的，只有两个，01通过，02驳回
        String status = respVO.getStatus();
        // 取出前端操作的配件申请表的子项id
        List<String> twItemIds = respVO.getItems().stream().map(DlTwItem::getId).collect(Collectors.toList());
        // 查所有的子项
        List<DlTwItem> twItems = twItemService.listByIds(twItemIds);
        // 取所有的配件信息
        List<String> wareIds = twItems.stream().map(DlTwItem::getWaresId).collect(Collectors.toList());
        // 更新配件申请表子表
        List<DlTwItem> newTwitems = twItemIds.stream().map(item -> {
            DlTwItem twItem = new DlTwItem();
            twItem.setId(item);
            twItem.setWaresStatus(status.equals("01") ? "1" : "0");
            twItem.setHandleId(SecurityFrameworkUtils.getLoginUserId());
            twItem.setHandleName(SecurityFrameworkUtils.getLoginUserNickname());
            return twItem;
        }).collect(Collectors.toList());
        twItemService.updateBatchById(newTwitems);
        // 更新配件申请主表
        List<DlTwItem> allTwitems = twItemService.list(new LambdaQueryWrapper<DlTwItem>().in(DlTwItem::getTwId, respVO.getId()));
        List<DlTwItem> passTwitems = allTwitems.stream().filter(item -> item.getWaresStatus().equals("1") || item.getWaresStatus().equals("0")).collect(Collectors.toList());
        boolean isStatus = CollectionUtil.isNotEmpty(passTwitems) && passTwitems.size() == allTwitems.size();
        if (isStatus) {
            baseMapper.update(new LambdaUpdateWrapper<DlTicketWares>().set(DlTicketWares::getStatus, "02").eq(DlTicketWares::getId, respVO.getId()));
        }
        /* 审核配件申请单暂时不操作工单子表 */
//        // 更新维修工单子表
//        List<RepairWares> repairWares = repairWaresService.listByIds(wareIds);
//        if (status.equals("01")) {
//            DlTicketWares ticketWares = baseMapper.selectById(respVO.getId());
//            List<DlRepairTitem> titems = repairTitemService.list(new LambdaQueryWrapper<DlRepairTitem>().and(i -> {
//                i.in(DlRepairTitem::getTicketId, ticketWares.getTicketId())
//                        .eq(DlRepairTitem::getItemType, "02");
//            }));
//            // 要修改的
//            List<DlRepairTitem> updateTitems = titems.stream().filter(item -> wareIds.contains(item.getPartId())).collect(Collectors.toList());
//            // 修改
//            if (CollectionUtil.isNotEmpty(updateTitems)) {
//                List<DlRepairTitem> newTitems = updateTitems.stream().map(item -> {
//                    DlRepairTitem titem = new DlRepairTitem();
//                    titem.setId(item.getId());
//                    DlTwItem twItem = allTwitems.stream().filter(i -> i.getWaresId().equals(item.getPartId())).findFirst().orElse(null);
//                    if (twItem != null) {
//                        titem.setItemCount(item.getItemCount() + twItem.getWaresCount());
//                        titem.setItemMoney(item.getItemPrice().multiply(BigDecimal.valueOf(titem.getItemCount())).multiply(item.getItemDiscount()));
//                    }
//                    return titem;
//                }).collect(Collectors.toList());
//                repairTitemService.updateBatchById(newTitems);
//            }
//            // 要新增的
//            if (updateTitems.size() < wareIds.size()) {
//                List<String> titemIds = updateTitems.stream().map(DlRepairTitem::getPartId).collect(Collectors.toList());
//                List<RepairWares> newWares = repairWares.stream().filter(item -> !titemIds.contains(item.getId())).collect(Collectors.toList());
//                // 新增
//                List<DlRepairTitem> newTitems = newWares.stream().map(item -> {
//                    DlRepairTitem titem = new DlRepairTitem();
//                    titem.setTicketId(ticketWares.getTicketId());
//                    titem.setItemType("02");
//                    titem.setItemName(item.getName());
//                    DlTwItem twItem = allTwitems.stream().filter(i -> i.getWaresId().equals(item.getId())).findFirst().orElse(null);
//                    titem.setItemCount(twItem != null ? twItem.getWaresCount() : 0);
//                    titem.setItemUnit(item.getUnit());
//                    titem.setItemPrice((item.getPrice() != null) ? item.getPrice() : BigDecimal.ZERO);
//                    titem.setItemDiscount(BigDecimal.ONE);
//                    titem.setItemMoney(titem.getItemPrice().multiply(BigDecimal.valueOf(titem.getItemCount())).multiply(titem.getItemDiscount()));
//                    titem.setRepairIds(String.valueOf(ticketWares.getRepairId()));
//                    titem.setRepairNames(ticketWares.getRepairName());
//                    titem.setSaleId(ticketWares.getAdviserId());
//                    titem.setSaleName(ticketWares.getAdviserName());
//                    titem.setPartId(item.getId());
//                    titem.setItemStatus("04");
//                    titem.setRemark(twItem != null ? twItem.getRemark() : null);
//                    return titem;
//                }).collect(Collectors.toList());
//                repairTitemService.saveBatch(newTitems);
//            }
//            // 更新维修工单主表
//            boolean flag = repairTicketsService.computeTicket(ticketWares.getTicketId());
//            if (!flag) {
//                throw exception0(500, "重新计算工单错误");
//            }
//            // 发送通过的消息给仓库
//            RoleReqDTO roleInfo = roleApi.getRoleInfo(RepairRoleEnum.WAREHOUSE.getCode());
//            List<Long> ids = permissionApi.getUserIdByRoleId(roleInfo.getId());
//            if (CollectionUtil.isNotEmpty(ids)) {
//                ids.forEach(id -> repairWorkerService.sentMessage(id, "您有新的配件申请单需要处理"));
//            }
//        }
        // 通知维修工
        DlTicketWares ticketWares = baseMapper.selectById(respVO.getId());
        repairWorkerService.sentMessage(SystemEnum.REPAIR.getCode(),ticketWares.getRepairId(), "您有新的配件申请单" + (status.equals("01") ? "审批通过了" : "被驳回了"));

        //插入记录
        repairRecordsService.saveRepairRecord(respVO.getTicketId(), null, RecordTypeEnum.SPPJSQD.getCode(), "审批配件申请单", null);
    }

    /**
     * 仓库通知领料、退料
     *
     * @param respVO 请求对象
     * @author 小李
     * @date 20:45 2024/10/16
     **/
    @Override
    @DSTransactional
    public void passTicketWares(DlTicketWaresRespVO respVO) {
        respVO.getRepairSo().setSoTime(new Date());
        // 把单据类型先取出来（02是领料，04是退料）
        String type = respVO.getRepairSo().getSoType();
        // 查工单子表中的配件信息
        List<DlRepairTitem> list = repairTitemService.list(new LambdaQueryWrapper<DlRepairTitem>().and(i -> {
                    i.eq(DlRepairTitem::getTicketId, respVO.getTicketId())
                            .in(DlRepairTitem::getPartId, respVO.getRepairSois()
                                    .stream()
                                    .map(DlRepairSoi::getGoodsId)
                                    .collect(Collectors.toList()));
                })
        );
        // 计算总价 （通知领料的数量可能和请求的不一样，所以需要这样计算）
        BigDecimal reduce = list.stream()
                /*
                    item：维修工单子表中的每一个配件
                    map中是找到与item对应的领料单子表的配件，记soi
                    将item的价格设置给soi的价格
                 */
                .map(item -> {
                    DlRepairSoi repairSoi = respVO.getRepairSois().stream()
                            .filter(i -> i.getGoodsId().equals(item.getPartId())).findFirst()
                            .orElse(null);
                    if (repairSoi != null) {
                        repairSoi.setGoodsPrice(item.getItemPrice());
                    }
                    return repairSoi;
                })
                .filter(Objects::nonNull)
                // 计算soi的价格
                .map(i -> new BigDecimal(i.getGoodsCount()).multiply(i.getGoodsPrice()))
                // 计算总价
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        // 生成领料单、退料单
        respVO.getRepairSo().setTotalPrice(reduce);
        respVO.getRepairSo().setItemCount(respVO.getRepairSois().stream().mapToInt(DlRepairSoi::getGoodsCount).sum());
        respVO.getRepairSo().setTwId(respVO.getId());
        repairSoService.save(respVO.getRepairSo());
        // 生成领料单、退料单子表
        respVO.getRepairSois().forEach(item -> {
            item.setSoId(respVO.getRepairSo().getId());
        });
        repairSoiService.saveBatch(respVO.getRepairSois());
        // 更新配件申请子表
        // 分领料和退料
        // 先取出要操作的子表数据
        List<DlTwItem> oldData = twItemService.listByIds(respVO.getIds());
//        List<DlTwItem> oldData = twItemService.list(new LambdaQueryWrapper<DlTwItem>().and(item -> {
//            item.eq(DlTwItem::getTwId, respVO.getRepairSo().getTwId())
//                    .in(DlTwItem::getWaresId, respVO.getRepairSois().stream().map(DlRepairSoi::getGoodsId).collect(Collectors.toList()));
//        }));
        // 要操作的库存数据
        List<RepairWares> wares = repairWaresService.list(new LambdaQueryWrapper<RepairWares>().in(RepairWares::getId, respVO.getRepairSois().stream().map(DlRepairSoi::getGoodsId).collect(Collectors.toList())));
        Map<String, String> waresNameMap = wares.stream().collect(Collectors.toMap(RepairWares::getId, RepairWares::getName));
        StringBuilder remarkStr = new StringBuilder();
        for (int i = 0; i < respVO.getRepairSois().size(); i++) {
            DlRepairSoi repairSoi = respVO.getRepairSois().get(i);
            remarkStr.append(i + 1).append(".").append(waresNameMap.get(repairSoi.getGoodsId())).append("x").append(repairSoi.getGoodsCount()).append("; ");
        }
        if (type.equals("02")) { // 领料
            // 构造新数据
            List<DlTwItem> newData = oldData.stream().map(item -> {
                DlTwItem dlTwItem = new DlTwItem();
                dlTwItem.setId(item.getId());
                respVO.getRepairSois().stream()
                        .filter(i -> i.getGoodsId().equals(item.getWaresId()))
                        .findFirst()
                        .ifPresent(repairSoi -> {
                            // 先取该申请配件的已领料数量，如过是第一次就是0
                            Integer waresAlreadyCount = item.getWaresAlreadyCount() == null ? 0 : item.getWaresAlreadyCount();
                            // 取本来的已领取数量+本次要领取的数量
                            dlTwItem.setWaresAlreadyCount(repairSoi.getGoodsCount() + waresAlreadyCount);
                            // 如果已领取数量等于申请数量，那这个配件就是领料完了，为01已领料，反之不变----这里不变了
//                            dlTwItem.setWaresStatus(item.getWaresCount().equals(dlTwItem.getWaresAlreadyCount()) ? "01" : item.getWaresStatus());
                        });
                return dlTwItem;
            }).collect(Collectors.toList());
            twItemService.updateBatchById(newData);

            // 同时操作库存扣减
            // 构造新数据
            List<RepairWares> newWares = wares.stream().map(item -> {
                RepairWares ware = new RepairWares();
                ware.setId(item.getId());
                respVO.getRepairSois().stream().filter(i -> i.getGoodsId().equals(item.getId())).findFirst().ifPresent(repairSoi -> ware.setStock(item.getStock().subtract(BigDecimal.valueOf(repairSoi.getGoodsCount()))));
                return ware;
            }).collect(Collectors.toList());
            // 更新库存
            repairWaresService.updateBatchById(newWares);
        } else { // 退料
            // 构造新数据
            List<DlTwItem> newData = oldData.stream().map(item -> {
                DlTwItem dlTwItem = new DlTwItem();
                dlTwItem.setId(item.getId());
                respVO.getRepairSois().stream()
                        .filter(i -> i.getGoodsId().equals(item.getWaresId()))
                        .findFirst()
                        .ifPresent(repairSoi -> {
                            // 取本来的已领取数量-本次要退料的数量
                            dlTwItem.setWaresAlreadyCount(item.getWaresAlreadyCount() - repairSoi.getGoodsCount());
//                            dlTwItem.setWaresStatus(repairSoi.getGoodsCount().equals(item.getWaresCount()) ? "04" : item.getWaresStatus());
                            // 如果可领料数量等于申请数量，那这个配件就是退料完了，为03已退料，反之不变---这里也不变了
//                            dlTwItem.setWaresStatus(item.getWaresCount().equals(dlTwItem.getWaresAlreadyCount()) ? "1" : "0");
                        });
                return dlTwItem;
            }).collect(Collectors.toList());
            twItemService.updateBatchById(newData);

            // 同时操作库存新增
            // 构造新数据
            List<RepairWares> newWares = wares.stream().map(item -> {
                RepairWares ware = new RepairWares();
                ware.setId(item.getId());
                respVO.getRepairSois().stream().filter(i -> i.getGoodsId().equals(item.getId())).findFirst().ifPresent(repairSoi -> ware.setStock(item.getStock().add(BigDecimal.valueOf(repairSoi.getGoodsCount()))));
                return ware;
            }).collect(Collectors.toList());
            // 更新库存
            repairWaresService.updateBatchById(newWares);
        }
        //插入记录
        //最后记录操作日志--创建工单
        repairRecordsService.saveRepairRecord(respVO.getTicketId(), null, "02".equals(type) ? RecordTypeEnum.TZLL.getCode() : RecordTypeEnum.TZTL.getCode(),
                ("02".equals(type) ? "通知领料" : "通知退料") + ": " + remarkStr.toString(), respVO.getImages());
        // 通知维修工
        // 查维修工的userId
        repairWorkerService.sentMessage(SystemEnum.REPAIR.getCode(),respVO.getRepairId(), type.equals("02") ? "您有新的领料单需要确认" : "您有新的退料单需要确认");

        // 刷新工单主表时间
        if (ObjectUtil.isNotEmpty(respVO.getTicketId())){
            repairTicketsService.refreshUpdateTime(respVO.getTicketId());
        }
    }

    /**
     * 员工确认领料
     *
     * @param respVO 请求对象
     * @author 小李
     * @date 22:07 2024/10/16 应该是弃用了，但不确定，先不删
     **/
    @Override
    @DSTransactional
    public void repairPassTicketWares(DlTicketWaresRespVO respVO) {
//        // 更新领料申请子表
//        twItemService.updateBatchById(respVO.getItems());
//        // 更新领料申请表
//        // 判断是全部完成完成部分完成
//        List<DlTwItem> list = twItemService.list(new LambdaQueryWrapper<DlTwItem>().eq(DlTwItem::getTwId, respVO.getId()));
//        List<DlTwItem> list1 = list.stream().filter(item -> item.getWaresStatus().equals(respVO.getType().equals("01") ? "01" : "03")).collect(Collectors.toList());
//        respVO.setStatus(list1.size() == list.size() ? "03" : "04");
//        baseMapper.updateById(respVO);
//        // 操作库存
//        list.forEach(item -> {
//            repairWaresService.update(new LambdaUpdateWrapper<RepairWares>()
//                    .setSql("stock = stock" + (respVO.getType().equals("01") ? "-" : "+") + item.getWaresCount())
//                    .eq(RepairWares::getId, item.getWaresId())
//            );
//        });
    }

    /**
     * 仓库确认退料
     *
     * @param respVO 请求对象
     * @author 小李
     * @date 22:03 2024/10/17 应该是弃用了，但不确定，先不删
     **/
    @Override
    public void passBackTicketWares(DlTicketWaresRespVO respVO) {
        // 更新申请单子表状态
        twItemService.updateBatchById(respVO.getItems());
    }

    /**
     * 创建配件申请单
     *
     * @param respVO 请求体
     * @author vinjor-M
     * @date 14:48 2024/10/22
     **/
    @Override
    public void createApplyOrder(DlTicketWaresRespVO respVO) {
        //默认待审核
        respVO.setStatus("01");
        //查维修单信息
        DlRepairTickets tickets = repairTicketsService.getById(respVO.getTicketId());
        respVO.setLicenseNumber(tickets.getCarNo());
        respVO.setAdviserId(Long.valueOf(tickets.getAdviserId()));
        respVO.setAdviserName(tickets.getAdviserName());
        this.save(respVO);
        if (!respVO.getItems().isEmpty()) {
            List<DlTwItem> list = respVO.getItems().stream().map(dlTwItem -> dlTwItem.setTwId(respVO.getId())).collect(Collectors.toList());
            twItemService.saveBatch(list);
        }

        // 更新工单主表时间
        if (ObjectUtil.isNotEmpty(respVO.getTicketId())){
            repairTicketsService.refreshUpdateTime(respVO.getTicketId());
        }
    }

    /**
     * 维修工的角度查提交的配件申请单\待确认领料单\待确认退料单 待处理数量
     *
     * @author vinjor-M
     * @date 15:38 2024/10/22
     **/
    @Override
    public Map<String, Integer> getWorkerTodo() {
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        LambdaQueryWrapper<DlTicketWares> queryWrapper = new LambdaQueryWrapper<DlTicketWares>()
                .eq(DlTicketWares::getRepairId, loginUser.getId());
        List<DlTicketWares> list = this.list(queryWrapper);
        Map<String, Integer> rtnMap = new HashMap<>();
        //所有提交的
        Integer submitNum = list.size();
        //已通过的
        Integer allowNum = 0;
        //未通过的
        Integer noAllowNum = 0;
        //待确认领料单
        Integer waitingReceiveNum = dlRepairSoMapper.selectCountNum("02", loginUser.getId(), SoStatusEnum.TO_BE_PICKED.getCode());
        //待确认退料单
        Integer waitingBackNum = dlRepairSoMapper.selectCountNum("04", loginUser.getId(), SoStatusEnum.TO_BE_RETURNED.getCode());
        for (DlTicketWares wares : list) {
            if ("02".equals(wares.getStatus())) {
                //已通过
                allowNum++;
            } else if ("05".equals(wares.getStatus())) {
                //被驳回
                noAllowNum++;
            }
        }
        rtnMap.put("submitNum", submitNum);
        rtnMap.put("allowNum", allowNum);
        rtnMap.put("noAllowNum", noAllowNum);
        rtnMap.put("waitingReceiveNum", waitingReceiveNum);
        rtnMap.put("waitingBackNum", waitingBackNum);
        return rtnMap;
    }

    /**
     * 修改是否传给保险公司
     *
     * @author 小李
     * @date 15:48 2024/11/18
     * @param respVO 对象
     **/
    @Override
    public void updateSafe(DlTicketWaresRespVO respVO){
        // 先取出状态
        String toSafe = respVO.getToSafe();
        // 准备更新条件
        LambdaUpdateWrapper<DlTicketWares> lambdaUpdate = Wrappers.lambdaUpdate(DlTicketWares.class);
        lambdaUpdate.eq(DlTicketWares::getId, respVO.getId());
        lambdaUpdate.set(DlTicketWares::getToSafe, respVO.getToSafe());
        // 根据状态更新
        if (toSafe.equals("1")){
            lambdaUpdate.set(DlTicketWares::getSafeName, respVO.getSafeName());
            lambdaUpdate.set(DlTicketWares::getSafeContact, respVO.getSafeContact());
            lambdaUpdate.set(DlTicketWares::getSafeMobile, respVO.getSafeMobile());
        }
        // 更新
        baseMapper.update(lambdaUpdate);
    }

    /**
     * 根据选择的配件生成采购单需要的数据
     *
     * @author 小李
     * @date 18:14 2024/11/18
     * @param ids ids
     **/
    @Override
    public Map<String, List<DlTwItemRespVO>> getByIds(List<String> ids){
        // 查配件申请表子表
        List<DlTwItem> twItems = twItemService.listByIds(ids);
        // 查配件
        List<String> waresIds = twItems.stream().map(DlTwItem::getWaresId).collect(Collectors.toList());
        List<RepairWares> wares = repairWaresService.listByIds(waresIds);
        // 关联配件申请表子项和配件
        List<DlTwItemRespVO> newTwItems = twItems.stream().map(item -> {
            DlTwItemRespVO twItem = BeanUtil.toBean(item, DlTwItemRespVO.class);
            RepairWares ware = wares.stream().filter(i -> i.getId().equals(item.getWaresId())).findFirst().orElse(null);
            if (ware != null) {
                twItem.setWares(ware);
            }
            return twItem;
        }).collect(Collectors.toList());
        // 分组
        Map<String, List<DlTwItemRespVO>> map = newTwItems.stream().collect(Collectors.groupingBy(item -> {
            String key = item.getWares().getType();
            return key != null && !key.isEmpty() ? key : "default";
        }));
        // 查分类
        List<BaseType> baseTypes = baseTypeService.listByIds(map.keySet());
        Map<String, String> TypeMap = baseTypes.stream().collect(Collectors.toMap(BaseType::getId, BaseType::getName));
        // 映射
        Map<String, List<DlTwItemRespVO>> result = new HashMap<>();
        for (Map.Entry<String, List<DlTwItemRespVO>> entry : map.entrySet()) {
            String key = entry.getKey();
            String newKey = TypeMap.get(key);
            if (newKey == null || newKey.isEmpty()) {
                newKey = "未分类";
            }
            result.put(newKey, entry.getValue());
        }
        return result;
    }
}




