@@ -41,6 +41,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.* ;
import java.util.stream.Collectors ;
import java.math.BigDecimal ;
import java.math.RoundingMode ;
import java.util.Arrays ;
import java.io.IOException ;
import java.net.URLEncoder ;
@@ -697,6 +698,10 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
qw . eq ( bo . getActualWidth ( ) ! = null , " mc.actual_width " , bo . getActualWidth ( ) ) ;
// 实测厚度
qw . eq ( StringUtils . isNotBlank ( bo . getActualThickness ( ) ) , " mc.actual_thickness " , bo . getActualThickness ( ) ) ;
// 理论厚度
qw . eq ( bo . getTheoreticalThickness ( ) ! = null , " mc.theoretical_thickness " , bo . getTheoreticalThickness ( ) ) ;
// 镀铬卷号
qw . like ( StringUtils . isNotBlank ( bo . getChromePlateCoilNo ( ) ) , " mc.chrome_plate_coil_no " , bo . getChromePlateCoilNo ( ) ) ;
// 生产开始时间
qw . eq ( bo . getProductionStartTime ( ) ! = null , " mc.production_start_time " , bo . getProductionStartTime ( ) ) ;
// 生产结束时间
@@ -1028,6 +1033,123 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
return '(' + String . join ( " OR " , parts ) + ')' ;
}
/**
* 根据净重(吨)、实测长度(mm)、物品规格宽度(mm)自动计算理论厚度(mm)
* 公式:理论厚度 = 净重(吨) × 1000 / (7.85 × 实测长度(mm) × 宽度(mm))
*/
private void calculateTheoreticalThickness ( WmsMaterialCoilBo bo ) {
if ( bo . getTheoreticalThickness ( ) ! = null ) {
return ;
}
if ( bo . getNetWeight ( ) = = null | | bo . getActualLength ( ) = = null ) {
return ;
}
if ( StringUtils . isBlank ( bo . getItemType ( ) ) | | bo . getItemId ( ) = = null ) {
return ;
}
String specWidth = null ;
try {
if ( " raw_material " . equals ( bo . getItemType ( ) ) ) {
WmsRawMaterial rm = rawMaterialMapper . selectById ( bo . getItemId ( ) ) ;
if ( rm ! = null & & StringUtils . isNotBlank ( rm . getSpecification ( ) ) ) {
String [ ] parts = rm . getSpecification ( ) . split ( " \\ * " ) ;
if ( parts . length > = 2 ) {
specWidth = parts [ parts . length - 1 ] . trim ( ) ;
}
}
} else if ( " product " . equals ( bo . getItemType ( ) ) ) {
WmsProduct p = productMapper . selectById ( bo . getItemId ( ) ) ;
if ( p ! = null & & StringUtils . isNotBlank ( p . getSpecification ( ) ) ) {
String [ ] parts = p . getSpecification ( ) . split ( " \\ * " ) ;
if ( parts . length > = 2 ) {
specWidth = parts [ parts . length - 1 ] . trim ( ) ;
}
}
}
} catch ( Exception e ) {
log . warn ( " 查询物品规格失败, itemType: {}, itemId: {} " , bo . getItemType ( ) , bo . getItemId ( ) , e ) ;
return ;
}
if ( StringUtils . isBlank ( specWidth ) ) {
return ;
}
try {
BigDecimal weight = bo . getNetWeight ( ) ;
BigDecimal length = new BigDecimal ( bo . getActualLength ( ) ) ;
BigDecimal width = new BigDecimal ( specWidth ) ;
BigDecimal numerator = weight . multiply ( new BigDecimal ( " 1000 " ) ) ;
BigDecimal denominator = new BigDecimal ( " 7.85 " ) . multiply ( length ) . multiply ( width ) ;
BigDecimal theoretical = numerator . divide ( denominator , 3 , RoundingMode . HALF_UP ) ;
bo . setTheoreticalThickness ( theoretical ) ;
} catch ( Exception e ) {
log . warn ( " 计算理论厚度失败 " , e ) ;
}
}
/**
* 根据物品类型和ID获取规格中的宽度( 规格格式: 厚度*宽度,取 * 后面部分)
*/
private BigDecimal getSpecWidth ( String itemType , Long itemId ) {
if ( StringUtils . isBlank ( itemType ) | | itemId = = null ) {
return null ;
}
try {
String specification = null ;
if ( " raw_material " . equals ( itemType ) ) {
WmsRawMaterial rm = rawMaterialMapper . selectById ( itemId ) ;
if ( rm ! = null ) {
specification = rm . getSpecification ( ) ;
}
} else if ( " product " . equals ( itemType ) ) {
WmsProduct p = productMapper . selectById ( itemId ) ;
if ( p ! = null ) {
specification = p . getSpecification ( ) ;
}
}
if ( StringUtils . isNotBlank ( specification ) ) {
String [ ] parts = specification . split ( " \\ * " ) ;
if ( parts . length > = 2 ) {
return new BigDecimal ( parts [ parts . length - 1 ] . trim ( ) ) ;
}
}
} catch ( Exception e ) {
log . warn ( " 获取规格宽度失败, itemType: {}, itemId: {} " , itemType , itemId , e ) ;
}
return null ;
}
/**
* 根据物品类型和ID获取规格中的厚度( 规格格式: 厚度*宽度,取 * 前面部分)
*/
private BigDecimal getSpecThickness ( String itemType , Long itemId ) {
if ( StringUtils . isBlank ( itemType ) | | itemId = = null ) {
return null ;
}
try {
String specification = null ;
if ( " raw_material " . equals ( itemType ) ) {
WmsRawMaterial rm = rawMaterialMapper . selectById ( itemId ) ;
if ( rm ! = null ) {
specification = rm . getSpecification ( ) ;
}
} else if ( " product " . equals ( itemType ) ) {
WmsProduct p = productMapper . selectById ( itemId ) ;
if ( p ! = null ) {
specification = p . getSpecification ( ) ;
}
}
if ( StringUtils . isNotBlank ( specification ) ) {
String [ ] parts = specification . split ( " \\ * " ) ;
if ( parts . length > = 2 ) {
return new BigDecimal ( parts [ 0 ] . trim ( ) ) ;
}
}
} catch ( Exception e ) {
log . warn ( " 获取规格厚度失败, itemType: {}, itemId: {} " , itemType , itemId , e ) ;
}
return null ;
}
/**
* 获取库位及其所有子库位的ID列表
* 逻辑参考 WmsActualWarehouseServiceImpl.queryList 中的拆分处理逻辑:
@@ -1333,6 +1455,7 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
bo . setActualWarehouseId ( null ) ;
}
// 3. 插入钢卷数据
calculateTheoreticalThickness ( bo ) ;
WmsMaterialCoil add = BeanUtil . toBean ( bo , WmsMaterialCoil . class ) ;
if ( bo . getDataType ( ) ! = null & & bo . getDataType ( ) = = 10 ) {
add . setDataType ( 10 ) ;
@@ -1548,6 +1671,7 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
}
}
validateCoilWeight ( bo . getGrossWeight ( ) , bo . getNetWeight ( ) ) ;
calculateTheoreticalThickness ( bo ) ;
// 直接更新钢卷属性
WmsMaterialCoil updateCoil = BeanUtil . toBean ( bo , WmsMaterialCoil . class ) ;
validEntityBeforeSave ( updateCoil ) ;
@@ -1641,6 +1765,7 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
baseMapper . update ( null , updateWrapper ) ;
// 2. 创建新记录
calculateTheoreticalThickness ( bo ) ;
WmsMaterialCoil newCoil = BeanUtil . toBean ( bo , WmsMaterialCoil . class ) ;
newCoil . setCoilId ( null ) ; // 清空ID, 让数据库自动生成新ID
newCoil . setDataType ( 1 ) ; // 设置为当前数据
@@ -1888,6 +2013,7 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
? newCoilBo . getActualWarehouseId ( ) : null ;
validateActualWarehouseForAssign ( newCoilBo . getActualWarehouseId ( ) , ignoreOccupiedId ) ;
}
calculateTheoreticalThickness ( newCoilBo ) ;
WmsMaterialCoil newCoil = BeanUtil . toBean ( newCoilBo , WmsMaterialCoil . class ) ;
newCoil . setCoilId ( null ) ;
newCoil . setDataType ( 1 ) ;
@@ -2016,6 +2142,7 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
if ( bo . getActualWarehouseId ( ) ! = null ) {
validateActualWarehouseForAssign ( bo . getActualWarehouseId ( ) , null ) ;
}
calculateTheoreticalThickness ( bo ) ;
WmsMaterialCoil newCoil = BeanUtil . toBean ( bo , WmsMaterialCoil . class ) ;
newCoil . setCoilId ( null ) ;
newCoil . setDataType ( 1 ) ;
@@ -4855,7 +4982,25 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
validateActualWarehouseForAssign ( childCoilBo . getActualWarehouseId ( ) , null ) ;
}
// 校验子卷净重不超过母卷
if ( childCoilBo . getNetWeight ( ) ! = null & & parentCoil . getNetWeight ( ) ! = null ) {
if ( childCoilBo . getNetWeight ( ) . compareTo ( parentCoil . getNetWeight ( ) ) > 0 ) {
throw new RuntimeException ( " 子卷净重[ " + childCoilBo . getNetWeight ( ) + " ]不能超过母卷净重[ " + parentCoil . getNetWeight ( ) + " ] " ) ;
}
}
// 校验子卷规格厚度不超过母卷
String childItemType = StringUtils . isNotBlank ( childCoilBo . getItemType ( ) ) ? childCoilBo . getItemType ( ) : parentCoil . getItemType ( ) ;
Long childItemId = childCoilBo . getItemId ( ) ! = null ? childCoilBo . getItemId ( ) : parentCoil . getItemId ( ) ;
BigDecimal parentSpecThickness = getSpecThickness ( parentCoil . getItemType ( ) , parentCoil . getItemId ( ) ) ;
BigDecimal childSpecThickness = getSpecThickness ( childItemType , childItemId ) ;
if ( parentSpecThickness ! = null & & childSpecThickness ! = null ) {
if ( childSpecThickness . compareTo ( parentSpecThickness ) > 0 ) {
throw new RuntimeException ( " 子卷规格厚度[ " + childSpecThickness + " ]不能超过母卷规格厚度[ " + parentSpecThickness + " ] " ) ;
}
}
// 5. 创建子钢卷(参考普通分卷逻辑,但不设置母卷为历史数据)
calculateTheoreticalThickness ( childCoilBo ) ;
WmsMaterialCoil childCoil = BeanUtil . toBean ( childCoilBo , WmsMaterialCoil . class ) ;
childCoil . setCoilId ( null ) ;
childCoil . setDataType ( 1 ) ; // 当前数据
@@ -4971,6 +5116,17 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
. map ( WmsMaterialCoil : : getCurrentCoilNo )
. collect ( Collectors . toList ( ) ) ;
// 校验所有子卷总重不超过母卷净重
if ( parentCoil . getNetWeight ( ) ! = null ) {
BigDecimal totalChildWeight = childCoils . stream ( )
. map ( WmsMaterialCoil : : getNetWeight )
. filter ( Objects : : nonNull )
. reduce ( BigDecimal . ZERO , BigDecimal : : add ) ;
if ( totalChildWeight . compareTo ( parentCoil . getNetWeight ( ) ) > 0 ) {
throw new RuntimeException ( " 所有子卷总重[ " + totalChildWeight + " ]不能超过母卷净重[ " + parentCoil . getNetWeight ( ) + " ] " ) ;
}
}
// 如果母卷即将成为历史卷 证明已经加工完成则释放库位
if ( parentCoil . getActualWarehouseId ( ) ! = null ) {
updateActualWarehouseEnableStatus ( parentCoil . getActualWarehouseId ( ) , null ) ;