diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/number/MoneyUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/number/MoneyUtils.java index dbc16dc86..90888d7d3 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/number/MoneyUtils.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/number/MoneyUtils.java @@ -18,6 +18,11 @@ public class MoneyUtils { */ private static final int PRICE_SCALE = 2; + /** + * 百分比对应的 BigDecimal 对象 + */ + public static final BigDecimal PERCENT_100 = BigDecimal.valueOf(100); + /** * 计算百分比金额,四舍五入 * @@ -107,4 +112,20 @@ public class MoneyUtils { return price.multiply(count).setScale(PRICE_SCALE, RoundingMode.HALF_UP); } + /** + * 金额相乘(百分比),默认进行四舍五入 + * + * 位数:{@link #PRICE_SCALE} + * + * @param price 金额 + * @param percent 百分比 + * @return 金额相乘结果 + */ + public static BigDecimal priceMultiplyPercent(BigDecimal price, BigDecimal percent) { + if (price == null || percent == null) { + return null; + } + return price.multiply(percent).divide(PERCENT_100, PRICE_SCALE, RoundingMode.HALF_UP); + } + } diff --git a/yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/stock/ErpStockRecordBizTypeEnum.java b/yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/stock/ErpStockRecordBizTypeEnum.java index 31129a2e4..01da541b9 100644 --- a/yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/stock/ErpStockRecordBizTypeEnum.java +++ b/yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/stock/ErpStockRecordBizTypeEnum.java @@ -30,6 +30,9 @@ public enum ErpStockRecordBizTypeEnum implements IntArrayValuable { CHECK_MORE_IN_CANCEL(41, "盘盈入库(作废)"), CHECK_LESS_OUT(42, "盘亏出库"), CHECK_LESS_OUT_CANCEL(43, "盘亏出库(作废)"), + + SALE_OUT(50, "销售出库"), + SALE_OUT_CANCEL(51, "销售出库(作废)"), ; public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ErpStockRecordBizTypeEnum::getType).toArray(); diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpSaleOrderServiceImpl.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpSaleOrderServiceImpl.java index c9945b5e4..fff5add14 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpSaleOrderServiceImpl.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpSaleOrderServiceImpl.java @@ -131,7 +131,7 @@ public class ErpSaleOrderServiceImpl implements ErpSaleOrderService { if (saleOrder.getDiscountPercent() == null) { saleOrder.setDiscountPercent(BigDecimal.ZERO); } - saleOrder.setDiscountPrice(MoneyUtils.priceMultiply(saleOrder.getTotalPrice(), saleOrder.getDiscountPercent())); + saleOrder.setDiscountPrice(MoneyUtils.priceMultiplyPercent(saleOrder.getTotalPrice(), saleOrder.getDiscountPercent())); saleOrder.setTotalPrice(saleOrder.getTotalPrice().subtract(saleOrder.getDiscountPrice())); } @@ -191,8 +191,11 @@ public class ErpSaleOrderServiceImpl implements ErpSaleOrderService { if (item.getTotalPrice() == null) { return; } - item.setTaxPrice(MoneyUtils.priceMultiply(item.getTotalPrice(), item.getTaxPercent())); - item.setTotalPrice(item.getTotalPrice().add(item.getTaxPrice())); + if (item.getTaxPercent() == null) { + item.setTaxPercent(BigDecimal.ZERO); + } else { + item.setTaxPrice(MoneyUtils.priceMultiplyPercent(item.getTotalPrice(), item.getTaxPercent())); + } })); } diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpSaleOutServiceImpl.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpSaleOutServiceImpl.java index 7f6ebc777..f0943d407 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpSaleOutServiceImpl.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpSaleOutServiceImpl.java @@ -15,8 +15,11 @@ import cn.iocoder.yudao.module.erp.dal.mysql.sale.ErpSaleOutItemMapper; import cn.iocoder.yudao.module.erp.dal.mysql.sale.ErpSaleOutMapper; import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO; import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus; +import cn.iocoder.yudao.module.erp.enums.stock.ErpStockRecordBizTypeEnum; import cn.iocoder.yudao.module.erp.service.finance.ErpAccountService; import cn.iocoder.yudao.module.erp.service.product.ErpProductService; +import cn.iocoder.yudao.module.erp.service.stock.ErpStockRecordService; +import cn.iocoder.yudao.module.erp.service.stock.bo.ErpStockRecordCreateReqBO; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import jakarta.annotation.Resource; import org.springframework.context.annotation.Lazy; @@ -60,6 +63,8 @@ public class ErpSaleOutServiceImpl implements ErpSaleOutService { private ErpSaleOrderService saleOrderService; @Resource private ErpAccountService accountService; + @Resource + private ErpStockRecordService stockRecordService; @Resource private AdminUserApi adminUserApi; @@ -142,8 +147,11 @@ public class ErpSaleOutServiceImpl implements ErpSaleOutService { if (saleOut.getDiscountPercent() == null) { saleOut.setDiscountPercent(BigDecimal.ZERO); } - saleOut.setDiscountPrice(MoneyUtils.priceMultiply(saleOut.getTotalPrice(), saleOut.getDiscountPercent())); + saleOut.setDiscountPrice(MoneyUtils.priceMultiplyPercent(saleOut.getTotalPrice(), saleOut.getDiscountPercent())); saleOut.setTotalPrice(saleOut.getTotalPrice().subtract(saleOut.getDiscountPrice())); + // 计算应收金额 + BigDecimal allPrice = saleOut.getTotalPrice().add(saleOut.getOtherPrice()); + saleOut.setDebtPrice(allPrice.subtract(saleOut.getPayPrice())); } private void updateSaleOrderOutCount(Long orderId) { @@ -173,6 +181,17 @@ public class ErpSaleOutServiceImpl implements ErpSaleOutService { if (updateCount == 0) { throw exception(approve ? SALE_OUT_APPROVE_FAIL : SALE_OUT_PROCESS_FAIL); } + + // 3. 变更库存 + List saleOutItems = saleOutItemMapper.selectListByOutId(id); + Integer bizType = approve ? ErpStockRecordBizTypeEnum.SALE_OUT.getType() + : ErpStockRecordBizTypeEnum.SALE_OUT_CANCEL.getType(); + saleOutItems.forEach(saleOutItem -> { + BigDecimal count = approve ? saleOutItem.getCount().negate() : saleOutItem.getCount(); + stockRecordService.createStockRecord(new ErpStockRecordCreateReqBO( + saleOutItem.getProductId(), saleOutItem.getWarehouseId(), count, + bizType, saleOutItem.getOutId(), saleOutItem.getId(), saleOut.getNo())); + }); } private List validateSaleOutItems(List list) { @@ -187,8 +206,11 @@ public class ErpSaleOutServiceImpl implements ErpSaleOutService { if (item.getTotalPrice() == null) { return; } - item.setTaxPrice(MoneyUtils.priceMultiply(item.getTotalPrice(), item.getTaxPercent())); - item.setTotalPrice(item.getTotalPrice().add(item.getTaxPrice())); + if (item.getTaxPercent() == null) { + item.setTaxPercent(BigDecimal.ZERO); + } else { + item.setTaxPrice(MoneyUtils.priceMultiplyPercent(item.getTotalPrice(), item.getTaxPercent())); + } })); }