skyouc
6 天以前 830db9a372955f1c85ab020d2e12e273570dca87
rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/MobileServiceImpl.java
@@ -1,24 +1,26 @@
package com.vincent.rsf.server.api.service.impl;
import com.alibaba.druid.sql.visitor.functions.If;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.vincent.rsf.framework.common.Cools;
import com.vincent.rsf.framework.common.R;
import com.vincent.rsf.framework.exception.CoolException;
import com.vincent.rsf.server.api.controller.params.OtherReceiptParams;
import com.vincent.rsf.server.api.controller.params.ReceiptParams;
import com.vincent.rsf.server.api.entity.dto.ReceiptDetlsDto;
import com.vincent.rsf.server.api.entity.enums.OrderWorkType;
import com.vincent.rsf.server.api.controller.params.*;
import com.vincent.rsf.server.api.entity.dto.*;
import com.vincent.rsf.server.manager.enums.*;
import com.vincent.rsf.server.api.service.MobileService;
import com.vincent.rsf.server.common.config.ConfigProperties;
import com.vincent.rsf.server.common.enums.WarehouseAreaType;
import com.vincent.rsf.server.common.security.JwtSubject;
import com.vincent.rsf.server.common.utils.CommonUtil;
import com.vincent.rsf.server.common.utils.FieldsUtils;
import com.vincent.rsf.server.common.utils.JwtUtil;
import com.vincent.rsf.server.manager.controller.params.GenerateTaskParams;
import com.vincent.rsf.server.manager.controller.params.IsptItemsParams;
import com.vincent.rsf.server.manager.controller.params.WaitPakinParam;
import com.vincent.rsf.server.manager.entity.*;
import com.vincent.rsf.server.manager.mapper.*;
import com.vincent.rsf.server.manager.service.WarehouseAreasItemService;
import com.vincent.rsf.server.manager.service.WarehouseAreasService;
import com.vincent.rsf.server.manager.service.*;
import com.vincent.rsf.server.system.constant.CodeRes;
import com.vincent.rsf.server.system.constant.SerialRuleCode;
import com.vincent.rsf.server.system.controller.param.LoginParam;
@@ -26,12 +28,12 @@
import com.vincent.rsf.server.system.entity.*;
import com.vincent.rsf.server.system.mapper.FieldsMapper;
import com.vincent.rsf.server.system.mapper.TenantMapper;
import com.vincent.rsf.server.system.mapper.UserMapper;
import com.vincent.rsf.server.system.service.FieldsItemService;
import com.vincent.rsf.server.system.service.FieldsService;
import com.vincent.rsf.server.system.service.UserLoginService;
import com.vincent.rsf.server.system.service.UserService;
import com.vincent.rsf.server.system.utils.SerialRuleUtils;
import org.apache.tika.utils.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@@ -40,6 +42,7 @@
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;
/**
 * @author Ryan
@@ -58,7 +61,7 @@
    @Autowired
    private TenantMapper tenantService;
    @Autowired
    private UserMapper userService;
    private UserService userService;
    @Autowired
    private UserLoginService userLoginService;
    @Autowired
@@ -67,28 +70,63 @@
    private WarehouseAreasService warehouseAreasService;
    @Resource
    private AsnOrderItemMapper asnOrderItemMapper;
    @Resource
    private AsnOrderMapper asnOrderMapper;
    @Autowired
    private AsnOrderService asnOrderMapper;
    @Resource
    private MatnrMapper matnrMapper;
    @Resource
    private QlyInspectMapper qlyInspectMapper;
    @Autowired
    private QlyIsptItemService qlyIsptItemService;
    @Resource
    private StockItemMapper stockItemMapper;
    @Autowired
    private LocItemService locItemService;
    @Resource
    private PurchaseItemMapper purchaseItemMapper;
    @Resource
    private FieldsMapper fieldsMapper;
    @Autowired
    private IsptHistoriesMapper isptHistoriesMapper;
    @Autowired
    private FieldsItemService fieldsItemService;
    private AsnOrderLogService asnOrderLogService;
    @Autowired
    private WaitPakinService waitPakinService;
    @Autowired
    private WaitPakinItemService waitPakinItemService;
    @Autowired
    private AsnOrderItemLogService asnOrderItemLogService;
    @Autowired
    private FieldsItemService fieldsItemService;
    @Autowired
    private LocService locService;
    @Autowired
    private PurchaseService purchaseService;
    @Autowired
    private StockService stockService;
    @Autowired
    private StockItemService stockItemService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private TaskItemService taskItemService;
    @Autowired
    private LocAreaMatRelaMapper locAreaMatRelaMapper;
    @Autowired
    private LocAreaRelaMapper locAreaRelaMapper;
    @Autowired
    private LocAreaMapper locAreaMapper;
    @Autowired
    private DeviceSiteMapper deviceSiteMapper;
    /**
     * @return
     * @author Ryan
     * @description 手持PDA登录接口
     * @params LoginParam param, HttpServletRequest request
     * @return
     * @time 2025/3/10 15:36
     */
    @Override
