Skip to content

Commit

Permalink
Merge pull request #650 from catenax-ng/feat/pool_Update_only_changed…
Browse files Browse the repository at this point in the history
…_Business_Partners

feat(pool): Update only changed Business Partners
  • Loading branch information
nicoprow authored Jan 11, 2024
2 parents b300d30 + 08ca45c commit c81d08b
Show file tree
Hide file tree
Showing 3 changed files with 288 additions and 30 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
/*******************************************************************************
* Copyright (c) 2021,2023 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.bpdm.pool.service

import org.eclipse.tractusx.bpdm.pool.entity.*
import org.springframework.stereotype.Service

@Service
class BusinessPartnerEquivalenceService {
fun isEquivalent(original: LegalEntity, updated: LegalEntity): Boolean =
original.bpn != updated.bpn ||
isEquivalent(original.legalForm, updated.legalForm) ||
isEquivalentLegalEntityIdentifier(original.identifiers, updated.identifiers) ||
isEquivalentLegalEntityState(original.states, updated.states) ||
isEquivalentLogisticAddress(original.addresses, updated.addresses) ||
isEquivalent(original.sites, updated.sites) ||
isEquivalentLegalEntityClassification(original.classifications, updated.classifications) ||
isEquivalent(original.legalName, updated.legalName) ||
isEquivalent(original.legalAddress, updated.legalAddress)


private fun isEquivalentLegalEntityIdentifier(
originalSet: MutableSet<LegalEntityIdentifier>,
updatedSet: MutableSet<LegalEntityIdentifier>
): Boolean {
return isEquivalent(originalSet, updatedSet) { entity1, entity2 ->
isEquivalent(entity1, entity2)
}
}

private fun isEquivalent(original: LegalEntityIdentifier, updated: LegalEntityIdentifier): Boolean =
original.value != updated.value ||
isEquivalent(original.type, updated.type) ||
original.issuingBody != updated.issuingBody

private fun isEquivalent(original: IdentifierType, updated: IdentifierType): Boolean =
original.technicalKey != updated.technicalKey ||
original.name != updated.name ||
original.businessPartnerType.name != updated.businessPartnerType.name


private fun isEquivalentLegalEntityState(
originalSet: MutableSet<LegalEntityState>,
updatedSet: MutableSet<LegalEntityState>
): Boolean {
return isEquivalent(originalSet, updatedSet) { entity1, entity2 ->
isEquivalent(entity1, entity2)
}
}

private fun isEquivalent(original: LegalEntityState, updated: LegalEntityState): Boolean =
original.description != updated.description ||
original.validFrom != updated.validFrom ||
original.validTo != updated.validTo ||
original.type != updated.type


private fun isEquivalentLegalEntityClassification(
originalSet: MutableSet<LegalEntityClassification>,
updatedSet: MutableSet<LegalEntityClassification>
): Boolean {
return isEquivalent(originalSet, updatedSet) { entity1, entity2 ->
isEquivalent(entity1, entity2)
}
}


private fun isEquivalent(original: LegalEntityClassification, updated: LegalEntityClassification): Boolean {
return (
original.value != updated.value ||
original.code != updated.code ||
original.type != updated.type
)
}

private fun isEquivalent(original: Name, updated: Name): Boolean =
original.value != updated.value ||
original.shortName != updated.shortName

private fun isEquivalent(original: LegalForm?, updated: LegalForm?): Boolean =
original?.name != updated?.name ||
original?.technicalKey != updated?.technicalKey ||
original?.abbreviation != updated?.abbreviation


private fun isEquivalentLogisticAddress(
originalSet: MutableSet<LogisticAddress>,
updatedSet: MutableSet<LogisticAddress>
): Boolean {
return isEquivalent(originalSet, updatedSet) { entity1, entity2 ->
isEquivalent(entity1, entity2)
}
}


fun isEquivalent(original: LogisticAddress, updated: LogisticAddress): Boolean =
original.bpn != updated.bpn ||
original.name != updated.name ||
isEquivalent(original.physicalPostalAddress, updated.physicalPostalAddress) ||
isEquivalent(original.alternativePostalAddress, updated.alternativePostalAddress)


fun isEquivalentLogisticAddressSite(original: LogisticAddress, updated: LogisticAddress): Boolean =
original.name != updated.name ||
isEquivalent(original.physicalPostalAddress, updated.physicalPostalAddress) ||
isEquivalent(original.alternativePostalAddress, updated.alternativePostalAddress)


private fun isEquivalent(
originalSet: MutableSet<Site>,
updatedSet: MutableSet<Site>
): Boolean {
return isEquivalent(originalSet, updatedSet) { entity1, entity2 ->
isEquivalent(entity1, entity2)
}
}

fun isEquivalent(original: Site, updated: Site): Boolean =
original.bpn != updated.bpn ||
original.name != updated.name ||
isEquivalentLogisticAddressSite(original.mainAddress, updated.mainAddress)

private fun isEquivalent(
original: AlternativePostalAddress?,
updated: AlternativePostalAddress?
): Boolean =
isEquivalent(original?.geographicCoordinates, updated?.geographicCoordinates) ||
original?.country != updated?.country ||
isEquivalent(original?.administrativeAreaLevel1, updated?.administrativeAreaLevel1) ||
original?.postCode != updated?.postCode ||
original?.city != updated?.city ||
original?.deliveryServiceType != updated?.deliveryServiceType ||
original?.deliveryServiceNumber != updated?.deliveryServiceNumber ||
original?.deliveryServiceQualifier != updated?.deliveryServiceQualifier


private fun isEquivalent(original: GeographicCoordinate?, updated: GeographicCoordinate?): Boolean =
original?.latitude != updated?.latitude ||
original?.longitude != updated?.longitude ||
original?.altitude != updated?.altitude

private fun isEquivalent(original: Region?, updated: Region?): Boolean =
original?.countryCode != updated?.countryCode ||
original?.regionCode != updated?.regionCode ||
original?.regionName != updated?.regionName


private fun isEquivalent(
original: PhysicalPostalAddress,
updated: PhysicalPostalAddress
): Boolean =
original.country.name != updated.country.name ||
original.administrativeAreaLevel1 != updated.administrativeAreaLevel1 ||
original.administrativeAreaLevel2 != updated.administrativeAreaLevel2 ||
original.administrativeAreaLevel3 != updated.administrativeAreaLevel3 ||
original.administrativeAreaLevel4 != updated.administrativeAreaLevel4 ||
original.postCode != updated.postCode ||
original.city != updated.city ||
original.districtLevel1 != updated.districtLevel1 ||
original.districtLevel2 != updated.districtLevel2 ||
original.companyPostCode != updated.companyPostCode ||
original.industrialZone != updated.industrialZone ||
original.building != updated.building ||
original.floor != updated.floor ||
original.door != updated.door ||
isEquivalent(original.geographicCoordinates, updated.geographicCoordinates) ||
isEquivalent(original.street, updated.street)

private fun isEquivalent(original: Street?, updated: Street?): Boolean =
original?.name != updated?.name ||
original?.houseNumber != updated?.houseNumber ||
original?.milestone != updated?.milestone ||
original?.direction != updated?.direction

private fun <T> isEquivalent(
originalSet: MutableSet<T>,
updatedSet: MutableSet<T>,
comparator: (T, T) -> Boolean
): Boolean {
if (originalSet.size != updatedSet.size) {
return true
}

for (originalEntity in originalSet) {
val updatedEntity = updatedSet.find { comparator(it, originalEntity) }

if (updatedEntity == null || comparator(originalEntity, updatedEntity)) {
return true
}
}

return false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class TaskStepBuildService(
private val legalEntityRepository: LegalEntityRepository,
private val logisticAddressRepository: LogisticAddressRepository,
private val siteRepository: SiteRepository,
private val businessPartnerEquivalenceService: BusinessPartnerEquivalenceService,
) {

enum class CleaningError(val message: String) {
Expand Down Expand Up @@ -100,7 +101,7 @@ class TaskStepBuildService(
)
},
legalEntity = businessPartnerDto.legalEntity!!.copy(
bpnLReference = BpnReferenceDto(referenceValue = legalEntity.bpn, referenceType = BpnReferenceType.Bpn) ,
bpnLReference = BpnReferenceDto(referenceValue = legalEntity.bpn, referenceType = BpnReferenceType.Bpn),
legalAddress = businessPartnerDto.legalEntity!!.legalAddress!!.copy(
bpnAReference = BpnReferenceDto(referenceValue = legalEntity.legalAddress.bpn, referenceType = BpnReferenceType.Bpn)
)
Expand All @@ -117,19 +118,22 @@ class TaskStepBuildService(
siteEntity: Site?,
taskEntryBpnMapping: TaskEntryBpnMapping
): LogisticAddress {

val bpnAReference = addressDto?.bpnAReference ?: throw BpdmValidationException(CleaningError.BPNA_IS_NULL.message)

val bpn = taskEntryBpnMapping.getBpn(bpnAReference)

var hasChanges = false
val upsertAddress = if (bpn == null) {
val bpnA = bpnIssuingService.issueAddressBpns(1).single()
taskEntryBpnMapping.addMapping(bpnAReference, bpnA)
createLogisticAddressInternal(addressDto, bpnA)
} else {
val addressMetadataMap = metadataService.getMetadata(listOf(addressDto)).toMapping()
val updateAddress = logisticAddressRepository.findByBpn(bpn)

if (updateAddress != null) {
val newAddress = createLogisticAddressInternal(addressDto, updateAddress.bpn)
updateLogisticAddress(newAddress, addressDto, addressMetadataMap)
hasChanges = businessPartnerEquivalenceService.isEquivalent(updateAddress, newAddress)
updateLogisticAddress(updateAddress, addressDto, addressMetadataMap)
} else {
throw BpdmValidationException(CleaningError.INVALID_LOGISTIC_ADDRESS_BPN.message)
Expand All @@ -141,15 +145,22 @@ class TaskStepBuildService(
} else {
upsertAddress.legalEntity = legalEntity
}
logisticAddressRepository.save(upsertAddress)

if (hasChanges || bpn == null) {
logisticAddressRepository.save(upsertAddress)
}


val changelogType =
if (bpn == null) ChangelogType.CREATE else ChangelogType.UPDATE
changelogService.createChangelogEntries(
listOf(
ChangelogEntryCreateRequest(upsertAddress.bpn, changelogType, BusinessPartnerType.ADDRESS)
if (hasChanges || bpn == null) {
changelogService.createChangelogEntries(
listOf(
ChangelogEntryCreateRequest(upsertAddress.bpn, changelogType, BusinessPartnerType.ADDRESS)
)
)
)
}


return upsertAddress
}
Expand Down Expand Up @@ -253,7 +264,7 @@ class TaskStepBuildService(
val legalEntityMetadataMap = metadataService.getMetadata(listOf(legalEntityDto)).toMapping()

val bpn = taskEntryBpnMapping.getBpn(bpnLReference)

var hasChanges = false
val upsertLe = if (bpn == null) {
val bpnL = bpnIssuingService.issueLegalEntityBpns(1).single()
taskEntryBpnMapping.addMapping(bpnLReference, bpnL)
Expand All @@ -267,6 +278,14 @@ class TaskStepBuildService(
val updateLe = legalEntityRepository.findByBpn(bpn)
if (updateLe != null) {
if (legalEntityDto.hasChanged == true) {

val createdLe =
BusinessPartnerBuildService.createLegalEntity(legalEntityDto, updateLe.bpn, legalEntityDto.legalName, legalEntityMetadataMap)
val address = createLogisticAddress(legalAddress, taskEntryBpnMapping)
createdLe.legalAddress = address
address.legalEntity = createdLe
hasChanges = businessPartnerEquivalenceService.isEquivalent(updateLe, createdLe)

BusinessPartnerBuildService.updateLegalEntity(updateLe, legalEntityDto, legalEntityDto.legalName, legalEntityMetadataMap)
val addressMetadataMap = metadataService.getMetadata(listOf(legalAddress)).toMapping()
updateLogisticAddress(updateLe.legalAddress, legalAddress, addressMetadataMap)
Expand All @@ -276,15 +295,17 @@ class TaskStepBuildService(
}
updateLe
}
legalEntityRepository.save(upsertLe)
val changelogType =
if (bpn == null) ChangelogType.CREATE else ChangelogType.UPDATE
changelogService.createChangelogEntries(
listOf(
ChangelogEntryCreateRequest(upsertLe.bpn, changelogType, BusinessPartnerType.LEGAL_ENTITY)
)
)

if (hasChanges || bpn == null) {
legalEntityRepository.save(upsertLe)
changelogService.createChangelogEntries(
listOf(
ChangelogEntryCreateRequest(upsertLe.bpn, changelogType, BusinessPartnerType.LEGAL_ENTITY)
)
)
}
return upsertLe
}

Expand All @@ -300,7 +321,7 @@ class TaskStepBuildService(

val bpn = taskEntryBpnMapping.getBpn(bpnSReference)
val changelogType = if (bpn == null) ChangelogType.CREATE else ChangelogType.UPDATE

var hasChanges = false
val upsertSite = if (bpn == null) {
val bpnS = bpnIssuingService.issueSiteBpns(1).single()
val createSite = BusinessPartnerBuildService.createSite(siteDto, bpnS, legalEntity)
Expand All @@ -321,6 +342,16 @@ class TaskStepBuildService(
val updateSite = siteRepository.findByBpn(bpn)
if (updateSite != null) {
if (siteDto.hasChanged == true) {
val createSite = BusinessPartnerBuildService.createSite(siteDto, updateSite.bpn, legalEntity)
val siteMainAddress =
if (genericBusinessPartner.generic.postalAddress.addressType == AddressType.LegalAndSiteMainAddress)
legalEntity.legalAddress
else
createLogisticAddress(mainAddress, taskEntryBpnMapping)
createSite.mainAddress = siteMainAddress
siteMainAddress.site = createSite
hasChanges = businessPartnerEquivalenceService.isEquivalent(updateSite, createSite)

BusinessPartnerBuildService.updateSite(updateSite, siteDto)
val addressMetadataMap = metadataService.getMetadata(listOf(mainAddress)).toMapping()
updateLogisticAddress(updateSite.mainAddress, mainAddress, addressMetadataMap)
Expand All @@ -330,12 +361,15 @@ class TaskStepBuildService(
}
updateSite
}
siteRepository.save(upsertSite)
changelogService.createChangelogEntries(
listOf(
ChangelogEntryCreateRequest(upsertSite.bpn, changelogType, BusinessPartnerType.SITE)

if (hasChanges || bpn == null) {
siteRepository.save(upsertSite)
changelogService.createChangelogEntries(
listOf(
ChangelogEntryCreateRequest(upsertSite.bpn, changelogType, BusinessPartnerType.SITE)
)
)
)
}

return upsertSite
}
Expand Down
Loading

0 comments on commit c81d08b

Please sign in to comment.