package cn.ezhizao.project.business.controller;

import cn.ezhizao.common.utils.SecurityUtils;
import cn.ezhizao.common.utils.poi.ExcelUtil;
import cn.ezhizao.framework.aspectj.lang.annotation.Log;
import cn.ezhizao.framework.aspectj.lang.enums.BusinessType;
import cn.ezhizao.framework.redis.RedisCache;
import cn.ezhizao.framework.web.controller.BaseController;
import cn.ezhizao.framework.web.domain.AjaxResult;
import cn.ezhizao.framework.web.page.TableDataInfo;
import cn.ezhizao.project.business.domain.*;
import cn.ezhizao.project.business.service.*;
import cn.ezhizao.project.system.domain.SysDept;
import cn.ezhizao.project.system.mapper.SysDeptMapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 外协单主
 * 带箱方式，是整单的。如果换新箱子，明细中，都需要更换箱子Controller
 *
 * @author ezhizao
 * @date 2024-05-08
 */
@RestController
@RequestMapping("/business/returnTurnover")
public class BizReturnTurnoverController extends BaseController {
    @Resource
    private IBizReturnReceiptService bizReturnReceiptService;
    @Resource
    private IBizReturnReceiptDetailService bizReturnReceiptDetailService;
    @Resource
    private IBizOutsourcedOrderDetailProcessService bizOutsourcedOrderDetailProcessService;
    @Resource
    private IBizTechnologicalProcessService bizTechnologicalProcessService;
    @Resource
    private IBizProductionPlanDetailService bizProductionPlanDetailService;
    @Resource
    private IBizCarrierService carrierService;
    @Resource
    private IBizDayworkItemService bizDayworkItemService;
    @Resource
    private IBizDayworkCarrierService bizDayworkCarrierService;
    @Resource
    private IBizLotTechnologicalProcessService bizLotTechnologicalProcessService;
    @Resource
    private IBizProductionResourceGroupSubPlanService bizProductionResourceGroupSubPlanService;
    @Resource
    private IBizOutsourcedOrderDetailService bizOutsourcedOrderDetailService;
    @Resource
    private IBizDayworkService bizDayworkService;
    @Resource
    private IBizProcessInspecionService bizProcessInspecionService;
    @Resource
    private IBizProductionResourceGroupService bizProductionResourceGroupService;
    @Resource
    private IBizCarrierCategoryService carrierCategoryService;
    @Resource
    private IBizTakeStockPeriodService bizTakeStockPeriodService;
    @Resource
    private SysDeptMapper sysDeptMapper;
    @Resource
    private IBizDayworkItemExamineService bizDayworkItemExamineService;
    @Resource
    private IBizCarrierCategoryService bizCarrierCategoryService;
    @Resource
    private IBizCarrierService bizCarrierService;
    @Resource
    private RedisCache redisCache;
    @Resource
    HttpServletRequest request;

