ERP:初始化采购订单 50%

This commit is contained in:
YunaiV 2024-02-12 08:39:43 +08:00
parent 798b72778e
commit c5d9ad59e0
32 changed files with 1266 additions and 58 deletions

View File

@ -13,6 +13,19 @@ public interface ErrorCodeConstants {
ErrorCode SUPPLIER_NOT_EXISTS = new ErrorCode(1_030_100_000, "供应商不存在"); ErrorCode SUPPLIER_NOT_EXISTS = new ErrorCode(1_030_100_000, "供应商不存在");
ErrorCode SUPPLIER_NOT_ENABLE = new ErrorCode(1_030_100_000, "供应商({})未启用"); ErrorCode SUPPLIER_NOT_ENABLE = new ErrorCode(1_030_100_000, "供应商({})未启用");
// ========== ERP 采购订单1-030-101-000 ==========
ErrorCode PURCHASE_ORDER_NOT_EXISTS = new ErrorCode(1_030_101_000, "采购订单不存在");
ErrorCode PURCHASE_ORDER_DELETE_FAIL_APPROVE = new ErrorCode(1_030_101_001, "采购订单({})已审核,无法删除");
ErrorCode PURCHASE_ORDER_PROCESS_FAIL = new ErrorCode(1_030_101_002, "反审核失败,只有已审核的采购订单才能反审核");
ErrorCode PURCHASE_ORDER_APPROVE_FAIL = new ErrorCode(1_030_101_003, "审核失败,只有未审核的采购订单才能审核");
ErrorCode PURCHASE_ORDER_NO_EXISTS = new ErrorCode(1_030_101_004, "生成采购单号失败,请重新提交");
ErrorCode PURCHASE_ORDER_UPDATE_FAIL_APPROVE = new ErrorCode(1_030_101_005, "采购订单({})已审核,无法修改");
ErrorCode PURCHASE_ORDER_NOT_APPROVE = new ErrorCode(1_030_101_006, "采购订单未审核,无法操作");
ErrorCode PURCHASE_ORDER_ITEM_IN_FAIL_PRODUCT_EXCEED = new ErrorCode(1_030_101_007, "采购订单项({})超过最大允许入库数量({})");
ErrorCode PURCHASE_ORDER_PROCESS_FAIL_EXISTS_IN = new ErrorCode(1_030_101_008, "反审核失败,已存在对应的采购入库单");
ErrorCode PURCHASE_ORDER_ITEM_RETURN_FAIL_IN_EXCEED = new ErrorCode(1_030_101_009, "采购订单项({})超过最大允许退货数量({})");
ErrorCode PURCHASE_ORDER_PROCESS_FAIL_EXISTS_RETURN = new ErrorCode(1_030_101_010, "反审核失败,已存在对应的采购退货单");
// ========== ERP 客户1-030-200-000========== // ========== ERP 客户1-030-200-000==========
ErrorCode CUSTOMER_NOT_EXISTS = new ErrorCode(1_020_200_000, "客户不存在"); ErrorCode CUSTOMER_NOT_EXISTS = new ErrorCode(1_020_200_000, "客户不存在");
ErrorCode CUSTOMER_NOT_ENABLE = new ErrorCode(1_020_200_001, "客户({})未启用"); ErrorCode CUSTOMER_NOT_ENABLE = new ErrorCode(1_020_200_001, "客户({})未启用");

View File

@ -0,0 +1,165 @@
package cn.iocoder.yudao.module.erp.controller.admin.purchase;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order.ErpPurchaseOrderPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order.ErpPurchaseOrderRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order.ErpPurchaseOrderSaveReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderItemDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpSupplierDO;
import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
import cn.iocoder.yudao.module.erp.service.purchase.ErpPurchaseOrderService;
import cn.iocoder.yudao.module.erp.service.purchase.ErpSupplierService;
import cn.iocoder.yudao.module.erp.service.stock.ErpStockService;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMultiMap;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
@Tag(name = "管理后台 - ERP 采购订单")
@RestController
@RequestMapping("/erp/purchase-order")
@Validated
public class ErpPurchaseOrderController {
@Resource
private ErpPurchaseOrderService purchaseOrderService;
@Resource
private ErpStockService stockService;
@Resource
private ErpProductService productService;
@Resource
private ErpSupplierService supplierService;
@Resource
private AdminUserApi adminUserApi;
@PostMapping("/create")
@Operation(summary = "创建采购订单")
@PreAuthorize("@ss.hasPermission('erp:purchase-out:create')")
public CommonResult<Long> createPurchaseOrder(@Valid @RequestBody ErpPurchaseOrderSaveReqVO createReqVO) {
return success(purchaseOrderService.createPurchaseOrder(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新采购订单")
@PreAuthorize("@ss.hasPermission('erp:purchase-out:update')")
public CommonResult<Boolean> updatePurchaseOrder(@Valid @RequestBody ErpPurchaseOrderSaveReqVO updateReqVO) {
purchaseOrderService.updatePurchaseOrder(updateReqVO);
return success(true);
}
@PutMapping("/update-status")
@Operation(summary = "更新采购订单的状态")
@PreAuthorize("@ss.hasPermission('erp:purchase-out:update-status')")
public CommonResult<Boolean> updatePurchaseOrderStatus(@RequestParam("id") Long id,
@RequestParam("status") Integer status) {
purchaseOrderService.updatePurchaseOrderStatus(id, status);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除采购订单")
@Parameter(name = "ids", description = "编号数组", required = true)
@PreAuthorize("@ss.hasPermission('erp:purchase-out:delete')")
public CommonResult<Boolean> deletePurchaseOrder(@RequestParam("ids") List<Long> ids) {
purchaseOrderService.deletePurchaseOrder(ids);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得采购订单")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('erp:purchase-out:query')")
public CommonResult<ErpPurchaseOrderRespVO> getPurchaseOrder(@RequestParam("id") Long id) {
ErpPurchaseOrderDO purchaseOrder = purchaseOrderService.getPurchaseOrder(id);
if (purchaseOrder == null) {
return success(null);
}
List<ErpPurchaseOrderItemDO> purchaseOrderItemList = purchaseOrderService.getPurchaseOrderItemListByOrderId(id);
Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
convertSet(purchaseOrderItemList, ErpPurchaseOrderItemDO::getProductId));
return success(BeanUtils.toBean(purchaseOrder, ErpPurchaseOrderRespVO.class, purchaseOrderVO ->
purchaseOrderVO.setItems(BeanUtils.toBean(purchaseOrderItemList, ErpPurchaseOrderRespVO.Item.class, item -> {
BigDecimal purchaseCount = stockService.getStockCount(item.getProductId());
item.setStockCount(purchaseCount != null ? purchaseCount : BigDecimal.ZERO);
MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName())
.setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName()));
}))));
}
@GetMapping("/page")
@Operation(summary = "获得采购订单分页")
@PreAuthorize("@ss.hasPermission('erp:purchase-out:query')")
public CommonResult<PageResult<ErpPurchaseOrderRespVO>> getPurchaseOrderPage(@Valid ErpPurchaseOrderPageReqVO pageReqVO) {
PageResult<ErpPurchaseOrderDO> pageResult = purchaseOrderService.getPurchaseOrderPage(pageReqVO);
return success(buildPurchaseOrderVOPageResult(pageResult));
}
@GetMapping("/export-excel")
@Operation(summary = "导出采购订单 Excel")
@PreAuthorize("@ss.hasPermission('erp:purchase-out:export')")
@OperateLog(type = EXPORT)
public void exportPurchaseOrderExcel(@Valid ErpPurchaseOrderPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<ErpPurchaseOrderRespVO> list = buildPurchaseOrderVOPageResult(purchaseOrderService.getPurchaseOrderPage(pageReqVO)).getList();
// 导出 Excel
ExcelUtils.write(response, "采购订单.xls", "数据", ErpPurchaseOrderRespVO.class, list);
}
private PageResult<ErpPurchaseOrderRespVO> buildPurchaseOrderVOPageResult(PageResult<ErpPurchaseOrderDO> pageResult) {
if (CollUtil.isEmpty(pageResult.getList())) {
return PageResult.empty(pageResult.getTotal());
}
// 1.1 出库项
List<ErpPurchaseOrderItemDO> purchaseOrderItemList = purchaseOrderService.getPurchaseOrderItemListByOrderIds(
convertSet(pageResult.getList(), ErpPurchaseOrderDO::getId));
Map<Long, List<ErpPurchaseOrderItemDO>> purchaseOrderItemMap = convertMultiMap(purchaseOrderItemList, ErpPurchaseOrderItemDO::getOrderId);
// 1.2 产品信息
Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
convertSet(purchaseOrderItemList, ErpPurchaseOrderItemDO::getProductId));
// 1.3 供应商信息
Map<Long, ErpSupplierDO> supplierMap = supplierService.getSupplierMap(
convertSet(pageResult.getList(), ErpPurchaseOrderDO::getSupplierId));
// 1.4 管理员信息
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
convertSet(pageResult.getList(), erpStockRecordDO -> Long.parseLong(erpStockRecordDO.getCreator())));
// 2. 开始拼接
return BeanUtils.toBean(pageResult, ErpPurchaseOrderRespVO.class, purchaseOrder -> {
purchaseOrder.setItems(BeanUtils.toBean(purchaseOrderItemMap.get(purchaseOrder.getId()), ErpPurchaseOrderRespVO.Item.class,
item -> MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName())
.setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName()))));
purchaseOrder.setProductNames(CollUtil.join(purchaseOrder.getItems(), "", ErpPurchaseOrderRespVO.Item::getProductName));
MapUtils.findAndThen(supplierMap, purchaseOrder.getSupplierId(), supplier -> purchaseOrder.setSupplierName(supplier.getName()));
MapUtils.findAndThen(userMap, Long.parseLong(purchaseOrder.getCreator()), user -> purchaseOrder.setCreatorName(user.getNickname()));
});
}
}

