feat(dealer): 添加经销商账款明细管理功能

- 创建经销商账款明细控制器,提供完整的CRUD接口
- 定义经销商账款明细服务接口和实现类
- 添加创建、查询、更新、删除经销商账款明细的数据传输对象
- 实现经销商账款明细的领域实体和网关接口
- 集成订单发货单的应收金额和调整总额字段
- 添加分页查询中发货时间范围筛选功能
- 实现经销商账款明细的数据访问对象和转换器
This commit is contained in:
shenyifei 2026-01-09 18:02:23 +08:00
parent a6f3195190
commit 00efacd14c
38 changed files with 1686 additions and 0 deletions

87
.claude/rules/project.md Normal file
View File

@ -0,0 +1,87 @@
---
paths: erp-turbo-*/**/*.java
---
# ERPTurbo 项目规则
## 模块架构
ERPTurbo 项目包含两个主要模块:
- **erp-turbo-business** - 主要业务模块(**仅操作此模块**
- **erp-turbo-svc** - 旧版服务模块(**禁止操作**
### 重要规则
⚠️ **绝对不要修改 `erp-turbo-svc` 模块下的任何文件**
所有代码变更都应该在 `erp-turbo-business` 模块中进行。
## 目录结构
```
ERPTurbo_Server/
├── erp-turbo-business/ # 主业务模块 ✅ 可操作
│ ├── erp-turbo-biz/ # 业务逻辑层
│ │ ├── src/main/java/
│ │ │ ├── domain/ # 领域层
│ │ │ ├── app/ # 应用层
│ │ │ └── infrastructure/ # 基础设施层
│ └── erp-turbo-api/ # API 定义层
└── erp-turbo-svc/ # 聚合服务模块自动生成 ❌ 禁止操作
├── erp-turbo-biz/
└── erp-turbo-api/
```
## 文件路径规范
在进行字段添加、枚举添加等操作时,**仅处理以下路径**
### API 层erp-turbo-business/erp-turbo-api
```
erp-turbo-common/erp-turbo-api/src/main/java/com/xunhong/erp/turbo/api/biz/dto/
├── cmd/ # 命令对象CreateCmd, UpdateCmd, DestroyCmd
├── vo/ # 视图对象
├── qry/ # 查询对象
├── common/ # 通用对象
└── enums/ # 枚举类
```
### Domain 层erp-turbo-business/erp-turbo-biz
```
erp-turbo-business/erp-turbo-biz/src/main/java/com/xunhong/erp/turbo/biz/
├── domain/ # 领域实体
└── infrastructure/
├── entity/ # DO 实体
├── mapper/ # MyBatis Mapper
└── convert/ # 对象转换器
```
### 禁止操作的路径
```
❌ erp-turbo-svc/
```
## 示例
### ✅ 正确操作
添加字段到 OrderShip
- `erp-turbo-business/erp-turbo-biz/.../entity/OrderShipDO.java`
- `erp-turbo-business/erp-turbo-biz/.../domain/entity/OrderShip.java`
- `erp-turbo-common/erp-turbo-api/.../vo/OrderShipVO.java`
### ❌ 错误操作
- `erp-turbo-svc/erp-turbo-biz/.../entity/OrderShipDO.java`
- `erp-turbo-svc/erp-turbo-biz/.../domain/entity/OrderShip.java`
## 文件搜索策略
使用 Glob/Grep 工具时,应排除 `erp-turbo-svc` 目录:
```bash
# 错误示例
**/*OrderShip*.java
# 正确示例(使用路径限制)
erp-turbo-business/**/*OrderShip*.java
```

View File

@ -0,0 +1,201 @@
---
name: "Add Enum Field"
description: "Add enum field to ERPTurbo project entities following DDD layered architecture. Automatically creates enum class, updates DO, VO, Cmd, and Domain Entity with proper type mapping and MyBatis annotations."
---
# Add Enum Field
为 ERPTurbo 项目实体添加枚举字段,遵循 DDD 分层架构规范。
## ⚠️ 重要规则
**仅操作 `erp-turbo-business` 模块,禁止修改 `erp-turbo-svc` 模块!**
详见:`.claude/PROJECT_RULES.md`
## 工作流程
## 输入格式
```
Enum: EnumName | value1:description1, value2:description2, ... | fieldName | fieldComment
```
**示例:**
```
Enum: DealerAccountRecordTargetType | 1:产地采购发货单,2:市场采购发货单,3:市场调货发货单 | targetType | 变动类型
```
## 工作流程
### 1. 创建枚举类
路径:`erp-turbo-api/src/main/java/com/xunhong/erp/turbo/api/biz/dto/enums/`
```java
@Getter
@RequiredArgsConstructor
public enum YourEnumName {
VALUE1(1, "描述1"),
VALUE2(2, "描述2");
@EnumValue
private final Integer type;
private final String message;
}
```
### 2. 更新相关文件(仅限 erp-turbo-business 模块)
| 文件路径 | 类型 | 修改内容 |
|---------|------|---------|
| `erp-turbo-business/erp-turbo-biz/.../entity/*DO.java` | Entity | 添加枚举类型字段 + `@TableField` |
| `erp-turbo-common/erp-turbo-api/.../vo/*VO.java` | VO | 添加枚举类型字段 + `@Schema` |
| `erp-turbo-common/erp-turbo-api/.../cmd/*CreateCmd.java` | CMD | 添加枚举类型字段 + `@Schema` |
| `erp-turbo-common/erp-turbo-api/.../cmd/*UpdateCmd.java` | CMD | 添加枚举类型字段 + `@Schema` |
| `erp-turbo-business/erp-turbo-biz/.../domain/entity/*.java` | Domain Entity | 添加枚举类型字段 |
⚠️ **禁止修改** `erp-turbo-svc/` 下的任何文件!
### 3. 生成 DDL
```sql
ALTER TABLE table_name
ADD COLUMN field_name TINYINT COMMENT 'field comment';
```
## 枚举设计规范
### 基本结构
```java
package com.xunhong.erp.turbo.api.biz.dto.enums;
import com.baomidou.mybatisplus.annotation.EnumValue;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@Getter
@RequiredArgsConstructor
public enum YourEnum {
/**
* 枚举值1
*/
VALUE1(1, "描述1"),
/**
* 枚举值2
*/
VALUE2(2, "描述2");
@EnumValue
private final Integer type;
private final String message;
}
```
### 实用方法(可选)
```java
/**
* 根据类型值获取枚举
*/
public static YourEnum fromType(Integer type) {
if (type == null) {
return null;
}
for (YourEnum value : values()) {
if (value.type.equals(type)) {
return value;
}
}
return null;
}
/**
* 根据其他枚举转换
*/
public static YourEnum fromOtherEnum(OtherEnum other) {
if (other == null) {
return null;
}
return switch (other) {
case OTHER_VALUE1 -> VALUE1;
case OTHER_VALUE2 -> VALUE2;
default -> null;
};
}
```
## 数据库类型映射
| 枚举值数量 | 数据库类型 | Java 类型 |
|----------|----------|----------|
| 1-10 | `TINYINT` | `Integer` + 枚举 |
| 11-100 | `SMALLINT` | `Integer` + 枚举 |
| 100+ | `INT` | `Integer` + 枚举 |
## 使用示例
### 示例 1简单状态枚举
```
Enum: AuditState | 1:待审核,2:审核中,3:审核成功,4:审核驳回,5:审核取消 | state | 审核状态
```
### 示例 2带转换方法的枚举
```
Enum: DealerAccountRecordTargetType | 1:产地采购发货单,2:市场采购发货单,3:市场调货发货单 | targetType | 变动类型
```
## 注意事项
1. **@EnumValue 注解**MyBatis-Plus 需要此注解来识别数据库存储的枚举值
2. **Integer 类型**:枚举的存储值使用 `Integer` 而非 `int`,避免空值问题
3. **命名规范**
- 枚举类名:`PascalCase` + `Enum` 后缀(可选)
- 枚举值:`UPPER_SNAKE_CASE`
4. **null 处理**:转换方法中正确处理 null 值
5. **业务逻辑**:复杂转换逻辑放在枚举类的静态方法中,保持业务代码整洁
## 输出示例
```
✅ 已完成枚举字段添加
========================================
创建文件:
✅ api/.../enums/YourEnum.java (erp-turbo-common)
更新文件:
✅ biz/.../entity/YourEntityDO.java (erp-turbo-business)
✅ api/.../vo/YourEntityVO.java (erp-turbo-common)
✅ api/.../cmd/YourEntityCreateCmd.java (erp-turbo-common)
✅ api/.../cmd/YourEntityUpdateCmd.java (erp-turbo-common)
✅ biz/.../domain/entity/YourEntity.java (erp-turbo-business)
⚠️ 请执行数据库迁移:
ALTER TABLE your_table
ADD COLUMN your_field TINYINT COMMENT 'your comment';
```
## 文件搜索规则
使用 Glob 工具时,**必须限制在 erp-turbo-business 模块**
```bash
# ✅ 正确:限定路径
erp-turbo-business/**/*.java
erp-turbo-common/**/*.java
# ❌ 错误:会匹配到 svc 模块
**/*OrderShip*.java
```
使用 Grep 工具时,**排除 erp-turbo-svc 目录**
```bash
# ✅ 正确:指定路径
grep -r "pattern" erp-turbo-business/ erp-turbo-common/
# ❌ 错误:搜索所有目录
grep -r "pattern" .
```

View File

@ -0,0 +1,78 @@
---
name: "Add Database Field"
description: "Standardized field addition tool for ERPTurbo project. Automatically adds fields to DO, VO, Cmd, and Domain Entity classes with proper type mapping, annotations, and generates DDL migration script. Supports snake_case to camelCase conversion, BigDecimal for decimal types, and proper Java imports."
---
# Add Database Field
Add fields to ERPTurbo project entities following the standard DDD layered architecture.
## ⚠️ 重要规则
**仅操作 `erp-turbo-business` 模块,禁止修改 `erp-turbo-svc` 模块!**
详见:`.claude/PROJECT_RULES.md`
## Workflow
## Input Format
Provide field information in this format:
```markdown
Field: field_name | java_type | default_value | comment
```
**Example:**
```
Field: receivable_amount | BigDecimal | 0.00 | 应收金额(元)
Field: adjusted_amount | BigDecimal | 0.00 | 调整总额(元)
```
## Supported Java Types
| Database Type | Java Type | Import |
|---------------|-----------|--------|
| DECIMAL(p,s) | BigDecimal | `java.math.BigDecimal` |
| INT / BIGINT | Long | (primitive) |
| VARCHAR | String | (primitive) |
| DATETIME | LocalDateTime | `java.time.LocalDateTime` |
| DATE | LocalDate | `java.time.LocalDate` |
| BOOLEAN / TINYINT | Boolean | (primitive) |
| DOUBLE / FLOAT | Double | (primitive) |
## Workflow
1. **Locate Entity File**: Find `*DO.java` in `erp-turbo-business/erp-turbo-biz/.../infrastructure/entity/` **跳过 erp-turbo-svc**
2. **Find Related Files**: Locate corresponding VO, Cmd, common DTO, and domain Entity files**仅在 erp-turbo-business 模块**
3. **Add Import**: Add `java.math.BigDecimal` if needed
4. **Add Field**: Insert after `remark` field with proper annotations:
- DO: `@TableField(value = "snake_case_name")`
- VO: `@Schema(title = "comment")`
- Cmd: `@Schema(title = "comment")`
- Domain Entity: No annotations
5. **Generate DDL**: Output migration script
## Output Example
```
✅ 已完成字段添加
========================================
文件变更:
✅ biz/.../entity/OrderShipDO.java
✅ api/.../vo/OrderShipVO.java
✅ api/.../cmd/OrderShipCreateCmd.java
✅ api/.../cmd/OrderShipUpdateCmd.java
✅ api/.../common/OrderShip.java
✅ biz/.../domain/entity/OrderShip.java
⚠️ 请执行数据库迁移:
ALTER TABLE order_ship
ADD COLUMN receivable_amount DECIMAL(16, 2) DEFAULT 0.00 NULL COMMENT '应收金额(元)',
ADD COLUMN adjusted_amount DECIMAL(16, 2) DEFAULT 0.00 NULL COMMENT '调整总额(元)';
```
## Naming Convention
- **Database**: snake_case (e.g., `receivable_amount`)
- **Java**: camelCase (e.g., `receivableAmount`)
- **Comment**: Chinese description with unit if applicable

View File

@ -0,0 +1,79 @@
package com.xunhong.erp.turbo.admin.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import com.alibaba.cola.dto.MultiResponse;
import com.alibaba.cola.dto.PageResponse;
import com.alibaba.cola.dto.Response;
import com.alibaba.cola.dto.SingleResponse;
import com.xunhong.erp.turbo.api.biz.api.DealerAccountRecordServiceI;
import com.xunhong.erp.turbo.api.biz.dto.cmd.DealerAccountRecordCreateCmd;
import com.xunhong.erp.turbo.api.biz.dto.cmd.DealerAccountRecordDestroyCmd;
import com.xunhong.erp.turbo.api.biz.dto.cmd.DealerAccountRecordUpdateCmd;
import com.xunhong.erp.turbo.api.biz.dto.qry.DealerAccountRecordListQry;
import com.xunhong.erp.turbo.api.biz.dto.qry.DealerAccountRecordPageQry;
import com.xunhong.erp.turbo.api.biz.dto.qry.DealerAccountRecordShowQry;
import com.xunhong.erp.turbo.api.biz.dto.vo.DealerAccountRecordVO;
import com.xunhong.erp.turbo.base.dto.PageDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
/**
* @author shenyifei
*/
@Tag(name = "DealerAccountRecord", description = "经销商账款明细管理")
@RestController("operationDealerAccountRecordController")
@RequestMapping(value = "/operation")
@RequiredArgsConstructor
public class DealerAccountRecordController {
@DubboReference(version = "1.0.0")
private final DealerAccountRecordServiceI dealerAccountRecordService;
@SaCheckLogin
@GetMapping("listDealerAccountRecord")
@Operation(summary = "经销商账款明细列表", method = "GET")
public MultiResponse<DealerAccountRecordVO> listDealerAccountRecord(@ModelAttribute @Validated DealerAccountRecordListQry dealerAccountRecordListQry) {
return MultiResponse.of(dealerAccountRecordService.list(dealerAccountRecordListQry));
}
@SaCheckLogin
@PostMapping("createDealerAccountRecord")
@Operation(summary = "创建经销商账款明细", method = "POST")
public SingleResponse<DealerAccountRecordVO> createDealerAccountRecord(@RequestBody @Validated DealerAccountRecordCreateCmd dealerAccountRecordCreateCmd) {
return SingleResponse.of(dealerAccountRecordService.create(dealerAccountRecordCreateCmd));
}
@SaCheckLogin
@GetMapping("showDealerAccountRecord")
@Operation(summary = "经销商账款明细详情", method = "GET")
public SingleResponse<DealerAccountRecordVO> showDealerAccountRecord(@ModelAttribute @Validated DealerAccountRecordShowQry dealerAccountRecordShowQry) {
return SingleResponse.of(dealerAccountRecordService.show(dealerAccountRecordShowQry));
}
@SaCheckLogin
@GetMapping("pageDealerAccountRecord")
@Operation(summary = "经销商账款明细列表", method = "GET")
public PageResponse<DealerAccountRecordVO> pageDealerAccountRecord(@ModelAttribute @Validated DealerAccountRecordPageQry dealerAccountRecordPageQry) {
PageDTO<DealerAccountRecordVO> page = dealerAccountRecordService.page(dealerAccountRecordPageQry);
return PageResponse.of(page.getRecords(), (int) page.getTotal(), (int) page.getSize(), (int) page.getCurrent());
}
@SaCheckLogin
@RequestMapping(value = "updateDealerAccountRecord", method = {RequestMethod.PATCH, RequestMethod.PUT})
@Operation(summary = "经销商账款明细更新", method = "PATCH")
public SingleResponse<DealerAccountRecordVO> updateDealerAccountRecord(@RequestBody @Validated DealerAccountRecordUpdateCmd dealerAccountRecordUpdateCmd) {
return SingleResponse.of(dealerAccountRecordService.update(dealerAccountRecordUpdateCmd));
}
@SaCheckLogin
@DeleteMapping("destroyDealerAccountRecord")
@Operation(summary = "经销商账款明细删除", method = "DELETE")
public Response destroyDealerAccountRecord(@RequestBody @Validated DealerAccountRecordDestroyCmd dealerAccountRecordDestroyCmd) {
dealerAccountRecordService.destroy(dealerAccountRecordDestroyCmd);
return Response.buildSuccess();
}
}

View File

@ -0,0 +1,19 @@
package com.xunhong.erp.turbo.biz.app.assembler;
import com.xunhong.erp.turbo.api.biz.dto.vo.DealerAccountRecordVO;
import com.xunhong.erp.turbo.biz.domain.entity.DealerAccountRecord;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.NullValueCheckStrategy;
/**
* @author shenyifei
*/
@Mapper(componentModel = "spring", nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, uses = {OrderAssembler.class})
public interface DealerAccountRecordAssembler {
@Mapping(target = "orderVO", source = "order")
@Mapping(target = "orderShipVO", source = "orderShip")
@Mapping(target = "dealerVO", source = "dealer")
DealerAccountRecordVO toDealerAccountRecordVO(DealerAccountRecord dealerAccountRecord);
}

View File

@ -0,0 +1,29 @@
package com.xunhong.erp.turbo.biz.app.executor.cmd;
import com.xunhong.erp.turbo.api.biz.dto.cmd.DealerAccountRecordCreateCmd;
import com.xunhong.erp.turbo.api.biz.dto.vo.DealerAccountRecordVO;
import com.xunhong.erp.turbo.biz.app.assembler.DealerAccountRecordAssembler;
import com.xunhong.erp.turbo.biz.domain.entity.DealerAccountRecord;
import com.xunhong.erp.turbo.biz.domain.gateway.DealerAccountRecordGateway;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* @author shenyifei
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class DealerAccountRecordCreateCmdExe {
private final DealerAccountRecordAssembler dealerAccountRecordAssembler;
private final DealerAccountRecordGateway dealerAccountRecordGateway;
public DealerAccountRecordVO execute(DealerAccountRecordCreateCmd dealerAccountRecordCreateCmd) {
DealerAccountRecord dealerAccountRecord = dealerAccountRecordGateway.save(dealerAccountRecordCreateCmd);
return dealerAccountRecordAssembler.toDealerAccountRecordVO(dealerAccountRecord);
}
}

View File

@ -0,0 +1,22 @@
package com.xunhong.erp.turbo.biz.app.executor.cmd;
import com.xunhong.erp.turbo.api.biz.dto.cmd.DealerAccountRecordDestroyCmd;
import com.xunhong.erp.turbo.biz.domain.gateway.DealerAccountRecordGateway;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* @author shenyifei
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class DealerAccountRecordDestroyCmdExe {
private final DealerAccountRecordGateway dealerAccountRecordGateway;
public void execute(DealerAccountRecordDestroyCmd dealerAccountRecordDestroyCmd) {
dealerAccountRecordGateway.destroy(dealerAccountRecordDestroyCmd);
}
}

View File

@ -0,0 +1,27 @@
package com.xunhong.erp.turbo.biz.app.executor.cmd;
import com.xunhong.erp.turbo.api.biz.dto.cmd.DealerAccountRecordUpdateCmd;
import com.xunhong.erp.turbo.api.biz.dto.vo.DealerAccountRecordVO;
import com.xunhong.erp.turbo.biz.app.assembler.DealerAccountRecordAssembler;
import com.xunhong.erp.turbo.biz.domain.entity.DealerAccountRecord;
import com.xunhong.erp.turbo.biz.domain.gateway.DealerAccountRecordGateway;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* @author shenyifei
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class DealerAccountRecordUpdateCmdExe {
private final DealerAccountRecordAssembler dealerAccountRecordAssembler;
private final DealerAccountRecordGateway dealerAccountRecordGateway;
public DealerAccountRecordVO execute(DealerAccountRecordUpdateCmd dealerAccountRecordUpdateCmd) {
DealerAccountRecord dealerAccountRecord = dealerAccountRecordGateway.update(dealerAccountRecordUpdateCmd);
return dealerAccountRecordAssembler.toDealerAccountRecordVO(dealerAccountRecord);
}
}

View File

@ -0,0 +1,30 @@
package com.xunhong.erp.turbo.biz.app.executor.query;
import com.xunhong.erp.turbo.api.biz.dto.qry.DealerAccountRecordListQry;
import com.xunhong.erp.turbo.api.biz.dto.vo.DealerAccountRecordVO;
import com.xunhong.erp.turbo.biz.app.assembler.DealerAccountRecordAssembler;
import com.xunhong.erp.turbo.biz.domain.entity.DealerAccountRecord;
import com.xunhong.erp.turbo.biz.domain.gateway.DealerAccountRecordGateway;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author shenyifei
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class DealerAccountRecordListQryExe {
private final DealerAccountRecordGateway dealerAccountRecordGateway;
private final DealerAccountRecordAssembler dealerAccountRecordAssembler;
public List<DealerAccountRecordVO> execute(DealerAccountRecordListQry dealerAccountRecordListQry) {
List<DealerAccountRecord> dealerAccountRecordList = dealerAccountRecordGateway.list(dealerAccountRecordListQry);
return dealerAccountRecordList.stream().map(dealerAccountRecordAssembler::toDealerAccountRecordVO).toList();
}
}

View File

@ -0,0 +1,29 @@
package com.xunhong.erp.turbo.biz.app.executor.query;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.xunhong.erp.turbo.api.biz.dto.qry.DealerAccountRecordPageQry;
import com.xunhong.erp.turbo.api.biz.dto.vo.DealerAccountRecordVO;
import com.xunhong.erp.turbo.biz.app.assembler.DealerAccountRecordAssembler;
import com.xunhong.erp.turbo.biz.domain.entity.DealerAccountRecord;
import com.xunhong.erp.turbo.biz.domain.gateway.DealerAccountRecordGateway;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* @author shenyifei
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class DealerAccountRecordPageQryExe {
private final DealerAccountRecordGateway dealerAccountRecordGateway;
private final DealerAccountRecordAssembler dealerAccountRecordAssembler;
public IPage<DealerAccountRecordVO> execute(DealerAccountRecordPageQry dealerAccountRecordPageQry) {
IPage<DealerAccountRecord> page = dealerAccountRecordGateway.page(dealerAccountRecordPageQry);
return page.convert(dealerAccountRecordAssembler::toDealerAccountRecordVO);
}
}

View File

@ -0,0 +1,29 @@
package com.xunhong.erp.turbo.biz.app.executor.query;
import com.xunhong.erp.turbo.api.biz.dto.qry.DealerAccountRecordShowQry;
import com.xunhong.erp.turbo.api.biz.dto.vo.DealerAccountRecordVO;
import com.xunhong.erp.turbo.biz.app.assembler.DealerAccountRecordAssembler;
import com.xunhong.erp.turbo.biz.domain.entity.DealerAccountRecord;
import com.xunhong.erp.turbo.biz.domain.gateway.DealerAccountRecordGateway;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* @author shenyifei
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class DealerAccountRecordShowQryExe {
private final DealerAccountRecordAssembler dealerAccountRecordAssembler;
private final DealerAccountRecordGateway dealerAccountRecordGateway;
public DealerAccountRecordVO execute(DealerAccountRecordShowQry dealerAccountRecordShowQry) {
DealerAccountRecord dealerAccountRecord = dealerAccountRecordGateway.show(dealerAccountRecordShowQry);
return dealerAccountRecordAssembler.toDealerAccountRecordVO(dealerAccountRecord);
}
}

View File

@ -0,0 +1,71 @@
package com.xunhong.erp.turbo.biz.app.service;
import com.xunhong.erp.turbo.api.biz.api.DealerAccountRecordServiceI;
import com.xunhong.erp.turbo.api.biz.dto.cmd.DealerAccountRecordCreateCmd;
import com.xunhong.erp.turbo.api.biz.dto.cmd.DealerAccountRecordDestroyCmd;
import com.xunhong.erp.turbo.api.biz.dto.cmd.DealerAccountRecordUpdateCmd;
import com.xunhong.erp.turbo.api.biz.dto.qry.DealerAccountRecordListQry;
import com.xunhong.erp.turbo.api.biz.dto.qry.DealerAccountRecordPageQry;
import com.xunhong.erp.turbo.api.biz.dto.qry.DealerAccountRecordShowQry;
import com.xunhong.erp.turbo.api.biz.dto.vo.DealerAccountRecordVO;
import com.xunhong.erp.turbo.base.dto.PageDTO;
import com.xunhong.erp.turbo.biz.app.executor.cmd.DealerAccountRecordCreateCmdExe;
import com.xunhong.erp.turbo.biz.app.executor.cmd.DealerAccountRecordDestroyCmdExe;
import com.xunhong.erp.turbo.biz.app.executor.cmd.DealerAccountRecordUpdateCmdExe;
import com.xunhong.erp.turbo.biz.app.executor.query.DealerAccountRecordListQryExe;
import com.xunhong.erp.turbo.biz.app.executor.query.DealerAccountRecordPageQryExe;
import com.xunhong.erp.turbo.biz.app.executor.query.DealerAccountRecordShowQryExe;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author shenyifei
*/
@Slf4j
@Service
@DubboService(interfaceClass = DealerAccountRecordServiceI.class, version = "1.0.0")
@RequiredArgsConstructor
public class DealerAccountRecordServiceImpl implements DealerAccountRecordServiceI {
private final DealerAccountRecordCreateCmdExe dealerAccountRecordCreateCmdExe;
private final DealerAccountRecordUpdateCmdExe dealerAccountRecordUpdateCmdExe;
private final DealerAccountRecordPageQryExe dealerAccountRecordPageQryExe;
private final DealerAccountRecordListQryExe dealerAccountRecordListQryExe;
private final DealerAccountRecordShowQryExe dealerAccountRecordShowQryExe;
private final DealerAccountRecordDestroyCmdExe dealerAccountRecordDestroyCmdExe;
@Override
public DealerAccountRecordVO create(DealerAccountRecordCreateCmd dealerAccountRecordCreateCmd) {
return dealerAccountRecordCreateCmdExe.execute(dealerAccountRecordCreateCmd);
}
@Override
public PageDTO<DealerAccountRecordVO> page(DealerAccountRecordPageQry dealerAccountRecordPageQry) {
return PageDTO.of(dealerAccountRecordPageQryExe.execute(dealerAccountRecordPageQry));
}
@Override
public List<DealerAccountRecordVO> list(DealerAccountRecordListQry dealerAccountRecordListQry) {
return dealerAccountRecordListQryExe.execute(dealerAccountRecordListQry);
}
@Override
public DealerAccountRecordVO update(DealerAccountRecordUpdateCmd dealerAccountRecordUpdateCmd) {
return dealerAccountRecordUpdateCmdExe.execute(dealerAccountRecordUpdateCmd);
}
@Override
public DealerAccountRecordVO show(DealerAccountRecordShowQry dealerAccountRecordShowQry) {
return dealerAccountRecordShowQryExe.execute(dealerAccountRecordShowQry);
}
@Override
public void destroy(DealerAccountRecordDestroyCmd dealerAccountRecordDestroyCmd) {
dealerAccountRecordDestroyCmdExe.execute(dealerAccountRecordDestroyCmd);
}
}

View File

@ -0,0 +1,82 @@
package com.xunhong.erp.turbo.biz.domain.entity;
import com.alibaba.cola.domain.Entity;
import com.alibaba.cola.dto.DTO;
import com.xunhong.erp.turbo.api.biz.dto.enums.DealerAccountRecordTargetTypeEnum;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* @author shenyifei
*/
@Data
@Entity
@EqualsAndHashCode(callSuper = true)
public class DealerAccountRecord extends DTO {
/**
* 应收账款明细ID
*/
private Long dealerAccountRecordId;
/**
* 流水编号
*/
private String recordSn;
/**
* 经销商ID
*/
private Long dealerId;
/**
* 订单ID
*/
private Long orderId;
/**
* 变动对象ID
*/
private Long targetId;
/**
* 变动类型:1-产地采购发货单2-市场采购发货单3-市场调货发货单
*/
private DealerAccountRecordTargetTypeEnum targetType;
/**
* 变动前金额
*/
private BigDecimal beforeAmount;
/**
* 变动金额
*/
private BigDecimal amount;
/**
* 变动后金额
*/
private BigDecimal afterAmount;
/**
* 备注
*/
private String remark;
/**
* 创建时间
*/
private LocalDateTime createdAt;
private Dealer dealer;
private Order order;
private OrderShip orderShip;
}

View File

@ -9,6 +9,7 @@ import com.xunhong.erp.turbo.api.biz.dto.enums.OrderShipTypeEnum;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
@ -116,6 +117,16 @@ public class OrderShip extends DTO {
*/ */
private String remark; private String remark;
/**
* 应收金额
*/
private BigDecimal receivableAmount;
/**
* 调整总额
*/
private BigDecimal adjustedAmount;
/** /**
* 创建人ID * 创建人ID
*/ */

View File

@ -0,0 +1,30 @@
package com.xunhong.erp.turbo.biz.domain.gateway;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.xunhong.erp.turbo.api.biz.dto.cmd.DealerAccountRecordCreateCmd;
import com.xunhong.erp.turbo.api.biz.dto.cmd.DealerAccountRecordDestroyCmd;
import com.xunhong.erp.turbo.api.biz.dto.cmd.DealerAccountRecordUpdateCmd;
import com.xunhong.erp.turbo.api.biz.dto.qry.DealerAccountRecordListQry;
import com.xunhong.erp.turbo.api.biz.dto.qry.DealerAccountRecordPageQry;
import com.xunhong.erp.turbo.api.biz.dto.qry.DealerAccountRecordShowQry;
import com.xunhong.erp.turbo.biz.domain.entity.DealerAccountRecord;
import java.util.List;
/**
* @author shenyifei
*/
public interface DealerAccountRecordGateway {
DealerAccountRecord save(DealerAccountRecordCreateCmd dealerAccountRecordCreateCmd);
IPage<DealerAccountRecord> page(DealerAccountRecordPageQry dealerAccountRecordPageQry);
List<DealerAccountRecord> list(DealerAccountRecordListQry dealerAccountRecordListQry);
DealerAccountRecord update(DealerAccountRecordUpdateCmd dealerAccountRecordUpdateCmd);
DealerAccountRecord show(DealerAccountRecordShowQry dealerAccountRecordShowQry);
void destroy(DealerAccountRecordDestroyCmd dealerAccountRecordDestroyCmd);
}

View File

@ -0,0 +1,41 @@
package com.xunhong.erp.turbo.biz.infrastructure.convert;
import com.xunhong.erp.turbo.api.biz.dto.cmd.DealerAccountRecordCreateCmd;
import com.xunhong.erp.turbo.api.biz.dto.cmd.DealerAccountRecordUpdateCmd;
import com.xunhong.erp.turbo.biz.domain.entity.DealerAccountRecord;
import com.xunhong.erp.turbo.biz.infrastructure.entity.DealerAccountRecordDO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import org.mapstruct.NullValueCheckStrategy;
/**
* @author shenyifei
*/
@Mapper(componentModel = "spring", nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, uses = {OrderConvert.class})
public interface DealerAccountRecordConvert {
@Mapping(target = "dealer", source = "dealerDO")
@Mapping(target = "orderShip", source = "orderShipDO")
@Mapping(target = "order", source = "orderDO")
DealerAccountRecord toDealerAccountRecord(DealerAccountRecordDO dealerAccountRecordDO);
@Mapping(target = "orderShipDO", ignore = true)
@Mapping(target = "orderDO", ignore = true)
@Mapping(target = "dealerDO", ignore = true)
@Mapping(target = "version", ignore = true)
@Mapping(target = "updatedAt", ignore = true)
@Mapping(target = "isDelete", ignore = true)
@Mapping(target = "createdAt", ignore = true)
DealerAccountRecordDO toDealerAccountRecordDO(DealerAccountRecordCreateCmd dealerAccountRecordCreateCmd);
@Mapping(target = "orderShipDO", ignore = true)
@Mapping(target = "orderDO", ignore = true)
@Mapping(target = "dealerDO", ignore = true)
@Mapping(target = "version", ignore = true)
@Mapping(target = "updatedAt", ignore = true)
@Mapping(target = "isDelete", ignore = true)
@Mapping(target = "createdAt", ignore = true)
void toDealerAccountRecordDO(@MappingTarget DealerAccountRecordDO dealerAccountRecordDO, DealerAccountRecordUpdateCmd dealerAccountRecordUpdateCmd);
}

View File

@ -0,0 +1,91 @@
package com.xunhong.erp.turbo.biz.infrastructure.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.xunhong.erp.turbo.api.biz.dto.enums.DealerAccountRecordTargetTypeEnum;
import com.xunhong.erp.turbo.datasource.domain.entity.BaseDO;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
/**
* @author shenyifei
*/
@Data
@TableName(value = "dealer_account_record")
@EqualsAndHashCode(callSuper = true)
public class DealerAccountRecordDO extends BaseDO<DealerAccountRecordDO> {
/**
* 应收账款明细ID
*/
@TableId(value = "dealer_account_record_id", type = IdType.ASSIGN_ID)
private Long dealerAccountRecordId;
/**
* 流水编号
*/
@TableField(value = "record_sn")
private String recordSn;
/**
* 经销商ID
*/
@TableField(value = "dealer_id")
private Long dealerId;
/**
* 订单ID
*/
@TableField(value = "order_id")
private Long orderId;
/**
* 变动对象ID
*/
@TableField(value = "target_id")
private Long targetId;
/**
* 变动类型:1-产地采购发货单2-市场采购发货单3-市场调货发货单
*/
@TableField(value = "target_type")
private DealerAccountRecordTargetTypeEnum targetType;
/**
* 变动前金额
*/
@TableField(value = "before_amount")
private BigDecimal beforeAmount;
/**
* 变动金额
*/
@TableField(value = "amount")
private BigDecimal amount;
/**
* 变动后金额
*/
@TableField(value = "after_amount")
private BigDecimal afterAmount;
/**
* 备注
*/
@TableField(value = "remark")
private String remark;
@TableField(exist = false)
private OrderDO orderDO;
@TableField(exist = false)
private DealerDO dealerDO;
@TableField(exist = false)
private OrderShipDO orderShipDO;
}

View File

@ -11,6 +11,7 @@ import com.xunhong.erp.turbo.datasource.domain.entity.BaseDO;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.List; import java.util.List;
@ -137,6 +138,18 @@ public class OrderShipDO extends BaseDO<OrderShipDO> {
@TableField(value = "remark") @TableField(value = "remark")
private String remark; private String remark;
/**
* 应收金额
*/
@TableField(value = "receivable_amount")
private BigDecimal receivableAmount;
/**
* 调整总额
*/
@TableField(value = "adjusted_amount")
private BigDecimal adjustedAmount;
/** /**
* 创建人ID * 创建人ID
*/ */

View File

@ -0,0 +1,144 @@
package com.xunhong.erp.turbo.biz.infrastructure.gateway;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xunhong.erp.turbo.api.biz.dto.cmd.DealerAccountRecordCreateCmd;
import com.xunhong.erp.turbo.api.biz.dto.cmd.DealerAccountRecordDestroyCmd;
import com.xunhong.erp.turbo.api.biz.dto.cmd.DealerAccountRecordUpdateCmd;
import com.xunhong.erp.turbo.api.biz.dto.enums.DealerAccountRecordTargetTypeEnum;
import com.xunhong.erp.turbo.api.biz.dto.qry.DealerAccountRecordListQry;
import com.xunhong.erp.turbo.api.biz.dto.qry.DealerAccountRecordPageQry;
import com.xunhong.erp.turbo.api.biz.dto.qry.DealerAccountRecordShowQry;
import com.xunhong.erp.turbo.biz.domain.entity.DealerAccountRecord;
import com.xunhong.erp.turbo.biz.domain.gateway.DealerAccountRecordGateway;
import com.xunhong.erp.turbo.biz.infrastructure.convert.DealerAccountRecordConvert;
import com.xunhong.erp.turbo.biz.infrastructure.entity.DealerAccountRecordDO;
import com.xunhong.erp.turbo.biz.infrastructure.entity.DealerDO;
import com.xunhong.erp.turbo.biz.infrastructure.entity.OrderDO;
import com.xunhong.erp.turbo.biz.infrastructure.entity.OrderShipDO;
import com.xunhong.erp.turbo.biz.infrastructure.mapper.DealerAccountRecordMapper;
import com.xunhong.erp.turbo.biz.infrastructure.mapper.DealerMapper;
import com.xunhong.erp.turbo.biz.infrastructure.mapper.OrderMapper;
import com.xunhong.erp.turbo.biz.infrastructure.mapper.OrderShipMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* @author shenyifei
*/
@Repository
@RequiredArgsConstructor
public class DealerAccountRecordGatewayImpl implements DealerAccountRecordGateway {
private final DealerAccountRecordMapper dealerAccountRecordMapper;
private final DealerAccountRecordConvert dealerAccountRecordConvert;
private final OrderMapper orderMapper;
private final DealerMapper dealerMapper;
private final OrderShipMapper orderShipMapper;
@Override
public DealerAccountRecord save(DealerAccountRecordCreateCmd dealerAccountRecordCreateCmd) {
DealerAccountRecordDO dealerAccountRecordDO = dealerAccountRecordConvert.toDealerAccountRecordDO(dealerAccountRecordCreateCmd);
dealerAccountRecordMapper.insert(dealerAccountRecordDO);
return dealerAccountRecordConvert.toDealerAccountRecord(dealerAccountRecordDO);
}
@Override
public IPage<DealerAccountRecord> page(DealerAccountRecordPageQry dealerAccountRecordPageQry) {
LambdaQueryWrapper<DealerAccountRecordDO> queryWrapper = Wrappers.lambdaQuery(DealerAccountRecordDO.class);
queryWrapper.eq(Objects.nonNull(dealerAccountRecordPageQry.getDealerAccountRecordId()), DealerAccountRecordDO::getDealerAccountRecordId, dealerAccountRecordPageQry.getDealerAccountRecordId());
queryWrapper.eq(Objects.nonNull(dealerAccountRecordPageQry.getDealerId()), DealerAccountRecordDO::getDealerId, dealerAccountRecordPageQry.getDealerId());
queryWrapper.eq(Objects.nonNull(dealerAccountRecordPageQry.getOrderId()), DealerAccountRecordDO::getOrderId, dealerAccountRecordPageQry.getOrderId());
queryWrapper.eq(Objects.nonNull(dealerAccountRecordPageQry.getTargetType()), DealerAccountRecordDO::getTargetType, dealerAccountRecordPageQry.getTargetType());
queryWrapper.eq(Objects.nonNull(dealerAccountRecordPageQry.getTargetId()), DealerAccountRecordDO::getTargetId, dealerAccountRecordPageQry.getTargetId());
queryWrapper.like(StrUtil.isNotBlank(dealerAccountRecordPageQry.getRecordSn()), DealerAccountRecordDO::getRecordSn, dealerAccountRecordPageQry.getRecordSn());
queryWrapper.like(StrUtil.isNotBlank(dealerAccountRecordPageQry.getRemark()), DealerAccountRecordDO::getRemark, dealerAccountRecordPageQry.getRemark());
queryWrapper.orderByDesc(DealerAccountRecordDO::getCreatedAt);
IPage<DealerAccountRecordDO> page = new Page<>(dealerAccountRecordPageQry.getPageIndex(), dealerAccountRecordPageQry.getPageSize());
page = dealerAccountRecordMapper.selectPage(page, queryWrapper);
Set<Long> orderIdList = page.getRecords().stream().map(DealerAccountRecordDO::getOrderId).collect(Collectors.toSet());
if (CollUtil.isNotEmpty(orderIdList)) {
List<OrderDO> orderDOList = orderMapper.selectByOrderIdList(orderIdList);
Map<Long, OrderDO> orderDOMap = orderDOList.stream().collect(Collectors.toMap(OrderDO::getOrderId, Function.identity()));
page.getRecords().forEach(dealerAccountRecordDO -> dealerAccountRecordDO.setOrderDO(orderDOMap.get(dealerAccountRecordDO.getOrderId())));
}
Set<Long> dealerIdList = page.getRecords().stream().map(DealerAccountRecordDO::getDealerId).collect(Collectors.toSet());
if (CollUtil.isNotEmpty(dealerIdList)) {
List<DealerDO> dealerDOList = dealerMapper.selectByIds(dealerIdList);
Map<Long, DealerDO> dealerDOMap = dealerDOList.stream().collect(Collectors.toMap(DealerDO::getDealerId, Function.identity()));
page.getRecords().forEach(dealerAccountRecordDO -> dealerAccountRecordDO.setDealerDO(dealerDOMap.get(dealerAccountRecordDO.getDealerId())));
}
Set<Long> orderShipIdList = page.getRecords().stream().filter(dealerAccountRecordDO -> {
return dealerAccountRecordDO.getTargetType().equals(DealerAccountRecordTargetTypeEnum.MARKET_PURCHASE_SHIP)
|| dealerAccountRecordDO.getTargetType().equals(DealerAccountRecordTargetTypeEnum.MARKET_TRANSFER_SHIP)
|| dealerAccountRecordDO.getTargetType().equals(DealerAccountRecordTargetTypeEnum.ORIGIN_PURCHASE_SHIP);
}).map(DealerAccountRecordDO::getTargetId).collect(Collectors.toSet());
if (CollUtil.isNotEmpty(orderShipIdList)) {
List<OrderShipDO> orderShipDOList = orderShipMapper.selectByIds(orderShipIdList);
Map<Long, OrderShipDO> orderShipDOMap = orderShipDOList.stream().collect(Collectors.toMap(OrderShipDO::getOrderShipId, Function.identity()));
page.getRecords().forEach(dealerAccountRecordDO -> dealerAccountRecordDO.setOrderShipDO(orderShipDOMap.get(dealerAccountRecordDO.getTargetId())));
}
return page.convert(dealerAccountRecordConvert::toDealerAccountRecord);
}
@Override
public List<DealerAccountRecord> list(DealerAccountRecordListQry dealerAccountRecordListQry) {
LambdaQueryWrapper<DealerAccountRecordDO> queryWrapper = Wrappers.lambdaQuery(DealerAccountRecordDO.class);
List<DealerAccountRecordDO> dealerAccountRecordDOList = dealerAccountRecordMapper.selectList(queryWrapper);
return dealerAccountRecordDOList.stream().map(dealerAccountRecordConvert::toDealerAccountRecord).toList();
}
@Override
public DealerAccountRecord update(DealerAccountRecordUpdateCmd dealerAccountRecordUpdateCmd) {
LambdaQueryWrapper<DealerAccountRecordDO> queryWrapper = Wrappers.lambdaQuery(DealerAccountRecordDO.class);
queryWrapper.eq(DealerAccountRecordDO::getDealerAccountRecordId, dealerAccountRecordUpdateCmd.getDealerAccountRecordId());
queryWrapper.last("limit 1");
DealerAccountRecordDO dealerAccountRecordDO = dealerAccountRecordMapper.selectOne(queryWrapper);
dealerAccountRecordConvert.toDealerAccountRecordDO(dealerAccountRecordDO, dealerAccountRecordUpdateCmd);
dealerAccountRecordMapper.updateById(dealerAccountRecordDO);
return dealerAccountRecordConvert.toDealerAccountRecord(dealerAccountRecordDO);
}
@Override
public DealerAccountRecord show(DealerAccountRecordShowQry dealerAccountRecordShowQry) {
LambdaQueryWrapper<DealerAccountRecordDO> queryWrapper = Wrappers.lambdaQuery(DealerAccountRecordDO.class);
queryWrapper.eq(DealerAccountRecordDO::getDealerAccountRecordId, dealerAccountRecordShowQry.getDealerAccountRecordId());
queryWrapper.last("limit 1");
DealerAccountRecordDO dealerAccountRecordDO = dealerAccountRecordMapper.selectOne(queryWrapper);
return dealerAccountRecordConvert.toDealerAccountRecord(dealerAccountRecordDO);
}
@Override
public void destroy(DealerAccountRecordDestroyCmd dealerAccountRecordDestroyCmd) {
LambdaQueryWrapper<DealerAccountRecordDO> queryWrapper = Wrappers.lambdaQuery(DealerAccountRecordDO.class);
queryWrapper.eq(DealerAccountRecordDO::getDealerAccountRecordId, dealerAccountRecordDestroyCmd.getDealerAccountRecordId());
queryWrapper.last("limit 1");
DealerAccountRecordDO dealerAccountRecordDO = dealerAccountRecordMapper.selectOne(queryWrapper);
dealerAccountRecordDO.deleteById();
}
}

View File

@ -68,6 +68,8 @@ public class OrderGatewayImpl implements OrderGateway {
private final DealerMapper dealerMapper; private final DealerMapper dealerMapper;
private final SupplierInvoiceMapper supplierInvoiceMapper; private final SupplierInvoiceMapper supplierInvoiceMapper;
private final DealerAccountRecordMapper dealerAccountRecordMapper;
@Override @Override
@Transactional @Transactional
public Order save(OrderCreateCmd orderCreateCmd) { public Order save(OrderCreateCmd orderCreateCmd) {
@ -632,6 +634,86 @@ public class OrderGatewayImpl implements OrderGateway {
updateWrapper.eq(OrderShipDO::getOrderId, orderDO.getOrderId()); updateWrapper.eq(OrderShipDO::getOrderId, orderDO.getOrderId());
updateWrapper.set(OrderShipDO::getState, OrderShipStateEnum.WAIT_PAYMENT); updateWrapper.set(OrderShipDO::getState, OrderShipStateEnum.WAIT_PAYMENT);
orderShipMapper.update(null, updateWrapper); orderShipMapper.update(null, updateWrapper);
// 批量创建经销商应收账款明细
createDealerAccountRecords(orderDO);
}
/**
* 创建经销商应收账款明细
* 在老板审批通过后根据发货单的应收金额生成应收账款明细
*
* @param orderDO 订单ID
*/
private void createDealerAccountRecords(OrderDO orderDO) {
// 查询该订单的所有发货单
LambdaQueryWrapper<OrderShipDO> shipQueryWrapper = Wrappers.lambdaQuery(OrderShipDO.class);
shipQueryWrapper.eq(OrderShipDO::getOrderId, orderDO.getOrderId());
List<OrderShipDO> orderShipDOList = orderShipMapper.selectList(shipQueryWrapper);
if (CollUtil.isEmpty(orderShipDOList)) {
return;
}
// 按经销商分组避免同一经销商的记录重复计算
Map<Long, List<OrderShipDO>> dealerShipMap = orderShipDOList.stream()
.filter(ship -> ship.getReceivableAmount() != null && ship.getReceivableAmount().compareTo(BigDecimal.ZERO) > 0)
.collect(Collectors.groupingBy(OrderShipDO::getDealerId));
// 为每个经销商创建应收账款明细
for (Map.Entry<Long, List<OrderShipDO>> entry : dealerShipMap.entrySet()) {
Long dealerId = entry.getKey();
List<OrderShipDO> ships = entry.getValue();
// 计算该经销商的总应收金额
BigDecimal totalReceivableAmount = ships.stream()
.map(OrderShipDO::getReceivableAmount)
.reduce(BigDecimal.ZERO, BigDecimal::add);
// 获取经销商当前应收金额变动前金额
DealerDO dealerDO = dealerMapper.selectById(dealerId);
if (dealerDO == null) {
continue;
}
BigDecimal beforeAmount = dealerDO.getReceivable() != null ? dealerDO.getReceivable() : BigDecimal.ZERO;
// 计算变动后金额
BigDecimal afterAmount = beforeAmount.add(totalReceivableAmount);
// 更新经销商的应收金额
dealerDO.setReceivable(afterAmount);
dealerMapper.updateById(dealerDO);
// 为每个发货单创建应收账款明细
for (OrderShipDO ship : ships) {
// 获取该经销商在该发货单之前的累计金额之前已处理的发货单
BigDecimal shipBeforeAmount = beforeAmount.add(
ships.stream()
.filter(s -> s.getOrderShipId().compareTo(ship.getOrderShipId()) < 0)
.map(OrderShipDO::getReceivableAmount)
.reduce(BigDecimal.ZERO, BigDecimal::add)
);
BigDecimal shipAfterAmount = shipBeforeAmount.add(ship.getReceivableAmount());
// 创建应收账款明细
DealerAccountRecordDO recordDO = new DealerAccountRecordDO();
recordDO.setRecordSn("AR" + java.time.LocalDate.now().format(java.time.format.DateTimeFormatter.BASIC_ISO_DATE)
+ String.format("%04d", System.currentTimeMillis() % 10000));
recordDO.setDealerId(dealerId);
recordDO.setOrderId(orderDO.getOrderId());
recordDO.setTargetId(ship.getOrderShipId());
// 根据 OrderShipTypeEnum 和订单类型设置 targetType
recordDO.setTargetType(DealerAccountRecordTargetTypeEnum.fromOrderShipType(ship.getType(), orderDO.getType()));
recordDO.setBeforeAmount(shipBeforeAmount);
recordDO.setAmount(ship.getReceivableAmount());
recordDO.setAfterAmount(shipAfterAmount);
recordDO.setRemark("发货单应收账款:" + ship.getOrderSn());
dealerAccountRecordMapper.insert(recordDO);
}
}
} }
/** /**

View File

@ -61,12 +61,20 @@ public class OrderShipGatewayImpl implements OrderShipGateway {
public IPage<OrderShip> page(OrderShipPageQry orderShipPageQry) { public IPage<OrderShip> page(OrderShipPageQry orderShipPageQry) {
LambdaQueryWrapper<OrderShipDO> queryWrapper = Wrappers.lambdaQuery(OrderShipDO.class); LambdaQueryWrapper<OrderShipDO> queryWrapper = Wrappers.lambdaQuery(OrderShipDO.class);
queryWrapper.like(StrUtil.isNotBlank(orderShipPageQry.getOrderSn()), OrderShipDO::getOrderSn, orderShipPageQry.getOrderSn()); queryWrapper.like(StrUtil.isNotBlank(orderShipPageQry.getOrderSn()), OrderShipDO::getOrderSn, orderShipPageQry.getOrderSn());
queryWrapper.eq(Objects.nonNull(orderShipPageQry.getDealerId()), OrderShipDO::getDealerId, orderShipPageQry.getDealerId());
queryWrapper.eq(Objects.nonNull(orderShipPageQry.getState()), OrderShipDO::getState, orderShipPageQry.getState()); queryWrapper.eq(Objects.nonNull(orderShipPageQry.getState()), OrderShipDO::getState, orderShipPageQry.getState());
queryWrapper.eq(Objects.nonNull(orderShipPageQry.getCreatedBy()), OrderShipDO::getCreatedBy, orderShipPageQry.getCreatedBy()); queryWrapper.eq(Objects.nonNull(orderShipPageQry.getCreatedBy()), OrderShipDO::getCreatedBy, orderShipPageQry.getCreatedBy());
if (CollUtil.isNotEmpty(orderShipPageQry.getShippingDate())) {
queryWrapper.ge(OrderShipDO::getShippingDate, orderShipPageQry.getShippingDate().get(0));
queryWrapper.le(OrderShipDO::getShippingDate, orderShipPageQry.getShippingDate().get(1));
}
queryWrapper.orderBy("shippingDate".equals(orderShipPageQry.getOrderBy()), orderShipPageQry.getOrderDirection().equals("asc"), OrderShipDO::getShippingDate);
queryWrapper.orderByDesc(OrderShipDO::getCreatedAt); queryWrapper.orderByDesc(OrderShipDO::getCreatedAt);
IPage<OrderShipDO> page = new Page<>(orderShipPageQry.getPageIndex(), orderShipPageQry.getPageSize()); IPage<OrderShipDO> page = new Page<>(orderShipPageQry.getPageIndex(), orderShipPageQry.getPageSize());
page = orderShipMapper.selectPage(page, queryWrapper); page = orderShipMapper.selectPage(page, queryWrapper);
Set<Long> orderIdList = page.getRecords().stream().map(OrderShipDO::getOrderId).collect(Collectors.toSet()); Set<Long> orderIdList = page.getRecords().stream().map(OrderShipDO::getOrderId).collect(Collectors.toSet());

View File

@ -0,0 +1,13 @@
package com.xunhong.erp.turbo.biz.infrastructure.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xunhong.erp.turbo.biz.infrastructure.entity.DealerAccountRecordDO;
import org.apache.ibatis.annotations.Mapper;
/**
* @author shenyifei
*/
@Mapper
public interface DealerAccountRecordMapper extends BaseMapper<DealerAccountRecordDO> {
}

View File

@ -0,0 +1,22 @@
<?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.xunhong.erp.turbo.biz.infrastructure.mapper.DealerAccountRecordMapper">
<resultMap id="BaseResultMap" type="com.xunhong.erp.turbo.biz.infrastructure.entity.DealerAccountRecordDO">
<result property="dealerAccountRecordId" column="dealer_account_record_id"/>
<result property="recordSn" column="record_sn"/>
<result property="dealerId" column="dealer_id"/>
<result property="orderId" column="order_id"/>
<result property="targetId" column="target_id"/>
<result property="targetType" column="target_type"/>
<result property="beforeAmount" column="before_amount"/>
<result property="amount" column="amount"/>
<result property="afterAmount" column="after_amount"/>
<result property="remark" column="remark"/>
<result property="createdAt" column="created_at"/>
<result property="createdAt" column="created_at"/>
<result property="updatedAt" column="updated_at"/>
<result property="isDelete" column="is_delete"/>
<result property="version" column="version"/>
</resultMap>
</mapper>

View File

@ -15,6 +15,10 @@
<result property="shippingAddress" column="shipping_address"/> <result property="shippingAddress" column="shipping_address"/>
<result property="receivingAddress" column="receiving_address"/> <result property="receivingAddress" column="receiving_address"/>
<result property="shippingDate" column="shipping_date"/> <result property="shippingDate" column="shipping_date"/>
<result property="dealerId" column="dealer_id"/>
<result property="dealerName" column="dealer_name"/>
<result property="receivableAmount" column="receivable_amount"/>
<result property="adjustedAmount" column="adjusted_amount"/>
<result property="estimatedArrivalDate" <result property="estimatedArrivalDate"
column="estimated_arrival_date"/> column="estimated_arrival_date"/>
<result property="watermelonGrade" column="watermelon_grade"/> <result property="watermelonGrade" column="watermelon_grade"/>

View File

@ -0,0 +1,30 @@
package com.xunhong.erp.turbo.api.biz.api;
import com.xunhong.erp.turbo.api.biz.dto.cmd.DealerAccountRecordCreateCmd;
import com.xunhong.erp.turbo.api.biz.dto.cmd.DealerAccountRecordDestroyCmd;
import com.xunhong.erp.turbo.api.biz.dto.cmd.DealerAccountRecordUpdateCmd;
import com.xunhong.erp.turbo.api.biz.dto.qry.DealerAccountRecordListQry;
import com.xunhong.erp.turbo.api.biz.dto.qry.DealerAccountRecordPageQry;
import com.xunhong.erp.turbo.api.biz.dto.qry.DealerAccountRecordShowQry;
import com.xunhong.erp.turbo.api.biz.dto.vo.DealerAccountRecordVO;
import com.xunhong.erp.turbo.base.dto.PageDTO;
import java.util.List;
/**
* @author shenyifei
*/
public interface DealerAccountRecordServiceI {
DealerAccountRecordVO create(DealerAccountRecordCreateCmd dealerAccountRecordCreateCmd);
PageDTO<DealerAccountRecordVO> page(DealerAccountRecordPageQry dealerAccountRecordPageQry);
List<DealerAccountRecordVO> list(DealerAccountRecordListQry dealerAccountRecordListQry);
DealerAccountRecordVO update(DealerAccountRecordUpdateCmd dealerAccountRecordUpdateCmd);
DealerAccountRecordVO show(DealerAccountRecordShowQry dealerAccountRecordShowQry);
void destroy(DealerAccountRecordDestroyCmd dealerAccountRecordDestroyCmd);
}

View File

@ -0,0 +1,80 @@
package com.xunhong.erp.turbo.api.biz.dto.cmd;
import com.xunhong.erp.turbo.api.biz.dto.enums.DealerAccountRecordTargetTypeEnum;
import com.xunhong.erp.turbo.base.dto.Command;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
/**
* @author shenyifei
*/
@Data
@Schema(title = "经销商账款明细创建")
@EqualsAndHashCode(callSuper = true)
public class DealerAccountRecordCreateCmd extends Command {
/**
* 应收账款明细ID
*/
@Schema(title = "应收账款明细ID", type = "string", requiredMode = Schema.RequiredMode.REQUIRED)
private Long dealerAccountRecordId;
/**
* 流水编号
*/
@Schema(title = "流水编号", requiredMode = Schema.RequiredMode.REQUIRED)
private String recordSn;
/**
* 经销商ID
*/
@Schema(title = "经销商ID", type = "string", requiredMode = Schema.RequiredMode.REQUIRED)
private Long dealerId;
/**
* 订单ID
*/
@Schema(title = "订单ID", type = "string", requiredMode = Schema.RequiredMode.REQUIRED)
private Long orderId;
/**
* 变动对象ID
*/
@Schema(title = "变动对象ID", type = "string", requiredMode = Schema.RequiredMode.REQUIRED)
private Long targetId;
/**
* 变动类型:1-产地采购发货单2-市场采购发货单3-市场调货发货单
*/
@Schema(title = "变动类型:1-产地采购发货单2-市场采购发货单3-市场调货发货单;", requiredMode = Schema.RequiredMode.REQUIRED)
private DealerAccountRecordTargetTypeEnum targetType;
/**
* 变动前金额
*/
@Schema(title = "变动前金额", requiredMode = Schema.RequiredMode.REQUIRED)
private BigDecimal beforeAmount;
/**
* 变动金额
*/
@Schema(title = "变动金额", requiredMode = Schema.RequiredMode.REQUIRED)
private BigDecimal amount;
/**
* 变动后金额
*/
@Schema(title = "变动后金额", requiredMode = Schema.RequiredMode.REQUIRED)
private BigDecimal afterAmount;
/**
* 备注
*/
@Schema(title = "备注")
private String remark;
}

View File

@ -0,0 +1,19 @@
package com.xunhong.erp.turbo.api.biz.dto.cmd;
import com.xunhong.erp.turbo.base.dto.Command;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author shenyifei
*/
@Data
@Schema(title = "删除经销商账款明细")
@EqualsAndHashCode(callSuper = true)
public class DealerAccountRecordDestroyCmd extends Command {
@Schema(title = "经销商账款明细ID", requiredMode = Schema.RequiredMode.REQUIRED, type = "string")
private Long dealerAccountRecordId;
}

View File

@ -0,0 +1,18 @@
package com.xunhong.erp.turbo.api.biz.dto.cmd;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author shenyifei
*/
@Data
@Schema(title = "经销商账款明细更新")
@EqualsAndHashCode(callSuper = true)
public class DealerAccountRecordUpdateCmd extends DealerAccountRecordCreateCmd {
@Schema(title = "经销商账款明细ID", requiredMode = Schema.RequiredMode.REQUIRED, type = "string")
private Long dealerAccountRecordId;
}

View File

@ -6,6 +6,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.List; import java.util.List;
@ -89,6 +90,18 @@ public class OrderShipCreateCmd extends Command {
@Schema(title = "备注") @Schema(title = "备注")
private String remark; private String remark;
/**
* 应收金额
*/
@Schema(title = "应收金额(元)")
private BigDecimal receivableAmount;
/**
* 调整总额
*/
@Schema(title = "调整总额(元)")
private BigDecimal adjustedAmount;
/** /**
* 创建人ID * 创建人ID
*/ */

View File

@ -6,6 +6,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.List; import java.util.List;
@ -56,6 +57,18 @@ public class OrderShipUpdateCmd extends Command {
@Schema(title = "备注") @Schema(title = "备注")
private String remark; private String remark;
/**
* 应收金额
*/
@Schema(title = "应收金额(元)")
private BigDecimal receivableAmount;
/**
* 调整总额
*/
@Schema(title = "调整总额(元)")
private BigDecimal adjustedAmount;
/** /**
* 发货单明细 * 发货单明细
*/ */

View File

@ -9,6 +9,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import org.springframework.format.annotation.DateTimeFormat; import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.List; import java.util.List;
@ -132,6 +133,18 @@ public class OrderShip extends Command {
@Schema(title = "备注") @Schema(title = "备注")
private String remark; private String remark;
/**
* 应收金额
*/
@Schema(title = "应收金额(元)")
private BigDecimal receivableAmount;
/**
* 调整总额
*/
@Schema(title = "调整总额(元)")
private BigDecimal adjustedAmount;
/** /**
* 发货单明细 * 发货单明细
*/ */

View File

@ -0,0 +1,57 @@
package com.xunhong.erp.turbo.api.biz.dto.enums;
import com.baomidou.mybatisplus.annotation.EnumValue;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
/**
* 经销商应收账款明细变动类型枚举
*
* @author shenyifei
*/
@Getter
@RequiredArgsConstructor
public enum DealerAccountRecordTargetTypeEnum {
/**
* 变动类型:1_产地采购发货单2_市场采购发货单3_市场调货发货单
*/
ORIGIN_PURCHASE_SHIP(1, "产地采购发货单"),
MARKET_PURCHASE_SHIP(2, "市场采购发货单"),
MARKET_TRANSFER_SHIP(3, "市场调货发货单");
@EnumValue
private final Integer type;
private final String message;
/**
* 根据 OrderShipTypeEnum 转换为对应的应收账款明细变动类型
* 产地采购 ORIGIN_PURCHASE_SHIP(1)
* 市场采购 MARKET_PURCHASE_SHIP(2)
* 调货发货 MARKET_TRANSFER_SHIP(3)
* 改签发货 MARKET_TRANSFER_SHIP(3) (按调货处理)
* 退货发货 不产生应收账款
*
* @param orderShipType 发货单类型
* @param orderType 采购单类型
* @return 应收账款明细变动类型
*/
public static DealerAccountRecordTargetTypeEnum fromOrderShipType(OrderShipTypeEnum orderShipType, OrderTypeEnum orderType) {
if (orderShipType == null) {
return null;
}
// 退货发货不产生应收账款
if (orderShipType == OrderShipTypeEnum.RETURN_SHIP) {
return null;
}
// 根据发货单类型和是否产地判断
return switch (orderShipType) {
case PURCHASE_SHIP ->
orderType == OrderTypeEnum.PRODUCTION_PURCHASE ? ORIGIN_PURCHASE_SHIP : MARKET_PURCHASE_SHIP;
case TRANSFER_SHIP, CHANGE_SHIP -> MARKET_TRANSFER_SHIP;
default -> null;
};
}
}

View File

@ -0,0 +1,19 @@
package com.xunhong.erp.turbo.api.biz.dto.qry;
import com.xunhong.erp.turbo.base.dto.Query;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author shenyifei
*/
@Data
@Schema(title = "经销商账款明细列表查询")
@EqualsAndHashCode(callSuper = true)
public class DealerAccountRecordListQry extends Query {
@Schema(title = "经销商账款明细ID", type = "string")
private Long dealerAccountRecordId;
}

View File

@ -0,0 +1,50 @@
package com.xunhong.erp.turbo.api.biz.dto.qry;
import com.xunhong.erp.turbo.api.biz.dto.enums.DealerAccountRecordTargetTypeEnum;
import com.xunhong.erp.turbo.base.dto.PageQuery;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author shenyifei
*/
@Data
@Schema(title = "经销商账款明细分页查询")
@EqualsAndHashCode(callSuper = true)
public class DealerAccountRecordPageQry extends PageQuery {
@Schema(title = "经销商账款明细ID", type = "string")
private Long dealerAccountRecordId;
/**
* 流水编号
*/
@Schema(title = "流水编号", requiredMode = Schema.RequiredMode.REQUIRED)
private String recordSn;
/**
* 经销商ID
*/
@Schema(title = "经销商ID", type = "string", requiredMode = Schema.RequiredMode.REQUIRED)
private Long dealerId;
/**
* 订单ID
*/
@Schema(title = "订单ID", type = "string", requiredMode = Schema.RequiredMode.REQUIRED)
private Long orderId;
/**
* 变动对象ID
*/
@Schema(title = "变动对象ID", type = "string", requiredMode = Schema.RequiredMode.REQUIRED)
private Long targetId;
/**
* 变动类型:1-产地采购发货单2-市场采购发货单3-市场调货发货单
*/
@Schema(title = "变动类型:1-产地采购发货单2-市场采购发货单3-市场调货发货单;", requiredMode = Schema.RequiredMode.REQUIRED)
private DealerAccountRecordTargetTypeEnum targetType;
}

View File

@ -0,0 +1,19 @@
package com.xunhong.erp.turbo.api.biz.dto.qry;
import com.xunhong.erp.turbo.base.dto.Query;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author shenyifei
*/
@Data
@Schema(title = "经销商账款明细查询")
@EqualsAndHashCode(callSuper = true)
public class DealerAccountRecordShowQry extends Query {
@Schema(title = "经销商账款明细ID", type = "string")
private Long dealerAccountRecordId;
}

View File

@ -7,6 +7,8 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import java.util.List;
/** /**
* @author shenyifei * @author shenyifei
*/ */
@ -40,5 +42,8 @@ public class OrderShipPageQry extends PageQuery {
@Schema(title = "经销商ID", type = "string") @Schema(title = "经销商ID", type = "string")
private Long dealerId; private Long dealerId;
@Schema(title = "发货时间", type = "string")
private List<String> shippingDate;
} }

View File

@ -0,0 +1,95 @@
package com.xunhong.erp.turbo.api.biz.dto.vo;
import com.alibaba.cola.dto.DTO;
import com.xunhong.erp.turbo.api.biz.dto.enums.DealerAccountRecordTargetTypeEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* @author shenyifei
*/
@Data
@Schema(title = "经销商账款明细")
@EqualsAndHashCode(callSuper = true)
public class DealerAccountRecordVO extends DTO {
/**
* 应收账款明细ID
*/
@Schema(title = "应收账款明细ID", type = "string", requiredMode = Schema.RequiredMode.REQUIRED)
private Long dealerAccountRecordId;
/**
* 流水编号
*/
@Schema(title = "流水编号", requiredMode = Schema.RequiredMode.REQUIRED)
private String recordSn;
/**
* 经销商ID
*/
@Schema(title = "经销商ID", type = "string", requiredMode = Schema.RequiredMode.REQUIRED)
private Long dealerId;
/**
* 订单ID
*/
@Schema(title = "订单ID", type = "string", requiredMode = Schema.RequiredMode.REQUIRED)
private Long orderId;
/**
* 变动对象ID
*/
@Schema(title = "变动对象ID", type = "string", requiredMode = Schema.RequiredMode.REQUIRED)
private Long targetId;
/**
* 变动类型:1-产地采购发货单2-市场采购发货单3-市场调货发货单
*/
@Schema(title = "变动类型:1-产地采购发货单2-市场采购发货单3-市场调货发货单;", requiredMode = Schema.RequiredMode.REQUIRED)
private DealerAccountRecordTargetTypeEnum targetType;
/**
* 变动前金额
*/
@Schema(title = "变动前金额", requiredMode = Schema.RequiredMode.REQUIRED)
private BigDecimal beforeAmount;
/**
* 变动金额
*/
@Schema(title = "变动金额", requiredMode = Schema.RequiredMode.REQUIRED)
private BigDecimal amount;
/**
* 变动后金额
*/
@Schema(title = "变动后金额", requiredMode = Schema.RequiredMode.REQUIRED)
private BigDecimal afterAmount;
/**
* 备注
*/
@Schema(title = "备注")
private String remark;
/**
* 创建时间
*/
@Schema(title = "创建时间")
private LocalDateTime createdAt;
@Schema(title = "经销商信息")
private DealerVO dealerVO;
@Schema(title = "订单信息")
private OrderVO orderVO;
@Schema(title = "发货单信息")
private OrderShipVO orderShipVO;
}

View File

@ -11,6 +11,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import org.springframework.format.annotation.DateTimeFormat; import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
@ -147,6 +148,18 @@ public class OrderShipVO extends DTO {
@Schema(title = "备注") @Schema(title = "备注")
private String remark; private String remark;
/**
* 应收金额
*/
@Schema(title = "应收金额(元)", requiredMode = Schema.RequiredMode.REQUIRED)
private BigDecimal receivableAmount;
/**
* 调整总额
*/
@Schema(title = "调整总额(元)", requiredMode = Schema.RequiredMode.REQUIRED)
private BigDecimal adjustedAmount;
/** /**
* 创建人ID * 创建人ID
*/ */