package com.vincent.rsf.server.manager.service.impl; 
 | 
  
 | 
import cn.afterturn.easypoi.excel.ExcelImportUtil; 
 | 
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult; 
 | 
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 
 | 
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; 
 | 
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 
 | 
import com.vincent.rsf.framework.common.R; 
 | 
import com.vincent.rsf.framework.exception.CoolException; 
 | 
import com.vincent.rsf.server.common.utils.ExcelUtil; 
 | 
import com.vincent.rsf.server.manager.controller.params.*; 
 | 
import com.vincent.rsf.server.manager.entity.*; 
 | 
import com.vincent.rsf.server.manager.entity.excel.CheckOrderTemplate; 
 | 
import com.vincent.rsf.server.manager.enums.*; 
 | 
import com.vincent.rsf.server.manager.mapper.CheckOrderMapper; 
 | 
import com.vincent.rsf.server.manager.service.*; 
 | 
import com.vincent.rsf.server.system.constant.SerialRuleCode; 
 | 
import com.vincent.rsf.server.system.utils.SerialRuleUtils; 
 | 
import org.apache.commons.lang3.StringUtils; 
 | 
import org.springframework.beans.factory.annotation.Autowired; 
 | 
import org.springframework.stereotype.Service; 
 | 
import org.springframework.transaction.annotation.Transactional; 
 | 
import org.springframework.web.multipart.MultipartFile; 
 | 
import java.text.ParseException; 
 | 
import java.text.SimpleDateFormat; 
 | 
import java.util.*; 
 | 
import java.util.stream.Collectors; 
 | 
  
 | 
@Service("checkOrderService") 
 | 
public class CheckOrderServiceImpl extends ServiceImpl<CheckOrderMapper, WkOrder> implements CheckOrderService { 
 | 
  
 | 
    @Autowired 
 | 
    private MatnrService matnrService; 
 | 
    @Autowired 
 | 
    private CheckOrderItemService checkOrderItemService; 
 | 
    @Autowired 
 | 
    private AsnOrderItemService asnOrderItemService; 
 | 
    @Autowired 
 | 
    private DeviceSiteService deviceSiteService; 
 | 
    @Autowired 
 | 
    private LocItemService locItemService; 
 | 
    @Autowired 
 | 
    private TaskService taskService; 
 | 
    @Autowired 
 | 
    private LocServiceImpl locService; 
 | 
    @Autowired 
 | 
    private TaskItemServiceImpl taskItemService; 
 | 
    @Autowired 
 | 
    private CheckOrderService checkOrderService; 
 | 
  