    /**
     * 查询外协单主
     * 带箱方式，是整单的。如果换新箱子，明细中，都需要更换箱子列表
     */
    @PreAuthorize("@ss.hasPermi('business:returnTurnover:list')")
    @GetMapping("/getFinishedReturnList")
    @Log(title = "获取外协收回周转列表", businessType = BusinessType.SELECT)
    public TableDataInfo getFinishedReturnList(BizOutsourcedOrderDetail bizOutsourcedOrderDetail) throws NoSuchFieldException, IllegalAccessException {
        setTenantId(bizOutsourcedOrderDetail);
        if (bizOutsourcedOrderDetail.getStartTime() != null) {
            bizOutsourcedOrderDetail.setStartTime(bizOutsourcedOrderDetail.getStartTime() + " 00:00:00");
        }
        if (bizOutsourcedOrderDetail.getEndTime() != null) {
            bizOutsourcedOrderDetail.setEndTime(bizOutsourcedOrderDetail.getEndTime() + " 23:59:59");
        }
        startPage();
        List<BizOutsourcedOrderDetail> list = bizOutsourcedOrderDetailService.getFinishedReturnList(bizOutsourcedOrderDetail);
        list.forEach(item -> {
            if (item.getInspectionStatus() == null) {
                item.setInspectionStatus(-1);
            }
        });
        //查询周转到外协的工序
        List<Long> outsourceDetailIds = list.stream().map(BizOutsourcedOrderDetail::getId).collect(Collectors.toList());
        List<Long> dayworkIds = list.stream().map(BizOutsourcedOrderDetail::getDayworkId).collect(Collectors.toList());
        List<BizDaywork> dayworks = bizDayworkService.query().in("id", dayworkIds.isEmpty() ? Collections.singletonList(0L) : dayworkIds).list();
        if (!dayworkIds.isEmpty()) {
            List<BizOutsourcedOrderDetailProcess> outsourceDetailProcess = bizOutsourcedOrderDetailProcessService.query().in("detail_id", outsourceDetailIds).list();
            //如果下道序扫码开始新批次了，则不能编辑载具和周转信息
            List<BizDayworkItem> dayworkItemList = bizDayworkItemService.getListByDayworkIds(dayworkIds);
            List<BizDayworkCarrier> dayworkCarrierList = bizDayworkCarrierService.query().in("daywork_id", dayworkIds).eq("is_changed",0).list();
            for (BizOutsourcedOrderDetail detail : list) {
                detail.setFlag(true);
                //拿到最新的工序
                BizOutsourcedOrderDetailProcess lastProcess = outsourceDetailProcess.stream().filter(process -> process.getDetailId().equals(detail.getId())).sorted(Comparator.comparing(BizOutsourcedOrderDetailProcess::getProcessStepNumber).reversed()).collect(Collectors.toList()).get(0);
                //拿到最新的一条报工
                BizDayworkItem lastItem = dayworkItemList.stream().filter(dayworkItem -> dayworkItem.getDayworkId().equals(detail.getDayworkId())).sorted(Comparator.comparing(BizDayworkItem::getProcessStepNumber).thenComparing(BizDayworkItem::getCreateTime).reversed()).collect(Collectors.toList()).stream().findFirst().orElse(null);
                if (lastItem != null && !Objects.equals(lastProcess.getProcessStepNumber(), lastItem.getProcessStepNumber())) {
                    detail.setFlag(false);
                }
                //判断当前批次绑定箱是否包含无箱
                detail.setHasIsNoneCarrier(false);
                List<BizDayworkCarrier> dayworkCarrier = dayworkCarrierList.stream().filter(l -> l.getDayworkId().equals(detail.getDayworkId())).collect(Collectors.toList());
                if(!dayworkCarrier.isEmpty()) {
                    List<BizCarrier> carrier = bizCarrierService.query().in("id", dayworkCarrier.stream().map(BizDayworkCarrier::getCarrierId).collect(Collectors.toList())).list();
                    List<BizCarrierCategory> bizCarrierCategories = bizCarrierCategoryService.query().in("id", carrier.isEmpty() ? Collections.singletonList(0L) : carrier.stream().map(BizCarrier::getCategoryId).collect(Collectors.toList())).list();
                    if (!bizCarrierCategories.isEmpty()) {
                        // 是否有无箱的
                        if (bizCarrierCategories.stream().anyMatch(v -> v.getIsNone().equals(1))) {
                            detail.setHasIsNoneCarrier(true);
                        }
                    }
                }
                BizDaywork daywork = dayworks.stream().filter(l -> l.getId().equals(detail.getDayworkId())).findFirst().orElse(null);
                if (daywork != null) {
                    detail.setIsAmend(daywork.getIsAmend());
                    detail.setIsWaste(daywork.getIsWaste());
                    detail.setIsWasteRecycling(Integer.parseInt(daywork.getIsWasteRecycling().toString()));
                    detail.setIsSuperaddition(daywork.getIsSuperaddition());
                }

            }
//            List<BizDayworkCarrier> dayworkCarrierList = bizDayworkCarrierService.query().in("daywork_id", dayworkIds).eq("is_changed",0).list();
//            for (BizOutsourcedOrderDetail detail : list) {
//                if(!detail.getProductionCarrier().isEmpty()) {
//                    List<String> carrierCode = Arrays.stream(detail.getProductionCarrier().split(",")).collect(Collectors.toList());
//                    List<Long> carrierIds = bizDayworkCarrierService.query().in("carrier_code", carrierCode).eq("is_changed",0).list().stream().map(BizDayworkCarrier::getCarrierId).collect(Collectors.toList());
//                    detail.setDayworkCarrierList(dayworkCarrierList.stream().filter(carrier -> carrier.getDayworkId().equals(detail.getDayworkId())).collect(Collectors.toList()));
//                    detail.setCarrierIds(carrierIds);
//                }else {
//                    //用的原箱
//                    if ("0".equals(detail.getPackagingMethod())) {
//                        List<Long> carrierIds = dayworkCarrierList.stream().filter(carrier -> carrier.getDayworkId().equals(detail.getDayworkId())).map(BizDayworkCarrier::getCarrierId).collect(Collectors.toList());
//                        detail.setCarrierIds(carrierIds);
//                        detail.setDayworkCarrierList(dayworkCarrierList.stream().filter(carrier -> carrier.getDayworkId().equals(detail.getDayworkId())).collect(Collectors.toList()));
//                    } else {
//                        //外协使用新箱，则把新箱解绑，返回空
//                        List<BizDayworkCarrier> wxCarrier = dayworkCarrierList.stream().filter(carrier -> carrier.getDayworkId().equals(detail.getDayworkId())).collect(Collectors.toList());
//                        wxCarrier.stream().forEach(carrier -> {
//                            carrier.setIsChanged(1);
//                        });
//                        bizDayworkCarrierService.updateBatchById(wxCarrier);
//                        detail.setCarrierIds(new ArrayList<>());
//                    }
//                }
//            }
        }
        return getDataTable(list);
    }

