| | |
| | | -- å¨è´¢å¡ç®¡çä¸å¢å ç¬ç«å®¡æ ¸è稿å
¥å£ï¼è§è²æéå¨ç®æ ç³»ç»ä¸æ¾å¼åé
ã |
| | | SET @finance_parent := (SELECT id FROM system_menu WHERE path='finance' AND type=1 AND deleted=b'0' AND name='è´¢å¡ç®¡ç' LIMIT 1); |
| | | -- å
¥å£å½å
¥æ¢æå®å管çä¸çº§èåï¼ä¸æ°å¢æä¿®æ¹ä¸çº§èåã |
| | | -- ç´æ¥æ§è¡åéæç®æ ç¯å¢è¿ç»´æµç¨å·æ°ç¸å
³èååè§è²æéç¼åã |
| | | SET @finance_parent := (SELECT id FROM system_menu WHERE path='/aftersales' AND parent_id=0 AND type=1 AND deleted=b'0' LIMIT 1); |
| | | INSERT INTO system_menu (name,permission,type,sort,parent_id,path,icon,component,component_name,status,visible,keep_alive,always_show,creator,updater) |
| | | SELECT 'å®åè´¢å¡è稿','',2,30,@finance_parent,'after-sale-draft','lucide:file-check','erp/finance/after-sale-draft/index','ErpAfterSaleFinanceDraft',0,b'1',b'1',b'1','1','1' |
| | | WHERE @finance_parent IS NOT NULL AND NOT EXISTS(SELECT 1 FROM system_menu WHERE component='erp/finance/after-sale-draft/index' AND deleted=b'0'); |
| | | SET @finance_page := (SELECT id FROM system_menu WHERE component='erp/finance/after-sale-draft/index' AND deleted=b'0' LIMIT 1); |
| | | -- å
¼å®¹å
åå®è£
å° ERP è´¢å¡ç®¡çä¸ççæ¬ï¼ä»
ç§»å¨å·²ç¥çæ§å
¥å£ã |
| | | UPDATE system_menu SET parent_id=@finance_parent, path='after-sale-draft', updater='1', update_time=NOW() |
| | | WHERE id=@finance_page AND @finance_parent IS NOT NULL AND parent_id IN |
| | | (SELECT id FROM (SELECT f.id FROM system_menu f JOIN system_menu e ON f.parent_id=e.id |
| | | WHERE f.path='finance' AND e.path='/erp' AND e.parent_id=0 AND f.deleted=b'0' AND e.deleted=b'0') old_parent); |
| | | -- åæè稿使ç¨è§è²éè¦å®å管çç®å½æè½çå°å·²ææç页é¢ã |
| | | INSERT INTO system_role_menu (role_id,menu_id,creator,updater,tenant_id) |
| | | SELECT DISTINCT rm.role_id,@finance_parent,'1','1',rm.tenant_id |
| | | FROM system_role_menu rm |
| | | WHERE @finance_parent IS NOT NULL AND @finance_page IS NOT NULL AND rm.deleted=b'0' |
| | | AND rm.menu_id=@finance_page |
| | | AND NOT EXISTS (SELECT 1 FROM system_role_menu existing |
| | | WHERE existing.role_id=rm.role_id AND existing.tenant_id=rm.tenant_id |
| | | AND existing.menu_id=@finance_parent AND existing.deleted=b'0'); |
| | | INSERT INTO system_menu (name,permission,type,sort,parent_id,path,icon,status,visible,keep_alive,always_show,creator,updater) |
| | | SELECT p.name,p.permission,3,p.sort_no,@finance_page,'','',0,b'1',b'1',b'1','1','1' |
| | | FROM (SELECT 'è稿æ¥è¯¢' name,'erp:after-sale-finance:query' permission,1 sort_no UNION ALL SELECT 'èç¨¿å®¡æ ¸','erp:after-sale-finance:review',2) p |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | -- MES éè´§åå
³èå®åç³è¯·ãé¿è¾çº¿ä¸åæ¬å°å·²å卿¤åï¼ |
| | | -- å
¶ä»é¡¹ç®è¿ç§»æ¶å®å
¨è¡¥åï¼ä¸åå¡«å岿°æ®ã |
| | | SET @as_return_link_sql := IF( |
| | | (SELECT COUNT(*) FROM information_schema.columns |
| | | WHERE table_schema=DATABASE() AND table_name='mes_wm_return_sales' |
| | | AND column_name='after_sale_return_id')=0, |
| | | 'ALTER TABLE mes_wm_return_sales ADD COLUMN after_sale_return_id BIGINT NULL COMMENT ''æ¥æºå®åéè´§ç³è¯·''', |
| | | 'SELECT 1'); |
| | | PREPARE as_return_link_stmt FROM @as_return_link_sql; |
| | | EXECUTE as_return_link_stmt; |
| | | DEALLOCATE PREPARE as_return_link_stmt; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | -- å®åå®ç©éè´§éè¦ RQC æ£éªãä»
å¯ç¨è´¨é管çä¸å·²æçéè´§æ£éªé¡µé¢ï¼ |
| | | -- ä¸è°æ´ä¸çº§èåï¼ä¸æ°å¢ç¨æ·æè§è²ææãæ§è¡åæç¯å¢è¿ç»´æµç¨å·æ°æéç¼åã |
| | | UPDATE system_menu |
| | | SET status=0, visible=b'1', updater='1', update_time=NOW() |
| | | WHERE component='mes/qc/rqc/index' AND type=2 AND deleted=b'0' |
| | | AND (status<>0 OR visible<>b'1') |
| | | AND parent_id IN (SELECT id FROM (SELECT id FROM system_menu |
| | | WHERE parent_id=0 AND path='/qc' AND deleted=b'0') qc_parent); |
| | |
| | | import cn.iocoder.yudao.module.aftersales.service.permission.bo.AfterSalePermissionCreateReqBO; |
| | | import cn.iocoder.yudao.module.mes.api.returnsales.MesWmReturnSalesApi; |
| | | import cn.iocoder.yudao.module.mes.api.returnsales.dto.MesWmReturnSalesCreateReqDTO; |
| | | import cn.iocoder.yudao.module.mes.api.returnsales.dto.MesWmReturnSalesLineCreateDTO; |
| | | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| | | import jakarta.annotation.Resource; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Service; |
| | |
| | | import java.util.List; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.invalidParamException; |
| | | import static cn.iocoder.yudao.module.aftersales.enums.ErrorCodeConstants.*; |
| | | |
| | | /** |
| | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Long createReturn(AfterSaleReturnSaveReqVO createReqVO, Long userId) { |
| | | if (Integer.valueOf(3).equals(createReqVO.getReturnType())) |
| | | throw invalidParamException("ä»
鿬¾æµç¨å°æªæ¥å
¥è´¢å¡å®¡æ ¸ï¼æä¸è½å建éè´§ç³è¯·"); |
| | | // 1. æ ¡éªå·¥ååå¨ |
| | | AfterSaleTicketDO ticket = ticketMapper.selectById(createReqVO.getTicketId()); |
| | | if (ticket == null) { |
| | |
| | | if (!AfterSaleReturnStatusEnum.DRAFT.getStatus().equals(returnDO.getStatus())) { |
| | | throw exception(RETURN_APPROVE_FAIL); |
| | | } |
| | | if (Integer.valueOf(3).equals(returnDO.getReturnType())) |
| | | throw invalidParamException("ä»
鿬¾æµç¨å°æªæ¥å
¥è´¢å¡å®¡æ ¸ï¼æä¸è½åæ¥ä¸ºå®ç©éè´§å"); |
| | | List<AfterSaleReturnItemDO> items = returnItemMapper.selectListByReturnId(id); |
| | | if (CollUtil.isEmpty(items) || items.stream().anyMatch(item -> item.getItemId() == null |
| | | || item.getReturnQuantity() == null || item.getReturnQuantity().signum() <= 0)) |
| | | throw invalidParamException("请å
å¡«åææçéè´§ç©æåæ°é"); |
| | | // å¨äºå¡ä¸æ¢å èç¨¿ç¶æï¼é¿å
å¹¶åå®¡æ ¸éå¤çæéè´§åã |
| | | if (returnMapper.update(null, new LambdaUpdateWrapper<AfterSaleReturnDO>() |
| | | .eq(AfterSaleReturnDO::getId, id) |
| | | .eq(AfterSaleReturnDO::getStatus, AfterSaleReturnStatusEnum.DRAFT.getStatus()) |
| | | .set(AfterSaleReturnDO::getStatus, AfterSaleReturnStatusEnum.AUDITING.getStatus())) != 1) |
| | | throw exception(RETURN_APPROVE_FAIL); |
| | | |
| | | // 2. è·åå
³èå·¥åï¼ç¨äºè·åéå®è®¢åå·çåä½ä¿¡æ¯ï¼ |
| | | AfterSaleTicketDO ticket = ticketMapper.selectById(returnDO.getTicketId()); |
| | |
| | | mesReqDTO.setRemark("å®åå·¥åéè´§ - å·¥åå·: " + (ticket != null ? ticket.getNo() : "")); |
| | | mesReqDTO.setAfterSaleReturnId(returnDO.getId()); |
| | | Long mesReturnId = mesWmReturnSalesApi.createReturnSales(mesReqDTO); |
| | | if (mesReturnId == null) throw invalidParamException("MES éè´§åå建失败"); |
| | | for (AfterSaleReturnItemDO item : items) { |
| | | var line = new MesWmReturnSalesLineCreateDTO(); |
| | | line.setReturnId(mesReturnId); line.setItemId(item.getItemId()); line.setQuantity(item.getReturnQuantity()); |
| | | line.setBatchId(item.getBatchId()); line.setBatchCode(item.getBatchCode()); line.setRemark(item.getRemark()); |
| | | Long lineId = mesWmReturnSalesApi.createReturnSalesLine(line); |
| | | if (lineId == null || returnItemMapper.updateById(new AfterSaleReturnItemDO().setId(item.getId()).setMesReturnLineId(lineId)) != 1) |
| | | throw invalidParamException("MES éè´§æç»åæ¥å¤±è´¥"); |
| | | } |
| | | |
| | | // 4. æ´æ°éè´§ç³è¯·ç¶æ |
| | | returnMapper.updateById(new AfterSaleReturnDO().setId(id) |
| | | if (returnMapper.updateById(new AfterSaleReturnDO().setId(id) |
| | | .setStatus(AfterSaleReturnStatusEnum.APPROVED.getStatus()) |
| | | .setMesReturnId(mesReturnId) |
| | | .setMesReturnCode(returnDO.getNo()) |
| | | .setAuditTime(LocalDateTime.now())); |
| | | .setAuditTime(LocalDateTime.now())) != 1) throw invalidParamException("æ´æ°éè´§ç³è¯·å¤±è´¥"); |
| | | } |
| | | |
| | | @Override |
| | |
| | | */ |
| | | CommonResult<ErpSaleOrderRespDTO> getSaleOrder(Long id); |
| | | |
| | | /** å¨è°ç¨æ¹äºå¡ä¸éå®å¹¶æ ¡éªå¯ç¨äºåè´§çéå®è®¢åã */ |
| | | CommonResult<ErpSaleOrderRespDTO> lockSaleOrderForNotice(Long id, String orderNo); |
| | | |
| | | /** |
| | | * æ ¹æ®ååç¼å·è·åéå®è®¢å |
| | | * |
| | |
| | | */ |
| | | CommonResult<Boolean> updateOrderOutStatusTo(Long orderId, Integer outStatus); |
| | | |
| | | } |
| | | } |
| | |
| | | import cn.iocoder.yudao.module.erp.service.sale.ErpSaleOrderService; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.transaction.annotation.Propagation; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus; |
| | | import java.util.Objects; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | |
| | | import java.util.List; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.invalidParamException; |
| | | |
| | | /** |
| | | * ERP éå®è®¢å API å®ç°ç±» |
| | |
| | | @Override |
| | | public CommonResult<ErpSaleOrderRespDTO> getSaleOrder(Long id) { |
| | | ErpSaleOrderDO order = saleOrderService.getSaleOrder(id); |
| | | return success(BeanUtils.toBean(order, ErpSaleOrderRespDTO.class)); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(propagation = Propagation.MANDATORY) |
| | | public CommonResult<ErpSaleOrderRespDTO> lockSaleOrderForNotice(Long id, String orderNo) { |
| | | if (id == null && (orderNo == null || orderNo.isBlank())) return success(null); |
| | | ErpSaleOrderDO order = id != null ? saleOrderMapper.selectByIdForUpdate(id) : saleOrderMapper.selectByNoForUpdate(orderNo); |
| | | if (order == null || (orderNo != null && !orderNo.isBlank() && !Objects.equals(orderNo, order.getNo()))) |
| | | throw invalidParamException("å
³èéå®è®¢åä¸åå¨æè®¢åç¼å·ä¸å¹é
"); |
| | | if (!Objects.equals(order.getStatus(), ErpAuditStatus.APPROVE.getStatus())) |
| | | throw invalidParamException("éå®è®¢åæªå®¡æ ¸æå·²ä½åºï¼ä¸è½çæåè´§éç¥"); |
| | | return success(BeanUtils.toBean(order, ErpSaleOrderRespDTO.class)); |
| | | } |
| | | |
| | |
| | | return success(true); |
| | | } |
| | | |
| | | } |
| | | } |
| | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.order.ErpSaleOrderPageReqVO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpSaleOrderDO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpSaleOrderItemDO; |
| | |
| | | return selectOne(ErpSaleOrderDO::getNo, no); |
| | | } |
| | | |
| | | default ErpSaleOrderDO selectByIdForUpdate(Long id) { |
| | | return selectOne(new LambdaQueryWrapperX<ErpSaleOrderDO>().eq(ErpSaleOrderDO::getId, id).last("FOR UPDATE")); |
| | | } |
| | | |
| | | default ErpSaleOrderDO selectByNoForUpdate(String no) { |
| | | return selectOne(new LambdaQueryWrapperX<ErpSaleOrderDO>().eq(ErpSaleOrderDO::getNo, no).last("FOR UPDATE")); |
| | | } |
| | | |
| | | default ErpSaleOrderDO selectByContractId(Long contractId) { |
| | | return selectOne(ErpSaleOrderDO::getContractId, contractId); |
| | | } |
| | | |
| | | } |
| | | } |
| | |
| | | ErrorCode SALE_ORDER_BPM_PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1_020_201_020, "éå®è®¢åå®¡æ ¸åç±»ä¸æ²¡æå¯ç¨çæµç¨æ¨¡åï¼è¯·å
å建并å叿µç¨"); |
| | | ErrorCode SALE_ORDER_CANCEL_FAIL_ACTIVE_MPS = new ErrorCode(1_020_201_021, "ä½åºå¤±è´¥ï¼è®¢å仿å
³èç产计åï¼è¯·å
å¤çå¹¶åæ¶ç产计å"); |
| | | ErrorCode SALE_ORDER_CANCEL_FAIL_MPS_UNKNOWN = new ErrorCode(1_020_201_022, "æ æ³ç¡®è®¤å
³èç产计åç¶æï¼è¯·ç¨åéè¯"); |
| | | ErrorCode SALE_ORDER_CANCEL_FAIL_NOTICE_EXISTS = new ErrorCode(1_020_201_023, "ä½åºå¤±è´¥ï¼è®¢åå·²çæåè´§éç¥ï¼è¯·å
å¤çç¸å
³éç¥å"); |
| | | ErrorCode SALE_ORDER_CANCEL_FAIL_NOTICE_UNKNOWN = new ErrorCode(1_020_201_024, "æ æ³ç¡®è®¤åè´§éç¥ç¶æï¼è¯·ç¨åéè¯"); |
| | | |
| | | // ========== ERP éå®åºåºï¼1-030-202-000ï¼ ========== |
| | | ErrorCode SALE_OUT_NOT_EXISTS = new ErrorCode(1_020_202_000, "éå®åºåºåä¸åå¨"); |
| | |
| | | import cn.iocoder.yudao.module.mes.api.mps.MesProMpsApi; |
| | | import cn.iocoder.yudao.module.mes.api.mps.dto.MesProMpsCreateReqDTO; |
| | | import cn.iocoder.yudao.module.mes.api.mps.dto.MesProMpsRespDTO; |
| | | import cn.iocoder.yudao.module.mes.api.salesnotice.MesWmSalesNoticeApi; |
| | | import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi; |
| | | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| | | import com.mzt.logapi.starter.annotation.LogRecord; |
| | |
| | | private MdmItemApi mdmItemApi; |
| | | @Resource |
| | | private MesProMpsApi mpsApi; |
| | | @Resource |
| | | private MesWmSalesNoticeApi salesNoticeApi; |
| | | |
| | | @Resource |
| | | private StorageAttachmentApi storageAttachmentApi; |
| | |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void cancelSaleOrder(Long id) { |
| | | // 1.1 æ ¡éªåå¨ |
| | | ErpSaleOrderDO saleOrder = validateSaleOrderExists(id); |
| | | ErpSaleOrderDO saleOrder = saleOrderMapper.selectByIdForUpdate(id); |
| | | if (saleOrder == null) throw exception(SALE_ORDER_NOT_EXISTS); |
| | | // 1.2 æ ¡éªç¶æï¼åªæå·²å®¡æ ¸ç订åæè½ä½åº |
| | | if (!ErpAuditStatus.APPROVE.getStatus().equals(saleOrder.getStatus())) { |
| | | throw exception(SALE_ORDER_CANCEL_FAIL_NOT_APPROVE, saleOrder.getNo()); |
| | |
| | | throw exception(SALE_ORDER_CANCEL_FAIL_ACTIVE_MPS); |
| | | } |
| | | } |
| | | Map<Long, Boolean> noticeStatus = salesNoticeApi.checkSalesNoticeBySaleOrderIds(List.of(id)); |
| | | if (noticeStatus == null || noticeStatus.get(id) == null) throw exception(SALE_ORDER_CANCEL_FAIL_NOTICE_UNKNOWN); |
| | | if (Boolean.TRUE.equals(noticeStatus.get(id))) throw exception(SALE_ORDER_CANCEL_FAIL_NOTICE_EXISTS); |
| | | |
| | | // 2. æ´æ°ç¶æä¸ºå·²ä½åº |
| | | int updateCount = saleOrderMapper.updateByIdAndStatus(id, saleOrder.getStatus(), |
| | |
| | | package cn.iocoder.yudao.module.mes.api.returnsales; |
| | | |
| | | import cn.iocoder.yudao.module.mes.api.returnsales.dto.MesWmReturnSalesCreateReqDTO; |
| | | import cn.iocoder.yudao.module.mes.api.returnsales.dto.MesWmReturnSalesLineCreateDTO; |
| | | |
| | | /** |
| | | * MES éå®éè´§å API æ¥å£ |
| | |
| | | */ |
| | | Long createReturnSales(MesWmReturnSalesCreateReqDTO reqDTO); |
| | | |
| | | Long createReturnSalesLine(MesWmReturnSalesLineCreateDTO reqDTO); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.api.returnsales.dto; |
| | | |
| | | import lombok.Data; |
| | | import java.math.BigDecimal; |
| | | |
| | | /** å®åç³è¯·åæ¥å° MES çéè´§ç©æè¡ã */ |
| | | @Data |
| | | public class MesWmReturnSalesLineCreateDTO { |
| | | private Long returnId; |
| | | private Long itemId; |
| | | private BigDecimal quantity; |
| | | private Long batchId; |
| | | private String batchCode; |
| | | private String remark; |
| | | } |
| | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>cn.iocoder.boot</groupId> |
| | | <artifactId>yudao-module-aftersales-api</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>cn.iocoder.boot</groupId> |
| | | <artifactId>yudao-module-system</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | |
| | | |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.mes.api.returnsales.dto.MesWmReturnSalesCreateReqDTO; |
| | | import cn.iocoder.yudao.module.mes.api.returnsales.dto.MesWmReturnSalesLineCreateDTO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.returnsales.vo.MesWmReturnSalesSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.returnsales.vo.line.MesWmReturnSalesLineSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.service.wm.returnsales.MesWmReturnSalesService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.returnsales.MesWmReturnSalesLineService; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | |
| | | |
| | | @Resource |
| | | private MesWmReturnSalesService returnSalesService; |
| | | @Resource |
| | | private MesWmReturnSalesLineService returnSalesLineService; |
| | | |
| | | @Override |
| | | public Long createReturnSales(MesWmReturnSalesCreateReqDTO reqDTO) { |
| | |
| | | return returnSalesService.createReturnSales(createReqVO); |
| | | } |
| | | |
| | | @Override |
| | | public Long createReturnSalesLine(MesWmReturnSalesLineCreateDTO reqDTO) { |
| | | MesWmReturnSalesLineSaveReqVO line = BeanUtils.toBean(reqDTO, MesWmReturnSalesLineSaveReqVO.class); |
| | | // å®åéåç©æé¡»ç»è¿æ£éªï¼ä¸è½æâä¸éæ£éªâèªå¨å¤ä¸ºåæ ¼ã |
| | | line.setRqcCheckFlag(true); |
| | | return returnSalesLineService.createReturnSalesLine(line); |
| | | } |
| | | |
| | | } |
| | |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | import com.fasterxml.jackson.annotation.JsonIgnore; |
| | | |
| | | import java.time.LocalDate; |
| | | |
| | |
| | | @NotBlank(message = "éè´§åå ä¸è½ä¸ºç©º") |
| | | private String returnReason; |
| | | |
| | | /** ä»
便å¡ç«¯å®åèå¨è®¾ç½®ï¼ä¸è½ä»æ®éä»åºéè´§åæ¥å£ä¼ å
¥ã */ |
| | | @JsonIgnore |
| | | private Long afterSaleReturnId; |
| | | |
| | | @Schema(description = "夿³¨", example = "夿³¨") |
| | | private String remark; |
| | | |
| | |
| | | * éè´§åå |
| | | */ |
| | | private String returnReason; |
| | | /** æ¥æºå®åéè´§ç³è¯·ï¼æ®éä»åºéè´§å为空ã */ |
| | | private Long afterSaleReturnId; |
| | | /** |
| | | * ç¶æ |
| | | * |
| | |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmReturnSalesStatusEnum; |
| | | import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.batch.MesWmBatchService; |
| | | import cn.iocoder.yudao.module.aftersales.api.AfterSaleTicketApi; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.context.annotation.Lazy; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.beans.factory.ObjectProvider; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.invalidParamException; |
| | | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.MD_ITEM_BATCH_REQUIRED; |
| | | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_RETURN_SALES_LINE_NOT_EXISTS; |
| | | |
| | |
| | | @Resource |
| | | @Lazy |
| | | private MesWmReturnSalesDetailService returnSalesDetailService; |
| | | @Resource |
| | | private ObjectProvider<AfterSaleTicketApi> afterSaleTicketApiProvider; |
| | | |
| | | @Override |
| | | public Long createReturnSalesLine(MesWmReturnSalesLineSaveReqVO createReqVO) { |
| | |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void updateReturnSalesLineWhenRqcFinish(Long sourceLineId, Long sourceDocId, Integer checkResult, |
| | | BigDecimal qualifiedQuantity, BigDecimal unqualifiedQuantity) { |
| | | MesWmReturnSalesLineDO sourceLine = validateReturnSalesLineExists(sourceLineId); |
| | |
| | | // 2. æ£æ¥éè´§å䏿¯å¦è¿æå¾
æ£éªçè¡ï¼è¥å
¨æ£å®åå°éè´§åç¶æè®¾ä¸º"å¾
䏿¶" |
| | | if (sourceDocId != null) { |
| | | List<MesWmReturnSalesLineDO> allLines = returnSalesLineMapper.selectListByReturnId(sourceDocId); |
| | | boolean allInspected = !CollUtil.contains(allLines, |
| | | line -> Objects.equals(line.getQualityStatus(), MesWmQualityStatusEnum.PENDING.getStatus())); |
| | | boolean allInspected = CollUtil.isNotEmpty(allLines) && allLines.stream().allMatch(line -> |
| | | Objects.equals(line.getQualityStatus(), MesWmQualityStatusEnum.PASS.getStatus()) |
| | | || Objects.equals(line.getQualityStatus(), MesWmQualityStatusEnum.FAIL.getStatus())); |
| | | if (allInspected) { |
| | | returnSalesService.updateReturnSalesStatus(sourceDocId, MesWmReturnSalesStatusEnum.APPROVING.getStatus()); |
| | | MesWmReturnSalesDO source = returnSalesService.validateReturnSalesExists(sourceDocId); |
| | | if (source.getAfterSaleReturnId() != null) { |
| | | AfterSaleTicketApi api = afterSaleTicketApiProvider.getIfAvailable(); |
| | | if (api == null) throw invalidParamException("å®åæå¡ä¸å¯ç¨ï¼æ æ³åæ¥éè´§æ£éªç»æ"); |
| | | boolean hasFailed = allLines.stream().anyMatch(line -> |
| | | Objects.equals(line.getQualityStatus(), MesWmQualityStatusEnum.FAIL.getStatus())); |
| | | var response = api.onReturnQualityFinished(source.getAfterSaleReturnId(), hasFailed ? "åå¨ä¸åæ ¼" : "åæ ¼", null); |
| | | if (response == null || !Boolean.TRUE.equals(response.getCheckedData())) |
| | | throw invalidParamException("å®åéè´§æ£éªç»æåæ¥å¤±è´¥"); |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmReturnSalesStatusEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum; |
| | | import cn.iocoder.yudao.module.crm.api.customer.CrmCustomerApi; |
| | | import cn.iocoder.yudao.module.aftersales.api.AfterSaleTicketApi; |
| | | import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.beans.factory.ObjectProvider; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.math.BigDecimal; |
| | |
| | | import java.util.Map; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.invalidParamException; |
| | | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; |
| | | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; |
| | | |
| | |
| | | private MesMdmItemService mdmItemService; |
| | | @Resource |
| | | private MesWmTransactionService wmTransactionService; |
| | | @Resource |
| | | private ObjectProvider<AfterSaleTicketApi> afterSaleTicketApiProvider; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | |
| | | // 3. æ´æ°éè´§åç¶æ |
| | | returnSalesMapper.updateById(new MesWmReturnSalesDO() |
| | | .setId(id).setStatus(MesWmReturnSalesStatusEnum.FINISHED.getStatus())); |
| | | if (returnSales.getAfterSaleReturnId() != null) { |
| | | AfterSaleTicketApi api = afterSaleTicketApiProvider.getIfAvailable(); |
| | | if (api == null) throw invalidParamException("å®åæå¡ä¸å¯ç¨ï¼æ æ³åæ¥éè´§å
¥åºç¶æ"); |
| | | var response = api.onReturnInboundFinished(returnSales.getAfterSaleReturnId()); |
| | | if (response == null || !Boolean.TRUE.equals(response.getCheckedData())) |
| | | throw invalidParamException("å®åéè´§å
¥åºç¶æåæ¥å¤±è´¥"); |
| | | } |
| | | } |
| | | |
| | | private void createTransactionList(MesWmReturnSalesDO returnSales) { |
| | |
| | | private MesWmSalesNoticeLineMapper salesNoticeLineMapper; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Long createSalesNotice(MesWmSalesNoticeSaveReqVO createReqVO) { |
| | | lockReferencedSaleOrder(createReqVO, null); |
| | | // æ ¡éªæ°æ® |
| | | validateSalesNoticeSave(createReqVO); |
| | | |
| | |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void updateSalesNotice(MesWmSalesNoticeSaveReqVO updateReqVO) { |
| | | // æ ¡éªåå¨ + èç¨¿ç¶æ |
| | | validateSalesNoticeExistsAndDraft(updateReqVO.getId()); |
| | | MesWmSalesNoticeDO existing = validateSalesNoticeExistsAndDraft(updateReqVO.getId()); |
| | | lockReferencedSaleOrder(updateReqVO, existing); |
| | | // æ ¡éªæ°æ® |
| | | validateSalesNoticeSave(updateReqVO); |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | /** ä¸è®¢åä½åºä½¿ç¨åä¸è®¢åè¡éï¼æ¯æåå²è¯·æ±ä»
ä¼ è®¢åå·ã */ |
| | | private void lockReferencedSaleOrder(MesWmSalesNoticeSaveReqVO request, MesWmSalesNoticeDO existing) { |
| | | Long orderId = request.getSaleOrderId(); |
| | | String orderNo = request.getSaleOrderCode(); |
| | | if (orderId == null && (orderNo == null || orderNo.isBlank()) && existing != null) { |
| | | orderId = existing.getSaleOrderId(); |
| | | orderNo = existing.getSaleOrderCode(); |
| | | } |
| | | if (orderId == null && (orderNo == null || orderNo.isBlank())) return; |
| | | ErpSaleOrderRespDTO order = saleOrderApi.lockSaleOrderForNotice(orderId, orderNo).getCheckedData(); |
| | | if (order == null) throw exception(WM_SALES_NOTICE_SALE_ORDER_NOT_EXISTS); |
| | | request.setSaleOrderId(order.getId()); |
| | | request.setSaleOrderCode(order.getNo()); |
| | | } |
| | | |
| | | private void validateNoticeCodeUnique(Long id, String code) { |
| | | MesWmSalesNoticeDO notice = salesNoticeMapper.selectByCode(code); |
| | | if (notice == null) { |
| | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Long generateSalesNoticeFromSaleOrder(Long saleOrderId) { |
| | | // å
éå®è®¢åï¼åæ£æ¥éç¥ï¼ä¸è®¢åä½åºä¸²è¡æ§è¡ã |
| | | ErpSaleOrderRespDTO saleOrder = saleOrderApi.lockSaleOrderForNotice(saleOrderId, null).getCheckedData(); |
| | | if (saleOrder == null) throw exception(WM_SALES_NOTICE_SALE_ORDER_NOT_EXISTS); |
| | | // 1. æ ¡éªæ¯å¦å·²çæè¿åè´§éç¥åï¼é²æ¢éå¤çæï¼ |
| | | MesWmSalesNoticeDO existNotice = salesNoticeMapper.selectBySaleOrderId(saleOrderId); |
| | | if (existNotice != null) { |
| | | throw exception(WM_SALES_NOTICE_ALREADY_EXISTS); |
| | | } |
| | | |
| | | // 2. è·åéå®è®¢åä¿¡æ¯ |
| | | ErpSaleOrderRespDTO saleOrder = saleOrderApi.getSaleOrder(saleOrderId).getCheckedData(); |
| | | if (saleOrder == null) { |
| | | throw exception(WM_SALES_NOTICE_SALE_ORDER_NOT_EXISTS); |
| | | } |
| | | |
| | | // 3. è·åéå®è®¢åæç» |