Commit c5d9ad59e0075d2e8397beed117c1179668b6aa6

Authored by YunaiV
1 parent 798b7277

✨ ERP:初始化采购订单 50%

Showing 32 changed files with 1266 additions and 58 deletions
yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/ErrorCodeConstants.java
@@ -13,6 +13,19 @@ public interface ErrorCodeConstants { @@ -13,6 +13,19 @@ public interface ErrorCodeConstants {
13 ErrorCode SUPPLIER_NOT_EXISTS = new ErrorCode(1_030_100_000, "供应商不存在"); 13 ErrorCode SUPPLIER_NOT_EXISTS = new ErrorCode(1_030_100_000, "供应商不存在");
14 ErrorCode SUPPLIER_NOT_ENABLE = new ErrorCode(1_030_100_000, "供应商({})未启用"); 14 ErrorCode SUPPLIER_NOT_ENABLE = new ErrorCode(1_030_100_000, "供应商({})未启用");
15 15
  16 + // ========== ERP 采购订单(1-030-101-000) ==========
  17 + ErrorCode PURCHASE_ORDER_NOT_EXISTS = new ErrorCode(1_030_101_000, "采购订单不存在");
  18 + ErrorCode PURCHASE_ORDER_DELETE_FAIL_APPROVE = new ErrorCode(1_030_101_001, "采购订单({})已审核,无法删除");
  19 + ErrorCode PURCHASE_ORDER_PROCESS_FAIL = new ErrorCode(1_030_101_002, "反审核失败,只有已审核的采购订单才能反审核");
  20 + ErrorCode PURCHASE_ORDER_APPROVE_FAIL = new ErrorCode(1_030_101_003, "审核失败,只有未审核的采购订单才能审核");
  21 + ErrorCode PURCHASE_ORDER_NO_EXISTS = new ErrorCode(1_030_101_004, "生成采购单号失败,请重新提交");
  22 + ErrorCode PURCHASE_ORDER_UPDATE_FAIL_APPROVE = new ErrorCode(1_030_101_005, "采购订单({})已审核,无法修改");
  23 + ErrorCode PURCHASE_ORDER_NOT_APPROVE = new ErrorCode(1_030_101_006, "采购订单未审核,无法操作");
  24 + ErrorCode PURCHASE_ORDER_ITEM_IN_FAIL_PRODUCT_EXCEED = new ErrorCode(1_030_101_007, "采购订单项({})超过最大允许入库数量({})");
  25 + ErrorCode PURCHASE_ORDER_PROCESS_FAIL_EXISTS_IN = new ErrorCode(1_030_101_008, "反审核失败,已存在对应的采购入库单");
  26 +ErrorCode PURCHASE_ORDER_ITEM_RETURN_FAIL_IN_EXCEED = new ErrorCode(1_030_101_009, "采购订单项({})超过最大允许退货数量({})");
  27 + ErrorCode PURCHASE_ORDER_PROCESS_FAIL_EXISTS_RETURN = new ErrorCode(1_030_101_010, "反审核失败,已存在对应的采购退货单");
  28 +
16 // ========== ERP 客户(1-030-200-000)========== 29 // ========== ERP 客户(1-030-200-000)==========
17 ErrorCode CUSTOMER_NOT_EXISTS = new ErrorCode(1_020_200_000, "客户不存在"); 30 ErrorCode CUSTOMER_NOT_EXISTS = new ErrorCode(1_020_200_000, "客户不存在");
18 ErrorCode CUSTOMER_NOT_ENABLE = new ErrorCode(1_020_200_001, "客户({})未启用"); 31 ErrorCode CUSTOMER_NOT_ENABLE = new ErrorCode(1_020_200_001, "客户({})未启用");
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseOrderController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.purchase;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
  8 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  9 +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  10 +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
  11 +import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO;
  12 +import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order.ErpPurchaseOrderPageReqVO;
  13 +import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order.ErpPurchaseOrderRespVO;
  14 +import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order.ErpPurchaseOrderSaveReqVO;
  15 +import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderDO;
  16 +import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderItemDO;
  17 +import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpSupplierDO;
  18 +import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
  19 +import cn.iocoder.yudao.module.erp.service.purchase.ErpPurchaseOrderService;
  20 +import cn.iocoder.yudao.module.erp.service.purchase.ErpSupplierService;
  21 +import cn.iocoder.yudao.module.erp.service.stock.ErpStockService;
  22 +import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  23 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
  24 +import io.swagger.v3.oas.annotations.Operation;
  25 +import io.swagger.v3.oas.annotations.Parameter;
  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 org.springframework.security.access.prepost.PreAuthorize;
  31 +import org.springframework.validation.annotation.Validated;
  32 +import org.springframework.web.bind.annotation.*;
  33 +
  34 +import java.io.IOException;
  35 +import java.math.BigDecimal;
  36 +import java.util.List;
  37 +import java.util.Map;
  38 +
  39 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  40 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMultiMap;
  41 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
  42 +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
  43 +
  44 +
  45 +@Tag(name = "管理后台 - ERP 采购订单")
  46 +@RestController
  47 +@RequestMapping("/erp/purchase-order")
  48 +@Validated
  49 +public class ErpPurchaseOrderController {
  50 +
  51 + @Resource
  52 + private ErpPurchaseOrderService purchaseOrderService;
  53 + @Resource
  54 + private ErpStockService stockService;
  55 + @Resource
  56 + private ErpProductService productService;
  57 + @Resource
  58 + private ErpSupplierService supplierService;
  59 +
  60 + @Resource
  61 + private AdminUserApi adminUserApi;
  62 +
  63 + @PostMapping("/create")
  64 + @Operation(summary = "创建采购订单")
  65 + @PreAuthorize("@ss.hasPermission('erp:purchase-out:create')")
  66 + public CommonResult<Long> createPurchaseOrder(@Valid @RequestBody ErpPurchaseOrderSaveReqVO createReqVO) {
  67 + return success(purchaseOrderService.createPurchaseOrder(createReqVO));
  68 + }
  69 +
  70 + @PutMapping("/update")
  71 + @Operation(summary = "更新采购订单")
  72 + @PreAuthorize("@ss.hasPermission('erp:purchase-out:update')")
  73 + public CommonResult<Boolean> updatePurchaseOrder(@Valid @RequestBody ErpPurchaseOrderSaveReqVO updateReqVO) {
  74 + purchaseOrderService.updatePurchaseOrder(updateReqVO);
  75 + return success(true);
  76 + }
  77 +
  78 + @PutMapping("/update-status")
  79 + @Operation(summary = "更新采购订单的状态")
  80 + @PreAuthorize("@ss.hasPermission('erp:purchase-out:update-status')")
  81 + public CommonResult<Boolean> updatePurchaseOrderStatus(@RequestParam("id") Long id,
  82 + @RequestParam("status") Integer status) {
  83 + purchaseOrderService.updatePurchaseOrderStatus(id, status);
  84 + return success(true);
  85 + }
  86 +
  87 + @DeleteMapping("/delete")
  88 + @Operation(summary = "删除采购订单")
  89 + @Parameter(name = "ids", description = "编号数组", required = true)
  90 + @PreAuthorize("@ss.hasPermission('erp:purchase-out:delete')")
  91 + public CommonResult<Boolean> deletePurchaseOrder(@RequestParam("ids") List<Long> ids) {
  92 + purchaseOrderService.deletePurchaseOrder(ids);
  93 + return success(true);
  94 + }
  95 +
  96 + @GetMapping("/get")
  97 + @Operation(summary = "获得采购订单")
  98 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  99 + @PreAuthorize("@ss.hasPermission('erp:purchase-out:query')")
  100 + public CommonResult<ErpPurchaseOrderRespVO> getPurchaseOrder(@RequestParam("id") Long id) {
  101 + ErpPurchaseOrderDO purchaseOrder = purchaseOrderService.getPurchaseOrder(id);
  102 + if (purchaseOrder == null) {
  103 + return success(null);
  104 + }
  105 + List<ErpPurchaseOrderItemDO> purchaseOrderItemList = purchaseOrderService.getPurchaseOrderItemListByOrderId(id);
  106 + Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
  107 + convertSet(purchaseOrderItemList, ErpPurchaseOrderItemDO::getProductId));
  108 + return success(BeanUtils.toBean(purchaseOrder, ErpPurchaseOrderRespVO.class, purchaseOrderVO ->
  109 + purchaseOrderVO.setItems(BeanUtils.toBean(purchaseOrderItemList, ErpPurchaseOrderRespVO.Item.class, item -> {
  110 + BigDecimal purchaseCount = stockService.getStockCount(item.getProductId());
  111 + item.setStockCount(purchaseCount != null ? purchaseCount : BigDecimal.ZERO);
  112 + MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName())
  113 + .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName()));
  114 + }))));
  115 + }
  116 +
  117 + @GetMapping("/page")
  118 + @Operation(summary = "获得采购订单分页")
  119 + @PreAuthorize("@ss.hasPermission('erp:purchase-out:query')")
  120 + public CommonResult<PageResult<ErpPurchaseOrderRespVO>> getPurchaseOrderPage(@Valid ErpPurchaseOrderPageReqVO pageReqVO) {
  121 + PageResult<ErpPurchaseOrderDO> pageResult = purchaseOrderService.getPurchaseOrderPage(pageReqVO);
  122 + return success(buildPurchaseOrderVOPageResult(pageResult));
  123 + }
  124 +
  125 + @GetMapping("/export-excel")
  126 + @Operation(summary = "导出采购订单 Excel")
  127 + @PreAuthorize("@ss.hasPermission('erp:purchase-out:export')")
  128 + @OperateLog(type = EXPORT)
  129 + public void exportPurchaseOrderExcel(@Valid ErpPurchaseOrderPageReqVO pageReqVO,
  130 + HttpServletResponse response) throws IOException {
  131 + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
  132 + List<ErpPurchaseOrderRespVO> list = buildPurchaseOrderVOPageResult(purchaseOrderService.getPurchaseOrderPage(pageReqVO)).getList();
  133 + // 导出 Excel
  134 + ExcelUtils.write(response, "采购订单.xls", "数据", ErpPurchaseOrderRespVO.class, list);
  135 + }
  136 +
  137 + private PageResult<ErpPurchaseOrderRespVO> buildPurchaseOrderVOPageResult(PageResult<ErpPurchaseOrderDO> pageResult) {
  138 + if (CollUtil.isEmpty(pageResult.getList())) {
  139 + return PageResult.empty(pageResult.getTotal());
  140 + }
  141 + // 1.1 出库项
  142 + List<ErpPurchaseOrderItemDO> purchaseOrderItemList = purchaseOrderService.getPurchaseOrderItemListByOrderIds(
  143 + convertSet(pageResult.getList(), ErpPurchaseOrderDO::getId));
  144 + Map<Long, List<ErpPurchaseOrderItemDO>> purchaseOrderItemMap = convertMultiMap(purchaseOrderItemList, ErpPurchaseOrderItemDO::getOrderId);
  145 + // 1.2 产品信息
  146 + Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
  147 + convertSet(purchaseOrderItemList, ErpPurchaseOrderItemDO::getProductId));
  148 + // 1.3 供应商信息
  149 + Map<Long, ErpSupplierDO> supplierMap = supplierService.getSupplierMap(
  150 + convertSet(pageResult.getList(), ErpPurchaseOrderDO::getSupplierId));
  151 + // 1.4 管理员信息
  152 + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
  153 + convertSet(pageResult.getList(), erpStockRecordDO -> Long.parseLong(erpStockRecordDO.getCreator())));
  154 + // 2. 开始拼接
  155 + return BeanUtils.toBean(pageResult, ErpPurchaseOrderRespVO.class, purchaseOrder -> {
  156 + purchaseOrder.setItems(BeanUtils.toBean(purchaseOrderItemMap.get(purchaseOrder.getId()), ErpPurchaseOrderRespVO.Item.class,
  157 + item -> MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName())
  158 + .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName()))));
  159 + purchaseOrder.setProductNames(CollUtil.join(purchaseOrder.getItems(), ",", ErpPurchaseOrderRespVO.Item::getProductName));
  160 + MapUtils.findAndThen(supplierMap, purchaseOrder.getSupplierId(), supplier -> purchaseOrder.setSupplierName(supplier.getName()));
  161 + MapUtils.findAndThen(userMap, Long.parseLong(purchaseOrder.getCreator()), user -> purchaseOrder.setCreatorName(user.getNickname()));
  162 + });
  163 + }
  164 +
  165 +}
