/* * Copyright (c) 2018-2025, ztt All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * Neither the name of the pig4cloud.com developer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * Author: ztt */ package com.chinaztt.mes.warehouse.service.impl; import cn.hutool.core.collection.CollectionUtil; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.chinaztt.ifs.api.feign.IfsFeignClient; import com.chinaztt.mes.basic.entity.Part; import com.chinaztt.mes.basic.mapper.LocationMapper; import com.chinaztt.mes.basic.mapper.PartMapper; import com.chinaztt.mes.warehouse.dto.IfsImportChangeWdrStdDTO; import com.chinaztt.mes.warehouse.dto.MoveLibraryBoxDTO; import com.chinaztt.mes.warehouse.dto.PackagingItemDTO; import com.chinaztt.mes.warehouse.entity.Packaging; import com.chinaztt.mes.warehouse.entity.PackagingItem; import com.chinaztt.mes.warehouse.entity.ZxLabelBindRelation; import com.chinaztt.mes.warehouse.mapper.PackagingItemMapper; import com.chinaztt.mes.warehouse.mapper.PackagingMapper; import com.chinaztt.mes.warehouse.mapper.ZxLabelBindRelationMapper; import com.chinaztt.mes.warehouse.service.PackagingItemService; import com.chinaztt.mes.warehouse.service.PackagingService; import com.chinaztt.mes.warehouse.util.WareHouseUtils; import com.chinaztt.ztt.common.core.util.R; import com.google.gson.Gson; import lombok.AllArgsConstructor; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors; /** * 包装从表 * * @author sunxl * @date 2021-06-03 15:19:30 */ @Service @AllArgsConstructor @Transactional(rollbackFor = Exception.class) public class PackagingItemServiceImpl extends ServiceImpl implements PackagingItemService { @Resource private PackagingMapper packagingMapper; @Resource private PartMapper partMapper; @Resource private WareHouseUtils wareHouseUtils; @Resource private PackagingService packagingService; @Resource private IfsFeignClient ifsFeignClient; @Resource private LocationMapper locationMapper; //@Qualifier("zxRelationMapper") @Resource private ZxLabelBindRelationMapper zxRelationMapper; @Override public IPage> getPackagingItemPage(Page page, QueryWrapper gen) { return baseMapper.getPackagingItemPage(page,gen); } @Override public Packaging removePackagingItemById(Long id) { PackagingItem packagingItem = baseMapper.selectById(id); if(wareHouseUtils.isPackConfirm(packagingItem.getPackagingId())){ throw new RuntimeException("包装已提交->冻结该操作"); } Part part = partMapper.selectById(packagingItem.getPartId()); Packaging packaging = packagingMapper.selectById(packagingItem.getPackagingId()); //修正包装主表的净重、包装数量、毛重、差异重量 if (part!=null){ //packaging.setNetWeight(packaging.getNetWeight().subtract(part.getWeight().multiply(packagingItem.getPackageQty()))); //修改包装净重 = 包装净重 - 明细理论重量 packaging.setNetWeight(packaging.getNetWeight().subtract(packagingItem.getTheoryWeight())); //修改包装毛重 = 包装净重 + 包装重量 packaging.setGrossWeight(packaging.getNetWeight().add(packaging.getPackWeight())); if (packaging.getNetWeight().compareTo(BigDecimal.ZERO)!=0){ if(packaging.getRealWeight() != null){ packaging.setDifferenceWeight(packaging.getNetWeight().subtract(packaging.getRealWeight())); }else{ packaging.setDifferenceWeight(packaging.getNetWeight()); } }else{ packaging.setDifferenceWeight(BigDecimal.ZERO);//差异重量置0 packaging.setRealWeight(BigDecimal.ZERO);//实际重量置0 } } //修改包装数量 = 包装数量 - 明细包装数量 packaging.setNumber(packaging.getNumber().subtract(packagingItem.getPackageQty())); packagingMapper.updateById(packaging); baseMapper.deleteById(id); return packaging; } @Override public R updateInLocationNoBatch(List packagingItemDTOList){ List packIdList = new ArrayList<>();//包装主表记录行id if(CollectionUtil.isNotEmpty(packagingItemDTOList)){ packIdList = packagingItemDTOList.stream().filter(o -> o.getPackagingId() != null).map(o -> o.getPackagingId()).collect(Collectors.toList()); //包装主表id集合 List distPackIdList = packIdList.stream().distinct().collect(Collectors.toList()); if(distPackIdList.size() > 1){ return R.failed("提交明细主表id不一致"); }else if(distPackIdList.size() == 0){ return R.failed("未获取到有效的包装主表id"); }else{ if(wareHouseUtils.isPackConfirm(distPackIdList.get(0))){ return R.failed("包装已提交->冻结该操作"); } for(PackagingItemDTO packagingItemDTO : packagingItemDTOList){ //根据库位编号获取库位id List inLicationIdList = Collections.singletonList(baseMapper.getLocationIdByLocationNo(packagingItemDTO.getInLocationNo())); if(inLicationIdList.size() > 1 || inLicationIdList.size() == 0 || inLicationIdList.get(0) == null){ return R.failed("根据库位编号=" + packagingItemDTO.getInLocationNo() + "->无法获取对应的库位id"); } baseMapper.updateInLocationNoById(packagingItemDTO.getId(),inLicationIdList.get(0)); } return R.ok(null,"操作成功"); } }else{ return R.failed("请求参数为空"); } } @Override public R getEnableFinishProdList(String locType){ return R.ok(baseMapper.getEnableFinishProdList(locType)); } @Override public R updateInLocationByPda(String packagingNo,String inLocationNo){ if(StringUtils.isBlank(packagingNo)||StringUtils.isBlank(inLocationNo)){ throw new RuntimeException("包装编号和库位号不能为空"); } List packagingItemList = baseMapper.getPackagingItemList(packagingNo); if (CollectionUtil.isEmpty(packagingItemList)) { throw new RuntimeException("没有包装明细"); } if (wareHouseUtils.isPackConfirm(packagingItemList.get(0).getPackagingId())) { throw new RuntimeException("包装已提交->冻结该操作"); } //更新至库位 Long inLocationId = baseMapper.getLocationIdByLocationNo(inLocationNo); packagingItemList.stream().forEach(a-> a.setInLocationId(inLocationId)); updateBatchById(packagingItemList); //移库 R res = packagingService.packConfirm(packagingItemList.get(0).getPackagingId()); //更新wdr doPdaPackaging(packagingItemList,packagingNo,inLocationNo); return res; } //ifs更新wdr接口 private void doPdaPackaging(List packagingItemList, String packagingNo, String inLocationNo) { List ifsPackagingList = baseMapper.getIfsPackagingList(packagingNo); //将list按照零件号进行分组,去除IFS启用批次管理为true的数据 Map> map = ifsPackagingList.stream().filter(x -> !x.getLotTrackingIfs()).collect(Collectors.groupingBy(PackagingItemDTO::getPartNo)); List ifsList = new ArrayList<>(); for (Map.Entry> entry : map.entrySet()){ List packagingItemDTOByGroupList = entry.getValue(); //汇总相同零件号的移库数量 BigDecimal packageQtySum = packagingItemDTOByGroupList.stream().filter(x -> x.getPackageQty() != null).map(PackagingItemDTO::getPackageQty).reduce(BigDecimal.ZERO, BigDecimal::add); PackagingItemDTO ifsDTO = new PackagingItemDTO(); BeanUtils.copyProperties(packagingItemDTOByGroupList.get(0), ifsDTO); ifsDTO.setPackageQty(packageQtySum); ifsList.add(ifsDTO); } //筛选出IFS启用批次管理为true的数据 List lotTrackingIfsList = ifsPackagingList.stream().filter(PackagingItemDTO::getLotTrackingIfs).collect(Collectors.toList()); ifsList.addAll(lotTrackingIfsList); IfsImportChangeWdrStdDTO ifsImportChangeWdrStdDTO = new IfsImportChangeWdrStdDTO(); ifsImportChangeWdrStdDTO.setRECORD_ID(UUID.randomUUID().toString().replace("-", "")); List dataBeanList = new ArrayList<>();//批量标识 for(PackagingItemDTO packagingItemDTO:ifsList){ IfsImportChangeWdrStdDTO.DataBean batchInfo = new IfsImportChangeWdrStdDTO.DataBean(); batchInfo.setPART_NO(packagingItemDTO.getPartNo());//零件号 batchInfo.setMOVE_QTY(packagingItemDTO.getPackageQty());//移库数量 //判断是否启用批次管理 //WDR号&批次号 if(packagingItemDTO.getLotTrackingIfs() != null && packagingItemDTO.getLotTrackingIfs()){ batchInfo.setWAIV_DEV_REJ_NO(packagingItemDTO.getOutBatchNo()); batchInfo.setLOT_BATCH_NO(packagingItemDTO.getOutBatchNo()); }else{ batchInfo.setWAIV_DEV_REJ_NO("*"); batchInfo.setLOT_BATCH_NO("*"); } //版本号 batchInfo.setENG_CHG_LEVEL(packagingItemDTO.getEngChgLevel()); //库位号 if(false){ //移库与更新wdr操作调换了顺序,先移库,再更新wdr,此时更新wdr时传的库位由移库前的库位改成移库后的库位 batchInfo.setLOCATION_NO(packagingItemDTO.getLocationNo()); } batchInfo.setLOCATION_NO(inLocationNo); //至WDR号 batchInfo.setTO_WAIV_DEV_REJ_NO(packagingNo); dataBeanList.add(batchInfo); } ifsImportChangeWdrStdDTO.setBATCH_INFO(dataBeanList); Gson gson = new Gson(); String jsonstr = gson.toJson(ifsImportChangeWdrStdDTO); JSONObject jsonObject = JSONObject.parseObject(jsonstr); R res = ifsFeignClient.importChangeWdrStd(jsonObject, true); if(res.getCode() != 0){ throw new RuntimeException("ifs更新wdr接口失败;erromsg:" + res.getMsg()); } if(false){ //更新至库位操作调到了移库操作之前执行 Long inLocationId = baseMapper.getLocationIdByLocationNo(inLocationNo); packagingItemList.stream().forEach(a-> a.setInLocationId(inLocationId)); updateBatchById(packagingItemList); } } @Override public R validatePackagingNoRepeat(String packagingCode, String pkgCode) { Integer count = zxRelationMapper.selectCount(Wrappers.lambdaQuery().eq(ZxLabelBindRelation::getShopCode, "ZX") .and(wrapper -> wrapper.eq(ZxLabelBindRelation::getPackagingCode, packagingCode).or().eq(ZxLabelBindRelation::getPkgId, pkgCode))); if (count > 0) { return R.failed("请勿重复扫描入库"); } else { return R.ok(); } } @Override public R updateZxInLocationByPda(String packagingCode, String pkgCode, String inLocationNo) { if(StringUtils.isBlank(packagingCode)||StringUtils.isBlank(inLocationNo)){ throw new RuntimeException("包装编号和库位号不能为空"); } List packagingItemList = baseMapper.getPackagingItemList(packagingCode); if (CollectionUtil.isEmpty(packagingItemList)) { throw new RuntimeException("没有包装明细"); } if (wareHouseUtils.isPackConfirm(packagingItemList.get(0).getPackagingId())) { throw new RuntimeException("包装已提交->冻结该操作"); } R r = R.ok(); try{ //更新至库位 Long inLocationId = baseMapper.getLocationIdByLocationNo(inLocationNo); packagingItemList.stream().forEach(a-> a.setInLocationId(inLocationId)); updateBatchById(packagingItemList); //移库 packagingService.packConfirm(packagingItemList.get(0).getPackagingId()); //更新wdr doPdaPackaging(packagingItemList, packagingCode, inLocationNo); }catch(Exception e){ r = R.failed(e.getMessage()); } if (r.getCode() == 0) { //解析出所需数据 String pkgId; String materialCode;//物料编码 BigDecimal quality;//数量 try{ List stringList = Arrays.asList(pkgCode.split("&")); if(stringList.size() < 3){ //正常的按&切割后是8段,但只有前3段对我们是有用的 throw new RuntimeException("PKG码格式错误"); }else{ pkgId = stringList.get(0); materialCode = stringList.get(1); quality = new BigDecimal(stringList.get(2)); } }catch(Exception e){ throw new RuntimeException("解析pkg码异常 -> " + e.getMessage()); } ZxLabelBindRelation zxLabelBindRelation = new ZxLabelBindRelation(); zxLabelBindRelation.setPackagingCode(packagingCode); zxLabelBindRelation.setPkgCode(pkgCode); zxLabelBindRelation.setShopCode("ZX"); //追加补充部分信息,零件号、mes码、批次号、ce码无法补充 zxLabelBindRelation.setPkgId(pkgId); zxLabelBindRelation.setMaterialCode(materialCode); zxLabelBindRelation.setQuantity(quality); zxRelationMapper.insert(zxLabelBindRelation); return R.ok(); }else { return r; } } }