Commit 34c1199b762e36afd7b628cf8cebf6677f4ee2bb
1 parent
caf4c2ff
✨ feat(mes): 添加数量校验逻辑,更新入库明细处理
新增对上架数量和入库数量的校验逻辑,确保入库明细的总数量不超过行入库数量。优化了入库单和入库明细的创建与更新流程,提升数据一致性和准确性。
Showing
9 changed files
with
108 additions
and
55 deletions
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/MesWmItemReceiptRespVO.java
| ... | ... | @@ -38,10 +38,6 @@ public class MesWmItemReceiptRespVO { |
| 38 | 38 | @ExcelProperty("到货通知单") |
| 39 | 39 | private String noticeCode; |
| 40 | 40 | |
| 41 | - @Schema(description = "采购订单编号", example = "PO20260101") | |
| 42 | - @ExcelProperty("采购订单编号") | |
| 43 | - private String purchaseOrderCode; | |
| 44 | - | |
| 45 | 41 | @Schema(description = "供应商编号", example = "1") |
| 46 | 42 | private Long vendorId; |
| 47 | 43 | |
| ... | ... | @@ -49,27 +45,6 @@ public class MesWmItemReceiptRespVO { |
| 49 | 45 | @ExcelProperty("供应商") |
| 50 | 46 | private String vendorName; |
| 51 | 47 | |
| 52 | - @Schema(description = "仓库编号", example = "1") | |
| 53 | - private Long warehouseId; | |
| 54 | - | |
| 55 | - @Schema(description = "仓库名称", example = "原料仓") | |
| 56 | - @ExcelProperty("仓库") | |
| 57 | - private String warehouseName; | |
| 58 | - | |
| 59 | - @Schema(description = "库区编号", example = "1") | |
| 60 | - private Long locationId; | |
| 61 | - | |
| 62 | - @Schema(description = "库区名称", example = "A 区") | |
| 63 | - @ExcelProperty("库区") | |
| 64 | - private String locationName; | |
| 65 | - | |
| 66 | - @Schema(description = "库位编号", example = "1") | |
| 67 | - private Long areaId; | |
| 68 | - | |
| 69 | - @Schema(description = "库位名称", example = "A-01") | |
| 70 | - @ExcelProperty("库位") | |
| 71 | - private String areaName; | |
| 72 | - | |
| 73 | 48 | @Schema(description = "入库日期") |
| 74 | 49 | @ExcelProperty("入库日期") |
| 75 | 50 | private LocalDateTime receiptDate; | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/detail/MesWmItemReceiptDetailSaveReqVO.java
| 1 | 1 | package cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.detail; |
| 2 | 2 | |
| 3 | 3 | import io.swagger.v3.oas.annotations.media.Schema; |
| 4 | +import jakarta.validation.constraints.DecimalMin; | |
| 4 | 5 | import jakarta.validation.constraints.NotNull; |
| 5 | 6 | import lombok.Data; |
| 6 | 7 | |
| ... | ... | @@ -27,6 +28,7 @@ public class MesWmItemReceiptDetailSaveReqVO { |
| 27 | 28 | |
| 28 | 29 | @Schema(description = "上架数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "300.00") |
| 29 | 30 | @NotNull(message = "上架数量不能为空") |
| 31 | + @DecimalMin(value = "0", inclusive = false, message = "上架数量必须大于 0") | |
| 30 | 32 | private BigDecimal quantity; |
| 31 | 33 | |
| 32 | 34 | @Schema(description = "批次编号", example = "1") | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/line/MesWmItemReceiptLineSaveReqVO.java
| 1 | 1 | package cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.line; |
| 2 | 2 | |
| 3 | 3 | import io.swagger.v3.oas.annotations.media.Schema; |
| 4 | +import jakarta.validation.constraints.DecimalMin; | |
| 4 | 5 | import jakarta.validation.constraints.NotNull; |
| 5 | 6 | import lombok.Data; |
| 6 | 7 | |
| ... | ... | @@ -27,6 +28,7 @@ public class MesWmItemReceiptLineSaveReqVO { |
| 27 | 28 | |
| 28 | 29 | @Schema(description = "入库数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "500.00") |
| 29 | 30 | @NotNull(message = "入库数量不能为空") |
| 31 | + @DecimalMin(value = "0", inclusive = false, message = "入库数量必须大于 0") | |
| 30 | 32 | private BigDecimal receivedQuantity; |
| 31 | 33 | |
| 32 | 34 | // TODO DONE @芋艿:已添加 batchCode 字段,前端可以使用 batchCode 输入批次编码 | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
| ... | ... | @@ -397,6 +397,7 @@ public interface ErrorCodeConstants { |
| 397 | 397 | ErrorCode WM_ITEM_RECEIPT_LINE_ARRIVAL_NOTICE_LINE_NOT_ALLOWED = new ErrorCode(1_040_705_102, |
| 398 | 398 | "入库单未关联到货通知单,不能选择到货通知单行"); |
| 399 | 399 | ErrorCode WM_ITEM_RECEIPT_DETAIL_NOT_EXISTS = new ErrorCode(1_040_705_200, "采购入库明细不存在"); |
| 400 | + ErrorCode WM_ITEM_RECEIPT_DETAIL_QUANTITY_EXCEED = new ErrorCode(1_040_705_202, "上架明细总数量不能超过行入库数量"); | |
| 400 | 401 | |
| 401 | 402 | // ========== MES 仓库管理-领料申请单(1-040-706-000) ========== |
| 402 | 403 | ErrorCode WM_MATERIAL_REQUEST_NOT_EXISTS = new ErrorCode(1_040_706_000, "领料申请单不存在"); | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeService.java
| ... | ... | @@ -93,6 +93,14 @@ public interface MesWmArrivalNoticeService { |
| 93 | 93 | } |
| 94 | 94 | |
| 95 | 95 | /** |
| 96 | + * 校验到货通知单存在 | |
| 97 | + * | |
| 98 | + * @param id 编号 | |
| 99 | + * @return 到货通知单 | |
| 100 | + */ | |
| 101 | + MesWmArrivalNoticeDO validateArrivalNoticeExists(Long id); | |
| 102 | + | |
| 103 | + /** | |
| 96 | 104 | * 校验到货通知单和行存在,且行属于该通知单 |
| 97 | 105 | * |
| 98 | 106 | * @param noticeId 到货通知单 ID | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeServiceImpl.java
| ... | ... | @@ -184,7 +184,8 @@ public class MesWmArrivalNoticeServiceImpl implements MesWmArrivalNoticeService |
| 184 | 184 | } |
| 185 | 185 | } |
| 186 | 186 | |
| 187 | - private MesWmArrivalNoticeDO validateArrivalNoticeExists(Long id) { | |
| 187 | + @Override | |
| 188 | + public MesWmArrivalNoticeDO validateArrivalNoticeExists(Long id) { | |
| 188 | 189 | MesWmArrivalNoticeDO notice = arrivalNoticeMapper.selectById(id); |
| 189 | 190 | if (notice == null) { |
| 190 | 191 | throw exception(WM_ARRIVAL_NOTICE_NOT_EXISTS); | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptDetailServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.module.mes.service.wm.itemreceipt; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 3 | 4 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 4 | 5 | import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.detail.MesWmItemReceiptDetailSaveReqVO; |
| 5 | 6 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptDetailDO; |
| 7 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptLineDO; | |
| 6 | 8 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.itemreceipt.MesWmItemReceiptDetailMapper; |
| 9 | +import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService; | |
| 7 | 10 | import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService; |
| 8 | 11 | import jakarta.annotation.Resource; |
| 9 | 12 | import org.springframework.context.annotation.Lazy; |
| 10 | 13 | import org.springframework.stereotype.Service; |
| 11 | 14 | import org.springframework.validation.annotation.Validated; |
| 12 | 15 | |
| 16 | +import java.math.BigDecimal; | |
| 13 | 17 | import java.util.List; |
| 14 | 18 | |
| 15 | 19 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| ... | ... | @@ -30,40 +34,53 @@ public class MesWmItemReceiptDetailServiceImpl implements MesWmItemReceiptDetail |
| 30 | 34 | private MesWmItemReceiptService itemReceiptService; |
| 31 | 35 | |
| 32 | 36 | @Resource |
| 37 | + @Lazy | |
| 38 | + private MesWmItemReceiptLineService itemReceiptLineService; | |
| 39 | + | |
| 40 | + @Resource | |
| 33 | 41 | private MesWmWarehouseAreaService warehouseAreaService; |
| 42 | + @Resource | |
| 43 | + @Lazy | |
| 44 | + private MesWmMaterialStockService materialStockService; | |
| 34 | 45 | |
| 35 | 46 | @Override |
| 36 | 47 | public Long createItemReceiptDetail(MesWmItemReceiptDetailSaveReqVO createReqVO) { |
| 37 | - // 校验父单据存在且为可编辑状态 | |
| 48 | + // 1. 校验数据 | |
| 38 | 49 | itemReceiptService.validateItemReceiptEditable(createReqVO.getReceiptId()); |
| 39 | - // 校验库区关系 | |
| 40 | - warehouseAreaService.validateWarehouseAreaExists( | |
| 41 | - createReqVO.getWarehouseId(), createReqVO.getLocationId(), createReqVO.getAreaId()); | |
| 42 | - // TODO @芋艿:【后续搞】超过数量验证; | |
| 43 | - | |
| 44 | - // TODO @芋艿:【后续搞】不允许物资混放 | |
| 50 | + validateItemReceiptDetailSaveData(createReqVO); | |
| 45 | 51 | |
| 52 | + // 2. 插入 | |
| 46 | 53 | MesWmItemReceiptDetailDO detail = BeanUtils.toBean(createReqVO, MesWmItemReceiptDetailDO.class); |
| 47 | 54 | itemReceiptDetailMapper.insert(detail); |
| 55 | + | |
| 56 | + // 3. 插入后校验数量是否超出 | |
| 57 | + validateDetailQuantityNotExceed(createReqVO.getLineId()); | |
| 48 | 58 | return detail.getId(); |
| 49 | 59 | } |
| 50 | 60 | |
| 51 | 61 | @Override |
| 52 | 62 | public void updateItemReceiptDetail(MesWmItemReceiptDetailSaveReqVO updateReqVO) { |
| 53 | - // 校验存在 | |
| 63 | + // 1.1 校验存在 | |
| 54 | 64 | MesWmItemReceiptDetailDO detail = validateItemReceiptDetailExists(updateReqVO.getId()); |
| 55 | - // 校验父单据存在且为可编辑状态 | |
| 56 | - itemReceiptService.validateItemReceiptEditable(detail.getReceiptId()); | |
| 57 | - // 校验库区关系 | |
| 58 | - warehouseAreaService.validateWarehouseAreaExists( | |
| 59 | - updateReqVO.getWarehouseId(), updateReqVO.getLocationId(), updateReqVO.getAreaId()); | |
| 60 | - // TODO @芋艿:【后续搞】超过数量验证; | |
| 61 | - | |
| 62 | - // TODO @芋艿:【后续搞】不允许物资混放 | |
| 65 | + // 1.2 校验数据 | |
| 66 | + updateReqVO.setReceiptId(detail.getReceiptId()); | |
| 67 | + validateItemReceiptDetailSaveData(updateReqVO); | |
| 63 | 68 | |
| 64 | - // 更新 | |
| 69 | + // 2. 更新 | |
| 65 | 70 | MesWmItemReceiptDetailDO updateObj = BeanUtils.toBean(updateReqVO, MesWmItemReceiptDetailDO.class); |
| 66 | 71 | itemReceiptDetailMapper.updateById(updateObj); |
| 72 | + | |
| 73 | + // 3. 更新后校验数量是否超出 | |
| 74 | + validateDetailQuantityNotExceed(detail.getLineId()); | |
| 75 | + } | |
| 76 | + | |
| 77 | + private void validateItemReceiptDetailSaveData(MesWmItemReceiptDetailSaveReqVO reqVO) { | |
| 78 | + // 校验父单据存在且为可编辑状态 | |
| 79 | + itemReceiptService.validateItemReceiptEditable(reqVO.getReceiptId()); | |
| 80 | + // 校验库区关系 | |
| 81 | + warehouseAreaService.validateWarehouseAreaExists(reqVO.getWarehouseId(), reqVO.getLocationId(), reqVO.getAreaId()); | |
| 82 | + // 校验库位物料/批次混放规则 | |
| 83 | + materialStockService.checkAreaMixingRule(reqVO.getAreaId(), reqVO.getItemId(), reqVO.getBatchId()); | |
| 67 | 84 | } |
| 68 | 85 | |
| 69 | 86 | @Override |
| ... | ... | @@ -107,4 +124,22 @@ public class MesWmItemReceiptDetailServiceImpl implements MesWmItemReceiptDetail |
| 107 | 124 | return detail; |
| 108 | 125 | } |
| 109 | 126 | |
| 127 | + /** | |
| 128 | + * 校验行下所有明细的数量之和不超过行的入库数量 | |
| 129 | + * | |
| 130 | + * @param lineId 行编号 | |
| 131 | + */ | |
| 132 | + private void validateDetailQuantityNotExceed(Long lineId) { | |
| 133 | + MesWmItemReceiptLineDO line = itemReceiptLineService.getItemReceiptLine(lineId); | |
| 134 | + if (line == null || line.getReceivedQuantity() == null) { | |
| 135 | + return; | |
| 136 | + } | |
| 137 | + List<MesWmItemReceiptDetailDO> details = itemReceiptDetailMapper.selectListByLineId(lineId); | |
| 138 | + BigDecimal totalDetailQty = CollectionUtils.getSumValue(details, | |
| 139 | + MesWmItemReceiptDetailDO::getQuantity, BigDecimal::add, BigDecimal.ZERO); | |
| 140 | + if (totalDetailQty.compareTo(line.getReceivedQuantity()) > 0) { | |
| 141 | + throw exception(WM_ITEM_RECEIPT_DETAIL_QUANTITY_EXCEED); | |
| 142 | + } | |
| 143 | + } | |
| 144 | + | |
| 110 | 145 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptLineServiceImpl.java
| ... | ... | @@ -52,20 +52,20 @@ public class MesWmItemReceiptLineServiceImpl implements MesWmItemReceiptLineServ |
| 52 | 52 | |
| 53 | 53 | @Override |
| 54 | 54 | public Long createItemReceiptLine(MesWmItemReceiptLineSaveReqVO createReqVO) { |
| 55 | - // 1.1 校验父单据存在且为可编辑状态 | |
| 55 | + // 1. 校验父单据存在且为可编辑状态 | |
| 56 | 56 | MesWmItemReceiptDO receipt = itemReceiptService.validateItemReceiptEditable(createReqVO.getReceiptId()); |
| 57 | - // 1.2 校验关联到货通知单行存在 | |
| 58 | - validateArrivalNoticeLine(receipt, createReqVO.getArrivalNoticeLineId()); | |
| 57 | + // 2. 校验数据 | |
| 58 | + validateItemReceiptLineSaveData(receipt, createReqVO); | |
| 59 | 59 | |
| 60 | - // 2.1 创建入库单行 | |
| 60 | + // 3.1 创建入库单行 | |
| 61 | 61 | MesWmItemReceiptLineDO line = BeanUtils.toBean(createReqVO, MesWmItemReceiptLineDO.class); |
| 62 | - // 2.2 生成或获取批次 | |
| 62 | + // 3.2 生成或获取批次 | |
| 63 | 63 | MesWmBatchDO batch = generateOrGetBatch(receipt, createReqVO); |
| 64 | 64 | if (batch != null) { |
| 65 | 65 | line.setBatchId(batch.getId()); |
| 66 | 66 | line.setBatchCode(batch.getCode()); |
| 67 | 67 | } |
| 68 | - // 2.3 插入数据库 | |
| 68 | + // 3.3 插入数据库 | |
| 69 | 69 | itemReceiptLineMapper.insert(line); |
| 70 | 70 | return line.getId(); |
| 71 | 71 | } |
| ... | ... | @@ -76,8 +76,8 @@ public class MesWmItemReceiptLineServiceImpl implements MesWmItemReceiptLineServ |
| 76 | 76 | MesWmItemReceiptLineDO line = validateItemReceiptLineExists(updateReqVO.getId()); |
| 77 | 77 | // 1.2 校验父单据存在且为可编辑状态 |
| 78 | 78 | MesWmItemReceiptDO receipt = itemReceiptService.validateItemReceiptEditable(line.getReceiptId()); |
| 79 | - // 1.3 校验关联到货通知单行存在 | |
| 80 | - validateArrivalNoticeLine(receipt, updateReqVO.getArrivalNoticeLineId()); | |
| 79 | + // 1.3 校验数据 | |
| 80 | + validateItemReceiptLineSaveData(receipt, updateReqVO); | |
| 81 | 81 | |
| 82 | 82 | // 2.1 更新 |
| 83 | 83 | MesWmItemReceiptLineDO updateObj = BeanUtils.toBean(updateReqVO, MesWmItemReceiptLineDO.class); |
| ... | ... | @@ -90,6 +90,11 @@ public class MesWmItemReceiptLineServiceImpl implements MesWmItemReceiptLineServ |
| 90 | 90 | itemReceiptLineMapper.updateById(updateObj); |
| 91 | 91 | } |
| 92 | 92 | |
| 93 | + private void validateItemReceiptLineSaveData(MesWmItemReceiptDO receipt, MesWmItemReceiptLineSaveReqVO reqVO) { | |
| 94 | + // 校验关联到货通知单行 | |
| 95 | + validateArrivalNoticeLine(receipt, reqVO.getArrivalNoticeLineId()); | |
| 96 | + } | |
| 97 | + | |
| 93 | 98 | @Override |
| 94 | 99 | @Transactional(rollbackFor = Exception.class) |
| 95 | 100 | public void deleteItemReceiptLine(Long id) { |
| ... | ... | @@ -162,6 +167,8 @@ public class MesWmItemReceiptLineServiceImpl implements MesWmItemReceiptLineServ |
| 162 | 167 | return line; |
| 163 | 168 | } |
| 164 | 169 | |
| 170 | + | |
| 171 | + | |
| 165 | 172 | /** |
| 166 | 173 | * 生成或获取批次 |
| 167 | 174 | * | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptServiceImpl.java
| ... | ... | @@ -15,6 +15,8 @@ import cn.iocoder.yudao.module.mes.dal.mysql.wm.itemreceipt.MesWmItemReceiptMapp |
| 15 | 15 | import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants; |
| 16 | 16 | import cn.iocoder.yudao.module.mes.enums.wm.MesWmItemReceiptStatusEnum; |
| 17 | 17 | import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum; |
| 18 | +import cn.iocoder.yudao.module.mes.service.md.vendor.MesMdVendorService; | |
| 19 | +import cn.iocoder.yudao.module.mes.service.qc.iqc.MesQcIqcService; | |
| 18 | 20 | import cn.iocoder.yudao.module.mes.service.wm.arrivalnotice.MesWmArrivalNoticeService; |
| 19 | 21 | import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService; |
| 20 | 22 | import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO; |
| ... | ... | @@ -48,14 +50,19 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService { |
| 48 | 50 | @Resource |
| 49 | 51 | @Lazy |
| 50 | 52 | private MesWmArrivalNoticeService arrivalNoticeService; |
| 53 | + @Resource | |
| 54 | + private MesMdVendorService vendorService; | |
| 55 | + @Resource | |
| 56 | + @Lazy | |
| 57 | + private MesQcIqcService iqcService; | |
| 51 | 58 | |
| 52 | 59 | @Resource |
| 53 | 60 | private MesWmTransactionService wmTransactionService; |
| 54 | 61 | |
| 55 | 62 | @Override |
| 56 | 63 | public Long createItemReceipt(MesWmItemReceiptSaveReqVO createReqVO) { |
| 57 | - // 校验编码唯一 | |
| 58 | - validateCodeUnique(null, createReqVO.getCode()); | |
| 64 | + // 校验数据 | |
| 65 | + validateItemReceiptSaveData(createReqVO); | |
| 59 | 66 | |
| 60 | 67 | // 插入 |
| 61 | 68 | MesWmItemReceiptDO receipt = BeanUtils.toBean(createReqVO, MesWmItemReceiptDO.class); |
| ... | ... | @@ -68,14 +75,29 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService { |
| 68 | 75 | public void updateItemReceipt(MesWmItemReceiptSaveReqVO updateReqVO) { |
| 69 | 76 | // 校验存在 + 草稿状态 |
| 70 | 77 | validateItemReceiptExistsAndDraft(updateReqVO.getId()); |
| 71 | - // 校验编码唯一 | |
| 72 | - validateCodeUnique(updateReqVO.getId(), updateReqVO.getCode()); | |
| 78 | + // 校验数据 | |
| 79 | + validateItemReceiptSaveData(updateReqVO); | |
| 73 | 80 | |
| 74 | 81 | // 更新 |
| 75 | 82 | MesWmItemReceiptDO updateObj = BeanUtils.toBean(updateReqVO, MesWmItemReceiptDO.class); |
| 76 | 83 | itemReceiptMapper.updateById(updateObj); |
| 77 | 84 | } |
| 78 | 85 | |
| 86 | + private void validateItemReceiptSaveData(MesWmItemReceiptSaveReqVO reqVO) { | |
| 87 | + // 校验编码唯一 | |
| 88 | + validateCodeUnique(reqVO.getId(), reqVO.getCode()); | |
| 89 | + // 校验供应商存在 | |
| 90 | + vendorService.validateVendorExists(reqVO.getVendorId()); | |
| 91 | + // 校验到货通知单存在 | |
| 92 | + if (reqVO.getNoticeId() != null) { | |
| 93 | + arrivalNoticeService.validateArrivalNoticeExists(reqVO.getNoticeId()); | |
| 94 | + } | |
| 95 | + // 校验来料检验单存在 | |
| 96 | + if (reqVO.getIqcId() != null) { | |
| 97 | + iqcService.validateIqcExists(reqVO.getIqcId()); | |
| 98 | + } | |
| 99 | + } | |
| 100 | + | |
| 79 | 101 | @Override |
| 80 | 102 | @Transactional(rollbackFor = Exception.class) |
| 81 | 103 | public void deleteItemReceipt(Long id) { | ... | ... |