@@ -108,7 +146,7 @@
        if (user.getStatus() != 1) {
            return R.parse(CodeRes.USER_10002);
        }
        if (!user.getPassword().equals(param.getPassword())) {
        if (!userService.comparePassword(user.getPassword(), param.getPassword())) {
            return R.parse(CodeRes.USER_10003);
        }
@@ -120,18 +158,21 @@
    }
    /**
     * @author Ryan
     * @description 扫码获取收货明细
     * @param barcode
     * @return
     * @author Ryan
     * @description 扫码获取收货明细
     * @time 2025/3/10 15:37
     */
    @Override
    public R getOrderByCode(String barcode) {
        if (StringUtils.isEmpty(barcode)) {
        if (StringUtils.isBlank(barcode)) {
            return R.error("标签码不能为空!!");
        }
        List<AsnOrderItem> asnOrderItem = asnOrderItemMapper.selectList(new LambdaQueryWrapper<AsnOrderItem>().eq(AsnOrderItem::getBarcode, barcode));
        List<AsnOrderItem> asnOrderItem = asnOrderItemMapper.selectList(new LambdaQueryWrapper<AsnOrderItem>()
                .eq(AsnOrderItem::getTrackCode, barcode));
        if (Objects.isNull(asnOrderItem)) {
            throw new CoolException("单据明细不存在!!");
        }
@@ -140,98 +181,197 @@
    }
    /**
     * @param params
     * @param loginUserId
     * @return
     * @author Ryan
     * @description 收货至收货区
     * @param  params
     * @return
     * @time 2025/3/10 15:41
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R receiptToWarehouse(ReceiptParams params) {
        if (params.getReceipts().isEmpty()) {
    public synchronized R receiptToWarehouse(Map<String, Object> params, Long loginUserId) {
        if (Objects.isNull(params)) {
            throw new CoolException("参数不能为空!!");
        }
        ReceiptParams receiptParam = JSONObject.parseObject(JSONObject.toJSONString(params), ReceiptParams.class);
        if (receiptParam.getReceipts().isEmpty()) {
            throw new CoolException("收货明细不能为空!!");
        }
        if (Objects.isNull(params.getWhAreaId())) {
        if (Objects.isNull(receiptParam.getWhAreaId())) {
            throw new CoolException("库区标识不能为空!!");
        }
        WarehouseAreas areasItem = warehouseAreasService.getOne(new LambdaQueryWrapper<WarehouseAreas>().eq(WarehouseAreas::getId, params.getWhAreaId()));
        WarehouseAreas areasItem = warehouseAreasService.getOne(new LambdaQueryWrapper<WarehouseAreas>()
                .eq(WarehouseAreas::getId, receiptParam.getWhAreaId()));
        if (Objects.isNull(areasItem)) {
            throw new CoolException("数据错误:当前库区不存在!!");
        }
        //获取已启用的动态扩展字
        List<Fields> fields = fieldsMapper.selectList(new LambdaQueryWrapper<Fields>().eq(Fields::getFlagEnable, 1).eq(Fields::getStatus, 1));
        List<ReceiptDetlsDto> receipts = params.getReceipts();
        List<WarehouseAreasItem> allOrders =   new ArrayList<>();
        receipts.forEach(dto -> {
        List<ReceiptDetlsDto> receipts = receiptParam.getReceipts();
        Double receiptQty = receipts.stream().mapToDouble(ReceiptDetlsDto::getReceiptQty).sum();
        if (Objects.isNull(receiptQty) || receiptQty.compareTo(0.00) <= 0) {
            throw new CoolException("收货数量不能小于或等于零!!");
        }
        String asnCode = receipts.stream().findFirst().get().getAsnCode();
        AsnOrder asnOrder = asnOrderMapper.getOne(new LambdaQueryWrapper<AsnOrder>()
                .eq(AsnOrder::getCode, asnCode));
        if (Objects.isNull(asnOrder)) {
            throw new CoolException("数据错误:主单不存在!!");
        }
        //TODO /**收货数量累加,1. 会出超收情况 2. 会有收货不足情况*/
        Double rcptedQty = asnOrder.getQty() + receiptQty;
        asnOrder.setQty(rcptedQty).setExceStatus(AsnExceStatus.ASN_EXCE_STATUS_EXCE_ING.val);
        if (!asnOrderMapper.updateById(asnOrder)) {
            throw new CoolException("已收货数量修改失败!!");
        }
        List<Map<String, Object>> receipts1 = (List<Map<String, Object>>) params.get("receipts");
        for (Map<String, Object> rcpt : receipts1) {
            if (null == rcpt || Objects.isNull(rcpt)) {
                continue;
            }
            ReceiptDetlsDto dto = JSONObject.parseObject(JSONObject.toJSONString(rcpt), ReceiptDetlsDto.class);
            Matnr matnr = matnrMapper.selectById(dto.getMatnrId());
            if (Objects.isNull(matnr)) {
                throw new CoolException("数据错误:当前物料不存在!!");
            }
            WarehouseAreasItem item = new WarehouseAreasItem();
            item.setBarcode(dto.getBarcode())
                    .setAreaName(areasItem.getName())
                    .setAreaId(areasItem.getId())
                    .setStockUnit(dto.getStockUnit())
                    .setBatch(SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_RECEIPT_BATCH, dto))
                    .setAnfme(dto.getReceiptQty())
                    .setSplrBtch(dto.getSplrBatch())
                    .setMatnrCode(matnr.getCode())
                    .setMatnrId(matnr.getId())
                    .setMatnrName(matnr.getName())
                    //库存单位为最小单位
                    .setUnit(dto.getStockUnit())
                    .setStockUnit(dto.getStockUnit())
                    .setWeight(matnr.getWeight())
                    .setShipperId(matnr.getShipperId());
                    //TODO 供应商标识未设置,标识由PO单供应商编码转换
            if (Objects.isNull(dto.getReceiptQty())) {
                throw new CoolException("收货数据不能为空!!");
            }
//            if (dto.getReceiptQty().compareTo(dto.getAnfme()) > 0) {
//                throw new CoolException("收货数量不能大于采购数量!!");
//            }
//            AsnOrderItem orderItem = asnOrderItemMapper.selectOne(new LambdaQueryWrapper<AsnOrderItem>()
//                    .eq(AsnOrderItem::getAsnCode, asnCode)
//                    .eq(AsnOrderItem::getId, dto.getId())
//                    .eq(AsnOrderItem::getTrackCode, dto.getBarcode())
//                    .eq(AsnOrderItem::getSplrBatch, dto.getSplrBatch()));
            if (!Objects.isNull(fields)) {
                if (!Objects.isNull(dto.getExtendFields())) {
                    //获取16位uuid
                    String uuid16 = CommonUtil.randomUUID16();
                    Map<String, Object> extendFields = dto.getExtendFields();
                    //字段集合申明
                    List<FieldsItem> fieldsItems = new ArrayList<>();
                    extendFields.keySet().forEach(key -> {
                        fields.forEach(obj -> {
                            //判断key值与fields表字段是否相同
                            if (obj.getFields().equals(key)) {
                                FieldsItem fieldsItem = new FieldsItem();
                                fieldsItem.setMatnrId(matnr.getId()).setFieldsId(obj.getId())
                                        .setShiperId(matnr.getShipperId())
                                        .setValue(extendFields.get(key).toString())
                                        .setUuid(uuid16);
            AsnOrderItem orderItem = asnOrderItemMapper.selectOne(new LambdaQueryWrapper<AsnOrderItem>().eq(AsnOrderItem::getId, dto.getId()));
            //asnOrderItemMapper.resultById(new LambdaQueryWrapper<AsnOrderItem>().eq(AsnOrderItem::getId, dto.getId()));
                                fieldsItems.add(fieldsItem);
                                //唯一标识入库
                                item.setFieldsIndex(uuid16);
                            }
                        });
                    });
                    if (!fieldsItemService.saveBatch(fieldsItems)) {
                        throw new CoolException("扩展字段保存失败!!");
            if (Objects.isNull(orderItem)) {
                throw new CoolException("通知单明细不存在!!");
            }
            if (Objects.isNull(dto.getReceiptQty()) || Double.compare(dto.getReceiptQty(), 0.0) == 0) {
                throw new CoolException("物料:" + dto.getMaktx() + "收货数量不能为零!!");
            }
            Double itemRcptQty = dto.getReceiptQty() + orderItem.getQty();
            orderItem.setQty(itemRcptQty)
//                    .setSplrBatch(dto.getSplrBatch())
                    .setUpdateBy(loginUserId)
                    .setStockUnit(dto.getStockUnit())
                    .setProdTime(dto.getProdTime());
            if (!Objects.isNull(rcpt)) {
                try {
                    if (Objects.isNull(rcpt.get("fieldsindex")) || StringUtils.isBlank(rcpt.get("fieldsindex").toString())) {
                        //获取16位uuid
//                        String uuid16 = Cools.md5(dto.getBarcode());
                        String uuid16 = Cools.md5(dto.getId() + dto.getMatnr());
                        rcpt.put("index", uuid16);
                        orderItem.setFieldsIndex(uuid16);
                    }
                    //保存或更新扩展字段
                    FieldsUtils.updateFieldsValue(rcpt);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
            allOrders.add(item);
        });
            if (asnOrderItemMapper.updateById(orderItem) < 1) {
                throw new CoolException("通知单明细数量修改失败!!");
            }
            /**保存明细至收货区**/
            extracted(loginUserId, dto, areasItem, orderItem, asnOrder, matnr);
        if (!warehouseAreasItemService.saveBatch(allOrders)) {
        }
        AsnOrder order = asnOrderMapper.getOne(new LambdaQueryWrapper<AsnOrder>().eq(AsnOrder::getCode, asnCode));
        if (order.getQty().compareTo(order.getAnfme()) >= 0.00) {
            order.setExceStatus(AsnExceStatus.ASN_EXCE_STATUS_RECEIPT_DONE.val).setRleStatus(Short.valueOf("1"));
            if (!asnOrderMapper.updateById(order)) {
                throw new CoolException("订单状态修改失败!!");
            }
        }
        return R.ok("收货成功!!");
    }
    private void extracted(Long loginUserId, ReceiptDetlsDto dto, WarehouseAreas areasItem, AsnOrderItem orderItem, AsnOrder asnOrder, Matnr matnr) {
        WarehouseAreasItem item = new WarehouseAreasItem();
        item.setTrackCode(dto.getBarcode())
                .setAreaName(areasItem.getName())
                .setAreaId(areasItem.getId())
                .setAsnItemId(orderItem.getId())
                .setAsnCode(asnOrder.getCode())
                .setAsnId(asnOrder.getId())
                .setProdTime(dto.getProdTime())
                .setWeight(dto.getWeigth())
                //库存单位为最小单位
                .setUnit(orderItem.getStockUnit())
                .setStockUnit(orderItem.getStockUnit())
                .setBatch(StringUtils.isBlank(orderItem.getBatch()) ? SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_RECEIPT_BATCH, dto) : orderItem.getBatch())
                .setAnfme(dto.getReceiptQty())
                .setSplrBatch(dto.getSplrBatch())
                .setMatnrCode(matnr.getCode())
                .setUpdateBy(loginUserId)
                .setCreateBy(loginUserId)
                .setMatnrId(matnr.getId())
                .setIsptResult(orderItem.getIsptResult())
                .setMaktx(matnr.getName())
                .setWeight(matnr.getWeight())
                .setFieldsIndex(orderItem.getFieldsIndex())
                .setShipperId(matnr.getShipperId());
        //TODO 供应商标识未设置,标识由PO单供应商编码转换
        WarehouseAreasItem serviceOne = warehouseAreasItemService.getOne(new LambdaQueryWrapper<WarehouseAreasItem>()
//                .eq(WarehouseAreasItem::getAsnItemId, item.getAsnItemId())
                        .eq(WarehouseAreasItem::getMatnrCode, item.getMatnrCode())
                        .eq(!Cools.isEmpty(item.getFieldsIndex()), WarehouseAreasItem::getFieldsIndex, item.getFieldsIndex())
                        .eq(WarehouseAreasItem::getAsnCode, item.getAsnCode())
                        .eq(!Cools.isEmpty(item.getIsptResult()), WarehouseAreasItem::getIsptResult, item.getIsptResult())
                .eq(StringUtils.isNotBlank(item.getSplrBatch()), WarehouseAreasItem::getSplrBatch, item.getSplrBatch()));
        if (!Objects.isNull(serviceOne)) {
            item.setId(serviceOne.getId());
            item.setAnfme(item.getAnfme() + serviceOne.getAnfme());
        }
        //未质检
        if (!warehouseAreasItemService.saveOrUpdate(item)) {
            throw new CoolException("收货失败!!");
        }
        return R.ok("操作成功");
//        if (null != orderItem.getSafeQty() || null != orderItem.getDisQty() ) {
//
//        }
//        else {
//            //不合格数量
//            if (orderItem.getDisQty().compareTo(0.00) > 0) {
//                item.setIsptQty(orderItem.getDisQty()).setFlagNorm(QlyIsptResult.QLY_ISPT_RESULT_DEFECT.val);
//                if (!warehouseAreasItemService.saveOrUpdate(item)) {
//                    throw new CoolException("收货失败!!");
//                }
//            }
//
//            item.setIsptQty(orderItem.getSafeQty()).setFlagNorm(QlyIsptResult.QLY_ISPT_RESULT_EXCELLENT.val);
//            if (!warehouseAreasItemService.saveOrUpdate(item)) {
//                throw new CoolException("收货失败!!");
//            }
//        }
    }
    /**
     * @author Ryan
     * @description 其它收货
     * @param params
     * @return
     * @author Ryan
     * @description 其它收货
     */
    @Override
    public R otherReceipt(OtherReceiptParams params) {
@@ -240,49 +380,581 @@
        }
        List<AsnOrderItem> asnOrderItem = asnOrderItemMapper.selectList(new LambdaQueryWrapper<AsnOrderItem>()
                .eq(AsnOrderItem::getAsnCode, params.getAsnCode())
                .eq(!Objects.isNull(params.getBarcode()) ,AsnOrderItem::getBarcode, params.getBarcode()));
                .eq(!Objects.isNull(params.getTrackCode()), AsnOrderItem::getTrackCode, params.getTrackCode())
                .eq(!Cools.isEmpty(params.getMatnrCode()), AsnOrderItem::getMatnrCode, params.getMatnrCode())
        );
        if (Objects.isNull(asnOrderItem)) {
            throw new CoolException("单据明细不存在!!");
        }
        List<Short> shorts = Arrays.asList(AsnExceStatus.ASN_EXCE_STATUS_TASK_CANCEL.val, AsnExceStatus.ASN_EXCE_STATUS_TASK_CLOSE
                .val, AsnExceStatus.ASN_EXCE_STATUS_TASK_DONE.val);
        AsnOrder order = asnOrderMapper.getOne(new LambdaQueryWrapper<AsnOrder>()
                .notIn(AsnOrder::getExceStatus, shorts)
                .eq(AsnOrder::getCode, params.getAsnCode()));
        if (Objects.isNull(order)) {
            throw new CoolException("请检查订单状态是否已完成或已取消!!");
        }
       return getAsnOrderItem(asnOrderItem);
        return getAsnOrderItem(asnOrderItem);
    }
    /**
     * @return
     * @author Ryan
     * @description 获取所有通知单
     * @return
     */
    @Override
    public List<AsnOrder> getAllAsnOrders() {
        List<AsnOrder> asnOrders = asnOrderMapper.selectList(new LambdaQueryWrapper<AsnOrder>().eq(AsnOrder::getWkType, OrderWorkType.ORDER_PURCHASE_IN.type));
        List<AsnOrder> asnOrders = asnOrderMapper.list(new LambdaQueryWrapper<AsnOrder>().eq(AsnOrder::getWkType, OrderWorkType.ORDER_WORK_TYPE_PURCHASE.type));
        return asnOrders;
    }
    /**
     * @author Ryan
     * @description 获取收货区
     * @param
     * @return
     * @author Ryan
     * @description 获取收货区
     * @time 2025/3/11 10:12
     */
    @Override
    public R getReceiptAreas() {
        return R.ok(warehouseAreasService.list(new LambdaQueryWrapper<WarehouseAreas>().eq(WarehouseAreas::getType, WarehouseAreaType.WAREHOUSE_AREA_RECEIPT.type)));
        List<WarehouseAreas> areas = warehouseAreasService.list(new LambdaQueryWrapper<WarehouseAreas>()
                .eq(WarehouseAreas::getType, WarehouseAreaType.WAREHOUSE_AREA_RECEIPT.type));
        return R.ok(areas);
    }
    /**
     * @author Ryan
     * @description 获取所有启用动态字段
     * @param
     * @return
     * @author Ryan
     * @description 获取所有启用动态字段
     * @time 2025/3/12 09:23
     */
    @Override
    public List<Fields> getDynamicFields() {
        return fieldsMapper.selectList(new LambdaQueryWrapper<Fields>().eq(Fields::getFlagEnable, 1).eq(Fields::getStatus, 1));
    }
    /**
     * @param
     * @return
     * @author Ryan
     * @description 获取组盘明细
     * @time 2025/4/7 16:58
     */
    @Override
    public R getDeltByCode(Map<String, Object> params) {
        Object code = params.get("code");
        Object matnrCode = params.get("matnrCode");
        Object asnCode = params.get("asnCode");
        Object batch = params.get("batch");
        //TODO 后续需根据策略配置,获取组拖数据。如:混装,按批次混装等
        LambdaQueryWrapper<WarehouseAreasItem> queryWrapper = new LambdaQueryWrapper<WarehouseAreasItem>()
                .eq(!Cools.isEmpty(code), WarehouseAreasItem::getTrackCode, code)
                .eq(!Cools.isEmpty(batch), WarehouseAreasItem::getSplrBatch, batch)
                .eq(!Cools.isEmpty(matnrCode), WarehouseAreasItem::getMatnrCode, matnrCode)
                .eq(!Cools.isEmpty(asnCode), WarehouseAreasItem::getAsnCode, asnCode);
        List<WarehouseAreasItem> list = warehouseAreasItemService.list(queryWrapper);
        list.removeIf(e -> e.getAnfme() <= e.getWorkQty());
        return R.ok(list);
    }
    /**
     * @param
     * @param userId
     * @return
     * @author Ryan
     * @description PDA组拖
     * @time 2025/3/29 14:26
     */
    @Override
    public WaitPakin mergeItems(WaitPakinParam waitPakin, Long userId) {
        return waitPakinService.mergeItems(waitPakin, userId);
    }
    /**
     * @param param
     * @return
     * @author Ryan
     * @description 解绑
     */
    @Override
    public WaitPakin unBind(WaitPakinParam param) {
        return waitPakinService.unBind(param);
    }
    /**
     * 报检功能
     *
     * @param code
     * @param loginUserId
     * @return
     */
    @Override
    public R inspect(String code, Long loginUserId) {
        AsnOrder asnOrders = asnOrderMapper.getOne(new LambdaQueryWrapper<AsnOrder>().eq(AsnOrder::getCode, code));
        if (Objects.isNull(asnOrders)) {
            throw new CoolException("单据不存在!!");
        }
        InspectDetlDto detlDto = new InspectDetlDto();
        detlDto.setCode(asnOrders.getCode()).setId(asnOrders.getId()).setPoCode(asnOrders.getPoCode());
        List<AsnOrderItem> orderItems = asnOrderItemMapper.selectList(new LambdaQueryWrapper<AsnOrderItem>().eq(AsnOrderItem::getAsnCode, code));
        if (orderItems.isEmpty()) {
            detlDto.setItems(new ArrayList<>());
        } else {
            List<InspectItemDto> itemDtos = new ArrayList<>();
            orderItems.forEach(dto -> {
                InspectItemDto itemDto = new InspectItemDto();
                if (!Objects.isNull(dto.getMatnrCode())) {
                    Matnr matnr = matnrMapper.selectOne(new LambdaQueryWrapper<Matnr>().eq(Matnr::getCode, dto.getMatnrCode()));
                    itemDto.setGroup(matnr.getGroupCode());
                }
                itemDto.setMaktx(dto.getMaktx())
                        .setMatnrCode(dto.getMatnrCode())
                        .setPurUnit(dto.getPurUnit())
                        .setSuplierCode(dto.getSplrCode())
                        .setSuplierName(dto.getSplrName())
                        .setPurQty(dto.getPurQty());
                itemDtos.add(itemDto);
            });
            detlDto.setItems(itemDtos);
        }
        List<IsptHistories> histories = isptHistoriesMapper.selectList(new LambdaQueryWrapper<IsptHistories>().eq(IsptHistories::getAsnId, asnOrders.getId()));
        detlDto.setHistories(histories);
        return R.ok(detlDto);
    }
    /**
     * @param
     * @return
     * @author Ryan
     * @description 提交报检
     * @time 2025/4/1 16:47
     */
    @Override
    public R confirmIspt(String id) {
        if (org.apache.commons.lang3.StringUtils.isBlank(id)) {
            throw new CoolException("参数不能为空!!");
        }
        AsnOrder asnOrder = asnOrderMapper.getById(id);
        if (Objects.isNull(asnOrder)) {
            throw new CoolException("单据不存在!!");
        }
        List<AsnOrder> orders = new ArrayList<>();
        orders.add(asnOrder);
        if (asnOrderMapper.notifyInspect(orders)) {
            return R.ok("上报成功!!");
        } else {
            return R.error("上报失败!!");
        }
    }
    /**
     * 通过物料,质检单获取需要质检单据
     *
     * @param params
     * @return
     */
    @Override
    public R checkObjs(CheckObjParams params) {
        if (Objects.isNull(params.getIsptCode())) {
            throw new CoolException("质检单不能为空");
        }
        List<Short> asList = Arrays.asList(QlyIsptStatus.QLY_ISPT_STAS_DONE.val, QlyIsptStatus.QLY_ISPT_STAS_CLOSE.val);
        QlyInspect inspect = qlyInspectMapper.selectOne(new LambdaQueryWrapper<QlyInspect>()
                .notIn(QlyInspect::getIsptStatus, asList)
                .eq(QlyInspect::getCode, params.getIsptCode()));
        if (Objects.isNull(inspect)) {
            throw new CoolException("质检单据不存在!!");
        }
        List<QlyIsptItem> isptItems = qlyIsptItemService.list(new LambdaQueryWrapper<QlyIsptItem>()
                .eq(StringUtils.isNotBlank(params.getMatnrCode()), QlyIsptItem::getMatnrCode, StringUtils.isNotBlank(params.getMatnrCode()) ? params.getMatnrCode() : null)
                .eq(QlyIsptItem::getIspectId, inspect.getId()));
        if (Objects.isNull(isptItems)) {
            throw new CoolException("质检单明细不存在!!");
        }
        List<CheckObjDto> dtos = new ArrayList<>();
        isptItems.forEach(isptItem -> {
            CheckObjDto objDto = new CheckObjDto();
            objDto.setIsptCode(inspect.getCode())
                    .setAsnCode(inspect.getAsnCode())
                    .setId(isptItem.getId())
                    .setMatnrCode(isptItem.getMatnrCode())
                    .setMaktx(isptItem.getMaktx())
                    .setDisQty(isptItem.getDisQty())
                    .setDlyQty(isptItem.getDlyQty())
                    .setRcptQty(isptItem.getRcptQty())
                    .setIsptResult(isptItem.getIsptResult())
                    .setSplrBatch(isptItem.getSplrBatch())
                    .setSplrName(isptItem.getSplrName())
                    .setPicPath(isptItem.getPicPath())
                    .setMemo(isptItem.getMemo())
                    .setSafeQty(isptItem.getSafeQty());
            dtos.add(objDto);
        });
        return R.ok(dtos);
    }
    /**
     * 快速质检
     *
     * @param params
     * @return
     */
    @Override
    public R checkUpdate(List<QlyIsptItem> params) {
        if (Objects.isNull(params) || params.isEmpty()) {
            throw new CoolException("参数不能为空!!");
        }
        IsptItemsParams itemsParams = new IsptItemsParams();
        itemsParams.setIsptItem(params).setType("0");
        if (qlyIsptItemService.batchUpdate(itemsParams)) {
            return R.ok();
        } else {
            return R.error("保存失败!!");
        }
    }
    /**
     * @param
     * @return
     * @author Ryan
     * @description 人工上架
     * @time 2025/4/2 16:33
     */
    @Override
    public R operateToStock(OpStockParams params) {
        if (org.apache.commons.lang3.StringUtils.isBlank(params.getBarcode())) {
            throw new CoolException("拖盘码不能为空!!");
        }
        if (StringUtils.isBlank(params.getAsnCode())) {
            throw new CoolException("单据不能为空!!");
        }
        if (StringUtils.isBlank(params.getMatnrCode())) {
            throw new CoolException("物料编码不能为空!!");
        }
        AsnOrder asnOrders = asnOrderMapper.getOne(new LambdaQueryWrapper<AsnOrder>().eq(AsnOrder::getCode, params.getAsnCode()));
        if (Objects.isNull(asnOrders)) {
            throw new CoolException("单据不存在!!");
        }
        List<Loc> locs = locService.list(new LambdaQueryWrapper<Loc>().eq(Loc::getBarcode, params.getBarcode()));
        if (!locs.isEmpty()) {
            throw new CoolException("拖盘已使用");
        }
        List<WaitPakin> waitPakins = waitPakinService.list(new LambdaQueryWrapper<WaitPakin>().eq(WaitPakin::getBarcode, params.getBarcode()));
        if (!waitPakins.isEmpty()) {
            throw new CoolException("拖盘已使用!!");
        }
        AsnOrderItem orderItems = asnOrderItemMapper.selectOne(new LambdaQueryWrapper<AsnOrderItem>()
                .eq(AsnOrderItem::getAsnId, asnOrders.getId())
                .eq(AsnOrderItem::getMatnrCode, params.getMatnrCode()));
        if (Objects.isNull(orderItems)) {
            return R.ok(null);
        }
        orderItems.setBarcode(params.getBarcode());
        return R.ok(orderItems);
    }
    /**
     * 人工上架入库
     *
     * @param params
     * @param loginUserId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized R publicToStock(PublicToStockParams params, Long loginUserId) {
        if (Objects.isNull(params.getLocCode()) || StringUtils.isBlank(params.getLocCode())) {
            throw new CoolException("库位不能为空!!");
        }
        if (Objects.isNull(params.getItemList()) || params.getItemList().isEmpty()) {
            throw new CoolException("单据明细不能为空!!");
        }
        Long OrderId = params.getItemList().stream().findFirst().get().getAsnId();
        /**获取平库订单*/
        AsnOrder order = asnOrderMapper.getOne(new LambdaQueryWrapper<AsnOrder>()
                .eq(AsnOrder::getId, OrderId)
                .eq(AsnOrder::getType, OrderType.ORDER_PLAT_IN.type));
        if (Objects.isNull(order)) {
            throw new CoolException("非平库单据不可执行人工上架!!");
        }
        Stock stock = new Stock();