 | 
    /** 
 | 
     * @author Ryan 
 | 
     * @date 2025/7/14 
 | 
     * @description: 盘点单导入 
 | 
     * @version 1.0 
 | 
     */ 
 | 
    @Override 
 | 
    @Transactional(rollbackFor = Exception.class) 
 | 
    public R excelImport(MultipartFile file, HashMap<String, Object> hashMap, Long loginUserId) { 
 | 
        ExcelImportResult result = null; 
 | 
        try { 
 | 
            result = ExcelImportUtil.importExcelMore(file.getInputStream(), CheckOrderTemplate.class, ExcelUtil.getDefaultImportParams()); 
 | 
        } catch (Exception e) { 
 | 
            throw new RuntimeException(e); 
 | 
        } 
 | 
        if (result.getList().isEmpty()) { 
 | 
            throw new CoolException("表格内容不能为空!!"); 
 | 
        } 
 | 
        List<CheckOrderTemplate> resultList = result.getList(); 
 | 
        Map<String, List<CheckOrderTemplate>> listMap = resultList.stream().collect(Collectors.groupingBy(CheckOrderTemplate::getCode)); 
 | 
        for (String key : listMap.keySet()) { 
 | 
            CheckOrderTemplate template = listMap.get(key).stream().findFirst().get(); 
 | 
            WkOrder wkOrder = this.getOne(new LambdaQueryWrapper<WkOrder>().eq(WkOrder::getCode, template.getCode())); 
 | 
            if (!Objects.isNull(wkOrder)) { 
 | 
                continue; 
 | 
            } 
 | 
            WkOrder order = new WkOrder(); 
 | 
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); 
 | 
            Date arrTime = null; 
 | 
            try { 
 | 
                 arrTime = dateFormat.parse(template.getArrTime()); 
 | 
            } catch (ParseException e) { 
 | 
                throw new RuntimeException(e); 
 | 
            } 
 | 
            order.setCode(template.getCode()) 
 | 
                    .setArrTime(arrTime) 
 | 
                    .setMemo(template.getMemo()) 
 | 
                    .setUpdateBy(loginUserId) 
 | 
                    .setCreateBy(loginUserId) 
 | 
                    .setType(OrderType.getTypeVal(template.getType())) 
 | 
                    .setWkType(CheckOrderType.getTypeVal(template.getWkType())); 
 | 
            if (!this.save(order)) { 
 | 
                throw new CoolException("单据保存失败!!"); 
 | 
            } 
 | 
            List<WkOrderItem> items = new ArrayList<>(); 
 | 
            for (CheckOrderTemplate orderTemplate : listMap.get(key)) { 
 | 
                WkOrderItem orderItem = new WkOrderItem(); 
 | 
                Matnr matnr = null; 
 | 
                if (StringUtils.isNotBlank(orderTemplate.getMatnrCode())) { 
 | 
                    matnr = matnrService.getOne(new LambdaQueryWrapper<Matnr>() 
 | 
                            .eq(Matnr::getCode, orderTemplate.getMatnrCode())); 
 | 
                } 
 | 
                orderItem.setOrderId(order.getId()) 
 | 
                        .setOrderCode(order.getCode()) 
 | 
                        .setSplrBatch(orderTemplate.getSplrBatch()) 
 | 
                        .setAnfme(Double.parseDouble(orderTemplate.getAnfme())) 
 | 
                        .setSplrName(orderTemplate.getSplrName()) 
 | 
                        .setSplrCode(orderTemplate.getSplrCode()) 
 | 
                        .setMaktx(orderTemplate.getMaktx()) 
 | 
                        .setMatnrCode(orderTemplate.getMatnrCode()); 
 | 
                if (!Objects.isNull(matnr)) { 
 | 
                    orderItem.setMaktx(matnr.getName()).setMatnrCode(matnr.getCode()).setMatnrId(matnr.getId()); 
 | 
                } 
 | 
                items.add(orderItem); 
 | 
                if (!checkOrderItemService.saveBatch(items)) { 
 | 
                    throw new CoolException("单据明细保存失败!!"); 
 | 
                } 
 | 
            } 
 | 
            if (!items.isEmpty()) { 
 | 
                double purQty = items.stream().mapToDouble(WkOrderItem::getAnfme).sum(); 
 | 
                if (!this.update(new LambdaUpdateWrapper<WkOrder>() 
 | 
                        .set(WkOrder::getExceStatus, CheckExceStatus.CHECK_ORDER_STATUS_UN_EXCE.val) 
 | 
                        .set(WkOrder::getAnfme, purQty).eq(WkOrder::getId, order.getId()))) { 
 | 
                    throw new CoolException("单据数量修改失败!!"); 
 | 
                } 
 | 
            } 
 | 
        } 
 | 
  
