From 2d8f120303947768741fc2b61525bf58e8d09bb9 Mon Sep 17 00:00:00 2001 From: Tankaikai Date: Mon, 24 Feb 2025 14:07:42 +0800 Subject: [PATCH] =?UTF-8?q?=E5=95=86=E5=93=81=E6=A8=A1=E5=9D=97=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/ConsStockFlowController.java | 80 +++++++++ .../com/czg/product/dto/ConsStockFlowDTO.java | 126 ++++++++++++++ .../com/czg/product/entity/ConsStockFlow.java | 130 ++++++++++++++ .../com/czg/product/enums/InOutItemEnum.java | 50 ++++++ .../com/czg/product/enums/InOutTypeEnum.java | 30 ++++ .../product/param/ConsCheckStockParam.java | 58 +++++++ .../param/ConsInOutStockBodyParam.java | 56 ++++++ .../param/ConsInOutStockHeadParam.java | 60 +++++++ .../product/service/ConsStockFlowService.java | 49 ++++++ .../product/vo/ConsCheckStockRecordVo.java | 73 ++++++++ .../czg/product/vo/ShopProductSkuInfoVo.java | 2 +- .../product/mapper/ConsStockFlowMapper.java | 16 ++ .../impl/ConsStockFlowServiceImpl.java | 164 ++++++++++++++++++ .../impl/ProdConsRelationServiceImpl.java | 4 +- .../resources/mapper/ConsStockFlowMapper.xml | 6 + 15 files changed, 901 insertions(+), 3 deletions(-) create mode 100644 cash-api/product-server/src/main/java/com/czg/controller/admin/ConsStockFlowController.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/product/dto/ConsStockFlowDTO.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/product/entity/ConsStockFlow.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/product/enums/InOutItemEnum.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/product/enums/InOutTypeEnum.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/product/param/ConsCheckStockParam.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/product/param/ConsInOutStockBodyParam.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/product/param/ConsInOutStockHeadParam.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/product/service/ConsStockFlowService.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/product/vo/ConsCheckStockRecordVo.java create mode 100644 cash-service/product-service/src/main/java/com/czg/service/product/mapper/ConsStockFlowMapper.java create mode 100644 cash-service/product-service/src/main/java/com/czg/service/product/service/impl/ConsStockFlowServiceImpl.java create mode 100644 cash-service/product-service/src/main/resources/mapper/ConsStockFlowMapper.xml diff --git a/cash-api/product-server/src/main/java/com/czg/controller/admin/ConsStockFlowController.java b/cash-api/product-server/src/main/java/com/czg/controller/admin/ConsStockFlowController.java new file mode 100644 index 00000000..9a237081 --- /dev/null +++ b/cash-api/product-server/src/main/java/com/czg/controller/admin/ConsStockFlowController.java @@ -0,0 +1,80 @@ +package com.czg.controller.admin; + +import com.czg.log.annotation.OperationLog; +import com.czg.product.param.ConsCheckStockParam; +import com.czg.product.param.ConsInOutStockHeadParam; +import com.czg.product.service.ConsStockFlowService; +import com.czg.product.vo.ConsCheckStockRecordVo; +import com.czg.resp.CzgResult; +import com.czg.utils.AssertUtil; +import com.czg.validator.ValidatorUtil; +import com.czg.validator.group.DefaultGroup; +import lombok.AllArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + + +/** + * 耗材进销存 + * + * @author Tankaikai tankaikai@aliyun.com + * @since 1.0 2025-02-21 + */ +@AllArgsConstructor +@RestController +@RequestMapping("/admin/product/stock") +public class ConsStockFlowController { + private final ConsStockFlowService consStockFlowService; + + /** + * 耗材入库 + */ + @PostMapping("in") + @OperationLog("耗材入库") + //@SaAdminCheckPermission("consStockFlow:in") + public CzgResult inStock(@RequestBody ConsInOutStockHeadParam param) { + ValidatorUtil.validateEntity(param, DefaultGroup.class); + ValidatorUtil.validateEntity(param.getBodyList(), DefaultGroup.class); + consStockFlowService.inStock(param); + return CzgResult.success(); + } + + /** + * 耗材出库 + */ + @PostMapping("out") + @OperationLog("耗材出库") + //@SaAdminCheckPermission("consStockFlow:out") + public CzgResult outStock(@RequestBody ConsInOutStockHeadParam param) { + ValidatorUtil.validateEntity(param, DefaultGroup.class); + ValidatorUtil.validateEntity(param.getBodyList(), DefaultGroup.class); + consStockFlowService.outStock(param); + return CzgResult.success(); + } + + /** + * 库存盘点记录 + * param conId 耗材ID + */ + @GetMapping("check-record") + @OperationLog("库存盘点记录") + //@SaAdminCheckPermission("consStockFlow:check-record") + public CzgResult> checkStock(@RequestParam Long conId) { + AssertUtil.isNull(conId, "耗材ID不能为空"); + List data = consStockFlowService.getCheckStockRecordList(conId); + return CzgResult.success(data); + } + + /** + * 库存盘点 + */ + @PostMapping("check") + @OperationLog("库存盘点") + //@SaAdminCheckPermission("consStockFlow:check") + public CzgResult checkStock(@RequestBody ConsCheckStockParam param) { + ValidatorUtil.validateEntity(param, DefaultGroup.class); + consStockFlowService.checkStock(param); + return CzgResult.success(); + } +} \ No newline at end of file diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ConsStockFlowDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ConsStockFlowDTO.java new file mode 100644 index 00000000..6ac84a39 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/dto/ConsStockFlowDTO.java @@ -0,0 +1,126 @@ +package com.czg.product.dto; + +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; + +/** + * 耗材库存变动记录 + * + * @author Tankaikai tankaikai@aliyun.com + * @since 1.0 2025-02-21 + */ +@Data +public class ConsStockFlowDTO implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * id + */ + private Long id; + /** + * 店铺id + */ + private Long shopId; + /** + * 供应商id + */ + private Long vendorId; + /** + * 出入库类型 in-入库 out-出库 + */ + private String inOutType; + /** + * 出入库名目 manual-in:手动入库 manual-out:手动出库 win-in:盘盈入库 loss-out:盘亏出库 order-in:订单退款入库 order-out:订单消费出库 + */ + private String inOutItem; + /** + * 出入库日期 + */ + private LocalDate inOutDate; + /** + * 应付金额 + */ + private BigDecimal amountPayable; + /** + * 实付金额 + */ + private BigDecimal actualPaymentAmount; + /** + * 付款日期 + */ + private LocalDate paymentDate; + /** + * 批次号 + */ + private String batchNo; + /** + * 耗材名称 + */ + private String conName; + /** + * 采购价/进价 + */ + private BigDecimal purchasePrice; + /** + * 耗材id + */ + private Long conId; + /** + * 单位 + */ + private String unitName; + /** + * 变动前的库存 + */ + private BigDecimal beforeNumber; + /** + * 出入库数量 + */ + private BigDecimal inOutNumber; + /** + * 变动后的库存 + */ + private BigDecimal afterNumber; + /** + * 小计 + */ + private BigDecimal subTotal; + /** + * 商品id + */ + private Long productId; + /** + * sku id + */ + private Long skuId; + /** + * 商品订单id + */ + private Long orderId; + /** + * 创建人id + */ + private Long createUserId; + /** + * 创建人name + */ + private String createUserName; + /** + * 创建时间 + */ + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime createTime; + /** + * 备注 + */ + private String remark; + +} \ No newline at end of file diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ConsStockFlow.java b/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ConsStockFlow.java new file mode 100644 index 00000000..bba81d38 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/entity/ConsStockFlow.java @@ -0,0 +1,130 @@ +package com.czg.product.entity; + +import com.mybatisflex.annotation.Column; +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.KeyType; +import com.mybatisflex.annotation.Table; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; + +/** + * 耗材库存变动记录 + * + * @author Tankaikai tankaikai@aliyun.com + * @since 1.0 2025-02-21 + */ +@Data +@Table("tb_cons_stock_flow") +public class ConsStockFlow implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * id + */ + @Id(keyType = KeyType.Auto) + private Long id; + /** + * 店铺id + */ + private Long shopId; + /** + * 供应商id + */ + private Long vendorId; + /** + * 出入库类型 in-入库 out-出库 + */ + private String inOutType; + /** + * 出入库名目 manual-in:手动入库 manual-out:手动出库 win-in:盘盈入库 loss-out:盘亏出库 order-in:订单退款入库 order-out:订单消费出库 + */ + private String inOutItem; + /** + * 出入库日期 + */ + private LocalDate inOutDate; + /** + * 应付金额 + */ + private BigDecimal amountPayable; + /** + * 实付金额 + */ + private BigDecimal actualPaymentAmount; + /** + * 付款日期 + */ + private LocalDate paymentDate; + /** + * 批次号 + */ + private String batchNo; + /** + * 耗材id + */ + private Long conId; + /** + * 耗材名称 + */ + private String conName; + /** + * 采购价/进价 + */ + private BigDecimal purchasePrice; + /** + * 单位 + */ + private String unitName; + /** + * 变动前的库存 + */ + private BigDecimal beforeNumber; + /** + * 出入库数量 + */ + private BigDecimal inOutNumber; + /** + * 变动后的库存 + */ + private BigDecimal afterNumber; + /** + * 小计 + */ + private BigDecimal subTotal; + /** + * 商品id + */ + private Long productId; + /** + * sku id + */ + private Long skuId; + /** + * 商品订单id + */ + private Long orderId; + /** + * 创建人id + */ + private Long createUserId; + /** + * 创建人name + */ + private String createUserName; + /** + * 创建时间 + */ + @Column(onInsertValue = "now()") + private LocalDateTime createTime; + /** + * 备注 + */ + private String remark; +} \ No newline at end of file diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/enums/InOutItemEnum.java b/cash-common/cash-common-service/src/main/java/com/czg/product/enums/InOutItemEnum.java new file mode 100644 index 00000000..f9d6b8ce --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/enums/InOutItemEnum.java @@ -0,0 +1,50 @@ +package com.czg.product.enums; + +/** + * 出入库名目枚举 + * + * @author tankaikai + * @since 2025-02-24 09:54 + */ +public enum InOutItemEnum { + + /** + * 手动入库 + */ + MANUAL_IN("manual-in"), + + /** + * 手动出库 + */ + MANUAL_OUT("manual-out"), + + /** + * 盘盈入库 + */ + WIN_IN("win-in"), + + /** + * 盘亏出库 + */ + LOSS_OUT("loss-out"), + + /** + * 订单退款入库 + */ + ORDER_IN("order-in"), + + /** + * 订单消费出库 + */ + ORDER_OUT("order-out"); + + private String value; + + InOutItemEnum(String value) { + this.value = value; + } + + public String value() { + return this.value; + } +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/enums/InOutTypeEnum.java b/cash-common/cash-common-service/src/main/java/com/czg/product/enums/InOutTypeEnum.java new file mode 100644 index 00000000..1b317e58 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/enums/InOutTypeEnum.java @@ -0,0 +1,30 @@ +package com.czg.product.enums; + +/** + * 出入库类型枚举 + * + * @author tankaikai + * @since 2025-02-24 09:54 + */ +public enum InOutTypeEnum { + + /** + * 入库 + */ + IN("in"), + + /** + * 出库 + */ + OUT("out"); + + private String value; + + InOutTypeEnum(String value) { + this.value = value; + } + + public String value() { + return this.value; + } +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/param/ConsCheckStockParam.java b/cash-common/cash-common-service/src/main/java/com/czg/product/param/ConsCheckStockParam.java new file mode 100644 index 00000000..b02ee464 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/param/ConsCheckStockParam.java @@ -0,0 +1,58 @@ +package com.czg.product.param; + +import com.czg.validator.group.DefaultGroup; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 库存盘点入参 + * + * @author Tankaikai tankaikai@aliyun.com + * @since 1.0 2025-02-20 + */ +@Data +public class ConsCheckStockParam implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 耗材id + */ + @NotNull(message = "耗材id不能为空", groups = DefaultGroup.class) + private Long conId; + /** + * 耗材名称 + */ + @NotBlank(message = "耗材名称不能为空", groups = DefaultGroup.class) + private String conName; + /** + * 账存数量 + */ + @NotNull(message = "账存数量不能为空", groups = DefaultGroup.class) + private BigDecimal stockNumber; + /** + * 实际数量 + */ + @NotNull(message = "实际数量不能为空", groups = DefaultGroup.class) + private BigDecimal actualNumber; + /** + * 盈亏数量 + */ + @NotNull(message = "盈亏数量不能为空", groups = DefaultGroup.class) + private BigDecimal winLossNumber; + /** + * 单价 + */ + @NotNull(message = "单价不能为空", groups = DefaultGroup.class) + private BigDecimal price; + /** + * 备注 + */ + private String remark; +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/param/ConsInOutStockBodyParam.java b/cash-common/cash-common-service/src/main/java/com/czg/product/param/ConsInOutStockBodyParam.java new file mode 100644 index 00000000..c64709d4 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/param/ConsInOutStockBodyParam.java @@ -0,0 +1,56 @@ +package com.czg.product.param; + +import com.czg.validator.group.DefaultGroup; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 出入库耗材入参 + * + * @author Tankaikai tankaikai@aliyun.com + * @since 1.0 2025-02-20 + */ +@Data +public class ConsInOutStockBodyParam implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 耗材id + */ + @NotNull(message = "耗材id不能为空", groups = DefaultGroup.class) + private String conId; + /** + * 耗材名称 + */ + @NotBlank(message = "耗材名称不能为空", groups = DefaultGroup.class) + private String conName; + /** + * 采购价/进价 + */ + @NotNull(message = "进价不能为空", groups = DefaultGroup.class) + private BigDecimal purchasePrice; + /** + * 单位 + */ + @NotBlank(message = "单位不能为空", groups = DefaultGroup.class) + private String unitName; + /** + * 出入库数量 + */ + @NotNull(message = "数量不能为空", groups = DefaultGroup.class) + @Min(value = 0, message = "数量不能小于0") + private BigDecimal inOutNumber; + /** + * 小计 + */ + @NotNull(message = "小计不能为空", groups = DefaultGroup.class) + private BigDecimal subTotal; +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/param/ConsInOutStockHeadParam.java b/cash-common/cash-common-service/src/main/java/com/czg/product/param/ConsInOutStockHeadParam.java new file mode 100644 index 00000000..1bf91e83 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/param/ConsInOutStockHeadParam.java @@ -0,0 +1,60 @@ +package com.czg.product.param; + +import com.alibaba.fastjson2.annotation.JSONField; +import com.czg.validator.group.DefaultGroup; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.List; + +/** + * 出入库入参 + * + * @author Tankaikai tankaikai@aliyun.com + * @since 1.0 2025-02-20 + */ +@Data +public class ConsInOutStockHeadParam implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 供应商id + */ + private Long vendorId; + /** + * 出入库日期 + */ + @NotNull(message = "出入库日期不能为空", groups = DefaultGroup.class) + @JSONField(format = "yyyy-MM-dd") + private LocalDate inOutDate; + /** + * 应付金额 + */ + private BigDecimal amountPayable; + /** + * 实付金额 + */ + private BigDecimal actualPaymentAmount; + /** + * 付款日期 + */ + private LocalDate paymentDate; + /** + * 批次号 + */ + private String batchNo; + /** + * 备注 + */ + private String remark; + /** + * 耗材明细列表 + */ + List bodyList; +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/service/ConsStockFlowService.java b/cash-common/cash-common-service/src/main/java/com/czg/product/service/ConsStockFlowService.java new file mode 100644 index 00000000..6e8f6107 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/service/ConsStockFlowService.java @@ -0,0 +1,49 @@ +package com.czg.product.service; + +import com.czg.product.entity.ConsStockFlow; +import com.czg.product.param.ConsCheckStockParam; +import com.czg.product.param.ConsInOutStockHeadParam; +import com.czg.product.vo.ConsCheckStockRecordVo; +import com.mybatisflex.core.service.IService; + +import java.util.List; + +/** + * 耗材库存变动记录 + * + * @author Tankaikai tankaikai@aliyun.com + * @since 1.0 2025-02-21 + */ +public interface ConsStockFlowService extends IService { + + /** + * 手动入库 + * + * @param param 手动出库入参 + */ + void inStock(ConsInOutStockHeadParam param); + + /** + * 手动出库 + * + * @param param 手动出库入参 + */ + void outStock(ConsInOutStockHeadParam param); + + /** + * 库存盘点 + * + * @param param 库存盘点入参 + */ + void checkStock(ConsCheckStockParam param); + + /** + * 获取盘点记录 + * + * @param conId 耗材id + * @return 盘点记录列表 + */ + List getCheckStockRecordList(Long conId); + + +} \ No newline at end of file diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/vo/ConsCheckStockRecordVo.java b/cash-common/cash-common-service/src/main/java/com/czg/product/vo/ConsCheckStockRecordVo.java new file mode 100644 index 00000000..ae240ecb --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/vo/ConsCheckStockRecordVo.java @@ -0,0 +1,73 @@ +package com.czg.product.vo; + +import cn.hutool.core.util.NumberUtil; +import com.alibaba.fastjson2.annotation.JSONField; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * 库存盘点记录 + * + * @author tankaikai + * @since 2025-02-24 13:40 + */ +@Data +public class ConsCheckStockRecordVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + /** + * 耗材id + */ + private Long conId; + /** + * 耗材名称 + */ + private String conName; + /** + * 单价 + */ + private BigDecimal purchasePrice; + /** + * 账存数量 + */ + private BigDecimal beforeNumber; + /** + * 盈亏数量 + */ + private BigDecimal inOutNumber; + /** + * 盘点后的数量 + */ + @JSONField(serialize = false) + private BigDecimal afterNumber; + /** + * 盈亏金额 + */ + private BigDecimal winLossAmount; + /** + * 实际库存 + */ + private BigDecimal actualNumber; + /** + * 盘点时间 + */ + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime createTime; + /** + * 备注 + */ + private String remark; + + public BigDecimal getWinLossAmount() { + return NumberUtil.mul(purchasePrice, purchasePrice); + } + + public BigDecimal getActualNumber() { + return afterNumber; + } +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/product/vo/ShopProductSkuInfoVo.java b/cash-common/cash-common-service/src/main/java/com/czg/product/vo/ShopProductSkuInfoVo.java index 79cc436d..04f0a525 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/product/vo/ShopProductSkuInfoVo.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/product/vo/ShopProductSkuInfoVo.java @@ -19,7 +19,7 @@ public class ShopProductSkuInfoVo implements Serializable { private static final long serialVersionUID = 1L; /** - * id + * sku-id */ private Long id; /** diff --git a/cash-service/product-service/src/main/java/com/czg/service/product/mapper/ConsStockFlowMapper.java b/cash-service/product-service/src/main/java/com/czg/service/product/mapper/ConsStockFlowMapper.java new file mode 100644 index 00000000..4e16671f --- /dev/null +++ b/cash-service/product-service/src/main/java/com/czg/service/product/mapper/ConsStockFlowMapper.java @@ -0,0 +1,16 @@ +package com.czg.service.product.mapper; + +import com.czg.product.entity.ConsStockFlow; +import com.mybatisflex.core.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * 耗材库存变动记录 + * + * @author Tankaikai tankaikai@aliyun.com + * @since 1.0 2025-02-21 + */ +@Mapper +public interface ConsStockFlowMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/cash-service/product-service/src/main/java/com/czg/service/product/service/impl/ConsStockFlowServiceImpl.java b/cash-service/product-service/src/main/java/com/czg/service/product/service/impl/ConsStockFlowServiceImpl.java new file mode 100644 index 00000000..ffd7fc74 --- /dev/null +++ b/cash-service/product-service/src/main/java/com/czg/service/product/service/impl/ConsStockFlowServiceImpl.java @@ -0,0 +1,164 @@ +package com.czg.service.product.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.bean.copier.CopyOptions; +import cn.hutool.core.util.NumberUtil; +import cn.hutool.core.util.StrUtil; +import com.czg.exception.CzgException; +import com.czg.product.dto.ConsStockFlowDTO; +import com.czg.product.entity.ConsInfo; +import com.czg.product.entity.ConsStockFlow; +import com.czg.product.enums.InOutItemEnum; +import com.czg.product.enums.InOutTypeEnum; +import com.czg.product.param.ConsCheckStockParam; +import com.czg.product.param.ConsInOutStockHeadParam; +import com.czg.product.service.ConsStockFlowService; +import com.czg.product.vo.ConsCheckStockRecordVo; +import com.czg.sa.StpKit; +import com.czg.service.product.mapper.ConsInfoMapper; +import com.czg.service.product.mapper.ConsStockFlowMapper; +import com.czg.utils.PageUtil; +import com.mybatisflex.core.query.QueryWrapper; +import com.mybatisflex.spring.service.impl.ServiceImpl; +import lombok.AllArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +/** + * 耗材库存变动记录 + * + * @author Tankaikai tankaikai@aliyun.com + * @since 1.0 2025-02-21 + */ +@AllArgsConstructor +@Service +public class ConsStockFlowServiceImpl extends ServiceImpl implements ConsStockFlowService { + + private final ConsInfoMapper consInfoMapper; + + private QueryWrapper buildQueryWrapper(ConsStockFlowDTO param) { + QueryWrapper queryWrapper = PageUtil.buildSortQueryWrapper(); + /*if (StrUtil.isNotEmpty(param.getName())) { + queryWrapper.like(ConsStockFlow::getName, param.getName()); + }*/ + Long shopId = StpKit.USER.getShopId(0L); + queryWrapper.eq(ConsStockFlow::getShopId, shopId); + queryWrapper.orderBy(ConsStockFlow::getId, false); + return queryWrapper; + } + + + @Override + @Transactional(rollbackFor = Exception.class) + public void inStock(ConsInOutStockHeadParam param) { + Long shopId = StpKit.USER.getShopId(0L); + Long createUserId = StpKit.USER.getLoginIdAsLong(); + String createUserName = StpKit.USER.getAccount(); + ConsStockFlow head = BeanUtil.copyProperties(param, ConsStockFlow.class); + List entityList = BeanUtil.copyToList(param.getBodyList(), ConsStockFlow.class); + List insertList = new ArrayList<>(); + List updateStockList = new ArrayList<>(); + for (ConsStockFlow entity : entityList) { + BeanUtil.copyProperties(head, entity, CopyOptions.create().ignoreNullValue()); + entity.setShopId(shopId); + entity.setInOutType(InOutTypeEnum.IN.value()); + entity.setInOutItem(InOutItemEnum.MANUAL_IN.value()); + entity.setCreateUserId(createUserId); + entity.setCreateUserName(createUserName); + Long conId = entity.getConId(); + ConsInfo consInfo = consInfoMapper.selectOneById(conId); + if (consInfo == null) { + throw new CzgException(StrUtil.format("耗材{}不存在", entity.getConName())); + } + entity.setBeforeNumber(consInfo.getStockNumber()); + entity.setAfterNumber(NumberUtil.add(entity.getBeforeNumber(), entity.getInOutNumber())); + insertList.add(entity); + consInfo.setStockNumber(entity.getAfterNumber()); + updateStockList.add(consInfo); + } + super.saveBatch(insertList); + updateStockList.parallelStream().forEach(consInfoMapper::update); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void outStock(ConsInOutStockHeadParam param) { + Long shopId = StpKit.USER.getShopId(0L); + Long createUserId = StpKit.USER.getLoginIdAsLong(); + String createUserName = StpKit.USER.getAccount(); + ConsStockFlow head = BeanUtil.copyProperties(param, ConsStockFlow.class); + List entityList = BeanUtil.copyToList(param.getBodyList(), ConsStockFlow.class); + List insertList = new ArrayList<>(); + List updateStockList = new ArrayList<>(); + for (ConsStockFlow entity : entityList) { + BeanUtil.copyProperties(head, entity, CopyOptions.create().ignoreNullValue()); + entity.setInOutNumber(NumberUtil.sub(BigDecimal.ZERO, entity.getInOutNumber())); + entity.setShopId(shopId); + entity.setInOutType(InOutTypeEnum.OUT.value()); + entity.setInOutItem(InOutItemEnum.MANUAL_OUT.value()); + entity.setCreateUserId(createUserId); + entity.setCreateUserName(createUserName); + Long conId = entity.getConId(); + ConsInfo consInfo = consInfoMapper.selectOneById(conId); + if (consInfo == null) { + throw new CzgException(StrUtil.format("耗材{}不存在", entity.getConName())); + } + entity.setBeforeNumber(consInfo.getStockNumber()); + entity.setAfterNumber(NumberUtil.add(entity.getBeforeNumber(), entity.getInOutNumber())); + insertList.add(entity); + consInfo.setStockNumber(entity.getAfterNumber()); + updateStockList.add(consInfo); + } + super.saveBatch(insertList); + updateStockList.parallelStream().forEach(consInfoMapper::update); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void checkStock(ConsCheckStockParam param) { + Long shopId = StpKit.USER.getShopId(0L); + Long createUserId = StpKit.USER.getLoginIdAsLong(); + String createUserName = StpKit.USER.getAccount(); + ConsStockFlow entity = new ConsStockFlow(); + entity.setCreateUserId(createUserId); + entity.setCreateUserName(createUserName); + entity.setShopId(shopId); + entity.setConId(param.getConId()); + entity.setConName(param.getConName()); + entity.setPurchasePrice(param.getPrice()); + ConsInfo consInfo = consInfoMapper.selectOneById(param.getConId()); + if (consInfo == null) { + throw new CzgException(StrUtil.format("耗材{}不存在", entity.getConName())); + } + BigDecimal winLossNumber = NumberUtil.sub(param.getActualNumber(), param.getStockNumber()); + if (!NumberUtil.equals(winLossNumber, param.getWinLossNumber())) { + throw new CzgException(StrUtil.format("耗材{}存在发生变动,请刷新后重试", entity.getConName())); + } + entity.setBeforeNumber(consInfo.getStockNumber()); + entity.setInOutNumber(winLossNumber); + entity.setAfterNumber(NumberUtil.add(entity.getBeforeNumber(), entity.getInOutNumber())); + if (NumberUtil.isLess(winLossNumber, BigDecimal.ZERO)) { + entity.setInOutType(InOutTypeEnum.OUT.value()); + entity.setInOutItem(InOutItemEnum.LOSS_OUT.value()); + } else { + entity.setInOutType(InOutTypeEnum.IN.value()); + entity.setInOutItem(InOutItemEnum.WIN_IN.value()); + } + entity.setSubTotal(NumberUtil.mul(winLossNumber, param.getPrice())); + entity.setRemark(param.getRemark()); + super.save(entity); + consInfo.setStockNumber(entity.getAfterNumber()); + consInfoMapper.update(consInfo); + } + + @Override + public List getCheckStockRecordList(Long conId) { + Long shopId = StpKit.USER.getShopId(0L); + return super.mapper.selectListByQueryAs(query().eq(ConsStockFlow::getShopId, shopId).eq(ConsStockFlow::getConId, conId).orderBy(ConsStockFlow::getId, true), ConsCheckStockRecordVo.class); + } + +} \ No newline at end of file diff --git a/cash-service/product-service/src/main/java/com/czg/service/product/service/impl/ProdConsRelationServiceImpl.java b/cash-service/product-service/src/main/java/com/czg/service/product/service/impl/ProdConsRelationServiceImpl.java index e58b0352..73e36df6 100644 --- a/cash-service/product-service/src/main/java/com/czg/service/product/service/impl/ProdConsRelationServiceImpl.java +++ b/cash-service/product-service/src/main/java/com/czg/service/product/service/impl/ProdConsRelationServiceImpl.java @@ -36,7 +36,7 @@ public class ProdConsRelationServiceImpl extends ServiceImpl + + + + + \ No newline at end of file