    @PostMapping("/getNowBindCarriers")
    @Log(title = "获取当前绑定载具", businessType = BusinessType.SELECT)
    public AjaxResult getNowBindCarriers(@RequestBody BizOutsourcedOrderDetail bizOutsourcedOrderDetail) throws NoSuchFieldException, IllegalAccessException {
        List<BizDayworkCarrier> dayworkCarrierList = bizDayworkCarrierService.query().eq("daywork_id", bizOutsourcedOrderDetail.getDayworkId()).eq("is_changed", 0).list();
        if (!bizOutsourcedOrderDetail.getProductionCarrier().isEmpty()) {
            List<String> carrierCode = Arrays.stream(bizOutsourcedOrderDetail.getProductionCarrier().split(",")).collect(Collectors.toList());
            List<Long> carrierIds = bizDayworkCarrierService.query().in("carrier_code", carrierCode).eq("is_changed", 0).eq("daywork_id",bizOutsourcedOrderDetail.getDayworkId()).list().stream().map(BizDayworkCarrier::getCarrierId).collect(Collectors.toList());
            bizOutsourcedOrderDetail.setDayworkCarrierList(dayworkCarrierList.stream().filter(carrier -> carrier.getDayworkId().equals(bizOutsourcedOrderDetail.getDayworkId())).collect(Collectors.toList()));
            bizOutsourcedOrderDetail.setCarrierIds(carrierIds);
        } else {
//          if("1".equals(bizOutsourcedOrderDetail.getPackagingMethod())){
//                //外协使用新箱，则把新箱解绑，返回空
//                List<BizDayworkCarrier> wxCarrier = dayworkCarrierList.stream().filter(carrier -> carrier.getDayworkId().equals(bizOutsourcedOrderDetail.getDayworkId())).collect(Collectors.toList());
//                wxCarrier.stream().forEach(carrier -> {
//                    carrier.setIsChanged(1);
//                });
//                bizDayworkCarrierService.updateBatchById(wxCarrier);
//                bizOutsourcedOrderDetail.setCarrierIds(new ArrayList<>());
//            }else {
                List<Long> carrierIds = dayworkCarrierList.stream().filter(carrier -> carrier.getDayworkId().equals(bizOutsourcedOrderDetail.getDayworkId())).map(BizDayworkCarrier::getCarrierId).collect(Collectors.toList());
                //如果箱子存在外协箱，则解绑外协箱
                if(!carrierIds.isEmpty()){
                    List<BizCarrier> carrierList = bizCarrierService.query().in("id", carrierIds).list();
                    List<BizCarrierCategory> carrierCategoryList = bizCarrierCategoryService.query().in("id", carrierList.stream().map(BizCarrier::getCategoryId).collect(Collectors.toList())).list();
                    if(carrierCategoryList.stream().anyMatch(v->v.getName().equals("外协箱"))){
                        List<BizCarrierCategory> wxCarrierCategory = carrierCategoryList.stream().filter(v -> v.getName().equals("外协箱")).collect(Collectors.toList());
                        //存在外协箱类型的箱子，解绑载具
                        List<BizCarrier> wxCarrier = carrierList.stream().filter(carrier -> wxCarrierCategory.stream().map(BizCarrierCategory::getId).collect(Collectors.toList()).contains(carrier.getCategoryId())).collect(Collectors.toList());
                        List<BizDayworkCarrier> removeDayworkCarriers = new ArrayList<>();
                        List<BizDayworkCarrier> lastDayworkCarriers = new ArrayList<>();
                        dayworkCarrierList.forEach(carrier -> {
                            if(wxCarrier.stream().map(BizCarrier::getId).collect(Collectors.toList()).contains(carrier.getCarrierId())){
                                carrier.setIsChanged(1);
                                removeDayworkCarriers.add(carrier);
                            }else{
                                lastDayworkCarriers.add(carrier);
                            }
                        });
                        bizDayworkCarrierService.updateBatchById(removeDayworkCarriers);
                        carrierIds = lastDayworkCarriers.stream().map(BizDayworkCarrier::getCarrierId).collect(Collectors.toList());
                        dayworkCarrierList = lastDayworkCarriers;
                    }

                }
                bizOutsourcedOrderDetail.setCarrierIds(carrierIds);
                bizOutsourcedOrderDetail.setDayworkCarrierList(dayworkCarrierList.stream().filter(carrier -> carrier.getDayworkId().equals(bizOutsourcedOrderDetail.getDayworkId())).collect(Collectors.toList()));
        }
        return success(bizOutsourcedOrderDetail);
    }

    /**
     * 查询周转工段
     */
    @GetMapping("/getTurnoverDeptList")
    @Log(title = "获取周转部门列表", businessType = BusinessType.SELECT)
    public AjaxResult getTurnoverDeptList(BizReturnReceiptDetail bizReturnReceiptDetail) throws NoSuchFieldException, IllegalAccessException {
        List<SysDept> departments = new ArrayList<>();
        BizDaywork daywork = bizDayworkService.query().eq("id", bizReturnReceiptDetail.getDayworkId()).list().get(0);
        daywork.setProcessStepNumber(bizReturnReceiptDetail.getProcessStepNumber());
        BizDaywork info = new BizDaywork();
        if (daywork.getIsWasteRecycling() == 1 || daywork.getIsAmend() == 1) {
            departments = bizReturnReceiptDetailService.getTurnoverAbDeptList(daywork);
        } else {
            departments = bizReturnReceiptDetailService.getTurnoverDeptList(daywork);
        }
        return success(departments);
    }

    @PostMapping("/getProcessInspectionList")
    @Log(title = "获取工序", businessType = BusinessType.SELECT)
    public AjaxResult getProcessInspectionList(@RequestBody BizOutsourcedOrderDetailProcess bizOutsourcedOrderDetailProcess) throws NoSuchFieldException, IllegalAccessException {
        Boolean flag = false;
        List<BizProcessInspecion> processInspecions = bizProcessInspecionService.query().eq("return_receipt_detail_id", bizOutsourcedOrderDetailProcess.getReturnReceiptDetailId()).orderByDesc("create_time").list();
        if (processInspecions.size() > 0 && processInspecions.get(0).getStatus() == 1) {
            flag = true;
            return success(flag);
        }
        return success(flag);
    }

    @PostMapping("/getProcessInspectionLists")
    @Log(title = "获取序检列表", businessType = BusinessType.SELECT)
    public AjaxResult getProcessInspectionLists(@RequestBody List<BizOutsourcedOrderDetailProcess> bizOutsourcedOrderDetailProcess) throws NoSuchFieldException, IllegalAccessException {
        boolean flag = false;
        List<BizProcessInspecion> processInspecions = bizProcessInspecionService.query().in("return_receipt_detail_id", bizOutsourcedOrderDetailProcess.stream().map(BizOutsourcedOrderDetailProcess::getReturnReceiptDetailId).collect(Collectors.toList())).orderByDesc("create_time").list();
        if (processInspecions.size() > 0 && bizOutsourcedOrderDetailProcess.stream().allMatch(t -> processInspecions.stream().filter(e -> e.getStatus().equals(1)).anyMatch(e -> e.getReturnReceiptDetailId().equals(t.getReturnReceiptDetailId())))) {
            flag = true;
            return success(flag);
        }
        return success(flag);
    }

