@@ -23,7 +23,6 @@ import com.zg.project.system.service.ISysConfigService;
import com.zg.project.wisdom.domain.AuditSignature ;
import com.zg.project.wisdom.domain.GysJh ;
import com.zg.project.wisdom.domain.dto.* ;
import com.zg.project.wisdom.domain.vo.PcodeQtyVO ;
import com.zg.project.wisdom.mapper.AuditSignatureMapper ;
import com.zg.project.wisdom.mapper.GysJhMapper ;
import com.zg.project.wisdom.utils.BillNoUtil ;
@@ -36,6 +35,8 @@ import com.zg.project.wisdom.domain.RkInfo;
import com.zg.project.wisdom.service.IRkInfoService ;
import org.springframework.transaction.annotation.Transactional ;
import static com.zg.common.utils.SecurityUtils.getUsername ;
/**
* 库存单据主Service业务层处理
*
@@ -259,7 +260,7 @@ public class RkInfoServiceImpl implements IRkInfoService
RkInfo update = new RkInfo ( ) ;
update . setId ( id ) ;
update . setIsChuku ( " 4 " ) ; // 4 = 已撤销
update . setUpdateBy ( SecurityUtils . getUsername( ) ) ;
update . setUpdateBy ( getUsername ( ) ) ;
update . setUpdateTime ( DateUtils . getNowDate ( ) ) ;
return rkInfoMapper . updateRkInfo ( update ) ;
@@ -927,7 +928,7 @@ public class RkInfoServiceImpl implements IRkInfoService
update . setId ( originalId ) ;
update . setIsBorrowed ( " 2 " ) ;
update . setReturnTime ( DateUtils . getNowDate ( ) ) ;
update . setUpdateBy ( SecurityUtils . getUsername( ) ) ;
update . setUpdateBy ( getUsername ( ) ) ;
update . setUpdateTime ( DateUtils . getNowDate ( ) ) ;
rkInfoMapper . updateById ( update ) ;
@@ -940,7 +941,7 @@ public class RkInfoServiceImpl implements IRkInfoService
RkInfo update = new RkInfo ( ) ;
update . setId ( id ) ;
update . setIsChuku ( " 5 " ) ;
update . setUpdateBy ( SecurityUtils . getUsername( ) ) ;
update . setUpdateBy ( getUsername ( ) ) ;
update . setUpdateTime ( DateUtils . getNowDate ( ) ) ;
// 执行更新
@@ -1019,8 +1020,118 @@ public class RkInfoServiceImpl implements IRkInfoService
return rkInfoMapper . updateBillInfo ( query ) ;
}
@Override
@Transactional ( rollbackFor = Exception . class )
public void appendToExistingBill ( PcRkInfoBatchDTO dto ) {
// ========== 参数校验 ==========
if ( StringUtils . isEmpty ( dto . getBillNo ( ) ) ) {
throw new ServiceException ( " 入库单号 billNo 不能为空 " ) ;
}
if ( dto . getRkList ( ) = = null | | dto . getRkList ( ) . isEmpty ( ) ) {
throw new ServiceException ( " 追加明细不能为空 " ) ;
}
// ========== 1. 校验原单据是否存在 ==========
List < RkInfo > exists = rkInfoMapper . selectRkInfoListByBillNo ( dto . getBillNo ( ) ) ;
if ( exists = = null | | exists . isEmpty ( ) ) {
throw new ServiceException ( " 目标入库单不存在: " + dto . getBillNo ( ) ) ;
}
Date now = DateUtils . getNowDate ( ) ;
String user = getUsername ( ) ;
// ========== 2. 组装并插入追加的入库明细(无审批:直接入库) ==========
List < RkInfo > toSave = new ArrayList < > ( dto . getRkList ( ) . size ( ) ) ;
Date rkTime = dto . getRkTime ( ) ! = null ? dto . getRkTime ( ) : now ;
for ( PcRkInfoItemDTO item : dto . getRkList ( ) ) {
RkInfo e = new RkInfo ( ) ;
BeanUtils . copyProperties ( item , e ) ; // 拷贝 DTO 相同字段
// 公共字段
e . setBillNo ( dto . getBillNo ( ) ) ;
e . setRkType ( dto . getRkType ( ) ) ;
e . setWlType ( dto . getWlType ( ) ) ;
e . setCangku ( dto . getCangku ( ) ) ;
e . setLihuoY ( dto . getLihuoY ( ) ) ;
e . setRkTime ( rkTime ) ;
// 入库状态(未启用审批)
e . setIsChuku ( " 0 " ) ; // 已入库
e . setStatus ( " 1 " ) ; // 正常
e . setIsDelete ( " 0 " ) ;
e . setCreateBy ( user ) ;
e . setCreateTime ( now ) ;
e . setUpdateBy ( user ) ;
e . setUpdateTime ( now ) ;
toSave . add ( e ) ;
}
rkInfoMapper . batchInsertRkInfo ( toSave ) ;
// ========== 3. 更新供应计划(关键改动):只在“部分入库”时扣减 ==========
for ( PcRkInfoItemDTO item : dto . getRkList ( ) ) {
Long jhId = item . getGysJhId ( ) ;
BigDecimal realQty = item . getRealQty ( ) ;
if ( jhId = = null | | realQty = = null ) continue ;
// 查当前计划行
GysJh plan = gysJhMapper . selectGysJhById ( jhId ) ;
if ( plan = = null ) continue ;
// 已经标记为全部入库的行,直接跳过(既不扣减也不改)
if ( " 1 " . equals ( plan . getStatus ( ) ) ) {
continue ;
}
// 计划剩余(表里 jh_qty 列)
BigDecimal remain = plan . getJhQty ( ) = = null
? BigDecimal . ZERO
: BigDecimal . valueOf ( plan . getJhQty ( ) ) ;
// ① 全额入库: realQty >= remain -> 直接置 1, 不做扣减
if ( remain . compareTo ( BigDecimal . ZERO ) < = 0 | | realQty . compareTo ( remain ) > = 0 ) {
gysJhMapper . updateStatusById ( jhId , " 1 " ) ; // 全部入库
// 不调用 decreaseJhQtyById, 避免出现负数
continue ;
}
// ② 部分入库: realQty < remain -> 先扣减,再把该行置 2
gysJhMapper . decreaseJhQtyById ( jhId , realQty ) ; // jh_qty = jh_qty - realQty
gysJhMapper . updateStatusById ( jhId , " 2 " ) ; // 部分入库
}
// ========== 4. 按 sapNo 再做一轮收尾(把 <=0 的行批量收敛到 1, 其余置 2) ==========
// 说明:上面已经对每个行做了状态落地;此处是“兜底收敛”,确保同一 sapNo 下的行一致
Set < String > sapNos = dto . getRkList ( ) . stream ( )
. map ( PcRkInfoItemDTO : : getSapNo )
. filter ( StringUtils : : isNotEmpty )
. collect ( Collectors . toSet ( ) ) ;
for ( String sapNo : sapNos ) {
// 仅返回 status != '1' 的行(未完全入库的)
List < GysJh > rows = gysJhMapper . getBySapNo ( sapNo ) ;
if ( rows = = null | | rows . isEmpty ( ) ) continue ;
List < Long > toAll = new ArrayList < > ( ) ;
List < Long > toPartial = new ArrayList < > ( ) ;
for ( GysJh r : rows ) {
long remain = r . getJhQty ( ) = = null ? 0L : r . getJhQty ( ) ;
if ( remain < = 0L ) {
toAll . add ( r . getId ( ) ) ; // 已经无剩余 -> 置 1
} else {
toPartial . add ( r . getId ( ) ) ; // 仍有剩余 -> 置 2
}
}
for ( Long id : toAll ) {
gysJhMapper . updateStatusById ( id , " 1 " ) ; // 全部入库
}
if ( ! toPartial . isEmpty ( ) ) {
gysJhMapper . batchUpdateStatusByIds ( new HashSet < > ( toPartial ) ) ; // 部分入库
}
}
}
}