Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(DeliveryRequestApiService): filter deliveries requested by partner role and incoterms #435

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public ResponseEntity<DeliveryInformation> getDeliveryMapping(
log.warn("Rejecting request at Delivery Information Submodel request 2.0.0 endpoint");
return ResponseEntity.badRequest().build();
}

if (!"$value".equals(representation)) {
log.warn("Rejecting request at Delivery Information Submodel request 2.0.0 endpoint, missing '$value' in request");
if (!PatternStore.NON_EMPTY_NON_VERTICAL_WHITESPACE_PATTERN.matcher(representation).matches()) {
Expand All @@ -75,8 +75,11 @@ public ResponseEntity<DeliveryInformation> getDeliveryMapping(
log.warn("Received " + representation + " from " + bpnl);
return ResponseEntity.status(501).build();
}

log.info("Received request for " + materialNumberCx + " from " + bpnl);
Dismissed Show dismissed Hide dismissed
var samm = deliveryRequestApiSrvice.handleDeliverySubmodelRequest(bpnl, materialNumberCx);
if (samm == null) {
log.error("SAMM for delivery is null, return 500.");
return ResponseEntity.status(500).build();
}
return ResponseEntity.ok(samm);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import jakarta.validation.constraints.Pattern;
import lombok.*;
import lombok.experimental.SuperBuilder;

import org.eclipse.tractusx.puris.backend.common.domain.model.measurement.ItemUnitEnumeration;
import org.eclipse.tractusx.puris.backend.common.util.PatternStore;
import org.eclipse.tractusx.puris.backend.masterdata.domain.model.Material;
Expand Down Expand Up @@ -108,23 +107,23 @@ public boolean equals(Object o) {

final Delivery that = (Delivery) o;
return this.getMaterial().getOwnMaterialNumber().equals(that.getMaterial().getOwnMaterialNumber()) &&
this.getPartner().getUuid().equals(that.getPartner().getUuid()) &&
this.getTrackingNumber().equals(that.getTrackingNumber()) &&
this.getIncoterm().equals(that.getIncoterm()) &&
this.getDestinationBpns().equals(that.getDestinationBpns()) &&
this.getDestinationBpna().equals(that.getDestinationBpna()) &&
this.getOriginBpns().equals(that.getOriginBpns()) &&
this.getOriginBpna().equals(that.getOriginBpna()) &&
this.getDateOfDeparture().equals(that.getDateOfDeparture()) &&
this.getDateOfArrival().equals(that.getDateOfArrival()) &&
this.getDepartureType().equals(that.getDepartureType()) &&
this.getArrivalType().equals(that.getArrivalType()) &&
this.getIncoterm().equals(that.getIncoterm()) &&
(
Objects.equals(this.getCustomerOrderNumber(), that.getCustomerOrderNumber()) &&
this.getPartner().getUuid().equals(that.getPartner().getUuid()) &&
Objects.equals(this.getTrackingNumber(), that.getTrackingNumber()) &&
this.getIncoterm().equals(that.getIncoterm()) &&
this.getDestinationBpns().equals(that.getDestinationBpns()) &&
this.getDestinationBpna().equals(that.getDestinationBpna()) &&
this.getOriginBpns().equals(that.getOriginBpns()) &&
this.getOriginBpna().equals(that.getOriginBpna()) &&
this.getDateOfDeparture().equals(that.getDateOfDeparture()) &&
this.getDateOfArrival().equals(that.getDateOfArrival()) &&
this.getDepartureType().equals(that.getDepartureType()) &&
this.getArrivalType().equals(that.getArrivalType()) &&
this.getIncoterm().equals(that.getIncoterm()) &&
(
Objects.equals(this.getCustomerOrderNumber(), that.getCustomerOrderNumber()) &&
Objects.equals(this.getCustomerOrderPositionNumber(), that.getCustomerOrderPositionNumber()) &&
Objects.equals(this.getSupplierOrderNumber(), that.getSupplierOrderNumber())
);
);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,12 @@
import lombok.extern.slf4j.Slf4j;
import org.eclipse.tractusx.puris.backend.common.edc.domain.model.SubmodelType;
import org.eclipse.tractusx.puris.backend.common.edc.logic.service.EdcAdapterService;
import org.eclipse.tractusx.puris.backend.delivery.domain.model.DeliveryResponsibilityEnumeration;
import org.eclipse.tractusx.puris.backend.delivery.domain.model.OwnDelivery;
import org.eclipse.tractusx.puris.backend.delivery.logic.adapter.DeliveryInformationSammMapper;
import org.eclipse.tractusx.puris.backend.delivery.logic.dto.deliverysamm.DeliveryInformation;
import org.eclipse.tractusx.puris.backend.masterdata.domain.model.Material;
import org.eclipse.tractusx.puris.backend.masterdata.domain.model.MaterialPartnerRelation;
import org.eclipse.tractusx.puris.backend.masterdata.domain.model.Partner;
import org.eclipse.tractusx.puris.backend.masterdata.logic.service.MaterialPartnerRelationService;
import org.eclipse.tractusx.puris.backend.masterdata.logic.service.MaterialService;
Expand All @@ -35,7 +38,9 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;

@Service
@Slf4j
Expand Down Expand Up @@ -84,13 +89,42 @@ public DeliveryInformation handleDeliverySubmodelRequest(String bpnl, String mat
return null;
}

var mpr = mprService.find(material,partner);
if (mpr == null || !mpr.isPartnerSuppliesMaterial()) {
// if the material number cx has been defined by us, we're returning information as an supplier
// that means our partner is acting as customer
boolean partnerIsCustomer = material.getMaterialNumberCx().equals(materialNumberCx);
var mpr = mprService.find(material, partner);
if (mpr == null ||
(partnerIsCustomer && !mpr.isPartnerBuysMaterial()) ||
(!partnerIsCustomer && !mpr.isPartnerSuppliesMaterial())
) {
// only send an answer if partner is registered as supplier
log.warn(
"Partner acts as role '{}' but tried to access data for material number cx '{}' for the " +
"opposite role '{}'. Returning no data at all.",
partnerIsCustomer ? "Customer" : "Supplier",
materialNumberCx,
partnerIsCustomer ? "Supplier" : " Customer"
);
Dismissed Show dismissed Hide dismissed
return null;
}

var currentDeliveries = ownDeliveryService.findAllByFilters(Optional.of(material.getOwnMaterialNumber()), Optional.empty(), Optional.of(partner.getBpnl()));
List<OwnDelivery> currentDeliveries = ownDeliveryService.findAllByFilters(
Optional.of(material.getOwnMaterialNumber()),
Optional.empty(),
Optional.of(partner.getBpnl())
);

Predicate<OwnDelivery> parnterRoleDirectionPredicate = partnerRoleDirectionPredicate(partnerIsCustomer, mpr);
currentDeliveries = currentDeliveries.stream().filter(
parnterRoleDirectionPredicate
).toList();
log.debug(
"Found '{}' deliveries for material number cx '{}' for partner with bpnl '{}' asking in role '{}'.",
currentDeliveries.size(),
materialNumberCx,
bpnl,
partnerIsCustomer ? "Customer" : "Supplier"
);
Dismissed Show dismissed Hide dismissed
return sammMapper.ownDeliveryToSamm(currentDeliveries, partner, material);
}

Expand Down Expand Up @@ -126,4 +160,38 @@ public void doReportedDeliveryRequest(Partner partner, Material material) {
log.error("Error in Reported Deliveries Request for " + material.getOwnMaterialNumber() + " and partner " + partner.getBpnl(), e);
}
}

/**
* filters OwnDelivery entities to be returned to a partner based on his role
* <p>
* Based on accuracy the following rules apply:
* <li>use role derived from cx id and incoterm responsibility</li>
* <li>use mpr role, if only one is present and no incoterms are given</li>
*
* @param partnerIsCustomer to use as role in combination with incoterms (derived from material number cx)
* @param mpr to check the supplies / orders relation in case of missing incoterms
* @return Predicate<OwnDelivery> returning true if incoterms and role match or no incoterm but only one role on mpr is given, else false
*/
public static Predicate<OwnDelivery> partnerRoleDirectionPredicate(boolean partnerIsCustomer, MaterialPartnerRelation mpr) {
return delivery -> {
// return all, if no incoterm is set but partner only acts in one role
if (delivery.getIncoterm() == null) {
// unlikely that we have a mpr without any role set but then we also don't return something
if (mpr.isPartnerBuysMaterial() && mpr.isPartnerSuppliesMaterial()) {
return false;
} else return mpr.isPartnerBuysMaterial() || mpr.isPartnerSuppliesMaterial();
}

// if we have incoterms set, filter more sophisticatedly based on responsbility of incoterms and role
// derived from material number cx
DeliveryResponsibilityEnumeration responsibility = delivery.getIncoterm().getResponsibility();
if (partnerIsCustomer) {
tom-rm-meyer-ISST marked this conversation as resolved.
Show resolved Hide resolved
return responsibility == DeliveryResponsibilityEnumeration.CUSTOMER ||
responsibility == DeliveryResponsibilityEnumeration.PARTIAL;
} else {
return responsibility == DeliveryResponsibilityEnumeration.SUPPLIER ||
responsibility == DeliveryResponsibilityEnumeration.PARTIAL;
}
};
}
}
Loading
Loading