Commit 0628a46b3cf172fa3423bf64f23293d8d3357ec1

Authored by YunaiV
1 parent e2fa61b7

feat(fms): consolidate financial management

Showing 291 changed files with 37950 additions and 0 deletions

Too many changes.

To preserve performance only 100 of 291 files are displayed.

yudao-module-fms/pom.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project xmlns="http://maven.apache.org/POM/4.0.0"
  3 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5 + <modelVersion>4.0.0</modelVersion>
  6 + <parent>
  7 + <groupId>cn.iocoder.boot</groupId>
  8 + <artifactId>yudao</artifactId>
  9 + <version>${revision}</version>
  10 + </parent>
  11 +
  12 + <artifactId>yudao-module-fms</artifactId>
  13 + <packaging>jar</packaging>
  14 +
  15 + <name>${project.artifactId}</name>
  16 + <description>
  17 + fms 包下,财务管理(Financial Management System)
  18 + 例如说:凭证、账簿、报表、结账等等
  19 + </description>
  20 +
  21 + <dependencies>
  22 + <dependency>
  23 + <groupId>cn.iocoder.boot</groupId>
  24 + <artifactId>yudao-module-system</artifactId>
  25 + <version>${revision}</version>
  26 + </dependency>
  27 + <dependency>
  28 + <groupId>cn.iocoder.boot</groupId>
  29 + <artifactId>yudao-module-infra</artifactId>
  30 + <version>${revision}</version>
  31 + </dependency>
  32 +
  33 + <!-- Web 相关 -->
  34 + <dependency>
  35 + <groupId>cn.iocoder.boot</groupId>
  36 + <artifactId>yudao-spring-boot-starter-web</artifactId>
  37 + </dependency>
  38 + <dependency>
  39 + <groupId>cn.iocoder.boot</groupId>
  40 + <artifactId>yudao-spring-boot-starter-security</artifactId>
  41 + </dependency>
  42 + <dependency>
  43 + <groupId>cn.iocoder.boot</groupId>
  44 + <artifactId>yudao-spring-boot-starter-excel</artifactId>
  45 + </dependency>
  46 +
  47 + <!-- DB 相关 -->
  48 + <dependency>
  49 + <groupId>cn.iocoder.boot</groupId>
  50 + <artifactId>yudao-spring-boot-starter-mybatis</artifactId>
  51 + </dependency>
  52 +
  53 + <!-- 现金流量表公式计算 -->
  54 + <dependency>
  55 + <groupId>com.googlecode.aviator</groupId>
  56 + <artifactId>aviator</artifactId>
  57 + </dependency>
  58 +
  59 + <!-- Test 测试相关 -->
  60 + <dependency>
  61 + <groupId>cn.iocoder.boot</groupId>
  62 + <artifactId>yudao-spring-boot-starter-test</artifactId>
  63 + <scope>test</scope>
  64 + </dependency>
  65 + </dependencies>
  66 +
  67 +</project>
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/closing/FmsClosingPeriodController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.closing;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.module.fms.controller.admin.closing.vo.FmsClosingOverviewRespVO;
  5 +import cn.iocoder.yudao.module.fms.controller.admin.closing.vo.FmsClosingQueryReqVO;
  6 +import cn.iocoder.yudao.module.fms.service.closing.FmsClosingPeriodService;
  7 +import io.swagger.v3.oas.annotations.Operation;
  8 +import io.swagger.v3.oas.annotations.tags.Tag;
  9 +import jakarta.annotation.Resource;
  10 +import jakarta.validation.Valid;
  11 +import jakarta.validation.constraints.NotNull;
  12 +import org.springframework.security.access.prepost.PreAuthorize;
  13 +import org.springframework.validation.annotation.Validated;
  14 +import org.springframework.web.bind.annotation.DeleteMapping;
  15 +import org.springframework.web.bind.annotation.GetMapping;
  16 +import org.springframework.web.bind.annotation.PutMapping;
  17 +import org.springframework.web.bind.annotation.RequestBody;
  18 +import org.springframework.web.bind.annotation.RequestMapping;
  19 +import org.springframework.web.bind.annotation.RequestParam;
  20 +import org.springframework.web.bind.annotation.RestController;
  21 +
  22 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  23 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  24 +
  25 +@Tag(name = "管理后台 - FMS 结账期间")
  26 +@RestController
  27 +@RequestMapping("/fms/closing/period")
  28 +@Validated
  29 +public class FmsClosingPeriodController {
  30 +
  31 + @Resource
  32 + private FmsClosingPeriodService closingPeriodService;
  33 +
  34 + @GetMapping("/current-month")
  35 + @Operation(summary = "获得当前会计期间")
  36 + public CommonResult<String> getCurrentMonth(@RequestParam("accountSetId") @NotNull Long accountSetId) {
  37 + return success(closingPeriodService.getCurrentMonth(accountSetId, getLoginUserId()));
  38 + }
  39 +
  40 + @GetMapping("/overview")
  41 + @Operation(summary = "获得结账概况")
  42 + @PreAuthorize("@ss.hasPermission('fms:closing:query')")
  43 + public CommonResult<FmsClosingOverviewRespVO> getClosingOverview(@Valid FmsClosingQueryReqVO queryReqVO) {
  44 + return success(closingPeriodService.getClosingOverview(queryReqVO, getLoginUserId()));
  45 + }
  46 +
  47 + @PutMapping("/close")
  48 + @Operation(summary = "结账")
  49 + @PreAuthorize("@ss.hasPermission('fms:closing:close')")
  50 + public CommonResult<Boolean> closePeriod(@Valid @RequestBody FmsClosingQueryReqVO queryReqVO) {
  51 + closingPeriodService.closePeriod(queryReqVO, getLoginUserId());
  52 + return success(true);
  53 + }
  54 +
  55 + @DeleteMapping("/cancel")
  56 + @Operation(summary = "反结账")
  57 + @PreAuthorize("@ss.hasPermission('fms:closing:cancel')")
  58 + public CommonResult<Boolean> cancelClosePeriod(@Valid FmsClosingQueryReqVO queryReqVO) {
  59 + closingPeriodService.cancelClosePeriod(queryReqVO, getLoginUserId());
  60 + return success(true);
  61 + }
  62 +
  63 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/closing/FmsClosingSchemeController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.closing;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.module.fms.controller.admin.closing.vo.FmsClosingQueryReqVO;
  5 +import cn.iocoder.yudao.module.fms.controller.admin.closing.vo.FmsClosingSchemeRespVO;
  6 +import cn.iocoder.yudao.module.fms.controller.admin.closing.vo.FmsClosingSchemeSaveReqVO;
  7 +import cn.iocoder.yudao.module.fms.controller.admin.closing.vo.FmsProfitLossSettingsSaveReqVO;
  8 +import cn.iocoder.yudao.module.fms.controller.admin.closing.vo.FmsSpecialClosingSettingsSaveReqVO;
  9 +import cn.iocoder.yudao.module.fms.service.closing.FmsClosingSchemeService;
  10 +import io.swagger.v3.oas.annotations.Operation;
  11 +import io.swagger.v3.oas.annotations.tags.Tag;
  12 +import jakarta.annotation.Resource;
  13 +import jakarta.validation.Valid;
  14 +import jakarta.validation.constraints.NotNull;
  15 +import org.springframework.security.access.prepost.PreAuthorize;
  16 +import org.springframework.validation.annotation.Validated;
  17 +import org.springframework.web.bind.annotation.DeleteMapping;
  18 +import org.springframework.web.bind.annotation.GetMapping;
  19 +import org.springframework.web.bind.annotation.PostMapping;
  20 +import org.springframework.web.bind.annotation.PutMapping;
  21 +import org.springframework.web.bind.annotation.RequestBody;
  22 +import org.springframework.web.bind.annotation.RequestMapping;
  23 +import org.springframework.web.bind.annotation.RequestParam;
  24 +import org.springframework.web.bind.annotation.RestController;
  25 +
  26 +import java.util.List;
  27 +
  28 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  29 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  30 +
  31 +@Tag(name = "管理后台 - FMS 结账方案")
  32 +@RestController
  33 +@RequestMapping("/fms/closing/scheme")
  34 +@Validated
  35 +public class FmsClosingSchemeController {
  36 +
  37 + @Resource
  38 + private FmsClosingSchemeService closingSchemeService;
  39 +
  40 + @GetMapping("/list")
  41 + @Operation(summary = "获得结账方案列表")
  42 + @PreAuthorize("@ss.hasPermission('fms:closing:query')")
  43 + public CommonResult<List<FmsClosingSchemeRespVO>> getClosingSchemeList(@Valid FmsClosingQueryReqVO queryReqVO) {
  44 + return success(closingSchemeService.getClosingSchemeList(queryReqVO, getLoginUserId()));
  45 + }
  46 +
  47 + @PostMapping("/create")
  48 + @Operation(summary = "创建结账方案")
  49 + @PreAuthorize("@ss.hasPermission('fms:closing:update')")
  50 + public CommonResult<Long> createClosingScheme(@Valid @RequestBody FmsClosingSchemeSaveReqVO createReqVO) {
  51 + return success(closingSchemeService.createClosingScheme(createReqVO, getLoginUserId()));
  52 + }
  53 +
  54 + @PutMapping("/update")
  55 + @Operation(summary = "修改结账方案")
  56 + @PreAuthorize("@ss.hasPermission('fms:closing:update')")
  57 + public CommonResult<Boolean> updateClosingScheme(@Valid @RequestBody FmsClosingSchemeSaveReqVO updateReqVO) {
  58 + closingSchemeService.updateClosingScheme(updateReqVO, getLoginUserId());
  59 + return success(true);
  60 + }
  61 +
  62 + @PutMapping("/update-profit-loss-settings")
  63 + @Operation(summary = "保存结转损益设置")
  64 + @PreAuthorize("@ss.hasPermission('fms:closing:update')")
  65 + public CommonResult<Long> saveProfitLossSettings(@Valid @RequestBody FmsProfitLossSettingsSaveReqVO saveReqVO) {
  66 + return success(closingSchemeService.saveProfitLossSettings(saveReqVO, getLoginUserId()));
  67 + }
  68 +
  69 + @PutMapping("/update-special-settings")
  70 + @Operation(summary = "保存专用结转设置")
  71 + @PreAuthorize("@ss.hasPermission('fms:closing:update')")
  72 + public CommonResult<Boolean> updateSpecialClosingSettings(@Valid @RequestBody FmsSpecialClosingSettingsSaveReqVO updateReqVO) {
  73 + closingSchemeService.updateSpecialClosingSettings(updateReqVO, getLoginUserId());
  74 + return success(true);
  75 + }
  76 +
  77 + @DeleteMapping("/delete")
  78 + @Operation(summary = "删除结账方案")
  79 + @PreAuthorize("@ss.hasPermission('fms:closing:update')")
  80 + public CommonResult<Boolean> deleteClosingScheme(@RequestParam("accountSetId") @NotNull Long accountSetId,
  81 + @RequestParam("id") @NotNull Long id) {
  82 + closingSchemeService.deleteClosingScheme(accountSetId, id, getLoginUserId());
  83 + return success(true);
  84 + }
  85 +
  86 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/closing/FmsClosingTemplateController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.closing;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.module.fms.controller.admin.closing.vo.FmsClosingTemplateRespVO;
  5 +import cn.iocoder.yudao.module.fms.controller.admin.closing.vo.FmsClosingTemplateSaveReqVO;
  6 +import cn.iocoder.yudao.module.fms.service.closing.FmsClosingTemplateService;
  7 +import io.swagger.v3.oas.annotations.Operation;
  8 +import io.swagger.v3.oas.annotations.Parameter;
  9 +import io.swagger.v3.oas.annotations.Parameters;
  10 +import io.swagger.v3.oas.annotations.tags.Tag;
  11 +import jakarta.annotation.Resource;
  12 +import jakarta.validation.Valid;
  13 +import jakarta.validation.constraints.NotNull;
  14 +import org.springframework.security.access.prepost.PreAuthorize;
  15 +import org.springframework.validation.annotation.Validated;
  16 +import org.springframework.web.bind.annotation.DeleteMapping;
  17 +import org.springframework.web.bind.annotation.GetMapping;
  18 +import org.springframework.web.bind.annotation.PostMapping;
  19 +import org.springframework.web.bind.annotation.PutMapping;
  20 +import org.springframework.web.bind.annotation.RequestBody;
  21 +import org.springframework.web.bind.annotation.RequestMapping;
  22 +import org.springframework.web.bind.annotation.RequestParam;
  23 +import org.springframework.web.bind.annotation.RestController;
  24 +
  25 +import java.util.List;
  26 +
  27 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  28 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  29 +
  30 +@Tag(name = "管理后台 - FMS 结账模板")
  31 +@RestController
  32 +@RequestMapping("/fms/closing/template")
  33 +@Validated
  34 +public class FmsClosingTemplateController {
  35 +
  36 + @Resource
  37 + private FmsClosingTemplateService closingTemplateService;
  38 +
  39 + @GetMapping("/list")
  40 + @Operation(summary = "获得结账模板列表")
  41 + @Parameter(name = "accountSetId", description = "账套编号", required = true, example = "1024")
  42 + @PreAuthorize("@ss.hasPermission('fms:closing:query')")
  43 + public CommonResult<List<FmsClosingTemplateRespVO>> getClosingTemplateList(
  44 + @RequestParam("accountSetId") @NotNull Long accountSetId) {
  45 + return success(closingTemplateService.getClosingTemplateList(accountSetId, getLoginUserId()));
  46 + }
  47 +
  48 + @PostMapping("/create")
  49 + @Operation(summary = "创建结账模板")
  50 + @PreAuthorize("@ss.hasPermission('fms:closing:update')")
  51 + public CommonResult<Long> createClosingTemplate(
  52 + @Valid @RequestBody FmsClosingTemplateSaveReqVO createReqVO) {
  53 + return success(closingTemplateService.createClosingTemplate(createReqVO, getLoginUserId()));
  54 + }
  55 +
  56 + @PutMapping("/update")
  57 + @Operation(summary = "更新结账模板")
  58 + @PreAuthorize("@ss.hasPermission('fms:closing:update')")
  59 + public CommonResult<Boolean> updateClosingTemplate(
  60 + @Valid @RequestBody FmsClosingTemplateSaveReqVO updateReqVO) {
  61 + closingTemplateService.updateClosingTemplate(updateReqVO, getLoginUserId());
  62 + return success(true);
  63 + }
  64 +
  65 + @DeleteMapping("/delete")
  66 + @Operation(summary = "删除结账模板")
  67 + @Parameters({
  68 + @Parameter(name = "accountSetId", description = "账套编号", required = true, example = "1024"),
  69 + @Parameter(name = "id", description = "结账模板编号", required = true, example = "1024")
  70 + })
  71 + @PreAuthorize("@ss.hasPermission('fms:closing:update')")
  72 + public CommonResult<Boolean> deleteClosingTemplate(@RequestParam("accountSetId") @NotNull Long accountSetId,
  73 + @RequestParam("id") @NotNull Long id) {
  74 + closingTemplateService.deleteClosingTemplate(accountSetId, id, getLoginUserId());
  75 + return success(true);
  76 + }
  77 +
  78 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/closing/FmsClosingVoucherController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.closing;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.module.fms.controller.admin.closing.vo.FmsClosingSchemeGenerateReqVO;
  5 +import cn.iocoder.yudao.module.fms.controller.admin.closing.vo.FmsClosingVoucherGenerateReqVO;
  6 +import cn.iocoder.yudao.module.fms.controller.admin.closing.vo.FmsProfitLossGenerateReqVO;
  7 +import cn.iocoder.yudao.module.fms.service.closing.FmsClosingVoucherService;
  8 +import io.swagger.v3.oas.annotations.Operation;
  9 +import io.swagger.v3.oas.annotations.tags.Tag;
  10 +import jakarta.annotation.Resource;
  11 +import jakarta.validation.Valid;
  12 +import org.springframework.security.access.prepost.PreAuthorize;
  13 +import org.springframework.validation.annotation.Validated;
  14 +import org.springframework.web.bind.annotation.PostMapping;
  15 +import org.springframework.web.bind.annotation.RequestBody;
  16 +import org.springframework.web.bind.annotation.RequestMapping;
  17 +import org.springframework.web.bind.annotation.RestController;
  18 +
  19 +import java.util.List;
  20 +
  21 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  22 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  23 +
  24 +@Tag(name = "管理后台 - FMS 结转凭证")
  25 +@RestController
  26 +@RequestMapping("/fms/closing/voucher")
  27 +@Validated
  28 +public class FmsClosingVoucherController {
  29 +
  30 + @Resource
  31 + private FmsClosingVoucherService closingVoucherService;
  32 +
  33 + @PostMapping("/generate-profit-loss")
  34 + @Operation(summary = "生成结转损益凭证")
  35 + @PreAuthorize("@ss.hasPermission('fms:closing:profit-loss')")
  36 + public CommonResult<Long> generateProfitLossVoucher(@Valid @RequestBody FmsProfitLossGenerateReqVO generateReqVO) {
  37 + return success(closingVoucherService.generateProfitLossVoucher(generateReqVO, getLoginUserId()));
  38 + }
  39 +
  40 + @PostMapping("/generate-scheme")
  41 + @Operation(summary = "生成结账方案凭证")
  42 + @PreAuthorize("@ss.hasPermission('fms:closing:profit-loss')")
  43 + public CommonResult<Long> generateClosingSchemeVoucher(@Valid @RequestBody FmsClosingSchemeGenerateReqVO generateReqVO) {
  44 + return success(closingVoucherService.generateClosingSchemeVoucher(generateReqVO, getLoginUserId()));
  45 + }
  46 +
  47 + @PostMapping("/generate-list")
  48 + @Operation(summary = "批量生成结转凭证")
  49 + @PreAuthorize("@ss.hasPermission('fms:closing:profit-loss')")
  50 + public CommonResult<List<Long>> generateClosingVoucherList(@Valid @RequestBody FmsClosingVoucherGenerateReqVO generateReqVO) {
  51 + return success(closingVoucherService.generateClosingVoucherList(generateReqVO, getLoginUserId()));
  52 + }
  53 +
  54 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/closing/vo/FmsClosingOverviewRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.closing.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.math.BigDecimal;
  7 +
  8 +@Schema(description = "管理后台 - FMS 结账概况 Response VO")
  9 +@Data
  10 +public class FmsClosingOverviewRespVO {
  11 +
  12 + @Schema(description = "会计期间", example = "2026-08")
  13 + private String month;
  14 +
  15 + @Schema(description = "是否已结账")
  16 + private Boolean closed;
  17 +
  18 + @Schema(description = "是否要求凭证审核")
  19 + private Boolean voucherReviewRequired;
  20 +
  21 + @Schema(description = "未审核凭证数量", example = "2")
  22 + private Long pendingVoucherCount;
  23 +
  24 + @Schema(description = "凭证数量", example = "12")
  25 + private Long voucherCount;
  26 +
  27 + @Schema(description = "损益类科目余额", example = "9100.00")
  28 + private BigDecimal profitLossBalance;
  29 +
  30 + @Schema(description = "资产负债表差额", example = "0.00")
  31 + private BigDecimal balanceSheetDifference;
  32 +
  33 + @Schema(description = "结转损益凭证编号", example = "1024")
  34 + private Long profitLossVoucherId;
  35 +
  36 + @Schema(description = "初始余额是否试算平衡")
  37 + private Boolean initialBalanceBalanced;
  38 +
  39 + @Schema(description = "凭证编号是否连续")
  40 + private Boolean voucherNumberContinuous;
  41 +
  42 + @Schema(description = "需要结转损益时是否已生成凭证")
  43 + private Boolean profitLossVoucherGenerated;
  44 +
  45 + @Schema(description = "利润表勾稽是否平衡")
  46 + private Boolean incomeStatementBalanced;
  47 +
  48 + @Schema(description = "利润表未纳入公式的科目数量", example = "0")
  49 + private Integer incomeStatementUnmappedSubjectCount;
  50 +
  51 + @Schema(description = "资产负债表损益是否已结转")
  52 + private Boolean balanceSheetProfitLossTransferred;
  53 +
  54 + @Schema(description = "资产负债表是否平衡")
  55 + private Boolean balanceSheetBalanced;
  56 +
  57 + @Schema(description = "资产负债表未纳入公式的科目数量", example = "0")
  58 + private Integer balanceSheetUnmappedSubjectCount;
  59 +
  60 + @Schema(description = "是否满足全部结账条件")
  61 + private Boolean canClose;
  62 +
  63 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/closing/vo/FmsClosingQueryReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.closing.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotNull;
  5 +import jakarta.validation.constraints.NotBlank;
  6 +import jakarta.validation.constraints.Pattern;
  7 +import lombok.Data;
  8 +
  9 +@Schema(description = "管理后台 - FMS 结账查询 Request VO")
  10 +@Data
  11 +public class FmsClosingQueryReqVO {
  12 +
  13 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  14 + @NotNull(message = "账套不能为空")
  15 + private Long accountSetId;
  16 +
  17 + @Schema(description = "目标会计期间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026-08")
  18 + @NotBlank(message = "会计期间不能为空")
  19 + @Pattern(regexp = "\\d{4}-(0[1-9]|1[0-2])", message = "会计期间格式不正确")
  20 + private String month;
  21 +
  22 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/closing/vo/FmsClosingSchemeGenerateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.closing.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotBlank;
  5 +import jakarta.validation.constraints.NotNull;
  6 +import jakarta.validation.constraints.Pattern;
  7 +import lombok.Data;
  8 +
  9 +@Schema(description = "管理后台 - FMS 结账方案生成凭证 Request VO")
  10 +@Data
  11 +public class FmsClosingSchemeGenerateReqVO {
  12 +
  13 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  14 + @NotNull(message = "账套不能为空")
  15 + private Long accountSetId;
  16 +
  17 + @Schema(description = "方案编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  18 + @NotNull(message = "方案编号不能为空")
  19 + private Long id;
  20 +
  21 + @Schema(description = "会计期间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026-08")
  22 + @NotBlank(message = "会计期间不能为空")
  23 + @Pattern(regexp = "\\d{4}-(0[1-9]|1[0-2])", message = "会计期间格式不正确")
  24 + private String month;
  25 +
  26 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/closing/vo/FmsClosingSchemeRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.closing.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.math.BigDecimal;
  7 +import java.util.List;
  8 +
  9 +@Schema(description = "管理后台 - FMS 结账方案 Response VO")
  10 +@Data
  11 +public class FmsClosingSchemeRespVO {
  12 +
  13 + @Schema(description = "方案编号", example = "1024")
  14 + private Long id;
  15 +
  16 + @Schema(description = "账套编号", example = "1")
  17 + private Long accountSetId;
  18 +
  19 + @Schema(description = "方案名称", example = "结转本月房租")
  20 + private String name;
  21 +
  22 + @Schema(description = "是否期末结转")
  23 + private Boolean periodEnd;
  24 +
  25 + @Schema(description = "来源科目编号", example = "1024")
  26 + private Long subjectId;
  27 +
  28 + @Schema(description = "取数规则", example = "0")
  29 + private Integer formulaRule;
  30 +
  31 + @Schema(description = "取数时间类型", example = "1")
  32 + private Integer timeType;
  33 +
  34 + @Schema(description = "凭证字编号", example = "11")
  35 + private Long voucherWordId;
  36 +
  37 + @Schema(description = "凭证摘要", example = "结转损益")
  38 + private String digest;
  39 +
  40 + @Schema(description = "结转凭证类型", example = "2")
  41 + private Integer voucherType;
  42 +
  43 + @Schema(description = "以前年度损益调整科目编号", example = "1024")
  44 + private Long priorYearAdjustmentSubjectId;
  45 +
  46 + @Schema(description = "以前年度损益调整结转科目编号", example = "1025")
  47 + private Long adjustmentClosingSubjectId;
  48 +
  49 + @Schema(description = "其他损益结转科目编号", example = "1026")
  50 + private Long otherClosingSubjectId;
  51 +
  52 + @Schema(description = "是否按余额反向结转")
  53 + private Boolean reverseBalance;
  54 +
  55 + @Schema(description = "结转日期", example = "31")
  56 + private Integer closingDay;
  57 +
  58 + @Schema(description = "类型", example = "1")
  59 + private Integer type;
  60 +
  61 + @Schema(description = "结转科目规则数组")
  62 + private List<SubjectRule> subjects;
  63 +
  64 + @Schema(description = "待结转金额", example = "12000.00")
  65 + private BigDecimal balance;
  66 +
  67 + @Schema(description = "当前期间已生成凭证编号数组")
  68 + private List<Long> voucherIds;
  69 +
  70 + @Schema(description = "管理后台 - FMS 结账方案科目规则")
  71 + @Data
  72 + public static class SubjectRule {
  73 +
  74 + @Schema(description = "科目编号", example = "1024")
  75 + private Long subjectId;
  76 +
  77 + @Schema(description = "科目编码快照", example = "6602")
  78 + private String subjectCode;
  79 +
  80 + @Schema(description = "摘要", example = "结转本月房租")
  81 + private String digest;
  82 +
  83 + @Schema(description = "借贷方向", example = "1")
  84 + private Integer direction;
  85 +
  86 + @Schema(description = "金额比例", example = "100")
  87 + private BigDecimal amountRatio;
  88 + }
  89 +
  90 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/closing/vo/FmsClosingSchemeSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.closing.vo;
  2 +
  3 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  4 +import cn.iocoder.yudao.module.fms.enums.common.FmsDebitCreditDirectionEnum;
  5 +import cn.iocoder.yudao.module.fms.enums.closing.FmsClosingTimeTypeEnum;
  6 +import cn.iocoder.yudao.module.fms.enums.report.FmsFormulaRuleEnum;
  7 +import io.swagger.v3.oas.annotations.media.Schema;
  8 +import jakarta.validation.Valid;
  9 +import jakarta.validation.constraints.DecimalMax;
  10 +import jakarta.validation.constraints.DecimalMin;
  11 +import jakarta.validation.constraints.NotBlank;
  12 +import jakarta.validation.constraints.NotEmpty;
  13 +import jakarta.validation.constraints.NotNull;
  14 +import jakarta.validation.constraints.Size;
  15 +import lombok.Data;
  16 +
  17 +import java.math.BigDecimal;
  18 +import java.util.List;
  19 +
  20 +@Schema(description = "管理后台 - FMS 结账方案保存 Request VO")
  21 +@Data
  22 +public class FmsClosingSchemeSaveReqVO {
  23 +
  24 + @Schema(description = "方案编号", example = "1024")
  25 + private Long id;
  26 +
  27 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  28 + @NotNull(message = "账套不能为空")
  29 + private Long accountSetId;
  30 +
  31 + @Schema(description = "方案名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "结转本月房租")
  32 + @NotBlank(message = "方案名称不能为空")
  33 + @Size(max = 255, message = "方案名称长度不能超过 255 个字符")
  34 + private String name;
  35 +
  36 + @Schema(description = "是否期末结转", requiredMode = Schema.RequiredMode.REQUIRED)
  37 + @NotNull(message = "是否期末结转不能为空")
  38 + private Boolean periodEnd;
  39 +
  40 + @Schema(description = "来源科目编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  41 + @NotNull(message = "来源科目不能为空")
  42 + private Long subjectId;
  43 +
  44 + @Schema(description = "取数规则", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
  45 + @NotNull(message = "取数规则不能为空")
  46 + @InEnum(FmsFormulaRuleEnum.class)
  47 + private Integer formulaRule;
  48 +
  49 + @Schema(description = "取数时间类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  50 + @NotNull(message = "取数时间类型不能为空")
  51 + @InEnum(FmsClosingTimeTypeEnum.class)
  52 + private Integer timeType;
  53 +
  54 + @Schema(description = "凭证字编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11")
  55 + @NotNull(message = "凭证字不能为空")
  56 + private Long voucherWordId;
  57 +
  58 + @Schema(description = "结转科目规则数组", requiredMode = Schema.RequiredMode.REQUIRED)
  59 + @Valid
  60 + @NotEmpty(message = "结转科目规则不能为空")
  61 + @Size(min = 2, message = "结转科目规则至少需要两条")
  62 + private List<SubjectRule> subjects;
  63 +
  64 + @Schema(description = "管理后台 - FMS 结账方案科目规则")
  65 + @Data
  66 + public static class SubjectRule {
  67 +
  68 + @Schema(description = "科目编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  69 + @NotNull(message = "科目不能为空")
  70 + private Long subjectId;
  71 +
  72 + @Schema(description = "摘要", requiredMode = Schema.RequiredMode.REQUIRED, example = "结转本月房租")
  73 + @NotBlank(message = "摘要不能为空")
  74 + @Size(max = 500, message = "摘要长度不能超过 500 个字符")
  75 + private String digest;
  76 +
  77 + @Schema(description = "借贷方向", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  78 + @NotNull(message = "借贷方向不能为空")
  79 + @InEnum(FmsDebitCreditDirectionEnum.class)
  80 + private Integer direction;
  81 +
  82 + @Schema(description = "金额比例", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
  83 + @NotNull(message = "金额比例不能为空")
  84 + @DecimalMin(value = "0", inclusive = false, message = "金额比例必须大于 0")
  85 + @DecimalMax(value = "100", message = "金额比例不能超过 100")
  86 + private BigDecimal amountRatio;
  87 + }
  88 +
  89 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/closing/vo/FmsClosingTemplateRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.closing.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.math.BigDecimal;
  7 +import java.time.LocalDateTime;
  8 +import java.util.List;
  9 +
  10 +@Schema(description = "管理后台 - FMS 结账模板 Response VO")
  11 +@Data
  12 +public class FmsClosingTemplateRespVO {
  13 +
  14 + @Schema(description = "模板编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  15 + private Long id;
  16 +
  17 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  18 + private Long accountSetId;
  19 +
  20 + @Schema(description = "系统预置编码", example = "daily-travel-reimbursement")
  21 + private String presetCode;
  22 +
  23 + @Schema(description = "模板名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "报销差旅费")
  24 + private String name;
  25 +
  26 + @Schema(description = "模板分类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  27 + private Integer category;
  28 +
  29 + @Schema(description = "是否期末结转", requiredMode = Schema.RequiredMode.REQUIRED)
  30 + private Boolean periodEnd;
  31 +
  32 + @Schema(description = "来源科目编号", example = "1024")
  33 + private Long subjectId;
  34 +
  35 + @Schema(description = "取数规则", example = "0")
  36 + private Integer formulaRule;
  37 +
  38 + @Schema(description = "取数时间类型", example = "1")
  39 + private Integer timeType;
  40 +
  41 + @Schema(description = "结转科目规则数组", requiredMode = Schema.RequiredMode.REQUIRED)
  42 + private List<SubjectRule> subjects;
  43 +
  44 + @Schema(description = "显示顺序", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  45 + private Integer sort;
  46 +
  47 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  48 + private LocalDateTime createTime;
  49 +
  50 + @Schema(description = "管理后台 - FMS 结账模板科目规则")
  51 + @Data
  52 + public static class SubjectRule {
  53 +
  54 + @Schema(description = "科目编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  55 + private Long subjectId;
  56 +
  57 + @Schema(description = "科目编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "560107")
  58 + private String subjectCode;
  59 +
  60 + @Schema(description = "摘要", requiredMode = Schema.RequiredMode.REQUIRED, example = "报销差旅费")
  61 + private String digest;
  62 +
  63 + @Schema(description = "借贷方向", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  64 + private Integer direction;
  65 +
  66 + @Schema(description = "金额比例", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
  67 + private BigDecimal amountRatio;
  68 + }
  69 +
  70 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/closing/vo/FmsClosingTemplateSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.closing.vo;
  2 +
  3 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  4 +import cn.iocoder.yudao.module.fms.enums.closing.FmsClosingTemplateCategoryEnum;
  5 +import cn.iocoder.yudao.module.fms.enums.closing.FmsClosingTimeTypeEnum;
  6 +import cn.iocoder.yudao.module.fms.enums.common.FmsDebitCreditDirectionEnum;
  7 +import cn.iocoder.yudao.module.fms.enums.report.FmsFormulaRuleEnum;
  8 +import io.swagger.v3.oas.annotations.media.Schema;
  9 +import jakarta.validation.Valid;
  10 +import jakarta.validation.constraints.DecimalMax;
  11 +import jakarta.validation.constraints.DecimalMin;
  12 +import jakarta.validation.constraints.NotBlank;
  13 +import jakarta.validation.constraints.NotEmpty;
  14 +import jakarta.validation.constraints.NotNull;
  15 +import jakarta.validation.constraints.Size;
  16 +import lombok.Data;
  17 +
  18 +import java.math.BigDecimal;
  19 +import java.util.List;
  20 +
  21 +@Schema(description = "管理后台 - FMS 结账模板保存 Request VO")
  22 +@Data
  23 +public class FmsClosingTemplateSaveReqVO {
  24 +
  25 + @Schema(description = "模板编号", example = "1024")
  26 + private Long id;
  27 +
  28 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  29 + @NotNull(message = "账套不能为空")
  30 + private Long accountSetId;
  31 +
  32 + @Schema(description = "模板名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "报销差旅费")
  33 + @NotBlank(message = "模板名称不能为空")
  34 + @Size(max = 255, message = "模板名称长度不能超过 255 个字符")
  35 + private String name;
  36 +
  37 + @Schema(description = "模板分类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  38 + @NotNull(message = "模板分类不能为空")
  39 + @InEnum(FmsClosingTemplateCategoryEnum.class)
  40 + private Integer category;
  41 +
  42 + @Schema(description = "是否期末结转", requiredMode = Schema.RequiredMode.REQUIRED)
  43 + @NotNull(message = "是否期末结转不能为空")
  44 + private Boolean periodEnd;
  45 +
  46 + @Schema(description = "来源科目编号", example = "1024")
  47 + private Long subjectId;
  48 +
  49 + @Schema(description = "取数规则", example = "0")
  50 + @InEnum(FmsFormulaRuleEnum.class)
  51 + private Integer formulaRule;
  52 +
  53 + @Schema(description = "取数时间类型", example = "1")
  54 + @InEnum(FmsClosingTimeTypeEnum.class)
  55 + private Integer timeType;
  56 +
  57 + @Schema(description = "结转科目规则数组", requiredMode = Schema.RequiredMode.REQUIRED)
  58 + @Valid
  59 + @NotEmpty(message = "结转科目规则不能为空")
  60 + @Size(min = 2, message = "结转科目规则至少需要两条")
  61 + private List<SubjectRule> subjects;
  62 +
  63 + @Schema(description = "显示顺序", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  64 + @NotNull(message = "显示顺序不能为空")
  65 + private Integer sort;
  66 +
  67 + @Schema(description = "管理后台 - FMS 结账模板科目规则")
  68 + @Data
  69 + public static class SubjectRule {
  70 +
  71 + @Schema(description = "科目编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  72 + @NotNull(message = "科目不能为空")
  73 + private Long subjectId;
  74 +
  75 + @Schema(description = "摘要", requiredMode = Schema.RequiredMode.REQUIRED, example = "报销差旅费")
  76 + @NotBlank(message = "摘要不能为空")
  77 + @Size(max = 500, message = "摘要长度不能超过 500 个字符")
  78 + private String digest;
  79 +
  80 + @Schema(description = "借贷方向", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  81 + @NotNull(message = "借贷方向不能为空")
  82 + @InEnum(FmsDebitCreditDirectionEnum.class)
  83 + private Integer direction;
  84 +
  85 + @Schema(description = "金额比例", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
  86 + @NotNull(message = "金额比例不能为空")
  87 + @DecimalMin(value = "0", inclusive = false, message = "金额比例必须大于 0")
  88 + @DecimalMax(value = "100", message = "金额比例不能超过 100")
  89 + private BigDecimal amountRatio;
  90 + }
  91 +
  92 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/closing/vo/FmsClosingVoucherGenerateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.closing.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotBlank;
  5 +import jakarta.validation.constraints.NotEmpty;
  6 +import jakarta.validation.constraints.NotNull;
  7 +import jakarta.validation.constraints.Pattern;
  8 +import lombok.Data;
  9 +
  10 +import java.util.List;
  11 +
  12 +@Schema(description = "管理后台 - FMS 批量生成结转凭证 Request VO")
  13 +@Data
  14 +public class FmsClosingVoucherGenerateReqVO {
  15 +
  16 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  17 + @NotNull(message = "账套不能为空")
  18 + private Long accountSetId;
  19 +
  20 + @Schema(description = "方案编号数组", requiredMode = Schema.RequiredMode.REQUIRED)
  21 + @NotEmpty(message = "方案编号不能为空")
  22 + private List<@NotNull(message = "方案编号不能为空") Long> ids;
  23 +
  24 + @Schema(description = "会计期间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026-08")
  25 + @NotBlank(message = "会计期间不能为空")
  26 + @Pattern(regexp = "\\d{4}-(0[1-9]|1[0-2])", message = "会计期间格式不正确")
  27 + private String month;
  28 +
  29 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/closing/vo/FmsProfitLossGenerateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.closing.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotBlank;
  5 +import jakarta.validation.constraints.NotNull;
  6 +import jakarta.validation.constraints.Pattern;
  7 +import lombok.Data;
  8 +
  9 +@Schema(description = "管理后台 - FMS 生成结转损益凭证 Request VO")
  10 +@Data
  11 +public class FmsProfitLossGenerateReqVO {
  12 +
  13 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  14 + @NotNull(message = "账套不能为空")
  15 + private Long accountSetId;
  16 +
  17 + @Schema(description = "会计期间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026-08")
  18 + @NotBlank(message = "会计期间不能为空")
  19 + @Pattern(regexp = "\\d{4}-(0[1-9]|1[0-2])", message = "会计期间格式不正确")
  20 + private String month;
  21 +
  22 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/closing/vo/FmsProfitLossSettingsSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.closing.vo;
  2 +
  3 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  4 +import cn.iocoder.yudao.module.fms.enums.closing.FmsClosingVoucherTypeEnum;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import jakarta.validation.constraints.Max;
  7 +import jakarta.validation.constraints.Min;
  8 +import jakarta.validation.constraints.NotBlank;
  9 +import jakarta.validation.constraints.NotNull;
  10 +import jakarta.validation.constraints.Size;
  11 +import lombok.Data;
  12 +
  13 +@Schema(description = "管理后台 - FMS 结转损益设置保存 Request VO")
  14 +@Data
  15 +public class FmsProfitLossSettingsSaveReqVO {
  16 +
  17 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  18 + @NotNull(message = "账套不能为空")
  19 + private Long accountSetId;
  20 +
  21 + @Schema(description = "凭证字编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11")
  22 + @NotNull(message = "凭证字不能为空")
  23 + private Long voucherWordId;
  24 +
  25 + @Schema(description = "凭证摘要", requiredMode = Schema.RequiredMode.REQUIRED, example = "结转损益")
  26 + @NotBlank(message = "凭证摘要不能为空")
  27 + @Size(max = 500, message = "凭证摘要长度不能超过 500 个字符")
  28 + private String digest;
  29 +
  30 + @Schema(description = "结转凭证类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  31 + @NotNull(message = "结转凭证类型不能为空")
  32 + @InEnum(FmsClosingVoucherTypeEnum.class)
  33 + private Integer voucherType;
  34 +
  35 + @Schema(description = "以前年度损益调整科目编号", requiredMode = Schema.RequiredMode.REQUIRED,
  36 + example = "1024")
  37 + @NotNull(message = "以前年度损益调整科目不能为空")
  38 + private Long priorYearAdjustmentSubjectId;
  39 +
  40 + @Schema(description = "以前年度损益调整结转科目编号", requiredMode = Schema.RequiredMode.REQUIRED,
  41 + example = "1025")
  42 + @NotNull(message = "以前年度损益调整结转科目不能为空")
  43 + private Long adjustmentClosingSubjectId;
  44 +
  45 + @Schema(description = "其他损益结转科目编号", requiredMode = Schema.RequiredMode.REQUIRED,
  46 + example = "1026")
  47 + @NotNull(message = "其他损益结转科目不能为空")
  48 + private Long otherClosingSubjectId;
  49 +
  50 + @Schema(description = "是否按余额反向结转", requiredMode = Schema.RequiredMode.REQUIRED)
  51 + @NotNull(message = "结转方式不能为空")
  52 + private Boolean reverseBalance;
  53 +
  54 + @Schema(description = "结转日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "31")
  55 + @NotNull(message = "结转日期不能为空")
  56 + @Min(value = 1, message = "结转日期不能小于 1")
  57 + @Max(value = 31, message = "结转日期不能大于 31")
  58 + private Integer closingDay;
  59 +
  60 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/closing/vo/FmsSpecialClosingSettingsSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.closing.vo;
  2 +
  3 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  4 +import cn.iocoder.yudao.module.fms.enums.common.FmsDebitCreditDirectionEnum;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import jakarta.validation.Valid;
  7 +import jakarta.validation.constraints.DecimalMax;
  8 +import jakarta.validation.constraints.DecimalMin;
  9 +import jakarta.validation.constraints.NotBlank;
  10 +import jakarta.validation.constraints.NotEmpty;
  11 +import jakarta.validation.constraints.NotNull;
  12 +import jakarta.validation.constraints.Size;
  13 +import lombok.Data;
  14 +
  15 +import java.math.BigDecimal;
  16 +import java.util.List;
  17 +
  18 +@Schema(description = "管理后台 - FMS 专用结转设置保存 Request VO")
  19 +@Data
  20 +public class FmsSpecialClosingSettingsSaveReqVO {
  21 +
  22 + @Schema(description = "方案编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  23 + @NotNull(message = "方案编号不能为空")
  24 + private Long id;
  25 +
  26 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  27 + @NotNull(message = "账套不能为空")
  28 + private Long accountSetId;
  29 +
  30 + @Schema(description = "凭证字编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11")
  31 + @NotNull(message = "凭证字不能为空")
  32 + private Long voucherWordId;
  33 +
  34 + @Schema(description = "结转科目规则数组", requiredMode = Schema.RequiredMode.REQUIRED)
  35 + @Valid
  36 + @NotEmpty(message = "结转科目规则不能为空")
  37 + @Size(min = 2, message = "结转科目规则至少需要两条")
  38 + private List<SubjectRule> subjects;
  39 +
  40 + @Schema(description = "管理后台 - FMS 专用结转科目规则")
  41 + @Data
  42 + public static class SubjectRule {
  43 +
  44 + @Schema(description = "科目编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  45 + @NotNull(message = "科目不能为空")
  46 + private Long subjectId;
  47 +
  48 + @Schema(description = "摘要", requiredMode = Schema.RequiredMode.REQUIRED, example = "计提所得税")
  49 + @NotBlank(message = "摘要不能为空")
  50 + @Size(max = 500, message = "摘要长度不能超过 500 个字符")
  51 + private String digest;
  52 +
  53 + @Schema(description = "借贷方向", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  54 + @NotNull(message = "借贷方向不能为空")
  55 + @InEnum(FmsDebitCreditDirectionEnum.class)
  56 + private Integer direction;
  57 +
  58 + @Schema(description = "金额比例", requiredMode = Schema.RequiredMode.REQUIRED, example = "25")
  59 + @NotNull(message = "金额比例不能为空")
  60 + @DecimalMin(value = "0", inclusive = false, message = "金额比例必须大于 0")
  61 + @DecimalMax(value = "100", message = "金额比例不能超过 100")
  62 + private BigDecimal amountRatio;
  63 + }
  64 +
  65 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/FmsAccountSetController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  5 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.accountset.FmsAccountSetInitializeReqVO;
  6 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.accountset.FmsAccountSetRespVO;
  7 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.accountset.FmsAccountSetSaveReqVO;
  8 +import cn.iocoder.yudao.module.fms.dal.dataobject.config.FmsAccountSetDO;
  9 +import cn.iocoder.yudao.module.fms.dal.dataobject.config.FmsAccountUserDO;
  10 +import cn.iocoder.yudao.module.fms.service.config.FmsAccountSetService;
  11 +import cn.iocoder.yudao.module.fms.service.config.FmsAccountUserService;
  12 +import io.swagger.v3.oas.annotations.Operation;
  13 +import io.swagger.v3.oas.annotations.Parameter;
  14 +import io.swagger.v3.oas.annotations.tags.Tag;
  15 +import jakarta.annotation.Resource;
  16 +import jakarta.validation.Valid;
  17 +import org.springframework.security.access.prepost.PreAuthorize;
  18 +import org.springframework.validation.annotation.Validated;
  19 +import org.springframework.web.bind.annotation.GetMapping;
  20 +import org.springframework.web.bind.annotation.PostMapping;
  21 +import org.springframework.web.bind.annotation.PutMapping;
  22 +import org.springframework.web.bind.annotation.RequestBody;
  23 +import org.springframework.web.bind.annotation.RequestMapping;
  24 +import org.springframework.web.bind.annotation.RequestParam;
  25 +import org.springframework.web.bind.annotation.RestController;
  26 +
  27 +import java.util.List;
  28 +import java.util.Map;
  29 +
  30 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  31 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  32 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
  33 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  34 +
  35 +@Tag(name = "管理后台 - FMS 账套")
  36 +@RestController
  37 +@RequestMapping("/fms/config/account-set")
  38 +@Validated
  39 +public class FmsAccountSetController {
  40 +
  41 + @Resource
  42 + private FmsAccountSetService accountSetService;
  43 + @Resource
  44 + private FmsAccountUserService accountUserService;
  45 +
  46 + @PostMapping("/create")
  47 + @Operation(summary = "创建账套")
  48 + @PreAuthorize("@ss.hasPermission('fms:config:account-set:create')")
  49 + public CommonResult<Long> createAccountSet(@Valid @RequestBody FmsAccountSetSaveReqVO createReqVO) {
  50 + return success(accountSetService.createAccountSet(createReqVO, getLoginUserId()));
  51 + }
  52 +
  53 + @PutMapping("/update")
  54 + @Operation(summary = "更新账套")
  55 + @PreAuthorize("@ss.hasPermission('fms:config:account-set:update')")
  56 + public CommonResult<Boolean> updateAccountSet(@Valid @RequestBody FmsAccountSetSaveReqVO updateReqVO) {
  57 + accountSetService.updateAccountSet(updateReqVO, getLoginUserId());
  58 + return success(true);
  59 + }
  60 +
  61 + @PutMapping("/initialize")
  62 + @Operation(summary = "初始化账套")
  63 + @PreAuthorize("@ss.hasPermission('fms:config:account-set:initialize')")
  64 + public CommonResult<Boolean> initializeAccountSet(
  65 + @Valid @RequestBody FmsAccountSetInitializeReqVO initializeReqVO) {
  66 + accountSetService.initializeAccountSet(initializeReqVO, getLoginUserId());
  67 + return success(true);
  68 + }
  69 +
  70 + @GetMapping("/get")
  71 + @Operation(summary = "获得账套")
  72 + @Parameter(name = "id", description = "账套编号", required = true, example = "1024")
  73 + @PreAuthorize("@ss.hasPermission('fms:config:account-set:query')")
  74 + public CommonResult<FmsAccountSetRespVO> getAccountSet(@RequestParam("id") Long id) {
  75 + FmsAccountSetDO accountSet = accountSetService.validateAccountSetReadPermission(id, getLoginUserId());
  76 + FmsAccountUserDO accountUser = accountUserService.getAccountUser(id, getLoginUserId());
  77 + return success(buildAccountSetRespVO(accountSet, accountUser));
  78 + }
  79 +
  80 + @GetMapping("/list")
  81 + @Operation(summary = "获得当前用户账套列表")
  82 + @PreAuthorize("@ss.hasPermission('fms:config:account-set:query')")
  83 + public CommonResult<List<FmsAccountSetRespVO>> getAccountSetList() {
  84 + List<FmsAccountUserDO> accountUsers = accountUserService.getAccountUserList(getLoginUserId());
  85 + Map<Long, FmsAccountSetDO> accountSetMap = accountSetService.getAccountSetMap(
  86 + convertSet(accountUsers, FmsAccountUserDO::getAccountSetId));
  87 + return success(buildAccountSetRespVOList(accountSetMap, accountUsers));
  88 + }
  89 +
  90 + // ==================== 拼接 VO ====================
  91 +
  92 + private FmsAccountSetRespVO buildAccountSetRespVO(
  93 + FmsAccountSetDO accountSet, FmsAccountUserDO accountUser) {
  94 + return BeanUtils.toBean(accountSet, FmsAccountSetRespVO.class)
  95 + .setDefaultStatus(accountUser.getDefaultStatus()).setFounder(accountUser.getFounder())
  96 + .setLevel(accountUser.getLevel());
  97 + }
  98 +
  99 + private List<FmsAccountSetRespVO> buildAccountSetRespVOList(
  100 + Map<Long, FmsAccountSetDO> accountSetMap, List<FmsAccountUserDO> accountUsers) {
  101 + return convertList(accountUsers, accountUser -> buildAccountSetRespVO(
  102 + accountSetMap.get(accountUser.getAccountSetId()), accountUser));
  103 + }
  104 +
  105 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/FmsAccountUserController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  5 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.accountuser.FmsAccountUserRespVO;
  6 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.accountuser.FmsAccountUserUpdateReqVO;
  7 +import cn.iocoder.yudao.module.fms.dal.dataobject.config.FmsAccountUserDO;
  8 +import cn.iocoder.yudao.module.fms.service.config.FmsAccountUserService;
  9 +import cn.iocoder.yudao.module.system.api.dept.DeptApi;
  10 +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
  11 +import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  12 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
  13 +import io.swagger.v3.oas.annotations.Operation;
  14 +import io.swagger.v3.oas.annotations.Parameter;
  15 +import io.swagger.v3.oas.annotations.tags.Tag;
  16 +import jakarta.annotation.Resource;
  17 +import jakarta.validation.Valid;
  18 +import org.springframework.security.access.prepost.PreAuthorize;
  19 +import org.springframework.validation.annotation.Validated;
  20 +import org.springframework.web.bind.annotation.GetMapping;
  21 +import org.springframework.web.bind.annotation.PutMapping;
  22 +import org.springframework.web.bind.annotation.RequestBody;
  23 +import org.springframework.web.bind.annotation.RequestMapping;
  24 +import org.springframework.web.bind.annotation.RequestParam;
  25 +import org.springframework.web.bind.annotation.RestController;
  26 +
  27 +import java.util.List;
  28 +import java.util.Map;
  29 +
  30 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  31 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  32 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
  33 +import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
  34 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  35 +
  36 +@Tag(name = "管理后台 - FMS 账套用户")
  37 +@RestController
  38 +@RequestMapping("/fms/config/account-user")
  39 +@Validated
  40 +public class FmsAccountUserController {
  41 +
  42 + @Resource
  43 + private FmsAccountUserService accountUserService;
  44 + @Resource
  45 + private AdminUserApi adminUserApi;
  46 + @Resource
  47 + private DeptApi deptApi;
  48 +
  49 + @GetMapping("/list")
  50 + @Operation(summary = "获得账套用户列表")
  51 + @Parameter(name = "accountSetId", description = "账套编号", required = true, example = "1024")
  52 + @PreAuthorize("@ss.hasPermission('fms:config:account-set:authorize')")
  53 + public CommonResult<List<FmsAccountUserRespVO>> getAccountUserList(
  54 + @RequestParam("accountSetId") Long accountSetId) {
  55 + List<FmsAccountUserDO> accountUsers = accountUserService.getAccountUserList(
  56 + accountSetId, getLoginUserId());
  57 + return success(buildAccountUserRespVOList(accountUsers));
  58 + }
  59 +
  60 + @PutMapping("/update")
  61 + @Operation(summary = "更新账套用户列表")
  62 + @PreAuthorize("@ss.hasPermission('fms:config:account-set:authorize')")
  63 + public CommonResult<Boolean> updateAccountUserList(
  64 + @Valid @RequestBody FmsAccountUserUpdateReqVO updateReqVO) {
  65 + accountUserService.updateAccountUserList(updateReqVO, getLoginUserId());
  66 + return success(true);
  67 + }
  68 +
  69 + @PutMapping("/update-default-status")
  70 + @Operation(summary = "更新默认账套状态")
  71 + @PreAuthorize("@ss.hasPermission('fms:config:account-set:query')")
  72 + public CommonResult<Boolean> updateAccountSetDefaultStatus(@RequestParam("accountSetId") Long accountSetId) {
  73 + accountUserService.updateAccountSetDefaultStatus(accountSetId, getLoginUserId());
  74 + return success(true);
  75 + }
  76 +
  77 + // ==================== 拼接 VO ====================
  78 +
  79 + private List<FmsAccountUserRespVO> buildAccountUserRespVOList(List<FmsAccountUserDO> accountUsers) {
  80 + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
  81 + convertSet(accountUsers, FmsAccountUserDO::getUserId));
  82 + Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(
  83 + convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
  84 + return convertList(accountUsers, accountUser -> {
  85 + FmsAccountUserRespVO respVO = BeanUtils.toBean(accountUser, FmsAccountUserRespVO.class);
  86 + findAndThen(userMap, accountUser.getUserId(), user -> {
  87 + respVO.setNickname(user.getNickname()).setMobile(user.getMobile())
  88 + .setEmail(user.getEmail()).setStatus(user.getStatus());
  89 + findAndThen(deptMap, user.getDeptId(), dept -> respVO.setDeptName(dept.getName()));
  90 + });
  91 + return respVO;
  92 + });
  93 + }
  94 +
  95 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/FmsAuxiliaryItemController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config;
  2 +
  3 +import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
  4 +import cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum;
  5 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  6 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  7 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  8 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  9 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  10 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  11 +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  12 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.auxiliaryitem.FmsAuxiliaryItemImportExcelVO;
  13 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.auxiliaryitem.FmsAuxiliaryItemImportRespVO;
  14 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.auxiliaryitem.FmsAuxiliaryItemPageReqVO;
  15 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.auxiliaryitem.FmsAuxiliaryItemRespVO;
  16 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.auxiliaryitem.FmsAuxiliaryItemSaveReqVO;
  17 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.auxiliaryitem.FmsAuxiliaryItemStatusReqVO;
  18 +import cn.iocoder.yudao.module.fms.dal.dataobject.config.FmsAuxiliaryItemDO;
  19 +import cn.iocoder.yudao.module.fms.dal.dataobject.config.FmsAuxiliaryTypeDO;
  20 +import cn.iocoder.yudao.module.fms.enums.config.FmsAuxiliaryTypeEnum;
  21 +import cn.iocoder.yudao.module.fms.service.config.FmsAuxiliaryItemService;
  22 +import cn.iocoder.yudao.module.fms.service.config.FmsAuxiliaryTypeService;
  23 +import io.swagger.v3.oas.annotations.Operation;
  24 +import io.swagger.v3.oas.annotations.Parameter;
  25 +import io.swagger.v3.oas.annotations.Parameters;
  26 +import io.swagger.v3.oas.annotations.tags.Tag;
  27 +import jakarta.annotation.Resource;
  28 +import jakarta.servlet.http.HttpServletResponse;
  29 +import jakarta.validation.Valid;
  30 +import jakarta.validation.constraints.NotEmpty;
  31 +import jakarta.validation.constraints.NotNull;
  32 +import org.springframework.security.access.prepost.PreAuthorize;
  33 +import org.springframework.validation.annotation.Validated;
  34 +import org.springframework.web.bind.annotation.DeleteMapping;
  35 +import org.springframework.web.bind.annotation.GetMapping;
  36 +import org.springframework.web.bind.annotation.PostMapping;
  37 +import org.springframework.web.bind.annotation.PutMapping;
  38 +import org.springframework.web.bind.annotation.RequestBody;
  39 +import org.springframework.web.bind.annotation.RequestMapping;
  40 +import org.springframework.web.bind.annotation.RequestParam;
  41 +import org.springframework.web.bind.annotation.RestController;
  42 +import org.springframework.web.multipart.MultipartFile;
  43 +
  44 +import java.io.IOException;
  45 +import java.util.ArrayList;
  46 +import java.util.Arrays;
  47 +import java.util.Collections;
  48 +import java.util.List;
  49 +
  50 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  51 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  52 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  53 +
  54 +@Tag(name = "管理后台 - FMS 辅助核算项目")
  55 +@RestController
  56 +@RequestMapping("/fms/config/auxiliary-item")
  57 +@Validated
  58 +public class FmsAuxiliaryItemController {
  59 +
  60 + @Resource
  61 + private FmsAuxiliaryItemService auxiliaryItemService;
  62 + @Resource
  63 + private FmsAuxiliaryTypeService auxiliaryTypeService;
  64 +
  65 + @PostMapping("/create")
  66 + @Operation(summary = "创建辅助核算项目")
  67 + @PreAuthorize("@ss.hasPermission('fms:config:auxiliary:create')")
  68 + public CommonResult<Long> createAuxiliaryItem(@Valid @RequestBody FmsAuxiliaryItemSaveReqVO createReqVO) {
  69 + return success(auxiliaryItemService.createAuxiliaryItem(createReqVO, getLoginUserId()));
  70 + }
  71 +
  72 + @PutMapping("/update")
  73 + @Operation(summary = "更新辅助核算项目")
  74 + @PreAuthorize("@ss.hasPermission('fms:config:auxiliary:update')")
  75 + public CommonResult<Boolean> updateAuxiliaryItem(
  76 + @Valid @RequestBody FmsAuxiliaryItemSaveReqVO updateReqVO) {
  77 + auxiliaryItemService.updateAuxiliaryItem(updateReqVO, getLoginUserId());
  78 + return success(true);
  79 + }
  80 +
  81 + @DeleteMapping("/delete-list")
  82 + @Operation(summary = "删除辅助核算项目")
  83 + @Parameters({
  84 + @Parameter(name = "accountSetId", description = "账套编号", required = true, example = "1024"),
  85 + @Parameter(name = "ids", description = "辅助核算项目编号数组", required = true, example = "[1024]")
  86 + })
  87 + @PreAuthorize("@ss.hasPermission('fms:config:auxiliary:delete')")
  88 + public CommonResult<Boolean> deleteAuxiliaryItemList(
  89 + @RequestParam("accountSetId") @NotNull Long accountSetId,
  90 + @RequestParam("ids") @NotEmpty List<Long> ids) {
  91 + auxiliaryItemService.deleteAuxiliaryItemList(accountSetId, ids, getLoginUserId());
  92 + return success(true);
  93 + }
  94 +
  95 + @PutMapping("/update-status")
  96 + @Operation(summary = "更新辅助核算项目状态")
  97 + @PreAuthorize("@ss.hasPermission('fms:config:auxiliary:update')")
  98 + public CommonResult<Boolean> updateAuxiliaryItemStatus(
  99 + @Valid @RequestBody FmsAuxiliaryItemStatusReqVO reqVO) {
  100 + auxiliaryItemService.updateAuxiliaryItemStatus(
  101 + reqVO.getAccountSetId(), reqVO.getId(), reqVO.getStatus(), getLoginUserId());
  102 + return success(true);
  103 + }
  104 +
  105 + @GetMapping("/get")
  106 + @Operation(summary = "获得辅助核算项目")
  107 + @Parameters({
  108 + @Parameter(name = "accountSetId", description = "账套编号", required = true, example = "1024"),
  109 + @Parameter(name = "id", description = "辅助核算项目编号", required = true, example = "1024")
  110 + })
  111 + @PreAuthorize("@ss.hasPermission('fms:config:auxiliary:query')")
  112 + public CommonResult<FmsAuxiliaryItemRespVO> getAuxiliaryItem(@RequestParam("accountSetId") @NotNull Long accountSetId,
  113 + @RequestParam("id") @NotNull Long id) {
  114 + FmsAuxiliaryItemDO item = auxiliaryItemService.getAuxiliaryItem(accountSetId, id, getLoginUserId());
  115 + return success(BeanUtils.toBean(item, FmsAuxiliaryItemRespVO.class));
  116 + }
  117 +
  118 + @GetMapping("/page")
  119 + @Operation(summary = "获得辅助核算项目分页")
  120 + @PreAuthorize("@ss.hasAnyPermissions('fms:config:auxiliary:query', 'fms:voucher:create', "
  121 + + "'fms:voucher:update')")
  122 + public CommonResult<PageResult<FmsAuxiliaryItemRespVO>> getAuxiliaryItemPage(
  123 + @Valid FmsAuxiliaryItemPageReqVO pageReqVO) {
  124 + PageResult<FmsAuxiliaryItemDO> pageResult = auxiliaryItemService
  125 + .getAuxiliaryItemPage(pageReqVO, getLoginUserId());
  126 + return success(BeanUtils.toBean(pageResult, FmsAuxiliaryItemRespVO.class));
  127 + }
  128 +
  129 + @GetMapping("/simple-list")
  130 + @Operation(summary = "获得辅助核算项目精简列表", description = "只包含启用的项目,主要用于前端下拉选项")
  131 + @Parameters({
  132 + @Parameter(name = "accountSetId", description = "账套编号", required = true, example = "1024"),
  133 + @Parameter(name = "auxiliaryTypeId", description = "辅助核算类别编号", required = true,
  134 + example = "1024")
  135 + })
  136 + public CommonResult<List<FmsAuxiliaryItemRespVO>> getAuxiliaryItemSimpleList(
  137 + @RequestParam("accountSetId") @NotNull Long accountSetId,
  138 + @RequestParam("auxiliaryTypeId") @NotNull Long auxiliaryTypeId) {
  139 + List<FmsAuxiliaryItemDO> list = auxiliaryItemService
  140 + .getAuxiliaryItemListByAccountSetIdAndAuxiliaryTypeIdAndStatus(
  141 + accountSetId, auxiliaryTypeId, CommonStatusEnum.ENABLE.getStatus(), getLoginUserId());
  142 + return success(convertList(list, item -> new FmsAuxiliaryItemRespVO()
  143 + .setId(item.getId()).setCode(item.getCode()).setName(item.getName())));
  144 + }
  145 +
  146 + @GetMapping("/export-excel")
  147 + @Operation(summary = "导出辅助核算项目")
  148 + @PreAuthorize("@ss.hasPermission('fms:config:auxiliary:export')")
  149 + @ApiAccessLog(operateType = OperateTypeEnum.EXPORT)
  150 + public void exportAuxiliaryItemExcel(
  151 + @Valid FmsAuxiliaryItemPageReqVO pageReqVO, HttpServletResponse response) throws IOException {
  152 + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
  153 + List<FmsAuxiliaryItemDO> list = auxiliaryItemService
  154 + .getAuxiliaryItemPage(pageReqVO, getLoginUserId()).getList();
  155 + FmsAuxiliaryTypeDO auxiliaryType = auxiliaryTypeService.getAuxiliaryType(
  156 + pageReqVO.getAccountSetId(), pageReqVO.getAuxiliaryTypeId(), getLoginUserId());
  157 + ExcelUtils.write(response, auxiliaryType.getName() + ".xlsx", "辅助核算项目",
  158 + buildAuxiliaryItemExcelHead(auxiliaryType.getType()), buildAuxiliaryItemExcelData(list,
  159 + auxiliaryType.getType()));
  160 + }
  161 +
  162 + @GetMapping("/get-import-template")
  163 + @Operation(summary = "获得辅助核算项目导入模板")
  164 + @Parameter(name = "type", description = "辅助核算类别类型", required = true, example = "1")
  165 + @PreAuthorize("@ss.hasPermission('fms:config:auxiliary:import')")
  166 + @ApiAccessLog(operateType = OperateTypeEnum.EXPORT)
  167 + public void getAuxiliaryItemImportTemplate(
  168 + @RequestParam("type") @InEnum(FmsAuxiliaryTypeEnum.class) Integer type,
  169 + HttpServletResponse response) throws IOException {
  170 + FmsAuxiliaryItemImportExcelVO example = new FmsAuxiliaryItemImportExcelVO()
  171 + .setCode("001").setName("示例项目").setRemark("示例备注");
  172 + if (FmsAuxiliaryTypeEnum.INVENTORY.getType().equals(type)) {
  173 + example.setSpecification("标准版").setUnit("个");
  174 + }
  175 + ExcelUtils.write(response, "辅助核算项目导入模板.xlsx", "辅助核算项目",
  176 + FmsAuxiliaryItemImportExcelVO.class, Collections.singletonList(example));
  177 + }
  178 +
  179 + @PostMapping("/import")
  180 + @Operation(summary = "导入辅助核算项目")
  181 + @Parameters({
  182 + @Parameter(name = "accountSetId", description = "账套编号", required = true),
  183 + @Parameter(name = "auxiliaryTypeId", description = "辅助核算类别编号", required = true),
  184 + @Parameter(name = "file", description = "Excel 文件", required = true)
  185 + })
  186 + @PreAuthorize("@ss.hasPermission('fms:config:auxiliary:import')")
  187 + @ApiAccessLog(operateType = OperateTypeEnum.IMPORT)
  188 + public CommonResult<FmsAuxiliaryItemImportRespVO> importAuxiliaryItem(
  189 + @RequestParam("accountSetId") @NotNull Long accountSetId,
  190 + @RequestParam("auxiliaryTypeId") @NotNull Long auxiliaryTypeId,
  191 + @RequestParam("file") MultipartFile file) throws Exception {
  192 + List<FmsAuxiliaryItemImportExcelVO> importItems = ExcelUtils.read(
  193 + file, FmsAuxiliaryItemImportExcelVO.class);
  194 + return success(auxiliaryItemService.importAuxiliaryItemList(
  195 + accountSetId, auxiliaryTypeId, importItems, getLoginUserId()));
  196 + }
  197 +
  198 + /** 构建辅助核算项目导出的动态表头 */
  199 + private List<List<String>> buildAuxiliaryItemExcelHead(Integer type) {
  200 + if (FmsAuxiliaryTypeEnum.CUSTOMER.getType().equals(type)
  201 + || FmsAuxiliaryTypeEnum.SUPPLIER.getType().equals(type)) {
  202 + return Arrays.asList(Collections.singletonList("编码"), Collections.singletonList("名称"),
  203 + Collections.singletonList("备注"));
  204 + }
  205 + if (FmsAuxiliaryTypeEnum.INVENTORY.getType().equals(type)) {
  206 + return Arrays.asList(Collections.singletonList("编码"), Collections.singletonList("名称"),
  207 + Collections.singletonList("规格"), Collections.singletonList("单位"));
  208 + }
  209 + return Arrays.asList(Collections.singletonList("编码"), Collections.singletonList("名称"));
  210 + }
  211 +
  212 + /** 构建辅助核算项目导出的动态数据 */
  213 + private List<List<Object>> buildAuxiliaryItemExcelData(List<FmsAuxiliaryItemDO> items, Integer type) {
  214 + List<List<Object>> rows = new ArrayList<>(items.size());
  215 + for (FmsAuxiliaryItemDO item : items) {
  216 + if (FmsAuxiliaryTypeEnum.CUSTOMER.getType().equals(type)
  217 + || FmsAuxiliaryTypeEnum.SUPPLIER.getType().equals(type)) {
  218 + rows.add(Arrays.asList(item.getCode(), item.getName(), item.getRemark()));
  219 + } else if (FmsAuxiliaryTypeEnum.INVENTORY.getType().equals(type)) {
  220 + rows.add(Arrays.asList(item.getCode(), item.getName(), item.getSpecification(), item.getUnit()));
  221 + } else {
  222 + rows.add(Arrays.asList(item.getCode(), item.getName()));
  223 + }
  224 + }
  225 + return rows;
  226 + }
  227 +
  228 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/FmsAuxiliaryTypeController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  5 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.auxiliarytype.FmsAuxiliaryTypeRespVO;
  6 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.auxiliarytype.FmsAuxiliaryTypeSaveReqVO;
  7 +import cn.iocoder.yudao.module.fms.dal.dataobject.config.FmsAuxiliaryTypeDO;
  8 +import cn.iocoder.yudao.module.fms.service.config.FmsAuxiliaryTypeService;
  9 +import io.swagger.v3.oas.annotations.Operation;
  10 +import io.swagger.v3.oas.annotations.Parameter;
  11 +import io.swagger.v3.oas.annotations.Parameters;
  12 +import io.swagger.v3.oas.annotations.tags.Tag;
  13 +import jakarta.annotation.Resource;
  14 +import jakarta.validation.Valid;
  15 +import jakarta.validation.constraints.NotNull;
  16 +import org.springframework.security.access.prepost.PreAuthorize;
  17 +import org.springframework.validation.annotation.Validated;
  18 +import org.springframework.web.bind.annotation.DeleteMapping;
  19 +import org.springframework.web.bind.annotation.GetMapping;
  20 +import org.springframework.web.bind.annotation.PostMapping;
  21 +import org.springframework.web.bind.annotation.PutMapping;
  22 +import org.springframework.web.bind.annotation.RequestMapping;
  23 +import org.springframework.web.bind.annotation.RequestBody;
  24 +import org.springframework.web.bind.annotation.RequestParam;
  25 +import org.springframework.web.bind.annotation.RestController;
  26 +
  27 +import java.util.List;
  28 +
  29 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  30 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  31 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  32 +
  33 +@Tag(name = "管理后台 - FMS 辅助核算类别")
  34 +@RestController
  35 +@RequestMapping("/fms/config/auxiliary-type")
  36 +@Validated
  37 +public class FmsAuxiliaryTypeController {
  38 +
  39 + @Resource
  40 + private FmsAuxiliaryTypeService auxiliaryTypeService;
  41 +
  42 + @PostMapping("/create")
  43 + @Operation(summary = "创建辅助核算类别")
  44 + @PreAuthorize("@ss.hasPermission('fms:config:auxiliary:create')")
  45 + public CommonResult<Long> createAuxiliaryType(@Valid @RequestBody FmsAuxiliaryTypeSaveReqVO createReqVO) {
  46 + return success(auxiliaryTypeService.createAuxiliaryType(createReqVO, getLoginUserId()));
  47 + }
  48 +
  49 + @PutMapping("/update")
  50 + @Operation(summary = "更新辅助核算类别")
  51 + @PreAuthorize("@ss.hasPermission('fms:config:auxiliary:update')")
  52 + public CommonResult<Boolean> updateAuxiliaryType(@Valid @RequestBody FmsAuxiliaryTypeSaveReqVO updateReqVO) {
  53 + auxiliaryTypeService.updateAuxiliaryType(updateReqVO, getLoginUserId());
  54 + return success(true);
  55 + }
  56 +
  57 + @DeleteMapping("/delete")
  58 + @Operation(summary = "删除辅助核算类别")
  59 + @Parameters({
  60 + @Parameter(name = "accountSetId", description = "账套编号", required = true, example = "1024"),
  61 + @Parameter(name = "id", description = "辅助核算类别编号", required = true, example = "1024")
  62 + })
  63 + @PreAuthorize("@ss.hasPermission('fms:config:auxiliary:delete')")
  64 + public CommonResult<Boolean> deleteAuxiliaryType(
  65 + @RequestParam("accountSetId") @NotNull Long accountSetId,
  66 + @RequestParam("id") @NotNull Long id) {
  67 + auxiliaryTypeService.deleteAuxiliaryType(accountSetId, id, getLoginUserId());
  68 + return success(true);
  69 + }
  70 +
  71 + @GetMapping("/list")
  72 + @Operation(summary = "获得辅助核算类别列表")
  73 + @Parameter(name = "accountSetId", description = "账套编号", required = true, example = "1024")
  74 + @PreAuthorize("@ss.hasPermission('fms:config:auxiliary:query')")
  75 + public CommonResult<List<FmsAuxiliaryTypeRespVO>> getAuxiliaryTypeList(
  76 + @RequestParam("accountSetId") @NotNull Long accountSetId) {
  77 + return success(BeanUtils.toBean(auxiliaryTypeService.getAuxiliaryTypeList(
  78 + accountSetId, getLoginUserId()), FmsAuxiliaryTypeRespVO.class));
  79 + }
  80 +
  81 + @GetMapping("/simple-list")
  82 + @Operation(summary = "获得辅助核算类别精简列表", description = "主要用于前端的下拉选项")
  83 + @Parameter(name = "accountSetId", description = "账套编号", required = true, example = "1024")
  84 + public CommonResult<List<FmsAuxiliaryTypeRespVO>> getAuxiliaryTypeSimpleList(
  85 + @RequestParam("accountSetId") @NotNull Long accountSetId) {
  86 + List<FmsAuxiliaryTypeDO> list = auxiliaryTypeService.getAuxiliaryTypeList(
  87 + accountSetId, getLoginUserId());
  88 + return success(convertList(list, auxiliaryType -> new FmsAuxiliaryTypeRespVO()
  89 + .setId(auxiliaryType.getId()).setName(auxiliaryType.getName()).setType(auxiliaryType.getType())));
  90 + }
  91 +
  92 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/FmsCurrencyController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  5 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.currency.FmsCurrencyRespVO;
  6 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.currency.FmsCurrencySaveReqVO;
  7 +import cn.iocoder.yudao.module.fms.dal.dataobject.config.FmsCurrencyDO;
  8 +import cn.iocoder.yudao.module.fms.service.config.FmsCurrencyService;
  9 +import io.swagger.v3.oas.annotations.Operation;
  10 +import io.swagger.v3.oas.annotations.Parameter;
  11 +import io.swagger.v3.oas.annotations.Parameters;
  12 +import io.swagger.v3.oas.annotations.tags.Tag;
  13 +import jakarta.annotation.Resource;
  14 +import jakarta.validation.Valid;
  15 +import jakarta.validation.constraints.NotNull;
  16 +import org.springframework.security.access.prepost.PreAuthorize;
  17 +import org.springframework.validation.annotation.Validated;
  18 +import org.springframework.web.bind.annotation.DeleteMapping;
  19 +import org.springframework.web.bind.annotation.GetMapping;
  20 +import org.springframework.web.bind.annotation.PostMapping;
  21 +import org.springframework.web.bind.annotation.PutMapping;
  22 +import org.springframework.web.bind.annotation.RequestBody;
  23 +import org.springframework.web.bind.annotation.RequestMapping;
  24 +import org.springframework.web.bind.annotation.RequestParam;
  25 +import org.springframework.web.bind.annotation.RestController;
  26 +
  27 +import java.util.List;
  28 +
  29 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  30 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  31 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  32 +
  33 +@Tag(name = "管理后台 - FMS 币别")
  34 +@RestController
  35 +@RequestMapping("/fms/config/currency")
  36 +@Validated
  37 +public class FmsCurrencyController {
  38 +
  39 + @Resource
  40 + private FmsCurrencyService currencyService;
  41 +
  42 + @PostMapping("/create")
  43 + @Operation(summary = "创建币别")
  44 + @PreAuthorize("@ss.hasPermission('fms:config:currency:create')")
  45 + public CommonResult<Long> createCurrency(@Valid @RequestBody FmsCurrencySaveReqVO createReqVO) {
  46 + return success(currencyService.createCurrency(createReqVO, getLoginUserId()));
  47 + }
  48 +
  49 + @PutMapping("/update")
  50 + @Operation(summary = "更新币别")
  51 + @PreAuthorize("@ss.hasPermission('fms:config:currency:update')")
  52 + public CommonResult<Boolean> updateCurrency(@Valid @RequestBody FmsCurrencySaveReqVO updateReqVO) {
  53 + currencyService.updateCurrency(updateReqVO, getLoginUserId());
  54 + return success(true);
  55 + }
  56 +
  57 + @DeleteMapping("/delete")
  58 + @Operation(summary = "删除币别")
  59 + @Parameters({
  60 + @Parameter(name = "accountSetId", description = "账套编号", required = true, example = "1024"),
  61 + @Parameter(name = "id", description = "币别编号", required = true, example = "1024")
  62 + })
  63 + @PreAuthorize("@ss.hasPermission('fms:config:currency:delete')")
  64 + public CommonResult<Boolean> deleteCurrency(
  65 + @RequestParam("accountSetId") @NotNull Long accountSetId,
  66 + @RequestParam("id") @NotNull Long id) {
  67 + currencyService.deleteCurrency(accountSetId, id, getLoginUserId());
  68 + return success(true);
  69 + }
  70 +
  71 + @GetMapping("/list")
  72 + @Operation(summary = "获得币别列表")
  73 + @Parameter(name = "accountSetId", description = "账套编号", required = true, example = "1024")
  74 + @PreAuthorize("@ss.hasPermission('fms:config:currency:query')")
  75 + public CommonResult<List<FmsCurrencyRespVO>> getCurrencyList(
  76 + @RequestParam("accountSetId") @NotNull Long accountSetId) {
  77 + List<FmsCurrencyDO> list = currencyService.getCurrencyList(accountSetId, getLoginUserId());
  78 + return success(BeanUtils.toBean(list, FmsCurrencyRespVO.class));
  79 + }
  80 +
  81 + @GetMapping("/simple-list")
  82 + @Operation(summary = "获得币别精简列表", description = "主要用于前端的下拉选项")
  83 + @Parameter(name = "accountSetId", description = "账套编号", required = true, example = "1024")
  84 + public CommonResult<List<FmsCurrencyRespVO>> getCurrencySimpleList(
  85 + @RequestParam("accountSetId") @NotNull Long accountSetId) {
  86 + List<FmsCurrencyDO> list = currencyService.getCurrencyList(accountSetId, getLoginUserId());
  87 + return success(convertList(list, currency -> new FmsCurrencyRespVO()
  88 + .setId(currency.getId()).setCode(currency.getCode()).setName(currency.getName())
  89 + .setExchangeRate(currency.getExchangeRate()).setStandard(currency.getStandard())));
  90 + }
  91 +
  92 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/FmsDigestController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  5 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.digest.FmsDigestRespVO;
  6 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.digest.FmsDigestSaveReqVO;
  7 +import cn.iocoder.yudao.module.fms.dal.dataobject.config.FmsDigestDO;
  8 +import cn.iocoder.yudao.module.fms.service.config.FmsDigestService;
  9 +import io.swagger.v3.oas.annotations.Operation;
  10 +import io.swagger.v3.oas.annotations.Parameter;
  11 +import io.swagger.v3.oas.annotations.tags.Tag;
  12 +import jakarta.annotation.Resource;
  13 +import jakarta.validation.Valid;
  14 +import jakarta.validation.constraints.NotNull;
  15 +import org.springframework.security.access.prepost.PreAuthorize;
  16 +import org.springframework.validation.annotation.Validated;
  17 +import org.springframework.web.bind.annotation.DeleteMapping;
  18 +import org.springframework.web.bind.annotation.GetMapping;
  19 +import org.springframework.web.bind.annotation.PostMapping;
  20 +import org.springframework.web.bind.annotation.PutMapping;
  21 +import org.springframework.web.bind.annotation.RequestBody;
  22 +import org.springframework.web.bind.annotation.RequestMapping;
  23 +import org.springframework.web.bind.annotation.RequestParam;
  24 +import org.springframework.web.bind.annotation.RestController;
  25 +
  26 +import java.util.List;
  27 +
  28 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  29 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  30 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  31 +
  32 +/**
  33 + * FMS 常用摘要 Controller
  34 + *
  35 + * @author 芋道源码
  36 + */
  37 +@Tag(name = "管理后台 - FMS 常用摘要")
  38 +@RestController
  39 +@RequestMapping("/fms/config/digest")
  40 +@Validated
  41 +public class FmsDigestController {
  42 +
  43 + @Resource
  44 + private FmsDigestService digestService;
  45 +
  46 + @PostMapping("/create")
  47 + @Operation(summary = "创建常用摘要")
  48 + @PreAuthorize("@ss.hasPermission('fms:config:digest:create')")
  49 + public CommonResult<Long> createDigest(@Valid @RequestBody FmsDigestSaveReqVO createReqVO) {
  50 + return success(digestService.createDigest(createReqVO, getLoginUserId()));
  51 + }
  52 +
  53 + @PutMapping("/update")
  54 + @Operation(summary = "修改常用摘要")
  55 + @PreAuthorize("@ss.hasPermission('fms:config:digest:update')")
  56 + public CommonResult<Boolean> updateDigest(@Valid @RequestBody FmsDigestSaveReqVO updateReqVO) {
  57 + digestService.updateDigest(updateReqVO, getLoginUserId());
  58 + return success(true);
  59 + }
  60 +
  61 + @DeleteMapping("/delete")
  62 + @Operation(summary = "删除常用摘要")
  63 + @Parameter(name = "id", description = "常用摘要编号", required = true, example = "1024")
  64 + @PreAuthorize("@ss.hasPermission('fms:config:digest:delete')")
  65 + public CommonResult<Boolean> deleteDigest(@RequestParam("accountSetId") @NotNull Long accountSetId,
  66 + @RequestParam("id") @NotNull Long id) {
  67 + digestService.deleteDigest(accountSetId, id, getLoginUserId());
  68 + return success(true);
  69 + }
  70 +
  71 + @GetMapping("/list")
  72 + @Operation(summary = "获得常用摘要管理列表")
  73 + @Parameter(name = "accountSetId", description = "账套编号", required = true, example = "1024")
  74 + @PreAuthorize("@ss.hasPermission('fms:config:digest:query')")
  75 + public CommonResult<List<FmsDigestRespVO>> getDigestList(
  76 + @RequestParam("accountSetId") @NotNull Long accountSetId) {
  77 + List<FmsDigestDO> list = digestService.getDigestList(accountSetId, getLoginUserId());
  78 + return success(BeanUtils.toBean(list, FmsDigestRespVO.class));
  79 + }
  80 +
  81 + @GetMapping("/simple-list")
  82 + @Operation(summary = "获得常用摘要精简列表")
  83 + @Parameter(name = "accountSetId", description = "账套编号", required = true, example = "1024")
  84 + public CommonResult<List<FmsDigestRespVO>> getDigestSimpleList(
  85 + @RequestParam("accountSetId") @NotNull Long accountSetId) {
  86 + List<FmsDigestDO> list = digestService.getDigestList(accountSetId, getLoginUserId());
  87 + return success(convertList(list, digest -> new FmsDigestRespVO()
  88 + .setId(digest.getId()).setAccountSetId(digest.getAccountSetId()).setContent(digest.getContent())));
  89 + }
  90 +
  91 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/FmsFinanceIndicatorController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  5 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.financeindicator.FmsFinanceIndicatorRespVO;
  6 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.financeindicator.FmsFinanceIndicatorSaveReqVO;
  7 +import cn.iocoder.yudao.module.fms.dal.dataobject.config.FmsFinanceIndicatorDO;
  8 +import cn.iocoder.yudao.module.fms.service.config.FmsFinanceIndicatorService;
  9 +import io.swagger.v3.oas.annotations.Operation;
  10 +import io.swagger.v3.oas.annotations.Parameter;
  11 +import io.swagger.v3.oas.annotations.tags.Tag;
  12 +import jakarta.annotation.Resource;
  13 +import jakarta.validation.Valid;
  14 +import jakarta.validation.constraints.NotNull;
  15 +import org.springframework.security.access.prepost.PreAuthorize;
  16 +import org.springframework.validation.annotation.Validated;
  17 +import org.springframework.web.bind.annotation.DeleteMapping;
  18 +import org.springframework.web.bind.annotation.GetMapping;
  19 +import org.springframework.web.bind.annotation.PostMapping;
  20 +import org.springframework.web.bind.annotation.PutMapping;
  21 +import org.springframework.web.bind.annotation.RequestBody;
  22 +import org.springframework.web.bind.annotation.RequestMapping;
  23 +import org.springframework.web.bind.annotation.RequestParam;
  24 +import org.springframework.web.bind.annotation.RestController;
  25 +
  26 +import java.util.List;
  27 +
  28 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  29 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  30 +
  31 +@Tag(name = "管理后台 - FMS 财务指标")
  32 +@RestController
  33 +@RequestMapping("/fms/config/finance-indicator")
  34 +@Validated
  35 +public class FmsFinanceIndicatorController {
  36 +
  37 + @Resource
  38 + private FmsFinanceIndicatorService financeIndicatorService;
  39 +
  40 + @PostMapping("/create")
  41 + @Operation(summary = "创建首页财务指标")
  42 + @PreAuthorize("@ss.hasPermission('fms:config:finance-indicator:create')")
  43 + public CommonResult<Long> create(@Valid @RequestBody FmsFinanceIndicatorSaveReqVO reqVO) {
  44 + return success(financeIndicatorService.createFinanceIndicator(reqVO, getLoginUserId()));
  45 + }
  46 +
  47 + @PutMapping("/update")
  48 + @Operation(summary = "修改首页财务指标")
  49 + @PreAuthorize("@ss.hasPermission('fms:config:finance-indicator:update')")
  50 + public CommonResult<Boolean> update(@Valid @RequestBody FmsFinanceIndicatorSaveReqVO reqVO) {
  51 + financeIndicatorService.updateFinanceIndicator(reqVO, getLoginUserId());
  52 + return success(true);
  53 + }
  54 +
  55 + @DeleteMapping("/delete")
  56 + @Operation(summary = "删除首页财务指标")
  57 + @Parameter(name = "accountSetId", description = "账套编号", required = true, example = "1024")
  58 + @Parameter(name = "id", description = "指标编号", required = true, example = "1024")
  59 + @PreAuthorize("@ss.hasPermission('fms:config:finance-indicator:delete')")
  60 + public CommonResult<Boolean> delete(@RequestParam("accountSetId") @NotNull Long accountSetId,
  61 + @RequestParam("id") @NotNull Long id) {
  62 + financeIndicatorService.deleteFinanceIndicator(accountSetId, id, getLoginUserId());
  63 + return success(true);
  64 + }
  65 +
  66 + @GetMapping("/get")
  67 + @Operation(summary = "获得首页财务指标")
  68 + @Parameter(name = "accountSetId", description = "账套编号", required = true, example = "1024")
  69 + @Parameter(name = "id", description = "指标编号", required = true, example = "1024")
  70 + @PreAuthorize("@ss.hasPermission('fms:config:finance-indicator:query')")
  71 + public CommonResult<FmsFinanceIndicatorRespVO> get(@RequestParam("accountSetId") @NotNull Long accountSetId,
  72 + @RequestParam("id") @NotNull Long id) {
  73 + FmsFinanceIndicatorDO indicator = financeIndicatorService.getFinanceIndicator(accountSetId, id, getLoginUserId());
  74 + return success(BeanUtils.toBean(indicator, FmsFinanceIndicatorRespVO.class));
  75 + }
  76 +
  77 + @GetMapping("/list")
  78 + @Operation(summary = "获得首页财务指标列表")
  79 + @PreAuthorize("@ss.hasPermission('fms:config:finance-indicator:query')")
  80 + public CommonResult<List<FmsFinanceIndicatorRespVO>> getList(@RequestParam("accountSetId") @NotNull Long accountSetId) {
  81 + List<FmsFinanceIndicatorDO> list = financeIndicatorService.getFinanceIndicatorList(accountSetId,
  82 + getLoginUserId());
  83 + return success(BeanUtils.toBean(list, FmsFinanceIndicatorRespVO.class));
  84 + }
  85 +
  86 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/FmsFinanceParameterController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  5 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.financeparameter.FmsFinanceParameterRespVO;
  6 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.financeparameter.FmsFinanceParameterUpdateReqVO;
  7 +import cn.iocoder.yudao.module.fms.dal.dataobject.config.FmsFinanceParameterDO;
  8 +import cn.iocoder.yudao.module.fms.service.config.FmsFinanceParameterService;
  9 +import io.swagger.v3.oas.annotations.Operation;
  10 +import io.swagger.v3.oas.annotations.Parameter;
  11 +import io.swagger.v3.oas.annotations.tags.Tag;
  12 +import jakarta.annotation.Resource;
  13 +import jakarta.validation.Valid;
  14 +import org.springframework.security.access.prepost.PreAuthorize;
  15 +import org.springframework.validation.annotation.Validated;
  16 +import org.springframework.web.bind.annotation.GetMapping;
  17 +import org.springframework.web.bind.annotation.PutMapping;
  18 +import org.springframework.web.bind.annotation.RequestBody;
  19 +import org.springframework.web.bind.annotation.RequestMapping;
  20 +import org.springframework.web.bind.annotation.RequestParam;
  21 +import org.springframework.web.bind.annotation.RestController;
  22 +
  23 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  24 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  25 +
  26 +@Tag(name = "管理后台 - FMS 财务参数")
  27 +@RestController
  28 +@RequestMapping("/fms/config/finance-parameter")
  29 +@Validated
  30 +public class FmsFinanceParameterController {
  31 +
  32 + @Resource
  33 + private FmsFinanceParameterService financeParameterService;
  34 +
  35 + @GetMapping("/get")
  36 + @Operation(summary = "获得财务参数")
  37 + @Parameter(name = "accountSetId", description = "账套编号", required = true, example = "1024")
  38 + @PreAuthorize("@ss.hasPermission('fms:config:finance-parameter:query')")
  39 + public CommonResult<FmsFinanceParameterRespVO> getFinanceParameter(
  40 + @RequestParam("accountSetId") Long accountSetId) {
  41 + FmsFinanceParameterDO financeParameter = financeParameterService.getFinanceParameter(
  42 + accountSetId, getLoginUserId());
  43 + return success(BeanUtils.toBean(financeParameter, FmsFinanceParameterRespVO.class));
  44 + }
  45 +
  46 + @PutMapping("/update")
  47 + @Operation(summary = "更新财务参数")
  48 + @PreAuthorize("@ss.hasPermission('fms:config:finance-parameter:update')")
  49 + public CommonResult<Boolean> updateFinanceParameter(
  50 + @Valid @RequestBody FmsFinanceParameterUpdateReqVO updateReqVO) {
  51 + financeParameterService.updateFinanceParameter(updateReqVO, getLoginUserId());
  52 + return success(true);
  53 + }
  54 +
  55 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/FmsInitialBalanceController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
  5 +import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
  6 +import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
  7 +import cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum;
  8 +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  9 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.initialbalance.FmsInitialBalanceRespVO;
  10 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.initialbalance.FmsInitialBalanceSaveReqVO;
  11 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.initialbalance.FmsTrialBalanceRespVO;
  12 +import cn.iocoder.yudao.module.fms.dal.dataobject.config.FmsAccountSetDO;
  13 +import cn.iocoder.yudao.module.fms.service.config.FmsAccountSetService;
  14 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.initialbalance.FmsInitialBalanceExcelVO;
  15 +import cn.iocoder.yudao.module.fms.service.config.FmsInitialBalanceService;
  16 +import io.swagger.v3.oas.annotations.Operation;
  17 +import io.swagger.v3.oas.annotations.Parameter;
  18 +import io.swagger.v3.oas.annotations.tags.Tag;
  19 +import jakarta.annotation.Resource;
  20 +import jakarta.validation.Valid;
  21 +import jakarta.validation.constraints.NotNull;
  22 +import jakarta.servlet.http.HttpServletResponse;
  23 +import org.springframework.security.access.prepost.PreAuthorize;
  24 +import org.springframework.validation.annotation.Validated;
  25 +import org.springframework.web.bind.annotation.GetMapping;
  26 +import org.springframework.web.bind.annotation.PostMapping;
  27 +import org.springframework.web.bind.annotation.PutMapping;
  28 +import org.springframework.web.bind.annotation.RequestBody;
  29 +import org.springframework.web.bind.annotation.RequestMapping;
  30 +import org.springframework.web.bind.annotation.RequestParam;
  31 +import org.springframework.web.bind.annotation.RestController;
  32 +import org.springframework.web.multipart.MultipartFile;
  33 +
  34 +import java.io.IOException;
  35 +import java.util.List;
  36 +
  37 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  38 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  39 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  40 +import static cn.iocoder.yudao.module.fms.enums.ErrorCodeConstants.INITIAL_BALANCE_IMPORT_TEMPLATE_INVALID;
  41 +
  42 +@Tag(name = "管理后台 - FMS 初始余额")
  43 +@RestController
  44 +@RequestMapping("/fms/config/initial-balance")
  45 +@Validated
  46 +public class FmsInitialBalanceController {
  47 +
  48 + @Resource
  49 + private FmsInitialBalanceService initialBalanceService;
  50 + @Resource
  51 + private FmsAccountSetService accountSetService;
  52 +
  53 + @GetMapping("/list")
  54 + @Operation(summary = "获得初始余额列表")
  55 + @Parameter(name = "accountSetId", description = "账套编号", required = true, example = "1024")
  56 + @Parameter(name = "subjectType", description = "科目类型", required = true, example = "1")
  57 + @PreAuthorize("@ss.hasPermission('fms:config:initial-balance:query')")
  58 + public CommonResult<List<FmsInitialBalanceRespVO>> getInitialBalanceList(
  59 + @RequestParam("accountSetId") @NotNull Long accountSetId,
  60 + @RequestParam("subjectType") @NotNull Integer subjectType) {
  61 + return success(initialBalanceService.getInitialBalanceList(accountSetId, subjectType, getLoginUserId()));
  62 + }
  63 +
  64 + @PutMapping("/save")
  65 + @Operation(summary = "保存初始余额")
  66 + @PreAuthorize("@ss.hasPermission('fms:config:initial-balance:update')")
  67 + public CommonResult<Boolean> saveInitialBalance(@Valid @RequestBody FmsInitialBalanceSaveReqVO saveReqVO) {
  68 + initialBalanceService.saveInitialBalance(saveReqVO, getLoginUserId());
  69 + return success(true);
  70 + }
  71 +
  72 + @GetMapping("/trial-balance")
  73 + @Operation(summary = "获得试算平衡结果")
  74 + @Parameter(name = "accountSetId", description = "账套编号", required = true, example = "1024")
  75 + @PreAuthorize("@ss.hasPermission('fms:config:initial-balance:query')")
  76 + public CommonResult<FmsTrialBalanceRespVO> getTrialBalance(
  77 + @RequestParam("accountSetId") @NotNull Long accountSetId) {
  78 + return success(initialBalanceService.getTrialBalance(accountSetId, getLoginUserId()));
  79 + }
  80 +
  81 + @GetMapping("/export-excel")
  82 + @Operation(summary = "导出初始余额")
  83 + @Parameter(name = "accountSetId", description = "账套编号", required = true, example = "1024")
  84 + @PreAuthorize("@ss.hasPermission('fms:config:initial-balance:export')")
  85 + @ApiAccessLog(operateType = OperateTypeEnum.EXPORT)
  86 + public void exportInitialBalance(
  87 + @RequestParam("accountSetId") @NotNull Long accountSetId,
  88 + HttpServletResponse response) throws IOException {
  89 + // 1. 读取初始余额列表,并展开为 Excel 行
  90 + List<FmsInitialBalanceExcelVO> rows = FmsInitialBalanceExcelHelper.toRows(
  91 + initialBalanceService.getInitialBalanceList(accountSetId, null, getLoginUserId()), true);
  92 + // 2. 输出 Excel
  93 + ExcelUtils.write(response, "财务初始余额.xlsx", "财务初始余额",
  94 + FmsInitialBalanceExcelVO.class, rows);
  95 + }
  96 +
  97 + @GetMapping("/get-import-template")
  98 + @Operation(summary = "获得初始余额导入模板")
  99 + @Parameter(name = "accountSetId", description = "账套编号", required = true, example = "1024")
  100 + @PreAuthorize("@ss.hasPermission('fms:config:initial-balance:import')")
  101 + @ApiAccessLog(operateType = OperateTypeEnum.EXPORT)
  102 + public void getInitialBalanceImportTemplate(@RequestParam("accountSetId") @NotNull Long accountSetId,
  103 + HttpServletResponse response)
  104 + throws IOException {
  105 + // 1. 读取初始余额列表,并展开为 Excel 行
  106 + Long userId = getLoginUserId();
  107 + List<FmsInitialBalanceRespVO> initialBalances = initialBalanceService.getInitialBalanceList(accountSetId, null, userId);
  108 + List<FmsInitialBalanceExcelVO> rows = FmsInitialBalanceExcelHelper.toRows(initialBalances, false);
  109 + // 2. 生成导入模板,一月启用时只需要录入期初余额
  110 + FmsAccountSetDO accountSet = accountSetService.validateAccountSetReadPermission(accountSetId, userId);
  111 + byte[] content = FmsInitialBalanceExcelHelper.writeTemplate(
  112 + rows, LocalDateTimeUtils.isJanuary(accountSet.getStartTime()));
  113 + // 3. 写入响应
  114 + ServletUtils.writeAttachment(response, "财务初始余额导入模板.xlsx", content);
  115 + }
  116 +
  117 + @PostMapping("/import")
  118 + @Operation(summary = "导入初始余额")
  119 + @Parameter(name = "accountSetId", description = "账套编号", required = true, example = "1024")
  120 + @PreAuthorize("@ss.hasPermission('fms:config:initial-balance:import')")
  121 + @ApiAccessLog(operateType = OperateTypeEnum.IMPORT)
  122 + public CommonResult<Integer> importInitialBalance(
  123 + @RequestParam("accountSetId") @NotNull Long accountSetId,
  124 + @RequestParam("file") MultipartFile file) throws IOException {
  125 + // 1. 读取 Excel
  126 + List<FmsInitialBalanceExcelVO> rows;
  127 + try {
  128 + rows = FmsInitialBalanceExcelHelper.read(file);
  129 + } catch (IllegalArgumentException | IOException ex) {
  130 + throw exception(INITIAL_BALANCE_IMPORT_TEMPLATE_INVALID);
  131 + }
  132 + // 2. 导入数据
  133 + return success(initialBalanceService.importInitialBalance(accountSetId, rows, getLoginUserId()));
  134 + }
  135 +
  136 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/FmsInitialBalanceExcelHelper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.initialbalance.FmsInitialBalanceRespVO;
  5 +import cn.iocoder.yudao.module.fms.enums.common.FmsDebitCreditDirectionEnum;
  6 +import cn.iocoder.yudao.module.fms.enums.config.FmsSubjectTypeEnum;
  7 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.initialbalance.FmsInitialBalanceExcelVO;
  8 +import lombok.experimental.UtilityClass;
  9 +import org.apache.poi.ss.usermodel.Cell;
  10 +import org.apache.poi.ss.usermodel.CellStyle;
  11 +import org.apache.poi.ss.usermodel.FormulaEvaluator;
  12 +import org.apache.poi.ss.usermodel.IndexedColors;
  13 +import org.apache.poi.ss.usermodel.Row;
  14 +import org.apache.poi.ss.usermodel.Sheet;
  15 +import org.apache.poi.ss.usermodel.Workbook;
  16 +import org.apache.poi.ss.usermodel.WorkbookFactory;
  17 +import org.apache.poi.ss.util.CellRangeAddress;
  18 +import org.apache.poi.xssf.usermodel.XSSFWorkbook;
  19 +import org.springframework.web.multipart.MultipartFile;
  20 +
  21 +import java.io.ByteArrayOutputStream;
  22 +import java.io.IOException;
  23 +import java.math.BigDecimal;
  24 +import java.util.ArrayList;
  25 +import java.util.Arrays;
  26 +import java.util.List;
  27 +import java.util.Map;
  28 +import java.util.Set;
  29 +
  30 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  31 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  32 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
  33 +import static cn.iocoder.yudao.framework.common.util.number.NumberUtils.zeroIfNull;
  34 +import static cn.iocoder.yudao.framework.excel.core.util.PoiExcelUtils.createDataStyle;
  35 +import static cn.iocoder.yudao.framework.excel.core.util.PoiExcelUtils.createHeaderStyle;
  36 +import static cn.iocoder.yudao.framework.excel.core.util.PoiExcelUtils.createNumberStyle;
  37 +import static cn.iocoder.yudao.framework.excel.core.util.PoiExcelUtils.getCellText;
  38 +import static cn.iocoder.yudao.framework.excel.core.util.PoiExcelUtils.getDecimal;
  39 +import static cn.iocoder.yudao.framework.excel.core.util.PoiExcelUtils.isEmptyRow;
  40 +import static cn.iocoder.yudao.framework.excel.core.util.PoiExcelUtils.mergeHeader;
  41 +import static cn.iocoder.yudao.framework.excel.core.util.PoiExcelUtils.writeFormula;
  42 +import static cn.iocoder.yudao.framework.excel.core.util.PoiExcelUtils.writeNumber;
  43 +import static cn.iocoder.yudao.framework.excel.core.util.PoiExcelUtils.writeText;
  44 +
  45 +/**
  46 + * FMS 初始余额 Excel 工具
  47 + *
  48 + * @author 芋道源码
  49 + */
  50 +@UtilityClass
  51 +public final class FmsInitialBalanceExcelHelper {
  52 +
  53 + private static final String TEMPLATE_SHEET_NAME = "初始余额模板";
  54 +
  55 + /**
  56 + * 展开初始余额平铺列表为 Excel 行
  57 + *
  58 + * 父级科目仅在 includeParent 时输出行;启用辅助核算且存在明细的科目按明细逐行输出
  59 + */
  60 + public static List<FmsInitialBalanceExcelVO> toRows(List<FmsInitialBalanceRespVO> results,
  61 + boolean includeParent) {
  62 + Set<Long> parentIds = convertSet(results, FmsInitialBalanceRespVO::getParentId);
  63 + List<FmsInitialBalanceExcelVO> rows = new ArrayList<>();
  64 + results.forEach(result -> {
  65 + if (parentIds.contains(result.getSubjectId())) {
  66 + if (includeParent) {
  67 + rows.add(buildRow(result, null));
  68 + }
  69 + return;
  70 + }
  71 + if (Boolean.FALSE.equals(result.getAuxiliaryAccounting())
  72 + || CollUtil.isEmpty(result.getAssistBalances())) {
  73 + rows.add(buildRow(result, null));
  74 + return;
  75 + }
  76 + result.getAssistBalances().forEach(assist -> rows.add(buildRow(result, assist)));
  77 + });
  78 + return rows;
  79 + }
  80 +
  81 + /**
  82 + * 构建单个科目或辅助核算明细对应的 Excel 行
  83 + */
  84 + private static FmsInitialBalanceExcelVO buildRow(FmsInitialBalanceRespVO result,
  85 + FmsInitialBalanceRespVO.AssistBalance assist) {
  86 + FmsInitialBalanceExcelVO row = new FmsInitialBalanceExcelVO()
  87 + .setSubjectCode(result.getSubjectCode()).setSubjectName(result.getSubjectName())
  88 + .setDirectionName(FmsDebitCreditDirectionEnum.valueOf(result.getBalanceDirection()).getName())
  89 + .setSubjectType(result.getType()).setQuantityAccounting(result.getQuantityAccounting())
  90 + .setAuxiliaryAccounting(result.getAuxiliaryAccounting());
  91 + if (assist == null) {
  92 + copyAmounts(result, row);
  93 + } else {
  94 + // 辅助核算项目拼接为“类别:名称/类别:名称”,与导入解析的格式对应
  95 + Map<Long, String> auxiliaryTypeNameMap = convertMap(result.getAuxiliaryConfigs(),
  96 + FmsInitialBalanceRespVO.AuxiliaryConfig::getAuxiliaryTypeId,
  97 + FmsInitialBalanceRespVO.AuxiliaryConfig::getName);
  98 + row.setAuxiliaryItems(String.join("/", convertList(assist.getAuxiliaries(),
  99 + item -> auxiliaryTypeNameMap.get(item.getTypeId()) + ":" + item.getName())));
  100 + copyAmounts(assist, row);
  101 + }
  102 + return row;
  103 + }
  104 +
  105 + private static void copyAmounts(FmsInitialBalanceRespVO source, FmsInitialBalanceExcelVO target) {
  106 + target.setOpeningAmount(zeroIfNull(source.getOpeningAmount()))
  107 + .setOpeningQuantity(zeroIfNull(source.getOpeningQuantity()))
  108 + .setYearDebitAmount(zeroIfNull(source.getYearDebitAmount()))
  109 + .setYearDebitQuantity(zeroIfNull(source.getYearDebitQuantity()))
  110 + .setYearCreditAmount(zeroIfNull(source.getYearCreditAmount()))
  111 + .setYearCreditQuantity(zeroIfNull(source.getYearCreditQuantity()))
  112 + .setYearOpeningAmount(zeroIfNull(source.getYearOpeningAmount()))
  113 + .setYearOpeningQuantity(zeroIfNull(source.getYearOpeningQuantity()))
  114 + .setProfitLossAmount(zeroIfNull(source.getProfitLossAmount()))
  115 + .setProfitLossQuantity(zeroIfNull(source.getProfitLossQuantity()));
  116 + }
  117 +
  118 + private static void copyAmounts(FmsInitialBalanceRespVO.AssistBalance source,
  119 + FmsInitialBalanceExcelVO target) {
  120 + target.setOpeningAmount(zeroIfNull(source.getOpeningAmount()))
  121 + .setOpeningQuantity(zeroIfNull(source.getOpeningQuantity()))
  122 + .setYearDebitAmount(zeroIfNull(source.getYearDebitAmount()))
  123 + .setYearDebitQuantity(zeroIfNull(source.getYearDebitQuantity()))
  124 + .setYearCreditAmount(zeroIfNull(source.getYearCreditAmount()))
  125 + .setYearCreditQuantity(zeroIfNull(source.getYearCreditQuantity()))
  126 + .setYearOpeningAmount(zeroIfNull(source.getYearOpeningAmount()))
  127 + .setYearOpeningQuantity(zeroIfNull(source.getYearOpeningQuantity()))
  128 + .setProfitLossAmount(zeroIfNull(source.getProfitLossAmount()))
  129 + .setProfitLossQuantity(zeroIfNull(source.getProfitLossQuantity()));
  130 + }
  131 +
  132 + /**
  133 + * 生成导入模板
  134 + *
  135 + * 模板锁定系统生成列,年初余额列写入公式,并通过 protectSheet 防止误改
  136 + */
  137 + public static byte[] writeTemplate(List<FmsInitialBalanceExcelVO> rows,
  138 + boolean january) throws IOException {
  139 + try (Workbook workbook = new XSSFWorkbook(); ByteArrayOutputStream output = new ByteArrayOutputStream()) {
  140 + // 1. 写入表头,一月启用时只保留期初余额
  141 + Sheet sheet = workbook.createSheet(TEMPLATE_SHEET_NAME);
  142 + writeHeaders(workbook, sheet, 0, january);
  143 + // 2. 写入科目数据,系统生成列锁定,可填写列解锁
  144 + CellStyle lockedStyle = createDataStyle(workbook, true, IndexedColors.GREY_25_PERCENT);
  145 + CellStyle editableStyle = createDataStyle(workbook, false, IndexedColors.WHITE);
  146 + CellStyle numberLockedStyle = createNumberStyle(workbook, lockedStyle, "#,##0.0000");
  147 + CellStyle amountLockedStyle = createNumberStyle(workbook, lockedStyle, "#,##0.00");
  148 + CellStyle numberEditableStyle = createNumberStyle(workbook, editableStyle, "#,##0.0000");
  149 + CellStyle amountEditableStyle = createNumberStyle(workbook, editableStyle, "#,##0.00");
  150 + for (int index = 0; index < rows.size(); index++) {
  151 + writeDataRow(sheet.createRow(index + 2), rows.get(index), january, true,
  152 + lockedStyle, editableStyle, numberLockedStyle, amountLockedStyle,
  153 + numberEditableStyle, amountEditableStyle);
  154 + }
  155 + // 3. 保护工作表并补充填写说明
  156 + sheet.protectSheet("yudao-fms");
  157 + sheet.createFreezePane(4, 2);
  158 + writeInstructions(workbook);
  159 + workbook.write(output);
  160 + return output.toByteArray();
  161 + }
  162 + }
  163 +
  164 + /**
  165 + * 读取导入文件
  166 + *
  167 + * 按模板表头校验文件合法性,年初余额等公式单元格取公式计算值;不限制导入行数
  168 + */
  169 + public static List<FmsInitialBalanceExcelVO> read(MultipartFile file) throws IOException {
  170 + try (Workbook workbook = WorkbookFactory.create(file.getInputStream())) {
  171 + // 1. 校验模板 sheet 和表头
  172 + Sheet sheet = workbook.getSheet(TEMPLATE_SHEET_NAME);
  173 + if (sheet == null || !hasValidHeaders(sheet)) {
  174 + throw new IllegalArgumentException("初始余额模板表头不正确");
  175 + }
  176 + // 2. 逐行解析,跳过空行
  177 + FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
  178 + boolean january = sheet.getRow(1).getLastCellNum() <= 6;
  179 + List<FmsInitialBalanceExcelVO> rows = new ArrayList<>();
  180 + for (int rowIndex = 2; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
  181 + Row row = sheet.getRow(rowIndex);
  182 + if (isEmptyRow(row, evaluator, Arrays.asList(0, 1, 3, 4, 5))) {
  183 + continue;
  184 + }
  185 + rows.add(parseRow(row, january, evaluator));
  186 + }
  187 + return rows;
  188 + }
  189 + }
  190 +
  191 + /**
  192 + * 写入双行表头,数量和金额成组;一月启用时只保留期初余额组
  193 + */
  194 + private static void writeHeaders(Workbook workbook, Sheet sheet, int rowIndex, boolean january) {
  195 + CellStyle style = createHeaderStyle(workbook, IndexedColors.GREY_25_PERCENT);
  196 + int lastColumn = january ? 5 : 13;
  197 + Row firstRow = sheet.createRow(rowIndex);
  198 + Row secondRow = sheet.createRow(rowIndex + 1);
  199 + mergeHeader(sheet, firstRow, secondRow, 0, 0, "科目编码", style);
  200 + mergeHeader(sheet, firstRow, secondRow, 1, 1, "科目名称", style);
  201 + mergeHeader(sheet, firstRow, secondRow, 2, 2, "方向", style);
  202 + mergeHeader(sheet, firstRow, secondRow, 3, 3, "辅助核算项目", style);
  203 + writeGroupHeader(sheet, firstRow, secondRow, 4, "期初余额", style);
  204 + if (!january) {
  205 + writeGroupHeader(sheet, firstRow, secondRow, 6, "本年累计借方", style);
  206 + writeGroupHeader(sheet, firstRow, secondRow, 8, "本年累计贷方", style);
  207 + writeGroupHeader(sheet, firstRow, secondRow, 10, "年初余额", style);
  208 + writeGroupHeader(sheet, firstRow, secondRow, 12, "实际损益发生额", style);
  209 + }
  210 + for (int column = 0; column <= lastColumn; column++) {
  211 + sheet.setColumnWidth(column, column == 1 || column == 3 ? 7_000 : 4_000);
  212 + }
  213 + firstRow.setHeightInPoints(28);
  214 + secondRow.setHeightInPoints(24);
  215 + }
  216 +
  217 + /**
  218 + * 写入“数量/金额”成组表头,第一行合并组名,第二行拆出数量和金额
  219 + */
  220 + private static void writeGroupHeader(Sheet sheet, Row firstRow, Row secondRow,
  221 + int beginColumn, String title, CellStyle style) {
  222 + sheet.addMergedRegion(new CellRangeAddress(firstRow.getRowNum(), firstRow.getRowNum(), beginColumn, beginColumn + 1));
  223 + Cell groupCell = firstRow.createCell(beginColumn);
  224 + groupCell.setCellValue(title);
  225 + groupCell.setCellStyle(style);
  226 + firstRow.createCell(beginColumn + 1).setCellStyle(style);
  227 + Cell quantityCell = secondRow.createCell(beginColumn);
  228 + quantityCell.setCellValue("数量");
  229 + quantityCell.setCellStyle(style);
  230 + Cell amountCell = secondRow.createCell(beginColumn + 1);
  231 + amountCell.setCellValue("金额");
  232 + amountCell.setCellStyle(style);
  233 + }
  234 +
  235 + /**
  236 + * 写入一行数据
  237 + *
  238 + * 模板模式下按科目配置解锁可填写单元格(数量列仅数量核算科目可填,损益列仅损益类科目可填),
  239 + * 年初余额列写入“期初 ± 累计借贷”公式
  240 + */
  241 + private static void writeDataRow(Row excelRow, FmsInitialBalanceExcelVO data,
  242 + boolean january, boolean template, CellStyle lockedStyle, CellStyle editableStyle,
  243 + CellStyle numberLockedStyle, CellStyle amountLockedStyle,
  244 + CellStyle numberEditableStyle, CellStyle amountEditableStyle) {
  245 + writeText(excelRow, 0, data.getSubjectCode(), lockedStyle);
  246 + writeText(excelRow, 1, data.getSubjectName(), lockedStyle);
  247 + writeText(excelRow, 2, data.getDirectionName(), lockedStyle);
  248 + writeText(excelRow, 3, data.getAuxiliaryItems(),
  249 + template && Boolean.TRUE.equals(data.getAuxiliaryAccounting()) ? editableStyle : lockedStyle);
  250 + writeNumber(excelRow, 4, data.getOpeningQuantity(),
  251 + template && Boolean.TRUE.equals(data.getQuantityAccounting())
  252 + ? numberEditableStyle : numberLockedStyle);
  253 + writeNumber(excelRow, 5, data.getOpeningAmount(), template ? amountEditableStyle : amountLockedStyle);
  254 + if (january) {
  255 + return;
  256 + }
  257 + writeNumber(excelRow, 6, data.getYearDebitQuantity(),
  258 + template && Boolean.TRUE.equals(data.getQuantityAccounting())
  259 + ? numberEditableStyle : numberLockedStyle);
  260 + writeNumber(excelRow, 7, data.getYearDebitAmount(), template ? amountEditableStyle : amountLockedStyle);
  261 + writeNumber(excelRow, 8, data.getYearCreditQuantity(),
  262 + template && Boolean.TRUE.equals(data.getQuantityAccounting())
  263 + ? numberEditableStyle : numberLockedStyle);
  264 + writeNumber(excelRow, 9, data.getYearCreditAmount(), template ? amountEditableStyle : amountLockedStyle);
  265 + if (template) {
  266 + String quantityFormula = "借".equals(data.getDirectionName())
  267 + ? "E" + (excelRow.getRowNum() + 1) + "-G" + (excelRow.getRowNum() + 1)
  268 + + "+I" + (excelRow.getRowNum() + 1)
  269 + : "E" + (excelRow.getRowNum() + 1) + "+G" + (excelRow.getRowNum() + 1)
  270 + + "-I" + (excelRow.getRowNum() + 1);
  271 + String amountFormula = "借".equals(data.getDirectionName())
  272 + ? "F" + (excelRow.getRowNum() + 1) + "-H" + (excelRow.getRowNum() + 1)
  273 + + "+J" + (excelRow.getRowNum() + 1)
  274 + : "F" + (excelRow.getRowNum() + 1) + "+H" + (excelRow.getRowNum() + 1)
  275 + + "-J" + (excelRow.getRowNum() + 1);
  276 + writeFormula(excelRow, 10, quantityFormula, numberLockedStyle);
  277 + writeFormula(excelRow, 11, amountFormula, amountLockedStyle);
  278 + } else {
  279 + writeNumber(excelRow, 10, data.getYearOpeningQuantity(), numberLockedStyle);
  280 + writeNumber(excelRow, 11, data.getYearOpeningAmount(), amountLockedStyle);
  281 + }
  282 + boolean profitLoss = FmsSubjectTypeEnum.PROFIT_LOSS.getType().equals(data.getSubjectType());
  283 + writeNumber(excelRow, 12, profitLoss ? data.getProfitLossQuantity() : null,
  284 + template && profitLoss && Boolean.TRUE.equals(data.getQuantityAccounting())
  285 + ? numberEditableStyle : numberLockedStyle);
  286 + writeNumber(excelRow, 13, profitLoss ? data.getProfitLossAmount() : null,
  287 + template && profitLoss ? amountEditableStyle : amountLockedStyle);
  288 + }
  289 +
  290 + /**
  291 + * 解析一行数据,公式单元格通过 evaluator 取计算值
  292 + */
  293 + private static FmsInitialBalanceExcelVO parseRow(Row row, boolean january, FormulaEvaluator evaluator) {
  294 + FmsInitialBalanceExcelVO result = new FmsInitialBalanceExcelVO()
  295 + .setRowNumber(row.getRowNum() + 1)
  296 + .setSubjectCode(getCellText(row, 0, evaluator))
  297 + .setSubjectName(getCellText(row, 1, evaluator))
  298 + .setDirectionName(getCellText(row, 2, evaluator))
  299 + .setAuxiliaryItems(getCellText(row, 3, evaluator))
  300 + .setOpeningQuantity(getDecimal(row, 4, evaluator))
  301 + .setOpeningAmount(getDecimal(row, 5, evaluator));
  302 + if (!january) {
  303 + result.setYearDebitQuantity(getDecimal(row, 6, evaluator))
  304 + .setYearDebitAmount(getDecimal(row, 7, evaluator))
  305 + .setYearCreditQuantity(getDecimal(row, 8, evaluator))
  306 + .setYearCreditAmount(getDecimal(row, 9, evaluator))
  307 + .setYearOpeningQuantity(getDecimal(row, 10, evaluator))
  308 + .setYearOpeningAmount(getDecimal(row, 11, evaluator))
  309 + .setProfitLossQuantity(getDecimal(row, 12, evaluator))
  310 + .setProfitLossAmount(getDecimal(row, 13, evaluator));
  311 + }
  312 + return result;
  313 + }
  314 +
  315 + private static boolean hasValidHeaders(Sheet sheet) {
  316 + Row firstRow = sheet.getRow(0);
  317 + Row secondRow = sheet.getRow(1);
  318 + return firstRow != null && secondRow != null
  319 + && "科目编码".equals(getCellText(firstRow, 0, null))
  320 + && "科目名称".equals(getCellText(firstRow, 1, null))
  321 + && "方向".equals(getCellText(firstRow, 2, null))
  322 + && "辅助核算项目".equals(getCellText(firstRow, 3, null))
  323 + && "期初余额".equals(getCellText(firstRow, 4, null))
  324 + && "数量".equals(getCellText(secondRow, 4, null))
  325 + && "金额".equals(getCellText(secondRow, 5, null));
  326 + }
  327 +
  328 + private static void writeInstructions(Workbook workbook) {
  329 + Sheet sheet = workbook.createSheet("填写说明");
  330 + String[] instructions = {
  331 + "1. 灰色单元格由系统生成,请勿修改",
  332 + "2. 仅末级科目可以导入初始余额",
  333 + "3. 辅助核算项目使用“类别:名称/类别:名称”格式,例如“客户:北京客户/部门:销售部”",
  334 + "4. 数量核算科目可填写数量,金额和数量不能小于 0",
  335 + "5. 年初余额由期初余额和本年累计发生额自动计算"
  336 + };
  337 + for (int index = 0; index < instructions.length; index++) {
  338 + sheet.createRow(index).createCell(0).setCellValue(instructions[index]);
  339 + }
  340 + sheet.setColumnWidth(0, 20_000);
  341 + }
  342 +
  343 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/FmsSubjectController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
  5 +import cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum;
  6 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  7 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  8 +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  9 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.subject.FmsSubjectDeleteReqVO;
  10 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.subject.FmsSubjectImportExcelVO;
  11 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.subject.FmsSubjectImportRespVO;
  12 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.subject.FmsSubjectListReqVO;
  13 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.subject.FmsSubjectRespVO;
  14 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.subject.FmsSubjectSaveReqVO;
  15 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.subject.FmsSubjectStatusReqVO;
  16 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.subject.FmsSubjectUsageRespVO;
  17 +import cn.iocoder.yudao.module.fms.dal.dataobject.config.FmsAuxiliaryTypeDO;
  18 +import cn.iocoder.yudao.module.fms.dal.dataobject.config.FmsSubjectDO;
  19 +import cn.iocoder.yudao.module.fms.service.config.FmsAuxiliaryTypeService;
  20 +import cn.iocoder.yudao.module.fms.service.config.FmsSubjectService;
  21 +import io.swagger.v3.oas.annotations.Operation;
  22 +import io.swagger.v3.oas.annotations.Parameter;
  23 +import io.swagger.v3.oas.annotations.Parameters;
  24 +import io.swagger.v3.oas.annotations.tags.Tag;
  25 +import jakarta.annotation.Resource;
  26 +import jakarta.servlet.http.HttpServletResponse;
  27 +import jakarta.validation.Valid;
  28 +import jakarta.validation.constraints.NotNull;
  29 +import org.springframework.security.access.prepost.PreAuthorize;
  30 +import org.springframework.validation.annotation.Validated;
  31 +import org.springframework.web.bind.annotation.*;
  32 +import org.springframework.web.multipart.MultipartFile;
  33 +
  34 +import java.io.IOException;
  35 +import java.util.Arrays;
  36 +import java.util.Collections;
  37 +import java.util.List;
  38 +import java.util.Map;
  39 +
  40 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  41 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  42 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSetByFlatMap;
  43 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  44 +
  45 +@Tag(name = "管理后台 - FMS 会计科目")
  46 +@RestController
  47 +@RequestMapping("/fms/config/subject")
  48 +@Validated
  49 +public class FmsSubjectController {
  50 +
  51 + @Resource
  52 + private FmsSubjectService subjectService;
  53 + @Resource
  54 + private FmsAuxiliaryTypeService auxiliaryTypeService;
  55 +
  56 + @PostMapping("/create")
  57 + @Operation(summary = "创建科目")
  58 + @PreAuthorize("@ss.hasPermission('fms:config:subject:create')")
  59 + public CommonResult<Long> createSubject(@Valid @RequestBody FmsSubjectSaveReqVO createReqVO) {
  60 + return success(subjectService.createSubject(createReqVO, getLoginUserId()));
  61 + }
  62 +
  63 + @PutMapping("/update")
  64 + @Operation(summary = "更新科目")
  65 + @PreAuthorize("@ss.hasPermission('fms:config:subject:update')")
  66 + public CommonResult<Boolean> updateSubject(@Valid @RequestBody FmsSubjectSaveReqVO updateReqVO) {
  67 + subjectService.updateSubject(updateReqVO, getLoginUserId());
  68 + return success(true);
  69 + }
  70 +
  71 + @DeleteMapping("/delete-list")
  72 + @Operation(summary = "删除科目")
  73 + @PreAuthorize("@ss.hasPermission('fms:config:subject:delete')")
  74 + public CommonResult<Boolean> deleteSubjectList(@Valid @RequestBody FmsSubjectDeleteReqVO deleteReqVO) {
  75 + subjectService.deleteSubjectList(deleteReqVO, getLoginUserId());
  76 + return success(true);
  77 + }
  78 +
  79 + @PutMapping("/update-status")
  80 + @Operation(summary = "更新科目状态")
  81 + @PreAuthorize("@ss.hasPermission('fms:config:subject:update')")
  82 + public CommonResult<Boolean> updateSubjectStatus(@Valid @RequestBody FmsSubjectStatusReqVO statusReqVO) {
  83 + subjectService.updateSubjectStatus(statusReqVO, getLoginUserId());
  84 + return success(true);
  85 + }
  86 +
  87 + @GetMapping("/get")
  88 + @Operation(summary = "获得科目")
  89 + @Parameters({
  90 + @Parameter(name = "accountSetId", description = "账套编号", required = true, example = "1024"),
  91 + @Parameter(name = "id", description = "科目编号", required = true, example = "1024")
  92 + })
  93 + @PreAuthorize("@ss.hasPermission('fms:config:subject:query')")
  94 + public CommonResult<FmsSubjectRespVO> getSubject(@RequestParam("accountSetId") @NotNull Long accountSetId,
  95 + @RequestParam("id") @NotNull Long id) {
  96 + FmsSubjectDO subject = subjectService.getSubject(accountSetId, id, getLoginUserId());
  97 + return success(buildSubjectRespVO(subject));
  98 + }
  99 +
  100 + @GetMapping("/get-usage")
  101 + @Operation(summary = "获得科目使用情况")
  102 + @Parameters({
  103 + @Parameter(name = "accountSetId", description = "账套编号", required = true, example = "1024"),
  104 + @Parameter(name = "id", description = "科目编号", required = true, example = "1024")
  105 + })
  106 + @PreAuthorize("@ss.hasPermission('fms:config:subject:query')")
  107 + public CommonResult<FmsSubjectUsageRespVO> getSubjectUsage(
  108 + @RequestParam("accountSetId") @NotNull Long accountSetId,
  109 + @RequestParam("id") @NotNull Long id) {
  110 + return success(subjectService.getSubjectUsage(accountSetId, id, getLoginUserId()));
  111 + }
  112 +
  113 + @GetMapping("/list")
  114 + @Operation(summary = "获得科目列表")
  115 + @PreAuthorize("@ss.hasPermission('fms:config:subject:query')")
  116 + public CommonResult<List<FmsSubjectRespVO>> getSubjectList(@Valid FmsSubjectListReqVO listReqVO) {
  117 + List<FmsSubjectDO> subjects = subjectService.getSubjectList(listReqVO, getLoginUserId());
  118 + return success(buildSubjectRespVOList(subjects));
  119 + }
  120 +
  121 + @GetMapping("/simple-list")
  122 + @Operation(summary = "获得科目精简列表")
  123 + public CommonResult<List<FmsSubjectRespVO>> getSubjectSimpleList(@Valid FmsSubjectListReqVO listReqVO) {
  124 + List<FmsSubjectDO> subjects = subjectService.getSubjectList(listReqVO, getLoginUserId());
  125 + return success(convertList(subjects, subject -> new FmsSubjectRespVO()
  126 + .setId(subject.getId()).setParentId(subject.getParentId())
  127 + .setCode(subject.getCode()).setName(subject.getName()).setType(subject.getType())
  128 + .setBalanceDirection(subject.getBalanceDirection()).setStatus(subject.getStatus())
  129 + .setLevel(subject.getLevel()).setAuxiliaryTypeIds(subject.getAuxiliaryTypeIds())
  130 + .setQuantityAccounting(subject.getQuantityAccounting()).setQuantityUnit(subject.getQuantityUnit())));
  131 + }
  132 +
  133 + @GetMapping("/export-excel")
  134 + @Operation(summary = "导出科目")
  135 + @PreAuthorize("@ss.hasPermission('fms:config:subject:export')")
  136 + @ApiAccessLog(operateType = OperateTypeEnum.EXPORT)
  137 + public void exportSubject(@Valid FmsSubjectListReqVO listReqVO,
  138 + HttpServletResponse response) throws IOException {
  139 + List<FmsSubjectDO> subjects = subjectService.getSubjectList(listReqVO, getLoginUserId());
  140 + ExcelUtils.write(response, "科目设置.xlsx", "科目设置", FmsSubjectRespVO.class,
  141 + buildSubjectRespVOList(subjects));
  142 + }
  143 +
  144 + @GetMapping("/get-import-template")
  145 + @Operation(summary = "获得科目导入模板")
  146 + @PreAuthorize("@ss.hasPermission('fms:config:subject:import')")
  147 + @ApiAccessLog(operateType = OperateTypeEnum.EXPORT)
  148 + public void getSubjectImportTemplate(HttpServletResponse response) throws IOException {
  149 + List<FmsSubjectImportExcelVO> list = Arrays.asList(
  150 + FmsSubjectImportExcelVO.builder().code("1001").name("库存现金")
  151 + .parentSubjectCode("0").balanceDirection("借").categoryName("流动资产").build(),
  152 + FmsSubjectImportExcelVO.builder().code("100101").name("人民币现金")
  153 + .parentSubjectCode("1001").balanceDirection("借").categoryName("流动资产")
  154 + .auxiliaryNames("部门/职员").build());
  155 + ExcelUtils.write(response, "科目导入模板.xlsx", "科目列表", FmsSubjectImportExcelVO.class, list);
  156 + }
  157 +
  158 + @PostMapping("/import")
  159 + @Operation(summary = "导入科目")
  160 + @Parameters({
  161 + @Parameter(name = "accountSetId", description = "账套编号", required = true, example = "1024"),
  162 + @Parameter(name = "file", description = "Excel 文件", required = true)
  163 + })
  164 + @PreAuthorize("@ss.hasPermission('fms:config:subject:import')")
  165 + @ApiAccessLog(operateType = OperateTypeEnum.IMPORT)
  166 + public CommonResult<FmsSubjectImportRespVO> importSubject(
  167 + @RequestParam("accountSetId") @NotNull Long accountSetId,
  168 + @RequestParam("file") MultipartFile file) throws IOException {
  169 + List<FmsSubjectImportExcelVO> importSubjects = ExcelUtils.read(file, FmsSubjectImportExcelVO.class);
  170 + return success(subjectService.importSubjectList(accountSetId, importSubjects, getLoginUserId()));
  171 + }
  172 +
  173 + // ==================== 拼接 VO ====================
  174 +
  175 + private List<FmsSubjectRespVO> buildSubjectRespVOList(List<FmsSubjectDO> subjects) {
  176 + Map<Long, FmsAuxiliaryTypeDO> auxiliaryTypeMap = auxiliaryTypeService.getAuxiliaryTypeMap(
  177 + convertSetByFlatMap(subjects, FmsSubjectDO::getAuxiliaryTypeIds, List::stream));
  178 + return convertList(subjects, subject -> {
  179 + FmsSubjectRespVO subjectVO = BeanUtils.toBean(subject, FmsSubjectRespVO.class)
  180 + .setCategoryDictValue(subject.getType() + "-" + subject.getCategory());
  181 + subjectVO.setAuxiliaryTypeNames(convertList(subject.getAuxiliaryTypeIds(),
  182 + auxiliaryTypeId -> auxiliaryTypeMap.get(auxiliaryTypeId).getName()));
  183 + if (Boolean.FALSE.equals(subject.getQuantityAccounting())) {
  184 + subjectVO.setQuantityUnit("");
  185 + }
  186 + return subjectVO;
  187 + });
  188 + }
  189 +
  190 + private FmsSubjectRespVO buildSubjectRespVO(FmsSubjectDO subject) {
  191 + return subject == null ? null
  192 + : CollUtil.getFirst(buildSubjectRespVOList(Collections.singletonList(subject)));
  193 + }
  194 +
  195 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/FmsVoucherTemplateCategoryController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  5 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.vouchertemplatecategory.FmsVoucherTemplateCategoryRespVO;
  6 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.vouchertemplatecategory.FmsVoucherTemplateCategorySaveReqVO;
  7 +import cn.iocoder.yudao.module.fms.dal.dataobject.config.FmsVoucherTemplateCategoryDO;
  8 +import cn.iocoder.yudao.module.fms.service.config.FmsAccountSetService;
  9 +import cn.iocoder.yudao.module.fms.service.config.FmsVoucherTemplateService;
  10 +import io.swagger.v3.oas.annotations.Operation;
  11 +import io.swagger.v3.oas.annotations.tags.Tag;
  12 +import jakarta.annotation.Resource;
  13 +import jakarta.validation.Valid;
  14 +import jakarta.validation.constraints.NotNull;
  15 +import org.springframework.security.access.prepost.PreAuthorize;
  16 +import org.springframework.validation.annotation.Validated;
  17 +import org.springframework.web.bind.annotation.DeleteMapping;
  18 +import org.springframework.web.bind.annotation.GetMapping;
  19 +import org.springframework.web.bind.annotation.PostMapping;
  20 +import org.springframework.web.bind.annotation.PutMapping;
  21 +import org.springframework.web.bind.annotation.RequestBody;
  22 +import org.springframework.web.bind.annotation.RequestMapping;
  23 +import org.springframework.web.bind.annotation.RequestParam;
  24 +import org.springframework.web.bind.annotation.RestController;
  25 +
  26 +import java.util.List;
  27 +
  28 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  29 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  30 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  31 +
  32 +@Tag(name = "管理后台 - FMS 凭证模板分类")
  33 +@RestController
  34 +@RequestMapping("/fms/config/voucher-template-category")
  35 +@Validated
  36 +public class FmsVoucherTemplateCategoryController {
  37 +
  38 + @Resource
  39 + private FmsVoucherTemplateService voucherTemplateService;
  40 + @Resource
  41 + private FmsAccountSetService accountSetService;
  42 +
  43 + @PostMapping("/create")
  44 + @Operation(summary = "创建凭证模板分类")
  45 + @PreAuthorize("@ss.hasPermission('fms:config:voucher-template-category:create')")
  46 + public CommonResult<Long> createTemplateCategory(
  47 + @Valid @RequestBody FmsVoucherTemplateCategorySaveReqVO createReqVO) {
  48 + return success(voucherTemplateService.createTemplateCategory(createReqVO, getLoginUserId()));
  49 + }
  50 +
  51 + @PutMapping("/update")
  52 + @Operation(summary = "修改凭证模板分类")
  53 + @PreAuthorize("@ss.hasPermission('fms:config:voucher-template-category:update')")
  54 + public CommonResult<Boolean> updateTemplateCategory(
  55 + @Valid @RequestBody FmsVoucherTemplateCategorySaveReqVO updateReqVO) {
  56 + voucherTemplateService.updateTemplateCategory(updateReqVO, getLoginUserId());
  57 + return success(true);
  58 + }
  59 +
  60 + @DeleteMapping("/delete")
  61 + @Operation(summary = "删除凭证模板分类")
  62 + @PreAuthorize("@ss.hasPermission('fms:config:voucher-template-category:delete')")
  63 + public CommonResult<Boolean> deleteTemplateCategory(@RequestParam("accountSetId") @NotNull Long accountSetId,
  64 + @RequestParam("id") @NotNull Long id) {
  65 + voucherTemplateService.deleteTemplateCategory(accountSetId, id, getLoginUserId());
  66 + return success(true);
  67 + }
  68 +
  69 + @GetMapping("/list")
  70 + @Operation(summary = "获得凭证模板分类列表")
  71 + @PreAuthorize("@ss.hasPermission('fms:config:voucher-template-category:query')")
  72 + public CommonResult<List<FmsVoucherTemplateCategoryRespVO>> getTemplateCategoryList(
  73 + @RequestParam("accountSetId") @NotNull Long accountSetId) {
  74 + accountSetService.validateAccountSetReadPermission(accountSetId, getLoginUserId());
  75 + List<FmsVoucherTemplateCategoryDO> categories = voucherTemplateService.getTemplateCategoryList(accountSetId);
  76 + return success(BeanUtils.toBean(categories, FmsVoucherTemplateCategoryRespVO.class));
  77 + }
  78 +
  79 + @GetMapping("/simple-list")
  80 + @Operation(summary = "获得凭证模板分类精简列表", description = "主要用于前端的下拉选项")
  81 + public CommonResult<List<FmsVoucherTemplateCategoryRespVO>> getTemplateCategorySimpleList(
  82 + @RequestParam("accountSetId") @NotNull Long accountSetId) {
  83 + accountSetService.validateAccountSetReadPermission(accountSetId, getLoginUserId());
  84 + List<FmsVoucherTemplateCategoryDO> categories = voucherTemplateService.getTemplateCategoryList(accountSetId);
  85 + return success(convertList(categories, category -> new FmsVoucherTemplateCategoryRespVO()
  86 + .setId(category.getId()).setName(category.getName())));
  87 + }
  88 +
  89 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/FmsVoucherTemplateController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  5 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.vouchertemplate.FmsVoucherTemplateRespVO;
  6 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.vouchertemplate.FmsVoucherTemplateSaveReqVO;
  7 +import cn.iocoder.yudao.module.fms.dal.dataobject.config.FmsVoucherTemplateCategoryDO;
  8 +import cn.iocoder.yudao.module.fms.dal.dataobject.config.FmsVoucherTemplateDO;
  9 +import cn.iocoder.yudao.module.fms.service.config.FmsAccountSetService;
  10 +import cn.iocoder.yudao.module.fms.service.config.FmsVoucherTemplateService;
  11 +import io.swagger.v3.oas.annotations.Operation;
  12 +import io.swagger.v3.oas.annotations.tags.Tag;
  13 +import jakarta.annotation.Resource;
  14 +import jakarta.validation.Valid;
  15 +import jakarta.validation.constraints.NotNull;
  16 +import org.springframework.security.access.prepost.PreAuthorize;
  17 +import org.springframework.validation.annotation.Validated;
  18 +import org.springframework.web.bind.annotation.DeleteMapping;
  19 +import org.springframework.web.bind.annotation.GetMapping;
  20 +import org.springframework.web.bind.annotation.PostMapping;
  21 +import org.springframework.web.bind.annotation.PutMapping;
  22 +import org.springframework.web.bind.annotation.RequestBody;
  23 +import org.springframework.web.bind.annotation.RequestMapping;
  24 +import org.springframework.web.bind.annotation.RequestParam;
  25 +import org.springframework.web.bind.annotation.RestController;
  26 +
  27 +import java.util.List;
  28 +import java.util.Map;
  29 +
  30 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  31 +import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
  32 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  33 +
  34 +@Tag(name = "管理后台 - FMS 凭证模板")
  35 +@RestController
  36 +@RequestMapping("/fms/config/voucher-template")
  37 +@Validated
  38 +public class FmsVoucherTemplateController {
  39 +
  40 + @Resource
  41 + private FmsVoucherTemplateService voucherTemplateService;
  42 + @Resource
  43 + private FmsAccountSetService accountSetService;
  44 +
  45 + @PostMapping("/create")
  46 + @Operation(summary = "创建凭证模板")
  47 + @PreAuthorize("@ss.hasPermission('fms:config:voucher-template:create')")
  48 + public CommonResult<Long> createVoucherTemplate(
  49 + @Valid @RequestBody FmsVoucherTemplateSaveReqVO createReqVO) {
  50 + return success(voucherTemplateService.createVoucherTemplate(createReqVO, getLoginUserId()));
  51 + }
  52 +
  53 + @PutMapping("/update")
  54 + @Operation(summary = "修改凭证模板")
  55 + @PreAuthorize("@ss.hasPermission('fms:config:voucher-template:update')")
  56 + public CommonResult<Boolean> updateVoucherTemplate(
  57 + @Valid @RequestBody FmsVoucherTemplateSaveReqVO updateReqVO) {
  58 + voucherTemplateService.updateVoucherTemplate(updateReqVO, getLoginUserId());
  59 + return success(true);
  60 + }
  61 +
  62 + @DeleteMapping("/delete")
  63 + @Operation(summary = "删除凭证模板")
  64 + @PreAuthorize("@ss.hasPermission('fms:config:voucher-template:delete')")
  65 + public CommonResult<Boolean> deleteVoucherTemplate(@RequestParam("accountSetId") @NotNull Long accountSetId,
  66 + @RequestParam("id") @NotNull Long id) {
  67 + voucherTemplateService.deleteVoucherTemplate(accountSetId, id, getLoginUserId());
  68 + return success(true);
  69 + }
  70 +
  71 + @GetMapping("/list")
  72 + @Operation(summary = "获得凭证模板列表")
  73 + @PreAuthorize("@ss.hasPermission('fms:config:voucher-template:query')")
  74 + public CommonResult<List<FmsVoucherTemplateRespVO>> getVoucherTemplateList(
  75 + @RequestParam("accountSetId") @NotNull Long accountSetId) {
  76 + accountSetService.validateAccountSetReadPermission(accountSetId, getLoginUserId());
  77 + return success(buildVoucherTemplateRespVOList(accountSetId));
  78 + }
  79 +
  80 + @GetMapping("/simple-list")
  81 + @Operation(summary = "获得凭证模板精简列表", description = "主要用于录凭证时套用凭证模板")
  82 + public CommonResult<List<FmsVoucherTemplateRespVO>> getVoucherTemplateSimpleList(
  83 + @RequestParam("accountSetId") @NotNull Long accountSetId) {
  84 + accountSetService.validateAccountSetReadPermission(accountSetId, getLoginUserId());
  85 + return success(buildVoucherTemplateRespVOList(accountSetId));
  86 + }
  87 +
  88 + // ==================== 拼接 VO ====================
  89 +
  90 + private List<FmsVoucherTemplateRespVO> buildVoucherTemplateRespVOList(Long accountSetId) {
  91 + Map<Long, FmsVoucherTemplateCategoryDO> categoryMap =
  92 + voucherTemplateService.getTemplateCategoryMap(accountSetId);
  93 + List<FmsVoucherTemplateDO> templates = voucherTemplateService.getVoucherTemplateList(accountSetId);
  94 + return BeanUtils.toBean(templates, FmsVoucherTemplateRespVO.class, template -> {
  95 + findAndThen(categoryMap, template.getCategoryId(),
  96 + category -> template.setCategoryName(category.getName()));
  97 + });
  98 + }
  99 +
  100 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/FmsVoucherWordController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  5 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.voucherword.FmsVoucherWordRespVO;
  6 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.voucherword.FmsVoucherWordSaveReqVO;
  7 +import cn.iocoder.yudao.module.fms.dal.dataobject.config.FmsVoucherWordDO;
  8 +import cn.iocoder.yudao.module.fms.service.config.FmsVoucherWordService;
  9 +import io.swagger.v3.oas.annotations.Operation;
  10 +import io.swagger.v3.oas.annotations.Parameter;
  11 +import io.swagger.v3.oas.annotations.tags.Tag;
  12 +import jakarta.annotation.Resource;
  13 +import jakarta.validation.Valid;
  14 +import jakarta.validation.constraints.NotNull;
  15 +import org.springframework.security.access.prepost.PreAuthorize;
  16 +import org.springframework.validation.annotation.Validated;
  17 +import org.springframework.web.bind.annotation.DeleteMapping;
  18 +import org.springframework.web.bind.annotation.GetMapping;
  19 +import org.springframework.web.bind.annotation.PostMapping;
  20 +import org.springframework.web.bind.annotation.PutMapping;
  21 +import org.springframework.web.bind.annotation.RequestBody;
  22 +import org.springframework.web.bind.annotation.RequestMapping;
  23 +import org.springframework.web.bind.annotation.RequestParam;
  24 +import org.springframework.web.bind.annotation.RestController;
  25 +
  26 +import java.util.List;
  27 +
  28 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  29 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  30 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  31 +
  32 +/**
  33 + * FMS 凭证字 Controller
  34 + *
  35 + * @author 芋道源码
  36 + */
  37 +@Tag(name = "管理后台 - FMS 凭证字")
  38 +@RestController
  39 +@RequestMapping("/fms/config/voucher-word")
  40 +@Validated
  41 +public class FmsVoucherWordController {
  42 +
  43 + @Resource
  44 + private FmsVoucherWordService voucherWordService;
  45 +
  46 + @PostMapping("/create")
  47 + @Operation(summary = "创建凭证字")
  48 + @PreAuthorize("@ss.hasPermission('fms:config:voucher-word:create')")
  49 + public CommonResult<Long> createVoucherWord(@Valid @RequestBody FmsVoucherWordSaveReqVO createReqVO) {
  50 + return success(voucherWordService.createVoucherWord(createReqVO, getLoginUserId()));
  51 + }
  52 +
  53 + @PutMapping("/update")
  54 + @Operation(summary = "修改凭证字")
  55 + @PreAuthorize("@ss.hasPermission('fms:config:voucher-word:update')")
  56 + public CommonResult<Boolean> updateVoucherWord(@Valid @RequestBody FmsVoucherWordSaveReqVO updateReqVO) {
  57 + voucherWordService.updateVoucherWord(updateReqVO, getLoginUserId());
  58 + return success(true);
  59 + }
  60 +
  61 + @DeleteMapping("/delete")
  62 + @Operation(summary = "删除凭证字")
  63 + @Parameter(name = "id", description = "凭证字编号", required = true, example = "1024")
  64 + @PreAuthorize("@ss.hasPermission('fms:config:voucher-word:delete')")
  65 + public CommonResult<Boolean> deleteVoucherWord(
  66 + @RequestParam("accountSetId") @NotNull Long accountSetId,
  67 + @RequestParam("id") @NotNull Long id) {
  68 + voucherWordService.deleteVoucherWord(accountSetId, id, getLoginUserId());
  69 + return success(true);
  70 + }
  71 +
  72 + @GetMapping("/list")
  73 + @Operation(summary = "获得凭证字管理列表")
  74 + @Parameter(name = "accountSetId", description = "账套编号", required = true, example = "1024")
  75 + @PreAuthorize("@ss.hasPermission('fms:config:voucher-word:query')")
  76 + public CommonResult<List<FmsVoucherWordRespVO>> getVoucherWordList(
  77 + @RequestParam("accountSetId") @NotNull Long accountSetId) {
  78 + List<FmsVoucherWordDO> list = voucherWordService.getVoucherWordList(accountSetId, getLoginUserId());
  79 + return success(BeanUtils.toBean(list, FmsVoucherWordRespVO.class));
  80 + }
  81 +
  82 + @GetMapping("/simple-list")
  83 + @Operation(summary = "获得凭证字精简列表")
  84 + @Parameter(name = "accountSetId", description = "账套编号", required = true, example = "1024")
  85 + public CommonResult<List<FmsVoucherWordRespVO>> getVoucherWordSimpleList(
  86 + @RequestParam("accountSetId") @NotNull Long accountSetId) {
  87 + return success(convertList(voucherWordService.getVoucherWordList(
  88 + accountSetId, getLoginUserId()), voucherWord -> new FmsVoucherWordRespVO()
  89 + .setId(voucherWord.getId()).setName(voucherWord.getName())
  90 + .setDefaultStatus(voucherWord.getDefaultStatus())));
  91 + }
  92 +
  93 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/accountset/FmsAccountSetInitializeReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.accountset;
  2 +
  3 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  4 +import cn.iocoder.yudao.module.fms.enums.config.FmsAccountingStandardEnum;
  5 +import cn.iocoder.yudao.module.fms.enums.config.FmsCurrencyPresetEnum;
  6 +import cn.iocoder.yudao.module.fms.enums.ledger.FmsLedgerBalanceModeEnum;
  7 +import io.swagger.v3.oas.annotations.media.Schema;
  8 +import jakarta.validation.constraints.NotBlank;
  9 +import jakarta.validation.constraints.NotNull;
  10 +import jakarta.validation.constraints.Max;
  11 +import jakarta.validation.constraints.Min;
  12 +import jakarta.validation.constraints.Size;
  13 +import lombok.Data;
  14 +
  15 +import java.time.LocalDateTime;
  16 +
  17 +@Schema(description = "管理后台 - FMS 账套初始化 Request VO")
  18 +@Data
  19 +public class FmsAccountSetInitializeReqVO {
  20 +
  21 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  22 + @NotNull(message = "账套编号不能为空")
  23 + private Long accountSetId;
  24 +
  25 + @Schema(description = "本位币编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "RMB")
  26 + @NotBlank(message = "本位币不能为空")
  27 + @InEnum(value = FmsCurrencyPresetEnum.class, message = "本位币必须是 {value}")
  28 + private String currencyCode;
  29 +
  30 + @Schema(description = "启用期间", requiredMode = Schema.RequiredMode.REQUIRED)
  31 + @NotNull(message = "启用期间不能为空")
  32 + private LocalDateTime startTime;
  33 +
  34 + @Schema(description = "会计制度", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  35 + @NotNull(message = "会计制度不能为空")
  36 + @InEnum(value = FmsAccountingStandardEnum.class, message = "会计制度必须是 {value}")
  37 + private Integer standard;
  38 +
  39 + @Schema(description = "科目层级", requiredMode = Schema.RequiredMode.REQUIRED, example = "4")
  40 + @NotNull(message = "科目层级不能为空")
  41 + @Min(value = 1, message = "科目层级不能小于 1")
  42 + @Max(value = 8, message = "科目层级不能大于 8")
  43 + private Integer level;
  44 +
  45 + @Schema(description = "科目编码规则", requiredMode = Schema.RequiredMode.REQUIRED, example = "4-2-2-2")
  46 + @NotBlank(message = "科目编码规则不能为空")
  47 + @Size(max = 64, message = "科目编码规则不能超过 64 个字符")
  48 + private String subjectCodeRule;
  49 +
  50 + @Schema(description = "账簿余额方向模式", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  51 + @NotNull(message = "账簿余额方向模式不能为空")
  52 + @InEnum(FmsLedgerBalanceModeEnum.class)
  53 + private Integer ledgerBalanceMode;
  54 +
  55 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/accountset/FmsAccountSetRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.accountset;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.time.LocalDateTime;
  7 +
  8 +@Schema(description = "管理后台 - FMS 账套 Response VO")
  9 +@Data
  10 +public class FmsAccountSetRespVO {
  11 +
  12 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  13 + private Long id;
  14 +
  15 + @Schema(description = "公司编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "WK001")
  16 + private String companyCode;
  17 +
  18 + @Schema(description = "公司名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "测试科技有限公司")
  19 + private String companyName;
  20 +
  21 + @Schema(description = "公司简介", example = "专注企业数字化服务")
  22 + private String companyProfile;
  23 +
  24 + @Schema(description = "所在行业", example = "软件和信息技术服务业")
  25 + private String industry;
  26 +
  27 + @Schema(description = "所在地", example = "上海市浦东新区")
  28 + private String location;
  29 +
  30 + @Schema(description = "法人代表", example = "张三")
  31 + private String legalRepresentative;
  32 +
  33 + @Schema(description = "法人身份证号", example = "310101199001011234")
  34 + private String legalRepresentativeIdNumber;
  35 +
  36 + @Schema(description = "营业执照号", example = "91310000MA1K123456")
  37 + private String businessLicenseNumber;
  38 +
  39 + @Schema(description = "组织机构代码", example = "MA1K12345")
  40 + private String organizationCode;
  41 +
  42 + @Schema(description = "备注", example = "一般纳税人")
  43 + private String remark;
  44 +
  45 + @Schema(description = "联系人", example = "李四")
  46 + private String contactName;
  47 +
  48 + @Schema(description = "办公电话", example = "021-12345678")
  49 + private String officeTelephone;
  50 +
  51 + @Schema(description = "手机号码", example = "15601691399")
  52 + private String mobile;
  53 +
  54 + @Schema(description = "传真号码", example = "021-87654321")
  55 + private String faxNumber;
  56 +
  57 + @Schema(description = "QQ 号码", example = "12345678")
  58 + private String qqNumber;
  59 +
  60 + @Schema(description = "邮箱", example = "finance@example.com")
  61 + private String email;
  62 +
  63 + @Schema(description = "其他联系方式", example = "企业微信:wk-finance")
  64 + private String otherContact;
  65 +
  66 + @Schema(description = "详细地址", example = "张江高科技园区 1 号楼")
  67 + private String address;
  68 +
  69 + @Schema(description = "币种编号", example = "1024")
  70 + private Long currencyId;
  71 +
  72 + @Schema(description = "启用期间")
  73 + private LocalDateTime startTime;
  74 +
  75 + @Schema(description = "会计制度", example = "1")
  76 + private Integer standard;
  77 +
  78 + @Schema(description = "是否已初始化", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
  79 + private Boolean initialized;
  80 +
  81 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  82 + private LocalDateTime createTime;
  83 +
  84 + // ==================== 来自 FmsAccountUserDO ====================
  85 +
  86 + @Schema(description = "是否默认账套", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
  87 + private Boolean defaultStatus;
  88 +
  89 + @Schema(description = "是否账套创建人", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
  90 + private Boolean founder;
  91 +
  92 + @Schema(description = "当前用户的成员权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "3")
  93 + private Integer level;
  94 +
  95 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/accountset/FmsAccountSetSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.accountset;
  2 +
  3 +import com.mzt.logapi.starter.annotation.DiffLogField;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import jakarta.validation.constraints.Email;
  6 +import jakarta.validation.constraints.NotBlank;
  7 +import jakarta.validation.constraints.Size;
  8 +import lombok.Data;
  9 +
  10 +@Schema(description = "管理后台 - FMS 账套新增/修改 Request VO")
  11 +@Data
  12 +public class FmsAccountSetSaveReqVO {
  13 +
  14 + @Schema(description = "账套编号", example = "1024")
  15 + private Long id;
  16 +
  17 + @Schema(description = "公司编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "WK001")
  18 + @NotBlank(message = "公司编码不能为空")
  19 + @Size(max = 64, message = "公司编码不能超过 64 个字符")
  20 + @DiffLogField(name = "公司编码")
  21 + private String companyCode;
  22 +
  23 + @Schema(description = "公司名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "测试科技有限公司")
  24 + @NotBlank(message = "公司名称不能为空")
  25 + @Size(max = 255, message = "公司名称不能超过 255 个字符")
  26 + @DiffLogField(name = "公司名称")
  27 + private String companyName;
  28 +
  29 + @Schema(description = "公司简介", example = "专注企业数字化服务")
  30 + @Size(max = 500, message = "公司简介不能超过 500 个字符")
  31 + @DiffLogField(name = "公司简介")
  32 + private String companyProfile;
  33 +
  34 + @Schema(description = "所在行业", example = "软件和信息技术服务业")
  35 + @Size(max = 255, message = "所在行业不能超过 255 个字符")
  36 + @DiffLogField(name = "所在行业")
  37 + private String industry;
  38 +
  39 + @Schema(description = "所在地", example = "上海市浦东新区")
  40 + @Size(max = 255, message = "所在地不能超过 255 个字符")
  41 + @DiffLogField(name = "所在地")
  42 + private String location;
  43 +
  44 + @Schema(description = "法人代表", example = "张三")
  45 + @Size(max = 255, message = "法人代表不能超过 255 个字符")
  46 + @DiffLogField(name = "法人代表")
  47 + private String legalRepresentative;
  48 +
  49 + @Schema(description = "法人身份证号", example = "310101199001011234")
  50 + @Size(max = 255, message = "法人身份证号不能超过 255 个字符")
  51 + @DiffLogField(name = "法人身份证号")
  52 + private String legalRepresentativeIdNumber;
  53 +
  54 + @Schema(description = "营业执照号", example = "91310000MA1K123456")
  55 + @Size(max = 255, message = "营业执照号不能超过 255 个字符")
  56 + @DiffLogField(name = "营业执照号")
  57 + private String businessLicenseNumber;
  58 +
  59 + @Schema(description = "组织机构代码", example = "MA1K12345")
  60 + @Size(max = 255, message = "组织机构代码不能超过 255 个字符")
  61 + @DiffLogField(name = "组织机构代码")
  62 + private String organizationCode;
  63 +
  64 + @Schema(description = "备注", example = "一般纳税人")
  65 + @Size(max = 500, message = "备注不能超过 500 个字符")
  66 + @DiffLogField(name = "备注")
  67 + private String remark;
  68 +
  69 + @Schema(description = "联系人", example = "李四")
  70 + @Size(max = 255, message = "联系人不能超过 255 个字符")
  71 + @DiffLogField(name = "联系人")
  72 + private String contactName;
  73 +
  74 + @Schema(description = "办公电话", example = "021-12345678")
  75 + @Size(max = 32, message = "办公电话不能超过 32 个字符")
  76 + @DiffLogField(name = "办公电话")
  77 + private String officeTelephone;
  78 +
  79 + @Schema(description = "手机号码", example = "15601691399")
  80 + @Size(max = 32, message = "手机号码不能超过 32 个字符")
  81 + @DiffLogField(name = "手机号码")
  82 + private String mobile;
  83 +
  84 + @Schema(description = "传真号码", example = "021-87654321")
  85 + @Size(max = 32, message = "传真号码不能超过 32 个字符")
  86 + @DiffLogField(name = "传真号码")
  87 + private String faxNumber;
  88 +
  89 + @Schema(description = "QQ 号码", example = "12345678")
  90 + @Size(max = 255, message = "QQ 号码不能超过 255 个字符")
  91 + @DiffLogField(name = "QQ 号码")
  92 + private String qqNumber;
  93 +
  94 + @Schema(description = "邮箱", example = "finance@example.com")
  95 + @Email(message = "邮箱格式不正确")
  96 + @Size(max = 255, message = "邮箱不能超过 255 个字符")
  97 + @DiffLogField(name = "邮箱")
  98 + private String email;
  99 +
  100 + @Schema(description = "其他联系方式", example = "企业微信:wk-finance")
  101 + @Size(max = 255, message = "其他联系方式不能超过 255 个字符")
  102 + @DiffLogField(name = "其他联系方式")
  103 + private String otherContact;
  104 +
  105 + @Schema(description = "详细地址", example = "张江高科技园区 1 号楼")
  106 + @Size(max = 255, message = "详细地址不能超过 255 个字符")
  107 + @DiffLogField(name = "详细地址")
  108 + private String address;
  109 +
  110 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/accountuser/FmsAccountUserRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.accountuser;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +@Schema(description = "管理后台 - FMS 账套用户 Response VO")
  7 +@Data
  8 +public class FmsAccountUserRespVO {
  9 +
  10 + @Schema(description = "后台用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  11 + private Long userId;
  12 +
  13 + @Schema(description = "用户昵称", example = "芋道")
  14 + private String nickname;
  15 +
  16 + @Schema(description = "部门名称", example = "财务部")
  17 + private String deptName;
  18 +
  19 + @Schema(description = "手机号码", example = "15601691399")
  20 + private String mobile;
  21 +
  22 + @Schema(description = "用户邮箱", example = "finance@example.com")
  23 + private String email;
  24 +
  25 + @Schema(description = "用户状态", example = "0")
  26 + private Integer status;
  27 +
  28 + @Schema(description = "是否默认账套", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
  29 + private Boolean defaultStatus;
  30 +
  31 + @Schema(description = "是否账套创建人", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
  32 + private Boolean founder;
  33 +
  34 + @Schema(description = "成员权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  35 + private Integer level;
  36 +
  37 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/accountuser/FmsAccountUserUpdateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.accountuser;
  2 +
  3 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  4 +import cn.iocoder.yudao.module.fms.enums.config.FmsAccountUserLevelEnum;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import jakarta.validation.Valid;
  7 +import jakarta.validation.constraints.NotNull;
  8 +import jakarta.validation.constraints.Size;
  9 +import lombok.Data;
  10 +
  11 +import java.util.List;
  12 +
  13 +@Schema(description = "管理后台 - FMS 账套用户更新 Request VO")
  14 +@Data
  15 +public class FmsAccountUserUpdateReqVO {
  16 +
  17 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  18 + @NotNull(message = "账套编号不能为空")
  19 + private Long accountSetId;
  20 +
  21 + @Schema(description = "账套成员数组", requiredMode = Schema.RequiredMode.REQUIRED)
  22 + @NotNull(message = "账套成员数组不能为空")
  23 + @Size(max = 100, message = "单个账套最多授权 100 名成员")
  24 + @Valid
  25 + private List<Member> members;
  26 +
  27 + @Schema(description = "管理后台 - FMS 账套成员")
  28 + @Data
  29 + public static class Member {
  30 +
  31 + @Schema(description = "后台用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  32 + @NotNull(message = "成员用户编号不能为空")
  33 + private Long userId;
  34 +
  35 + @Schema(description = "成员权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  36 + @NotNull(message = "成员权限级别不能为空")
  37 + @InEnum(FmsAccountUserLevelEnum.class)
  38 + private Integer level;
  39 +
  40 + }
  41 +
  42 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/auxiliaryitem/FmsAuxiliaryItemImportExcelVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.auxiliaryitem;
  2 +
  3 +import cn.idev.excel.annotation.ExcelProperty;
  4 +import jakarta.validation.constraints.NotBlank;
  5 +import jakarta.validation.constraints.Size;
  6 +import lombok.Data;
  7 +
  8 +/**
  9 + * FMS 辅助核算项目 Excel 导入 VO
  10 + *
  11 + * @author 芋道源码
  12 + */
  13 +@Data
  14 +public class FmsAuxiliaryItemImportExcelVO {
  15 +
  16 + @ExcelProperty("编码")
  17 + @NotBlank(message = "编码不能为空")
  18 + @Size(max = 64, message = "编码长度不能超过 64 个字符")
  19 + private String code;
  20 +
  21 + @ExcelProperty("名称")
  22 + @NotBlank(message = "名称不能为空")
  23 + @Size(max = 255, message = "名称长度不能超过 255 个字符")
  24 + private String name;
  25 +
  26 + @ExcelProperty("备注")
  27 + @Size(max = 500, message = "备注长度不能超过 500 个字符")
  28 + private String remark;
  29 +
  30 + @ExcelProperty("规格")
  31 + @Size(max = 255, message = "规格长度不能超过 255 个字符")
  32 + private String specification;
  33 +
  34 + @ExcelProperty("单位")
  35 + @Size(max = 255, message = "单位长度不能超过 255 个字符")
  36 + private String unit;
  37 +
  38 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/auxiliaryitem/FmsAuxiliaryItemImportRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.auxiliaryitem;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.util.List;
  7 +import java.util.Map;
  8 +
  9 +/**
  10 + * FMS 辅助核算项目导入结果 Response VO
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Schema(description = "管理后台 - FMS 辅助核算项目导入结果 Response VO")
  15 +@Data
  16 +public class FmsAuxiliaryItemImportRespVO {
  17 +
  18 + @Schema(description = "总数量", requiredMode = Schema.RequiredMode.REQUIRED)
  19 + private Integer totalCount;
  20 +
  21 + @Schema(description = "成功编码数组", requiredMode = Schema.RequiredMode.REQUIRED)
  22 + private List<String> successItemCodes;
  23 +
  24 + @Schema(description = "失败原因 Map", requiredMode = Schema.RequiredMode.REQUIRED)
  25 + private Map<String, String> failureReasons;
  26 +
  27 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/auxiliaryitem/FmsAuxiliaryItemPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.auxiliaryitem;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import jakarta.validation.constraints.NotNull;
  6 +import lombok.Data;
  7 +import lombok.EqualsAndHashCode;
  8 +
  9 +/**
  10 + * FMS 辅助核算项目分页 Request VO
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Schema(description = "管理后台 - FMS 辅助核算项目分页 Request VO")
  15 +@Data
  16 +@EqualsAndHashCode(callSuper = true)
  17 +public class FmsAuxiliaryItemPageReqVO extends PageParam {
  18 +
  19 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  20 + @NotNull(message = "账套编号不能为空")
  21 + private Long accountSetId;
  22 +
  23 + @Schema(description = "辅助核算类别编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  24 + @NotNull(message = "辅助核算类别编号不能为空")
  25 + private Long auxiliaryTypeId;
  26 +
  27 + @Schema(description = "关键词,匹配编码或名称", example = "测试")
  28 + private String search;
  29 +
  30 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/auxiliaryitem/FmsAuxiliaryItemRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.auxiliaryitem;
  2 +
  3 +import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
  4 +import cn.idev.excel.annotation.ExcelProperty;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import lombok.Data;
  7 +
  8 +import java.time.LocalDateTime;
  9 +
  10 +/**
  11 + * FMS 辅助核算项目 Response VO
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@Schema(description = "管理后台 - FMS 辅助核算项目 Response VO")
  16 +@Data
  17 +@ExcelIgnoreUnannotated
  18 +public class FmsAuxiliaryItemRespVO {
  19 +
  20 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  21 + private Long id;
  22 +
  23 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  24 + private Long accountSetId;
  25 +
  26 + @Schema(description = "辅助核算类别编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  27 + private Long auxiliaryTypeId;
  28 +
  29 + @Schema(description = "编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "KH001")
  30 + @ExcelProperty("编码")
  31 + private String code;
  32 +
  33 + @Schema(description = "名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "上海测试数字科技有限公司")
  34 + @ExcelProperty("名称")
  35 + private String name;
  36 +
  37 + @Schema(description = "备注", example = "重点客户")
  38 + @ExcelProperty("备注")
  39 + private String remark;
  40 +
  41 + @Schema(description = "规格", example = "标准版")
  42 + @ExcelProperty("规格")
  43 + private String specification;
  44 +
  45 + @Schema(description = "单位", example = "台")
  46 + @ExcelProperty("单位")
  47 + private String unit;
  48 +
  49 + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  50 + private Integer status;
  51 +
  52 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  53 + private LocalDateTime createTime;
  54 +
  55 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/auxiliaryitem/FmsAuxiliaryItemSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.auxiliaryitem;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotBlank;
  5 +import jakarta.validation.constraints.NotNull;
  6 +import jakarta.validation.constraints.Size;
  7 +import lombok.Data;
  8 +
  9 +/**
  10 + * FMS 辅助核算项目创建或修改 Request VO
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Schema(description = "管理后台 - FMS 辅助核算项目创建或修改 Request VO")
  15 +@Data
  16 +public class FmsAuxiliaryItemSaveReqVO {
  17 +
  18 + @Schema(description = "编号", example = "1024")
  19 + private Long id;
  20 +
  21 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  22 + @NotNull(message = "账套编号不能为空")
  23 + private Long accountSetId;
  24 +
  25 + @Schema(description = "辅助核算类别编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  26 + @NotNull(message = "辅助核算类别编号不能为空")
  27 + private Long auxiliaryTypeId;
  28 +
  29 + @Schema(description = "编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "KH001")
  30 + @NotBlank(message = "编码不能为空")
  31 + @Size(max = 64, message = "编码长度不能超过 64 个字符")
  32 + private String code;
  33 +
  34 + @Schema(description = "名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "上海测试数字科技有限公司")
  35 + @NotBlank(message = "名称不能为空")
  36 + @Size(max = 255, message = "名称长度不能超过 255 个字符")
  37 + private String name;
  38 +
  39 + @Schema(description = "备注", example = "重点客户")
  40 + @Size(max = 500, message = "备注长度不能超过 500 个字符")
  41 + private String remark;
  42 +
  43 + @Schema(description = "规格", example = "标准版")
  44 + @Size(max = 255, message = "规格长度不能超过 255 个字符")
  45 + private String specification;
  46 +
  47 + @Schema(description = "单位", example = "台")
  48 + @Size(max = 255, message = "单位长度不能超过 255 个字符")
  49 + private String unit;
  50 +
  51 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/auxiliaryitem/FmsAuxiliaryItemStatusReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.auxiliaryitem;
  2 +
  3 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  4 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import jakarta.validation.constraints.NotNull;
  7 +import lombok.Data;
  8 +
  9 +/**
  10 + * FMS 辅助核算项目状态更新 Request VO
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Schema(description = "管理后台 - FMS 辅助核算项目状态更新 Request VO")
  15 +@Data
  16 +public class FmsAuxiliaryItemStatusReqVO {
  17 +
  18 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  19 + @NotNull(message = "账套编号不能为空")
  20 + private Long accountSetId;
  21 +
  22 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  23 + @NotNull(message = "编号不能为空")
  24 + private Long id;
  25 +
  26 + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
  27 + @NotNull(message = "状态不能为空")
  28 + @InEnum(CommonStatusEnum.class)
  29 + private Integer status;
  30 +
  31 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/auxiliarytype/FmsAuxiliaryTypeRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.auxiliarytype;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +/**
  7 + * FMS 辅助核算类别 Response VO
  8 + *
  9 + * @author 芋道源码
  10 + */
  11 +@Schema(description = "管理后台 - FMS 辅助核算类别 Response VO")
  12 +@Data
  13 +public class FmsAuxiliaryTypeRespVO {
  14 +
  15 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  16 + private Long id;
  17 +
  18 + @Schema(description = "名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "客户")
  19 + private String name;
  20 +
  21 + @Schema(description = "是否系统预置", requiredMode = Schema.RequiredMode.REQUIRED)
  22 + private Boolean systemPreset;
  23 +
  24 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  25 + private Long accountSetId;
  26 +
  27 + @Schema(description = "类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  28 + private Integer type;
  29 +
  30 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/auxiliarytype/FmsAuxiliaryTypeSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.auxiliarytype;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotBlank;
  5 +import jakarta.validation.constraints.NotNull;
  6 +import jakarta.validation.constraints.Size;
  7 +import lombok.Data;
  8 +
  9 +/**
  10 + * FMS 辅助核算类别创建或修改 Request VO
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Schema(description = "管理后台 - FMS 辅助核算类别创建或修改 Request VO")
  15 +@Data
  16 +public class FmsAuxiliaryTypeSaveReqVO {
  17 +
  18 + @Schema(description = "编号", example = "1024")
  19 + private Long id;
  20 +
  21 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  22 + @NotNull(message = "账套编号不能为空")
  23 + private Long accountSetId;
  24 +
  25 + @Schema(description = "名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "门店")
  26 + @NotBlank(message = "名称不能为空")
  27 + @Size(max = 255, message = "名称长度不能超过 255 个字符")
  28 + private String name;
  29 +
  30 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/currency/FmsCurrencyRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.currency;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.math.BigDecimal;
  7 +import java.time.LocalDateTime;
  8 +
  9 +/**
  10 + * FMS 币别 Response VO
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Schema(description = "管理后台 - FMS 币别 Response VO")
  15 +@Data
  16 +public class FmsCurrencyRespVO {
  17 +
  18 + @Schema(description = "币别编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  19 + private Long id;
  20 +
  21 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  22 + private Long accountSetId;
  23 +
  24 + @Schema(description = "币别编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "USD")
  25 + private String code;
  26 +
  27 + @Schema(description = "币别名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "美元")
  28 + private String name;
  29 +
  30 + @Schema(description = "汇率", requiredMode = Schema.RequiredMode.REQUIRED, example = "7.120000")
  31 + private BigDecimal exchangeRate;
  32 +
  33 + @Schema(description = "是否本位币", requiredMode = Schema.RequiredMode.REQUIRED)
  34 + private Boolean standard;
  35 +
  36 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  37 + private LocalDateTime createTime;
  38 +
  39 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/currency/FmsCurrencySaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.currency;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.DecimalMin;
  5 +import jakarta.validation.constraints.Digits;
  6 +import jakarta.validation.constraints.NotBlank;
  7 +import jakarta.validation.constraints.NotNull;
  8 +import jakarta.validation.constraints.Pattern;
  9 +import jakarta.validation.constraints.Size;
  10 +import lombok.Data;
  11 +
  12 +import java.math.BigDecimal;
  13 +
  14 +/**
  15 + * FMS 币别保存 Request VO
  16 + *
  17 + * @author 芋道源码
  18 + */
  19 +@Schema(description = "管理后台 - FMS 币别保存 Request VO")
  20 +@Data
  21 +public class FmsCurrencySaveReqVO {
  22 +
  23 + @Schema(description = "币别编号", example = "1024")
  24 + private Long id;
  25 +
  26 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  27 + @NotNull(message = "账套不能为空")
  28 + private Long accountSetId;
  29 +
  30 + @Schema(description = "币别编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "USD")
  31 + @NotBlank(message = "币别编码不能为空")
  32 + @Size(max = 64, message = "币别编码长度不能超过 64 个字符")
  33 + @Pattern(regexp = "^[A-Za-z][A-Za-z0-9_]*$", message = "币别编码必须以字母开头,只能包含字母、数字和下划线")
  34 + private String code;
  35 +
  36 + @Schema(description = "币别名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "美元")
  37 + @NotBlank(message = "币别名称不能为空")
  38 + @Size(max = 255, message = "币别名称长度不能超过 255 个字符")
  39 + private String name;
  40 +
  41 + @Schema(description = "汇率", requiredMode = Schema.RequiredMode.REQUIRED, example = "7.120000")
  42 + @NotNull(message = "汇率不能为空")
  43 + @DecimalMin(value = "0", inclusive = false, message = "汇率必须大于 0")
  44 + @Digits(integer = 12, fraction = 6, message = "汇率最多 12 位整数和 6 位小数")
  45 + private BigDecimal exchangeRate;
  46 +
  47 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/digest/FmsDigestRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.digest;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.time.LocalDateTime;
  7 +
  8 +/**
  9 + * FMS 常用摘要 Response VO
  10 + *
  11 + * @author 芋道源码
  12 + */
  13 +@Schema(description = "管理后台 - FMS 常用摘要 Response VO")
  14 +@Data
  15 +public class FmsDigestRespVO {
  16 +
  17 + @Schema(description = "常用摘要编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  18 + private Long id;
  19 +
  20 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  21 + private Long accountSetId;
  22 +
  23 + @Schema(description = "摘要内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "购买办公用品")
  24 + private String content;
  25 +
  26 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  27 + private LocalDateTime createTime;
  28 +
  29 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/digest/FmsDigestSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.digest;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotBlank;
  5 +import jakarta.validation.constraints.NotNull;
  6 +import jakarta.validation.constraints.Size;
  7 +import lombok.Data;
  8 +
  9 +/**
  10 + * FMS 常用摘要保存 Request VO
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Schema(description = "管理后台 - FMS 常用摘要保存 Request VO")
  15 +@Data
  16 +public class FmsDigestSaveReqVO {
  17 +
  18 + @Schema(description = "常用摘要编号", example = "1024")
  19 + private Long id;
  20 +
  21 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  22 + @NotNull(message = "账套编号不能为空")
  23 + private Long accountSetId;
  24 +
  25 + @Schema(description = "摘要内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "购买办公用品")
  26 + @NotBlank(message = "摘要内容不能为空")
  27 + @Size(max = 500, message = "摘要内容长度不能超过 500 个字符")
  28 + private String content;
  29 +
  30 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/financeindicator/FmsFinanceIndicatorRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.financeindicator;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.time.LocalDateTime;
  7 +
  8 +// TODO DONE @AI:字段 Swagger 注解和空行已补齐。
  9 +@Schema(description = "管理后台 - FMS 财务指标 Response VO")
  10 +@Data
  11 +public class FmsFinanceIndicatorRespVO {
  12 +
  13 + @Schema(description = "指标编号", example = "1024")
  14 + private Long id;
  15 +
  16 + @Schema(description = "账套编号", example = "1")
  17 + private Long accountSetId;
  18 +
  19 + @Schema(description = "指标名称", example = "现金")
  20 + private String name;
  21 +
  22 + @Schema(description = "指标编码", example = "cash")
  23 + private String code;
  24 +
  25 + @Schema(description = "取数报表类型", example = "1")
  26 + private Integer type;
  27 +
  28 + @Schema(description = "指标公式")
  29 + private String formula;
  30 +
  31 + @Schema(description = "展示顺序", example = "10")
  32 + private Integer sort;
  33 +
  34 + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
  35 + private Integer status;
  36 +
  37 + @Schema(description = "创建时间")
  38 + private LocalDateTime createTime;
  39 +
  40 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/financeindicator/FmsFinanceIndicatorSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.financeindicator;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  5 +import cn.iocoder.yudao.module.fms.enums.config.FmsFinanceIndicatorTypeEnum;
  6 +import io.swagger.v3.oas.annotations.media.Schema;
  7 +import jakarta.validation.constraints.NotBlank;
  8 +import jakarta.validation.constraints.NotNull;
  9 +import jakarta.validation.constraints.Size;
  10 +import lombok.Data;
  11 +
  12 +// TODO DONE @AI:字段空行已对齐现有 SaveReqVO。
  13 +@Schema(description = "管理后台 - FMS 财务指标保存 Request VO")
  14 +@Data
  15 +public class FmsFinanceIndicatorSaveReqVO {
  16 +
  17 + @Schema(description = "指标编号", example = "1024")
  18 + private Long id;
  19 +
  20 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  21 + @NotNull(message = "账套编号不能为空")
  22 + private Long accountSetId;
  23 +
  24 + @Schema(description = "指标名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "现金")
  25 + @NotBlank(message = "指标名称不能为空")
  26 + @Size(max = 100, message = "指标名称长度不能超过 100 个字符")
  27 + private String name;
  28 +
  29 + @Schema(description = "指标编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "cash")
  30 + @NotBlank(message = "指标编码不能为空")
  31 + @Size(max = 64, message = "指标编码长度不能超过 64 个字符")
  32 + private String code;
  33 +
  34 + @Schema(description = "取数报表类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  35 + @NotNull(message = "取数报表类型不能为空")
  36 + @InEnum(FmsFinanceIndicatorTypeEnum.class)
  37 + private Integer type;
  38 +
  39 + @Schema(description = "指标公式,支持 L1+L2 或科目公式 JSON", requiredMode = Schema.RequiredMode.REQUIRED)
  40 + @NotBlank(message = "指标公式不能为空")
  41 + @Size(max = 2000, message = "指标公式长度不能超过 2000 个字符")
  42 + private String formula;
  43 +
  44 + @Schema(description = "展示顺序", example = "10")
  45 + @NotNull(message = "展示顺序不能为空")
  46 + private Integer sort;
  47 +
  48 + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
  49 + @NotNull(message = "状态不能为空")
  50 + @InEnum(CommonStatusEnum.class)
  51 + private Integer status;
  52 +
  53 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/financeparameter/FmsFinanceParameterRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.financeparameter;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +@Schema(description = "管理后台 - FMS 财务参数 Response VO")
  7 +@Data
  8 +public class FmsFinanceParameterRespVO {
  9 +
  10 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  11 + private Long accountSetId;
  12 +
  13 + @Schema(description = "科目层级", requiredMode = Schema.RequiredMode.REQUIRED, example = "4")
  14 + private Integer level;
  15 +
  16 + @Schema(description = "科目编码规则", requiredMode = Schema.RequiredMode.REQUIRED, example = "4-2-2-2")
  17 + private String subjectCodeRule;
  18 +
  19 + @Schema(description = "账簿余额方向模式", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  20 + private Integer ledgerBalanceMode;
  21 +
  22 + @Schema(description = "结账前是否要求凭证审核", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
  23 + private Boolean voucherReviewRequired;
  24 +
  25 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/financeparameter/FmsFinanceParameterUpdateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.financeparameter;
  2 +
  3 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  4 +import cn.iocoder.yudao.module.fms.enums.ledger.FmsLedgerBalanceModeEnum;
  5 +import cn.iocoder.yudao.module.fms.enums.config.FmsAccountingStandardEnum;
  6 +import com.mzt.logapi.starter.annotation.DiffLogField;
  7 +import io.swagger.v3.oas.annotations.media.Schema;
  8 +import jakarta.validation.constraints.Max;
  9 +import jakarta.validation.constraints.Min;
  10 +import jakarta.validation.constraints.NotBlank;
  11 +import jakarta.validation.constraints.NotNull;
  12 +import jakarta.validation.constraints.Size;
  13 +import lombok.Data;
  14 +
  15 +@Schema(description = "管理后台 - FMS 财务参数更新 Request VO")
  16 +@Data
  17 +public class FmsFinanceParameterUpdateReqVO {
  18 +
  19 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  20 + @NotNull(message = "账套编号不能为空")
  21 + private Long accountSetId;
  22 +
  23 + @Schema(description = "会计制度", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  24 + @NotNull(message = "会计制度不能为空")
  25 + @InEnum(FmsAccountingStandardEnum.class)
  26 + @DiffLogField(name = "会计制度")
  27 + private Integer standard;
  28 +
  29 + @Schema(description = "科目层级", requiredMode = Schema.RequiredMode.REQUIRED, example = "4")
  30 + @NotNull(message = "科目层级不能为空")
  31 + @Min(value = 1, message = "科目层级不能小于 1")
  32 + @Max(value = 8, message = "科目层级不能大于 8")
  33 + @DiffLogField(name = "科目层级")
  34 + private Integer level;
  35 +
  36 + @Schema(description = "科目编码规则", requiredMode = Schema.RequiredMode.REQUIRED, example = "4-2-2-2")
  37 + @NotBlank(message = "科目编码规则不能为空")
  38 + @Size(max = 64, message = "科目编码规则不能超过 64 个字符")
  39 + @DiffLogField(name = "科目编码规则")
  40 + private String subjectCodeRule;
  41 +
  42 + @Schema(description = "账簿余额方向模式", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  43 + @NotNull(message = "账簿余额方向模式不能为空")
  44 + @InEnum(FmsLedgerBalanceModeEnum.class)
  45 + @DiffLogField(name = "账簿余额方向")
  46 + private Integer ledgerBalanceMode;
  47 +
  48 + @Schema(description = "结账前是否要求凭证审核", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
  49 + @NotNull(message = "结账前凭证审核设置不能为空")
  50 + @DiffLogField(name = "凭证审核后才允许结账")
  51 + private Boolean voucherReviewRequired;
  52 +
  53 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/initialbalance/FmsInitialBalanceExcelVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.initialbalance;
  2 +
  3 +import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
  4 +import cn.idev.excel.annotation.ExcelProperty;
  5 +import lombok.Data;
  6 +
  7 +import java.math.BigDecimal;
  8 +
  9 +/**
  10 + * FMS 初始余额 Excel VO
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Data
  15 +@ExcelIgnoreUnannotated
  16 +public class FmsInitialBalanceExcelVO {
  17 +
  18 + /**
  19 + * Excel 行号
  20 + */
  21 + private Integer rowNumber;
  22 + /**
  23 + * 科目编码
  24 + */
  25 + @ExcelProperty("科目编码")
  26 + private String subjectCode;
  27 + /**
  28 + * 科目名称
  29 + */
  30 + @ExcelProperty("科目名称")
  31 + private String subjectName;
  32 + /**
  33 + * 余额方向名称
  34 + */
  35 + @ExcelProperty("方向")
  36 + private String directionName;
  37 + /**
  38 + * 辅助核算项目,格式为“类别:名称/类别:名称”
  39 + */
  40 + @ExcelProperty("辅助核算项目")
  41 + private String auxiliaryItems;
  42 + /**
  43 + * 科目类型
  44 + */
  45 + private Integer subjectType;
  46 + /**
  47 + * 是否启用数量核算
  48 + */
  49 + private Boolean quantityAccounting;
  50 + /**
  51 + * 是否启用辅助核算
  52 + */
  53 + private Boolean auxiliaryAccounting;
  54 + /**
  55 + * 期初数量
  56 + */
  57 + @ExcelProperty("期初数量")
  58 + private BigDecimal openingQuantity;
  59 + /**
  60 + * 期初金额
  61 + */
  62 + @ExcelProperty("期初金额")
  63 + private BigDecimal openingAmount;
  64 + /**
  65 + * 本年累计借方数量
  66 + */
  67 + @ExcelProperty("本年累计借方数量")
  68 + private BigDecimal yearDebitQuantity;
  69 + /**
  70 + * 本年累计借方金额
  71 + */
  72 + @ExcelProperty("本年累计借方金额")
  73 + private BigDecimal yearDebitAmount;
  74 + /**
  75 + * 本年累计贷方数量
  76 + */
  77 + @ExcelProperty("本年累计贷方数量")
  78 + private BigDecimal yearCreditQuantity;
  79 + /**
  80 + * 本年累计贷方金额
  81 + */
  82 + @ExcelProperty("本年累计贷方金额")
  83 + private BigDecimal yearCreditAmount;
  84 + /**
  85 + * 年初数量
  86 + */
  87 + @ExcelProperty("年初数量")
  88 + private BigDecimal yearOpeningQuantity;
  89 + /**
  90 + * 年初金额
  91 + */
  92 + @ExcelProperty("年初金额")
  93 + private BigDecimal yearOpeningAmount;
  94 + /**
  95 + * 实际损益发生数量
  96 + */
  97 + @ExcelProperty("实际损益发生数量")
  98 + private BigDecimal profitLossQuantity;
  99 + /**
  100 + * 实际损益发生金额
  101 + */
  102 + @ExcelProperty("实际损益发生金额")
  103 + private BigDecimal profitLossAmount;
  104 +
  105 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/initialbalance/FmsInitialBalanceRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.initialbalance;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.math.BigDecimal;
  7 +import java.util.List;
  8 +
  9 +@Schema(description = "管理后台 - FMS 初始余额 Response VO")
  10 +@Data
  11 +public class FmsInitialBalanceRespVO {
  12 +
  13 + @Schema(description = "初始余额编号", example = "1024")
  14 + private Long id;
  15 +
  16 + @Schema(description = "科目编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  17 + private Long subjectId;
  18 +
  19 + @Schema(description = "科目编码", requiredMode = Schema.RequiredMode.REQUIRED)
  20 + private String subjectCode;
  21 +
  22 + @Schema(description = "科目名称", requiredMode = Schema.RequiredMode.REQUIRED)
  23 + private String subjectName;
  24 +
  25 + @Schema(description = "上级科目编号", example = "1024")
  26 + private Long parentId;
  27 +
  28 + @Schema(description = "科目类型", requiredMode = Schema.RequiredMode.REQUIRED)
  29 + private Integer type;
  30 +
  31 + @Schema(description = "余额方向", requiredMode = Schema.RequiredMode.REQUIRED)
  32 + private Integer balanceDirection;
  33 +
  34 + @Schema(description = "是否启用数量核算", requiredMode = Schema.RequiredMode.REQUIRED)
  35 + private Boolean quantityAccounting;
  36 +
  37 + @Schema(description = "数量单位")
  38 + private String quantityUnit;
  39 +
  40 + @Schema(description = "是否启用辅助核算", requiredMode = Schema.RequiredMode.REQUIRED)
  41 + private Boolean auxiliaryAccounting;
  42 +
  43 + @Schema(description = "期初金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000.00")
  44 + private BigDecimal openingAmount;
  45 +
  46 + @Schema(description = "期初数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "10.0000")
  47 + private BigDecimal openingQuantity;
  48 +
  49 + @Schema(description = "本年累计借方金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  50 + private BigDecimal yearDebitAmount;
  51 +
  52 + @Schema(description = "本年累计借方数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1.0000")
  53 + private BigDecimal yearDebitQuantity;
  54 +
  55 + @Schema(description = "本年累计贷方金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "50.00")
  56 + private BigDecimal yearCreditAmount;
  57 +
  58 + @Schema(description = "本年累计贷方数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1.0000")
  59 + private BigDecimal yearCreditQuantity;
  60 +
  61 + @Schema(description = "年初金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "950.00")
  62 + private BigDecimal yearOpeningAmount;
  63 +
  64 + @Schema(description = "年初数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "10.0000")
  65 + private BigDecimal yearOpeningQuantity;
  66 +
  67 + @Schema(description = "实际损益发生额", requiredMode = Schema.RequiredMode.REQUIRED, example = "0.00")
  68 + private BigDecimal profitLossAmount;
  69 +
  70 + @Schema(description = "实际损益发生数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1.0000")
  71 + private BigDecimal profitLossQuantity;
  72 +
  73 + @Schema(description = "辅助核算配置数组")
  74 + private List<AuxiliaryConfig> auxiliaryConfigs;
  75 +
  76 + @Schema(description = "辅助核算余额数组")
  77 + private List<AssistBalance> assistBalances;
  78 +
  79 + @Schema(description = "管理后台 - FMS 初始余额辅助核算配置")
  80 + @Data
  81 + public static class AuxiliaryConfig {
  82 +
  83 + @Schema(description = "辅助核算类别编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  84 + private Long auxiliaryTypeId;
  85 +
  86 + @Schema(description = "辅助核算类型", requiredMode = Schema.RequiredMode.REQUIRED)
  87 + private Integer type;
  88 +
  89 + @Schema(description = "辅助核算类别名称", requiredMode = Schema.RequiredMode.REQUIRED)
  90 + private String name;
  91 +
  92 + }
  93 +
  94 + @Schema(description = "管理后台 - FMS 初始余额辅助核算余额")
  95 + @Data
  96 + public static class AssistBalance {
  97 +
  98 + @Schema(description = "辅助核算组合编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  99 + private Long assistCombinationId;
  100 +
  101 + @Schema(description = "辅助核算项目数组", requiredMode = Schema.RequiredMode.REQUIRED)
  102 + private List<AuxiliaryItem> auxiliaries;
  103 +
  104 + @Schema(description = "期初金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000.00")
  105 + private BigDecimal openingAmount;
  106 +
  107 + @Schema(description = "期初数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "10.0000")
  108 + private BigDecimal openingQuantity;
  109 +
  110 + @Schema(description = "本年累计借方金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  111 + private BigDecimal yearDebitAmount;
  112 +
  113 + @Schema(description = "本年累计借方数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1.0000")
  114 + private BigDecimal yearDebitQuantity;
  115 +
  116 + @Schema(description = "本年累计贷方金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "50.00")
  117 + private BigDecimal yearCreditAmount;
  118 +
  119 + @Schema(description = "本年累计贷方数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1.0000")
  120 + private BigDecimal yearCreditQuantity;
  121 +
  122 + @Schema(description = "年初金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "950.00")
  123 + private BigDecimal yearOpeningAmount;
  124 +
  125 + @Schema(description = "年初数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "10.0000")
  126 + private BigDecimal yearOpeningQuantity;
  127 +
  128 + @Schema(description = "实际损益发生额", requiredMode = Schema.RequiredMode.REQUIRED, example = "0.00")
  129 + private BigDecimal profitLossAmount;
  130 +
  131 + @Schema(description = "实际损益发生数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1.0000")
  132 + private BigDecimal profitLossQuantity;
  133 +
  134 + }
  135 +
  136 + @Schema(description = "管理后台 - FMS 初始余额辅助核算项目")
  137 + @Data
  138 + public static class AuxiliaryItem {
  139 +
  140 + @Schema(description = "辅助核算类型", requiredMode = Schema.RequiredMode.REQUIRED)
  141 + private Integer type;
  142 +
  143 + @Schema(description = "辅助核算类别编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  144 + private Long typeId;
  145 +
  146 + @Schema(description = "辅助核算项目编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  147 + private Long itemId;
  148 +
  149 + @Schema(description = "辅助核算项目名称", requiredMode = Schema.RequiredMode.REQUIRED)
  150 + private String name;
  151 +
  152 + }
  153 +
  154 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/initialbalance/FmsInitialBalanceSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.initialbalance;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.Valid;
  5 +import jakarta.validation.constraints.DecimalMin;
  6 +import jakarta.validation.constraints.NotEmpty;
  7 +import jakarta.validation.constraints.NotNull;
  8 +import lombok.Data;
  9 +
  10 +import java.math.BigDecimal;
  11 +import java.util.List;
  12 +
  13 +@Schema(description = "管理后台 - FMS 初始余额保存 Request VO")
  14 +@Data
  15 +public class FmsInitialBalanceSaveReqVO {
  16 +
  17 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  18 + @NotNull(message = "账套编号不能为空")
  19 + private Long accountSetId;
  20 +
  21 + @Schema(description = "科目余额数组", requiredMode = Schema.RequiredMode.REQUIRED)
  22 + @Valid
  23 + @NotEmpty(message = "科目余额不能为空")
  24 + private List<Balance> balances;
  25 +
  26 + @Data
  27 + public static class Balance extends Amounts {
  28 +
  29 + @Schema(description = "科目编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  30 + @NotNull(message = "科目编号不能为空")
  31 + private Long subjectId;
  32 +
  33 + @Schema(description = "辅助核算余额数组")
  34 + @Valid
  35 + private List<AssistBalance> assistBalances;
  36 +
  37 + }
  38 +
  39 + @Data
  40 + public static class AssistBalance extends Amounts {
  41 +
  42 + @Schema(description = "辅助核算项目编号数组", requiredMode = Schema.RequiredMode.REQUIRED)
  43 + @NotEmpty(message = "辅助核算项目不能为空")
  44 + private List<Long> auxiliaryItemIds;
  45 + }
  46 +
  47 + @Data
  48 + public static class Amounts {
  49 +
  50 + @Schema(description = "期初金额", example = "1000.00")
  51 + @DecimalMin(value = "0", message = "期初金额不能小于 0")
  52 + private BigDecimal openingAmount;
  53 +
  54 + @Schema(description = "期初数量", example = "10.0000")
  55 + @DecimalMin(value = "0", message = "期初数量不能小于 0")
  56 + private BigDecimal openingQuantity;
  57 +
  58 + @Schema(description = "本年累计借方金额", example = "100.00")
  59 + @DecimalMin(value = "0", message = "本年累计借方金额不能小于 0")
  60 + private BigDecimal yearDebitAmount;
  61 +
  62 + @Schema(description = "本年累计借方数量", example = "1.0000")
  63 + @DecimalMin(value = "0", message = "本年累计借方数量不能小于 0")
  64 + private BigDecimal yearDebitQuantity;
  65 +
  66 + @Schema(description = "本年累计贷方金额", example = "50.00")
  67 + @DecimalMin(value = "0", message = "本年累计贷方金额不能小于 0")
  68 + private BigDecimal yearCreditAmount;
  69 +
  70 + @Schema(description = "本年累计贷方数量", example = "1.0000")
  71 + @DecimalMin(value = "0", message = "本年累计贷方数量不能小于 0")
  72 + private BigDecimal yearCreditQuantity;
  73 +
  74 + @Schema(description = "年初金额", example = "950.00")
  75 + @DecimalMin(value = "0", message = "年初金额不能小于 0")
  76 + private BigDecimal yearOpeningAmount;
  77 +
  78 + @Schema(description = "年初数量", example = "10.0000")
  79 + @DecimalMin(value = "0", message = "年初数量不能小于 0")
  80 + private BigDecimal yearOpeningQuantity;
  81 +
  82 + @Schema(description = "实际损益发生额", example = "0.00")
  83 + @DecimalMin(value = "0", message = "实际损益发生额不能小于 0")
  84 + private BigDecimal profitLossAmount;
  85 +
  86 + @Schema(description = "实际损益发生数量", example = "1.0000")
  87 + @DecimalMin(value = "0", message = "实际损益发生数量不能小于 0")
  88 + private BigDecimal profitLossQuantity;
  89 + }
  90 +
  91 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/initialbalance/FmsTrialBalanceRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.initialbalance;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.math.BigDecimal;
  7 +
  8 +@Schema(description = "管理后台 - FMS 试算平衡 Response VO")
  9 +@Data
  10 +public class FmsTrialBalanceRespVO {
  11 +
  12 + @Schema(description = "期初借方金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000.00")
  13 + private BigDecimal openingDebitAmount;
  14 +
  15 + @Schema(description = "期初贷方金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000.00")
  16 + private BigDecimal openingCreditAmount;
  17 +
  18 + @Schema(description = "期初差额", requiredMode = Schema.RequiredMode.REQUIRED, example = "0.00")
  19 + private BigDecimal openingDifferenceAmount;
  20 +
  21 + @Schema(description = "本年累计借方金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  22 + private BigDecimal yearDebitAmount;
  23 +
  24 + @Schema(description = "本年累计贷方金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  25 + private BigDecimal yearCreditAmount;
  26 +
  27 + @Schema(description = "本年累计差额", requiredMode = Schema.RequiredMode.REQUIRED, example = "0.00")
  28 + private BigDecimal yearDifferenceAmount;
  29 +
  30 + @Schema(description = "是否平衡", requiredMode = Schema.RequiredMode.REQUIRED)
  31 + private Boolean balanced;
  32 +
  33 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/subject/FmsSubjectDeleteReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.subject;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotEmpty;
  5 +import jakarta.validation.constraints.NotNull;
  6 +import lombok.Data;
  7 +
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * FMS 科目删除 Request VO
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@Schema(description = "管理后台 - FMS 科目删除 Request VO")
  16 +@Data
  17 +public class FmsSubjectDeleteReqVO {
  18 +
  19 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  20 + @NotNull(message = "账套编号不能为空")
  21 + private Long accountSetId;
  22 +
  23 + @Schema(description = "科目编号数组", requiredMode = Schema.RequiredMode.REQUIRED)
  24 + @NotEmpty(message = "科目编号数组不能为空")
  25 + private List<Long> ids;
  26 +
  27 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/subject/FmsSubjectImportExcelVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.subject;
  2 +
  3 +import cn.idev.excel.annotation.ExcelProperty;
  4 +import jakarta.validation.constraints.NotBlank;
  5 +import lombok.AllArgsConstructor;
  6 +import lombok.Builder;
  7 +import lombok.Data;
  8 +import lombok.NoArgsConstructor;
  9 +
  10 +/**
  11 + * FMS 科目 Excel 导入 VO
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@Data
  16 +@Builder
  17 +@AllArgsConstructor
  18 +@NoArgsConstructor
  19 +public class FmsSubjectImportExcelVO {
  20 +
  21 + @ExcelProperty("科目编码")
  22 + @NotBlank(message = "科目编码不能为空")
  23 + private String code;
  24 +
  25 + @ExcelProperty("科目名称")
  26 + @NotBlank(message = "科目名称不能为空")
  27 + private String name;
  28 +
  29 + @ExcelProperty("上级科目编码")
  30 + private String parentSubjectCode;
  31 +
  32 + @ExcelProperty("余额方向")
  33 + @NotBlank(message = "余额方向不能为空")
  34 + private String balanceDirection;
  35 +
  36 + @ExcelProperty("类别")
  37 + @NotBlank(message = "类别不能为空")
  38 + private String categoryName;
  39 +
  40 + @ExcelProperty("辅助核算")
  41 + private String auxiliaryNames;
  42 +
  43 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/subject/FmsSubjectImportRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.subject;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.util.List;
  7 +import java.util.Map;
  8 +
  9 +@Schema(description = "管理后台 - FMS 科目导入结果 Response VO")
  10 +@Data
  11 +public class FmsSubjectImportRespVO {
  12 +
  13 + @Schema(description = "总数量", requiredMode = Schema.RequiredMode.REQUIRED)
  14 + private Integer totalCount;
  15 +
  16 + @Schema(description = "成功科目编码数组", requiredMode = Schema.RequiredMode.REQUIRED)
  17 + private List<String> successSubjectCodes;
  18 +
  19 + @Schema(description = "失败原因 Map", requiredMode = Schema.RequiredMode.REQUIRED)
  20 + private Map<String, String> failureReasons;
  21 +
  22 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/subject/FmsSubjectListReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.subject;
  2 +
  3 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  4 +import cn.iocoder.yudao.module.fms.enums.config.FmsSubjectTypeEnum;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import jakarta.validation.constraints.NotNull;
  7 +import lombok.Data;
  8 +
  9 +/**
  10 + * FMS 科目列表 Request VO
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Schema(description = "管理后台 - FMS 科目列表 Request VO")
  15 +@Data
  16 +public class FmsSubjectListReqVO {
  17 +
  18 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  19 + @NotNull(message = "账套编号不能为空")
  20 + private Long accountSetId;
  21 +
  22 + @Schema(description = "科目类型", example = "1")
  23 + @InEnum(FmsSubjectTypeEnum.class)
  24 + private Integer type;
  25 +
  26 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/subject/FmsSubjectRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.subject;
  2 +
  3 +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
  4 +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
  5 +import cn.iocoder.yudao.framework.excel.core.convert.StringListConvert;
  6 +import cn.iocoder.yudao.module.fms.enums.DictTypeConstants;
  7 +import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
  8 +import cn.idev.excel.annotation.ExcelProperty;
  9 +import com.fasterxml.jackson.annotation.JsonIgnore;
  10 +import io.swagger.v3.oas.annotations.media.Schema;
  11 +import lombok.Data;
  12 +
  13 +import java.time.LocalDateTime;
  14 +import java.util.List;
  15 +
  16 +import static cn.iocoder.yudao.module.infra.enums.DictTypeConstants.BOOLEAN_STRING;
  17 +
  18 +/**
  19 + * FMS 科目 Response VO
  20 + *
  21 + * @author 芋道源码
  22 + */
  23 +@Schema(description = "管理后台 - FMS 科目 Response VO")
  24 +@Data
  25 +@ExcelIgnoreUnannotated
  26 +public class FmsSubjectRespVO {
  27 +
  28 + @Schema(description = "科目编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  29 + private Long id;
  30 +
  31 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  32 + private Long accountSetId;
  33 +
  34 + @Schema(description = "科目编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "1001")
  35 + @ExcelProperty(value = "编码", index = 0)
  36 + private String code;
  37 +
  38 + @Schema(description = "科目名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "库存现金")
  39 + @ExcelProperty(value = "名称", index = 1)
  40 + private String name;
  41 +
  42 + @Schema(description = "上级科目编号", example = "1024")
  43 + private Long parentId;
  44 +
  45 + @Schema(description = "科目类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  46 + private Integer type;
  47 +
  48 + @Schema(description = "科目类别", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  49 + private Integer category;
  50 +
  51 + @JsonIgnore // 仅 excel 导出使用
  52 + @ExcelProperty(value = "类别", index = 2, converter = DictConvert.class)
  53 + @DictFormat(DictTypeConstants.SUBJECT_CATEGORY)
  54 + private String categoryDictValue;
  55 +
  56 + @Schema(description = "余额方向", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  57 + @ExcelProperty(value = "余额方向", index = 3, converter = DictConvert.class)
  58 + @DictFormat(DictTypeConstants.DEBIT_CREDIT_DIRECTION)
  59 + private Integer balanceDirection;
  60 +
  61 + @Schema(description = "辅助核算类别编号数组")
  62 + private List<Long> auxiliaryTypeIds;
  63 +
  64 + @Schema(description = "外币核算币别编号数组")
  65 + private List<Long> currencyIds;
  66 +
  67 + @Schema(description = "是否启用数量核算", requiredMode = Schema.RequiredMode.REQUIRED)
  68 + private Boolean quantityAccounting;
  69 +
  70 + @Schema(description = "数量单位", example = "件")
  71 + @ExcelProperty(value = "数量", index = 5)
  72 + private String quantityUnit;
  73 +
  74 + @Schema(description = "是否现金及现金等价物", requiredMode = Schema.RequiredMode.REQUIRED)
  75 + @ExcelProperty(value = "是否现金项", index = 6, converter = DictConvert.class)
  76 + @DictFormat(BOOLEAN_STRING)
  77 + private Boolean cash;
  78 +
  79 + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  80 + private Integer status;
  81 +
  82 + @Schema(description = "层级", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  83 + private Integer level;
  84 +
  85 + @Schema(description = "辅助核算类别名称数组")
  86 + @ExcelProperty(value = "辅助核算", index = 4, converter = StringListConvert.class)
  87 + private List<String> auxiliaryTypeNames;
  88 +
  89 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  90 + private LocalDateTime createTime;
  91 +
  92 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/subject/FmsSubjectSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.subject;
  2 +
  3 +import cn.hutool.core.util.StrUtil;
  4 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  5 +import cn.iocoder.yudao.module.fms.enums.common.FmsDebitCreditDirectionEnum;
  6 +import cn.iocoder.yudao.module.fms.enums.config.FmsSubjectCategoryEnum;
  7 +import cn.iocoder.yudao.module.fms.enums.config.FmsSubjectTypeEnum;
  8 +import io.swagger.v3.oas.annotations.media.Schema;
  9 +import jakarta.validation.constraints.AssertTrue;
  10 +import jakarta.validation.constraints.NotBlank;
  11 +import jakarta.validation.constraints.NotNull;
  12 +import jakarta.validation.constraints.Size;
  13 +import lombok.Data;
  14 +
  15 +import java.util.List;
  16 +
  17 +/**
  18 + * FMS 科目保存 Request VO
  19 + *
  20 + * @author 芋道源码
  21 + */
  22 +@Schema(description = "管理后台 - FMS 科目保存 Request VO")
  23 +@Data
  24 +public class FmsSubjectSaveReqVO {
  25 +
  26 + @Schema(description = "科目编号", example = "1024")
  27 + private Long id;
  28 +
  29 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  30 + @NotNull(message = "账套编号不能为空")
  31 + private Long accountSetId;
  32 +
  33 + @Schema(description = "科目编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "1001")
  34 + @NotBlank(message = "科目编码不能为空")
  35 + @Size(max = 64, message = "科目编码长度不能超过 64 个字符")
  36 + private String code;
  37 +
  38 + @Schema(description = "科目名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "库存现金")
  39 + @NotBlank(message = "科目名称不能为空")
  40 + @Size(max = 255, message = "科目名称长度不能超过 255 个字符")
  41 + private String name;
  42 +
  43 + @Schema(description = "上级科目编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  44 + @NotNull(message = "上级科目编号不能为空")
  45 + private Long parentId;
  46 +
  47 + @Schema(description = "科目类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  48 + @NotNull(message = "科目类型不能为空")
  49 + @InEnum(FmsSubjectTypeEnum.class)
  50 + private Integer type;
  51 +
  52 + @Schema(description = "科目类别", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  53 + @NotNull(message = "科目类别不能为空")
  54 + private Integer category;
  55 +
  56 + @Schema(description = "余额方向", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  57 + @NotNull(message = "余额方向不能为空")
  58 + @InEnum(FmsDebitCreditDirectionEnum.class)
  59 + private Integer balanceDirection;
  60 +
  61 + @Schema(description = "辅助核算类别编号数组")
  62 + @NotNull(message = "辅助核算类别编号数组不能为空")
  63 + private List<Long> auxiliaryTypeIds;
  64 +
  65 + @Schema(description = "外币核算币别编号数组")
  66 + @NotNull(message = "外币核算币别编号数组不能为空")
  67 + private List<Long> currencyIds;
  68 +
  69 + @Schema(description = "是否启用数量核算", requiredMode = Schema.RequiredMode.REQUIRED)
  70 + @NotNull(message = "是否启用数量核算不能为空")
  71 + private Boolean quantityAccounting;
  72 +
  73 + @Schema(description = "数量单位", example = "件")
  74 + @Size(max = 255, message = "数量单位长度不能超过 255 个字符")
  75 + private String quantityUnit;
  76 +
  77 + @Schema(description = "是否现金及现金等价物", requiredMode = Schema.RequiredMode.REQUIRED)
  78 + @NotNull(message = "是否现金及现金等价物不能为空")
  79 + private Boolean cash;
  80 +
  81 + @Schema(description = "是否迁移上级科目历史数据")
  82 + private Boolean migrateParentData;
  83 +
  84 + @Schema(description = "辅助核算历史数据迁移项目数组")
  85 + private List<AuxiliaryMapping> auxiliaryMappings;
  86 +
  87 + @AssertTrue(message = "科目类别与科目类型不匹配")
  88 + public boolean isCategoryValid() {
  89 + return type == null || category == null || FmsSubjectCategoryEnum.valueOf(type, category) != null;
  90 + }
  91 +
  92 + @AssertTrue(message = "启用数量核算时数量单位不能为空")
  93 + public boolean isQuantityUnitValid() {
  94 + return !Boolean.TRUE.equals(quantityAccounting) || StrUtil.isNotBlank(quantityUnit);
  95 + }
  96 +
  97 + /**
  98 + * 辅助核算历史数据迁移项目
  99 + */
  100 + @Data
  101 + public static class AuxiliaryMapping {
  102 +
  103 + @Schema(description = "辅助核算类别编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  104 + @NotNull(message = "辅助核算类别编号不能为空")
  105 + private Long typeId;
  106 +
  107 + @Schema(description = "辅助核算项目编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  108 + @NotNull(message = "辅助核算项目编号不能为空")
  109 + private Long itemId;
  110 +
  111 + }
  112 +
  113 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/subject/FmsSubjectStatusReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.subject;
  2 +
  3 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  4 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  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 +import java.util.List;
  11 +
  12 +/**
  13 + * FMS 科目状态更新 Request VO
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@Schema(description = "管理后台 - FMS 科目状态更新 Request VO")
  18 +@Data
  19 +public class FmsSubjectStatusReqVO {
  20 +
  21 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  22 + @NotNull(message = "账套编号不能为空")
  23 + private Long accountSetId;
  24 +
  25 + @Schema(description = "科目编号数组", requiredMode = Schema.RequiredMode.REQUIRED)
  26 + @NotEmpty(message = "科目编号数组不能为空")
  27 + private List<Long> ids;
  28 +
  29 + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  30 + @NotNull(message = "状态不能为空")
  31 + @InEnum(CommonStatusEnum.class)
  32 + private Integer status;
  33 +
  34 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/subject/FmsSubjectUsageRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.subject;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +/**
  7 + * FMS 科目使用情况 Response VO
  8 + *
  9 + * @author 芋道源码
  10 + */
  11 +@Schema(description = "管理后台 - FMS 科目使用情况 Response VO")
  12 +@Data
  13 +public class FmsSubjectUsageRespVO {
  14 +
  15 + @Schema(description = "下级科目数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  16 + private Long childCount;
  17 +
  18 + @Schema(description = "凭证分录数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  19 + private Long voucherEntryCount;
  20 +
  21 + @Schema(description = "初始余额数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  22 + private Long initialBalanceCount;
  23 +
  24 + @Schema(description = "辅助核算组合数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "3")
  25 + private Long auxiliaryCombinationCount;
  26 +
  27 + @Schema(description = "包含数量数据的记录数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  28 + private Long quantityDataCount;
  29 +
  30 + @Schema(description = "是否已被业务使用", requiredMode = Schema.RequiredMode.REQUIRED)
  31 + private Boolean used;
  32 +
  33 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/vouchertemplate/FmsVoucherTemplateEntryVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.vouchertemplate;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.Valid;
  5 +import jakarta.validation.constraints.DecimalMin;
  6 +import jakarta.validation.constraints.Digits;
  7 +import jakarta.validation.constraints.NotBlank;
  8 +import jakarta.validation.constraints.NotNull;
  9 +import jakarta.validation.constraints.Size;
  10 +import lombok.Data;
  11 +
  12 +import java.math.BigDecimal;
  13 +import java.util.List;
  14 +
  15 +@Schema(description = "管理后台 - FMS 凭证模板分录 VO")
  16 +@Data
  17 +public class FmsVoucherTemplateEntryVO {
  18 +
  19 + @Schema(description = "摘要内容", requiredMode = Schema.RequiredMode.REQUIRED)
  20 + @NotBlank(message = "摘要不能为空")
  21 + @Size(max = 500, message = "摘要长度不能超过 500 个字符")
  22 + private String digest;
  23 +
  24 + @Schema(description = "科目编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  25 + @NotNull(message = "科目不能为空")
  26 + private Long subjectId;
  27 +
  28 + @Schema(description = "数量")
  29 + @DecimalMin(value = "0", message = "数量不能小于 0")
  30 + @Digits(integer = 14, fraction = 4, message = "数量最多保留 4 位小数")
  31 + private BigDecimal quantity;
  32 +
  33 + @Schema(description = "单价")
  34 + @DecimalMin(value = "0", message = "单价不能小于 0")
  35 + @Digits(integer = 12, fraction = 6, message = "单价最多保留 6 位小数")
  36 + private BigDecimal unitPrice;
  37 +
  38 + @Schema(description = "借方金额")
  39 + @Digits(integer = 16, fraction = 2, message = "借方金额最多保留 2 位小数")
  40 + private BigDecimal debitAmount;
  41 +
  42 + @Schema(description = "贷方金额")
  43 + @Digits(integer = 16, fraction = 2, message = "贷方金额最多保留 2 位小数")
  44 + private BigDecimal creditAmount;
  45 +
  46 + @Schema(description = "辅助核算项目数组")
  47 + @Valid
  48 + private List<AuxiliaryItem> auxiliaries;
  49 +
  50 + @Schema(description = "管理后台 - FMS 凭证模板分录辅助核算项目")
  51 + @Data
  52 + public static class AuxiliaryItem {
  53 +
  54 + @Schema(description = "辅助核算类型")
  55 + private Integer type;
  56 +
  57 + @Schema(description = "辅助核算类别编号", requiredMode = Schema.RequiredMode.REQUIRED)
  58 + @NotNull(message = "辅助核算类别不能为空")
  59 + private Long typeId;
  60 +
  61 + @Schema(description = "辅助核算项目编号", requiredMode = Schema.RequiredMode.REQUIRED)
  62 + @NotNull(message = "辅助核算项目不能为空")
  63 + private Long itemId;
  64 +
  65 + @Schema(description = "辅助核算项目名称")
  66 + private String name;
  67 + }
  68 +
  69 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/vouchertemplate/FmsVoucherTemplateRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.vouchertemplate;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.util.List;
  7 +
  8 +@Schema(description = "管理后台 - FMS 凭证模板 Response VO")
  9 +@Data
  10 +public class FmsVoucherTemplateRespVO {
  11 +
  12 + @Schema(description = "模板编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  13 + private Long id;
  14 +
  15 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  16 + private Long accountSetId;
  17 +
  18 + @Schema(description = "模板名称", requiredMode = Schema.RequiredMode.REQUIRED)
  19 + private String name;
  20 +
  21 + @Schema(description = "分类编号", requiredMode = Schema.RequiredMode.REQUIRED)
  22 + private Long categoryId;
  23 +
  24 + @Schema(description = "分类名称", requiredMode = Schema.RequiredMode.REQUIRED)
  25 + private String categoryName;
  26 +
  27 + @Schema(description = "凭证模板分录数组", requiredMode = Schema.RequiredMode.REQUIRED)
  28 + private List<FmsVoucherTemplateEntryVO> entries;
  29 +
  30 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/vouchertemplate/FmsVoucherTemplateSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.vouchertemplate;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.Valid;
  5 +import jakarta.validation.constraints.NotBlank;
  6 +import jakarta.validation.constraints.NotEmpty;
  7 +import jakarta.validation.constraints.NotNull;
  8 +import jakarta.validation.constraints.Size;
  9 +import lombok.Data;
  10 +
  11 +import java.util.List;
  12 +
  13 +@Schema(description = "管理后台 - FMS 凭证模板保存 Request VO")
  14 +@Data
  15 +public class FmsVoucherTemplateSaveReqVO {
  16 +
  17 + @Schema(description = "模板编号", example = "1024")
  18 + private Long id;
  19 +
  20 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  21 + @NotNull(message = "账套编号不能为空")
  22 + private Long accountSetId;
  23 +
  24 + @Schema(description = "模板名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "办公用品采购")
  25 + @NotBlank(message = "模板名称不能为空")
  26 + @Size(max = 255, message = "模板名称长度不能超过 255 个字符")
  27 + private String name;
  28 +
  29 + @Schema(description = "分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  30 + @NotNull(message = "模板分类不能为空")
  31 + private Long categoryId;
  32 +
  33 + @Schema(description = "凭证模板分录数组", requiredMode = Schema.RequiredMode.REQUIRED)
  34 + @Valid
  35 + @NotEmpty(message = "凭证模板分录不能为空")
  36 + @Size(min = 2, message = "凭证模板至少需要两条分录")
  37 + private List<FmsVoucherTemplateEntryVO> entries;
  38 +
  39 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/vouchertemplatecategory/FmsVoucherTemplateCategoryRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.vouchertemplatecategory;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +@Schema(description = "管理后台 - FMS 凭证模板分类 Response VO")
  7 +@Data
  8 +public class FmsVoucherTemplateCategoryRespVO {
  9 +
  10 + @Schema(description = "分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  11 + private Long id;
  12 +
  13 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  14 + private Long accountSetId;
  15 +
  16 + @Schema(description = "分类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "日常收支")
  17 + private String name;
  18 +
  19 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/vouchertemplatecategory/FmsVoucherTemplateCategorySaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.vouchertemplatecategory;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotBlank;
  5 +import jakarta.validation.constraints.NotNull;
  6 +import jakarta.validation.constraints.Size;
  7 +import lombok.Data;
  8 +
  9 +@Schema(description = "管理后台 - FMS 凭证模板分类保存 Request VO")
  10 +@Data
  11 +public class FmsVoucherTemplateCategorySaveReqVO {
  12 +
  13 + @Schema(description = "分类编号", example = "1024")
  14 + private Long id;
  15 +
  16 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  17 + @NotNull(message = "账套编号不能为空")
  18 + private Long accountSetId;
  19 +
  20 + @Schema(description = "分类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "日常收支")
  21 + @NotBlank(message = "分类名称不能为空")
  22 + @Size(max = 255, message = "分类名称长度不能超过 255 个字符")
  23 + private String name;
  24 +
  25 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/voucherword/FmsVoucherWordRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.voucherword;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.time.LocalDateTime;
  7 +
  8 +/**
  9 + * FMS 凭证字 Response VO
  10 + *
  11 + * @author 芋道源码
  12 + */
  13 +@Schema(description = "管理后台 - FMS 凭证字 Response VO")
  14 +@Data
  15 +public class FmsVoucherWordRespVO {
  16 +
  17 + @Schema(description = "凭证字编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  18 + private Long id;
  19 +
  20 + @Schema(description = "凭证字", requiredMode = Schema.RequiredMode.REQUIRED, example = "记")
  21 + private String name;
  22 +
  23 + @Schema(description = "打印标题", example = "记账凭证")
  24 + private String printTitle;
  25 +
  26 + @Schema(description = "是否默认凭证字", requiredMode = Schema.RequiredMode.REQUIRED)
  27 + private Boolean defaultStatus;
  28 +
  29 + @Schema(description = "显示顺序", requiredMode = Schema.RequiredMode.REQUIRED)
  30 + private Integer sort;
  31 +
  32 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  33 + private Long accountSetId;
  34 +
  35 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  36 + private LocalDateTime createTime;
  37 +
  38 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/config/vo/voucherword/FmsVoucherWordSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.config.vo.voucherword;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotBlank;
  5 +import jakarta.validation.constraints.NotNull;
  6 +import jakarta.validation.constraints.Size;
  7 +import lombok.Data;
  8 +
  9 +/**
  10 + * FMS 凭证字保存 Request VO
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Schema(description = "管理后台 - FMS 凭证字保存 Request VO")
  15 +@Data
  16 +public class FmsVoucherWordSaveReqVO {
  17 +
  18 + @Schema(description = "凭证字编号", example = "1024")
  19 + private Long id;
  20 +
  21 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  22 + @NotNull(message = "账套编号不能为空")
  23 + private Long accountSetId;
  24 +
  25 + @Schema(description = "凭证字", requiredMode = Schema.RequiredMode.REQUIRED, example = "记")
  26 + @NotBlank(message = "凭证字不能为空")
  27 + @Size(max = 255, message = "凭证字长度不能超过 255 个字符")
  28 + private String name;
  29 +
  30 + @Schema(description = "打印标题", example = "记账凭证")
  31 + @Size(max = 255, message = "打印标题长度不能超过 255 个字符")
  32 + private String printTitle;
  33 +
  34 + @Schema(description = "是否默认凭证字", requiredMode = Schema.RequiredMode.REQUIRED)
  35 + @NotNull(message = "是否默认凭证字不能为空")
  36 + private Boolean defaultStatus;
  37 +
  38 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/home/FmsHomeController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.home;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.module.fms.controller.admin.home.vo.FmsHomeMetricDetailRespVO;
  5 +import cn.iocoder.yudao.module.fms.controller.admin.home.vo.FmsHomeRespVO;
  6 +import cn.iocoder.yudao.module.fms.service.home.FmsHomeService;
  7 +import io.swagger.v3.oas.annotations.Operation;
  8 +import io.swagger.v3.oas.annotations.Parameter;
  9 +import io.swagger.v3.oas.annotations.Parameters;
  10 +import io.swagger.v3.oas.annotations.tags.Tag;
  11 +import jakarta.annotation.Resource;
  12 +import jakarta.validation.constraints.NotBlank;
  13 +import jakarta.validation.constraints.NotNull;
  14 +import org.springframework.security.access.prepost.PreAuthorize;
  15 +import org.springframework.validation.annotation.Validated;
  16 +import org.springframework.web.bind.annotation.GetMapping;
  17 +import org.springframework.web.bind.annotation.RequestMapping;
  18 +import org.springframework.web.bind.annotation.RequestParam;
  19 +import org.springframework.web.bind.annotation.RestController;
  20 +
  21 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  22 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  23 +
  24 +@Tag(name = "管理后台 - FMS 首页")
  25 +@RestController
  26 +@RequestMapping("/fms/home")
  27 +@Validated
  28 +public class FmsHomeController {
  29 +
  30 + @Resource
  31 + private FmsHomeService homeService;
  32 +
  33 + @GetMapping("/get")
  34 + @Operation(summary = "获得首页")
  35 + @Parameter(name = "accountSetId", description = "账套编号", required = true, example = "1024")
  36 + @PreAuthorize("@ss.hasPermission('fms:home:query')")
  37 + public CommonResult<FmsHomeRespVO> getHome(@RequestParam("accountSetId") @NotNull Long accountSetId) {
  38 + return success(homeService.getHome(accountSetId, getLoginUserId()));
  39 + }
  40 +
  41 + @GetMapping("/metric-detail")
  42 + @Operation(summary = "获得财务指标明细")
  43 + @Parameters({
  44 + @Parameter(name = "accountSetId", description = "账套编号", required = true, example = "1024"),
  45 + @Parameter(name = "metricKey", description = "财务指标标识", required = true, example = "income")
  46 + })
  47 + @PreAuthorize("@ss.hasPermission('fms:home:query')")
  48 + public CommonResult<FmsHomeMetricDetailRespVO> getMetricDetail(
  49 + @RequestParam("accountSetId") @NotNull Long accountSetId,
  50 + @RequestParam("metricKey") @NotBlank String metricKey) {
  51 + return success(homeService.getMetricDetail(accountSetId, metricKey, getLoginUserId()));
  52 + }
  53 +
  54 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/home/vo/FmsHomeMetricDetailRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.home.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.math.BigDecimal;
  7 +import java.util.List;
  8 +
  9 +@Schema(description = "管理后台 - FMS 首页财务指标明细 Response VO")
  10 +@Data
  11 +public class FmsHomeMetricDetailRespVO {
  12 +
  13 + @Schema(description = "指标标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "income")
  14 + private String key;
  15 +
  16 + @Schema(description = "指标名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "收入")
  17 + private String name;
  18 +
  19 + @Schema(description = "财务指标趋势数组", requiredMode = Schema.RequiredMode.REQUIRED)
  20 + private List<Trend> trends;
  21 +
  22 + @Schema(description = "当期科目构成数组", requiredMode = Schema.RequiredMode.REQUIRED)
  23 + private List<Structure> structure;
  24 +
  25 + @Schema(description = "管理后台 - FMS 首页财务指标趋势 Response VO")
  26 + @Data
  27 + public static class Trend {
  28 +
  29 + @Schema(description = "会计期间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026-08")
  30 + private String month;
  31 +
  32 + @Schema(description = "指标金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "10000.00")
  33 + private BigDecimal amount;
  34 +
  35 + }
  36 +
  37 + @Schema(description = "管理后台 - FMS 首页财务指标科目构成 Response VO")
  38 + @Data
  39 + public static class Structure {
  40 +
  41 + @Schema(description = "科目编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  42 + private Long subjectId;
  43 +
  44 + @Schema(description = "科目编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "5001")
  45 + private String subjectCode;
  46 +
  47 + @Schema(description = "科目名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "主营业务收入")
  48 + private String subjectName;
  49 +
  50 + @Schema(description = "科目金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "8000.00")
  51 + private BigDecimal amount;
  52 +
  53 + }
  54 +
  55 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/home/vo/FmsHomeRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.home.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.math.BigDecimal;
  7 +import java.util.List;
  8 +
  9 +@Schema(description = "管理后台 - FMS 首页 Response VO")
  10 +@Data
  11 +public class FmsHomeRespVO {
  12 +
  13 + @Schema(description = "当前会计期间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026-08")
  14 + private String currentMonth;
  15 +
  16 + @Schema(description = "当期财务指标数组", requiredMode = Schema.RequiredMode.REQUIRED)
  17 + private List<Metric> metrics;
  18 +
  19 + @Schema(description = "财务指标趋势数组", requiredMode = Schema.RequiredMode.REQUIRED)
  20 + private List<Trend> trends;
  21 +
  22 + @Schema(description = "管理后台 - FMS 首页财务指标 Response VO")
  23 + @Data
  24 + public static class Metric {
  25 +
  26 + @Schema(description = "指标标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "income")
  27 + private String key;
  28 +
  29 + @Schema(description = "指标名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "收入")
  30 + private String name;
  31 +
  32 + @Schema(description = "指标金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "10000.00")
  33 + private BigDecimal amount;
  34 +
  35 + }
  36 +
  37 + @Schema(description = "管理后台 - FMS 首页财务指标趋势 Response VO")
  38 + @Data
  39 + public static class Trend {
  40 +
  41 + @Schema(description = "会计期间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026-08")
  42 + private String month;
  43 +
  44 + @Schema(description = "动态财务指标数组", requiredMode = Schema.RequiredMode.REQUIRED)
  45 + private List<Metric> metrics;
  46 +
  47 + @Schema(description = "收入", requiredMode = Schema.RequiredMode.REQUIRED)
  48 + private BigDecimal income;
  49 +
  50 + @Schema(description = "成本", requiredMode = Schema.RequiredMode.REQUIRED)
  51 + private BigDecimal operatingCost;
  52 +
  53 + @Schema(description = "利润", requiredMode = Schema.RequiredMode.REQUIRED)
  54 + private BigDecimal profit;
  55 +
  56 + @Schema(description = "费用", requiredMode = Schema.RequiredMode.REQUIRED)
  57 + private BigDecimal expense;
  58 +
  59 + @Schema(description = "其他", requiredMode = Schema.RequiredMode.REQUIRED)
  60 + private BigDecimal other;
  61 +
  62 + }
  63 +
  64 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/ledger/FmsLedgerController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.ledger;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
  5 +import cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum;
  6 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  7 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  8 +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  9 +import cn.iocoder.yudao.module.fms.controller.admin.config.vo.subject.FmsSubjectRespVO;
  10 +import cn.iocoder.yudao.module.fms.controller.admin.ledger.vo.FmsLedgerAuxiliaryListReqVO;
  11 +import cn.iocoder.yudao.module.fms.controller.admin.ledger.vo.FmsLedgerListReqVO;
  12 +import cn.iocoder.yudao.module.fms.controller.admin.ledger.vo.auxiliarybalance.FmsLedgerAuxiliaryBalanceRespVO;
  13 +import cn.iocoder.yudao.module.fms.controller.admin.ledger.vo.auxiliarydetail.FmsLedgerAuxiliaryDetailRespVO;
  14 +import cn.iocoder.yudao.module.fms.controller.admin.ledger.vo.detail.FmsLedgerDetailExportRespVO;
  15 +import cn.iocoder.yudao.module.fms.controller.admin.ledger.vo.detail.FmsLedgerDetailRespVO;
  16 +import cn.iocoder.yudao.module.fms.controller.admin.ledger.vo.general.FmsLedgerGeneralRespVO;
  17 +import cn.iocoder.yudao.module.fms.controller.admin.ledger.vo.multicolumn.FmsLedgerMultiColumnRespVO;
  18 +import cn.iocoder.yudao.module.fms.controller.admin.ledger.vo.quantitydetail.FmsLedgerQuantityDetailRespVO;
  19 +import cn.iocoder.yudao.module.fms.controller.admin.ledger.vo.quantitygeneral.FmsLedgerQuantityGeneralRespVO;
  20 +import cn.iocoder.yudao.module.fms.controller.admin.ledger.vo.subjectbalance.FmsLedgerSubjectBalanceRespVO;
  21 +import cn.iocoder.yudao.module.fms.service.ledger.FmsLedgerService;
  22 +import io.swagger.v3.oas.annotations.Operation;
  23 +import io.swagger.v3.oas.annotations.tags.Tag;
  24 +import jakarta.annotation.Resource;
  25 +import jakarta.servlet.http.HttpServletResponse;
  26 +import jakarta.validation.Valid;
  27 +import org.springframework.security.access.prepost.PreAuthorize;
  28 +import org.springframework.validation.annotation.Validated;
  29 +import org.springframework.web.bind.annotation.GetMapping;
  30 +import org.springframework.web.bind.annotation.RequestMapping;
  31 +import org.springframework.web.bind.annotation.RestController;
  32 +
  33 +import java.io.IOException;
  34 +import java.util.ArrayList;
  35 +import java.util.List;
  36 +
  37 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  38 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  39 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  40 +
  41 +@Tag(name = "管理后台 - FMS 账簿")
  42 +@RestController
  43 +@RequestMapping("/fms/ledger")
  44 +@Validated
  45 +public class FmsLedgerController {
  46 +
  47 + @Resource
  48 + private FmsLedgerService ledgerService;
  49 +
  50 + // ==================== 明细账 ====================
  51 +
  52 + @GetMapping("/detail/list")
  53 + @Operation(summary = "获得明细账")
  54 + @PreAuthorize("@ss.hasPermission('fms:ledger:detail:query')")
  55 + public CommonResult<List<FmsLedgerDetailRespVO>> getDetailList(@Valid FmsLedgerListReqVO listReqVO) {
  56 + return success(ledgerService.getDetailList(listReqVO, getLoginUserId()));
  57 + }
  58 +
  59 + @GetMapping("/detail/subject-list")
  60 + @Operation(summary = "获得指定期间有发生额的明细账科目")
  61 + public CommonResult<List<FmsSubjectRespVO>> getDetailSubjectList(@Valid FmsLedgerListReqVO listReqVO) {
  62 + // TODO @AI:先查询出来,list 变量;然后在去 convert;字段不多,倒是可以考虑 beanutils 去 copy 下?
  63 + return success(convertList(ledgerService.getDetailSubjectList(listReqVO, getLoginUserId()), subject ->
  64 + new FmsSubjectRespVO().setId(subject.getId()).setParentId(subject.getParentId())
  65 + .setCode(subject.getCode()).setName(subject.getName()).setType(subject.getType())
  66 + .setBalanceDirection(subject.getBalanceDirection()).setStatus(subject.getStatus())
  67 + .setLevel(subject.getLevel()).setAuxiliaryTypeIds(subject.getAuxiliaryTypeIds())
  68 + .setQuantityAccounting(subject.getQuantityAccounting()).setQuantityUnit(subject.getQuantityUnit())));
  69 + }
  70 +
  71 + @GetMapping("/detail/export-excel")
  72 + @Operation(summary = "导出明细账")
  73 + @PreAuthorize("@ss.hasPermission('fms:ledger:detail:export')")
  74 + @ApiAccessLog(operateType = OperateTypeEnum.EXPORT)
  75 + public void exportDetail(@Valid FmsLedgerListReqVO listReqVO, HttpServletResponse response) throws IOException {
  76 + List<FmsLedgerDetailExportRespVO> rows = convertList(
  77 + ledgerService.getDetailList(listReqVO, getLoginUserId()), item ->
  78 + BeanUtils.toBean(item, FmsLedgerDetailExportRespVO.class)
  79 + .setSubject(item.getSubjectCode() + " " + item.getSubjectName()));
  80 + ExcelUtils.write(response, "明细账.xls", "明细账", FmsLedgerDetailExportRespVO.class, rows);
  81 + }
  82 +
  83 + // ==================== 总账 ====================
  84 +
  85 + @GetMapping("/general/list")
  86 + @Operation(summary = "获得总账")
  87 + @PreAuthorize("@ss.hasPermission('fms:ledger:general:query')")
  88 + public CommonResult<List<FmsLedgerGeneralRespVO>> getGeneralList(@Valid FmsLedgerListReqVO listReqVO) {
  89 + return success(ledgerService.getGeneralList(listReqVO, getLoginUserId()));
  90 + }
  91 +
  92 + @GetMapping("/general/export-excel")
  93 + @Operation(summary = "导出总账")
  94 + @PreAuthorize("@ss.hasPermission('fms:ledger:general:export')")
  95 + @ApiAccessLog(operateType = OperateTypeEnum.EXPORT)
  96 + public void exportGeneral(@Valid FmsLedgerListReqVO listReqVO, HttpServletResponse response) throws IOException {
  97 + ExcelUtils.write(response, "总账.xls", "总账", FmsLedgerGeneralRespVO.class,
  98 + ledgerService.getGeneralList(listReqVO, getLoginUserId()));
  99 + }
  100 +
  101 + // ==================== 科目余额表 ====================
  102 +
  103 + @GetMapping("/subject-balance/list")
  104 + @Operation(summary = "获得科目余额表")
  105 + @PreAuthorize("@ss.hasPermission('fms:ledger:subject-balance:query')")
  106 + public CommonResult<List<FmsLedgerSubjectBalanceRespVO>> getSubjectBalanceList(@Valid FmsLedgerListReqVO listReqVO) {
  107 + return success(ledgerService.getSubjectBalanceList(listReqVO, getLoginUserId()));
  108 + }
  109 +
  110 + @GetMapping("/subject-balance/export-excel")
  111 + @Operation(summary = "导出科目余额表")
  112 + @PreAuthorize("@ss.hasPermission('fms:ledger:subject-balance:export')")
  113 + @ApiAccessLog(operateType = OperateTypeEnum.EXPORT)
  114 + public void exportSubjectBalance(@Valid FmsLedgerListReqVO listReqVO, HttpServletResponse response) throws IOException {
  115 + ExcelUtils.write(response, "科目余额表.xls", "科目余额表", FmsLedgerSubjectBalanceRespVO.class,
  116 + flattenSubjectBalanceList(ledgerService.getSubjectBalanceList(listReqVO, getLoginUserId())));
  117 + }
  118 +
  119 + // ==================== 多栏账 ====================
  120 +
  121 + @GetMapping("/multi-column/list")
  122 + @Operation(summary = "获得多栏账")
  123 + @PreAuthorize("@ss.hasPermission('fms:ledger:multi-column:query')")
  124 + public CommonResult<FmsLedgerMultiColumnRespVO> getMultiColumn(@Valid FmsLedgerListReqVO listReqVO) {
  125 + return success(ledgerService.getMultiColumn(listReqVO, getLoginUserId()));
  126 + }
  127 +
  128 + @GetMapping("/multi-column/export-excel")
  129 + @Operation(summary = "导出多栏账")
  130 + @PreAuthorize("@ss.hasPermission('fms:ledger:multi-column:export')")
  131 + @ApiAccessLog(operateType = OperateTypeEnum.EXPORT)
  132 + public void exportMultiColumn(@Valid FmsLedgerListReqVO listReqVO, HttpServletResponse response) throws IOException {
  133 + FmsLedgerMultiColumnRespVO result = ledgerService.getMultiColumn(listReqVO, getLoginUserId());
  134 + ExcelUtils.write(response, "多栏账.xls", "多栏账",
  135 + FmsLedgerMultiColumnExcelHelper.buildHead(result),
  136 + FmsLedgerMultiColumnExcelHelper.buildData(result));
  137 + }
  138 +
  139 + // ==================== 核算项目明细账 ====================
  140 +
  141 + @GetMapping("/auxiliary-detail/list")
  142 + @Operation(summary = "获得核算项目明细账")
  143 + @PreAuthorize("@ss.hasPermission('fms:ledger:detail:query')")
  144 + public CommonResult<List<FmsLedgerAuxiliaryDetailRespVO>> getAuxiliaryDetailList(@Valid FmsLedgerAuxiliaryListReqVO listReqVO) {
  145 + return success(ledgerService.getAuxiliaryDetailList(listReqVO, getLoginUserId()));
  146 + }
  147 +
  148 + @GetMapping("/auxiliary-detail/export-excel")
  149 + @Operation(summary = "导出核算项目明细账")
  150 + @PreAuthorize("@ss.hasPermission('fms:ledger:detail:export')")
  151 + @ApiAccessLog(operateType = OperateTypeEnum.EXPORT)
  152 + public void exportAuxiliaryDetail(@Valid FmsLedgerAuxiliaryListReqVO listReqVO, HttpServletResponse response) throws IOException {
  153 + ExcelUtils.write(response, "核算项目明细账.xls", "核算项目明细账",
  154 + FmsLedgerAuxiliaryDetailRespVO.class,
  155 + ledgerService.getAuxiliaryDetailList(listReqVO, getLoginUserId()));
  156 + }
  157 +
  158 + // ==================== 核算项目余额表 ====================
  159 +
  160 + @GetMapping("/auxiliary-balance/list")
  161 + @Operation(summary = "获得核算项目余额表")
  162 + @PreAuthorize("@ss.hasPermission('fms:ledger:subject-balance:query')")
  163 + public CommonResult<List<FmsLedgerAuxiliaryBalanceRespVO>> getAuxiliaryBalanceList(@Valid FmsLedgerAuxiliaryListReqVO listReqVO) {
  164 + return success(ledgerService.getAuxiliaryBalanceList(listReqVO, getLoginUserId()));
  165 + }
  166 +
  167 + @GetMapping("/auxiliary-balance/export-excel")
  168 + @Operation(summary = "导出核算项目余额表")
  169 + @PreAuthorize("@ss.hasPermission('fms:ledger:subject-balance:export')")
  170 + @ApiAccessLog(operateType = OperateTypeEnum.EXPORT)
  171 + public void exportAuxiliaryBalance(@Valid FmsLedgerAuxiliaryListReqVO listReqVO, HttpServletResponse response) throws IOException {
  172 + ExcelUtils.write(response, "核算项目余额表.xls", "核算项目余额表",
  173 + FmsLedgerAuxiliaryBalanceRespVO.class,
  174 + ledgerService.getAuxiliaryBalanceList(listReqVO, getLoginUserId()));
  175 + }
  176 +
  177 + // ==================== 数量金额明细账 ====================
  178 +
  179 + @GetMapping("/quantity-detail/list")
  180 + @Operation(summary = "获得数量金额明细账")
  181 + @PreAuthorize("@ss.hasPermission('fms:ledger:detail:query')")
  182 + public CommonResult<List<FmsLedgerQuantityDetailRespVO>> getQuantityDetailList(@Valid FmsLedgerListReqVO listReqVO) {
  183 + return success(ledgerService.getQuantityDetailList(listReqVO, getLoginUserId()));
  184 + }
  185 +
  186 + @GetMapping("/quantity-detail/export-excel")
  187 + @Operation(summary = "导出数量金额明细账")
  188 + @PreAuthorize("@ss.hasPermission('fms:ledger:detail:export')")
  189 + @ApiAccessLog(operateType = OperateTypeEnum.EXPORT)
  190 + public void exportQuantityDetail(@Valid FmsLedgerListReqVO listReqVO, HttpServletResponse response) throws IOException {
  191 + ExcelUtils.write(response, "数量金额明细账.xls", "数量金额明细账",
  192 + FmsLedgerQuantityDetailRespVO.class,
  193 + ledgerService.getQuantityDetailList(listReqVO, getLoginUserId()));
  194 + }
  195 +
  196 + // ==================== 数量金额总账 ====================
  197 +
  198 + @GetMapping("/quantity-general/list")
  199 + @Operation(summary = "获得数量金额总账")
  200 + @PreAuthorize("@ss.hasPermission('fms:ledger:general:query')")
  201 + public CommonResult<List<FmsLedgerQuantityGeneralRespVO>> getQuantityGeneralList(@Valid FmsLedgerListReqVO listReqVO) {
  202 + return success(ledgerService.getQuantityGeneralList(listReqVO, getLoginUserId()));
  203 + }
  204 +
  205 + @GetMapping("/quantity-general/export-excel")
  206 + @Operation(summary = "导出数量金额总账")
  207 + @PreAuthorize("@ss.hasPermission('fms:ledger:general:export')")
  208 + @ApiAccessLog(operateType = OperateTypeEnum.EXPORT)
  209 + public void exportQuantityGeneral(@Valid FmsLedgerListReqVO listReqVO, HttpServletResponse response) throws IOException {
  210 + ExcelUtils.write(response, "数量金额总账.xls", "数量金额总账",
  211 + FmsLedgerQuantityGeneralRespVO.class,
  212 + flattenQuantityGeneralList(ledgerService.getQuantityGeneralList(
  213 + listReqVO, getLoginUserId())));
  214 + }
  215 +
  216 + private static List<FmsLedgerSubjectBalanceRespVO> flattenSubjectBalanceList(List<FmsLedgerSubjectBalanceRespVO> list) {
  217 + List<FmsLedgerSubjectBalanceRespVO> result = new ArrayList<>();
  218 + list.forEach(item -> {
  219 + result.add(item);
  220 + result.addAll(flattenSubjectBalanceList(item.getChildren()));
  221 + });
  222 + return result;
  223 + }
  224 +
  225 + private static List<FmsLedgerQuantityGeneralRespVO> flattenQuantityGeneralList(List<FmsLedgerQuantityGeneralRespVO> list) {
  226 + List<FmsLedgerQuantityGeneralRespVO> result = new ArrayList<>();
  227 + list.forEach(item -> {
  228 + if (Boolean.TRUE.equals(item.getQuantityAccounting()) || CollUtil.isNotEmpty(item.getChildren())) {
  229 + result.add(item);
  230 + }
  231 + result.addAll(flattenQuantityGeneralList(item.getChildren()));
  232 + });
  233 + return result;
  234 + }
  235 +
  236 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/ledger/FmsLedgerMultiColumnExcelHelper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.ledger;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.module.fms.controller.admin.ledger.vo.detail.FmsLedgerDetailRespVO;
  5 +import cn.iocoder.yudao.module.fms.controller.admin.ledger.vo.multicolumn.FmsLedgerMultiColumnRespVO;
  6 +import cn.iocoder.yudao.module.fms.enums.common.FmsDebitCreditDirectionEnum;
  7 +
  8 +import java.util.ArrayList;
  9 +import java.util.Arrays;
  10 +import java.util.List;
  11 +
  12 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList;
  13 +
  14 +/**
  15 + * FMS 多栏账 Excel 构建工具
  16 + *
  17 + * @author 芋道源码
  18 + */
  19 +public class FmsLedgerMultiColumnExcelHelper {
  20 +
  21 + private FmsLedgerMultiColumnExcelHelper() {
  22 + }
  23 +
  24 + /**
  25 + * 构建多栏账动态表头
  26 + *
  27 + * @param result 多栏账结果
  28 + * @return 动态表头
  29 + */
  30 + public static List<List<String>> buildHead(FmsLedgerMultiColumnRespVO result) {
  31 + List<List<String>> head = new ArrayList<>();
  32 + head.add(Arrays.asList("日期", "日期"));
  33 + head.add(Arrays.asList("凭证字号", "凭证字号"));
  34 + head.add(Arrays.asList("摘要", "摘要"));
  35 + head.add(Arrays.asList("发生额", "借方"));
  36 + head.add(Arrays.asList("发生额", "贷方"));
  37 + head.add(Arrays.asList("余额", "方向"));
  38 + head.add(Arrays.asList("余额", "金额"));
  39 + for (FmsLedgerMultiColumnRespVO.Column column : getColumns(result,
  40 + FmsDebitCreditDirectionEnum.DEBIT.getType())) {
  41 + head.add(Arrays.asList(FmsDebitCreditDirectionEnum.DEBIT.getName(),
  42 + column.getSubjectCode() + "/" + column.getSubjectName()));
  43 + }
  44 + for (FmsLedgerMultiColumnRespVO.Column column : getColumns(result,
  45 + FmsDebitCreditDirectionEnum.CREDIT.getType())) {
  46 + head.add(Arrays.asList(FmsDebitCreditDirectionEnum.CREDIT.getName(),
  47 + column.getSubjectCode() + "/" + column.getSubjectName()));
  48 + }
  49 + return head;
  50 + }
  51 +
  52 + /**
  53 + * 构建多栏账动态数据
  54 + *
  55 + * @param result 多栏账结果
  56 + * @return 动态数据
  57 + */
  58 + public static List<List<Object>> buildData(FmsLedgerMultiColumnRespVO result) {
  59 + List<FmsLedgerMultiColumnRespVO.Column> debitColumns = getColumns(
  60 + result, FmsDebitCreditDirectionEnum.DEBIT.getType());
  61 + List<FmsLedgerMultiColumnRespVO.Column> creditColumns = getColumns(
  62 + result, FmsDebitCreditDirectionEnum.CREDIT.getType());
  63 + List<List<Object>> data = new ArrayList<>();
  64 + for (FmsLedgerDetailRespVO row : CollUtil.emptyIfNull(result.getRows())) {
  65 + List<Object> values = new ArrayList<>(Arrays.asList(row.getAccountDate(), row.getVoucherNumber(),
  66 + row.getDigest(), row.getDebitAmount(), row.getCreditAmount(),
  67 + row.getBalanceDirection(), row.getBalance()));
  68 + debitColumns.forEach(column -> values.add(row.getColumnAmounts().get(column.getSubjectId())));
  69 + creditColumns.forEach(column -> values.add(row.getColumnAmounts().get(column.getSubjectId())));
  70 + data.add(values);
  71 + }
  72 + return data;
  73 + }
  74 +
  75 + private static List<FmsLedgerMultiColumnRespVO.Column> getColumns(
  76 + FmsLedgerMultiColumnRespVO result, Integer balanceDirection) {
  77 + return filterList(CollUtil.emptyIfNull(result.getColumns()),
  78 + column -> balanceDirection.equals(column.getBalanceDirection()));
  79 + }
  80 +
  81 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/ledger/vo/FmsLedgerAuxiliaryListReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.ledger.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotNull;
  5 +import jakarta.validation.constraints.Pattern;
  6 +import lombok.Data;
  7 +
  8 +@Schema(description = "管理后台 - FMS 核算项目账簿列表查询 Request VO")
  9 +@Data
  10 +public class FmsLedgerAuxiliaryListReqVO {
  11 +
  12 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  13 + @NotNull(message = "账套编号不能为空")
  14 + private Long accountSetId;
  15 +
  16 + @Schema(description = "开始会计期间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026-08")
  17 + @NotNull(message = "开始会计期间不能为空")
  18 + @Pattern(regexp = "\\d{4}-(0[1-9]|1[0-2])", message = "开始会计期间格式不正确")
  19 + private String startMonth;
  20 +
  21 + @Schema(description = "结束会计期间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026-12")
  22 + @NotNull(message = "结束会计期间不能为空")
  23 + @Pattern(regexp = "\\d{4}-(0[1-9]|1[0-2])", message = "结束会计期间格式不正确")
  24 + private String endMonth;
  25 +
  26 + @Schema(description = "辅助核算类别编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  27 + @NotNull(message = "辅助核算类别编号不能为空")
  28 + private Long auxiliaryTypeId;
  29 +
  30 + @Schema(description = "科目编号", example = "1024")
  31 + private Long subjectId;
  32 +
  33 + @Schema(description = "辅助核算项目编号", example = "1024")
  34 + private Long auxiliaryItemId;
  35 +
  36 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/ledger/vo/FmsLedgerEntryVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.ledger.vo;
  2 +
  3 +import cn.iocoder.yudao.module.fms.dal.dataobject.voucher.FmsVoucherEntryDO;
  4 +import lombok.Data;
  5 +
  6 +import java.math.BigDecimal;
  7 +import java.time.LocalDateTime;
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * FMS 账簿凭证分录 VO
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@Data
  16 +public class FmsLedgerEntryVO {
  17 +
  18 + /**
  19 + * 分录编号
  20 + */
  21 + private Long entryId;
  22 + /**
  23 + * 凭证编号
  24 + */
  25 + private Long voucherId;
  26 + /**
  27 + * 科目编号
  28 + */
  29 + private Long subjectId;
  30 + /**
  31 + * 凭证日期
  32 + */
  33 + private LocalDateTime voucherTime;
  34 + /**
  35 + * 凭证号
  36 + */
  37 + private Integer voucherNumber;
  38 + /**
  39 + * 凭证字名称
  40 + */
  41 + private String voucherWordName;
  42 + /**
  43 + * 摘要内容
  44 + */
  45 + private String digest;
  46 + /**
  47 + * 借方金额
  48 + */
  49 + private BigDecimal debitAmount;
  50 + /**
  51 + * 贷方金额
  52 + */
  53 + private BigDecimal creditAmount;
  54 + /**
  55 + * 数量
  56 + */
  57 + private BigDecimal quantity;
  58 + /**
  59 + * 单价
  60 + */
  61 + private BigDecimal unitPrice;
  62 + /**
  63 + * 显示顺序
  64 + */
  65 + private Integer sort;
  66 + /**
  67 + * 辅助核算组合编号
  68 + */
  69 + private Long assistCombinationId;
  70 + /**
  71 + * 辅助核算项目数组
  72 + */
  73 + private List<FmsVoucherEntryDO.AuxiliaryItem> auxiliaries;
  74 +
  75 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/ledger/vo/FmsLedgerListReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.ledger.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.Max;
  5 +import jakarta.validation.constraints.Min;
  6 +import jakarta.validation.constraints.NotNull;
  7 +import jakarta.validation.constraints.Pattern;
  8 +import lombok.Data;
  9 +
  10 +@Schema(description = "管理后台 - FMS 账簿列表查询 Request VO")
  11 +@Data
  12 +public class FmsLedgerListReqVO {
  13 +
  14 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  15 + @NotNull(message = "账套编号不能为空")
  16 + private Long accountSetId;
  17 +
  18 + @Schema(description = "开始会计期间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026-08")
  19 + @NotNull(message = "开始会计期间不能为空")
  20 + @Pattern(regexp = "\\d{4}-(0[1-9]|1[0-2])", message = "开始会计期间格式不正确")
  21 + private String startMonth;
  22 +
  23 + @Schema(description = "结束会计期间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026-12")
  24 + @NotNull(message = "结束会计期间不能为空")
  25 + @Pattern(regexp = "\\d{4}-(0[1-9]|1[0-2])", message = "结束会计期间格式不正确")
  26 + private String endMonth;
  27 +
  28 + @Schema(description = "科目编号", example = "1024")
  29 + private Long subjectId;
  30 +
  31 + @Schema(description = "起始科目编号", example = "1024")
  32 + private Long startSubjectId;
  33 +
  34 + @Schema(description = "结束科目编号", example = "2048")
  35 + private Long endSubjectId;
  36 +
  37 + @Schema(description = "最小科目级次", example = "1")
  38 + @Min(value = 1, message = "最小科目级次不能小于 1")
  39 + @Max(value = 10, message = "最小科目级次不能大于 10")
  40 + private Integer minLevel;
  41 +
  42 + @Schema(description = "最大科目级次", example = "4")
  43 + @Min(value = 1, message = "最大科目级次不能小于 1")
  44 + @Max(value = 10, message = "最大科目级次不能大于 10")
  45 + private Integer maxLevel;
  46 +
  47 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/ledger/vo/auxiliarybalance/FmsLedgerAuxiliaryBalanceRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.ledger.vo.auxiliarybalance;
  2 +
  3 +import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
  4 +import cn.idev.excel.annotation.ExcelProperty;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import lombok.Data;
  7 +import lombok.experimental.Accessors;
  8 +
  9 +import java.math.BigDecimal;
  10 +
  11 +@Schema(description = "管理后台 - FMS 核算项目余额 Response VO")
  12 +@Data
  13 +@ExcelIgnoreUnannotated
  14 +public class FmsLedgerAuxiliaryBalanceRespVO {
  15 +
  16 + @Schema(description = "辅助核算项目编号", requiredMode = Schema.RequiredMode.REQUIRED)
  17 + private Long auxiliaryItemId;
  18 +
  19 + @Schema(description = "编码", requiredMode = Schema.RequiredMode.REQUIRED)
  20 + @ExcelProperty("编码")
  21 + private String code;
  22 +
  23 + @Schema(description = "项目名称", requiredMode = Schema.RequiredMode.REQUIRED)
  24 + @ExcelProperty("项目名称")
  25 + private String name;
  26 +
  27 + @Schema(description = "期初借方余额", requiredMode = Schema.RequiredMode.REQUIRED)
  28 + @ExcelProperty("期初借方")
  29 + private BigDecimal openingDebitAmount;
  30 +
  31 + @Schema(description = "期初贷方余额", requiredMode = Schema.RequiredMode.REQUIRED)
  32 + @ExcelProperty("期初贷方")
  33 + private BigDecimal openingCreditAmount;
  34 +
  35 + @Schema(description = "本期借方发生额", requiredMode = Schema.RequiredMode.REQUIRED)
  36 + @ExcelProperty("本期借方")
  37 + private BigDecimal periodDebitAmount;
  38 +
  39 + @Schema(description = "本期贷方发生额", requiredMode = Schema.RequiredMode.REQUIRED)
  40 + @ExcelProperty("本期贷方")
  41 + private BigDecimal periodCreditAmount;
  42 +
  43 + @Schema(description = "本年累计借方发生额", requiredMode = Schema.RequiredMode.REQUIRED)
  44 + @ExcelProperty("本年累计借方")
  45 + private BigDecimal yearDebitAmount;
  46 +
  47 + @Schema(description = "本年累计贷方发生额", requiredMode = Schema.RequiredMode.REQUIRED)
  48 + @ExcelProperty("本年累计贷方")
  49 + private BigDecimal yearCreditAmount;
  50 +
  51 + @Schema(description = "期末借方余额", requiredMode = Schema.RequiredMode.REQUIRED)
  52 + @ExcelProperty("期末借方")
  53 + private BigDecimal endingDebitAmount;
  54 +
  55 + @Schema(description = "期末贷方余额", requiredMode = Schema.RequiredMode.REQUIRED)
  56 + @ExcelProperty("期末贷方")
  57 + private BigDecimal endingCreditAmount;
  58 +
  59 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/ledger/vo/auxiliarydetail/FmsLedgerAuxiliaryDetailRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.ledger.vo.auxiliarydetail;
  2 +
  3 +import com.fasterxml.jackson.annotation.JsonFormat;
  4 +import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
  5 +import cn.idev.excel.annotation.ExcelProperty;
  6 +import io.swagger.v3.oas.annotations.media.Schema;
  7 +import lombok.Data;
  8 +
  9 +import java.math.BigDecimal;
  10 +import java.time.LocalDate;
  11 +
  12 +@Schema(description = "管理后台 - FMS 核算项目明细账 Response VO")
  13 +@Data
  14 +@ExcelIgnoreUnannotated
  15 +public class FmsLedgerAuxiliaryDetailRespVO {
  16 +
  17 + public static final Integer ROW_TYPE_OPENING = 1;
  18 + public static final Integer ROW_TYPE_VOUCHER = 2;
  19 + public static final Integer ROW_TYPE_PERIOD_TOTAL = 3;
  20 + public static final Integer ROW_TYPE_YEAR_TOTAL = 4;
  21 +
  22 + @Schema(description = "行类型", example = "2")
  23 + private Integer rowType;
  24 +
  25 + @Schema(description = "分录编号", example = "1024")
  26 + private Long entryId;
  27 +
  28 + @Schema(description = "科目编号", example = "1024")
  29 + private Long subjectId;
  30 +
  31 + @Schema(description = "科目编码", example = "1001")
  32 + private String subjectCode;
  33 +
  34 + @Schema(description = "科目名称", example = "库存现金")
  35 + private String subjectName;
  36 +
  37 + @Schema(description = "会计期间", example = "2026-08")
  38 + private String period;
  39 +
  40 + @Schema(description = "日期")
  41 + @JsonFormat(pattern = "yyyy-MM-dd")
  42 + @ExcelProperty("日期")
  43 + private LocalDate accountDate;
  44 +
  45 + @Schema(description = "凭证编号", example = "1024")
  46 + private Long voucherId;
  47 +
  48 + @Schema(description = "凭证字号", example = "记-1")
  49 + @ExcelProperty("凭证字号")
  50 + private String voucherNumber;
  51 +
  52 + @Schema(description = "摘要", example = "报销办公用品")
  53 + @ExcelProperty("摘要")
  54 + private String digest;
  55 +
  56 + @Schema(description = "借方金额")
  57 + @ExcelProperty("借方")
  58 + private BigDecimal debitAmount;
  59 +
  60 + @Schema(description = "贷方金额")
  61 + @ExcelProperty("贷方")
  62 + private BigDecimal creditAmount;
  63 +
  64 + @Schema(description = "余额方向", example = "借")
  65 + @ExcelProperty("方向")
  66 + private String balanceDirection;
  67 +
  68 + @Schema(description = "余额")
  69 + @ExcelProperty("余额")
  70 + private BigDecimal balance;
  71 +
  72 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/ledger/vo/detail/FmsLedgerDetailExportRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.ledger.vo.detail;
  2 +
  3 +import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
  4 +import cn.idev.excel.annotation.ExcelProperty;
  5 +import lombok.Data;
  6 +
  7 +import java.math.BigDecimal;
  8 +import java.time.LocalDate;
  9 +
  10 +/**
  11 + * FMS 明细账导出 Response VO
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@Data
  16 +@ExcelIgnoreUnannotated
  17 +public class FmsLedgerDetailExportRespVO {
  18 +
  19 + @ExcelProperty("科目")
  20 + private String subject;
  21 +
  22 + @ExcelProperty("日期")
  23 + private LocalDate accountDate;
  24 +
  25 + @ExcelProperty("凭证字号")
  26 + private String voucherNumber;
  27 +
  28 + @ExcelProperty("摘要")
  29 + private String digest;
  30 +
  31 + @ExcelProperty("借方")
  32 + private BigDecimal debitAmount;
  33 +
  34 + @ExcelProperty("贷方")
  35 + private BigDecimal creditAmount;
  36 +
  37 + @ExcelProperty("方向")
  38 + private String balanceDirection;
  39 +
  40 + @ExcelProperty("余额")
  41 + private BigDecimal balance;
  42 +
  43 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/ledger/vo/detail/FmsLedgerDetailRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.ledger.vo.detail;
  2 +
  3 +import com.fasterxml.jackson.annotation.JsonFormat;
  4 +import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
  5 +import cn.idev.excel.annotation.ExcelProperty;
  6 +import io.swagger.v3.oas.annotations.media.Schema;
  7 +import lombok.Data;
  8 +
  9 +import java.math.BigDecimal;
  10 +import java.time.LocalDate;
  11 +
  12 +@Schema(description = "管理后台 - FMS 账簿明细 Response VO")
  13 +@Data
  14 +@ExcelIgnoreUnannotated
  15 +public class FmsLedgerDetailRespVO {
  16 +
  17 + public static final Integer ROW_TYPE_OPENING = 1;
  18 + public static final Integer ROW_TYPE_VOUCHER = 2;
  19 + public static final Integer ROW_TYPE_PERIOD_TOTAL = 3;
  20 + public static final Integer ROW_TYPE_YEAR_TOTAL = 4;
  21 + public static final Integer ROW_TYPE_ENDING = 5;
  22 +
  23 + @Schema(description = "行类型", example = "2")
  24 + private Integer rowType;
  25 +
  26 + @Schema(description = "分录编号", example = "1024")
  27 + private Long entryId;
  28 +
  29 + @Schema(description = "分录科目编号", example = "1024")
  30 + private Long entrySubjectId;
  31 +
  32 + @Schema(description = "科目编号", example = "1024")
  33 + private Long subjectId;
  34 +
  35 + @Schema(description = "科目编码", example = "1001")
  36 + private String subjectCode;
  37 +
  38 + @Schema(description = "科目名称", example = "库存现金")
  39 + private String subjectName;
  40 +
  41 + @Schema(description = "会计期间", example = "2026-08")
  42 + private String period;
  43 +
  44 + @Schema(description = "日期")
  45 + @JsonFormat(pattern = "yyyy-MM-dd")
  46 + @ExcelProperty("日期")
  47 + private LocalDate accountDate;
  48 +
  49 + @Schema(description = "凭证编号", example = "1024")
  50 + private Long voucherId;
  51 +
  52 + @Schema(description = "凭证字号", example = "记-1")
  53 + @ExcelProperty("凭证字号")
  54 + private String voucherNumber;
  55 +
  56 + @Schema(description = "摘要", example = "报销办公用品")
  57 + @ExcelProperty("摘要")
  58 + private String digest;
  59 +
  60 + @Schema(description = "借方金额")
  61 + @ExcelProperty("借方")
  62 + private BigDecimal debitAmount;
  63 +
  64 + @Schema(description = "贷方金额")
  65 + @ExcelProperty("贷方")
  66 + private BigDecimal creditAmount;
  67 +
  68 + @Schema(description = "余额方向", example = "借")
  69 + @ExcelProperty("方向")
  70 + private String balanceDirection;
  71 +
  72 + @Schema(description = "余额")
  73 + @ExcelProperty("余额")
  74 + private BigDecimal balance;
  75 +
  76 + @Schema(description = "借方数量")
  77 + private BigDecimal debitQuantity;
  78 +
  79 + @Schema(description = "贷方数量")
  80 + private BigDecimal creditQuantity;
  81 +
  82 + @Schema(description = "结存数量")
  83 + private BigDecimal balanceQuantity;
  84 +
  85 + @Schema(description = "单价")
  86 + private BigDecimal unitPrice;
  87 +
  88 + @Schema(description = "计量单位", example = "件")
  89 + private String quantityUnit;
  90 +
  91 + @Schema(description = "多栏账科目金额")
  92 + private java.util.Map<Long, BigDecimal> columnAmounts;
  93 +
  94 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/ledger/vo/general/FmsLedgerGeneralRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.ledger.vo.general;
  2 +
  3 +import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
  4 +import cn.idev.excel.annotation.ExcelProperty;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import lombok.Data;
  7 +
  8 +import java.math.BigDecimal;
  9 +
  10 +@Schema(description = "管理后台 - FMS 总账 Response VO")
  11 +@Data
  12 +@ExcelIgnoreUnannotated
  13 +public class FmsLedgerGeneralRespVO {
  14 +
  15 + @Schema(description = "行类型", example = "2")
  16 + private Integer rowType;
  17 +
  18 + @Schema(description = "科目编号", example = "1024")
  19 + private Long subjectId;
  20 +
  21 + @Schema(description = "科目编码", example = "1001")
  22 + @ExcelProperty("科目编码")
  23 + private String subjectCode;
  24 +
  25 + @Schema(description = "科目名称", example = "库存现金")
  26 + @ExcelProperty("科目名称")
  27 + private String subjectName;
  28 +
  29 + @Schema(description = "会计期间", example = "2026-08")
  30 + @ExcelProperty("期间")
  31 + private String period;
  32 +
  33 + @Schema(description = "摘要", example = "本期合计")
  34 + @ExcelProperty("摘要")
  35 + private String digest;
  36 +
  37 + @Schema(description = "借方金额")
  38 + @ExcelProperty("借方")
  39 + private BigDecimal debitAmount;
  40 +
  41 + @Schema(description = "贷方金额")
  42 + @ExcelProperty("贷方")
  43 + private BigDecimal creditAmount;
  44 +
  45 + @Schema(description = "余额方向", example = "借")
  46 + @ExcelProperty("方向")
  47 + private String balanceDirection;
  48 +
  49 + @Schema(description = "余额")
  50 + @ExcelProperty("余额")
  51 + private BigDecimal balance;
  52 +
  53 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/ledger/vo/multicolumn/FmsLedgerMultiColumnRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.ledger.vo.multicolumn;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import lombok.experimental.Accessors;
  6 +
  7 +import cn.iocoder.yudao.module.fms.controller.admin.ledger.vo.detail.FmsLedgerDetailRespVO;
  8 +
  9 +import java.util.List;
  10 +
  11 +@Schema(description = "管理后台 - FMS 多栏账 Response VO")
  12 +@Data
  13 +@Accessors(chain = true)
  14 +public class FmsLedgerMultiColumnRespVO {
  15 +
  16 + @Schema(description = "动态科目列")
  17 + private List<Column> columns;
  18 +
  19 + @Schema(description = "账簿行")
  20 + private List<FmsLedgerDetailRespVO> rows;
  21 +
  22 + @Schema(description = "管理后台 - FMS 多栏账科目列 Response VO")
  23 + @Data
  24 + public static class Column {
  25 +
  26 + @Schema(description = "科目编号", example = "1024")
  27 + private Long subjectId;
  28 +
  29 + @Schema(description = "科目编码", example = "560101")
  30 + private String subjectCode;
  31 +
  32 + @Schema(description = "科目名称", example = "办公用品")
  33 + private String subjectName;
  34 +
  35 + @Schema(description = "余额方向", example = "1")
  36 + private Integer balanceDirection;
  37 +
  38 + }
  39 +
  40 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/ledger/vo/quantitydetail/FmsLedgerQuantityDetailRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.ledger.vo.quantitydetail;
  2 +
  3 +import com.fasterxml.jackson.annotation.JsonFormat;
  4 +import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
  5 +import cn.idev.excel.annotation.ExcelProperty;
  6 +import io.swagger.v3.oas.annotations.media.Schema;
  7 +import lombok.Data;
  8 +
  9 +import java.math.BigDecimal;
  10 +import java.time.LocalDate;
  11 +
  12 +@Schema(description = "管理后台 - FMS 数量金额明细账 Response VO")
  13 +@Data
  14 +@ExcelIgnoreUnannotated
  15 +public class FmsLedgerQuantityDetailRespVO {
  16 +
  17 + public static final Integer ROW_TYPE_OPENING = 1;
  18 + public static final Integer ROW_TYPE_VOUCHER = 2;
  19 + public static final Integer ROW_TYPE_PERIOD_TOTAL = 3;
  20 + public static final Integer ROW_TYPE_YEAR_TOTAL = 4;
  21 +
  22 + @Schema(description = "行类型", example = "2")
  23 + private Integer rowType;
  24 +
  25 + @Schema(description = "分录编号", example = "1024")
  26 + private Long entryId;
  27 +
  28 + @Schema(description = "科目编号", example = "1024")
  29 + private Long subjectId;
  30 +
  31 + @Schema(description = "科目编码", example = "1405")
  32 + private String subjectCode;
  33 +
  34 + @Schema(description = "科目名称", example = "库存商品")
  35 + private String subjectName;
  36 +
  37 + @Schema(description = "会计期间", example = "2026-08")
  38 + private String period;
  39 +
  40 + @Schema(description = "日期")
  41 + @JsonFormat(pattern = "yyyy-MM-dd")
  42 + @ExcelProperty("日期")
  43 + private LocalDate accountDate;
  44 +
  45 + @Schema(description = "凭证编号", example = "1024")
  46 + private Long voucherId;
  47 +
  48 + @Schema(description = "凭证字号", example = "记-1")
  49 + @ExcelProperty("凭证字号")
  50 + private String voucherNumber;
  51 +
  52 + @Schema(description = "摘要", example = "采购商品")
  53 + @ExcelProperty("摘要")
  54 + private String digest;
  55 +
  56 + @Schema(description = "借方金额")
  57 + @ExcelProperty("借方金额")
  58 + private BigDecimal debitAmount;
  59 +
  60 + @Schema(description = "贷方金额")
  61 + @ExcelProperty("贷方金额")
  62 + private BigDecimal creditAmount;
  63 +
  64 + @Schema(description = "余额方向", example = "借")
  65 + @ExcelProperty("方向")
  66 + private String balanceDirection;
  67 +
  68 + @Schema(description = "余额")
  69 + @ExcelProperty("结存金额")
  70 + private BigDecimal balance;
  71 +
  72 + @Schema(description = "借方数量")
  73 + @ExcelProperty("借方数量")
  74 + private BigDecimal debitQuantity;
  75 +
  76 + @Schema(description = "贷方数量")
  77 + @ExcelProperty("贷方数量")
  78 + private BigDecimal creditQuantity;
  79 +
  80 + @Schema(description = "结存数量")
  81 + @ExcelProperty("结存数量")
  82 + private BigDecimal balanceQuantity;
  83 +
  84 + @Schema(description = "单价")
  85 + @ExcelProperty("分录单价")
  86 + private BigDecimal unitPrice;
  87 +
  88 + @ExcelProperty("期初单价")
  89 + private BigDecimal openingUnitPrice;
  90 +
  91 + @ExcelProperty("本期单价")
  92 + private BigDecimal periodUnitPrice;
  93 +
  94 + @ExcelProperty("累计单价")
  95 + private BigDecimal yearUnitPrice;
  96 +
  97 + @ExcelProperty("期末单价")
  98 + private BigDecimal endingUnitPrice;
  99 +
  100 + @Schema(description = "计量单位", example = "件")
  101 + @ExcelProperty("单位")
  102 + private String quantityUnit;
  103 +
  104 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/ledger/vo/quantitygeneral/FmsLedgerQuantityGeneralRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.ledger.vo.quantitygeneral;
  2 +
  3 +import cn.idev.excel.annotation.ExcelIgnore;
  4 +import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
  5 +import cn.idev.excel.annotation.ExcelProperty;
  6 +import io.swagger.v3.oas.annotations.media.Schema;
  7 +import lombok.Data;
  8 +
  9 +import java.math.BigDecimal;
  10 +import java.util.ArrayList;
  11 +import java.util.List;
  12 +
  13 +@Schema(description = "管理后台 - FMS 数量金额总账 Response VO")
  14 +@Data
  15 +@ExcelIgnoreUnannotated
  16 +public class FmsLedgerQuantityGeneralRespVO {
  17 +
  18 + @Schema(description = "科目编号", example = "1024")
  19 + private Long subjectId;
  20 +
  21 + @Schema(description = "科目编码", example = "1405")
  22 + @ExcelProperty({"科目", "编码"})
  23 + private String subjectCode;
  24 +
  25 + @Schema(description = "科目名称", example = "库存商品")
  26 + @ExcelProperty({"科目", "名称"})
  27 + private String subjectName;
  28 +
  29 + @Schema(description = "科目级次", example = "1")
  30 + private Integer level;
  31 +
  32 + @Schema(description = "是否启用数量核算")
  33 + private Boolean quantityAccounting;
  34 +
  35 + @Schema(description = "计量单位", example = "件")
  36 + @ExcelProperty({"基础信息", "单位"})
  37 + private String quantityUnit;
  38 +
  39 + @Schema(description = "期初余额方向", example = "借")
  40 + @ExcelProperty({"期初余额", "方向"})
  41 + private String openingBalanceDirection;
  42 +
  43 + @Schema(description = "期初数量")
  44 + @ExcelProperty({"期初余额", "数量"})
  45 + private BigDecimal openingQuantity;
  46 +
  47 + @Schema(description = "期初单价")
  48 + @ExcelProperty({"期初余额", "单价"})
  49 + private BigDecimal openingUnitPrice;
  50 +
  51 + @Schema(description = "期初借方余额")
  52 + @ExcelIgnore
  53 + private BigDecimal openingDebitAmount;
  54 +
  55 + @Schema(description = "期初贷方余额")
  56 + @ExcelIgnore
  57 + private BigDecimal openingCreditAmount;
  58 +
  59 + @ExcelProperty({"期初余额", "金额"})
  60 + private BigDecimal openingAmount;
  61 +
  62 + @Schema(description = "本期借方数量")
  63 + @ExcelProperty({"本期借方", "数量"})
  64 + private BigDecimal periodDebitQuantity;
  65 +
  66 + @Schema(description = "本期借方发生额")
  67 + @ExcelProperty({"本期借方", "金额"})
  68 + private BigDecimal periodDebitAmount;
  69 +
  70 + @Schema(description = "本期贷方数量")
  71 + @ExcelProperty({"本期贷方", "数量"})
  72 + private BigDecimal periodCreditQuantity;
  73 +
  74 + @Schema(description = "本期贷方发生额")
  75 + @ExcelProperty({"本期贷方", "金额"})
  76 + private BigDecimal periodCreditAmount;
  77 +
  78 + @Schema(description = "本年累计借方数量")
  79 + @ExcelProperty({"本年累计借方", "数量"})
  80 + private BigDecimal yearDebitQuantity;
  81 +
  82 + @Schema(description = "本年累计借方发生额")
  83 + @ExcelProperty({"本年累计借方", "金额"})
  84 + private BigDecimal yearDebitAmount;
  85 +
  86 + @Schema(description = "本年累计贷方数量")
  87 + @ExcelProperty({"本年累计贷方", "数量"})
  88 + private BigDecimal yearCreditQuantity;
  89 +
  90 + @Schema(description = "本年累计贷方发生额")
  91 + @ExcelProperty({"本年累计贷方", "金额"})
  92 + private BigDecimal yearCreditAmount;
  93 +
  94 + @Schema(description = "期末余额方向", example = "借")
  95 + @ExcelProperty({"期末余额", "方向"})
  96 + private String endingBalanceDirection;
  97 +
  98 + @Schema(description = "期末数量")
  99 + @ExcelProperty({"期末余额", "数量"})
  100 + private BigDecimal endingQuantity;
  101 +
  102 + @Schema(description = "期末单价")
  103 + @ExcelProperty({"期末余额", "单价"})
  104 + private BigDecimal endingUnitPrice;
  105 +
  106 + @Schema(description = "期末借方余额")
  107 + @ExcelIgnore
  108 + private BigDecimal endingDebitAmount;
  109 +
  110 + @Schema(description = "期末贷方余额")
  111 + @ExcelIgnore
  112 + private BigDecimal endingCreditAmount;
  113 +
  114 + @ExcelProperty({"期末余额", "金额"})
  115 + private BigDecimal endingAmount;
  116 +
  117 + @Schema(description = "下级科目")
  118 + private List<FmsLedgerQuantityGeneralRespVO> children = new ArrayList<>();
  119 +
  120 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/ledger/vo/subjectbalance/FmsLedgerSubjectBalanceRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.ledger.vo.subjectbalance;
  2 +
  3 +import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
  4 +import cn.idev.excel.annotation.ExcelProperty;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import lombok.Data;
  7 +import lombok.experimental.Accessors;
  8 +
  9 +import java.math.BigDecimal;
  10 +import java.util.ArrayList;
  11 +import java.util.List;
  12 +
  13 +@Schema(description = "管理后台 - FMS 科目余额 Response VO")
  14 +@Data
  15 +@Accessors(chain = true)
  16 +@ExcelIgnoreUnannotated
  17 +public class FmsLedgerSubjectBalanceRespVO {
  18 +
  19 + public static final int NODE_TYPE_SUBJECT = 1;
  20 + public static final int NODE_TYPE_AUXILIARY_COMBINATION = 2;
  21 +
  22 + @Schema(description = "节点唯一键", example = "S:1024")
  23 + private String nodeKey;
  24 +
  25 + @Schema(description = "节点类型", example = "1")
  26 + private Integer nodeType;
  27 +
  28 + @Schema(description = "科目编号", example = "1024")
  29 + private Long subjectId;
  30 +
  31 + @Schema(description = "辅助核算组合编号", example = "2048")
  32 + private Long assistCombinationId;
  33 +
  34 + @Schema(description = "科目编码", example = "1001")
  35 + @ExcelProperty("科目编码")
  36 + private String subjectCode;
  37 +
  38 + @Schema(description = "科目名称", example = "库存现金")
  39 + @ExcelProperty("科目名称")
  40 + private String subjectName;
  41 +
  42 + @Schema(description = "科目级次", example = "1")
  43 + private Integer level;
  44 +
  45 + @Schema(description = "是否启用数量核算")
  46 + private Boolean quantityAccounting;
  47 +
  48 + @Schema(description = "计量单位", example = "件")
  49 + private String quantityUnit;
  50 +
  51 + @Schema(description = "期初借方余额")
  52 + @ExcelProperty("期初借方")
  53 + private BigDecimal openingDebitAmount;
  54 +
  55 + @Schema(description = "期初贷方余额")
  56 + @ExcelProperty("期初贷方")
  57 + private BigDecimal openingCreditAmount;
  58 +
  59 + @Schema(description = "期初余额方向", example = "借")
  60 + private String openingBalanceDirection;
  61 +
  62 + @Schema(description = "期初数量")
  63 + private BigDecimal openingQuantity;
  64 +
  65 + @Schema(description = "期初单价")
  66 + private BigDecimal openingUnitPrice;
  67 +
  68 + @Schema(description = "本期借方发生额")
  69 + @ExcelProperty("本期借方")
  70 + private BigDecimal periodDebitAmount;
  71 +
  72 + @Schema(description = "本期贷方发生额")
  73 + @ExcelProperty("本期贷方")
  74 + private BigDecimal periodCreditAmount;
  75 +
  76 + @Schema(description = "本期借方数量")
  77 + private BigDecimal periodDebitQuantity;
  78 +
  79 + @Schema(description = "本期贷方数量")
  80 + private BigDecimal periodCreditQuantity;
  81 +
  82 + @Schema(description = "本年累计借方发生额")
  83 + @ExcelProperty("本年累计借方")
  84 + private BigDecimal yearDebitAmount;
  85 +
  86 + @Schema(description = "本年累计贷方发生额")
  87 + @ExcelProperty("本年累计贷方")
  88 + private BigDecimal yearCreditAmount;
  89 +
  90 + @Schema(description = "本年累计借方数量")
  91 + private BigDecimal yearDebitQuantity;
  92 +
  93 + @Schema(description = "本年累计贷方数量")
  94 + private BigDecimal yearCreditQuantity;
  95 +
  96 + @Schema(description = "期末借方余额")
  97 + @ExcelProperty("期末借方")
  98 + private BigDecimal endingDebitAmount;
  99 +
  100 + @Schema(description = "期末贷方余额")
  101 + @ExcelProperty("期末贷方")
  102 + private BigDecimal endingCreditAmount;
  103 +
  104 + @Schema(description = "期末余额方向", example = "借")
  105 + private String endingBalanceDirection;
  106 +
  107 + @Schema(description = "期末数量")
  108 + private BigDecimal endingQuantity;
  109 +
  110 + @Schema(description = "期末单价")
  111 + private BigDecimal endingUnitPrice;
  112 +
  113 + @Schema(description = "下级科目")
  114 + private List<FmsLedgerSubjectBalanceRespVO> children = new ArrayList<>();
  115 +
  116 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/report/FmsBalanceSheetController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.report;
  2 +
  3 +import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
  4 +import cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum;
  5 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  6 +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  7 +import cn.iocoder.yudao.module.fms.controller.admin.report.vo.balance.FmsBalanceSheetCheckRespVO;
  8 +import cn.iocoder.yudao.module.fms.controller.admin.report.vo.balance.FmsBalanceSheetRowRespVO;
  9 +import cn.iocoder.yudao.module.fms.controller.admin.report.vo.FmsReportFormulaUpdateReqVO;
  10 +import cn.iocoder.yudao.module.fms.controller.admin.report.vo.FmsReportListReqVO;
  11 +import cn.iocoder.yudao.module.fms.service.report.FmsBalanceSheetService;
  12 +import io.swagger.v3.oas.annotations.Operation;
  13 +import io.swagger.v3.oas.annotations.tags.Tag;
  14 +import jakarta.annotation.Resource;
  15 +import jakarta.servlet.http.HttpServletResponse;
  16 +import jakarta.validation.Valid;
  17 +import org.springframework.security.access.prepost.PreAuthorize;
  18 +import org.springframework.validation.annotation.Validated;
  19 +import org.springframework.web.bind.annotation.GetMapping;
  20 +import org.springframework.web.bind.annotation.PutMapping;
  21 +import org.springframework.web.bind.annotation.RequestBody;
  22 +import org.springframework.web.bind.annotation.RequestMapping;
  23 +import org.springframework.web.bind.annotation.RestController;
  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.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  30 +
  31 +@Tag(name = "管理后台 - FMS 资产负债表")
  32 +@RestController
  33 +@RequestMapping("/fms/report/balance-sheet")
  34 +@Validated
  35 +public class FmsBalanceSheetController {
  36 +
  37 + @Resource
  38 + private FmsBalanceSheetService balanceSheetService;
  39 +
  40 + @GetMapping("/get")
  41 + @Operation(summary = "获得资产负债表")
  42 + @PreAuthorize("@ss.hasPermission('fms:report:balance-sheet:query')")
  43 + public CommonResult<List<FmsBalanceSheetRowRespVO>> getBalanceSheet(@Valid FmsReportListReqVO listReqVO) {
  44 + return success(balanceSheetService.getBalanceSheet(listReqVO, getLoginUserId()));
  45 + }
  46 +
  47 + @GetMapping("/export-excel")
  48 + @Operation(summary = "导出资产负债表")
  49 + @PreAuthorize("@ss.hasPermission('fms:report:balance-sheet:export')")
  50 + @ApiAccessLog(operateType = OperateTypeEnum.EXPORT)
  51 + public void exportBalanceSheet(@Valid FmsReportListReqVO listReqVO,
  52 + HttpServletResponse response) throws IOException {
  53 + List<FmsBalanceSheetRowRespVO> list = balanceSheetService.getBalanceSheet(listReqVO, getLoginUserId());
  54 + ExcelUtils.write(response, "资产负债表.xls", "资产负债表", FmsBalanceSheetRowRespVO.class, list);
  55 + }
  56 +
  57 + @PutMapping("/update")
  58 + @Operation(summary = "更新资产负债表公式")
  59 + @PreAuthorize("@ss.hasPermission('fms:report:balance-sheet:update')")
  60 + public CommonResult<Boolean> updateBalanceSheetFormula(@Valid @RequestBody FmsReportFormulaUpdateReqVO updateReqVO) {
  61 + balanceSheetService.updateBalanceSheetFormula(updateReqVO, getLoginUserId());
  62 + return success(true);
  63 + }
  64 +
  65 + @GetMapping("/check")
  66 + @Operation(summary = "检查资产负债表")
  67 + @PreAuthorize("@ss.hasPermission('fms:report:balance-sheet:query')")
  68 + public CommonResult<FmsBalanceSheetCheckRespVO> checkBalanceSheet(@Valid FmsReportListReqVO listReqVO) {
  69 + return success(balanceSheetService.checkBalanceSheet(listReqVO, getLoginUserId()));
  70 + }
  71 +
  72 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/report/FmsCashFlowStatementController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.report;
  2 +
  3 +import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
  4 +import cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum;
  5 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  6 +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  7 +import cn.iocoder.yudao.module.fms.controller.admin.report.vo.cashflow.FmsCashFlowAdjustmentRespVO;
  8 +import cn.iocoder.yudao.module.fms.controller.admin.report.vo.cashflow.FmsCashFlowAdjustmentUpdateReqVO;
  9 +import cn.iocoder.yudao.module.fms.controller.admin.report.vo.cashflow.FmsCashFlowCheckRespVO;
  10 +import cn.iocoder.yudao.module.fms.controller.admin.report.vo.cashflow.FmsCashFlowStatementUpdateReqVO;
  11 +import cn.iocoder.yudao.module.fms.controller.admin.report.vo.FmsReportFormulaUpdateReqVO;
  12 +import cn.iocoder.yudao.module.fms.controller.admin.report.vo.FmsReportItemRespVO;
  13 +import cn.iocoder.yudao.module.fms.controller.admin.report.vo.FmsReportListReqVO;
  14 +import cn.iocoder.yudao.module.fms.service.report.FmsCashFlowStatementService;
  15 +import io.swagger.v3.oas.annotations.Operation;
  16 +import io.swagger.v3.oas.annotations.tags.Tag;
  17 +import jakarta.annotation.Resource;
  18 +import jakarta.servlet.http.HttpServletResponse;
  19 +import jakarta.validation.Valid;
  20 +import org.springframework.security.access.prepost.PreAuthorize;
  21 +import org.springframework.validation.annotation.Validated;
  22 +import org.springframework.web.bind.annotation.GetMapping;
  23 +import org.springframework.web.bind.annotation.PutMapping;
  24 +import org.springframework.web.bind.annotation.RequestBody;
  25 +import org.springframework.web.bind.annotation.RequestMapping;
  26 +import org.springframework.web.bind.annotation.RestController;
  27 +
  28 +import java.io.IOException;
  29 +import java.util.List;
  30 +
  31 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  32 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  33 +
  34 +@Tag(name = "管理后台 - FMS 现金流量表")
  35 +@RestController
  36 +@RequestMapping("/fms/report/cash-flow-statement")
  37 +@Validated
  38 +public class FmsCashFlowStatementController {
  39 +
  40 + @Resource
  41 + private FmsCashFlowStatementService cashFlowStatementService;
  42 +
  43 + @GetMapping("/get")
  44 + @Operation(summary = "获得现金流量表")
  45 + @PreAuthorize("@ss.hasPermission('fms:report:cash-flow-statement:query')")
  46 + public CommonResult<List<FmsReportItemRespVO>> getCashFlowStatement(
  47 + @Valid FmsReportListReqVO listReqVO) {
  48 + return success(cashFlowStatementService.getCashFlowStatement(listReqVO, getLoginUserId()));
  49 + }
  50 +
  51 + @GetMapping("/export-excel")
  52 + @Operation(summary = "导出现金流量表")
  53 + @PreAuthorize("@ss.hasPermission('fms:report:cash-flow-statement:export')")
  54 + @ApiAccessLog(operateType = OperateTypeEnum.EXPORT)
  55 + public void exportCashFlowStatement(@Valid FmsReportListReqVO listReqVO,
  56 + HttpServletResponse response) throws IOException {
  57 + List<FmsReportItemRespVO> list = cashFlowStatementService.getCashFlowStatement(
  58 + listReqVO, getLoginUserId());
  59 + ExcelUtils.write(response, "现金流量表.xls", "现金流量表", FmsReportItemRespVO.class, list);
  60 + }
  61 +
  62 + @PutMapping("/update")
  63 + @Operation(summary = "更新现金流量表")
  64 + @PreAuthorize("@ss.hasPermission('fms:report:cash-flow-statement:update')")
  65 + public CommonResult<Boolean> updateCashFlowStatement(
  66 + @Valid @RequestBody FmsCashFlowStatementUpdateReqVO updateReqVO) {
  67 + cashFlowStatementService.updateCashFlowStatement(updateReqVO, getLoginUserId());
  68 + return success(true);
  69 + }
  70 +
  71 + @GetMapping("/check")
  72 + @Operation(summary = "检查现金流量表")
  73 + @PreAuthorize("@ss.hasPermission('fms:report:cash-flow-statement:query')")
  74 + public CommonResult<FmsCashFlowCheckRespVO> checkCashFlowStatement(
  75 + @Valid FmsReportListReqVO listReqVO) {
  76 + return success(cashFlowStatementService.checkCashFlowStatement(listReqVO, getLoginUserId()));
  77 + }
  78 +
  79 + @GetMapping("/adjustment/list")
  80 + @Operation(summary = "获得现金流量辅助数据列表")
  81 + @PreAuthorize("@ss.hasPermission('fms:report:cash-flow-statement:query')")
  82 + public CommonResult<List<FmsCashFlowAdjustmentRespVO>> getCashFlowAdjustmentList(@Valid FmsReportListReqVO listReqVO) {
  83 + return success(cashFlowStatementService.getCashFlowAdjustmentList(listReqVO, getLoginUserId()));
  84 + }
  85 +
  86 + @PutMapping("/adjustment/update")
  87 + @Operation(summary = "更新现金流量辅助数据")
  88 + @PreAuthorize("@ss.hasPermission('fms:report:cash-flow-statement:update')")
  89 + public CommonResult<Boolean> updateCashFlowAdjustment(@Valid @RequestBody FmsCashFlowAdjustmentUpdateReqVO updateReqVO) {
  90 + cashFlowStatementService.updateCashFlowAdjustment(updateReqVO, getLoginUserId());
  91 + return success(true);
  92 + }
  93 +
  94 + @PutMapping("/adjustment/update-formula")
  95 + @Operation(summary = "更新现金流量辅助数据公式")
  96 + @PreAuthorize("@ss.hasPermission('fms:report:cash-flow-statement:update')")
  97 + public CommonResult<Boolean> updateCashFlowAdjustmentFormula(@Valid @RequestBody FmsReportFormulaUpdateReqVO updateReqVO) {
  98 + cashFlowStatementService.updateCashFlowAdjustmentFormula(updateReqVO, getLoginUserId());
  99 + return success(true);
  100 + }
  101 +
  102 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/report/FmsIncomeStatementController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.report;
  2 +
  3 +import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
  4 +import cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum;
  5 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  6 +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  7 +import cn.iocoder.yudao.module.fms.controller.admin.report.vo.income.FmsIncomeStatementCheckRespVO;
  8 +import cn.iocoder.yudao.module.fms.controller.admin.report.vo.FmsReportFormulaUpdateReqVO;
  9 +import cn.iocoder.yudao.module.fms.controller.admin.report.vo.FmsReportItemRespVO;
  10 +import cn.iocoder.yudao.module.fms.controller.admin.report.vo.FmsReportListReqVO;
  11 +import cn.iocoder.yudao.module.fms.service.report.FmsIncomeStatementService;
  12 +import io.swagger.v3.oas.annotations.Operation;
  13 +import io.swagger.v3.oas.annotations.tags.Tag;
  14 +import jakarta.annotation.Resource;
  15 +import jakarta.servlet.http.HttpServletResponse;
  16 +import jakarta.validation.Valid;
  17 +import org.springframework.security.access.prepost.PreAuthorize;
  18 +import org.springframework.validation.annotation.Validated;
  19 +import org.springframework.web.bind.annotation.GetMapping;
  20 +import org.springframework.web.bind.annotation.PutMapping;
  21 +import org.springframework.web.bind.annotation.RequestBody;
  22 +import org.springframework.web.bind.annotation.RequestMapping;
  23 +import org.springframework.web.bind.annotation.RestController;
  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.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  30 +
  31 +@Tag(name = "管理后台 - FMS 利润表")
  32 +@RestController
  33 +@RequestMapping("/fms/report/income-statement")
  34 +@Validated
  35 +public class FmsIncomeStatementController {
  36 +
  37 + @Resource
  38 + private FmsIncomeStatementService incomeStatementService;
  39 +
  40 + @GetMapping("/get")
  41 + @Operation(summary = "获得利润表")
  42 + @PreAuthorize("@ss.hasPermission('fms:report:income-statement:query')")
  43 + public CommonResult<List<FmsReportItemRespVO>> getIncomeStatement(@Valid FmsReportListReqVO listReqVO) {
  44 + return success(incomeStatementService.getIncomeStatement(listReqVO, getLoginUserId()));
  45 + }
  46 +
  47 + @GetMapping("/export-excel")
  48 + @Operation(summary = "导出利润表")
  49 + @PreAuthorize("@ss.hasPermission('fms:report:income-statement:export')")
  50 + @ApiAccessLog(operateType = OperateTypeEnum.EXPORT)
  51 + public void exportIncomeStatement(@Valid FmsReportListReqVO listReqVO, HttpServletResponse response) throws IOException {
  52 + List<FmsReportItemRespVO> list = incomeStatementService.getIncomeStatement(listReqVO, getLoginUserId());
  53 + ExcelUtils.write(response, "利润表.xls", "利润表", FmsReportItemRespVO.class, list);
  54 + }
  55 +
  56 + @PutMapping("/update")
  57 + @Operation(summary = "更新利润表公式")
  58 + @PreAuthorize("@ss.hasPermission('fms:report:income-statement:update')")
  59 + public CommonResult<Boolean> updateIncomeStatementFormula(@Valid @RequestBody FmsReportFormulaUpdateReqVO updateReqVO) {
  60 + incomeStatementService.updateIncomeStatementFormula(updateReqVO, getLoginUserId());
  61 + return success(true);
  62 + }
  63 +
  64 + @GetMapping("/check")
  65 + @Operation(summary = "检查利润表")
  66 + @PreAuthorize("@ss.hasPermission('fms:report:income-statement:query')")
  67 + public CommonResult<FmsIncomeStatementCheckRespVO> checkIncomeStatement(@Valid FmsReportListReqVO listReqVO) {
  68 + return success(incomeStatementService.checkIncomeStatement(listReqVO, getLoginUserId()));
  69 + }
  70 +
  71 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/report/vo/FmsReportFormulaRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.report.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.math.BigDecimal;
  7 +
  8 +@Schema(description = "管理后台 - FMS 报表公式项 Response VO")
  9 +@Data
  10 +public class FmsReportFormulaRespVO {
  11 +
  12 + @Schema(description = "科目编号", example = "1024")
  13 + private Long subjectId;
  14 +
  15 + @Schema(description = "科目名称", example = "库存现金")
  16 + private String subjectName;
  17 +
  18 + @Schema(description = "科目编码", example = "1001")
  19 + private String subjectNumber;
  20 +
  21 + @Schema(description = "运算符", example = "+")
  22 + private String operator;
  23 +
  24 + @Schema(description = "取数规则", example = "0")
  25 + private Integer rules;
  26 +
  27 + @Schema(description = "期初金额", example = "100.00")
  28 + private BigDecimal openingAmount;
  29 +
  30 + @Schema(description = "期末金额", example = "200.00")
  31 + private BigDecimal closingAmount;
  32 +
  33 + @Schema(description = "本期金额", example = "100.00")
  34 + private BigDecimal currentAmount;
  35 +
  36 + @Schema(description = "本年累计金额", example = "200.00")
  37 + private BigDecimal yearAmount;
  38 +
  39 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/report/vo/FmsReportFormulaUpdateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.report.vo;
  2 +
  3 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  4 +import cn.iocoder.yudao.module.fms.enums.report.FmsFormulaRuleEnum;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import jakarta.validation.Valid;
  7 +import jakarta.validation.constraints.NotNull;
  8 +import jakarta.validation.constraints.Pattern;
  9 +import lombok.Data;
  10 +
  11 +import java.util.ArrayList;
  12 +import java.util.List;
  13 +
  14 +@Schema(description = "管理后台 - FMS 报表公式更新 Request VO")
  15 +@Data
  16 +public class FmsReportFormulaUpdateReqVO {
  17 +
  18 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  19 + @NotNull(message = "账套编号不能为空")
  20 + private Long accountSetId;
  21 +
  22 + @Schema(description = "配置编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  23 + @NotNull(message = "配置编号不能为空")
  24 + private Long id;
  25 +
  26 + @Schema(description = "公式项数组", requiredMode = Schema.RequiredMode.REQUIRED)
  27 + @NotNull(message = "公式项数组不能为空")
  28 + @Valid
  29 + private List<Formula> formulas = new ArrayList<>();
  30 +
  31 + @Schema(description = "管理后台 - FMS 报表公式项 Request VO")
  32 + @Data
  33 + public static class Formula {
  34 +
  35 + @Schema(description = "科目编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  36 + @NotNull(message = "科目编号不能为空")
  37 + private Long subjectId;
  38 +
  39 + @Schema(description = "运算符", requiredMode = Schema.RequiredMode.REQUIRED, example = "+")
  40 + @NotNull(message = "运算符不能为空")
  41 + @Pattern(regexp = "[+-]", message = "运算符必须是 + 或 -")
  42 + private String operator;
  43 +
  44 + @Schema(description = "取数规则", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
  45 + @NotNull(message = "取数规则不能为空")
  46 + @InEnum(value = FmsFormulaRuleEnum.class, message = "取数规则必须是 {value}")
  47 + private Integer rules;
  48 +
  49 + }
  50 +
  51 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/report/vo/FmsReportItemRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.report.vo;
  2 +
  3 +import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
  4 +import cn.idev.excel.annotation.ExcelProperty;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import lombok.Data;
  7 +
  8 +import java.math.BigDecimal;
  9 +
  10 +@Schema(description = "管理后台 - FMS 财务报表项目 Response VO")
  11 +@Data
  12 +@ExcelIgnoreUnannotated
  13 +public class FmsReportItemRespVO {
  14 +
  15 + @Schema(description = "配置编号", example = "1024")
  16 + private Long id;
  17 +
  18 + @Schema(description = "项目名称", example = "货币资金")
  19 + @ExcelProperty("项目")
  20 + private String name;
  21 +
  22 + @Schema(description = "行次", example = "1")
  23 + @ExcelProperty("行次")
  24 + private Integer rowNo;
  25 +
  26 + @Schema(description = "层级", example = "2")
  27 + private Integer level;
  28 +
  29 + @Schema(description = "是否可编辑", example = "true")
  30 + private Boolean editable;
  31 +
  32 + @Schema(description = "公式")
  33 + private String formula;
  34 +
  35 + @Schema(description = "期初金额", example = "100.00")
  36 + private BigDecimal openingAmount;
  37 +
  38 + @Schema(description = "期末金额", example = "200.00")
  39 + private BigDecimal closingAmount;
  40 +
  41 + @Schema(description = "本年累计金额", example = "200.00")
  42 + @ExcelProperty("本年累计金额")
  43 + private BigDecimal yearAmount;
  44 +
  45 + @Schema(description = "本期金额", example = "100.00")
  46 + @ExcelProperty("本期金额")
  47 + private BigDecimal currentAmount;
  48 +
  49 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/report/vo/FmsReportListReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.report.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotNull;
  5 +import jakarta.validation.constraints.Pattern;
  6 +import lombok.Data;
  7 +
  8 +@Schema(description = "管理后台 - FMS 财务报表查询 Request VO")
  9 +@Data
  10 +public class FmsReportListReqVO {
  11 +
  12 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  13 + @NotNull(message = "账套编号不能为空")
  14 + private Long accountSetId;
  15 +
  16 + @Schema(description = "开始会计期间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026-08")
  17 + @NotNull(message = "开始会计期间不能为空")
  18 + @Pattern(regexp = "\\d{4}-(0[1-9]|1[0-2])", message = "开始会计期间格式不正确")
  19 + private String startMonth;
  20 +
  21 + @Schema(description = "结束会计期间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026-08")
  22 + @NotNull(message = "结束会计期间不能为空")
  23 + @Pattern(regexp = "\\d{4}-(0[1-9]|1[0-2])", message = "结束会计期间格式不正确")
  24 + private String endMonth;
  25 +
  26 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/report/vo/balance/FmsBalanceSheetCheckRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.report.vo.balance;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.math.BigDecimal;
  7 +import java.util.List;
  8 +
  9 +@Schema(description = "管理后台 - FMS 资产负债表检查 Response VO")
  10 +@Data
  11 +public class FmsBalanceSheetCheckRespVO {
  12 +
  13 + @Schema(description = "报表是否平衡", example = "true")
  14 + private Boolean balanced;
  15 +
  16 + @Schema(description = "初始余额是否平衡", example = "true")
  17 + private Boolean initialBalanceBalanced;
  18 +
  19 + @Schema(description = "损益是否已结转", example = "true")
  20 + private Boolean profitLossTransferred;
  21 +
  22 + @Schema(description = "年初余额差额", example = "0.00")
  23 + private BigDecimal openingDifferenceAmount;
  24 +
  25 + @Schema(description = "期末余额差额", example = "0.00")
  26 + private BigDecimal closingDifferenceAmount;
  27 +
  28 + @Schema(description = "未纳入报表公式的科目")
  29 + private List<UnmappedSubject> unmappedSubjects;
  30 +
  31 + @Schema(description = "管理后台 - FMS 未纳入报表公式的科目")
  32 + @Data
  33 + public static class UnmappedSubject {
  34 +
  35 + @Schema(description = "科目编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  36 + private Long id;
  37 +
  38 + @Schema(description = "科目编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "1001")
  39 + private String code;
  40 +
  41 + @Schema(description = "科目名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "库存现金")
  42 + private String name;
  43 +
  44 + }
  45 +
  46 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/report/vo/balance/FmsBalanceSheetRowRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.report.vo.balance;
  2 +
  3 +import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
  4 +import cn.idev.excel.annotation.ExcelProperty;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import lombok.Data;
  7 +
  8 +import java.math.BigDecimal;
  9 +
  10 +@Schema(description = "管理后台 - FMS 资产负债表行 Response VO")
  11 +@Data
  12 +@ExcelIgnoreUnannotated
  13 +public class FmsBalanceSheetRowRespVO {
  14 +
  15 + @Schema(description = "行编号", example = "1")
  16 + private Integer rowId;
  17 +
  18 + @Schema(description = "资产项目配置编号", example = "1024")
  19 + private Long assetId;
  20 +
  21 + @Schema(description = "资产项目名称", example = "货币资金")
  22 + @ExcelProperty("资产")
  23 + private String assetName;
  24 +
  25 + @Schema(description = "资产项目行次", example = "1")
  26 + @ExcelProperty("行次")
  27 + private Integer assetRowNo;
  28 +
  29 + @Schema(description = "资产项目期末余额", example = "200.00")
  30 + @ExcelProperty("期末余额")
  31 + private BigDecimal assetClosingAmount;
  32 +
  33 + @Schema(description = "资产项目年初余额", example = "100.00")
  34 + @ExcelProperty("年初余额")
  35 + private BigDecimal assetOpeningAmount;
  36 +
  37 + @Schema(description = "资产项目层级", example = "2")
  38 + private Integer assetLevel;
  39 +
  40 + @Schema(description = "资产项目是否可编辑", example = "true")
  41 + private Boolean assetEditable;
  42 +
  43 + @Schema(description = "资产项目公式")
  44 + private String assetFormula;
  45 +
  46 + @Schema(description = "负债和所有者权益项目配置编号", example = "1024")
  47 + private Long liabilityId;
  48 +
  49 + @Schema(description = "负债和所有者权益项目名称", example = "短期借款")
  50 + @ExcelProperty("负债和所有者权益")
  51 + private String liabilityName;
  52 +
  53 + @Schema(description = "负债和所有者权益项目行次", example = "31")
  54 + @ExcelProperty("行次")
  55 + private Integer liabilityRowNo;
  56 +
  57 + @Schema(description = "负债和所有者权益项目期末余额", example = "200.00")
  58 + @ExcelProperty("期末余额")
  59 + private BigDecimal liabilityClosingAmount;
  60 +
  61 + @Schema(description = "负债和所有者权益项目年初余额", example = "100.00")
  62 + @ExcelProperty("年初余额")
  63 + private BigDecimal liabilityOpeningAmount;
  64 +
  65 + @Schema(description = "负债和所有者权益项目层级", example = "2")
  66 + private Integer liabilityLevel;
  67 +
  68 + @Schema(description = "负债和所有者权益项目是否可编辑", example = "true")
  69 + private Boolean liabilityEditable;
  70 +
  71 + @Schema(description = "负债和所有者权益项目公式")
  72 + private String liabilityFormula;
  73 +
  74 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/report/vo/cashflow/FmsCashFlowAdjustmentRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.report.vo.cashflow;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.math.BigDecimal;
  7 +
  8 +@Schema(description = "管理后台 - FMS 现金流量辅助数据 Response VO")
  9 +@Data
  10 +public class FmsCashFlowAdjustmentRespVO {
  11 +
  12 + @Schema(description = "数据编号", example = "1024")
  13 + private Long id;
  14 +
  15 + @Schema(description = "项目名称", example = "支付给职工的工资")
  16 + private String name;
  17 +
  18 + @Schema(description = "行次", example = "1")
  19 + private Integer rowNo;
  20 +
  21 + @Schema(description = "公式")
  22 + private String formula;
  23 +
  24 + @Schema(description = "说明")
  25 + private String remark;
  26 +
  27 + @Schema(description = "是否可编辑", example = "true")
  28 + private Boolean editable;
  29 +
  30 + @Schema(description = "本期金额", example = "100.00")
  31 + private BigDecimal currentAmount;
  32 +
  33 + @Schema(description = "本年累计金额", example = "200.00")
  34 + private BigDecimal yearAmount;
  35 +
  36 + @Schema(description = "层级", example = "1")
  37 + private Integer level;
  38 +
  39 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/report/vo/cashflow/FmsCashFlowAdjustmentUpdateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.report.vo.cashflow;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.Valid;
  5 +import jakarta.validation.constraints.NotEmpty;
  6 +import jakarta.validation.constraints.NotNull;
  7 +import lombok.Data;
  8 +
  9 +import java.math.BigDecimal;
  10 +import java.util.ArrayList;
  11 +import java.util.List;
  12 +
  13 +@Schema(description = "管理后台 - FMS 现金流量辅助数据更新 Request VO")
  14 +@Data
  15 +public class FmsCashFlowAdjustmentUpdateReqVO {
  16 +
  17 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  18 + @NotNull(message = "账套编号不能为空")
  19 + private Long accountSetId;
  20 +
  21 + @Schema(description = "辅助数据项", requiredMode = Schema.RequiredMode.REQUIRED)
  22 + @NotEmpty(message = "辅助数据项不能为空")
  23 + @Valid
  24 + private List<Item> items = new ArrayList<>();
  25 +
  26 + @Schema(description = "管理后台 - FMS 现金流量辅助数据更新项 Request VO")
  27 + @Data
  28 + public static class Item {
  29 +
  30 + @Schema(description = "数据编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  31 + @NotNull(message = "数据编号不能为空")
  32 + private Long id;
  33 +
  34 + @Schema(description = "本期金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  35 + @NotNull(message = "本期金额不能为空")
  36 + private BigDecimal currentAmount;
  37 +
  38 + @Schema(description = "本年累计金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "200.00")
  39 + @NotNull(message = "本年累计金额不能为空")
  40 + private BigDecimal yearAmount;
  41 +
  42 + }
  43 +
  44 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/report/vo/cashflow/FmsCashFlowCheckRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.report.vo.cashflow;
  2 +
  3 +import cn.iocoder.yudao.module.fms.controller.admin.report.vo.balance.FmsBalanceSheetCheckRespVO;
  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 = "管理后台 - FMS 现金流量表检查 Response VO")
  10 +@Data
  11 +@EqualsAndHashCode(callSuper = true)
  12 +@ToString(callSuper = true)
  13 +public class FmsCashFlowCheckRespVO extends FmsBalanceSheetCheckRespVO {
  14 +
  15 + @Schema(description = "资产负债表是否满足现金流量表取数条件", example = "true")
  16 + private Boolean balanceSheetReady;
  17 +
  18 +}
... ...
yudao-module-fms/src/main/java/cn/iocoder/yudao/module/fms/controller/admin/report/vo/cashflow/FmsCashFlowStatementUpdateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.fms.controller.admin.report.vo.cashflow;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.Valid;
  5 +import jakarta.validation.constraints.NotEmpty;
  6 +import jakarta.validation.constraints.NotNull;
  7 +import jakarta.validation.constraints.Pattern;
  8 +import lombok.Data;
  9 +
  10 +import java.math.BigDecimal;
  11 +import java.util.ArrayList;
  12 +import java.util.List;
  13 +
  14 +@Schema(description = "管理后台 - FMS 现金流量表修改 Request VO")
  15 +@Data
  16 +public class FmsCashFlowStatementUpdateReqVO {
  17 +
  18 + @Schema(description = "账套编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  19 + @NotNull(message = "账套编号不能为空")
  20 + private Long accountSetId;
  21 +
  22 + @Schema(description = "开始会计期间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026-08")
  23 + @NotNull(message = "开始会计期间不能为空")
  24 + @Pattern(regexp = "\\d{4}-(0[1-9]|1[0-2])", message = "开始会计期间格式不正确")
  25 + private String startMonth;
  26 +
  27 + @Schema(description = "结束会计期间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026-08")
  28 + @NotNull(message = "结束会计期间不能为空")
  29 + @Pattern(regexp = "\\d{4}-(0[1-9]|1[0-2])", message = "结束会计期间格式不正确")
  30 + private String endMonth;
  31 +
  32 + @Schema(description = "现金流量表项目", requiredMode = Schema.RequiredMode.REQUIRED)
  33 + @NotEmpty(message = "现金流量表项目不能为空")
  34 + @Valid
  35 + private List<Item> items = new ArrayList<>();
  36 +
  37 + @Schema(description = "管理后台 - FMS 现金流量表修改项 Request VO")
  38 + @Data
  39 + public static class Item {
  40 +
  41 + @Schema(description = "报表项目编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  42 + @NotNull(message = "报表项目编号不能为空")
  43 + private Long id;
  44 +
  45 + @Schema(description = "本期金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  46 + @NotNull(message = "本期金额不能为空")
  47 + private BigDecimal currentAmount;
  48 +
  49 + @Schema(description = "本年累计金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "200.00")
  50 + @NotNull(message = "本年累计金额不能为空")
  51 + private BigDecimal yearAmount;
  52 +
  53 + }
  54 +
  55 +}
... ...