|
@@ -1,31 +1,37 @@
|
|
|
package com.yc.ship.module.product.api;
|
|
|
|
|
|
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.ReduceStockReqDTO;
|
|
|
+import com.yc.ship.module.product.controller.admin.voyagestockdistributeNew.vo.VoyageStockDistributeNewDetailReqVO;
|
|
|
+import com.yc.ship.module.product.controller.admin.voyagestockdistributeNew.vo.VoyageStockDistributeNewRespVO;
|
|
|
import com.yc.ship.module.product.dal.dataobject.voyagestock.VoyageStockDO;
|
|
|
import com.yc.ship.module.product.dal.dataobject.voyagestockdetail.VoyageStockDetailDO;
|
|
|
-import com.yc.ship.module.product.dal.dataobject.voyagestockdistribute.VoyageStockDistributeDO;
|
|
|
+import com.yc.ship.module.product.dal.dataobject.voyagestockdistribute.VoyageStockDistributeNewDO;
|
|
|
import com.yc.ship.module.product.dal.mysql.voyagestock.VoyageStockMapper;
|
|
|
import com.yc.ship.module.product.dal.mysql.voyagestockdetail.VoyageStockDetailMapper;
|
|
|
import com.yc.ship.module.product.dal.mysql.voyagestockdistribute.VoyageStockDistributeMapper;
|
|
|
+import com.yc.ship.module.product.dal.mysql.voyagestockdistribute.VoyageStockDistributeNewMapper;
|
|
|
import com.yc.ship.module.product.enums.DistributorOrStoreEnum;
|
|
|
+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 org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
import java.math.BigDecimal;
|
|
|
-import java.util.ArrayList;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
-import java.util.concurrent.atomic.AtomicReference;
|
|
|
|
|
|
-import static com.yc.ship.framework.common.exception.util.ServiceExceptionUtil.exception0;
|
|
|
+import static com.yc.ship.framework.common.exception.util.ServiceExceptionUtil.exception;
|
|
|
+import static com.yc.ship.module.product.enums.ErrorCodeConstants.*;
|
|
|
|
|
|
@Service
|
|
|
public class VoyageApiImpl implements VoyageApi{
|
|
|
|
|
|
@Resource
|
|
|
- private VoyageStockDistributeMapper voyageStockDistributeMapper;
|
|
|
+ private VoyageStockDistributeNewMapper voyageStockDistributeNewMapper;
|
|
|
|
|
|
@Resource
|
|
|
private VoyageStockMapper voyageStockMapper;
|
|
@@ -33,102 +39,198 @@ public class VoyageApiImpl implements VoyageApi{
|
|
|
@Resource
|
|
|
private VoyageStockDetailMapper voyageStockDetailMapper;
|
|
|
|
|
|
+ @Resource
|
|
|
+ private VoyageStockDistributeNewService voyageStockDistributeNewService;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private RoomApi roomApi;
|
|
|
+
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
@Override
|
|
|
//TODO: 待完善 加锁
|
|
|
public void preReduceStock(ReduceStockReqDTO reqDTO) {
|
|
|
- // 1.扣门店库存
|
|
|
- // 2.扣分销商库存
|
|
|
- // 3.扣分销商类型库存
|
|
|
- // 4.扣航次库存,优先扣虚拟库存
|
|
|
+ //TODO: 当前阶段不考虑门店库存
|
|
|
|
|
|
Integer type = reqDTO.getType();//判断是分销商还是门店下单 1:分销商,2:门店
|
|
|
+
|
|
|
+ if(type == DistributorOrStoreEnum.DISTRIBUTOR.getValue()) {//分销商下单,当前阶段不考虑门店下单
|
|
|
+ //分销商下单只扣分销商库存,默认是OTA,默认OTC只能门店下单
|
|
|
+ //初定扣分销商库存
|
|
|
+ preReduceStockDistributor(reqDTO);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 预定扣分销商库存
|
|
|
+ * @param reqDTO
|
|
|
+ */
|
|
|
+ private void preReduceStockDistributor(ReduceStockReqDTO reqDTO) {
|
|
|
+ Integer type = reqDTO.getType();
|
|
|
Long voyageId = reqDTO.getVoyageId(); //航次ID
|
|
|
Long distributorId = reqDTO.getDistributorId(); //分销商ID
|
|
|
Long storeId = reqDTO.getStoreId(); //门店ID
|
|
|
- List<ReduceStockReqDTO.OrderRoomDTO> orderRoomList = reqDTO.getOrderRoomList();//订单使用房间详情
|
|
|
-
|
|
|
- if(type == DistributorOrStoreEnum.DISTRIBUTOR.getValue()) {//分销商下单
|
|
|
- //分销商下单只扣分销商库存,默认是OTA,默认OTC只能门店下单
|
|
|
+ BigDecimal totalUseNum = reqDTO.getUseRoomNum(); //总共使用房间数量
|
|
|
|
|
|
+ // 获取航次总库存
|
|
|
+ VoyageStockDO stockDO = voyageStockMapper.selectById(voyageId);
|
|
|
+ if(stockDO == null) {
|
|
|
+ throw exception(VOYAGE_NO_STOCK);
|
|
|
}
|
|
|
+ //共享库存
|
|
|
+ BigDecimal shareNum = stockDO.getShareNum();
|
|
|
+
|
|
|
+ ///航次库存详情
|
|
|
+ List<VoyageStockDetailDO> stockDetailList = voyageStockDetailMapper.selectListByVoyageId(voyageId);
|
|
|
+
|
|
|
+ //判断分销商库存是否存在
|
|
|
+ VoyageStockDistributeNewDetailReqVO detailReqVO = new VoyageStockDistributeNewDetailReqVO();
|
|
|
+ detailReqVO.setVoyageId(voyageId);
|
|
|
+ detailReqVO.setType(type);
|
|
|
+ detailReqVO.setObjectId(distributorId);
|
|
|
+ List<VoyageStockDistributeNewRespVO> distributeNewRespVOS = voyageStockDistributeNewService.getDetail(detailReqVO);
|
|
|
+ if(distributeNewRespVOS.isEmpty()) {//分销商未分配库存,扣共享库存
|
|
|
+ //判断共享库存是否充足
|
|
|
+ if(shareNum.compareTo(totalUseNum) < 0) {
|
|
|
+ throw exception(VOYAGE_SHARE_STOCK_NOT_ENOUGH);
|
|
|
+ }
|
|
|
+ //判断航次房型楼层库存是否充足
|
|
|
+ List<ReduceStockReqDTO.OrderRoomDTO> orderRoomList = reqDTO.getOrderRoomList();//订单使用房间详情
|
|
|
+ Map<Long, BigDecimal> roomMap = CollectionUtils.convertMap(orderRoomList, item -> item.getRoomId(), item -> item.getNum());
|
|
|
+ List<Long> roomIds = CollectionUtils.convertList(orderRoomList, ReduceStockReqDTO.OrderRoomDTO::getRoomId);
|
|
|
+ List<RoomRespDTO> roomList = roomApi.getRoomListByIds(roomIds);
|
|
|
+ Map<String, BigDecimal> roomModelFloorNumMap = CollectionUtils.convertMap(roomList,
|
|
|
+ item -> item.getRoomModelId() + "_" + item.getFloors(),
|
|
|
+ item -> roomMap.get(item.getId()) == null ? BigDecimal.ZERO : roomMap.get(item.getId()));
|
|
|
+ // 判断库存是否充足
|
|
|
+ stockDetailList.stream().forEach(item -> {
|
|
|
+ BigDecimal canSellNum = item.getCanSellNum();
|
|
|
+ BigDecimal useNum = roomModelFloorNumMap.get(item.getRoomModelId() + "_" + item.getFloor());
|
|
|
+ if(useNum == null) {
|
|
|
+ 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()));
|
|
|
+ }
|
|
|
+ });
|
|
|
+ // 库存充足,扣库存详情
|
|
|
+ stockDetailList.stream().forEach(item -> {
|
|
|
+ BigDecimal useNum = roomModelFloorNumMap.get(item.getRoomModelId() + "_" + item.getFloor());
|
|
|
+ if(useNum == null) {
|
|
|
+ useNum = BigDecimal.ZERO;
|
|
|
+ }
|
|
|
+ // 减可售房间数
|
|
|
+ item.setCanSellNum(item.getCanSellNum().subtract(useNum));
|
|
|
+ // 减剩余房间数
|
|
|
+ item.setSurplusNum(item.getSurplusNum().subtract(useNum));
|
|
|
+ // 减虚拟房间数,此处初定,先扣虚拟库存,虚拟库存不足再扣实际库存
|
|
|
+ if(item.getVirtualNum().compareTo(useNum) >= 0) {
|
|
|
+ item.setVirtualNum(item.getVirtualNum().subtract(useNum));
|
|
|
+ }else {
|
|
|
+ item.setVirtualNum(BigDecimal.ZERO);
|
|
|
+ // 扣实际房间数
|
|
|
+ item.setRealTotalNum(item.getRealTotalNum().subtract(useNum.subtract(item.getVirtualNum())));
|
|
|
+ }
|
|
|
+ // 加预定房间数
|
|
|
+ item.setBookNum(item.getBookNum().add(useNum));
|
|
|
+
|
|
|
+ });
|
|
|
+ voyageStockDetailMapper.updateBatch(stockDetailList);
|
|
|
+
|
|
|
+ // 扣总库存
|
|
|
+ // 减可售房间数
|
|
|
+ stockDO.setCanSellNum(stockDO.getCanSellNum().subtract(totalUseNum));
|
|
|
+ // 减剩余房间数
|
|
|
+ stockDO.setSurplusNum(stockDO.getSurplusNum().subtract(totalUseNum));
|
|
|
+ // 减虚拟房间数,此处初定,先扣虚拟库存,虚拟库存不足再扣实际库存
|
|
|
+ if(stockDO.getVirtualNum().compareTo(totalUseNum) >= 0) {
|
|
|
+ stockDO.setVirtualNum(stockDO.getVirtualNum().subtract(totalUseNum));
|
|
|
+ }else {
|
|
|
+ stockDO.setVirtualNum(BigDecimal.ZERO);
|
|
|
+ // 扣实际房间数
|
|
|
+ stockDO.setRealTotalNum(stockDO.getRealTotalNum().subtract(totalUseNum.subtract(stockDO.getVirtualNum())));
|
|
|
+ }
|
|
|
+ // 加预定房间数
|
|
|
+ stockDO.setBookNum(stockDO.getBookNum().add(totalUseNum));
|
|
|
+ // 扣共享库存
|
|
|
+ stockDO.setShareNum(stockDO.getShareNum().subtract(totalUseNum));
|
|
|
+ voyageStockMapper.updateById(stockDO);
|
|
|
+ }else {
|
|
|
+ //分销商已分配库存,扣自身库存
|
|
|
|
|
|
+ //判断航次房型楼层库存是否充足
|
|
|
+ List<ReduceStockReqDTO.OrderRoomDTO> orderRoomList = reqDTO.getOrderRoomList();//订单使用房间详情
|
|
|
+ Map<Long, BigDecimal> roomMap = CollectionUtils.convertMap(orderRoomList, item -> item.getRoomId(), item -> item.getNum());
|
|
|
+ List<Long> roomIds = CollectionUtils.convertList(orderRoomList, ReduceStockReqDTO.OrderRoomDTO::getRoomId);
|
|
|
+ List<RoomRespDTO> roomList = roomApi.getRoomListByIds(roomIds);
|
|
|
+ Map<String, BigDecimal> roomModelFloorNumMap = CollectionUtils.convertMap(roomList,
|
|
|
+ item -> item.getRoomModelId() + "_" + item.getFloors(),
|
|
|
+ item -> roomMap.get(item.getId()) == null ? BigDecimal.ZERO : roomMap.get(item.getId()));
|
|
|
|
|
|
- // 1.扣门店库存
|
|
|
- // 2.扣分销商库存
|
|
|
- // 3.扣分销商类型库存
|
|
|
-// List<VoyageStockDistributeDO> distributeDOList = voyageStockDistributeMapper.selectListByVoyageId(voyageId);
|
|
|
-// List<ReduceStockReqDTO.OrderDetailReqDTO> orderDetailList = reqDTO.getOrderDetailList();
|
|
|
-// Map<String, ReduceStockReqDTO.OrderDetailReqDTO> map = CollectionUtils.convertMap(orderDetailList, item -> {
|
|
|
-// String key = distributorType + "_" + distributorId + "_" + storeId + "_" + item.getRoomModelId() + "_" + item.getFloor();
|
|
|
-// return key;
|
|
|
-// });
|
|
|
-// AtomicReference<BigDecimal> totalNum = new AtomicReference<>(BigDecimal.ZERO);
|
|
|
-// List<VoyageStockDistributeDO> updateList = new ArrayList<>();
|
|
|
-// distributeDOList.stream().forEach(item -> {
|
|
|
-// String key = item.getDistributorType() + "_" + item.getDistributorId() + "_" + item.getStoreId() + "_" + item.getRoomModelId() + "_" + item.getFloor();
|
|
|
-// ReduceStockReqDTO.OrderDetailReqDTO orderDetailReqDTO = map.get(key);
|
|
|
-// if (orderDetailReqDTO != null) {
|
|
|
-// item.setSurplusNum(item.getSurplusNum().subtract(orderDetailReqDTO.getNum()));
|
|
|
-// item.setBookNum(item.getBookNum().add(orderDetailReqDTO.getNum()));
|
|
|
-// updateList.add(item);
|
|
|
-// }
|
|
|
-// totalNum.updateAndGet(v -> v.add(item.getNum()));
|
|
|
-// });
|
|
|
-// BigDecimal total = totalNum.get();
|
|
|
-// voyageStockDistributeMapper.updateBatch(updateList);
|
|
|
-//
|
|
|
-// // 4.扣航次库存,优先扣虚拟库存
|
|
|
-// VoyageStockDO stockDO = voyageStockMapper.selectById(voyageId);
|
|
|
-// //判断可售房间数是否大于等于订单的房间数
|
|
|
-// if(stockDO.getCanSellNum().compareTo(total) == -1) {
|
|
|
-// throw exception0(500,"可售房间数不足");
|
|
|
-// }
|
|
|
-// //减虚拟房间数
|
|
|
-// if(stockDO.getVirtualNum().compareTo(total) >=0 ) {
|
|
|
-// stockDO.setVirtualNum(stockDO.getVirtualNum().subtract(totalNum.get()));
|
|
|
-// }else {
|
|
|
-// stockDO.setVirtualNum(BigDecimal.ZERO);
|
|
|
-// // 加超卖房间数
|
|
|
-// stockDO.setOversoldNum(stockDO.getOversoldNum().add(total.subtract(stockDO.getVirtualNum())));
|
|
|
-// }
|
|
|
-// //减可售房间数
|
|
|
-// stockDO.setCanSellNum(stockDO.getCanSellNum().subtract(total));
|
|
|
-// //加预定房间数
|
|
|
-// stockDO.setBookNum(stockDO.getBookNum().add(total));
|
|
|
-// voyageStockMapper.updateById(stockDO);
|
|
|
-//
|
|
|
-// // 5.扣库存详情
|
|
|
-// Map<String, ReduceStockReqDTO.OrderDetailReqDTO> detailMap = CollectionUtils.convertMap(orderDetailList, item -> {
|
|
|
-// String key = item.getRoomModelId() + "_" + item.getFloor();
|
|
|
-// return key;
|
|
|
-// });
|
|
|
-// List<VoyageStockDetailDO> stockDetailList = voyageStockDetailMapper.selectListByVoyageId(voyageId);
|
|
|
-// List<VoyageStockDetailDO> updateDetailList = new ArrayList<>();
|
|
|
-// stockDetailList.stream().forEach(item -> {
|
|
|
-// String key = item.getRoomModelId() + "_" + item.getFloor();
|
|
|
-// ReduceStockReqDTO.OrderDetailReqDTO orderDetailReqDTO = detailMap.get(key);
|
|
|
-// BigDecimal num = orderDetailReqDTO.getNum();
|
|
|
-// if (orderDetailReqDTO != null) {
|
|
|
-// //判断可售房间数是否大于等于订单的房间数
|
|
|
-// if(item.getCanSellNum().compareTo(num) < 0) {
|
|
|
-// throw exception0(500,"房型楼层可售房间数不足");
|
|
|
-// }
|
|
|
-// //减虚拟房间数
|
|
|
-// if(item.getVirtualNum().compareTo(num) >= 0) {
|
|
|
-// item.setVirtualNum(item.getVirtualNum().subtract(num));
|
|
|
-// }else {
|
|
|
-// item.setVirtualNum(BigDecimal.ZERO);
|
|
|
-// // 加超卖房间数
|
|
|
-// item.setOversoldNum(item.getOversoldNum().add(num.subtract(item.getVirtualNum())));
|
|
|
-// }
|
|
|
-// //减可售房间数
|
|
|
-// item.setCanSellNum(item.getCanSellNum().subtract(num));
|
|
|
-// //加预定房间数
|
|
|
-// item.setBookNum(item.getBookNum().add(num));
|
|
|
-// updateDetailList.add(item);
|
|
|
-// }
|
|
|
-// });
|
|
|
-// voyageStockDetailMapper.updateBatch(updateDetailList);
|
|
|
+ distributeNewRespVOS.stream().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()));
|
|
|
+ }
|
|
|
+ });
|
|
|
+ // 扣分销商库存
|
|
|
+ // 库存充足,扣库存详情
|
|
|
+ distributeNewRespVOS.stream().forEach(item -> {
|
|
|
+ BigDecimal useNum = roomModelFloorNumMap.get(item.getRoomModelId() + "_" + item.getFloor());
|
|
|
+ if(useNum == null) {
|
|
|
+ useNum = BigDecimal.ZERO;
|
|
|
+ }
|
|
|
+ // 减可售房间数
|
|
|
+ item.setNum(item.getNum().subtract(useNum));
|
|
|
+ });
|
|
|
+ List<VoyageStockDistributeNewDO> list = BeanUtils.toBean(distributeNewRespVOS, VoyageStockDistributeNewDO.class);
|
|
|
+ voyageStockDistributeNewMapper.updateBatch(list);
|
|
|
+
|
|
|
+ // 库存充足,扣库存详情
|
|
|
+ stockDetailList.stream().forEach(item -> {
|
|
|
+ BigDecimal useNum = roomModelFloorNumMap.get(item.getRoomModelId() + "_" + item.getFloor());
|
|
|
+ if(useNum == null) {
|
|
|
+ useNum = BigDecimal.ZERO;
|
|
|
+ }
|
|
|
+ // 减可售房间数
|
|
|
+ item.setCanSellNum(item.getCanSellNum().subtract(useNum));
|
|
|
+ // 减剩余房间数
|
|
|
+ item.setSurplusNum(item.getSurplusNum().subtract(useNum));
|
|
|
+ // 减虚拟房间数,此处初定,先扣虚拟库存,虚拟库存不足再扣实际库存
|
|
|
+ if(item.getVirtualNum().compareTo(useNum) >= 0) {
|
|
|
+ item.setVirtualNum(item.getVirtualNum().subtract(useNum));
|
|
|
+ }else {
|
|
|
+ item.setVirtualNum(BigDecimal.ZERO);
|
|
|
+ // 扣实际房间数
|
|
|
+ item.setRealTotalNum(item.getRealTotalNum().subtract(useNum.subtract(item.getVirtualNum())));
|
|
|
+ }
|
|
|
+ // 加预定房间数
|
|
|
+ item.setBookNum(item.getBookNum().add(useNum));
|
|
|
+
|
|
|
+ });
|
|
|
+ voyageStockDetailMapper.updateBatch(stockDetailList);
|
|
|
+
|
|
|
+ // 扣总库存
|
|
|
+ // 减可售房间数
|
|
|
+ stockDO.setCanSellNum(stockDO.getCanSellNum().subtract(totalUseNum));
|
|
|
+ // 减剩余房间数
|
|
|
+ stockDO.setSurplusNum(stockDO.getSurplusNum().subtract(totalUseNum));
|
|
|
+ // 减虚拟房间数,此处初定,先扣虚拟库存,虚拟库存不足再扣实际库存
|
|
|
+ if(stockDO.getVirtualNum().compareTo(totalUseNum) >= 0) {
|
|
|
+ stockDO.setVirtualNum(stockDO.getVirtualNum().subtract(totalUseNum));
|
|
|
+ }else {
|
|
|
+ stockDO.setVirtualNum(BigDecimal.ZERO);
|
|
|
+ // 扣实际房间数
|
|
|
+ stockDO.setRealTotalNum(stockDO.getRealTotalNum().subtract(totalUseNum.subtract(stockDO.getVirtualNum())));
|
|
|
+ }
|
|
|
+ // 加预定房间数
|
|
|
+ stockDO.setBookNum(stockDO.getBookNum().add(totalUseNum));
|
|
|
+ // 扣共享库存
|
|
|
+ stockDO.setShareNum(stockDO.getShareNum().subtract(totalUseNum));
|
|
|
+ voyageStockMapper.updateById(stockDO);
|
|
|
+ }
|
|
|
}
|
|
|
}
|