Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5892efccaf | ||
|
|
ae4e0e129b | ||
|
|
5c4e460cac | ||
|
|
0d9ea32f85 | ||
|
|
6cb70805f1 | ||
|
|
81630339e4 | ||
|
|
ed809e82d4 |
+102
@@ -2,12 +2,14 @@ package com.mhd.bms.application.server.receiptManage;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.mhd.bms.domain.billManage.entity.BillManage;
|
||||
import com.mhd.bms.domain.billManage.service.BillManageDomainService;
|
||||
import com.mhd.bms.domain.receiptManage.entity.ReceiptManage;
|
||||
import com.mhd.bms.domain.receiptManage.repository.po.ReceiptManagePO;
|
||||
import com.mhd.bms.domain.receiptManage.repository.todo.ReceiptManageDO;
|
||||
import com.mhd.bms.domain.receiptManage.service.ReceiptManageDomainService;
|
||||
import com.mhd.bms.infrastructure.utils.CheckPasswordUtil;
|
||||
import com.mhd.bms.interfaces.dto.receiptManage.ReceiptDetailDTO;
|
||||
import com.mhd.bms.interfaces.dto.receiptManage.ReceiptManageDTO;
|
||||
import com.mhd.common.core.exception.ServiceException;
|
||||
import com.mhd.common.core.exception.digitalLogisticsException.DigitalLogisticsException;
|
||||
@@ -18,10 +20,13 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.interceptor.TransactionAspectSupport;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
@@ -147,6 +152,103 @@ public class ReceiptManageApplicationService {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 排队批量收款
|
||||
* 接收集合按顺序逐笔处理,任意一笔收款失败则整体回滚
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean queueBatchCollection(List<ReceiptManageDO> receiptManageDOList) {
|
||||
LoginUser loginUser = SecurityUtils.getLoginUser();
|
||||
if (ObjectUtil.isNull(loginUser)) {
|
||||
throw new DigitalLogisticsException(UserError.TIMEOUT);
|
||||
}
|
||||
int index = 1;
|
||||
for (ReceiptManageDO receiptManageDO : receiptManageDOList) {
|
||||
try {
|
||||
//根据账单id查询账单当前金额数据,替换前端传的账单金额、已收金额、未收金额等(仅保留前端传的收款金额和优惠金额)
|
||||
fillBillAmountFromBillManage(receiptManageDO);
|
||||
Boolean flag = batchCollection(receiptManageDO);
|
||||
if (!Boolean.TRUE.equals(flag)) {
|
||||
throw new ServiceException("收款数据处理失败");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
//自己try捕获的异常也要标记事务回滚,确保收款失败时全部回滚
|
||||
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
|
||||
throw new ServiceException("第" + index + "笔收款失败:" + e.getMessage() + ",本次收款已全部回滚");
|
||||
}
|
||||
index++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 排队批量收款-根据账单id查询账单当前金额,替换前端传的账单金额、已收金额、未收金额、剩余未收(仅保留前端传的收款金额和优惠金额)
|
||||
*/
|
||||
private void fillBillAmountFromBillManage(ReceiptManageDO receiptManageDO) {
|
||||
List<ReceiptDetailDTO> receiptDetailDTOList = receiptManageDO.getReceiptDetailDTOList();
|
||||
if (null == receiptDetailDTOList || receiptDetailDTOList.size() == 0) {
|
||||
throw new ServiceException("费用结算明细不能为空");
|
||||
}
|
||||
//汇总收款明细的账单id并查询账单当前数据
|
||||
Set<Long> billManageIdSet = receiptDetailDTOList.stream().map(ReceiptDetailDTO::getBillManageId).filter(ObjectUtil::isNotNull).collect(Collectors.toSet());
|
||||
if (billManageIdSet.size() == 0) {
|
||||
throw new ServiceException("收款账单不能为空");
|
||||
}
|
||||
LambdaQueryWrapper<BillManage> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.in(BillManage::getBillManageId, billManageIdSet);
|
||||
queryWrapper.eq(BillManage::getDelFlag, 1);
|
||||
List<BillManage> billManageList = billManageDomainService.queryListLambda(queryWrapper);
|
||||
if (null == billManageList || billManageList.size() == 0) {
|
||||
throw new ServiceException("账单信息未找到");
|
||||
}
|
||||
Map<Long, BillManage> billManageMap = billManageList.stream().collect(Collectors.toMap(BillManage::getBillManageId, billManage -> billManage, (oldValue, newValue) -> oldValue));
|
||||
//汇总账单金额、已收金额、未收金额、收款金额、优惠金额
|
||||
BigDecimal billAmount = BigDecimal.ZERO;
|
||||
BigDecimal billAmountSettlement = BigDecimal.ZERO;
|
||||
BigDecimal billAmountUnsettled = BigDecimal.ZERO;
|
||||
BigDecimal collectedAmount = BigDecimal.ZERO;
|
||||
BigDecimal collectedDiscount = BigDecimal.ZERO;
|
||||
for (ReceiptDetailDTO receiptDetailDTO : receiptDetailDTOList) {
|
||||
BillManage billManage = billManageMap.get(receiptDetailDTO.getBillManageId());
|
||||
if (null == billManage) {
|
||||
throw new ServiceException("账单" + receiptDetailDTO.getBillNumber() + "信息未找到,请刷新后重试");
|
||||
}
|
||||
//只取前端传的收款金额、优惠金额,为空按0处理
|
||||
BigDecimal detailCollectedAmount = null == receiptDetailDTO.getCollectedAmount() ? BigDecimal.ZERO : receiptDetailDTO.getCollectedAmount();
|
||||
BigDecimal detailCollectedDiscount = null == receiptDetailDTO.getCollectedDiscount() ? BigDecimal.ZERO : receiptDetailDTO.getCollectedDiscount();
|
||||
//账单当前金额以数据库为准
|
||||
BigDecimal detailBillAmount = billManage.getBillAmount();
|
||||
BigDecimal detailBillAmountSettlement = billManage.getBillAmountSettlement();
|
||||
BigDecimal detailBillAmountUnsettled = billManage.getBillAmountUnsettled();
|
||||
//剩余未收金额 = 未收金额 - 收款金额 - 优惠金额
|
||||
BigDecimal detailBillAmountUnsettledResidue = detailBillAmountUnsettled.subtract(detailCollectedAmount).subtract(detailCollectedDiscount);
|
||||
if (detailBillAmountUnsettledResidue.compareTo(BigDecimal.ZERO) < 0) {
|
||||
throw new ServiceException("账单" + billManage.getBillNumber() + "未收金额小于本次收款金额与优惠金额之和,无法完成收款,请刷新后重试");
|
||||
}
|
||||
//用数据库当前值替换前端传的账单金额、已收金额、未收金额、剩余未收
|
||||
receiptDetailDTO.setBillAmount(detailBillAmount);
|
||||
receiptDetailDTO.setBillAmountSettlement(detailBillAmountSettlement);
|
||||
receiptDetailDTO.setBillAmountUnsettled(detailBillAmountUnsettled);
|
||||
receiptDetailDTO.setBillAmountUnsettledResidue(detailBillAmountUnsettledResidue);
|
||||
//累计收款单金额
|
||||
billAmount = billAmount.add(detailBillAmount);
|
||||
billAmountSettlement = billAmountSettlement.add(detailBillAmountSettlement);
|
||||
billAmountUnsettled = billAmountUnsettled.add(detailBillAmountUnsettled);
|
||||
collectedAmount = collectedAmount.add(detailCollectedAmount);
|
||||
collectedDiscount = collectedDiscount.add(detailCollectedDiscount);
|
||||
}
|
||||
//收款单金额:账单金额、已收金额、未收金额取查询值汇总,收款金额、优惠金额取前端传值汇总
|
||||
receiptManageDO.setBillAmount(billAmount);
|
||||
receiptManageDO.setBillAmountSettlement(billAmountSettlement);
|
||||
receiptManageDO.setBillAmountUnsettled(billAmountUnsettled);
|
||||
receiptManageDO.setCollectedAmount(collectedAmount);
|
||||
receiptManageDO.setCollectedDiscount(collectedDiscount);
|
||||
//剩余未收 = 未收金额 - 收款金额 - 优惠金额
|
||||
receiptManageDO.setUncollectedAmount(billAmountUnsettled.subtract(collectedAmount).subtract(collectedDiscount));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 撤销收款
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,7 @@ import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
@@ -56,6 +57,11 @@ public class ReceiptManageApi extends BaseController{
|
||||
@Autowired
|
||||
private RedisLock redisLock;
|
||||
|
||||
/**
|
||||
* 排队批量收款-获取账单锁的最大等待时间(秒),等待期内排队获取锁,避免并发收款直接失败
|
||||
*/
|
||||
private static final long QUEUE_COLLECTION_LOCK_WAIT_SECONDS = 30L;
|
||||
|
||||
/**
|
||||
* 分页查询收款单管理列表
|
||||
*/
|
||||
@@ -115,6 +121,65 @@ public class ReceiptManageApi extends BaseController{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 排队批量收款
|
||||
* 接收多个批量收款请求参数集合,整体加锁后按顺序排队依次处理;
|
||||
* 同一账单分多次收款时前一笔处理完成后才处理下一笔,避免redis锁冲突导致收款失败;
|
||||
* 整个集合在同一事务内处理,任意一笔收款失败则全部回滚
|
||||
*/
|
||||
@ApiOperation("排队批量收款")
|
||||
@RepeatSubmit
|
||||
@PostMapping("/queueBatchCollection")
|
||||
public AjaxResult queueBatchCollection(@RequestBody List<ReceiptManageDTO> receiptManageDTOList)
|
||||
{
|
||||
if(StringUtils.isEmpty(receiptManageDTOList)){
|
||||
throw new ServiceException("收款账单不能为空");
|
||||
}
|
||||
//汇总所有收款请求涉及的账单id并排序,整体加锁,保证事务期间锁不释放且加锁顺序一致避免死锁
|
||||
Set<String> lockKeySet = new TreeSet<>();
|
||||
for (ReceiptManageDTO receiptManageDTO : receiptManageDTOList) {
|
||||
if(!StringUtils.isNotEmpty(receiptManageDTO.getBillManageIds())){
|
||||
throw new ServiceException("收款账单不能为空");
|
||||
}
|
||||
lockKeySet.addAll(Stream.of(receiptManageDTO.getBillManageIds().split(",")).filter(StringUtils::isNotEmpty).map(String::trim).collect(Collectors.toSet()));
|
||||
}
|
||||
RedisLockTypeEnum redisLockTypeEnum = RedisLockTypeEnum.BMS;
|
||||
List<RLock> locks = new ArrayList<>();
|
||||
lockKeySet.forEach(x -> {
|
||||
//获取唯一key值
|
||||
String key = redisLockTypeEnum.getUniqueKey(UniqueKeyUtil.getBillingKey(x));
|
||||
locks.add(redisLock.getRLock(key));
|
||||
});
|
||||
RedissonMultiLock redissonMultiLock = new RedissonMultiLock(locks.toArray(new RLock[lockKeySet.size()]));
|
||||
boolean payInfoDetailLock = false;
|
||||
try {
|
||||
//尝试获取锁 等待指定时间内排队获取 持有锁10分钟
|
||||
payInfoDetailLock = redissonMultiLock.tryLock(QUEUE_COLLECTION_LOCK_WAIT_SECONDS, 10, TimeUnit.MINUTES);
|
||||
if (!payInfoDetailLock) {
|
||||
redissonMultiLock = null;
|
||||
return AjaxResult.error("账单正在处理,请稍后再试");
|
||||
}
|
||||
log.info("排队批量收款-生成账单加锁成功");
|
||||
//转换实体
|
||||
List<ReceiptManageDO> receiptManageDOList = new ArrayList<>();
|
||||
for (ReceiptManageDTO receiptManageDTO : receiptManageDTOList) {
|
||||
ReceiptManageDO receiptManageDO = new ReceiptManageDO();
|
||||
BeanUtils.copyProperties(receiptManageDTO,receiptManageDO);
|
||||
receiptManageDOList.add(receiptManageDO);
|
||||
}
|
||||
//事务内排队逐笔收款,任意一笔失败全部回滚
|
||||
return toAjax(receiptManageApplicationService.queueBatchCollection(receiptManageDOList));
|
||||
}catch (Exception e){
|
||||
//异常已在应用服务层事务内标记回滚(收款失败必回滚),此处仅返回失败结果
|
||||
return AjaxResult.error("收款失败:" + e.getMessage());
|
||||
}finally {
|
||||
if (redissonMultiLock != null && payInfoDetailLock) {
|
||||
redissonMultiLock.unlock();
|
||||
log.info("排队批量收款-生成账单释放了锁");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 撤销收款
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
-- ----------------------------
|
||||
-- 入库业务单推送bms计费流水定时任务(XXL-Job: pushBillingRecord)执行日志表 -- 达梦(DM)数据库版
|
||||
-- 适用:mhd-wms-service 连接的达梦库(生产/测试按环境选择,在WMS服务连接的用户/模式下执行)
|
||||
-- 用途:记录任务执行过程中的例外情况(执行异常报错、业务continue跳过、生成业务单据失败),
|
||||
-- 本次执行全程无任何例外时保留一条成功记录(LOG_TYPE=SUCCESS)
|
||||
-- @date 2026-09-15
|
||||
-- ----------------------------
|
||||
|
||||
CREATE TABLE WMS_PUSH_BILLING_RECORD_LOG (
|
||||
ID BIGINT IDENTITY(1,1) NOT NULL,
|
||||
JOB_NAME VARCHAR(100) DEFAULT NULL,
|
||||
SHIPPER_ID VARCHAR(50) DEFAULT NULL,
|
||||
MATERIAL_INVENTORY_ID BIGINT DEFAULT NULL,
|
||||
IN_ORDER_NUMBER VARCHAR(100) DEFAULT NULL,
|
||||
MATERIAL_BASE_INFO_ID BIGINT DEFAULT NULL,
|
||||
LOT_NUMBER VARCHAR(100) DEFAULT NULL,
|
||||
WAREHOUSE_CODE VARCHAR(50) DEFAULT NULL,
|
||||
LOG_TYPE VARCHAR(20) DEFAULT NULL,
|
||||
LOG_MESSAGE VARCHAR(2000) DEFAULT NULL,
|
||||
EXECUTION_TIME DATETIME DEFAULT NULL,
|
||||
DEL_FLAG INT DEFAULT 1,
|
||||
CONSTRAINT PK_WMS_PUSH_BILLING_RECORD_LOG PRIMARY KEY (ID)
|
||||
);
|
||||
|
||||
COMMENT ON TABLE WMS_PUSH_BILLING_RECORD_LOG IS '入库业务单推送bms计费流水任务执行日志表';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.ID IS '主键ID';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.JOB_NAME IS '任务名称(XXL-Job任务标识,如pushBillingRecord)';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.SHIPPER_ID IS '货主ID(任务参数)';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.MATERIAL_INVENTORY_ID IS '物料库存ID';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.IN_ORDER_NUMBER IS '入库单号';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.MATERIAL_BASE_INFO_ID IS '物料基础信息ID';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.LOT_NUMBER IS 'LOT编号';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.WAREHOUSE_CODE IS '仓库编码';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.LOG_TYPE IS '日志类型:SUCCESS-全部执行成功 SKIP-业务跳过(continue) ERROR-执行异常';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.LOG_MESSAGE IS '日志信息(成功说明/跳过原因/异常信息)';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.EXECUTION_TIME IS '执行时间';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.DEL_FLAG IS '删除标记:0-无状态,1-正常,2-已删除';
|
||||
|
||||
CREATE INDEX IDX_WPBR_JOB_NAME ON WMS_PUSH_BILLING_RECORD_LOG (JOB_NAME);
|
||||
CREATE INDEX IDX_WPBR_SHIPPER_ID ON WMS_PUSH_BILLING_RECORD_LOG (SHIPPER_ID);
|
||||
CREATE INDEX IDX_WPBR_EXECUTION_TIME ON WMS_PUSH_BILLING_RECORD_LOG (EXECUTION_TIME);
|
||||
|
||||
-- ----------------------------
|
||||
-- 回滚脚本
|
||||
-- DROP TABLE WMS_PUSH_BILLING_RECORD_LOG;
|
||||
-- ----------------------------
|
||||
@@ -0,0 +1,2 @@
|
||||
-- test write permission
|
||||
SELECT 1;
|
||||
+278
-123
@@ -20,7 +20,9 @@ import com.mhd.system.api.model.LoginUser;
|
||||
import com.mhd.wms.domain.materialBaseInfo.entity.MaterialBaseInfo;
|
||||
import com.mhd.wms.domain.materialBaseInfo.repository.mapper.MaterialBaseInfoMapper;
|
||||
import com.mhd.wms.domain.materialInventory.entity.MaterialInventory;
|
||||
import com.mhd.wms.domain.materialInventory.entity.PushBillingRecordLog;
|
||||
import com.mhd.wms.domain.materialInventory.repository.mapper.MaterialInventoryMapper;
|
||||
import com.mhd.wms.domain.materialInventory.repository.mapper.PushBillingRecordLogMapper;
|
||||
import com.mhd.wms.domain.materialInventory.repository.po.MaterialInventoryPO;
|
||||
import com.mhd.wms.domain.materialInventory.repository.po.MaterialInventoryQueryListPO;
|
||||
import com.mhd.wms.domain.materialInventory.repository.todo.MaterialInventoryDO;
|
||||
@@ -75,6 +77,11 @@ public class MaterialInventoryApplicationService {
|
||||
private OutMaterialDetailMapper outMaterialDetailMapper;
|
||||
@Autowired
|
||||
private MaterialBaseInfoMapper materialBaseInfoMapper;
|
||||
@Autowired
|
||||
private PushBillingRecordLogMapper pushBillingRecordLogMapper;
|
||||
|
||||
/** XXL-Job任务标识:入库业务单推送bms计费流水 */
|
||||
private static final String JOB_NAME_PUSH_BILLING_RECORD = "pushBillingRecord";
|
||||
|
||||
|
||||
/**
|
||||
@@ -904,7 +911,9 @@ public class MaterialInventoryApplicationService {
|
||||
String inOrderNumber = materialInventoryPO.getInOrderNumber();
|
||||
Long warehouseId = materialInventoryPO.getWarehouseId();
|
||||
Date lastBillingTime = materialInventoryPO.getLastBillingTime();
|
||||
if (warehouseId==19) {//干仓计费
|
||||
String warehouseCode = materialInventoryMapper.queryWarehouseCode(warehouseId);
|
||||
if (warehouseCode == null) return;
|
||||
if ("CMD".equals(warehouseCode)) {//干仓计费
|
||||
Map<String,Object> shipperParameters = materialInventoryDomainService.queryShipperParameters(shipperId,"干仓计费配置");
|
||||
//客户未配置干仓计费配置
|
||||
if (shipperParameters == null || shipperParameters.size()==0) return;
|
||||
@@ -962,7 +971,7 @@ public class MaterialInventoryApplicationService {
|
||||
buildBusinessDocument(totalWarehouseRent, materialInventoryPO,"0D01","租金(固定租)",contractManageId,"冻仓");
|
||||
buildBusinessDocument(fireInsureFee, materialInventoryPO,"0D08","火险保费",contractManageId,"冻仓");
|
||||
}
|
||||
} else if (warehouseId==20) {//冻仓计费
|
||||
} else if ("CMC".equals(warehouseCode)) {//冻仓计费
|
||||
Map<String,Object> shipperParameters = materialInventoryDomainService.queryShipperParameters(Long.valueOf(shipperId),"冻仓计费配置");
|
||||
if (shipperParameters == null || shipperParameters.size()==0) return;
|
||||
Long contractManageId = (Long) shipperParameters.get("contractManageId");
|
||||
@@ -1017,134 +1026,270 @@ public class MaterialInventoryApplicationService {
|
||||
|
||||
public void pushBillingRecord(String shipperId) {
|
||||
|
||||
List<MaterialInventoryPO> materialInventoryPOS = materialInventoryDomainService.queryPushBms(shipperId);
|
||||
//未查询到库存记录
|
||||
if (materialInventoryPOS==null || materialInventoryPOS.size()==0) return;
|
||||
for (MaterialInventoryPO materialInventoryPO : materialInventoryPOS) {
|
||||
Date createTime = materialInventoryPO.getCreateTime();
|
||||
Long materialBaseInfoId = materialInventoryPO.getMaterialBaseInfoId();
|
||||
String lotNumber = materialInventoryPO.getLotNumber();
|
||||
String inOrderNumber = materialInventoryPO.getInOrderNumber();
|
||||
Long warehouseId = materialInventoryPO.getWarehouseId();
|
||||
Date lastBillingTime = materialInventoryPO.getLastBillingTime();
|
||||
if (warehouseId==19) {//干仓计费
|
||||
Map<String,Object> shipperParameters = materialInventoryDomainService.queryShipperParameters(Long.valueOf(shipperId),"干仓计费配置");
|
||||
//客户未配置干仓计费配置
|
||||
if (shipperParameters == null || shipperParameters.size()==0) continue;
|
||||
Long contractManageId = (Long) shipperParameters.get("contractManageId");
|
||||
Long settlementCustomersId = (Long) shipperParameters.get("settlementCustomersId");
|
||||
String contractNumber = (String) shipperParameters.get("contractNumber");
|
||||
String content = (String) shipperParameters.get("content");
|
||||
Map<String, Object> contentMap = content != null ? JSON.parseObject(content, Map.class) : new HashMap<>();
|
||||
Integer sfzdcz = (Integer) contentMap.get("sfzdcz");
|
||||
//客户未配置或是否自动推送设置为否
|
||||
if (sfzdcz==null) continue;
|
||||
if (sfzdcz!=1) continue;
|
||||
//计算费用
|
||||
List<Map<String, Object>> monthFee = materialInventoryDomainService.getMonthFee(inOrderNumber, materialBaseInfoId,lotNumber);
|
||||
//入库业务单未设置每月仓租
|
||||
if (monthFee == null || monthFee.size()==0) continue;
|
||||
Map<String, Object> feeMap = monthFee.get(0);
|
||||
//半月仓租
|
||||
BigDecimal halfMonthWhFee = (BigDecimal) feeMap.get("halfMonthWhFee");
|
||||
//整月仓租
|
||||
BigDecimal monthlyWarehouseFee = (BigDecimal) feeMap.get("monthlyWarehouseFee");
|
||||
// 判断是否为昨天
|
||||
boolean isYesterday = false;
|
||||
if (createTime != null) {
|
||||
LocalDate yesterday = LocalDate.now().minusDays(1);
|
||||
LocalDate createDate = createTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
||||
isYesterday = yesterday.isEqual(createDate);
|
||||
}
|
||||
if (isYesterday) {
|
||||
//首次计费 需要夫力费
|
||||
//库存数量
|
||||
BigDecimal inventoryQuantity = materialInventoryPO.getInventoryQuantity();
|
||||
//仓租
|
||||
BigDecimal totalWarehouseRent = inventoryQuantity.multiply(monthlyWarehouseFee);
|
||||
//夫力费
|
||||
BigDecimal manpowerFee = totalWarehouseRent.multiply(new BigDecimal("0.2"));
|
||||
MaterialBaseInfo materialBaseInfo = materialBaseInfoMapper.selectById(materialBaseInfoId);
|
||||
BigDecimal unitPrice = materialBaseInfo.getUnitPrice();
|
||||
//火险保费
|
||||
BigDecimal fireInsureFee = unitPrice.multiply(inventoryQuantity).multiply(new BigDecimal("0.0003"));
|
||||
buildBusinessDocument(totalWarehouseRent, materialInventoryPO,"0D01","租金(固定租)",contractManageId,"干仓");
|
||||
buildBusinessDocument(manpowerFee, materialInventoryPO,"0D082","夫力费",contractManageId,"干仓");
|
||||
buildBusinessDocument(fireInsureFee, materialInventoryPO,"0D08","火险保费",contractManageId,"干仓");
|
||||
|
||||
} else {
|
||||
//期间付费 不需要夫力费
|
||||
//库存数量
|
||||
BigDecimal inventoryQuantity = materialInventoryPO.getInventoryQuantity();
|
||||
//仓租
|
||||
BigDecimal totalWarehouseRent = inventoryQuantity.multiply(monthlyWarehouseFee);
|
||||
MaterialBaseInfo materialBaseInfo = materialBaseInfoMapper.selectById(materialBaseInfoId);
|
||||
BigDecimal unitPrice = materialBaseInfo.getUnitPrice();
|
||||
//火险保费
|
||||
BigDecimal fireInsureFee = unitPrice.multiply(inventoryQuantity).multiply(new BigDecimal("0.0003"));
|
||||
buildBusinessDocument(totalWarehouseRent, materialInventoryPO,"0D01","租金(固定租)",contractManageId,"干仓");
|
||||
buildBusinessDocument(fireInsureFee, materialInventoryPO,"0D08","火险保费",contractManageId,"干仓");
|
||||
}
|
||||
} else if (warehouseId==20) {//冻仓计费
|
||||
Map<String,Object> shipperParameters = materialInventoryDomainService.queryShipperParameters(Long.valueOf(shipperId),"冻仓计费配置");
|
||||
if (shipperParameters == null || shipperParameters.size()==0) continue;
|
||||
Long contractManageId = (Long) shipperParameters.get("contractManageId");
|
||||
Long settlementCustomersId = (Long) shipperParameters.get("settlementCustomersId");
|
||||
String contractNumber = (String) shipperParameters.get("contractNumber");
|
||||
String content = (String) shipperParameters.get("content");
|
||||
Map<String, Object> contentMap = content != null ? JSON.parseObject(content, Map.class) : new HashMap<>();
|
||||
Integer sfzdcz = (Integer) contentMap.get("sfzdcz");
|
||||
//客户未配置或是否自动推送设置为否
|
||||
if (sfzdcz==null) continue;
|
||||
if (sfzdcz!=1) continue;
|
||||
//计算费用
|
||||
MaterialBaseInfo materialBaseInfo = materialBaseInfoMapper.selectById(materialBaseInfoId);
|
||||
BigDecimal unitPrice = materialBaseInfo.getUnitPrice();
|
||||
String materialClassifyId = materialBaseInfo.getMaterialClassifyId();
|
||||
BigDecimal weightLimit = materialBaseInfo.getWeightLimit();
|
||||
Map<String,Object> materialClassify = materialInventoryDomainService.queryMaterialClassify(Long.valueOf(materialClassifyId));
|
||||
//物料分类不存在
|
||||
if (materialClassify == null || materialClassify.size()==0) continue;
|
||||
BigDecimal monthlyWarehouseRent = (BigDecimal) materialClassify.get("monthlyWarehouseRent");
|
||||
BigDecimal halfMonthWarehouseRent = (BigDecimal) materialClassify.get("halfMonthWarehouseRent");
|
||||
String monthlyWarehouseRentUnit = (String) materialClassify.get("monthlyWarehouseRentUnit");
|
||||
String halfMonthWarehouseRentUnit = (String) materialClassify.get("halfMonthWarehouseRentUnit");
|
||||
//半月仓租
|
||||
BigDecimal halfMonthWhFee = halfMonthWarehouseRent;
|
||||
//整月仓租
|
||||
BigDecimal monthlyWarehouseFee = monthlyWarehouseRent;
|
||||
long daysDiff = 0;
|
||||
if (lastBillingTime != null) {
|
||||
LocalDate lastBillingDate = lastBillingTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
||||
daysDiff = ChronoUnit.DAYS.between(lastBillingDate, LocalDate.now());
|
||||
} else {
|
||||
daysDiff = -1;
|
||||
}
|
||||
BigDecimal inventoryQuantity = materialInventoryPO.getInventoryQuantity();
|
||||
if (daysDiff < 15) {
|
||||
// 不足半月: 收半月仓租
|
||||
BigDecimal totalWarehouseRent = inventoryQuantity.multiply(halfMonthWhFee).multiply(weightLimit);
|
||||
buildBusinessDocument(totalWarehouseRent, materialInventoryPO,"0D01","租金(固定租)",contractManageId,"冻仓");
|
||||
} else {
|
||||
// 大于等于半月: 收整月仓租
|
||||
BigDecimal totalWarehouseRent = inventoryQuantity.multiply(monthlyWarehouseFee).multiply(weightLimit);
|
||||
buildBusinessDocument(totalWarehouseRent, materialInventoryPO,"0D01","租金(固定租)",contractManageId,"冻仓");
|
||||
}
|
||||
//更新最后计费时间
|
||||
Long materialInventoryId = materialInventoryPO.getMaterialInventoryId();
|
||||
MaterialInventory materialInventory = materialInventoryMapper.selectById(materialInventoryId);
|
||||
materialInventory.setLastBillingTime(new Date());
|
||||
materialInventoryMapper.updateById(materialInventory);
|
||||
// 例外情况计数(业务跳过continue、执行异常、生成业务单据失败),为0时说明本次执行全程无例外,保留成功记录
|
||||
int exceptionCount = 0;
|
||||
try {
|
||||
List<MaterialInventoryPO> materialInventoryPOS = materialInventoryDomainService.queryPushBms(shipperId);
|
||||
//未查询到库存记录
|
||||
if (materialInventoryPOS==null || materialInventoryPOS.size()==0) {
|
||||
savePushBillingRecordLog(shipperId, null, null, PushBillingRecordLog.LOG_TYPE_SUCCESS,
|
||||
"未查询到待推送的库存记录,任务正常结束");
|
||||
return;
|
||||
}
|
||||
for (MaterialInventoryPO materialInventoryPO : materialInventoryPOS) {
|
||||
try {
|
||||
String businessChargeType = materialInventoryPO.getBusinessChargeType();
|
||||
//非散租
|
||||
if (!"散租".equals(businessChargeType)) {
|
||||
savePushBillingRecordLog(shipperId, materialInventoryPO, null, PushBillingRecordLog.LOG_TYPE_SKIP,
|
||||
"业务计价类型[" + businessChargeType + "]非散租,跳过推送");
|
||||
exceptionCount++;
|
||||
continue;
|
||||
}
|
||||
Date createTime = materialInventoryPO.getCreateTime();
|
||||
Long materialBaseInfoId = materialInventoryPO.getMaterialBaseInfoId();
|
||||
String lotNumber = materialInventoryPO.getLotNumber();
|
||||
String inOrderNumber = materialInventoryPO.getInOrderNumber();
|
||||
Long warehouseId = materialInventoryPO.getWarehouseId();
|
||||
Date lastBillingTime = materialInventoryPO.getLastBillingTime();
|
||||
String warehouseCode = materialInventoryDomainService.queryWarehouseCode(warehouseId);
|
||||
//仓库代码为空
|
||||
if (warehouseCode==null) {
|
||||
savePushBillingRecordLog(shipperId, materialInventoryPO, null, PushBillingRecordLog.LOG_TYPE_SKIP,
|
||||
"仓库ID[" + warehouseId + "]未查询到仓库编码,跳过推送");
|
||||
exceptionCount++;
|
||||
continue;
|
||||
}
|
||||
if ("CMD".equals(warehouseCode)) {//干仓计费
|
||||
Map<String,Object> shipperParameters = materialInventoryDomainService.queryShipperParameters(Long.valueOf(shipperId),"干仓计费配置");
|
||||
//客户未配置干仓计费配置
|
||||
if (shipperParameters == null || shipperParameters.size()==0) {
|
||||
savePushBillingRecordLog(shipperId, materialInventoryPO, warehouseCode, PushBillingRecordLog.LOG_TYPE_SKIP,
|
||||
"货主未配置[干仓计费配置],跳过推送");
|
||||
exceptionCount++;
|
||||
continue;
|
||||
}
|
||||
Long contractManageId = (Long) shipperParameters.get("contractManageId");
|
||||
Long settlementCustomersId = (Long) shipperParameters.get("settlementCustomersId");
|
||||
String contractNumber = (String) shipperParameters.get("contractNumber");
|
||||
String content = (String) shipperParameters.get("content");
|
||||
Map<String, Object> contentMap = content != null ? JSON.parseObject(content, Map.class) : new HashMap<>();
|
||||
Integer sfzdcz = (Integer) contentMap.get("sfzdcz");
|
||||
//客户未配置或是否自动推送设置为否
|
||||
if (sfzdcz==null) {
|
||||
savePushBillingRecordLog(shipperId, materialInventoryPO, warehouseCode, PushBillingRecordLog.LOG_TYPE_SKIP,
|
||||
"干仓计费配置未设置[是否自动推送],跳过推送");
|
||||
exceptionCount++;
|
||||
continue;
|
||||
}
|
||||
if (sfzdcz!=1) {
|
||||
savePushBillingRecordLog(shipperId, materialInventoryPO, warehouseCode, PushBillingRecordLog.LOG_TYPE_SKIP,
|
||||
"干仓计费配置[是否自动推送]为否,跳过推送");
|
||||
exceptionCount++;
|
||||
continue;
|
||||
}
|
||||
//计算费用
|
||||
List<Map<String, Object>> monthFee = materialInventoryDomainService.getMonthFee(inOrderNumber, materialBaseInfoId,lotNumber);
|
||||
//入库业务单未设置每月仓租
|
||||
if (monthFee == null || monthFee.size()==0) {
|
||||
savePushBillingRecordLog(shipperId, materialInventoryPO, warehouseCode, PushBillingRecordLog.LOG_TYPE_SKIP,
|
||||
"入库业务单未设置每月仓租,跳过推送");
|
||||
exceptionCount++;
|
||||
continue;
|
||||
}
|
||||
Map<String, Object> feeMap = monthFee.get(0);
|
||||
//半月仓租
|
||||
BigDecimal halfMonthWhFee = (BigDecimal) feeMap.get("halfMonthWhFee");
|
||||
//整月仓租
|
||||
BigDecimal monthlyWarehouseFee = (BigDecimal) feeMap.get("monthlyWarehouseFee");
|
||||
// 判断是否为昨天
|
||||
boolean isYesterday = false;
|
||||
if (createTime != null) {
|
||||
LocalDate yesterday = LocalDate.now().minusDays(1);
|
||||
LocalDate createDate = createTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
||||
isYesterday = yesterday.isEqual(createDate);
|
||||
}
|
||||
if (isYesterday) {
|
||||
//首次计费 需要夫力费
|
||||
//库存数量
|
||||
BigDecimal inventoryQuantity = materialInventoryPO.getInventoryQuantity();
|
||||
//仓租
|
||||
BigDecimal totalWarehouseRent = inventoryQuantity.multiply(monthlyWarehouseFee);
|
||||
//夫力费
|
||||
BigDecimal manpowerFee = totalWarehouseRent.multiply(new BigDecimal("0.2"));
|
||||
MaterialBaseInfo materialBaseInfo = materialBaseInfoMapper.selectById(materialBaseInfoId);
|
||||
BigDecimal unitPrice = materialBaseInfo.getUnitPrice();
|
||||
//火险保费
|
||||
BigDecimal fireInsureFee = unitPrice.multiply(inventoryQuantity).multiply(new BigDecimal("0.0003"));
|
||||
if (!buildBusinessDocument(totalWarehouseRent, materialInventoryPO,"0D01","租金(固定租)",contractManageId,"干仓")) {
|
||||
exceptionCount++;
|
||||
}
|
||||
if (!buildBusinessDocument(manpowerFee, materialInventoryPO,"0D082","夫力费",contractManageId,"干仓")) {
|
||||
exceptionCount++;
|
||||
}
|
||||
if (!buildBusinessDocument(fireInsureFee, materialInventoryPO,"0D08","火险保费",contractManageId,"干仓")) {
|
||||
exceptionCount++;
|
||||
}
|
||||
|
||||
} else {
|
||||
//期间付费 不需要夫力费
|
||||
//库存数量
|
||||
BigDecimal inventoryQuantity = materialInventoryPO.getInventoryQuantity();
|
||||
//仓租
|
||||
BigDecimal totalWarehouseRent = inventoryQuantity.multiply(monthlyWarehouseFee);
|
||||
MaterialBaseInfo materialBaseInfo = materialBaseInfoMapper.selectById(materialBaseInfoId);
|
||||
BigDecimal unitPrice = materialBaseInfo.getUnitPrice();
|
||||
//火险保费
|
||||
BigDecimal fireInsureFee = unitPrice.multiply(inventoryQuantity).multiply(new BigDecimal("0.0003"));
|
||||
if (!buildBusinessDocument(totalWarehouseRent, materialInventoryPO,"0D01","租金(固定租)",contractManageId,"干仓")) {
|
||||
exceptionCount++;
|
||||
}
|
||||
if (!buildBusinessDocument(fireInsureFee, materialInventoryPO,"0D08","火险保费",contractManageId,"干仓")) {
|
||||
exceptionCount++;
|
||||
}
|
||||
}
|
||||
} else if ("CMC".equals(warehouseCode)) {//冻仓计费
|
||||
Map<String,Object> shipperParameters = materialInventoryDomainService.queryShipperParameters(Long.valueOf(shipperId),"冻仓计费配置");
|
||||
if (shipperParameters == null || shipperParameters.size()==0) {
|
||||
savePushBillingRecordLog(shipperId, materialInventoryPO, warehouseCode, PushBillingRecordLog.LOG_TYPE_SKIP,
|
||||
"货主未配置[冻仓计费配置],跳过推送");
|
||||
exceptionCount++;
|
||||
continue;
|
||||
}
|
||||
Long contractManageId = (Long) shipperParameters.get("contractManageId");
|
||||
Long settlementCustomersId = (Long) shipperParameters.get("settlementCustomersId");
|
||||
String contractNumber = (String) shipperParameters.get("contractNumber");
|
||||
String content = (String) shipperParameters.get("content");
|
||||
Map<String, Object> contentMap = content != null ? JSON.parseObject(content, Map.class) : new HashMap<>();
|
||||
Integer sfzdcz = (Integer) contentMap.get("sfzdcz");
|
||||
//客户未配置或是否自动推送设置为否
|
||||
if (sfzdcz==null) {
|
||||
savePushBillingRecordLog(shipperId, materialInventoryPO, warehouseCode, PushBillingRecordLog.LOG_TYPE_SKIP,
|
||||
"冻仓计费配置未设置[是否自动推送],跳过推送");
|
||||
exceptionCount++;
|
||||
continue;
|
||||
}
|
||||
if (sfzdcz!=1) {
|
||||
savePushBillingRecordLog(shipperId, materialInventoryPO, warehouseCode, PushBillingRecordLog.LOG_TYPE_SKIP,
|
||||
"冻仓计费配置[是否自动推送]为否,跳过推送");
|
||||
exceptionCount++;
|
||||
continue;
|
||||
}
|
||||
//计算费用
|
||||
MaterialBaseInfo materialBaseInfo = materialBaseInfoMapper.selectById(materialBaseInfoId);
|
||||
BigDecimal unitPrice = materialBaseInfo.getUnitPrice();
|
||||
String materialClassifyId = materialBaseInfo.getMaterialClassifyId();
|
||||
BigDecimal weightLimit = materialBaseInfo.getWeightLimit();
|
||||
Map<String,Object> materialClassify = materialInventoryDomainService.queryMaterialClassify(Long.valueOf(materialClassifyId));
|
||||
//物料分类不存在
|
||||
if (materialClassify == null || materialClassify.size()==0) {
|
||||
savePushBillingRecordLog(shipperId, materialInventoryPO, warehouseCode, PushBillingRecordLog.LOG_TYPE_SKIP,
|
||||
"物料分类[" + materialClassifyId + "]不存在,跳过推送");
|
||||
exceptionCount++;
|
||||
continue;
|
||||
}
|
||||
BigDecimal monthlyWarehouseRent = (BigDecimal) materialClassify.get("monthlyWarehouseRent");
|
||||
BigDecimal halfMonthWarehouseRent = (BigDecimal) materialClassify.get("halfMonthWarehouseRent");
|
||||
String monthlyWarehouseRentUnit = (String) materialClassify.get("monthlyWarehouseRentUnit");
|
||||
String halfMonthWarehouseRentUnit = (String) materialClassify.get("halfMonthWarehouseRentUnit");
|
||||
//半月仓租
|
||||
BigDecimal halfMonthWhFee = halfMonthWarehouseRent;
|
||||
//整月仓租
|
||||
BigDecimal monthlyWarehouseFee = monthlyWarehouseRent;
|
||||
long daysDiff = 0;
|
||||
if (lastBillingTime != null) {
|
||||
LocalDate lastBillingDate = lastBillingTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
||||
daysDiff = ChronoUnit.DAYS.between(lastBillingDate, LocalDate.now());
|
||||
} else {
|
||||
daysDiff = -1;
|
||||
}
|
||||
BigDecimal inventoryQuantity = materialInventoryPO.getInventoryQuantity();
|
||||
if (daysDiff < 15) {
|
||||
// 不足半月: 收半月仓租
|
||||
BigDecimal totalWarehouseRent = inventoryQuantity.multiply(halfMonthWhFee).multiply(weightLimit);
|
||||
if (!buildBusinessDocument(totalWarehouseRent, materialInventoryPO,"0D01","租金(固定租)",contractManageId,"冻仓")) {
|
||||
exceptionCount++;
|
||||
}
|
||||
} else {
|
||||
// 大于等于半月: 收整月仓租
|
||||
BigDecimal totalWarehouseRent = inventoryQuantity.multiply(monthlyWarehouseFee).multiply(weightLimit);
|
||||
if (!buildBusinessDocument(totalWarehouseRent, materialInventoryPO,"0D01","租金(固定租)",contractManageId,"冻仓")) {
|
||||
exceptionCount++;
|
||||
}
|
||||
}
|
||||
//更新最后计费时间
|
||||
Long materialInventoryId = materialInventoryPO.getMaterialInventoryId();
|
||||
MaterialInventory materialInventory = materialInventoryMapper.selectById(materialInventoryId);
|
||||
materialInventory.setLastBillingTime(new Date());
|
||||
materialInventoryMapper.updateById(materialInventory);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
savePushBillingRecordLog(shipperId, materialInventoryPO, null, PushBillingRecordLog.LOG_TYPE_ERROR,
|
||||
"处理物料库存时发生异常:" + e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
savePushBillingRecordLog(shipperId, null, null, PushBillingRecordLog.LOG_TYPE_ERROR,
|
||||
"任务执行异常中断:" + e);
|
||||
throw e;
|
||||
}
|
||||
// 本次执行无任何例外(无跳过、无异常),保留成功记录
|
||||
if (exceptionCount == 0) {
|
||||
savePushBillingRecordLog(shipperId, null, null, PushBillingRecordLog.LOG_TYPE_SUCCESS,
|
||||
"入库业务单推送bms计费流水全部执行成功");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存入库业务单推送bms计费流水执行日志(日志写入失败仅打印错误,不影响任务主流程)
|
||||
*
|
||||
* @param shipperId 货主ID(任务参数),为空时从物料库存取
|
||||
* @param materialInventoryPO 物料库存(为空表示任务级日志)
|
||||
* @param warehouseCode 仓库编码
|
||||
* @param logType 日志类型:SUCCESS-全部执行成功 SKIP-业务跳过 ERROR-执行异常
|
||||
* @param logMessage 日志信息(成功说明/跳过原因/异常信息)
|
||||
*/
|
||||
private void savePushBillingRecordLog(String shipperId, MaterialInventoryPO materialInventoryPO, String warehouseCode,
|
||||
String logType, String logMessage) {
|
||||
try {
|
||||
PushBillingRecordLog logRecord = new PushBillingRecordLog();
|
||||
logRecord.setJobName(JOB_NAME_PUSH_BILLING_RECORD);
|
||||
if (StringUtils.isNotBlank(shipperId)) {
|
||||
logRecord.setShipperId(shipperId);
|
||||
} else if (materialInventoryPO != null && materialInventoryPO.getShipperId() != null) {
|
||||
logRecord.setShipperId(String.valueOf(materialInventoryPO.getShipperId()));
|
||||
}
|
||||
if (materialInventoryPO != null) {
|
||||
logRecord.setMaterialInventoryId(materialInventoryPO.getMaterialInventoryId());
|
||||
logRecord.setInOrderNumber(materialInventoryPO.getInOrderNumber());
|
||||
logRecord.setMaterialBaseInfoId(materialInventoryPO.getMaterialBaseInfoId());
|
||||
logRecord.setLotNumber(materialInventoryPO.getLotNumber());
|
||||
}
|
||||
logRecord.setWarehouseCode(warehouseCode);
|
||||
logRecord.setLogType(logType);
|
||||
// 日志信息截断,防止超长导致入库失败
|
||||
if (logMessage != null && logMessage.length() > 2000) {
|
||||
logMessage = logMessage.substring(0, 2000);
|
||||
}
|
||||
logRecord.setLogMessage(logMessage);
|
||||
logRecord.setExecutionTime(new Date());
|
||||
logRecord.setDelFlag(1);
|
||||
pushBillingRecordLogMapper.insert(logRecord);
|
||||
} catch (Exception e) {
|
||||
log.error("保存入库业务单推送bms计费流水执行日志失败: {}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void buildBusinessDocument(BigDecimal fee, MaterialInventoryPO materialInventoryPO,String code,String name,Long contractManageId,String warehouseType) {
|
||||
private boolean buildBusinessDocument(BigDecimal fee, MaterialInventoryPO materialInventoryPO,String code,String name,Long contractManageId,String warehouseType) {
|
||||
Long shipperId = materialInventoryPO.getShipperId();
|
||||
Map<String, Object> shipper = materialInventoryMapper.querySetlleByShipperId(shipperId);
|
||||
if (shipper == null) {
|
||||
return;
|
||||
savePushBillingRecordLog(null, materialInventoryPO, materialInventoryPO.getWarehouseCode(),
|
||||
PushBillingRecordLog.LOG_TYPE_SKIP,
|
||||
"货主[" + shipperId + "]未查询到结算客户信息,未生成业务单据");
|
||||
return false;
|
||||
}
|
||||
Long settlementCustomersId = (Long) shipper.get("settlementCustomersId");
|
||||
Long settlementEntityId = (Long) shipper.get("settlementEntityId");
|
||||
@@ -1174,7 +1319,12 @@ public class MaterialInventoryApplicationService {
|
||||
businessDocumentFeign.setWarehouseType(warehouseType);
|
||||
businessDocumentFeign.setOriginalBusinessNum(materialInventoryPO.getInOrderNumber());
|
||||
Map<String, Object> contract = materialInventoryDomainService.queryContract(contractManageId);
|
||||
if (contract == null) {return;}
|
||||
if (contract == null) {
|
||||
savePushBillingRecordLog(null, materialInventoryPO, materialInventoryPO.getWarehouseCode(),
|
||||
PushBillingRecordLog.LOG_TYPE_SKIP,
|
||||
"合同[" + contractManageId + "]未查询到合同信息,未生成业务单据");
|
||||
return false;
|
||||
}
|
||||
String contractName = (String) contract.get("contractName");
|
||||
String contractNumber = (String) contract.get("contractNumber");
|
||||
businessDocumentFeign.setContractName(contractName);
|
||||
@@ -1185,6 +1335,11 @@ public class MaterialInventoryApplicationService {
|
||||
AjaxResult ajaxResult = bmsServiceFeign.feignSaveBusinessDocument(businessDocumentFeign);
|
||||
if (ajaxResult == null || !"200".equals(String.valueOf(ajaxResult.get("code")))) {
|
||||
log.error("保存业务单据失败: {}", ajaxResult != null ? ajaxResult.get("msg") : "feign调用异常");
|
||||
savePushBillingRecordLog(null, materialInventoryPO, materialInventoryPO.getWarehouseCode(),
|
||||
PushBillingRecordLog.LOG_TYPE_ERROR,
|
||||
"保存业务单据失败:" + (ajaxResult != null ? ajaxResult.get("msg") : "feign调用异常"));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
package com.mhd.wms.domain.materialInventory.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 入库业务单推送bms计费流水任务(XXL-Job:pushBillingRecord)执行日志对象 wms_push_billing_record_log
|
||||
*
|
||||
* @author mhd
|
||||
* @date 2026-09-15
|
||||
*/
|
||||
@Data
|
||||
@TableName("WMS_PUSH_BILLING_RECORD_LOG")
|
||||
public class PushBillingRecordLog implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 日志类型:全部执行成功 */
|
||||
public static final String LOG_TYPE_SUCCESS = "SUCCESS";
|
||||
/** 日志类型:业务跳过(continue跳出) */
|
||||
public static final String LOG_TYPE_SKIP = "SKIP";
|
||||
/** 日志类型:执行异常(报错) */
|
||||
public static final String LOG_TYPE_ERROR = "ERROR";
|
||||
|
||||
@ApiModelProperty("主键ID")
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty("任务名称(XXL-Job任务标识)")
|
||||
private String jobName;
|
||||
|
||||
@ApiModelProperty("货主ID(任务参数)")
|
||||
private String shipperId;
|
||||
|
||||
@ApiModelProperty("物料库存ID")
|
||||
private Long materialInventoryId;
|
||||
|
||||
@ApiModelProperty("入库单号")
|
||||
private String inOrderNumber;
|
||||
|
||||
@ApiModelProperty("物料基础信息ID")
|
||||
private Long materialBaseInfoId;
|
||||
|
||||
@ApiModelProperty("LOT编号")
|
||||
private String lotNumber;
|
||||
|
||||
@ApiModelProperty("仓库编码")
|
||||
private String warehouseCode;
|
||||
|
||||
@ApiModelProperty("日志类型:SUCCESS-全部执行成功 SKIP-业务跳过 ERROR-执行异常")
|
||||
private String logType;
|
||||
|
||||
@ApiModelProperty("日志信息(成功说明/跳过原因/异常信息)")
|
||||
private String logMessage;
|
||||
|
||||
@ApiModelProperty("执行时间")
|
||||
private Date executionTime;
|
||||
|
||||
@ApiModelProperty("删除标记:0-无状态,1-正常,2-已删除")
|
||||
private Integer delFlag;
|
||||
}
|
||||
+2
@@ -136,4 +136,6 @@ public interface IMaterialInventoryService extends IService<MaterialInventory>
|
||||
public Map<String,Object> queryShipperParameters(Long shipperId,String parametersName);
|
||||
|
||||
Map<String, Object> queryMaterialClassify(Long id);
|
||||
|
||||
String queryWarehouseCode(Long id);
|
||||
}
|
||||
+2
@@ -140,4 +140,6 @@ public interface MaterialInventoryMapper extends BaseMapper<MaterialInventory>
|
||||
public Map<String,Object> queryShipperParameters(@Param("shipperId") Long shipperId,@Param("parametersName") String parametersName);
|
||||
|
||||
public Map<String, Object> queryMaterialClassify(@Param("id") Long id);
|
||||
|
||||
public String queryWarehouseCode(@Param("id") Long id);
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.mhd.wms.domain.materialInventory.repository.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.mhd.wms.domain.materialInventory.entity.PushBillingRecordLog;
|
||||
|
||||
/**
|
||||
* 入库业务单推送bms计费流水任务执行日志Mapper接口
|
||||
*
|
||||
* @author mhd
|
||||
* @date 2026-09-15
|
||||
*/
|
||||
public interface PushBillingRecordLogMapper extends BaseMapper<PushBillingRecordLog> {
|
||||
}
|
||||
+5
@@ -1286,4 +1286,9 @@ public class MaterialInventoryImpl extends ServiceImpl<MaterialInventoryMapper,
|
||||
public Map<String, Object> queryMaterialClassify(Long id) {
|
||||
return materialInventoryMapper.queryMaterialClassify(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String queryWarehouseCode(Long id) {
|
||||
return materialInventoryMapper.queryWarehouseCode(id);
|
||||
}
|
||||
}
|
||||
+3
@@ -277,4 +277,7 @@ public class MaterialInventoryPO extends MaterialBasePO {
|
||||
@ApiModelProperty("半月仓租单位")
|
||||
@Excel(name = "半月仓租单位")
|
||||
private String halfMonthWarehouseRentUnit;
|
||||
|
||||
@ApiModelProperty("业务计价类型")
|
||||
private String businessChargeType;
|
||||
}
|
||||
+4
@@ -149,4 +149,8 @@ public class MaterialInventoryDomainService {
|
||||
public Map<String,Object> queryMaterialClassify(Long id) {
|
||||
return materialInventoryService.queryMaterialClassify(id);
|
||||
}
|
||||
|
||||
public String queryWarehouseCode(Long id) {
|
||||
return materialInventoryService.queryWarehouseCode(id);
|
||||
}
|
||||
}
|
||||
@@ -75,6 +75,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<result property="halfMonthWarehouseRentUnit" column="half_month_warehouse_rent_unit" />
|
||||
<result property="halfMonthWarehouseRent" column="half_month_warehouse_rent" />
|
||||
<result property="monthlyWarehouseRent" column="monthly_warehouse_rent" />
|
||||
<result property="businessChargeType" column="BUSINESS_CHARGE_TYPE" />
|
||||
</resultMap>
|
||||
|
||||
|
||||
@@ -1822,8 +1823,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</select>
|
||||
|
||||
<select id="queryPushBms" resultMap="MaterialInventoryResult">
|
||||
SELECT *
|
||||
FROM MATERIAL_INVENTORY
|
||||
SELECT *,
|
||||
(SELECT BUSINESS_CHARGE_TYPE FROM NGWL_TEST_OMS.RESERVATION_STOCK_IN_ORDER WHERE EXECUTION_IN_ORDER_NUMBER = a.in_order_number) as BUSINESS_CHARGE_TYPE
|
||||
FROM MATERIAL_INVENTORY a
|
||||
WHERE EXTRACT(DAY FROM CREATE_TIME) = EXTRACT(DAY FROM SYSDATE - 1) AND INVENTORY_QUANTITY > 0
|
||||
AND DEL_FLAG = 1 AND SHIPPER_ID = #{shipperId}
|
||||
</select>
|
||||
@@ -1894,4 +1896,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
1 = 1
|
||||
AND MATERIAL_CLASSIFY_ID = #{id} AND DEL_FLAG = 1
|
||||
</select>
|
||||
|
||||
<select id="queryWarehouseCode" resultType="java.lang.String">
|
||||
SELECT
|
||||
WAREHOUSE_CODE AS "warehouseCode"
|
||||
FROM
|
||||
NGWL_TEST_SYSTEM.WAREHOUSE
|
||||
WHERE
|
||||
1 = 1
|
||||
AND WAREHOUSE_ID = #{id} AND DEL_FLAG = 1
|
||||
</select>
|
||||
</mapper>
|
||||
@@ -0,0 +1,46 @@
|
||||
-- ----------------------------
|
||||
-- 入库业务单推送bms计费流水定时任务(XXL-Job: pushBillingRecord)执行日志表 -- 达梦(DM)数据库版
|
||||
-- 适用:mhd-wms-service 连接的达梦库(生产/测试按环境选择,在WMS服务连接的用户/模式下执行)
|
||||
-- 用途:记录任务执行过程中的例外情况(执行异常报错、业务continue跳过、生成业务单据失败),
|
||||
-- 本次执行全程无任何例外时保留一条成功记录(LOG_TYPE=SUCCESS)
|
||||
-- @date 2026-09-15
|
||||
-- ----------------------------
|
||||
|
||||
CREATE TABLE WMS_PUSH_BILLING_RECORD_LOG (
|
||||
ID BIGINT IDENTITY(1,1) NOT NULL,
|
||||
JOB_NAME VARCHAR(100) DEFAULT NULL,
|
||||
SHIPPER_ID VARCHAR(50) DEFAULT NULL,
|
||||
MATERIAL_INVENTORY_ID BIGINT DEFAULT NULL,
|
||||
IN_ORDER_NUMBER VARCHAR(100) DEFAULT NULL,
|
||||
MATERIAL_BASE_INFO_ID BIGINT DEFAULT NULL,
|
||||
LOT_NUMBER VARCHAR(100) DEFAULT NULL,
|
||||
WAREHOUSE_CODE VARCHAR(50) DEFAULT NULL,
|
||||
LOG_TYPE VARCHAR(20) DEFAULT NULL,
|
||||
LOG_MESSAGE VARCHAR(2000) DEFAULT NULL,
|
||||
EXECUTION_TIME DATETIME DEFAULT NULL,
|
||||
DEL_FLAG INT DEFAULT 1,
|
||||
CONSTRAINT PK_WMS_PUSH_BILLING_RECORD_LOG PRIMARY KEY (ID)
|
||||
);
|
||||
|
||||
COMMENT ON TABLE WMS_PUSH_BILLING_RECORD_LOG IS '入库业务单推送bms计费流水任务执行日志表';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.ID IS '主键ID';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.JOB_NAME IS '任务名称(XXL-Job任务标识,如pushBillingRecord)';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.SHIPPER_ID IS '货主ID(任务参数)';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.MATERIAL_INVENTORY_ID IS '物料库存ID';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.IN_ORDER_NUMBER IS '入库单号';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.MATERIAL_BASE_INFO_ID IS '物料基础信息ID';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.LOT_NUMBER IS 'LOT编号';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.WAREHOUSE_CODE IS '仓库编码';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.LOG_TYPE IS '日志类型:SUCCESS-全部执行成功 SKIP-业务跳过(continue) ERROR-执行异常';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.LOG_MESSAGE IS '日志信息(成功说明/跳过原因/异常信息)';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.EXECUTION_TIME IS '执行时间';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.DEL_FLAG IS '删除标记:0-无状态,1-正常,2-已删除';
|
||||
|
||||
CREATE INDEX IDX_WPBR_JOB_NAME ON WMS_PUSH_BILLING_RECORD_LOG (JOB_NAME);
|
||||
CREATE INDEX IDX_WPBR_SHIPPER_ID ON WMS_PUSH_BILLING_RECORD_LOG (SHIPPER_ID);
|
||||
CREATE INDEX IDX_WPBR_EXECUTION_TIME ON WMS_PUSH_BILLING_RECORD_LOG (EXECUTION_TIME);
|
||||
|
||||
-- ----------------------------
|
||||
-- 回滚脚本
|
||||
-- DROP TABLE WMS_PUSH_BILLING_RECORD_LOG;
|
||||
-- ----------------------------
|
||||
@@ -0,0 +1,46 @@
|
||||
-- ----------------------------
|
||||
-- 入库业务单推送bms计费流水定时任务(XXL-Job: pushBillingRecord)执行日志表 -- 达梦(DM)数据库版
|
||||
-- 适用:mhd-wms-service 连接的达梦库(生产/测试按环境选择,在WMS服务连接的用户/模式下执行)
|
||||
-- 用途:记录任务执行过程中的例外情况(执行异常报错、业务continue跳过、生成业务单据失败),
|
||||
-- 本次执行全程无任何例外时保留一条成功记录(LOG_TYPE=SUCCESS)
|
||||
-- @date 2026-09-15
|
||||
-- ----------------------------
|
||||
|
||||
CREATE TABLE WMS_PUSH_BILLING_RECORD_LOG (
|
||||
ID BIGINT IDENTITY(1,1) NOT NULL,
|
||||
JOB_NAME VARCHAR(100) DEFAULT NULL,
|
||||
SHIPPER_ID VARCHAR(50) DEFAULT NULL,
|
||||
MATERIAL_INVENTORY_ID BIGINT DEFAULT NULL,
|
||||
IN_ORDER_NUMBER VARCHAR(100) DEFAULT NULL,
|
||||
MATERIAL_BASE_INFO_ID BIGINT DEFAULT NULL,
|
||||
LOT_NUMBER VARCHAR(100) DEFAULT NULL,
|
||||
WAREHOUSE_CODE VARCHAR(50) DEFAULT NULL,
|
||||
LOG_TYPE VARCHAR(20) DEFAULT NULL,
|
||||
LOG_MESSAGE VARCHAR(2000) DEFAULT NULL,
|
||||
EXECUTION_TIME DATETIME DEFAULT NULL,
|
||||
DEL_FLAG INT DEFAULT 1,
|
||||
CONSTRAINT PK_WMS_PUSH_BILLING_RECORD_LOG PRIMARY KEY (ID)
|
||||
);
|
||||
|
||||
COMMENT ON TABLE WMS_PUSH_BILLING_RECORD_LOG IS '入库业务单推送bms计费流水任务执行日志表';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.ID IS '主键ID';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.JOB_NAME IS '任务名称(XXL-Job任务标识,如pushBillingRecord)';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.SHIPPER_ID IS '货主ID(任务参数)';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.MATERIAL_INVENTORY_ID IS '物料库存ID';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.IN_ORDER_NUMBER IS '入库单号';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.MATERIAL_BASE_INFO_ID IS '物料基础信息ID';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.LOT_NUMBER IS 'LOT编号';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.WAREHOUSE_CODE IS '仓库编码';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.LOG_TYPE IS '日志类型:SUCCESS-全部执行成功 SKIP-业务跳过(continue) ERROR-执行异常';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.LOG_MESSAGE IS '日志信息(成功说明/跳过原因/异常信息)';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.EXECUTION_TIME IS '执行时间';
|
||||
COMMENT ON COLUMN WMS_PUSH_BILLING_RECORD_LOG.DEL_FLAG IS '删除标记:0-无状态,1-正常,2-已删除';
|
||||
|
||||
CREATE INDEX IDX_WPBR_JOB_NAME ON WMS_PUSH_BILLING_RECORD_LOG (JOB_NAME);
|
||||
CREATE INDEX IDX_WPBR_SHIPPER_ID ON WMS_PUSH_BILLING_RECORD_LOG (SHIPPER_ID);
|
||||
CREATE INDEX IDX_WPBR_EXECUTION_TIME ON WMS_PUSH_BILLING_RECORD_LOG (EXECUTION_TIME);
|
||||
|
||||
-- ----------------------------
|
||||
-- 回滚脚本
|
||||
-- DROP TABLE WMS_PUSH_BILLING_RECORD_LOG;
|
||||
-- ----------------------------
|
||||
Reference in New Issue
Block a user