Commit 55426245a1ff84a8ce67ce33e6b53f4f38f720f7
1 parent
ee20f777
feat(wms):优化 receipt order 实体的实现(增加 code review)
Showing
19 changed files
with
1535 additions
and
1 deletions
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/order/receipt/WmsReceiptOrderController.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.wms.controller.admin.order.receipt; | ||
| 2 | + | ||
| 3 | +import cn.hutool.core.collection.CollUtil; | ||
| 4 | +import cn.hutool.core.util.NumberUtil; | ||
| 5 | +import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; | ||
| 6 | +import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||
| 7 | +import cn.iocoder.yudao.framework.common.pojo.PageParam; | ||
| 8 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 9 | +import cn.iocoder.yudao.framework.common.util.collection.MapUtils; | ||
| 10 | +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | ||
| 11 | +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; | ||
| 12 | +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | ||
| 13 | +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; | ||
| 14 | +import cn.iocoder.yudao.module.wms.controller.admin.order.receipt.vo.detail.WmsReceiptOrderDetailRespVO; | ||
| 15 | +import cn.iocoder.yudao.module.wms.controller.admin.order.receipt.vo.order.WmsReceiptOrderPageReqVO; | ||
| 16 | +import cn.iocoder.yudao.module.wms.controller.admin.order.receipt.vo.order.WmsReceiptOrderRespVO; | ||
| 17 | +import cn.iocoder.yudao.module.wms.controller.admin.order.receipt.vo.order.WmsReceiptOrderSaveReqVO; | ||
| 18 | +import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemDO; | ||
| 19 | +import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemSkuDO; | ||
| 20 | +import cn.iocoder.yudao.module.wms.dal.dataobject.md.merchant.WmsMerchantDO; | ||
| 21 | +import cn.iocoder.yudao.module.wms.dal.dataobject.md.warehouse.WmsWarehouseAreaDO; | ||
| 22 | +import cn.iocoder.yudao.module.wms.dal.dataobject.md.warehouse.WmsWarehouseDO; | ||
| 23 | +import cn.iocoder.yudao.module.wms.dal.dataobject.order.receipt.WmsReceiptOrderDO; | ||
| 24 | +import cn.iocoder.yudao.module.wms.dal.dataobject.order.receipt.WmsReceiptOrderDetailDO; | ||
| 25 | +import cn.iocoder.yudao.module.wms.framework.config.WmsProperties; | ||
| 26 | +import cn.iocoder.yudao.module.wms.service.md.item.WmsItemService; | ||
| 27 | +import cn.iocoder.yudao.module.wms.service.md.item.WmsItemSkuService; | ||
| 28 | +import cn.iocoder.yudao.module.wms.service.md.merchant.WmsMerchantService; | ||
| 29 | +import cn.iocoder.yudao.module.wms.service.md.warehouse.WmsWarehouseAreaService; | ||
| 30 | +import cn.iocoder.yudao.module.wms.service.md.warehouse.WmsWarehouseService; | ||
| 31 | +import cn.iocoder.yudao.module.wms.service.order.receipt.WmsReceiptOrderDetailService; | ||
| 32 | +import cn.iocoder.yudao.module.wms.service.order.receipt.WmsReceiptOrderService; | ||
| 33 | +import io.swagger.v3.oas.annotations.Operation; | ||
| 34 | +import io.swagger.v3.oas.annotations.Parameter; | ||
| 35 | +import io.swagger.v3.oas.annotations.tags.Tag; | ||
| 36 | +import jakarta.annotation.Resource; | ||
| 37 | +import jakarta.servlet.http.HttpServletResponse; | ||
| 38 | +import jakarta.validation.Valid; | ||
| 39 | +import org.springframework.security.access.prepost.PreAuthorize; | ||
| 40 | +import org.springframework.validation.annotation.Validated; | ||
| 41 | +import org.springframework.web.bind.annotation.*; | ||
| 42 | + | ||
| 43 | +import java.io.IOException; | ||
| 44 | +import java.util.Collections; | ||
| 45 | +import java.util.List; | ||
| 46 | +import java.util.Map; | ||
| 47 | +import java.util.stream.Stream; | ||
| 48 | + | ||
| 49 | +import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; | ||
| 50 | +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | ||
| 51 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | ||
| 52 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSetByFlatMap; | ||
| 53 | + | ||
| 54 | +@Tag(name = "管理后台 - WMS 入库单") | ||
| 55 | +@RestController | ||
| 56 | +@RequestMapping("/wms/receipt-order") | ||
| 57 | +@Validated | ||
| 58 | +public class WmsReceiptOrderController { | ||
| 59 | + | ||
| 60 | + @Resource | ||
| 61 | + private WmsReceiptOrderService receiptOrderService; | ||
| 62 | + @Resource | ||
| 63 | + private WmsReceiptOrderDetailService receiptOrderDetailService; | ||
| 64 | + @Resource | ||
| 65 | + private WmsMerchantService merchantService; | ||
| 66 | + @Resource | ||
| 67 | + private WmsWarehouseService warehouseService; | ||
| 68 | + @Resource | ||
| 69 | + private WmsWarehouseAreaService warehouseAreaService; | ||
| 70 | + @Resource | ||
| 71 | + private WmsItemService itemService; | ||
| 72 | + @Resource | ||
| 73 | + private WmsItemSkuService itemSkuService; | ||
| 74 | + | ||
| 75 | + @Resource | ||
| 76 | + private WmsProperties wmsProperties; | ||
| 77 | + | ||
| 78 | + @Resource | ||
| 79 | + private AdminUserApi adminUserApi; | ||
| 80 | + | ||
| 81 | + @PostMapping("/create") | ||
| 82 | + @Operation(summary = "创建入库单") | ||
| 83 | + @PreAuthorize("@ss.hasPermission('wms:receipt-order:create')") | ||
| 84 | + public CommonResult<Long> createReceiptOrder(@Valid @RequestBody WmsReceiptOrderSaveReqVO createReqVO) { | ||
| 85 | + return success(receiptOrderService.createReceiptOrder(createReqVO)); | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + @PutMapping("/update") | ||
| 89 | + @Operation(summary = "更新入库单") | ||
| 90 | + @PreAuthorize("@ss.hasPermission('wms:receipt-order:update')") | ||
| 91 | + public CommonResult<Boolean> updateReceiptOrder(@Valid @RequestBody WmsReceiptOrderSaveReqVO updateReqVO) { | ||
| 92 | + receiptOrderService.updateReceiptOrder(updateReqVO); | ||
| 93 | + return success(true); | ||
| 94 | + } | ||
| 95 | + | ||
| 96 | + @DeleteMapping("/delete") | ||
| 97 | + @Operation(summary = "删除入库单") | ||
| 98 | + @Parameter(name = "id", description = "编号", required = true) | ||
| 99 | + @PreAuthorize("@ss.hasPermission('wms:receipt-order:delete')") | ||
| 100 | + public CommonResult<Boolean> deleteReceiptOrder(@RequestParam("id") Long id) { | ||
| 101 | + receiptOrderService.deleteReceiptOrder(id); | ||
| 102 | + return success(true); | ||
| 103 | + } | ||
| 104 | + | ||
| 105 | + @PutMapping("/complete") | ||
| 106 | + @Operation(summary = "完成入库") | ||
| 107 | + @Parameter(name = "id", description = "编号", required = true) | ||
| 108 | + @PreAuthorize("@ss.hasPermission('wms:receipt-order:complete')") | ||
| 109 | + public CommonResult<Boolean> completeReceiptOrder(@RequestParam("id") Long id) { | ||
| 110 | + receiptOrderService.completeReceiptOrder(id); | ||
| 111 | + return success(true); | ||
| 112 | + } | ||
| 113 | + | ||
| 114 | + @PutMapping("/cancel") | ||
| 115 | + @Operation(summary = "作废入库单") | ||
| 116 | + @Parameter(name = "id", description = "编号", required = true) | ||
| 117 | + @PreAuthorize("@ss.hasPermission('wms:receipt-order:cancel')") | ||
| 118 | + public CommonResult<Boolean> cancelReceiptOrder(@RequestParam("id") Long id) { | ||
| 119 | + receiptOrderService.cancelReceiptOrder(id); | ||
| 120 | + return success(true); | ||
| 121 | + } | ||
| 122 | + | ||
| 123 | + @GetMapping("/get") | ||
| 124 | + @Operation(summary = "获得入库单") | ||
| 125 | + @Parameter(name = "id", description = "编号", required = true, example = "1024") | ||
| 126 | + @PreAuthorize("@ss.hasPermission('wms:receipt-order:query')") | ||
| 127 | + public CommonResult<WmsReceiptOrderRespVO> getReceiptOrder(@RequestParam("id") Long id) { | ||
| 128 | + WmsReceiptOrderDO order = receiptOrderService.getReceiptOrder(id); | ||
| 129 | + if (order == null) { | ||
| 130 | + return success(null); | ||
| 131 | + } | ||
| 132 | + // 获得入库单的明细列表 | ||
| 133 | + List<WmsReceiptOrderDetailDO> detailList = receiptOrderDetailService.getReceiptOrderDetailList(id); | ||
| 134 | + // 拼接结果返回 | ||
| 135 | + WmsReceiptOrderRespVO respVO = buildReceiptOrderRespVO(order) | ||
| 136 | + .setDetails(buildReceiptOrderDetailRespVOList(detailList)); | ||
| 137 | + return success(respVO); | ||
| 138 | + } | ||
| 139 | + | ||
| 140 | + @GetMapping("/page") | ||
| 141 | + @Operation(summary = "获得入库单分页") | ||
| 142 | + @PreAuthorize("@ss.hasPermission('wms:receipt-order:query')") | ||
| 143 | + public CommonResult<PageResult<WmsReceiptOrderRespVO>> getReceiptOrderPage(@Valid WmsReceiptOrderPageReqVO pageReqVO) { | ||
| 144 | + PageResult<WmsReceiptOrderDO> pageResult = receiptOrderService.getReceiptOrderPage(pageReqVO); | ||
| 145 | + return success(new PageResult<>(buildReceiptOrderRespVOList(pageResult.getList()), pageResult.getTotal())); | ||
| 146 | + } | ||
| 147 | + | ||
| 148 | + @GetMapping("/export-excel") | ||
| 149 | + @Operation(summary = "导出入库单 Excel") | ||
| 150 | + @PreAuthorize("@ss.hasPermission('wms:receipt-order:export')") | ||
| 151 | + @ApiAccessLog(operateType = EXPORT) | ||
| 152 | + public void exportReceiptOrderExcel(@Valid WmsReceiptOrderPageReqVO pageReqVO, | ||
| 153 | + HttpServletResponse response) throws IOException { | ||
| 154 | + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); | ||
| 155 | + List<WmsReceiptOrderDO> list = receiptOrderService.getReceiptOrderPage(pageReqVO).getList(); | ||
| 156 | + ExcelUtils.write(response, "入库单.xls", "数据", WmsReceiptOrderRespVO.class, | ||
| 157 | + buildReceiptOrderRespVOList(list)); | ||
| 158 | + } | ||
| 159 | + | ||
| 160 | + // ==================== 拼接 VO ==================== | ||
| 161 | + | ||
| 162 | + private WmsReceiptOrderRespVO buildReceiptOrderRespVO(WmsReceiptOrderDO order) { | ||
| 163 | + if (order == null) { | ||
| 164 | + return null; | ||
| 165 | + } | ||
| 166 | + List<WmsReceiptOrderRespVO> list = buildReceiptOrderRespVOList(List.of(order)); | ||
| 167 | + return CollUtil.getFirst(list); | ||
| 168 | + } | ||
| 169 | + | ||
| 170 | + private List<WmsReceiptOrderRespVO> buildReceiptOrderRespVOList(List<WmsReceiptOrderDO> list) { | ||
| 171 | + if (CollUtil.isEmpty(list)) { | ||
| 172 | + return Collections.emptyList(); | ||
| 173 | + } | ||
| 174 | + // 获取相关的商户、仓库、库区、用户等数据 | ||
| 175 | + Map<Long, WmsMerchantDO> merchantMap = merchantService.getMerchantMap(convertSet(list, WmsReceiptOrderDO::getMerchantId)); | ||
| 176 | + Map<Long, WmsWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(convertSet(list, WmsReceiptOrderDO::getWarehouseId)); | ||
| 177 | + Map<Long, WmsWarehouseAreaDO> areaMap = wmsProperties.isAreaEnabled() | ||
| 178 | + ? warehouseAreaService.getWarehouseAreaMap(convertSet(list, WmsReceiptOrderDO::getAreaId)) | ||
| 179 | + : Collections.emptyMap(); | ||
| 180 | + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertSetByFlatMap(list, | ||
| 181 | + order -> Stream.of(parseUserId(order.getCreator()), parseUserId(order.getUpdater())))); | ||
| 182 | + // 拼接数据 | ||
| 183 | + return BeanUtils.toBean(list, WmsReceiptOrderRespVO.class, vo -> { | ||
| 184 | + MapUtils.findAndThen(merchantMap, vo.getMerchantId(), merchant -> vo.setMerchantName(merchant.getName())); | ||
| 185 | + MapUtils.findAndThen(warehouseMap, vo.getWarehouseId(), warehouse -> vo.setWarehouseName(warehouse.getName())); | ||
| 186 | + MapUtils.findAndThen(areaMap, vo.getAreaId(), area -> vo.setAreaName(area.getName())); | ||
| 187 | + MapUtils.findAndThen(userMap, parseUserId(vo.getCreator()), user -> vo.setCreatorName(user.getNickname())); | ||
| 188 | + MapUtils.findAndThen(userMap, parseUserId(vo.getUpdater()), user -> vo.setUpdaterName(user.getNickname())); | ||
| 189 | + }); | ||
| 190 | + } | ||
| 191 | + | ||
| 192 | + private Long parseUserId(String userId) { | ||
| 193 | + return NumberUtil.parseLong(userId, null); | ||
| 194 | + } | ||
| 195 | + | ||
| 196 | + private List<WmsReceiptOrderDetailRespVO> buildReceiptOrderDetailRespVOList(List<WmsReceiptOrderDetailDO> list) { | ||
| 197 | + if (CollUtil.isEmpty(list)) { | ||
| 198 | + return Collections.emptyList(); | ||
| 199 | + } | ||
| 200 | + // 获取相关的商品、SKU、仓库、库区等数据 | ||
| 201 | + Map<Long, WmsItemSkuDO> skuMap = itemSkuService.getItemSkuMap(convertSet(list, WmsReceiptOrderDetailDO::getSkuId)); | ||
| 202 | + Map<Long, WmsItemDO> itemMap = itemService.getItemMap(convertSet(skuMap.values(), WmsItemSkuDO::getItemId)); | ||
| 203 | + Map<Long, WmsWarehouseDO> warehouseMap = warehouseService.getWarehouseMap( | ||
| 204 | + convertSet(list, WmsReceiptOrderDetailDO::getWarehouseId)); | ||
| 205 | + Map<Long, WmsWarehouseAreaDO> areaMap = wmsProperties.isAreaEnabled() | ||
| 206 | + ? warehouseAreaService.getWarehouseAreaMap(convertSet(list, WmsReceiptOrderDetailDO::getAreaId)) | ||
| 207 | + : Collections.emptyMap(); | ||
| 208 | + // 拼接数据 | ||
| 209 | + return BeanUtils.toBean(list, WmsReceiptOrderDetailRespVO.class, vo -> { | ||
| 210 | + MapUtils.findAndThen(skuMap, vo.getSkuId(), sku -> { | ||
| 211 | + vo.setSkuCode(sku.getCode()).setSkuName(sku.getName()).setItemId(sku.getItemId()); | ||
| 212 | + MapUtils.findAndThen(itemMap, sku.getItemId(), item -> vo.setItemCode(item.getCode()) | ||
| 213 | + .setItemName(item.getName()).setUnit(item.getUnit())); | ||
| 214 | + }); | ||
| 215 | + MapUtils.findAndThen(warehouseMap, vo.getWarehouseId(), warehouse -> vo.setWarehouseName(warehouse.getName())); | ||
| 216 | + MapUtils.findAndThen(areaMap, vo.getAreaId(), area -> vo.setAreaName(area.getName())); | ||
| 217 | + }); | ||
| 218 | + } | ||
| 219 | + | ||
| 220 | +} |
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/order/receipt/WmsReceiptOrderDetailController.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.wms.controller.admin.order.receipt; | ||
| 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.wms.controller.admin.order.receipt.vo.detail.WmsReceiptOrderDetailRespVO; | ||
| 8 | +import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemDO; | ||
| 9 | +import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemSkuDO; | ||
| 10 | +import cn.iocoder.yudao.module.wms.dal.dataobject.md.warehouse.WmsWarehouseAreaDO; | ||
| 11 | +import cn.iocoder.yudao.module.wms.dal.dataobject.md.warehouse.WmsWarehouseDO; | ||
| 12 | +import cn.iocoder.yudao.module.wms.dal.dataobject.order.receipt.WmsReceiptOrderDetailDO; | ||
| 13 | +import cn.iocoder.yudao.module.wms.framework.config.WmsProperties; | ||
| 14 | +import cn.iocoder.yudao.module.wms.service.md.item.WmsItemService; | ||
| 15 | +import cn.iocoder.yudao.module.wms.service.md.item.WmsItemSkuService; | ||
| 16 | +import cn.iocoder.yudao.module.wms.service.md.warehouse.WmsWarehouseAreaService; | ||
| 17 | +import cn.iocoder.yudao.module.wms.service.md.warehouse.WmsWarehouseService; | ||
| 18 | +import cn.iocoder.yudao.module.wms.service.order.receipt.WmsReceiptOrderDetailService; | ||
| 19 | +import io.swagger.v3.oas.annotations.Operation; | ||
| 20 | +import io.swagger.v3.oas.annotations.Parameter; | ||
| 21 | +import io.swagger.v3.oas.annotations.tags.Tag; | ||
| 22 | +import jakarta.annotation.Resource; | ||
| 23 | +import org.springframework.security.access.prepost.PreAuthorize; | ||
| 24 | +import org.springframework.validation.annotation.Validated; | ||
| 25 | +import org.springframework.web.bind.annotation.GetMapping; | ||
| 26 | +import org.springframework.web.bind.annotation.RequestMapping; | ||
| 27 | +import org.springframework.web.bind.annotation.RequestParam; | ||
| 28 | +import org.springframework.web.bind.annotation.RestController; | ||
| 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 = "管理后台 - WMS 入库单明细") | ||
| 38 | +@RestController | ||
| 39 | +@RequestMapping("/wms/receipt-order-detail") | ||
| 40 | +@Validated | ||
| 41 | +public class WmsReceiptOrderDetailController { | ||
| 42 | + | ||
| 43 | + @Resource | ||
| 44 | + private WmsReceiptOrderDetailService receiptOrderDetailService; | ||
| 45 | + @Resource | ||
| 46 | + private WmsItemService itemService; | ||
| 47 | + @Resource | ||
| 48 | + private WmsItemSkuService itemSkuService; | ||
| 49 | + @Resource | ||
| 50 | + private WmsWarehouseService warehouseService; | ||
| 51 | + @Resource | ||
| 52 | + private WmsWarehouseAreaService warehouseAreaService; | ||
| 53 | + | ||
| 54 | + @Resource | ||
| 55 | + private WmsProperties wmsProperties; | ||
| 56 | + | ||
| 57 | + @GetMapping("/list-by-order-id") | ||
| 58 | + @Operation(summary = "获得入库单明细列表") | ||
| 59 | + @Parameter(name = "orderId", description = "入库单编号", required = true, example = "1024") | ||
| 60 | + @PreAuthorize("@ss.hasPermission('wms:receipt-order:query')") | ||
| 61 | + public CommonResult<List<WmsReceiptOrderDetailRespVO>> getReceiptOrderDetailListByOrderId( | ||
| 62 | + @RequestParam("orderId") Long orderId) { | ||
| 63 | + List<WmsReceiptOrderDetailDO> list = receiptOrderDetailService.getReceiptOrderDetailList(orderId); | ||
| 64 | + return success(buildReceiptOrderDetailRespVOList(list)); | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + // ==================== 拼接 VO ==================== | ||
| 68 | + | ||
| 69 | + private List<WmsReceiptOrderDetailRespVO> buildReceiptOrderDetailRespVOList(List<WmsReceiptOrderDetailDO> list) { | ||
| 70 | + if (CollUtil.isEmpty(list)) { | ||
| 71 | + return Collections.emptyList(); | ||
| 72 | + } | ||
| 73 | + // 查询关联数据 | ||
| 74 | + Map<Long, WmsItemSkuDO> skuMap = itemSkuService.getItemSkuMap(convertSet(list, WmsReceiptOrderDetailDO::getSkuId)); | ||
| 75 | + Map<Long, WmsItemDO> itemMap = itemService.getItemMap(convertSet(skuMap.values(), WmsItemSkuDO::getItemId)); | ||
| 76 | + Map<Long, WmsWarehouseDO> warehouseMap = warehouseService.getWarehouseMap( | ||
| 77 | + convertSet(list, WmsReceiptOrderDetailDO::getWarehouseId)); | ||
| 78 | + Map<Long, WmsWarehouseAreaDO> areaMap = wmsProperties.isAreaEnabled() | ||
| 79 | + ? warehouseAreaService.getWarehouseAreaMap(convertSet(list, WmsReceiptOrderDetailDO::getAreaId)) | ||
| 80 | + : Collections.emptyMap(); | ||
| 81 | + // 拼接数据 | ||
| 82 | + return BeanUtils.toBean(list, WmsReceiptOrderDetailRespVO.class, vo -> { | ||
| 83 | + MapUtils.findAndThen(skuMap, vo.getSkuId(), sku -> { | ||
| 84 | + vo.setSkuCode(sku.getCode()).setSkuName(sku.getName()).setItemId(sku.getItemId()); | ||
| 85 | + MapUtils.findAndThen(itemMap, sku.getItemId(), item -> vo.setItemCode(item.getCode()) | ||
| 86 | + .setItemName(item.getName()).setUnit(item.getUnit())); | ||
| 87 | + }); | ||
| 88 | + MapUtils.findAndThen(warehouseMap, vo.getWarehouseId(), warehouse -> vo.setWarehouseName(warehouse.getName())); | ||
| 89 | + MapUtils.findAndThen(areaMap, vo.getAreaId(), area -> vo.setAreaName(area.getName())); | ||
| 90 | + }); | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | +} |
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/order/receipt/vo/detail/WmsReceiptOrderDetailRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.wms.controller.admin.order.receipt.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 = "管理后台 - WMS 入库单明细 Response VO") | ||
| 10 | +@Data | ||
| 11 | +public class WmsReceiptOrderDetailRespVO { | ||
| 12 | + | ||
| 13 | + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") | ||
| 14 | + private Long id; | ||
| 15 | + | ||
| 16 | + @Schema(description = "入库单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") | ||
| 17 | + private Long orderId; | ||
| 18 | + | ||
| 19 | + @Schema(description = "商品编号", example = "2048") | ||
| 20 | + private Long itemId; | ||
| 21 | + | ||
| 22 | + @Schema(description = "商品编号", example = "SPU-APPLE") | ||
| 23 | + private String itemCode; | ||
| 24 | + | ||
| 25 | + @Schema(description = "商品名称", example = "红富士苹果") | ||
| 26 | + private String itemName; | ||
| 27 | + | ||
| 28 | + @Schema(description = "商品单位", example = "箱") | ||
| 29 | + private String unit; | ||
| 30 | + | ||
| 31 | + @Schema(description = "SKU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048") | ||
| 32 | + private Long skuId; | ||
| 33 | + | ||
| 34 | + @Schema(description = "规格编号", example = "SKU-APPLE-10KG") | ||
| 35 | + private String skuCode; | ||
| 36 | + | ||
| 37 | + @Schema(description = "规格名称", example = "10kg 箱装") | ||
| 38 | + private String skuName; | ||
| 39 | + | ||
| 40 | + @Schema(description = "仓库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") | ||
| 41 | + private Long warehouseId; | ||
| 42 | + | ||
| 43 | + @Schema(description = "仓库名称", example = "北京仓") | ||
| 44 | + private String warehouseName; | ||
| 45 | + | ||
| 46 | + @Schema(description = "库区编号", example = "1024") | ||
| 47 | + private Long areaId; | ||
| 48 | + | ||
| 49 | + @Schema(description = "库区名称", example = "北京库区01") | ||
| 50 | + private String areaName; | ||
| 51 | + | ||
| 52 | + @Schema(description = "批号", example = "B202605110001") | ||
| 53 | + private String batchNo; | ||
| 54 | + | ||
| 55 | + @Schema(description = "生产日期") | ||
| 56 | + private LocalDateTime productionDate; | ||
| 57 | + | ||
| 58 | + @Schema(description = "过期日期") | ||
| 59 | + private LocalDateTime expirationDate; | ||
| 60 | + | ||
| 61 | + @Schema(description = "入库数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00") | ||
| 62 | + private BigDecimal quantity; | ||
| 63 | + | ||
| 64 | + @Schema(description = "金额", example = "1000.00") | ||
| 65 | + private BigDecimal amount; | ||
| 66 | + | ||
| 67 | + @Schema(description = "备注", example = "备注") | ||
| 68 | + private String remark; | ||
| 69 | + | ||
| 70 | + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) | ||
| 71 | + private LocalDateTime createTime; | ||
| 72 | + | ||
| 73 | +} |
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/order/receipt/vo/detail/WmsReceiptOrderDetailSaveReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.wms.controller.admin.order.receipt.vo.detail; | ||
| 2 | + | ||
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 4 | +import jakarta.validation.constraints.DecimalMin; | ||
| 5 | +import jakarta.validation.constraints.NotNull; | ||
| 6 | +import jakarta.validation.constraints.Size; | ||
| 7 | +import lombok.Data; | ||
| 8 | + | ||
| 9 | +import java.math.BigDecimal; | ||
| 10 | +import java.time.LocalDateTime; | ||
| 11 | + | ||
| 12 | +@Schema(description = "管理后台 - WMS 入库单明细保存 Request VO") | ||
| 13 | +@Data | ||
| 14 | +public class WmsReceiptOrderDetailSaveReqVO { | ||
| 15 | + | ||
| 16 | + @Schema(description = "编号", example = "1024") | ||
| 17 | + private Long id; | ||
| 18 | + | ||
| 19 | + @Schema(description = "SKU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048") | ||
| 20 | + @NotNull(message = "SKU 不能为空") | ||
| 21 | + private Long skuId; | ||
| 22 | + | ||
| 23 | + @Schema(description = "库区编号", example = "1024") | ||
| 24 | + private Long areaId; | ||
| 25 | + | ||
| 26 | + @Schema(description = "批号", example = "B202605110001") | ||
| 27 | + @Size(max = 64, message = "批号长度不能超过 64 个字符") | ||
| 28 | + private String batchNo; | ||
| 29 | + | ||
| 30 | + @Schema(description = "生产日期") | ||
| 31 | + private LocalDateTime productionDate; | ||
| 32 | + | ||
| 33 | + @Schema(description = "过期日期") | ||
| 34 | + private LocalDateTime expirationDate; | ||
| 35 | + | ||
| 36 | + @Schema(description = "入库数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00") | ||
| 37 | + @NotNull(message = "入库数量不能为空") | ||
| 38 | + @DecimalMin(value = "0", inclusive = false, message = "入库数量必须大于 0") | ||
| 39 | + private BigDecimal quantity; | ||
| 40 | + | ||
| 41 | + @Schema(description = "金额", example = "1000.00") | ||
| 42 | + @DecimalMin(value = "0", message = "金额不能小于 0") | ||
| 43 | + private BigDecimal amount; | ||
| 44 | + | ||
| 45 | + @Schema(description = "备注", example = "备注") | ||
| 46 | + @Size(max = 255, message = "备注长度不能超过 255 个字符") | ||
| 47 | + private String remark; | ||
| 48 | + | ||
| 49 | +} |
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/order/receipt/vo/order/WmsReceiptOrderPageReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.wms.controller.admin.order.receipt.vo.order; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageParam; | ||
| 4 | +import cn.iocoder.yudao.framework.common.validation.InEnum; | ||
| 5 | +import cn.iocoder.yudao.module.wms.enums.order.WmsReceiptOrderStatusEnum; | ||
| 6 | +import cn.iocoder.yudao.module.wms.enums.order.WmsReceiptOrderTypeEnum; | ||
| 7 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 8 | +import lombok.Data; | ||
| 9 | +import lombok.EqualsAndHashCode; | ||
| 10 | +import lombok.ToString; | ||
| 11 | +import org.springframework.format.annotation.DateTimeFormat; | ||
| 12 | + | ||
| 13 | +import java.math.BigDecimal; | ||
| 14 | +import java.time.LocalDateTime; | ||
| 15 | + | ||
| 16 | +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | ||
| 17 | + | ||
| 18 | +@Schema(description = "管理后台 - WMS 入库单分页 Request VO") | ||
| 19 | +@Data | ||
| 20 | +@EqualsAndHashCode(callSuper = true) | ||
| 21 | +@ToString(callSuper = true) | ||
| 22 | +public class WmsReceiptOrderPageReqVO extends PageParam { | ||
| 23 | + | ||
| 24 | + @Schema(description = "入库单号", example = "RK202605110001") | ||
| 25 | + private String no; | ||
| 26 | + | ||
| 27 | + @Schema(description = "单据状态", example = "0") | ||
| 28 | + @InEnum(WmsReceiptOrderStatusEnum.class) | ||
| 29 | + private Integer status; | ||
| 30 | + | ||
| 31 | + @Schema(description = "仓库编号", example = "1024") | ||
| 32 | + private Long warehouseId; | ||
| 33 | + | ||
| 34 | + @Schema(description = "供应商编号", example = "1024") | ||
| 35 | + private Long merchantId; | ||
| 36 | + | ||
| 37 | + @Schema(description = "单据日期") | ||
| 38 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | ||
| 39 | + private LocalDateTime[] orderDate; | ||
| 40 | + | ||
| 41 | + @Schema(description = "最小数量", example = "1.00") | ||
| 42 | + private BigDecimal totalQuantityMin; | ||
| 43 | + | ||
| 44 | + @Schema(description = "最大数量", example = "100.00") | ||
| 45 | + private BigDecimal totalQuantityMax; | ||
| 46 | + | ||
| 47 | + @Schema(description = "最小总金额", example = "1.00") | ||
| 48 | + private BigDecimal totalAmountMin; | ||
| 49 | + | ||
| 50 | + @Schema(description = "最大总金额", example = "1000.00") | ||
| 51 | + private BigDecimal totalAmountMax; | ||
| 52 | + | ||
| 53 | + @Schema(description = "入库类型", example = "1") | ||
| 54 | + @InEnum(WmsReceiptOrderTypeEnum.class) | ||
| 55 | + private Integer type; | ||
| 56 | + | ||
| 57 | + @Schema(description = "业务单号", example = "PO202605110001") | ||
| 58 | + private String bizOrderNo; | ||
| 59 | + | ||
| 60 | + @Schema(description = "创建用户", example = "1") | ||
| 61 | + private String creator; | ||
| 62 | + | ||
| 63 | + @Schema(description = "更新用户", example = "1") | ||
| 64 | + private String updater; | ||
| 65 | + | ||
| 66 | + @Schema(description = "创建时间") | ||
| 67 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | ||
| 68 | + private LocalDateTime[] createTime; | ||
| 69 | + | ||
| 70 | + @Schema(description = "更新时间") | ||
| 71 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | ||
| 72 | + private LocalDateTime[] updateTime; | ||
| 73 | + | ||
| 74 | +} |
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/order/receipt/vo/order/WmsReceiptOrderRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.wms.controller.admin.order.receipt.vo.order; | ||
| 2 | + | ||
| 3 | +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; | ||
| 4 | +import cn.idev.excel.annotation.ExcelProperty; | ||
| 5 | +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; | ||
| 6 | +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; | ||
| 7 | +import cn.iocoder.yudao.module.wms.controller.admin.order.receipt.vo.detail.WmsReceiptOrderDetailRespVO; | ||
| 8 | +import cn.iocoder.yudao.module.wms.enums.DictTypeConstants; | ||
| 9 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 10 | +import lombok.Data; | ||
| 11 | + | ||
| 12 | +import java.math.BigDecimal; | ||
| 13 | +import java.time.LocalDateTime; | ||
| 14 | +import java.util.List; | ||
| 15 | + | ||
| 16 | +@Schema(description = "管理后台 - WMS 入库单 Response VO") | ||
| 17 | +@Data | ||
| 18 | +@ExcelIgnoreUnannotated | ||
| 19 | +public class WmsReceiptOrderRespVO { | ||
| 20 | + | ||
| 21 | + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") | ||
| 22 | + private Long id; | ||
| 23 | + | ||
| 24 | + @Schema(description = "入库单号", requiredMode = Schema.RequiredMode.REQUIRED, example = "RK202605110001") | ||
| 25 | + @ExcelProperty("入库单号") | ||
| 26 | + private String no; | ||
| 27 | + | ||
| 28 | + @Schema(description = "入库类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | ||
| 29 | + @ExcelProperty(value = "入库类型", converter = DictConvert.class) | ||
| 30 | + @DictFormat(DictTypeConstants.RECEIPT_ORDER_TYPE) | ||
| 31 | + private Integer type; | ||
| 32 | + | ||
| 33 | + @Schema(description = "入库状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") | ||
| 34 | + @ExcelProperty(value = "入库状态", converter = DictConvert.class) | ||
| 35 | + @DictFormat(DictTypeConstants.RECEIPT_ORDER_STATUS) | ||
| 36 | + private Integer status; | ||
| 37 | + | ||
| 38 | + @Schema(description = "业务单号", example = "PO202605110001") | ||
| 39 | + @ExcelProperty("业务单号") | ||
| 40 | + private String bizOrderNo; | ||
| 41 | + | ||
| 42 | + @Schema(description = "供应商编号", example = "1024") | ||
| 43 | + private Long merchantId; | ||
| 44 | + | ||
| 45 | + @Schema(description = "供应商名称", example = "某某公司") | ||
| 46 | + @ExcelProperty("供应商") | ||
| 47 | + private String merchantName; | ||
| 48 | + | ||
| 49 | + @Schema(description = "备注", example = "备注") | ||
| 50 | + private String remark; | ||
| 51 | + | ||
| 52 | + @Schema(description = "仓库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") | ||
| 53 | + private Long warehouseId; | ||
| 54 | + | ||
| 55 | + @Schema(description = "仓库名称", example = "北京仓") | ||
| 56 | + @ExcelProperty("仓库") | ||
| 57 | + private String warehouseName; | ||
| 58 | + | ||
| 59 | + @Schema(description = "库区编号", example = "1024") | ||
| 60 | + private Long areaId; | ||
| 61 | + | ||
| 62 | + @Schema(description = "库区名称", example = "北京库区01") | ||
| 63 | + private String areaName; | ||
| 64 | + | ||
| 65 | + @Schema(description = "入库数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00") | ||
| 66 | + @ExcelProperty("入库数量") | ||
| 67 | + private BigDecimal totalQuantity; | ||
| 68 | + | ||
| 69 | + @Schema(description = "总金额", example = "1000.00") | ||
| 70 | + @ExcelProperty("总金额") | ||
| 71 | + private BigDecimal totalAmount; | ||
| 72 | + | ||
| 73 | + @Schema(description = "入库明细") | ||
| 74 | + private List<WmsReceiptOrderDetailRespVO> details; | ||
| 75 | + | ||
| 76 | + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) | ||
| 77 | + @ExcelProperty("创建时间") | ||
| 78 | + private LocalDateTime createTime; | ||
| 79 | + | ||
| 80 | + @Schema(description = "创建者", example = "1") | ||
| 81 | + private String creator; | ||
| 82 | + @Schema(description = "创建者名称", example = "芋道") | ||
| 83 | + private String creatorName; | ||
| 84 | + | ||
| 85 | + @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED) | ||
| 86 | + private LocalDateTime updateTime; | ||
| 87 | + | ||
| 88 | + @Schema(description = "更新者", example = "1") | ||
| 89 | + private String updater; | ||
| 90 | + @Schema(description = "更新者名称", example = "芋道") | ||
| 91 | + private String updaterName; | ||
| 92 | + | ||
| 93 | +} |
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/order/receipt/vo/order/WmsReceiptOrderSaveReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.wms.controller.admin.order.receipt.vo.order; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.common.validation.InEnum; | ||
| 4 | +import cn.iocoder.yudao.module.wms.controller.admin.order.receipt.vo.detail.WmsReceiptOrderDetailSaveReqVO; | ||
| 5 | +import cn.iocoder.yudao.module.wms.enums.order.WmsReceiptOrderTypeEnum; | ||
| 6 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 7 | +import jakarta.validation.Valid; | ||
| 8 | +import jakarta.validation.constraints.NotBlank; | ||
| 9 | +import jakarta.validation.constraints.NotNull; | ||
| 10 | +import jakarta.validation.constraints.Size; | ||
| 11 | +import lombok.Data; | ||
| 12 | + | ||
| 13 | +import java.math.BigDecimal; | ||
| 14 | +import java.util.List; | ||
| 15 | + | ||
| 16 | +@Schema(description = "管理后台 - WMS 入库单保存 Request VO") | ||
| 17 | +@Data | ||
| 18 | +public class WmsReceiptOrderSaveReqVO { | ||
| 19 | + | ||
| 20 | + @Schema(description = "编号", example = "1024") | ||
| 21 | + private Long id; | ||
| 22 | + | ||
| 23 | + @Schema(description = "入库单号", requiredMode = Schema.RequiredMode.REQUIRED, example = "RK202605110001") | ||
| 24 | + @NotBlank(message = "入库单号不能为空") | ||
| 25 | + @Size(max = 64, message = "入库单号长度不能超过 64 个字符") | ||
| 26 | + private String no; | ||
| 27 | + | ||
| 28 | + @Schema(description = "入库类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | ||
| 29 | + @NotNull(message = "入库类型不能为空") | ||
| 30 | + @InEnum(WmsReceiptOrderTypeEnum.class) | ||
| 31 | + private Integer type; | ||
| 32 | + | ||
| 33 | + @Schema(description = "业务单号", example = "PO202605110001") | ||
| 34 | + @Size(max = 64, message = "业务单号长度不能超过 64 个字符") | ||
| 35 | + private String bizOrderNo; | ||
| 36 | + | ||
| 37 | + @Schema(description = "供应商编号", example = "1024") | ||
| 38 | + private Long merchantId; | ||
| 39 | + | ||
| 40 | + @Schema(description = "备注", example = "备注") | ||
| 41 | + @Size(max = 255, message = "备注长度不能超过 255 个字符") | ||
| 42 | + private String remark; | ||
| 43 | + | ||
| 44 | + @Schema(description = "仓库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") | ||
| 45 | + @NotNull(message = "仓库不能为空") | ||
| 46 | + private Long warehouseId; | ||
| 47 | + | ||
| 48 | + @Schema(description = "库区编号", example = "1024") | ||
| 49 | + private Long areaId; | ||
| 50 | + | ||
| 51 | + @Schema(description = "入库数量", example = "100.00") | ||
| 52 | + private BigDecimal totalQuantity; | ||
| 53 | + | ||
| 54 | + @Schema(description = "总金额", example = "1000.00") | ||
| 55 | + private BigDecimal totalAmount; | ||
| 56 | + | ||
| 57 | + @Schema(description = "入库明细") | ||
| 58 | + @Valid | ||
| 59 | + private List<WmsReceiptOrderDetailSaveReqVO> details; | ||
| 60 | + | ||
| 61 | +} |
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/dataobject/order/receipt/WmsReceiptOrderDO.java
| @@ -53,7 +53,7 @@ public class WmsReceiptOrderDO extends BaseDO { | @@ -53,7 +53,7 @@ public class WmsReceiptOrderDO extends BaseDO { | ||
| 53 | */ | 53 | */ |
| 54 | private String bizOrderNo; | 54 | private String bizOrderNo; |
| 55 | /** | 55 | /** |
| 56 | - * 往来企业编号 | 56 | + * 供应商编号 |
| 57 | * | 57 | * |
| 58 | * 关联 {@link WmsMerchantDO#getId()} | 58 | * 关联 {@link WmsMerchantDO#getId()} |
| 59 | */ | 59 | */ |
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/mysql/order/receipt/WmsReceiptOrderDetailMapper.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.wms.dal.mysql.order.receipt; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | ||
| 4 | +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | ||
| 5 | +import cn.iocoder.yudao.module.wms.dal.dataobject.order.receipt.WmsReceiptOrderDetailDO; | ||
| 6 | +import org.apache.ibatis.annotations.Mapper; | ||
| 7 | + | ||
| 8 | +import java.util.Collection; | ||
| 9 | +import java.util.List; | ||
| 10 | + | ||
| 11 | +/** | ||
| 12 | + * WMS 入库单明细 Mapper | ||
| 13 | + * | ||
| 14 | + * @author 芋道源码 | ||
| 15 | + */ | ||
| 16 | +@Mapper | ||
| 17 | +public interface WmsReceiptOrderDetailMapper extends BaseMapperX<WmsReceiptOrderDetailDO> { | ||
| 18 | + | ||
| 19 | + default List<WmsReceiptOrderDetailDO> selectListByOrderId(Long orderId) { | ||
| 20 | + return selectList(WmsReceiptOrderDetailDO::getOrderId, orderId); | ||
| 21 | + } | ||
| 22 | + | ||
| 23 | + default List<WmsReceiptOrderDetailDO> selectListByOrderIds(Collection<Long> orderIds) { | ||
| 24 | + return selectList(new LambdaQueryWrapperX<WmsReceiptOrderDetailDO>() | ||
| 25 | + .inIfPresent(WmsReceiptOrderDetailDO::getOrderId, orderIds) | ||
| 26 | + .orderByAsc(WmsReceiptOrderDetailDO::getOrderId) | ||
| 27 | + .orderByAsc(WmsReceiptOrderDetailDO::getId)); | ||
| 28 | + } | ||
| 29 | + | ||
| 30 | + default void deleteByOrderId(Long orderId) { | ||
| 31 | + delete(WmsReceiptOrderDetailDO::getOrderId, orderId); | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | +} |
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/mysql/order/receipt/WmsReceiptOrderMapper.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.wms.dal.mysql.order.receipt; | ||
| 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.wms.controller.admin.order.receipt.vo.order.WmsReceiptOrderPageReqVO; | ||
| 7 | +import cn.iocoder.yudao.module.wms.dal.dataobject.order.receipt.WmsReceiptOrderDO; | ||
| 8 | +import org.apache.ibatis.annotations.Mapper; | ||
| 9 | + | ||
| 10 | +/** | ||
| 11 | + * WMS 入库单 Mapper | ||
| 12 | + * | ||
| 13 | + * @author 芋道源码 | ||
| 14 | + */ | ||
| 15 | +@Mapper | ||
| 16 | +public interface WmsReceiptOrderMapper extends BaseMapperX<WmsReceiptOrderDO> { | ||
| 17 | + | ||
| 18 | + default PageResult<WmsReceiptOrderDO> selectPage(WmsReceiptOrderPageReqVO reqVO) { | ||
| 19 | + return selectPage(reqVO, new LambdaQueryWrapperX<WmsReceiptOrderDO>() | ||
| 20 | + .likeIfPresent(WmsReceiptOrderDO::getNo, reqVO.getNo()) | ||
| 21 | + .eqIfPresent(WmsReceiptOrderDO::getStatus, reqVO.getStatus()) | ||
| 22 | + .eqIfPresent(WmsReceiptOrderDO::getWarehouseId, reqVO.getWarehouseId()) | ||
| 23 | + .eqIfPresent(WmsReceiptOrderDO::getMerchantId, reqVO.getMerchantId()) | ||
| 24 | + .betweenIfPresent(WmsReceiptOrderDO::getCreateTime, reqVO.getOrderDate()) | ||
| 25 | + .geIfPresent(WmsReceiptOrderDO::getTotalQuantity, reqVO.getTotalQuantityMin()) | ||
| 26 | + .leIfPresent(WmsReceiptOrderDO::getTotalQuantity, reqVO.getTotalQuantityMax()) | ||
| 27 | + .geIfPresent(WmsReceiptOrderDO::getTotalAmount, reqVO.getTotalAmountMin()) | ||
| 28 | + .leIfPresent(WmsReceiptOrderDO::getTotalAmount, reqVO.getTotalAmountMax()) | ||
| 29 | + .eqIfPresent(WmsReceiptOrderDO::getType, reqVO.getType()) | ||
| 30 | + .likeIfPresent(WmsReceiptOrderDO::getBizOrderNo, reqVO.getBizOrderNo()) | ||
| 31 | + .eqIfPresent(WmsReceiptOrderDO::getCreator, reqVO.getCreator()) | ||
| 32 | + .eqIfPresent(WmsReceiptOrderDO::getUpdater, reqVO.getUpdater()) | ||
| 33 | + .betweenIfPresent(WmsReceiptOrderDO::getCreateTime, reqVO.getCreateTime()) | ||
| 34 | + .betweenIfPresent(WmsReceiptOrderDO::getUpdateTime, reqVO.getUpdateTime()) | ||
| 35 | + .orderByDesc(WmsReceiptOrderDO::getId)); | ||
| 36 | + } | ||
| 37 | + | ||
| 38 | + default WmsReceiptOrderDO selectByNo(String no) { | ||
| 39 | + return selectOne(WmsReceiptOrderDO::getNo, no); | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | +} |
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/enums/ErrorCodeConstants.java
| @@ -55,5 +55,7 @@ public interface ErrorCodeConstants { | @@ -55,5 +55,7 @@ public interface ErrorCodeConstants { | ||
| 55 | ErrorCode RECEIPT_ORDER_AREA_REQUIRED = new ErrorCode(1_060_200_004, "库区模式下,入库单库区不能为空"); | 55 | ErrorCode RECEIPT_ORDER_AREA_REQUIRED = new ErrorCode(1_060_200_004, "库区模式下,入库单库区不能为空"); |
| 56 | ErrorCode RECEIPT_ORDER_AREA_NOT_MATCH_WAREHOUSE = new ErrorCode(1_060_200_005, "库区不属于入库仓库"); | 56 | ErrorCode RECEIPT_ORDER_AREA_NOT_MATCH_WAREHOUSE = new ErrorCode(1_060_200_005, "库区不属于入库仓库"); |
| 57 | ErrorCode RECEIPT_ORDER_COMPLETED_CANNOT_DELETE = new ErrorCode(1_060_200_006, "入库单已完成,不能删除"); | 57 | ErrorCode RECEIPT_ORDER_COMPLETED_CANNOT_DELETE = new ErrorCode(1_060_200_006, "入库单已完成,不能删除"); |
| 58 | + ErrorCode RECEIPT_ORDER_DETAIL_NOT_EXISTS = new ErrorCode(1_060_200_007, "入库单明细不存在"); | ||
| 59 | + ErrorCode RECEIPT_ORDER_MERCHANT_NOT_SUPPLIER = new ErrorCode(1_060_200_008, "入库单供应商必须选择供应商或客户/供应商类型的往来企业"); | ||
| 58 | 60 | ||
| 59 | } | 61 | } |
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/enums/order/WmsReceiptOrderStatusEnum.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.wms.enums.order; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.common.core.ArrayValuable; | ||
| 4 | +import lombok.AllArgsConstructor; | ||
| 5 | +import lombok.Getter; | ||
| 6 | + | ||
| 7 | +import java.util.Arrays; | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * WMS 入库单状态枚举 | ||
| 11 | + * | ||
| 12 | + * @author 芋道源码 | ||
| 13 | + */ | ||
| 14 | +@Getter | ||
| 15 | +@AllArgsConstructor | ||
| 16 | +public enum WmsReceiptOrderStatusEnum implements ArrayValuable<Integer> { | ||
| 17 | + | ||
| 18 | + CANCELED(-1, "作废"), | ||
| 19 | + PENDING(0, "暂存"), | ||
| 20 | + COMPLETED(1, "完成入库"); | ||
| 21 | + | ||
| 22 | + public static final Integer[] ARRAYS = Arrays.stream(values()).map(WmsReceiptOrderStatusEnum::getStatus).toArray(Integer[]::new); | ||
| 23 | + | ||
| 24 | + /** | ||
| 25 | + * 状态 | ||
| 26 | + */ | ||
| 27 | + private final Integer status; | ||
| 28 | + /** | ||
| 29 | + * 名称 | ||
| 30 | + */ | ||
| 31 | + private final String name; | ||
| 32 | + | ||
| 33 | + @Override | ||
| 34 | + public Integer[] array() { | ||
| 35 | + return ARRAYS; | ||
| 36 | + } | ||
| 37 | + | ||
| 38 | +} |
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/enums/order/WmsReceiptOrderTypeEnum.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.wms.enums.order; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.common.core.ArrayValuable; | ||
| 4 | +import lombok.AllArgsConstructor; | ||
| 5 | +import lombok.Getter; | ||
| 6 | + | ||
| 7 | +import java.util.Arrays; | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * WMS 入库单类型枚举 | ||
| 11 | + * | ||
| 12 | + * @author 芋道源码 | ||
| 13 | + */ | ||
| 14 | +@Getter | ||
| 15 | +@AllArgsConstructor | ||
| 16 | +public enum WmsReceiptOrderTypeEnum implements ArrayValuable<Integer> { | ||
| 17 | + | ||
| 18 | + PURCHASE(1, "采购入库"), | ||
| 19 | + OUTSOURCING(2, "外协入库"), | ||
| 20 | + RETURN(3, "退货入库"); | ||
| 21 | + | ||
| 22 | + public static final Integer[] ARRAYS = Arrays.stream(values()).map(WmsReceiptOrderTypeEnum::getType).toArray(Integer[]::new); | ||
| 23 | + | ||
| 24 | + /** | ||
| 25 | + * 类型 | ||
| 26 | + */ | ||
| 27 | + private final Integer type; | ||
| 28 | + /** | ||
| 29 | + * 名称 | ||
| 30 | + */ | ||
| 31 | + private final String name; | ||
| 32 | + | ||
| 33 | + @Override | ||
| 34 | + public Integer[] array() { | ||
| 35 | + return ARRAYS; | ||
| 36 | + } | ||
| 37 | + | ||
| 38 | +} |
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/order/receipt/WmsReceiptOrderDetailService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.wms.service.order.receipt; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.module.wms.dal.dataobject.order.receipt.WmsReceiptOrderDetailDO; | ||
| 4 | + | ||
| 5 | +import java.util.Collection; | ||
| 6 | +import java.util.List; | ||
| 7 | + | ||
| 8 | +/** | ||
| 9 | + * WMS 入库单明细 Service 接口 | ||
| 10 | + * | ||
| 11 | + * @author 芋道源码 | ||
| 12 | + */ | ||
| 13 | +public interface WmsReceiptOrderDetailService { | ||
| 14 | + | ||
| 15 | + /** | ||
| 16 | + * 创建入库单明细列表 | ||
| 17 | + * | ||
| 18 | + * @param orderId 入库单编号 | ||
| 19 | + * @param list 明细列表 | ||
| 20 | + */ | ||
| 21 | + void createReceiptOrderDetailList(Long orderId, List<WmsReceiptOrderDetailDO> list); | ||
| 22 | + | ||
| 23 | + /** | ||
| 24 | + * 更新入库单明细列表 | ||
| 25 | + * | ||
| 26 | + * @param orderId 入库单编号 | ||
| 27 | + * @param list 明细列表 | ||
| 28 | + */ | ||
| 29 | + void updateReceiptOrderDetailList(Long orderId, List<WmsReceiptOrderDetailDO> list); | ||
| 30 | + | ||
| 31 | + /** | ||
| 32 | + * 按入库单编号删除明细列表 | ||
| 33 | + * | ||
| 34 | + * @param orderId 入库单编号 | ||
| 35 | + */ | ||
| 36 | + void deleteReceiptOrderDetailListByOrderId(Long orderId); | ||
| 37 | + | ||
| 38 | + /** | ||
| 39 | + * 按入库单编号获得明细列表 | ||
| 40 | + * | ||
| 41 | + * @param orderId 入库单编号 | ||
| 42 | + * @return 明细列表 | ||
| 43 | + */ | ||
| 44 | + List<WmsReceiptOrderDetailDO> getReceiptOrderDetailList(Long orderId); | ||
| 45 | + | ||
| 46 | + /** | ||
| 47 | + * 按入库单编号集合获得明细列表 | ||
| 48 | + * | ||
| 49 | + * @param orderIds 入库单编号集合 | ||
| 50 | + * @return 明细列表 | ||
| 51 | + */ | ||
| 52 | + List<WmsReceiptOrderDetailDO> getReceiptOrderDetailList(Collection<Long> orderIds); | ||
| 53 | + | ||
| 54 | +} |
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/order/receipt/WmsReceiptOrderDetailServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.wms.service.order.receipt; | ||
| 2 | + | ||
| 3 | +import cn.hutool.core.collection.CollUtil; | ||
| 4 | +import cn.hutool.core.collection.ListUtil; | ||
| 5 | +import cn.iocoder.yudao.module.wms.dal.dataobject.order.receipt.WmsReceiptOrderDetailDO; | ||
| 6 | +import cn.iocoder.yudao.module.wms.dal.mysql.order.receipt.WmsReceiptOrderDetailMapper; | ||
| 7 | +import jakarta.annotation.Resource; | ||
| 8 | +import org.springframework.stereotype.Service; | ||
| 9 | +import org.springframework.transaction.annotation.Transactional; | ||
| 10 | +import org.springframework.validation.annotation.Validated; | ||
| 11 | + | ||
| 12 | +import java.util.Collection; | ||
| 13 | +import java.util.List; | ||
| 14 | + | ||
| 15 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | ||
| 16 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; | ||
| 17 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.diffList; | ||
| 18 | +import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.RECEIPT_ORDER_DETAIL_NOT_EXISTS; | ||
| 19 | + | ||
| 20 | +/** | ||
| 21 | + * WMS 入库单明细 Service 实现类 | ||
| 22 | + * | ||
| 23 | + * @author 芋道源码 | ||
| 24 | + */ | ||
| 25 | +@Service | ||
| 26 | +@Validated | ||
| 27 | +public class WmsReceiptOrderDetailServiceImpl implements WmsReceiptOrderDetailService { | ||
| 28 | + | ||
| 29 | + @Resource | ||
| 30 | + private WmsReceiptOrderDetailMapper receiptOrderDetailMapper; | ||
| 31 | + | ||
| 32 | + @Override | ||
| 33 | + @Transactional(rollbackFor = Exception.class) | ||
| 34 | + public void createReceiptOrderDetailList(Long orderId, List<WmsReceiptOrderDetailDO> list) { | ||
| 35 | + if (CollUtil.isEmpty(list)) { | ||
| 36 | + return; | ||
| 37 | + } | ||
| 38 | + if (CollUtil.isNotEmpty(convertList(list, WmsReceiptOrderDetailDO::getId))) { | ||
| 39 | + throw exception(RECEIPT_ORDER_DETAIL_NOT_EXISTS); | ||
| 40 | + } | ||
| 41 | + list.forEach(detail -> detail.setOrderId(orderId)); | ||
| 42 | + receiptOrderDetailMapper.insertBatch(list); | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + @Override | ||
| 46 | + @Transactional(rollbackFor = Exception.class) | ||
| 47 | + public void updateReceiptOrderDetailList(Long orderId, List<WmsReceiptOrderDetailDO> list) { | ||
| 48 | + // 第一步,对比新老数据,获得添加、修改、删除的列表 | ||
| 49 | + List<WmsReceiptOrderDetailDO> oldList = receiptOrderDetailMapper.selectListByOrderId(orderId); | ||
| 50 | + List<WmsReceiptOrderDetailDO> newList = CollUtil.isEmpty(list) ? ListUtil.of() : list; | ||
| 51 | + List<List<WmsReceiptOrderDetailDO>> diffList = diffList(oldList, newList, // id 不同,就认为是不同的记录 | ||
| 52 | + (oldVal, newVal) -> oldVal.getId().equals(newVal.getId())); | ||
| 53 | + | ||
| 54 | + // 第二步,批量添加、修改、删除 | ||
| 55 | + if (CollUtil.isNotEmpty(diffList.get(0))) { | ||
| 56 | + if (CollUtil.isNotEmpty(convertList(diffList.get(0), WmsReceiptOrderDetailDO::getId))) { | ||
| 57 | + throw exception(RECEIPT_ORDER_DETAIL_NOT_EXISTS); | ||
| 58 | + } | ||
| 59 | + diffList.get(0).forEach(detail -> detail.setOrderId(orderId)); | ||
| 60 | + receiptOrderDetailMapper.insertBatch(diffList.get(0)); | ||
| 61 | + } | ||
| 62 | + if (CollUtil.isNotEmpty(diffList.get(1))) { | ||
| 63 | + diffList.get(1).forEach(detail -> detail.setOrderId(orderId)); | ||
| 64 | + receiptOrderDetailMapper.updateBatch(diffList.get(1)); | ||
| 65 | + } | ||
| 66 | + if (CollUtil.isNotEmpty(diffList.get(2))) { | ||
| 67 | + receiptOrderDetailMapper.deleteByIds(convertList(diffList.get(2), WmsReceiptOrderDetailDO::getId)); | ||
| 68 | + } | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + @Override | ||
| 72 | + public void deleteReceiptOrderDetailListByOrderId(Long orderId) { | ||
| 73 | + receiptOrderDetailMapper.deleteByOrderId(orderId); | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + @Override | ||
| 77 | + public List<WmsReceiptOrderDetailDO> getReceiptOrderDetailList(Long orderId) { | ||
| 78 | + return receiptOrderDetailMapper.selectListByOrderId(orderId); | ||
| 79 | + } | ||
| 80 | + | ||
| 81 | + @Override | ||
| 82 | + public List<WmsReceiptOrderDetailDO> getReceiptOrderDetailList(Collection<Long> orderIds) { | ||
| 83 | + if (CollUtil.isEmpty(orderIds)) { | ||
| 84 | + return ListUtil.of(); | ||
| 85 | + } | ||
| 86 | + return receiptOrderDetailMapper.selectListByOrderIds(orderIds); | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | +} |
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/order/receipt/WmsReceiptOrderService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.wms.service.order.receipt; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 4 | +import cn.iocoder.yudao.module.wms.controller.admin.order.receipt.vo.order.WmsReceiptOrderPageReqVO; | ||
| 5 | +import cn.iocoder.yudao.module.wms.controller.admin.order.receipt.vo.order.WmsReceiptOrderSaveReqVO; | ||
| 6 | +import cn.iocoder.yudao.module.wms.dal.dataobject.order.receipt.WmsReceiptOrderDO; | ||
| 7 | +import jakarta.validation.Valid; | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * WMS 入库单 Service 接口 | ||
| 11 | + * | ||
| 12 | + * @author 芋道源码 | ||
| 13 | + */ | ||
| 14 | +public interface WmsReceiptOrderService { | ||
| 15 | + | ||
| 16 | + /** | ||
| 17 | + * 创建入库单 | ||
| 18 | + * | ||
| 19 | + * @param createReqVO 创建信息 | ||
| 20 | + * @return 编号 | ||
| 21 | + */ | ||
| 22 | + Long createReceiptOrder(@Valid WmsReceiptOrderSaveReqVO createReqVO); | ||
| 23 | + | ||
| 24 | + /** | ||
| 25 | + * 更新入库单 | ||
| 26 | + * | ||
| 27 | + * @param updateReqVO 更新信息 | ||
| 28 | + */ | ||
| 29 | + void updateReceiptOrder(@Valid WmsReceiptOrderSaveReqVO updateReqVO); | ||
| 30 | + | ||
| 31 | + /** | ||
| 32 | + * 删除入库单 | ||
| 33 | + * | ||
| 34 | + * @param id 编号 | ||
| 35 | + */ | ||
| 36 | + void deleteReceiptOrder(Long id); | ||
| 37 | + | ||
| 38 | + /** | ||
| 39 | + * 完成入库 | ||
| 40 | + * | ||
| 41 | + * @param id 编号 | ||
| 42 | + */ | ||
| 43 | + void completeReceiptOrder(Long id); | ||
| 44 | + | ||
| 45 | + /** | ||
| 46 | + * 作废入库单 | ||
| 47 | + * | ||
| 48 | + * @param id 编号 | ||
| 49 | + */ | ||
| 50 | + void cancelReceiptOrder(Long id); | ||
| 51 | + | ||
| 52 | + /** | ||
| 53 | + * 获得入库单 | ||
| 54 | + * | ||
| 55 | + * @param id 编号 | ||
| 56 | + * @return 入库单 | ||
| 57 | + */ | ||
| 58 | + WmsReceiptOrderDO getReceiptOrder(Long id); | ||
| 59 | + | ||
| 60 | + /** | ||
| 61 | + * 获得入库单分页 | ||
| 62 | + * | ||
| 63 | + * @param pageReqVO 分页查询 | ||
| 64 | + * @return 入库单分页 | ||
| 65 | + */ | ||
| 66 | + PageResult<WmsReceiptOrderDO> getReceiptOrderPage(WmsReceiptOrderPageReqVO pageReqVO); | ||
| 67 | + | ||
| 68 | +} |
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/order/receipt/WmsReceiptOrderServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.wms.service.order.receipt; | ||
| 2 | + | ||
| 3 | +import cn.hutool.core.collection.CollUtil; | ||
| 4 | +import cn.hutool.core.collection.ListUtil; | ||
| 5 | +import cn.hutool.core.util.ObjectUtil; | ||
| 6 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 7 | +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | ||
| 8 | +import cn.iocoder.yudao.module.wms.controller.admin.order.receipt.vo.order.WmsReceiptOrderPageReqVO; | ||
| 9 | +import cn.iocoder.yudao.module.wms.controller.admin.order.receipt.vo.order.WmsReceiptOrderSaveReqVO; | ||
| 10 | +import cn.iocoder.yudao.module.wms.dal.dataobject.md.merchant.WmsMerchantDO; | ||
| 11 | +import cn.iocoder.yudao.module.wms.dal.dataobject.md.warehouse.WmsWarehouseAreaDO; | ||
| 12 | +import cn.iocoder.yudao.module.wms.dal.dataobject.order.receipt.WmsReceiptOrderDO; | ||
| 13 | +import cn.iocoder.yudao.module.wms.dal.dataobject.order.receipt.WmsReceiptOrderDetailDO; | ||
| 14 | +import cn.iocoder.yudao.module.wms.dal.mysql.order.receipt.WmsReceiptOrderMapper; | ||
| 15 | +import cn.iocoder.yudao.module.wms.enums.inventory.WmsInventoryOrderTypeEnum; | ||
| 16 | +import cn.iocoder.yudao.module.wms.enums.md.WmsMerchantTypeEnum; | ||
| 17 | +import cn.iocoder.yudao.module.wms.enums.order.WmsReceiptOrderStatusEnum; | ||
| 18 | +import cn.iocoder.yudao.module.wms.framework.config.WmsProperties; | ||
| 19 | +import cn.iocoder.yudao.module.wms.service.inventory.WmsInventoryService; | ||
| 20 | +import cn.iocoder.yudao.module.wms.service.inventory.dto.WmsInventoryChangeReqDTO; | ||
| 21 | +import cn.iocoder.yudao.module.wms.service.md.item.WmsItemSkuService; | ||
| 22 | +import cn.iocoder.yudao.module.wms.service.md.merchant.WmsMerchantService; | ||
| 23 | +import cn.iocoder.yudao.module.wms.service.md.warehouse.WmsWarehouseAreaService; | ||
| 24 | +import cn.iocoder.yudao.module.wms.service.md.warehouse.WmsWarehouseService; | ||
| 25 | +import jakarta.annotation.Resource; | ||
| 26 | +import org.springframework.stereotype.Service; | ||
| 27 | +import org.springframework.transaction.annotation.Transactional; | ||
| 28 | +import org.springframework.validation.annotation.Validated; | ||
| 29 | + | ||
| 30 | +import java.math.BigDecimal; | ||
| 31 | +import java.util.List; | ||
| 32 | + | ||
| 33 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | ||
| 34 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; | ||
| 35 | +import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.*; | ||
| 36 | + | ||
| 37 | +/** | ||
| 38 | + * WMS 入库单 Service 实现类 | ||
| 39 | + * | ||
| 40 | + * @author 芋道源码 | ||
| 41 | + */ | ||
| 42 | +@Service | ||
| 43 | +@Validated | ||
| 44 | +public class WmsReceiptOrderServiceImpl implements WmsReceiptOrderService { | ||
| 45 | + | ||
| 46 | + private static final Long EMPTY_AREA_ID = 0L; | ||
| 47 | + | ||
| 48 | + @Resource | ||
| 49 | + private WmsReceiptOrderMapper receiptOrderMapper; | ||
| 50 | + @Resource | ||
| 51 | + private WmsReceiptOrderDetailService receiptOrderDetailService; | ||
| 52 | + @Resource | ||
| 53 | + private WmsWarehouseService warehouseService; | ||
| 54 | + @Resource | ||
| 55 | + private WmsWarehouseAreaService warehouseAreaService; | ||
| 56 | + @Resource | ||
| 57 | + private WmsMerchantService merchantService; | ||
| 58 | + @Resource | ||
| 59 | + private WmsItemSkuService itemSkuService; | ||
| 60 | + @Resource | ||
| 61 | + private WmsInventoryService inventoryService; | ||
| 62 | + @Resource | ||
| 63 | + private WmsProperties wmsProperties; | ||
| 64 | + | ||
| 65 | + @Override | ||
| 66 | + @Transactional(rollbackFor = Exception.class) | ||
| 67 | + public Long createReceiptOrder(WmsReceiptOrderSaveReqVO createReqVO) { | ||
| 68 | + return createReceiptOrder(createReqVO, false).getId(); | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + // TODO @AI:不需要 detailRequired 参数呀。。。(对齐 mes 的做法) | ||
| 72 | + private WmsReceiptOrderDO createReceiptOrder(WmsReceiptOrderSaveReqVO createReqVO, boolean detailRequired) { | ||
| 73 | + // 1. 校验入库单保存数据 | ||
| 74 | + validateReceiptOrderSaveData(createReqVO); | ||
| 75 | + // TODO @AI:是不是(对齐 mes 的做法) | ||
| 76 | + List<WmsReceiptOrderDetailDO> details = buildReceiptOrderDetailList(createReqVO, detailRequired); | ||
| 77 | + | ||
| 78 | + // 2.1 插入入库单 | ||
| 79 | + WmsReceiptOrderDO order = BeanUtils.toBean(createReqVO, WmsReceiptOrderDO.class); | ||
| 80 | + order.setStatus(WmsReceiptOrderStatusEnum.PENDING.getStatus()); | ||
| 81 | + fillReceiptOrderTotal(order, details); | ||
| 82 | + receiptOrderMapper.insert(order); | ||
| 83 | + // 2.2 插入入库单明细 | ||
| 84 | + receiptOrderDetailService.createReceiptOrderDetailList(order.getId(), details); | ||
| 85 | + return order; | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + @Override | ||
| 89 | + @Transactional(rollbackFor = Exception.class) | ||
| 90 | + public void updateReceiptOrder(WmsReceiptOrderSaveReqVO updateReqVO) { | ||
| 91 | + updateReceiptOrder(updateReqVO, false); | ||
| 92 | + } | ||
| 93 | + | ||
| 94 | + @Override | ||
| 95 | + @Transactional(rollbackFor = Exception.class) | ||
| 96 | + public void deleteReceiptOrder(Long id) { | ||
| 97 | + // 1. 校验存在,且暂存 | ||
| 98 | + WmsReceiptOrderDO order = validateReceiptOrderExists(id); | ||
| 99 | + // TODO @AI:只有未“COMPLETED”不允许删除。 | ||
| 100 | + validateReceiptOrderPending(order); | ||
| 101 | + | ||
| 102 | + // 2.1 删除入库单 | ||
| 103 | + receiptOrderMapper.deleteById(id); | ||
| 104 | + // 2.1 删除入库单明细 | ||
| 105 | + receiptOrderDetailService.deleteReceiptOrderDetailListByOrderId(id); | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + @Override | ||
| 109 | + @Transactional(rollbackFor = Exception.class) | ||
| 110 | + public void completeReceiptOrder(Long id) { | ||
| 111 | + // 1.1 校验存在,且未完成 | ||
| 112 | + WmsReceiptOrderDO order = validateReceiptOrderExists(id); | ||
| 113 | + validateReceiptOrderPending(order); | ||
| 114 | + // 1.2 校验入库单明细存在 | ||
| 115 | + List<WmsReceiptOrderDetailDO> details = validateReceiptOrderDetailExists(id); | ||
| 116 | + | ||
| 117 | + // 2.1 完成入库单 | ||
| 118 | + WmsReceiptOrderDO updateObj = new WmsReceiptOrderDO().setId(id).setStatus(WmsReceiptOrderStatusEnum.COMPLETED.getStatus()); | ||
| 119 | + receiptOrderMapper.updateById(updateObj); | ||
| 120 | + // 2.2 写入库存 | ||
| 121 | + createInventory(order, details); | ||
| 122 | + } | ||
| 123 | + | ||
| 124 | + @Override | ||
| 125 | + @Transactional(rollbackFor = Exception.class) | ||
| 126 | + public void cancelReceiptOrder(Long id) { | ||
| 127 | + // 1. 校验存在,且未完成 | ||
| 128 | + WmsReceiptOrderDO order = validateReceiptOrderExists(id); | ||
| 129 | + validateReceiptOrderPending(order); | ||
| 130 | + | ||
| 131 | + // 2. 作废入库单 | ||
| 132 | + receiptOrderMapper.updateById(new WmsReceiptOrderDO().setId(id) | ||
| 133 | + .setStatus(WmsReceiptOrderStatusEnum.CANCELED.getStatus())); | ||
| 134 | + } | ||
| 135 | + | ||
| 136 | + @Override | ||
| 137 | + public WmsReceiptOrderDO getReceiptOrder(Long id) { | ||
| 138 | + return receiptOrderMapper.selectById(id); | ||
| 139 | + } | ||
| 140 | + | ||
| 141 | + @Override | ||
| 142 | + public PageResult<WmsReceiptOrderDO> getReceiptOrderPage(WmsReceiptOrderPageReqVO pageReqVO) { | ||
| 143 | + return receiptOrderMapper.selectPage(pageReqVO); | ||
| 144 | + } | ||
| 145 | + | ||
| 146 | + private WmsReceiptOrderDO updateReceiptOrder(WmsReceiptOrderSaveReqVO updateReqVO, boolean detailRequired) { | ||
| 147 | + // 1. 校验入库单保存数据 | ||
| 148 | + WmsReceiptOrderDO oldOrder = validateReceiptOrderExists(updateReqVO.getId()); | ||
| 149 | + validateReceiptOrderPending(oldOrder); | ||
| 150 | + validateReceiptOrderSaveData(updateReqVO); | ||
| 151 | + List<WmsReceiptOrderDetailDO> details = buildReceiptOrderDetailList(updateReqVO, detailRequired); | ||
| 152 | + | ||
| 153 | + // 2.1 更新入库单 | ||
| 154 | + WmsReceiptOrderDO updateObj = BeanUtils.toBean(updateReqVO, WmsReceiptOrderDO.class) | ||
| 155 | + .setStatus(WmsReceiptOrderStatusEnum.PENDING.getStatus()); | ||
| 156 | + fillReceiptOrderTotal(updateObj, details); | ||
| 157 | + receiptOrderMapper.updateById(updateObj); | ||
| 158 | + // 2.2 更新入库单明细 | ||
| 159 | + receiptOrderDetailService.updateReceiptOrderDetailList(updateReqVO.getId(), details); | ||
| 160 | + return updateObj; | ||
| 161 | + } | ||
| 162 | + | ||
| 163 | + private void validateReceiptOrderSaveData(WmsReceiptOrderSaveReqVO reqVO) { | ||
| 164 | + validateReceiptOrderNoUnique(reqVO.getId(), reqVO.getNo()); | ||
| 165 | + warehouseService.validateWarehouseExists(reqVO.getWarehouseId()); | ||
| 166 | + validateReceiptOrderMerchant(reqVO.getMerchantId()); | ||
| 167 | + reqVO.setAreaId(normalizeAreaId(reqVO.getAreaId(), reqVO.getWarehouseId(), false)); | ||
| 168 | + } | ||
| 169 | + | ||
| 170 | + private void validateReceiptOrderNoUnique(Long id, String no) { | ||
| 171 | + WmsReceiptOrderDO order = receiptOrderMapper.selectByNo(no); | ||
| 172 | + if (order == null) { | ||
| 173 | + return; | ||
| 174 | + } | ||
| 175 | + if (id == null || ObjectUtil.notEqual(order.getId(), id)) { | ||
| 176 | + throw exception(RECEIPT_ORDER_NO_DUPLICATE); | ||
| 177 | + } | ||
| 178 | + } | ||
| 179 | + | ||
| 180 | + private WmsReceiptOrderDO validateReceiptOrderExists(Long id) { | ||
| 181 | + WmsReceiptOrderDO order = id == null ? null : receiptOrderMapper.selectById(id); | ||
| 182 | + if (order == null) { | ||
| 183 | + throw exception(RECEIPT_ORDER_NOT_EXISTS); | ||
| 184 | + } | ||
| 185 | + return order; | ||
| 186 | + } | ||
| 187 | + | ||
| 188 | + private void validateReceiptOrderPending(WmsReceiptOrderDO order) { | ||
| 189 | + if (ObjectUtil.notEqual(order.getStatus(), WmsReceiptOrderStatusEnum.PENDING.getStatus())) { | ||
| 190 | + throw exception(RECEIPT_ORDER_STATUS_NOT_PENDING); | ||
| 191 | + } | ||
| 192 | + } | ||
| 193 | + | ||
| 194 | + private List<WmsReceiptOrderDetailDO> validateReceiptOrderDetailExists(Long id) { | ||
| 195 | + List<WmsReceiptOrderDetailDO> details = receiptOrderDetailService.getReceiptOrderDetailList(id); | ||
| 196 | + if (CollUtil.isEmpty(details)) { | ||
| 197 | + throw exception(RECEIPT_ORDER_DETAIL_REQUIRED); | ||
| 198 | + } | ||
| 199 | + return details; | ||
| 200 | + } | ||
| 201 | + | ||
| 202 | + private void validateReceiptOrderMerchant(Long merchantId) { | ||
| 203 | + if (merchantId == null) { | ||
| 204 | + return; | ||
| 205 | + } | ||
| 206 | + WmsMerchantDO merchant = merchantService.validateMerchantExists(merchantId); | ||
| 207 | + if (ObjectUtil.notEqual(merchant.getType(), WmsMerchantTypeEnum.SUPPLIER.getType()) | ||
| 208 | + && ObjectUtil.notEqual(merchant.getType(), WmsMerchantTypeEnum.CUSTOMER_SUPPLIER.getType())) { | ||
| 209 | + throw exception(RECEIPT_ORDER_MERCHANT_NOT_SUPPLIER); | ||
| 210 | + } | ||
| 211 | + } | ||
| 212 | + | ||
| 213 | + private List<WmsReceiptOrderDetailDO> buildReceiptOrderDetailList(WmsReceiptOrderSaveReqVO reqVO, boolean required) { | ||
| 214 | + if (CollUtil.isEmpty(reqVO.getDetails())) { | ||
| 215 | + if (required) { | ||
| 216 | + throw exception(RECEIPT_ORDER_DETAIL_REQUIRED); | ||
| 217 | + } | ||
| 218 | + return ListUtil.of(); | ||
| 219 | + } | ||
| 220 | + return convertList(reqVO.getDetails(), detail -> { | ||
| 221 | + itemSkuService.validateItemSkuExists(detail.getSkuId()); | ||
| 222 | + WmsReceiptOrderDetailDO detailDO = BeanUtils.toBean(detail, WmsReceiptOrderDetailDO.class); | ||
| 223 | + detailDO.setWarehouseId(reqVO.getWarehouseId()); | ||
| 224 | + detailDO.setAreaId(normalizeAreaId(detail.getAreaId() == null ? reqVO.getAreaId() : detail.getAreaId(), | ||
| 225 | + reqVO.getWarehouseId(), required)); | ||
| 226 | + return detailDO; | ||
| 227 | + }); | ||
| 228 | + } | ||
| 229 | + | ||
| 230 | + private Long normalizeAreaId(Long areaId, Long warehouseId, boolean required) { | ||
| 231 | + if (!wmsProperties.isAreaEnabled()) { | ||
| 232 | + return EMPTY_AREA_ID; | ||
| 233 | + } | ||
| 234 | + if (areaId == null || ObjectUtil.equal(areaId, EMPTY_AREA_ID)) { | ||
| 235 | + if (required) { | ||
| 236 | + throw exception(RECEIPT_ORDER_AREA_REQUIRED); | ||
| 237 | + } | ||
| 238 | + return EMPTY_AREA_ID; | ||
| 239 | + } | ||
| 240 | + WmsWarehouseAreaDO area = warehouseAreaService.validateWarehouseAreaExists(areaId); | ||
| 241 | + if (ObjectUtil.notEqual(area.getWarehouseId(), warehouseId)) { | ||
| 242 | + throw exception(RECEIPT_ORDER_AREA_NOT_MATCH_WAREHOUSE); | ||
| 243 | + } | ||
| 244 | + return areaId; | ||
| 245 | + } | ||
| 246 | + | ||
| 247 | + // DONE @AI:保留手工总金额优先;未填写时按明细金额汇总回填。 | ||
| 248 | + // TODO @AI:前端自动计算。 | ||
| 249 | + private void fillReceiptOrderTotal(WmsReceiptOrderDO order, List<WmsReceiptOrderDetailDO> details) { | ||
| 250 | + BigDecimal totalQuantity = BigDecimal.ZERO; | ||
| 251 | + BigDecimal totalAmount = BigDecimal.ZERO; | ||
| 252 | + for (WmsReceiptOrderDetailDO detail : details) { | ||
| 253 | + totalQuantity = totalQuantity.add(detail.getQuantity()); | ||
| 254 | + totalAmount = totalAmount.add(detail.getAmount() == null ? BigDecimal.ZERO : detail.getAmount()); | ||
| 255 | + } | ||
| 256 | + order.setTotalQuantity(totalQuantity); | ||
| 257 | + if (order.getTotalAmount() == null) { | ||
| 258 | + order.setTotalAmount(totalAmount); | ||
| 259 | + } | ||
| 260 | + } | ||
| 261 | + | ||
| 262 | + private void createInventory(WmsReceiptOrderDO order, List<WmsReceiptOrderDetailDO> details) { | ||
| 263 | + List<WmsInventoryChangeReqDTO.Item> items = convertList(details, detail -> new WmsInventoryChangeReqDTO.Item() | ||
| 264 | + .setSkuId(detail.getSkuId()).setWarehouseId(detail.getWarehouseId()).setAreaId(detail.getAreaId()) | ||
| 265 | + .setQuantity(detail.getQuantity()).setBatchNo(detail.getBatchNo()) | ||
| 266 | + .setProductionDate(detail.getProductionDate()).setExpirationDate(detail.getExpirationDate()) | ||
| 267 | + .setAmount(detail.getAmount()).setRemark(detail.getRemark())); | ||
| 268 | + inventoryService.changeInventory(new WmsInventoryChangeReqDTO() | ||
| 269 | + .setOrderId(order.getId()).setOrderNo(order.getNo()) | ||
| 270 | + .setOrderType(WmsInventoryOrderTypeEnum.RECEIPT.getType()).setItems(items)); | ||
| 271 | + } | ||
| 272 | + | ||
| 273 | +} |
yudao-module-wms/src/test/java/cn/iocoder/yudao/module/wms/service/order/receipt/WmsReceiptOrderDetailServiceImplTest.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.wms.service.order.receipt; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; | ||
| 4 | +import cn.iocoder.yudao.module.wms.dal.dataobject.order.receipt.WmsReceiptOrderDetailDO; | ||
| 5 | +import cn.iocoder.yudao.module.wms.dal.mysql.order.receipt.WmsReceiptOrderDetailMapper; | ||
| 6 | +import jakarta.annotation.Resource; | ||
| 7 | +import org.junit.jupiter.api.Test; | ||
| 8 | +import org.springframework.context.annotation.Import; | ||
| 9 | + | ||
| 10 | +import java.math.BigDecimal; | ||
| 11 | +import java.util.List; | ||
| 12 | + | ||
| 13 | +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; | ||
| 14 | +import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.RECEIPT_ORDER_DETAIL_NOT_EXISTS; | ||
| 15 | +import static org.junit.jupiter.api.Assertions.assertEquals; | ||
| 16 | +import static org.junit.jupiter.api.Assertions.assertNotNull; | ||
| 17 | +import static org.junit.jupiter.api.Assertions.assertNull; | ||
| 18 | + | ||
| 19 | +@Import(WmsReceiptOrderDetailServiceImpl.class) | ||
| 20 | +public class WmsReceiptOrderDetailServiceImplTest extends BaseDbUnitTest { | ||
| 21 | + | ||
| 22 | + @Resource | ||
| 23 | + private WmsReceiptOrderDetailServiceImpl receiptOrderDetailService; | ||
| 24 | + | ||
| 25 | + @Resource | ||
| 26 | + private WmsReceiptOrderDetailMapper receiptOrderDetailMapper; | ||
| 27 | + | ||
| 28 | + @Test | ||
| 29 | + public void testCreateReceiptOrderDetailList_success() { | ||
| 30 | + // mock 数据 | ||
| 31 | + Long orderId = 10L; | ||
| 32 | + WmsReceiptOrderDetailDO detail01 = createReceiptOrderDetail(null, 1001L, "1.00"); | ||
| 33 | + WmsReceiptOrderDetailDO detail02 = createReceiptOrderDetail(null, 1002L, "2.00"); | ||
| 34 | + | ||
| 35 | + // 调用 | ||
| 36 | + receiptOrderDetailService.createReceiptOrderDetailList(orderId, List.of(detail01, detail02)); | ||
| 37 | + | ||
| 38 | + // 断言 | ||
| 39 | + List<WmsReceiptOrderDetailDO> details = receiptOrderDetailMapper.selectListByOrderId(orderId); | ||
| 40 | + assertEquals(2, details.size()); | ||
| 41 | + assertEquals(orderId, details.get(0).getOrderId()); | ||
| 42 | + assertEquals(orderId, details.get(1).getOrderId()); | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + @Test | ||
| 46 | + public void testCreateReceiptOrderDetailList_detailNotExists() { | ||
| 47 | + // mock 数据 | ||
| 48 | + WmsReceiptOrderDetailDO detail = createReceiptOrderDetail(null, 1001L, "1.00"); | ||
| 49 | + detail.setId(999L); | ||
| 50 | + | ||
| 51 | + // 调用,并断言 | ||
| 52 | + assertServiceException(() -> receiptOrderDetailService.createReceiptOrderDetailList(10L, List.of(detail)), | ||
| 53 | + RECEIPT_ORDER_DETAIL_NOT_EXISTS); | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + @Test | ||
| 57 | + public void testUpdateReceiptOrderDetailList_diff() { | ||
| 58 | + // mock 数据 | ||
| 59 | + Long orderId = 10L; | ||
| 60 | + WmsReceiptOrderDetailDO detail01 = createReceiptOrderDetail(orderId, 1001L, "1.00"); | ||
| 61 | + WmsReceiptOrderDetailDO detail02 = createReceiptOrderDetail(orderId, 1002L, "2.00"); | ||
| 62 | + receiptOrderDetailMapper.insert(detail01); | ||
| 63 | + receiptOrderDetailMapper.insert(detail02); | ||
| 64 | + WmsReceiptOrderDetailDO updateDetail = createReceiptOrderDetail(999L, 2001L, "11.00"); | ||
| 65 | + updateDetail.setId(detail01.getId()); | ||
| 66 | + WmsReceiptOrderDetailDO createDetail = createReceiptOrderDetail(null, 2002L, "22.00"); | ||
| 67 | + | ||
| 68 | + // 调用 | ||
| 69 | + receiptOrderDetailService.updateReceiptOrderDetailList(orderId, List.of(updateDetail, createDetail)); | ||
| 70 | + | ||
| 71 | + // 断言:修改 | ||
| 72 | + WmsReceiptOrderDetailDO dbUpdateDetail = receiptOrderDetailMapper.selectById(detail01.getId()); | ||
| 73 | + assertNotNull(dbUpdateDetail); | ||
| 74 | + assertEquals(orderId, dbUpdateDetail.getOrderId()); | ||
| 75 | + assertEquals(2001L, dbUpdateDetail.getSkuId()); | ||
| 76 | + assertEquals(0, new BigDecimal("11.00").compareTo(dbUpdateDetail.getQuantity())); | ||
| 77 | + // 断言:新增 | ||
| 78 | + List<WmsReceiptOrderDetailDO> details = receiptOrderDetailMapper.selectListByOrderId(orderId); | ||
| 79 | + assertEquals(2, details.size()); | ||
| 80 | + WmsReceiptOrderDetailDO dbCreateDetail = details.stream() | ||
| 81 | + .filter(detail -> Long.valueOf(2002L).equals(detail.getSkuId())) | ||
| 82 | + .findFirst().orElse(null); | ||
| 83 | + assertNotNull(dbCreateDetail); | ||
| 84 | + assertEquals(orderId, dbCreateDetail.getOrderId()); | ||
| 85 | + assertEquals(0, new BigDecimal("22.00").compareTo(dbCreateDetail.getQuantity())); | ||
| 86 | + // 断言:删除 | ||
| 87 | + assertNull(receiptOrderDetailMapper.selectById(detail02.getId())); | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + @Test | ||
| 91 | + public void testUpdateReceiptOrderDetailList_detailNotExists() { | ||
| 92 | + // mock 数据 | ||
| 93 | + WmsReceiptOrderDetailDO detail = createReceiptOrderDetail(10L, 1001L, "1.00"); | ||
| 94 | + detail.setId(999L); | ||
| 95 | + | ||
| 96 | + // 调用,并断言 | ||
| 97 | + assertServiceException(() -> receiptOrderDetailService.updateReceiptOrderDetailList(10L, List.of(detail)), | ||
| 98 | + RECEIPT_ORDER_DETAIL_NOT_EXISTS); | ||
| 99 | + } | ||
| 100 | + | ||
| 101 | + private static WmsReceiptOrderDetailDO createReceiptOrderDetail(Long orderId, Long skuId, String quantity) { | ||
| 102 | + return WmsReceiptOrderDetailDO.builder() | ||
| 103 | + .orderId(orderId) | ||
| 104 | + .skuId(skuId) | ||
| 105 | + .warehouseId(100L) | ||
| 106 | + .areaId(0L) | ||
| 107 | + .quantity(new BigDecimal(quantity)) | ||
| 108 | + .amount(new BigDecimal("100.00")) | ||
| 109 | + .build(); | ||
| 110 | + } | ||
| 111 | + | ||
| 112 | +} |
yudao-module-wms/src/test/java/cn/iocoder/yudao/module/wms/service/order/receipt/WmsReceiptOrderServiceImplTest.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.wms.service.order.receipt; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; | ||
| 4 | +import cn.iocoder.yudao.module.wms.dal.dataobject.order.receipt.WmsReceiptOrderDO; | ||
| 5 | +import cn.iocoder.yudao.module.wms.dal.dataobject.order.receipt.WmsReceiptOrderDetailDO; | ||
| 6 | +import cn.iocoder.yudao.module.wms.dal.mysql.order.receipt.WmsReceiptOrderDetailMapper; | ||
| 7 | +import cn.iocoder.yudao.module.wms.dal.mysql.order.receipt.WmsReceiptOrderMapper; | ||
| 8 | +import cn.iocoder.yudao.module.wms.enums.inventory.WmsInventoryOrderTypeEnum; | ||
| 9 | +import cn.iocoder.yudao.module.wms.enums.order.WmsReceiptOrderStatusEnum; | ||
| 10 | +import cn.iocoder.yudao.module.wms.enums.order.WmsReceiptOrderTypeEnum; | ||
| 11 | +import cn.iocoder.yudao.module.wms.framework.config.WmsProperties; | ||
| 12 | +import cn.iocoder.yudao.module.wms.service.inventory.WmsInventoryService; | ||
| 13 | +import cn.iocoder.yudao.module.wms.service.inventory.dto.WmsInventoryChangeReqDTO; | ||
| 14 | +import cn.iocoder.yudao.module.wms.service.md.item.WmsItemSkuService; | ||
| 15 | +import cn.iocoder.yudao.module.wms.service.md.merchant.WmsMerchantService; | ||
| 16 | +import cn.iocoder.yudao.module.wms.service.md.warehouse.WmsWarehouseAreaService; | ||
| 17 | +import cn.iocoder.yudao.module.wms.service.md.warehouse.WmsWarehouseService; | ||
| 18 | +import jakarta.annotation.Resource; | ||
| 19 | +import org.junit.jupiter.api.Test; | ||
| 20 | +import org.mockito.ArgumentCaptor; | ||
| 21 | +import org.springframework.context.annotation.Import; | ||
| 22 | +import org.springframework.test.context.bean.override.mockito.MockitoBean; | ||
| 23 | + | ||
| 24 | +import java.math.BigDecimal; | ||
| 25 | + | ||
| 26 | +import static org.junit.jupiter.api.Assertions.assertEquals; | ||
| 27 | +import static org.junit.jupiter.api.Assertions.assertNotNull; | ||
| 28 | +import static org.mockito.ArgumentMatchers.any; | ||
| 29 | +import static org.mockito.Mockito.never; | ||
| 30 | +import static org.mockito.Mockito.verify; | ||
| 31 | + | ||
| 32 | +@Import({WmsReceiptOrderServiceImpl.class, WmsReceiptOrderDetailServiceImpl.class, WmsProperties.class}) | ||
| 33 | +public class WmsReceiptOrderServiceImplTest extends BaseDbUnitTest { | ||
| 34 | + | ||
| 35 | + @Resource | ||
| 36 | + private WmsReceiptOrderServiceImpl receiptOrderService; | ||
| 37 | + | ||
| 38 | + @Resource | ||
| 39 | + private WmsReceiptOrderMapper receiptOrderMapper; | ||
| 40 | + @Resource | ||
| 41 | + private WmsReceiptOrderDetailMapper receiptOrderDetailMapper; | ||
| 42 | + | ||
| 43 | + @MockitoBean | ||
| 44 | + private WmsWarehouseService warehouseService; | ||
| 45 | + @MockitoBean | ||
| 46 | + private WmsWarehouseAreaService warehouseAreaService; | ||
| 47 | + @MockitoBean | ||
| 48 | + private WmsMerchantService merchantService; | ||
| 49 | + @MockitoBean | ||
| 50 | + private WmsItemSkuService itemSkuService; | ||
| 51 | + @MockitoBean | ||
| 52 | + private WmsInventoryService inventoryService; | ||
| 53 | + | ||
| 54 | + @Test | ||
| 55 | + public void testCompleteReceiptOrder_success() { | ||
| 56 | + // mock 数据 | ||
| 57 | + Long warehouseId = 100L; | ||
| 58 | + Long skuId = 200L; | ||
| 59 | + WmsReceiptOrderDO order = createReceiptOrder(warehouseId); | ||
| 60 | + receiptOrderMapper.insert(order); | ||
| 61 | + receiptOrderDetailMapper.insert(createReceiptOrderDetail(order.getId(), skuId, warehouseId)); | ||
| 62 | + | ||
| 63 | + // 调用 | ||
| 64 | + receiptOrderService.completeReceiptOrder(order.getId()); | ||
| 65 | + | ||
| 66 | + // 断言:入库单 | ||
| 67 | + WmsReceiptOrderDO dbOrder = receiptOrderMapper.selectById(order.getId()); | ||
| 68 | + assertNotNull(dbOrder); | ||
| 69 | + assertEquals(WmsReceiptOrderStatusEnum.COMPLETED.getStatus(), dbOrder.getStatus()); | ||
| 70 | + // 断言:库存变更 | ||
| 71 | + ArgumentCaptor<WmsInventoryChangeReqDTO> captor = ArgumentCaptor.forClass(WmsInventoryChangeReqDTO.class); | ||
| 72 | + verify(inventoryService).changeInventory(captor.capture()); | ||
| 73 | + WmsInventoryChangeReqDTO inventoryReqDTO = captor.getValue(); | ||
| 74 | + assertEquals(order.getId(), inventoryReqDTO.getOrderId()); | ||
| 75 | + assertEquals(order.getNo(), inventoryReqDTO.getOrderNo()); | ||
| 76 | + assertEquals(WmsInventoryOrderTypeEnum.RECEIPT.getType(), inventoryReqDTO.getOrderType()); | ||
| 77 | + assertEquals(1, inventoryReqDTO.getItems().size()); | ||
| 78 | + assertEquals(skuId, inventoryReqDTO.getItems().get(0).getSkuId()); | ||
| 79 | + assertEquals(warehouseId, inventoryReqDTO.getItems().get(0).getWarehouseId()); | ||
| 80 | + assertEquals(0, new BigDecimal("2.00").compareTo(inventoryReqDTO.getItems().get(0).getQuantity())); | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + @Test | ||
| 84 | + public void testCancelReceiptOrder_success() { | ||
| 85 | + // mock 数据 | ||
| 86 | + WmsReceiptOrderDO order = createReceiptOrder(100L); | ||
| 87 | + receiptOrderMapper.insert(order); | ||
| 88 | + | ||
| 89 | + // 调用 | ||
| 90 | + receiptOrderService.cancelReceiptOrder(order.getId()); | ||
| 91 | + | ||
| 92 | + // 断言 | ||
| 93 | + WmsReceiptOrderDO dbOrder = receiptOrderMapper.selectById(order.getId()); | ||
| 94 | + assertNotNull(dbOrder); | ||
| 95 | + assertEquals(WmsReceiptOrderStatusEnum.CANCELED.getStatus(), dbOrder.getStatus()); | ||
| 96 | + verify(inventoryService, never()).changeInventory(any()); | ||
| 97 | + } | ||
| 98 | + | ||
| 99 | + private static WmsReceiptOrderDO createReceiptOrder(Long warehouseId) { | ||
| 100 | + return new WmsReceiptOrderDO() | ||
| 101 | + .setNo("RK202605120001") | ||
| 102 | + .setType(WmsReceiptOrderTypeEnum.PURCHASE.getType()) | ||
| 103 | + .setStatus(WmsReceiptOrderStatusEnum.PENDING.getStatus()) | ||
| 104 | + .setWarehouseId(warehouseId) | ||
| 105 | + .setAreaId(0L) | ||
| 106 | + .setTotalQuantity(new BigDecimal("2.00")) | ||
| 107 | + .setTotalAmount(new BigDecimal("20.00")); | ||
| 108 | + } | ||
| 109 | + | ||
| 110 | + private static WmsReceiptOrderDetailDO createReceiptOrderDetail(Long orderId, Long skuId, Long warehouseId) { | ||
| 111 | + return WmsReceiptOrderDetailDO.builder() | ||
| 112 | + .orderId(orderId) | ||
| 113 | + .skuId(skuId) | ||
| 114 | + .warehouseId(warehouseId) | ||
| 115 | + .areaId(0L) | ||
| 116 | + .quantity(new BigDecimal("2.00")) | ||
| 117 | + .amount(new BigDecimal("20.00")) | ||
| 118 | + .build(); | ||
| 119 | + } | ||
| 120 | + | ||
| 121 | +} |