0 \ No newline at end of file 166 \ No newline at end of file
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/order/ErpPurchaseOrderPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +import org.springframework.format.annotation.DateTimeFormat;
  9 +
  10 +import java.time.LocalDateTime;
  11 +
  12 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  13 +
  14 +@Schema(description = "管理后台 - ERP 采购订单分页 Request VO")
  15 +@Data
  16 +@EqualsAndHashCode(callSuper = true)
  17 +@ToString(callSuper = true)
  18 +public class ErpPurchaseOrderPageReqVO extends PageParam {
  19 +
  20 + /**
  21 + * 入库状态 - 无
  22 + */
  23 + public static final Integer IN_STATUS_NONE = 0;
  24 + /**
  25 + * 入库状态 - 部分
  26 + */
  27 + public static final Integer IN_STATUS_PART = 1;
  28 + /**
  29 + * 入库状态 - 全部
  30 + */
  31 + public static final Integer IN_STATUS_ALL = 2;
  32 +
  33 + /**
  34 + * 退货状态 - 无
  35 + */
  36 + public static final Integer RETURN_STATUS_NONE = 0;
  37 + /**
  38 + * 退货状态 - 部分
  39 + */
  40 + public static final Integer RETURN_STATUS_PART = 1;
  41 + /**
  42 + * 退货状态 - 全部
  43 + */
  44 + public static final Integer RETURN_STATUS_ALL = 2;
  45 +
  46 + @Schema(description = "采购单编号", example = "XS001")
  47 + private String no;
  48 +
  49 + @Schema(description = "供应商编号", example = "1724")
  50 + private Long supplierId;
  51 +
  52 + @Schema(description = "采购时间")
  53 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  54 + private LocalDateTime[] orderTime;
  55 +
  56 + @Schema(description = "备注", example = "你猜")
  57 + private String remark;
  58 +
  59 + @Schema(description = "采购状态", example = "2")
  60 + private Integer status;
  61 +
  62 + @Schema(description = "创建者")
  63 + private String creator;
  64 +
  65 + @Schema(description = "产品编号", example = "1")
  66 + private Long productId;
  67 +
  68 + @Schema(description = "入库状态", example = "2")
  69 + private Integer inStatus;
  70 +
  71 + @Schema(description = "退货状态", example = "2")
  72 + private Integer returnStatus;
  73 +
  74 + @Schema(description = "是否可入库", example = "true")
  75 + private Boolean inEnable;
  76 +
  77 + @Schema(description = "是否可退货", example = "true")
  78 + private Boolean returnEnable;
  79 +
  80 +}
