| | |
| | | |
| | | å端æ¥å£åæ´æ¶ï¼**ä¸çæå端代ç **ï¼åªçæå端èè°æ¹æ¡ææ¡£ï¼è¾åºå° `docs/` ç®å½ã |
| | | |
| | | ## ç¦æ¢å
容 |
| | | |
| | | - â ç¦æ¢å Vue 模æ¿ä»£ç ï¼`<el-table-column>`ã`<el-form-item>` çï¼ |
| | | - â ç¦æ¢å JavaScript/TypeScript 代ç ï¼æ¹æ³ã彿°ãé»è¾å¤æçï¼ |
| | | - â ç¦æ¢å CSS æ ·å¼ä»£ç |
| | | - â ç¦æ¢åå端ç»ä»¶ä½¿ç¨ç¤ºä¾ |
| | | |
| | | ## èè°æ¹æ¡å
å®¹è¦æ± |
| | | |
| | | ææ¡£åºåªå
å«ä»¥ä¸å
å®¹ï¼ |
| | | |
| | | - **API 说æ**ï¼è·¯å¾ãæ¹æ³ã请æ±åæ°ãååºæ ¼å¼ |
| | | - **æ¶åçå端页é¢**ï¼ååºéè¦ä¿®æ¹çé¡µé¢ |
| | | - **æ¶åçå端页é¢**ï¼ååºéè¦ä¿®æ¹ç页é¢åç§° |
| | | - **æ°æ®å¸¦å
¥è¯´æ**ï¼éç¹å¼ºè°ä¿¡æ¯å¦ä½ä»ä¸ä¸æ¥å¸¦å
¥ï¼å¦éè´è®¢å -> å°è´§éç¥ -> éè´å
¥åºï¼ |
| | | - **æ¥å£è°ç¨æ¶åº**ï¼è¯´æä½æ¶è°ç¨åªä¸ªæ¥å£è·åå
³èæ°æ® |
| | | - **表ååæ®µæ å°**ï¼æç¡®åªäºå段ä»ä¸æ¸¸æ°æ®èªå¨å¡«å
ï¼åªäºéè¦ç¨æ·æå¨è¾å
¥ |
| | | - **åæ®µå±ç¤ºè§å**ï¼ç¨è¡¨æ ¼è¯´æå段å±ç¤ºä½ç½®å说æï¼ä¸å代ç |
| | | - **ä¸å¡è§å说æ**ï¼ç¨æåæè¡¨æ ¼è¯´æä¸å¡é»è¾ |
| | | - **注æäºé¡¹**ï¼éè¦å端注æçè¾¹çæ
åµ |
| | | |
| | | ## ææ¡£æ¨¡æ¿ |
| | | |
| | |
| | | |------|------|------|------| |
| | | | xxx | String | æ¯ | xxx | |
| | | |
| | | **ååºï¼** `{ "code": 200, "msg": "æä½æå" }` |
| | | **ååºå段æ°å¢ï¼** |
| | | |
| | | ## å端å®ç°è¦ç¹ |
| | | | åæ®µ | ç±»å | 说æ | |
| | | |------|------|------| |
| | | | xxx | String | xxx | |
| | | |
| | | ### 1. æ°æ®è·åæ¶æº |
| | | **ååºç¤ºä¾ï¼** |
| | | |
| | | - 页颿弿¶è°ç¨ XXX æ¥å£è·åéè´è®¢åä¿¡æ¯ |
| | | - éæ©éè´è®¢ååï¼è°ç¨ YYY æ¥å£è·åç©ææç» |
| | | ```json |
| | | { |
| | | "code": 0, |
| | | "data": {} |
| | | } |
| | | ``` |
| | | |
| | | ### 2. åæ®µèªå¨å¡«å
è§å |
| | | ## åæ®µå±ç¤ºè§å |
| | | |
| | | | ç®æ åæ®µ | æ°æ®æ¥æº | å¡«å
æ¶æº | |
| | | |----------|----------|----------| |
| | | | ç©æç¼ç | éè´è®¢åè¡.itemCode | éæ©è®¢åè¡å | |
| | | | ç©æåç§° | éè´è®¢åè¡.itemName | éæ©è®¢åè¡å | |
| | | | åæ®µ | å±ç¤ºä½ç½® | 说æ | |
| | | |------|----------|------| |
| | | | åæ®µA | å表ã详æ
| 说æ | |
| | | | åæ®µB | 详æ
| 说æ | |
| | | |
| | | ### 3. ç¨æ·å¯ç¼è¾å段 |
| | | ## ä¸å¡è§å说æ |
| | | |
| | | - åæ®µAï¼ç¨æ·å¯ä¿®æ¹ |
| | | - åæ®µBï¼ç¨æ·å¯ä¿®æ¹ |
| | | | åºæ¯ | è§å | |
| | | |------|------| |
| | | | åºæ¯1 | è§å说æ | |
| | | | åºæ¯2 | è§å说æ | |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # åºåå¯ç¨é管ç - å端èè°æ¹æ¡ |
| | | |
| | | ## æ¶åé¡µé¢ |
| | | |
| | | - åºåç°æéé¡µé¢ |
| | | |
| | | ## ä¸å¡æµç¨ä¸æ°æ®å¸¦å
¥ |
| | | |
| | | æ¬æ¬¡ä¸ºåºåå°è´¦å段æ©å±ï¼æ è·¨é¡µé¢æ°æ®æµè½¬ã |
| | | |
| | | ## API |
| | | |
| | | | æ¹æ³ | è·¯å¾ | 说æ | |
| | | |------|------|------| |
| | | | GET | /mes/wm/material-stock/page | åºåå°è´¦å页æ¥è¯¢ | |
| | | | GET | /mes/wm/material-stock/get | åæ¡åºåæ¥è¯¢ | |
| | | |
| | | **ååºå段æ°å¢ï¼** |
| | | |
| | | | åæ®µ | ç±»å | 说æ | |
| | | |------|------|------| |
| | | | frozenQuantity | Decimal | å»ç»æ°é | |
| | | | reservedQuantity | Decimal | å ç¨éï¼å·²åé
å¾
åºåºï¼ | |
| | | | inTransitQuantity | Decimal | å¨ééï¼è°æ¨å¨éï¼ | |
| | | | availableQuantity | Decimal | å¯ç¨éï¼å端计ç®ï¼å¨åºæ°é - å»ç»æ°é - å ç¨éï¼ | |
| | | |
| | | **ååºç¤ºä¾ï¼** |
| | | |
| | | ```json |
| | | { |
| | | "code": 0, |
| | | "data": { |
| | | "list": [ |
| | | { |
| | | "id": 1, |
| | | "itemCode": "M001", |
| | | "itemName": "颿¿", |
| | | "quantity": 100.00, |
| | | "frozenQuantity": 10.00, |
| | | "reservedQuantity": 20.00, |
| | | "inTransitQuantity": 5.00, |
| | | "availableQuantity": 70.00 |
| | | } |
| | | ], |
| | | "total": 1 |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | ## å端å®ç°è¦ç¹ |
| | | |
| | | ### 1. æ°æ®è·åæ¶æº |
| | | |
| | | - 页颿弿¶è°ç¨åºåå°è´¦æ¥è¯¢æ¥å£ï¼ååºä¸å·²å
嫿°å¢å段 |
| | | - æ éé¢å¤æ¥å£è°ç¨ |
| | | |
| | | ### 2. åæ®µå±ç¤ºè§å |
| | | |
| | | | åæ®µ | å±ç¤ºä½ç½® | 说æ | |
| | | |------|----------|------| |
| | | | å¨åºæ°é | å表ã详æ
| ç°æåæ®µï¼ä¿æä¸å | |
| | | | å»ç»æ°é | å表ã详æ
| æ°å¢å段ï¼å¯è½ä¸º null æ¶æ¾ç¤º 0 | |
| | | | å ç¨é | å表ã详æ
| æ°å¢å段ï¼å¯è½ä¸º null æ¶æ¾ç¤º 0 | |
| | | | å¨éé | å表ã详æ
| æ°å¢å段ï¼å¯è½ä¸º null æ¶æ¾ç¤º 0 | |
| | | | å¯ç¨é | å表ã详æ
| å端已计ç®ï¼ç´æ¥å±ç¤ºï¼ä¸ºè´æ°æ¶å»ºè®®é«äº®æç¤º | |
| | | |
| | | ### 3. ç¨æ·å¯ç¼è¾å段 |
| | | |
| | | æ æ°å¢å¯ç¼è¾åæ®µï¼æ¬æ¬¡ä»
为å±ç¤ºç±»å段æ©å±ã |
| | | |
| | | ## ä¸å¡è§å说æ |
| | | |
| | | ### 1. ååæ®µå«ä¹ |
| | | |
| | | | åæ®µ | å«ä¹ | |
| | | |------|------| |
| | | | å¨åºæ°é | ä»åºä¸å®é
åå¨çåºå | |
| | | | å»ç»æ°é | å çç¹ãè´¨æ£çåå 被å»ç»çåºå | |
| | | | å ç¨é | å·²åé
å¾
åºåºçæ°éï¼æ£è´§åæªåºåºï¼ | |
| | | | å¨éé | è°æ¨å¨éï¼æºä»åºå·²åºåºï¼ç®æ ä»åºæªå
¥åºï¼ | |
| | | | å¯ç¨é | å®é
å¯ç¨äºåé
çåºå | |
| | | |
| | | ### 2. å ç¨é产çä¸éæ¾åºæ¯ |
| | | |
| | | | åºæ¯ | æ¶æº | å½±å | |
| | | |------|------|------| |
| | | | éå®åºåºæ£è´§ | æ£è´§æä½æ¶ | å ç¨éå¢å ï¼å¯ç¨éåå° | |
| | | | çäº§é¢ææ£è´§ | æ£è´§æä½æ¶ | å ç¨éå¢å ï¼å¯ç¨éåå° | |
| | | | åºåºå®æ | æ§è¡åºåºæ¶ | å ç¨éåå°ï¼å¨åºæ°éåå° | |
| | | | 忮忶 | åæ¶åºåºåæ¶ | å ç¨ééæ¾ï¼å¯ç¨éæ¢å¤ | |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | - æ°å¢å段å¨å岿°æ®ä¸å¯è½ä¸º nullï¼å端å±ç¤ºæ¶éå空å¼å¤çï¼é»è®¤æ¾ç¤º 0 |
| | | - å¯ç¨éç±å端计ç®ï¼åç«¯ç´æ¥ä½¿ç¨ï¼æ éèªè¡è®¡ç® |
| | | - å¯¼åº Excel å·²å
嫿°åæ®µï¼æ éé¢å¤å¤ç |
| | |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- CRM 客æ·ç®¡ç API --> |
| | | <dependency> |
| | | <groupId>cn.iocoder.boot</groupId> |
| | | <artifactId>yudao-module-crm-api</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- BPM 工使µ API --> |
| | | <dependency> |
| | | <groupId>cn.iocoder.boot</groupId> |
| | |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.io.IOException; |
| | | import java.math.BigDecimal; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | |
| | | area -> vo.setAreaName(area.getName())); |
| | | MapUtils.findAndThen(vendorMap, vo.getVendorId(), |
| | | vendor -> vo.setVendorName(vendor.getName())); |
| | | // 计ç®å¯ç¨é = å¨åºæ°é - å»ç»æ°é - å ç¨é |
| | | BigDecimal quantity = vo.getQuantity() != null ? vo.getQuantity() : BigDecimal.ZERO; |
| | | BigDecimal frozenQty = vo.getFrozenQuantity() != null ? vo.getFrozenQuantity() : BigDecimal.ZERO; |
| | | BigDecimal reservedQty = vo.getReservedQuantity() != null ? vo.getReservedQuantity() : BigDecimal.ZERO; |
| | | vo.setAvailableQuantity(quantity.subtract(frozenQty).subtract(reservedQty)); |
| | | }); |
| | | } |
| | | |
| | |
| | | @ExcelProperty("å¨åºæ°é") |
| | | private BigDecimal quantity; |
| | | |
| | | @Schema(description = "å»ç»æ°é", example = "10.0000") |
| | | @ExcelProperty("å»ç»æ°é") |
| | | private BigDecimal frozenQuantity; |
| | | |
| | | @Schema(description = "å ç¨éï¼å·²åé
å¾
åºåºï¼", example = "20.0000") |
| | | @ExcelProperty("å ç¨é") |
| | | private BigDecimal reservedQuantity; |
| | | |
| | | @Schema(description = "å¨ééï¼è°æ¨å¨éï¼", example = "5.0000") |
| | | @ExcelProperty("å¨éé") |
| | | private BigDecimal inTransitQuantity; |
| | | |
| | | @Schema(description = "å¯ç¨éï¼å¨åºæ°é - å»ç»æ°é - å ç¨éï¼", example = "70.0000") |
| | | @ExcelProperty("å¯ç¨é") |
| | | private BigDecimal availableQuantity; |
| | | |
| | | @Schema(description = "å
¥åºæ¶é´") |
| | | @ExcelProperty("å
¥åºæ¶é´") |
| | | private LocalDateTime receiptTime; |
| | |
| | | import cn.iocoder.yudao.framework.common.util.collection.MapUtils; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; |
| | | import cn.iocoder.yudao.module.crm.api.customer.CrmCustomerApi; |
| | | import cn.iocoder.yudao.module.crm.api.customer.dto.CrmCustomerRespDTO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.MesWmProductSalesPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.MesWmProductSalesRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.MesWmProductSalesSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.MesWmProductSalesShippingReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.md.client.MesMdClientDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.salesnotice.MesWmSalesNoticeDO; |
| | | import cn.iocoder.yudao.module.mes.service.md.client.MesMdClientService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.productsales.MesWmProductSalesService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.salesnotice.MesWmSalesNoticeService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | |
| | | @Resource |
| | | private MesWmProductSalesService productSalesService; |
| | | @Resource |
| | | private MesMdClientService clientService; |
| | | private CrmCustomerApi crmCustomerApi; |
| | | @Resource |
| | | private MesWmSalesNoticeService salesNoticeService; |
| | | |
| | |
| | | return Collections.emptyList(); |
| | | } |
| | | // 1. è·å¾å
³èæ°æ® |
| | | Map<Long, MesMdClientDO> clientMap = clientService.getClientMap( |
| | | Map<Long, CrmCustomerRespDTO> customerMap = crmCustomerApi.getCustomerMap( |
| | | convertSet(list, MesWmProductSalesDO::getClientId)); |
| | | Map<Long, MesWmSalesNoticeDO> noticeMap = salesNoticeService.getSalesNoticeMap( |
| | | convertSet(list, MesWmProductSalesDO::getNoticeId)); |
| | | // 2. æå»ºç»æ |
| | | return BeanUtils.toBean(list, MesWmProductSalesRespVO.class, vo -> { |
| | | MapUtils.findAndThen(clientMap, vo.getClientId(), client -> |
| | | vo.setClientName(client.getName()).setClientCode(client.getCode())); |
| | | MapUtils.findAndThen(customerMap, vo.getClientId(), customer -> |
| | | vo.setClientName(customer.getName())); |
| | | MapUtils.findAndThen(noticeMap, vo.getNoticeId(), |
| | | notice -> vo.setNoticeCode(notice.getCode())); |
| | | }); |
| | | } |
| | | |
| | | } |
| | | } |
| | |
| | | @ExcelProperty("åè´§éç¥åç¼å·") |
| | | private String noticeCode; |
| | | |
| | | @Schema(description = "客æ·ç¼ç ", example = "C001") |
| | | @ExcelProperty("客æ·ç¼ç ") |
| | | private String clientCode; |
| | | |
| | | @Schema(description = "æ¶è´§äºº", example = "å¼ ä¸") |
| | | @ExcelProperty("æ¶è´§äºº") |
| | | private String contactName; |
| | |
| | | @ExcelProperty("å建æ¶é´") |
| | | private LocalDateTime createTime; |
| | | |
| | | } |
| | | } |
| | |
| | | import cn.iocoder.yudao.framework.common.util.collection.MapUtils; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; |
| | | import cn.iocoder.yudao.module.crm.api.customer.CrmCustomerApi; |
| | | import cn.iocoder.yudao.module.crm.api.customer.dto.CrmCustomerRespDTO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.returnsales.vo.MesWmReturnSalesPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.returnsales.vo.MesWmReturnSalesRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.returnsales.vo.MesWmReturnSalesSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.md.client.MesMdClientDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnsales.MesWmReturnSalesDO; |
| | | import cn.iocoder.yudao.module.mes.service.md.client.MesMdClientService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.returnsales.MesWmReturnSalesService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | |
| | | @Resource |
| | | private MesWmReturnSalesService returnSalesService; |
| | | @Resource |
| | | private MesMdClientService clientService; |
| | | private CrmCustomerApi crmCustomerApi; |
| | | |
| | | @PostMapping("/create") |
| | | @Operation(summary = "å建éå®éè´§å") |
| | |
| | | return Collections.emptyList(); |
| | | } |
| | | // 1. è·å¾å
³èæ°æ® |
| | | Map<Long, MesMdClientDO> clientMap = clientService.getClientMap( |
| | | Map<Long, CrmCustomerRespDTO> customerMap = crmCustomerApi.getCustomerMap( |
| | | convertSet(list, MesWmReturnSalesDO::getClientId)); |
| | | // 2. æå»ºç»æ |
| | | return BeanUtils.toBean(list, MesWmReturnSalesRespVO.class, vo -> |
| | | MapUtils.findAndThen(clientMap, vo.getClientId(), client -> |
| | | vo.setClientCode(client.getCode()).setClientName(client.getName()).setClientNickname(client.getNickname()))); |
| | | MapUtils.findAndThen(customerMap, vo.getClientId(), customer -> |
| | | vo.setClientName(customer.getName()))); |
| | | } |
| | | |
| | | } |
| | | } |
| | |
| | | @Schema(description = "å®¢æ· ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | private Long clientId; |
| | | |
| | | @Schema(description = "客æ·ç¼ç ", example = "C001") |
| | | private String clientCode; |
| | | |
| | | @Schema(description = "客æ·åç§°", example = "XX客æ·") |
| | | private String clientName; |
| | | |
| | | @Schema(description = "客æ·ç®ç§°", example = "XX") |
| | | private String clientNickname; |
| | | |
| | | @Schema(description = "éè´§æ¥æ") |
| | | private LocalDateTime returnDate; |
| | |
| | | @Schema(description = "å建æ¶é´", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | private LocalDateTime createTime; |
| | | |
| | | } |
| | | } |
| | |
| | | import cn.iocoder.yudao.framework.common.util.collection.MapUtils; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; |
| | | import cn.iocoder.yudao.module.crm.api.customer.CrmCustomerApi; |
| | | import cn.iocoder.yudao.module.crm.api.customer.dto.CrmCustomerRespDTO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.salesnotice.vo.MesWmSalesNoticePageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.salesnotice.vo.MesWmSalesNoticeRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.salesnotice.vo.MesWmSalesNoticeSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.md.client.MesMdClientDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.salesnotice.MesWmSalesNoticeDO; |
| | | import cn.iocoder.yudao.module.mes.service.md.client.MesMdClientService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.salesnotice.MesWmSalesNoticeService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | |
| | | @Resource |
| | | private MesWmSalesNoticeService salesNoticeService; |
| | | @Resource |
| | | private MesMdClientService clientService; |
| | | private CrmCustomerApi crmCustomerApi; |
| | | |
| | | @PostMapping("/create") |
| | | @Operation(summary = "å建åè´§éç¥å") |
| | |
| | | return Collections.emptyList(); |
| | | } |
| | | // 1. è·å¾å
³èæ°æ® |
| | | Map<Long, MesMdClientDO> clientMap = clientService.getClientMap( |
| | | Map<Long, CrmCustomerRespDTO> customerMap = crmCustomerApi.getCustomerMap( |
| | | convertSet(list, MesWmSalesNoticeDO::getClientId)); |
| | | // 2. æå»ºç»æ |
| | | return BeanUtils.toBean(list, MesWmSalesNoticeRespVO.class, vo -> { |
| | | MapUtils.findAndThen(clientMap, vo.getClientId(), client -> |
| | | vo.setClientCode(client.getCode()).setClientName(client.getName())); |
| | | MapUtils.findAndThen(customerMap, vo.getClientId(), customer -> |
| | | vo.setClientName(customer.getName())); |
| | | }); |
| | | } |
| | | |
| | | } |
| | | } |
| | |
| | | @Schema(description = "客æ·ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | private Long clientId; |
| | | |
| | | @Schema(description = "客æ·ç¼ç ", example = "C001") |
| | | @ExcelProperty("客æ·ç¼ç ") |
| | | private String clientCode; |
| | | |
| | | @Schema(description = "客æ·åç§°", example = "æå®¢æ·") |
| | | @ExcelProperty("客æ·åç§°") |
| | | private String clientName; |
| | |
| | | @ExcelProperty("å建æ¶é´") |
| | | private LocalDateTime createTime; |
| | | |
| | | } |
| | | } |
| | |
| | | */ |
| | | private BigDecimal quantity; |
| | | /** |
| | | * å»ç»æ°éï¼çç¹ãè´¨æ£çå»ç»ï¼ |
| | | */ |
| | | private BigDecimal frozenQuantity; |
| | | /** |
| | | * å ç¨éï¼å·²åé
å¾
åºåºï¼ |
| | | */ |
| | | private BigDecimal reservedQuantity; |
| | | /** |
| | | * å¨ééï¼è°æ¨å¨éï¼ |
| | | */ |
| | | private BigDecimal inTransitQuantity; |
| | | /** |
| | | * å
¥åºæ¶é´ |
| | | */ |
| | | private LocalDateTime receiptTime; |
| | |
| | | /** |
| | | * 客æ·ID |
| | | * |
| | | * å
³è {@link MesMdClientDO#getId()} |
| | | * å
³è CRM å®¢æ· {@link cn.iocoder.yudao.module.crm.api.customer.dto.CrmCustomerRespDTO#getId()} |
| | | */ |
| | | private Long clientId; |
| | | /** |
| | |
| | | package cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnsales; |
| | | |
| | | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.md.client.MesMdClientDO; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmReturnSalesStatusEnum; |
| | | import com.baomidou.mybatisplus.annotation.KeySequence; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | |
| | | /** |
| | | * å®¢æ· ID |
| | | * |
| | | * å
³è {@link MesMdClientDO#getId()} |
| | | * å
³è CRM å®¢æ· {@link cn.iocoder.yudao.module.crm.api.customer.dto.CrmCustomerRespDTO#getId()} |
| | | */ |
| | | private Long clientId; |
| | | /** |
| | |
| | | /** |
| | | * 客æ·ç¼å· |
| | | * |
| | | * å
³è {@link MesMdClientDO#getId()} |
| | | * å
³è CRM å®¢æ· {@link cn.iocoder.yudao.module.crm.api.customer.dto.CrmCustomerRespDTO#getId()} |
| | | */ |
| | | private Long clientId; |
| | | /** |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.dal.dataobject.wm.stockreserve; |
| | | |
| | | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmStockReserveBizTypeEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmStockReserveStatusEnum; |
| | | import com.baomidou.mybatisplus.annotation.KeySequence; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.*; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | /** |
| | | * MES åºåå ç¨è®°å½ DO |
| | | */ |
| | | @TableName("mes_wm_stock_reserve") |
| | | @KeySequence("mes_wm_stock_reserve_seq") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | @Builder |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public class MesWmStockReserveDO extends BaseDO { |
| | | |
| | | /** |
| | | * ç¼å· |
| | | */ |
| | | @TableId |
| | | private Long id; |
| | | |
| | | /** |
| | | * åºåè®°å½ID |
| | | * |
| | | * å
³è {@link cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO#getId()} |
| | | */ |
| | | private Long materialStockId; |
| | | |
| | | /** |
| | | * ä¸å¡ç±»å |
| | | * |
| | | * æä¸¾ {@link MesWmStockReserveBizTypeEnum} |
| | | */ |
| | | private Integer bizType; |
| | | |
| | | /** |
| | | * ä¸å¡åæ®ID |
| | | */ |
| | | private Long bizId; |
| | | |
| | | /** |
| | | * ä¸å¡åå· |
| | | */ |
| | | private String bizCode; |
| | | |
| | | /** |
| | | * ä¸å¡åæ®è¡ID |
| | | */ |
| | | private Long bizLineId; |
| | | |
| | | /** |
| | | * ç©æID |
| | | */ |
| | | private Long itemId; |
| | | |
| | | /** |
| | | * å ç¨æ°é |
| | | */ |
| | | private BigDecimal quantity; |
| | | |
| | | /** |
| | | * ç¶æ |
| | | * |
| | | * æä¸¾ {@link MesWmStockReserveStatusEnum} |
| | | */ |
| | | private Integer status; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | |
| | | } |
| | |
| | | } |
| | | |
| | | /** |
| | | * å¢éæ´æ°åºåå ç¨é |
| | | * |
| | | * @param id åºåè®°å½ç¼å· |
| | | * @param count å卿°éï¼æ£æ°=å¢å å ç¨ï¼è´æ°=åå°å ç¨ï¼ |
| | | * @param checkFlag æ¯å¦æ ¡éªå¯ç¨éå
è¶³ï¼ä¸º true æ¶å ç¨ä¸å
许è¶
è¿å¯ç¨éï¼ |
| | | * @return å½±åè¡æ° |
| | | */ |
| | | default int updateReservedQuantity(Long id, BigDecimal count, boolean checkFlag) { |
| | | LambdaUpdateWrapper<MesWmMaterialStockDO> updateWrapper = new LambdaUpdateWrapper<MesWmMaterialStockDO>() |
| | | .eq(MesWmMaterialStockDO::getId, id) |
| | | .setSql("reserved_quantity = reserved_quantity + " + count); |
| | | if (checkFlag && count.compareTo(BigDecimal.ZERO) > 0) { |
| | | // æ ¡éªå¯ç¨éå
è¶³ï¼quantity - frozen_quantity - reserved_quantity >= count |
| | | updateWrapper.setSql("reserved_quantity = reserved_quantity + " + count + |
| | | " WHERE quantity - IFNULL(frozen_quantity, 0) - IFNULL(reserved_quantity, 0) >= " + count); |
| | | } |
| | | return update(null, updateWrapper); |
| | | } |
| | | |
| | | /** |
| | | * å¢éæ´æ°åºåå¨éé |
| | | * |
| | | * @param id åºåè®°å½ç¼å· |
| | | * @param count å卿°éï¼æ£æ°=å¢å å¨éï¼è´æ°=åå°å¨éï¼ |
| | | * @return å½±åè¡æ° |
| | | */ |
| | | default int updateInTransitQuantity(Long id, BigDecimal count) { |
| | | LambdaUpdateWrapper<MesWmMaterialStockDO> updateWrapper = new LambdaUpdateWrapper<MesWmMaterialStockDO>() |
| | | .eq(MesWmMaterialStockDO::getId, id) |
| | | .setSql("in_transit_quantity = in_transit_quantity + " + count); |
| | | return update(null, updateWrapper); |
| | | } |
| | | |
| | | /** |
| | | * æç»å鮿¥è¯¢åºåè®°å½ |
| | | * |
| | | * å¯ä¸é®ï¼(itemId, warehouseId, locationId, areaId, batchId, vendorId) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.dal.mysql.wm.stockreserve; |
| | | |
| | | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stockreserve.MesWmStockReserveDO; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmStockReserveStatusEnum; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | import org.apache.ibatis.annotations.Param; |
| | | import org.apache.ibatis.annotations.Select; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * MES åºåå ç¨è®°å½ Mapper |
| | | */ |
| | | @Mapper |
| | | public interface MesWmStockReserveMapper extends BaseMapperX<MesWmStockReserveDO> { |
| | | |
| | | /** |
| | | * æ¥è¯¢æå®ä¸å¡åæ®çå ç¨è®°å½ |
| | | */ |
| | | default List<MesWmStockReserveDO> selectListByBiz(Integer bizType, Long bizId) { |
| | | return selectList(new LambdaQueryWrapperX<MesWmStockReserveDO>() |
| | | .eq(MesWmStockReserveDO::getBizType, bizType) |
| | | .eq(MesWmStockReserveDO::getBizId, bizId)); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢æå®ä¸å¡åæ®çå ç¨ä¸è®°å½ |
| | | */ |
| | | default List<MesWmStockReserveDO> selectReservingListByBiz(Integer bizType, Long bizId) { |
| | | return selectList(new LambdaQueryWrapperX<MesWmStockReserveDO>() |
| | | .eq(MesWmStockReserveDO::getBizType, bizType) |
| | | .eq(MesWmStockReserveDO::getBizId, bizId) |
| | | .eq(MesWmStockReserveDO::getStatus, MesWmStockReserveStatusEnum.RESERVING.getStatus())); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢æå®åºåè®°å½çå ç¨ä¸è®°å½ |
| | | */ |
| | | default List<MesWmStockReserveDO> selectReservingListByMaterialStockId(Long materialStockId) { |
| | | return selectList(new LambdaQueryWrapperX<MesWmStockReserveDO>() |
| | | .eq(MesWmStockReserveDO::getMaterialStockId, materialStockId) |
| | | .eq(MesWmStockReserveDO::getStatus, MesWmStockReserveStatusEnum.RESERVING.getStatus())); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢æå®ç©æå¨æå®ä»åºçå ç¨æ°éæ±æ» |
| | | */ |
| | | @Select("SELECT IFNULL(SUM(sr.quantity), 0) FROM mes_wm_stock_reserve sr " + |
| | | "INNER JOIN mes_wm_material_stock ms ON sr.material_stock_id = ms.id " + |
| | | "WHERE sr.deleted = 0 AND sr.status = 1 AND ms.deleted = 0 " + |
| | | "AND sr.item_id = #{itemId} AND ms.warehouse_id = #{warehouseId}") |
| | | BigDecimal sumReservedQuantityByItemAndWarehouse(@Param("itemId") Long itemId, @Param("warehouseId") Long warehouseId); |
| | | |
| | | /** |
| | | * æ¥è¯¢æå®ç©æçå ç¨æ°éæ±æ» |
| | | */ |
| | | @Select("SELECT IFNULL(SUM(quantity), 0) FROM mes_wm_stock_reserve " + |
| | | "WHERE deleted = 0 AND status = 1 AND item_id = #{itemId}") |
| | | BigDecimal sumReservedQuantityByItem(@Param("itemId") Long itemId); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.enums.wm; |
| | | |
| | | import cn.iocoder.yudao.framework.common.core.ArrayValuable; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | import java.util.Arrays; |
| | | |
| | | /** |
| | | * MES åºåå ç¨ä¸å¡ç±»åæä¸¾ |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum MesWmStockReserveBizTypeEnum implements ArrayValuable<Integer> { |
| | | |
| | | PRODUCT_SALES(1, "éå®åºåº"), |
| | | PRODUCT_ISSUE(2, "çäº§é¢æ"), |
| | | OUTSOURCE_ISSUE(3, "å¤ååæ"), |
| | | MISC_ISSUE(4, "æé¡¹åºåº"), |
| | | TRANSFER(5, "è½¬ç§»è°æ¨"); |
| | | |
| | | public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmStockReserveBizTypeEnum::getType).toArray(Integer[]::new); |
| | | |
| | | /** |
| | | * ç±»åå¼ |
| | | */ |
| | | private final Integer type; |
| | | /** |
| | | * ç±»åå |
| | | */ |
| | | private final String name; |
| | | |
| | | @Override |
| | | public Integer[] array() { |
| | | return ARRAYS; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.enums.wm; |
| | | |
| | | import cn.iocoder.yudao.framework.common.core.ArrayValuable; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | import java.util.Arrays; |
| | | |
| | | /** |
| | | * MES åºåå ç¨ç¶ææä¸¾ |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum MesWmStockReserveStatusEnum implements ArrayValuable<Integer> { |
| | | |
| | | RESERVING(1, "å ç¨ä¸"), |
| | | RELEASED(2, "已鿾"), |
| | | OUTBOUND(3, "å·²åºåº"); |
| | | |
| | | public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmStockReserveStatusEnum::getStatus).toArray(Integer[]::new); |
| | | |
| | | /** |
| | | * ç¶æå¼ |
| | | */ |
| | | private final Integer status; |
| | | /** |
| | | * ç¶æå |
| | | */ |
| | | private final String name; |
| | | |
| | | @Override |
| | | public Integer[] array() { |
| | | return ARRAYS; |
| | | } |
| | | |
| | | } |
| | |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.wm.productissue.MesWmProductIssueMapper; |
| | | import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmProductIssueStatusEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmStockReserveBizTypeEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum; |
| | | import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService; |
| | | import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.stockreserve.MesWmStockReserveService; |
| | | 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; |
| | |
| | | private MesWmWarehouseLocationService locationService; |
| | | @Resource |
| | | private MesWmWarehouseAreaService areaService; |
| | | @Resource |
| | | private MesWmStockReserveService stockReserveService; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | |
| | | throw exception(WM_PRODUCT_ISSUE_DETAIL_QUANTITY_MISMATCH); |
| | | } |
| | | |
| | | // å建åºåå ç¨ï¼ææç»å ç¨åºåï¼ |
| | | List<MesWmProductIssueDetailDO> details = issueDetailService.getProductIssueDetailListByIssueId(id); |
| | | for (MesWmProductIssueDetailDO detail : details) { |
| | | if (detail.getMaterialStockId() != null && detail.getQuantity() != null) { |
| | | stockReserveService.createReserve( |
| | | detail.getMaterialStockId(), |
| | | MesWmStockReserveBizTypeEnum.PRODUCT_ISSUE.getType(), |
| | | id, |
| | | issue.getCode(), |
| | | detail.getId(), |
| | | detail.getItemId(), |
| | | detail.getQuantity() |
| | | ); |
| | | } |
| | | } |
| | | |
| | | // æ§è¡æ£è´§ï¼å¾
æ£è´§ â å¾
æ§è¡é¢åºï¼ |
| | | issueMapper.updateById(new MesWmProductIssueDO() |
| | | .setId(id).setStatus(MesWmProductIssueStatusEnum.APPROVED.getStatus())); |
| | |
| | | throw exception(WM_PRODUCT_ISSUE_DETAIL_QUANTITY_MISMATCH); |
| | | } |
| | | |
| | | // 2. éåæææç»ï¼å建åºåäºå¡ï¼æ£ååºå + è®°å½æµæ°´ï¼ |
| | | // 2. 确认å ç¨è½¬åºåºï¼éæ¾å ç¨éï¼ |
| | | stockReserveService.confirmReserveToOutbound(MesWmStockReserveBizTypeEnum.PRODUCT_ISSUE.getType(), id); |
| | | |
| | | // 3. éåæææç»ï¼å建åºåäºå¡ï¼æ£ååºå + è®°å½æµæ°´ï¼ |
| | | createTransactionList(issue); |
| | | |
| | | // 3. æ´æ°åºåºåç¶æ + é¢ææ¥æ |
| | | // 4. æ´æ°åºåºåç¶æ + é¢ææ¥æ |
| | | issueMapper.updateById(new MesWmProductIssueDO() |
| | | .setId(id).setStatus(MesWmProductIssueStatusEnum.FINISHED.getStatus()) |
| | | .setIssueDate(LocalDateTime.now())); |
| | |
| | | throw exception(WM_PRODUCT_ISSUE_CANCEL_NOT_ALLOWED); |
| | | } |
| | | |
| | | // éæ¾åºåå ç¨ |
| | | stockReserveService.releaseReserve(MesWmStockReserveBizTypeEnum.PRODUCT_ISSUE.getType(), id); |
| | | |
| | | // åæ¶ |
| | | issueMapper.updateById(new MesWmProductIssueDO() |
| | | .setId(id).setStatus(MesWmProductIssueStatusEnum.CANCELED.getStatus())); |
| | |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmProductSalesStatusEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmSalesNoticeStatusEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmStockReserveBizTypeEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum; |
| | | import cn.iocoder.yudao.module.mes.service.md.client.MesMdClientService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.salesnotice.MesWmSalesNoticeService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.stockreserve.MesWmStockReserveService; |
| | | 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.erp.api.sale.ErpSaleOrderApi; |
| | |
| | | private MesWmTransactionService wmTransactionService; |
| | | @Resource |
| | | private MesWmMaterialStockService materialStockService; |
| | | @Resource |
| | | private MesWmStockReserveService stockReserveService; |
| | | |
| | | @Resource |
| | | private ErpSaleOrderApi saleOrderApi; |
| | |
| | | if (CollUtil.isEmpty(details)) { |
| | | throw exception(WM_PRODUCT_SALES_DETAILS_EMPTY); |
| | | } |
| | | // æ ¡éªåºåå
è¶³ |
| | | // æ ¡éªåºåå
足并å建å ç¨ |
| | | for (MesWmProductSalesDetailDO detail : details) { |
| | | materialStockService.validateSelectedStock( |
| | | detail.getMaterialStockId(), |
| | |
| | | detail.getWarehouseId(), |
| | | detail.getLocationId(), |
| | | detail.getAreaId(), |
| | | detail.getQuantity() |
| | | ); |
| | | // å建åºåå ç¨ |
| | | stockReserveService.createReserve( |
| | | detail.getMaterialStockId(), |
| | | MesWmStockReserveBizTypeEnum.PRODUCT_SALES.getType(), |
| | | id, |
| | | sales.getCode(), |
| | | detail.getId(), |
| | | detail.getItemId(), |
| | | detail.getQuantity() |
| | | ); |
| | | } |
| | |
| | | throw exception(WM_PRODUCT_SALES_CANNOT_FINISH); |
| | | } |
| | | |
| | | // 2. éåæææç»ï¼å建åºåäºå¡ï¼æ£ååºå + è®°å½æµæ°´ï¼ |
| | | // 2. 确认å ç¨è½¬åºåºï¼éæ¾å ç¨éï¼ |
| | | stockReserveService.confirmReserveToOutbound(MesWmStockReserveBizTypeEnum.PRODUCT_SALES.getType(), id); |
| | | |
| | | // 3. éåæææç»ï¼å建åºåäºå¡ï¼æ£ååºå + è®°å½æµæ°´ï¼ |
| | | createTransactionList(sales); |
| | | |
| | | // 3. æ´æ°åºåºåç¶æ |
| | | // 4. æ´æ°åºåºåç¶æ |
| | | productSalesMapper.updateById(new MesWmProductSalesDO() |
| | | .setId(id).setStatus(MesWmProductSalesStatusEnum.FINISHED.getStatus())); |
| | | |
| | | // 4. æ´æ°å
³èçåè´§éç¥åç¶æ |
| | | // 5. æ´æ°å
³èçåè´§éç¥åç¶æ |
| | | if (sales.getNoticeId() != null) { |
| | | salesNoticeService.finishSalesNotice(sales.getNoticeId()); |
| | | } |
| | | |
| | | // 5. åå ERP éå®è®¢åçåºåºæ°éåç¶æ |
| | | // 6. åå ERP éå®è®¢åçåºåºæ°éåç¶æ |
| | | updateErpSaleOrderOutCount(sales); |
| | | } |
| | | |
| | |
| | | MesWmProductSalesStatusEnum.CANCELED.getStatus())) { |
| | | throw exception(WM_PRODUCT_SALES_CANNOT_CANCEL); |
| | | } |
| | | // éæ¾åºåå ç¨ |
| | | stockReserveService.releaseReserve(MesWmStockReserveBizTypeEnum.PRODUCT_SALES.getType(), id); |
| | | // åæ¶ |
| | | productSalesMapper.updateById(new MesWmProductSalesDO() |
| | | .setId(id).setStatus(MesWmProductSalesStatusEnum.CANCELED.getStatus())); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.service.wm.stockreserve; |
| | | |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stockreserve.MesWmStockReserveDO; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * MES åºåå ç¨ Service æ¥å£ |
| | | */ |
| | | public interface MesWmStockReserveService { |
| | | |
| | | /** |
| | | * å建åºåå ç¨ |
| | | * |
| | | * @param materialStockId åºåè®°å½ID |
| | | * @param bizType ä¸å¡ç±»å |
| | | * @param bizId ä¸å¡åæ®ID |
| | | * @param bizCode ä¸å¡åå· |
| | | * @param bizLineId ä¸å¡åæ®è¡ID |
| | | * @param itemId ç©æID |
| | | * @param quantity å ç¨æ°é |
| | | */ |
| | | void createReserve(Long materialStockId, Integer bizType, Long bizId, String bizCode, Long bizLineId, Long itemId, BigDecimal quantity); |
| | | |
| | | /** |
| | | * æ¹éå建åºåå ç¨ |
| | | * |
| | | * @param reserves å ç¨ä¿¡æ¯å表 |
| | | */ |
| | | void createReserveBatch(List<ReserveInfo> reserves); |
| | | |
| | | /** |
| | | * éæ¾åºåå ç¨ï¼åæ¶åæ®æ¶ï¼ |
| | | * |
| | | * @param bizType ä¸å¡ç±»å |
| | | * @param bizId ä¸å¡åæ®ID |
| | | */ |
| | | void releaseReserve(Integer bizType, Long bizId); |
| | | |
| | | /** |
| | | * 确认å ç¨è½¬åºåºï¼æ§è¡åºåºæ¶ï¼ |
| | | * æ´æ°å ç¨è®°å½ç¶æä¸ºå·²åºåºï¼å¹¶æ£ååºåå ç¨éåæ®µ |
| | | * |
| | | * @param bizType ä¸å¡ç±»å |
| | | * @param bizId ä¸å¡åæ®ID |
| | | */ |
| | | void confirmReserveToOutbound(Integer bizType, Long bizId); |
| | | |
| | | /** |
| | | * æ¥è¯¢æå®ä¸å¡åæ®çå ç¨è®°å½ |
| | | * |
| | | * @param bizType ä¸å¡ç±»å |
| | | * @param bizId ä¸å¡åæ®ID |
| | | * @return å ç¨è®°å½å表 |
| | | */ |
| | | List<MesWmStockReserveDO> getReserveListByBiz(Integer bizType, Long bizId); |
| | | |
| | | /** |
| | | * æ¥è¯¢æå®ç©æçå ç¨æ°éæ±æ» |
| | | * |
| | | * @param itemId ç©æID |
| | | * @param warehouseId ä»åºIDï¼å¯éï¼ |
| | | * @return å ç¨æ°é |
| | | */ |
| | | BigDecimal sumReservedQuantity(Long itemId, Long warehouseId); |
| | | |
| | | /** |
| | | * å ç¨ä¿¡æ¯ |
| | | */ |
| | | record ReserveInfo(Long materialStockId, Integer bizType, Long bizId, String bizCode, Long bizLineId, Long itemId, BigDecimal quantity) {} |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.service.wm.stockreserve; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stockreserve.MesWmStockReserveDO; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.wm.materialstock.MesWmMaterialStockMapper; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.wm.stockreserve.MesWmStockReserveMapper; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmStockReserveStatusEnum; |
| | | import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService; |
| | | import jakarta.annotation.Resource; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.List; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; |
| | | |
| | | /** |
| | | * MES åºåå ç¨ Service å®ç°ç±» |
| | | */ |
| | | @Service |
| | | @Validated |
| | | @Slf4j |
| | | public class MesWmStockReserveServiceImpl implements MesWmStockReserveService { |
| | | |
| | | @Resource |
| | | private MesWmStockReserveMapper stockReserveMapper; |
| | | |
| | | @Resource |
| | | private MesWmMaterialStockMapper materialStockMapper; |
| | | |
| | | @Resource |
| | | private MesWmMaterialStockService materialStockService; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void createReserve(Long materialStockId, Integer bizType, Long bizId, String bizCode, Long bizLineId, Long itemId, BigDecimal quantity) { |
| | | // 1. æ ¡éªåºåè®°å½åå¨ |
| | | MesWmMaterialStockDO stock = materialStockService.getMaterialStock(materialStockId); |
| | | if (stock == null) { |
| | | throw exception(WM_MATERIAL_STOCK_NOT_EXISTS); |
| | | } |
| | | |
| | | // 2. æ ¡éªå¯ç¨éå
è¶³ï¼å¨åºæ°é - å»ç»æ°é - å·²å ç¨é >= æ¬æ¬¡å ç¨æ°éï¼ |
| | | BigDecimal availableQty = stock.getQuantity() |
| | | .subtract(stock.getFrozenQuantity() != null ? stock.getFrozenQuantity() : BigDecimal.ZERO) |
| | | .subtract(stock.getReservedQuantity() != null ? stock.getReservedQuantity() : BigDecimal.ZERO); |
| | | if (availableQty.compareTo(quantity) < 0) { |
| | | throw exception(WM_MATERIAL_STOCK_INSUFFICIENT); |
| | | } |
| | | |
| | | // 3. å建å ç¨è®°å½ |
| | | MesWmStockReserveDO reserve = MesWmStockReserveDO.builder() |
| | | .materialStockId(materialStockId) |
| | | .bizType(bizType) |
| | | .bizId(bizId) |
| | | .bizCode(bizCode) |
| | | .bizLineId(bizLineId) |
| | | .itemId(itemId) |
| | | .quantity(quantity) |
| | | .status(MesWmStockReserveStatusEnum.RESERVING.getStatus()) |
| | | .build(); |
| | | stockReserveMapper.insert(reserve); |
| | | |
| | | // 4. æ´æ°åºåå ç¨éåæ®µï¼ç´¯å ï¼ |
| | | int updatedRows = materialStockMapper.updateReservedQuantity(materialStockId, quantity, true); |
| | | if (updatedRows == 0) { |
| | | throw exception(WM_MATERIAL_STOCK_INSUFFICIENT); |
| | | } |
| | | |
| | | log.info("[createReserve] å建åºåå ç¨æåï¼materialStockId={}, bizType={}, bizId={}, quantity={}", |
| | | materialStockId, bizType, bizId, quantity); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void createReserveBatch(List<ReserveInfo> reserves) { |
| | | if (CollUtil.isEmpty(reserves)) { |
| | | return; |
| | | } |
| | | for (ReserveInfo reserve : reserves) { |
| | | createReserve(reserve.materialStockId(), reserve.bizType(), reserve.bizId(), |
| | | reserve.bizCode(), reserve.bizLineId(), reserve.itemId(), reserve.quantity()); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void releaseReserve(Integer bizType, Long bizId) { |
| | | // 1. æ¥è¯¢å ç¨ä¸çè®°å½ |
| | | List<MesWmStockReserveDO> reserveList = stockReserveMapper.selectReservingListByBiz(bizType, bizId); |
| | | if (CollUtil.isEmpty(reserveList)) { |
| | | log.warn("[releaseReserve] æªæ¾å°å ç¨è®°å½ï¼bizType={}, bizId={}", bizType, bizId); |
| | | return; |
| | | } |
| | | |
| | | // 2. æ´æ°å ç¨è®°å½ç¶æä¸ºå·²éæ¾ï¼å¹¶æ£ååºåå ç¨éåæ®µ |
| | | for (MesWmStockReserveDO reserve : reserveList) { |
| | | // 2.1 æ´æ°å ç¨è®°å½ç¶æ |
| | | stockReserveMapper.updateById(new MesWmStockReserveDO() |
| | | .setId(reserve.getId()) |
| | | .setStatus(MesWmStockReserveStatusEnum.RELEASED.getStatus())); |
| | | |
| | | // 2.2 æ£ååºåå ç¨éï¼è´æ°è¡¨ç¤ºåå°ï¼ |
| | | materialStockMapper.updateReservedQuantity(reserve.getMaterialStockId(), reserve.getQuantity().negate(), false); |
| | | } |
| | | |
| | | log.info("[releaseReserve] éæ¾åºåå ç¨æåï¼bizType={}, bizId={}, count={}", bizType, bizId, reserveList.size()); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void confirmReserveToOutbound(Integer bizType, Long bizId) { |
| | | // 1. æ¥è¯¢å ç¨ä¸çè®°å½ |
| | | List<MesWmStockReserveDO> reserveList = stockReserveMapper.selectReservingListByBiz(bizType, bizId); |
| | | if (CollUtil.isEmpty(reserveList)) { |
| | | log.warn("[confirmReserveToOutbound] æªæ¾å°å ç¨è®°å½ï¼bizType={}, bizId={}", bizType, bizId); |
| | | return; |
| | | } |
| | | |
| | | // 2. æ´æ°å ç¨è®°å½ç¶æä¸ºå·²åºåºï¼å¹¶æ£ååºåå ç¨éåæ®µ |
| | | for (MesWmStockReserveDO reserve : reserveList) { |
| | | // 2.1 æ´æ°å ç¨è®°å½ç¶æ |
| | | stockReserveMapper.updateById(new MesWmStockReserveDO() |
| | | .setId(reserve.getId()) |
| | | .setStatus(MesWmStockReserveStatusEnum.OUTBOUND.getStatus())); |
| | | |
| | | // 2.2 æ£ååºåå ç¨éï¼è´æ°è¡¨ç¤ºåå°ï¼ |
| | | materialStockMapper.updateReservedQuantity(reserve.getMaterialStockId(), reserve.getQuantity().negate(), false); |
| | | } |
| | | |
| | | log.info("[confirmReserveToOutbound] 确认å ç¨è½¬åºåºæåï¼bizType={}, bizId={}, count={}", bizType, bizId, reserveList.size()); |
| | | } |
| | | |
| | | @Override |
| | | public List<MesWmStockReserveDO> getReserveListByBiz(Integer bizType, Long bizId) { |
| | | return stockReserveMapper.selectListByBiz(bizType, bizId); |
| | | } |
| | | |
| | | @Override |
| | | public BigDecimal sumReservedQuantity(Long itemId, Long warehouseId) { |
| | | if (warehouseId != null) { |
| | | return stockReserveMapper.sumReservedQuantityByItemAndWarehouse(itemId, warehouseId); |
| | | } |
| | | return stockReserveMapper.sumReservedQuantityByItem(itemId); |
| | | } |
| | | |
| | | } |