    /**
     * 修改外协单主
     * 带箱方式，是整单的。如果换新箱子，明细中，都需要更换箱子
     */
    @PreAuthorize("@ss.hasPermi('business:returnTurnover:edit')")
    @Log(title = "修改外协单，外协周转", businessType = BusinessType.UPDATE)
    @Transactional
    @PutMapping
    public AjaxResult edit(@RequestBody BizOutsourcedOrderDetail outsourcedOrderDetail) throws NoSuchFieldException, IllegalAccessException {
        //判断盘点
        BizTakeStockPeriod bizTakeStockPeriod = bizTakeStockPeriodService.query().eq("status", 1).one();
        if (bizTakeStockPeriod != null && bizTakeStockPeriod.getStatus() == 1) {
            return error("正在盘点，不能周转");
        }
        //判断箱子是否没被占用
        List<Long> carrierIds = outsourcedOrderDetail.getCarriers().stream().map(BizCarrier::getId).collect(Collectors.toList());
        List<BizCarrier> carrierList = carrierService.query().in("id", carrierIds).list();
        //拿到其中的蓝箱子
        List<BizCarrier> blueCarrierList = carrierList.stream().filter(bizCarrier -> bizCarrier.getCategoryId().equals(2L)).collect(Collectors.toList());
        List<Long> blueCarrierIds = blueCarrierList.stream().map(BizCarrier::getId).collect(Collectors.toList());
        List<BizDayworkCarrier> dayworkCarrierList = bizDayworkCarrierService.query().in("carrier_id", blueCarrierIds.isEmpty() ? Collections.singletonList(0L) : blueCarrierList.stream().map(BizCarrier::getId).collect(Collectors.toList())).ne("daywork_id", outsourcedOrderDetail.getDayworkId()).eq("is_changed", 0).list();
        if (dayworkCarrierList.size() > 0) {
            String alreadyUseCarrierList = dayworkCarrierList.stream().map(BizDayworkCarrier::getCarrierCode).collect(Collectors.joining(","));
            return error("载具" + alreadyUseCarrierList + "已被占用");
        }
        //判断箱子是否是同类型
        List<Long> collect = carrierList.stream().map(BizCarrier::getCategoryId).distinct().collect(Collectors.toList());
        List<BizCarrierCategory> carrierCategoryList = bizCarrierCategoryService.query().in("id", collect).list();
        if (collect.size() > 1) {
            return error("箱子类型不一致");
        }
        //判断是否有多个铁箱子
        List<BizCarrierCategory> ironCarrierList = carrierCategoryList.stream().filter(item->item.getIsAllowMore()==1).collect(Collectors.toList());
        if (!ironCarrierList.isEmpty() && carrierIds.size()>1) {
            return error("一个批次不能绑多个铁箱子");
        }
        //如果绑定铁箱子，判断该批次是否能绑定该铁箱（一个计划单能绑定同一个铁箱）
        if (!ironCarrierList.isEmpty() && carrierIds.size()==1) {

            List<BizCarrier> ironCarrier= carrierList.stream().filter(v -> ironCarrierList.stream().map(BizCarrierCategory::getId).collect(Collectors.toList()).contains(v.getCategoryId())).collect(Collectors.toList());
            List<BizDayworkCarrier> iconDayworkCarrierList = bizDayworkCarrierService.query().ne("daywork_id", outsourcedOrderDetail.getDayworkId()).eq("carrier_id", ironCarrier.get(0).getId()).eq("is_changed", 0).list();
            if (iconDayworkCarrierList.size() > 0) {
                //铁箱子的报工
                BizDaywork iconDaywork = bizDayworkService.query().eq("id", iconDayworkCarrierList.get(0).getDayworkId()).list().get(0);
                //退回单的报工
                BizDaywork returnDaywork = bizDayworkService.query().eq("id", outsourcedOrderDetail.getDayworkId()).list().get(0);
                if (!iconDaywork.getProductionPlanDetailId().equals(returnDaywork.getProductionPlanDetailId())) {
                    return error("计划单不同，不能绑定该铁箱");
                }
                //如果铁箱绑定的批次已经周转，则不允许绑定这个铁箱
                List<BizDayworkItem> dayworkItemList = bizDayworkItemService.query().eq("daywork_id", iconDaywork.getId()).orderByDesc("process_step_number").orderByDesc("create_time").list();
                if(dayworkItemList.get(0).getStatus().compareTo("3")>0){
                    return error("该铁箱已周转，不能绑定");
                }
            }
        }
        //操作dayworkCarrier表，如果该批次已经绑箱，把对应箱解绑，并重新绑定新箱子
        List<BizDayworkCarrier> returnDayworkCarrierList = bizDayworkCarrierService.query().eq("daywork_id", outsourcedOrderDetail.getDayworkId()).eq("process_inspection_id", 0L).eq("is_changed", 0).list();
        if (returnDayworkCarrierList.size() > 0) {
            returnDayworkCarrierList.stream().forEach(bizDayworkCarrier -> {
                bizDayworkCarrier.setIsChanged(1);
            });
            bizDayworkCarrierService.updateBatchById(returnDayworkCarrierList);
        }
        List<BizDayworkCarrier> newDayworkCarrierList = new ArrayList<>();
        for (BizCarrier bizCarrier : outsourcedOrderDetail.getCarriers()) {
            BizDayworkCarrier bizDayworkCarrier = new BizDayworkCarrier();
            bizDayworkCarrier.setCarrierId(bizCarrier.getId());
            bizDayworkCarrier.setCarrierCode(bizCarrier.getCode());
            bizDayworkCarrier.setDayworkId(outsourcedOrderDetail.getDayworkId());
            bizDayworkCarrier.setLotId(outsourcedOrderDetail.getLotId());
            newDayworkCarrierList.add(bizDayworkCarrier);
        }
        bizDayworkCarrierService.saveBatch(newDayworkCarrierList);
        //箱子绑定了哪些批次
        List<BizDayworkCarrier> bizCarrierList = bizDayworkCarrierService.query().in("carrier_id", carrierIds).eq("is_changed",0).list();
        List<Long> dayworkIds = bizCarrierList.stream().map(BizDayworkCarrier::getDayworkId).collect(Collectors.toList());
        List<BizDaywork> allDayworkList =  bizDayworkService.query().in("id", dayworkIds).list();
        List<BizDayworkItem> allDayworkItemList =  bizDayworkItemService.getListInfoByDayworkIds(dayworkIds);
        //一个箱号绑定的所有发出单明细
        List<BizOutsourcedOrderDetail> outsourceOrderDetailList = bizOutsourcedOrderDetailService.query().eq("master_id", outsourcedOrderDetail.getMasterId()).in("daywork_id", dayworkIds).list();
        List<BizReturnReceiptDetail> returnReceiptDetailList = bizReturnReceiptDetailService.query().in("outsource_detail_id", outsourceOrderDetailList.stream().map(BizOutsourcedOrderDetail::getId).collect(Collectors.toList())).list();

        for (Long dayworkId : dayworkIds) {
            BizDaywork currentDaywork =  allDayworkList.stream().filter(v -> v.getId().equals(dayworkId)).findFirst().orElse(null);
            BizDayworkItem currentDayworkItem = allDayworkItemList.stream()
                    .filter(v -> v.getDayworkId().equals(dayworkId)).sorted(Comparator.comparing(BizDayworkItem::getProcessStepNumber).reversed())
                    .sorted(Comparator.comparing(BizDayworkItem::getCreateTime).reversed()).findFirst().orElse(null);
            //下序分选包装审核
            if (outsourcedOrderDetail.getIsSortPackaging() != null && outsourcedOrderDetail.getIsSortPackaging() == 1) {
                List<BizDayworkItemExamine> dayworkItemExamineList = bizDayworkItemExamineService.query().eq("daywork_id", dayworkId).list();
                if (!dayworkItemExamineList.isEmpty()) {
                    bizDayworkItemExamineService.removeBatchByIds(dayworkItemExamineList);
                }
                //新增
                BizDayworkItemExamine examine = new BizDayworkItemExamine();
                examine.setDayworkId(dayworkId);
                examine.setDayworkItemId(currentDayworkItem.getId());
                examine.setDeptId(outsourcedOrderDetail.getProductionDeptId());
                examine.setProductionPlanDetailId(outsourcedOrderDetail.getProductionPlanDetailId());
                examine.setProductDescription(outsourcedOrderDetail.getProductDescription());
                examine.setLotId(currentDaywork.getLotId());
                examine.setLotCode(currentDaywork.getLotCode());
                examine.setProductId(outsourcedOrderDetail.getProductId());
                examine.setTechnologicalProcessId(currentDayworkItem.getTechnologicalProcessId());
                examine.setTechnologicalProcessDetailId(currentDayworkItem.getTechnologicalProcessDetailId());
                examine.setProcessId(currentDayworkItem.getProcessId());
                examine.setProcessAlias(currentDayworkItem.getProcessAlias());
                examine.setStatus(0);
                bizDayworkItemExamineService.save(examine);
            }
//           //箱子判断完，修改收回单明细的箱号和周转工段
//           bizOutsourcedOrderDetailService.updateById(outsourcedOrderDetail);
            //拿到外协的最后一条报工
            List<Long> dayworks = new ArrayList<>();
            dayworks.add(dayworkId);
            BizDayworkItem lastDayworkItem = bizDayworkItemService.getListByDayworkIdsForOutsourced(dayworks).stream().sorted(Comparator.comparing(BizDayworkItem::getProcessStepNumber).reversed()).collect(Collectors.toList()).get(0);
            //判断dayworkItem最新的一条状态，如果是7，则把这条删除，重新新增
            List<BizDayworkItem> dayworkItem = bizDayworkItemService.getListByDayworkIds(dayworks);
            BizDayworkItem bizDayworkItem = dayworkItem.stream().sorted(Comparator.comparing(BizDayworkItem::getProcessStepNumber).thenComparing(BizDayworkItem::getCreateTime).reversed()).collect(Collectors.toList()).get(0);
            if ("4".equals(bizDayworkItem.getStatus())) {
                bizDayworkItemService.removeById(bizDayworkItem);
            }
//            BizDaywork bizDaywork = bizDayworkService.query().eq("id", outsourcedOrderDetail.getDayworkId()).list().get(0);
            //添加周转的一条dayworkItem
            BizDayworkItem newBizDayworkItem = new BizDayworkItem();
            //拿到周转到外协的最后一条数据
            if (currentDaywork.getIsAmend() == 1) {
                newBizDayworkItem.setFormDayworkItemId(1L);
            }
            BizOutsourcedOrderDetail currentOutsourceDetail = outsourceOrderDetailList.stream().filter(v -> v.getDayworkId().equals(dayworkId)).findFirst().orElse(null);
            BizReturnReceiptDetail currentReturnDetail = returnReceiptDetailList.stream().filter(v -> v.getDayworkId().equals(dayworkId)).sorted(Comparator.comparing(BizReturnReceiptDetail::getProcessStepNumber).reversed()).findFirst().orElse(null);
            newBizDayworkItem.setDayworkId(currentDaywork.getId());
            newBizDayworkItem.setProductionPlanDetailId(lastDayworkItem.getProductionPlanDetailId());
            newBizDayworkItem.setLotId(currentDaywork.getLotId());
            newBizDayworkItem.setProdNum(currentReturnDetail.getAuditNum());
            newBizDayworkItem.setQualifiedNum(currentReturnDetail.getAuditNum());
            newBizDayworkItem.setTechnologicalProcessId(lastDayworkItem.getTechnologicalProcessId());
            newBizDayworkItem.setTechnologicalProcessDetailId(lastDayworkItem.getTechnologicalProcessDetailId());
            newBizDayworkItem.setProcessStepNumber(lastDayworkItem.getProcessStepNumber());
            newBizDayworkItem.setProcessId(lastDayworkItem.getProcessId());
            newBizDayworkItem.setDeptId(outsourcedOrderDetail.getProductionDeptId());
            newBizDayworkItem.setDeptName(outsourcedOrderDetail.getProductionDeptName());
            newBizDayworkItem.setIsWx(1);
            newBizDayworkItem.setStatus("4");
            newBizDayworkItem.setNickName("外协");
            newBizDayworkItem.setStartTime(new Date());
            if (newBizDayworkItem.getDeptId().equals(114L)) {
                newBizDayworkItem.setTurnoverType("3");
            } else {
                newBizDayworkItem.setTurnoverType("2");
            }
            newBizDayworkItem.setIsWx(1);
            newBizDayworkItem.setTurnoverArea("外协周转区");
            newBizDayworkItem.setFromDeptId(lastDayworkItem.getDeptId());
            newBizDayworkItem.setFromDeptName(lastDayworkItem.getDeptName());
            newBizDayworkItem.setTenantId(SecurityUtils.getLoginUser().getTenantId());
            bizDayworkItemService.save(newBizDayworkItem);
            //修改daywork主表数据

            currentDaywork.setProcessQualifiedNum(currentReturnDetail.getAuditNum());
            currentDaywork.setTemporaryProcessQualifiedNum(currentReturnDetail.getAuditNum());
            currentDaywork.setDeptId(outsourcedOrderDetail.getProductionDeptId());
            bizDayworkService.updateById(currentDaywork);
        }
        //修改发出单
        outsourceOrderDetailList.forEach(item ->{
            item.setProductionCarrier(outsourcedOrderDetail.getProductionCarrier());
            item.setProductionDeptId(outsourcedOrderDetail.getProductionDeptId());
        });
        bizOutsourcedOrderDetailService.updateBatchById(outsourceOrderDetailList);
        // 自动派活
        SysDept sysDept = sysDeptMapper.selectDeptById(outsourcedOrderDetail.getProductionDeptId());

        List<BizProductionResourceGroup> productionResourceGroupList = bizProductionResourceGroupService.list(new QueryWrapper<BizProductionResourceGroup>().eq("dept_id", outsourcedOrderDetail.getProductionDeptId()).eq("is_deactivate", 0));

        if (sysDept.getAutoAllocation() == 1) {
            // 查资源组

            //查询是否已经分配资源组
            BizProductionResourceGroupSubPlan groupSubPlan = new BizProductionResourceGroupSubPlan();
            groupSubPlan.setDeptId(outsourcedOrderDetail.getProductionDeptId());
            groupSubPlan.setProductionPlanDetailId(outsourcedOrderDetail.getProductionPlanDetailId());

            List<BizProductionResourceGroupSubPlan> groupSubPlanList = bizProductionResourceGroupSubPlanService.getAotList(groupSubPlan);

            List<BizProductionResourceGroupSubPlan> subPlanList = new ArrayList<>();
            //如果没分配
            if (groupSubPlanList.size() == 0) {
                //查产品id
                BizProductionPlanDetail productionPlanDetail = bizProductionPlanDetailService.getOne(new QueryWrapper<BizProductionPlanDetail>().eq("id", outsourcedOrderDetail.getProductionPlanDetailId()));
                for (BizProductionResourceGroup info : productionResourceGroupList) {
                    BizProductionResourceGroupSubPlan subPlan = new BizProductionResourceGroupSubPlan();
                    subPlan.setProductId(productionPlanDetail.getProductId());
                    subPlan.setProductionPlanDetailId(outsourcedOrderDetail.getProductionPlanDetailId());
                    subPlan.setTechnologicalProcessId(outsourcedOrderDetail.getTechnologicalProcessId());
                    subPlan.setResourceGroupId(info.getId());
                    subPlan.setDeptId(outsourcedOrderDetail.getProductionDeptId());
                    subPlan.setResourceGroupCode(info.getCode());
                    subPlanList.add(subPlan);
                }
                bizProductionResourceGroupSubPlanService.saveBatch(subPlanList);
            }

        }
        return success();
    }


