package cn.iocoder.yudao.module.mes.controller.admin.wm.scrap;
|
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.scrap.MesWmScrapReceiptDO;
|
import cn.iocoder.yudao.module.mes.dal.mysql.pro.workorder.MesProWorkOrderMapper;
|
import cn.iocoder.yudao.module.mes.dal.mysql.wm.scrap.MesWmScrapReceiptMapper;
|
import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum;
|
import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService;
|
import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO;
|
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
|
import jakarta.annotation.Resource;
|
import jakarta.validation.Valid;
|
import jakarta.validation.constraints.DecimalMin;
|
import jakarta.validation.constraints.Digits;
|
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.Size;
|
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.Pattern;
|
import lombok.Data;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.validation.annotation.Validated;
|
import org.springframework.web.bind.annotation.*;
|
|
import java.math.BigDecimal;
|
import java.time.LocalDateTime;
|
import java.time.YearMonth;
|
import java.util.List;
|
import java.util.Map;
|
import cn.iocoder.yudao.framework.common.exception.ServiceException;
|
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
|
/** 独立废料入库:记录和库存流水在同一个事务中提交。 */
|
@RestController
|
@RequestMapping("/mes/wm/scrap-receipt")
|
@Validated
|
public class MesWmScrapReceiptController {
|
@Resource private MesWmScrapReceiptMapper receiptMapper;
|
@Resource private MesProWorkOrderMapper workOrderMapper;
|
@Resource private MesWmTransactionService transactionService;
|
@Resource private MesWmWarehouseAreaService areaService;
|
@Resource private cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseService warehouseService;
|
@Resource private cn.iocoder.yudao.module.mdm.api.item.MdmItemApi itemApi;
|
|
@GetMapping("/order-outputs")
|
@PreAuthorize("@ss.hasPermission('mes:wm-scrap-receipt:create')")
|
public CommonResult<List<OutputItem>> orderOutputs(@RequestParam("workOrderId") Long workOrderId) {
|
var order = workOrderMapper.selectById(workOrderId);
|
if (order == null || !java.util.Objects.equals(order.getStatus(), cn.iocoder.yudao.module.mes.enums.pro.MesProWorkOrderStatusEnum.FINISHED.getStatus()))
|
throw new ServiceException(400, "仅已完成的生产订单可以登记废料");
|
var list = receiptMapper.selectOrderOutputs(workOrderId, cn.iocoder.yudao.module.mes.enums.wm.MesWmProductProduceStatusEnum.FINISHED.getStatus());
|
var items = itemApi.getItemMap(list.stream().map(OutputItem::getItemId).collect(java.util.stream.Collectors.toSet()));
|
list.forEach(output -> { var item = items.get(output.getItemId()); if (item != null) { output.setItemName(item.getName()); output.setItemCode(item.getCode()); } });
|
return success(list);
|
}
|
|
@PostMapping("/create-from-output")
|
@PreAuthorize("@ss.hasPermission('mes:wm-scrap-receipt:create')")
|
@Transactional(rollbackFor = Exception.class)
|
public CommonResult<Long> createFromOutput(@Valid @RequestBody CreateReq req) {
|
var locked = workOrderMapper.lockScheduleOrders(List.of(req.getWorkOrderId()));
|
if (locked.isEmpty() || !java.util.Objects.equals(locked.get(0).getStatus(), cn.iocoder.yudao.module.mes.enums.pro.MesProWorkOrderStatusEnum.FINISHED.getStatus()))
|
throw new ServiceException(400, "仅已完成的生产订单可以登记废料");
|
if (receiptMapper.selectOrderOutputs(req.getWorkOrderId(), cn.iocoder.yudao.module.mes.enums.wm.MesWmProductProduceStatusEnum.FINISHED.getStatus()).stream()
|
.noneMatch(item -> java.util.Objects.equals(item.getItemId(), req.getItemId())
|
&& java.util.Objects.equals(item.getBatchId(), req.getBatchId())
|
&& java.util.Objects.equals(cn.hutool.core.util.StrUtil.blankToDefault(item.getBatchCode(), ""),
|
cn.hutool.core.util.StrUtil.blankToDefault(req.getBatchCode(), ""))))
|
throw new ServiceException(400, "所选物料不是该订单的已完成产出");
|
var warehouse = warehouseService.validateWarehouseExists(req.getWarehouseId());
|
if (!java.util.Objects.equals("废料仓", warehouse.getWarehouseType()) && !java.util.Objects.equals("废料", warehouse.getWarehouseType()))
|
throw new ServiceException(400, "请选择仓库类型为废料仓的仓库");
|
return create(req);
|
}
|
|
@Data
|
public static class OutputItem {
|
private Long itemId;
|
private String itemCode;
|
private String itemName;
|
private Long batchId;
|
private String batchCode;
|
private BigDecimal quantity;
|
}
|
|
@PostMapping("/create")
|
@PreAuthorize("@ss.hasPermission('mes:wm-scrap-receipt:create')")
|
@Transactional(rollbackFor = Exception.class)
|
public CommonResult<Long> create(@Valid @RequestBody CreateReq req) {
|
var order = workOrderMapper.selectById(req.getWorkOrderId());
|
if (order == null) throw new ServiceException(400, "生产工单不存在");
|
areaService.validateWarehouseAreaExists(req.getWarehouseId(), req.getLocationId(), req.getAreaId());
|
String code = "SCR-" + req.getRequestId();
|
if (receiptMapper.selectByCode(code) != null) throw new ServiceException(400, "请求已提交,请刷新入库记录");
|
MesWmScrapReceiptDO receipt = new MesWmScrapReceiptDO();
|
receipt.setCode(code);
|
receipt.setWorkOrderId(order.getId());
|
receipt.setWorkOrderCode(order.getCode());
|
receipt.setItemId(req.getItemId());
|
receipt.setQuantity(req.getQuantity());
|
receipt.setWarehouseId(req.getWarehouseId());
|
receipt.setLocationId(req.getLocationId());
|
receipt.setAreaId(req.getAreaId());
|
receipt.setBatchId(req.getBatchId());
|
receipt.setBatchCode(req.getBatchCode());
|
receipt.setReceiptTime(LocalDateTime.now());
|
receipt.setRemark(req.getRemark());
|
receiptMapper.insert(receipt);
|
Long transactionId = transactionService.createTransaction(new MesWmTransactionSaveReqDTO()
|
.setType(MesWmTransactionTypeEnum.IN.getType()).setBizType(cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants.WM_SCRAP_RECEIPT)
|
.setBizId(receipt.getId()).setBizLineId(receipt.getId()).setBizCode(receipt.getCode())
|
.setItemId(receipt.getItemId()).setQuantity(receipt.getQuantity())
|
.setWarehouseId(receipt.getWarehouseId()).setLocationId(receipt.getLocationId())
|
.setAreaId(receipt.getAreaId()).setBatchId(receipt.getBatchId()).setBatchCode(receipt.getBatchCode())
|
.setReceiptTime(receipt.getReceiptTime()).setForceCreateNewStock(true));
|
receipt.setTransactionId(transactionId);
|
receiptMapper.updateById(receipt);
|
return success(receipt.getId());
|
}
|
|
@GetMapping("/monthly-summary")
|
@PreAuthorize("@ss.hasPermission('mes:wm-scrap-receipt:query')")
|
public CommonResult<List<Map<String, Object>>> monthlySummary(@RequestParam String month) {
|
YearMonth period = YearMonth.parse(month);
|
return success(receiptMapper.summarize(period.atDay(1).atStartOfDay(),
|
period.plusMonths(1).atDay(1).atStartOfDay()));
|
}
|
|
@GetMapping("/page")
|
@PreAuthorize("@ss.hasPermission('mes:wm-scrap-receipt:query')")
|
public CommonResult<PageResult<MesWmScrapReceiptDO>> page(@Valid PageParam page,
|
@RequestParam(required = false) Long workOrderId) {
|
return success(receiptMapper.selectReceiptPage(page, workOrderId));
|
}
|
|
@Data
|
public static class CreateReq {
|
@NotBlank @Pattern(regexp = "[A-Za-z0-9-]{1,60}") private String requestId;
|
@NotNull private Long workOrderId;
|
@NotNull private Long itemId;
|
@NotNull @DecimalMin(value = "0", inclusive = false) @Digits(integer = 16, fraction = 4) private BigDecimal quantity;
|
@NotNull private Long warehouseId;
|
@NotNull private Long locationId;
|
@NotNull private Long areaId;
|
private Long batchId;
|
@Size(max = 100) private String batchCode;
|
@Size(max = 500) private String remark;
|
}
|
}
|