0 \ No newline at end of file 81 \ No newline at end of file
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/order/ErpPurchaseOrderRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order;
  2 +
  3 +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
  4 +import com.alibaba.excel.annotation.ExcelProperty;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import jakarta.validation.constraints.NotNull;
  7 +import lombok.Data;
  8 +
  9 +import java.math.BigDecimal;
  10 +import java.time.LocalDateTime;
  11 +import java.util.List;
  12 +
  13 +@Schema(description = "管理后台 - ERP 采购订单 Response VO")
  14 +@Data
  15 +@ExcelIgnoreUnannotated
  16 +public class ErpPurchaseOrderRespVO {
  17 +
  18 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17386")
  19 + @ExcelProperty("编号")
  20 + private Long id;
  21 +
  22 + @Schema(description = "采购单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "XS001")
  23 + @ExcelProperty("采购单编号")
  24 + private String no;
  25 +
  26 + @Schema(description = "采购状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  27 + @ExcelProperty("采购状态")
  28 + private Integer status;
  29 +
  30 + @Schema(description = "供应商编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1724")
  31 + private Long supplierId;
  32 + @Schema(description = "供应商名称", example = "芋道")
  33 + @ExcelProperty("供应商名称")
  34 + private String supplierName;
  35 +
  36 + @Schema(description = "结算账户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "311.89")
  37 + @ExcelProperty("结算账户编号")
  38 + private Long accountId;
  39 +
  40 + @Schema(description = "采购时间", requiredMode = Schema.RequiredMode.REQUIRED)
  41 + @ExcelProperty("采购时间")
  42 + private LocalDateTime orderTime;
  43 +
  44 + @Schema(description = "合计数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "15663")
  45 + @ExcelProperty("合计数量")
  46 + private BigDecimal totalCount;
  47 + @Schema(description = "最终合计价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "24906")
  48 + @ExcelProperty("最终合计价格")
  49 + private BigDecimal totalPrice;
  50 +
  51 + @Schema(description = "合计产品价格,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127")
  52 + private BigDecimal totalProductPrice;
  53 +
  54 + @Schema(description = "合计税额,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127")
  55 + private BigDecimal totalTaxPrice;
  56 +
  57 + @Schema(description = "优惠率,百分比", requiredMode = Schema.RequiredMode.REQUIRED, example = "99.88")
  58 + private BigDecimal discountPercent;
  59 +
  60 + @Schema(description = "优惠金额,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127")
  61 + private BigDecimal discountPrice;
  62 +
  63 + @Schema(description = "定金金额,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127")
  64 + private BigDecimal depositPrice;
  65 +
  66 + @Schema(description = "附件地址", example = "https://www.iocoder.cn")
  67 + @ExcelProperty("附件地址")
  68 + private String fileUrl;
  69 +
  70 + @Schema(description = "备注", example = "你猜")
  71 + @ExcelProperty("备注")
  72 + private String remark;
  73 +
  74 + @Schema(description = "创建人", example = "芋道")
  75 + private String creator;
  76 + @Schema(description = "创建人名称", example = "芋道")
  77 + private String creatorName;
  78 +
  79 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  80 + @ExcelProperty("创建时间")
  81 + private LocalDateTime createTime;
  82 +
  83 + @Schema(description = "订单项列表", requiredMode = Schema.RequiredMode.REQUIRED)
  84 + private List<Item> items;
  85 +
  86 + @Schema(description = "产品信息", requiredMode = Schema.RequiredMode.REQUIRED)
  87 + @ExcelProperty("产品信息")
  88 + private String productNames;
  89 +
  90 + // ========== 采购出库 ==========
  91 +
  92 + @Schema(description = "采购出库数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  93 + private BigDecimal outCount;
  94 +
  95 + // ========== 采购退货(出库)) ==========
  96 +
  97 + @Schema(description = "采购退货数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  98 + private BigDecimal returnCount;
  99 +
  100 + @Data
  101 + public static class Item {
  102 +
  103 + @Schema(description = "订单项编号", example = "11756")
  104 + private Long id;
  105 +
  106 + @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
  107 + private Long productId;
  108 +
  109 + @Schema(description = "产品单位单位", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
  110 + private Long productUnitId;
  111 +
  112 + @Schema(description = "产品单价", example = "100.00")
  113 + private BigDecimal productPrice;
  114 +
  115 + @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  116 + @NotNull(message = "产品数量不能为空")
  117 + private BigDecimal count;
  118 +
  119 + @Schema(description = "税率,百分比", example = "99.88")
  120 + private BigDecimal taxPercent;
  121 +
  122 + @Schema(description = "税额,单位:元", example = "100.00")
  123 + private BigDecimal taxPrice;
  124 +
  125 + @Schema(description = "备注", example = "随便")
  126 + private String remark;
  127 +
  128 + // ========== 采购出库 ==========
  129 +
  130 + @Schema(description = "采购出库数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  131 + private BigDecimal outCount;
  132 +
  133 + // ========== 采购退货(入库)) ==========
  134 +
  135 + @Schema(description = "采购退货数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  136 + private BigDecimal returnCount;
  137 +
  138 + // ========== 关联字段 ==========
  139 +
  140 + @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "巧克力")
  141 + private String productName;
  142 + @Schema(description = "产品条码", requiredMode = Schema.RequiredMode.REQUIRED, example = "A9985")
  143 + private String productBarCode;
  144 + @Schema(description = "产品单位名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "盒")
  145 + private String productUnitName;
  146 +
  147 + @Schema(description = "库存数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  148 + private BigDecimal stockCount; // 该字段仅仅在“详情”和“编辑”时使用
  149 +
  150 + }
  151 +
  152 +}
0 \ No newline at end of file 153 \ No newline at end of file
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/order/ErpPurchaseOrderSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotNull;
  5 +import lombok.Data;
  6 +
  7 +import java.math.BigDecimal;
  8 +import java.time.LocalDateTime;
  9 +import java.util.List;
  10 +
  11 +@Schema(description = "管理后台 - ERP 采购订单新增/修改 Request VO")
  12 +@Data
  13 +public class ErpPurchaseOrderSaveReqVO {
  14 +
  15 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17386")
  16 + private Long id;
  17 +
  18 + @Schema(description = "供应商编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1724")
  19 + @NotNull(message = "供应商编号不能为空")
  20 + private Long supplierId;
  21 +
  22 + @Schema(description = "结算账户编号", example = "31189")
  23 + private Long accountId;
  24 +
  25 + @Schema(description = "采购时间", requiredMode = Schema.RequiredMode.REQUIRED)
  26 + @NotNull(message = "采购时间不能为空")
  27 + private LocalDateTime orderTime;
  28 +
  29 + @Schema(description = "优惠率,百分比", requiredMode = Schema.RequiredMode.REQUIRED, example = "99.88")
  30 + private BigDecimal discountPercent;
  31 +
  32 + @Schema(description = "定金金额,单位:元", example = "7127")
  33 + private BigDecimal depositPrice;
  34 +
  35 + @Schema(description = "附件地址", example = "https://www.iocoder.cn")
  36 + private String fileUrl;
  37 +
  38 + @Schema(description = "备注", example = "你猜")
  39 + private String remark;
  40 +
  41 + @Schema(description = "订单清单列表")
  42 + private List<Item> items;
  43 +
  44 + @Data
  45 + public static class Item {
  46 +
  47 + @Schema(description = "订单项编号", example = "11756")
  48 + private Long id;
  49 +
  50 + @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
  51 + @NotNull(message = "产品编号不能为空")
  52 + private Long productId;
  53 +
  54 + @Schema(description = "产品单位单位", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
  55 + @NotNull(message = "产品单位单位不能为空")
  56 + private Long productUnitId;
  57 +
  58 + @Schema(description = "产品单价", example = "100.00")
  59 + private BigDecimal productPrice;
  60 +
  61 + @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  62 + @NotNull(message = "产品数量不能为空")
  63 + private BigDecimal count;
  64 +
  65 + @Schema(description = "税率,百分比", example = "99.88")
  66 + private BigDecimal taxPercent;
  67 +
  68 + @Schema(description = "备注", example = "随便")
  69 + private String remark;
  70 +
  71 + }
  72 +
  73 +}
0 \ No newline at end of file 74 \ No newline at end of file
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpSaleOrderController.java
@@ -62,14 +62,14 @@ public class ErpSaleOrderController { @@ -62,14 +62,14 @@ public class ErpSaleOrderController {
62 62
63 @PostMapping("/create") 63 @PostMapping("/create")
64 @Operation(summary = "创建销售订单") 64 @Operation(summary = "创建销售订单")
65 - @PreAuthorize("@ss.hasPermission('erp:stock-out:create')") 65 + @PreAuthorize("@ss.hasPermission('erp:sale-out:create')")
66 public CommonResult<Long> createSaleOrder(@Valid @RequestBody ErpSaleOrderSaveReqVO createReqVO) { 66 public CommonResult<Long> createSaleOrder(@Valid @RequestBody ErpSaleOrderSaveReqVO createReqVO) {
67 return success(saleOrderService.createSaleOrder(createReqVO)); 67 return success(saleOrderService.createSaleOrder(createReqVO));
68 } 68 }
69 69
70 @PutMapping("/update") 70 @PutMapping("/update")
71 @Operation(summary = "更新销售订单") 71 @Operation(summary = "更新销售订单")
72 - @PreAuthorize("@ss.hasPermission('erp:stock-out:update')") 72 + @PreAuthorize("@ss.hasPermission('erp:sale-out:update')")
73 public CommonResult<Boolean> updateSaleOrder(@Valid @RequestBody ErpSaleOrderSaveReqVO updateReqVO) { 73 public CommonResult<Boolean> updateSaleOrder(@Valid @RequestBody ErpSaleOrderSaveReqVO updateReqVO) {
74 saleOrderService.updateSaleOrder(updateReqVO); 74 saleOrderService.updateSaleOrder(updateReqVO);
75 return success(true); 75 return success(true);
@@ -77,7 +77,7 @@ public class ErpSaleOrderController { @@ -77,7 +77,7 @@ public class ErpSaleOrderController {
77 77
78 @PutMapping("/update-status") 78 @PutMapping("/update-status")
79 @Operation(summary = "更新销售订单的状态") 79 @Operation(summary = "更新销售订单的状态")
80 - @PreAuthorize("@ss.hasPermission('erp:stock-out:update-status')") 80 + @PreAuthorize("@ss.hasPermission('erp:sale-out:update-status')")
81 public CommonResult<Boolean> updateSaleOrderStatus(@RequestParam("id") Long id, 81 public CommonResult<Boolean> updateSaleOrderStatus(@RequestParam("id") Long id,
82 @RequestParam("status") Integer status) { 82 @RequestParam("status") Integer status) {
83 saleOrderService.updateSaleOrderStatus(id, status); 83 saleOrderService.updateSaleOrderStatus(id, status);
@@ -87,7 +87,7 @@ public class ErpSaleOrderController { @@ -87,7 +87,7 @@ public class ErpSaleOrderController {
87 @DeleteMapping("/delete") 87 @DeleteMapping("/delete")
88 @Operation(summary = "删除销售订单") 88 @Operation(summary = "删除销售订单")
89 @Parameter(name = "ids", description = "编号数组", required = true) 89 @Parameter(name = "ids", description = "编号数组", required = true)
90 - @PreAuthorize("@ss.hasPermission('erp:stock-out:delete')") 90 + @PreAuthorize("@ss.hasPermission('erp:sale-out:delete')")
91 public CommonResult<Boolean> deleteSaleOrder(@RequestParam("ids") List<Long> ids) { 91 public CommonResult<Boolean> deleteSaleOrder(@RequestParam("ids") List<Long> ids) {
92 saleOrderService.deleteSaleOrder(ids); 92 saleOrderService.deleteSaleOrder(ids);
93 return success(true); 93 return success(true);
@@ -96,7 +96,7 @@ public class ErpSaleOrderController { @@ -96,7 +96,7 @@ public class ErpSaleOrderController {
96 @GetMapping("/get") 96 @GetMapping("/get")
97 @Operation(summary = "获得销售订单") 97 @Operation(summary = "获得销售订单")
98 @Parameter(name = "id", description = "编号", required = true, example = "1024") 98 @Parameter(name = "id", description = "编号", required = true, example = "1024")
99 - @PreAuthorize("@ss.hasPermission('erp:stock-out:query')") 99 + @PreAuthorize("@ss.hasPermission('erp:sale-out:query')")
100 public CommonResult<ErpSaleOrderRespVO> getSaleOrder(@RequestParam("id") Long id) { 100 public CommonResult<ErpSaleOrderRespVO> getSaleOrder(@RequestParam("id") Long id) {
101 ErpSaleOrderDO saleOrder = saleOrderService.getSaleOrder(id); 101 ErpSaleOrderDO saleOrder = saleOrderService.getSaleOrder(id);
102 if (saleOrder == null) { 102 if (saleOrder == null) {
@@ -116,7 +116,7 @@ public class ErpSaleOrderController { @@ -116,7 +116,7 @@ public class ErpSaleOrderController {
116 116
117 @GetMapping("/page") 117 @GetMapping("/page")
118 @Operation(summary = "获得销售订单分页") 118 @Operation(summary = "获得销售订单分页")
119 - @PreAuthorize("@ss.hasPermission('erp:stock-out:query')") 119 + @PreAuthorize("@ss.hasPermission('erp:sale-out:query')")
120 public CommonResult<PageResult<ErpSaleOrderRespVO>> getSaleOrderPage(@Valid ErpSaleOrderPageReqVO pageReqVO) { 120 public CommonResult<PageResult<ErpSaleOrderRespVO>> getSaleOrderPage(@Valid ErpSaleOrderPageReqVO pageReqVO) {
121 PageResult<ErpSaleOrderDO> pageResult = saleOrderService.getSaleOrderPage(pageReqVO); 121 PageResult<ErpSaleOrderDO> pageResult = saleOrderService.getSaleOrderPage(pageReqVO);
122 return success(buildSaleOrderVOPageResult(pageResult)); 122 return success(buildSaleOrderVOPageResult(pageResult));
@@ -124,7 +124,7 @@ public class ErpSaleOrderController { @@ -124,7 +124,7 @@ public class ErpSaleOrderController {
124 124
125 @GetMapping("/export-excel") 125 @GetMapping("/export-excel")
126 @Operation(summary = "导出销售订单 Excel") 126 @Operation(summary = "导出销售订单 Excel")
127 - @PreAuthorize("@ss.hasPermission('erp:stock-out:export')") 127 + @PreAuthorize("@ss.hasPermission('erp:sale-out:export')")
128 @OperateLog(type = EXPORT) 128 @OperateLog(type = EXPORT)
129 public void exportSaleOrderExcel(@Valid ErpSaleOrderPageReqVO pageReqVO, 129 public void exportSaleOrderExcel(@Valid ErpSaleOrderPageReqVO pageReqVO,
130 HttpServletResponse response) throws IOException { 130 HttpServletResponse response) throws IOException {
@@ -142,7 +142,7 @@ public class ErpSaleOrderController { @@ -142,7 +142,7 @@ public class ErpSaleOrderController {
142 List<ErpSaleOrderItemDO> saleOrderItemList = saleOrderService.getSaleOrderItemListByOrderIds( 142 List<ErpSaleOrderItemDO> saleOrderItemList = saleOrderService.getSaleOrderItemListByOrderIds(
143 convertSet(pageResult.getList(), ErpSaleOrderDO::getId)); 143 convertSet(pageResult.getList(), ErpSaleOrderDO::getId));
144 Map<Long, List<ErpSaleOrderItemDO>> saleOrderItemMap = convertMultiMap(saleOrderItemList, ErpSaleOrderItemDO::getOrderId); 144 Map<Long, List<ErpSaleOrderItemDO>> saleOrderItemMap = convertMultiMap(saleOrderItemList, ErpSaleOrderItemDO::getOrderId);
145 - // 1.2 商品信息 145 + // 1.2 产品信息
146 Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap( 146 Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
147 convertSet(saleOrderItemList, ErpSaleOrderItemDO::getProductId)); 147 convertSet(saleOrderItemList, ErpSaleOrderItemDO::getProductId));
148 // 1.3 客户信息 148 // 1.3 客户信息
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpSaleOutController.java
@@ -62,14 +62,14 @@ public class ErpSaleOutController { @@ -62,14 +62,14 @@ public class ErpSaleOutController {
62 62
63 @PostMapping("/create") 63 @PostMapping("/create")
64 @Operation(summary = "创建销售出库") 64 @Operation(summary = "创建销售出库")
65 - @PreAuthorize("@ss.hasPermission('erp:stock-out:create')") 65 + @PreAuthorize("@ss.hasPermission('erp:sale-out:create')")
66 public CommonResult<Long> createSaleOut(@Valid @RequestBody ErpSaleOutSaveReqVO createReqVO) { 66 public CommonResult<Long> createSaleOut(@Valid @RequestBody ErpSaleOutSaveReqVO createReqVO) {
67 return success(saleOutService.createSaleOut(createReqVO)); 67 return success(saleOutService.createSaleOut(createReqVO));
68 } 68 }
69 69
70 @PutMapping("/update") 70 @PutMapping("/update")
71 @Operation(summary = "更新销售出库") 71 @Operation(summary = "更新销售出库")
72 - @PreAuthorize("@ss.hasPermission('erp:stock-out:update')") 72 + @PreAuthorize("@ss.hasPermission('erp:sale-out:update')")
73 public CommonResult<Boolean> updateSaleOut(@Valid @RequestBody ErpSaleOutSaveReqVO updateReqVO) { 73 public CommonResult<Boolean> updateSaleOut(@Valid @RequestBody ErpSaleOutSaveReqVO updateReqVO) {
74 saleOutService.updateSaleOut(updateReqVO); 74 saleOutService.updateSaleOut(updateReqVO);
75 return success(true); 75 return success(true);
@@ -77,7 +77,7 @@ public class ErpSaleOutController { @@ -77,7 +77,7 @@ public class ErpSaleOutController {
77 77
78 @PutMapping("/update-status") 78 @PutMapping("/update-status")
79 @Operation(summary = "更新销售出库的状态") 79 @Operation(summary = "更新销售出库的状态")
80 - @PreAuthorize("@ss.hasPermission('erp:stock-out:update-status')") 80 + @PreAuthorize("@ss.hasPermission('erp:sale-out:update-status')")
81 public CommonResult<Boolean> updateSaleOutStatus(@RequestParam("id") Long id, 81 public CommonResult<Boolean> updateSaleOutStatus(@RequestParam("id") Long id,
82 @RequestParam("status") Integer status) { 82 @RequestParam("status") Integer status) {
83 saleOutService.updateSaleOutStatus(id, status); 83 saleOutService.updateSaleOutStatus(id, status);
@@ -87,7 +87,7 @@ public class ErpSaleOutController { @@ -87,7 +87,7 @@ public class ErpSaleOutController {
87 @DeleteMapping("/delete") 87 @DeleteMapping("/delete")
88 @Operation(summary = "删除销售出库") 88 @Operation(summary = "删除销售出库")
89 @Parameter(name = "ids", description = "编号数组", required = true) 89 @Parameter(name = "ids", description = "编号数组", required = true)
90 - @PreAuthorize("@ss.hasPermission('erp:stock-out:delete')") 90 + @PreAuthorize("@ss.hasPermission('erp:sale-out:delete')")
91 public CommonResult<Boolean> deleteSaleOut(@RequestParam("ids") List<Long> ids) { 91 public CommonResult<Boolean> deleteSaleOut(@RequestParam("ids") List<Long> ids) {
92 saleOutService.deleteSaleOut(ids); 92 saleOutService.deleteSaleOut(ids);
93 return success(true); 93 return success(true);
@@ -96,7 +96,7 @@ public class ErpSaleOutController { @@ -96,7 +96,7 @@ public class ErpSaleOutController {
96 @GetMapping("/get") 96 @GetMapping("/get")
97 @Operation(summary = "获得销售出库") 97 @Operation(summary = "获得销售出库")
98 @Parameter(name = "id", description = "编号", required = true, example = "1024") 98 @Parameter(name = "id", description = "编号", required = true, example = "1024")
99 - @PreAuthorize("@ss.hasPermission('erp:stock-out:query')") 99 + @PreAuthorize("@ss.hasPermission('erp:sale-out:query')")
100 public CommonResult<ErpSaleOutRespVO> getSaleOut(@RequestParam("id") Long id) { 100 public CommonResult<ErpSaleOutRespVO> getSaleOut(@RequestParam("id") Long id) {
101 ErpSaleOutDO saleOut = saleOutService.getSaleOut(id); 101 ErpSaleOutDO saleOut = saleOutService.getSaleOut(id);
102 if (saleOut == null) { 102 if (saleOut == null) {
@@ -116,7 +116,7 @@ public class ErpSaleOutController { @@ -116,7 +116,7 @@ public class ErpSaleOutController {
116 116
117 @GetMapping("/page") 117 @GetMapping("/page")
118 @Operation(summary = "获得销售出库分页") 118 @Operation(summary = "获得销售出库分页")
119 - @PreAuthorize("@ss.hasPermission('erp:stock-out:query')") 119 + @PreAuthorize("@ss.hasPermission('erp:sale-out:query')")
120 public CommonResult<PageResult<ErpSaleOutRespVO>> getSaleOutPage(@Valid ErpSaleOutPageReqVO pageReqVO) { 120 public CommonResult<PageResult<ErpSaleOutRespVO>> getSaleOutPage(@Valid ErpSaleOutPageReqVO pageReqVO) {
121 PageResult<ErpSaleOutDO> pageResult = saleOutService.getSaleOutPage(pageReqVO); 121 PageResult<ErpSaleOutDO> pageResult = saleOutService.getSaleOutPage(pageReqVO);
122 return success(buildSaleOutVOPageResult(pageResult)); 122 return success(buildSaleOutVOPageResult(pageResult));
@@ -124,7 +124,7 @@ public class ErpSaleOutController { @@ -124,7 +124,7 @@ public class ErpSaleOutController {
124 124
125 @GetMapping("/export-excel") 125 @GetMapping("/export-excel")
126 @Operation(summary = "导出销售出库 Excel") 126 @Operation(summary = "导出销售出库 Excel")
127 - @PreAuthorize("@ss.hasPermission('erp:stock-out:export')") 127 + @PreAuthorize("@ss.hasPermission('erp:sale-out:export')")
128 @OperateLog(type = EXPORT) 128 @OperateLog(type = EXPORT)
129 public void exportSaleOutExcel(@Valid ErpSaleOutPageReqVO pageReqVO, 129 public void exportSaleOutExcel(@Valid ErpSaleOutPageReqVO pageReqVO,
130 HttpServletResponse response) throws IOException { 130 HttpServletResponse response) throws IOException {
@@ -142,7 +142,7 @@ public class ErpSaleOutController { @@ -142,7 +142,7 @@ public class ErpSaleOutController {
142 List<ErpSaleOutItemDO> saleOutItemList = saleOutService.getSaleOutItemListByOutIds( 142 List<ErpSaleOutItemDO> saleOutItemList = saleOutService.getSaleOutItemListByOutIds(
143 convertSet(pageResult.getList(), ErpSaleOutDO::getId)); 143 convertSet(pageResult.getList(), ErpSaleOutDO::getId));
144 Map<Long, List<ErpSaleOutItemDO>> saleOutItemMap = convertMultiMap(saleOutItemList, ErpSaleOutItemDO::getOutId); 144 Map<Long, List<ErpSaleOutItemDO>> saleOutItemMap = convertMultiMap(saleOutItemList, ErpSaleOutItemDO::getOutId);
145 - // 1.2 商品信息 145 + // 1.2 产品信息
146 Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap( 146 Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
147 convertSet(saleOutItemList, ErpSaleOutItemDO::getProductId)); 147 convertSet(saleOutItemList, ErpSaleOutItemDO::getProductId));
148 // 1.3 客户信息 148 // 1.3 客户信息
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpSaleReturnController.java
@@ -62,14 +62,14 @@ public class ErpSaleReturnController { @@ -62,14 +62,14 @@ public class ErpSaleReturnController {
62 62
63 @PostMapping("/create") 63 @PostMapping("/create")
64 @Operation(summary = "创建销售退货") 64 @Operation(summary = "创建销售退货")
65 - @PreAuthorize("@ss.hasPermission('erp:stock-return:create')") 65 + @PreAuthorize("@ss.hasPermission('erp:sale-return:create')")
66 public CommonResult<Long> createSaleReturn(@Valid @RequestBody ErpSaleReturnSaveReqVO createReqVO) { 66 public CommonResult<Long> createSaleReturn(@Valid @RequestBody ErpSaleReturnSaveReqVO createReqVO) {
67 return success(saleReturnService.createSaleReturn(createReqVO)); 67 return success(saleReturnService.createSaleReturn(createReqVO));
68 } 68 }
69 69
70 @PutMapping("/update") 70 @PutMapping("/update")
71 @Operation(summary = "更新销售退货") 71 @Operation(summary = "更新销售退货")
72 - @PreAuthorize("@ss.hasPermission('erp:stock-return:update')") 72 + @PreAuthorize("@ss.hasPermission('erp:sale-return:update')")
73 public CommonResult<Boolean> updateSaleReturn(@Valid @RequestBody ErpSaleReturnSaveReqVO updateReqVO) { 73 public CommonResult<Boolean> updateSaleReturn(@Valid @RequestBody ErpSaleReturnSaveReqVO updateReqVO) {
74 saleReturnService.updateSaleReturn(updateReqVO); 74 saleReturnService.updateSaleReturn(updateReqVO);
75 return success(true); 75 return success(true);
@@ -77,7 +77,7 @@ public class ErpSaleReturnController { @@ -77,7 +77,7 @@ public class ErpSaleReturnController {
77 77
78 @PutMapping("/update-status") 78 @PutMapping("/update-status")
79 @Operation(summary = "更新销售退货的状态") 79 @Operation(summary = "更新销售退货的状态")
80 - @PreAuthorize("@ss.hasPermission('erp:stock-return:update-status')") 80 + @PreAuthorize("@ss.hasPermission('erp:sale-return:update-status')")
81 public CommonResult<Boolean> updateSaleReturnStatus(@RequestParam("id") Long id, 81 public CommonResult<Boolean> updateSaleReturnStatus(@RequestParam("id") Long id,
82 @RequestParam("status") Integer status) { 82 @RequestParam("status") Integer status) {
83 saleReturnService.updateSaleReturnStatus(id, status); 83 saleReturnService.updateSaleReturnStatus(id, status);
@@ -87,7 +87,7 @@ public class ErpSaleReturnController { @@ -87,7 +87,7 @@ public class ErpSaleReturnController {
87 @DeleteMapping("/delete") 87 @DeleteMapping("/delete")
88 @Operation(summary = "删除销售退货") 88 @Operation(summary = "删除销售退货")
89 @Parameter(name = "ids", description = "编号数组", required = true) 89 @Parameter(name = "ids", description = "编号数组", required = true)
90 - @PreAuthorize("@ss.hasPermission('erp:stock-return:delete')") 90 + @PreAuthorize("@ss.hasPermission('erp:sale-return:delete')")
91 public CommonResult<Boolean> deleteSaleReturn(@RequestParam("ids") List<Long> ids) { 91 public CommonResult<Boolean> deleteSaleReturn(@RequestParam("ids") List<Long> ids) {
92 saleReturnService.deleteSaleReturn(ids); 92 saleReturnService.deleteSaleReturn(ids);
93 return success(true); 93 return success(true);
@@ -96,7 +96,7 @@ public class ErpSaleReturnController { @@ -96,7 +96,7 @@ public class ErpSaleReturnController {
96 @GetMapping("/get") 96 @GetMapping("/get")
97 @Operation(summary = "获得销售退货") 97 @Operation(summary = "获得销售退货")
98 @Parameter(name = "id", description = "编号", required = true, example = "1024") 98 @Parameter(name = "id", description = "编号", required = true, example = "1024")
99 - @PreAuthorize("@ss.hasPermission('erp:stock-return:query')") 99 + @PreAuthorize("@ss.hasPermission('erp:sale-return:query')")
100 public CommonResult<ErpSaleReturnRespVO> getSaleReturn(@RequestParam("id") Long id) { 100 public CommonResult<ErpSaleReturnRespVO> getSaleReturn(@RequestParam("id") Long id) {
101 ErpSaleReturnDO saleReturn = saleReturnService.getSaleReturn(id); 101 ErpSaleReturnDO saleReturn = saleReturnService.getSaleReturn(id);
102 if (saleReturn == null) { 102 if (saleReturn == null) {
@@ -116,7 +116,7 @@ public class ErpSaleReturnController { @@ -116,7 +116,7 @@ public class ErpSaleReturnController {
116 116
117 @GetMapping("/page") 117 @GetMapping("/page")
118 @Operation(summary = "获得销售退货分页") 118 @Operation(summary = "获得销售退货分页")
119 - @PreAuthorize("@ss.hasPermission('erp:stock-return:query')") 119 + @PreAuthorize("@ss.hasPermission('erp:sale-return:query')")
120 public CommonResult<PageResult<ErpSaleReturnRespVO>> getSaleReturnPage(@Valid ErpSaleReturnPageReqVO pageReqVO) { 120 public CommonResult<PageResult<ErpSaleReturnRespVO>> getSaleReturnPage(@Valid ErpSaleReturnPageReqVO pageReqVO) {
121 PageResult<ErpSaleReturnDO> pageResult = saleReturnService.getSaleReturnPage(pageReqVO); 121 PageResult<ErpSaleReturnDO> pageResult = saleReturnService.getSaleReturnPage(pageReqVO);
122 return success(buildSaleReturnVOPageResult(pageResult)); 122 return success(buildSaleReturnVOPageResult(pageResult));
@@ -124,7 +124,7 @@ public class ErpSaleReturnController { @@ -124,7 +124,7 @@ public class ErpSaleReturnController {
124 124
125 @GetMapping("/export-excel") 125 @GetMapping("/export-excel")
126 @Operation(summary = "导出销售退货 Excel") 126 @Operation(summary = "导出销售退货 Excel")
127 - @PreAuthorize("@ss.hasPermission('erp:stock-return:export')") 127 + @PreAuthorize("@ss.hasPermission('erp:sale-return:export')")
128 @OperateLog(type = EXPORT) 128 @OperateLog(type = EXPORT)
129 public void exportSaleReturnExcel(@Valid ErpSaleReturnPageReqVO pageReqVO, 129 public void exportSaleReturnExcel(@Valid ErpSaleReturnPageReqVO pageReqVO,
130 HttpServletResponse response) throws IOException { 130 HttpServletResponse response) throws IOException {
@@ -142,7 +142,7 @@ public class ErpSaleReturnController { @@ -142,7 +142,7 @@ public class ErpSaleReturnController {
142 List<ErpSaleReturnItemDO> saleReturnItemList = saleReturnService.getSaleReturnItemListByReturnIds( 142 List<ErpSaleReturnItemDO> saleReturnItemList = saleReturnService.getSaleReturnItemListByReturnIds(
143 convertSet(pageResult.getList(), ErpSaleReturnDO::getId)); 143 convertSet(pageResult.getList(), ErpSaleReturnDO::getId));
144 Map<Long, List<ErpSaleReturnItemDO>> saleReturnItemMap = convertMultiMap(saleReturnItemList, ErpSaleReturnItemDO::getReturnId); 144 Map<Long, List<ErpSaleReturnItemDO>> saleReturnItemMap = convertMultiMap(saleReturnItemList, ErpSaleReturnItemDO::getReturnId);
145 - // 1.2 商品信息 145 + // 1.2 产品信息
146 Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap( 146 Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
147 convertSet(saleReturnItemList, ErpSaleReturnItemDO::getProductId)); 147 convertSet(saleReturnItemList, ErpSaleReturnItemDO::getProductId));
148 // 1.3 客户信息 148 // 1.3 客户信息
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/order/ErpSaleOrderPageReqVO.java
@@ -18,17 +18,17 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @@ -18,17 +18,17 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
18 public class ErpSaleOrderPageReqVO extends PageParam { 18 public class ErpSaleOrderPageReqVO extends PageParam {
19 19
20 /** 20 /**
21 - * 入库状态 - 无 21 + * 出库状态 - 无
22 */ 22 */
23 - public static final Integer IN_STATUS_NONE = 0; 23 + public static final Integer OUT_STATUS_NONE = 0;
24 /** 24 /**
25 - * 入库状态 - 部分 25 + * 出库状态 - 部分
26 */ 26 */
27 - public static final Integer IN_STATUS_PART = 1; 27 + public static final Integer OUT_STATUS_PART = 1;
28 /** 28 /**
29 - * 入库状态 - 全部 29 + * 出库状态 - 全部
30 */ 30 */
31 - public static final Integer IN_STATUS_ALL = 2; 31 + public static final Integer OUT_STATUS_ALL = 2;
32 32
33 /** 33 /**
34 * 退货状态 - 无 34 * 退货状态 - 无
@@ -65,8 +65,8 @@ public class ErpSaleOrderPageReqVO extends PageParam { @@ -65,8 +65,8 @@ public class ErpSaleOrderPageReqVO extends PageParam {
65 @Schema(description = "产品编号", example = "1") 65 @Schema(description = "产品编号", example = "1")
66 private Long productId; 66 private Long productId;
67 67
68 - @Schema(description = "入库状态", example = "2")  
69 - private Integer inStatus; 68 + @Schema(description = "出库状态", example = "2")
  69 + private Integer outStatus;
70 70
71 @Schema(description = "退货状态", example = "2") 71 @Schema(description = "退货状态", example = "2")
72 private Integer returnStatus; 72 private Integer returnStatus;
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/order/ErpSaleOrderRespVO.java
@@ -74,9 +74,9 @@ public class ErpSaleOrderRespVO { @@ -74,9 +74,9 @@ public class ErpSaleOrderRespVO {
74 @ExcelProperty("备注") 74 @ExcelProperty("备注")
75 private String remark; 75 private String remark;
76 76
77 - @Schema(description = "审核人", example = "芋道") 77 + @Schema(description = "创建人", example = "芋道")
78 private String creator; 78 private String creator;
79 - @Schema(description = "审核人名称", example = "芋道") 79 + @Schema(description = "创建人名称", example = "芋道")
80 private String creatorName; 80 private String creatorName;
81 81
82 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 82 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@@ -133,7 +133,7 @@ public class ErpSaleOrderRespVO { @@ -133,7 +133,7 @@ public class ErpSaleOrderRespVO {
133 @Schema(description = "销售出库数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00") 133 @Schema(description = "销售出库数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
134 private BigDecimal outCount; 134 private BigDecimal outCount;
135 135
136 - // ========== 销售退货(出库)) ========== 136 + // ========== 销售退货(入库)) ==========
137 137
138 @Schema(description = "销售退货数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00") 138 @Schema(description = "销售退货数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
139 private BigDecimal returnCount; 139 private BigDecimal returnCount;
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/out/ErpSaleOutRespVO.java
@@ -85,9 +85,9 @@ public class ErpSaleOutRespVO { @@ -85,9 +85,9 @@ public class ErpSaleOutRespVO {
85 @ExcelProperty("备注") 85 @ExcelProperty("备注")
86 private String remark; 86 private String remark;
87 87
88 - @Schema(description = "审核人", example = "芋道") 88 + @Schema(description = "创建人", example = "芋道")
89 private String creator; 89 private String creator;
90 - @Schema(description = "审核人名称", example = "芋道") 90 + @Schema(description = "创建人名称", example = "芋道")
91 private String creatorName; 91 private String creatorName;
92 92
93 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 93 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/returns/ErpSaleReturnRespVO.java
@@ -85,9 +85,9 @@ public class ErpSaleReturnRespVO { @@ -85,9 +85,9 @@ public class ErpSaleReturnRespVO {
85 @ExcelProperty("备注") 85 @ExcelProperty("备注")
86 private String remark; 86 private String remark;
87 87
88 - @Schema(description = "审核人", example = "芋道") 88 + @Schema(description = "创建人", example = "芋道")
89 private String creator; 89 private String creator;
90 - @Schema(description = "审核人名称", example = "芋道") 90 + @Schema(description = "创建人名称", example = "芋道")
91 private String creatorName; 91 private String creatorName;
92 92
93 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 93 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockCheckController.java
@@ -130,7 +130,7 @@ public class ErpStockCheckController { @@ -130,7 +130,7 @@ public class ErpStockCheckController {
130 List<ErpStockCheckItemDO> stockCheckItemList = stockCheckService.getStockCheckItemListByCheckIds( 130 List<ErpStockCheckItemDO> stockCheckItemList = stockCheckService.getStockCheckItemListByCheckIds(
131 convertSet(pageResult.getList(), ErpStockCheckDO::getId)); 131 convertSet(pageResult.getList(), ErpStockCheckDO::getId));
132 Map<Long, List<ErpStockCheckItemDO>> stockCheckItemMap = convertMultiMap(stockCheckItemList, ErpStockCheckItemDO::getCheckId); 132 Map<Long, List<ErpStockCheckItemDO>> stockCheckItemMap = convertMultiMap(stockCheckItemList, ErpStockCheckItemDO::getCheckId);
133 - // 1.2 商品信息 133 + // 1.2 产品信息
134 Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap( 134 Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
135 convertSet(stockCheckItemList, ErpStockCheckItemDO::getProductId)); 135 convertSet(stockCheckItemList, ErpStockCheckItemDO::getProductId));
136 // 1.3 管理员信息 136 // 1.3 管理员信息
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockInController.java
@@ -142,7 +142,7 @@ public class ErpStockInController { @@ -142,7 +142,7 @@ public class ErpStockInController {
142 List<ErpStockInItemDO> stockInItemList = stockInService.getStockInItemListByInIds( 142 List<ErpStockInItemDO> stockInItemList = stockInService.getStockInItemListByInIds(
143 convertSet(pageResult.getList(), ErpStockInDO::getId)); 143 convertSet(pageResult.getList(), ErpStockInDO::getId));
144 Map<Long, List<ErpStockInItemDO>> stockInItemMap = convertMultiMap(stockInItemList, ErpStockInItemDO::getInId); 144 Map<Long, List<ErpStockInItemDO>> stockInItemMap = convertMultiMap(stockInItemList, ErpStockInItemDO::getInId);
145 - // 1.2 商品信息 145 + // 1.2 产品信息
146 Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap( 146 Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
147 convertSet(stockInItemList, ErpStockInItemDO::getProductId)); 147 convertSet(stockInItemList, ErpStockInItemDO::getProductId));
148 // 1.3 供应商信息 148 // 1.3 供应商信息
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockMoveController.java
@@ -138,7 +138,7 @@ public class ErpStockMoveController { @@ -138,7 +138,7 @@ public class ErpStockMoveController {
138 List<ErpStockMoveItemDO> stockMoveItemList = stockMoveService.getStockMoveItemListByMoveIds( 138 List<ErpStockMoveItemDO> stockMoveItemList = stockMoveService.getStockMoveItemListByMoveIds(
139 convertSet(pageResult.getList(), ErpStockMoveDO::getId)); 139 convertSet(pageResult.getList(), ErpStockMoveDO::getId));
140 Map<Long, List<ErpStockMoveItemDO>> stockMoveItemMap = convertMultiMap(stockMoveItemList, ErpStockMoveItemDO::getMoveId); 140 Map<Long, List<ErpStockMoveItemDO>> stockMoveItemMap = convertMultiMap(stockMoveItemList, ErpStockMoveItemDO::getMoveId);
141 - // 1.2 商品信息 141 + // 1.2 产品信息
142 Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap( 142 Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
143 convertSet(stockMoveItemList, ErpStockMoveItemDO::getProductId)); 143 convertSet(stockMoveItemList, ErpStockMoveItemDO::getProductId));
144 // 1.3 TODO 芋艿:搞仓库信息 144 // 1.3 TODO 芋艿:搞仓库信息
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockOutController.java
@@ -142,7 +142,7 @@ public class ErpStockOutController { @@ -142,7 +142,7 @@ public class ErpStockOutController {
142 List<ErpStockOutItemDO> stockOutItemList = stockOutService.getStockOutItemListByOutIds( 142 List<ErpStockOutItemDO> stockOutItemList = stockOutService.getStockOutItemListByOutIds(
143 convertSet(pageResult.getList(), ErpStockOutDO::getId)); 143 convertSet(pageResult.getList(), ErpStockOutDO::getId));
144 Map<Long, List<ErpStockOutItemDO>> stockOutItemMap = convertMultiMap(stockOutItemList, ErpStockOutItemDO::getOutId); 144 Map<Long, List<ErpStockOutItemDO>> stockOutItemMap = convertMultiMap(stockOutItemList, ErpStockOutItemDO::getOutId);
145 - // 1.2 商品信息 145 + // 1.2 产品信息
146 Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap( 146 Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
147 convertSet(stockOutItemList, ErpStockOutItemDO::getProductId)); 147 convertSet(stockOutItemList, ErpStockOutItemDO::getProductId));
148 // 1.3 客户信息 148 // 1.3 客户信息
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/check/ErpStockCheckRespVO.java
@@ -51,9 +51,9 @@ public class ErpStockCheckRespVO { @@ -51,9 +51,9 @@ public class ErpStockCheckRespVO {
51 @Schema(description = "附件 URL", example = "https://www.iocoder.cn/1.doc") 51 @Schema(description = "附件 URL", example = "https://www.iocoder.cn/1.doc")
52 private String fileUrl; 52 private String fileUrl;
53 53
54 - @Schema(description = "审核人", example = "芋道") 54 + @Schema(description = "创建人", example = "芋道")
55 private String creator; 55 private String creator;
56 - @Schema(description = "审核人名称", example = "芋道") 56 + @Schema(description = "创建人名称", example = "芋道")
57 private String creatorName; 57 private String creatorName;
58 58
59 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 59 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/in/ErpStockInRespVO.java
@@ -56,9 +56,9 @@ public class ErpStockInRespVO { @@ -56,9 +56,9 @@ public class ErpStockInRespVO {
56 @Schema(description = "附件 URL", example = "https://www.iocoder.cn/1.doc") 56 @Schema(description = "附件 URL", example = "https://www.iocoder.cn/1.doc")
57 private String fileUrl; 57 private String fileUrl;
58 58
59 - @Schema(description = "审核人", example = "芋道") 59 + @Schema(description = "创建人", example = "芋道")
60 private String creator; 60 private String creator;
61 - @Schema(description = "审核人名称", example = "芋道") 61 + @Schema(description = "创建人名称", example = "芋道")
62 private String creatorName; 62 private String creatorName;
63 63
64 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 64 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/move/ErpStockMoveRespVO.java
@@ -50,9 +50,9 @@ public class ErpStockMoveRespVO { @@ -50,9 +50,9 @@ public class ErpStockMoveRespVO {
50 @Schema(description = "附件 URL", example = "https://www.iocoder.cn/1.doc") 50 @Schema(description = "附件 URL", example = "https://www.iocoder.cn/1.doc")
51 private String fileUrl; 51 private String fileUrl;
52 52
53 - @Schema(description = "审核人", example = "芋道") 53 + @Schema(description = "创建人", example = "芋道")
54 private String creator; 54 private String creator;
55 - @Schema(description = "审核人名称", example = "芋道") 55 + @Schema(description = "创建人名称", example = "芋道")
56 private String creatorName; 56 private String creatorName;
57 57
58 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 58 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/out/ErpStockOutRespVO.java
@@ -56,9 +56,9 @@ public class ErpStockOutRespVO { @@ -56,9 +56,9 @@ public class ErpStockOutRespVO {
56 @Schema(description = "附件 URL", example = "https://www.iocoder.cn/1.doc") 56 @Schema(description = "附件 URL", example = "https://www.iocoder.cn/1.doc")
57 private String fileUrl; 57 private String fileUrl;
58 58
59 - @Schema(description = "审核人", example = "芋道") 59 + @Schema(description = "创建人", example = "芋道")
60 private String creator; 60 private String creator;
61 - @Schema(description = "审核人名称", example = "芋道") 61 + @Schema(description = "创建人名称", example = "芋道")
62 private String creatorName; 62 private String creatorName;
63 63
64 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 64 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/purchase/ErpPurchaseOrderDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.dataobject.purchase;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpAccountDO;
  5 +import com.baomidou.mybatisplus.annotation.KeySequence;
  6 +import com.baomidou.mybatisplus.annotation.TableId;
  7 +import com.baomidou.mybatisplus.annotation.TableName;
  8 +import lombok.*;
  9 +
  10 +import java.math.BigDecimal;
  11 +import java.time.LocalDateTime;
  12 +
  13 +/**
  14 + * ERP 采购订单 DO
  15 + *
  16 + * @author 芋道源码
  17 + */
  18 +@TableName(value = "erp_purchase_order")
  19 +@KeySequence("erp_purchase_order_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  20 +@Data
  21 +@EqualsAndHashCode(callSuper = true)
  22 +@ToString(callSuper = true)
  23 +@Builder
  24 +@NoArgsConstructor
  25 +@AllArgsConstructor
  26 +public class ErpPurchaseOrderDO extends BaseDO {
  27 +
  28 + /**
  29 + * 编号
  30 + */
  31 + @TableId
  32 + private Long id;
  33 + /**
  34 + * 采购订单号
  35 + */
  36 + private String no;
  37 + /**
  38 + * 采购状态
  39 + *
  40 + * 枚举 {@link cn.iocoder.yudao.module.erp.enums.ErpAuditStatus}
  41 + */
  42 + private Integer status;
  43 + /**
  44 + * 供应商编号
  45 + *
  46 + * 关联 {@link ErpSupplierDO#getId()}
  47 + */
  48 + private Long supplierId;
  49 + /**
  50 + * 结算账户编号
  51 + *
  52 + * 关联 {@link ErpAccountDO#getId()}
  53 + */
  54 + private Long accountId;
  55 + /**
  56 + * 下单时间
  57 + */
  58 + private LocalDateTime orderTime;
  59 +
  60 + /**
  61 + * 合计数量
  62 + */
  63 + private BigDecimal totalCount;
  64 + /**
  65 + * 最终合计价格,单位:元
  66 + *
  67 + * totalPrice = totalProductPrice + totalTaxPrice - discountPrice
  68 + */
  69 + private BigDecimal totalPrice;
  70 +
  71 + /**
  72 + * 合计产品价格,单位:元
  73 + */
  74 + private BigDecimal totalProductPrice;
  75 + /**
  76 + * 合计税额,单位:元
  77 + */
  78 + private BigDecimal totalTaxPrice;
  79 + /**
  80 + * 优惠率,百分比
  81 + */
  82 + private BigDecimal discountPercent;
  83 + /**
  84 + * 优惠金额,单位:元
  85 + *
  86 + * discountPrice = (totalProductPrice + totalTaxPrice) * discountPercent
  87 + */
  88 + private BigDecimal discountPrice;
  89 + /**
  90 + * 定金金额,单位:元
  91 + */
  92 + private BigDecimal depositPrice;
  93 +
  94 + /**
  95 + * 附件地址
  96 + */
  97 + private String fileUrl;
  98 + /**
  99 + * 备注
  100 + */
  101 + private String remark;
  102 +
  103 + // ========== 采购入库 ==========
  104 + /**
  105 + * 采购入库数量
  106 + */
  107 + private BigDecimal inCount;
  108 +
  109 + // ========== 采购退货(出库)) ==========
  110 + /**
  111 + * 采购退货数量
  112 + */
  113 + private BigDecimal returnCount;
  114 +
  115 +}
0 \ No newline at end of file 116 \ No newline at end of file
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/purchase/ErpPurchaseOrderItemDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.dataobject.purchase;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
  5 +import com.baomidou.mybatisplus.annotation.KeySequence;
  6 +import com.baomidou.mybatisplus.annotation.TableId;
  7 +import com.baomidou.mybatisplus.annotation.TableName;
  8 +import lombok.*;
  9 +
  10 +import java.math.BigDecimal;
  11 +
  12 +/**
  13 + * ERP 采购订单项 DO
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@TableName("erp_sale_order_items")
  18 +@KeySequence("erp_sale_order_items_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  19 +@Data
  20 +@EqualsAndHashCode(callSuper = true)
  21 +@ToString(callSuper = true)
  22 +@Builder
  23 +@NoArgsConstructor
  24 +@AllArgsConstructor
  25 +public class ErpPurchaseOrderItemDO extends BaseDO {
  26 +
  27 + /**
  28 + * 编号
  29 + */
  30 + @TableId
  31 + private Long id;
  32 + /**
  33 + * 采购订单编号
  34 + *
  35 + * 关联 {@link ErpPurchaseOrderDO#getId()}
  36 + */
  37 + private Long orderId;
  38 + /**
  39 + * 产品编号
  40 + *
  41 + * 关联 {@link ErpProductDO#getId()}
  42 + */
  43 + private Long productId;
  44 + /**
  45 + * 产品单位单位
  46 + *
  47 + * 冗余 {@link ErpProductDO#getUnitId()}
  48 + */
  49 + private Long productUnitId;
  50 +
  51 + /**
  52 + * 产品单位单价,单位:元
  53 + */
  54 + private BigDecimal productPrice;
  55 + /**
  56 + * 数量
  57 + */
  58 + private BigDecimal count;
  59 + /**
  60 + * 总价,单位:元
  61 + *
  62 + * totalPrice = productPrice * count
  63 + */
  64 + private BigDecimal totalPrice;
  65 + /**
  66 + * 税率,百分比
  67 + */
  68 + private BigDecimal taxPercent;
  69 + /**
  70 + * 税额,单位:元
  71 + *
  72 + * taxPrice = totalPrice * taxPercent
  73 + */
  74 + private BigDecimal taxPrice;
  75 +
  76 + /**
  77 + * 备注
  78 + */
  79 + private String remark;
  80 +
  81 + // ========== 采购入库 ==========
  82 + /**
  83 + * 采购入库数量
  84 + */
  85 + private BigDecimal inCount;
  86 +
  87 + // ========== 采购退货(出库)) ==========
  88 + /**
  89 + * 采购退货数量
  90 + */
  91 + private BigDecimal returnCount;
  92 +
  93 +}
0 \ No newline at end of file 94 \ No newline at end of file
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/sale/ErpSaleOrderDO.java
@@ -112,7 +112,7 @@ public class ErpSaleOrderDO extends BaseDO { @@ -112,7 +112,7 @@ public class ErpSaleOrderDO extends BaseDO {
112 */ 112 */
113 private BigDecimal outCount; 113 private BigDecimal outCount;
114 114
115 - // ========== 销售退货(出库)) ========== 115 + // ========== 销售退货(入库)) ==========
116 /** 116 /**
117 * 销售退货数量 117 * 销售退货数量
118 */ 118 */
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/sale/ErpSaleOrderItemDO.java
@@ -84,7 +84,7 @@ public class ErpSaleOrderItemDO extends BaseDO { @@ -84,7 +84,7 @@ public class ErpSaleOrderItemDO extends BaseDO {
84 */ 84 */
85 private BigDecimal outCount; 85 private BigDecimal outCount;
86 86
87 - // ========== 销售退货(出库)) ========== 87 + // ========== 销售退货(入库)) ==========
88 /** 88 /**
89 * 销售退货数量 89 * 销售退货数量
90 */ 90 */
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/purchase/ErpPurchaseOrderItemMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.mysql.purchase;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  4 +import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderItemDO;
  5 +import org.apache.ibatis.annotations.Mapper;
  6 +
  7 +import java.util.Collection;
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * ERP 采购订单明项目 Mapper
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@Mapper
  16 +public interface ErpPurchaseOrderItemMapper extends BaseMapperX<ErpPurchaseOrderItemDO> {
  17 +
  18 + default List<ErpPurchaseOrderItemDO> selectListByOrderId(Long orderId) {
  19 + return selectList(ErpPurchaseOrderItemDO::getOrderId, orderId);
  20 + }
  21 +
  22 + default List<ErpPurchaseOrderItemDO> selectListByOrderIds(Collection<Long> orderIds) {
  23 + return selectList(ErpPurchaseOrderItemDO::getOrderId, orderIds);
  24 + }
  25 +
  26 + default int deleteByOrderId(Long orderId) {
  27 + return delete(ErpPurchaseOrderItemDO::getOrderId, orderId);
  28 + }
  29 +
  30 +}
0 \ No newline at end of file 31 \ No newline at end of file
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/purchase/ErpPurchaseOrderMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.dal.mysql.purchase;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
  6 +import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order.ErpPurchaseOrderPageReqVO;
  7 +import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderDO;
  8 +import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderItemDO;
  9 +import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
  10 +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
  11 +import org.apache.ibatis.annotations.Mapper;
  12 +
  13 +import java.util.Objects;
  14 +
  15 +/**
  16 + * ERP 采购订单 Mapper
  17 + *
  18 + * @author 芋道源码
  19 + */
  20 +@Mapper
  21 +public interface ErpPurchaseOrderMapper extends BaseMapperX<ErpPurchaseOrderDO> {
  22 +
  23 + default PageResult<ErpPurchaseOrderDO> selectPage(ErpPurchaseOrderPageReqVO reqVO) {
  24 + MPJLambdaWrapperX<ErpPurchaseOrderDO> query = new MPJLambdaWrapperX<ErpPurchaseOrderDO>()
  25 + .likeIfPresent(ErpPurchaseOrderDO::getNo, reqVO.getNo())
  26 + .eqIfPresent(ErpPurchaseOrderDO::getSupplierId, reqVO.getSupplierId())
  27 + .betweenIfPresent(ErpPurchaseOrderDO::getOrderTime, reqVO.getOrderTime())
  28 + .eqIfPresent(ErpPurchaseOrderDO::getStatus, reqVO.getStatus())
  29 + .likeIfPresent(ErpPurchaseOrderDO::getRemark, reqVO.getRemark())
  30 + .eqIfPresent(ErpPurchaseOrderDO::getCreator, reqVO.getCreator())
  31 + .orderByDesc(ErpPurchaseOrderDO::getId);
  32 + // 入库状态。为什么需要 t. 的原因,是因为联表查询时,需要指定表名,不然会报 in_count 错误
  33 + if (Objects.equals(reqVO.getInStatus(), ErpPurchaseOrderPageReqVO.IN_STATUS_NONE)) {
  34 + query.eq(ErpPurchaseOrderDO::getInCount, 0);
  35 + } else if (Objects.equals(reqVO.getInStatus(), ErpPurchaseOrderPageReqVO.IN_STATUS_PART)) {
  36 + query.gt(ErpPurchaseOrderDO::getInCount, 0).apply("t.in_count < t.total_count");
  37 + } else if (Objects.equals(reqVO.getInStatus(), ErpPurchaseOrderPageReqVO.IN_STATUS_ALL)) {
  38 + query.apply("t.in_count = t.total_count");
  39 + }
  40 + // 退货状态
  41 + if (Objects.equals(reqVO.getReturnStatus(), ErpPurchaseOrderPageReqVO.RETURN_STATUS_NONE)) {
  42 + query.eq(ErpPurchaseOrderDO::getReturnCount, 0);
  43 + } else if (Objects.equals(reqVO.getReturnStatus(), ErpPurchaseOrderPageReqVO.RETURN_STATUS_PART)) {
  44 + query.gt(ErpPurchaseOrderDO::getReturnCount, 0).apply("t.return_count < t.total_count");
  45 + } else if (Objects.equals(reqVO.getReturnStatus(), ErpPurchaseOrderPageReqVO.RETURN_STATUS_ALL)) {
  46 + query.apply("t.return_count = t.total_count");
  47 + }
  48 + // 可采购出库
  49 + if (Boolean.TRUE.equals(reqVO.getInEnable())) {
  50 + query.eq(ErpPurchaseOrderDO::getStatus, ErpAuditStatus.APPROVE.getStatus())
  51 + .apply("t.in_count < t.total_count");
  52 + }
  53 + // 可采购退货
  54 + if (Boolean.TRUE.equals(reqVO.getReturnEnable())) {
  55 + query.eq(ErpPurchaseOrderDO::getStatus, ErpAuditStatus.APPROVE.getStatus())
  56 + .apply("t.return_count < t.in_count");
  57 + }
  58 + if (reqVO.getProductId() != null) {
  59 + query.leftJoin(ErpPurchaseOrderItemDO.class, ErpPurchaseOrderItemDO::getOrderId, ErpPurchaseOrderDO::getId)
  60 + .eq(reqVO.getProductId() != null, ErpPurchaseOrderItemDO::getProductId, reqVO.getProductId())
  61 + .groupBy(ErpPurchaseOrderDO::getId); // 避免 1 对多查询,产生相同的 1
  62 + }
  63 + return selectJoinPage(reqVO, ErpPurchaseOrderDO.class, query);
  64 + }
  65 +
  66 + default int updateByIdAndStatus(Long id, Integer status, ErpPurchaseOrderDO updateObj) {
  67 + return update(updateObj, new LambdaUpdateWrapper<ErpPurchaseOrderDO>()
  68 + .eq(ErpPurchaseOrderDO::getId, id).eq(ErpPurchaseOrderDO::getStatus, status));
  69 + }
  70 +
  71 + default ErpPurchaseOrderDO selectByNo(String no) {
  72 + return selectOne(ErpPurchaseOrderDO::getNo, no);
  73 + }
  74 +
  75 +}
0 \ No newline at end of file 76 \ No newline at end of file
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/sale/ErpSaleOrderMapper.java
@@ -31,11 +31,11 @@ public interface ErpSaleOrderMapper extends BaseMapperX&lt;ErpSaleOrderDO&gt; { @@ -31,11 +31,11 @@ public interface ErpSaleOrderMapper extends BaseMapperX&lt;ErpSaleOrderDO&gt; {
31 .eqIfPresent(ErpSaleOrderDO::getCreator, reqVO.getCreator()) 31 .eqIfPresent(ErpSaleOrderDO::getCreator, reqVO.getCreator())
32 .orderByDesc(ErpSaleOrderDO::getId); 32 .orderByDesc(ErpSaleOrderDO::getId);
33 // 入库状态。为什么需要 t. 的原因,是因为联表查询时,需要指定表名,不然会报 out_count 错误 33 // 入库状态。为什么需要 t. 的原因,是因为联表查询时,需要指定表名,不然会报 out_count 错误
34 - if (Objects.equals(reqVO.getInStatus(), ErpSaleOrderPageReqVO.IN_STATUS_NONE)) { 34 + if (Objects.equals(reqVO.getOutStatus(), ErpSaleOrderPageReqVO.OUT_STATUS_NONE)) {
35 query.eq(ErpSaleOrderDO::getOutCount, 0); 35 query.eq(ErpSaleOrderDO::getOutCount, 0);
36 - } else if (Objects.equals(reqVO.getInStatus(), ErpSaleOrderPageReqVO.IN_STATUS_PART)) { 36 + } else if (Objects.equals(reqVO.getOutStatus(), ErpSaleOrderPageReqVO.OUT_STATUS_PART)) {
37 query.gt(ErpSaleOrderDO::getOutCount, 0).apply("t.out_count < t.total_count"); 37 query.gt(ErpSaleOrderDO::getOutCount, 0).apply("t.out_count < t.total_count");
38 - } else if (Objects.equals(reqVO.getInStatus(), ErpSaleOrderPageReqVO.IN_STATUS_ALL)) { 38 + } else if (Objects.equals(reqVO.getOutStatus(), ErpSaleOrderPageReqVO.OUT_STATUS_ALL)) {
39 query.apply("t.out_count = t.total_count"); 39 query.apply("t.out_count = t.total_count");
40 } 40 }
41 // 退货状态 41 // 退货状态
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/redis/no/ErpNoRedisDAO.java
@@ -51,6 +51,11 @@ public class ErpNoRedisDAO { @@ -51,6 +51,11 @@ public class ErpNoRedisDAO {
51 */ 51 */
52 public static final String SALE_RETURN_NO_PREFIX = "XSTH"; 52 public static final String SALE_RETURN_NO_PREFIX = "XSTH";
53 53
  54 + /**
  55 + * 采购订单 {@link cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderDO}
  56 + */
  57 + public static final String PURCHASE_ORDER_NO_PREFIX = "CGDD";
  58 +
54 @Resource 59 @Resource
55 private StringRedisTemplate stringRedisTemplate; 60 private StringRedisTemplate stringRedisTemplate;
56 61
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/product/ErpProductUnitServiceImpl.java
@@ -74,7 +74,7 @@ public class ErpProductUnitServiceImpl implements ErpProductUnitService { @@ -74,7 +74,7 @@ public class ErpProductUnitServiceImpl implements ErpProductUnitService {
74 public void deleteProductUnit(Long id) { 74 public void deleteProductUnit(Long id) {
75 // 1.1 校验存在 75 // 1.1 校验存在
76 validateProductUnitExists(id); 76 validateProductUnitExists(id);
77 - // 1.2 校验商品是否使用 77 + // 1.2 校验产品是否使用
78 if (productService.getProductCountByUnitId(id) > 0) { 78 if (productService.getProductCountByUnitId(id) > 0) {
79 throw exception(PRODUCT_UNIT_EXITS_PRODUCT); 79 throw exception(PRODUCT_UNIT_EXITS_PRODUCT);
80 } 80 }
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseOrderService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.service.purchase;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order.ErpPurchaseOrderPageReqVO;
  5 +import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order.ErpPurchaseOrderSaveReqVO;
  6 +import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderDO;
  7 +import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderItemDO;
  8 +import jakarta.validation.Valid;
  9 +
  10 +import java.math.BigDecimal;
  11 +import java.util.Collection;
  12 +import java.util.List;
  13 +import java.util.Map;
  14 +
  15 +/**
  16 + * ERP 采购订单 Service 接口
  17 + *
  18 + * @author 芋道源码
  19 + */
  20 +public interface ErpPurchaseOrderService {
  21 +
  22 + /**
  23 + * 创建采购订单
  24 + *
  25 + * @param createReqVO 创建信息
  26 + * @return 编号
  27 + */
  28 + Long createPurchaseOrder(@Valid ErpPurchaseOrderSaveReqVO createReqVO);
  29 +
  30 + /**
  31 + * 更新采购订单
  32 + *
  33 + * @param updateReqVO 更新信息
  34 + */
  35 + void updatePurchaseOrder(@Valid ErpPurchaseOrderSaveReqVO updateReqVO);
  36 +
  37 + /**
  38 + * 更新采购订单的状态
  39 + *
  40 + * @param id 编号
  41 + * @param status 状态
  42 + */
  43 + void updatePurchaseOrderStatus(Long id, Integer status);
  44 +
  45 + /**
  46 + * 更新采购订单的入库数量
  47 + *
  48 + * @param id 编号
  49 + * @param inCountMap 入库数量 Map:key 采购订单项编号;value 入库数量
  50 + */
  51 + void updatePurchaseOrderInCount(Long id, Map<Long, BigDecimal> inCountMap);
  52 +
  53 + /**
  54 + * 更新采购订单的退货数量
  55 + *
  56 + * @param orderId 编号
  57 + * @param returnCountMap 退货数量 Map:key 采购订单项编号;value 退货数量
  58 + */
  59 + void updatePurchaseOrderReturnCount(Long orderId, Map<Long, BigDecimal> returnCountMap);
  60 +
  61 + /**
  62 + * 删除采购订单
  63 + *
  64 + * @param ids 编号数组
  65 + */
  66 + void deletePurchaseOrder(List<Long> ids);
  67 +
  68 + /**
  69 + * 获得采购订单
  70 + *
  71 + * @param id 编号
  72 + * @return 采购订单
  73 + */
  74 + ErpPurchaseOrderDO getPurchaseOrder(Long id);
  75 +
  76 + /**
  77 + * 校验采购订单,已经审核通过
  78 + *
  79 + * @param id 编号
  80 + * @return 采购订单
  81 + */
  82 + ErpPurchaseOrderDO validatePurchaseOrder(Long id);
  83 +
  84 + /**
  85 + * 获得采购订单分页
  86 + *
  87 + * @param pageReqVO 分页查询
  88 + * @return 采购订单分页
  89 + */
  90 + PageResult<ErpPurchaseOrderDO> getPurchaseOrderPage(ErpPurchaseOrderPageReqVO pageReqVO);
  91 +
  92 + // ==================== 采购订单项 ====================
  93 +
  94 + /**
  95 + * 获得采购订单项列表
  96 + *
  97 + * @param orderId 采购订单编号
  98 + * @return 采购订单项列表
  99 + */
  100 + List<ErpPurchaseOrderItemDO> getPurchaseOrderItemListByOrderId(Long orderId);
  101 +
  102 + /**
  103 + * 获得采购订单项 List
  104 + *
  105 + * @param orderIds 采购订单编号数组
  106 + * @return 采购订单项 List
  107 + */
  108 + List<ErpPurchaseOrderItemDO> getPurchaseOrderItemListByOrderIds(Collection<Long> orderIds);
  109 +
  110 +}
0 \ No newline at end of file 111 \ No newline at end of file
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseOrderServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.erp.service.purchase;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.util.ObjectUtil;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
  7 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  8 +import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order.ErpPurchaseOrderPageReqVO;
  9 +import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order.ErpPurchaseOrderSaveReqVO;
  10 +import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
  11 +import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderDO;
  12 +import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderItemDO;
  13 +import cn.iocoder.yudao.module.erp.dal.mysql.purchase.ErpPurchaseOrderItemMapper;
  14 +import cn.iocoder.yudao.module.erp.dal.mysql.purchase.ErpPurchaseOrderMapper;
  15 +import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO;
  16 +import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
  17 +import cn.iocoder.yudao.module.erp.service.finance.ErpAccountService;
  18 +import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
  19 +import jakarta.annotation.Resource;
  20 +import org.springframework.stereotype.Service;
  21 +import org.springframework.transaction.annotation.Transactional;
  22 +import org.springframework.validation.annotation.Validated;
  23 +
  24 +import java.math.BigDecimal;
  25 +import java.util.Collection;
  26 +import java.util.Collections;
  27 +import java.util.List;
  28 +import java.util.Map;
  29 +
  30 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  31 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
  32 +import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
  33 +
  34 +// TODO 芋艿:记录操作日志
  35 +
  36 +/**
  37 + * ERP 采购订单 Service 实现类
  38 + *
  39 + * @author 芋道源码
  40 + */
  41 +@Service
  42 +@Validated
  43 +public class ErpPurchaseOrderServiceImpl implements ErpPurchaseOrderService {
  44 +
  45 + @Resource
  46 + private ErpPurchaseOrderMapper purchaseOrderMapper;
  47 + @Resource
  48 + private ErpPurchaseOrderItemMapper purchaseOrderItemMapper;
  49 +
  50 + @Resource
  51 + private ErpNoRedisDAO noRedisDAO;
  52 +
  53 + @Resource
  54 + private ErpProductService productService;
  55 + @Resource
  56 + private ErpSupplierService supplierService;
  57 + @Resource
  58 + private ErpAccountService accountService;
  59 +
  60 + @Override
  61 + @Transactional(rollbackFor = Exception.class)
  62 + public Long createPurchaseOrder(ErpPurchaseOrderSaveReqVO createReqVO) {
  63 + // 1.1 校验订单项的有效性
  64 + List<ErpPurchaseOrderItemDO> purchaseOrderItems = validatePurchaseOrderItems(createReqVO.getItems());
  65 + // 1.2 校验供应商
  66 + supplierService.validateSupplier(createReqVO.getSupplierId());
  67 + // 1.3 校验结算账户
  68 + if (createReqVO.getAccountId() != null) {
  69 + accountService.validateAccount(createReqVO.getAccountId());
  70 + }
  71 + // 1.4 生成调拨单号,并校验唯一性
  72 + String no = noRedisDAO.generate(ErpNoRedisDAO.PURCHASE_ORDER_NO_PREFIX);
  73 + if (purchaseOrderMapper.selectByNo(no) != null) {
  74 + throw exception(PURCHASE_ORDER_NO_EXISTS);
  75 + }
  76 +
  77 + // 2.1 插入订单
  78 + ErpPurchaseOrderDO purchaseOrder = BeanUtils.toBean(createReqVO, ErpPurchaseOrderDO.class, in -> in
  79 + .setNo(no).setStatus(ErpAuditStatus.PROCESS.getStatus()));
  80 + calculateTotalPrice(purchaseOrder, purchaseOrderItems);
  81 + purchaseOrderMapper.insert(purchaseOrder);
  82 + // 2.2 插入订单项
  83 + purchaseOrderItems.forEach(o -> o.setOrderId(purchaseOrder.getId()));
  84 + purchaseOrderItemMapper.insertBatch(purchaseOrderItems);
  85 + return purchaseOrder.getId();
  86 + }
  87 +
  88 + @Override
  89 + @Transactional(rollbackFor = Exception.class)
  90 + public void updatePurchaseOrder(ErpPurchaseOrderSaveReqVO updateReqVO) {
  91 + // 1.1 校验存在
  92 + ErpPurchaseOrderDO purchaseOrder = validatePurchaseOrderExists(updateReqVO.getId());
  93 + if (ErpAuditStatus.APPROVE.getStatus().equals(purchaseOrder.getStatus())) {
  94 + throw exception(PURCHASE_ORDER_UPDATE_FAIL_APPROVE, purchaseOrder.getNo());
  95 + }
  96 + // 1.2 校验供应商
  97 + supplierService.validateSupplier(updateReqVO.getSupplierId());
  98 + // 1.3 校验结算账户
  99 + if (updateReqVO.getAccountId() != null) {
  100 + accountService.validateAccount(updateReqVO.getAccountId());
  101 + }
  102 + // 1.4 校验订单项的有效性
  103 + List<ErpPurchaseOrderItemDO> purchaseOrderItems = validatePurchaseOrderItems(updateReqVO.getItems());
  104 +
  105 + // 2.1 更新订单
  106 + ErpPurchaseOrderDO updateObj = BeanUtils.toBean(updateReqVO, ErpPurchaseOrderDO.class);
  107 + calculateTotalPrice(updateObj, purchaseOrderItems);
  108 + purchaseOrderMapper.updateById(updateObj);
  109 + // 2.2 更新订单项
  110 + updatePurchaseOrderItemList(updateReqVO.getId(), purchaseOrderItems);
  111 + }
  112 +
  113 + private void calculateTotalPrice(ErpPurchaseOrderDO purchaseOrder, List<ErpPurchaseOrderItemDO> purchaseOrderItems) {
  114 + purchaseOrder.setTotalCount(getSumValue(purchaseOrderItems, ErpPurchaseOrderItemDO::getCount, BigDecimal::add));
  115 + purchaseOrder.setTotalProductPrice(getSumValue(purchaseOrderItems, ErpPurchaseOrderItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO));
  116 + purchaseOrder.setTotalTaxPrice(getSumValue(purchaseOrderItems, ErpPurchaseOrderItemDO::getTaxPrice, BigDecimal::add, BigDecimal.ZERO));
  117 + purchaseOrder.setTotalPrice(purchaseOrder.getTotalProductPrice().add(purchaseOrder.getTotalTaxPrice()));
  118 + // 计算优惠价格
  119 + if (purchaseOrder.getDiscountPercent() == null) {
  120 + purchaseOrder.setDiscountPercent(BigDecimal.ZERO);
  121 + }
  122 + purchaseOrder.setDiscountPrice(MoneyUtils.priceMultiplyPercent(purchaseOrder.getTotalPrice(), purchaseOrder.getDiscountPercent()));
  123 + purchaseOrder.setTotalPrice(purchaseOrder.getTotalPrice().subtract(purchaseOrder.getDiscountPrice()));
  124 + }
  125 +
  126 + @Override
  127 + @Transactional(rollbackFor = Exception.class)
  128 + public void updatePurchaseOrderStatus(Long id, Integer status) {
  129 + boolean approve = ErpAuditStatus.APPROVE.getStatus().equals(status);
  130 + // 1.1 校验存在
  131 + ErpPurchaseOrderDO purchaseOrder = validatePurchaseOrderExists(id);
  132 + // 1.2 校验状态
  133 + if (purchaseOrder.getStatus().equals(status)) {
  134 + throw exception(approve ? PURCHASE_ORDER_APPROVE_FAIL : PURCHASE_ORDER_PROCESS_FAIL);
  135 + }
  136 + // 1.3 存在采购入单,无法反审核
  137 + if (!approve && purchaseOrder.getInCount().compareTo(BigDecimal.ZERO) > 0) {
  138 + throw exception(PURCHASE_ORDER_PROCESS_FAIL_EXISTS_IN);
  139 + }
  140 + // 1.4 存在采购退货单,无法反审核
  141 + if (!approve && purchaseOrder.getReturnCount().compareTo(BigDecimal.ZERO) > 0) {
  142 + throw exception(PURCHASE_ORDER_PROCESS_FAIL_EXISTS_RETURN);
  143 + }
  144 +
  145 + // 2. 更新状态
  146 + int updateCount = purchaseOrderMapper.updateByIdAndStatus(id, purchaseOrder.getStatus(),
  147 + new ErpPurchaseOrderDO().setStatus(status));
  148 + if (updateCount == 0) {
  149 + throw exception(approve ? PURCHASE_ORDER_APPROVE_FAIL : PURCHASE_ORDER_PROCESS_FAIL);
  150 + }
  151 + }
  152 +
  153 + private List<ErpPurchaseOrderItemDO> validatePurchaseOrderItems(List<ErpPurchaseOrderSaveReqVO.Item> list) {
  154 + // 1. 校验产品存在
  155 + List<ErpProductDO> productList = productService.validProductList(
  156 + convertSet(list, ErpPurchaseOrderSaveReqVO.Item::getProductId));
  157 + Map<Long, ErpProductDO> productMap = convertMap(productList, ErpProductDO::getId);
  158 + // 2. 转化为 ErpPurchaseOrderItemDO 列表
  159 + return convertList(list, o -> BeanUtils.toBean(o, ErpPurchaseOrderItemDO.class, item -> {
  160 + item.setProductUnitId(productMap.get(item.getProductId()).getUnitId());
  161 + item.setTotalPrice(MoneyUtils.priceMultiply(item.getProductPrice(), item.getCount()));
  162 + if (item.getTotalPrice() == null) {
  163 + return;
  164 + }
  165 + if (item.getTaxPercent() == null) {
  166 + item.setTaxPercent(BigDecimal.ZERO);
  167 + } else {
  168 + item.setTaxPrice(MoneyUtils.priceMultiplyPercent(item.getTotalPrice(), item.getTaxPercent()));
  169 + }
  170 + }));
  171 + }
  172 +
  173 + private void updatePurchaseOrderItemList(Long id, List<ErpPurchaseOrderItemDO> newList) {
  174 + // 第一步,对比新老数据,获得添加、修改、删除的列表
  175 + List<ErpPurchaseOrderItemDO> oldList = purchaseOrderItemMapper.selectListByOrderId(id);
  176 + List<List<ErpPurchaseOrderItemDO>> diffList = diffList(oldList, newList, // id 不同,就认为是不同的记录
  177 + (oldVal, newVal) -> oldVal.getId().equals(newVal.getId()));
  178 +
  179 + // 第二步,批量添加、修改、删除
  180 + if (CollUtil.isNotEmpty(diffList.get(0))) {
  181 + diffList.get(0).forEach(o -> o.setOrderId(id));
  182 + purchaseOrderItemMapper.insertBatch(diffList.get(0));
  183 + }
  184 + if (CollUtil.isNotEmpty(diffList.get(1))) {
  185 + purchaseOrderItemMapper.updateBatch(diffList.get(1));
  186 + }
  187 + if (CollUtil.isNotEmpty(diffList.get(2))) {
  188 + purchaseOrderItemMapper.deleteBatchIds(convertList(diffList.get(2), ErpPurchaseOrderItemDO::getId));
  189 + }
  190 + }
  191 +
  192 + @Override
  193 + public void updatePurchaseOrderInCount(Long id, Map<Long, BigDecimal> inCountMap) {
  194 + List<ErpPurchaseOrderItemDO> orderItems = purchaseOrderItemMapper.selectListByOrderId(id);
  195 + // 1. 更新每个采购订单项
  196 + orderItems.forEach(item -> {
  197 + BigDecimal inCount = inCountMap.getOrDefault(item.getId(), BigDecimal.ZERO);
  198 + if (item.getInCount().equals(inCount)) {
  199 + return;
  200 + }
  201 + if (inCount.compareTo(item.getCount()) > 0) {
  202 + throw exception(PURCHASE_ORDER_ITEM_IN_FAIL_PRODUCT_EXCEED,
  203 + productService.getProduct(item.getProductId()).getName(), item.getCount());
  204 + }
  205 + purchaseOrderItemMapper.updateById(new ErpPurchaseOrderItemDO().setId(item.getId()).setInCount(inCount));
  206 + });
  207 + // 2. 更新采购订单
  208 + BigDecimal totalInCount = getSumValue(inCountMap.values(), value -> value, BigDecimal::add, BigDecimal.ZERO);
  209 + purchaseOrderMapper.updateById(new ErpPurchaseOrderDO().setId(id).setInCount(totalInCount));
  210 + }
  211 +
  212 + @Override
  213 + public void updatePurchaseOrderReturnCount(Long orderId, Map<Long, BigDecimal> returnCountMap) {
  214 + List<ErpPurchaseOrderItemDO> orderItems = purchaseOrderItemMapper.selectListByOrderId(orderId);
  215 + // 1. 更新每个采购订单项
  216 + orderItems.forEach(item -> {
  217 + BigDecimal returnCount = returnCountMap.getOrDefault(item.getId(), BigDecimal.ZERO);
  218 + if (item.getReturnCount().equals(returnCount)) {
  219 + return;
  220 + }
  221 + if (returnCount.compareTo(item.getInCount()) > 0) {
  222 + throw exception(PURCHASE_ORDER_ITEM_RETURN_FAIL_IN_EXCEED,
  223 + productService.getProduct(item.getProductId()).getName(), item.getInCount());
  224 + }
  225 + purchaseOrderItemMapper.updateById(new ErpPurchaseOrderItemDO().setId(item.getId()).setReturnCount(returnCount));
  226 + });
  227 + // 2. 更新采购订单
  228 + BigDecimal totalReturnCount = getSumValue(returnCountMap.values(), value -> value, BigDecimal::add, BigDecimal.ZERO);
  229 + purchaseOrderMapper.updateById(new ErpPurchaseOrderDO().setId(orderId).setReturnCount(totalReturnCount));
  230 + }
  231 +
  232 + @Override
  233 + @Transactional(rollbackFor = Exception.class)
  234 + public void deletePurchaseOrder(List<Long> ids) {
  235 + // 1. 校验不处于已审批
  236 + List<ErpPurchaseOrderDO> purchaseOrders = purchaseOrderMapper.selectBatchIds(ids);
  237 + if (CollUtil.isEmpty(purchaseOrders)) {
  238 + return;
  239 + }
  240 + purchaseOrders.forEach(purchaseOrder -> {
  241 + if (ErpAuditStatus.APPROVE.getStatus().equals(purchaseOrder.getStatus())) {
  242 + throw exception(PURCHASE_ORDER_DELETE_FAIL_APPROVE, purchaseOrder.getNo());
  243 + }
  244 + });
  245 +
  246 + // 2. 遍历删除,并记录操作日志
  247 + purchaseOrders.forEach(purchaseOrder -> {
  248 + // 2.1 删除订单
  249 + purchaseOrderMapper.deleteById(purchaseOrder.getId());
  250 + // 2.2 删除订单项
  251 + purchaseOrderItemMapper.deleteByOrderId(purchaseOrder.getId());
  252 + });
  253 + }
  254 +
  255 + private ErpPurchaseOrderDO validatePurchaseOrderExists(Long id) {
  256 + ErpPurchaseOrderDO purchaseOrder = purchaseOrderMapper.selectById(id);
  257 + if (purchaseOrder == null) {
  258 + throw exception(PURCHASE_ORDER_NOT_EXISTS);
  259 + }
  260 + return purchaseOrder;
  261 + }
  262 +
  263 + @Override
  264 + public ErpPurchaseOrderDO getPurchaseOrder(Long id) {
  265 + return purchaseOrderMapper.selectById(id);
  266 + }
  267 +
  268 + @Override
  269 + public ErpPurchaseOrderDO validatePurchaseOrder(Long id) {
  270 + ErpPurchaseOrderDO purchaseOrder = validatePurchaseOrderExists(id);
  271 + if (ObjectUtil.notEqual(purchaseOrder.getStatus(), ErpAuditStatus.APPROVE.getStatus())) {
  272 + throw exception(PURCHASE_ORDER_NOT_APPROVE);
  273 + }
  274 + return purchaseOrder;
  275 + }
  276 +
  277 + @Override
  278 + public PageResult<ErpPurchaseOrderDO> getPurchaseOrderPage(ErpPurchaseOrderPageReqVO pageReqVO) {
  279 + return purchaseOrderMapper.selectPage(pageReqVO);
  280 + }
  281 +
  282 + // ==================== 订单项 ====================
  283 +
  284 + @Override
  285 + public List<ErpPurchaseOrderItemDO> getPurchaseOrderItemListByOrderId(Long orderId) {
  286 + return purchaseOrderItemMapper.selectListByOrderId(orderId);
  287 + }
  288 +
  289 + @Override
  290 + public List<ErpPurchaseOrderItemDO> getPurchaseOrderItemListByOrderIds(Collection<Long> orderIds) {
  291 + if (CollUtil.isEmpty(orderIds)) {
  292 + return Collections.emptyList();
  293 + }
  294 + return purchaseOrderItemMapper.selectListByOrderIds(orderIds);
  295 + }
  296 +
  297 +}
0 \ No newline at end of file 298 \ No newline at end of file
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpSaleReturnServiceImpl.java
@@ -187,7 +187,7 @@ public class ErpSaleReturnServiceImpl implements ErpSaleReturnService { @@ -187,7 +187,7 @@ public class ErpSaleReturnServiceImpl implements ErpSaleReturnService {
187 Integer bizType = approve ? ErpStockRecordBizTypeEnum.SALE_RETURN.getType() 187 Integer bizType = approve ? ErpStockRecordBizTypeEnum.SALE_RETURN.getType()
188 : ErpStockRecordBizTypeEnum.SALE_RETURN_CANCEL.getType(); 188 : ErpStockRecordBizTypeEnum.SALE_RETURN_CANCEL.getType();
189 saleReturnItems.forEach(saleReturnItem -> { 189 saleReturnItems.forEach(saleReturnItem -> {
190 - BigDecimal count = approve ? saleReturnItem.getCount().negate() : saleReturnItem.getCount(); 190 + BigDecimal count = approve ? saleReturnItem.getCount() : saleReturnItem.getCount().negate();
191 stockRecordService.createStockRecord(new ErpStockRecordCreateReqBO( 191 stockRecordService.createStockRecord(new ErpStockRecordCreateReqBO(
192 saleReturnItem.getProductId(), saleReturnItem.getWarehouseId(), count, 192 saleReturnItem.getProductId(), saleReturnItem.getWarehouseId(), count,
193 bizType, saleReturnItem.getReturnId(), saleReturnItem.getId(), saleReturn.getNo())); 193 bizType, saleReturnItem.getReturnId(), saleReturnItem.getId(), saleReturn.getNo()));