skyouc
1 天以前 37467bf7d119ef9b599f1c19b869d046d730b7cb
rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/MobileServiceImpl.java
@@ -1,24 +1,31 @@
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.controller.params.*;
import com.vincent.rsf.server.api.entity.dto.*;
import com.vincent.rsf.server.api.entity.enums.OrderType;
import com.vincent.rsf.server.api.entity.enums.OrderWorkType;
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.enums.AsnExceStatus;
import com.vincent.rsf.server.manager.enums.PakinIOStatus;
import com.vincent.rsf.server.manager.enums.QlyIsptStatus;
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 +33,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 +47,7 @@
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;
/**
 * @author Ryan
@@ -58,7 +66,7 @@
    @Autowired
    private TenantMapper tenantService;
    @Autowired
    private UserMapper userService;
    private UserService userService;
    @Autowired
    private UserLoginService userLoginService;
    @Autowired
@@ -67,22 +75,57 @@
    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;
    /**
     * @author Ryan
@@ -108,7 +151,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);
        }
@@ -128,10 +171,10 @@
     */
    @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("单据明细不存在!!");
        }
@@ -148,37 +191,51 @@
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R receiptToWarehouse(ReceiptParams params) {
        if (params.getReceipts().isEmpty()) {
    public R receiptToWarehouse(Map<String, Object> params) {
        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<ReceiptDetlsDto> receipts = receiptParam.getReceipts();
        List<WarehouseAreasItem> allOrders = new ArrayList<>();
        double receiptQty = receipts.stream().mapToDouble(ReceiptDetlsDto::getReceiptQty).sum();
        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.selectOne(new LambdaQueryWrapper<AsnOrder>().eq(AsnOrder::getCode, asnCode));
        asnOrder.setQty(receiptQty);
        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) < 1) {
        if (!asnOrderMapper.updateById(asnOrder)) {
            throw new CoolException("已收货数量修改失败!!");
        }
        receipts.forEach(dto -> {
        List<Map<String, Object>> receipts1 = (List<Map<String, Object>>) params.get("receipts");
        for (Map<String, Object> rcpt : receipts1) {
            if (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("数据错误:当前物料不存在!!");
@@ -186,76 +243,90 @@
            if (Objects.isNull(dto.getReceiptQty())) {
                throw new CoolException("收货数据不能为空!!");
            }
            if (dto.getReceiptQty() < dto.getPurQty()) {
                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::getTrackCode, dto.getBarcode())
                    .eq(AsnOrderItem::getMatnrId, dto.getMatnrId()));
            if (Objects.isNull(orderItem)) {
                throw new CoolException("通知单明细不存在!!");
            }
            orderItem.setQty(dto.getReceiptQty());
            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())
                    .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 = CommonUtil.randomUUID16();
                        rcpt.put("index", uuid16);
                        orderItem.setFieldsIndex(uuid16);
                    }
                    //保存或更新扩展字段
                    FieldsUtils.updateFieldsValue(rcpt);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
            if (asnOrderItemMapper.updateById(orderItem) < 1) {
                throw new CoolException("通知单明细数量修改失败!!");
            }
            WarehouseAreasItem item = new WarehouseAreasItem();
            item.setBarcode(dto.getBarcode())
//            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//            String format = null;
//            if (Objects.isNull(dto.getProdTime())) {
//                 format = dateFormat.format(dto.getProdTime());
//            }
            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())
                    .setStockUnit(dto.getStockUnit())
                    .setBatch(SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_RECEIPT_BATCH, dto))
                    .setAnfme(dto.getReceiptQty())
                    .setSplrBtch(dto.getSplrBatch())
                    .setSplrBatch(dto.getSplrBatch())
                    .setMatnrCode(matnr.getCode())
                    .setMatnrId(matnr.getId())
                    .setMatnrName(matnr.getName())
                    .setMaktx(matnr.getName())
                    //库存单位为最小单位
                    .setUnit(dto.getStockUnit())
                    .setStockUnit(dto.getStockUnit())
                    .setWeight(matnr.getWeight())
                    .setFieldsIndex(orderItem.getFieldsIndex())
                    .setShipperId(matnr.getShipperId());
                    //TODO 供应商标识未设置,标识由PO单供应商编码转换
            //TODO 供应商标识未设置,标识由PO单供应商编码转换
            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);
                                fieldsItems.add(fieldsItem);
                                //唯一标识入库
                                item.setFieldsIndex(uuid16);
                            }
                        });
                    });
                    if (!fieldsItemService.saveBatch(fieldsItems)) {
                        throw new CoolException("扩展字段保存失败!!");
                    }
                }
            }
            allOrders.add(item);
        });
        }
        if (!warehouseAreasItemService.saveBatch(allOrders)) {
            throw new CoolException("收货失败!!");
        }
        return R.ok("操作成功");