    @PreAuthorize("@ss.hasPermi('business:returnTurnover:edit')")
    @Log(title = "外协批量周转", businessType = BusinessType.UPDATE)
    @Transactional
    @PostMapping("/batchTurnover")
    public AjaxResult batchTurnover(@RequestBody BizOutsourcedOrderDetail outsourcedOrderDetail) throws NoSuchFieldException, IllegalAccessException {
        //判断盘点
        BizTakeStockPeriod bizTakeStockPeriod = bizTakeStockPeriodService.query().eq("status", 1).one();
        if (bizTakeStockPeriod != null && bizTakeStockPeriod.getStatus() == 1) {
            return error("正在盘点，不能周转");
        }
        // 批量周转不换箱 则不需要判断是否箱被占用
        //修改收回单明细的箱号和周转工段
        List<BizOutsourcedOrderDetail> batches = outsourcedOrderDetail.getBatches();
        List<BizDayworkItem> addItems = new ArrayList<>();
        List<BizDayworkItem> removeItems = new ArrayList<>();
        List<BizDaywork> updateDaywork = new ArrayList<>();
        List<BizProductionResourceGroupSubPlan> subPlanList = new ArrayList<>();
        //操作dayworkCarrier表，如果该批次已经绑箱，把对应箱解绑，并重新绑定新箱子
//        List<BizDayworkCarrier> newDayworkCarrierList = new ArrayList<>();
        List<BizDayworkCarrier> returnDayworkCarrierList = bizDayworkCarrierService.query().in("daywork_id", batches.isEmpty() ? Collections.singletonList(0L) : batches.stream().map(BizOutsourcedOrderDetail::getDayworkId).collect(Collectors.toList())).eq("process_inspection_id", 0L).eq("is_changed", 0).list();
        List<BizDayworkCarrier> allDayworkCarriers = bizDayworkCarrierService.query().in("carrier_id", returnDayworkCarrierList.isEmpty() ? Collections.singletonList(0L): returnDayworkCarrierList.stream().map(BizDayworkCarrier::getCarrierId).collect(Collectors.toList())).eq("is_changed", 0).list();

        List<BizDaywork> bizDayworks = bizDayworkService.query().in("id", allDayworkCarriers.isEmpty() ? Collections.singletonList(0L) : allDayworkCarriers.stream().map(BizDayworkCarrier::getDayworkId).collect(Collectors.toList())).list();
        List<BizReturnReceiptDetail> bizReturnReceiptDetails = bizReturnReceiptDetailService.query()
                .in("daywork_id", bizDayworks.isEmpty() ? Collections.singletonList(0L) : bizDayworks.stream().map(BizDaywork::getId).collect(Collectors.toList()))
                .in("outsource_detail_id",batches.isEmpty() ? Collections.singletonList(0L) : batches.stream().map(BizOutsourcedOrderDetail::getId).collect(Collectors.toList()))
                .list();
        // 获取所有明细
        List<BizOutsourcedOrderDetail> returnBatchs = bizOutsourcedOrderDetailService.query().in("id", bizReturnReceiptDetails.stream().map(BizReturnReceiptDetail::getOutsourceDetailId).collect(Collectors.toList())).list();
        List<BizOutsourcedOrderDetailProcess> bizOutsourcedOrderDetailProcesses = bizOutsourcedOrderDetailProcessService.query().in("detail_id", returnBatchs.isEmpty()? Collections.singletonList(0L): returnBatchs.stream().map(BizOutsourcedOrderDetail::getId).collect(Collectors.toList())).list();
        returnBatchs.forEach(l -> {
            l.setReturnReceiptDetailList(bizReturnReceiptDetails.stream().filter(e -> e.getOutsourceDetailId().equals(l.getId())).collect(Collectors.toList()));
            l.setFinishedProcesses(bizOutsourcedOrderDetailProcesses.stream().filter(v -> v.getDetailId().equals(l.getId())).sorted(Comparator.comparing(BizOutsourcedOrderDetailProcess::getProcessStepNumber)).collect(Collectors.toList()));
            BizReturnReceiptDetail latest = l.getReturnReceiptDetailList().stream().max(Comparator.comparing(BizReturnReceiptDetail::getProcessStepNumber)).orElse(null);
            l.setAuditNum(latest != null ? latest.getAuditNum(): null);
            l.setProductionDeptId(outsourcedOrderDetail.getProductionDeptId());
            l.setProductionDeptName(outsourcedOrderDetail.getProductionDeptName());
        });
        List<BizDayworkItem> bizDayworkItems = bizDayworkItemService.getListByDayworkIds(returnBatchs.stream().map(BizOutsourcedOrderDetail::getDayworkId).collect(Collectors.toList()));

// 不用解绑载具，因为载具不换
//        if (returnDayworkCarrierList.size() > 0) {
//            returnDayworkCarrierList.stream().forEach(bizDayworkCarrier -> bizDayworkCarrier.setIsChanged(1));
//        }
        //下序是否包装审核
        if (outsourcedOrderDetail.getIsSortPackaging() != null && outsourcedOrderDetail.getIsSortPackaging() == 1) {
            List<BizDayworkItemExamine> dayworkItemExamineList = bizDayworkItemExamineService.query().in("daywork_id", batches.isEmpty() ? Collections.singletonList(0L) : batches.stream().map(BizOutsourcedOrderDetail::getDayworkId).collect(Collectors.toList())).list();
            if (!dayworkItemExamineList.isEmpty()) {
                bizDayworkItemExamineService.removeBatchByIds(dayworkItemExamineList);
            }
            //新增包装前审核
            List<BizDayworkItemExamine> addExamineList = new ArrayList<>();
            for (BizOutsourcedOrderDetail item : returnBatchs) {
                BizDayworkItemExamine examine = new BizDayworkItemExamine();
                examine.setDayworkId(item.getDayworkId());
                examine.setDayworkItemId(item.getDayworkItemId());
                examine.setDeptId(item.getProductionDeptId());
                examine.setProductionPlanDetailId(item.getProductionPlanDetailId());
                examine.setProductDescription(item.getProductDescription());
                examine.setLotId(item.getLotId());
                examine.setLotCode(item.getLotCode());
                examine.setProductId(item.getProductId());
                examine.setTechnologicalProcessId(item.getTechnologicalProcessId());
                examine.setTechnologicalProcessDetailId(item.getFinishedProcesses().get(item.getFinishedProcesses().size() - 1).getTechnologicalProcessDetailId());
                examine.setProcessId(item.getFinishedProcesses().get(item.getFinishedProcesses().size() - 1).getProcessId());
                examine.setProcessAlias(item.getFinishedProcesses().get(item.getFinishedProcesses().size() - 1).getProcessAlias());
                examine.setStatus(0);
                addExamineList.add(examine);
            }
            bizDayworkItemExamineService.saveBatch(addExamineList);
        }

        // 自动派活
        SysDept sysDept = sysDeptMapper.selectDeptById(outsourcedOrderDetail.getProductionDeptId());

        List<BizProductionResourceGroup> productionResourceGroupList = bizProductionResourceGroupService.list(new QueryWrapper<BizProductionResourceGroup>().eq("dept_id", outsourcedOrderDetail.getProductionDeptId()).eq("is_deactivate", 0));

        returnBatchs.forEach(l -> {
            l.setProductionCarrier(l.getReturnReceiptDetailList().isEmpty() ? l.getNewCarrierName() : l.getReturnReceiptDetailList().get(0).getNewCarrier());

//            l.getCarriers().forEach(v -> {
//                BizDayworkCarrier carrier = new BizDayworkCarrier();
//                carrier.setCarrierId(v.getId());
//                carrier.setCarrierCode(v.getCode());
//                carrier.setDayworkId(l.getDayworkId());
//                carrier.setLotId(l.getLotId());
//                newDayworkCarrierList.add(carrier);
//            });
            BizDaywork daywork = bizDayworks.stream().filter(v -> v.getId().equals(l.getDayworkId())).findFirst().orElse(null);
            BizDayworkItem lastDayworkItem = bizDayworkItems.stream().filter(v -> v.getDayworkId().equals(l.getDayworkId())).sorted(Comparator.comparing(BizDayworkItem::getProcessStepNumber).reversed()).collect(Collectors.toList()).get(0);
            if ("4".equals(lastDayworkItem.getStatus())) {
                removeItems.add(lastDayworkItem);
            }
            BizDayworkItem item = new BizDayworkItem();
            if (daywork.getIsAmend() == 1) {
                item.setFormDayworkItemId(1L);
            }
            item.setDayworkId(l.getDayworkId());
            item.setProductionPlanDetailId(lastDayworkItem.getProductionPlanDetailId());
            item.setLotId(l.getLotId());
            item.setProdNum(l.getAuditNum());
            item.setQualifiedNum(l.getAuditNum());
            item.setTechnologicalProcessId(lastDayworkItem.getTechnologicalProcessId());
            item.setTechnologicalProcessDetailId(lastDayworkItem.getTechnologicalProcessDetailId());
            item.setProcessStepNumber(lastDayworkItem.getProcessStepNumber());
            item.setIsWx(1);
            item.setProcessId(lastDayworkItem.getProcessId());
            item.setDeptId(l.getProductionDeptId());
            item.setDeptName(l.getProductionDeptName());
            item.setStatus("4");
            item.setNickName("外协");
            item.setStartTime(new Date());
            if (item.getDeptId().equals(114L)) {
                item.setTurnoverType("3");
            } else {
                item.setTurnoverType("2");
            }
            item.setTurnoverArea("外协周转区");
            item.setIsWx(1);
            item.setFromDeptId(lastDayworkItem.getDeptId());
            item.setFromDeptName(lastDayworkItem.getDeptName());
            item.setTenantId(SecurityUtils.getLoginUser().getTenantId());
            addItems.add(item);

            //修改daywork主表数据
            daywork.setProcessQualifiedNum(l.getAuditNum());
            daywork.setTemporaryProcessQualifiedNum(l.getAuditNum());
            daywork.setDeptId(outsourcedOrderDetail.getProductionDeptId());
            updateDaywork.add(daywork);

            if (sysDept.getAutoAllocation() == 1) {
                // 查资源组

                //查询是否已经分配资源组
                BizProductionResourceGroupSubPlan groupSubPlan = new BizProductionResourceGroupSubPlan();
                groupSubPlan.setDeptId(outsourcedOrderDetail.getProductionDeptId());
                groupSubPlan.setProductionPlanDetailId(daywork.getProductionPlanDetailId());

                List<BizProductionResourceGroupSubPlan> groupSubPlanList = bizProductionResourceGroupSubPlanService.getAotList(groupSubPlan);
                //如果没分配
                if (groupSubPlanList.size() == 0) {
                    //查产品id
                    BizProductionPlanDetail productionPlanDetail = bizProductionPlanDetailService.getOne(new QueryWrapper<BizProductionPlanDetail>().eq("id", item.getProductionPlanDetailId()));
                    for (BizProductionResourceGroup info : productionResourceGroupList) {
                        BizProductionResourceGroupSubPlan subPlan = new BizProductionResourceGroupSubPlan();
                        subPlan.setProductId(productionPlanDetail.getProductId());
                        subPlan.setProductionPlanDetailId(lastDayworkItem.getProductionPlanDetailId());
                        subPlan.setTechnologicalProcessId(outsourcedOrderDetail.getTechnologicalProcessId());
                        subPlan.setResourceGroupId(info.getId());
                        subPlan.setDeptId(outsourcedOrderDetail.getProductionDeptId());
                        subPlan.setResourceGroupCode(info.getCode());
                        if(subPlanList.stream().noneMatch(v -> v.getProductionPlanDetailId().equals(subPlan.getProductionPlanDetailId()) && v.getResourceGroupCode().equals(subPlan.getResourceGroupCode()))) {
                            subPlanList.add(subPlan);
                        }
                    }
                }

            }
        });
        bizOutsourcedOrderDetailService.updateBatchById(returnBatchs);
//        bizDayworkCarrierService.updateBatchById(returnDayworkCarrierList);
        // 批量周转补充绑箱
//        bizDayworkCarrierService.saveBatch(newDayworkCarrierList);
        bizDayworkItemService.removeBatchByIds(removeItems);
        bizDayworkItemService.saveBatch(addItems);
        bizDayworkService.updateBatchById(updateDaywork);
        bizProductionResourceGroupSubPlanService.saveBatch(subPlanList);
        return success();
    }

