diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/controller/ErpAdapterController.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/controller/ErpAdapterController.java index 10c8b649..bce3fe71 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/controller/ErpAdapterController.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/controller/ErpAdapterController.java @@ -78,7 +78,11 @@ public ResponseEntity scheduleErpUpdate( @RequestParam("asset-type") AssetType assetType, @RequestParam(required = false, value = "direction") DirectionCharacteristic directionCharacteristic ) { - materialNumber = new String(Base64.getDecoder().decode(materialNumber)); + try { + materialNumber = new String(Base64.getDecoder().decode(materialNumber)); + } catch (Exception e) { + return ResponseEntity.badRequest().build(); + } boolean valid = BPNL_PATTERN.matcher(bpnl).matches() && NON_EMPTY_NON_VERTICAL_WHITESPACE_PATTERN.matcher(materialNumber).matches() && ErpAdapterRequest.SUPPORTED_TYPES.contains(assetType); diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/logic/service/ItemStockErpAdapterService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/logic/service/ItemStockErpAdapterService.java index 1ea34bb1..43059ba6 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/logic/service/ItemStockErpAdapterService.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/logic/service/ItemStockErpAdapterService.java @@ -64,6 +64,7 @@ public class ItemStockErpAdapterService { @Autowired private MaterialItemStockService materialItemStockService; + @Autowired private ProductItemStockService productItemStockService; diff --git a/backend/src/test/java/org/eclipse/tractusx/puris/backend/erpadapter/logic/service/ItemStockErpAdapterServiceTest.java b/backend/src/test/java/org/eclipse/tractusx/puris/backend/erpadapter/logic/service/ItemStockErpAdapterServiceTest.java new file mode 100644 index 00000000..cfdc912c --- /dev/null +++ b/backend/src/test/java/org/eclipse/tractusx/puris/backend/erpadapter/logic/service/ItemStockErpAdapterServiceTest.java @@ -0,0 +1,408 @@ +/* + * Copyright (c) 2024 Volkswagen AG + * Copyright (c) 2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.puris.backend.erpadapter.logic.service; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.eclipse.tractusx.puris.backend.common.edc.domain.model.AssetType; +import org.eclipse.tractusx.puris.backend.erpadapter.controller.ErpAdapterController; +import org.eclipse.tractusx.puris.backend.erpadapter.domain.model.ErpAdapterRequest; +import org.eclipse.tractusx.puris.backend.masterdata.domain.model.Material; +import org.eclipse.tractusx.puris.backend.masterdata.domain.model.MaterialPartnerRelation; +import org.eclipse.tractusx.puris.backend.masterdata.domain.model.Partner; +import org.eclipse.tractusx.puris.backend.masterdata.logic.service.MaterialPartnerRelationService; +import org.eclipse.tractusx.puris.backend.masterdata.logic.service.MaterialService; +import org.eclipse.tractusx.puris.backend.masterdata.logic.service.PartnerService; +import org.eclipse.tractusx.puris.backend.stock.logic.adapter.ItemStockSammMapper; +import org.eclipse.tractusx.puris.backend.stock.logic.dto.itemstocksamm.DirectionCharacteristic; +import org.eclipse.tractusx.puris.backend.stock.logic.service.MaterialItemStockService; +import org.eclipse.tractusx.puris.backend.stock.logic.service.ProductItemStockService; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.Date; +import java.util.UUID; + +@ExtendWith(MockitoExtension.class) +public class ItemStockErpAdapterServiceTest { + + private final static ObjectMapper mapper = new ObjectMapper(); + + @Mock + private ErpAdapterRequestService erpAdapterRequestService; + + @Mock + private MaterialPartnerRelationService mprService; + + @Mock + private PartnerService partnerService; + + @Mock + private MaterialService materialService; + + @Mock + private ItemStockSammMapper sammMapper; + + @Mock + private MaterialItemStockService materialItemStockService; + + @Mock + private ProductItemStockService productItemStockService; + + @InjectMocks + private ItemStockErpAdapterService itemStockErpAdapterService; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + } + + + private static final Partner partner = new Partner( + "Control Unit Creator Inc.", + "http://customer-control-plane:8184/api/v1/dsp", + "BPNL4444444444XX", + "BPNS4444444444XX", + "Control Unit Creator Production Site", + "BPNA4444444444AA", + "13th Street 47", + "10011 New York", + "USA" + ); + + private static final String ownMaterialNumber = "MNR-8101-ID146955.001"; + + private static final String partnerMaterialNumber = "MNR-7307-AU340474.002"; + + private static final Material material = new Material(); + + private static final String partnerBpnl = partner.getBpnl(); + + private static final String responseType = AssetType.ITEM_STOCK_SUBMODEL.ERP_KEYWORD; + + private static final String sammVersion = AssetType.ITEM_STOCK_SUBMODEL.ERP_SAMMVERSION; + + static { + material.setOwnMaterialNumber(ownMaterialNumber); + material.setProductFlag(true); + material.setName("Semiconductor"); + } + + private static final MaterialPartnerRelation mpr = new MaterialPartnerRelation(material, partner, + partnerMaterialNumber, false, true); + + private final static String itemStock20Sample = "{\n" + + " \"materialGlobalAssetId\": null,\n" + + " \"positions\": [\n" + + " {\n" + + " \"orderPositionReference\": {\n" + + " \"supplierOrderId\": \"M-Nbr-4711\",\n" + + " \"customerOrderId\": \"C-Nbr-4711\",\n" + + " \"customerOrderPositionId\": \"PositionId-01\"\n" + + " },\n" + + " \"allocatedStocks\": [\n" + + " {\n" + + " \"isBlocked\": false,\n" + + " \"stockLocationBPNA\": \"BPNA4444444444AA\",\n" + + " \"lastUpdatedOnDateTime\": \"2023-04-28T14:23:00.123456+14:00\",\n" + + " \"quantityOnAllocatedStock\": {\n" + + " \"value\": 22.0,\n" + + " \"unit\": \"unit:piece\"\n" + + " },\n" + + " \"stockLocationBPNS\": \"BPNS4444444444XX\"\n" + + " }\n" + + " ]\n" + + " },\n" + + " {\n" + + " \"orderPositionReference\": {\n" + + " \"supplierOrderId\": \"M-Nbr-4711\",\n" + + " \"customerOrderId\": \"C-Nbr-4711\",\n" + + " \"customerOrderPositionId\": \"PositionId-03\"\n" + + " },\n" + + " \"allocatedStocks\": [\n" + + " {\n" + + " \"isBlocked\": false,\n" + + " \"stockLocationBPNA\": \"BPNA4444444444AA\",\n" + + " \"lastUpdatedOnDateTime\": \"2023-04-28T14:23:00.123456+14:00\",\n" + + " \"quantityOnAllocatedStock\": {\n" + + " \"value\": 66.0,\n" + + " \"unit\": \"unit:piece\"\n" + + " },\n" + + " \"stockLocationBPNS\": \"BPNS4444444444XX\"\n" + + " }\n" + + " ]\n" + + " },\n" + + " {\n" + + " \"orderPositionReference\": {\n" + + " \"supplierOrderId\": \"M-Nbr-4711\",\n" + + " \"customerOrderId\": \"C-Nbr-4711\",\n" + + " \"customerOrderPositionId\": \"PositionId-02\"\n" + + " },\n" + + " \"allocatedStocks\": [\n" + + " {\n" + + " \"isBlocked\": true,\n" + + " \"stockLocationBPNA\": \"BPNA4444444444AA\",\n" + + " \"lastUpdatedOnDateTime\": \"2023-04-28T14:23:00.123456+14:00\",\n" + + " \"quantityOnAllocatedStock\": {\n" + + " \"value\": 44.0,\n" + + " \"unit\": \"unit:piece\"\n" + + " },\n" + + " \"stockLocationBPNS\": \"BPNS4444444444XX\"\n" + + " }\n" + + " ]\n" + + " }\n" + + " ],\n" + + " \"direction\": \"OUTBOUND\"\n" + + "}"; + + @Test + void testReceivedMessageForExistingRequest_should_succeed() throws Exception { + UUID requestId = UUID.randomUUID(); + + // given + ErpAdapterRequest request = ErpAdapterRequest.builder() + .id(requestId) + .requestType(AssetType.ITEM_STOCK_SUBMODEL) + .sammVersion(AssetType.ITEM_STOCK_SUBMODEL.ERP_SAMMVERSION) + .responseCode(201) + .ownMaterialNumber(ownMaterialNumber) + .directionCharacteristic(DirectionCharacteristic.OUTBOUND) + .requestDate(new Date()) + .partnerBpnl(partnerBpnl) + .build(); + + ErpAdapterController.Dto dto = new ErpAdapterController.Dto(requestId, partnerBpnl, responseType, sammVersion, + new Date(), mapper.readTree(itemStock20Sample)); + + // when + Mockito.when(erpAdapterRequestService.get(requestId)).thenReturn(request); + Mockito.when(partnerService.findByBpnl(partnerBpnl)).thenReturn(partner); + Mockito.when(materialService.findByOwnMaterialNumber(ownMaterialNumber)).thenReturn(material); + Mockito.when(mprService.find(material, partner)).thenReturn(mpr); + + // then + int result = itemStockErpAdapterService.receiveItemStockUpdate(dto); + + Assertions.assertEquals(201, result); + } + + @Test + void testReceivedMessageForNonExistingRequest_should_fail() throws Exception { + UUID requestId = UUID.randomUUID(); + + // given + ErpAdapterController.Dto dto = new ErpAdapterController.Dto(requestId, partnerBpnl, responseType, sammVersion, + new Date(), mapper.readTree(itemStock20Sample)); + + // when + Mockito.when(erpAdapterRequestService.get(requestId)).thenReturn(null); + + // then + int result = itemStockErpAdapterService.receiveItemStockUpdate(dto); + + Assertions.assertEquals(404, result); + } + + @Test + void testReceivedMessageForAlreadyAnsweredRequest_should_fail() throws Exception { + UUID requestId = UUID.randomUUID(); + + // given + ErpAdapterRequest request = ErpAdapterRequest.builder() + .id(requestId) + .requestType(AssetType.ITEM_STOCK_SUBMODEL) + .sammVersion(AssetType.ITEM_STOCK_SUBMODEL.ERP_SAMMVERSION) + .responseCode(201) + .ownMaterialNumber(ownMaterialNumber) + .directionCharacteristic(DirectionCharacteristic.OUTBOUND) + .requestDate(new Date()) + .responseReceivedDate(new Date()) + .partnerBpnl(partnerBpnl) + .build(); + + ErpAdapterController.Dto dto = new ErpAdapterController.Dto(requestId, partnerBpnl, responseType, sammVersion, + new Date(), mapper.readTree(itemStock20Sample)); + + // when + Mockito.when(erpAdapterRequestService.get(requestId)).thenReturn(request); + + // then + int result = itemStockErpAdapterService.receiveItemStockUpdate(dto); + + Assertions.assertEquals(409, result); + } + + @Test + void testReceivedMessageForNotReceivedRequest_should_fail() throws Exception { + UUID requestId = UUID.randomUUID(); + + // given + ErpAdapterRequest request = ErpAdapterRequest.builder() + .id(requestId) + .requestType(AssetType.ITEM_STOCK_SUBMODEL) + .sammVersion(AssetType.ITEM_STOCK_SUBMODEL.ERP_SAMMVERSION) + .responseCode(null) + .ownMaterialNumber(ownMaterialNumber) + .directionCharacteristic(DirectionCharacteristic.OUTBOUND) + .requestDate(new Date()) + .partnerBpnl(partnerBpnl) + .build(); + + ErpAdapterController.Dto dto = new ErpAdapterController.Dto(requestId, partnerBpnl, responseType, sammVersion, + new Date(), mapper.readTree(itemStock20Sample)); + + // when + Mockito.when(erpAdapterRequestService.get(requestId)).thenReturn(request); + + // then + int result = itemStockErpAdapterService.receiveItemStockUpdate(dto); + + Assertions.assertEquals(404, result); + } + + @Test + void testReceivedMessageWithInconsistentBPNL_should_fail() throws Exception { + UUID requestId = UUID.randomUUID(); + + // given + ErpAdapterRequest request = ErpAdapterRequest.builder() + .id(requestId) + .requestType(AssetType.ITEM_STOCK_SUBMODEL) + .sammVersion(AssetType.ITEM_STOCK_SUBMODEL.ERP_SAMMVERSION) + .responseCode(201) + .ownMaterialNumber(ownMaterialNumber) + .directionCharacteristic(DirectionCharacteristic.OUTBOUND) + .requestDate(new Date()) + .partnerBpnl("BPNL1234567890") + .build(); + + ErpAdapterController.Dto dto = new ErpAdapterController.Dto(requestId, partnerBpnl, responseType, sammVersion, + new Date(), mapper.readTree(itemStock20Sample)); + + // when + Mockito.when(erpAdapterRequestService.get(requestId)).thenReturn(request); + + // then + int result = itemStockErpAdapterService.receiveItemStockUpdate(dto); + + Assertions.assertEquals(400, result); + } + + @Test + void testReceivedMessageWithDirectionMismatch_should_fail() throws Exception { + UUID requestId = UUID.randomUUID(); + + // given + ErpAdapterRequest request = ErpAdapterRequest.builder() + .id(requestId) + .requestType(AssetType.ITEM_STOCK_SUBMODEL) + .sammVersion(AssetType.ITEM_STOCK_SUBMODEL.ERP_SAMMVERSION) + .responseCode(201) + .ownMaterialNumber(ownMaterialNumber) + .directionCharacteristic(DirectionCharacteristic.INBOUND) + .requestDate(new Date()) + .partnerBpnl(partnerBpnl) + .build(); + + ErpAdapterController.Dto dto = new ErpAdapterController.Dto(requestId, partnerBpnl, responseType, sammVersion, + new Date(), mapper.readTree(itemStock20Sample)); + + // when + Mockito.when(erpAdapterRequestService.get(requestId)).thenReturn(request); + + // then + int result = itemStockErpAdapterService.receiveItemStockUpdate(dto); + + Assertions.assertEquals(400, result); + } + + @Test + void testReceivedMessageWithUnsupportedSammVersion_should_fail() throws Exception { + UUID requestId = UUID.randomUUID(); + + // given + ErpAdapterRequest request = ErpAdapterRequest.builder() + .id(requestId) + .requestType(AssetType.ITEM_STOCK_SUBMODEL) + .sammVersion(AssetType.ITEM_STOCK_SUBMODEL.ERP_SAMMVERSION) + .responseCode(201) + .ownMaterialNumber(ownMaterialNumber) + .directionCharacteristic(DirectionCharacteristic.OUTBOUND) + .requestDate(new Date()) + .partnerBpnl(partnerBpnl) + .build(); + + ErpAdapterController.Dto dto = new ErpAdapterController.Dto(requestId, partnerBpnl, responseType, "0.1", + new Date(), mapper.readTree(itemStock20Sample)); + + // when + Mockito.when(erpAdapterRequestService.get(requestId)).thenReturn(request); + + // then + int result = itemStockErpAdapterService.receiveItemStockUpdate(dto); + + Assertions.assertEquals(400, result); + } + + @Test + void testReceivedMessageForPartnerWithoutAppropriateFlag_should_fail() throws Exception { + UUID requestId = UUID.randomUUID(); + + // given + ErpAdapterRequest request = ErpAdapterRequest.builder() + .id(requestId) + .requestType(AssetType.ITEM_STOCK_SUBMODEL) + .sammVersion(AssetType.ITEM_STOCK_SUBMODEL.ERP_SAMMVERSION) + .responseCode(201) + .ownMaterialNumber(ownMaterialNumber) + .directionCharacteristic(DirectionCharacteristic.OUTBOUND) + .requestDate(new Date()) + .partnerBpnl(partnerBpnl) + .build(); + + ErpAdapterController.Dto dto = new ErpAdapterController.Dto(requestId, partnerBpnl, responseType, sammVersion, + new Date(), mapper.readTree(itemStock20Sample)); + + // NOTE: we must revert this edit after test run + mpr.setPartnerBuysMaterial(false); + + // when + Mockito.when(erpAdapterRequestService.get(requestId)).thenReturn(request); + Mockito.when(partnerService.findByBpnl(partnerBpnl)).thenReturn(partner); + Mockito.when(materialService.findByOwnMaterialNumber(ownMaterialNumber)).thenReturn(material); + Mockito.when(mprService.find(material, partner)).thenReturn(mpr); + + // then + int result = itemStockErpAdapterService.receiveItemStockUpdate(dto); + + Assertions.assertEquals(400, result); + + // reverting edit + mpr.setPartnerBuysMaterial(true); + } + +} diff --git a/backend/src/test/java/org/eclipse/tractusx/puris/backend/stock/logic/adapter/ItemStockSammMapperTest.java b/backend/src/test/java/org/eclipse/tractusx/puris/backend/stock/logic/adapter/ItemStockSammMapperTest.java index 7049c5b9..6d54eb37 100644 --- a/backend/src/test/java/org/eclipse/tractusx/puris/backend/stock/logic/adapter/ItemStockSammMapperTest.java +++ b/backend/src/test/java/org/eclipse/tractusx/puris/backend/stock/logic/adapter/ItemStockSammMapperTest.java @@ -22,14 +22,12 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.eclipse.tractusx.puris.backend.common.domain.model.measurement.ItemQuantityEntity; import org.eclipse.tractusx.puris.backend.common.domain.model.measurement.ItemUnitEnumeration; -import org.eclipse.tractusx.puris.backend.masterdata.domain.model.Material; -import org.eclipse.tractusx.puris.backend.masterdata.domain.model.MaterialPartnerRelation; -import org.eclipse.tractusx.puris.backend.masterdata.domain.model.Partner; -import org.eclipse.tractusx.puris.backend.masterdata.domain.model.Site; +import org.eclipse.tractusx.puris.backend.masterdata.domain.model.*; import org.eclipse.tractusx.puris.backend.masterdata.logic.service.MaterialPartnerRelationService; import org.eclipse.tractusx.puris.backend.masterdata.logic.service.MaterialService; import org.eclipse.tractusx.puris.backend.stock.domain.model.ItemStock; import org.eclipse.tractusx.puris.backend.stock.domain.model.MaterialItemStock; +import org.eclipse.tractusx.puris.backend.stock.domain.model.ProductItemStock; import org.eclipse.tractusx.puris.backend.stock.domain.model.ReportedProductItemStock; import org.eclipse.tractusx.puris.backend.stock.logic.dto.itemstocksamm.*; import org.junit.jupiter.api.*; @@ -444,6 +442,105 @@ void test_deserializationFromJson() throws Exception { assertEquals(5, list.size()); } + @Test + @Order(5) + void testErpMaterialItemStockMapping() { + // given + Material semiconductorMaterial = Material.builder() + .ownMaterialNumber(SUPPLIER_MAT_NUMBER) + .materialFlag(false) + .productFlag(true) + .name("Semiconductor") + .build(); + + Site site = customerPartner.getSites().getFirst(); + Address address = site.getAddresses().first(); + + ItemStockSamm itemStockSamm = new ItemStockSamm(); + itemStockSamm.setDirection(DirectionCharacteristic.INBOUND); + itemStockSamm.setMaterialGlobalAssetId(CX_MAT_NUMBER); + Position position = new Position(); + ItemQuantityEntity itemQuantityEntity = new ItemQuantityEntity(); + itemQuantityEntity.setUnit(ItemUnitEnumeration.UNIT_PIECE); + itemQuantityEntity.setValue(20.0); + AllocatedStock allocatedStock = new AllocatedStock(itemQuantityEntity, site.getBpns(), false, address.getBpna(), + new Date()); + position.setAllocatedStocks(Set.of(allocatedStock)); + + String supplierOrderId = "abc123"; + String customerOrderId = "def456"; + String customerOrderPositionId = "ghi789"; + + OrderPositionReference orderPositionReference = new OrderPositionReference(supplierOrderId, customerOrderId, customerOrderPositionId); + position.setOrderPositionReference(orderPositionReference); + itemStockSamm.setPositions(Set.of(position)); + + // then + List resultList = itemStockSammMapper.erpSammToMaterialItemStock(itemStockSamm, customerPartner, semiconductorMaterial); + + Assertions.assertEquals(1, resultList.size()); + MaterialItemStock materialItemStock = resultList.getFirst(); + Assertions.assertEquals(materialItemStock.getLocationBpna(), address.getBpna()); + Assertions.assertEquals(materialItemStock.getLocationBpns(), site.getBpns()); + Assertions.assertEquals(materialItemStock.getQuantity(), 20.0); + Assertions.assertEquals(materialItemStock.getMeasurementUnit(), ItemUnitEnumeration.UNIT_PIECE); + Assertions.assertEquals(materialItemStock.getMaterial(), semiconductorMaterial); + Assertions.assertEquals(materialItemStock.getCustomerOrderId(), customerOrderId); + Assertions.assertEquals(materialItemStock.getCustomerOrderPositionId(), customerOrderPositionId); + Assertions.assertEquals(materialItemStock.getSupplierOrderId(), supplierOrderId); + Assertions.assertFalse(materialItemStock.isBlocked()); + } + + @Test + @Order(6) + void testErpProductItemStockMapping() { + // given + Material semiconductorMaterial = Material.builder() + .ownMaterialNumber(CUSTOMER_MAT_NUMBER) + .materialFlag(true) + .productFlag(false) + .name("Semiconductor") + .build(); + + Site site = supplierPartner.getSites().getFirst(); + Address address = site.getAddresses().first(); + + ItemStockSamm itemStockSamm = new ItemStockSamm(); + itemStockSamm.setDirection(DirectionCharacteristic.OUTBOUND); + itemStockSamm.setMaterialGlobalAssetId(CX_MAT_NUMBER); + Position position = new Position(); + ItemQuantityEntity itemQuantityEntity = new ItemQuantityEntity(); + itemQuantityEntity.setUnit(ItemUnitEnumeration.UNIT_PIECE); + itemQuantityEntity.setValue(20.0); + AllocatedStock allocatedStock = new AllocatedStock(itemQuantityEntity, site.getBpns(), false, address.getBpna(), + new Date()); + position.setAllocatedStocks(Set.of(allocatedStock)); + + String supplierOrderId = "abc123"; + String customerOrderId = "def456"; + String customerOrderPositionId = "ghi789"; + + OrderPositionReference orderPositionReference = new OrderPositionReference(supplierOrderId, customerOrderId, customerOrderPositionId); + position.setOrderPositionReference(orderPositionReference); + + itemStockSamm.setPositions(Set.of(position)); + + // then + List resultList = itemStockSammMapper.erpSammToProductItemStock(itemStockSamm, supplierPartner, semiconductorMaterial); + + Assertions.assertEquals(1, resultList.size()); + ProductItemStock productItemStock = resultList.getFirst(); + Assertions.assertEquals(productItemStock.getLocationBpna(), address.getBpna()); + Assertions.assertEquals(productItemStock.getLocationBpns(), site.getBpns()); + Assertions.assertEquals(productItemStock.getQuantity(), 20.0); + Assertions.assertEquals(productItemStock.getMeasurementUnit(), ItemUnitEnumeration.UNIT_PIECE); + Assertions.assertEquals(productItemStock.getMaterial(), semiconductorMaterial); + Assertions.assertEquals(productItemStock.getCustomerOrderId(), customerOrderId); + Assertions.assertEquals(productItemStock.getCustomerOrderPositionId(), customerOrderPositionId); + Assertions.assertEquals(productItemStock.getSupplierOrderId(), supplierOrderId); + Assertions.assertFalse(productItemStock.isBlocked()); + } + private List filterReportedItemStock(List reportedProductItemStocks, AllocatedStock allocatedStock, Position position, String cxMaterialNumber) { if (position.getOrderPositionReference() == null) {