 | 
        return R.ok("操作成功!!"); 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * @param 
 | 
     * @return 
 | 
     * @author Ryan 
 | 
     * @description 保存出库主单及明细 
 | 
     * @time 2025/4/29 13:47 
 | 
     */ 
 | 
    @Override 
 | 
    @Transactional(rollbackFor = Exception.class) 
 | 
    public R saveCheckOrder(AsnOrderAndItemsParams params, Long loginUserId) { 
 | 
        if (Objects.isNull(params.getOrders())) { 
 | 
            throw new CoolException("主单信息不能为空"); 
 | 
        } 
 | 
        WkOrder orders = params.getOrders(); 
 | 
        if (StringUtils.isBlank(orders.getWkType())) { 
 | 
            throw new CoolException("业务类型不能为空!!"); 
 | 
        } 
 | 
  
 | 
        String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_CHECK_RULE_CODE, orders); 
 | 
        if (StringUtils.isBlank(ruleCode)) { 
 | 
            throw new CoolException("编码规则错误:请检查「SYS_CHECK_RULE_CODE」是否设置正确!!"); 
 | 
        } 
 | 
        orders.setCode(ruleCode) 
 | 
                .setType(OrderType.ORDER_CHECK.type) 
 | 
                .setExceStatus(CheckExceStatus.CHECK_ORDER_STATUS_UN_EXCE.val) 
 | 
                .setUpdateBy(loginUserId) 
 | 
                .setCreateBy(loginUserId); 
 | 
        if (!this.save(orders)) { 
 | 
            throw new CoolException("主单保存失败!!"); 
 | 
        } 
 | 
        if (params.getItems().isEmpty()) { 
 | 
            throw new CoolException("盘点单明细不能为空!!"); 
 | 
        } 
 | 
        params.setOrders(orders); 
 | 
        try { 
 | 
            svaeOrUpdateOrderItem(params, loginUserId); 
 | 
        } catch (Exception e) { 
 | 
            throw new CoolException(e.getMessage()); 
 | 
        } 
 | 
        return R.ok(); 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * @param 
 | 
     * @return 
 | 
     * @author Ryan 
 | 
     * @description 修改主单及明细 
 | 
     * @time 2025/4/29 13:47 
 | 
     */ 
 | 
    @Override 
 | 
    public R updateOrderItem(AsnOrderAndItemsParams params, Long loginUserId) { 
 | 
        WkOrder orders = params.getOrders(); 
 | 
        if (Objects.isNull(orders)) { 
 | 
            throw new CoolException("主单信息不能为空!!"); 
 | 
        } 
 | 
        if (Objects.isNull(orders.getId())) { 
 | 
            throw new CoolException("数据错误:单据ID不能为空!!"); 
 | 
        } 
 | 
        if (!this.updateById(orders)) { 
 | 
            throw new CoolException("主单修改失败!!"); 
 | 
        } 
 | 
        if (Objects.isNull(params.getItems()) || params.getItems().isEmpty()) { 
 | 
            throw new CoolException("明细参数不能为空!!"); 
 | 
        } 
 | 
        try { 
 | 
            svaeOrUpdateOrderItem(params, loginUserId); 
 | 
        } catch (Exception e) { 
 | 
            throw new CoolException(e.getMessage()); 
 | 
        } 
 | 
        return R.ok(); 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * @author Ryan 
 | 
     * @date 2025/7/16 
 | 
     * @description: 获取盘点出入站口 
 | 
     * @version 1.0 
 | 
     */ 
 | 
    @Override 
 | 
    public R getSiteNos() { 
 | 
        List<Integer> list = Arrays.asList(TaskType.TASK_TYPE_CHECK_OUT.type, TaskType.TASK_TYPE_CHECK_IN.type); 
 | 
        List<DeviceSite> sites = deviceSiteService.list(new LambdaQueryWrapper<DeviceSite>().in(DeviceSite::getType, list).groupBy(DeviceSite::getSite)); 
 | 
        return R.ok().add(sites); 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * @author Ryan 
 | 
     * @date 2025/7/16 
 | 
     * @description: 盘点出库预览 
 | 
     * @version 1.0 
 | 
     */ 
 | 
    @Override 
 | 
    public R genCheckPreview(OrderOutTaskParam param) { 
 | 
        List<WkOrderItem> orderItems = checkOrderItemService.list(new LambdaQueryWrapper<WkOrderItem>().eq(WkOrderItem::getOrderId, param.getOrderId())); 
 | 
        if (orderItems.isEmpty()) { 
 | 
            throw new CoolException("数据错误:盘点单明细不存在!!"); 
 | 
        } 
 | 
        return R.ok().add(orderItems); 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * @author Ryan 
 | 
     * @date 2025/7/16 
 | 
     * @description: 根据物料码获取所有在库明细 
 | 
     * @version 1.0 
 | 
     */ 
 | 
    @Override 
 | 
    public R getAllLocByMatnr(CheckLocQueryParams matnrs) { 
 | 
        if (Objects.isNull(matnrs.getMatnrCode()) && matnrs.getMatnrCode().isEmpty()) { 
 | 
            throw new CoolException("参数不能为空!!"); 
 | 
        } 
 | 
        List<LocItem> locItems = locItemService.listByMatnr(matnrs); 
 | 
        if (!locItems.isEmpty()) { 
 | 
            List<Integer> list = Arrays.asList(TaskType.TASK_TYPE_CHECK_OUT.type, TaskType.TASK_TYPE_CHECK_IN.type); 
 | 
            DeviceSite deviceSite = deviceSiteService.getOne(new LambdaQueryWrapper<DeviceSite>() 
 | 
                    .in(DeviceSite::getType, list) 
 | 
                    .groupBy(DeviceSite::getSite) 
 | 
                    .last("limit 1")); 
 | 
            if (Objects.isNull(deviceSite)) { 
 | 
                throw new CoolException("库口不为空!!"); 
 | 
            } 
 | 
            locItems.forEach(locItem -> { 
 | 
                locItem.setSiteNo(deviceSite.getSite()); 
 | 
            }); 
 | 
        } 
 | 
        return R.ok().add(locItems); 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * @author Ryan 
 | 
     * @date 2025/7/17 
 | 
     * @description: 生成盘点任务 
 | 
     * @version 1.0 
 | 
     */ 
 | 
    @Override 
 | 
    @Transactional(rollbackFor = Exception.class) 
 | 
    public R genCheckOutTask(List<CheckOrderParams> checkParams, Long loginUserId) { 
 | 
        if (checkParams.isEmpty()) { 
 | 
            throw new CoolException("参数不能为空!!"); 
 | 
        } 
 | 
        for (CheckOrderParams checkParam : checkParams) { 
 | 
            if (checkParam.getItems().isEmpty()) { 
 | 
                continue; 
 | 
            } 
 | 
            Map<String, List<CheckOrderItemParams>> listMap = checkParam.getItems().stream() 
 | 
                    .collect(Collectors.groupingBy(CheckOrderItemParams::getBarcode)); 
 | 
            listMap.keySet().forEach(key -> { 
 | 
                Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getBarcode, key)); 
 | 
                if (Objects.isNull(loc)) { 
 | 
                    throw new CoolException("当前库位不存在!!"); 
 | 
                } 
 | 
                Task task1 = taskService.getOne(new LambdaQueryWrapper<Task>().eq(Task::getBarcode, key)); 
 | 
                if (!Objects.isNull(task1)) { 
 | 
                    throw new CoolException("托盘任务已存在!!"); 
 | 
                } 
 | 
                List<CheckOrderItemParams> itemParams = listMap.get(key); 
 | 
                CheckOrderItemParams checkItem = itemParams.stream().findFirst().get(); 
 | 
                Task task = new Task(); 
 | 
                String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_TASK_CODE, null); 
 | 
                if (StringUtils.isBlank(ruleCode)) { 
 | 
                    throw new CoolException("任务号不能为空!!"); 
 | 
                } 
 | 
                task.setOrgLoc(loc.getCode()) 
 | 
                        .setTaskCode(ruleCode) 
 | 
                        .setTargSite(checkItem.getSiteNo()) 
 | 
                        .setResource(TaskResouceType.TASK_RESOUCE_CHECK_TYPE.val) 
 | 
                        .setTaskType(TaskType.TASK_TYPE_CHECK_OUT.type) 
 | 
                        .setTaskStatus(TaskStsType.GENERATE_OUT.id) 
 | 
                        .setCreateTime(new Date()) 
 | 
                        .setUpdateBy(loginUserId) 
 | 
                        .setUpdateTime(new Date()) 
 | 
                        .setCreateBy(loginUserId) 
 | 
                        .setBarcode(key); 
 | 
  
 | 
                if (!taskService.save(task)) { 
 | 
                    throw new CoolException("盘点任务生成失败!!"); 
 | 
                } 
 | 
                List<TaskItem> items = new ArrayList<>(); 
 | 
                itemParams.forEach(item -> { 
 | 
                    TaskItem taskItem = new TaskItem(); 
 | 
                    taskItem.setTaskId(task.getId()) 
 | 
                            .setOrderType(OrderType.ORDER_CHECK.type) 
 | 
                            .setWkType(Short.parseShort(OrderWorkType.ORDER_WORK_TYPE_STOCK_CHECK.type)) 
 | 
                            .setAnfme(item.getAnfme()) 
 | 
                            .setWorkQty(0.0) 
 | 
                            .setBatch(checkParam.getBatch()) 
 | 
                            .setMaktx(checkParam.getMaktx()) 
 | 
                            .setMatnrCode(checkParam.getMatnrCode()) 
 | 
                            .setPlatOrderCode(checkParam.getPlatOrderCode()) 
 | 
                            .setPlatWorkCode(checkParam.getPlatWorkCode()) 
 | 
                            .setUnit(checkParam.getStockUnit()) 
 | 
                            .setSpec(checkParam.getSpec()) 
 | 
                            .setModel(checkParam.getModel()) 
 | 
                            .setFieldsIndex(checkParam.getFieldsIndex()) 
 | 
                            .setMatnrId(checkParam.getMatnrId()) 
 | 
                            .setCreateBy(loginUserId) 
 | 
                            .setSource(checkParam.getId()) 
 | 
                            .setSourceId(checkParam.getOrderId()) 
 | 
                            .setSourceCode(checkParam.getOrderCode()) 
 | 
                            .setCreateTime(new Date()) 
 | 
                            .setUpdateBy(loginUserId) 
 | 
                            .setUpdateTime(new Date()) 
 | 
                            .setOrderItemId(checkParam.getId()) 
 | 
                            .setOrderId(checkParam.getOrderId()) 
 | 
                            .setPlatItemId(checkParam.getPlatItemId()); 
 | 
                    items.add(taskItem); 
 | 
  
 | 
                    if (!checkOrderItemService.update(new LambdaUpdateWrapper<WkOrderItem>() 
 | 
                            .eq(WkOrderItem::getId, checkParam.getId()) 
 | 
                            .setSql("work_qty = work_qty + " + item.getAnfme()) 
 | 
                            .set(WkOrderItem::getWorkQty, checkItem.getAnfme()))) { 
 | 
                        throw new CoolException("盘点明细修改失败!!"); 
 | 
                    } 
 | 
                }); 
 | 
                if (!taskItemService.saveBatch(items)) { 
 | 
                    throw new CoolException("任务明细保存失败!!"); 
 | 
                } 
 | 
  
 | 
                loc.setUseStatus(LocStsType.LOC_STS_TYPE_R.type); 
 | 
                if (!locService.updateById(loc)) { 
 | 
                    throw new CoolException("库位预约出库失败!!"); 
 | 
                } 
 | 
  
 | 
            }); 
 | 
  
 | 
            Set<Long> checkItemIds = checkParams.stream().map(CheckOrderParams::getOrderId).collect(Collectors.toSet()); 
 | 
            checkItemIds.forEach(orderId -> { 
 | 
                WkOrder order = this.getById(orderId); 
 | 
                if (Objects.isNull(order)) { 
 | 
                    throw new CoolException("数据错误:单据不存在!!"); 
 | 
                } 
 | 
                List<WkOrderItem> orderItems = checkOrderItemService.list(new LambdaQueryWrapper<WkOrderItem>().eq(WkOrderItem::getOrderId, orderId)); 
 | 
                if (orderItems.isEmpty()) { 
 | 
                    throw new CoolException("数据错误:单据明细不存在!!"); 
 | 
                } 
 | 
                Double sum = orderItems.stream().mapToDouble(WkOrderItem::getWorkQty).sum(); 
 | 
  
 | 
                if (order.getAnfme().compareTo(sum) <= 0) { 
 | 
                    order.setWorkQty(sum).setExceStatus(CheckExceStatus.CHECK_ORDER_STATUS_EXCE_DONE.val); 
 | 
                } else { 
 | 
                    order.setWorkQty(sum).setExceStatus(CheckExceStatus.CHECK_ORDER_STATUS_EXCE_ING.val); 
 | 
                } 
 | 
  
 | 
                if (!this.updateById(order)) { 
 | 
                    throw new CoolException("盘点单信息修改失败!!"); 
 | 
                } 
 | 
            }); 
 | 
        } 
 | 
        return R.ok(); 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * @author Ryan 
 | 
     * @date 2025/7/16 
 | 
     * @description: 取消盘点单据 
 | 
     * @version 1.0 
 | 
     */ 
 | 
    @Override 
 | 
    public R cancelCheckOrder(Long id) { 
 | 
        WkOrder order = this.getById(id); 
 | 
        if (Objects.isNull(order)) { 
 | 
            throw new CoolException("单据不存在!!"); 
 | 
        } 
 | 
        if (!order.getExceStatus().equals(CheckExceStatus.CHECK_ORDER_STATUS_UN_EXCE.val)) { 
 | 
            throw new CoolException("当前单据不可执行取消操作!!"); 
 | 
        } 
 | 
  
 | 
        if (!this.removeById(id)) { 
 | 
            throw new CoolException("盘点单据删除失败!!"); 
 | 
        } 
 | 
  
 | 
        if (!checkOrderItemService.remove(new LambdaQueryWrapper<WkOrderItem>().eq(WkOrderItem::getOrderId, id))) { 
 | 
            throw new CoolException("盘点单明细删除失败!!"); 
 | 
        } 
 | 
        return R.ok(); 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * @param 
 | 
     * @return 
 | 
     * @author Ryan 
 | 
     * @description 更新或保存明细 
 | 
     * @time 2025/4/7 13:28 
 | 
     */ 
 | 
    @Transactional(rollbackFor = Exception.class) 
 | 
    public void svaeOrUpdateOrderItem(AsnOrderAndItemsParams params, Long loginUserId) throws Exception { 
 | 
        WkOrder orders = params.getOrders(); 
 | 
        params.getItems().forEach(item -> { 
 | 
            item.put("orderId", orders.getId()); 
 | 
            item.put("orderCode", orders.getCode()); 
 | 
            item.put("poCode", orders.getPoCode()); 
 | 
            item.put("createBy", loginUserId); 
 | 
            item.put("updateBy", loginUserId); 
 | 
            if (!asnOrderItemService.fieldsSave(item, loginUserId)) { 
 | 
                throw new CoolException("明细保存失败!!"); 
 | 
            } 
 | 
        }); 
 | 
        List<WkOrderItem> orderItems = checkOrderItemService.list(new LambdaQueryWrapper<WkOrderItem>() 
 | 
                .eq(WkOrderItem::getOrderId, params.getOrders().getId())); 
 | 
        Double sum = orderItems.stream().mapToDouble(WkOrderItem::getAnfme).sum(); 
 | 
        orders.setAnfme(sum); 
 | 
        if (!this.updateById(orders)) { 
 | 
            throw new CoolException("计划收货数量修改失败!!"); 
 | 
        } 
 | 
    } 
 | 
} 
 |