//        if (!Objects.isNull(order.getPoCode()) && StringUtils.isNotBlank(order.getPoCode())) {
//            Purchase purchase = purchaseService.getOne(new LambdaQueryWrapper<Purchase>().eq(Purchase::getCode, order.getPoCode()));
//            if (!Objects.isNull(purchase)) {
//                stock.setPlatOrderNo(purchase.getPlatCode()).setPlatToken(purchase.getPlatId());
//            }
//        }
        String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_STOCK_CODE, null);
        if (StringUtils.isBlank(ruleCode)) {
            throw new CoolException("当前业务:" + SerialRuleCode.SYS_STOCK_CODE + ",编码规则不存在!!");
        }
        List<AsnOrderItem> itemList = params.getItemList();
        double sum = itemList.stream().mapToDouble(AsnOrderItem::getAnfme).sum();
        stock.setAnfme(sum)
                .setSourceId(order.getId())
                .setType(order.getType())
                .setUpdateBy(loginUserId)
                .setCreateBy(loginUserId)
                .setWkType(Short.parseShort(order.getWkType()));
        if (!stockService.save(stock)) {
            throw new CoolException("库存保存失败!!");
        }
        //TODO  平库上架策略问题: 1 平库库位是单独设计,还是与产库一起用类型区分
        Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getCode, params.getLocCode()));
        if (Objects.isNull(loc)) {
            throw new CoolException("库位不存在!!");
        }
        //locItemSerivce
        List<LocItem> locItems = new ArrayList<>();
        itemList.forEach(asnOrderItem -> {
            LocItem item = new LocItem();
            BeanUtils.copyProperties(asnOrderItem, item);
            item.setLocId(loc.getId())
                    .setId(null)
                    .setLocCode(loc.getCode())
                    .setOrderId(order.getId())
                    .setUpdateBy(loginUserId)
                    .setUpdateBy(loginUserId)
                    .setOrderItemId(asnOrderItem.getId())
                    .setWkType(Short.parseShort(order.getWkType()))
                    .setType(order.getType());
            locItems.add(item);
        });
        if (!locItemService.saveBatch(locItems)) {
            throw new CoolException("库位明细更新失败!!");
        }
        List<StockItem> stockItems = new ArrayList<>();
        itemList.forEach(orderItem -> {
            StockItem stockItem = new StockItem();
            BeanUtils.copyProperties(orderItem, stockItem);
            stockItem.setSourceItemId(orderItem.getId())
                    .setBarcode(orderItem.getBarcode())
                    .setStockCode(stock.getCode())
                    .setUpdateBy(loginUserId)
                    .setCreateBy(loginUserId)
                    .setId(null)
                    .setStockId(stock.getId());
            stockItems.add(stockItem);
        });
        if (!stockItemService.saveBatch(stockItems)) {
            throw new CoolException("任务上架失败!!");
        }
        return R.ok(stock);
    }
    /**
     * 获取任务信息
     *
     * @param code
     * @return
     */
    @Override
    public R taskToStock(String code) {
        if (StringUtils.isBlank(code)) {
            throw new CoolException("拖盘码不能为空!!");
        }
        Task task = taskService.getOne(new LambdaQueryWrapper<Task>().eq(Task::getBarcode, code));
        if (Objects.isNull(task)) {
            throw new CoolException("拖盘任务不存在!!");
        }
        List<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, task.getId()));
        if (taskItems.isEmpty()) {
            throw new CoolException("拖盘任务明细不存在!!");
        }
        TaskQueueDto queueDto = new TaskQueueDto();
        queueDto.setTask(task).setTaskItems(taskItems);
        List<Long> list = taskItems.stream().map(TaskItem::getMatnrId).collect(Collectors.toList());
        List<LocAreaMatRela> matRelas = locAreaMatRelaMapper.selectList(new LambdaQueryWrapper<LocAreaMatRela>().in(LocAreaMatRela::getMatnrId,
                list));
        TaskLocAreaDto locAreaDto = new TaskLocAreaDto();
        /**判断是否为空*/
        if (matRelas.isEmpty()) {
            locAreaDto.setLocs(new ArrayList<>());
        } else {
            Long ids = matRelas.stream().map(LocAreaMatRela::getLocId).collect(Collectors.toList()).stream().findFirst().get();
            List<Loc> locs = locService.list(new LambdaQueryWrapper<Loc>().eq(Loc::getId, ids));
            if (locs.isEmpty()) {
                locAreaDto.setLocs(new ArrayList<>());
            } else {
                LocArea locArea = locAreaMapper.selectById(new LambdaQueryWrapper<Loc>().in(Loc::getId, ids));
                if (!Objects.isNull(locArea)) {
                    locAreaDto.setAreaName(locArea.getName()).setAreaCode(locArea.getCode()).setAreaId(locArea.getId());
                }
                locAreaDto.setLocs(locs);
            }
        }
        queueDto.setLocArea(locAreaDto);
        return R.ok(queueDto);
    }
    /**
     * @param code
     * @return
     * @Author Ryan
     * @desc 任务上架
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized R taskGetLocs(String code) throws Exception {
        if (StringUtils.isBlank(code)) {
            throw new CoolException("拖盘码不能为空!!");
        }
        Task task = taskService.getOne(new LambdaQueryWrapper<Task>().eq(Task::getBarcode, code));
        if (Objects.isNull(task)) {
            throw new CoolException("拖盘任务不存在!!");
        }
        List<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, task.getId()));
        if (!taskItems.isEmpty()) {
            throw new CoolException("拖盘任务明细不存在!!");
        }
        List<Task> tasks = new ArrayList<>();
        tasks.add(task);
        taskService.completeTask(tasks);
        return R.ok();
    }
    @Override
    public R completeOrder(Long id, Long loginUserId) {
        return asnOrderMapper.completeOrder(id, loginUserId);
    }
    /**
     * @param
     * @return
     * @author Ryan
     * @description 通过容器获取组拖物料
     * @time 2025/4/9 16:57
     */
    @Override
    public R getItemByContainer(Map<String, Object> params) {
//        if (Objects.isNull(params.get("code"))) {
//            throw new CoolException("参数不能为空!!");
//        }
        //获取组拖未生成任务的组拖档
        List<Short> asList = Arrays.asList(Short.valueOf(PakinIOStatus.PAKIN_IO_STATUS_DONE.val), Short.valueOf(PakinIOStatus.PAKIN_IO_STATUS_DONE.val));
        Short flagDefect = 0;
        if (!Objects.isNull(params.get("type")) && params.get("type").equals("defective")) {
            flagDefect = 1;
        }
        WaitPakin waitPakin = waitPakinService.getOne(new LambdaQueryWrapper<WaitPakin>()
                .eq(WaitPakin::getBarcode, params.get("barcode").toString())
                .eq(WaitPakin::getFlagDefect, flagDefect)
                .in(WaitPakin::getIoStatus, asList));
        if (Objects.isNull(waitPakin)) {
            return R.ok(new ArrayList<>());
        }
        List<WaitPakinItem> pakinItems = waitPakinItemService.list(new LambdaQueryWrapper<WaitPakinItem>()
                .eq(WaitPakinItem::getPakinId, waitPakin.getId()));
        if (pakinItems.isEmpty()) {
            return R.ok(new ArrayList<>());
        }
        if (!Objects.isNull(params.get("type")) && params.get("type").equals("defective")) {
            return R.ok(pakinItems);
        } else {
            List<String> list = pakinItems.stream().map(WaitPakinItem::getTrackCode).collect(Collectors.toList());
            LambdaQueryWrapper<WarehouseAreasItem> queryWrapper = new QueryWrapper<WarehouseAreasItem>()
                    .lambda()
                    .in(WarehouseAreasItem::getTrackCode, list);
            List<WarehouseAreasItem> warehouseAreasItems = warehouseAreasItemService.list(queryWrapper);
            for (int i = 0; i < warehouseAreasItems.size(); i++) {
                for (WaitPakinItem pakinItem : pakinItems) {
                    if (warehouseAreasItems.get(i).getTrackCode().equals(pakinItem.getTrackCode())) {
                        warehouseAreasItems.get(i).setAnfme(pakinItem.getAnfme());
                    }
                }
            }
            return R.ok(warehouseAreasItems);
        }
    }
    /**
     * @param
     * @return
     * @author Ryan
     * @description 不良标签
     * @time 2025/4/12 08:12
     */
    @Override
    public R defectProducts(String trackCode) {
        AsnOrderItem orderItem = asnOrderItemMapper.selectOne(new LambdaQueryWrapper<AsnOrderItem>().eq(AsnOrderItem::getTrackCode, trackCode));
        return R.ok(orderItem);
    }
    /**
     * @param barcode
     * @return
     * @author Ryan
     * @description 获取入库组拖信息
     */
    @Override
    public R getPakinInStock(String barcode) {
        WaitPakin waitPakin = waitPakinService.getOne(new LambdaQueryWrapper<WaitPakin>().eq(WaitPakin::getBarcode, barcode));
        if (Objects.isNull(waitPakin)) {
            throw new CoolException("组拖单据不存在!!");
        }
        List<WaitPakinItem> pakinItems = waitPakinItemService.list(new LambdaQueryWrapper<WaitPakinItem>().eq(WaitPakinItem::getPakinId, waitPakin.getId()));
        if (pakinItems.isEmpty()) {
            return R.ok(new ArrayList<>());
        }
        return R.ok(pakinItems);
    }
    /**
     * @return
     * @author Ryan
     * @description 获取库口站点信息
     */
    @Override
    public R getDeviceSites() {
        List<DeviceSite> sites = deviceSiteMapper.selectList(new LambdaQueryWrapper<DeviceSite>()
                .select(DeviceSite::getId, DeviceSite::getSite, DeviceSite::getName)
                .eq(DeviceSite::getStatus, 1)
                .groupBy(DeviceSite::getSite, DeviceSite::getId, DeviceSite::getName));
        return R.ok(sites);
    }
    /**
     * @return
     * @author Ryan
     * @description 获取推荐库位
     */
    @Override
    public R getRecommondLocs() {
        return R.ok(locService.list(new LambdaQueryWrapper<Loc>().last("limit 10")));
    }
    /**
     * @param map
     * @param loginUserId
     * @return
     * @author Ryan
     * @description 生成任务列表
     */
    @Override
    public synchronized R generateTask(Map<String, Object> map, Long loginUserId) {
        String barcode = map.get("barcode").toString();
        List<WaitPakin> waitPakins = waitPakinService.list(new LambdaQueryWrapper<WaitPakin>().eq(WaitPakin::getBarcode, barcode));
        if (waitPakins.isEmpty()) {
            throw new CoolException("单据不存在 !!");
        }
        GenerateTaskParams taskParams = new GenerateTaskParams();
        taskParams.setWaitPakins(waitPakins)
                .setSiteId(Long.parseLong(map.get("site").toString()))
                .setLocCode(map.get("locCode").toString());
        return R.ok(taskService.generateTasks(taskParams, loginUserId));
    }
    /**
@@ -294,11 +966,21 @@
            ReceiptDetlsDto detlsDto = new ReceiptDetlsDto();
            detlsDto.setAsnCode(asnOrderItem.getAsnCode())
                    .setMatnk(asnOrderItem.getMatnk())
                    .setBarcode(asnOrderItem.getBarcode())
                    .setId(asnOrderItem.getId())
                    .setMaktx(asnOrderItem.getMaktx())
                    .setFieldsIndex(asnOrderItem.getFieldsIndex())
                    .setBarcode(asnOrderItem.getTrackCode())
                    .setQty(asnOrderItem.getQty())
                    .setStockUnit(asnOrderItem.getStockUnit())
                    .setPurUnit(asnOrderItem.getPurUnit())
                    .setPoCode(asnOrderItem.getPoCode())
                    .setPurQty(asnOrderItem.getAnfme())
                    .setSplrBatch(asnOrderItem.getSplrBatch());
                    .setAnfme(asnOrderItem.getAnfme())
                    .setPurQty(asnOrderItem.getPurQty())
                    .setSplrBatch(asnOrderItem.getSplrBatch())
                    .setMatnr(asnOrderItem.getMatnrCode())
                    .setInspect(asnOrderItem.getIsptResult$()) //质检结果
                    .setPlatItemId(asnOrderItem.getPlatItemId())
            ;
            Matnr matnr = matnrMapper.selectById(asnOrderItem.getMatnrId());
            if (Objects.isNull(matnr)) {
@@ -306,33 +988,36 @@
            }
            //SET 物料最大存放数量
            detlsDto.setMaxQty(matnr.getMaxQty())
                    .setMatnrId(matnr.getId())
                    .setStockUnit(matnr.getStockUnit());
            QlyInspect inspect = qlyInspectMapper.selectOne(new LambdaQueryWrapper<QlyInspect>()
                    .eq(QlyInspect::getAsnItemId, asnOrderItem.getId()).eq(QlyInspect::getPoItemId, asnOrderItem.getPoDetlId()));
            if (!Objects.isNull(inspect)) {
                //set 质检结果
                detlsDto.setInspect(inspect.getStatus$());
            }
                    .setMatnrId(matnr.getId());
//            QlyInspect inspect = qlyInspectMapper.selectOne(new LambdaQueryWrapper<QlyInspect>()
//                    .eq(QlyInspect::getAsnId, asnOrderItem.getAsnId()));
//            if (!Objects.isNull(inspect)) {
//                //set 质检结果
//                detlsDto.setInspect(inspect.getStatus$());
//            }
            //获取当前库存信息
            StockItem stockItem = stockItemMapper.selectOne(new LambdaQueryWrapper<StockItem>()
                    .eq(StockItem::getAsnItemId, asnOrderItem.getId())
                    .eq(StockItem::getMatnrId, asnOrderItem.getMatnrId()));
            LocItem stockItem = locItemService.getOne(new LambdaQueryWrapper<LocItem>()
//                    .eq(LocItem::getOrderItemId, asnOrderItem.getId())
                    .eq(LocItem::getFieldsIndex, asnOrderItem.getFieldsIndex())
                    .eq(LocItem::getBatch, asnOrderItem.getSplrBatch())
                    .eq(LocItem::getMatnrId, asnOrderItem.getMatnrId()));
            //SET 当前库存数量
            if (Objects.isNull(stockItem)) {
                detlsDto.setStockQty(0.0);
            } else {
                detlsDto.setStockQty(stockItem.getQty() + stockItem.getWorkQty());
                detlsDto.setStockQty(stockItem.getAnfme() + stockItem.getWorkQty());
            }
            //获取采购单明细信息
            PurchaseItem purchaseItem = purchaseItemMapper.selectOne(new LambdaQueryWrapper<PurchaseItem>().eq(PurchaseItem::getId, asnOrderItem.getPoDetlId()));
            //SET 平台行号
            detlsDto.setPlatformId(purchaseItem.getPlatItemId());
            if (!Objects.isNull(asnOrderItem.getPoDetlId())) {
                //获取采购单明细信息
                PurchaseItem purchaseItem = purchaseItemMapper.selectOne(new LambdaQueryWrapper<PurchaseItem>().eq(PurchaseItem::getId, asnOrderItem.getPoDetlId()));
                if (Objects.isNull(purchaseItem)) {
                    //SET 平台行号
                    detlsDto.setPlatformId(purchaseItem.getPlatItemId());
                }
            }
            detlsDtos.add(detlsDto);
        });
        return R.ok(detlsDtos);
    }