//        //获取采购数量
//        double purQty = receipts.stream().mapToDouble(ReceiptDetlsDto::getPurQty).sum();
//
//        BigDecimal subtract = BigDecimal.valueOf(receiptQty).subtract(BigDecimal.valueOf(purQty));
//        //判断已收货数量是否小于等于采购数量
//        if (subtract.compareTo(new BigDecimal("0.0")) <= 0) {
//            asnOrder.setRleStatus(Short.valueOf("1"));
//            //日志表操作
//            operateOrderLogs(asnOrder);
//        }
        return R.ok(asnOrder);
    }
    /**
@@ -271,7 +342,7 @@
        }
        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()));
        if (Objects.isNull(asnOrderItem)) {
            throw new CoolException("单据明细不存在!!");
@@ -288,7 +359,7 @@
     */
    @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;
    }
@@ -301,7 +372,8 @@
     */
    @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);
    }
    /**
@@ -317,6 +389,510 @@
    }
    /**
     * @author Ryan
     * @description 获取组盘明细
     * @param
     * @return
     * @time 2025/4/7 16:58
     */
    @Override
    public R getDeltByCode(String code) {
        //TODO 后续需根据策略配置,获取组拖数据。如:混装,按批次混装等
        LambdaQueryWrapper<WarehouseAreasItem> queryWrapper = new QueryWrapper<WarehouseAreasItem>()
                .select("SUM(anfme) as anfme, track_code, asn_code, id, splr_batch, ispt_result, plat_item_id, batch, qty, work_qty, matnr_code, matnr_id, maktx").lambda()
                .eq(WarehouseAreasItem::getTrackCode, code)
                .groupBy(WarehouseAreasItem::getSplrBatch, WarehouseAreasItem::getAsnId, WarehouseAreasItem::getAreaId, WarehouseAreasItem::getMatnrId);
        return R.ok(warehouseAreasItemService.getOne(queryWrapper));
    }
    /**
     * @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);
    }
    /**
     * @author Ryan
     * @description 解绑
     * @param param
     * @return
     */
    @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);
    }
    /**
     * @author Ryan
     * @description 提交报检
     * @param
     * @return
     * @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("保存失败!!");
        }
    }
    /**
    * @author Ryan
    * @description 人工上架
    * @param
    * @return
    * @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 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())
                .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())
                    .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);
    }
    /**
     * @Author Ryan
     * @param code
     * @desc  任务上架
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public 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);
    }
    /**
     * @author Ryan
     * @description 通过容器获取组拖物料
     * @param
     * @return
     * @time 2025/4/9 16:57
     */
    @Override
    public R getItemByContainer(Map<String, Object> params) {
        //获取组拖未生成任务的组拖档
        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>()
                    .select("SUM(anfme) as anfme, track_code, asn_code, id, splr_batch, ispt_result, plat_item_id, batch, qty, work_qty, matnr_code, matnr_id, maktx")
                    .lambda()
                    .in(WarehouseAreasItem::getTrackCode, list)
                    .groupBy(WarehouseAreasItem::getSplrBatch,
                            WarehouseAreasItem::getTrackCode);
            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);
        }
    }
    /**
     * @author Ryan
     * @description 不良标签
     * @param
     * @return
     * @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);
    }
    /**
     * @author Ryan
     * @description 获取入库组拖信息
     * @param barcode
     * @return
     */
    @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);
    }
    /**
     * @author Ryan
     * @description 获取库口站点信息
     * @return
     */
    @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);
    }
    /**
     * @author Ryan
     * @description 获取推荐库位
     * @return
     */
    @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 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));
    }
    /**
     * 获取ReceiptDetlsDtos
     */
    private R getAsnOrderItem(List<AsnOrderItem> items) {
@@ -326,9 +902,12 @@
            detlsDto.setAsnCode(asnOrderItem.getAsnCode())
                    .setMaktx(asnOrderItem.getMaktx())
                    .setBarcode(asnOrderItem.getBarcode())
                    .setFieldsIndex(asnOrderItem.getFieldsIndex())
                    .setBarcode(asnOrderItem.getTrackCode())
                    .setQty(asnOrderItem.getQty())
                    .setPoCode(asnOrderItem.getPoCode())
                    .setPurQty(asnOrderItem.getAnfme())
                    .setAnfme(asnOrderItem.getAnfme())
                    .setPurQty(asnOrderItem.getPurQty())
                    .setSplrBatch(asnOrderItem.getSplrBatch());
            Matnr matnr = matnrMapper.selectById(asnOrderItem.getMatnrId());
@@ -340,20 +919,22 @@
                    .setMatnrId(matnr.getId())
                    .setStockUnit(matnr.getStockUnit());
            QlyInspect inspect = qlyInspectMapper.selectOne(new LambdaQueryWrapper<QlyInspect>()
                    .eq(QlyInspect::getAsnItemId, asnOrderItem.getId()));
                    .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.getBatch())
                    .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());
            }
            if (!Objects.isNull(asnOrderItem.getPoDetlId())) {
@@ -364,7 +945,6 @@
                    detlsDto.setPlatformId(purchaseItem.getPlatItemId());
                }
            }
            detlsDtos.add(detlsDto);
        });