Commit ab7c12d34b2caaeb2487e2e36e149aaca119c7a7

Authored by YunaiV
1 parent c9c362a2

✨ feat(mes): 新增销售出库单行及明细相关功能和数据结构

新增销售出库单行和明细的请求和响应对象,包含分页查询、创建、更新和删除功能。实现了销售出库单行和明细的数据库映射,并提供了相应的服务接口和控制器,支持前端调用。

同时,更新了相关的 API 接口,确保前端能够正确获取和操作销售出库单行及明细数据。
Showing 25 changed files with 1882 additions and 0 deletions
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productsales/MesWmProductSalesController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.wm.productsales;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
  5 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  7 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  8 +import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
  9 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  10 +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  11 +import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.MesWmProductSalesPageReqVO;
  12 +import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.MesWmProductSalesRespVO;
  13 +import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.MesWmProductSalesSaveReqVO;
  14 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.client.MesMdClientDO;
  15 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesDO;
  16 +import cn.iocoder.yudao.module.mes.service.md.client.MesMdClientService;
  17 +import cn.iocoder.yudao.module.mes.service.wm.productsales.MesWmProductSalesService;
  18 +import io.swagger.v3.oas.annotations.Operation;
  19 +import io.swagger.v3.oas.annotations.Parameter;
  20 +import io.swagger.v3.oas.annotations.tags.Tag;
  21 +import jakarta.annotation.Resource;
  22 +import jakarta.servlet.http.HttpServletResponse;
  23 +import jakarta.validation.Valid;
  24 +import org.springframework.security.access.prepost.PreAuthorize;
  25 +import org.springframework.validation.annotation.Validated;
  26 +import org.springframework.web.bind.annotation.*;
  27 +
  28 +import java.io.IOException;
  29 +import java.util.Collections;
  30 +import java.util.List;
  31 +import java.util.Map;
  32 +
  33 +import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
  34 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  35 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
  36 +
  37 +@Tag(name = "管理后台 - MES 销售出库单")
  38 +@RestController
  39 +@RequestMapping("/mes/wm/product-sales")
  40 +@Validated
  41 +public class MesWmProductSalesController {
  42 +
  43 + @Resource
  44 + private MesWmProductSalesService productSalesService;
  45 +
  46 + @Resource
  47 + private MesMdClientService clientService;
  48 +
  49 + @PostMapping("/create")
  50 + @Operation(summary = "创建销售出库单")
  51 + @PreAuthorize("@ss.hasPermission('mes:wm-product-sales:create')")
  52 + public CommonResult<Long> createProductSales(@Valid @RequestBody MesWmProductSalesSaveReqVO createReqVO) {
  53 + return success(productSalesService.createProductSales(createReqVO));
  54 + }
  55 +
  56 + @PutMapping("/update")
  57 + @Operation(summary = "修改销售出库单")
  58 + @PreAuthorize("@ss.hasPermission('mes:wm-product-sales:update')")
  59 + public CommonResult<Boolean> updateProductSales(@Valid @RequestBody MesWmProductSalesSaveReqVO updateReqVO) {
  60 + productSalesService.updateProductSales(updateReqVO);
  61 + return success(true);
  62 + }
  63 +
  64 + @DeleteMapping("/delete")
  65 + @Operation(summary = "删除销售出库单")
  66 + @Parameter(name = "id", description = "编号", required = true)
  67 + @PreAuthorize("@ss.hasPermission('mes:wm-product-sales:delete')")
  68 + public CommonResult<Boolean> deleteProductSales(@RequestParam("id") Long id) {
  69 + productSalesService.deleteProductSales(id);
  70 + return success(true);
  71 + }
  72 +
  73 + @GetMapping("/get")
  74 + @Operation(summary = "获得销售出库单")
  75 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  76 + @PreAuthorize("@ss.hasPermission('mes:wm-product-sales:query')")
  77 + public CommonResult<MesWmProductSalesRespVO> getProductSales(@RequestParam("id") Long id) {
  78 + MesWmProductSalesDO sales = productSalesService.getProductSales(id);
  79 + if (sales == null) {
  80 + return success(null);
  81 + }
  82 + return success(buildRespVOList(Collections.singletonList(sales)).get(0));
  83 + }
  84 +
  85 + @GetMapping("/page")
  86 + @Operation(summary = "获得销售出库单分页")
  87 + @PreAuthorize("@ss.hasPermission('mes:wm-product-sales:query')")
  88 + public CommonResult<PageResult<MesWmProductSalesRespVO>> getProductSalesPage(
  89 + @Valid MesWmProductSalesPageReqVO pageReqVO) {
  90 + PageResult<MesWmProductSalesDO> pageResult = productSalesService.getProductSalesPage(pageReqVO);
  91 + return success(new PageResult<>(buildRespVOList(pageResult.getList()), pageResult.getTotal()));
  92 + }
  93 +
  94 + @GetMapping("/export-excel")
  95 + @Operation(summary = "导出销售出库单 Excel")
  96 + @PreAuthorize("@ss.hasPermission('mes:wm-product-sales:export')")
  97 + @ApiAccessLog(operateType = EXPORT)
  98 + public void exportProductSalesExcel(@Valid MesWmProductSalesPageReqVO pageReqVO,
  99 + HttpServletResponse response) throws IOException {
  100 + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
  101 + PageResult<MesWmProductSalesDO> pageResult = productSalesService.getProductSalesPage(pageReqVO);
  102 + ExcelUtils.write(response, "销售出库单.xls", "数据", MesWmProductSalesRespVO.class,
  103 + buildRespVOList(pageResult.getList()));
  104 + }
  105 +
  106 + @PutMapping("/submit")
  107 + @Operation(summary = "提交销售出库单")
  108 + @Parameter(name = "id", description = "编号", required = true)
  109 + @PreAuthorize("@ss.hasPermission('mes:wm-product-sales:submit')")
  110 + public CommonResult<Boolean> submitProductSales(@RequestParam("id") Long id) {
  111 + productSalesService.submitProductSales(id);
  112 + return success(true);
  113 + }
  114 +
  115 + @PutMapping("/pick")
  116 + @Operation(summary = "执行拣货")
  117 + @Parameter(name = "id", description = "编号", required = true)
  118 + @PreAuthorize("@ss.hasPermission('mes:wm-product-sales:pick')")
  119 + public CommonResult<Boolean> pickProductSales(@RequestParam("id") Long id) {
  120 + productSalesService.pickProductSales(id);
  121 + return success(true);
  122 + }
  123 +
  124 + @PutMapping("/execute")
  125 + @Operation(summary = "执行出库")
  126 + @Parameter(name = "id", description = "编号", required = true)
  127 + @PreAuthorize("@ss.hasPermission('mes:wm-product-sales:execute')")
  128 + public CommonResult<Boolean> executeProductSales(@RequestParam("id") Long id) {
  129 + productSalesService.executeProductSales(id);
  130 + return success(true);
  131 + }
  132 +
  133 + @PutMapping("/cancel")
  134 + @Operation(summary = "取消销售出库单")
  135 + @Parameter(name = "id", description = "编号", required = true)
  136 + @PreAuthorize("@ss.hasPermission('mes:wm-product-sales:cancel')")
  137 + public CommonResult<Boolean> cancelProductSales(@RequestParam("id") Long id) {
  138 + productSalesService.cancelProductSales(id);
  139 + return success(true);
  140 + }
  141 +
  142 + // ==================== 拼接 VO ====================
  143 +
  144 + private List<MesWmProductSalesRespVO> buildRespVOList(List<MesWmProductSalesDO> list) {
  145 + if (CollUtil.isEmpty(list)) {
  146 + return Collections.emptyList();
  147 + }
  148 + // 1. 获得关联数据
  149 + Map<Long, MesMdClientDO> clientMap = clientService.getClientMap(
  150 + convertSet(list, MesWmProductSalesDO::getClientId));
  151 + // 2. 构建结果
  152 + return BeanUtils.toBean(list, MesWmProductSalesRespVO.class, vo -> {
  153 + MapUtils.findAndThen(clientMap, vo.getClientId(),
  154 + client -> vo.setClientName(client.getName()));
  155 + });
  156 + }
  157 +
  158 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productsales/MesWmProductSalesDetailController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.wm.productsales;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  5 +import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
  6 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  7 +import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.detail.MesWmProductSalesDetailRespVO;
  8 +import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.detail.MesWmProductSalesDetailSaveReqVO;
  9 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
  10 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
  11 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesDetailDO;
  12 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO;
  13 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO;
  14 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO;
  15 +import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
  16 +import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
  17 +import cn.iocoder.yudao.module.mes.service.wm.productsales.MesWmProductSalesDetailService;
  18 +import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
  19 +import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseLocationService;
  20 +import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseService;
  21 +import io.swagger.v3.oas.annotations.Operation;
  22 +import io.swagger.v3.oas.annotations.Parameter;
  23 +import io.swagger.v3.oas.annotations.tags.Tag;
  24 +import jakarta.annotation.Resource;
  25 +import jakarta.validation.Valid;
  26 +import org.springframework.security.access.prepost.PreAuthorize;
  27 +import org.springframework.validation.annotation.Validated;
  28 +import org.springframework.web.bind.annotation.*;
  29 +
  30 +import java.util.Collections;
  31 +import java.util.List;
  32 +import java.util.Map;
  33 +
  34 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  35 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
  36 +
  37 +@Tag(name = "管理后台 - MES 销售出库明细")
  38 +@RestController
  39 +@RequestMapping("/mes/wm/product-sales-detail")
  40 +@Validated
  41 +public class MesWmProductSalesDetailController {
  42 +
  43 + @Resource
  44 + private MesWmProductSalesDetailService productSalesDetailService;
  45 +
  46 + @Resource
  47 + private MesMdItemService itemService;
  48 +
  49 + @Resource
  50 + private MesMdUnitMeasureService unitMeasureService;
  51 +
  52 + @Resource
  53 + private MesWmWarehouseService warehouseService;
  54 +
  55 + @Resource
  56 + private MesWmWarehouseLocationService locationService;
  57 +
  58 + @Resource
  59 + private MesWmWarehouseAreaService areaService;
  60 +
  61 + @PostMapping("/create")
  62 + @Operation(summary = "创建销售出库明细")
  63 + @PreAuthorize("@ss.hasPermission('mes:wm-product-sales:create')")
  64 + public CommonResult<Long> createProductSalesDetail(@Valid @RequestBody MesWmProductSalesDetailSaveReqVO createReqVO) {
  65 + return success(productSalesDetailService.createProductSalesDetail(createReqVO));
  66 + }
  67 +
  68 + @PutMapping("/update")
  69 + @Operation(summary = "修改销售出库明细")
  70 + @PreAuthorize("@ss.hasPermission('mes:wm-product-sales:update')")
  71 + public CommonResult<Boolean> updateProductSalesDetail(@Valid @RequestBody MesWmProductSalesDetailSaveReqVO updateReqVO) {
  72 + productSalesDetailService.updateProductSalesDetail(updateReqVO);
  73 + return success(true);
  74 + }
  75 +
  76 + @DeleteMapping("/delete")
  77 + @Operation(summary = "删除销售出库明细")
  78 + @Parameter(name = "id", description = "编号", required = true)
  79 + @PreAuthorize("@ss.hasPermission('mes:wm-product-sales:delete')")
  80 + public CommonResult<Boolean> deleteProductSalesDetail(@RequestParam("id") Long id) {
  81 + productSalesDetailService.deleteProductSalesDetail(id);
  82 + return success(true);
  83 + }
  84 +
  85 + @GetMapping("/get")
  86 + @Operation(summary = "获得销售出库明细")
  87 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  88 + @PreAuthorize("@ss.hasPermission('mes:wm-product-sales:query')")
  89 + public CommonResult<MesWmProductSalesDetailRespVO> getProductSalesDetail(@RequestParam("id") Long id) {
  90 + MesWmProductSalesDetailDO detail = productSalesDetailService.getProductSalesDetail(id);
  91 + if (detail == null) {
  92 + return success(null);
  93 + }
  94 + return success(buildRespVOList(Collections.singletonList(detail)).get(0));
  95 + }
  96 +
  97 + @GetMapping("/list-by-line")
  98 + @Operation(summary = "获得销售出库明细列表(按行编号)")
  99 + @Parameter(name = "lineId", description = "行编号", required = true, example = "1024")
  100 + @PreAuthorize("@ss.hasPermission('mes:wm-product-sales:query')")
  101 + public CommonResult<List<MesWmProductSalesDetailRespVO>> getProductSalesDetailListByLineId(
  102 + @RequestParam("lineId") Long lineId) {
  103 + List<MesWmProductSalesDetailDO> list = productSalesDetailService.getProductSalesDetailListByLineId(lineId);
  104 + return success(buildRespVOList(list));
  105 + }
  106 +
  107 + // ==================== 拼接 VO ====================
  108 +
  109 + private List<MesWmProductSalesDetailRespVO> buildRespVOList(List<MesWmProductSalesDetailDO> list) {
  110 + if (CollUtil.isEmpty(list)) {
  111 + return Collections.emptyList();
  112 + }
  113 + // 1. 获得关联数据
  114 + Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
  115 + convertSet(list, MesWmProductSalesDetailDO::getItemId));
  116 + Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
  117 + convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
  118 + Map<Long, MesWmWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(
  119 + convertSet(list, MesWmProductSalesDetailDO::getWarehouseId));
  120 + Map<Long, MesWmWarehouseLocationDO> locationMap = locationService.getWarehouseLocationMap(
  121 + convertSet(list, MesWmProductSalesDetailDO::getLocationId));
  122 + Map<Long, MesWmWarehouseAreaDO> areaMap = areaService.getWarehouseAreaMap(
  123 + convertSet(list, MesWmProductSalesDetailDO::getAreaId));
  124 + // 2. 构建结果
  125 + return BeanUtils.toBean(list, MesWmProductSalesDetailRespVO.class, vo -> {
  126 + MapUtils.findAndThen(itemMap, vo.getItemId(), item -> {
  127 + vo.setItemCode(item.getCode()).setItemName(item.getName()).setSpecification(item.getSpecification());
  128 + MapUtils.findAndThen(unitMeasureMap, item.getUnitMeasureId(),
  129 + unitMeasure -> vo.setUnitMeasureName(unitMeasure.getName()));
  130 + });
  131 + MapUtils.findAndThen(warehouseMap, vo.getWarehouseId(),
  132 + warehouse -> vo.setWarehouseName(warehouse.getName()));
  133 + MapUtils.findAndThen(locationMap, vo.getLocationId(),
  134 + location -> vo.setLocationName(location.getName()));
  135 + MapUtils.findAndThen(areaMap, vo.getAreaId(),
  136 + area -> vo.setAreaName(area.getName()));
  137 + });
  138 + }
  139 +
  140 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productsales/MesWmProductSalesLineController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.wm.productsales;
  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.PageResult;
  6 +import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
  7 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  8 +import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.line.MesWmProductSalesLinePageReqVO;
  9 +import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.line.MesWmProductSalesLineRespVO;
  10 +import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.line.MesWmProductSalesLineSaveReqVO;
  11 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
  12 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
  13 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesLineDO;
  14 +import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
  15 +import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
  16 +import cn.iocoder.yudao.module.mes.service.wm.productsales.MesWmProductSalesLineService;
  17 +import io.swagger.v3.oas.annotations.Operation;
  18 +import io.swagger.v3.oas.annotations.Parameter;
  19 +import io.swagger.v3.oas.annotations.tags.Tag;
  20 +import jakarta.annotation.Resource;
  21 +import jakarta.validation.Valid;
  22 +import org.springframework.security.access.prepost.PreAuthorize;
  23 +import org.springframework.validation.annotation.Validated;
  24 +import org.springframework.web.bind.annotation.*;
  25 +
  26 +import java.util.Collections;
  27 +import java.util.List;
  28 +import java.util.Map;
  29 +
  30 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  31 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
  32 +
  33 +@Tag(name = "管理后台 - MES 销售出库单行")
  34 +@RestController
  35 +@RequestMapping("/mes/wm/product-sales-line")
  36 +@Validated
  37 +public class MesWmProductSalesLineController {
  38 +
  39 + @Resource
  40 + private MesWmProductSalesLineService productSalesLineService;
  41 +
  42 + @Resource
  43 + private MesMdItemService itemService;
  44 +
  45 + @Resource
  46 + private MesMdUnitMeasureService unitMeasureService;
  47 +
  48 + @PostMapping("/create")
  49 + @Operation(summary = "创建销售出库单行")
  50 + @PreAuthorize("@ss.hasPermission('mes:wm-product-sales:create')")
  51 + public CommonResult<Long> createProductSalesLine(@Valid @RequestBody MesWmProductSalesLineSaveReqVO createReqVO) {
  52 + return success(productSalesLineService.createProductSalesLine(createReqVO));
  53 + }
  54 +
  55 + @PutMapping("/update")
  56 + @Operation(summary = "修改销售出库单行")
  57 + @PreAuthorize("@ss.hasPermission('mes:wm-product-sales:update')")
  58 + public CommonResult<Boolean> updateProductSalesLine(@Valid @RequestBody MesWmProductSalesLineSaveReqVO updateReqVO) {
  59 + productSalesLineService.updateProductSalesLine(updateReqVO);
  60 + return success(true);
  61 + }
  62 +
  63 + @DeleteMapping("/delete")
  64 + @Operation(summary = "删除销售出库单行")
  65 + @Parameter(name = "id", description = "编号", required = true)
  66 + @PreAuthorize("@ss.hasPermission('mes:wm-product-sales:delete')")
  67 + public CommonResult<Boolean> deleteProductSalesLine(@RequestParam("id") Long id) {
  68 + productSalesLineService.deleteProductSalesLine(id);
  69 + return success(true);
  70 + }
  71 +
  72 + @GetMapping("/get")
  73 + @Operation(summary = "获得销售出库单行")
  74 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  75 + @PreAuthorize("@ss.hasPermission('mes:wm-product-sales:query')")
  76 + public CommonResult<MesWmProductSalesLineRespVO> getProductSalesLine(@RequestParam("id") Long id) {
  77 + MesWmProductSalesLineDO line = productSalesLineService.getProductSalesLine(id);
  78 + if (line == null) {
  79 + return success(null);
  80 + }
  81 + return success(buildRespVOList(Collections.singletonList(line)).get(0));
  82 + }
  83 +
  84 + @GetMapping("/page")
  85 + @Operation(summary = "获得销售出库单行分页")
  86 + @PreAuthorize("@ss.hasPermission('mes:wm-product-sales:query')")
  87 + public CommonResult<PageResult<MesWmProductSalesLineRespVO>> getProductSalesLinePage(
  88 + @Valid MesWmProductSalesLinePageReqVO pageReqVO) {
  89 + PageResult<MesWmProductSalesLineDO> pageResult = productSalesLineService.getProductSalesLinePage(pageReqVO);
  90 + return success(new PageResult<>(buildRespVOList(pageResult.getList()), pageResult.getTotal()));
  91 + }
  92 +
  93 + // ==================== 拼接 VO ====================
  94 +
  95 + private List<MesWmProductSalesLineRespVO> buildRespVOList(List<MesWmProductSalesLineDO> list) {
  96 + if (CollUtil.isEmpty(list)) {
  97 + return Collections.emptyList();
  98 + }
  99 + // 1. 获得关联数据
  100 + Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
  101 + convertSet(list, MesWmProductSalesLineDO::getItemId));
  102 + Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
  103 + convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
  104 + // 2. 构建结果
  105 + return BeanUtils.toBean(list, MesWmProductSalesLineRespVO.class, vo -> {
  106 + MapUtils.findAndThen(itemMap, vo.getItemId(), item -> {
  107 + vo.setItemCode(item.getCode()).setItemName(item.getName()).setSpecification(item.getSpecification());
  108 + MapUtils.findAndThen(unitMeasureMap, item.getUnitMeasureId(),
  109 + unitMeasure -> vo.setUnitMeasureName(unitMeasure.getName()));
  110 + });
  111 + });
  112 + }
  113 +
  114 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productsales/vo/MesWmProductSalesPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +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 = "管理后台 - MES 销售出库单分页 Request VO")
  15 +@Data
  16 +@EqualsAndHashCode(callSuper = true)
  17 +@ToString(callSuper = true)
  18 +public class MesWmProductSalesPageReqVO extends PageParam {
  19 +
  20 + @Schema(description = "出库单号", example = "PS2026030001")
  21 + private String code;
  22 +
  23 + @Schema(description = "出库单名称", example = "产品出库单")
  24 + private String name;
  25 +
  26 + @Schema(description = "客户编号", example = "1")
  27 + private Long clientId;
  28 +
  29 + @Schema(description = "状态", example = "0")
  30 + private Integer status;
  31 +
  32 + @Schema(description = "计划发货日期")
  33 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  34 + private LocalDateTime[] shipmentDate;
  35 +
  36 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productsales/vo/MesWmProductSalesRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo;
  2 +
  3 +import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
  4 +import cn.idev.excel.annotation.ExcelProperty;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import lombok.Data;
  7 +
  8 +import java.time.LocalDateTime;
  9 +
  10 +@Schema(description = "管理后台 - MES 销售出库单 Response VO")
  11 +@Data
  12 +@ExcelIgnoreUnannotated
  13 +public class MesWmProductSalesRespVO {
  14 +
  15 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  16 + @ExcelProperty("编号")
  17 + private Long id;
  18 +
  19 + @Schema(description = "出库单号", requiredMode = Schema.RequiredMode.REQUIRED, example = "PS2026030001")
  20 + @ExcelProperty("出库单号")
  21 + private String code;
  22 +
  23 + @Schema(description = "出库单名称", example = "产品出库单")
  24 + @ExcelProperty("出库单名称")
  25 + private String name;
  26 +
  27 + @Schema(description = "客户ID", example = "1")
  28 + private Long clientId;
  29 +
  30 + @Schema(description = "客户名称", example = "某客户")
  31 + @ExcelProperty("客户")
  32 + private String clientName;
  33 +
  34 + @Schema(description = "销售订单号", example = "SO2026030001")
  35 + @ExcelProperty("销售订单号")
  36 + private String salesOrderCode;
  37 +
  38 + @Schema(description = "计划发货日期")
  39 + @ExcelProperty("计划发货日期")
  40 + private LocalDateTime shipmentDate;
  41 +
  42 + @Schema(description = "联系人", example = "张三")
  43 + @ExcelProperty("联系人")
  44 + private String contactName;
  45 +
  46 + @Schema(description = "联系电话", example = "13800138000")
  47 + @ExcelProperty("联系电话")
  48 + private String contactTelephone;
  49 +
  50 + @Schema(description = "收货地址", example = "北京市朝阳区xxx")
  51 + @ExcelProperty("收货地址")
  52 + private String contactAddress;
  53 +
  54 + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
  55 + @ExcelProperty("状态")
  56 + private Integer status;
  57 +
  58 + @Schema(description = "备注", example = "备注")
  59 + @ExcelProperty("备注")
  60 + private String remark;
  61 +
  62 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  63 + @ExcelProperty("创建时间")
  64 + private LocalDateTime createTime;
  65 +
  66 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productsales/vo/MesWmProductSalesSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotEmpty;
  5 +import jakarta.validation.constraints.NotNull;
  6 +import lombok.Data;
  7 +
  8 +import java.time.LocalDateTime;
  9 +
  10 +@Schema(description = "管理后台 - MES 销售出库单新增/修改 Request VO")
  11 +@Data
  12 +public class MesWmProductSalesSaveReqVO {
  13 +
  14 + @Schema(description = "编号", example = "1024")
  15 + private Long id;
  16 +
  17 + @Schema(description = "出库单号", requiredMode = Schema.RequiredMode.REQUIRED, example = "PS2026030001")
  18 + @NotEmpty(message = "出库单号不能为空")
  19 + private String code;
  20 +
  21 + @Schema(description = "出库单名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "产品出库单")
  22 + @NotEmpty(message = "出库单名称不能为空")
  23 + private String name;
  24 +
  25 + @Schema(description = "客户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  26 + @NotNull(message = "客户不能为空")
  27 + private Long clientId;
  28 +
  29 + @Schema(description = "销售订单号", example = "SO2026030001")
  30 + private String salesOrderCode;
  31 +
  32 + @Schema(description = "计划发货日期", requiredMode = Schema.RequiredMode.REQUIRED)
  33 + @NotNull(message = "计划发货日期不能为空")
  34 + private LocalDateTime shipmentDate;
  35 +
  36 + @Schema(description = "联系人", example = "张三")
  37 + private String contactName;
  38 +
  39 + @Schema(description = "联系电话", example = "13800138000")
  40 + private String contactTelephone;
  41 +
  42 + @Schema(description = "收货地址", example = "北京市朝阳区xxx")
  43 + private String contactAddress;
  44 +
  45 + @Schema(description = "备注", example = "备注")
  46 + private String remark;
  47 +
  48 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productsales/vo/detail/MesWmProductSalesDetailPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.detail;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +@Schema(description = "管理后台 - MES 销售出库明细分页 Request VO")
  10 +@Data
  11 +@EqualsAndHashCode(callSuper = true)
  12 +@ToString(callSuper = true)
  13 +public class MesWmProductSalesDetailPageReqVO extends PageParam {
  14 +
  15 + @Schema(description = "出库单ID", example = "1")
  16 + private Long salesId;
  17 +
  18 + @Schema(description = "出库单行ID", example = "1")
  19 + private Long lineId;
  20 +
  21 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productsales/vo/detail/MesWmProductSalesDetailRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.detail;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.math.BigDecimal;
  7 +import java.time.LocalDateTime;
  8 +
  9 +@Schema(description = "管理后台 - MES 销售出库明细 Response VO")
  10 +@Data
  11 +public class MesWmProductSalesDetailRespVO {
  12 +
  13 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  14 + private Long id;
  15 +
  16 + @Schema(description = "出库单行ID", example = "1")
  17 + private Long lineId;
  18 +
  19 + @Schema(description = "出库单ID", example = "1")
  20 + private Long salesId;
  21 +
  22 + @Schema(description = "物料ID", example = "1")
  23 + private Long itemId;
  24 +
  25 + @Schema(description = "物料编码", example = "M001")
  26 + private String itemCode;
  27 +
  28 + @Schema(description = "物料名称", example = "产品A")
  29 + private String itemName;
  30 +
  31 + @Schema(description = "规格型号", example = "100g")
  32 + private String specification;
  33 +
  34 + @Schema(description = "单位名称", example = "个")
  35 + private String unitMeasureName;
  36 +
  37 + @Schema(description = "拣货数量", example = "50")
  38 + private BigDecimal quantity;
  39 +
  40 + @Schema(description = "批次ID", example = "1")
  41 + private Long batchId;
  42 +
  43 + @Schema(description = "仓库ID", example = "1")
  44 + private Long warehouseId;
  45 +
  46 + @Schema(description = "仓库名称", example = "成品仓")
  47 + private String warehouseName;
  48 +
  49 + @Schema(description = "库区ID", example = "1")
  50 + private Long locationId;
  51 +
  52 + @Schema(description = "库区名称", example = "A区")
  53 + private String locationName;
  54 +
  55 + @Schema(description = "库位ID", example = "1")
  56 + private Long areaId;
  57 +
  58 + @Schema(description = "库位名称", example = "A-01")
  59 + private String areaName;
  60 +
  61 + @Schema(description = "备注", example = "备注")
  62 + private String remark;
  63 +
  64 + @Schema(description = "创建时间")
  65 + private LocalDateTime createTime;
  66 +
  67 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productsales/vo/detail/MesWmProductSalesDetailSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.detail;
  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 +
  9 +@Schema(description = "管理后台 - MES 销售出库明细新增/修改 Request VO")
  10 +@Data
  11 +public class MesWmProductSalesDetailSaveReqVO {
  12 +
  13 + @Schema(description = "编号", example = "1024")
  14 + private Long id;
  15 +
  16 + @Schema(description = "出库单行ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  17 + @NotNull(message = "出库单行ID不能为空")
  18 + private Long lineId;
  19 +
  20 + @Schema(description = "出库单ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  21 + @NotNull(message = "出库单ID不能为空")
  22 + private Long salesId;
  23 +
  24 + @Schema(description = "物料ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  25 + @NotNull(message = "物料不能为空")
  26 + private Long itemId;
  27 +
  28 + @Schema(description = "拣货数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "50")
  29 + @NotNull(message = "拣货数量不能为空")
  30 + private BigDecimal quantity;
  31 +
  32 + @Schema(description = "批次ID", example = "1")
  33 + private Long batchId;
  34 +
  35 + @Schema(description = "仓库ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  36 + @NotNull(message = "仓库不能为空")
  37 + private Long warehouseId;
  38 +
  39 + @Schema(description = "库区ID", example = "1")
  40 + private Long locationId;
  41 +
  42 + @Schema(description = "库位ID", example = "1")
  43 + private Long areaId;
  44 +
  45 + @Schema(description = "备注", example = "备注")
  46 + private String remark;
  47 +
  48 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productsales/vo/line/MesWmProductSalesLinePageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.line;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +@Schema(description = "管理后台 - MES 销售出库单行分页 Request VO")
  10 +@Data
  11 +@EqualsAndHashCode(callSuper = true)
  12 +@ToString(callSuper = true)
  13 +public class MesWmProductSalesLinePageReqVO extends PageParam {
  14 +
  15 + @Schema(description = "出库单ID", example = "1")
  16 + private Long salesId;
  17 +
  18 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productsales/vo/line/MesWmProductSalesLineRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.line;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.math.BigDecimal;
  7 +import java.time.LocalDateTime;
  8 +
  9 +@Schema(description = "管理后台 - MES 销售出库单行 Response VO")
  10 +@Data
  11 +public class MesWmProductSalesLineRespVO {
  12 +
  13 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  14 + private Long id;
  15 +
  16 + @Schema(description = "出库单ID", example = "1")
  17 + private Long salesId;
  18 +
  19 + @Schema(description = "物料ID", example = "1")
  20 + private Long itemId;
  21 +
  22 + @Schema(description = "物料编码", example = "M001")
  23 + private String itemCode;
  24 +
  25 + @Schema(description = "物料名称", example = "产品A")
  26 + private String itemName;
  27 +
  28 + @Schema(description = "规格型号", example = "100g")
  29 + private String specification;
  30 +
  31 + @Schema(description = "单位名称", example = "个")
  32 + private String unitMeasureName;
  33 +
  34 + @Schema(description = "出库数量", example = "100")
  35 + private BigDecimal quantity;
  36 +
  37 + @Schema(description = "已拣货数量", example = "50")
  38 + private BigDecimal pickedQuantity;
  39 +
  40 + @Schema(description = "批次ID", example = "1")
  41 + private Long batchId;
  42 +
  43 + @Schema(description = "备注", example = "备注")
  44 + private String remark;
  45 +
  46 + @Schema(description = "创建时间")
  47 + private LocalDateTime createTime;
  48 +
  49 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productsales/vo/line/MesWmProductSalesLineSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.line;
  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 +
  9 +@Schema(description = "管理后台 - MES 销售出库单行新增/修改 Request VO")
  10 +@Data
  11 +public class MesWmProductSalesLineSaveReqVO {
  12 +
  13 + @Schema(description = "编号", example = "1024")
  14 + private Long id;
  15 +
  16 + @Schema(description = "出库单ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  17 + @NotNull(message = "出库单ID不能为空")
  18 + private Long salesId;
  19 +
  20 + @Schema(description = "物料ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  21 + @NotNull(message = "物料不能为空")
  22 + private Long itemId;
  23 +
  24 + @Schema(description = "出库数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
  25 + @NotNull(message = "出库数量不能为空")
  26 + private BigDecimal quantity;
  27 +
  28 + @Schema(description = "批次ID", example = "1")
  29 + private Long batchId;
  30 +
  31 + @Schema(description = "备注", example = "备注")
  32 + private String remark;
  33 +
  34 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productsales/MesWmProductSalesDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.client.MesMdClientDO;
  5 +import cn.iocoder.yudao.module.mes.enums.wm.MesWmProductSalesStatusEnum;
  6 +import com.baomidou.mybatisplus.annotation.KeySequence;
  7 +import com.baomidou.mybatisplus.annotation.TableId;
  8 +import com.baomidou.mybatisplus.annotation.TableName;
  9 +import lombok.*;
  10 +
  11 +import java.time.LocalDateTime;
  12 +
  13 +/**
  14 + * MES 销售出库单 DO
  15 + *
  16 + * @author 芋道源码
  17 + */
  18 +@TableName("mes_wm_product_sales")
  19 +@KeySequence("mes_wm_product_sales_seq")
  20 +@Data
  21 +@EqualsAndHashCode(callSuper = true)
  22 +@ToString(callSuper = true)
  23 +@Builder
  24 +@NoArgsConstructor
  25 +@AllArgsConstructor
  26 +public class MesWmProductSalesDO extends BaseDO {
  27 +
  28 + /**
  29 + * 编号
  30 + */
  31 + @TableId
  32 + private Long id;
  33 + /**
  34 + * 出库单号
  35 + */
  36 + private String code;
  37 + /**
  38 + * 出库单名称
  39 + */
  40 + private String name;
  41 + /**
  42 + * 客户ID
  43 + *
  44 + * 关联 {@link MesMdClientDO#getId()}
  45 + */
  46 + private Long clientId;
  47 + /**
  48 + * 销售订单号
  49 + */
  50 + private String salesOrderCode;
  51 + // TODO @AI:sales_date 改成这个字段。出库日期
  52 + /**
  53 + * 计划发货日期
  54 + */
  55 + private LocalDateTime shipmentDate;
  56 +
  57 + // TODO @AI:收货地址,删除掉;(界面里也删除掉)
  58 + /**
  59 + * 收货地址
  60 + */
  61 + private String contactAddress;
  62 + // TODO @AI:关联下对应的字段 salesnotice;
  63 + /**
  64 + * 发货通知单ID
  65 + */
  66 + private Long noticeId;
  67 + // TODO @AI:noticeCode 不存储;
  68 + /**
  69 + * 发货通知单编号
  70 + */
  71 + private String noticeCode;
  72 +
  73 + /**
  74 + * 联系人
  75 + */
  76 + private String contactName;
  77 + /**
  78 + * 联系电话
  79 + */
  80 + private String contactTelephone;
  81 +
  82 + /**
  83 + * 承运商
  84 + */
  85 + private String carrier;
  86 + /**
  87 + * 运输单号
  88 + */
  89 + private String shippingNumber;
  90 +
  91 + /**
  92 + * 状态
  93 + *
  94 + * 枚举 {@link MesWmProductSalesStatusEnum}
  95 + */
  96 + private Integer status;
  97 + /**
  98 + * 备注
  99 + */
  100 + private String remark;
  101 +
  102 +}
0 \ No newline at end of file 103 \ No newline at end of file
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productsales/MesWmProductSalesDetailDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
  5 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO;
  6 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO;
  7 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO;
  8 +import com.baomidou.mybatisplus.annotation.KeySequence;
  9 +import com.baomidou.mybatisplus.annotation.TableId;
  10 +import com.baomidou.mybatisplus.annotation.TableName;
  11 +import lombok.*;
  12 +
  13 +import java.math.BigDecimal;
  14 +
  15 +/**
  16 + * MES 销售出库明细 DO
  17 + *
  18 + * @author 芋道源码
  19 + */
  20 +@TableName("mes_wm_product_sales_detail")
  21 +@KeySequence("mes_wm_product_sales_detail_seq")
  22 +@Data
  23 +@EqualsAndHashCode(callSuper = true)
  24 +@ToString(callSuper = true)
  25 +@Builder
  26 +@NoArgsConstructor
  27 +@AllArgsConstructor
  28 +public class MesWmProductSalesDetailDO extends BaseDO {
  29 +
  30 + /**
  31 + * 编号
  32 + */
  33 + @TableId
  34 + private Long id;
  35 + /**
  36 + * 出库单行ID
  37 + *
  38 + * 关联 {@link MesWmProductSalesLineDO#getId()}
  39 + */
  40 + private Long lineId;
  41 + /**
  42 + * 出库单ID
  43 + *
  44 + * 关联 {@link MesWmProductSalesDO#getId()}
  45 + */
  46 + private Long salesId;
  47 + /**
  48 + * 物料ID
  49 + *
  50 + * 关联 {@link MesMdItemDO#getId()}
  51 + */
  52 + private Long itemId;
  53 + /**
  54 + * 拣货数量
  55 + */
  56 + private BigDecimal quantity;
  57 + /**
  58 + * 批次ID
  59 + */
  60 + private Long batchId;
  61 + /**
  62 + * 仓库ID
  63 + *
  64 + * 关联 {@link MesWmWarehouseDO#getId()}
  65 + */
  66 + private Long warehouseId;
  67 + /**
  68 + * 库区ID
  69 + *
  70 + * 关联 {@link MesWmWarehouseLocationDO#getId()}
  71 + */
  72 + private Long locationId;
  73 + /**
  74 + * 库位ID
  75 + *
  76 + * 关联 {@link MesWmWarehouseAreaDO#getId()}
  77 + */
  78 + private Long areaId;
  79 + /**
  80 + * 备注
  81 + */
  82 + private String remark;
  83 +
  84 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productsales/MesWmProductSalesLineDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
  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 + * MES 销售出库单行 DO
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@TableName("mes_wm_product_sales_line")
  18 +@KeySequence("mes_wm_product_sales_line_seq")
  19 +@Data
  20 +@EqualsAndHashCode(callSuper = true)
  21 +@ToString(callSuper = true)
  22 +@Builder
  23 +@NoArgsConstructor
  24 +@AllArgsConstructor
  25 +public class MesWmProductSalesLineDO extends BaseDO {
  26 +
  27 + /**
  28 + * 编号
  29 + */
  30 + @TableId
  31 + private Long id;
  32 + /**
  33 + * 出库单ID
  34 + *
  35 + * 关联 {@link MesWmProductSalesDO#getId()}
  36 + */
  37 + private Long salesId;
  38 + /**
  39 + * 物料ID
  40 + *
  41 + * 关联 {@link MesMdItemDO#getId()}
  42 + */
  43 + private Long itemId;
  44 + /**
  45 + * 出库数量
  46 + */
  47 + private BigDecimal quantity;
  48 + // TODO @AI:去掉 pickedQuantity 字段;(不存储)
  49 + /**
  50 + * 已拣货数量
  51 + */
  52 + private BigDecimal pickedQuantity;
  53 + /**
  54 + * 批次ID
  55 + */
  56 + private Long batchId;
  57 + /**
  58 + * 库存记录ID
  59 + */
  60 + private Long materialStockId;
  61 + // TODO @AI:换成 Boolean;
  62 + /**
  63 + * 是否出厂检验(Y/N)
  64 + */
  65 + private String oqcCheck;
  66 + /**
  67 + * 出厂检验单 ID
  68 + */
  69 + // TODO @AI:字段关联
  70 + private Long oqcId;
  71 + // TODO @AI:不用 oqcCode 字段;
  72 + /**
  73 + * 出厂检验单编号
  74 + */
  75 + private String oqcCode;
  76 + // TODO @AI:关联枚举类;
  77 + /**
  78 + * 质量状态
  79 + */
  80 + private String qualityStatus;
  81 + /**
  82 + * 备注
  83 + */
  84 + private String remark;
  85 +
  86 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productsales/MesWmProductSalesDetailMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.dal.mysql.wm.productsales;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  4 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesDetailDO;
  5 +import org.apache.ibatis.annotations.Mapper;
  6 +
  7 +import java.util.List;
  8 +
  9 +/**
  10 + * MES 销售出库明细 Mapper
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Mapper
  15 +public interface MesWmProductSalesDetailMapper extends BaseMapperX<MesWmProductSalesDetailDO> {
  16 +
  17 + default List<MesWmProductSalesDetailDO> selectListByLineId(Long lineId) {
  18 + return selectList(MesWmProductSalesDetailDO::getLineId, lineId);
  19 + }
  20 +
  21 + default List<MesWmProductSalesDetailDO> selectListBySalesId(Long salesId) {
  22 + return selectList(MesWmProductSalesDetailDO::getSalesId, salesId);
  23 + }
  24 +
  25 + default void deleteByLineId(Long lineId) {
  26 + delete(MesWmProductSalesDetailDO::getLineId, lineId);
  27 + }
  28 +
  29 + default void deleteBySalesId(Long salesId) {
  30 + delete(MesWmProductSalesDetailDO::getSalesId, salesId);
  31 + }
  32 +
  33 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productsales/MesWmProductSalesLineMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.dal.mysql.wm.productsales;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  4 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesLineDO;
  5 +import org.apache.ibatis.annotations.Mapper;
  6 +
  7 +import java.util.List;
  8 +
  9 +/**
  10 + * MES 销售出库单行 Mapper
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Mapper
  15 +public interface MesWmProductSalesLineMapper extends BaseMapperX<MesWmProductSalesLineDO> {
  16 +
  17 + default List<MesWmProductSalesLineDO> selectListBySalesId(Long salesId) {
  18 + return selectList(MesWmProductSalesLineDO::getSalesId, salesId);
  19 + }
  20 +
  21 + default void deleteBySalesId(Long salesId) {
  22 + delete(MesWmProductSalesLineDO::getSalesId, salesId);
  23 + }
  24 +
  25 + default cn.iocoder.yudao.framework.common.pojo.PageResult<MesWmProductSalesLineDO> selectPage(
  26 + cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.line.MesWmProductSalesLinePageReqVO reqVO) {
  27 + return selectPage(reqVO, new cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX<MesWmProductSalesLineDO>()
  28 + .eqIfPresent(MesWmProductSalesLineDO::getSalesId, reqVO.getSalesId())
  29 + .orderByDesc(MesWmProductSalesLineDO::getId));
  30 + }
  31 +
  32 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productsales/MesWmProductSalesMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.dal.mysql.wm.productsales;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.MesWmProductSalesPageReqVO;
  7 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesDO;
  8 +import org.apache.ibatis.annotations.Mapper;
  9 +
  10 +/**
  11 + * MES 销售出库单 Mapper
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@Mapper
  16 +public interface MesWmProductSalesMapper extends BaseMapperX<MesWmProductSalesDO> {
  17 +
  18 + default PageResult<MesWmProductSalesDO> selectPage(MesWmProductSalesPageReqVO reqVO) {
  19 + return selectPage(reqVO, new LambdaQueryWrapperX<MesWmProductSalesDO>()
  20 + .likeIfPresent(MesWmProductSalesDO::getCode, reqVO.getCode())
  21 + .likeIfPresent(MesWmProductSalesDO::getName, reqVO.getName())
  22 + .eqIfPresent(MesWmProductSalesDO::getClientId, reqVO.getClientId())
  23 + .eqIfPresent(MesWmProductSalesDO::getStatus, reqVO.getStatus())
  24 + .betweenIfPresent(MesWmProductSalesDO::getShipmentDate, reqVO.getShipmentDate())
  25 + .orderByDesc(MesWmProductSalesDO::getId));
  26 + }
  27 +
  28 + default MesWmProductSalesDO selectByCode(String code) {
  29 + return selectOne(MesWmProductSalesDO::getCode, code);
  30 + }
  31 +
  32 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmProductSalesStatusEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.enums.wm;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.ArrayValuable;
  4 +import cn.iocoder.yudao.module.mes.enums.MesOrderStatusConstants;
  5 +import lombok.AllArgsConstructor;
  6 +import lombok.Getter;
  7 +
  8 +import java.util.Arrays;
  9 +
  10 +/**
  11 + * MES 销售出库单状态枚举
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@Getter
  16 +@AllArgsConstructor
  17 +public enum MesWmProductSalesStatusEnum implements ArrayValuable<Integer> {
  18 +
  19 + /**
  20 + * 草稿
  21 + */
  22 + PREPARE(MesOrderStatusConstants.PREPARE, "草稿"),
  23 + /**
  24 + * 待拣货
  25 + */
  26 + APPROVING(MesOrderStatusConstants.APPROVING, "待拣货"),
  27 + /**
  28 + * 待出库
  29 + */
  30 + APPROVED(MesOrderStatusConstants.APPROVED, "待出库"),
  31 + /**
  32 + * 已完成
  33 + */
  34 + FINISHED(MesOrderStatusConstants.FINISHED, "已完成"),
  35 + /**
  36 + * 已取消
  37 + */
  38 + CANCELED(MesOrderStatusConstants.CANCELLED, "已取消");
  39 +
  40 + public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmProductSalesStatusEnum::getStatus).toArray(Integer[]::new);
  41 +
  42 + /**
  43 + * 状态值
  44 + */
  45 + private final Integer status;
  46 + /**
  47 + * 状态名
  48 + */
  49 + private final String name;
  50 +
  51 + @Override
  52 + public Integer[] array() {
  53 + return ARRAYS;
  54 + }
  55 +
  56 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesDetailService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.wm.productsales;
  2 +
  3 +import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.detail.MesWmProductSalesDetailSaveReqVO;
  4 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesDetailDO;
  5 +import jakarta.validation.Valid;
  6 +
  7 +import java.util.List;
  8 +
  9 +/**
  10 + * MES 销售出库明细 Service 接口
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +public interface MesWmProductSalesDetailService {
  15 +
  16 + /**
  17 + * 创建销售出库明细
  18 + *
  19 + * @param createReqVO 创建信息
  20 + * @return 编号
  21 + */
  22 + Long createProductSalesDetail(@Valid MesWmProductSalesDetailSaveReqVO createReqVO);
  23 +
  24 + /**
  25 + * 修改销售出库明细
  26 + *
  27 + * @param updateReqVO 修改信息
  28 + */
  29 + void updateProductSalesDetail(@Valid MesWmProductSalesDetailSaveReqVO updateReqVO);
  30 +
  31 + /**
  32 + * 删除销售出库明细
  33 + *
  34 + * @param id 编号
  35 + */
  36 + void deleteProductSalesDetail(Long id);
  37 +
  38 + /**
  39 + * 获得销售出库明细
  40 + *
  41 + * @param id 编号
  42 + * @return 销售出库明细
  43 + */
  44 + MesWmProductSalesDetailDO getProductSalesDetail(Long id);
  45 +
  46 + /**
  47 + * 按出库单编号获得明细列表
  48 + *
  49 + * @param salesId 出库单编号
  50 + * @return 明细列表
  51 + */
  52 + List<MesWmProductSalesDetailDO> getProductSalesDetailListBySalesId(Long salesId);
  53 +
  54 + /**
  55 + * 按出库单行编号获得明细列表
  56 + *
  57 + * @param lineId 行编号
  58 + * @return 明细列表
  59 + */
  60 + List<MesWmProductSalesDetailDO> getProductSalesDetailListByLineId(Long lineId);
  61 +
  62 + /**
  63 + * 按出库单行编号批量删除明细
  64 + *
  65 + * @param lineId 行编号
  66 + */
  67 + void deleteProductSalesDetailByLineId(Long lineId);
  68 +
  69 + /**
  70 + * 按出库单编号批量删除明细
  71 + *
  72 + * @param salesId 出库单编号
  73 + */
  74 + void deleteProductSalesDetailBySalesId(Long salesId);
  75 +
  76 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesDetailServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.wm.productsales;
  2 +
  3 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  4 +import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.detail.MesWmProductSalesDetailSaveReqVO;
  5 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesDetailDO;
  6 +import cn.iocoder.yudao.module.mes.dal.mysql.wm.productsales.MesWmProductSalesDetailMapper;
  7 +import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
  8 +import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
  9 +import jakarta.annotation.Resource;
  10 +import org.springframework.stereotype.Service;
  11 +import org.springframework.validation.annotation.Validated;
  12 +
  13 +import java.util.List;
  14 +
  15 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  16 +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
  17 +
  18 +/**
  19 + * MES 销售出库明细 Service 实现类
  20 + *
  21 + * @author 芋道源码
  22 + */
  23 +@Service
  24 +@Validated
  25 +public class MesWmProductSalesDetailServiceImpl implements MesWmProductSalesDetailService {
  26 +
  27 + @Resource
  28 + private MesWmProductSalesDetailMapper productSalesDetailMapper;
  29 +
  30 + @Resource
  31 + private MesMdItemService itemService;
  32 +
  33 + @Resource
  34 + private MesWmWarehouseAreaService warehouseAreaService;
  35 +
  36 + @Override
  37 + public Long createProductSalesDetail(MesWmProductSalesDetailSaveReqVO createReqVO) {
  38 + // 校验物料存在
  39 + itemService.validateItemExists(createReqVO.getItemId());
  40 + // 校验库区关系
  41 + warehouseAreaService.validateWarehouseAreaExists(
  42 + createReqVO.getWarehouseId(), createReqVO.getLocationId(), createReqVO.getAreaId());
  43 +
  44 + // 插入
  45 + MesWmProductSalesDetailDO detail = BeanUtils.toBean(createReqVO, MesWmProductSalesDetailDO.class);
  46 + productSalesDetailMapper.insert(detail);
  47 + return detail.getId();
  48 + }
  49 +
  50 + @Override
  51 + public void updateProductSalesDetail(MesWmProductSalesDetailSaveReqVO updateReqVO) {
  52 + // 校验存在
  53 + validateProductSalesDetailExists(updateReqVO.getId());
  54 + // 校验物料存在
  55 + itemService.validateItemExists(updateReqVO.getItemId());
  56 + // 校验库区关系
  57 + warehouseAreaService.validateWarehouseAreaExists(
  58 + updateReqVO.getWarehouseId(), updateReqVO.getLocationId(), updateReqVO.getAreaId());
  59 +
  60 + // 更新
  61 + MesWmProductSalesDetailDO updateObj = BeanUtils.toBean(updateReqVO, MesWmProductSalesDetailDO.class);
  62 + productSalesDetailMapper.updateById(updateObj);
  63 + }
  64 +
  65 + @Override
  66 + public void deleteProductSalesDetail(Long id) {
  67 + // 校验存在
  68 + validateProductSalesDetailExists(id);
  69 + // 删除
  70 + productSalesDetailMapper.deleteById(id);
  71 + }
  72 +
  73 + @Override
  74 + public MesWmProductSalesDetailDO getProductSalesDetail(Long id) {
  75 + return productSalesDetailMapper.selectById(id);
  76 + }
  77 +
  78 + @Override
  79 + public List<MesWmProductSalesDetailDO> getProductSalesDetailListBySalesId(Long salesId) {
  80 + return productSalesDetailMapper.selectListBySalesId(salesId);
  81 + }
  82 +
  83 + @Override
  84 + public List<MesWmProductSalesDetailDO> getProductSalesDetailListByLineId(Long lineId) {
  85 + return productSalesDetailMapper.selectListByLineId(lineId);
  86 + }
  87 +
  88 + @Override
  89 + public void deleteProductSalesDetailByLineId(Long lineId) {
  90 + productSalesDetailMapper.deleteByLineId(lineId);
  91 + }
  92 +
  93 + @Override
  94 + public void deleteProductSalesDetailBySalesId(Long salesId) {
  95 + productSalesDetailMapper.deleteBySalesId(salesId);
  96 + }
  97 +
  98 + private MesWmProductSalesDetailDO validateProductSalesDetailExists(Long id) {
  99 + MesWmProductSalesDetailDO detail = productSalesDetailMapper.selectById(id);
  100 + if (detail == null) {
  101 + throw exception(WM_PRODUCT_SALES_DETAIL_NOT_EXISTS);
  102 + }
  103 + return detail;
  104 + }
  105 +
  106 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesLineService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.wm.productsales;
  2 +
  3 +import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.line.MesWmProductSalesLinePageReqVO;
  4 +import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.line.MesWmProductSalesLineSaveReqVO;
  5 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesLineDO;
  6 +import jakarta.validation.Valid;
  7 +
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * MES 销售出库单行 Service 接口
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +public interface MesWmProductSalesLineService {
  16 +
  17 + /**
  18 + * 创建销售出库单行
  19 + *
  20 + * @param createReqVO 创建信息
  21 + * @return 编号
  22 + */
  23 + Long createProductSalesLine(@Valid MesWmProductSalesLineSaveReqVO createReqVO);
  24 +
  25 + /**
  26 + * 修改销售出库单行
  27 + *
  28 + * @param updateReqVO 修改信息
  29 + */
  30 + void updateProductSalesLine(@Valid MesWmProductSalesLineSaveReqVO updateReqVO);
  31 +
  32 + /**
  33 + * 删除销售出库单行(级联删除明细)
  34 + *
  35 + * @param id 编号
  36 + */
  37 + void deleteProductSalesLine(Long id);
  38 +
  39 + /**
  40 + * 获得销售出库单行
  41 + *
  42 + * @param id 编号
  43 + * @return 销售出库单行
  44 + */
  45 + MesWmProductSalesLineDO getProductSalesLine(Long id);
  46 +
  47 + /**
  48 + * 按出库单编号获得行列表
  49 + *
  50 + * @param salesId 出库单编号
  51 + * @return 行列表
  52 + */
  53 + List<MesWmProductSalesLineDO> getProductSalesLineListBySalesId(Long salesId);
  54 +
  55 + /**
  56 + * 按出库单编号批量删除行
  57 + *
  58 + * @param salesId 出库单编号
  59 + */
  60 + void deleteProductSalesLineBySalesId(Long salesId);
  61 +
  62 + /**
  63 + * 获得销售出库单行分页
  64 + *
  65 + * @param pageReqVO 分页查询
  66 + * @return 销售出库单行分页
  67 + */
  68 + cn.iocoder.yudao.framework.common.pojo.PageResult<MesWmProductSalesLineDO> getProductSalesLinePage(
  69 + MesWmProductSalesLinePageReqVO pageReqVO);
  70 +
  71 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesLineServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.wm.productsales;
  2 +
  3 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  4 +import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.line.MesWmProductSalesLinePageReqVO;
  5 +import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.line.MesWmProductSalesLineSaveReqVO;
  6 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesLineDO;
  7 +import cn.iocoder.yudao.module.mes.dal.mysql.wm.productsales.MesWmProductSalesLineMapper;
  8 +import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
  9 +import jakarta.annotation.Resource;
  10 +import org.springframework.context.annotation.Lazy;
  11 +import org.springframework.stereotype.Service;
  12 +import org.springframework.transaction.annotation.Transactional;
  13 +import org.springframework.validation.annotation.Validated;
  14 +
  15 +import java.math.BigDecimal;
  16 +import java.util.List;
  17 +
  18 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  19 +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_PRODUCT_SALES_LINE_NOT_EXISTS;
  20 +
  21 +/**
  22 + * MES 销售出库单行 Service 实现类
  23 + *
  24 + * @author 芋道源码
  25 + */
  26 +@Service
  27 +@Validated
  28 +public class MesWmProductSalesLineServiceImpl implements MesWmProductSalesLineService {
  29 +
  30 + @Resource
  31 + private MesWmProductSalesLineMapper productSalesLineMapper;
  32 +
  33 + @Resource
  34 + @Lazy
  35 + private MesWmProductSalesService productSalesService;
  36 +
  37 + @Resource
  38 + private MesWmProductSalesDetailService productSalesDetailService;
  39 +
  40 + @Resource
  41 + private MesMdItemService itemService;
  42 +
  43 + @Override
  44 + public Long createProductSalesLine(MesWmProductSalesLineSaveReqVO createReqVO) {
  45 + // 校验物料存在
  46 + itemService.validateItemExists(createReqVO.getItemId());
  47 +
  48 + // 新增
  49 + MesWmProductSalesLineDO line = BeanUtils.toBean(createReqVO, MesWmProductSalesLineDO.class);
  50 + line.setPickedQuantity(BigDecimal.ZERO);
  51 + productSalesLineMapper.insert(line);
  52 + return line.getId();
  53 + }
  54 +
  55 + @Override
  56 + public void updateProductSalesLine(MesWmProductSalesLineSaveReqVO updateReqVO) {
  57 + // 校验存在
  58 + validateProductSalesLineExists(updateReqVO.getId());
  59 + // 校验物料存在
  60 + itemService.validateItemExists(updateReqVO.getItemId());
  61 +
  62 + // 更新
  63 + MesWmProductSalesLineDO updateObj = BeanUtils.toBean(updateReqVO, MesWmProductSalesLineDO.class);
  64 + productSalesLineMapper.updateById(updateObj);
  65 + }
  66 +
  67 + @Override
  68 + @Transactional(rollbackFor = Exception.class)
  69 + public void deleteProductSalesLine(Long id) {
  70 + // 校验存在
  71 + validateProductSalesLineExists(id);
  72 +
  73 + // 级联删除明细
  74 + productSalesDetailService.deleteProductSalesDetailByLineId(id);
  75 + // 删除
  76 + productSalesLineMapper.deleteById(id);
  77 + }
  78 +
  79 + @Override
  80 + public MesWmProductSalesLineDO getProductSalesLine(Long id) {
  81 + return productSalesLineMapper.selectById(id);
  82 + }
  83 +
  84 + @Override
  85 + public List<MesWmProductSalesLineDO> getProductSalesLineListBySalesId(Long salesId) {
  86 + return productSalesLineMapper.selectListBySalesId(salesId);
  87 + }
  88 +
  89 + @Override
  90 + public void deleteProductSalesLineBySalesId(Long salesId) {
  91 + productSalesLineMapper.deleteBySalesId(salesId);
  92 + }
  93 +
  94 + @Override
  95 + public cn.iocoder.yudao.framework.common.pojo.PageResult<MesWmProductSalesLineDO> getProductSalesLinePage(
  96 + MesWmProductSalesLinePageReqVO pageReqVO) {
  97 + return productSalesLineMapper.selectPage(pageReqVO);
  98 + }
  99 +
  100 + private MesWmProductSalesLineDO validateProductSalesLineExists(Long id) {
  101 + MesWmProductSalesLineDO line = productSalesLineMapper.selectById(id);
  102 + if (line == null) {
  103 + throw exception(WM_PRODUCT_SALES_LINE_NOT_EXISTS);
  104 + }
  105 + return line;
  106 + }
  107 +
  108 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.wm.productsales;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.MesWmProductSalesPageReqVO;
  5 +import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.MesWmProductSalesSaveReqVO;
  6 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesDO;
  7 +import jakarta.validation.Valid;
  8 +
  9 +/**
  10 + * MES 销售出库单 Service 接口
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +public interface MesWmProductSalesService {
  15 +
  16 + /**
  17 + * 创建销售出库单
  18 + *
  19 + * @param createReqVO 创建信息
  20 + * @return 编号
  21 + */
  22 + Long createProductSales(@Valid MesWmProductSalesSaveReqVO createReqVO);
  23 +
  24 + /**
  25 + * 修改销售出库单
  26 + *
  27 + * @param updateReqVO 修改信息
  28 + */
  29 + void updateProductSales(@Valid MesWmProductSalesSaveReqVO updateReqVO);
  30 +
  31 + /**
  32 + * 删除销售出库单(级联删除行+明细)
  33 + *
  34 + * @param id 编号
  35 + */
  36 + void deleteProductSales(Long id);
  37 +
  38 + /**
  39 + * 获得销售出库单
  40 + *
  41 + * @param id 编号
  42 + * @return 销售出库单
  43 + */
  44 + MesWmProductSalesDO getProductSales(Long id);
  45 +
  46 + /**
  47 + * 获得销售出库单分页
  48 + *
  49 + * @param pageReqVO 分页参数
  50 + * @return 销售出库单分页
  51 + */
  52 + PageResult<MesWmProductSalesDO> getProductSalesPage(MesWmProductSalesPageReqVO pageReqVO);
  53 +
  54 + /**
  55 + * 提交销售出库单(草稿 → 待拣货)
  56 + *
  57 + * @param id 编号
  58 + */
  59 + void submitProductSales(Long id);
  60 +
  61 + /**
  62 + * 执行拣货(待拣货 → 待出库)
  63 + *
  64 + * @param id 编号
  65 + */
  66 + void pickProductSales(Long id);
  67 +
  68 + /**
  69 + * 执行出库(待出库 → 已完成),扣减库存
  70 + *
  71 + * @param id 编号
  72 + */
  73 + void executeProductSales(Long id);
  74 +
  75 + /**
  76 + * 取消销售出库单(任意非已完成/已取消状态 → 已取消)
  77 + *
  78 + * @param id 编号
  79 + */
  80 + void cancelProductSales(Long id);
  81 +
  82 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.wm.productsales;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.util.ObjUtil;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  7 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  8 +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
  9 +import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.MesWmProductSalesPageReqVO;
  10 +import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.MesWmProductSalesSaveReqVO;
  11 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesDO;
  12 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesDetailDO;
  13 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesLineDO;
  14 +import cn.iocoder.yudao.module.mes.dal.mysql.wm.productsales.MesWmProductSalesMapper;
  15 +import cn.iocoder.yudao.module.mes.enums.wm.MesWmProductSalesStatusEnum;
  16 +import cn.iocoder.yudao.module.mes.service.md.client.MesMdClientService;
  17 +import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService;
  18 +import jakarta.annotation.Resource;
  19 +import org.springframework.stereotype.Service;
  20 +import org.springframework.transaction.annotation.Transactional;
  21 +import org.springframework.validation.annotation.Validated;
  22 +
  23 +import java.math.BigDecimal;
  24 +import java.util.List;
  25 +
  26 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  27 +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
  28 +
  29 +/**
  30 + * MES 销售出库单 Service 实现类
  31 + *
  32 + * @author 芋道源码
  33 + */
  34 +@Service
  35 +@Validated
  36 +public class MesWmProductSalesServiceImpl implements MesWmProductSalesService {
  37 +
  38 + @Resource
  39 + private MesWmProductSalesMapper productSalesMapper;
  40 +
  41 + @Resource
  42 + private MesWmProductSalesLineService productSalesLineService;
  43 +
  44 + @Resource
  45 + private MesWmProductSalesDetailService productSalesDetailService;
  46 +
  47 + @Resource
  48 + private MesMdClientService clientService;
  49 +
  50 + @Resource
  51 + private MesWmMaterialStockService materialStockService;
  52 +
  53 + @Override
  54 + public Long createProductSales(MesWmProductSalesSaveReqVO createReqVO) {
  55 + // 校验编码唯一
  56 + validateCodeUnique(null, createReqVO.getCode());
  57 + // 校验客户存在
  58 + clientService.validateClientExists(createReqVO.getClientId());
  59 +
  60 + // 插入
  61 + MesWmProductSalesDO sales = BeanUtils.toBean(createReqVO, MesWmProductSalesDO.class);
  62 + sales.setStatus(MesWmProductSalesStatusEnum.PREPARE.getStatus());
  63 + productSalesMapper.insert(sales);
  64 + return sales.getId();
  65 + }
  66 +
  67 + @Override
  68 + public void updateProductSales(MesWmProductSalesSaveReqVO updateReqVO) {
  69 + // 校验存在 + 草稿状态
  70 + validateProductSalesExistsAndDraft(updateReqVO.getId());
  71 + // 校验编码唯一
  72 + validateCodeUnique(updateReqVO.getId(), updateReqVO.getCode());
  73 + // 校验客户存在
  74 + clientService.validateClientExists(updateReqVO.getClientId());
  75 +
  76 + // 更新
  77 + MesWmProductSalesDO updateObj = BeanUtils.toBean(updateReqVO, MesWmProductSalesDO.class);
  78 + productSalesMapper.updateById(updateObj);
  79 + }
  80 +
  81 + @Override
  82 + @Transactional(rollbackFor = Exception.class)
  83 + public void deleteProductSales(Long id) {
  84 + // 校验存在 + 草稿状态
  85 + validateProductSalesExistsAndDraft(id);
  86 +
  87 + // 级联删除明细和行
  88 + productSalesDetailService.deleteProductSalesDetailBySalesId(id);
  89 + productSalesLineService.deleteProductSalesLineBySalesId(id);
  90 + // 删除
  91 + productSalesMapper.deleteById(id);
  92 + }
  93 +
  94 + @Override
  95 + public MesWmProductSalesDO getProductSales(Long id) {
  96 + return productSalesMapper.selectById(id);
  97 + }
  98 +
  99 + @Override
  100 + public PageResult<MesWmProductSalesDO> getProductSalesPage(MesWmProductSalesPageReqVO pageReqVO) {
  101 + return productSalesMapper.selectPage(pageReqVO);
  102 + }
  103 +
  104 + @Override
  105 + @Transactional(rollbackFor = Exception.class)
  106 + public void submitProductSales(Long id) {
  107 + // 校验存在 + 草稿状态
  108 + validateProductSalesExistsAndDraft(id);
  109 + // 校验至少有一条行
  110 + List<MesWmProductSalesLineDO> lines = productSalesLineService.getProductSalesLineListBySalesId(id);
  111 + if (CollUtil.isEmpty(lines)) {
  112 + throw exception(WM_PRODUCT_SALES_LINES_EMPTY);
  113 + }
  114 +
  115 + // 提交(草稿 → 待拣货)
  116 + productSalesMapper.updateById(new MesWmProductSalesDO()
  117 + .setId(id).setStatus(MesWmProductSalesStatusEnum.APPROVING.getStatus()));
  118 + }
  119 +
  120 + @Override
  121 + @Transactional(rollbackFor = Exception.class)
  122 + public void pickProductSales(Long id) {
  123 + // 校验存在
  124 + MesWmProductSalesDO sales = validateProductSalesExists(id);
  125 + if (ObjUtil.notEqual(MesWmProductSalesStatusEnum.APPROVING.getStatus(), sales.getStatus())) {
  126 + throw exception(WM_PRODUCT_SALES_CANNOT_PICK);
  127 + }
  128 + // 校验每行明细数量之和是否等于行出库数量
  129 + List<MesWmProductSalesLineDO> lines = productSalesLineService.getProductSalesLineListBySalesId(id);
  130 + for (MesWmProductSalesLineDO line : lines) {
  131 + List<MesWmProductSalesDetailDO> details = productSalesDetailService.getProductSalesDetailListByLineId(line.getId());
  132 + if (CollUtil.isEmpty(details)) {
  133 + throw exception(WM_PRODUCT_SALES_DETAILS_EMPTY);
  134 + }
  135 + BigDecimal totalDetailQty = CollectionUtils.getSumValue(details,
  136 + MesWmProductSalesDetailDO::getQuantity, BigDecimal::add, BigDecimal.ZERO);
  137 + if (line.getQuantity() != null && totalDetailQty.compareTo(line.getQuantity()) != 0) {
  138 + throw exception(WM_PRODUCT_SALES_DETAIL_QUANTITY_MISMATCH);
  139 + }
  140 + }
  141 +
  142 + // 执行拣货(待拣货 → 待出库)
  143 + productSalesMapper.updateById(new MesWmProductSalesDO()
  144 + .setId(id).setStatus(MesWmProductSalesStatusEnum.APPROVED.getStatus()));
  145 + }
  146 +
  147 + @Override
  148 + @Transactional(rollbackFor = Exception.class)
  149 + public void executeProductSales(Long id) {
  150 + // 校验存在
  151 + MesWmProductSalesDO sales = validateProductSalesExists(id);
  152 + if (ObjUtil.notEqual(MesWmProductSalesStatusEnum.APPROVED.getStatus(), sales.getStatus())) {
  153 + throw exception(WM_PRODUCT_SALES_CANNOT_EXECUTE);
  154 + }
  155 +
  156 + // 遍历所有明细,扣减库存
  157 + // TODO @AI:需要实现 decreaseStock 方法
  158 + List<MesWmProductSalesDetailDO> details = productSalesDetailService.getProductSalesDetailListBySalesId(id);
  159 + for (MesWmProductSalesDetailDO detail : details) {
  160 + // materialStockService.decreaseStock(
  161 + // detail.getItemId(), detail.getWarehouseId(), detail.getLocationId(), detail.getAreaId(),
  162 + // detail.getBatchId(), detail.getQuantity(), sales.getClientId(), null, null);
  163 + }
  164 +
  165 + // 更新出库单状态
  166 + productSalesMapper.updateById(new MesWmProductSalesDO()
  167 + .setId(id).setStatus(MesWmProductSalesStatusEnum.FINISHED.getStatus()));
  168 + }
  169 +
  170 + @Override
  171 + @Transactional(rollbackFor = Exception.class)
  172 + public void cancelProductSales(Long id) {
  173 + // 校验存在
  174 + MesWmProductSalesDO sales = validateProductSalesExists(id);
  175 + // 已完成和已取消不允许取消
  176 + if (ObjectUtils.equalsAny(sales.getStatus(),
  177 + MesWmProductSalesStatusEnum.FINISHED.getStatus(),
  178 + MesWmProductSalesStatusEnum.CANCELED.getStatus())) {
  179 + throw exception(WM_PRODUCT_SALES_CANNOT_CANCEL);
  180 + }
  181 + // 取消
  182 + productSalesMapper.updateById(new MesWmProductSalesDO()
  183 + .setId(id).setStatus(MesWmProductSalesStatusEnum.CANCELED.getStatus()));
  184 + }
  185 +
  186 + private MesWmProductSalesDO validateProductSalesExists(Long id) {
  187 + MesWmProductSalesDO sales = productSalesMapper.selectById(id);
  188 + if (sales == null) {
  189 + throw exception(WM_PRODUCT_SALES_NOT_EXISTS);
  190 + }
  191 + return sales;
  192 + }
  193 +
  194 + /**
  195 + * 校验销售出库单存在且为草稿状态
  196 + */
  197 + private MesWmProductSalesDO validateProductSalesExistsAndDraft(Long id) {
  198 + MesWmProductSalesDO sales = validateProductSalesExists(id);
  199 + if (ObjUtil.notEqual(MesWmProductSalesStatusEnum.PREPARE.getStatus(), sales.getStatus())) {
  200 + throw exception(WM_PRODUCT_SALES_NOT_PREPARE);
  201 + }
  202 + return sales;
  203 + }
  204 +
  205 + private void validateCodeUnique(Long id, String code) {
  206 + MesWmProductSalesDO sales = productSalesMapper.selectByCode(code);
  207 + if (sales == null) {
  208 + return;
  209 + }
  210 + if (ObjUtil.notEqual(id, sales.getId())) {
  211 + throw exception(WM_PRODUCT_SALES_CODE_DUPLICATE);
  212 + }
  213 + }
  214 +
  215 +}