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(Pool): equivalence check on legal entities and addresses #715

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
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 @@ -23,10 +23,7 @@ import mu.KotlinLogging
import org.eclipse.tractusx.bpdm.common.dto.*
import org.eclipse.tractusx.bpdm.common.exception.BpdmNotFoundException
import org.eclipse.tractusx.bpdm.common.util.replace
import org.eclipse.tractusx.bpdm.pool.api.model.ChangelogType
import org.eclipse.tractusx.bpdm.pool.api.model.ConfidenceCriteriaDto
import org.eclipse.tractusx.bpdm.pool.api.model.LogisticAddressDto
import org.eclipse.tractusx.bpdm.pool.api.model.SiteStateDto
import org.eclipse.tractusx.bpdm.pool.api.model.*
import org.eclipse.tractusx.bpdm.pool.api.model.request.*
import org.eclipse.tractusx.bpdm.pool.api.model.response.*
import org.eclipse.tractusx.bpdm.pool.dto.AddressMetadataDto
Expand Down Expand Up @@ -55,7 +52,7 @@ class BusinessPartnerBuildService(
private val siteRepository: SiteRepository,
private val logisticAddressRepository: LogisticAddressRepository,
private val requestValidationService: RequestValidationService,
private val businessPartnerEquivalenceService: BusinessPartnerEquivalenceService
private val businessPartnerEquivalenceMapper: BusinessPartnerEquivalenceMapper
) {

private val logger = KotlinLogging.logger { }
Expand All @@ -79,7 +76,7 @@ class BusinessPartnerBuildService(

val requestsByLegalEntities = validRequests
.mapIndexed { bpnIndex, request ->
val legalEntity = createLegalEntity(request.legalEntity, bpnLs[bpnIndex], request.legalEntity.legalName, legalEntityMetadataMap)
val legalEntity = createLegalEntity(request.legalEntity, bpnLs[bpnIndex], legalEntityMetadataMap)
val legalAddress = createLogisticAddress(request.legalAddress, bpnAs[bpnIndex], legalEntity, addressMetadataMap)
legalEntity.legalAddress = legalAddress
Pair(legalEntity, request)
Expand Down Expand Up @@ -222,9 +219,12 @@ class BusinessPartnerBuildService(

val legalEntityRequestPairs = legalEntities.map { legalEntity -> Pair(legalEntity, requestsByBpn[legalEntity.bpn]!!) }
legalEntityRequestPairs.forEach { (legalEntity, request) ->
if (!businessPartnerEquivalenceService.isEquivalent(request)) {
updateLegalEntity(legalEntity, request.legalEntity, request.legalEntity.legalName, legalEntityMetadataMap)
updateLogisticAddress(legalEntity.legalAddress, request.legalAddress, addressMetadataMap)
val legalEntityBeforeUpdate = businessPartnerEquivalenceMapper.toEquivalenceDto(legalEntity)
updateLegalEntity(legalEntity, request.legalEntity, legalEntityMetadataMap)
updateLogisticAddress(legalEntity.legalAddress, request.legalAddress, addressMetadataMap)
val legalEntityAfterUpdate = businessPartnerEquivalenceMapper.toEquivalenceDto(legalEntity)

if (legalEntityBeforeUpdate != legalEntityAfterUpdate) {
legalEntityRepository.save(legalEntity)

changelogService.createChangelogEntries(
Expand Down Expand Up @@ -269,9 +269,12 @@ class BusinessPartnerBuildService(

val siteRequestPairs = sites.map { site -> Pair(site, requestByBpnMap[site.bpn]!!) }
siteRequestPairs.forEach { (site, request) ->
if (!businessPartnerEquivalenceService.isEquivalent(request)) {
updateSite(site, request.site)
updateLogisticAddress(site.mainAddress, request.site.mainAddress, addressMetadataMap)
val siteBeforeUpdate = businessPartnerEquivalenceMapper.toEquivalenceDto(site)
updateSite(site, request.site)
updateLogisticAddress(site.mainAddress, request.site.mainAddress, addressMetadataMap)
val siteAfterUpdate = businessPartnerEquivalenceMapper.toEquivalenceDto(site)

if (siteBeforeUpdate != siteAfterUpdate) {
siteRepository.save(site)

changelogService.createChangelogEntries(listOf(ChangelogEntryCreateRequest(site.bpn, ChangelogType.UPDATE, BusinessPartnerType.SITE)))
Expand Down Expand Up @@ -304,8 +307,11 @@ class BusinessPartnerBuildService(

val addressRequestPairs = addresses.sortedBy { it.bpn }.zip(requests.sortedBy { it.bpna })
addressRequestPairs.forEach { (address, request) ->
if (!businessPartnerEquivalenceService.isEquivalent(request)) {
updateLogisticAddress(address, request.address, metadataMap)
val addressBeforeUpdate = businessPartnerEquivalenceMapper.toEquivalenceDto(address)
updateLogisticAddress(address, request.address, metadataMap)
val addressAfterUpdate = businessPartnerEquivalenceMapper.toEquivalenceDto(address)

if (addressBeforeUpdate != addressAfterUpdate) {
logisticAddressRepository.save(address)

changelogService.createChangelogEntries(listOf(ChangelogEntryCreateRequest(address.bpn, ChangelogType.UPDATE, BusinessPartnerType.ADDRESS)))
Expand Down Expand Up @@ -550,51 +556,39 @@ class BusinessPartnerBuildService(
}

fun createLegalEntity(
legalEntityDto: IBaseLegalEntityDto,
legalEntityDto: LegalEntityDto,
bpnL: String,
legalNameValue: String?,
metadataMap: LegalEntityMetadataMapping
): LegalEntity {

if (legalNameValue == null) {
throw BpdmValidationException(TaskStepBuildService.CleaningError.LEGAL_NAME_IS_NULL.message)
}

// it has to be validated that the legalForm exits
val legalForm = legalEntityDto.legalForm?.let { metadataMap.legalForms[it]!! }
val legalName = Name(value = legalNameValue, shortName = legalEntityDto.legalShortName)
val legalName = Name(value = legalEntityDto.legalName, shortName = legalEntityDto.legalShortName)
val newLegalEntity = LegalEntity(
bpn = bpnL,
legalName = legalName,
legalForm = legalForm,
currentness = Instant.now().truncatedTo(ChronoUnit.MICROS),
confidenceCriteria = createConfidenceCriteria(legalEntityDto.confidenceCriteria!!)
confidenceCriteria = createConfidenceCriteria(legalEntityDto.confidenceCriteria)
)
updateLegalEntity(newLegalEntity, legalEntityDto, legalNameValue, metadataMap)
updateLegalEntity(newLegalEntity, legalEntityDto, metadataMap)

return newLegalEntity
}
fun updateLegalEntity(
legalEntity: LegalEntity,
legalEntityDto: IBaseLegalEntityDto,
legalName: String?,
legalEntityDto: LegalEntityDto,
metadataMap: LegalEntityMetadataMapping
) {
if(legalName == null) {
throw BpdmValidationException(TaskStepBuildService.CleaningError.LEGAL_NAME_IS_NULL.message)
}


legalEntity.currentness = createCurrentnessTimestamp()

legalEntity.legalName = Name(value = legalName, shortName = legalEntityDto.legalShortName)
legalEntity.legalName = Name(value = legalEntityDto.legalName, shortName = legalEntityDto.legalShortName)

legalEntity.legalForm = legalEntityDto.legalForm?.let { metadataMap.legalForms[it]!! }

legalEntity.identifiers.replace(legalEntityDto.identifiers.map { toLegalEntityIdentifier(it, metadataMap.idTypes, legalEntity) })
legalEntity.states.replace(legalEntityDto.states.map { toLegalEntityState(it, legalEntity) })
legalEntity.classifications.replace(legalEntityDto.classifications.map { toLegalEntityClassification(it, legalEntity) }.toSet())
legalEntity.confidenceCriteria = createConfidenceCriteria(legalEntityDto.confidenceCriteria!!)
legalEntity.confidenceCriteria = createConfidenceCriteria(legalEntityDto.confidenceCriteria)
}

fun createPhysicalAddress(physicalAddress: IBasePhysicalPostalAddressDto, regions: Map<String, Region>): PhysicalPostalAddress {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,51 +25,18 @@ import org.eclipse.tractusx.bpdm.common.model.BusinessStateType
import org.eclipse.tractusx.bpdm.common.model.ClassificationType
import org.eclipse.tractusx.bpdm.common.model.DeliveryServiceType
import org.eclipse.tractusx.bpdm.pool.api.model.ConfidenceCriteriaDto
import org.eclipse.tractusx.bpdm.pool.api.model.LogisticAddressDto
import org.eclipse.tractusx.bpdm.pool.api.model.request.AddressPartnerUpdateRequest
import org.eclipse.tractusx.bpdm.pool.api.model.request.LegalEntityPartnerUpdateRequest
import org.eclipse.tractusx.bpdm.pool.api.model.request.SitePartnerUpdateRequest
import org.eclipse.tractusx.bpdm.pool.entity.ConfidenceCriteria
import org.eclipse.tractusx.bpdm.pool.entity.LegalEntity
import org.eclipse.tractusx.bpdm.pool.entity.LogisticAddress
import org.eclipse.tractusx.bpdm.pool.entity.Site
import org.eclipse.tractusx.bpdm.pool.exception.BpdmValidationException
import org.eclipse.tractusx.bpdm.pool.repository.LegalEntityRepository
import org.eclipse.tractusx.bpdm.pool.repository.LogisticAddressRepository
import org.eclipse.tractusx.bpdm.pool.repository.SiteRepository
import org.springframework.stereotype.Service
import java.time.LocalDateTime
import java.util.*

@Service
class BusinessPartnerEquivalenceService(
private val legalEntityRepository: LegalEntityRepository,
private val siteRepository: SiteRepository,
private val logisticAddressRepository: LogisticAddressRepository
) {
class BusinessPartnerEquivalenceMapper {

fun isEquivalent(updateDto: LegalEntityPartnerUpdateRequest): Boolean {
val entity = legalEntityRepository.findByBpn(updateDto.bpnl)
?: throw BpdmValidationException(TaskStepBuildService.CleaningError.INVALID_LEGAL_ENTITY_BPN.message)

return toEquivalenceDto(updateDto) == toEquivalenceDto(entity)
}

fun isEquivalent(updateDto: SitePartnerUpdateRequest): Boolean {
val entity =
siteRepository.findByBpn(updateDto.bpns) ?: throw BpdmValidationException(TaskStepBuildService.CleaningError.INVALID_LEGAL_ENTITY_BPN.message)

return toEquivalenceDto(updateDto) == toEquivalenceDto(entity)
}

fun isEquivalent(updateDto: AddressPartnerUpdateRequest): Boolean {
val entity = logisticAddressRepository.findByBpn(updateDto.bpna)
?: throw BpdmValidationException(TaskStepBuildService.CleaningError.INVALID_LEGAL_ENTITY_BPN.message)

return toEquivalenceDto(updateDto) == toEquivalenceDto(entity)
}

private fun toEquivalenceDto(legalEntity: LegalEntity) =
fun toEquivalenceDto(legalEntity: LegalEntity) =
with(legalEntity) {
LegalEntityEquivalenceDto(
legalForm = legalForm?.technicalKey,
Expand All @@ -83,22 +50,7 @@ class BusinessPartnerEquivalenceService(
)
}


private fun toEquivalenceDto(request: LegalEntityPartnerUpdateRequest) =
with(request.legalEntity) {
LegalEntityEquivalenceDto(
legalForm = legalForm,
legalName = legalName,
legalShortName = legalShortName,
identifiers = identifiers.map { IdentifierEquivalenceDto(it.value, it.type) }.toSortedSet(compareBy { it.value }),
states = states.map { StateEquivalenceDto(it.validFrom, it.validTo, it.type) }.toSortedSet(compareBy { it.validFrom }),
classifications = classifications.map { ClassificationEquivalenceDto(it.code, it.value, it.type) }.toSortedSet(compareBy { it.value }),
confidenceCriteria = toEquivalenceDto(confidenceCriteria),
legalAddress = toEquivalenceDto(request.legalAddress)
)
}

private fun toEquivalenceDto(site: Site) =
fun toEquivalenceDto(site: Site) =
with(site) {
SiteEquivalenceDto(
name = name,
Expand All @@ -108,18 +60,7 @@ class BusinessPartnerEquivalenceService(
)
}


private fun toEquivalenceDto(request: SitePartnerUpdateRequest) =
with(request.site) {
SiteEquivalenceDto(
name = name,
states = states.map { StateEquivalenceDto(it.validFrom, it.validTo, it.type) }.toSortedSet(compareBy { it.validFrom }),
confidenceCriteria = toEquivalenceDto(confidenceCriteria),
mainAddress = toEquivalenceDto(mainAddress)
)
}

private fun toEquivalenceDto(logisticAddress: LogisticAddress) =
fun toEquivalenceDto(logisticAddress: LogisticAddress) =
LogisticAddressEquivalenceDto(
name = logisticAddress.name,
states = logisticAddress.states.map { StateEquivalenceDto(it.validFrom, it.validTo, it.type) }.toSortedSet(compareBy { it.validFrom }),
Expand Down Expand Up @@ -173,66 +114,6 @@ class BusinessPartnerEquivalenceService(
confidenceCriteria = toEquivalenceDto(logisticAddress.confidenceCriteria)
)

private fun toEquivalenceDto(request: AddressPartnerUpdateRequest) =
toEquivalenceDto(request.address)


private fun toEquivalenceDto(logisticAddress: LogisticAddressDto) =
with(logisticAddress) {
LogisticAddressEquivalenceDto(
name = logisticAddress.name,
states = states.map { StateEquivalenceDto(it.validFrom, it.validTo, it.type) }.toSortedSet(compareBy { it.validFrom }),
identifiers = identifiers.map { IdentifierEquivalenceDto(it.value, it.type) }.toSortedSet(compareBy { it.value }),
physicalPostalAddress = with(physicalPostalAddress) {
PhysicalAddressEquivalenceDto(
geographicCoordinates = with(geographicCoordinates) { this?.let { GeoCoordinateDto(longitude, latitude, altitude) } },
country = country,
administrativeAreaLevel1 = administrativeAreaLevel1,
administrativeAreaLevel2 = administrativeAreaLevel2,
administrativeAreaLevel3 = administrativeAreaLevel3,
postalCode = postalCode,
city = city,
district = district,
companyPostalCode = companyPostalCode,
industrialZone = industrialZone,
building = building,
floor = floor,
door = door,
street = with(street) {
this?.let {
StreetEquivalenceDto(
name,
houseNumber,
houseNumberSupplement,
milestone,
direction,
namePrefix,
additionalNamePrefix,
nameSuffix,
additionalNameSuffix
)
}
}
)
},
alternativePostalAddress = with(logisticAddress.alternativePostalAddress) {
this?.let {
AlternativeEquivalenceDto(
geographicCoordinates = with(geographicCoordinates) { this?.let { GeoCoordinateDto(longitude, latitude, altitude) } },
country = country,
administrativeAreaLevel1 = administrativeAreaLevel1,
postalCode = postalCode,
city = city,
deliveryServiceType = deliveryServiceType,
deliveryServiceQualifier = deliveryServiceQualifier,
deliveryServiceNumber = deliveryServiceNumber
)
}
},
confidenceCriteria = toEquivalenceDto(confidenceCriteria)
)
}

private fun toEquivalenceDto(confidenceCriteriaDto: ConfidenceCriteriaDto) =
with(confidenceCriteriaDto) {
ConfidenceCriteriaEquivalenceDto(
Expand Down
Loading