View File

@ -0,0 +1,80 @@
package cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - ERP 采购订单分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ErpPurchaseOrderPageReqVO extends PageParam {
/**
* 入库状态 -
*/
public static final Integer IN_STATUS_NONE = 0;
/**
* 入库状态 - 部分
*/
public static final Integer IN_STATUS_PART = 1;
/**
* 入库状态 - 全部
*/
public static final Integer IN_STATUS_ALL = 2;
/**
* 退货状态 -
*/
public static final Integer RETURN_STATUS_NONE = 0;
/**
* 退货状态 - 部分
*/
public static final Integer RETURN_STATUS_PART = 1;
/**
* 退货状态 - 全部
*/
public static final Integer RETURN_STATUS_ALL = 2;
@Schema(description = "采购单编号", example = "XS001")
private String no;
@Schema(description = "供应商编号", example = "1724")
private Long supplierId;
@Schema(description = "采购时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] orderTime;
@Schema(description = "备注", example = "你猜")
private String remark;
@Schema(description = "采购状态", example = "2")
private Integer status;
@Schema(description = "创建者")
private String creator;
@Schema(description = "产品编号", example = "1")
private Long productId;
@Schema(description = "入库状态", example = "2")
private Integer inStatus;
@Schema(description = "退货状态", example = "2")
private Integer returnStatus;
@Schema(description = "是否可入库", example = "true")
private Boolean inEnable;
@Schema(description = "是否可退货", example = "true")
private Boolean returnEnable;
}

View File

@ -0,0 +1,152 @@
package cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
@Schema(description = "管理后台 - ERP 采购订单 Response VO")
@Data
@ExcelIgnoreUnannotated
public class ErpPurchaseOrderRespVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17386")
@ExcelProperty("编号")
private Long id;
@Schema(description = "采购单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "XS001")
@ExcelProperty("采购单编号")
private String no;
@Schema(description = "采购状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@ExcelProperty("采购状态")
private Integer status;
@Schema(description = "供应商编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1724")
private Long supplierId;
@Schema(description = "供应商名称", example = "芋道")
@ExcelProperty("供应商名称")
private String supplierName;
@Schema(description = "结算账户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "311.89")
@ExcelProperty("结算账户编号")
private Long accountId;
@Schema(description = "采购时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("采购时间")
private LocalDateTime orderTime;
@Schema(description = "合计数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "15663")
@ExcelProperty("合计数量")
private BigDecimal totalCount;
@Schema(description = "最终合计价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "24906")
@ExcelProperty("最终合计价格")
private BigDecimal totalPrice;
@Schema(description = "合计产品价格,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127")
private BigDecimal totalProductPrice;
@Schema(description = "合计税额,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127")
private BigDecimal totalTaxPrice;
@Schema(description = "优惠率,百分比", requiredMode = Schema.RequiredMode.REQUIRED, example = "99.88")
private BigDecimal discountPercent;
@Schema(description = "优惠金额,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127")
private BigDecimal discountPrice;
@Schema(description = "定金金额,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127")
private BigDecimal depositPrice;
@Schema(description = "附件地址", example = "https://www.iocoder.cn")
@ExcelProperty("附件地址")
private String fileUrl;
@Schema(description = "备注", example = "你猜")
@ExcelProperty("备注")
private String remark;
@Schema(description = "创建人", example = "芋道")
private String creator;
@Schema(description = "创建人名称", example = "芋道")
private String creatorName;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
@Schema(description = "订单项列表", requiredMode = Schema.RequiredMode.REQUIRED)
private List<Item> items;
@Schema(description = "产品信息", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("产品信息")
private String productNames;
// ========== 采购出库 ==========
@Schema(description = "采购出库数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
private BigDecimal outCount;
// ========== 采购退货出库 ==========
@Schema(description = "采购退货数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
private BigDecimal returnCount;
@Data
public static class Item {
@Schema(description = "订单项编号", example = "11756")
private Long id;
@Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
private Long productId;
@Schema(description = "产品单位单位", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
private Long productUnitId;
@Schema(description = "产品单价", example = "100.00")
private BigDecimal productPrice;
@Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
@NotNull(message = "产品数量不能为空")
private BigDecimal count;
@Schema(description = "税率,百分比", example = "99.88")
private BigDecimal taxPercent;
@Schema(description = "税额,单位:元", example = "100.00")
private BigDecimal taxPrice;
@Schema(description = "备注", example = "随便")
private String remark;
// ========== 采购出库 ==========
@Schema(description = "采购出库数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
private BigDecimal outCount;
// ========== 采购退货入库 ==========
@Schema(description = "采购退货数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
private BigDecimal returnCount;
// ========== 关联字段 ==========
@Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "巧克力")
private String productName;
@Schema(description = "产品条码", requiredMode = Schema.RequiredMode.REQUIRED, example = "A9985")
private String productBarCode;
@Schema(description = "产品单位名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "")
private String productUnitName;
@Schema(description = "库存数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
private BigDecimal stockCount; // 该字段仅仅在详情编辑时使用
}
}

View File

@ -0,0 +1,73 @@
package cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
@Schema(description = "管理后台 - ERP 采购订单新增/修改 Request VO")
@Data
public class ErpPurchaseOrderSaveReqVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17386")
private Long id;
@Schema(description = "供应商编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1724")
@NotNull(message = "供应商编号不能为空")
private Long supplierId;
@Schema(description = "结算账户编号", example = "31189")
private Long accountId;
@Schema(description = "采购时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "采购时间不能为空")
private LocalDateTime orderTime;
@Schema(description = "优惠率,百分比", requiredMode = Schema.RequiredMode.REQUIRED, example = "99.88")
private BigDecimal discountPercent;
@Schema(description = "定金金额,单位:元", example = "7127")
private BigDecimal depositPrice;
@Schema(description = "附件地址", example = "https://www.iocoder.cn")
private String fileUrl;
@Schema(description = "备注", example = "你猜")
private String remark;
@Schema(description = "订单清单列表")
private List<Item> items;
@Data
public static class Item {
@Schema(description = "订单项编号", example = "11756")
private Long id;
@Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
@NotNull(message = "产品编号不能为空")
private Long productId;
@Schema(description = "产品单位单位", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
@NotNull(message = "产品单位单位不能为空")
private Long productUnitId;
@Schema(description = "产品单价", example = "100.00")
private BigDecimal productPrice;
@Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
@NotNull(message = "产品数量不能为空")
private BigDecimal count;
@Schema(description = "税率,百分比", example = "99.88")
private BigDecimal taxPercent;
@Schema(description = "备注", example = "随便")
private String remark;
}
}

View File

@ -62,14 +62,14 @@ public class ErpSaleOrderController {
@PostMapping("/create") @PostMapping("/create")
@Operation(summary = "创建销售订单") @Operation(summary = "创建销售订单")
@PreAuthorize("@ss.hasPermission('erp:stock-out:create')") @PreAuthorize("@ss.hasPermission('erp:sale-out:create')")
public CommonResult<Long> createSaleOrder(@Valid @RequestBody ErpSaleOrderSaveReqVO createReqVO) { public CommonResult<Long> createSaleOrder(@Valid @RequestBody ErpSaleOrderSaveReqVO createReqVO) {
return success(saleOrderService.createSaleOrder(createReqVO)); return success(saleOrderService.createSaleOrder(createReqVO));
} }
@PutMapping("/update") @PutMapping("/update")
@Operation(summary = "更新销售订单") @Operation(summary = "更新销售订单")
@PreAuthorize("@ss.hasPermission('erp:stock-out:update')") @PreAuthorize("@ss.hasPermission('erp:sale-out:update')")
public CommonResult<Boolean> updateSaleOrder(@Valid @RequestBody ErpSaleOrderSaveReqVO updateReqVO) { public CommonResult<Boolean> updateSaleOrder(@Valid @RequestBody ErpSaleOrderSaveReqVO updateReqVO) {
saleOrderService.updateSaleOrder(updateReqVO); saleOrderService.updateSaleOrder(updateReqVO);
return success(true); return success(true);
@ -77,7 +77,7 @@ public class ErpSaleOrderController {
@PutMapping("/update-status") @PutMapping("/update-status")
@Operation(summary = "更新销售订单的状态") @Operation(summary = "更新销售订单的状态")
@PreAuthorize("@ss.hasPermission('erp:stock-out:update-status')") @PreAuthorize("@ss.hasPermission('erp:sale-out:update-status')")
public CommonResult<Boolean> updateSaleOrderStatus(@RequestParam("id") Long id, public CommonResult<Boolean> updateSaleOrderStatus(@RequestParam("id") Long id,
@RequestParam("status") Integer status) { @RequestParam("status") Integer status) {
saleOrderService.updateSaleOrderStatus(id, status); saleOrderService.updateSaleOrderStatus(id, status);
@ -87,7 +87,7 @@ public class ErpSaleOrderController {
@DeleteMapping("/delete") @DeleteMapping("/delete")
@Operation(summary = "删除销售订单") @Operation(summary = "删除销售订单")
@Parameter(name = "ids", description = "编号数组", required = true) @Parameter(name = "ids", description = "编号数组", required = true)
@PreAuthorize("@ss.hasPermission('erp:stock-out:delete')") @PreAuthorize("@ss.hasPermission('erp:sale-out:delete')")
public CommonResult<Boolean> deleteSaleOrder(@RequestParam("ids") List<Long> ids) { public CommonResult<Boolean> deleteSaleOrder(@RequestParam("ids") List<Long> ids) {
saleOrderService.deleteSaleOrder(ids); saleOrderService.deleteSaleOrder(ids);
return success(true); return success(true);
@ -96,7 +96,7 @@ public class ErpSaleOrderController {
@GetMapping("/get") @GetMapping("/get")
@Operation(summary = "获得销售订单") @Operation(summary = "获得销售订单")
@Parameter(name = "id", description = "编号", required = true, example = "1024") @Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('erp:stock-out:query')") @PreAuthorize("@ss.hasPermission('erp:sale-out:query')")
public CommonResult<ErpSaleOrderRespVO> getSaleOrder(@RequestParam("id") Long id) { public CommonResult<ErpSaleOrderRespVO> getSaleOrder(@RequestParam("id") Long id) {
ErpSaleOrderDO saleOrder = saleOrderService.getSaleOrder(id); ErpSaleOrderDO saleOrder = saleOrderService.getSaleOrder(id);
if (saleOrder == null) { if (saleOrder == null) {
@ -116,7 +116,7 @@ public class ErpSaleOrderController {
@GetMapping("/page") @GetMapping("/page")
@Operation(summary = "获得销售订单分页") @Operation(summary = "获得销售订单分页")
@PreAuthorize("@ss.hasPermission('erp:stock-out:query')") @PreAuthorize("@ss.hasPermission('erp:sale-out:query')")
public CommonResult<PageResult<ErpSaleOrderRespVO>> getSaleOrderPage(@Valid ErpSaleOrderPageReqVO pageReqVO) { public CommonResult<PageResult<ErpSaleOrderRespVO>> getSaleOrderPage(@Valid ErpSaleOrderPageReqVO pageReqVO) {
PageResult<ErpSaleOrderDO> pageResult = saleOrderService.getSaleOrderPage(pageReqVO); PageResult<ErpSaleOrderDO> pageResult = saleOrderService.getSaleOrderPage(pageReqVO);
return success(buildSaleOrderVOPageResult(pageResult)); return success(buildSaleOrderVOPageResult(pageResult));
@ -124,7 +124,7 @@ public class ErpSaleOrderController {
@GetMapping("/export-excel") @GetMapping("/export-excel")
@Operation(summary = "导出销售订单 Excel") @Operation(summary = "导出销售订单 Excel")
@PreAuthorize("@ss.hasPermission('erp:stock-out:export')") @PreAuthorize("@ss.hasPermission('erp:sale-out:export')")
@OperateLog(type = EXPORT) @OperateLog(type = EXPORT)
public void exportSaleOrderExcel(@Valid ErpSaleOrderPageReqVO pageReqVO, public void exportSaleOrderExcel(@Valid ErpSaleOrderPageReqVO pageReqVO,
HttpServletResponse response) throws IOException { HttpServletResponse response) throws IOException {
@ -142,7 +142,7 @@ public class ErpSaleOrderController {
List<ErpSaleOrderItemDO> saleOrderItemList = saleOrderService.getSaleOrderItemListByOrderIds( List<ErpSaleOrderItemDO> saleOrderItemList = saleOrderService.getSaleOrderItemListByOrderIds(
convertSet(pageResult.getList(), ErpSaleOrderDO::getId)); convertSet(pageResult.getList(), ErpSaleOrderDO::getId));
Map<Long, List<ErpSaleOrderItemDO>> saleOrderItemMap = convertMultiMap(saleOrderItemList, ErpSaleOrderItemDO::getOrderId); Map<Long, List<ErpSaleOrderItemDO>> saleOrderItemMap = convertMultiMap(saleOrderItemList, ErpSaleOrderItemDO::getOrderId);
// 1.2 品信息 // 1.2 品信息
Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap( Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
convertSet(saleOrderItemList, ErpSaleOrderItemDO::getProductId)); convertSet(saleOrderItemList, ErpSaleOrderItemDO::getProductId));
// 1.3 客户信息 // 1.3 客户信息

View File

@ -62,14 +62,14 @@ public class ErpSaleOutController {
@PostMapping("/create") @PostMapping("/create")
@Operation(summary = "创建销售出库") @Operation(summary = "创建销售出库")
@PreAuthorize("@ss.hasPermission('erp:stock-out:create')") @PreAuthorize("@ss.hasPermission('erp:sale-out:create')")
public CommonResult<Long> createSaleOut(@Valid @RequestBody ErpSaleOutSaveReqVO createReqVO) { public CommonResult<Long> createSaleOut(@Valid @RequestBody ErpSaleOutSaveReqVO createReqVO) {
return success(saleOutService.createSaleOut(createReqVO)); return success(saleOutService.createSaleOut(createReqVO));
} }
@PutMapping("/update") @PutMapping("/update")
@Operation(summary = "更新销售出库") @Operation(summary = "更新销售出库")
@PreAuthorize("@ss.hasPermission('erp:stock-out:update')") @PreAuthorize("@ss.hasPermission('erp:sale-out:update')")
public CommonResult<Boolean> updateSaleOut(@Valid @RequestBody ErpSaleOutSaveReqVO updateReqVO) { public CommonResult<Boolean> updateSaleOut(@Valid @RequestBody ErpSaleOutSaveReqVO updateReqVO) {
saleOutService.updateSaleOut(updateReqVO); saleOutService.updateSaleOut(updateReqVO);
return success(true); return success(true);
@ -77,7 +77,7 @@ public class ErpSaleOutController {
@PutMapping("/update-status") @PutMapping("/update-status")
@Operation(summary = "更新销售出库的状态") @Operation(summary = "更新销售出库的状态")
@PreAuthorize("@ss.hasPermission('erp:stock-out:update-status')") @PreAuthorize("@ss.hasPermission('erp:sale-out:update-status')")
public CommonResult<Boolean> updateSaleOutStatus(@RequestParam("id") Long id, public CommonResult<Boolean> updateSaleOutStatus(@RequestParam("id") Long id,
@RequestParam("status") Integer status) { @RequestParam("status") Integer status) {
saleOutService.updateSaleOutStatus(id, status); saleOutService.updateSaleOutStatus(id, status);
@ -87,7 +87,7 @@ public class ErpSaleOutController {
@DeleteMapping("/delete") @DeleteMapping("/delete")
@Operation(summary = "删除销售出库") @Operation(summary = "删除销售出库")
@Parameter(name = "ids", description = "编号数组", required = true) @Parameter(name = "ids", description = "编号数组", required = true)
@PreAuthorize("@ss.hasPermission('erp:stock-out:delete')") @PreAuthorize("@ss.hasPermission('erp:sale-out:delete')")
public CommonResult<Boolean> deleteSaleOut(@RequestParam("ids") List<Long> ids) { public CommonResult<Boolean> deleteSaleOut(@RequestParam("ids") List<Long> ids) {
saleOutService.deleteSaleOut(ids); saleOutService.deleteSaleOut(ids);
return success(true); return success(true);
@ -96,7 +96,7 @@ public class ErpSaleOutController {
@GetMapping("/get") @GetMapping("/get")
@Operation(summary = "获得销售出库") @Operation(summary = "获得销售出库")
@Parameter(name = "id", description = "编号", required = true, example = "1024") @Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('erp:stock-out:query')") @PreAuthorize("@ss.hasPermission('erp:sale-out:query')")
public CommonResult<ErpSaleOutRespVO> getSaleOut(@RequestParam("id") Long id) { public CommonResult<ErpSaleOutRespVO> getSaleOut(@RequestParam("id") Long id) {
ErpSaleOutDO saleOut = saleOutService.getSaleOut(id); ErpSaleOutDO saleOut = saleOutService.getSaleOut(id);
if (saleOut == null) { if (saleOut == null) {
@ -116,7 +116,7 @@ public class ErpSaleOutController {
@GetMapping("/page") @GetMapping("/page")
@Operation(summary = "获得销售出库分页") @Operation(summary = "获得销售出库分页")
@PreAuthorize("@ss.hasPermission('erp:stock-out:query')") @PreAuthorize("@ss.hasPermission('erp:sale-out:query')")
public CommonResult<PageResult<ErpSaleOutRespVO>> getSaleOutPage(@Valid ErpSaleOutPageReqVO pageReqVO) { public CommonResult<PageResult<ErpSaleOutRespVO>> getSaleOutPage(@Valid ErpSaleOutPageReqVO pageReqVO) {
PageResult<ErpSaleOutDO> pageResult = saleOutService.getSaleOutPage(pageReqVO); PageResult<ErpSaleOutDO> pageResult = saleOutService.getSaleOutPage(pageReqVO);
return success(buildSaleOutVOPageResult(pageResult)); return success(buildSaleOutVOPageResult(pageResult));
@ -124,7 +124,7 @@ public class ErpSaleOutController {
@GetMapping("/export-excel") @GetMapping("/export-excel")
@Operation(summary = "导出销售出库 Excel") @Operation(summary = "导出销售出库 Excel")
@PreAuthorize("@ss.hasPermission('erp:stock-out:export')") @PreAuthorize("@ss.hasPermission('erp:sale-out:export')")
@OperateLog(type = EXPORT) @OperateLog(type = EXPORT)
public void exportSaleOutExcel(@Valid ErpSaleOutPageReqVO pageReqVO, public void exportSaleOutExcel(@Valid ErpSaleOutPageReqVO pageReqVO,
HttpServletResponse response) throws IOException { HttpServletResponse response) throws IOException {
@ -142,7 +142,7 @@ public class ErpSaleOutController {
List<ErpSaleOutItemDO> saleOutItemList = saleOutService.getSaleOutItemListByOutIds( List<ErpSaleOutItemDO> saleOutItemList = saleOutService.getSaleOutItemListByOutIds(
convertSet(pageResult.getList(), ErpSaleOutDO::getId)); convertSet(pageResult.getList(), ErpSaleOutDO::getId));
Map<Long, List<ErpSaleOutItemDO>> saleOutItemMap = convertMultiMap(saleOutItemList, ErpSaleOutItemDO::getOutId); Map<Long, List<ErpSaleOutItemDO>> saleOutItemMap = convertMultiMap(saleOutItemList, ErpSaleOutItemDO::getOutId);
// 1.2 品信息 // 1.2 品信息
Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap( Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
convertSet(saleOutItemList, ErpSaleOutItemDO::getProductId)); convertSet(saleOutItemList, ErpSaleOutItemDO::getProductId));
// 1.3 客户信息 // 1.3 客户信息

View File

@ -62,14 +62,14 @@ public class ErpSaleReturnController {
@PostMapping("/create") @PostMapping("/create")
@Operation(summary = "创建销售退货") @Operation(summary = "创建销售退货")
@PreAuthorize("@ss.hasPermission('erp:stock-return:create')") @PreAuthorize("@ss.hasPermission('erp:sale-return:create')")
public CommonResult<Long> createSaleReturn(@Valid @RequestBody ErpSaleReturnSaveReqVO createReqVO) { public CommonResult<Long> createSaleReturn(@Valid @RequestBody ErpSaleReturnSaveReqVO createReqVO) {
return success(saleReturnService.createSaleReturn(createReqVO)); return success(saleReturnService.createSaleReturn(createReqVO));
} }
@PutMapping("/update") @PutMapping("/update")
@Operation(summary = "更新销售退货") @Operation(summary = "更新销售退货")
@PreAuthorize("@ss.hasPermission('erp:stock-return:update')") @PreAuthorize("@ss.hasPermission('erp:sale-return:update')")
public CommonResult<Boolean> updateSaleReturn(@Valid @RequestBody ErpSaleReturnSaveReqVO updateReqVO) { public CommonResult<Boolean> updateSaleReturn(@Valid @RequestBody ErpSaleReturnSaveReqVO updateReqVO) {
saleReturnService.updateSaleReturn(updateReqVO); saleReturnService.updateSaleReturn(updateReqVO);
return success(true); return success(true);
@ -77,7 +77,7 @@ public class ErpSaleReturnController {
@PutMapping("/update-status") @PutMapping("/update-status")
@Operation(summary = "更新销售退货的状态") @Operation(summary = "更新销售退货的状态")
@PreAuthorize("@ss.hasPermission('erp:stock-return:update-status')") @PreAuthorize("@ss.hasPermission('erp:sale-return:update-status')")
public CommonResult<Boolean> updateSaleReturnStatus(@RequestParam("id") Long id, public CommonResult<Boolean> updateSaleReturnStatus(@RequestParam("id") Long id,
@RequestParam("status") Integer status) { @RequestParam("status") Integer status) {
saleReturnService.updateSaleReturnStatus(id, status); saleReturnService.updateSaleReturnStatus(id, status);
@ -87,7 +87,7 @@ public class ErpSaleReturnController {
@DeleteMapping("/delete") @DeleteMapping("/delete")
@Operation(summary = "删除销售退货") @Operation(summary = "删除销售退货")
@Parameter(name = "ids", description = "编号数组", required = true) @Parameter(name = "ids", description = "编号数组", required = true)
@PreAuthorize("@ss.hasPermission('erp:stock-return:delete')") @PreAuthorize("@ss.hasPermission('erp:sale-return:delete')")
public CommonResult<Boolean> deleteSaleReturn(@RequestParam("ids") List<Long> ids) { public CommonResult<Boolean> deleteSaleReturn(@RequestParam("ids") List<Long> ids) {
saleReturnService.deleteSaleReturn(ids); saleReturnService.deleteSaleReturn(ids);
return success(true); return success(true);
@ -96,7 +96,7 @@ public class ErpSaleReturnController {
@GetMapping("/get") @GetMapping("/get")
@Operation(summary = "获得销售退货") @Operation(summary = "获得销售退货")
@Parameter(name = "id", description = "编号", required = true, example = "1024") @Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('erp:stock-return:query')") @PreAuthorize("@ss.hasPermission('erp:sale-return:query')")
public CommonResult<ErpSaleReturnRespVO> getSaleReturn(@RequestParam("id") Long id) { public CommonResult<ErpSaleReturnRespVO> getSaleReturn(@RequestParam("id") Long id) {
ErpSaleReturnDO saleReturn = saleReturnService.getSaleReturn(id); ErpSaleReturnDO saleReturn = saleReturnService.getSaleReturn(id);
if (saleReturn == null) { if (saleReturn == null) {
@ -116,7 +116,7 @@ public class ErpSaleReturnController {
@GetMapping("/page") @GetMapping("/page")
@Operation(summary = "获得销售退货分页") @Operation(summary = "获得销售退货分页")
@PreAuthorize("@ss.hasPermission('erp:stock-return:query')") @PreAuthorize("@ss.hasPermission('erp:sale-return:query')")
public CommonResult<PageResult<ErpSaleReturnRespVO>> getSaleReturnPage(@Valid ErpSaleReturnPageReqVO pageReqVO) { public CommonResult<PageResult<ErpSaleReturnRespVO>> getSaleReturnPage(@Valid ErpSaleReturnPageReqVO pageReqVO) {
PageResult<ErpSaleReturnDO> pageResult = saleReturnService.getSaleReturnPage(pageReqVO); PageResult<ErpSaleReturnDO> pageResult = saleReturnService.getSaleReturnPage(pageReqVO);
return success(buildSaleReturnVOPageResult(pageResult)); return success(buildSaleReturnVOPageResult(pageResult));
@ -124,7 +124,7 @@ public class ErpSaleReturnController {
@GetMapping("/export-excel") @GetMapping("/export-excel")
@Operation(summary = "导出销售退货 Excel") @Operation(summary = "导出销售退货 Excel")
@PreAuthorize("@ss.hasPermission('erp:stock-return:export')") @PreAuthorize("@ss.hasPermission('erp:sale-return:export')")
@OperateLog(type = EXPORT) @OperateLog(type = EXPORT)
public void exportSaleReturnExcel(@Valid ErpSaleReturnPageReqVO pageReqVO, public void exportSaleReturnExcel(@Valid ErpSaleReturnPageReqVO pageReqVO,
HttpServletResponse response) throws IOException { HttpServletResponse response) throws IOException {
@ -142,7 +142,7 @@ public class ErpSaleReturnController {
List<ErpSaleReturnItemDO> saleReturnItemList = saleReturnService.getSaleReturnItemListByReturnIds( List<ErpSaleReturnItemDO> saleReturnItemList = saleReturnService.getSaleReturnItemListByReturnIds(
convertSet(pageResult.getList(), ErpSaleReturnDO::getId)); convertSet(pageResult.getList(), ErpSaleReturnDO::getId));
Map<Long, List<ErpSaleReturnItemDO>> saleReturnItemMap = convertMultiMap(saleReturnItemList, ErpSaleReturnItemDO::getReturnId); Map<Long, List<ErpSaleReturnItemDO>> saleReturnItemMap = convertMultiMap(saleReturnItemList, ErpSaleReturnItemDO::getReturnId);
// 1.2 品信息 // 1.2 品信息
Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap( Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
convertSet(saleReturnItemList, ErpSaleReturnItemDO::getProductId)); convertSet(saleReturnItemList, ErpSaleReturnItemDO::getProductId));
// 1.3 客户信息 // 1.3 客户信息

View File

@ -18,17 +18,17 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
public class ErpSaleOrderPageReqVO extends PageParam { public class ErpSaleOrderPageReqVO extends PageParam {
/** /**
* 库状态 - * 库状态 -
*/ */
public static final Integer IN_STATUS_NONE = 0; public static final Integer OUT_STATUS_NONE = 0;
/** /**
* 库状态 - 部分 * 库状态 - 部分
*/ */
public static final Integer IN_STATUS_PART = 1; public static final Integer OUT_STATUS_PART = 1;
/** /**
* 库状态 - 全部 * 库状态 - 全部
*/ */
public static final Integer IN_STATUS_ALL = 2; public static final Integer OUT_STATUS_ALL = 2;
/** /**
* 退货状态 - * 退货状态 -
@ -65,8 +65,8 @@ public class ErpSaleOrderPageReqVO extends PageParam {
@Schema(description = "产品编号", example = "1") @Schema(description = "产品编号", example = "1")
private Long productId; private Long productId;
@Schema(description = "库状态", example = "2") @Schema(description = "库状态", example = "2")
private Integer inStatus; private Integer outStatus;
@Schema(description = "退货状态", example = "2") @Schema(description = "退货状态", example = "2")
private Integer returnStatus; private Integer returnStatus;

View File

@ -74,9 +74,9 @@ public class ErpSaleOrderRespVO {
@ExcelProperty("备注") @ExcelProperty("备注")
private String remark; private String remark;
@Schema(description = "审核", example = "芋道") @Schema(description = "创建", example = "芋道")
private String creator; private String creator;
@Schema(description = "审核人名称", example = "芋道") @Schema(description = "创建人名称", example = "芋道")
private String creatorName; private String creatorName;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ -133,7 +133,7 @@ public class ErpSaleOrderRespVO {
@Schema(description = "销售出库数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00") @Schema(description = "销售出库数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
private BigDecimal outCount; private BigDecimal outCount;
// ========== 销售退货 ========== // ========== 销售退货 ==========
@Schema(description = "销售退货数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00") @Schema(description = "销售退货数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
private BigDecimal returnCount; private BigDecimal returnCount;

View File

@ -85,9 +85,9 @@ public class ErpSaleOutRespVO {
@ExcelProperty("备注") @ExcelProperty("备注")
private String remark; private String remark;
@Schema(description = "审核", example = "芋道") @Schema(description = "创建", example = "芋道")
private String creator; private String creator;
@Schema(description = "审核人名称", example = "芋道") @Schema(description = "创建人名称", example = "芋道")
private String creatorName; private String creatorName;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)

View File

@ -85,9 +85,9 @@ public class ErpSaleReturnRespVO {
@ExcelProperty("备注") @ExcelProperty("备注")
private String remark; private String remark;
@Schema(description = "审核", example = "芋道") @Schema(description = "创建", example = "芋道")
private String creator; private String creator;
@Schema(description = "审核人名称", example = "芋道") @Schema(description = "创建人名称", example = "芋道")
private String creatorName; private String creatorName;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)

View File

@ -130,7 +130,7 @@ public class ErpStockCheckController {
List<ErpStockCheckItemDO> stockCheckItemList = stockCheckService.getStockCheckItemListByCheckIds( List<ErpStockCheckItemDO> stockCheckItemList = stockCheckService.getStockCheckItemListByCheckIds(
convertSet(pageResult.getList(), ErpStockCheckDO::getId)); convertSet(pageResult.getList(), ErpStockCheckDO::getId));
Map<Long, List<ErpStockCheckItemDO>> stockCheckItemMap = convertMultiMap(stockCheckItemList, ErpStockCheckItemDO::getCheckId); Map<Long, List<ErpStockCheckItemDO>> stockCheckItemMap = convertMultiMap(stockCheckItemList, ErpStockCheckItemDO::getCheckId);
// 1.2 品信息 // 1.2 品信息
Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap( Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
convertSet(stockCheckItemList, ErpStockCheckItemDO::getProductId)); convertSet(stockCheckItemList, ErpStockCheckItemDO::getProductId));
// 1.3 管理员信息 // 1.3 管理员信息

View File

@ -142,7 +142,7 @@ public class ErpStockInController {
List<ErpStockInItemDO> stockInItemList = stockInService.getStockInItemListByInIds( List<ErpStockInItemDO> stockInItemList = stockInService.getStockInItemListByInIds(
convertSet(pageResult.getList(), ErpStockInDO::getId)); convertSet(pageResult.getList(), ErpStockInDO::getId));
Map<Long, List<ErpStockInItemDO>> stockInItemMap = convertMultiMap(stockInItemList, ErpStockInItemDO::getInId); Map<Long, List<ErpStockInItemDO>> stockInItemMap = convertMultiMap(stockInItemList, ErpStockInItemDO::getInId);
// 1.2 品信息 // 1.2 品信息
Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap( Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
convertSet(stockInItemList, ErpStockInItemDO::getProductId)); convertSet(stockInItemList, ErpStockInItemDO::getProductId));
// 1.3 供应商信息 // 1.3 供应商信息

View File

@ -138,7 +138,7 @@ public class ErpStockMoveController {
List<ErpStockMoveItemDO> stockMoveItemList = stockMoveService.getStockMoveItemListByMoveIds( List<ErpStockMoveItemDO> stockMoveItemList = stockMoveService.getStockMoveItemListByMoveIds(
convertSet(pageResult.getList(), ErpStockMoveDO::getId)); convertSet(pageResult.getList(), ErpStockMoveDO::getId));
Map<Long, List<ErpStockMoveItemDO>> stockMoveItemMap = convertMultiMap(stockMoveItemList, ErpStockMoveItemDO::getMoveId); Map<Long, List<ErpStockMoveItemDO>> stockMoveItemMap = convertMultiMap(stockMoveItemList, ErpStockMoveItemDO::getMoveId);
// 1.2 品信息 // 1.2 品信息
Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap( Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
convertSet(stockMoveItemList, ErpStockMoveItemDO::getProductId)); convertSet(stockMoveItemList, ErpStockMoveItemDO::getProductId));
// 1.3 TODO 芋艿搞仓库信息 // 1.3 TODO 芋艿搞仓库信息

View File

@ -142,7 +142,7 @@ public class ErpStockOutController {
List<ErpStockOutItemDO> stockOutItemList = stockOutService.getStockOutItemListByOutIds( List<ErpStockOutItemDO> stockOutItemList = stockOutService.getStockOutItemListByOutIds(
convertSet(pageResult.getList(), ErpStockOutDO::getId)); convertSet(pageResult.getList(), ErpStockOutDO::getId));
Map<Long, List<ErpStockOutItemDO>> stockOutItemMap = convertMultiMap(stockOutItemList, ErpStockOutItemDO::getOutId); Map<Long, List<ErpStockOutItemDO>> stockOutItemMap = convertMultiMap(stockOutItemList, ErpStockOutItemDO::getOutId);
// 1.2 品信息 // 1.2 品信息
Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap( Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
convertSet(stockOutItemList, ErpStockOutItemDO::getProductId)); convertSet(stockOutItemList, ErpStockOutItemDO::getProductId));
// 1.3 客户信息 // 1.3 客户信息

View File

@ -51,9 +51,9 @@ public class ErpStockCheckRespVO {
@Schema(description = "附件 URL", example = "https://www.iocoder.cn/1.doc") @Schema(description = "附件 URL", example = "https://www.iocoder.cn/1.doc")
private String fileUrl; private String fileUrl;
@Schema(description = "审核", example = "芋道") @Schema(description = "创建", example = "芋道")
private String creator; private String creator;
@Schema(description = "审核人名称", example = "芋道") @Schema(description = "创建人名称", example = "芋道")
private String creatorName; private String creatorName;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)

View File

@ -56,9 +56,9 @@ public class ErpStockInRespVO {
@Schema(description = "附件 URL", example = "https://www.iocoder.cn/1.doc") @Schema(description = "附件 URL", example = "https://www.iocoder.cn/1.doc")
private String fileUrl; private String fileUrl;
@Schema(description = "审核", example = "芋道") @Schema(description = "创建", example = "芋道")
private String creator; private String creator;
@Schema(description = "审核人名称", example = "芋道") @Schema(description = "创建人名称", example = "芋道")
private String creatorName; private String creatorName;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)

View File

@ -50,9 +50,9 @@ public class ErpStockMoveRespVO {
@Schema(description = "附件 URL", example = "https://www.iocoder.cn/1.doc") @Schema(description = "附件 URL", example = "https://www.iocoder.cn/1.doc")
private String fileUrl; private String fileUrl;
@Schema(description = "审核", example = "芋道") @Schema(description = "创建", example = "芋道")
private String creator; private String creator;
@Schema(description = "审核人名称", example = "芋道") @Schema(description = "创建人名称", example = "芋道")
private String creatorName; private String creatorName;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)

View File

@ -56,9 +56,9 @@ public class ErpStockOutRespVO {
@Schema(description = "附件 URL", example = "https://www.iocoder.cn/1.doc") @Schema(description = "附件 URL", example = "https://www.iocoder.cn/1.doc")
private String fileUrl; private String fileUrl;
@Schema(description = "审核", example = "芋道") @Schema(description = "创建", example = "芋道")
private String creator; private String creator;
@Schema(description = "审核人名称", example = "芋道") @Schema(description = "创建人名称", example = "芋道")
private String creatorName; private String creatorName;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)

View File

@ -0,0 +1,115 @@
package cn.iocoder.yudao.module.erp.dal.dataobject.purchase;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpAccountDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* ERP 采购订单 DO
*
* @author 芋道源码
*/
@TableName(value = "erp_purchase_order")
@KeySequence("erp_purchase_order_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ErpPurchaseOrderDO extends BaseDO {
/**
* 编号
*/
@TableId
private Long id;
/**
* 采购订单号
*/
private String no;
/**
* 采购状态
*
* 枚举 {@link cn.iocoder.yudao.module.erp.enums.ErpAuditStatus}
*/
private Integer status;
/**
* 供应商编号
*
* 关联 {@link ErpSupplierDO#getId()}
*/
private Long supplierId;
/**
* 结算账户编号
*
* 关联 {@link ErpAccountDO#getId()}
*/
private Long accountId;
/**
* 下单时间
*/
private LocalDateTime orderTime;
/**
* 合计数量
*/
private BigDecimal totalCount;
/**
* 最终合计价格单位
*
* totalPrice = totalProductPrice + totalTaxPrice - discountPrice
*/
private BigDecimal totalPrice;
/**
* 合计产品价格单位
*/
private BigDecimal totalProductPrice;
/**
* 合计税额单位
*/
private BigDecimal totalTaxPrice;
/**
* 优惠率百分比
*/
private BigDecimal discountPercent;
/**
* 优惠金额单位
*
* discountPrice = (totalProductPrice + totalTaxPrice) * discountPercent
*/
private BigDecimal discountPrice;
/**
* 定金金额单位
*/
private BigDecimal depositPrice;
/**
* 附件地址
*/
private String fileUrl;
/**
* 备注
*/
private String remark;
// ========== 采购入库 ==========
/**
* 采购入库数量
*/
private BigDecimal inCount;
// ========== 采购退货出库 ==========
/**
* 采购退货数量
*/
private BigDecimal returnCount;
}

View File

@ -0,0 +1,93 @@
package cn.iocoder.yudao.module.erp.dal.dataobject.purchase;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import java.math.BigDecimal;
/**
* ERP 采购订单项 DO
*
* @author 芋道源码
*/
@TableName("erp_sale_order_items")
@KeySequence("erp_sale_order_items_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ErpPurchaseOrderItemDO extends BaseDO {
/**
* 编号
*/
@TableId
private Long id;
/**
* 采购订单编号
*
* 关联 {@link ErpPurchaseOrderDO#getId()}
*/
private Long orderId;
/**
* 产品编号
*
* 关联 {@link ErpProductDO#getId()}
*/
private Long productId;
/**
* 产品单位单位
*
* 冗余 {@link ErpProductDO#getUnitId()}
*/
private Long productUnitId;
/**
* 产品单位单价单位
*/
private BigDecimal productPrice;
/**
* 数量
*/
private BigDecimal count;
/**
* 总价单位
*
* totalPrice = productPrice * count
*/
private BigDecimal totalPrice;
/**
* 税率百分比
*/
private BigDecimal taxPercent;
/**
* 税额单位
*
* taxPrice = totalPrice * taxPercent
*/
private BigDecimal taxPrice;
/**
* 备注
*/
private String remark;
// ========== 采购入库 ==========
/**
* 采购入库数量
*/
private BigDecimal inCount;
// ========== 采购退货出库 ==========
/**
* 采购退货数量
*/
private BigDecimal returnCount;
}

View File

@ -112,7 +112,7 @@ public class ErpSaleOrderDO extends BaseDO {
*/ */
private BigDecimal outCount; private BigDecimal outCount;
// ========== 销售退货 ========== // ========== 销售退货 ==========
/** /**
* 销售退货数量 * 销售退货数量
*/ */

View File

@ -84,7 +84,7 @@ public class ErpSaleOrderItemDO extends BaseDO {
*/ */
private BigDecimal outCount; private BigDecimal outCount;
// ========== 销售退货 ========== // ========== 销售退货 ==========
/** /**
* 销售退货数量 * 销售退货数量
*/ */

View File

@ -0,0 +1,30 @@
package cn.iocoder.yudao.module.erp.dal.mysql.purchase;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderItemDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.Collection;
import java.util.List;
/**
* ERP 采购订单明项目 Mapper
*
* @author 芋道源码
*/
@Mapper
public interface ErpPurchaseOrderItemMapper extends BaseMapperX<ErpPurchaseOrderItemDO> {
default List<ErpPurchaseOrderItemDO> selectListByOrderId(Long orderId) {
return selectList(ErpPurchaseOrderItemDO::getOrderId, orderId);
}
default List<ErpPurchaseOrderItemDO> selectListByOrderIds(Collection<Long> orderIds) {
return selectList(ErpPurchaseOrderItemDO::getOrderId, orderIds);
}
default int deleteByOrderId(Long orderId) {
return delete(ErpPurchaseOrderItemDO::getOrderId, orderId);
}
}

View File

@ -0,0 +1,75 @@
package cn.iocoder.yudao.module.erp.dal.mysql.purchase;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order.ErpPurchaseOrderPageReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderItemDO;
import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.Objects;
/**
* ERP 采购订单 Mapper
*
* @author 芋道源码
*/
@Mapper
public interface ErpPurchaseOrderMapper extends BaseMapperX<ErpPurchaseOrderDO> {
default PageResult<ErpPurchaseOrderDO> selectPage(ErpPurchaseOrderPageReqVO reqVO) {
MPJLambdaWrapperX<ErpPurchaseOrderDO> query = new MPJLambdaWrapperX<ErpPurchaseOrderDO>()
.likeIfPresent(ErpPurchaseOrderDO::getNo, reqVO.getNo())
.eqIfPresent(ErpPurchaseOrderDO::getSupplierId, reqVO.getSupplierId())
.betweenIfPresent(ErpPurchaseOrderDO::getOrderTime, reqVO.getOrderTime())
.eqIfPresent(ErpPurchaseOrderDO::getStatus, reqVO.getStatus())
.likeIfPresent(ErpPurchaseOrderDO::getRemark, reqVO.getRemark())
.eqIfPresent(ErpPurchaseOrderDO::getCreator, reqVO.getCreator())
.orderByDesc(ErpPurchaseOrderDO::getId);
// 入库状态为什么需要 t. 的原因是因为联表查询时需要指定表名不然会报 in_count 错误
if (Objects.equals(reqVO.getInStatus(), ErpPurchaseOrderPageReqVO.IN_STATUS_NONE)) {
query.eq(ErpPurchaseOrderDO::getInCount, 0);
} else if (Objects.equals(reqVO.getInStatus(), ErpPurchaseOrderPageReqVO.IN_STATUS_PART)) {
query.gt(ErpPurchaseOrderDO::getInCount, 0).apply("t.in_count < t.total_count");
} else if (Objects.equals(reqVO.getInStatus(), ErpPurchaseOrderPageReqVO.IN_STATUS_ALL)) {
query.apply("t.in_count = t.total_count");
}
// 退货状态
if (Objects.equals(reqVO.getReturnStatus(), ErpPurchaseOrderPageReqVO.RETURN_STATUS_NONE)) {
query.eq(ErpPurchaseOrderDO::getReturnCount, 0);
} else if (Objects.equals(reqVO.getReturnStatus(), ErpPurchaseOrderPageReqVO.RETURN_STATUS_PART)) {
query.gt(ErpPurchaseOrderDO::getReturnCount, 0).apply("t.return_count < t.total_count");
} else if (Objects.equals(reqVO.getReturnStatus(), ErpPurchaseOrderPageReqVO.RETURN_STATUS_ALL)) {
query.apply("t.return_count = t.total_count");
}
// 可采购出库
if (Boolean.TRUE.equals(reqVO.getInEnable())) {
query.eq(ErpPurchaseOrderDO::getStatus, ErpAuditStatus.APPROVE.getStatus())
.apply("t.in_count < t.total_count");
}
// 可采购退货
if (Boolean.TRUE.equals(reqVO.getReturnEnable())) {
query.eq(ErpPurchaseOrderDO::getStatus, ErpAuditStatus.APPROVE.getStatus())
.apply("t.return_count < t.in_count");
}
if (reqVO.getProductId() != null) {
query.leftJoin(ErpPurchaseOrderItemDO.class, ErpPurchaseOrderItemDO::getOrderId, ErpPurchaseOrderDO::getId)
.eq(reqVO.getProductId() != null, ErpPurchaseOrderItemDO::getProductId, reqVO.getProductId())
.groupBy(ErpPurchaseOrderDO::getId); // 避免 1 对多查询产生相同的 1
}
return selectJoinPage(reqVO, ErpPurchaseOrderDO.class, query);
}
default int updateByIdAndStatus(Long id, Integer status, ErpPurchaseOrderDO updateObj) {
return update(updateObj, new LambdaUpdateWrapper<ErpPurchaseOrderDO>()
.eq(ErpPurchaseOrderDO::getId, id).eq(ErpPurchaseOrderDO::getStatus, status));
}
default ErpPurchaseOrderDO selectByNo(String no) {
return selectOne(ErpPurchaseOrderDO::getNo, no);
}
}

View File

@ -31,11 +31,11 @@ public interface ErpSaleOrderMapper extends BaseMapperX<ErpSaleOrderDO> {
.eqIfPresent(ErpSaleOrderDO::getCreator, reqVO.getCreator()) .eqIfPresent(ErpSaleOrderDO::getCreator, reqVO.getCreator())
.orderByDesc(ErpSaleOrderDO::getId); .orderByDesc(ErpSaleOrderDO::getId);
// 入库状态为什么需要 t. 的原因是因为联表查询时需要指定表名不然会报 out_count 错误 // 入库状态为什么需要 t. 的原因是因为联表查询时需要指定表名不然会报 out_count 错误
if (Objects.equals(reqVO.getInStatus(), ErpSaleOrderPageReqVO.IN_STATUS_NONE)) { if (Objects.equals(reqVO.getOutStatus(), ErpSaleOrderPageReqVO.OUT_STATUS_NONE)) {
query.eq(ErpSaleOrderDO::getOutCount, 0); query.eq(ErpSaleOrderDO::getOutCount, 0);
} else if (Objects.equals(reqVO.getInStatus(), ErpSaleOrderPageReqVO.IN_STATUS_PART)) { } else if (Objects.equals(reqVO.getOutStatus(), ErpSaleOrderPageReqVO.OUT_STATUS_PART)) {
query.gt(ErpSaleOrderDO::getOutCount, 0).apply("t.out_count < t.total_count"); query.gt(ErpSaleOrderDO::getOutCount, 0).apply("t.out_count < t.total_count");
} else if (Objects.equals(reqVO.getInStatus(), ErpSaleOrderPageReqVO.IN_STATUS_ALL)) { } else if (Objects.equals(reqVO.getOutStatus(), ErpSaleOrderPageReqVO.OUT_STATUS_ALL)) {
query.apply("t.out_count = t.total_count"); query.apply("t.out_count = t.total_count");
} }
// 退货状态 // 退货状态

View File

@ -51,6 +51,11 @@ public class ErpNoRedisDAO {
*/ */
public static final String SALE_RETURN_NO_PREFIX = "XSTH"; public static final String SALE_RETURN_NO_PREFIX = "XSTH";
/**
* 采购订单 {@link cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderDO}
*/
public static final String PURCHASE_ORDER_NO_PREFIX = "CGDD";
@Resource @Resource
private StringRedisTemplate stringRedisTemplate; private StringRedisTemplate stringRedisTemplate;

View File

@ -74,7 +74,7 @@ public class ErpProductUnitServiceImpl implements ErpProductUnitService {
public void deleteProductUnit(Long id) { public void deleteProductUnit(Long id) {
// 1.1 校验存在 // 1.1 校验存在
validateProductUnitExists(id); validateProductUnitExists(id);
// 1.2 校验品是否使用 // 1.2 校验品是否使用
if (productService.getProductCountByUnitId(id) > 0) { if (productService.getProductCountByUnitId(id) > 0) {
throw exception(PRODUCT_UNIT_EXITS_PRODUCT); throw exception(PRODUCT_UNIT_EXITS_PRODUCT);
} }

View File

@ -0,0 +1,110 @@
package cn.iocoder.yudao.module.erp.service.purchase;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order.ErpPurchaseOrderPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order.ErpPurchaseOrderSaveReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderItemDO;
import jakarta.validation.Valid;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* ERP 采购订单 Service 接口
*
* @author 芋道源码
*/
public interface ErpPurchaseOrderService {
/**
* 创建采购订单
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createPurchaseOrder(@Valid ErpPurchaseOrderSaveReqVO createReqVO);
/**
* 更新采购订单
*
* @param updateReqVO 更新信息
*/
void updatePurchaseOrder(@Valid ErpPurchaseOrderSaveReqVO updateReqVO);
/**
* 更新采购订单的状态
*
* @param id 编号
* @param status 状态
*/
void updatePurchaseOrderStatus(Long id, Integer status);
/**
* 更新采购订单的入库数量
*
* @param id 编号
* @param inCountMap 入库数量 Mapkey 采购订单项编号value 入库数量
*/
void updatePurchaseOrderInCount(Long id, Map<Long, BigDecimal> inCountMap);
/**
* 更新采购订单的退货数量
*
* @param orderId 编号
* @param returnCountMap 退货数量 Mapkey 采购订单项编号value 退货数量
*/
void updatePurchaseOrderReturnCount(Long orderId, Map<Long, BigDecimal> returnCountMap);
/**
* 删除采购订单
*
* @param ids 编号数组
*/
void deletePurchaseOrder(List<Long> ids);
/**
* 获得采购订单
*
* @param id 编号
* @return 采购订单
*/
ErpPurchaseOrderDO getPurchaseOrder(Long id);
/**
* 校验采购订单已经审核通过
*
* @param id 编号
* @return 采购订单
*/
ErpPurchaseOrderDO validatePurchaseOrder(Long id);
/**
* 获得采购订单分页
*
* @param pageReqVO 分页查询
* @return 采购订单分页
*/
PageResult<ErpPurchaseOrderDO> getPurchaseOrderPage(ErpPurchaseOrderPageReqVO pageReqVO);
// ==================== 采购订单项 ====================
/**
* 获得采购订单项列表
*
* @param orderId 采购订单编号
* @return 采购订单项列表
*/
List<ErpPurchaseOrderItemDO> getPurchaseOrderItemListByOrderId(Long orderId);
/**
* 获得采购订单项 List
*
* @param orderIds 采购订单编号数组
* @return 采购订单项 List
*/
List<ErpPurchaseOrderItemDO> getPurchaseOrderItemListByOrderIds(Collection<Long> orderIds);
}

View File

@ -0,0 +1,297 @@
package cn.iocoder.yudao.module.erp.service.purchase;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order.ErpPurchaseOrderPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order.ErpPurchaseOrderSaveReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderItemDO;
import cn.iocoder.yudao.module.erp.dal.mysql.purchase.ErpPurchaseOrderItemMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.purchase.ErpPurchaseOrderMapper;
import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO;
import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
import cn.iocoder.yudao.module.erp.service.finance.ErpAccountService;
import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
// TODO 芋艿记录操作日志
/**
* ERP 采购订单 Service 实现类
*
* @author 芋道源码
*/
@Service
@Validated
public class ErpPurchaseOrderServiceImpl implements ErpPurchaseOrderService {
@Resource
private ErpPurchaseOrderMapper purchaseOrderMapper;
@Resource
private ErpPurchaseOrderItemMapper purchaseOrderItemMapper;
@Resource
private ErpNoRedisDAO noRedisDAO;
@Resource
private ErpProductService productService;
@Resource
private ErpSupplierService supplierService;
@Resource
private ErpAccountService accountService;
@Override
@Transactional(rollbackFor = Exception.class)
public Long createPurchaseOrder(ErpPurchaseOrderSaveReqVO createReqVO) {
// 1.1 校验订单项的有效性
List<ErpPurchaseOrderItemDO> purchaseOrderItems = validatePurchaseOrderItems(createReqVO.getItems());
// 1.2 校验供应商
supplierService.validateSupplier(createReqVO.getSupplierId());
// 1.3 校验结算账户
if (createReqVO.getAccountId() != null) {
accountService.validateAccount(createReqVO.getAccountId());
}
// 1.4 生成调拨单号并校验唯一性
String no = noRedisDAO.generate(ErpNoRedisDAO.PURCHASE_ORDER_NO_PREFIX);
if (purchaseOrderMapper.selectByNo(no) != null) {
throw exception(PURCHASE_ORDER_NO_EXISTS);
}
// 2.1 插入订单
ErpPurchaseOrderDO purchaseOrder = BeanUtils.toBean(createReqVO, ErpPurchaseOrderDO.class, in -> in
.setNo(no).setStatus(ErpAuditStatus.PROCESS.getStatus()));
calculateTotalPrice(purchaseOrder, purchaseOrderItems);
purchaseOrderMapper.insert(purchaseOrder);
// 2.2 插入订单项
purchaseOrderItems.forEach(o -> o.setOrderId(purchaseOrder.getId()));
purchaseOrderItemMapper.insertBatch(purchaseOrderItems);
return purchaseOrder.getId();
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updatePurchaseOrder(ErpPurchaseOrderSaveReqVO updateReqVO) {
// 1.1 校验存在
ErpPurchaseOrderDO purchaseOrder = validatePurchaseOrderExists(updateReqVO.getId());
if (ErpAuditStatus.APPROVE.getStatus().equals(purchaseOrder.getStatus())) {
throw exception(PURCHASE_ORDER_UPDATE_FAIL_APPROVE, purchaseOrder.getNo());
}
// 1.2 校验供应商
supplierService.validateSupplier(updateReqVO.getSupplierId());
// 1.3 校验结算账户
if (updateReqVO.getAccountId() != null) {
accountService.validateAccount(updateReqVO.getAccountId());
}
// 1.4 校验订单项的有效性
List<ErpPurchaseOrderItemDO> purchaseOrderItems = validatePurchaseOrderItems(updateReqVO.getItems());
// 2.1 更新订单
ErpPurchaseOrderDO updateObj = BeanUtils.toBean(updateReqVO, ErpPurchaseOrderDO.class);
calculateTotalPrice(updateObj, purchaseOrderItems);
purchaseOrderMapper.updateById(updateObj);
// 2.2 更新订单项
updatePurchaseOrderItemList(updateReqVO.getId(), purchaseOrderItems);
}
private void calculateTotalPrice(ErpPurchaseOrderDO purchaseOrder, List<ErpPurchaseOrderItemDO> purchaseOrderItems) {
purchaseOrder.setTotalCount(getSumValue(purchaseOrderItems, ErpPurchaseOrderItemDO::getCount, BigDecimal::add));
purchaseOrder.setTotalProductPrice(getSumValue(purchaseOrderItems, ErpPurchaseOrderItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO));
purchaseOrder.setTotalTaxPrice(getSumValue(purchaseOrderItems, ErpPurchaseOrderItemDO::getTaxPrice, BigDecimal::add, BigDecimal.ZERO));
purchaseOrder.setTotalPrice(purchaseOrder.getTotalProductPrice().add(purchaseOrder.getTotalTaxPrice()));
// 计算优惠价格
if (purchaseOrder.getDiscountPercent() == null) {
purchaseOrder.setDiscountPercent(BigDecimal.ZERO);
}
purchaseOrder.setDiscountPrice(MoneyUtils.priceMultiplyPercent(purchaseOrder.getTotalPrice(), purchaseOrder.getDiscountPercent()));
purchaseOrder.setTotalPrice(purchaseOrder.getTotalPrice().subtract(purchaseOrder.getDiscountPrice()));
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updatePurchaseOrderStatus(Long id, Integer status) {
boolean approve = ErpAuditStatus.APPROVE.getStatus().equals(status);
// 1.1 校验存在
ErpPurchaseOrderDO purchaseOrder = validatePurchaseOrderExists(id);
// 1.2 校验状态
if (purchaseOrder.getStatus().equals(status)) {
throw exception(approve ? PURCHASE_ORDER_APPROVE_FAIL : PURCHASE_ORDER_PROCESS_FAIL);
}
// 1.3 存在采购入单无法反审核
if (!approve && purchaseOrder.getInCount().compareTo(BigDecimal.ZERO) > 0) {
throw exception(PURCHASE_ORDER_PROCESS_FAIL_EXISTS_IN);
}
// 1.4 存在采购退货单无法反审核
if (!approve && purchaseOrder.getReturnCount().compareTo(BigDecimal.ZERO) > 0) {
throw exception(PURCHASE_ORDER_PROCESS_FAIL_EXISTS_RETURN);
}
// 2. 更新状态
int updateCount = purchaseOrderMapper.updateByIdAndStatus(id, purchaseOrder.getStatus(),
new ErpPurchaseOrderDO().setStatus(status));
if (updateCount == 0) {
throw exception(approve ? PURCHASE_ORDER_APPROVE_FAIL : PURCHASE_ORDER_PROCESS_FAIL);
}
}
private List<ErpPurchaseOrderItemDO> validatePurchaseOrderItems(List<ErpPurchaseOrderSaveReqVO.Item> list) {
// 1. 校验产品存在
List<ErpProductDO> productList = productService.validProductList(
convertSet(list, ErpPurchaseOrderSaveReqVO.Item::getProductId));
Map<Long, ErpProductDO> productMap = convertMap(productList, ErpProductDO::getId);
// 2. 转化为 ErpPurchaseOrderItemDO 列表
return convertList(list, o -> BeanUtils.toBean(o, ErpPurchaseOrderItemDO.class, item -> {
item.setProductUnitId(productMap.get(item.getProductId()).getUnitId());
item.setTotalPrice(MoneyUtils.priceMultiply(item.getProductPrice(), item.getCount()));
if (item.getTotalPrice() == null) {
return;
}
if (item.getTaxPercent() == null) {
item.setTaxPercent(BigDecimal.ZERO);
} else {
item.setTaxPrice(MoneyUtils.priceMultiplyPercent(item.getTotalPrice(), item.getTaxPercent()));
}
}));
}
private void updatePurchaseOrderItemList(Long id, List<ErpPurchaseOrderItemDO> newList) {
// 第一步对比新老数据获得添加修改删除的列表
List<ErpPurchaseOrderItemDO> oldList = purchaseOrderItemMapper.selectListByOrderId(id);
List<List<ErpPurchaseOrderItemDO>> diffList = diffList(oldList, newList, // id 不同就认为是不同的记录
(oldVal, newVal) -> oldVal.getId().equals(newVal.getId()));
// 第二步批量添加修改删除
if (CollUtil.isNotEmpty(diffList.get(0))) {
diffList.get(0).forEach(o -> o.setOrderId(id));
purchaseOrderItemMapper.insertBatch(diffList.get(0));
}
if (CollUtil.isNotEmpty(diffList.get(1))) {
purchaseOrderItemMapper.updateBatch(diffList.get(1));
}
if (CollUtil.isNotEmpty(diffList.get(2))) {
purchaseOrderItemMapper.deleteBatchIds(convertList(diffList.get(2), ErpPurchaseOrderItemDO::getId));
}
}
@Override
public void updatePurchaseOrderInCount(Long id, Map<Long, BigDecimal> inCountMap) {
List<ErpPurchaseOrderItemDO> orderItems = purchaseOrderItemMapper.selectListByOrderId(id);
// 1. 更新每个采购订单项
orderItems.forEach(item -> {
BigDecimal inCount = inCountMap.getOrDefault(item.getId(), BigDecimal.ZERO);
if (item.getInCount().equals(inCount)) {
return;
}
if (inCount.compareTo(item.getCount()) > 0) {
throw exception(PURCHASE_ORDER_ITEM_IN_FAIL_PRODUCT_EXCEED,
productService.getProduct(item.getProductId()).getName(), item.getCount());
}
purchaseOrderItemMapper.updateById(new ErpPurchaseOrderItemDO().setId(item.getId()).setInCount(inCount));
});
// 2. 更新采购订单
BigDecimal totalInCount = getSumValue(inCountMap.values(), value -> value, BigDecimal::add, BigDecimal.ZERO);
purchaseOrderMapper.updateById(new ErpPurchaseOrderDO().setId(id).setInCount(totalInCount));
}
@Override
public void updatePurchaseOrderReturnCount(Long orderId, Map<Long, BigDecimal> returnCountMap) {
List<ErpPurchaseOrderItemDO> orderItems = purchaseOrderItemMapper.selectListByOrderId(orderId);
// 1. 更新每个采购订单项
orderItems.forEach(item -> {
BigDecimal returnCount = returnCountMap.getOrDefault(item.getId(), BigDecimal.ZERO);
if (item.getReturnCount().equals(returnCount)) {
return;
}
if (returnCount.compareTo(item.getInCount()) > 0) {
throw exception(PURCHASE_ORDER_ITEM_RETURN_FAIL_IN_EXCEED,
productService.getProduct(item.getProductId()).getName(), item.getInCount());
}
purchaseOrderItemMapper.updateById(new ErpPurchaseOrderItemDO().setId(item.getId()).setReturnCount(returnCount));
});
// 2. 更新采购订单
BigDecimal totalReturnCount = getSumValue(returnCountMap.values(), value -> value, BigDecimal::add, BigDecimal.ZERO);
purchaseOrderMapper.updateById(new ErpPurchaseOrderDO().setId(orderId).setReturnCount(totalReturnCount));
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deletePurchaseOrder(List<Long> ids) {
// 1. 校验不处于已审批
List<ErpPurchaseOrderDO> purchaseOrders = purchaseOrderMapper.selectBatchIds(ids);
if (CollUtil.isEmpty(purchaseOrders)) {
return;
}
purchaseOrders.forEach(purchaseOrder -> {
if (ErpAuditStatus.APPROVE.getStatus().equals(purchaseOrder.getStatus())) {
throw exception(PURCHASE_ORDER_DELETE_FAIL_APPROVE, purchaseOrder.getNo());
}
});
// 2. 遍历删除并记录操作日志
purchaseOrders.forEach(purchaseOrder -> {
// 2.1 删除订单
purchaseOrderMapper.deleteById(purchaseOrder.getId());
// 2.2 删除订单项
purchaseOrderItemMapper.deleteByOrderId(purchaseOrder.getId());
});
}
private ErpPurchaseOrderDO validatePurchaseOrderExists(Long id) {
ErpPurchaseOrderDO purchaseOrder = purchaseOrderMapper.selectById(id);
if (purchaseOrder == null) {
throw exception(PURCHASE_ORDER_NOT_EXISTS);
}
return purchaseOrder;
}
@Override
public ErpPurchaseOrderDO getPurchaseOrder(Long id) {
return purchaseOrderMapper.selectById(id);
}
@Override
public ErpPurchaseOrderDO validatePurchaseOrder(Long id) {
ErpPurchaseOrderDO purchaseOrder = validatePurchaseOrderExists(id);
if (ObjectUtil.notEqual(purchaseOrder.getStatus(), ErpAuditStatus.APPROVE.getStatus())) {
throw exception(PURCHASE_ORDER_NOT_APPROVE);
}
return purchaseOrder;
}
@Override
public PageResult<ErpPurchaseOrderDO> getPurchaseOrderPage(ErpPurchaseOrderPageReqVO pageReqVO) {
return purchaseOrderMapper.selectPage(pageReqVO);
}
// ==================== 订单项 ====================
@Override
public List<ErpPurchaseOrderItemDO> getPurchaseOrderItemListByOrderId(Long orderId) {
return purchaseOrderItemMapper.selectListByOrderId(orderId);
}
@Override
public List<ErpPurchaseOrderItemDO> getPurchaseOrderItemListByOrderIds(Collection<Long> orderIds) {
if (CollUtil.isEmpty(orderIds)) {
return Collections.emptyList();
}
return purchaseOrderItemMapper.selectListByOrderIds(orderIds);
}
}

View File

@ -187,7 +187,7 @@ public class ErpSaleReturnServiceImpl implements ErpSaleReturnService {
Integer bizType = approve ? ErpStockRecordBizTypeEnum.SALE_RETURN.getType() Integer bizType = approve ? ErpStockRecordBizTypeEnum.SALE_RETURN.getType()
: ErpStockRecordBizTypeEnum.SALE_RETURN_CANCEL.getType(); : ErpStockRecordBizTypeEnum.SALE_RETURN_CANCEL.getType();
saleReturnItems.forEach(saleReturnItem -> { saleReturnItems.forEach(saleReturnItem -> {
BigDecimal count = approve ? saleReturnItem.getCount().negate() : saleReturnItem.getCount(); BigDecimal count = approve ? saleReturnItem.getCount() : saleReturnItem.getCount().negate();
stockRecordService.createStockRecord(new ErpStockRecordCreateReqBO( stockRecordService.createStockRecord(new ErpStockRecordCreateReqBO(
saleReturnItem.getProductId(), saleReturnItem.getWarehouseId(), count, saleReturnItem.getProductId(), saleReturnItem.getWarehouseId(), count,
bizType, saleReturnItem.getReturnId(), saleReturnItem.getId(), saleReturn.getNo())); bizType, saleReturnItem.getReturnId(), saleReturnItem.getId(), saleReturn.getNo()));