Commit d06a22dab34315f774aa68da9e3f8f6c2ba4c768

Authored by YunaiV
1 parent 5fd23cac

✨ ERP:增加结算账户 100%

Showing 14 changed files with 693 additions and 27 deletions
yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/ErrorCodeConstants.java
@@ -19,6 +19,11 @@ public interface ErrorCodeConstants { @@ -19,6 +19,11 @@ public interface ErrorCodeConstants {
19 19
20 // ========== ERP 销售订单(1-030-201-000) ========== 20 // ========== ERP 销售订单(1-030-201-000) ==========
21 ErrorCode SALE_ORDER_NOT_EXISTS = new ErrorCode(1_020_201_000, "销售订单不存在"); 21 ErrorCode SALE_ORDER_NOT_EXISTS = new ErrorCode(1_020_201_000, "销售订单不存在");
  22 + ErrorCode SALE_ORDER_DELETE_FAIL_APPROVE = new ErrorCode(1_020_201_001, "销售订单({})已审核,无法删除");
  23 + ErrorCode SALE_ORDER_PROCESS_FAIL = new ErrorCode(1_020_201_002, "反审核失败,只有已审核的销售订单才能反审核");
  24 + ErrorCode SALE_ORDER_APPROVE_FAIL = new ErrorCode(1_020_201_003, "审核失败,只有未审核的销售订单才能审核");
  25 + ErrorCode SALE_ORDER_NO_EXISTS = new ErrorCode(1_020_201_004, "生成销售单号失败,请重新提交");
  26 + ErrorCode SALE_ORDER_UPDATE_FAIL_APPROVE = new ErrorCode(1_020_201_005, "销售订单({})已审核,无法修改");
22 27
23 // ========== ERP 仓库 1-030-400-000 ========== 28 // ========== ERP 仓库 1-030-400-000 ==========
24 ErrorCode WAREHOUSE_NOT_EXISTS = new ErrorCode(1_030_400_000, "仓库不存在"); 29 ErrorCode WAREHOUSE_NOT_EXISTS = new ErrorCode(1_030_400_000, "仓库不存在");
@@ -78,4 +83,8 @@ public interface ErrorCodeConstants { @@ -78,4 +83,8 @@ public interface ErrorCodeConstants {
78 ErrorCode PRODUCT_UNIT_NAME_DUPLICATE = new ErrorCode(1_030_502_001, "已存在该名字的产品单位"); 83 ErrorCode PRODUCT_UNIT_NAME_DUPLICATE = new ErrorCode(1_030_502_001, "已存在该名字的产品单位");
79 ErrorCode PRODUCT_UNIT_EXITS_PRODUCT = new ErrorCode(1_030_502_002, "存在产品使用该单位,无法删除"); 84 ErrorCode PRODUCT_UNIT_EXITS_PRODUCT = new ErrorCode(1_030_502_002, "存在产品使用该单位,无法删除");
80 85
  86 + // ========== ERP 结算账户 1-030-600-000 ==========
  87 + ErrorCode ACCOUNT_NOT_EXISTS = new ErrorCode(1_030_600_000, "结算账户不存在");
  88 + ErrorCode ACCOUNT_NOT_ENABLE = new ErrorCode(1_030_600_001, "结算账户({})未启用");
  89 +
81 } 90 }
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/ErpAccountController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.finance;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  7 +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  8 +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
  9 +import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.ErpAccountPageReqVO;
  10 +import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.ErpAccountRespVO;
  11 +import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.ErpAccountSaveReqVO;
  12 +import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpAccountDO;
  13 +import cn.iocoder.yudao.module.erp.service.finance.ErpAccountService;
  14 +import io.swagger.v3.oas.annotations.Operation;
  15 +import io.swagger.v3.oas.annotations.Parameter;
  16 +import io.swagger.v3.oas.annotations.Parameters;
  17 +import io.swagger.v3.oas.annotations.tags.Tag;
  18 +import jakarta.annotation.Resource;
  19 +import jakarta.servlet.http.HttpServletResponse;
  20 +import jakarta.validation.Valid;
  21 +import org.springframework.security.access.prepost.PreAuthorize;
  22 +import org.springframework.validation.annotation.Validated;
  23 +import org.springframework.web.bind.annotation.*;
  24 +
  25 +import java.io.IOException;
  26 +import java.util.List;
  27 +
  28 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  29 +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
  30 +
  31 +@Tag(name = "管理后台 - ERP 结算账户")
  32 +@RestController
  33 +@RequestMapping("/erp/account")
  34 +@Validated
  35 +public class ErpAccountController {
  36 +
  37 + @Resource
  38 + private ErpAccountService accountService;
  39 +
  40 + @PostMapping("/create")
  41 + @Operation(summary = "创建结算账户")
  42 + @PreAuthorize("@ss.hasPermission('erp:account:create')")
  43 + public CommonResult<Long> createAccount(@Valid @RequestBody ErpAccountSaveReqVO createReqVO) {
  44 + return success(accountService.createAccount(createReqVO));
  45 + }
  46 +
  47 + @PutMapping("/update")
  48 + @Operation(summary = "更新结算账户")
  49 + @PreAuthorize("@ss.hasPermission('erp:account:update')")
  50 + public CommonResult<Boolean> updateAccount(@Valid @RequestBody ErpAccountSaveReqVO updateReqVO) {
  51 + accountService.updateAccount(updateReqVO);
  52 + return success(true);
  53 + }
  54 +
  55 + @PutMapping("/update-default-status")
  56 + @Operation(summary = "更新结算账户默认状态")
  57 + @Parameters({
  58 + @Parameter(name = "id", description = "编号", required = true),
  59 + @Parameter(name = "status", description = "状态", required = true)
  60 + })
  61 + public CommonResult<Boolean> updateAccountDefaultStatus(@RequestParam("id") Long id,
  62 + @RequestParam("defaultStatus") Boolean defaultStatus) {
  63 + accountService.updateAccountDefaultStatus(id, defaultStatus);
  64 + return success(true);
  65 + }
  66 +
  67 + @DeleteMapping("/delete")
  68 + @Operation(summary = "删除结算账户")
  69 + @Parameter(name = "id", description = "编号", required = true)
  70 + @PreAuthorize("@ss.hasPermission('erp:account:delete')")
  71 + public CommonResult<Boolean> deleteAccount(@RequestParam("id") Long id) {
  72 + accountService.deleteAccount(id);
  73 + return success(true);
  74 + }
  75 +
  76 + @GetMapping("/get")
  77 + @Operation(summary = "获得结算账户")
  78 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  79 + @PreAuthorize("@ss.hasPermission('erp:account:query')")
  80 + public CommonResult<ErpAccountRespVO> getAccount(@RequestParam("id") Long id) {
  81 + ErpAccountDO account = accountService.getAccount(id);
  82 + return success(BeanUtils.toBean(account, ErpAccountRespVO.class));
  83 + }
  84 +
  85 + @GetMapping("/page")
  86 + @Operation(summary = "获得结算账户分页")
  87 + @PreAuthorize("@ss.hasPermission('erp:account:query')")
  88 + public CommonResult<PageResult<ErpAccountRespVO>> getAccountPage(@Valid ErpAccountPageReqVO pageReqVO) {
  89 + PageResult<ErpAccountDO> pageResult = accountService.getAccountPage(pageReqVO);
  90 + return success(BeanUtils.toBean(pageResult, ErpAccountRespVO.class));
  91 + }
  92 +
  93 + @GetMapping("/export-excel")
  94 + @Operation(summary = "导出结算账户 Excel")
  95 + @PreAuthorize("@ss.hasPermission('erp:account:export')")
  96 + @OperateLog(type = EXPORT)
  97 + public void exportAccountExcel(@Valid ErpAccountPageReqVO pageReqVO,
  98 + HttpServletResponse response) throws IOException {
  99 + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
  100 + List<ErpAccountDO> list = accountService.getAccountPage(pageReqVO).getList();
  101 + // 导出 Excel
  102 + ExcelUtils.write(response, "结算账户.xls", "数据", ErpAccountRespVO.class,
  103 + BeanUtils.toBean(list, ErpAccountRespVO.class));
  104 + }
  105 +
  106 +}
0 \ No newline at end of file 107 \ No newline at end of file
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/vo/ErpAccountPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.finance.vo;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +@Schema(description = "管理后台 - ERP 结算账户分页 Request VO")
  10 +@Data
  11 +@EqualsAndHashCode(callSuper = true)
  12 +@ToString(callSuper = true)
  13 +public class ErpAccountPageReqVO extends PageParam {
  14 +
  15 + @Schema(description = "账户编码", example = "A88")
  16 + private String no;
  17 +
  18 + @Schema(description = "账户名称", example = "张三")
  19 + private String name;
  20 +
  21 + @Schema(description = "备注", example = "随便")
  22 + private String remark;
  23 +
  24 +}
0 \ No newline at end of file 25 \ No newline at end of file
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/vo/ErpAccountRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.finance.vo;
  2 +
  3 +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
  4 +import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
  5 +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
  6 +import com.alibaba.excel.annotation.ExcelProperty;
  7 +import io.swagger.v3.oas.annotations.media.Schema;
  8 +import lombok.Data;
  9 +
  10 +import java.time.LocalDateTime;
  11 +
  12 +@Schema(description = "管理后台 - ERP 结算账户 Response VO")
  13 +@Data
  14 +@ExcelIgnoreUnannotated
  15 +public class ErpAccountRespVO {
  16 +
  17 + @Schema(description = "结算账户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "28684")
  18 + @ExcelProperty("结算账户编号")
  19 + private Long id;
  20 +
  21 + @Schema(description = "账户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
  22 + @ExcelProperty("账户名称")
  23 + private String name;
  24 +
  25 + @Schema(description = "账户编码", example = "A88")
  26 + @ExcelProperty("账户编码")
  27 + private String no;
  28 +
  29 + @Schema(description = "备注", example = "随便")
  30 + @ExcelProperty("备注")
  31 + private String remark;
  32 +
  33 + @Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  34 + @ExcelProperty("开启状态")
  35 + @DictFormat(DictTypeConstants.COMMON_STATUS)
  36 + private Integer status;
  37 +
  38 + @Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  39 + @ExcelProperty("排序")
  40 + private Integer sort;
  41 +
  42 + @Schema(description = "是否默认", example = "1")
  43 + @ExcelProperty("是否默认")
  44 + private Boolean defaultStatus;
  45 +
  46 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  47 + @ExcelProperty("创建时间")
  48 + private LocalDateTime createTime;
  49 +
  50 +}
0 \ No newline at end of file 51 \ No newline at end of file
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/vo/ErpAccountSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.finance.vo;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import jakarta.validation.constraints.NotEmpty;
  7 +import jakarta.validation.constraints.NotNull;
  8 +import lombok.Data;
  9 +
  10 +@Schema(description = "管理后台 - ERP 结算账户新增/修改 Request VO")
  11 +@Data
  12 +public class ErpAccountSaveReqVO {
  13 +
  14 + @Schema(description = "结算账户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "28684")
  15 + private Long id;
  16 +
  17 + @Schema(description = "账户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
  18 + @NotEmpty(message = "账户名称不能为空")
  19 + private String name;
  20 +
  21 + @Schema(description = "账户编码", example = "A88")
  22 + private String no;
  23 +
  24 + @Schema(description = "备注", example = "随便")
  25 + private String remark;
  26 +
  27 + @Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  28 + @NotNull(message = "开启状态不能为空")
  29 + @InEnum(value = CommonStatusEnum.class)
  30 + private Integer status;
  31 +
  32 + @Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  33 + @NotNull(message = "排序不能为空")
  34 + private Integer sort;
  35 +
  36 +}
0 \ No newline at end of file 37 \ No newline at end of file
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/order/ErpSaleOrderSaveReqVO.java
1 package cn.iocoder.yudao.module.erp.controller.admin.sale.vo.order; 1 package cn.iocoder.yudao.module.erp.controller.admin.sale.vo.order;
2 2
3 import io.swagger.v3.oas.annotations.media.Schema; 3 import io.swagger.v3.oas.annotations.media.Schema;
4 -import jakarta.validation.constraints.NotEmpty;  
5 import jakarta.validation.constraints.NotNull; 4 import jakarta.validation.constraints.NotNull;
6 import lombok.Data; 5 import lombok.Data;
7 6
@@ -16,10 +15,6 @@ public class ErpSaleOrderSaveReqVO { @@ -16,10 +15,6 @@ public class ErpSaleOrderSaveReqVO {
16 @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17386") 15 @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17386")
17 private Long id; 16 private Long id;
18 17
19 - @Schema(description = "销售单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "XS001")  
20 - @NotEmpty(message = "销售单编号不能为空")  
21 - private String no;  
22 -  
23 @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1724") 18 @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1724")
24 @NotNull(message = "客户编号不能为空") 19 @NotNull(message = "客户编号不能为空")
25 private Long customerId; 20 private Long customerId;
@@ -31,15 +26,13 @@ public class ErpSaleOrderSaveReqVO { @@ -31,15 +26,13 @@ public class ErpSaleOrderSaveReqVO {
31 @Schema(description = "销售员编号", example = "1888") 26 @Schema(description = "销售员编号", example = "1888")
32 private Long saleUserId; 27 private Long saleUserId;
33 28
34 - @Schema(description = "结算账户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "31189")  
35 - @NotNull(message = "结算账户编号不能为空") 29 + @Schema(description = "结算账户编号", example = "31189")
36 private Long accountId; 30 private Long accountId;
37 31
38 @Schema(description = "优惠率,百分比", requiredMode = Schema.RequiredMode.REQUIRED, example = "99.88") 32 @Schema(description = "优惠率,百分比", requiredMode = Schema.RequiredMode.REQUIRED, example = "99.88")
39 private BigDecimal discountPercent; 33 private BigDecimal discountPercent;
40 34
41 - @Schema(description = "定金金额,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127")  
42 - @NotNull(message = "定金金额,单位:元不能为空") 35 + @Schema(description = "定金金额,单位:元", example = "7127")
43 private BigDecimal depositPrice; 36 private BigDecimal depositPrice;
44 37
45 @Schema(description = "附件地址", example = "https://www.iocoder.cn") 38 @Schema(description = "附件地址", example = "https://www.iocoder.cn")
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/finance/ErpAccountDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.dataobject.finance;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import com.baomidou.mybatisplus.annotation.KeySequence;
  5 +import com.baomidou.mybatisplus.annotation.TableId;
  6 +import com.baomidou.mybatisplus.annotation.TableName;
  7 +import lombok.*;
  8 +
  9 +/**
  10 + * ERP 结算账户 DO
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@TableName("erp_account")
  15 +@KeySequence("erp_account_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  16 +@Data
  17 +@EqualsAndHashCode(callSuper = true)
  18 +@ToString(callSuper = true)
  19 +@Builder
  20 +@NoArgsConstructor
  21 +@AllArgsConstructor
  22 +public class ErpAccountDO extends BaseDO {
  23 +
  24 + /**
  25 + * 结算账户编号
  26 + */
  27 + @TableId
  28 + private Long id;
  29 + /**
  30 + * 账户名称
  31 + */
  32 + private String name;
  33 + /**
  34 + * 账户编码
  35 + */
  36 + private String no;
  37 + /**
  38 + * 备注
  39 + */
  40 + private String remark;
  41 + /**
  42 + * 开启状态
  43 + *
  44 + * 枚举 {@link cn.iocoder.yudao.framework.common.enums.CommonStatusEnum}
  45 + */
  46 + private Integer status;
  47 + /**
  48 + * 排序
  49 + */
  50 + private Integer sort;
  51 + /**
  52 + * 是否默认
  53 + */
  54 + private Boolean defaultStatus;
  55 +
  56 +}
0 \ No newline at end of file 57 \ No newline at end of file
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/finance/ErpAccountMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.mysql.finance;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.ErpAccountPageReqVO;
  7 +import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpAccountDO;
  8 +import org.apache.ibatis.annotations.Mapper;
  9 +
  10 +import java.util.List;
  11 +
  12 +/**
  13 + * ERP 结算账户 Mapper
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@Mapper
  18 +public interface ErpAccountMapper extends BaseMapperX<ErpAccountDO> {
  19 +
  20 + default PageResult<ErpAccountDO> selectPage(ErpAccountPageReqVO reqVO) {
  21 + return selectPage(reqVO, new LambdaQueryWrapperX<ErpAccountDO>()
  22 + .likeIfPresent(ErpAccountDO::getName, reqVO.getName())
  23 + .eqIfPresent(ErpAccountDO::getNo, reqVO.getNo())
  24 + .eqIfPresent(ErpAccountDO::getRemark, reqVO.getRemark())
  25 + .orderByDesc(ErpAccountDO::getId));
  26 + }
  27 +
  28 + default ErpAccountDO selectByDefaultStatus() {
  29 + return selectOne(ErpAccountDO::getDefaultStatus, true);
  30 + }
  31 +
  32 + default List<ErpAccountDO> selectListByStatus(Integer status) {
  33 + return selectList(ErpAccountDO::getStatus, status);
  34 + }
  35 +
  36 +}
0 \ No newline at end of file 37 \ No newline at end of file
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/redis/no/ErpNoRedisDAO.java
@@ -38,6 +38,11 @@ public class ErpNoRedisDAO { @@ -38,6 +38,11 @@ public class ErpNoRedisDAO {
38 */ 38 */
39 public static final String STOCK_CHECK_NO_PREFIX = "QCPD"; 39 public static final String STOCK_CHECK_NO_PREFIX = "QCPD";
40 40
  41 + /**
  42 + * 销售订单 {@link cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpSaleOrderDO}
  43 + */
  44 + public static final String SALE_ORDER_NO_PREFIX = "XSDD";
  45 +
41 @Resource 46 @Resource
42 private StringRedisTemplate stringRedisTemplate; 47 private StringRedisTemplate stringRedisTemplate;
43 48
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/finance/ErpAccountService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.service.finance;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.ErpAccountPageReqVO;
  5 +import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.ErpAccountSaveReqVO;
  6 +import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpAccountDO;
  7 +import jakarta.validation.Valid;
  8 +
  9 +/**
  10 + * ERP 结算账户 Service 接口
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +public interface ErpAccountService {
  15 +
  16 + /**
  17 + * 创建结算账户
  18 + *
  19 + * @param createReqVO 创建信息
  20 + * @return 编号
  21 + */
  22 + Long createAccount(@Valid ErpAccountSaveReqVO createReqVO);
  23 +
  24 + /**
  25 + * 更新ERP 结算账户
  26 + *
  27 + * @param updateReqVO 更新信息
  28 + */
  29 + void updateAccount(@Valid ErpAccountSaveReqVO updateReqVO);
  30 +
  31 + /**
  32 + * 更新结算账户默认状态
  33 + *
  34 + * @param id 编号
  35 + * @param defaultStatus 默认状态
  36 + */
  37 + void updateAccountDefaultStatus(Long id, Boolean defaultStatus);
  38 +
  39 + /**
  40 + * 删除结算账户
  41 + *
  42 + * @param id 编号
  43 + */
  44 + void deleteAccount(Long id);
  45 +
  46 + /**
  47 + * 获得结算账户
  48 + *
  49 + * @param id 编号
  50 + * @return 结算账户
  51 + */
  52 + ErpAccountDO getAccount(Long id);
  53 +
  54 + /**
  55 + * 校验结算账户
  56 + *
  57 + * @param id 编号
  58 + * @return 结算账户
  59 + */
  60 + ErpAccountDO validateAccount(Long id);
  61 +
  62 + /**
  63 + * 获得结算账户分页
  64 + *
  65 + * @param pageReqVO 分页查询
  66 + * @return 结算账户分页
  67 + */
  68 + PageResult<ErpAccountDO> getAccountPage(ErpAccountPageReqVO pageReqVO);
  69 +
  70 +}
0 \ No newline at end of file 71 \ No newline at end of file
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/finance/ErpAccountServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.service.finance;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  6 +import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.ErpAccountPageReqVO;
  7 +import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.ErpAccountSaveReqVO;
  8 +import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpAccountDO;
  9 +import cn.iocoder.yudao.module.erp.dal.mysql.finance.ErpAccountMapper;
  10 +import jakarta.annotation.Resource;
  11 +import org.springframework.stereotype.Service;
  12 +import org.springframework.validation.annotation.Validated;
  13 +
  14 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  15 +import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
  16 +
  17 +/**
  18 + * ERP 结算账户 Service 实现类
  19 + *
  20 + * @author 芋道源码
  21 + */
  22 +@Service
  23 +@Validated
  24 +public class ErpAccountServiceImpl implements ErpAccountService {
  25 +
  26 + @Resource
  27 + private ErpAccountMapper accountMapper;
  28 +
  29 + @Override
  30 + public Long createAccount(ErpAccountSaveReqVO createReqVO) {
  31 + // 插入
  32 + ErpAccountDO account = BeanUtils.toBean(createReqVO, ErpAccountDO.class);
  33 + accountMapper.insert(account);
  34 + // 返回
  35 + return account.getId();
  36 + }
  37 +
  38 + @Override
  39 + public void updateAccount(ErpAccountSaveReqVO updateReqVO) {
  40 + // 校验存在
  41 + validateAccountExists(updateReqVO.getId());
  42 + // 更新
  43 + ErpAccountDO updateObj = BeanUtils.toBean(updateReqVO, ErpAccountDO.class);
  44 + accountMapper.updateById(updateObj);
  45 + }
  46 +
  47 + @Override
  48 + public void updateAccountDefaultStatus(Long id, Boolean defaultStatus) {
  49 + // 1. 校验存在
  50 + validateAccountExists(id);
  51 +
  52 + // 2.1 如果开启,则需要关闭所有其它的默认
  53 + if (defaultStatus) {
  54 + ErpAccountDO account = accountMapper.selectByDefaultStatus();
  55 + if (account != null) {
  56 + accountMapper.updateById(new ErpAccountDO().setId(account.getId()).setDefaultStatus(false));
  57 + }
  58 + }
  59 + // 2.2 更新对应的默认状态
  60 + accountMapper.updateById(new ErpAccountDO().setId(id).setDefaultStatus(defaultStatus));
  61 + }
  62 +
  63 + @Override
  64 + public void deleteAccount(Long id) {
  65 + // 校验存在
  66 + validateAccountExists(id);
  67 + // 删除
  68 + accountMapper.deleteById(id);
  69 + }
  70 +
  71 + private void validateAccountExists(Long id) {
  72 + if (accountMapper.selectById(id) == null) {
  73 + throw exception(ACCOUNT_NOT_EXISTS);
  74 + }
  75 + }
  76 +
  77 + @Override
  78 + public ErpAccountDO getAccount(Long id) {
  79 + return accountMapper.selectById(id);
  80 + }
  81 +
  82 + @Override
  83 + public ErpAccountDO validateAccount(Long id) {
  84 + ErpAccountDO account = accountMapper.selectById(id);
  85 + if (account == null) {
  86 + throw exception(ACCOUNT_NOT_EXISTS);
  87 + }
  88 + if (CommonStatusEnum.isDisable(account.getStatus())) {
  89 + throw exception(ACCOUNT_NOT_ENABLE, account.getName());
  90 + }
  91 + return account;
  92 + }
  93 +
  94 + @Override
  95 + public PageResult<ErpAccountDO> getAccountPage(ErpAccountPageReqVO pageReqVO) {
  96 + return accountMapper.selectPage(pageReqVO);
  97 + }
  98 +
  99 +}
0 \ No newline at end of file 100 \ No newline at end of file
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpSaleOrderServiceImpl.java
@@ -13,6 +13,7 @@ import cn.iocoder.yudao.module.erp.dal.mysql.sale.ErpSaleOrderItemMapper; @@ -13,6 +13,7 @@ import cn.iocoder.yudao.module.erp.dal.mysql.sale.ErpSaleOrderItemMapper;
13 import cn.iocoder.yudao.module.erp.dal.mysql.sale.ErpSaleOrderMapper; 13 import cn.iocoder.yudao.module.erp.dal.mysql.sale.ErpSaleOrderMapper;
14 import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO; 14 import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO;
15 import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus; 15 import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
  16 +import cn.iocoder.yudao.module.erp.service.finance.ErpAccountService;
16 import cn.iocoder.yudao.module.erp.service.product.ErpProductService; 17 import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
17 import jakarta.annotation.Resource; 18 import jakarta.annotation.Resource;
18 import org.springframework.stereotype.Service; 19 import org.springframework.stereotype.Service;
@@ -52,6 +53,8 @@ public class ErpSaleOrderServiceImpl implements ErpSaleOrderService { @@ -52,6 +53,8 @@ public class ErpSaleOrderServiceImpl implements ErpSaleOrderService {
52 private ErpProductService productService; 53 private ErpProductService productService;
53 @Resource 54 @Resource
54 private ErpCustomerService customerService; 55 private ErpCustomerService customerService;
  56 + @Resource
  57 + private ErpAccountService accountService;
55 58
56 @Override 59 @Override
57 @Transactional(rollbackFor = Exception.class) 60 @Transactional(rollbackFor = Exception.class)
@@ -60,17 +63,20 @@ public class ErpSaleOrderServiceImpl implements ErpSaleOrderService { @@ -60,17 +63,20 @@ public class ErpSaleOrderServiceImpl implements ErpSaleOrderService {
60 List<ErpSaleOrderItemDO> saleOrderItems = validateSaleOrderItems(createReqVO.getItems()); 63 List<ErpSaleOrderItemDO> saleOrderItems = validateSaleOrderItems(createReqVO.getItems());
61 // 1.2 校验客户 64 // 1.2 校验客户
62 customerService.validateCustomer(createReqVO.getCustomerId()); 65 customerService.validateCustomer(createReqVO.getCustomerId());
63 - // 1.3 生成调拨单号,并校验唯一性  
64 - String no = noRedisDAO.generate(ErpNoRedisDAO.STOCK_MOVE_NO_PREFIX); 66 + // 1.3 校验结算账户
  67 + if (createReqVO.getAccountId() != null) {
  68 + accountService.validateAccount(createReqVO.getAccountId());
  69 + }
  70 + // 1.4 生成调拨单号,并校验唯一性
  71 + String no = noRedisDAO.generate(ErpNoRedisDAO.SALE_ORDER_NO_PREFIX);
65 if (saleOrderMapper.selectByNo(no) != null) { 72 if (saleOrderMapper.selectByNo(no) != null) {
66 - throw exception(STOCK_MOVE_NO_EXISTS); 73 + throw exception(SALE_ORDER_NO_EXISTS);
67 } 74 }
68 75
69 // 2.1 插入订单 76 // 2.1 插入订单
70 ErpSaleOrderDO saleOrder = BeanUtils.toBean(createReqVO, ErpSaleOrderDO.class, in -> in 77 ErpSaleOrderDO saleOrder = BeanUtils.toBean(createReqVO, ErpSaleOrderDO.class, in -> in
71 - .setNo(no).setStatus(ErpAuditStatus.PROCESS.getStatus())  
72 - .setTotalCount(getSumValue(saleOrderItems, ErpSaleOrderItemDO::getCount, BigDecimal::add))  
73 - .setTotalPrice(getSumValue(saleOrderItems, ErpSaleOrderItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO))); 78 + .setNo(no).setStatus(ErpAuditStatus.PROCESS.getStatus()));
  79 + calculateTotalPrice(saleOrder, saleOrderItems);
74 saleOrderMapper.insert(saleOrder); 80 saleOrderMapper.insert(saleOrder);
75 // 2.2 插入订单项 81 // 2.2 插入订单项
76 saleOrderItems.forEach(o -> o.setOrderId(saleOrder.getId())); 82 saleOrderItems.forEach(o -> o.setOrderId(saleOrder.getId()));
@@ -84,22 +90,38 @@ public class ErpSaleOrderServiceImpl implements ErpSaleOrderService { @@ -84,22 +90,38 @@ public class ErpSaleOrderServiceImpl implements ErpSaleOrderService {
84 // 1.1 校验存在 90 // 1.1 校验存在
85 ErpSaleOrderDO saleOrder = validateSaleOrderExists(updateReqVO.getId()); 91 ErpSaleOrderDO saleOrder = validateSaleOrderExists(updateReqVO.getId());
86 if (ErpAuditStatus.APPROVE.getStatus().equals(saleOrder.getStatus())) { 92 if (ErpAuditStatus.APPROVE.getStatus().equals(saleOrder.getStatus())) {
87 - throw exception(STOCK_MOVE_UPDATE_FAIL_APPROVE, saleOrder.getNo()); 93 + throw exception(SALE_ORDER_UPDATE_FAIL_APPROVE, saleOrder.getNo());
88 } 94 }
89 // 1.2 校验客户 95 // 1.2 校验客户
90 customerService.validateCustomer(updateReqVO.getCustomerId()); 96 customerService.validateCustomer(updateReqVO.getCustomerId());
91 - // 1.3 校验订单项的有效性 97 + // 1.3 校验结算账户
  98 + if (updateReqVO.getAccountId() != null) {
  99 + accountService.validateAccount(updateReqVO.getAccountId());
  100 + }
  101 + // 1.4 校验订单项的有效性
92 List<ErpSaleOrderItemDO> saleOrderItems = validateSaleOrderItems(updateReqVO.getItems()); 102 List<ErpSaleOrderItemDO> saleOrderItems = validateSaleOrderItems(updateReqVO.getItems());
93 103
94 // 2.1 更新订单 104 // 2.1 更新订单
95 - ErpSaleOrderDO updateObj = BeanUtils.toBean(updateReqVO, ErpSaleOrderDO.class, in -> in  
96 - .setTotalCount(getSumValue(saleOrderItems, ErpSaleOrderItemDO::getCount, BigDecimal::add))  
97 - .setTotalPrice(getSumValue(saleOrderItems, ErpSaleOrderItemDO::getTotalPrice, BigDecimal::add))); 105 + ErpSaleOrderDO updateObj = BeanUtils.toBean(updateReqVO, ErpSaleOrderDO.class);
  106 + calculateTotalPrice(updateObj, saleOrderItems);
98 saleOrderMapper.updateById(updateObj); 107 saleOrderMapper.updateById(updateObj);
99 // 2.2 更新订单项 108 // 2.2 更新订单项
100 updateSaleOrderItemList(updateReqVO.getId(), saleOrderItems); 109 updateSaleOrderItemList(updateReqVO.getId(), saleOrderItems);
101 } 110 }
102 111
  112 + private void calculateTotalPrice(ErpSaleOrderDO saleOrder, List<ErpSaleOrderItemDO> saleOrderItems) {
  113 + saleOrder.setTotalCount(getSumValue(saleOrderItems, ErpSaleOrderItemDO::getCount, BigDecimal::add));
  114 + saleOrder.setTotalProductPrice(getSumValue(saleOrderItems, ErpSaleOrderItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO));
  115 + saleOrder.setTotalTaxPrice(getSumValue(saleOrderItems, ErpSaleOrderItemDO::getTaxPrice, BigDecimal::add, BigDecimal.ZERO));
  116 + saleOrder.setTotalPrice(saleOrder.getTotalProductPrice().add(saleOrder.getTotalTaxPrice()));
  117 + // 计算优惠价格
  118 + if (saleOrder.getDiscountPercent() == null) {
  119 + saleOrder.setDiscountPercent(BigDecimal.ZERO);
  120 + }
  121 + saleOrder.setDiscountPrice(MoneyUtils.priceMultiply(saleOrder.getTotalPrice(), saleOrder.getDiscountPercent()));
  122 + saleOrder.setTotalPrice(saleOrder.getTotalPrice().subtract(saleOrder.getDiscountPrice()));
  123 + }
  124 +
103 @Override 125 @Override
104 @Transactional(rollbackFor = Exception.class) 126 @Transactional(rollbackFor = Exception.class)
105 public void updateSaleOrderStatus(Long id, Integer status) { 127 public void updateSaleOrderStatus(Long id, Integer status) {
@@ -108,7 +130,7 @@ public class ErpSaleOrderServiceImpl implements ErpSaleOrderService { @@ -108,7 +130,7 @@ public class ErpSaleOrderServiceImpl implements ErpSaleOrderService {
108 ErpSaleOrderDO saleOrder = validateSaleOrderExists(id); 130 ErpSaleOrderDO saleOrder = validateSaleOrderExists(id);
109 // 1.2 校验状态 131 // 1.2 校验状态
110 if (saleOrder.getStatus().equals(status)) { 132 if (saleOrder.getStatus().equals(status)) {
111 - throw exception(approve ? STOCK_MOVE_APPROVE_FAIL : STOCK_MOVE_PROCESS_FAIL); 133 + throw exception(approve ? SALE_ORDER_APPROVE_FAIL : SALE_ORDER_PROCESS_FAIL);
112 } 134 }
113 // TODO @芋艿:需要校验是不是有入库、有退货 135 // TODO @芋艿:需要校验是不是有入库、有退货
114 136
@@ -116,7 +138,7 @@ public class ErpSaleOrderServiceImpl implements ErpSaleOrderService { @@ -116,7 +138,7 @@ public class ErpSaleOrderServiceImpl implements ErpSaleOrderService {
116 int updateCount = saleOrderMapper.updateByIdAndStatus(id, saleOrder.getStatus(), 138 int updateCount = saleOrderMapper.updateByIdAndStatus(id, saleOrder.getStatus(),
117 new ErpSaleOrderDO().setStatus(status)); 139 new ErpSaleOrderDO().setStatus(status));
118 if (updateCount == 0) { 140 if (updateCount == 0) {
119 - throw exception(approve ? STOCK_MOVE_APPROVE_FAIL : STOCK_MOVE_PROCESS_FAIL); 141 + throw exception(approve ? SALE_ORDER_APPROVE_FAIL : SALE_ORDER_PROCESS_FAIL);
120 } 142 }
121 } 143 }
122 144
@@ -126,9 +148,15 @@ public class ErpSaleOrderServiceImpl implements ErpSaleOrderService { @@ -126,9 +148,15 @@ public class ErpSaleOrderServiceImpl implements ErpSaleOrderService {
126 convertSet(list, ErpSaleOrderSaveReqVO.Item::getProductId)); 148 convertSet(list, ErpSaleOrderSaveReqVO.Item::getProductId));
127 Map<Long, ErpProductDO> productMap = convertMap(productList, ErpProductDO::getId); 149 Map<Long, ErpProductDO> productMap = convertMap(productList, ErpProductDO::getId);
128 // 2. 转化为 ErpSaleOrderItemDO 列表 150 // 2. 转化为 ErpSaleOrderItemDO 列表
129 - return convertList(list, o -> BeanUtils.toBean(o, ErpSaleOrderItemDO.class, item -> item  
130 - .setProductUnitId(productMap.get(item.getProductId()).getUnitId())  
131 - .setTotalPrice(MoneyUtils.priceMultiply(item.getProductPrice(), item.getCount())))); 151 + return convertList(list, o -> BeanUtils.toBean(o, ErpSaleOrderItemDO.class, item -> {
  152 + item.setProductUnitId(productMap.get(item.getProductId()).getUnitId());
  153 + item.setTotalPrice(MoneyUtils.priceMultiply(item.getProductPrice(), item.getCount()));
  154 + if (item.getTotalPrice() == null) {
  155 + return;
  156 + }
  157 + item.setTaxPrice(MoneyUtils.priceMultiply(item.getTotalPrice(), item.getTaxPercent()));
  158 + item.setTotalPrice(item.getTotalPrice().add(item.getTaxPrice()));
  159 + }));
132 } 160 }
133 161
134 private void updateSaleOrderItemList(Long id, List<ErpSaleOrderItemDO> newList) { 162 private void updateSaleOrderItemList(Long id, List<ErpSaleOrderItemDO> newList) {
@@ -160,7 +188,7 @@ public class ErpSaleOrderServiceImpl implements ErpSaleOrderService { @@ -160,7 +188,7 @@ public class ErpSaleOrderServiceImpl implements ErpSaleOrderService {
160 } 188 }
161 saleOrders.forEach(saleOrder -> { 189 saleOrders.forEach(saleOrder -> {
162 if (ErpAuditStatus.APPROVE.getStatus().equals(saleOrder.getStatus())) { 190 if (ErpAuditStatus.APPROVE.getStatus().equals(saleOrder.getStatus())) {
163 - throw exception(STOCK_MOVE_DELETE_FAIL_APPROVE, saleOrder.getNo()); 191 + throw exception(SALE_ORDER_DELETE_FAIL_APPROVE, saleOrder.getNo());
164 } 192 }
165 }); 193 });
166 194
@@ -176,7 +204,7 @@ public class ErpSaleOrderServiceImpl implements ErpSaleOrderService { @@ -176,7 +204,7 @@ public class ErpSaleOrderServiceImpl implements ErpSaleOrderService {
176 private ErpSaleOrderDO validateSaleOrderExists(Long id) { 204 private ErpSaleOrderDO validateSaleOrderExists(Long id) {
177 ErpSaleOrderDO saleOrder = saleOrderMapper.selectById(id); 205 ErpSaleOrderDO saleOrder = saleOrderMapper.selectById(id);
178 if (saleOrder == null) { 206 if (saleOrder == null) {
179 - throw exception(STOCK_MOVE_NOT_EXISTS); 207 + throw exception(SALE_ORDER_NOT_EXISTS);
180 } 208 }
181 return saleOrder; 209 return saleOrder;
182 } 210 }
yudao-module-erp/yudao-module-erp-biz/src/main/resources/mapper/finance/ErpAccountMapper.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3 +<mapper namespace="cn.iocoder.yudao.module.erp.dal.mysql.finance.ErpAccountMapper">
  4 +
  5 + <!--
  6 + 一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
  7 + 无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
  8 + 代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
  9 + 文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
  10 + -->
  11 +
  12 +</mapper>
0 \ No newline at end of file 13 \ No newline at end of file
yudao-module-erp/yudao-module-erp-biz/src/test/java/cn/iocoder/yudao/module/erp/service/finance/ErpAccountServiceImplTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.service.finance;
  2 +
  3 +import org.junit.jupiter.api.Disabled;
  4 +import org.junit.jupiter.api.Test;
  5 +import org.springframework.boot.test.mock.mockito.MockBean;
  6 +
  7 +import jakarta.annotation.Resource;
  8 +
  9 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
  10 +
  11 +import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.*;
  12 +import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpAccountDO;
  13 +import cn.iocoder.yudao.module.erp.dal.mysql.finance.ErpAccountMapper;
  14 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  15 +
  16 +import jakarta.annotation.Resource;
  17 +import org.springframework.context.annotation.Import;
  18 +import java.util.*;
  19 +import java.time.LocalDateTime;
  20 +
  21 +import static cn.hutool.core.util.RandomUtil.*;
  22 +import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
  23 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*;
  24 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
  25 +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*;
  26 +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*;
  27 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.*;
  28 +import static org.junit.jupiter.api.Assertions.*;
  29 +import static org.mockito.Mockito.*;
  30 +
  31 +/**
  32 + * {@link ErpAccountServiceImpl} 的单元测试类
  33 + *
  34 + * @author 芋道源码
  35 + */
  36 +@Import(ErpAccountServiceImpl.class)
  37 +public class ErpAccountServiceImplTest extends BaseDbUnitTest {
  38 +
  39 + @Resource
  40 + private ErpAccountServiceImpl accountService;
  41 +
  42 + @Resource
  43 + private ErpAccountMapper accountMapper;
  44 +
  45 + @Test
  46 + public void testCreateAccount_success() {
  47 + // 准备参数
  48 + ErpAccountSaveReqVO createReqVO = randomPojo(ErpAccountSaveReqVO.class).setId(null);
  49 +
  50 + // 调用
  51 + Long accountId = accountService.createAccount(createReqVO);
  52 + // 断言
  53 + assertNotNull(accountId);
  54 + // 校验记录的属性是否正确
  55 + ErpAccountDO account = accountMapper.selectById(accountId);
  56 + assertPojoEquals(createReqVO, account, "id");
  57 + }
  58 +
  59 + @Test
  60 + public void testUpdateAccount_success() {
  61 + // mock 数据
  62 + ErpAccountDO dbAccount = randomPojo(ErpAccountDO.class);
  63 + accountMapper.insert(dbAccount);// @Sql: 先插入出一条存在的数据
  64 + // 准备参数
  65 + ErpAccountSaveReqVO updateReqVO = randomPojo(ErpAccountSaveReqVO.class, o -> {
  66 + o.setId(dbAccount.getId()); // 设置更新的 ID
  67 + });
  68 +
  69 + // 调用
  70 + accountService.updateAccount(updateReqVO);
  71 + // 校验是否更新正确
  72 + ErpAccountDO account = accountMapper.selectById(updateReqVO.getId()); // 获取最新的
  73 + assertPojoEquals(updateReqVO, account);
  74 + }
  75 +
  76 + @Test
  77 + public void testUpdateAccount_notExists() {
  78 + // 准备参数
  79 + ErpAccountSaveReqVO updateReqVO = randomPojo(ErpAccountSaveReqVO.class);
  80 +
  81 + // 调用, 并断言异常
  82 + assertServiceException(() -> accountService.updateAccount(updateReqVO), ACCOUNT_NOT_EXISTS);
  83 + }
  84 +
  85 + @Test
  86 + public void testDeleteAccount_success() {
  87 + // mock 数据
  88 + ErpAccountDO dbAccount = randomPojo(ErpAccountDO.class);
  89 + accountMapper.insert(dbAccount);// @Sql: 先插入出一条存在的数据
  90 + // 准备参数
  91 + Long id = dbAccount.getId();
  92 +
  93 + // 调用
  94 + accountService.deleteAccount(id);
  95 + // 校验数据不存在了
  96 + assertNull(accountMapper.selectById(id));
  97 + }
  98 +
  99 + @Test
  100 + public void testDeleteAccount_notExists() {
  101 + // 准备参数
  102 + Long id = randomLongId();
  103 +
  104 + // 调用, 并断言异常
  105 + assertServiceException(() -> accountService.deleteAccount(id), ACCOUNT_NOT_EXISTS);
  106 + }
  107 +
  108 + @Test
  109 + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
  110 + public void testGetAccountPage() {
  111 + // mock 数据
  112 + ErpAccountDO dbAccount = randomPojo(ErpAccountDO.class, o -> { // 等会查询到
  113 + o.setNo(null);
  114 + o.setRemark(null);
  115 + o.setStatus(null);
  116 + o.setName(null);
  117 + });
  118 + accountMapper.insert(dbAccount);
  119 + // 测试 no 不匹配
  120 + accountMapper.insert(cloneIgnoreId(dbAccount, o -> o.setNo(null)));
  121 + // 测试 remark 不匹配
  122 + accountMapper.insert(cloneIgnoreId(dbAccount, o -> o.setRemark(null)));
  123 + // 测试 status 不匹配
  124 + accountMapper.insert(cloneIgnoreId(dbAccount, o -> o.setStatus(null)));
  125 + // 测试 name 不匹配
  126 + accountMapper.insert(cloneIgnoreId(dbAccount, o -> o.setName(null)));
  127 + // 准备参数
  128 + ErpAccountPageReqVO reqVO = new ErpAccountPageReqVO();
  129 + reqVO.setNo(null);
  130 + reqVO.setRemark(null);
  131 + reqVO.setStatus(null);
  132 + reqVO.setName(null);
  133 +
  134 + // 调用
  135 + PageResult<ErpAccountDO> pageResult = accountService.getAccountPage(reqVO);
  136 + // 断言
  137 + assertEquals(1, pageResult.getTotal());
  138 + assertEquals(1, pageResult.getList().size());
  139 + assertPojoEquals(dbAccount, pageResult.getList().get(0));
  140 + }
  141 +
  142 +}
0 \ No newline at end of file 143 \ No newline at end of file