@ -3,27 +3,36 @@ package com.gaotao.modules.outsourcing.service.impl;
import com.gaotao.modules.api.entity.issueAndReturnVo.* ;
import com.gaotao.modules.api.service.IfsApiIssueAndReturnService ;
import com.gaotao.modules.handlingunit.entity.HandlingUnit ;
import com.gaotao.modules.handlingunit.service.HandlingUnitIdGeneratorService ;
import com.gaotao.modules.handlingunit.service.HandlingUnitService ;
import com.gaotao.modules.outsourcing.dao.OutsourcingReturnMapper ;
import com.gaotao.modules.outsourcing.entity.dto.OutsourcingReturnDto ;
import com.gaotao.modules.outsourcing.entity.dto.MrIssueMaterialDto ;
import com.gaotao.modules.outsourcing.service.OutsourcingReturnService ;
import com.gaotao.modules.production.entity.dto.CreateHuRequestReturnIssueDto ;
import com.gaotao.modules.production.entity.dto.MaterialLabelInfo ;
import com.gaotao.modules.production.entity.dto.WorkOrderMaterialDto ;
import com.gaotao.modules.trans.entity.TransCommonRequestDto ;
import com.gaotao.modules.trans.entity.TransCommonSubDto ;
import com.gaotao.modules.trans.entity.TransDetail ;
import com.gaotao.modules.trans.service.TransHeaderService ;
import com.gaotao.modules.warehouse.entity.Location ;
import jakarta.transaction.Transactional ;
import lombok.extern.slf4j.Slf4j ;
import org.springframework.beans.factory.annotation.Autowired ;
import org.springframework.stereotype.Service ;
import org.springframework.util.CollectionUtils ;
import java.math.BigDecimal ;
import java.math.RoundingMode ;
import java.text.SimpleDateFormat ;
import java.util.* ;
import java.util.stream.Collectors ;
/ * *
* 委外退料服务实现类
* /
@Slf4j
@Service
public class OutsourcingReturnServiceImpl implements OutsourcingReturnService {
@ -35,6 +44,12 @@ public class OutsourcingReturnServiceImpl implements OutsourcingReturnService {
@Autowired
private TransHeaderService transHeaderService ;
@Autowired
private HandlingUnitService handlingUnitService ;
@Autowired
private HandlingUnitIdGeneratorService handlingUnitIdGeneratorService ;
@Autowired
private com . gaotao . modules . handlingunit . service . HandlingUnitIdLogService handlingUnitIdLogService ;
@Override
public List < PurchaseOrderLineVo > searchOutsourcingOrdersForReturn ( String searchValue , String site ) throws Exception {
@ -85,11 +100,39 @@ public class OutsourcingReturnServiceImpl implements OutsourcingReturnService {
@Override
@Transactional
public void outsourcingReturnUnissueConfirm ( OutsourcingReturnDto dto ) throws Exception {
public List < String > outsourcingReturnUnissueConfirm ( OutsourcingReturnDto dto ) throws Exception {
if ( dto . getSelectedMaterials ( ) = = null | | dto . getSelectedMaterials ( ) . isEmpty ( ) ) {
throw new Exception ( "没有选择要退料的物料" ) ;
}
validateLocal ( dto . getSelectedMaterials ( ) , dto . getSite ( ) ) ;
List < MrIssueMaterialDto > newSelectMaterials = new ArrayList < > ( ) ;
/ / 如果时NEW的HU , 改变他的unit
for ( MrIssueMaterialDto material : dto . getSelectedMaterials ( ) ) {
if ( "NEW" . equals ( material . getNewPrint ( ) ) ) {
CreateHuRequestReturnIssueDto huRequest = new CreateHuRequestReturnIssueDto ( ) ;
huRequest . setSite ( dto . getSite ( ) ) ;
huRequest . setLocationId ( material . getLocationId ( ) ) ;
huRequest . setPartNo ( dto . getComponentPartNo ( ) ) ;
huRequest . setPartDesc ( dto . getComponentPartNo ( ) ) ;
huRequest . setBatchNo ( dto . getBatchNo ( ) ) ;
huRequest . setWdr ( material . getWdrNo ( ) ) ;
huRequest . setHeight ( material . getHeight ( ) ) ;
huRequest . setQty ( material . getIssueQty ( ) ) ;
huRequest . setOrderNo ( dto . getOutsourcingOrderNo ( ) ) ;
String unitId = createNewReturnHandlingUnits ( huRequest ) ;
material . setLabelCode ( unitId ) ;
newSelectMaterials . add ( material ) ;
} else {
HandlingUnit byId = handlingUnitService . getById ( material . getLabelCode ( ) ) ;
if ( byId = = null ) {
throw new Exception ( "数据库不存在确认退料标签" ) ;
}
material . setHeight ( material . getHeight ( ) . add ( byId . getHeight ( ) = = null ? BigDecimal . ZERO : byId . getHeight ( ) ) ) ;
newSelectMaterials . add ( material ) ;
}
}
List < TransCommonSubDto > subList = new ArrayList < > ( ) ;
TransCommonRequestDto transCommonRequestDto = new TransCommonRequestDto ( ) ;
@ -99,8 +142,20 @@ public class OutsourcingReturnServiceImpl implements OutsourcingReturnService {
transCommonRequestDto . setRemark ( "委外退料-订单:" + dto . getOutsourcingOrderNo ( ) ) ;
transCommonRequestDto . setStatus ( "C" ) ;
transCommonRequestDto . setWorkOrderNo ( dto . getOutsourcingOrderNo ( ) ) ;
transCommonRequestDto . setWarehouseId ( dto . getWarehouseId ( ) ) ;
transCommonRequestDto . setSourceNo ( dto . getOutsourcingOrderNo ( ) ) ;
Double seqNo = 1 . 0 ;
List < Location > allLocation = outsourcingReturnMapper . getAllLocation ( dto . getSite ( ) ) ;
Map < String , String > locationWarehouseMap = allLocation . stream ( )
. filter ( loc - > loc ! = null
& & loc . getLocationId ( ) ! = null
& & ! loc . getLocationId ( ) . trim ( ) . isEmpty ( ) )
. collect ( Collectors . toMap (
loc - > loc . getLocationId ( ) . trim ( ) ,
Location : : getWarehouseId ,
( oldVal , newVal ) - > newVal
) ) ;
/ / 处理每个选择的物料
for ( MrIssueMaterialDto material : dto . getSelectedMaterials ( ) ) {
/ / 创建退料记录详情
@ -108,8 +163,11 @@ public class OutsourcingReturnServiceImpl implements OutsourcingReturnService {
subDto . setPartNo ( material . getPartNo ( ) ) ;
subDto . setSubNo ( material . getLabelCode ( ) ) ;
subDto . setBatchNo ( material . getBatchNo ( ) ) ;
subDto . setWarehouseId ( material . getWarehouseId ( ) ) ;
subDto . setLocationId ( material . getLocationId ( ) ) ;
String targetWarehouseId = locationWarehouseMap . get ( material . getLocationId ( ) ) ;
if ( targetWarehouseId ! = null ) {
subDto . setWarehouseId ( targetWarehouseId ) ;
}
subDto . setTransQty ( material . getIssueQty ( ) . toString ( ) ) ;
subDto . setDirection ( "+" ) ; / / 退料为正向
subDto . setWdrNo ( material . getWdrNo ( ) = = null ? "*" : material . getWdrNo ( ) ) ;
@ -122,6 +180,51 @@ public class OutsourcingReturnServiceImpl implements OutsourcingReturnService {
transCommonRequestDto . setSubList ( subList ) ;
List < TransDetail > out = transHeaderService . genTransAndChangeInventoryStock ( transCommonRequestDto , "IN" ) ;
/ / 前端打印新标签并跟新HandlingUnit的库位和长度
List < HandlingUnit > handlingUnits = new ArrayList < > ( ) ;
List < String > unitIdPrints = new ArrayList < > ( ) ;
Set < String > unitIds = dto . getSelectedMaterials ( ) . stream ( )
. map ( MrIssueMaterialDto : : getLabelCode )
. filter ( Objects : : nonNull )
. collect ( Collectors . toSet ( ) ) ;
if ( unitIds . isEmpty ( ) ) {
throw new IllegalArgumentException ( "列表中标签号均为空,无法查询数据库" ) ;
}
List < HandlingUnit > huList = outsourcingReturnMapper . selectByUnitIds ( unitIds ) ;
Map < String , HandlingUnit > huMap = huList . stream ( )
. collect ( Collectors . toMap ( HandlingUnit : : getUnitId , hu - > hu , ( existing , replacement ) - > existing ) ) ;
for ( MrIssueMaterialDto material : newSelectMaterials ) {
HandlingUnit hu = new HandlingUnit ( ) ;
hu . setUnitId ( material . getLabelCode ( ) ) ;
hu . setLocationId ( material . getLocationId ( ) ) ;
String targetWarehouseId = locationWarehouseMap . get ( material . getLocationId ( ) ) ;
if ( targetWarehouseId ! = null ) {
hu . setWarehouseId ( targetWarehouseId ) ;
}
if ( "NEW" . equals ( material . getNewPrint ( ) ) ) {
hu . setQty ( material . getIssueQty ( ) ) ;
} else {
String unitId = material . getLabelCode ( ) ;
if ( unitId ! = null & & huMap . containsKey ( unitId ) ) {
/ / 减去要出的hu上的数量
HandlingUnit unit = huMap . get ( unitId ) ;
BigDecimal qty = unit . getQty ( ) ;
BigDecimal materialIssueQty = material . getIssueQty ( ) ;
if ( qty ! = null & & materialIssueQty ! = null ) {
BigDecimal nowQty = qty . add ( materialIssueQty ) . setScale ( 6 , RoundingMode . HALF_UP ) ;
hu . setQty ( nowQty ) ;
}
}
}
hu . setHeight ( material . getHeight ( ) = = null ? BigDecimal . ZERO : material . getHeight ( ) ) ;
handlingUnits . add ( hu ) ;
unitIdPrints . add ( material . getLabelCode ( ) ) ;
}
outsourcingReturnMapper . updateNewHandingUnit ( handlingUnits ) ;
/ / 同步退料到IFS系统
for ( TransDetail issue : out ) {
PurchaseOrderUnIssueComponentDto reserveComponentDto = new PurchaseOrderUnIssueComponentDto ( ) ;
@ -142,14 +245,199 @@ public class OutsourcingReturnServiceImpl implements OutsourcingReturnService {
reserveComponentDto . setIfsQty ( dto . getAllQty ( ) ) ; / / 退料
String s = ifsApiIssueAndReturnService . addPurchaseOrderUnIssueComponent ( reserveComponentDto ) ;
}
List < HandlingUnit > handlingUnits = new ArrayList < > ( ) ;
for ( MrIssueMaterialDto material : dto . getSelectedMaterials ( ) ) {
HandlingUnit hu = new HandlingUnit ( ) ;
hu . setUnitId ( material . getLabelCode ( ) ) ;
hu . setLocationId ( material . getLocationId ( ) ) ;
hu . setQty ( material . getIssueQty ( ) ) ;
handlingUnits . add ( hu ) ;
return unitIdPrints ;
}
public boolean validateLocal ( List < MrIssueMaterialDto > selectedMaterials , String site ) throws Exception {
/ / 校验库位
Set < String > unitIds = selectedMaterials . stream ( )
. map ( MrIssueMaterialDto : : getLocationId )
. collect ( Collectors . toSet ( ) ) ;
if ( CollectionUtils . isEmpty ( unitIds ) ) {
throw new IllegalArgumentException ( "存在库位为输入" ) ;
}
List < Location > allLocation = outsourcingReturnMapper . getAllLocation ( site ) ;
Set < String > existingLocationIds = allLocation . stream ( )
. map ( Location : : getLocationId )
. filter ( locationId - > locationId ! = null & & ! locationId . trim ( ) . isEmpty ( ) ) / / 过滤无效值
. map ( String : : trim )
. collect ( Collectors . toSet ( ) ) ;
/ / 3 . 筛选出unitIds中不存在于existingLocationIds的元素
Set < String > nonExistentIds = unitIds . stream ( )
. filter ( locationId - > ! existingLocationIds . contains ( locationId ) )
. collect ( Collectors . toSet ( ) ) ;
/ / 4 . 若存在不存在的locationId , 抛异常 ( 明确提示不存在的ID , 方便排查 )
if ( ! CollectionUtils . isEmpty ( nonExistentIds ) ) {
throw new Exception (
String . format ( "列表中库位%s不存在" ,
String . join ( ", " , nonExistentIds ) )
) ;
}
return true ;
}
@Transactional
public String createNewReturnHandlingUnits ( CreateHuRequestReturnIssueDto request ) throws Exception {
Location location = outsourcingReturnMapper . getLocation ( request . getLocationId ( ) , request . getSite ( ) ) ;
if ( location = = null ) {
throw new Exception ( "库位不存在,请确认" ) ;
}
/ / 1 . 先创建packageCount个完整HU
HandlingUnit onunit = outsourcingReturnMapper . getOneHandlingUnit ( request ) ;
List < AnInventoryPartInStockVo > partInStock = null ;
Date newReceiveDate = null ;
Date newManufactureDate = null ;
Date newExpireData = null ;
String newUmId = request . getUmid ( ) = = null ? "" : request . getUmid ( ) ;
String newEngChgLevel = null ;
SimpleDateFormat sdf = new SimpleDateFormat ( "yyyy-MM-dd'-'HH.mm.ss" ) ;
if ( onunit = = null ) {
partInStock = ifsApiIssueAndReturnService . getAnInventoryPartInStock ( request . getSite ( ) , request . getPartNo ( ) ) ;
if ( partInStock = = null | | partInStock . size ( ) = = 0 ) {
/ / throw new Exception ( "无法获取物料信息" ) ;
/ / todo 目前一些物料没有入库信息 , 所以使用当前时间作为入库时间
newReceiveDate = new Date ( ) ;
newManufactureDate = new Date ( ) ;
Calendar calendar = Calendar . getInstance ( ) ;
calendar . setTime ( new Date ( ) ) ;
calendar . add ( Calendar . YEAR , 2 ) ;
Date datePlusTwoYears = calendar . getTime ( ) ;
newExpireData = datePlusTwoYears ;
newEngChgLevel = "1" ;
} else {
for ( AnInventoryPartInStockVo vo : partInStock ) {
if ( vo . getContract ( ) . equals ( request . getSite ( ) ) & & vo . getPartNo ( ) . equals ( request . getPartNo ( ) ) & & vo . getLotBatchNo ( ) . equals ( request . getBatchNo ( ) ) & & vo . getLocationNo ( ) . equals ( request . getLocationId ( ) ) ) {
newReceiveDate = sdf . parse ( vo . getReceiptDate ( ) ) ;
newManufactureDate = sdf . parse ( vo . getReceiptDate ( ) ) ;
newExpireData = sdf . parse ( vo . getExpirationDate ( ) ) ;
newEngChgLevel = vo . getEngChgLevel ( ) ;
}
}
}
} else {
newReceiveDate = onunit . getReceiveDate ( ) ;
newManufactureDate = onunit . getManufactureDate ( ) ;
newExpireData = onunit . getExpiredDate ( ) ;
newUmId = onunit . getUmId ( ) ;
newEngChgLevel = onunit . getEngChgLevel ( ) ! = null ? onunit . getEngChgLevel ( ) : "1" ;
}
/ / 生成处理单元ID
String unitId = handlingUnitIdGeneratorService . generateUnitId ( request . getSite ( ) ) ;
/ / 记录unitId生成日志到数据库
handlingUnitIdLogService . logUnitIdGeneration (
unitId ,
request . getSite ( ) ,
"IFS_INIT" ,
"" ,
"" ,
request . getPartNo ( ) ,
request . getBatchNo ( ) ,
request . getQty ( ) . doubleValue ( ) ,
"SYSTEM" ,
"GENERATING" ,
"IFS库存初始化-完整HU-第" + 1 + "个"
) ;
/ / 创建HandlingUnit对象
HandlingUnit handlingUnit = new HandlingUnit ( ) ;
handlingUnit . setUnitId ( unitId ) ;
handlingUnit . setSite ( request . getSite ( ) ) ;
handlingUnit . setUnitType ( "ROLL" ) ;
handlingUnit . setUnitTypeDb ( "ROLL" ) ;
handlingUnit . setPartNo ( request . getPartNo ( ) ) ;
handlingUnit . setPartDesc ( request . getPartDesc ( ) ) ;
handlingUnit . setQty ( request . getQty ( ) ) ; / / 使用计算后的数量
handlingUnit . setBatchNo ( request . getBatchNo ( ) ) ;
handlingUnit . setLocationId ( request . getLocationId ( ) ) ;
handlingUnit . setWarehouseId ( location . getWarehouseId ( ) ) ;
handlingUnit . setWdr ( request . getWdr ( ) ) ;
handlingUnit . setStatus ( "ACTIVE" ) ;
handlingUnit . setStatusDb ( "ACTIVE" ) ;
handlingUnit . setFreezeFlag ( "N" ) ;
handlingUnit . setReserveFlag ( "N" ) ;
handlingUnit . setMergedFlag ( "N" ) ;
handlingUnit . setInStockFlag ( "N" ) ;
handlingUnit . setCreatedDate ( new Date ( ) ) ;
handlingUnit . setCreatedBy ( "SYSTEM" ) ;
handlingUnit . setSourceType ( "IFS_INIT" ) ;
handlingUnit . setOriginalQty ( request . getQty ( ) ) ; / / 使用计算后的数量
handlingUnit . setReceiveDate ( newReceiveDate ) ;
handlingUnit . setHeight ( request . getHeight ( ) ) ;
/ / 根据料号和单位计算长宽
BigDecimal width = null ;
BigDecimal length = null ;
String partNo = request . getPartNo ( ) ;
if ( partNo ! = null & & partNo . contains ( "-" ) ) {
/ / 如果料号带尾缀 , 比如70001234 - 0250 , 那么width就是250
String [ ] parts = partNo . split ( "-" ) ;
String suffix = parts [ parts . length - 1 ] ;
try {
int widthVal = Integer . parseInt ( suffix ) ;
width = BigDecimal . valueOf ( widthVal ) ;
} catch ( NumberFormatException e ) {
/ / 默认1000
}
}
outsourcingReturnMapper . updateHandingUnit ( handlingUnits ) ;
/ / length就是数量乘以1000再除以width
if ( width ! = null & & width . compareTo ( BigDecimal . ZERO ) > 0 ) {
length = request . getQty ( ) . multiply ( BigDecimal . valueOf ( 1000 ) )
. divide ( width , 2 , java . math . RoundingMode . HALF_UP ) ;
}
handlingUnit . setWidth ( width ) ;
handlingUnit . setLength ( length ) ;
handlingUnit . setManufactureDate ( newManufactureDate ) ;
handlingUnit . setExpiredDate ( newExpireData ) ;
handlingUnit . setUmId ( newUmId ) ;
handlingUnit . setEngChgLevel ( newEngChgLevel ) ; / / 设置工程变更级别 , 默认1
/ / 保存HandlingUnit
boolean saveResult = handlingUnitService . save ( handlingUnit ) ;
if ( ! saveResult ) {
log . error ( "严重错误:HandlingUnit保存返回失败!unitId={}" , unitId ) ;
handlingUnitIdLogService . logUnitIdGeneration (
unitId , request . getSite ( ) , "IFS_INIT" , "" ,
"" , request . getPartNo ( ) , request . getBatchNo ( ) ,
request . getQty ( ) . doubleValue ( ) , "SYSTEM" ,
"N" , "保存失败-save返回false"
) ;
throw new RuntimeException ( "HandlingUnit保存失败(save返回false): " + unitId ) ;
}
/ / 立即验证是否保存成功 ( 防止保存失败但业务继续执行 )
HandlingUnit savedUnit = handlingUnitService . getById ( unitId ) ;
if ( savedUnit = = null ) {
log . error ( "严重错误:HandlingUnit保存验证失败!unitId={}" , unitId ) ;
/ / 更新日志为失败
handlingUnitIdLogService . logUnitIdGeneration (
unitId , request . getSite ( ) , "IFS_INIT" , "" ,
"" , request . getPartNo ( ) , request . getBatchNo ( ) ,
request . getQty ( ) . doubleValue ( ) , "SYSTEM" ,
"N" , "保存失败-验证未通过"
) ;
throw new RuntimeException ( "HandlingUnit保存失败(验证未通过): " + unitId ) ;
}
/ / 更新日志为成功
handlingUnitIdLogService . logUnitIdGeneration (
unitId , request . getSite ( ) , "IFS_INIT" , "" ,
"" , request . getPartNo ( ) , request . getBatchNo ( ) ,
request . getQty ( ) . doubleValue ( ) , "SYSTEM" ,
"Y" , "保存成功"
) ;
return unitId ;
}
}