商品模块代码提交
This commit is contained in:
parent
e09b55938f
commit
2d8f120303
|
|
@ -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<Void> 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<Void> 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<List<ConsCheckStockRecordVo>> checkStock(@RequestParam Long conId) {
|
||||||
|
AssertUtil.isNull(conId, "耗材ID不能为空");
|
||||||
|
List<ConsCheckStockRecordVo> data = consStockFlowService.getCheckStockRecordList(conId);
|
||||||
|
return CzgResult.success(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 库存盘点
|
||||||
|
*/
|
||||||
|
@PostMapping("check")
|
||||||
|
@OperationLog("库存盘点")
|
||||||
|
//@SaAdminCheckPermission("consStockFlow:check")
|
||||||
|
public CzgResult<Void> checkStock(@RequestBody ConsCheckStockParam param) {
|
||||||
|
ValidatorUtil.validateEntity(param, DefaultGroup.class);
|
||||||
|
consStockFlowService.checkStock(param);
|
||||||
|
return CzgResult.success();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -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<ConsInOutStockBodyParam> bodyList;
|
||||||
|
}
|
||||||
|
|
@ -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<ConsStockFlow> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手动入库
|
||||||
|
*
|
||||||
|
* @param param 手动出库入参
|
||||||
|
*/
|
||||||
|
void inStock(ConsInOutStockHeadParam param);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手动出库
|
||||||
|
*
|
||||||
|
* @param param 手动出库入参
|
||||||
|
*/
|
||||||
|
void outStock(ConsInOutStockHeadParam param);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 库存盘点
|
||||||
|
*
|
||||||
|
* @param param 库存盘点入参
|
||||||
|
*/
|
||||||
|
void checkStock(ConsCheckStockParam param);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取盘点记录
|
||||||
|
*
|
||||||
|
* @param conId 耗材id
|
||||||
|
* @return 盘点记录列表
|
||||||
|
*/
|
||||||
|
List<ConsCheckStockRecordVo> getCheckStockRecordList(Long conId);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -19,7 +19,7 @@ public class ShopProductSkuInfoVo implements Serializable {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* id
|
* sku-id
|
||||||
*/
|
*/
|
||||||
private Long id;
|
private Long id;
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -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<ConsStockFlow> {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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<ConsStockFlowMapper, ConsStockFlow> 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<ConsStockFlow> entityList = BeanUtil.copyToList(param.getBodyList(), ConsStockFlow.class);
|
||||||
|
List<ConsStockFlow> insertList = new ArrayList<>();
|
||||||
|
List<ConsInfo> 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<ConsStockFlow> entityList = BeanUtil.copyToList(param.getBodyList(), ConsStockFlow.class);
|
||||||
|
List<ConsStockFlow> insertList = new ArrayList<>();
|
||||||
|
List<ConsInfo> 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<ConsCheckStockRecordVo> 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -36,7 +36,7 @@ public class ProdConsRelationServiceImpl extends ServiceImpl<ProdConsRelationMap
|
||||||
|
|
||||||
private QueryWrapper buildQueryWrapper(ProdConsRelationDTO param) {
|
private QueryWrapper buildQueryWrapper(ProdConsRelationDTO param) {
|
||||||
QueryWrapper queryWrapper = PageUtil.buildSortQueryWrapper();
|
QueryWrapper queryWrapper = PageUtil.buildSortQueryWrapper();
|
||||||
Long shopId = StpKit.USER.getLoginIdAsLong();
|
Long shopId = StpKit.USER.getShopId(0L);
|
||||||
queryWrapper.eq(ProdConsRelation::getShopId, shopId);
|
queryWrapper.eq(ProdConsRelation::getShopId, shopId);
|
||||||
queryWrapper.orderBy(ProdConsRelation::getId, false);
|
queryWrapper.orderBy(ProdConsRelation::getId, false);
|
||||||
return queryWrapper;
|
return queryWrapper;
|
||||||
|
|
@ -51,7 +51,7 @@ public class ProdConsRelationServiceImpl extends ServiceImpl<ProdConsRelationMap
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public boolean saveProdConsRelation(ProdConsBindDTO dto) {
|
public boolean saveProdConsRelation(ProdConsBindDTO dto) {
|
||||||
Long shopId = StpKit.USER.getLoginIdAsLong();
|
Long shopId = StpKit.USER.getShopId(0L);
|
||||||
long count = productMapper.selectCountByQuery(query().eq(Product::getShopId, shopId).eq(Product::getId, dto.getId()));
|
long count = productMapper.selectCountByQuery(query().eq(Product::getShopId, shopId).eq(Product::getId, dto.getId()));
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
throw new CzgException("商品不存在");
|
throw new CzgException("商品不存在");
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
|
||||||
|
<mapper namespace="com.czg.service.product.mapper.ConsStockFlowMapper">
|
||||||
|
|
||||||
|
</mapper>
|
||||||
Loading…
Reference in New Issue