package cn.iocoder.yudao.module.mes.service.pro.route; import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.product.MesProRouteProductSaveReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemTypeDO; import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductDO; import cn.iocoder.yudao.module.mes.dal.mysql.pro.route.MesProRouteProductMapper; import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemTypeService; import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService; import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) class MesProRouteProductServiceImplTest { @InjectMocks private MesProRouteProductServiceImpl service; @Mock private MesProRouteProductMapper routeProductMapper; @Mock private MesProRouteService routeService; @Mock private MesMdItemService itemService; @Mock private MesMdItemTypeService itemTypeService; @Mock private MesWmWarehouseAreaService warehouseAreaService; @Mock private MdmItemApi mdmItemApi; @Test void updateWarehouseForExistingItemDoesNotRevalidateLegacyCategory() { MesProRouteProductSaveReqVO request = request(88L, 815L); MesProRouteProductDO existing = new MesProRouteProductDO().setId(88L).setItemId(815L); when(routeProductMapper.selectById(88L)).thenReturn(existing); when(routeProductMapper.selectByItemId(815L)).thenReturn(existing); assertDoesNotThrow(() -> service.updateRouteProduct(request)); verifyNoInteractions(itemService, itemTypeService); verify(routeProductMapper).updateById(any(MesProRouteProductDO.class)); } @Test void createAcceptsSemiFinishedItemInSfCategoryTree() { MesProRouteProductSaveReqVO request = request(null, 815L); when(itemService.validateItemExistsAndEnable(815L)) .thenReturn(new MesMdItemDO().setId(815L).setName("封装半成品").setItemTypeId(23L)); when(itemTypeService.getItemType(23L)).thenReturn(new MesMdItemTypeDO() .setId(23L).setCode("PACKAGED").setItemOrProduct("ITEM").setParentId(2L)); when(itemTypeService.getItemType(2L)).thenReturn(new MesMdItemTypeDO() .setId(2L).setCode("SF").setParentId(0L)); assertDoesNotThrow(() -> service.createRouteProduct(request)); verify(routeProductMapper).insert(any(MesProRouteProductDO.class)); } @Test void createRejectsRawMaterialOutsideProductTree() { MesProRouteProductSaveReqVO request = request(null, 815L); when(itemService.validateItemExistsAndEnable(815L)) .thenReturn(new MesMdItemDO().setId(815L).setName("原料").setItemTypeId(23L)); when(itemTypeService.getItemType(23L)).thenReturn(new MesMdItemTypeDO() .setId(23L).setCode("RAW").setItemOrProduct("ITEM").setParentId(0L)); assertThrows(ServiceException.class, () -> service.createRouteProduct(request)); verify(routeProductMapper, never()).insert(any(MesProRouteProductDO.class)); } @Test void createAcceptsNamedSemiFinishedInLegacyItemCategory() { MesProRouteProductSaveReqVO request = request(null, 815L); MesMdItemDO item = new MesMdItemDO().setId(815L).setCode("74000432") .setName("黑果枸杞半成品").setItemTypeId(23L); when(itemService.validateItemExistsAndEnable(815L)).thenReturn(item); when(itemTypeService.getItemType(23L)).thenReturn(new MesMdItemTypeDO() .setId(23L).setCode("FOOD").setName("黑果枸杞半成品") .setItemOrProduct("ITEM").setParentId(0L)); assertDoesNotThrow(() -> service.createRouteProduct(request)); verifyNoInteractions(mdmItemApi); verify(routeProductMapper).insert(any(MesProRouteProductDO.class)); } private static MesProRouteProductSaveReqVO request(Long id, Long itemId) { MesProRouteProductSaveReqVO request = new MesProRouteProductSaveReqVO(); request.setId(id); request.setRouteId(44L); request.setItemId(itemId); request.setWarehouseId(24L); request.setLocationId(9L); request.setAreaId(9L); return request; } }