From 70163b8a0ca0e3694ebb1a8aeddb709c88a322d4 Mon Sep 17 00:00:00 2001 From: BenjaminKotnik <158455098+BenjaminKotnik@users.noreply.github.com> Date: Tue, 11 Jun 2024 12:50:12 +0200 Subject: [PATCH 1/6] Days of supply (#15) feat: implemented the backend for Days of Supply --- .../DataInjectionCommandLineRunner.java | 2 - .../common/security/SecurityConfig.java | 1 + .../controller/DeliveryController.java | 4 +- ...sitory.java => OwnDeliveryRepository.java} | 2 +- .../service/DeliveryRequestApiService.java | 4 +- .../logic/service/OwnDeliveryService.java | 65 ++++++- .../service/ReportedDeliveryService.java | 59 +++++- .../demand/controller/DemandController.java | 4 +- .../services/DemandRequestApiService.java | 4 +- .../demand/logic/services/DemandService.java | 21 ++- .../logic/services/OwnDemandService.java | 30 +++ .../controller/ProductionController.java | 2 +- .../logic/service/OwnProductionService.java | 46 ++++- .../service/ProductionRequestApiService.java | 2 +- .../stock/logic/service/ItemStockService.java | 37 +++- .../service/MaterialItemStockService.java | 2 - .../supply/controller/SupplyController.java | 90 +++++++++ .../domain/model/OwnCustomerSupply.java | 35 ++++ .../domain/model/OwnSupplierSupply.java | 34 ++++ .../domain/model/ReportedCustomerSupply.java | 35 ++++ .../domain/model/ReportedSupplierSupply.java | 34 ++++ .../backend/supply/domain/model/Supply.java | 104 +++++++++++ .../ReportedCustomerSupplyRepository.java | 30 +++ .../ReportedSupplierSupplyRepository.java | 30 +++ .../backend/supply/logic/dto/SupplyDto.java | 38 ++++ .../logic/service/CustomerSupplyService.java | 175 ++++++++++++++++++ .../logic/service/SupplierSupplyService.java | 173 +++++++++++++++++ 27 files changed, 1033 insertions(+), 30 deletions(-) rename backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/domain/repository/{DeliveryRepository.java => OwnDeliveryRepository.java} (92%) create mode 100644 backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/controller/SupplyController.java create mode 100644 backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/model/OwnCustomerSupply.java create mode 100644 backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/model/OwnSupplierSupply.java create mode 100644 backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/model/ReportedCustomerSupply.java create mode 100644 backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/model/ReportedSupplierSupply.java create mode 100644 backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/model/Supply.java create mode 100644 backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/repository/ReportedCustomerSupplyRepository.java create mode 100644 backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/repository/ReportedSupplierSupplyRepository.java create mode 100644 backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/dto/SupplyDto.java create mode 100644 backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/CustomerSupplyService.java create mode 100644 backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/SupplierSupplyService.java diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/DataInjectionCommandLineRunner.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/DataInjectionCommandLineRunner.java index b84e8c3d..55ee9109 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/DataInjectionCommandLineRunner.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/DataInjectionCommandLineRunner.java @@ -78,7 +78,6 @@ public class DataInjectionCommandLineRunner implements CommandLineRunner { @Autowired private VariablesService variablesService; - @Autowired private ErpAdapterRequestService erpAdapterRequestService; @@ -490,5 +489,4 @@ private Material getNewCentralControlUnitMaterial() { material.setName("Central Control Unit"); return material; } - } diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/common/security/SecurityConfig.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/common/security/SecurityConfig.java index 468ea19d..da69ba0e 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/common/security/SecurityConfig.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/common/security/SecurityConfig.java @@ -96,6 +96,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { "/planned-production/**", "/material-demand/**", "/delivery-information/**", + "/supply/**", "/edc/**", "/erp-adapter/**", "/parttypeinformation/**" diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/controller/DeliveryController.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/controller/DeliveryController.java index df82500e..3b75b5ff 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/controller/DeliveryController.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/controller/DeliveryController.java @@ -108,9 +108,9 @@ public List getAllDeliveries(String ownMaterialNumber, Optional { +public interface OwnDeliveryRepository extends JpaRepository { } diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/logic/service/DeliveryRequestApiService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/logic/service/DeliveryRequestApiService.java index 11eb0919..37ed56d5 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/logic/service/DeliveryRequestApiService.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/logic/service/DeliveryRequestApiService.java @@ -90,7 +90,7 @@ public DeliveryInformation handleDeliverySubmodelRequest(String bpnl, String mat return null; } - var currentDeliveries = ownDeliveryService.findAllByFilters(Optional.of(material.getOwnMaterialNumber()), Optional.empty(), Optional.of(partner.getBpnl())); + var currentDeliveries = ownDeliveryService.findAllByFilters(Optional.of(material.getOwnMaterialNumber()), Optional.empty(), Optional.of(partner.getBpnl()), Optional.empty(), Optional.empty()); return sammMapper.ownDeliveryToSamm(currentDeliveries, partner, material); } @@ -114,7 +114,7 @@ public void doReportedDeliveryRequest(Partner partner, Material material) { } } // delete older data: - var oldDeliveries = reportedDeliveryService.findAllByFilters(Optional.of(material.getOwnMaterialNumber()), Optional.empty(), Optional.of(partner.getBpnl())); + var oldDeliveries = reportedDeliveryService.findAllByFilters(Optional.of(material.getOwnMaterialNumber()), Optional.empty(), Optional.of(partner.getBpnl()), Optional.empty(), Optional.empty()); for (var oldDelivery : oldDeliveries) { reportedDeliveryService.delete(oldDelivery.getUuid()); } diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/logic/service/OwnDeliveryService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/logic/service/OwnDeliveryService.java index 2ccca9d0..ba876ad2 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/logic/service/OwnDeliveryService.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/logic/service/OwnDeliveryService.java @@ -20,6 +20,11 @@ package org.eclipse.tractusx.puris.backend.delivery.logic.service; +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Optional; @@ -31,14 +36,15 @@ import org.eclipse.tractusx.puris.backend.delivery.domain.model.EventTypeEnumeration; import org.eclipse.tractusx.puris.backend.delivery.domain.model.OwnDelivery; -import org.eclipse.tractusx.puris.backend.delivery.domain.repository.DeliveryRepository; +import org.eclipse.tractusx.puris.backend.delivery.domain.repository.OwnDeliveryRepository; import org.eclipse.tractusx.puris.backend.masterdata.domain.model.Partner; import org.eclipse.tractusx.puris.backend.masterdata.logic.service.PartnerService; +import org.eclipse.tractusx.puris.backend.stock.logic.dto.itemstocksamm.DirectionCharacteristic; import org.springframework.stereotype.Service; @Service public class OwnDeliveryService { - public final DeliveryRepository repository; + private final OwnDeliveryRepository repository; private final PartnerService partnerService; @@ -46,7 +52,7 @@ public class OwnDeliveryService { private Partner ownPartnerEntity; - public OwnDeliveryService(DeliveryRepository repository, PartnerService partnerService) { + public OwnDeliveryService(OwnDeliveryRepository repository, PartnerService partnerService) { this.repository = repository; this.partnerService = partnerService; this.validator = this::validate; @@ -66,7 +72,12 @@ public final List findAllByOwnMaterialNumber(String ownMaterialNumb .toList(); } - public final List findAllByFilters(Optional ownMaterialNumber, Optional bpns, Optional bpnl) { + public final List findAllByFilters( + Optional ownMaterialNumber, + Optional bpns, + Optional bpnl, + Optional day, + Optional direction) { Stream stream = repository.findAll().stream(); if (ownMaterialNumber.isPresent()) { stream = stream.filter(delivery -> delivery.getMaterial().getOwnMaterialNumber().equals(ownMaterialNumber.get())); @@ -77,6 +88,27 @@ public final List findAllByFilters(Optional ownMaterialNumb if (bpnl.isPresent()) { stream = stream.filter(delivery -> delivery.getPartner().getBpnl().equals(bpnl.get())); } + if (day.isPresent()) { + LocalDate localDayDate = Instant.ofEpochMilli(day.get().getTime()) + .atOffset(ZoneOffset.UTC) + .toLocalDate(); + stream = stream.filter(delivery -> { + long time = direction.get() == DirectionCharacteristic.INBOUND + ? delivery.getDateOfArrival().getTime() + : delivery.getDateOfDeparture().getTime(); + LocalDate deliveryDayDate = Instant.ofEpochMilli(time) + .atOffset(ZoneOffset.UTC) + .toLocalDate(); + return deliveryDayDate.getDayOfMonth() == localDayDate.getDayOfMonth(); + }); + } + if (direction.isPresent()) { + if (direction.get() == DirectionCharacteristic.INBOUND) { + stream = stream.filter(delivery -> delivery.getDestinationBpns().equals(bpns.get())); + } else { + stream = stream.filter(delivery -> delivery.getOriginBpns().equals(bpns.get())); + } + } return stream.toList(); } @@ -84,6 +116,29 @@ public final OwnDelivery findById(UUID id) { return repository.findById(id).orElse(null); } + public final double getSumOfQuantities(List deliveries) { + double sum = 0; + for (OwnDelivery delivery : deliveries) { + sum += delivery.getQuantity(); + } + return sum; + } + + public final List getQuantityForDays(String material, String partnerBpnl, String siteBpns, DirectionCharacteristic direction, int numberOfDays) { + List deliveryQtys = new ArrayList<>(); + LocalDate localDate = LocalDate.now(); + + for (int i = 0; i < numberOfDays; i++) { + Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); + List deliveries = findAllByFilters(Optional.of(material), Optional.of(siteBpns), Optional.of(partnerBpnl), Optional.of(date), Optional.of(direction)); + double deliveryQuantity = getSumOfQuantities(deliveries); + deliveryQtys.add(deliveryQuantity); + + localDate = localDate.plusDays(1); + } + return deliveryQtys; + } + public final OwnDelivery create(OwnDelivery delivery) { if (!validator.apply(delivery)) { throw new IllegalArgumentException("Invalid delivery"); @@ -121,7 +176,7 @@ public boolean validate(OwnDelivery delivery) { ownPartnerEntity = partnerService.getOwnPartnerEntity(); } return - delivery.getQuantity() > 0 && + delivery.getQuantity() >= 0 && delivery.getMeasurementUnit() != null && delivery.getMaterial() != null && delivery.getPartner() != null && diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/logic/service/ReportedDeliveryService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/logic/service/ReportedDeliveryService.java index 3ff3c60b..0b96725d 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/logic/service/ReportedDeliveryService.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/logic/service/ReportedDeliveryService.java @@ -20,6 +20,11 @@ package org.eclipse.tractusx.puris.backend.delivery.logic.service; +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Optional; @@ -32,11 +37,12 @@ import org.eclipse.tractusx.puris.backend.delivery.domain.repository.ReportedDeliveryRepository; import org.eclipse.tractusx.puris.backend.masterdata.domain.model.Partner; import org.eclipse.tractusx.puris.backend.masterdata.logic.service.PartnerService; +import org.eclipse.tractusx.puris.backend.stock.logic.dto.itemstocksamm.DirectionCharacteristic; import org.springframework.stereotype.Service; @Service public class ReportedDeliveryService { - public final ReportedDeliveryRepository repository; + private final ReportedDeliveryRepository repository; private final PartnerService partnerService; @@ -63,7 +69,12 @@ public final ReportedDelivery findById(UUID id) { return repository.findById(id).orElse(null); } - public final List findAllByFilters(Optional ownMaterialNumber, Optional bpns, Optional bpnl) { + public final List findAllByFilters( + Optional ownMaterialNumber, + Optional bpns, + Optional bpnl, + Optional day, + Optional direction) { Stream stream = repository.findAll().stream(); if (ownMaterialNumber.isPresent()) { stream = stream.filter(delivery -> delivery.getMaterial().getOwnMaterialNumber().equals(ownMaterialNumber.get())); @@ -74,9 +85,53 @@ public final List findAllByFilters(Optional ownMateria if (bpnl.isPresent()) { stream = stream.filter(delivery -> delivery.getPartner().getBpnl().equals(bpnl.get())); } + if (day.isPresent()) { + LocalDate localDayDate = Instant.ofEpochMilli(day.get().getTime()) + .atOffset(ZoneOffset.UTC) + .toLocalDate(); + stream = stream.filter(delivery -> { + long time = direction.get() == DirectionCharacteristic.INBOUND + ? delivery.getDateOfArrival().getTime() + : delivery.getDateOfDeparture().getTime(); + LocalDate deliveryDayDate = Instant.ofEpochMilli(time) + .atOffset(ZoneOffset.UTC) + .toLocalDate(); + return deliveryDayDate.getDayOfMonth() == localDayDate.getDayOfMonth(); + }); + } + if (direction.isPresent()) { + if (direction.get() == DirectionCharacteristic.INBOUND) { + stream = stream.filter(delivery -> delivery.getDestinationBpns().equals(bpns.get())); + } else { + stream = stream.filter(delivery -> delivery.getOriginBpns().equals(bpns.get())); + } + } return stream.toList(); } + public final double getSumOfQuantities(List deliveries) { + double sum = 0; + for (ReportedDelivery delivery : deliveries) { + sum += delivery.getQuantity(); + } + return sum; + } + + public final List getQuantityForDays(String material, String partnerBpnl, String siteBpns, DirectionCharacteristic direction, int numberOfDays) { + List deliveryQtys = new ArrayList<>(); + LocalDate localDate = LocalDate.now(); + + for (int i = 0; i < numberOfDays; i++) { + Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); + List deliveries = findAllByFilters(Optional.of(material), Optional.of(siteBpns), Optional.of(partnerBpnl), Optional.of(date), Optional.of(direction)); + double deliveryQuantity = getSumOfQuantities(deliveries); + deliveryQtys.add(deliveryQuantity); + + localDate = localDate.plusDays(1); + } + return deliveryQtys; + } + public final ReportedDelivery create(ReportedDelivery delivery) { if (delivery.getUuid() != null && repository.findById(delivery.getUuid()).isPresent()) { return null; diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/demand/controller/DemandController.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/demand/controller/DemandController.java index 79bd61cf..15fb5eca 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/demand/controller/DemandController.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/demand/controller/DemandController.java @@ -91,7 +91,7 @@ public class DemandController { @ResponseBody @Operation(summary = "Get all own demands for the given Material", description = "Get all own demands for the given material number. Optionally the demanding site can be filtered by its bpns.") public List getAllDemands(String ownMaterialNumber, Optional site) { - return ownDemandService.findAllByFilters(Optional.of(ownMaterialNumber), Optional.empty(), site) + return ownDemandService.findAllByFilters(Optional.of(ownMaterialNumber), Optional.empty(), site, Optional.empty()) .stream().map(this::convertToDto).collect(Collectors.toList()); } @@ -171,7 +171,7 @@ public void deleteDemand(@PathVariable UUID id) { ) public List getAllDemandsForPartner(String ownMaterialNumber, Optional bpnl, Optional site) { - return reportedDemandService.findAllByFilters(Optional.of(ownMaterialNumber), bpnl, site) + return reportedDemandService.findAllByFilters(Optional.of(ownMaterialNumber), bpnl, site, Optional.empty()) .stream().map(this::convertToDto).collect(Collectors.toList()); } diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/demand/logic/services/DemandRequestApiService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/demand/logic/services/DemandRequestApiService.java index c3811da1..6d3c363a 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/demand/logic/services/DemandRequestApiService.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/demand/logic/services/DemandRequestApiService.java @@ -86,7 +86,7 @@ public ShortTermMaterialDemand handleDemandSubmodelRequest(String bpnl, String m return null; } - var currentDemands = ownDemandService.findAllByFilters(Optional.of(material.getOwnMaterialNumber()), Optional.of(partner.getBpnl()), Optional.empty()); + var currentDemands = ownDemandService.findAllByFilters(Optional.of(material.getOwnMaterialNumber()), Optional.of(partner.getBpnl()), Optional.empty(), Optional.empty()); return sammMapper.ownDemandToSamm(currentDemands, partner, material); } @@ -109,7 +109,7 @@ public void doReportedDemandRequest(Partner partner, Material material) { } } // delete older data: - var oldDemands = reportedDemandService.findAllByFilters(Optional.of(material.getOwnMaterialNumber()), Optional.of(partner.getBpnl()), Optional.empty()); + var oldDemands = reportedDemandService.findAllByFilters(Optional.of(material.getOwnMaterialNumber()), Optional.of(partner.getBpnl()), Optional.empty(), Optional.empty()); for (var oldDemand : oldDemands) { reportedDemandService.delete(oldDemand.getUuid()); } diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/demand/logic/services/DemandService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/demand/logic/services/DemandService.java index 391bbf90..ffde7cdf 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/demand/logic/services/DemandService.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/demand/logic/services/DemandService.java @@ -19,6 +19,10 @@ See the NOTICE file(s) distributed with this work for additional */ package org.eclipse.tractusx.puris.backend.demand.logic.services; +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneOffset; +import java.util.Date; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -63,7 +67,11 @@ public final List findAllByOwnMaterialNumber(String ownMaterialNumber) .toList(); } - public final List findAllByFilters(Optional ownMaterialNumber, Optional bpnl, Optional demandLocationBpns) { + public final List findAllByFilters( + Optional ownMaterialNumber, + Optional bpnl, + Optional demandLocationBpns, + Optional day) { var stream = repository.findAll().stream(); if (ownMaterialNumber.isPresent()) { stream = stream.filter(demand -> demand.getMaterial().getOwnMaterialNumber().equals(ownMaterialNumber.get())); @@ -74,6 +82,17 @@ public final List findAllByFilters(Optional ownMaterialNumber, if (demandLocationBpns.isPresent()) { stream = stream.filter(demand -> demand.getDemandLocationBpns().equals(demandLocationBpns.get())); } + if (day.isPresent()) { + LocalDate localDayDate = Instant.ofEpochMilli(day.get().getTime()) + .atOffset(ZoneOffset.UTC) + .toLocalDate(); + stream = stream.filter(demand -> { + LocalDate demandDayDate = Instant.ofEpochMilli(demand.getDay().getTime()) + .atOffset(ZoneOffset.UTC) + .toLocalDate(); + return demandDayDate.getDayOfMonth() == localDayDate.getDayOfMonth(); + }); + } return stream.toList(); } diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/demand/logic/services/OwnDemandService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/demand/logic/services/OwnDemandService.java index 68ed3bf2..027a8de2 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/demand/logic/services/OwnDemandService.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/demand/logic/services/OwnDemandService.java @@ -19,6 +19,13 @@ See the NOTICE file(s) distributed with this work for additional */ package org.eclipse.tractusx.puris.backend.demand.logic.services; +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Optional; + import org.eclipse.tractusx.puris.backend.demand.domain.model.OwnDemand; import org.eclipse.tractusx.puris.backend.demand.domain.repository.OwnDemandRepository; import org.eclipse.tractusx.puris.backend.masterdata.domain.model.Partner; @@ -32,6 +39,21 @@ public OwnDemandService(OwnDemandRepository repository, PartnerService partnerSe super(repository, partnerService, mprService); } + public final List getQuantityForDays(String material, String partnerBpnl, String siteBpns, int numberOfDays) { + List quantities = new ArrayList<>(); + LocalDate localDate = LocalDate.now(); + + for (int i = 0; i < numberOfDays; i++) { + Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); + List demands = findAllByFilters(Optional.of(material), Optional.of(partnerBpnl), Optional.of(siteBpns), Optional.of(date)); + double demandQuantity = getSumOfQuantities(demands); + quantities.add(demandQuantity); + + localDate = localDate.plusDays(1); + } + return quantities; + } + @Override public boolean validate(OwnDemand demand) { Partner ownPartnerEntity = partnerService.getOwnPartnerEntity(); @@ -48,4 +70,12 @@ public boolean validate(OwnDemand demand) { ownPartnerEntity.getSites().stream().anyMatch(site -> site.getBpns().equals(demand.getDemandLocationBpns())) && (demand.getSupplierLocationBpns() == null || demand.getPartner().getSites().stream().anyMatch(site -> site.getBpns().equals(demand.getSupplierLocationBpns()))); } + + private final double getSumOfQuantities(List demands) { + double sum = 0; + for (OwnDemand demand : demands) { + sum += demand.getQuantity(); + } + return sum; + } } diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/controller/ProductionController.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/controller/ProductionController.java index 259e7289..3f191757 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/controller/ProductionController.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/controller/ProductionController.java @@ -91,7 +91,7 @@ public class ProductionController { @ResponseBody @Operation(summary = "Get all planned productions for the given Material", description = "Get all planned productions for the given material number. Optionally the production site can be filtered by its bpns.") public List getAllProductions(String ownMaterialNumber, Optional site) { - return ownProductionService.findAllByFilters(Optional.of(ownMaterialNumber), Optional.empty(), site) + return ownProductionService.findAllByFilters(Optional.of(ownMaterialNumber), Optional.empty(), site, Optional.empty()) .stream().map(this::convertToDto).collect(Collectors.toList()); } diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/logic/service/OwnProductionService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/logic/service/OwnProductionService.java index d7602179..b78170bf 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/logic/service/OwnProductionService.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/logic/service/OwnProductionService.java @@ -20,6 +20,12 @@ See the NOTICE file(s) distributed with this work for additional package org.eclipse.tractusx.puris.backend.production.logic.service; +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.util.ArrayList; +import java.util.Date; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -62,7 +68,11 @@ public final List findAllByOwnMaterialNumber(String ownMaterialNu .toList(); } - public final List findAllByFilters(Optional ownMaterialNumber, Optional bpnl, Optional bpns) { + public final List findAllByFilters( + Optional ownMaterialNumber, + Optional bpnl, + Optional bpns, + Optional dayOfCompletion) { Stream stream = repository.findAll().stream(); if (ownMaterialNumber.isPresent()) { stream = stream.filter(production -> production.getMaterial().getOwnMaterialNumber().equals(ownMaterialNumber.get())); @@ -73,6 +83,17 @@ public final List findAllByFilters(Optional ownMaterialNu if (bpns.isPresent()) { stream = stream.filter(production -> production.getProductionSiteBpns().equals(bpns.get())); } + if (dayOfCompletion.isPresent()) { + LocalDate localEstimatedTimeOfCompletion = Instant.ofEpochMilli(dayOfCompletion.get().getTime()) + .atOffset(ZoneOffset.UTC) + .toLocalDate(); + stream = stream.filter(production -> { + LocalDate productionEstimatedTimeOfCompletion = Instant.ofEpochMilli(production.getEstimatedTimeOfCompletion().getTime()) + .atOffset(ZoneOffset.UTC) + .toLocalDate(); + return productionEstimatedTimeOfCompletion.getDayOfMonth() == localEstimatedTimeOfCompletion.getDayOfMonth(); + }); + } return stream.toList(); } @@ -80,6 +101,21 @@ public final OwnProduction findById(UUID uuid) { return repository.findById(uuid).orElse(null); } + public final List getQuantityForDays(String material, String partnerBpnl, String siteBpns, int numberOfDays) { + List quantities = new ArrayList<>(); + LocalDate localDate = LocalDate.now(); + + for (int i = 0; i < numberOfDays; i++) { + Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); + List productions = findAllByFilters(Optional.of(material), Optional.of(partnerBpnl), Optional.of(siteBpns), Optional.of(date)); + double productionQuantity = getSumOfQuantities(productions); + quantities.add(productionQuantity); + + localDate = localDate.plusDays(1); + } + return quantities; + } + public final OwnProduction create(OwnProduction production) { if (!validator.apply(production)) { @@ -133,4 +169,12 @@ public boolean validate(OwnProduction production) { production.getSupplierOrderNumber() == null )); } + + private final double getSumOfQuantities(List productions) { + double sum = 0; + for (OwnProduction production : productions) { + sum += production.getQuantity(); + } + return sum; + } } diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/logic/service/ProductionRequestApiService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/logic/service/ProductionRequestApiService.java index 3aa173b6..d5e5a1d4 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/logic/service/ProductionRequestApiService.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/logic/service/ProductionRequestApiService.java @@ -73,7 +73,7 @@ public PlannedProductionOutput handleProductionSubmodelRequest(String bpnl, Stri // only send an answer if partner is registered as customer return null; } - var currentProduction = ownProductionService.findAllByFilters(Optional.of(material.getOwnMaterialNumber()), Optional.of(partner.getBpnl()), Optional.empty()); + var currentProduction = ownProductionService.findAllByFilters(Optional.of(material.getOwnMaterialNumber()), Optional.of(partner.getBpnl()), Optional.empty(), Optional.empty()); return sammMapper.ownProductionToSamm(currentProduction, partner, material); } diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/stock/logic/service/ItemStockService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/stock/logic/service/ItemStockService.java index b3d8258f..06362371 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/stock/logic/service/ItemStockService.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/stock/logic/service/ItemStockService.java @@ -20,6 +20,7 @@ package org.eclipse.tractusx.puris.backend.stock.logic.service; import lombok.extern.slf4j.Slf4j; + 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; @@ -32,7 +33,7 @@ import java.util.Objects; import java.util.UUID; import java.util.function.Function; - +import java.util.stream.Stream; @Slf4j public abstract class ItemStockService { @@ -45,7 +46,8 @@ public abstract class ItemStockService { protected final Function validator; - public ItemStockService(PartnerService partnerService, MaterialPartnerRelationService mprService, ItemStockRepository repository) { + public ItemStockService(PartnerService partnerService, MaterialPartnerRelationService mprService, + ItemStockRepository repository) { this.partnerService = partnerService; this.mprService = mprService; this.repository = repository; @@ -105,6 +107,29 @@ public final List findByPartnerBpnlAndOwnMaterialNumber(String partnerBpnl, S return repository.getForPartnerBpnlAndOwnMatNbr(partnerBpnl, ownMaterialNumber); } + public final List findAllByMaterialAndPartner(String ownMaterialNumber, String partnerBpnl) { + Stream stream = repository.findAll().stream(); + + stream = stream.filter(stock -> stock.getMaterial().getOwnMaterialNumber().equals(ownMaterialNumber)); + stream = stream.filter(stock -> stock.getPartner().getBpnl().equals(partnerBpnl)); + return stream.toList(); + } + + public final double getSumOfQuantities(List stocks) { + double sum = 0; + for (T stock : stocks) { + sum = stock.getQuantity(); + } + return sum; + } + + public final double getInitialStockQuantity(String material, String partnerBpnl) { + List stocks = findAllByMaterialAndPartner(material, partnerBpnl); + double initialStockQuantity = getSumOfQuantities(stocks); + + return initialStockQuantity; + } + public abstract boolean validate(T itemStock); protected boolean basicValidation(ItemStock itemStock) { @@ -171,12 +196,12 @@ protected final boolean validateProductItemStock(ItemStock itemStock) { protected boolean validateLocation(ItemStock itemStock, Partner partner) { try { var stockSite = partner.getSites().stream() - .filter(site -> site.getBpns().equals(itemStock.getLocationBpns())) - .findFirst().orElse(null); + .filter(site -> site.getBpns().equals(itemStock.getLocationBpns())) + .findFirst().orElse(null); Objects.requireNonNull(stockSite, "Site not found"); var stockAddress = stockSite.getAddresses().stream() - .filter(addr -> addr.getBpna().equals(itemStock.getLocationBpna())) - .findFirst().orElse(null); + .filter(addr -> addr.getBpna().equals(itemStock.getLocationBpna())) + .findFirst().orElse(null); Objects.requireNonNull(stockAddress, "Address not found"); } catch (Exception e) { log.error("Location Validation failed: " + itemStock + "\n" + e.getMessage()); diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/stock/logic/service/MaterialItemStockService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/stock/logic/service/MaterialItemStockService.java index 8f0b79e0..a4430938 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/stock/logic/service/MaterialItemStockService.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/stock/logic/service/MaterialItemStockService.java @@ -44,6 +44,4 @@ public boolean validate(MaterialItemStock materialItemStock) { return basicValidation(materialItemStock) && validateLocalStock(materialItemStock) && validateMaterialItemStock(materialItemStock); } - - } diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/controller/SupplyController.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/controller/SupplyController.java new file mode 100644 index 00000000..927af4ab --- /dev/null +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/controller/SupplyController.java @@ -0,0 +1,90 @@ +/* + * 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.supply.controller; + +import java.util.List; +import java.util.Optional; + +import org.eclipse.tractusx.puris.backend.supply.domain.model.Supply; +import org.eclipse.tractusx.puris.backend.supply.logic.dto.SupplyDto; +import org.eclipse.tractusx.puris.backend.supply.logic.service.CustomerSupplyService; +import org.eclipse.tractusx.puris.backend.supply.logic.service.SupplierSupplyService; +import org.modelmapper.ModelMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import io.swagger.v3.oas.annotations.Operation; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; + + + +@RestController +@RequestMapping("supply") +public class SupplyController { + @Autowired + private CustomerSupplyService customerSupplyService; + @Autowired + private SupplierSupplyService supplierSupplyService; + + @Autowired + private ModelMapper modelMapper; + + @GetMapping("customer") + @ResponseBody + @Operation(summary = "Calculate days of supply for customer for given number of days.", + description = "Calculate days of supply for customer for given number of days. Filtered by given material number, partner bpnl and site bpns.") + public List calculateCustomerDaysOfSupply(String materialNumber, String bpnl, String siteBpns, int numberOfDays) { + return customerSupplyService.calculateCustomerDaysOfSupply(materialNumber, bpnl, siteBpns, numberOfDays) + .stream().map(this::convertToDto).toList(); + } + + @GetMapping("customer/reported") + @Operation(summary = "Get days of supply for customer.", + description = "Get days of supply for customer for given material number. Optionally it can be filtered by partner bpnl.") + public List getCustomerDaysOfSupply(String materialNumber, Optional bpnl) { + return customerSupplyService.findAllByFilters(Optional.of(materialNumber), bpnl) + .stream().map(this::convertToDto).toList(); + } + + @GetMapping("supplier") + @Operation(summary = "Calculate days of supply for supplier for given number of days.", + description = "Calculate days of supply for supplier for given number of days. Filtered by given material number, partner bpnl and site bpns.") + public List calculateSupplierDaysOfSupply(String materialNumber, String bpnl, String siteBpns, int numberOfDays) { + return supplierSupplyService.calculateSupplierDaysOfSupply(materialNumber, bpnl, siteBpns, numberOfDays) + .stream().map(this::convertToDto).toList(); + } + + @GetMapping("supplier/reported") + @Operation(summary = "Get days of supply for supplier.", + description = "Get days of supply for supplier for given material number. Optionally it can be filtered by partner bpnl.") + public List getSupplierDaysOfSupply(String materialNumber, Optional bpnl) { + return supplierSupplyService.findAllByFilters(Optional.of(materialNumber), bpnl) + .stream().map(this::convertToDto).toList(); + } + + private SupplyDto convertToDto(Supply entity) { + SupplyDto dto = modelMapper.map(entity, SupplyDto.class); + + return dto; + } +} diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/model/OwnCustomerSupply.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/model/OwnCustomerSupply.java new file mode 100644 index 00000000..ef0bec6b --- /dev/null +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/model/OwnCustomerSupply.java @@ -0,0 +1,35 @@ +/* + * 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.supply.domain.model; + + import jakarta.persistence.Entity; + import lombok.NoArgsConstructor; + import lombok.ToString; + import lombok.experimental.SuperBuilder; + + @Entity + @SuperBuilder + @NoArgsConstructor + @ToString(callSuper = true) + public class OwnCustomerSupply extends Supply { + + } + \ No newline at end of file diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/model/OwnSupplierSupply.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/model/OwnSupplierSupply.java new file mode 100644 index 00000000..0bba8c0c --- /dev/null +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/model/OwnSupplierSupply.java @@ -0,0 +1,34 @@ +/* + * 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.supply.domain.model; + +import jakarta.persistence.Entity; +import lombok.NoArgsConstructor; +import lombok.ToString; +import lombok.experimental.SuperBuilder; + +@Entity +@SuperBuilder +@NoArgsConstructor +@ToString(callSuper = true) +public class OwnSupplierSupply extends Supply { + +} diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/model/ReportedCustomerSupply.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/model/ReportedCustomerSupply.java new file mode 100644 index 00000000..6f0b6dd6 --- /dev/null +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/model/ReportedCustomerSupply.java @@ -0,0 +1,35 @@ +/* + * 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.supply.domain.model; + + import jakarta.persistence.Entity; + import lombok.NoArgsConstructor; + import lombok.ToString; + import lombok.experimental.SuperBuilder; + + @Entity + @SuperBuilder + @NoArgsConstructor + @ToString(callSuper = true) + public class ReportedCustomerSupply extends Supply { + + } + \ No newline at end of file diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/model/ReportedSupplierSupply.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/model/ReportedSupplierSupply.java new file mode 100644 index 00000000..ff2583fa --- /dev/null +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/model/ReportedSupplierSupply.java @@ -0,0 +1,34 @@ +/* + * 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.supply.domain.model; + +import jakarta.persistence.Entity; +import lombok.NoArgsConstructor; +import lombok.ToString; +import lombok.experimental.SuperBuilder; + +@Entity +@SuperBuilder +@NoArgsConstructor +@ToString(callSuper = true) +public class ReportedSupplierSupply extends Supply { + +} diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/model/Supply.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/model/Supply.java new file mode 100644 index 00000000..8a106ea4 --- /dev/null +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/model/Supply.java @@ -0,0 +1,104 @@ +/* + * 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.supply.domain.model; + +import org.eclipse.tractusx.puris.backend.common.util.PatternStore; +import org.eclipse.tractusx.puris.backend.masterdata.domain.model.Material; +import org.eclipse.tractusx.puris.backend.masterdata.domain.model.Partner; + +import java.util.UUID; +import java.util.Date; +import java.util.Objects; + +import jakarta.persistence.*; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; +import lombok.experimental.SuperBuilder; + +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +@SuperBuilder +@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) +@Entity +@ToString +public abstract class Supply { + // customer controller, supplier controller + // in dto flatten material and partner + @Id + @GeneratedValue + protected UUID uuid; + + @ManyToOne() + @JoinColumn(name = "partner_uuid") + @ToString.Exclude + @NotNull + protected Partner partner; + + @ManyToOne() + @JoinColumn(name = "material_ownMaterialNumber") + @ToString.Exclude + @NotNull + protected Material material; + + @Pattern(regexp = PatternStore.BPNA_STRING) + private String stockLocationBPNA; + + @Pattern(regexp = PatternStore.BPNS_STRING) + private String stockLocationBPNS; + + private Date date; + private double daysOfSupply; + + @ToString.Include + private String material_ownMaterialNumber() { + return material.getOwnMaterialNumber(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + final Supply that = (Supply) o; + return this.getMaterial().getOwnMaterialNumber().equals(that.getMaterial().getOwnMaterialNumber()) && + this.getPartner().getUuid().equals(that.getPartner().getUuid()) && + this.getStockLocationBPNA().equals(that.getStockLocationBPNA()) && + this.getStockLocationBPNS().equals(that.getStockLocationBPNS()) && + this.getDate().equals(that.getDate()) && + this.getDaysOfSupply() == that.getDaysOfSupply(); + } + + @Override + public int hashCode() { + return Objects.hash(partner, material, stockLocationBPNA, stockLocationBPNS, date, daysOfSupply); + } +} diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/repository/ReportedCustomerSupplyRepository.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/repository/ReportedCustomerSupplyRepository.java new file mode 100644 index 00000000..4bade94e --- /dev/null +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/repository/ReportedCustomerSupplyRepository.java @@ -0,0 +1,30 @@ +/* + * 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.supply.domain.repository; + +import java.util.UUID; + +import org.eclipse.tractusx.puris.backend.supply.domain.model.ReportedCustomerSupply; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ReportedCustomerSupplyRepository extends JpaRepository { + +} diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/repository/ReportedSupplierSupplyRepository.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/repository/ReportedSupplierSupplyRepository.java new file mode 100644 index 00000000..b8adca23 --- /dev/null +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/repository/ReportedSupplierSupplyRepository.java @@ -0,0 +1,30 @@ +/* + * 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.supply.domain.repository; + +import java.util.UUID; + +import org.eclipse.tractusx.puris.backend.supply.domain.model.ReportedSupplierSupply; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ReportedSupplierSupplyRepository extends JpaRepository { + +} diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/dto/SupplyDto.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/dto/SupplyDto.java new file mode 100644 index 00000000..2a188af5 --- /dev/null +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/dto/SupplyDto.java @@ -0,0 +1,38 @@ +/* + * 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.supply.logic.dto; + +import java.io.Serializable; +import java.util.Date; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@ToString +public class SupplyDto implements Serializable { + private Date date; + private double daysOfSupply; +} diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/CustomerSupplyService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/CustomerSupplyService.java new file mode 100644 index 00000000..ddada0f8 --- /dev/null +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/CustomerSupplyService.java @@ -0,0 +1,175 @@ +/* + * 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.supply.logic.service; + +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.function.Function; +import java.util.stream.Stream; + +import org.eclipse.tractusx.puris.backend.delivery.logic.service.OwnDeliveryService; +import org.eclipse.tractusx.puris.backend.delivery.logic.service.ReportedDeliveryService; +import org.eclipse.tractusx.puris.backend.demand.logic.services.OwnDemandService; +import org.eclipse.tractusx.puris.backend.masterdata.logic.service.MaterialServiceImpl; +import org.eclipse.tractusx.puris.backend.masterdata.logic.service.PartnerService; +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.supply.domain.model.OwnCustomerSupply; +import org.eclipse.tractusx.puris.backend.supply.domain.model.ReportedCustomerSupply; +import org.eclipse.tractusx.puris.backend.supply.domain.repository.ReportedCustomerSupplyRepository; +import org.springframework.stereotype.Service; + +@Service +public class CustomerSupplyService { + private final ReportedCustomerSupplyRepository repository; + private final PartnerService partnerService; + private final OwnDeliveryService ownDeliveryService; + private final ReportedDeliveryService reportedDeliveryService; + private final OwnDemandService demandService; + private final MaterialItemStockService stockService; + private final MaterialServiceImpl materialService; + + protected final Function validator; + + public CustomerSupplyService( + ReportedCustomerSupplyRepository customerRepository, + PartnerService partnerService, + OwnDeliveryService ownDeliveryService, + ReportedDeliveryService reportedDeliveryService, + OwnDemandService demandService, + MaterialItemStockService stockService, + MaterialServiceImpl materialService) { + this.repository = customerRepository; + this.partnerService = partnerService; + this.ownDeliveryService = ownDeliveryService; + this.reportedDeliveryService = reportedDeliveryService; + this.demandService = demandService; + this.stockService = stockService; + this.materialService = materialService; + this.validator = this::validate; + } + + public final List calculateCustomerDaysOfSupply(String material, String partnerBpnl, String siteBpns, int numberOfDays) { + List customerSupply = new ArrayList<>(); + LocalDate localDate = LocalDate.now(); + + List demands = demandService.getQuantityForDays(material, partnerBpnl, siteBpns, numberOfDays); + + List ownDeliveries = ownDeliveryService.getQuantityForDays(material, partnerBpnl, siteBpns, DirectionCharacteristic.INBOUND, numberOfDays); + List reportedDeliveries = reportedDeliveryService.getQuantityForDays(material, partnerBpnl, siteBpns, DirectionCharacteristic.INBOUND, numberOfDays); + List deliveries = mergeDeliveries(ownDeliveries, reportedDeliveries); + + double stockQuantity = stockService.getInitialStockQuantity(material, partnerBpnl); + + for (int i = 0; i < numberOfDays; i++) { + Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); + + if (i == numberOfDays - 1) { + stockQuantity += deliveries.get(i); + } + + double daysOfSupply = getDaysOfSupply( + stockQuantity, + demands.subList(i, demands.size())); + + OwnCustomerSupply supply = new OwnCustomerSupply(); + supply.setMaterial(materialService.findByOwnMaterialNumber(material)); + supply.setDate(date); + supply.setDaysOfSupply(daysOfSupply); + customerSupply.add(supply); + + stockQuantity = stockQuantity - demands.get(i) + deliveries.get(i); + + localDate = localDate.plusDays(1); + } + + return customerSupply; + } + + public final List findAll() { + return repository.findAll(); + } + + public final ReportedCustomerSupply findById(UUID id) { + return repository.findById(id).orElse(null); + } + + public final List findAllByFilters(Optional ownMaterialNumber, Optional bpnl) { + Stream stream = repository.findAll().stream(); + if (ownMaterialNumber.isPresent()) { + stream = stream.filter(dayOfSupply -> dayOfSupply.getMaterial().getOwnMaterialNumber().equals(ownMaterialNumber.get())); + } + if (bpnl.isPresent()) { + stream = stream.filter(dayOfSupply -> dayOfSupply.getPartner().getBpnl().equals(bpnl.get())); + } + return stream.toList(); + } + + public boolean validate(ReportedCustomerSupply daysOfSupply) { + return + daysOfSupply.getPartner() != null && + daysOfSupply.getMaterial() != null && + daysOfSupply.getDate() != null && + daysOfSupply.getStockLocationBPNS() != null && + daysOfSupply.getPartner() != partnerService.getOwnPartnerEntity() && + daysOfSupply.getPartner().getSites().stream().anyMatch(site -> site.getBpns().equals(daysOfSupply.getStockLocationBPNS())) && + (daysOfSupply.getStockLocationBPNA() == null || daysOfSupply.getStockLocationBPNA() == daysOfSupply.getStockLocationBPNS()); + } + + private final double getDaysOfSupply(double stockQuantity, List demands) { + double daysOfSupply = 0; + + for (int i = 0; i < demands.size(); i++) { + double demand = demands.get(i); + + if (stockQuantity >= demand) { + daysOfSupply += 1; + stockQuantity = stockQuantity - demand; + } else if (stockQuantity < demand && stockQuantity > 0) { + double fractional = stockQuantity / demand; + daysOfSupply = daysOfSupply + fractional; + break; + } else { + break; + } + } + return daysOfSupply; + } + + private static List mergeDeliveries(List list1, List list2) { + if (list1.size() != list2.size()) { + throw new IllegalArgumentException("Lists must be of the same length"); + } + + List mergedList = new ArrayList<>(list1.size()); + + for (int i = 0; i < list1.size(); i++) { + mergedList.add(list1.get(i) + list2.get(i)); + } + + return mergedList; + } +} diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/SupplierSupplyService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/SupplierSupplyService.java new file mode 100644 index 00000000..ee581c26 --- /dev/null +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/SupplierSupplyService.java @@ -0,0 +1,173 @@ +/* + * 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.supply.logic.service; + +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.function.Function; +import java.util.stream.Stream; + +import org.eclipse.tractusx.puris.backend.delivery.logic.service.OwnDeliveryService; +import org.eclipse.tractusx.puris.backend.delivery.logic.service.ReportedDeliveryService; +import org.eclipse.tractusx.puris.backend.masterdata.logic.service.MaterialServiceImpl; +import org.eclipse.tractusx.puris.backend.masterdata.logic.service.PartnerService; +import org.eclipse.tractusx.puris.backend.production.logic.service.OwnProductionService; +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.supply.domain.model.OwnSupplierSupply; +import org.eclipse.tractusx.puris.backend.supply.domain.model.ReportedSupplierSupply; +import org.eclipse.tractusx.puris.backend.supply.domain.repository.ReportedSupplierSupplyRepository; +import org.springframework.stereotype.Service; + +@Service +public class SupplierSupplyService { + private final ReportedSupplierSupplyRepository repository; + private final PartnerService partnerService; + private final OwnDeliveryService ownDeliveryService; + private final ReportedDeliveryService reportedDeliveryService; + private final OwnProductionService productionService; + private final MaterialItemStockService stockService; + private final MaterialServiceImpl materialService; + + protected final Function validator; + + public SupplierSupplyService( + ReportedSupplierSupplyRepository repository, + PartnerService partnerService, + OwnDeliveryService ownDeliveryService, + ReportedDeliveryService reportedDeliveryService, + OwnProductionService productionService, + MaterialItemStockService stockService, + MaterialServiceImpl materialService) { + this.repository = repository; + this.partnerService = partnerService; + this.ownDeliveryService = ownDeliveryService; + this.reportedDeliveryService = reportedDeliveryService; + this.productionService = productionService; + this.stockService = stockService; + this.materialService = materialService; + this.validator = this::validate; + } + + public final List calculateSupplierDaysOfSupply(String material, String partnerBpnl, String siteBpns, int numberOfDays) { + List supplierSupply = new ArrayList<>(); + LocalDate localDate = LocalDate.now(); + + List ownDeliveries = ownDeliveryService.getQuantityForDays(material, partnerBpnl, siteBpns, DirectionCharacteristic.OUTBOUND, numberOfDays); + List reportedDeliveries = reportedDeliveryService.getQuantityForDays(material, partnerBpnl, siteBpns, DirectionCharacteristic.OUTBOUND, numberOfDays); + List deliveries = mergeDeliveries(ownDeliveries, reportedDeliveries); + List productions = productionService.getQuantityForDays(material, partnerBpnl, siteBpns, numberOfDays); + double stockQuantity = stockService.getInitialStockQuantity(material, partnerBpnl); + + for (int i = 0; i < numberOfDays; i++) { + Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); + + if (i == numberOfDays - 1) { + stockQuantity += productions.get(i); + } + + double daysOfSupply = getDaysOfSupply( + stockQuantity, + deliveries.subList(i, deliveries.size())); + + OwnSupplierSupply supply = new OwnSupplierSupply(); + supply.setMaterial(materialService.findByOwnMaterialNumber(material)); + supply.setDate(date); + supply.setDaysOfSupply(daysOfSupply); + supplierSupply.add(supply); + + stockQuantity = stockQuantity - deliveries.get(i) + productions.get(i); + + localDate = localDate.plusDays(1); + } + + return supplierSupply; + } + + public final List findAll() { + return repository.findAll(); + } + + public final ReportedSupplierSupply findById(UUID id) { + return repository.findById(id).orElse(null); + } + + public final List findAllByFilters(Optional ownMaterialNumber, Optional bpnl) { + Stream stream = repository.findAll().stream(); + if (ownMaterialNumber.isPresent()) { + stream = stream.filter(dayOfSupply -> dayOfSupply.getMaterial().getOwnMaterialNumber().equals(ownMaterialNumber.get())); + } + if (bpnl.isPresent()) { + stream = stream.filter(dayOfSupply -> dayOfSupply.getPartner().getBpnl().equals(bpnl.get())); + } + return stream.toList(); + } + + public boolean validate(ReportedSupplierSupply daysOfSupply) { + return + daysOfSupply.getPartner() != null && + daysOfSupply.getMaterial() != null && + daysOfSupply.getDate() != null && + daysOfSupply.getStockLocationBPNS() != null && + daysOfSupply.getPartner() != partnerService.getOwnPartnerEntity() && + daysOfSupply.getPartner().getSites().stream().anyMatch(site -> site.getBpns().equals(daysOfSupply.getStockLocationBPNS())) && + (daysOfSupply.getStockLocationBPNA() == null || daysOfSupply.getStockLocationBPNA() == daysOfSupply.getStockLocationBPNS()); + } + + private final double getDaysOfSupply(double stockQuantity, List demands) { + double daysOfSupply = 0; + + for (int i = 0; i < demands.size(); i++) { + double demand = demands.get(i); + + if (stockQuantity >= demand) { + daysOfSupply += 1; + stockQuantity = stockQuantity - demand; + } else if (stockQuantity < demand && stockQuantity > 0) { + double fractional = stockQuantity / demand; + daysOfSupply = daysOfSupply + fractional; + break; + } else { + break; + } + } + return daysOfSupply; + } + + private static List mergeDeliveries(List list1, List list2) { + if (list1.size() != list2.size()) { + throw new IllegalArgumentException("Lists must be of the same length"); + } + + List mergedList = new ArrayList<>(list1.size()); + + for (int i = 0; i < list1.size(); i++) { + mergedList.add(list1.get(i) + list2.get(i)); + } + + return mergedList; + } +} From c61eed90e283595b9cd111afdc60973276e8ca6a Mon Sep 17 00:00:00 2001 From: Benjamin Kotnik Date: Tue, 11 Jun 2024 13:56:42 +0200 Subject: [PATCH 2/6] fix: added missing optional empty parameters --- .../delivery/controller/DeliveryRequestApiServiceTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/backend/src/test/java/org/eclipse/tractusx/puris/backend/delivery/controller/DeliveryRequestApiServiceTest.java b/backend/src/test/java/org/eclipse/tractusx/puris/backend/delivery/controller/DeliveryRequestApiServiceTest.java index 9cdc187a..c3890972 100644 --- a/backend/src/test/java/org/eclipse/tractusx/puris/backend/delivery/controller/DeliveryRequestApiServiceTest.java +++ b/backend/src/test/java/org/eclipse/tractusx/puris/backend/delivery/controller/DeliveryRequestApiServiceTest.java @@ -182,7 +182,9 @@ void customerGetsRequestNoCxId_testHandleDeliverySubmodelRequest_works() { when(ownDeliveryService.findAllByFilters( Optional.of(mpr.getMaterial().getOwnMaterialNumber()), Optional.empty(), - Optional.of(BPNL_SUPPLIER) + Optional.of(BPNL_SUPPLIER), + Optional.empty(), + Optional.empty() )).thenReturn(deliveries); // return mpr after update From e9d2e5ef3c05ebcd538530b0462d18a058167133 Mon Sep 17 00:00:00 2001 From: Benjamin Kotnik Date: Tue, 11 Jun 2024 22:00:45 +0200 Subject: [PATCH 3/6] fix(days-of-supply): evaluated strings with equals() --- .../backend/supply/logic/service/CustomerSupplyService.java | 2 +- .../backend/supply/logic/service/SupplierSupplyService.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/CustomerSupplyService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/CustomerSupplyService.java index ddada0f8..0d194083 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/CustomerSupplyService.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/CustomerSupplyService.java @@ -136,7 +136,7 @@ public boolean validate(ReportedCustomerSupply daysOfSupply) { daysOfSupply.getStockLocationBPNS() != null && daysOfSupply.getPartner() != partnerService.getOwnPartnerEntity() && daysOfSupply.getPartner().getSites().stream().anyMatch(site -> site.getBpns().equals(daysOfSupply.getStockLocationBPNS())) && - (daysOfSupply.getStockLocationBPNA() == null || daysOfSupply.getStockLocationBPNA() == daysOfSupply.getStockLocationBPNS()); + (daysOfSupply.getStockLocationBPNA().equals(null) || daysOfSupply.getStockLocationBPNA().equals(daysOfSupply.getStockLocationBPNS())); } private final double getDaysOfSupply(double stockQuantity, List demands) { diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/SupplierSupplyService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/SupplierSupplyService.java index ee581c26..1990011b 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/SupplierSupplyService.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/SupplierSupplyService.java @@ -134,7 +134,7 @@ public boolean validate(ReportedSupplierSupply daysOfSupply) { daysOfSupply.getStockLocationBPNS() != null && daysOfSupply.getPartner() != partnerService.getOwnPartnerEntity() && daysOfSupply.getPartner().getSites().stream().anyMatch(site -> site.getBpns().equals(daysOfSupply.getStockLocationBPNS())) && - (daysOfSupply.getStockLocationBPNA() == null || daysOfSupply.getStockLocationBPNA() == daysOfSupply.getStockLocationBPNS()); + (daysOfSupply.getStockLocationBPNA().equals(null) || daysOfSupply.getStockLocationBPNA().equals(daysOfSupply.getStockLocationBPNS())); } private final double getDaysOfSupply(double stockQuantity, List demands) { From 13dfa1016f37f07892c9888c4ff66937f635c05e Mon Sep 17 00:00:00 2001 From: Benjamin Kotnik Date: Wed, 12 Jun 2024 16:15:40 +0200 Subject: [PATCH 4/6] fix(days-of-supply): PR changes --- .../common/security/SecurityConfig.java | 2 +- .../domain/repository/DeliveryRepository.java | 30 +++++ .../repository/OwnDeliveryRepository.java | 5 +- .../ReportedDeliveryRepository.java | 5 +- .../logic/service/DeliveryService.java | 123 ++++++++++++++++++ .../logic/service/OwnDeliveryService.java | 93 +------------ .../service/ReportedDeliveryService.java | 92 +------------ .../controller/ProductionController.java | 2 +- .../repository/OwnProductionRepository.java | 5 +- .../repository/ProductionRepository.java | 10 ++ .../ReportedProductionRepository.java | 5 +- .../logic/service/OwnProductionService.java | 92 +------------ .../service/ProductionRequestApiService.java | 2 +- .../logic/service/ProductionService.java | 102 +++++++++++++++ .../service/ReportedProductionService.java | 48 +------ .../supply/controller/SupplyController.java | 17 +-- .../domain/model/OwnCustomerSupply.java | 64 ++++----- .../domain/model/OwnSupplierSupply.java | 1 + .../backend/supply/domain/model/Supply.java | 2 - .../ReportedCustomerSupplyRepository.java | 3 +- .../ReportedSupplierSupplyRepository.java | 4 +- .../logic/service/CustomerSupplyService.java | 70 ++++++---- .../logic/service/SupplierSupplyService.java | 72 ++++++---- 23 files changed, 410 insertions(+), 439 deletions(-) create mode 100644 backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/domain/repository/DeliveryRepository.java create mode 100644 backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/logic/service/DeliveryService.java create mode 100644 backend/src/main/java/org/eclipse/tractusx/puris/backend/production/domain/repository/ProductionRepository.java create mode 100644 backend/src/main/java/org/eclipse/tractusx/puris/backend/production/logic/service/ProductionService.java diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/common/security/SecurityConfig.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/common/security/SecurityConfig.java index da69ba0e..7df8c3e8 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/common/security/SecurityConfig.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/common/security/SecurityConfig.java @@ -96,7 +96,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { "/planned-production/**", "/material-demand/**", "/delivery-information/**", - "/supply/**", + "/days-of-supply/**", "/edc/**", "/erp-adapter/**", "/parttypeinformation/**" diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/domain/repository/DeliveryRepository.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/domain/repository/DeliveryRepository.java new file mode 100644 index 00000000..cea7881b --- /dev/null +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/domain/repository/DeliveryRepository.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2023, 2024 Volkswagen AG + * Copyright (c) 2023, 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.delivery.domain.repository; + +import java.util.UUID; + +import org.eclipse.tractusx.puris.backend.delivery.domain.model.Delivery; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface DeliveryRepository extends JpaRepository { + +} diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/domain/repository/OwnDeliveryRepository.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/domain/repository/OwnDeliveryRepository.java index 2d94a785..f1111d00 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/domain/repository/OwnDeliveryRepository.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/domain/repository/OwnDeliveryRepository.java @@ -20,11 +20,8 @@ package org.eclipse.tractusx.puris.backend.delivery.domain.repository; -import java.util.UUID; - import org.eclipse.tractusx.puris.backend.delivery.domain.model.OwnDelivery; -import org.springframework.data.jpa.repository.JpaRepository; -public interface OwnDeliveryRepository extends JpaRepository { +public interface OwnDeliveryRepository extends DeliveryRepository { } diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/domain/repository/ReportedDeliveryRepository.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/domain/repository/ReportedDeliveryRepository.java index 6dc5ef77..dfeaec5c 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/domain/repository/ReportedDeliveryRepository.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/domain/repository/ReportedDeliveryRepository.java @@ -20,11 +20,8 @@ package org.eclipse.tractusx.puris.backend.delivery.domain.repository; -import java.util.UUID; - import org.eclipse.tractusx.puris.backend.delivery.domain.model.ReportedDelivery; -import org.springframework.data.jpa.repository.JpaRepository; -public interface ReportedDeliveryRepository extends JpaRepository { +public interface ReportedDeliveryRepository extends DeliveryRepository { } diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/logic/service/DeliveryService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/logic/service/DeliveryService.java new file mode 100644 index 00000000..a0904183 --- /dev/null +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/logic/service/DeliveryService.java @@ -0,0 +1,123 @@ +/* + * 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.delivery.logic.service; + +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Stream; + +import org.eclipse.tractusx.puris.backend.delivery.domain.model.Delivery; +import org.eclipse.tractusx.puris.backend.delivery.domain.repository.DeliveryRepository; +import org.eclipse.tractusx.puris.backend.stock.logic.dto.itemstocksamm.DirectionCharacteristic; +import org.springframework.beans.factory.annotation.Autowired; + +public abstract class DeliveryService { + @Autowired + protected DeliveryRepository repository; + + public final List findAll() { + return repository.findAll(); + } + + public final T findById(UUID id) { + return repository.findById(id).orElse(null); + } + + public final List findAllByFilters( + Optional ownMaterialNumber, + Optional bpns, + Optional bpnl, + Optional day, + Optional direction) { + Stream stream = repository.findAll().stream(); + if (ownMaterialNumber.isPresent()) { + stream = stream.filter(delivery -> delivery.getMaterial().getOwnMaterialNumber().equals(ownMaterialNumber.get())); + } + if (bpns.isPresent()) { + stream = stream.filter(delivery -> delivery.getDestinationBpns().equals(bpns.get()) || delivery.getOriginBpns().equals(bpns.get())); + } + if (bpnl.isPresent()) { + stream = stream.filter(delivery -> delivery.getPartner().getBpnl().equals(bpnl.get())); + } + if (day.isPresent()) { + LocalDate localDayDate = Instant.ofEpochMilli(day.get().getTime()) + .atOffset(ZoneOffset.UTC) + .toLocalDate(); + stream = stream.filter(delivery -> { + long time = direction.get() == DirectionCharacteristic.INBOUND + ? delivery.getDateOfArrival().getTime() + : delivery.getDateOfDeparture().getTime(); + LocalDate deliveryDayDate = Instant.ofEpochMilli(time) + .atOffset(ZoneOffset.UTC) + .toLocalDate(); + return deliveryDayDate.getDayOfMonth() == localDayDate.getDayOfMonth(); + }); + } + if (direction.isPresent()) { + if (direction.get() == DirectionCharacteristic.INBOUND) { + stream = stream.filter(delivery -> delivery.getDestinationBpns().equals(bpns.get())); + } else { + stream = stream.filter(delivery -> delivery.getOriginBpns().equals(bpns.get())); + } + } + return stream.toList(); + } + + public final double getSumOfQuantities(List deliveries) { + double sum = 0; + for (T delivery : deliveries) { + sum += delivery.getQuantity(); + } + return sum; + } + + public final List getQuantityForDays(String material, String partnerBpnl, String siteBpns, DirectionCharacteristic direction, int numberOfDays) { + List deliveryQtys = new ArrayList<>(); + LocalDate localDate = LocalDate.now(); + + for (int i = 0; i < numberOfDays; i++) { + Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); + List deliveries = findAllByFilters(Optional.of(material), Optional.of(siteBpns), Optional.of(partnerBpnl), Optional.of(date), Optional.of(direction)); + deliveryQtys.add(getSumOfQuantities(deliveries)); + + localDate = localDate.plusDays(1); + } + return deliveryQtys; + } + + public final T update(T delivery) { + if (delivery.getUuid() == null || repository.findById(delivery.getUuid()).isEmpty()) { + return null; + } + return repository.save(delivery); + } + + public final void delete(UUID id) { + repository.deleteById(id); + } +} diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/logic/service/OwnDeliveryService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/logic/service/OwnDeliveryService.java index ba876ad2..a2e97e6f 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/logic/service/OwnDeliveryService.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/logic/service/OwnDeliveryService.java @@ -20,17 +20,9 @@ package org.eclipse.tractusx.puris.backend.delivery.logic.service; -import java.time.Instant; -import java.time.LocalDate; -import java.time.ZoneId; -import java.time.ZoneOffset; -import java.util.ArrayList; import java.util.Date; import java.util.List; -import java.util.Optional; -import java.util.UUID; import java.util.function.Function; -import java.util.stream.Stream; import javax.management.openmbean.KeyAlreadyExistsException; @@ -39,11 +31,10 @@ import org.eclipse.tractusx.puris.backend.delivery.domain.repository.OwnDeliveryRepository; import org.eclipse.tractusx.puris.backend.masterdata.domain.model.Partner; import org.eclipse.tractusx.puris.backend.masterdata.logic.service.PartnerService; -import org.eclipse.tractusx.puris.backend.stock.logic.dto.itemstocksamm.DirectionCharacteristic; import org.springframework.stereotype.Service; @Service -public class OwnDeliveryService { +public class OwnDeliveryService extends DeliveryService { private final OwnDeliveryRepository repository; private final PartnerService partnerService; @@ -58,10 +49,6 @@ public OwnDeliveryService(OwnDeliveryRepository repository, PartnerService partn this.validator = this::validate; } - public final List findAll() { - return repository.findAll(); - } - public final List findAllByBpnl(String bpnl) { return repository.findAll().stream().filter(delivery -> delivery.getPartner().getBpnl().equals(bpnl)) .toList(); @@ -72,73 +59,6 @@ public final List findAllByOwnMaterialNumber(String ownMaterialNumb .toList(); } - public final List findAllByFilters( - Optional ownMaterialNumber, - Optional bpns, - Optional bpnl, - Optional day, - Optional direction) { - Stream stream = repository.findAll().stream(); - if (ownMaterialNumber.isPresent()) { - stream = stream.filter(delivery -> delivery.getMaterial().getOwnMaterialNumber().equals(ownMaterialNumber.get())); - } - if (bpns.isPresent()) { - stream = stream.filter(delivery -> delivery.getDestinationBpns().equals(bpns.get()) || delivery.getOriginBpns().equals(bpns.get())); - } - if (bpnl.isPresent()) { - stream = stream.filter(delivery -> delivery.getPartner().getBpnl().equals(bpnl.get())); - } - if (day.isPresent()) { - LocalDate localDayDate = Instant.ofEpochMilli(day.get().getTime()) - .atOffset(ZoneOffset.UTC) - .toLocalDate(); - stream = stream.filter(delivery -> { - long time = direction.get() == DirectionCharacteristic.INBOUND - ? delivery.getDateOfArrival().getTime() - : delivery.getDateOfDeparture().getTime(); - LocalDate deliveryDayDate = Instant.ofEpochMilli(time) - .atOffset(ZoneOffset.UTC) - .toLocalDate(); - return deliveryDayDate.getDayOfMonth() == localDayDate.getDayOfMonth(); - }); - } - if (direction.isPresent()) { - if (direction.get() == DirectionCharacteristic.INBOUND) { - stream = stream.filter(delivery -> delivery.getDestinationBpns().equals(bpns.get())); - } else { - stream = stream.filter(delivery -> delivery.getOriginBpns().equals(bpns.get())); - } - } - return stream.toList(); - } - - public final OwnDelivery findById(UUID id) { - return repository.findById(id).orElse(null); - } - - public final double getSumOfQuantities(List deliveries) { - double sum = 0; - for (OwnDelivery delivery : deliveries) { - sum += delivery.getQuantity(); - } - return sum; - } - - public final List getQuantityForDays(String material, String partnerBpnl, String siteBpns, DirectionCharacteristic direction, int numberOfDays) { - List deliveryQtys = new ArrayList<>(); - LocalDate localDate = LocalDate.now(); - - for (int i = 0; i < numberOfDays; i++) { - Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); - List deliveries = findAllByFilters(Optional.of(material), Optional.of(siteBpns), Optional.of(partnerBpnl), Optional.of(date), Optional.of(direction)); - double deliveryQuantity = getSumOfQuantities(deliveries); - deliveryQtys.add(deliveryQuantity); - - localDate = localDate.plusDays(1); - } - return deliveryQtys; - } - public final OwnDelivery create(OwnDelivery delivery) { if (!validator.apply(delivery)) { throw new IllegalArgumentException("Invalid delivery"); @@ -160,17 +80,6 @@ public final List createAll(List deliveries) { return repository.saveAll(deliveries); } - public final OwnDelivery update(OwnDelivery delivery) { - if (delivery.getUuid() == null || repository.findById(delivery.getUuid()).isEmpty()) { - return null; - } - return repository.save(delivery); - } - - public final void delete(UUID id) { - repository.deleteById(id); - } - public boolean validate(OwnDelivery delivery) { if (ownPartnerEntity == null) { ownPartnerEntity = partnerService.getOwnPartnerEntity(); diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/logic/service/ReportedDeliveryService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/logic/service/ReportedDeliveryService.java index 0b96725d..f0f4f6d3 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/logic/service/ReportedDeliveryService.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/delivery/logic/service/ReportedDeliveryService.java @@ -20,28 +20,20 @@ package org.eclipse.tractusx.puris.backend.delivery.logic.service; -import java.time.Instant; -import java.time.LocalDate; -import java.time.ZoneId; -import java.time.ZoneOffset; -import java.util.ArrayList; import java.util.Date; import java.util.List; -import java.util.Optional; import java.util.UUID; import java.util.function.Function; -import java.util.stream.Stream; import org.eclipse.tractusx.puris.backend.delivery.domain.model.EventTypeEnumeration; import org.eclipse.tractusx.puris.backend.delivery.domain.model.ReportedDelivery; import org.eclipse.tractusx.puris.backend.delivery.domain.repository.ReportedDeliveryRepository; import org.eclipse.tractusx.puris.backend.masterdata.domain.model.Partner; import org.eclipse.tractusx.puris.backend.masterdata.logic.service.PartnerService; -import org.eclipse.tractusx.puris.backend.stock.logic.dto.itemstocksamm.DirectionCharacteristic; import org.springframework.stereotype.Service; @Service -public class ReportedDeliveryService { +public class ReportedDeliveryService extends DeliveryService { private final ReportedDeliveryRepository repository; private final PartnerService partnerService; @@ -56,82 +48,11 @@ public ReportedDeliveryService(ReportedDeliveryRepository repository, PartnerSer this.validator = this::validate; } - public final List findAll() { - return repository.findAll(); - } - public final List findAllByReportedId(UUID reportedId) { return repository.findAll().stream().filter(delivery -> delivery.getPartner().getUuid().equals(reportedId)) .toList(); } - public final ReportedDelivery findById(UUID id) { - return repository.findById(id).orElse(null); - } - - public final List findAllByFilters( - Optional ownMaterialNumber, - Optional bpns, - Optional bpnl, - Optional day, - Optional direction) { - Stream stream = repository.findAll().stream(); - if (ownMaterialNumber.isPresent()) { - stream = stream.filter(delivery -> delivery.getMaterial().getOwnMaterialNumber().equals(ownMaterialNumber.get())); - } - if (bpns.isPresent()) { - stream = stream.filter(delivery -> delivery.getDestinationBpns().equals(bpns.get()) || delivery.getOriginBpns().equals(bpns.get())); - } - if (bpnl.isPresent()) { - stream = stream.filter(delivery -> delivery.getPartner().getBpnl().equals(bpnl.get())); - } - if (day.isPresent()) { - LocalDate localDayDate = Instant.ofEpochMilli(day.get().getTime()) - .atOffset(ZoneOffset.UTC) - .toLocalDate(); - stream = stream.filter(delivery -> { - long time = direction.get() == DirectionCharacteristic.INBOUND - ? delivery.getDateOfArrival().getTime() - : delivery.getDateOfDeparture().getTime(); - LocalDate deliveryDayDate = Instant.ofEpochMilli(time) - .atOffset(ZoneOffset.UTC) - .toLocalDate(); - return deliveryDayDate.getDayOfMonth() == localDayDate.getDayOfMonth(); - }); - } - if (direction.isPresent()) { - if (direction.get() == DirectionCharacteristic.INBOUND) { - stream = stream.filter(delivery -> delivery.getDestinationBpns().equals(bpns.get())); - } else { - stream = stream.filter(delivery -> delivery.getOriginBpns().equals(bpns.get())); - } - } - return stream.toList(); - } - - public final double getSumOfQuantities(List deliveries) { - double sum = 0; - for (ReportedDelivery delivery : deliveries) { - sum += delivery.getQuantity(); - } - return sum; - } - - public final List getQuantityForDays(String material, String partnerBpnl, String siteBpns, DirectionCharacteristic direction, int numberOfDays) { - List deliveryQtys = new ArrayList<>(); - LocalDate localDate = LocalDate.now(); - - for (int i = 0; i < numberOfDays; i++) { - Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); - List deliveries = findAllByFilters(Optional.of(material), Optional.of(siteBpns), Optional.of(partnerBpnl), Optional.of(date), Optional.of(direction)); - double deliveryQuantity = getSumOfQuantities(deliveries); - deliveryQtys.add(deliveryQuantity); - - localDate = localDate.plusDays(1); - } - return deliveryQtys; - } - public final ReportedDelivery create(ReportedDelivery delivery) { if (delivery.getUuid() != null && repository.findById(delivery.getUuid()).isPresent()) { return null; @@ -153,17 +74,6 @@ public final List createAll(List deliveries) return repository.saveAll(deliveries); } - public final ReportedDelivery update(ReportedDelivery delivery) { - if (delivery.getUuid() == null || repository.findById(delivery.getUuid()).isEmpty()) { - return null; - } - return repository.save(delivery); - } - - public final void delete(UUID id) { - repository.deleteById(id); - } - public boolean validate(ReportedDelivery delivery) { return delivery.getQuantity() > 0 && diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/controller/ProductionController.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/controller/ProductionController.java index 3f191757..4420f507 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/controller/ProductionController.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/controller/ProductionController.java @@ -207,7 +207,7 @@ public void deleteProduction(@PathVariable UUID id) { ) public List getAllProductionsForPartner(String ownMaterialNumber, Optional bpnl, Optional site) { - return reportedProductionService.findAllByFilters(Optional.of(ownMaterialNumber), bpnl, site) + return reportedProductionService.findAllByFilters(Optional.of(ownMaterialNumber), bpnl, site, Optional.empty()) .stream().map(this::convertToDto).collect(Collectors.toList()); } diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/domain/repository/OwnProductionRepository.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/domain/repository/OwnProductionRepository.java index fd4988b3..c8b03cbb 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/domain/repository/OwnProductionRepository.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/domain/repository/OwnProductionRepository.java @@ -21,12 +21,9 @@ See the NOTICE file(s) distributed with this work for additional package org.eclipse.tractusx.puris.backend.production.domain.repository; import org.eclipse.tractusx.puris.backend.production.domain.model.OwnProduction; -import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; -import java.util.UUID; - @Repository -public interface OwnProductionRepository extends JpaRepository { +public interface OwnProductionRepository extends ProductionRepository { } diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/domain/repository/ProductionRepository.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/domain/repository/ProductionRepository.java new file mode 100644 index 00000000..161eb58e --- /dev/null +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/domain/repository/ProductionRepository.java @@ -0,0 +1,10 @@ +package org.eclipse.tractusx.puris.backend.production.domain.repository; + +import java.util.UUID; + +import org.eclipse.tractusx.puris.backend.production.domain.model.Production; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ProductionRepository extends JpaRepository { + +} diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/domain/repository/ReportedProductionRepository.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/domain/repository/ReportedProductionRepository.java index 065295ab..542a242f 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/domain/repository/ReportedProductionRepository.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/domain/repository/ReportedProductionRepository.java @@ -20,13 +20,10 @@ See the NOTICE file(s) distributed with this work for additional package org.eclipse.tractusx.puris.backend.production.domain.repository; -import java.util.UUID; - import org.eclipse.tractusx.puris.backend.production.domain.model.ReportedProduction; -import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository -public interface ReportedProductionRepository extends JpaRepository { +public interface ReportedProductionRepository extends ProductionRepository { } diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/logic/service/OwnProductionService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/logic/service/OwnProductionService.java index b78170bf..255f750a 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/logic/service/OwnProductionService.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/logic/service/OwnProductionService.java @@ -20,17 +20,8 @@ See the NOTICE file(s) distributed with this work for additional package org.eclipse.tractusx.puris.backend.production.logic.service; -import java.time.Instant; -import java.time.LocalDate; -import java.time.ZoneId; -import java.time.ZoneOffset; -import java.util.ArrayList; -import java.util.Date; import java.util.List; -import java.util.Optional; -import java.util.UUID; import java.util.function.Function; -import java.util.stream.Stream; import javax.management.openmbean.KeyAlreadyExistsException; @@ -41,7 +32,7 @@ See the NOTICE file(s) distributed with this work for additional import org.springframework.stereotype.Service; @Service -public class OwnProductionService { +public class OwnProductionService extends ProductionService { private final OwnProductionRepository repository; private final PartnerService partnerService; @@ -54,68 +45,6 @@ public OwnProductionService(OwnProductionRepository repository, PartnerService p this.validator = this::validate; } - public final List findAll() { - return repository.findAll(); - } - - public final List findAllByBpnl(String bpnl) { - return repository.findAll().stream().filter(production -> production.getPartner().getBpnl().equals(bpnl)) - .toList(); - } - - public final List findAllByOwnMaterialNumber(String ownMaterialNumber) { - return repository.findAll().stream().filter(production -> production.getMaterial().getOwnMaterialNumber().equals(ownMaterialNumber)) - .toList(); - } - - public final List findAllByFilters( - Optional ownMaterialNumber, - Optional bpnl, - Optional bpns, - Optional dayOfCompletion) { - Stream stream = repository.findAll().stream(); - if (ownMaterialNumber.isPresent()) { - stream = stream.filter(production -> production.getMaterial().getOwnMaterialNumber().equals(ownMaterialNumber.get())); - } - if (bpnl.isPresent()) { - stream = stream.filter(production -> production.getPartner().getBpnl().equals(bpnl.get())); - } - if (bpns.isPresent()) { - stream = stream.filter(production -> production.getProductionSiteBpns().equals(bpns.get())); - } - if (dayOfCompletion.isPresent()) { - LocalDate localEstimatedTimeOfCompletion = Instant.ofEpochMilli(dayOfCompletion.get().getTime()) - .atOffset(ZoneOffset.UTC) - .toLocalDate(); - stream = stream.filter(production -> { - LocalDate productionEstimatedTimeOfCompletion = Instant.ofEpochMilli(production.getEstimatedTimeOfCompletion().getTime()) - .atOffset(ZoneOffset.UTC) - .toLocalDate(); - return productionEstimatedTimeOfCompletion.getDayOfMonth() == localEstimatedTimeOfCompletion.getDayOfMonth(); - }); - } - return stream.toList(); - } - - public final OwnProduction findById(UUID uuid) { - return repository.findById(uuid).orElse(null); - } - - public final List getQuantityForDays(String material, String partnerBpnl, String siteBpns, int numberOfDays) { - List quantities = new ArrayList<>(); - LocalDate localDate = LocalDate.now(); - - for (int i = 0; i < numberOfDays; i++) { - Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); - List productions = findAllByFilters(Optional.of(material), Optional.of(partnerBpnl), Optional.of(siteBpns), Optional.of(date)); - double productionQuantity = getSumOfQuantities(productions); - quantities.add(productionQuantity); - - localDate = localDate.plusDays(1); - } - return quantities; - } - public final OwnProduction create(OwnProduction production) { if (!validator.apply(production)) { @@ -138,17 +67,6 @@ public final List createAll(List productions) { return repository.saveAll(productions); } - public final OwnProduction update(OwnProduction production) { - if (production.getUuid() == null || repository.findById(production.getUuid()).isEmpty()) { - return null; - } - return repository.save(production); - } - - public final void delete(UUID uuid) { - repository.deleteById(uuid); - } - public boolean validate(OwnProduction production) { Partner ownPartnerEntity = partnerService.getOwnPartnerEntity(); return @@ -169,12 +87,4 @@ public boolean validate(OwnProduction production) { production.getSupplierOrderNumber() == null )); } - - private final double getSumOfQuantities(List productions) { - double sum = 0; - for (OwnProduction production : productions) { - sum += production.getQuantity(); - } - return sum; - } } diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/logic/service/ProductionRequestApiService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/logic/service/ProductionRequestApiService.java index d5e5a1d4..e2b69a15 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/logic/service/ProductionRequestApiService.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/logic/service/ProductionRequestApiService.java @@ -92,7 +92,7 @@ public void doReportedProductionRequest(Partner partner, Material material) { } } // delete older data: - var oldProductions = reportedProductionService.findAllByFilters(Optional.of(material.getOwnMaterialNumber()), Optional.of(partner.getBpnl()), Optional.empty()); + var oldProductions = reportedProductionService.findAllByFilters(Optional.of(material.getOwnMaterialNumber()), Optional.of(partner.getBpnl()), Optional.empty(), Optional.empty()); for (var oldProduction : oldProductions) { reportedProductionService.delete(oldProduction.getUuid()); } diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/logic/service/ProductionService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/logic/service/ProductionService.java new file mode 100644 index 00000000..bbfd2765 --- /dev/null +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/logic/service/ProductionService.java @@ -0,0 +1,102 @@ +package org.eclipse.tractusx.puris.backend.production.logic.service; + +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Stream; + +import org.eclipse.tractusx.puris.backend.production.domain.model.Production; +import org.eclipse.tractusx.puris.backend.production.domain.repository.ProductionRepository; +import org.springframework.beans.factory.annotation.Autowired; + +public abstract class ProductionService { + @Autowired + protected ProductionRepository repository; + + public final List findAll() { + return repository.findAll(); + } + + public final T findById(UUID uuid) { + return repository.findById(uuid).orElse(null); + } + + public final List findAllByBpnl(String bpnl) { + return repository.findAll().stream().filter(production -> production.getPartner().getBpnl().equals(bpnl)) + .toList(); + } + + public final List findAllByOwnMaterialNumber(String ownMaterialNumber) { + return repository.findAll().stream().filter(production -> production.getMaterial().getOwnMaterialNumber().equals(ownMaterialNumber)) + .toList(); + } + + public final List findAllByFilters( + Optional ownMaterialNumber, + Optional bpnl, + Optional bpns, + Optional dayOfCompletion) { + Stream stream = repository.findAll().stream(); + if (ownMaterialNumber.isPresent()) { + stream = stream.filter(production -> production.getMaterial().getOwnMaterialNumber().equals(ownMaterialNumber.get())); + } + if (bpnl.isPresent()) { + stream = stream.filter(production -> production.getPartner().getBpnl().equals(bpnl.get())); + } + if (bpns.isPresent()) { + stream = stream.filter(production -> production.getProductionSiteBpns().equals(bpns.get())); + } + if (dayOfCompletion.isPresent()) { + LocalDate localEstimatedTimeOfCompletion = Instant.ofEpochMilli(dayOfCompletion.get().getTime()) + .atOffset(ZoneOffset.UTC) + .toLocalDate(); + stream = stream.filter(production -> { + LocalDate productionEstimatedTimeOfCompletion = Instant.ofEpochMilli(production.getEstimatedTimeOfCompletion().getTime()) + .atOffset(ZoneOffset.UTC) + .toLocalDate(); + return productionEstimatedTimeOfCompletion.getDayOfMonth() == localEstimatedTimeOfCompletion.getDayOfMonth(); + }); + } + return stream.toList(); + } + + public final List getQuantityForDays(String material, String partnerBpnl, String siteBpns, int numberOfDays) { + List quantities = new ArrayList<>(); + LocalDate localDate = LocalDate.now(); + + for (int i = 0; i < numberOfDays; i++) { + Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); + List productions = findAllByFilters(Optional.of(material), Optional.of(partnerBpnl), Optional.of(siteBpns), Optional.of(date)); + double productionQuantity = getSumOfQuantities(productions); + quantities.add(productionQuantity); + + localDate = localDate.plusDays(1); + } + return quantities; + } + + public final T update(T production) { + if (production.getUuid() == null || repository.findById(production.getUuid()).isEmpty()) { + return null; + } + return repository.save(production); + } + + public final void delete(UUID uuid) { + repository.deleteById(uuid); + } + + private final double getSumOfQuantities(List productions) { + double sum = 0; + for (T production : productions) { + sum += production.getQuantity(); + } + return sum; + } +} diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/logic/service/ReportedProductionService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/logic/service/ReportedProductionService.java index 4521f8a7..69070ef7 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/logic/service/ReportedProductionService.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/production/logic/service/ReportedProductionService.java @@ -21,17 +21,14 @@ See the NOTICE file(s) distributed with this work for additional package org.eclipse.tractusx.puris.backend.production.logic.service; import java.util.List; -import java.util.Optional; -import java.util.UUID; import java.util.function.Function; -import java.util.stream.Stream; import org.eclipse.tractusx.puris.backend.production.domain.model.ReportedProduction; import org.eclipse.tractusx.puris.backend.production.domain.repository.ReportedProductionRepository; import org.springframework.stereotype.Service; @Service -public class ReportedProductionService { +public class ReportedProductionService extends ProductionService { private final ReportedProductionRepository repository; protected final Function validator; @@ -41,38 +38,6 @@ public ReportedProductionService(ReportedProductionRepository repository) { this.validator = this::validate; } - public final List findAll() { - return repository.findAll(); - } - - public final List findAllByBpnl(String bpnl) { - return repository.findAll().stream().filter(production -> production.getPartner().getBpnl().equals(bpnl)) - .toList(); - } - - public final List findAllByOwnMaterialNumber(String ownMaterialNumber) { - return repository.findAll().stream().filter(production -> production.getMaterial().getOwnMaterialNumber().equals(ownMaterialNumber)) - .toList(); - } - - public final List findAllByFilters(Optional ownMaterialNumber, Optional bpnl, Optional bpns) { - Stream stream = repository.findAll().stream(); - if (ownMaterialNumber.isPresent()) { - stream = stream.filter(production -> production.getMaterial().getOwnMaterialNumber().equals(ownMaterialNumber.get())); - } - if (bpnl.isPresent()) { - stream = stream.filter(production -> production.getPartner().getBpnl().equals(bpnl.get())); - } - if (bpns.isPresent()) { - stream = stream.filter(production -> production.getProductionSiteBpns().equals(bpns.get())); - } - return stream.toList(); - } - - public final ReportedProduction findById(UUID uuid) { - return repository.findById(uuid).orElse(null); - } - public final ReportedProduction create(ReportedProduction production) { if (repository.findAll().stream().anyMatch(prod -> prod.equals(production))) { return null; @@ -94,17 +59,6 @@ public final List createAll(List product return repository.saveAll(productions); } - public final ReportedProduction update(ReportedProduction production) { - if (production.getUuid() == null || repository.findById(production.getUuid()).isEmpty()) { - return null; - } - return repository.save(production); - } - - public final void delete(UUID uuid) { - repository.deleteById(uuid); - } - public boolean validate(ReportedProduction production) { return production.getQuantity() > 0 && diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/controller/SupplyController.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/controller/SupplyController.java index 927af4ab..3a102e76 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/controller/SupplyController.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/controller/SupplyController.java @@ -21,7 +21,6 @@ package org.eclipse.tractusx.puris.backend.supply.controller; import java.util.List; -import java.util.Optional; import org.eclipse.tractusx.puris.backend.supply.domain.model.Supply; import org.eclipse.tractusx.puris.backend.supply.logic.dto.SupplyDto; @@ -36,10 +35,8 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ResponseBody; - - @RestController -@RequestMapping("supply") +@RequestMapping("days-of-supply") public class SupplyController { @Autowired private CustomerSupplyService customerSupplyService; @@ -60,9 +57,9 @@ public List calculateCustomerDaysOfSupply(String materialNumber, Stri @GetMapping("customer/reported") @Operation(summary = "Get days of supply for customer.", - description = "Get days of supply for customer for given material number. Optionally it can be filtered by partner bpnl.") - public List getCustomerDaysOfSupply(String materialNumber, Optional bpnl) { - return customerSupplyService.findAllByFilters(Optional.of(materialNumber), bpnl) + description = "Get days of supply for customer for given material number and partner bpnl.") + public List getCustomerDaysOfSupply(String materialNumber, String bpnl) { + return customerSupplyService.findByPartnerBpnlAndOwnMaterialNumber(materialNumber, bpnl) .stream().map(this::convertToDto).toList(); } @@ -76,9 +73,9 @@ public List calculateSupplierDaysOfSupply(String materialNumber, Stri @GetMapping("supplier/reported") @Operation(summary = "Get days of supply for supplier.", - description = "Get days of supply for supplier for given material number. Optionally it can be filtered by partner bpnl.") - public List getSupplierDaysOfSupply(String materialNumber, Optional bpnl) { - return supplierSupplyService.findAllByFilters(Optional.of(materialNumber), bpnl) + description = "Get days of supply for supplier for given material number and partner bpnl.") + public List getSupplierDaysOfSupply(String materialNumber, String bpnl) { + return supplierSupplyService.findByPartnerBpnlAndOwnMaterialNumber(materialNumber, bpnl) .stream().map(this::convertToDto).toList(); } diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/model/OwnCustomerSupply.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/model/OwnCustomerSupply.java index ef0bec6b..c1030bbe 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/model/OwnCustomerSupply.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/model/OwnCustomerSupply.java @@ -1,35 +1,35 @@ /* - * 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 - */ +* 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.supply.domain.model; +package org.eclipse.tractusx.puris.backend.supply.domain.model; + +import jakarta.persistence.Entity; +import lombok.NoArgsConstructor; +import lombok.ToString; +import lombok.experimental.SuperBuilder; + +@Entity +@SuperBuilder +@NoArgsConstructor +@ToString(callSuper = true) +public class OwnCustomerSupply extends Supply { + +} - import jakarta.persistence.Entity; - import lombok.NoArgsConstructor; - import lombok.ToString; - import lombok.experimental.SuperBuilder; - - @Entity - @SuperBuilder - @NoArgsConstructor - @ToString(callSuper = true) - public class OwnCustomerSupply extends Supply { - - } - \ No newline at end of file diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/model/OwnSupplierSupply.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/model/OwnSupplierSupply.java index 0bba8c0c..24a2a81e 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/model/OwnSupplierSupply.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/model/OwnSupplierSupply.java @@ -32,3 +32,4 @@ public class OwnSupplierSupply extends Supply { } + diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/model/Supply.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/model/Supply.java index 8a106ea4..fcd661b8 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/model/Supply.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/model/Supply.java @@ -47,8 +47,6 @@ @Entity @ToString public abstract class Supply { - // customer controller, supplier controller - // in dto flatten material and partner @Id @GeneratedValue protected UUID uuid; diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/repository/ReportedCustomerSupplyRepository.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/repository/ReportedCustomerSupplyRepository.java index 4bade94e..a4577527 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/repository/ReportedCustomerSupplyRepository.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/repository/ReportedCustomerSupplyRepository.java @@ -20,11 +20,12 @@ package org.eclipse.tractusx.puris.backend.supply.domain.repository; +import java.util.List; import java.util.UUID; import org.eclipse.tractusx.puris.backend.supply.domain.model.ReportedCustomerSupply; import org.springframework.data.jpa.repository.JpaRepository; public interface ReportedCustomerSupplyRepository extends JpaRepository { - + List findByPartner_BpnlAndMaterial_OwnMaterialNumber(String partnerBpnl, String ownMaterialNumber); } diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/repository/ReportedSupplierSupplyRepository.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/repository/ReportedSupplierSupplyRepository.java index b8adca23..f949ddb9 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/repository/ReportedSupplierSupplyRepository.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/domain/repository/ReportedSupplierSupplyRepository.java @@ -20,11 +20,13 @@ package org.eclipse.tractusx.puris.backend.supply.domain.repository; +import java.util.List; import java.util.UUID; import org.eclipse.tractusx.puris.backend.supply.domain.model.ReportedSupplierSupply; import org.springframework.data.jpa.repository.JpaRepository; public interface ReportedSupplierSupplyRepository extends JpaRepository { - + List findByPartner_BpnlAndMaterial_OwnMaterialNumber(String partnerBpnl, String ownMaterialNumber); } + diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/CustomerSupplyService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/CustomerSupplyService.java index 0d194083..4eb03e41 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/CustomerSupplyService.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/CustomerSupplyService.java @@ -33,45 +33,49 @@ import org.eclipse.tractusx.puris.backend.delivery.logic.service.OwnDeliveryService; import org.eclipse.tractusx.puris.backend.delivery.logic.service.ReportedDeliveryService; import org.eclipse.tractusx.puris.backend.demand.logic.services.OwnDemandService; -import org.eclipse.tractusx.puris.backend.masterdata.logic.service.MaterialServiceImpl; +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.dto.itemstocksamm.DirectionCharacteristic; import org.eclipse.tractusx.puris.backend.stock.logic.service.MaterialItemStockService; import org.eclipse.tractusx.puris.backend.supply.domain.model.OwnCustomerSupply; import org.eclipse.tractusx.puris.backend.supply.domain.model.ReportedCustomerSupply; import org.eclipse.tractusx.puris.backend.supply.domain.repository.ReportedCustomerSupplyRepository; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class CustomerSupplyService { - private final ReportedCustomerSupplyRepository repository; - private final PartnerService partnerService; - private final OwnDeliveryService ownDeliveryService; - private final ReportedDeliveryService reportedDeliveryService; - private final OwnDemandService demandService; - private final MaterialItemStockService stockService; - private final MaterialServiceImpl materialService; + @Autowired + private ReportedCustomerSupplyRepository repository; + @Autowired + private PartnerService partnerService; + @Autowired + private OwnDeliveryService ownDeliveryService; + @Autowired + private ReportedDeliveryService reportedDeliveryService; + @Autowired + private OwnDemandService demandService; + @Autowired + private MaterialItemStockService stockService; + @Autowired + private MaterialService materialService; protected final Function validator; - public CustomerSupplyService( - ReportedCustomerSupplyRepository customerRepository, - PartnerService partnerService, - OwnDeliveryService ownDeliveryService, - ReportedDeliveryService reportedDeliveryService, - OwnDemandService demandService, - MaterialItemStockService stockService, - MaterialServiceImpl materialService) { - this.repository = customerRepository; - this.partnerService = partnerService; - this.ownDeliveryService = ownDeliveryService; - this.reportedDeliveryService = reportedDeliveryService; - this.demandService = demandService; - this.stockService = stockService; - this.materialService = materialService; + public CustomerSupplyService() { this.validator = this::validate; } + /** + * Calculates the customer's days of supply for a given material, partner, and site over a specified number of days. + * It combines own and reported deliveries, and demand quantities to forecast the number of days the stock will last. + * + * @param material the material identifier for which the days of supply are being calculated. + * @param partnerBpnl The bpnl of the customer's partner. + * @param siteBpns the bpns of the site where the deliveries and demands are recorded. + * @param numberOfDays the number of days over which the forecast should be calculated. + * @return a list of {@link OwnCustomerSupply} objects, each containing the calculated days of supply for a specific date. + */ public final List calculateCustomerDaysOfSupply(String material, String partnerBpnl, String siteBpns, int numberOfDays) { List customerSupply = new ArrayList<>(); LocalDate localDate = LocalDate.now(); @@ -128,6 +132,10 @@ public final List findAllByFilters(Optional ownM return stream.toList(); } + public final List findByPartnerBpnlAndOwnMaterialNumber(String partnerBpnl, String ownMaterialNumber) { + return repository.findByPartner_BpnlAndMaterial_OwnMaterialNumber(partnerBpnl, ownMaterialNumber); + } + public boolean validate(ReportedCustomerSupply daysOfSupply) { return daysOfSupply.getPartner() != null && @@ -139,12 +147,16 @@ public boolean validate(ReportedCustomerSupply daysOfSupply) { (daysOfSupply.getStockLocationBPNA().equals(null) || daysOfSupply.getStockLocationBPNA().equals(daysOfSupply.getStockLocationBPNS())); } + /** + * Calculates the number of days of supply based on the current stock quantity and a list of demands. + * @param stockQuantity Current stock amount + * @param demands Sublist of demands for current iteration + * @return The number of days of supply that the stock can cover. + */ private final double getDaysOfSupply(double stockQuantity, List demands) { double daysOfSupply = 0; - for (int i = 0; i < demands.size(); i++) { - double demand = demands.get(i); - + for (double demand : demands) { if (stockQuantity >= demand) { daysOfSupply += 1; stockQuantity = stockQuantity - demand; @@ -159,6 +171,12 @@ private final double getDaysOfSupply(double stockQuantity, List demands) return daysOfSupply; } + /** + * Merges own and reported deliveries into a single list. + * @param list1 Own deliveries + * @param list2 Reported deliveries + * @return a new list containing the summed delivery quantities from the input lists. + */ private static List mergeDeliveries(List list1, List list2) { if (list1.size() != list2.size()) { throw new IllegalArgumentException("Lists must be of the same length"); diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/SupplierSupplyService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/SupplierSupplyService.java index 1990011b..5202744f 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/SupplierSupplyService.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/SupplierSupplyService.java @@ -32,7 +32,7 @@ import org.eclipse.tractusx.puris.backend.delivery.logic.service.OwnDeliveryService; import org.eclipse.tractusx.puris.backend.delivery.logic.service.ReportedDeliveryService; -import org.eclipse.tractusx.puris.backend.masterdata.logic.service.MaterialServiceImpl; +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.production.logic.service.OwnProductionService; import org.eclipse.tractusx.puris.backend.stock.logic.dto.itemstocksamm.DirectionCharacteristic; @@ -40,39 +40,43 @@ import org.eclipse.tractusx.puris.backend.supply.domain.model.OwnSupplierSupply; import org.eclipse.tractusx.puris.backend.supply.domain.model.ReportedSupplierSupply; import org.eclipse.tractusx.puris.backend.supply.domain.repository.ReportedSupplierSupplyRepository; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class SupplierSupplyService { - private final ReportedSupplierSupplyRepository repository; - private final PartnerService partnerService; - private final OwnDeliveryService ownDeliveryService; - private final ReportedDeliveryService reportedDeliveryService; - private final OwnProductionService productionService; - private final MaterialItemStockService stockService; - private final MaterialServiceImpl materialService; + @Autowired + private ReportedSupplierSupplyRepository repository; + @Autowired + private PartnerService partnerService; + @Autowired + private OwnDeliveryService ownDeliveryService; + @Autowired + private ReportedDeliveryService reportedDeliveryService; + @Autowired + private OwnProductionService productionService; + @Autowired + private MaterialItemStockService stockService; + @Autowired + private MaterialService materialService; protected final Function validator; - public SupplierSupplyService( - ReportedSupplierSupplyRepository repository, - PartnerService partnerService, - OwnDeliveryService ownDeliveryService, - ReportedDeliveryService reportedDeliveryService, - OwnProductionService productionService, - MaterialItemStockService stockService, - MaterialServiceImpl materialService) { - this.repository = repository; - this.partnerService = partnerService; - this.ownDeliveryService = ownDeliveryService; - this.reportedDeliveryService = reportedDeliveryService; - this.productionService = productionService; - this.stockService = stockService; - this.materialService = materialService; + public SupplierSupplyService() { this.validator = this::validate; } - public final List calculateSupplierDaysOfSupply(String material, String partnerBpnl, String siteBpns, int numberOfDays) { + /** + * Calculates the supplier's days of supply for a given material, partner, and site over a specified number of days. + * It combines own and reported deliveries, and production quantities to forecast the number of days the stock will last. + * + * @param material the material identifier for which the days of supply are being calculated. + * @param partnerBpnl The bpnl of the supplier's partner. + * @param siteBpns the bpns of the site where the deliveries and productions are recorded. + * @param numberOfDays the number of days over which the forecast should be calculated. + * @return a list of {@link OwnSupplierSupply} objects, each containing the calculated days of supply for a specific date. + */ + public final List calculateSupplierDaysOfSupply(String material, String partnerBpnl, String siteBpns, int numberOfDays) { List supplierSupply = new ArrayList<>(); LocalDate localDate = LocalDate.now(); @@ -126,6 +130,10 @@ public final List findAllByFilters(Optional ownM return stream.toList(); } + public final List findByPartnerBpnlAndOwnMaterialNumber(String partnerBpnl, String ownMaterialNumber) { + return repository.findByPartner_BpnlAndMaterial_OwnMaterialNumber(partnerBpnl, ownMaterialNumber); + } + public boolean validate(ReportedSupplierSupply daysOfSupply) { return daysOfSupply.getPartner() != null && @@ -137,12 +145,16 @@ public boolean validate(ReportedSupplierSupply daysOfSupply) { (daysOfSupply.getStockLocationBPNA().equals(null) || daysOfSupply.getStockLocationBPNA().equals(daysOfSupply.getStockLocationBPNS())); } + /** + * Calculates the number of days of supply based on the current stock quantity and a list of demands. + * @param stockQuantity Current stock amount + * @param demands Sublist of demands for current iteration + * @return The number of days of supply that the stock can cover. + */ private final double getDaysOfSupply(double stockQuantity, List demands) { double daysOfSupply = 0; - for (int i = 0; i < demands.size(); i++) { - double demand = demands.get(i); - + for (double demand : demands) { if (stockQuantity >= demand) { daysOfSupply += 1; stockQuantity = stockQuantity - demand; @@ -157,6 +169,12 @@ private final double getDaysOfSupply(double stockQuantity, List demands) return daysOfSupply; } + /** + * Merges own and reported deliveries into a single list. + * @param list1 Own deliveries + * @param list2 Reported deliveries + * @return a new list containing the summed delivery quantities from the input lists. + */ private static List mergeDeliveries(List list1, List list2) { if (list1.size() != list2.size()) { throw new IllegalArgumentException("Lists must be of the same length"); From 56db593cc15ea7be5bd0fdb475fd5216786c1068 Mon Sep 17 00:00:00 2001 From: Benjamin Kotnik Date: Wed, 12 Jun 2024 16:51:22 +0200 Subject: [PATCH 5/6] fix(days-of-supply): created base abstract class to reduce duplicated code --- .../logic/service/CustomerSupplyService.java | 89 ++++----------- .../logic/service/SupplierSupplyService.java | 87 ++++---------- .../supply/logic/service/SupplyService.java | 108 ++++++++++++++++++ 3 files changed, 150 insertions(+), 134 deletions(-) create mode 100644 backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/SupplyService.java diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/CustomerSupplyService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/CustomerSupplyService.java index 4eb03e41..3be98512 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/CustomerSupplyService.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/CustomerSupplyService.java @@ -20,10 +20,7 @@ package org.eclipse.tractusx.puris.backend.supply.logic.service; -import java.time.LocalDate; -import java.time.ZoneId; import java.util.ArrayList; -import java.util.Date; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -33,10 +30,8 @@ import org.eclipse.tractusx.puris.backend.delivery.logic.service.OwnDeliveryService; import org.eclipse.tractusx.puris.backend.delivery.logic.service.ReportedDeliveryService; import org.eclipse.tractusx.puris.backend.demand.logic.services.OwnDemandService; -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.dto.itemstocksamm.DirectionCharacteristic; -import org.eclipse.tractusx.puris.backend.stock.logic.service.MaterialItemStockService; import org.eclipse.tractusx.puris.backend.supply.domain.model.OwnCustomerSupply; import org.eclipse.tractusx.puris.backend.supply.domain.model.ReportedCustomerSupply; import org.eclipse.tractusx.puris.backend.supply.domain.repository.ReportedCustomerSupplyRepository; @@ -44,7 +39,7 @@ import org.springframework.stereotype.Service; @Service -public class CustomerSupplyService { +public class CustomerSupplyService extends SupplyService { @Autowired private ReportedCustomerSupplyRepository repository; @Autowired @@ -55,10 +50,6 @@ public class CustomerSupplyService { private ReportedDeliveryService reportedDeliveryService; @Autowired private OwnDemandService demandService; - @Autowired - private MaterialItemStockService stockService; - @Autowired - private MaterialService materialService; protected final Function validator; @@ -66,6 +57,25 @@ public CustomerSupplyService() { this.validator = this::validate; } + @Override + protected OwnCustomerSupply createSupplyInstance() { + return new OwnCustomerSupply(); + } + + @Override + protected List getAddedValues(String material, String partnerBpnl, String siteBpns, int numberOfDays) { + List ownDeliveries = ownDeliveryService.getQuantityForDays(material, partnerBpnl, siteBpns, DirectionCharacteristic.INBOUND, numberOfDays); + List reportedDeliveries = reportedDeliveryService.getQuantityForDays(material, partnerBpnl, siteBpns, DirectionCharacteristic.INBOUND, numberOfDays); + List deliveries = mergeDeliveries(ownDeliveries, reportedDeliveries); + return deliveries; + } + + @Override + protected List getConsumedValues(String material, String partnerBpnl, String siteBpns, int numberOfDays) { + List demands = demandService.getQuantityForDays(material, partnerBpnl, siteBpns, numberOfDays); + return demands; + } + /** * Calculates the customer's days of supply for a given material, partner, and site over a specified number of days. * It combines own and reported deliveries, and demand quantities to forecast the number of days the stock will last. @@ -77,40 +87,7 @@ public CustomerSupplyService() { * @return a list of {@link OwnCustomerSupply} objects, each containing the calculated days of supply for a specific date. */ public final List calculateCustomerDaysOfSupply(String material, String partnerBpnl, String siteBpns, int numberOfDays) { - List customerSupply = new ArrayList<>(); - LocalDate localDate = LocalDate.now(); - - List demands = demandService.getQuantityForDays(material, partnerBpnl, siteBpns, numberOfDays); - - List ownDeliveries = ownDeliveryService.getQuantityForDays(material, partnerBpnl, siteBpns, DirectionCharacteristic.INBOUND, numberOfDays); - List reportedDeliveries = reportedDeliveryService.getQuantityForDays(material, partnerBpnl, siteBpns, DirectionCharacteristic.INBOUND, numberOfDays); - List deliveries = mergeDeliveries(ownDeliveries, reportedDeliveries); - - double stockQuantity = stockService.getInitialStockQuantity(material, partnerBpnl); - - for (int i = 0; i < numberOfDays; i++) { - Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); - - if (i == numberOfDays - 1) { - stockQuantity += deliveries.get(i); - } - - double daysOfSupply = getDaysOfSupply( - stockQuantity, - demands.subList(i, demands.size())); - - OwnCustomerSupply supply = new OwnCustomerSupply(); - supply.setMaterial(materialService.findByOwnMaterialNumber(material)); - supply.setDate(date); - supply.setDaysOfSupply(daysOfSupply); - customerSupply.add(supply); - - stockQuantity = stockQuantity - demands.get(i) + deliveries.get(i); - - localDate = localDate.plusDays(1); - } - - return customerSupply; + return calculateDaysOfSupply(material, partnerBpnl, siteBpns, numberOfDays); } public final List findAll() { @@ -147,30 +124,6 @@ public boolean validate(ReportedCustomerSupply daysOfSupply) { (daysOfSupply.getStockLocationBPNA().equals(null) || daysOfSupply.getStockLocationBPNA().equals(daysOfSupply.getStockLocationBPNS())); } - /** - * Calculates the number of days of supply based on the current stock quantity and a list of demands. - * @param stockQuantity Current stock amount - * @param demands Sublist of demands for current iteration - * @return The number of days of supply that the stock can cover. - */ - private final double getDaysOfSupply(double stockQuantity, List demands) { - double daysOfSupply = 0; - - for (double demand : demands) { - if (stockQuantity >= demand) { - daysOfSupply += 1; - stockQuantity = stockQuantity - demand; - } else if (stockQuantity < demand && stockQuantity > 0) { - double fractional = stockQuantity / demand; - daysOfSupply = daysOfSupply + fractional; - break; - } else { - break; - } - } - return daysOfSupply; - } - /** * Merges own and reported deliveries into a single list. * @param list1 Own deliveries diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/SupplierSupplyService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/SupplierSupplyService.java index 5202744f..66b3f6a3 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/SupplierSupplyService.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/SupplierSupplyService.java @@ -20,10 +20,7 @@ package org.eclipse.tractusx.puris.backend.supply.logic.service; -import java.time.LocalDate; -import java.time.ZoneId; import java.util.ArrayList; -import java.util.Date; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -32,11 +29,9 @@ import org.eclipse.tractusx.puris.backend.delivery.logic.service.OwnDeliveryService; import org.eclipse.tractusx.puris.backend.delivery.logic.service.ReportedDeliveryService; -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.production.logic.service.OwnProductionService; 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.supply.domain.model.OwnSupplierSupply; import org.eclipse.tractusx.puris.backend.supply.domain.model.ReportedSupplierSupply; import org.eclipse.tractusx.puris.backend.supply.domain.repository.ReportedSupplierSupplyRepository; @@ -44,7 +39,7 @@ import org.springframework.stereotype.Service; @Service -public class SupplierSupplyService { +public class SupplierSupplyService extends SupplyService { @Autowired private ReportedSupplierSupplyRepository repository; @Autowired @@ -55,10 +50,6 @@ public class SupplierSupplyService { private ReportedDeliveryService reportedDeliveryService; @Autowired private OwnProductionService productionService; - @Autowired - private MaterialItemStockService stockService; - @Autowired - private MaterialService materialService; protected final Function validator; @@ -66,6 +57,25 @@ public SupplierSupplyService() { this.validator = this::validate; } + @Override + protected OwnSupplierSupply createSupplyInstance() { + return new OwnSupplierSupply(); + } + + @Override + protected List getAddedValues(String material, String partnerBpnl, String siteBpns, int numberOfDays) { + List productions = productionService.getQuantityForDays(material, partnerBpnl, siteBpns, numberOfDays); + return productions; + } + + @Override + protected List getConsumedValues(String material, String partnerBpnl, String siteBpns, int numberOfDays) { + List ownDeliveries = ownDeliveryService.getQuantityForDays(material, partnerBpnl, siteBpns, DirectionCharacteristic.OUTBOUND, numberOfDays); + List reportedDeliveries = reportedDeliveryService.getQuantityForDays(material, partnerBpnl, siteBpns, DirectionCharacteristic.OUTBOUND, numberOfDays); + List deliveries = mergeDeliveries(ownDeliveries, reportedDeliveries); + return deliveries; + } + /** * Calculates the supplier's days of supply for a given material, partner, and site over a specified number of days. * It combines own and reported deliveries, and production quantities to forecast the number of days the stock will last. @@ -77,38 +87,7 @@ public SupplierSupplyService() { * @return a list of {@link OwnSupplierSupply} objects, each containing the calculated days of supply for a specific date. */ public final List calculateSupplierDaysOfSupply(String material, String partnerBpnl, String siteBpns, int numberOfDays) { - List supplierSupply = new ArrayList<>(); - LocalDate localDate = LocalDate.now(); - - List ownDeliveries = ownDeliveryService.getQuantityForDays(material, partnerBpnl, siteBpns, DirectionCharacteristic.OUTBOUND, numberOfDays); - List reportedDeliveries = reportedDeliveryService.getQuantityForDays(material, partnerBpnl, siteBpns, DirectionCharacteristic.OUTBOUND, numberOfDays); - List deliveries = mergeDeliveries(ownDeliveries, reportedDeliveries); - List productions = productionService.getQuantityForDays(material, partnerBpnl, siteBpns, numberOfDays); - double stockQuantity = stockService.getInitialStockQuantity(material, partnerBpnl); - - for (int i = 0; i < numberOfDays; i++) { - Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); - - if (i == numberOfDays - 1) { - stockQuantity += productions.get(i); - } - - double daysOfSupply = getDaysOfSupply( - stockQuantity, - deliveries.subList(i, deliveries.size())); - - OwnSupplierSupply supply = new OwnSupplierSupply(); - supply.setMaterial(materialService.findByOwnMaterialNumber(material)); - supply.setDate(date); - supply.setDaysOfSupply(daysOfSupply); - supplierSupply.add(supply); - - stockQuantity = stockQuantity - deliveries.get(i) + productions.get(i); - - localDate = localDate.plusDays(1); - } - - return supplierSupply; + return calculateDaysOfSupply(material, partnerBpnl, siteBpns, numberOfDays); } public final List findAll() { @@ -145,30 +124,6 @@ public boolean validate(ReportedSupplierSupply daysOfSupply) { (daysOfSupply.getStockLocationBPNA().equals(null) || daysOfSupply.getStockLocationBPNA().equals(daysOfSupply.getStockLocationBPNS())); } - /** - * Calculates the number of days of supply based on the current stock quantity and a list of demands. - * @param stockQuantity Current stock amount - * @param demands Sublist of demands for current iteration - * @return The number of days of supply that the stock can cover. - */ - private final double getDaysOfSupply(double stockQuantity, List demands) { - double daysOfSupply = 0; - - for (double demand : demands) { - if (stockQuantity >= demand) { - daysOfSupply += 1; - stockQuantity = stockQuantity - demand; - } else if (stockQuantity < demand && stockQuantity > 0) { - double fractional = stockQuantity / demand; - daysOfSupply = daysOfSupply + fractional; - break; - } else { - break; - } - } - return daysOfSupply; - } - /** * Merges own and reported deliveries into a single list. * @param list1 Own deliveries diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/SupplyService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/SupplyService.java new file mode 100644 index 00000000..7a89c176 --- /dev/null +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/SupplyService.java @@ -0,0 +1,108 @@ +/* + * 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.supply.logic.service; + +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.eclipse.tractusx.puris.backend.masterdata.logic.service.MaterialService; +import org.eclipse.tractusx.puris.backend.stock.logic.service.MaterialItemStockService; +import org.eclipse.tractusx.puris.backend.supply.domain.model.Supply; +import org.springframework.beans.factory.annotation.Autowired; + +public abstract class SupplyService { + @Autowired + private MaterialItemStockService stockService; + @Autowired + private MaterialService materialService; + + protected abstract T createSupplyInstance(); + protected abstract List getAddedValues(String material, String partnerBpnl, String siteBpns, int numberOfDays); + protected abstract List getConsumedValues(String material, String partnerBpnl, String siteBpns, int numberOfDays); + + /** + * Calculates the days of supply for a given material, partner, and site over a specified number of days. + * It combines added values (deliveries/productions), and consumed values (deliveries/demands) to forecast the number of days the stock will last. + * + * @param material the material identifier for which the days of supply are being calculated. + * @param partnerBpnl The bpnl of the partner. + * @param siteBpns the bpns of the site where the added values and consumed values are recorded. + * @param numberOfDays the number of days over which the forecast should be calculated. + * @return a list of {@link Supply} objects, each containing the calculated days of supply for a specific date. + */ + public final List calculateDaysOfSupply(String material, String partnerBpnl, String siteBpns, int numberOfDays) { + List supplyList = new ArrayList<>(); + LocalDate localDate = LocalDate.now(); + + List addedValues = getAddedValues(material, partnerBpnl, siteBpns, numberOfDays); + List consumedValues = getConsumedValues(material, partnerBpnl, siteBpns, numberOfDays); + double stockQuantity = stockService.getInitialStockQuantity(material, partnerBpnl); + + for (int i = 0; i < numberOfDays; i++) { + Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); + + if (i == numberOfDays - 1) { + stockQuantity += addedValues.get(i); + } + + double daysOfSupply = getDaysOfSupply(stockQuantity, consumedValues.subList(i, consumedValues.size())); + + T supply = createSupplyInstance(); + supply.setMaterial(materialService.findByOwnMaterialNumber(material)); + supply.setDate(date); + supply.setDaysOfSupply(daysOfSupply); + supplyList.add(supply); + + stockQuantity = stockQuantity - consumedValues.get(i) + addedValues.get(i); + + localDate = localDate.plusDays(1); + } + + return supplyList; + } + + /** + * Calculates the number of days of supply based on the current stock quantity and a list of consumed values. + * @param stockQuantity Current stock amount + * @param demands Sublist of consumed values for current iteration + * @return The number of days of supply that the stock can cover. + */ + private final double getDaysOfSupply(double stockQuantity, List demands) { + double daysOfSupply = 0; + + for (double demand : demands) { + if (stockQuantity >= demand) { + daysOfSupply += 1; + stockQuantity = stockQuantity - demand; + } else if (stockQuantity < demand && stockQuantity > 0) { + double fractional = stockQuantity / demand; + daysOfSupply = daysOfSupply + fractional; + break; + } else { + break; + } + } + return daysOfSupply; + } +} From 96a1ff343696aa838756ad05a241a554554fbe00 Mon Sep 17 00:00:00 2001 From: Benjamin Kotnik Date: Fri, 14 Jun 2024 10:47:00 +0200 Subject: [PATCH 6/6] fix(days-of-supply): moved mergeDeliveries and fixed calculation --- .../logic/service/CustomerSupplyService.java | 21 -------- .../logic/service/SupplierSupplyService.java | 21 -------- .../supply/logic/service/SupplyService.java | 49 ++++++++++++++----- 3 files changed, 36 insertions(+), 55 deletions(-) diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/CustomerSupplyService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/CustomerSupplyService.java index 3be98512..565a7e0c 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/CustomerSupplyService.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/CustomerSupplyService.java @@ -20,7 +20,6 @@ package org.eclipse.tractusx.puris.backend.supply.logic.service; -import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -123,24 +122,4 @@ public boolean validate(ReportedCustomerSupply daysOfSupply) { daysOfSupply.getPartner().getSites().stream().anyMatch(site -> site.getBpns().equals(daysOfSupply.getStockLocationBPNS())) && (daysOfSupply.getStockLocationBPNA().equals(null) || daysOfSupply.getStockLocationBPNA().equals(daysOfSupply.getStockLocationBPNS())); } - - /** - * Merges own and reported deliveries into a single list. - * @param list1 Own deliveries - * @param list2 Reported deliveries - * @return a new list containing the summed delivery quantities from the input lists. - */ - private static List mergeDeliveries(List list1, List list2) { - if (list1.size() != list2.size()) { - throw new IllegalArgumentException("Lists must be of the same length"); - } - - List mergedList = new ArrayList<>(list1.size()); - - for (int i = 0; i < list1.size(); i++) { - mergedList.add(list1.get(i) + list2.get(i)); - } - - return mergedList; - } } diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/SupplierSupplyService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/SupplierSupplyService.java index 66b3f6a3..ba2d83a5 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/SupplierSupplyService.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/SupplierSupplyService.java @@ -20,7 +20,6 @@ package org.eclipse.tractusx.puris.backend.supply.logic.service; -import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -123,24 +122,4 @@ public boolean validate(ReportedSupplierSupply daysOfSupply) { daysOfSupply.getPartner().getSites().stream().anyMatch(site -> site.getBpns().equals(daysOfSupply.getStockLocationBPNS())) && (daysOfSupply.getStockLocationBPNA().equals(null) || daysOfSupply.getStockLocationBPNA().equals(daysOfSupply.getStockLocationBPNS())); } - - /** - * Merges own and reported deliveries into a single list. - * @param list1 Own deliveries - * @param list2 Reported deliveries - * @return a new list containing the summed delivery quantities from the input lists. - */ - private static List mergeDeliveries(List list1, List list2) { - if (list1.size() != list2.size()) { - throw new IllegalArgumentException("Lists must be of the same length"); - } - - List mergedList = new ArrayList<>(list1.size()); - - for (int i = 0; i < list1.size(); i++) { - mergedList.add(list1.get(i) + list2.get(i)); - } - - return mergedList; - } } diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/SupplyService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/SupplyService.java index 7a89c176..bccf067c 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/SupplyService.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/supply/logic/service/SupplyService.java @@ -62,11 +62,9 @@ public final List calculateDaysOfSupply(String material, String partnerBpnl, for (int i = 0; i < numberOfDays; i++) { Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); - if (i == numberOfDays - 1) { - stockQuantity += addedValues.get(i); - } - - double daysOfSupply = getDaysOfSupply(stockQuantity, consumedValues.subList(i, consumedValues.size())); + var remainingAddedValues = addedValues.subList(i, addedValues.size()); + var remainingConsumedValues = consumedValues.subList(i, consumedValues.size()); + double daysOfSupply = getDaysOfSupply(stockQuantity, remainingAddedValues, remainingConsumedValues); T supply = createSupplyInstance(); supply.setMaterial(materialService.findByOwnMaterialNumber(material)); @@ -82,22 +80,47 @@ public final List calculateDaysOfSupply(String material, String partnerBpnl, return supplyList; } + /** + * Merges own and reported deliveries into a single list. + * @param list1 Own deliveries + * @param list2 Reported deliveries + * @return a new list containing the summed delivery quantities from the input lists. + */ + public static List mergeDeliveries(List list1, List list2) { + if (list1.size() != list2.size()) { + throw new IllegalArgumentException("Lists must be of the same length"); + } + + List mergedList = new ArrayList<>(list1.size()); + + for (int i = 0; i < list1.size(); i++) { + mergedList.add(list1.get(i) + list2.get(i)); + } + + return mergedList; + } + /** * Calculates the number of days of supply based on the current stock quantity and a list of consumed values. * @param stockQuantity Current stock amount - * @param demands Sublist of consumed values for current iteration + * @param addedValues Remaining list of added values for current iteration + * @param consumedValues Remaining list of consumed values for current iteration * @return The number of days of supply that the stock can cover. */ - private final double getDaysOfSupply(double stockQuantity, List demands) { + private final double getDaysOfSupply(double stockQuantity, List addedValues, List consumedValues) { double daysOfSupply = 0; - for (double demand : demands) { - if (stockQuantity >= demand) { + for (int i = 0; i < addedValues.size(); i++) { + Double addedValue = addedValues.get(i); + Double consumedValue = consumedValues.get(i); + + if ((stockQuantity + addedValue - consumedValue) >= 0) { daysOfSupply += 1; - stockQuantity = stockQuantity - demand; - } else if (stockQuantity < demand && stockQuantity > 0) { - double fractional = stockQuantity / demand; - daysOfSupply = daysOfSupply + fractional; + stockQuantity = stockQuantity + addedValue - consumedValue; + } else if ((stockQuantity + addedValue - consumedValue) < 0 && stockQuantity > 0) { + double fractional = (stockQuantity + addedValue) / consumedValue; + daysOfSupply += fractional; + stockQuantity = stockQuantity + addedValue - consumedValue; break; } else { break;