| | |
| | | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; |
| | | import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; |
| | | import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi; |
| | | import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.returnvendor.vo.MesWmReturnVendorPageReqVO; |
| | |
| | | import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO; |
| | | import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.security.core.Authentication; |
| | | import org.springframework.security.core.context.SecurityContextHolder; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.validation.annotation.Validated; |
| | |
| | | */ |
| | | @Service |
| | | @Validated |
| | | @Slf4j |
| | | public class MesWmReturnVendorServiceImpl implements MesWmReturnVendorService { |
| | | |
| | | /** |
| | |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void submitReturnVendorApproval(Long id, String processDefinitionKey) { |
| | | // 1. 校验存在 + 草稿状态 + 至少一条行 |
| | | validateReturnVendorExistsAndPrepare(id); |
| | | MesWmReturnVendorDO returnVendor = validateReturnVendorExistsAndPrepare(id); |
| | | if (CollUtil.isEmpty(returnVendorLineService.getReturnVendorLineListByReturnId(id))) { |
| | | throw exception(WM_RETURN_VENDOR_NO_LINE); |
| | | } |
| | | // 1.1. 质量部发起退货必须上传附件(质检报告、不合格照片等),否则审批人无法判断退货依据 |
| | | if (CollUtil.isEmpty(storageAttachmentApi.listAttachments(RETURN_VENDOR_RECORD_TYPE, id))) { |
| | | throw exception(WM_RETURN_VENDOR_ATTACHMENT_REQUIRED, returnVendor.getCode()); |
| | | } |
| | | |
| | | // 2. 全局免审批:直接置为「待拣货」,无需流程模型 |
| | |
| | | * 获取当前用户编号(BPM 流程发起人、财务人员) |
| | | */ |
| | | private Long getCurrentUserId() { |
| | | Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); |
| | | if (authentication != null && authentication.getPrincipal() instanceof Long) { |
| | | return (Long) authentication.getPrincipal(); |
| | | } |
| | | return null; |
| | | // 统一从安全框架取登录用户;Spring Security 的 principal 是 LoginUser 而非 Long, |
| | | // 直接强转会取到 null,导致 BPM 流程实例的发起人为字符串 "null" |
| | | return SecurityFrameworkUtils.getLoginUserId(); |
| | | } |
| | | |
| | | private void createTransactionList(MesWmReturnVendorDO returnVendor, List<MesWmReturnVendorDetailDO> details) { |
| | | wmTransactionService.createTransactionList(convertList(details, detail -> new MesWmTransactionSaveReqDTO() |
| | | .setType(MesWmTransactionTypeEnum.OUT.getType()).setItemId(detail.getItemId()) |
| | | // 按拣货时选中的库存记录扣减:生产批次可能没有 vendor_id,仅靠 物料+库位+批次+供应商 组合键会找不到库存 |
| | | .setMaterialStockId(detail.getMaterialStockId()) |
| | | .setQuantity(detail.getQuantity().negate()) // 出库数量为负数 |
| | | .setBatchId(detail.getBatchId()).setBatchCode(detail.getBatchCode()) |
| | | .setWarehouseId(detail.getWarehouseId()).setLocationId(detail.getLocationId()).setAreaId(detail.getAreaId()) |
| | |
| | | } |
| | | try { |
| | | importPurchaseOrderItems(id); |
| | | } catch (ServiceException ignore) { |
| | | // 采购订单无明细 / 无可退物料等业务异常:单据主体仍正常保存,可在物料区另行处理 |
| | | } catch (ServiceException ex) { |
| | | // 采购订单无明细 / 无可退物料等业务异常:单据主体仍正常保存,可在物料区点「重新带入订单物料」补带 |
| | | // 打日志便于排查(例如:保存后才入库,此时订单还没有可退数量) |
| | | log.warn("[autoImportLinesFromLinkedOrder][退货单({}) 关联采购订单({}) 自动带入物料失败:{}]", |
| | | id, returnVendor.getPurchaseOrderId(), ex.getMessage()); |
| | | } |
| | | } |
| | | |