|
|
@@ -1,5 +1,6 @@
|
|
|
package com.yc.ship.module.product.api;
|
|
|
|
|
|
+import com.yc.ship.framework.common.exception.ServiceException;
|
|
|
import com.yc.ship.framework.common.util.collection.CollectionUtils;
|
|
|
import com.yc.ship.framework.common.util.object.BeanUtils;
|
|
|
import com.yc.ship.module.product.api.dto.OrderRoomUseDTO;
|
|
|
@@ -24,13 +25,11 @@ import com.yc.ship.module.product.enums.YesOrNoEnum;
|
|
|
import com.yc.ship.module.product.framework.lock.ProductRedisKeyConstants;
|
|
|
import com.yc.ship.module.product.service.voyagestockdistribute.VoyageStockDistributeNewService;
|
|
|
import com.yc.ship.module.resource.api.room.RoomApi;
|
|
|
-import com.yc.ship.module.resource.api.room.dto.RoomRespDTO;
|
|
|
import com.yc.ship.module.trade.enums.TradeOrderStatusEnum;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.redisson.api.RLock;
|
|
|
import org.redisson.api.RedissonClient;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
-import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
import java.math.BigDecimal;
|
|
|
@@ -42,6 +41,7 @@ import java.util.concurrent.TimeUnit;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
import static com.yc.ship.framework.common.exception.util.ServiceExceptionUtil.exception;
|
|
|
+import static com.yc.ship.framework.common.exception.util.ServiceExceptionUtil.exception0;
|
|
|
import static com.yc.ship.module.product.enums.ErrorCodeConstants.*;
|
|
|
|
|
|
@Service
|
|
|
@@ -75,7 +75,6 @@ public class VoyageApiImpl implements VoyageApi {
|
|
|
@Resource
|
|
|
private VoyageStockDetailLogMapper voyageStockDetailLogMapper;
|
|
|
|
|
|
- @Transactional(rollbackFor = Exception.class)
|
|
|
@Override
|
|
|
public void preReduceStock(ReduceStockReqDTO reqDTO) {
|
|
|
//TODO: 当前阶段不考虑门店库存
|
|
|
@@ -86,8 +85,10 @@ public class VoyageApiImpl implements VoyageApi {
|
|
|
RLock lock = redissonClient.getLock(lockKey);
|
|
|
try {
|
|
|
lock.lock(60, TimeUnit.SECONDS);
|
|
|
- Integer type = reqDTO.getType();//判断是分销商还是门店下单 1:分销商,2:门店
|
|
|
- if (Objects.equals(type, DistributorOrStoreEnum.DISTRIBUTOR.getValue())) {//分销商下单,当前阶段不考虑门店下单
|
|
|
+ //判断是分销商还是门店下单 1:分销商,2:门店
|
|
|
+ Integer type = reqDTO.getType();
|
|
|
+ //分销商下单,当前阶段不考虑门店下单
|
|
|
+ if (Objects.equals(type, DistributorOrStoreEnum.DISTRIBUTOR.getValue())) {
|
|
|
//分销商下单只扣分销商库存,默认是OTA,默认OTC只能门店下单
|
|
|
//初定扣分销商库存
|
|
|
//先返还初定扣的库存
|
|
|
@@ -95,15 +96,20 @@ public class VoyageApiImpl implements VoyageApi {
|
|
|
//再去扣初定的库存
|
|
|
preReduceStockDistributor(reqDTO);
|
|
|
}
|
|
|
+ } catch (ServiceException e) {
|
|
|
+ throw exception0(e.getCode(), e.getMessage());
|
|
|
} finally {
|
|
|
- if (lock.isHeldByCurrentThread() && lock.isLocked()) {
|
|
|
- lock.unlock();
|
|
|
+ try {
|
|
|
+ if (lock.isHeldByCurrentThread() && lock.isLocked()) {
|
|
|
+ lock.unlock();
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("释放锁异常", e);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- @Transactional(rollbackFor = Exception.class)
|
|
|
public void preCancelReduceStock(ReduceStockReqDTO reqDTO) {
|
|
|
//TODO: 当前阶段不考虑门店库存
|
|
|
|
|
|
@@ -127,7 +133,6 @@ public class VoyageApiImpl implements VoyageApi {
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- @Transactional(rollbackFor = Exception.class)
|
|
|
public void reduceStock(ReduceStockReqDTO reqDTO) {
|
|
|
//TODO: 当前阶段不考虑门店库存
|
|
|
|
|
|
@@ -225,8 +230,8 @@ public class VoyageApiImpl implements VoyageApi {
|
|
|
voyageStockDetailMapper.updateBatch(stockDetailList);
|
|
|
|
|
|
Integer stockType = detailLogList.get(0).getStockType();
|
|
|
-
|
|
|
- if (stockType == 2) { //2:还分销商库存
|
|
|
+ //2:还分销商库存
|
|
|
+ if (stockType == 2) {
|
|
|
//判断分销商库存是否存在
|
|
|
VoyageStockDistributeNewDetailReqVO detailReqVO = new VoyageStockDistributeNewDetailReqVO();
|
|
|
detailReqVO.setVoyageId(voyageId);
|
|
|
@@ -238,7 +243,7 @@ public class VoyageApiImpl implements VoyageApi {
|
|
|
list.forEach(item -> {
|
|
|
String key = item.getRoomModelId() + "_" + item.getFloor();
|
|
|
item.setNum(item.getNum().add(totalNumMap.get(key)));
|
|
|
- item.setBookNum(item.getBookNum().subtract(totalNumMap.get(key)));
|
|
|
+ item.setBookNum(item.getBookNum() == null ? BigDecimal.ZERO : item.getBookNum().subtract(totalNumMap.get(key)));
|
|
|
});
|
|
|
voyageStockDistributeNewMapper.updateBatch(list);
|
|
|
}
|
|
|
@@ -291,17 +296,20 @@ public class VoyageApiImpl implements VoyageApi {
|
|
|
detailReqVO.setVoyageId(voyageId);
|
|
|
detailReqVO.setType(type);
|
|
|
detailReqVO.setObjectId(distributorId);
|
|
|
- detailReqVO.setEnableShare(YesOrNoEnum.NO.getType());//先获取非共享库存(分销商库存)
|
|
|
- List<VoyageStockDistributeNewRespVO> distributeNewRespVOS = voyageStockDistributeNewService.getDetail(detailReqVO);
|
|
|
- List<OrderRoomUseDTO> orderRoomList = reqDTO.getOrderRoomList();//订单使用房间详情
|
|
|
+ //先获取非共享库存(分销商库存)
|
|
|
+ detailReqVO.setEnableShare(YesOrNoEnum.NO.getType());
|
|
|
+ List<VoyageStockDistributeNewRespVO> distributeNewResps = voyageStockDistributeNewService.getDetail(detailReqVO);
|
|
|
+ //订单使用房间详情
|
|
|
+ List<OrderRoomUseDTO> orderRoomList = reqDTO.getOrderRoomList();
|
|
|
Map<String, BigDecimal> roomModelFloorNumMap = orderRoomList.stream()
|
|
|
.collect(Collectors.groupingBy(
|
|
|
OrderRoomUseDTO::getKey,
|
|
|
Collectors.mapping(OrderRoomUseDTO::getNum, Collectors.reducing(BigDecimal.ZERO, BigDecimal::add)) // 直接使用BigDecimal的reduce操作进行求和
|
|
|
));
|
|
|
- if (distributeNewRespVOS.isEmpty()) {//分销商未分配库存,扣共享库存
|
|
|
-
|
|
|
- voyageStockLogDO.setStockType(1); //1共享库存
|
|
|
+ //分销商未分配库存,扣共享库存
|
|
|
+ if (distributeNewResps.isEmpty()) {
|
|
|
+ //1共享库存
|
|
|
+ voyageStockLogDO.setStockType(1);
|
|
|
//判断共享库存是否充足
|
|
|
if (shareNum.compareTo(totalUseNum) < 0) {
|
|
|
throw exception(VOYAGE_SHARE_STOCK_NOT_ENOUGH);
|
|
|
@@ -315,7 +323,7 @@ public class VoyageApiImpl implements VoyageApi {
|
|
|
useNum = BigDecimal.ZERO;
|
|
|
}
|
|
|
if (canSellNum.compareTo(useNum) < 0) {
|
|
|
- throw exception(VOYAGE_SHARE_ROOM_NOT_ENOUGH.getCode(), String.format(VOYAGE_SHARE_ROOM_NOT_ENOUGH.getMsg(), item.getRoomModelName(), item.getFloor()));
|
|
|
+ throw exception0(VOYAGE_SHARE_ROOM_NOT_ENOUGH.getCode(), String.format(VOYAGE_SHARE_ROOM_NOT_ENOUGH.getMsg(), item.getRoomModelName(), item.getFloor()));
|
|
|
}
|
|
|
});
|
|
|
// 库存充足,扣库存详情
|
|
|
@@ -353,7 +361,11 @@ public class VoyageApiImpl implements VoyageApi {
|
|
|
item.setVirtualNum(item.getVirtualNum().subtract(useNum.subtract(item.getRealTotalNum())));
|
|
|
}
|
|
|
// 加预定房间数
|
|
|
- item.setBookNum(item.getBookNum().add(useNum));
|
|
|
+ if (item.getBookNum() != null) {
|
|
|
+ item.setBookNum(item.getBookNum().add(useNum));
|
|
|
+ } else {
|
|
|
+ item.setBookNum(useNum);
|
|
|
+ }
|
|
|
|
|
|
detailLogList.add(voyageStockDetailLogDO);
|
|
|
|
|
|
@@ -383,25 +395,25 @@ public class VoyageApiImpl implements VoyageApi {
|
|
|
voyageStockLogDO.setShareNum(totalUseNum);
|
|
|
voyageStockMapper.updateById(stockDO);
|
|
|
} else {
|
|
|
-
|
|
|
- voyageStockLogDO.setStockType(2); //2分销商库存
|
|
|
+ //2分销商库存
|
|
|
+ voyageStockLogDO.setStockType(2);
|
|
|
|
|
|
//分销商已分配库存,扣自身库存
|
|
|
|
|
|
//判断航次房型楼层库存是否充足
|
|
|
- distributeNewRespVOS.forEach(item -> {
|
|
|
+ distributeNewResps.forEach(item -> {
|
|
|
BigDecimal canSellNum = item.getNum();
|
|
|
BigDecimal useNum = roomModelFloorNumMap.get(item.getRoomModelId() + "_" + item.getFloor());
|
|
|
if (useNum == null) {
|
|
|
useNum = BigDecimal.ZERO;
|
|
|
}
|
|
|
if (canSellNum.compareTo(useNum) < 0) {
|
|
|
- throw exception(VOYAGE_DISTRIBUTOR_ROOM_NOT_ENOUGH.getCode(), String.format(VOYAGE_DISTRIBUTOR_ROOM_NOT_ENOUGH.getMsg(), item.getRoomModelName(), item.getFloor()));
|
|
|
+ throw exception0(VOYAGE_DISTRIBUTOR_ROOM_NOT_ENOUGH.getCode(), String.format(VOYAGE_DISTRIBUTOR_ROOM_NOT_ENOUGH.getMsg(), item.getRoomModelName(), item.getFloor()));
|
|
|
}
|
|
|
});
|
|
|
// 扣分销商库存
|
|
|
// 库存充足,扣库存详情
|
|
|
- List<VoyageStockDistributeNewDO> list = BeanUtils.toBean(distributeNewRespVOS, VoyageStockDistributeNewDO.class);
|
|
|
+ List<VoyageStockDistributeNewDO> list = BeanUtils.toBean(distributeNewResps, VoyageStockDistributeNewDO.class);
|
|
|
list.forEach(item -> {
|
|
|
BigDecimal useNum = roomModelFloorNumMap.get(item.getRoomModelId() + "_" + item.getFloor());
|
|
|
if (useNum == null) {
|
|
|
@@ -410,7 +422,11 @@ public class VoyageApiImpl implements VoyageApi {
|
|
|
// 减可售房间数
|
|
|
item.setNum(item.getNum().subtract(useNum));
|
|
|
// 加预定房间数
|
|
|
- item.setBookNum(item.getBookNum().add(useNum));
|
|
|
+ if (item.getBookNum() != null) {
|
|
|
+ item.setBookNum(item.getBookNum().add(useNum));
|
|
|
+ } else {
|
|
|
+ item.setBookNum(useNum);
|
|
|
+ }
|
|
|
});
|
|
|
|
|
|
voyageStockDistributeNewMapper.updateBatch(list);
|
|
|
@@ -450,7 +466,11 @@ public class VoyageApiImpl implements VoyageApi {
|
|
|
item.setVirtualNum(item.getVirtualNum().subtract(useNum.subtract(item.getRealTotalNum())));
|
|
|
}
|
|
|
// 加预定房间数
|
|
|
- item.setBookNum(item.getBookNum().add(useNum));
|
|
|
+ if (item.getBookNum() != null) {
|
|
|
+ item.setBookNum(item.getBookNum().add(useNum));
|
|
|
+ } else {
|
|
|
+ item.setBookNum(useNum);
|
|
|
+ }
|
|
|
|
|
|
detailLogList.add(voyageStockDetailLogDO);
|
|
|
|
|
|
@@ -484,7 +504,7 @@ public class VoyageApiImpl implements VoyageApi {
|
|
|
List<VoyageStockRoomUsedDO> roomUsedList = new ArrayList<>();
|
|
|
Map<Long, OrderRoomUseDTO> roomIdMap = CollectionUtils.convertMap(orderRoomList, OrderRoomUseDTO::getRoomId);
|
|
|
orderRoomList.forEach(item -> {
|
|
|
- if(item.getRoomId() == null) {
|
|
|
+ if (item.getRoomId() == null) {
|
|
|
return;
|
|
|
}
|
|
|
VoyageStockRoomUsedDO roomUsedDO = new VoyageStockRoomUsedDO();
|
|
|
@@ -653,7 +673,7 @@ public class VoyageApiImpl implements VoyageApi {
|
|
|
}
|
|
|
if (canSellNum.compareTo(useNum) < 0) {
|
|
|
log.error(String.format(VOYAGE_SHARE_ROOM_NOT_ENOUGH.getMsg(), item.getRoomModelName(), item.getFloor()));
|
|
|
- throw exception(VOYAGE_SHARE_ROOM_NOT_ENOUGH.getCode(), String.format(VOYAGE_SHARE_ROOM_NOT_ENOUGH.getMsg(), item.getRoomModelName(), item.getFloor()));
|
|
|
+ throw exception0(VOYAGE_SHARE_ROOM_NOT_ENOUGH.getCode(), String.format(VOYAGE_SHARE_ROOM_NOT_ENOUGH.getMsg(), item.getRoomModelName(), item.getFloor()));
|
|
|
}
|
|
|
});
|
|
|
// 库存充足,扣库存详情
|
|
|
@@ -691,7 +711,11 @@ public class VoyageApiImpl implements VoyageApi {
|
|
|
item.setRealTotalNum(item.getRealTotalNum().subtract(useNum.subtract(item.getVirtualNum())));
|
|
|
}
|
|
|
// 加预定房间数
|
|
|
- item.setBookNum(item.getBookNum().add(useNum));
|
|
|
+ if (item.getBookNum() != null) {
|
|
|
+ item.setBookNum(item.getBookNum().add(useNum));
|
|
|
+ } else {
|
|
|
+ item.setBookNum(useNum);
|
|
|
+ }
|
|
|
|
|
|
detailLogList.add(voyageStockDetailLogDO);
|
|
|
|
|
|
@@ -734,7 +758,7 @@ public class VoyageApiImpl implements VoyageApi {
|
|
|
useNum = BigDecimal.ZERO;
|
|
|
}
|
|
|
if (canSellNum.compareTo(useNum) < 0) {
|
|
|
- throw exception(VOYAGE_DISTRIBUTOR_ROOM_NOT_ENOUGH.getCode(), String.format(VOYAGE_DISTRIBUTOR_ROOM_NOT_ENOUGH.getMsg(), item.getRoomModelName(), item.getFloor()));
|
|
|
+ throw exception0(VOYAGE_DISTRIBUTOR_ROOM_NOT_ENOUGH.getCode(), String.format(VOYAGE_DISTRIBUTOR_ROOM_NOT_ENOUGH.getMsg(), item.getRoomModelName(), item.getFloor()));
|
|
|
}
|
|
|
});
|
|
|
// 扣分销商库存
|
|
|
@@ -792,7 +816,11 @@ public class VoyageApiImpl implements VoyageApi {
|
|
|
item.setRealTotalNum(item.getRealTotalNum().subtract(useNum.subtract(item.getVirtualNum())));
|
|
|
}
|
|
|
// 加预定房间数
|
|
|
- item.setBookNum(item.getBookNum().add(useNum));
|
|
|
+ if (item.getBookNum() != null) {
|
|
|
+ item.setBookNum(item.getBookNum().add(useNum));
|
|
|
+ } else {
|
|
|
+ item.setBookNum(useNum);
|
|
|
+ }
|
|
|
|
|
|
detailLogList.add(voyageStockDetailLogDO);
|
|
|
|
|
|
@@ -826,7 +854,7 @@ public class VoyageApiImpl implements VoyageApi {
|
|
|
List<VoyageStockRoomUsedDO> roomUsedList = new ArrayList<>();
|
|
|
Map<Long, OrderRoomUseDTO> roomIdMap = CollectionUtils.convertMap(orderRoomList, OrderRoomUseDTO::getRoomId);
|
|
|
orderRoomList.forEach(item -> {
|
|
|
- if(item.getRoomId() == null) {
|
|
|
+ if (item.getRoomId() == null) {
|
|
|
return;
|
|
|
}
|
|
|
VoyageStockRoomUsedDO roomUsedDO = new VoyageStockRoomUsedDO();
|