    @Log(title = "判断携带箱类型", businessType = BusinessType.SELECT)
    @GetMapping("/checkCarriers")
    public AjaxResult checkCarriers(@RequestParam String carriers) {
        List<String> carrierCodes = Arrays.stream(carriers.split(",")).collect(Collectors.toList());
        List<BizCarrier> carrierList = carrierService.query().in("code", carrierCodes).list();
        List<BizCarrierCategory> categories = carrierCategoryService.query().in("id", carrierList.stream().map(BizCarrier::getCategoryId).collect(Collectors.toList())).list();
        if (categories.stream().anyMatch(v -> v.getName().equals("外协箱"))) {
            String msg = "请不要选择外协箱进行周转";
            return AjaxResult.success(msg, false);
        } else if(categories.stream().anyMatch(v -> v.getIsNone().equals(1))){
            String msg = "请不要选择无箱进行周转";
            return AjaxResult.success(msg, false);
        }else {
            return success(true);
        }

    }

    /**
     * 删除外协单主
     * 带箱方式，是整单的。如果换新箱子，明细中，都需要更换箱子
     */
    @PreAuthorize("@ss.hasPermi('business:returnTurnover:remove')")
    @Log(title = "删除外协单", businessType = BusinessType.DELETE)
    @Transactional
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable List<Long> ids) {
        bizReturnReceiptService.removeBatchByIds(ids);
        List<BizReturnReceiptDetail> bizReturnReceiptDetailList = bizReturnReceiptDetailService.query().in("master_id", ids).list();
        List<Long> bizReturnReceiptDetailIds = bizReturnReceiptDetailList.stream().map(BizReturnReceiptDetail::getId).collect(Collectors.toList());
        return toAjax(bizReturnReceiptDetailService.removeBatchByIds(bizReturnReceiptDetailIds));
    }
}
