From 07ba02f73c51f1e4d19619bb797fed87b6815daf Mon Sep 17 00:00:00 2001 From: ZhangYingJie Date: Fri, 18 Apr 2025 16:01:44 +0800 Subject: [PATCH] dev --- .../inventory/InventoryApplyService.java | 73 +++-- .../inventory/InventoryCheckService.java | 127 +++++++++ .../inventory/InventoryPurchaseService.java | 257 ++++++++++++++++++ .../service/inventory/InventoryService.java | 85 ++++++ 4 files changed, 503 insertions(+), 39 deletions(-) create mode 100644 src/main/java/com/syjiaer/clinic/server/service/inventory/InventoryCheckService.java create mode 100644 src/main/java/com/syjiaer/clinic/server/service/inventory/InventoryPurchaseService.java diff --git a/src/main/java/com/syjiaer/clinic/server/service/inventory/InventoryApplyService.java b/src/main/java/com/syjiaer/clinic/server/service/inventory/InventoryApplyService.java index 76f0ae4..96323ac 100644 --- a/src/main/java/com/syjiaer/clinic/server/service/inventory/InventoryApplyService.java +++ b/src/main/java/com/syjiaer/clinic/server/service/inventory/InventoryApplyService.java @@ -32,11 +32,17 @@ import java.util.Map; public class InventoryApplyService extends BaseService { @Autowired private InventoryService inventoryService; + @Autowired private InventoryLogMapper inventoryLogMapper; @Autowired private InventoryApplyMapper inventoryApplyMapper; @Autowired private InventoryApplyLogMapper inventoryApplyLogMapper; + /* + * 创建领用单 + * @param mapList + * @param useInfo 领用单信息 + */ @Transactional(rollbackFor = Exception.class) public void create(List mapList, InventoryApply useInfo) { ManagerUser user = getManagerUser(); @@ -79,6 +85,9 @@ public class InventoryApplyService extends BaseService { } } } + /* + * 生成领用单号 + */ private String getApplyCode() { return "LY"+ new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()); } @@ -86,43 +95,29 @@ public class InventoryApplyService extends BaseService { /** * 分页查询领用单 */ -// @RequestMapping("/list") -// public Result list() { -// ApplyOrderQuery query = parmsUtil.getObject("query", ApplyOrderQuery.class); -// if (query == null){ -// return error("没有带查询条件"); -// } -// QueryWrapper queryWrapper = new QueryWrapper<>(); -// if(query.getPageNum() == null || query.getPageNum() == 0){ -// query.setPageNum(1); -// } -// if (query.getPageSize() == null || query.getPageSize() == 0){ -// query.setPageSize(Constants.DetailPageSize); -// } -// long totalCount = iInventoryApplyService.count(queryWrapper); -// int totalPage = (int) Math.ceil((double) totalCount / query.getPageSize()); -// int offset = (query.getPageNum() - 1) * query.getPageSize(); -// Integer limit = query.getPageSize(); -// queryWrapper.orderByDesc("create_datetime"); -// queryWrapper.last("limit " + limit + " offset " + offset); -// Page page = new Page(); -// page.setTotal_count(totalCount); -// page.setTotal_page(totalPage); -// List inventoryApplies = iInventoryApplyService.list(queryWrapper); -// page.setList(inventoryApplies); -// return success(page); -// } -// -// /** -// * 获取领用单详情 -// */ -// @RequestMapping("/getApplyDetail") -// public Result getCheckDetail(){ -// Integer applyId = parmsUtil.getInteger("id", "id不能为空"); -// QueryWrapper queryWrapper=new QueryWrapper(); -// queryWrapper.eq("apply_id", applyId); -// InventoryApplyLog InventoryApplyLog = iInventoryApplyLogService.getOne(queryWrapper); -// return success(InventoryApplyLog.getData()); -// -// } + public Page list(int pageNum, int pageSize) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + long totalCount = inventoryApplyMapper.selectCount(queryWrapper); + int totalPage = (int) Math.ceil((double) totalCount / pageSize); + int offset = (pageNum - 1) * pageSize; + queryWrapper.orderByDesc("create_datetime"); + queryWrapper.last("limit " + pageSize + " offset " + offset); + Page page = new Page<>(); + page.setTotal_count(totalCount); + page.setTotal_page(totalPage); + List inventoryApplies = inventoryApplyMapper.selectList(queryWrapper); + page.setList(inventoryApplies); + return page; + } + + /** + * 获取领用单详情 + */ + public String getCheckDetail(int applyId){ + QueryWrapper queryWrapper=new QueryWrapper<>(); + queryWrapper.eq("apply_id", applyId); + InventoryApplyLog InventoryApplyLog = inventoryApplyLogMapper.selectOne(queryWrapper); + return InventoryApplyLog.getData(); + + } } diff --git a/src/main/java/com/syjiaer/clinic/server/service/inventory/InventoryCheckService.java b/src/main/java/com/syjiaer/clinic/server/service/inventory/InventoryCheckService.java new file mode 100644 index 0000000..e0f78f3 --- /dev/null +++ b/src/main/java/com/syjiaer/clinic/server/service/inventory/InventoryCheckService.java @@ -0,0 +1,127 @@ +package com.syjiaer.clinic.server.service.inventory; + +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.syjiaer.clinic.server.common.enums.InventorySocialTypeEnum; +import com.syjiaer.clinic.server.common.enums.InventoryTypeEnum; +import com.syjiaer.clinic.server.common.vo.Page; +import com.syjiaer.clinic.server.entity.inventory.InventoryCheck; +import com.syjiaer.clinic.server.entity.inventory.InventoryCheckLog; +import com.syjiaer.clinic.server.entity.inventory.InventoryLog; +import com.syjiaer.clinic.server.entity.manager.ManagerUser; +import com.syjiaer.clinic.server.mapper.inventory.InventoryCheckLogMapper; +import com.syjiaer.clinic.server.mapper.inventory.InventoryCheckMapper; +import com.syjiaer.clinic.server.mapper.inventory.InventoryLogMapper; +import com.syjiaer.clinic.server.service.BaseService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.util.Date; +import java.util.List; +import java.util.Map; + +@Service +public class InventoryCheckService extends BaseService { + @Autowired + private InventoryService inventoryService; + @Autowired + private InventoryLogMapper inventoryLogMapper; + @Autowired + private InventoryCheckMapper inventoryCheckMapper; + @Autowired + private InventoryCheckLogMapper inventoryCheckLogMapper; + public Page list(int pageNum, int pageSize) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + long totalCount = inventoryCheckMapper.selectCount(queryWrapper); + int totalPage = (int) Math.ceil((double) totalCount / pageSize); + int offset = (pageNum - 1) * pageSize; + queryWrapper.orderByDesc("id"); + queryWrapper.last("limit " + pageSize + " offset " + offset); + Page page = new Page<>(); + page.setTotal_count(totalCount); + page.setTotal_page(totalPage); + List inventorySuppliers = inventoryCheckMapper.selectList(queryWrapper); + page.setList(inventorySuppliers); + return page; + } + @Transactional + public void save(List list, String remark) { + ManagerUser user = getManagerUser(); + System.out.println(remark); + InventoryCheck inventoryCheck = new InventoryCheck(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); + String datePart = sdf.format(new Date()); + String code = "P" + datePart; + inventoryCheck.setCode(code); + inventoryCheck.setCreateDatetime(LocalDateTime.now()); + inventoryCheck.setState(1); + inventoryCheck.setRemark(remark); + inventoryCheckMapper.insert(inventoryCheck); + + InventoryCheckLog inventoryCheckLog = new InventoryCheckLog(); + inventoryCheckLog.setData(JSONObject.toJSONString(list)); + inventoryCheckLog.setInventoryCheckId(inventoryCheck.getId()); + inventoryCheckLogMapper.insert(inventoryCheckLog); + for (Map map : list) { + List children= (List) map.get("children"); + if(children.size()==0){ + int goodsId= (int) map.get("goodsId"); + Map after= (Map) map.get("after"); + List result = inventoryService.adjustNumberByGoodsId(goodsId,after.get("wholeNumber"),after.get("fragmentNumber"),"盘点"); + for (InventoryLog inventoryLog : result){ + if (inventoryLog.getChangeWholeNumber()<0 || inventoryLog.getChangeFragmentNumber()<0){ + inventoryLog.setOperateName(user.getName()); + inventoryLog.setOperateId(user.getId()); + inventoryLog.setType(InventoryTypeEnum.CHECK_OUT.getType()); + inventoryLog.setSocialType(InventorySocialTypeEnum.INVENTORY_LOSS.getType()); + }else { + inventoryLog.setOperateName(user.getName()); + inventoryLog.setOperateId(user.getId()); + inventoryLog.setType(InventoryTypeEnum.CHECK_IN.getType()); + inventoryLog.setSocialType(InventorySocialTypeEnum.INVENTORY_SURPLUS.getType()); + } + inventoryLogMapper.insert(inventoryLog); + } + }else{ + for (Map child : children) { + int id= (int) child.get("id"); + Map after= (Map) child.get("after"); + Map change= (Map) child.get("change"); + Integer changeWholeNumber=change.get("wholeNumber"); + Integer changeFragmentNumber=change.get("fragmentNumber"); + if (changeWholeNumber==0&&changeFragmentNumber==0){ + continue; + } + System.out.println(id); + System.out.println(after); + InventoryLog log = inventoryService.adjustNumber(id,after.get("wholeNumber"),after.get("fragmentNumber"),"盘点"); + if (log.getChangeWholeNumber()<0 || log.getChangeFragmentNumber()<0){ + log.setOperateName(user.getName()); + log.setOperateId(user.getId()); + log.setType(InventoryTypeEnum.CHECK_OUT.getType()); + log.setSocialType(InventorySocialTypeEnum.INVENTORY_LOSS.getType()); + }else { + log.setOperateName(user.getName()); + log.setOperateId(user.getId()); + log.setType(InventoryTypeEnum.CHECK_IN.getType()); + log.setSocialType(InventorySocialTypeEnum.INVENTORY_SURPLUS.getType()); + } + inventoryLogMapper.insert(log); + } + } + } + } + /** + * 获取盘点单详情 + */ + public String getCheckDetail(int checkId){ + QueryWrapper queryWrapper=new QueryWrapper(); + queryWrapper.eq("inventory_check_id", checkId); + InventoryCheckLog inventoryCheckLog = inventoryCheckLogMapper.selectOne(queryWrapper); + return inventoryCheckLog.getData(); + + } +} diff --git a/src/main/java/com/syjiaer/clinic/server/service/inventory/InventoryPurchaseService.java b/src/main/java/com/syjiaer/clinic/server/service/inventory/InventoryPurchaseService.java new file mode 100644 index 0000000..89107fa --- /dev/null +++ b/src/main/java/com/syjiaer/clinic/server/service/inventory/InventoryPurchaseService.java @@ -0,0 +1,257 @@ +package com.syjiaer.clinic.server.service.inventory; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.syjiaer.clinic.server.common.constants.Constants; +import com.syjiaer.clinic.server.common.enums.*; +import com.syjiaer.clinic.server.common.exception.MessageException; +import com.syjiaer.clinic.server.common.vo.Page; +import com.syjiaer.clinic.server.common.vo.Result; +import com.syjiaer.clinic.server.entity.goods.Goods; +import com.syjiaer.clinic.server.entity.inventory.*; +import com.syjiaer.clinic.server.mapper.goods.GoodsMapper; +import com.syjiaer.clinic.server.mapper.inventory.*; +import com.syjiaer.clinic.server.service.goods.GoodsService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.util.Date; +import java.util.List; + +@Service +public class InventoryPurchaseService { + @Autowired + private GoodsMapper goodsMapper; + @Autowired + private GoodsService goodsService; + @Autowired + private InventoryMapper inventoryMapper; + @Autowired + private InventoryLogMapper inventoryLogMapper; + @Autowired + private InventoryInitMapper inventoryInitMapper; + @Autowired + private InventoryPurchaseMapper inventoryPurchaseMapper; + @Autowired + private InventoryPurchaseLogMapper inventoryPurchaseLogMapper; + public void create(InventoryPurchase inventoryPurchase, List list) { + if (inventoryPurchase.getInvoiceCode() == null || inventoryPurchase.getInvoiceCode().isEmpty()) { + inventoryPurchase.setInvoiceCode("无"); + } + for (Inventory inventory_goods : list) { + if (inventory_goods.getWholeNumber() <= 0) { + throw new MessageException("[" + inventory_goods.getName() + "]采购数量不能小于等于0"); + } + if (inventory_goods.getPurchaseUnitPrice().compareTo(new BigDecimal(0)) <= 0) { + throw new MessageException("[" + inventory_goods.getName() + "]采购单价不能小于等于0"); + } + } + createOrder(inventoryPurchase, list); + } + public void createOrder(InventoryPurchase inventoryOrder, List list) { + //构造订单 + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); + String datePart = sdf.format(new Date()); + String code = Constants.IPurchaseCodePrefix + datePart; + inventoryOrder.setCode(code); + inventoryOrder.setCreateDatetime(LocalDateTime.now()); + inventoryOrder.setKindCount(list.size()); + BigDecimal total_price = new BigDecimal(0); + for (Inventory inventory : list) { + total_price = total_price.add(inventory.getPurchaseUnitPrice().multiply(new BigDecimal(inventory.getWholeNumber()))); + } + inventoryOrder.setTotalPrice(total_price); + inventoryPurchaseMapper.insert(inventoryOrder); + + for (Inventory inventory : list) { + //更新库存信息 + LocalDateTime now = LocalDateTime.now(); + inventory.setInventoryPurchaseCode(code); + inventory.setCreateDatetime(now); + inventory.setId(null); + + Goods goods = goodsMapper.selectById(inventory.getGoodId()); + if (goods == null) { + throw new RuntimeException("商品不存在"); + } + UploadStatusEnum uploadStatusEnum = UploadStatusEnum.NoUpload; + if(goods.getType().equals(GoodsTypeEnum.otherGoods.getType())){ + uploadStatusEnum = UploadStatusEnum.NotNeedUpload; + } + if (goods.getMinPackagingUnit() != null){ + BigDecimal fragmentPrice = inventory.getPurchaseUnitPrice(). + divide(new BigDecimal(goods.getMinPackagingNumber()), 6, RoundingMode.HALF_DOWN); + inventory.setFragmentPrice(fragmentPrice); + } + + + //判断库存是否需要初始化 + QueryWrapper inventoryWrapper = new QueryWrapper<>(); + inventoryWrapper.eq("good_id", inventory.getGoodId()); + List InventoryList = inventoryMapper.selectList(inventoryWrapper); + InventoryRefererTypeEnum refererTypeEnum = InventoryRefererTypeEnum.STORE; + InventorySocialTypeEnum type = InventorySocialTypeEnum.OTHER_INBOUND; + String remark = Constants.PurchaseInventory; + InventoryInit init = null; + if (InventoryList == null || InventoryList.isEmpty()){ + init = new InventoryInit(); + init.setGoodsId(goods.getId()); + init.setCode(code); + init.setWholeNumber(inventory.getWholeNumber()); + init.setFragmentNumber(inventory.getFragmentNumber()); + init.setCreateDate(now.toLocalDate()); + init.setUploadStatus(uploadStatusEnum.getStatus()); + refererTypeEnum = InventoryRefererTypeEnum.INIT; + type = InventorySocialTypeEnum.INITIAL_INBOUND; + remark = Constants.InitInventory; + } + inventory.setRefererType(refererTypeEnum.getType()); + inventoryMapper.insert(inventory); + if(init != null){ + init.setInventoryId(inventory.getId()); + inventoryInitMapper.insert(init); + } + + + //更新库存日志 + InventoryLog inventoryLog = new InventoryLog(); + inventoryLog.setInventoryId(inventory.getId()); + inventoryLog.setGoodsId(inventory.getGoodId()); + inventoryLog.setChangeWholeNumber(inventory.getWholeNumber()); + inventoryLog.setAfterWholeNumber(inventory.getWholeNumber()); + inventoryLog.setCreateTime(now); + inventoryLog.setRemark(remark); + inventoryLog.setUploadStatus(uploadStatusEnum.getStatus()); + inventoryLog.setSocialType(type.getType()); + if (init != null){ + inventoryLog.setType(InventoryTypeEnum.INIT.getType()); + }else { + inventoryLog.setType(InventoryTypeEnum.PURCHASE_IN.getType()); + } + inventoryLogMapper.insert(inventoryLog); + + //更新订单日志 + InventoryPurchaseLog inventoryPurchaseLog = new InventoryPurchaseLog(); + inventoryPurchaseLog.setInventoryPurchaseCode(code); + inventoryPurchaseLog.setSocialType(type.getType()); + inventoryPurchaseLog.setNumber(inventory.getWholeNumber()); + UploadStatusEnum pUploadStatusEnum = uploadStatusEnum; + if (type.equals(InventorySocialTypeEnum.INITIAL_INBOUND)){ + pUploadStatusEnum = UploadStatusEnum.NotNeedUpload; + } + //初始化上报不走这个表上报 标记为无需上报 + inventoryPurchaseLog.setUploadStatus(pUploadStatusEnum.getStatus()); + inventoryPurchaseLog.setInventoryId(inventory.getId()); + inventoryPurchaseLogMapper.insert(inventoryPurchaseLog); + + //更新商品数量盒最近进货价格goods表信息 + goodsService.updateInventoryInfoById(inventory.getGoodId()); + } + } +// public Page<> list(int pageNum, int pageSize) { +// QueryWrapper queryWrapper = new QueryWrapper<>(); +// if (query.getPageNum() == null || query.getPageNum() == 0) { +// query.setPageNum(1); +// } +// if (query.getPageSize() == null || query.getPageSize() == 0) { +// query.setPageSize(Constants.DetailPageSize); +// } +// long totalCount = iInventoryPurchaseViewService.count(queryWrapper); +// int totalPage = (int) Math.ceil((double) totalCount / query.getPageSize()); +// int offset = (query.getPageNum() - 1) * query.getPageSize(); +// Integer limit = query.getPageSize(); +// queryWrapper.orderByDesc("create_datetime"); +// queryWrapper.last("limit " + limit + " offset " + offset); +// Page page = new Page(); +// page.setTotal_count(totalCount); +// page.setTotal_page(totalPage); +// List InventoryPurchaseView = iInventoryPurchaseViewService.list(queryWrapper); +// page.setList(InventoryPurchaseView); +// return success(page); +// } + public void addOneGoods(Inventory inventory) { + QueryWrapper orderWrapper = new QueryWrapper(); + orderWrapper.eq("code", inventory.getInventoryPurchaseCode()); + LocalDateTime now = LocalDateTime.now(); + InventoryPurchase inventoryOrder = inventoryPurchaseMapper.selectOne(orderWrapper); + if (inventoryOrder == null) { + throw new MessageException("订单不存在"); + } + //更新订单信息 + BigDecimal totalPrice = inventoryOrder.getTotalPrice(). + add(inventory.getPurchaseUnitPrice(). + multiply(new BigDecimal(inventory.getWholeNumber()))); + UpdateWrapper updateOrder = new UpdateWrapper(); + updateOrder.set("total_price", totalPrice); + updateOrder.set("kind_count", inventoryOrder.getKindCount() + 1); + updateOrder.eq("code", inventory.getInventoryPurchaseCode()); + inventoryPurchaseMapper.update(updateOrder); + //更新库存信息 + Goods dbGoods = goodsMapper.selectById(inventory.getGoodId()); + UploadStatusEnum uploadStatusEnum = UploadStatusEnum.NoUpload; + if(dbGoods.getType().equals(GoodsTypeEnum.otherGoods.getType())){ + uploadStatusEnum = UploadStatusEnum.NotNeedUpload; + } + BigDecimal fragmentPrice = inventory.getPurchaseUnitPrice(). + divide(new BigDecimal(dbGoods.getMinPackagingNumber()), 6, RoundingMode.HALF_DOWN); + inventory.setFragmentPrice(fragmentPrice); + inventory.setCreateDatetime(now); + QueryWrapper inventoryWrapper = new QueryWrapper(); + inventoryWrapper.eq("good_id", inventory.getGoodId()); + List InventoryList = inventoryMapper.selectList(inventoryWrapper); + InventoryRefererTypeEnum refererTypeEnum = InventoryRefererTypeEnum.STORE; + InventorySocialTypeEnum type = InventorySocialTypeEnum.OTHER_INBOUND; + String remark = Constants.PurchaseInventory; + InventoryInit init = null; + if (InventoryList == null || InventoryList.isEmpty()){ + init = new InventoryInit(); + init.setGoodsId(inventory.getGoodId()); + init.setCode(inventory.getProductionBatchCode()); + init.setWholeNumber(inventory.getWholeNumber()); + init.setFragmentNumber(inventory.getFragmentNumber()); + init.setCreateDate(now.toLocalDate()); + init.setUploadStatus(uploadStatusEnum.getStatus()); + refererTypeEnum = InventoryRefererTypeEnum.INIT; + type = InventorySocialTypeEnum.INITIAL_INBOUND; + remark = Constants.InitInventory; + } + inventory.setRefererType(refererTypeEnum.getType()); + inventoryMapper.insert(inventory); + if(init != null){ + init.setInventoryId(inventory.getId()); + inventoryInitMapper.insert(init); + } + //更新库存日志 + InventoryLog inventoryLog = new InventoryLog(); + inventoryLog.setInventoryId(inventory.getId()); + inventoryLog.setGoodsId(inventory.getGoodId()); + inventoryLog.setSocialType(InventorySocialTypeEnum.INITIAL_INBOUND.getType()); + inventoryLog.setChangeWholeNumber(inventory.getWholeNumber()); + inventoryLog.setAfterWholeNumber(inventory.getWholeNumber()); + inventoryLog.setCreateTime(now); + inventoryLog.setRemark(remark); + inventoryLog.setUploadStatus(uploadStatusEnum.getStatus()); + inventoryLog.setSocialType(type.getType()); + inventoryLogMapper.insert(inventoryLog); + InventoryPurchaseLog inventoryPurchaseLog = new InventoryPurchaseLog(); + inventoryPurchaseLog.setInventoryPurchaseCode(inventory.getInventoryPurchaseCode()); + inventoryPurchaseLog.setInventoryId(inventory.getId()); + inventoryPurchaseLog.setNumber(inventory.getWholeNumber()); + inventoryPurchaseLog.setSocialType(type.getType()); + UploadStatusEnum pUploadStatusEnum = uploadStatusEnum; + if (type.equals(InventorySocialTypeEnum.INITIAL_INBOUND)){ + pUploadStatusEnum = UploadStatusEnum.NotNeedUpload; + } + //初始化上报不走这个表上报 标记为无需上报 + inventoryPurchaseLog.setUploadStatus(pUploadStatusEnum.getStatus()); + inventoryPurchaseLogMapper.insert(inventoryPurchaseLog); + + //更新商品信息 + goodsService.updateInventoryInfoById(inventory.getGoodId()); + + } +} diff --git a/src/main/java/com/syjiaer/clinic/server/service/inventory/InventoryService.java b/src/main/java/com/syjiaer/clinic/server/service/inventory/InventoryService.java index 53949a0..8d9b973 100644 --- a/src/main/java/com/syjiaer/clinic/server/service/inventory/InventoryService.java +++ b/src/main/java/com/syjiaer/clinic/server/service/inventory/InventoryService.java @@ -447,4 +447,89 @@ public class InventoryService extends BaseService { goodsService.updateInventoryInfoById(goods.getId()); return log; } + public List adjustNumberByGoodsId(Integer goodsId, Integer finalWholeNumber, Integer finalFragmentNumber, String remark) { + Goods goods = goodsMapper.selectById(goodsId); + Map totalMap = totalNumber(goodsId); + //获取总库并校验是否充足 + int totalFragment = totalMap.get("totalFragment"); + //计算最终库存到拆零单位 + int finalTotalFragment = finalWholeNumber * goods.getMinPackagingNumber() + finalFragmentNumber; + //不可以将最终库存设为负数 + if (finalWholeNumber < 0 || finalFragmentNumber < 0) { + throw new MessageException("[" + goods.getName() + "]不可以调整为负库存"); + } + int minPackaging = goods.getMinPackagingNumber(); + int changeTocalFragment = finalTotalFragment - totalFragment; + int changeFragment = changeTocalFragment % minPackaging; + int changeWhole = changeTocalFragment / minPackaging; + while (changeWhole < 0 && changeFragment > 0) { + changeFragment = changeFragment - minPackaging; + changeWhole = changeWhole + 1; + } + while (changeWhole > 0 && changeFragment < 0) { + changeFragment = changeFragment + minPackaging; + changeWhole = changeWhole - 1; + } + List list = new ArrayList<>(); + if (changeTocalFragment > 0) { + Inventory inventory = inventoryMapper.selectOne(new QueryWrapper() + .eq("good_id", goodsId) + .orderByDesc("create_datetime").last("limit 1")); + + list.add(this.changeNumber(inventory.getId(), Type.IN, changeWhole, changeFragment, remark)); + } else { + changeFragment = -changeFragment; + changeWhole = -changeWhole; + list = this.outByGoodsId(goodsId, changeWhole, changeFragment, remark); + } + return list; + } + public List outByGoodsId(Integer goodsId, Integer changeWholeNumber, Integer changeFragmentNumber, String remark) { + // 1. 获取商品信息和总库存 + Goods goods = goodsMapper.selectById(goodsId); + Map totalMap = this.totalNumber(goodsId); + // 2. 获取总库并校验是否充足 + int totalAvailable = totalMap.get("totalFragment"); + int requiredTotalFragment = changeWholeNumber * goods.getMinPackagingNumber() + changeFragmentNumber; + if (totalAvailable < requiredTotalFragment) { + throw new MessageException(goods.getName() + "库存不足,需要:" + + requiredTotalFragment + " 可用:" + totalAvailable); + } + + // 3. 按创建时间倒序获取库存记录 + List inventories = inventoryMapper.selectList(new QueryWrapper() + .eq("good_id", goodsId) + .orderByAsc("create_datetime")); + List result = new ArrayList<>(); + // 4. 逐个处理库存记录 + for (Inventory inv : inventories) { + if (requiredTotalFragment <= 0) break; + + // 计算当前库存的拆零总数 + int currentTotal = inv.getWholeNumber() * goods.getMinPackagingNumber() + + inv.getFragmentNumber(); + + // 跳过空库存 + if (currentTotal <= 0) continue; + + // 计算本次实际扣除量 + int deduct = Math.min(currentTotal, requiredTotalFragment); + + // 转换为整件+拆零的扣除方式 + int deductWhole = deduct / goods.getMinPackagingNumber(); + int deductFragment = deduct % goods.getMinPackagingNumber(); + + // 调用现有方法执行出库 + result.add(this.changeNumber(inv.getId(), Type.OUT, deductWhole, deductFragment, remark)); + + // 更新剩余需要扣除量 + requiredTotalFragment -= deduct; + } + + // 5. 最终校验(应对并发场景) + if (requiredTotalFragment > 0) { + throw new MessageException("部分库存已被占用,剩余需出库:" + requiredTotalFragment); + } + return result; + } }