@@ -29,6 +29,7 @@ import com.klp.domain.bo.WmsCoilPendingActionBo;
import com.klp.mapper.* ;
import com.klp.service.* ;
import com.klp.system.service.ISysUserService ;
import com.klp.utils.CoilBusinessRuleUtils ;
import lombok.RequiredArgsConstructor ;
import lombok.extern.slf4j.Slf4j ;
import org.apache.commons.collections4.CollectionUtils ;
@@ -1356,12 +1357,12 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
}
result = updateBySingle ( bo , qrcodeStepType ) ; // 返回新钢卷ID字符串
}
// 如果有关联的操作记录ID, 调用完成接口
if ( bo . getActionId ( ) ! = null & & bo . getActionId ( ) > 0 ) {
coilPendingActionService . completeAction ( bo . getActionId ( ) , result ) ;
}
return result ;
}
@@ -1410,6 +1411,9 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
validateActualWarehouseForAssign ( bo . getActualWarehouseId ( ) , ignoreOccupiedId ) ;
}
// 处理特殊业务逻辑:根据条件自动调整逻辑库区等字段
CoilBusinessRuleUtils . handleSpecialBusinessLogic ( oldCoil , bo ) ;
// 1. 历史钢卷( dataType=0) 禁止修改实际库区( actualWarehouseId非空且不等于-1)
if ( 0 = = oldCoil . getDataType ( ) ) { // 原钢卷是历史钢卷
// 场景1: 传入了新的实际库区ID, 且不是置空( -1) , 禁止操作
@@ -5195,232 +5199,6 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
return result ;
}
@Override
public WmsMaterialCoilReportSummaryVo reportSummary ( WmsMaterialCoilReportSummaryBo req ) {
WmsMaterialCoilBo coilFilter = req ! = null & & req . getMaterialCoilFilter ( ) ! = null
? req . getMaterialCoilFilter ( ) : new WmsMaterialCoilBo ( ) ;
WmsCoilPendingActionBo pendingFilter = req = = null ? null : req . getPendingActionFilter ( ) ;
if ( hasAnyPendingFilter ( pendingFilter ) ) {
List < Long > pendingCoilIds = queryCoilIdsByPendingFilter ( pendingFilter ) ;
if ( CollectionUtils . isEmpty ( pendingCoilIds ) ) {
return buildEmptySummary ( ) ;
}
coilFilter . setCoilIds ( mergeCoilIds ( coilFilter . getCoilIds ( ) , pendingCoilIds ) ) ;
}
List < WmsMaterialCoilVo > list = queryList ( coilFilter ) ;
return buildSummaryFromList ( list ) ;
}
private boolean hasAnyPendingFilter ( WmsCoilPendingActionBo bo ) {
if ( bo = = null ) {
return false ;
}
return bo . getCoilId ( ) ! = null
| | StringUtils . isNotBlank ( bo . getCurrentCoilNo ( ) )
| | bo . getActionType ( ) ! = null
| | CollectionUtils . isNotEmpty ( bo . getActionTypes ( ) )
| | bo . getActionStatus ( ) ! = null
| | bo . getWarehouseId ( ) ! = null
| | bo . getPriority ( ) ! = null
| | StringUtils . isNotBlank ( bo . getSourceType ( ) )
| | bo . getStartTime ( ) ! = null
| | bo . getEndTime ( ) ! = null
| | StringUtils . isNotBlank ( bo . getCreateBy ( ) )
| | StringUtils . isNotBlank ( bo . getUpdateBy ( ) )
| | StringUtils . isNotBlank ( bo . getProcessedCoilIds ( ) )
| | bo . getIncludeDeleted ( ) ! = null ;
}
private List < Long > queryCoilIdsByPendingFilter ( WmsCoilPendingActionBo bo ) {
LambdaQueryWrapper < WmsCoilPendingAction > qw = Wrappers . lambdaQuery ( ) ;
qw . select ( WmsCoilPendingAction : : getCoilId ) ;
qw . eq ( bo . getCoilId ( ) ! = null , WmsCoilPendingAction : : getCoilId , bo . getCoilId ( ) ) ;
qw . like ( StringUtils . isNotBlank ( bo . getCurrentCoilNo ( ) ) , WmsCoilPendingAction : : getCurrentCoilNo , bo . getCurrentCoilNo ( ) ) ;
if ( CollectionUtils . isNotEmpty ( bo . getActionTypes ( ) ) ) {
qw . in ( WmsCoilPendingAction : : getActionType , bo . getActionTypes ( ) ) ;
} else {
qw . eq ( bo . getActionType ( ) ! = null , WmsCoilPendingAction : : getActionType , bo . getActionType ( ) ) ;
}
if ( bo . getActionStatus ( ) ! = null ) {
if ( bo . getActionStatus ( ) = = - 1 ) {
qw . ne ( WmsCoilPendingAction : : getActionStatus , 2 ) ;
} else {
qw . eq ( WmsCoilPendingAction : : getActionStatus , bo . getActionStatus ( ) ) ;
}
}
qw . eq ( bo . getWarehouseId ( ) ! = null , WmsCoilPendingAction : : getWarehouseId , bo . getWarehouseId ( ) ) ;
qw . eq ( bo . getPriority ( ) ! = null , WmsCoilPendingAction : : getPriority , bo . getPriority ( ) ) ;
qw . like ( StringUtils . isNotBlank ( bo . getSourceType ( ) ) , WmsCoilPendingAction : : getSourceType , bo . getSourceType ( ) ) ;
qw . ge ( bo . getStartTime ( ) ! = null , WmsCoilPendingAction : : getCompleteTime , bo . getStartTime ( ) ) ;
qw . le ( bo . getEndTime ( ) ! = null , WmsCoilPendingAction : : getCompleteTime , bo . getEndTime ( ) ) ;
qw . eq ( StringUtils . isNotBlank ( bo . getCreateBy ( ) ) , WmsCoilPendingAction : : getCreateBy , bo . getCreateBy ( ) ) ;
qw . eq ( StringUtils . isNotBlank ( bo . getUpdateBy ( ) ) , WmsCoilPendingAction : : getUpdateBy , bo . getUpdateBy ( ) ) ;
qw . like ( StringUtils . isNotBlank ( bo . getProcessedCoilIds ( ) ) , WmsCoilPendingAction : : getProcessedCoilIds , bo . getProcessedCoilIds ( ) ) ;
if ( bo . getIncludeDeleted ( ) ! = null ) {
if ( bo . getIncludeDeleted ( ) = = 2 ) {
qw . eq ( WmsCoilPendingAction : : getDelFlag , 2 ) ;
} else if ( bo . getIncludeDeleted ( ) = = 0 ) {
qw . eq ( WmsCoilPendingAction : : getDelFlag , 0 ) ;
}
} else {
qw . eq ( WmsCoilPendingAction : : getDelFlag , 0 ) ;
}
List < WmsCoilPendingAction > actions = coilPendingActionMapper . selectList ( qw ) ;
if ( CollectionUtils . isEmpty ( actions ) ) {
return Collections . emptyList ( ) ;
}
return actions . stream ( )
. map ( WmsCoilPendingAction : : getCoilId )
. filter ( Objects : : nonNull )
. distinct ( )
. collect ( Collectors . toList ( ) ) ;
}
private String mergeCoilIds ( String coilIdsCsv , List < Long > pendingCoilIds ) {
Set < Long > pendingSet = new LinkedHashSet < > ( pendingCoilIds ) ;
if ( StringUtils . isBlank ( coilIdsCsv ) ) {
return pendingSet . stream ( ) . map ( String : : valueOf ) . collect ( Collectors . joining ( " , " ) ) ;
}
List < Long > existing = parseCsvLongs ( coilIdsCsv ) ;
if ( CollectionUtils . isEmpty ( existing ) ) {
return pendingSet . stream ( ) . map ( String : : valueOf ) . collect ( Collectors . joining ( " , " ) ) ;
}
Set < Long > existingSet = new LinkedHashSet < > ( existing ) ;
existingSet . retainAll ( pendingSet ) ;
if ( existingSet . isEmpty ( ) ) {
return " -1 " ;
}
return existingSet . stream ( ) . map ( String : : valueOf ) . collect ( Collectors . joining ( " , " ) ) ;
}
private WmsMaterialCoilReportSummaryVo buildEmptySummary ( ) {
WmsMaterialCoilReportSummaryVo vo = new WmsMaterialCoilReportSummaryVo ( ) ;
vo . setTotalCount ( 0 ) ;
vo . setTotalWeight ( " 0.00 " ) ;
vo . setAvgWeight ( " 0 " ) ;
vo . setAbnormalSummary ( buildAbnormalSummary ( Collections . emptyList ( ) ) ) ;
vo . setTeamSummary ( Collections . emptyMap ( ) ) ;
return vo ;
}
private WmsMaterialCoilReportSummaryVo buildSummaryFromList ( List < WmsMaterialCoilVo > list ) {
List < WmsMaterialCoilVo > safeList = list = = null ? Collections . emptyList ( ) : list ;
int totalCount = safeList . size ( ) ;
BigDecimal totalWeight = safeList . stream ( )
. map ( WmsMaterialCoilVo : : getNetWeight )
. filter ( Objects : : nonNull )
. reduce ( BigDecimal . ZERO , BigDecimal : : add ) ;
String avgWeight = totalCount > 0
? totalWeight . divide ( BigDecimal . valueOf ( totalCount ) , 2 , java . math . RoundingMode . HALF_UP ) . toPlainString ( )
: " 0 " ;
WmsMaterialCoilReportSummaryVo vo = new WmsMaterialCoilReportSummaryVo ( ) ;
vo . setTotalCount ( totalCount ) ;
vo . setTotalWeight ( totalWeight . setScale ( 2 , java . math . RoundingMode . HALF_UP ) . toPlainString ( ) ) ;
vo . setAvgWeight ( avgWeight ) ;
vo . setAbnormalSummary ( buildAbnormalSummary ( safeList ) ) ;
vo . setTeamSummary ( buildTeamSummary ( safeList ) ) ;
return vo ;
}
private List < Map < String , String > > buildAbnormalSummary ( List < WmsMaterialCoilVo > list ) {
int totalCount = list . size ( ) ;
int jishuCount = 0 ;
int miniCount = 0 ;
int rubbishCount = 0 ;
int returnCount = 0 ;
BigDecimal jishuWeight = BigDecimal . ZERO ;
BigDecimal miniWeight = BigDecimal . ZERO ;
BigDecimal rubbishWeight = BigDecimal . ZERO ;
BigDecimal returnWeight = BigDecimal . ZERO ;
for ( WmsMaterialCoilVo coil : list ) {
String warehouseId = coil . getWarehouseId ( ) = = null ? null : String . valueOf ( coil . getWarehouseId ( ) ) ;
String qualityStatus = coil . getQualityStatus ( ) ;
BigDecimal netWeight = coil . getNetWeight ( ) = = null ? BigDecimal . ZERO : coil . getNetWeight ( ) ;
if ( " 2019583656787259393 " . equals ( warehouseId ) | | " O " . equals ( qualityStatus ) ) {
jishuCount + + ;
jishuWeight = jishuWeight . add ( netWeight ) ;
} else if ( " 2019583325311414274 " . equals ( warehouseId ) ) {
miniCount + + ;
miniWeight = miniWeight . add ( netWeight ) ;
} else if ( " 2019583429955104769 " . equals ( warehouseId )
| | " D- " . equals ( qualityStatus )
| | " D " . equals ( qualityStatus )
| | " D+ " . equals ( qualityStatus )
| | " C- " . equals ( qualityStatus )
| | " C " . equals ( qualityStatus )
| | " C+ " . equals ( qualityStatus ) ) {
rubbishCount + + ;
rubbishWeight = rubbishWeight . add ( netWeight ) ;
} else if ( " 2019583137616310273 " . equals ( warehouseId ) ) {
returnCount + + ;
returnWeight = returnWeight . add ( netWeight ) ;
}
}
List < Map < String , String > > result = new ArrayList < > ( ) ;
result . add ( buildLabelValue ( " 技术部钢卷数 " , String . valueOf ( jishuCount ) ) ) ;
result . add ( buildLabelValue ( " 小钢卷库钢卷数 " , String . valueOf ( miniCount ) ) ) ;
result . add ( buildLabelValue ( " 废品库钢卷数 " , String . valueOf ( rubbishCount ) ) ) ;
result . add ( buildLabelValue ( " 退货库钢卷数 " , String . valueOf ( returnCount ) ) ) ;
result . add ( buildLabelValue ( " 技术部钢卷重量 " , jishuWeight . setScale ( 2 , java . math . RoundingMode . HALF_UP ) . toPlainString ( ) ) ) ;
result . add ( buildLabelValue ( " 小钢卷库钢卷重量 " , miniWeight . setScale ( 2 , java . math . RoundingMode . HALF_UP ) . toPlainString ( ) ) ) ;
result . add ( buildLabelValue ( " 废品库钢卷重量 " , rubbishWeight . setScale ( 2 , java . math . RoundingMode . HALF_UP ) . toPlainString ( ) ) ) ;
result . add ( buildLabelValue ( " 退货库钢卷重量 " , returnWeight . setScale ( 2 , java . math . RoundingMode . HALF_UP ) . toPlainString ( ) ) ) ;
result . add ( buildLabelValue ( " 技术部占比 " , percent ( jishuCount , totalCount ) ) ) ;
result . add ( buildLabelValue ( " 小钢卷库占比 " , percent ( miniCount , totalCount ) ) ) ;
result . add ( buildLabelValue ( " 废品库占比 " , percent ( rubbishCount , totalCount ) ) ) ;
result . add ( buildLabelValue ( " 退货库占比 " , percent ( returnCount , totalCount ) ) ) ;
return result ;
}
private Map < String , WmsMaterialCoilReportSummaryVo . TeamSummaryItem > buildTeamSummary ( List < WmsMaterialCoilVo > list ) {
Map < String , WmsMaterialCoilReportSummaryVo . TeamSummaryItem > teamSummary = new LinkedHashMap < > ( ) ;
for ( WmsMaterialCoilVo coil : list ) {
String team = StringUtils . isNotBlank ( coil . getTeam ( ) ) ? coil . getTeam ( ) : " 未分配 " ;
WmsMaterialCoilReportSummaryVo . TeamSummaryItem item = teamSummary . computeIfAbsent ( team , k - > {
WmsMaterialCoilReportSummaryVo . TeamSummaryItem summaryItem = new WmsMaterialCoilReportSummaryVo . TeamSummaryItem ( ) ;
summaryItem . setCount ( 0 ) ;
summaryItem . setWeight ( " 0.00 " ) ;
return summaryItem ;
} ) ;
int nextCount = item . getCount ( ) = = null ? 1 : item . getCount ( ) + 1 ;
BigDecimal currWeight = StringUtils . isBlank ( item . getWeight ( ) ) ? BigDecimal . ZERO : new BigDecimal ( item . getWeight ( ) ) ;
BigDecimal netWeight = coil . getNetWeight ( ) = = null ? BigDecimal . ZERO : coil . getNetWeight ( ) ;
item . setCount ( nextCount ) ;
item . setWeight ( currWeight . add ( netWeight ) . setScale ( 2 , java . math . RoundingMode . HALF_UP ) . toPlainString ( ) ) ;
}
return teamSummary ;
}
private Map < String , String > buildLabelValue ( String label , String value ) {
Map < String , String > map = new LinkedHashMap < > ( 2 ) ;
map . put ( " label " , label ) ;
map . put ( " value " , value ) ;
return map ;
}
private String percent ( int part , int total ) {
if ( total < = 0 ) {
return " 0.00% " ;
}
return BigDecimal . valueOf ( part )
. multiply ( BigDecimal . valueOf ( 100 ) )
. divide ( BigDecimal . valueOf ( total ) , 2 , java . math . RoundingMode . HALF_UP )
. toPlainString ( ) + " % " ;
}
/**
* 查询itemId和itemType不匹配的钢卷
* 检查所有钢卷的itemId是否存在于对应的表中( 根据itemType)