diff --git a/CHANGELOG.md b/CHANGELOG.md index feee886e5..fb9ae3115 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ For changes to the BPDM Helm charts please consult the [changelog](charts/bpdm/C - BPDM Orchestrator: Endpoint for checking the result state of given tasks - BPDM Orchestrator: Endpoint for getting event log for finished tasks - BPDM Pool: Enhanced data model for IdentifierTypes by adding three new fields/attributes: abbreviation, transliteratedName, and transliteratedAbbreviation.([#605](https://github.com/eclipse-tractusx/sig-release/issues/605)) +- BPDM Pool: Add CX endpoints for searching and updating the CX membership information of legal entities.([#1069](https://github.com/eclipse-tractusx/bpdm/issues/1069)) + ### Changed @@ -33,6 +35,8 @@ For changes to the BPDM Helm charts please consult the [changelog](charts/bpdm/C - BPDM Cleaning Service Dummy: Removed assignment of uncategorized states while performing cleaning legal entity process. - BPDM Gate: Fixed construction logic for states and identifiers by enabling business partner type - BPDM Gate: Fixed logic for identifiers to retrieve only generic type on output business partner +- BPDM Gate: Fixed construction logic for states and identifiers by enabling business partner type +- BPDM Pool: When processing golden record tasks the Pool now ignores isCatenaXMemberData field if it is set to null. ([#1069](https://github.com/eclipse-tractusx/bpdm/issues/1069)) ## [6.1.0] - [2024-07-15] diff --git a/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/exception/BpdmExceptionHandler.kt b/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/exception/BpdmExceptionHandler.kt index c66dc4e2d..d2223e4c7 100644 --- a/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/exception/BpdmExceptionHandler.kt +++ b/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/exception/BpdmExceptionHandler.kt @@ -32,7 +32,7 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExcep import kotlin.reflect.full.findAnnotations -open class BpdmExceptionHandler : ResponseEntityExceptionHandler() { +open class BpdmExceptionHandler: ResponseEntityExceptionHandler() { private val kotlinLogger = KotlinLogging.logger { } @@ -47,11 +47,33 @@ open class BpdmExceptionHandler : ResponseEntityExceptionHandler() { return handleExceptionInternal(ex, body, headers, status, request) } + @ExceptionHandler(value = [BpdmMultipleNotFoundException::class]) + protected fun handleMultipleObjectsNotFound( + ex: Exception, request: WebRequest + ): ResponseEntity? { + logException(ex) + + val body = createProblemDetail(ex, HttpStatusCode.valueOf(404), ex.toString(), null, null, request) + return handleExceptionInternal(ex, body, HttpHeaders(), HttpStatusCode.valueOf(404), request) + } + + @ExceptionHandler(value = [BpdmValidationErrorException::class]) + protected fun handleValidationErrors( + ex: Exception, request: WebRequest + ): ResponseEntity? { + val typedEx = ex as BpdmValidationErrorException + val errorMessage = typedEx.validationErrors.joinToString(" ") { "Error Code ${it.validationErrorCode}: '${it.errorDetails}' on value '${it.erroneousValue}' at ${it.context.propertyPath.joinToString(".")}." } + val body = createProblemDetail(ex, HttpStatusCode.valueOf(400), errorMessage, null, null, request) + return handleExceptionInternal(ex, body, HttpHeaders(), HttpStatusCode.valueOf(400), request) + } + + @ExceptionHandler(value = [Exception::class]) - protected fun logException( + protected fun handleGenericException( ex: Exception, request: WebRequest ): ResponseEntity? { logException(ex) + return handleException(ex, request) } diff --git a/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/exception/BpdmMultipleNotFoundException.kt b/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/exception/BpdmMultipleNotFoundException.kt index c948495ba..2d8a7334f 100644 --- a/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/exception/BpdmMultipleNotFoundException.kt +++ b/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/exception/BpdmMultipleNotFoundException.kt @@ -26,7 +26,7 @@ import kotlin.reflect.KClass @ResponseStatus(HttpStatus.NOT_FOUND) open class BpdmMultipleNotFoundException( objectType: String, - identifiers: Collection + val identifiers: Collection ) : RuntimeException("$objectType with following identifiers not found: ${identifiers.joinToString()}") { constructor(objectType: KClass<*>, identifiers: Collection) : this(objectType.simpleName ?: objectType.toString(), identifiers) diff --git a/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/exception/BpdmValidationErrorException.kt b/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/exception/BpdmValidationErrorException.kt new file mode 100644 index 000000000..ff1e84a41 --- /dev/null +++ b/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/exception/BpdmValidationErrorException.kt @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2021,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.bpdm.common.exception + +import org.eclipse.tractusx.bpdm.common.mapping.ValidationError +import org.springframework.http.HttpStatus +import org.springframework.web.bind.annotation.ResponseStatus + + +@ResponseStatus(HttpStatus.BAD_REQUEST) +class BpdmValidationErrorException( + val validationErrors: List +): RuntimeException(validationErrors.joinToString()) \ No newline at end of file diff --git a/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/BpdmFilledLimitedStringMapper.kt b/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/BpdmFilledLimitedStringMapper.kt index d96578220..62e4ab607 100644 --- a/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/BpdmFilledLimitedStringMapper.kt +++ b/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/BpdmFilledLimitedStringMapper.kt @@ -21,7 +21,7 @@ package org.eclipse.tractusx.bpdm.common.mapping abstract class BpdmFilledLimitedStringMapper( private val limitedLengthValidation: BpdmValidation -): BpdmStringMapper, BpdmValidateAndMapMapper { +): BpdmValidateAndMapStringMapper { private val isBlankValidation = object: BpdmValidation{ override fun validate(value: String, context: ValidationContext): ValidationError? { diff --git a/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/BpdmMapper.kt b/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/BpdmMapper.kt index 6c15332df..074eea76b 100644 --- a/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/BpdmMapper.kt +++ b/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/BpdmMapper.kt @@ -19,6 +19,8 @@ package org.eclipse.tractusx.bpdm.common.mapping +import org.eclipse.tractusx.bpdm.common.mapping.ValidationContext.Companion.onIndex + /** * Offers base logic to validate and map from one type to another */ @@ -31,6 +33,11 @@ interface BpdmMapper { */ fun map(valueToMap: FROM_TYPE, context: ValidationContext = ValidationContext.NoContext): MappingResult + fun map(listToMap: List, context: ValidationContext = ValidationContext.NoContext): MappingResult>{ + val entryResults = listToMap.mapIndexed { index, entry -> map(entry, context.onIndex(index)) } + val entryErrors = entryResults.flatMap { it.errors } + return MappingResult.invalidOnError(entryErrors){ entryResults.map { it.successfulResult } } + } /** * Check whether a non-null [valueToMap] of the [FROM_TYPE] should be treated as a valid null mapping result @@ -38,6 +45,8 @@ interface BpdmMapper { */ fun checkTreatAsNull(valueToMap: FROM_TYPE) = false + fun checkTreatAsNull(listToMap: List) = false + /** * Try to map given nullable [valueToMap] within the given [context] whereby null is an acceptable value * @@ -46,7 +55,14 @@ interface BpdmMapper { fun mapValidNull(valueToMap: FROM_TYPE?, context: ValidationContext = ValidationContext.NoContext): NullableMappingResult{ return valueToMap ?.let { if(checkTreatAsNull(it)) null else it } - ?.let { NullableMappingResult.fromResult(map(it)) } + ?.let { NullableMappingResult.fromResult(map(it, context)) } + ?: NullableMappingResult.ofValidNull() + } + + fun mapValidNull(listToMap: List?, context: ValidationContext = ValidationContext.NoContext): NullableMappingResult>{ + return listToMap + ?.let { if(checkTreatAsNull(it)) null else it } + ?.let { NullableMappingResult.fromResult(map(it, context)) } ?: NullableMappingResult.ofValidNull() } @@ -56,7 +72,11 @@ interface BpdmMapper { * Return a [NullableMappingResult] containing either the result or validation errors */ fun mapInvalidNull(valueToMap: FROM_TYPE?, context: ValidationContext = ValidationContext.NoContext): MappingResult{ - return valueToMap?.let { map(it) } ?: MappingResult.ofInvalidNull() + return valueToMap?.let { map(it, context) } ?: MappingResult.ofInvalidNull() + } + + fun mapInvalidNull(listToMap: List?, context: ValidationContext = ValidationContext.NoContext): MappingResult>{ + return listToMap?.let { map(it, context) } ?: MappingResult.ofInvalidNull() } } \ No newline at end of file diff --git a/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/BpdmValidateAndMapStringMapper.kt b/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/BpdmValidateAndMapStringMapper.kt new file mode 100644 index 000000000..b7b09d356 --- /dev/null +++ b/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/BpdmValidateAndMapStringMapper.kt @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2021,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.bpdm.common.mapping + +interface BpdmValidateAndMapStringMapper: BpdmStringMapper, BpdmValidateAndMapMapper \ No newline at end of file diff --git a/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/BpdmValidator.kt b/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/BpdmValidator.kt index c0420581a..8a42b89cd 100644 --- a/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/BpdmValidator.kt +++ b/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/BpdmValidator.kt @@ -19,6 +19,9 @@ package org.eclipse.tractusx.bpdm.common.mapping +import org.eclipse.tractusx.bpdm.common.exception.BpdmValidationErrorException +import org.eclipse.tractusx.bpdm.common.mapping.ValidationContext.Companion.onIndex + /** * Offers base logic to validate values */ @@ -39,7 +42,13 @@ interface BpdmValidator { /** * Validate given [value] and throw exception if any error is found */ - fun assert(value: T){ - require(validate(value).isEmpty()) + fun assert(value: T, context: ValidationContext = ValidationContext.NoContext){ + val errors = validate(value, context) + if(errors.isNotEmpty()) throw BpdmValidationErrorException(errors) + } + + fun assert(listOfValues: List, context: ValidationContext = ValidationContext.NoContext){ + val errors = listOfValues.flatMapIndexed { index, value -> validate(value, context.onIndex(index)) } + if(errors.isNotEmpty()) throw BpdmValidationErrorException(errors) } } \ No newline at end of file diff --git a/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/BpnValidation.kt b/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/BpnValidation.kt new file mode 100644 index 000000000..d54512561 --- /dev/null +++ b/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/BpnValidation.kt @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2021,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.bpdm.common.mapping + +class BpnValidation( + private val bpnTypeDescriptor: String, + private val errorCode: String, + private val errorDetails: String, + private val bpnPrefix: String = "BPN", + private val codeLength: Int = 10, + private val checksumLength: Int = 2, + private val allowedAlphabet: String = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", + +): BpdmValidation { + + companion object{ + val bpnLValidation = BpnValidation( + "L", + CommonValidationErrorCodes.BpnL.name, + CommonValidationErrorCodes.BpnL.description + ) + } + + + private val correctTypePrefix = bpnPrefix + bpnTypeDescriptor + private val correctPrefixLength = correctTypePrefix.length + private val correctLength = correctPrefixLength + codeLength + checksumLength + private val allowedAlphabetSet = allowedAlphabet.toSet() + + override fun validate(value: String, context: ValidationContext): ValidationError? { + val wrongLength = value.length != correctLength + val wrongTypePrefix = !value.startsWith(correctTypePrefix) + val wrongAlphabet = value.any { it !in allowedAlphabetSet } + // We could also check the checksum here but won't do for now to be compatible to legacy checksums + + return if(wrongLength || wrongTypePrefix || wrongAlphabet) + ValidationError(errorCode, errorDetails, value, context) + else null + + } +} \ No newline at end of file diff --git a/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/CommonValidationErrorCodes.kt b/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/CommonValidationErrorCodes.kt index dd2b1ef7d..b99cace63 100644 --- a/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/CommonValidationErrorCodes.kt +++ b/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/CommonValidationErrorCodes.kt @@ -31,7 +31,8 @@ enum class CommonValidationErrorCodes(val description: String) { ExceedsHugeLength("Exceeds maximum length of $HUGE_STRING_LENGTH"), ISO31661("Not ISO 3166-1 conform"), ISO31662("Not ISO 3166-2 conform"), - ISO6391("Not ISO 639-1 conform"); + ISO6391("Not ISO 639-1 conform"), + BpnL("Is not a BPNL"); fun toValidationError(value: String?, context: ValidationContext) = ValidationError(name, description, value, context) diff --git a/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/MappingResult.kt b/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/MappingResult.kt index 247949fdc..3cf59d933 100644 --- a/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/MappingResult.kt +++ b/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/MappingResult.kt @@ -19,6 +19,8 @@ package org.eclipse.tractusx.bpdm.common.mapping +import org.eclipse.tractusx.bpdm.common.exception.BpdmValidationErrorException + /** * Holds the non-null result of a mapping to type [T] * @@ -69,7 +71,8 @@ data class MappingResult( * On a successful mapping return the resulting value otherwise throw an exception */ override val successfulResult by lazy { - require(isSuccess) + if(!isSuccess) throw BpdmValidationErrorException(errors) + optionalResult!! } diff --git a/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/NullableMappingResult.kt b/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/NullableMappingResult.kt index 9089e9c5b..e694cbf51 100644 --- a/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/NullableMappingResult.kt +++ b/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/NullableMappingResult.kt @@ -19,6 +19,8 @@ package org.eclipse.tractusx.bpdm.common.mapping +import org.eclipse.tractusx.bpdm.common.exception.BpdmValidationErrorException + /** * Holds the nullable result of a mapping to type [T] * @@ -57,8 +59,8 @@ data class NullableMappingResult( * On a successful mapping return the resulting value otherwise throw an exception */ val successfulResult by lazy { - require(isSuccess) + if(!isSuccess) throw BpdmValidationErrorException(errors) + optionalResult } - } diff --git a/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/ValidationContext.kt b/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/ValidationContext.kt index c7f557936..660900023 100644 --- a/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/ValidationContext.kt +++ b/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/ValidationContext.kt @@ -23,17 +23,16 @@ import kotlin.reflect.KClass import kotlin.reflect.KProperty data class ValidationContext( - val classType: KClass<*>?, + val classType: String, val objectId: String, - val propertyPath: List>, + val propertyPath: List ) { companion object { - val NoContext = ValidationContext(null, "", emptyList()) + val NoContext = ValidationContext("", "", emptyList()) - fun fromRoot(classType: KClass<*>?, objectId: String) = ValidationContext(classType, objectId, emptyList()) + fun fromRoot(classType: KClass<*>?, objectId: String, vararg path: KProperty<*>) = ValidationContext(classType?.simpleName ?: "", objectId, path.map { it.name }) - fun ValidationContext.onProperty(property: KProperty<*>) = copy(propertyPath = propertyPath + property) + fun ValidationContext.onProperty(property: KProperty<*>) = copy(propertyPath = propertyPath + property.name) + fun ValidationContext.onIndex(index: Int) = copy(propertyPath = propertyPath + "Index $index") } - - val prefix = "Class ${classType?.simpleName} with Id $objectId on property ${propertyPath.joinToString()}: " } diff --git a/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/types/BpnLString.kt b/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/types/BpnLString.kt new file mode 100644 index 000000000..3b2e4a41e --- /dev/null +++ b/bpdm-common/src/main/kotlin/org/eclipse/tractusx/bpdm/common/mapping/types/BpnLString.kt @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2021,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.bpdm.common.mapping.types + +import org.eclipse.tractusx.bpdm.common.mapping.BpdmValidateAndMapStringMapper +import org.eclipse.tractusx.bpdm.common.mapping.BpnValidation + +@JvmInline +value class BpnLString(val value: String) { + + init { assert(value) } + + companion object: BpdmValidateAndMapStringMapper{ + override fun transform(value: String) = BpnLString(value) + + override val validations = listOf(BpnValidation.bpnLValidation) + } +} \ No newline at end of file diff --git a/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/PoolCxMembershipApi.kt b/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/PoolCxMembershipApi.kt new file mode 100644 index 000000000..f8767682a --- /dev/null +++ b/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/PoolCxMembershipApi.kt @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2021,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.bpdm.pool.api + +import org.eclipse.tractusx.bpdm.common.dto.PageDto +import org.eclipse.tractusx.bpdm.common.dto.PaginationRequest +import org.eclipse.tractusx.bpdm.pool.api.PoolCxMembershipApi.Companion.MEMBERSHIP_PATH +import org.eclipse.tractusx.bpdm.pool.api.model.CxMembershipDto +import org.eclipse.tractusx.bpdm.pool.api.model.request.CxMembershipSearchRequest +import org.eclipse.tractusx.bpdm.pool.api.model.request.CxMembershipUpdateRequest +import org.springdoc.core.annotations.ParameterObject +import org.springframework.http.MediaType +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PutMapping +import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RequestMapping + +@RequestMapping(MEMBERSHIP_PATH, produces = [MediaType.APPLICATION_JSON_VALUE]) +interface PoolCxMembershipApi { + + companion object{ + const val MEMBERSHIP_PATH = "${ApiCommons.BASE_PATH}/cx-memberships" + } + + @GetMapping + fun get( + @ParameterObject searchRequest: CxMembershipSearchRequest, + @ParameterObject paginationRequest: PaginationRequest + ): PageDto + + + @PutMapping + fun put(@RequestBody updateRequest: CxMembershipUpdateRequest) +} \ No newline at end of file diff --git a/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/client/CxMembershipApiClient.kt b/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/client/CxMembershipApiClient.kt new file mode 100644 index 000000000..fa172164d --- /dev/null +++ b/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/client/CxMembershipApiClient.kt @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2021,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.bpdm.pool.api.client + +import org.eclipse.tractusx.bpdm.common.dto.PageDto +import org.eclipse.tractusx.bpdm.common.dto.PaginationRequest +import org.eclipse.tractusx.bpdm.pool.api.PoolCxMembershipApi +import org.eclipse.tractusx.bpdm.pool.api.model.CxMembershipDto +import org.eclipse.tractusx.bpdm.pool.api.model.request.CxMembershipSearchRequest +import org.eclipse.tractusx.bpdm.pool.api.model.request.CxMembershipUpdateRequest +import org.springdoc.core.annotations.ParameterObject +import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.service.annotation.GetExchange +import org.springframework.web.service.annotation.HttpExchange +import org.springframework.web.service.annotation.PutExchange + +@HttpExchange(PoolCxMembershipApi.MEMBERSHIP_PATH) +interface CxMembershipApiClient: PoolCxMembershipApi { + + @GetExchange + override fun get(@ParameterObject searchRequest: CxMembershipSearchRequest, @ParameterObject paginationRequest: PaginationRequest): PageDto + + @PutExchange + override fun put(@RequestBody updateRequest: CxMembershipUpdateRequest) + +} \ No newline at end of file diff --git a/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/client/PoolApiClient.kt b/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/client/PoolApiClient.kt index 5fdc60ea7..94e36d746 100644 --- a/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/client/PoolApiClient.kt +++ b/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/client/PoolApiClient.kt @@ -34,4 +34,6 @@ interface PoolApiClient { val sites: SiteApiClient val members: MembersApiClient + + val memberships: CxMembershipApiClient } diff --git a/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/client/PoolClientImpl.kt b/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/client/PoolClientImpl.kt index a91baed6b..a668a0eaf 100644 --- a/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/client/PoolClientImpl.kt +++ b/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/client/PoolClientImpl.kt @@ -55,6 +55,8 @@ class PoolClientImpl( override val members by lazy { createClient() } + override val memberships by lazy { createClient() } + private inline fun createClient() = httpServiceProxyFactory.createClient(T::class.java) } diff --git a/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/model/CxMembershipDto.kt b/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/model/CxMembershipDto.kt new file mode 100644 index 000000000..78fabba0b --- /dev/null +++ b/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/model/CxMembershipDto.kt @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2021,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.bpdm.pool.api.model + +data class CxMembershipDto ( + val bpnL: String, + val isCatenaXMember: Boolean +) \ No newline at end of file diff --git a/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/model/request/CxMembershipSearchRequest.kt b/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/model/request/CxMembershipSearchRequest.kt new file mode 100644 index 000000000..7634f9bdd --- /dev/null +++ b/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/model/request/CxMembershipSearchRequest.kt @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2021,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.bpdm.pool.api.model.request + +data class CxMembershipSearchRequest( + val bpnLs: List? = null, + val isCatenaXMember: Boolean? = null +) \ No newline at end of file diff --git a/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/model/request/CxMembershipUpdateRequest.kt b/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/model/request/CxMembershipUpdateRequest.kt new file mode 100644 index 000000000..9b00585fc --- /dev/null +++ b/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/model/request/CxMembershipUpdateRequest.kt @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2021,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.bpdm.pool.api.model.request + +import org.eclipse.tractusx.bpdm.pool.api.model.CxMembershipDto + +data class CxMembershipUpdateRequest( + val memberships: List +) diff --git a/bpdm-pool/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/controller/CxMembershipController.kt b/bpdm-pool/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/controller/CxMembershipController.kt new file mode 100644 index 000000000..989677850 --- /dev/null +++ b/bpdm-pool/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/controller/CxMembershipController.kt @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2021,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.bpdm.pool.controller + +import org.eclipse.tractusx.bpdm.common.dto.PageDto +import org.eclipse.tractusx.bpdm.common.dto.PaginationRequest +import org.eclipse.tractusx.bpdm.pool.api.PoolCxMembershipApi +import org.eclipse.tractusx.bpdm.pool.api.model.CxMembershipDto +import org.eclipse.tractusx.bpdm.pool.api.model.request.CxMembershipSearchRequest +import org.eclipse.tractusx.bpdm.pool.api.model.request.CxMembershipUpdateRequest +import org.eclipse.tractusx.bpdm.pool.config.PermissionConfigProperties +import org.eclipse.tractusx.bpdm.pool.service.CxMembershipService +import org.springframework.security.access.prepost.PreAuthorize +import org.springframework.web.bind.annotation.RestController + +@RestController +class CxMembershipController( + private val cxMembershipService: CxMembershipService +): PoolCxMembershipApi { + + @PreAuthorize("hasAuthority(${PermissionConfigProperties.WRITE_PARTNER})") + override fun get(searchRequest: CxMembershipSearchRequest, paginationRequest: PaginationRequest): PageDto { + return cxMembershipService.searchMemberships(searchRequest, paginationRequest) + } + + @PreAuthorize("hasAuthority(${PermissionConfigProperties.WRITE_PARTNER})") + override fun put(updateRequest: CxMembershipUpdateRequest) { + return cxMembershipService.updateMemberships(updateRequest) + } +} \ No newline at end of file diff --git a/bpdm-pool/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/exception/PoolExceptionHandler.kt b/bpdm-pool/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/exception/PoolExceptionHandler.kt index b728ea0ca..eecc11bbf 100644 --- a/bpdm-pool/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/exception/PoolExceptionHandler.kt +++ b/bpdm-pool/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/exception/PoolExceptionHandler.kt @@ -23,4 +23,4 @@ import org.eclipse.tractusx.bpdm.common.exception.BpdmExceptionHandler import org.springframework.web.bind.annotation.ControllerAdvice @ControllerAdvice -class PoolExceptionHandler : BpdmExceptionHandler() \ No newline at end of file +class PoolExceptionHandler: BpdmExceptionHandler() \ No newline at end of file diff --git a/bpdm-pool/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/service/CxMembershipService.kt b/bpdm-pool/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/service/CxMembershipService.kt new file mode 100644 index 000000000..0f6f9d1b2 --- /dev/null +++ b/bpdm-pool/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/service/CxMembershipService.kt @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2021,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.bpdm.pool.service + +import org.eclipse.tractusx.bpdm.common.dto.BusinessPartnerType +import org.eclipse.tractusx.bpdm.common.dto.PageDto +import org.eclipse.tractusx.bpdm.common.dto.PaginationRequest +import org.eclipse.tractusx.bpdm.common.exception.BpdmMultipleNotFoundException +import org.eclipse.tractusx.bpdm.common.mapping.ValidationContext.Companion.fromRoot +import org.eclipse.tractusx.bpdm.common.mapping.types.BpnLString +import org.eclipse.tractusx.bpdm.common.service.toPageDto +import org.eclipse.tractusx.bpdm.pool.api.model.ChangelogType +import org.eclipse.tractusx.bpdm.pool.api.model.CxMembershipDto +import org.eclipse.tractusx.bpdm.pool.api.model.request.CxMembershipSearchRequest +import org.eclipse.tractusx.bpdm.pool.api.model.request.CxMembershipUpdateRequest +import org.eclipse.tractusx.bpdm.pool.dto.ChangelogEntryCreateRequest +import org.eclipse.tractusx.bpdm.pool.repository.LegalEntityRepository +import org.springframework.data.domain.PageRequest +import org.springframework.data.jpa.domain.Specification +import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional + +@Service +class CxMembershipService( + private val legalEntityRepository: LegalEntityRepository, + private val changelogService: PartnerChangelogService +) { + fun searchMemberships(searchRequest: CxMembershipSearchRequest, paginationRequest: PaginationRequest): PageDto{ + searchRequest.bpnLs?.let { BpnLString.assert(it, fromRoot(CxMembershipSearchRequest::class, "searchRequest", CxMembershipSearchRequest::bpnLs)) } + + val spec = Specification.allOf( + LegalEntityRepository.byBpns(searchRequest.bpnLs), + LegalEntityRepository.byIsMember(searchRequest.isCatenaXMember) + ) + val legalEntityPage = legalEntityRepository.findAll(spec, PageRequest.of(paginationRequest.page, paginationRequest.size)) + + return legalEntityPage.toPageDto { CxMembershipDto(it.bpn, it.isCatenaXMemberData) } + } + + @Transactional + fun updateMemberships(updateRequest: CxMembershipUpdateRequest){ + BpnLString.assert( + updateRequest.memberships.map { it.bpnL }, + fromRoot(CxMembershipUpdateRequest::class, "updateRequest", CxMembershipUpdateRequest::memberships, CxMembershipDto::bpnL) + ) + + val updatesByBpnL = updateRequest.memberships.associate { Pair(it.bpnL, it.isCatenaXMember) } + + val foundLegalEntities = legalEntityRepository.findDistinctByBpnIn(updatesByBpnL.keys) + + val notFoundBpnLs = updatesByBpnL.keys.minus( foundLegalEntities.map { it.bpn }.toSet()) + if(notFoundBpnLs.isNotEmpty()) + throw BpdmMultipleNotFoundException("Legal Entities", notFoundBpnLs) + + foundLegalEntities.forEach { legalEntity -> + val updateValue = updatesByBpnL[legalEntity.bpn]!! + if(legalEntity.isCatenaXMemberData != updateValue){ + legalEntity.isCatenaXMemberData = updateValue + legalEntityRepository.save(legalEntity) + + changelogService.createChangelogEntry(ChangelogEntryCreateRequest( + legalEntity.bpn, ChangelogType.UPDATE, BusinessPartnerType.LEGAL_ENTITY + )) + } + } + } +} \ No newline at end of file diff --git a/bpdm-pool/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/service/PartnerChangelogService.kt b/bpdm-pool/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/service/PartnerChangelogService.kt index 85f521670..f387de8ff 100644 --- a/bpdm-pool/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/service/PartnerChangelogService.kt +++ b/bpdm-pool/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/service/PartnerChangelogService.kt @@ -19,7 +19,6 @@ package org.eclipse.tractusx.bpdm.pool.service -import jakarta.persistence.EntityManager import mu.KotlinLogging import org.eclipse.tractusx.bpdm.common.dto.BusinessPartnerType import org.eclipse.tractusx.bpdm.common.dto.PageDto @@ -47,16 +46,19 @@ import java.time.Instant */ @Service class PartnerChangelogService( - private val partnerChangelogEntryRepository: PartnerChangelogEntryRepository, - private val entityManager: EntityManager + private val partnerChangelogEntryRepository: PartnerChangelogEntryRepository ) { private val logger = KotlinLogging.logger { } @Transactional fun createChangelogEntries(changelogEntries: Collection): List { logger.debug { "Create ${changelogEntries.size} new change log entries" } - val entities = changelogEntries.map { it.toEntity() } - return partnerChangelogEntryRepository.saveAll(entities) + return changelogEntries.map { createChangelogEntry(it) } + } + + fun createChangelogEntry(request: ChangelogEntryCreateRequest): PartnerChangelogEntryDb{ + logger.debug { "Create ${request.changelogType} changelog entry for ${request.bpn}" } + return partnerChangelogEntryRepository.save(request.toEntity()) } fun getChangelogEntriesCreatedAfter( diff --git a/bpdm-pool/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/service/TaskStepBuildService.kt b/bpdm-pool/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/service/TaskStepBuildService.kt index 893373c65..6dc9bb198 100644 --- a/bpdm-pool/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/service/TaskStepBuildService.kt +++ b/bpdm-pool/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/service/TaskStepBuildService.kt @@ -90,7 +90,8 @@ class TaskStepBuildService( bpnReference = toBpnReference(legalEntityBpns.legalEntityBpn), legalAddress = legalEntity.legalAddress.copy( bpnReference = toBpnReference(legalEntityBpns.legalAddressBpn) - ) + ), + isCatenaXMemberData = legalEntityBpns.isCatenaXMember ), site = siteBpns?.let { site?.copy( bpnReference = toBpnReference(siteBpns.siteBpn), @@ -115,14 +116,20 @@ class TaskStepBuildService( val bpnLReference = legalEntity.bpnReference val bpnL = taskEntryBpnMapping.getBpn(bpnLReference) - val bpnResults = if(bpnL != null && legalEntity.hasChanged == false){ - //No need to upsert, just fetch the information - businessPartnerFetchService.fetchByBpns(listOf(bpnL)) + val existingLegalEntityInformation by lazy { + businessPartnerFetchService.fetchByBpns(listOf(bpnL!!)) .firstOrNull() - ?.let { LegalEntityBpns(it.bpn, it.legalAddress.bpn) } ?: + ?.let { LegalEntityBpns(it.bpn, it.legalAddress.bpn, it.isCatenaXMemberData) } ?: throw BpdmValidationException("Legal entity with specified BPNL $bpnL not found") + } + + val isCatenaXMember = legalEntity.isCatenaXMemberData ?: if(bpnL != null) existingLegalEntityInformation.isCatenaXMember else false + + val bpnResults = if(bpnL != null && legalEntity.hasChanged == false){ + //No need to upsert, just fetch the information + existingLegalEntityInformation }else{ - upsertLegalEntity(legalEntity, taskEntryBpnMapping) + upsertLegalEntity(legalEntity.copy(isCatenaXMemberData = isCatenaXMember), taskEntryBpnMapping) } return bpnResults @@ -168,7 +175,7 @@ class TaskStepBuildService( val bpnL = legalEntityResult.legalEntity.bpnl val legalAddressBpnA = legalEntityResult.legalAddress.bpna - return LegalEntityBpns(bpnL, legalAddressBpnA) + return LegalEntityBpns(bpnL, legalAddressBpnA, legalEntityResult.legalEntity.isCatenaXMemberData) } private fun updateLegalEntity( @@ -187,7 +194,7 @@ class TaskStepBuildService( val legalEntityResult = result.entities.firstOrNull() ?: throw BpdmValidationException("Unknown error when trying to update legal entity") - return LegalEntityBpns(legalEntityResult.legalEntity.bpnl, legalEntityResult.legalAddress.bpna) + return LegalEntityBpns(legalEntityResult.legalEntity.bpnl, legalEntityResult.legalAddress.bpna, legalEntityResult.legalEntity.isCatenaXMemberData) } private fun processSite( @@ -497,7 +504,8 @@ class TaskStepBuildService( data class LegalEntityBpns( val legalEntityBpn: String, - val legalAddressBpn: String + val legalAddressBpn: String, + val isCatenaXMember: Boolean ) data class SiteBpns( diff --git a/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/auth/AuthAdminIT.kt b/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/auth/AuthAdminIT.kt index 82fb9c314..07ed14a8c 100644 --- a/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/auth/AuthAdminIT.kt +++ b/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/auth/AuthAdminIT.kt @@ -76,6 +76,10 @@ class AuthAdminIT @Autowired constructor( postLegalEntitySearch = AuthExpectationType.Authorized, postChangelogSearch = AuthExpectationType.Authorized ), + CxMembershipsAuthExpectations( + getMemberships = AuthExpectationType.Authorized, + putMemberships = AuthExpectationType.Authorized + ), changelogAuthExpectation = AuthExpectationType.Authorized, bpnAuthExpectation = AuthExpectationType.Authorized ) diff --git a/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/auth/AuthCxMemberIT.kt b/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/auth/AuthCxMemberIT.kt index 0e6d5321d..1399f5669 100644 --- a/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/auth/AuthCxMemberIT.kt +++ b/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/auth/AuthCxMemberIT.kt @@ -77,6 +77,10 @@ AuthCxMemberIT @Autowired constructor( postLegalEntitySearch = AuthExpectationType.Authorized, postChangelogSearch = AuthExpectationType.Authorized ), + CxMembershipsAuthExpectations( + getMemberships = AuthExpectationType.Forbidden, + putMemberships = AuthExpectationType.Forbidden + ), changelogAuthExpectation = AuthExpectationType.Forbidden, bpnAuthExpectation = AuthExpectationType.Forbidden ) diff --git a/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/auth/AuthSharingMemberIT.kt b/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/auth/AuthSharingMemberIT.kt index 90c217f20..86074c39c 100644 --- a/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/auth/AuthSharingMemberIT.kt +++ b/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/auth/AuthSharingMemberIT.kt @@ -76,6 +76,10 @@ class AuthSharingMemberIT @Autowired constructor( postLegalEntitySearch = AuthExpectationType.Forbidden, postChangelogSearch = AuthExpectationType.Forbidden ), + CxMembershipsAuthExpectations( + getMemberships = AuthExpectationType.Forbidden, + putMemberships = AuthExpectationType.Forbidden + ), changelogAuthExpectation = AuthExpectationType.Forbidden, bpnAuthExpectation = AuthExpectationType.Forbidden ) diff --git a/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/auth/AuthTestBase.kt b/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/auth/AuthTestBase.kt index ed72a8b72..b3ccd8655 100644 --- a/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/auth/AuthTestBase.kt +++ b/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/auth/AuthTestBase.kt @@ -38,6 +38,7 @@ abstract class AuthTestBase( private val legalEntityAuthExpectations: LegalEntityAuthExpectations, private val metadataAuthExpectations: MetadataAuthExpectations, private val membersAuthExpectations: MembersAuthExpectations, + private val membershipAuthExpectations: CxMembershipsAuthExpectations, private val changelogAuthExpectation: AuthExpectationType, private val bpnAuthExpectation: AuthExpectationType ) { @@ -194,6 +195,16 @@ abstract class AuthTestBase( fun `POST Bpn Search`(){ authAssertions.assert(bpnAuthExpectation) { poolApiClient.bpns.findBpnsByIdentifiers(IdentifiersSearchRequest(IdentifierBusinessPartnerType.ADDRESS, "ID", emptyList())) } } + + @Test + fun `GET CX Memberships`(){ + authAssertions.assert(membershipAuthExpectations.getMemberships) { poolApiClient.memberships.get(CxMembershipSearchRequest(), PaginationRequest()) } + } + + @Test + fun `PUT CX Memberships`(){ + authAssertions.assert(membershipAuthExpectations.putMemberships) { poolApiClient.memberships.put(CxMembershipUpdateRequest(listOf())) } + } } @@ -239,3 +250,8 @@ data class MembersAuthExpectations( val postChangelogSearch: AuthExpectationType ) +data class CxMembershipsAuthExpectations( + val getMemberships: AuthExpectationType, + val putMemberships: AuthExpectationType +) + diff --git a/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/auth/NoAuthIT.kt b/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/auth/NoAuthIT.kt index e2ddb6af3..a9e1651c7 100644 --- a/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/auth/NoAuthIT.kt +++ b/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/auth/NoAuthIT.kt @@ -74,6 +74,10 @@ class NoAuthIT @Autowired constructor( postLegalEntitySearch = AuthExpectationType.Unauthorized, postChangelogSearch = AuthExpectationType.Unauthorized ), + CxMembershipsAuthExpectations( + getMemberships = AuthExpectationType.Unauthorized, + putMemberships = AuthExpectationType.Unauthorized + ), changelogAuthExpectation = AuthExpectationType.Unauthorized, bpnAuthExpectation = AuthExpectationType.Unauthorized ) \ No newline at end of file diff --git a/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/controller/CxMembershipControllerIT.kt b/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/controller/CxMembershipControllerIT.kt new file mode 100644 index 000000000..319196c74 --- /dev/null +++ b/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/controller/CxMembershipControllerIT.kt @@ -0,0 +1,258 @@ +/******************************************************************************* + * Copyright (c) 2021,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.bpdm.pool.controller + +import org.assertj.core.api.Assertions.assertThat +import org.eclipse.tractusx.bpdm.common.dto.PaginationRequest +import org.eclipse.tractusx.bpdm.pool.Application +import org.eclipse.tractusx.bpdm.pool.api.client.PoolApiClient +import org.eclipse.tractusx.bpdm.pool.api.model.CxMembershipDto +import org.eclipse.tractusx.bpdm.pool.api.model.request.CxMembershipSearchRequest +import org.eclipse.tractusx.bpdm.pool.api.model.request.CxMembershipUpdateRequest +import org.eclipse.tractusx.bpdm.pool.api.model.request.LegalEntityPartnerCreateRequest +import org.eclipse.tractusx.bpdm.pool.api.model.response.LegalEntityPartnerCreateVerboseDto +import org.eclipse.tractusx.bpdm.pool.util.TestHelpers +import org.eclipse.tractusx.bpdm.test.containers.PostgreSQLContextInitializer +import org.eclipse.tractusx.bpdm.test.testdata.pool.PoolDataHelper +import org.eclipse.tractusx.bpdm.test.testdata.pool.TestDataEnvironment +import org.eclipse.tractusx.bpdm.test.util.DbTestHelpers +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.test.context.ActiveProfiles +import org.springframework.test.context.ContextConfiguration + +@SpringBootTest( + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = [Application::class, TestHelpers::class] +) +@ActiveProfiles("test-no-auth", "test-scheduling-disabled") +@ContextConfiguration(initializers = [PostgreSQLContextInitializer::class]) +class CxMembershipControllerIT @Autowired constructor( + private val poolClient: PoolApiClient, + private val dataHelper: PoolDataHelper, + private val dbTestHelpers: DbTestHelpers +) { + private lateinit var testDataEnvironment: TestDataEnvironment + + @BeforeEach + fun beforeEach() { + dbTestHelpers.truncateDbTables() + testDataEnvironment = dataHelper.createTestDataEnvironment() + } + + @Test + fun `get cx memberships without filter`(){ + val legalEntityRequests = listOf( + testDataEnvironment.requestFactory.createLegalEntityRequest("Member 1", isCatenaXMemberData = true), + testDataEnvironment.requestFactory.createLegalEntityRequest("Non-Member 1", isCatenaXMemberData = false), + testDataEnvironment.requestFactory.createLegalEntityRequest("Member 2", isCatenaXMemberData = true), + testDataEnvironment.requestFactory.createLegalEntityRequest("Non-Member 2", isCatenaXMemberData = false), + ) + val givenLegalEntities = poolClient.legalEntities.createBusinessPartners(legalEntityRequests).entities + val bpnLsToFind = getBpnLs(legalEntityRequests, givenLegalEntities) + + val actualMemberships = poolClient.memberships.get(CxMembershipSearchRequest(), PaginationRequest(size = legalEntityRequests.size)).content + + val expectedMemberships = legalEntityRequests.zip(bpnLsToFind) + .map { (request, bpnL) -> CxMembershipDto(bpnL, request.legalEntity.isCatenaXMemberData) } + + + assertThat(actualMemberships).isEqualTo(expectedMemberships) + } + + @Test + fun `get cx memberships paginated`(){ + val legalEntityRequests = listOf( + testDataEnvironment.requestFactory.createLegalEntityRequest("Member 1", isCatenaXMemberData = true), + testDataEnvironment.requestFactory.createLegalEntityRequest("Non-Member 1", isCatenaXMemberData = false), + testDataEnvironment.requestFactory.createLegalEntityRequest("Member 2", isCatenaXMemberData = true), + testDataEnvironment.requestFactory.createLegalEntityRequest("Non-Member 2", isCatenaXMemberData = false), + ) + val givenLegalEntities = poolClient.legalEntities.createBusinessPartners(legalEntityRequests).entities + val bpnLsToFind = getBpnLs(legalEntityRequests, givenLegalEntities) + + val actualMembershipsPage1 = poolClient.memberships.get(CxMembershipSearchRequest(), PaginationRequest(size = 2)).content + val actualMembershipsPage2 = poolClient.memberships.get(CxMembershipSearchRequest(), PaginationRequest(page = 1, size = 2)).content + + + val expectedMembershipsTotal = legalEntityRequests.zip(bpnLsToFind) + .map { (request, bpnL) -> CxMembershipDto(bpnL, request.legalEntity.isCatenaXMemberData) } + + val expectedMembershipsPage1 = expectedMembershipsTotal.take(2) + val expectedMembershipsPage2 = expectedMembershipsTotal.drop(2).take(2) + + assertThat(actualMembershipsPage1).isEqualTo(expectedMembershipsPage1) + assertThat(actualMembershipsPage2).isEqualTo(expectedMembershipsPage2) + } + + @Test + fun `get cx memberships with BPNL filter`(){ + val legalEntitiesToFind = listOf( + testDataEnvironment.requestFactory.createLegalEntityRequest("Member 1", isCatenaXMemberData = true), + testDataEnvironment.requestFactory.createLegalEntityRequest("Non-Member 1", isCatenaXMemberData = false) + ) + + val legalEntitiesToIgnore = listOf( + testDataEnvironment.requestFactory.createLegalEntityRequest("Member 2", isCatenaXMemberData = true), + testDataEnvironment.requestFactory.createLegalEntityRequest("Non-Member 2", isCatenaXMemberData = false), + ) + + val givenLegalEntities = poolClient.legalEntities.createBusinessPartners(legalEntitiesToFind + legalEntitiesToIgnore).entities + val bpnLsToFind = getBpnLs(legalEntitiesToFind, givenLegalEntities) + + val actualMemberships = poolClient.memberships.get(CxMembershipSearchRequest(bpnLsToFind), PaginationRequest()).content + + val expectedMemberships = legalEntitiesToFind.zip(bpnLsToFind) + .map { (request, bpnL) -> CxMembershipDto(bpnL, request.legalEntity.isCatenaXMemberData) } + + + assertThat(actualMemberships).isEqualTo(expectedMemberships) + } + + @Test + fun `get cx memberships with membership true filter`(){ + val legalEntitiesToFind = listOf( + testDataEnvironment.requestFactory.createLegalEntityRequest("Member 1", isCatenaXMemberData = true), + testDataEnvironment.requestFactory.createLegalEntityRequest("Member 2", isCatenaXMemberData = true), + ) + + val legalEntitiesToIgnore = listOf( + testDataEnvironment.requestFactory.createLegalEntityRequest("Non-Member 1", isCatenaXMemberData = false), + testDataEnvironment.requestFactory.createLegalEntityRequest("Non-Member 2", isCatenaXMemberData = false), + ) + + val givenLegalEntities = poolClient.legalEntities.createBusinessPartners(legalEntitiesToFind + legalEntitiesToIgnore).entities + val bpnLsToFind = getBpnLs(legalEntitiesToFind, givenLegalEntities) + + val actualMemberships = poolClient.memberships.get(CxMembershipSearchRequest(isCatenaXMember = true), PaginationRequest()).content + + val expectedMemberships = legalEntitiesToFind.zip(bpnLsToFind) + .map { (request, bpnL) -> CxMembershipDto(bpnL, request.legalEntity.isCatenaXMemberData) } + + + assertThat(actualMemberships).isEqualTo(expectedMemberships) + } + + @Test + fun `get cx memberships with membership false filter`(){ + + val legalEntitiesToFind = listOf( + testDataEnvironment.requestFactory.createLegalEntityRequest("Non-Member 1", isCatenaXMemberData = false), + testDataEnvironment.requestFactory.createLegalEntityRequest("Non-Member 2", isCatenaXMemberData = false), + ) + + val legalEntitiesToIgnore = listOf( + testDataEnvironment.requestFactory.createLegalEntityRequest("Member 1", isCatenaXMemberData = true), + testDataEnvironment.requestFactory.createLegalEntityRequest("Member 2", isCatenaXMemberData = true), + ) + + val givenLegalEntities = poolClient.legalEntities.createBusinessPartners(legalEntitiesToFind + legalEntitiesToIgnore).entities + val bpnLsToFind = getBpnLs(legalEntitiesToFind, givenLegalEntities) + + val actualMemberships = poolClient.memberships.get(CxMembershipSearchRequest(isCatenaXMember = false), PaginationRequest()).content + + val expectedMemberships = legalEntitiesToFind.zip(bpnLsToFind) + .map { (request, bpnL) -> CxMembershipDto(bpnL, request.legalEntity.isCatenaXMemberData) } + + + assertThat(actualMemberships).isEqualTo(expectedMemberships) + } + + @Test + fun `get cx memberships with BPNLs and membership true filter`(){ + val legalEntitiesToFind = listOf( + testDataEnvironment.requestFactory.createLegalEntityRequest("Member 1", isCatenaXMemberData = true), + ) + + val legalEntitiesToIgnore = listOf( + testDataEnvironment.requestFactory.createLegalEntityRequest("Member 2", isCatenaXMemberData = true), + testDataEnvironment.requestFactory.createLegalEntityRequest("Non-Member 1", isCatenaXMemberData = false), + testDataEnvironment.requestFactory.createLegalEntityRequest("Non-Member 2", isCatenaXMemberData = false), + ) + + val givenLegalEntities = poolClient.legalEntities.createBusinessPartners(legalEntitiesToFind + legalEntitiesToIgnore).entities + val bpnLsToFind = getBpnLs(legalEntitiesToFind, givenLegalEntities) + + val actualMemberships = poolClient.memberships.get(CxMembershipSearchRequest(bpnLs = bpnLsToFind, isCatenaXMember = true), PaginationRequest()).content + + val expectedMemberships = legalEntitiesToFind.zip(bpnLsToFind) + .map { (request, bpnL) -> CxMembershipDto(bpnL, request.legalEntity.isCatenaXMemberData) } + + + assertThat(actualMemberships).isEqualTo(expectedMemberships) + } + + @Test + fun `get cx memberships with BPNLs and membership false filter`(){ + val legalEntitiesToFind = listOf( + testDataEnvironment.requestFactory.createLegalEntityRequest("Non-Member 1", isCatenaXMemberData = false), + ) + + val legalEntitiesToIgnore = listOf( + testDataEnvironment.requestFactory.createLegalEntityRequest("Member 2", isCatenaXMemberData = true), + testDataEnvironment.requestFactory.createLegalEntityRequest("Member 1", isCatenaXMemberData = true), + testDataEnvironment.requestFactory.createLegalEntityRequest("Non-Member 2", isCatenaXMemberData = false), + ) + + val givenLegalEntities = poolClient.legalEntities.createBusinessPartners(legalEntitiesToFind + legalEntitiesToIgnore).entities + val bpnLsToFind = getBpnLs(legalEntitiesToFind, givenLegalEntities) + + val actualMemberships = poolClient.memberships.get(CxMembershipSearchRequest(bpnLs = bpnLsToFind, isCatenaXMember = false), PaginationRequest()).content + + val expectedMemberships = legalEntitiesToFind.zip(bpnLsToFind) + .map { (request, bpnL) -> CxMembershipDto(bpnL, request.legalEntity.isCatenaXMemberData) } + + + assertThat(actualMemberships).isEqualTo(expectedMemberships) + } + + @Test + fun `update cx memberships`(){ + val legalEntityRequests = listOf( + testDataEnvironment.requestFactory.createLegalEntityRequest("Member 1", isCatenaXMemberData = true), + testDataEnvironment.requestFactory.createLegalEntityRequest("Non-Member 1", isCatenaXMemberData = false), + testDataEnvironment.requestFactory.createLegalEntityRequest("Member 2", isCatenaXMemberData = true), + testDataEnvironment.requestFactory.createLegalEntityRequest("Non-Member 2", isCatenaXMemberData = false), + ) + val givenLegalEntities = poolClient.legalEntities.createBusinessPartners(legalEntityRequests).entities + val givenBpnLs = getBpnLs(legalEntityRequests, givenLegalEntities) + + val membershipUpdates = legalEntityRequests.zip(givenBpnLs).map { (request, bpnL) -> CxMembershipDto(bpnL, !request.legalEntity.isCatenaXMemberData) } + poolClient.memberships.put(CxMembershipUpdateRequest(membershipUpdates)) + + val actualMemberships = poolClient.memberships.get(CxMembershipSearchRequest(), PaginationRequest()).content + + assertThat(actualMemberships).isEqualTo(membershipUpdates) + } + + + /** + * Searches for BPNLs for the given [requests] by index in the overall [givenLegalEntities] + * Orders the returned BPNLs by the order given in the [requests] + */ + private fun getBpnLs(requests: List, givenLegalEntities: Collection): List{ + return givenLegalEntities + .associate { Pair(it.index, it.legalEntity.bpnl) } + .let { bpnLsByIndex -> requests.map { bpnLsByIndex[it.index]!! } } + } + + +} \ No newline at end of file diff --git a/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/service/TaskResolutionServiceTest.kt b/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/service/TaskResolutionServiceTest.kt index 4901a247e..8966f2eec 100644 --- a/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/service/TaskResolutionServiceTest.kt +++ b/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/service/TaskResolutionServiceTest.kt @@ -139,7 +139,7 @@ class TaskResolutionServiceTest @Autowired constructor( val bpnMappings = bpnRequestIdentifierRepository.findDistinctByRequestIdentifierIn(listOf(leRefValue, leAddressRefValue)) assertThat(bpnMappings.size).isEqualTo(2) - val createdLegalEntity = poolClient.legalEntities.getLegalEntity(createResult[0].businessPartner.legalEntity.bpnReference?.referenceValue!!) + val createdLegalEntity = poolClient.legalEntities.getLegalEntity(createResult[0].businessPartner.legalEntity.bpnReference.referenceValue!!) assertThat(createdLegalEntity.legalAddress.bpnLegalEntity).isNotNull() assertThat(createResult[0].businessPartner.legalEntity.bpnReference.referenceValue).isEqualTo(createdLegalEntity.legalEntity.bpnl) compareLegalEntity(createdLegalEntity, createResult[0].businessPartner.legalEntity) @@ -174,6 +174,35 @@ class TaskResolutionServiceTest @Autowired constructor( assertThat(createdAdditionalAddress.addressType == AddressType.AdditionalAddress).isTrue() } + @Test + fun `create legal entity with isCatenaXMemberData null`() { + + val leRefValue = "123" + val leAddressRefValue = "222" + val additionalAddressRefValue = "333" + val createLegalEntityRequest = orchTestDataFactory.createFullBusinessPartner("test") + .withLegalReferences(leRefValue.toBpnRequest(), leAddressRefValue.toBpnRequest()) + .withAdditionalAddressReference(additionalAddressRefValue.toBpnRequest()) + .withCxMembership(null) + .copy(site = null) + + val createResult = upsertGoldenRecordIntoPool(taskId = "TASK_1", businessPartner = createLegalEntityRequest) + assertThat(createResult[0].taskId).isEqualTo("TASK_1") + assertThat(createResult[0].errors.size).isEqualTo(0) + + val bpnMappings = bpnRequestIdentifierRepository.findDistinctByRequestIdentifierIn(listOf(leRefValue, leAddressRefValue, additionalAddressRefValue)) + assertThat(bpnMappings.size).isEqualTo(3) + + val createdLegalEntity = poolClient.legalEntities.getLegalEntity(createResult[0].businessPartner.legalEntity.bpnReference.referenceValue!!) + assertThat(createdLegalEntity.legalAddress.bpnLegalEntity).isEqualTo(createdLegalEntity.legalEntity.bpnl) + assertThat(createdLegalEntity.legalAddress.addressType == AddressType.LegalAddress).isTrue() + assertThat(createResult[0].businessPartner.legalEntity.bpnReference.referenceValue).isEqualTo(createdLegalEntity.legalEntity.bpnl) + compareLegalEntity(createdLegalEntity, createResult[0].businessPartner.legalEntity.copy(isCatenaXMemberData = false)) + val createdAdditionalAddress = poolClient.addresses.getAddress(createResult[0].businessPartner.additionalAddress?.bpnReference?.referenceValue!!) + assertThat(createdAdditionalAddress.bpnLegalEntity).isEqualTo(createdLegalEntity.legalEntity.bpnl) + assertThat(createdAdditionalAddress.addressType == AddressType.AdditionalAddress).isTrue() + } + @Test fun `create legal entity with invalid identifiers`() { @@ -401,6 +430,64 @@ class TaskResolutionServiceTest @Autowired constructor( compareLegalEntity(updatedLegalEntity, updateResult[0].businessPartner.legalEntity) } + @Test + fun `update Cx-Member legal entity without isCatenaXMemberData set`() { + + val leRefValue = "123" + val leAddressRefValue = "222" + val createLegalEntityRequest = orchTestDataFactory.createFullBusinessPartner("create") + .withLegalReferences(leRefValue.toBpnRequest(), leAddressRefValue.toBpnRequest()) + .withCxMembership(true) + .copy(site = null, additionalAddress = null) + + val createResult = upsertGoldenRecordIntoPool(taskId = "TASK_1", businessPartner = createLegalEntityRequest) + assertThat(createResult[0].taskId).isEqualTo("TASK_1") + assertThat(createResult[0].errors.size).isEqualTo(0) + + val createdLegalEntity = createResult.first().businessPartner.legalEntity + val updateLegalEntityRequest = orchTestDataFactory.createFullBusinessPartner("update") + .withLegalReferences(createdLegalEntity.bpnReference, createdLegalEntity.legalAddress.bpnReference) + .withCxMembership(null) + .copy(site = null, additionalAddress = null) + + val updateResult = upsertGoldenRecordIntoPool(taskId = "TASK_2", businessPartner = updateLegalEntityRequest) + assertThat(updateResult[0].taskId).isEqualTo("TASK_2") + assertThat(updateResult[0].errors.size).isEqualTo(0) + + val updatedLegalEntity = poolClient.legalEntities.getLegalEntity(updateResult[0].businessPartner.legalEntity.bpnReference.referenceValue!!) + assertThat(updatedLegalEntity.legalEntity.legalName).isEqualTo(updateLegalEntityRequest.legalEntity.legalName) + compareLegalEntity(updatedLegalEntity, updateResult[0].businessPartner.legalEntity.copy(isCatenaXMemberData = createLegalEntityRequest.legalEntity.isCatenaXMemberData)) + } + + @Test + fun `update Cx-Non-Member legal entity without isCatenaXMemberData set`() { + + val leRefValue = "123" + val leAddressRefValue = "222" + val createLegalEntityRequest = orchTestDataFactory.createFullBusinessPartner("create") + .withLegalReferences(leRefValue.toBpnRequest(), leAddressRefValue.toBpnRequest()) + .withCxMembership(false) + .copy(site = null, additionalAddress = null) + + val createResult = upsertGoldenRecordIntoPool(taskId = "TASK_1", businessPartner = createLegalEntityRequest) + assertThat(createResult[0].taskId).isEqualTo("TASK_1") + assertThat(createResult[0].errors.size).isEqualTo(0) + + val createdLegalEntity = createResult.first().businessPartner.legalEntity + val updateLegalEntityRequest = orchTestDataFactory.createFullBusinessPartner("update") + .withLegalReferences(createdLegalEntity.bpnReference, createdLegalEntity.legalAddress.bpnReference) + .withCxMembership(null) + .copy(site = null, additionalAddress = null) + + val updateResult = upsertGoldenRecordIntoPool(taskId = "TASK_2", businessPartner = updateLegalEntityRequest) + assertThat(updateResult[0].taskId).isEqualTo("TASK_2") + assertThat(updateResult[0].errors.size).isEqualTo(0) + + val updatedLegalEntity = poolClient.legalEntities.getLegalEntity(updateResult[0].businessPartner.legalEntity.bpnReference.referenceValue!!) + assertThat(updatedLegalEntity.legalEntity.legalName).isEqualTo(updateLegalEntityRequest.legalEntity.legalName) + compareLegalEntity(updatedLegalEntity, updateResult[0].businessPartner.legalEntity.copy(isCatenaXMemberData = createLegalEntityRequest.legalEntity.isCatenaXMemberData)) + } + @Test fun `update legal entity with all fields by BpnRequestIdentifier`() { @@ -467,7 +554,7 @@ class TaskResolutionServiceTest @Autowired constructor( copy(legalEntity = legalEntity.copy(legalForm = "Invalid Form")) }.withLegalReferences(legalEntityRequest.toBpnRequest(), legalAddressRequest.toBpnRequest()) - val updateResult = upsertGoldenRecordIntoPool(taskId = "TASK_2", businessPartner = updateLegalEntityRequest!!) + val updateResult = upsertGoldenRecordIntoPool(taskId = "TASK_2", businessPartner = updateLegalEntityRequest) assertThat(updateResult[0].taskId).isEqualTo("TASK_2") assertThat(updateResult[0].errors.size).isEqualTo(1) assertThat(updateResult[0].errors[0].type).isEqualTo(TaskErrorType.Unspecified) @@ -649,7 +736,7 @@ class TaskResolutionServiceTest @Autowired constructor( ) } - val updateResult = upsertGoldenRecordIntoPool(taskId = "TASK_2", businessPartner = updateSiteRequest!!) + val updateResult = upsertGoldenRecordIntoPool(taskId = "TASK_2", businessPartner = updateSiteRequest) assertThat(updateResult[0].taskId).isEqualTo("TASK_2") assertThat(updateResult[0].errors).isNotEmpty } @@ -791,6 +878,10 @@ class TaskResolutionServiceTest @Autowired constructor( ) } + fun BusinessPartner.withCxMembership(isCatenaXMemberData: Boolean?): BusinessPartner{ + return copy(legalEntity = legalEntity.copy(isCatenaXMemberData = isCatenaXMemberData)) + } + private fun minValidLegalEntity(): BusinessPartner { return with(BusinessPartner.empty) { copy( diff --git a/bpdm-pool/src/test/resources/application-test-scheduling-disabled.yml b/bpdm-pool/src/test/resources/application-test-scheduling-disabled.yml new file mode 100644 index 000000000..7ec41ae39 --- /dev/null +++ b/bpdm-pool/src/test/resources/application-test-scheduling-disabled.yml @@ -0,0 +1,3 @@ +bpdm: + tasks: + cron: '-' diff --git a/docs/api/pool.json b/docs/api/pool.json index d7d200dae..1023850d3 100644 --- a/docs/api/pool.json +++ b/docs/api/pool.json @@ -339,6 +339,83 @@ } } }, + "/v6/cx-memberships": { + "get": { + "tags": [ + "cx-membership-controller" + ], + "operationId": "get", + "parameters": [ + { + "name": "bpnLs", + "in": "query", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "name": "page", + "in": "query", + "description": "Number of page to get results from", + "required": false, + "schema": { + "minimum": 0, + "type": "string", + "default": "0" + } + }, + { + "name": "size", + "in": "query", + "description": "Size of each page", + "required": false, + "schema": { + "maximum": 100, + "minimum": 0, + "type": "string", + "default": "10" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageDtoCxMembershipDto" + } + } + } + } + } + }, + "put": { + "tags": [ + "cx-membership-controller" + ], + "operationId": "put", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CxMembershipUpdateRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, "/v6/addresses": { "get": { "tags": [ @@ -2204,11 +2281,11 @@ "$ref": "#/components/schemas/ErrorInfoAddressCreateError" } }, - "entityCount": { + "errorCount": { "type": "integer", "format": "int32" }, - "errorCount": { + "entityCount": { "type": "integer", "format": "int32" } @@ -2263,11 +2340,11 @@ "$ref": "#/components/schemas/ErrorInfoAddressUpdateError" } }, - "entityCount": { + "errorCount": { "type": "integer", "format": "int32" }, - "errorCount": { + "entityCount": { "type": "integer", "format": "int32" } @@ -3145,6 +3222,35 @@ }, "description": "Country subdivision" }, + "CxMembershipDto": { + "required": [ + "bpnL", + "isCatenaXMember" + ], + "type": "object", + "properties": { + "bpnL": { + "type": "string" + }, + "isCatenaXMember": { + "type": "boolean" + } + } + }, + "CxMembershipUpdateRequest": { + "required": [ + "memberships" + ], + "type": "object", + "properties": { + "memberships": { + "type": "array", + "items": { + "$ref": "#/components/schemas/CxMembershipDto" + } + } + } + }, "ErrorInfoAddressCreateError": { "title": "ErrorInfo", "required": [ @@ -3644,17 +3750,17 @@ "longitude": { "type": "number", "description": "Longitude coordinate", - "format": "float" + "format": "double" }, "latitude": { "type": "number", "description": "Latitude coordinate", - "format": "float" + "format": "double" }, "altitude": { "type": "number", "description": "Altitude, if applicable", - "format": "float" + "format": "double" } }, "description": "The exact location of the physical postal address in latitude, longitude, and altitude." @@ -4068,11 +4174,11 @@ "$ref": "#/components/schemas/ErrorInfoLegalEntityCreateError" } }, - "entityCount": { + "errorCount": { "type": "integer", "format": "int32" }, - "errorCount": { + "entityCount": { "type": "integer", "format": "int32" } @@ -4137,11 +4243,11 @@ "$ref": "#/components/schemas/ErrorInfoLegalEntityUpdateError" } }, - "entityCount": { + "errorCount": { "type": "integer", "format": "int32" }, - "errorCount": { + "entityCount": { "type": "integer", "format": "int32" } @@ -4179,6 +4285,7 @@ }, "LegalFormDto": { "required": [ + "isActive", "name", "technicalKey" ], @@ -4192,160 +4299,1125 @@ "type": "string", "description": "The name of legal form according to ISO 20275." }, - "abbreviation": { - "type": "string", - "description": "The abbreviated name of the legal form, such as AG for German Aktiengesellschaft." - } - }, - "description": "A legal form is a mandatory corporate legal framework by which companies can conduct business, charitable or other permissible activities." - }, - "LegalFormRequest": { - "required": [ - "name", - "technicalKey" - ], - "type": "object", - "properties": { - "technicalKey": { - "type": "string", - "description": "Unique key to be used for reference" - }, - "name": { - "type": "string", - "description": "Full name of the legal form" + "transliteratedName": { + "type": "string" }, "abbreviation": { "type": "string", - "description": "Abbreviation of the legal form name" - } - }, - "description": "New legal form record to be referenced by business partners" - }, - "LogisticAddressDto": { - "required": [ - "confidenceCriteria", - "identifiers", - "physicalPostalAddress", - "states" - ], - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "The name of the address. This is not according to official registers but according to the name the sharing member chooses." - }, - "states": { - "type": "array", - "description": "The list of (temporary) states of the address.", - "items": { - "$ref": "#/components/schemas/AddressStateDto" - } - }, - "identifiers": { - "type": "array", - "description": "The list of identifiers of the address.", - "items": { - "$ref": "#/components/schemas/AddressIdentifierDto" - } - }, - "physicalPostalAddress": { - "$ref": "#/components/schemas/PhysicalPostalAddressDto" - }, - "alternativePostalAddress": { - "$ref": "#/components/schemas/AlternativePostalAddressDto" - }, - "confidenceCriteria": { - "$ref": "#/components/schemas/ConfidenceCriteriaDto" - } - }, - "description": "In general, an address is a collection of information to describe a physical location, using a street name with a house number and/or a post office box as reference. In addition, an address consists of several postal attributes, such as country, region (state), county, township, city, district, or postal code, which help deliver mail.In Catena-X, an address is a type of business partner representing the legal address of a legal entity, and/or the main address of a site, or any additional address of a legal entity or site (such as different gates).An address is owned by a legal entity. Thus, exactly one legal entity is assigned to an address. An address can belong to a site. Thus, one or no site is assigned to an address. An address is uniquely identified by the BPNA." - }, - "LogisticAddressVerboseDto": { - "required": [ - "bpna", - "confidenceCriteria", - "createdAt", - "identifiers", - "isCatenaXMemberData", - "physicalPostalAddress", - "states", - "updatedAt" - ], - "type": "object", - "properties": { - "bpna": { - "type": "string", - "description": "A BPNA represents and uniquely identifies an address, which can be the legal address of a legal entity, and/or the main address of a site, or any additional address of a legal entity or site (such as different gates). It is important to note that only the BPNL must be used to uniquely identify a legal entity. Even in the case that the BPNA represents the legal address of the legal entity, it shall not be used to uniquely identify the legal entity." - }, - "name": { - "type": "string", - "description": "The name of the address. This is not according to official registers but according to the name the sharing member chooses." - }, - "states": { - "type": "array", - "description": "The list of (temporary) states of the address.", - "items": { - "$ref": "#/components/schemas/AddressStateVerboseDto" - } - }, - "identifiers": { - "type": "array", - "description": "The list of identifiers of the address.", - "items": { - "$ref": "#/components/schemas/AddressIdentifierVerboseDto" - } - }, - "physicalPostalAddress": { - "$ref": "#/components/schemas/PhysicalPostalAddressVerboseDto" - }, - "alternativePostalAddress": { - "$ref": "#/components/schemas/AlternativePostalAddressVerboseDto" - }, - "bpnLegalEntity": { - "type": "string", - "description": "The BPNL of the legal entity owning the address." - }, - "bpnSite": { - "type": "string", - "description": "The BPNS of the site the address belongs to." - }, - "isCatenaXMemberData": { - "type": "boolean", - "description": "Indicates whether the address is owned and thus provided by a Catena-X Member." - }, - "createdAt": { - "type": "string", - "description": "The date when the data record has been created.", - "format": "date-time" - }, - "updatedAt": { - "type": "string", - "description": "The date when the data record has been last updated.", - "format": "date-time" - }, - "confidenceCriteria": { - "$ref": "#/components/schemas/ConfidenceCriteriaDto" + "description": "The abbreviated name of the legal form, such as AG for German Aktiengesellschaft." }, - "addressType": { + "country": { "type": "string", - "description": "Indicates the address type, the legal address to a legal entity or the main address to a site, an additional address, or both legal and site address.The site main address is where typically the main entrance or the reception is located, or where the mail is delivered to.", "enum": [ - "LegalAndSiteMainAddress", - "LegalAddress", - "SiteMainAddress", - "AdditionalAddress" - ] - } - }, - "description": "In general, an address is a collection of information to describe a physical location, using a street name with a house number and/or a post office box as reference. In addition, an address consists of several postal attributes, such as country, region (state), county, township, city, district, or postal code, which help deliver mail.In Catena-X, an address is a type of business partner representing the legal address of a legal entity, and/or the main address of a site, or any additional address of a legal entity or site (such as different gates).An address is owned by a legal entity. Thus, exactly one legal entity is assigned to an address. An address can belong to a site. Thus, one or no site is assigned to an address. An address is uniquely identified by the BPNA." - }, - "PageDtoChangelogEntryVerboseDto": { - "required": [ - "content", - "contentSize", - "page", - "totalElements", - "totalPages" + "UNDEFINED", + "AC", + "AD", + "AE", + "AF", + "AG", + "AI", + "AL", + "AM", + "AN", + "AO", + "AQ", + "AR", + "AS", + "AT", + "AU", + "AW", + "AX", + "AZ", + "BA", + "BB", + "BD", + "BE", + "BF", + "BG", + "BH", + "BI", + "BJ", + "BL", + "BM", + "BN", + "BO", + "BQ", + "BR", + "BS", + "BT", + "BU", + "BV", + "BW", + "BY", + "BZ", + "CA", + "CC", + "CD", + "CF", + "CG", + "CH", + "CI", + "CK", + "CL", + "CM", + "CN", + "CO", + "CP", + "CR", + "CS", + "CU", + "CV", + "CW", + "CX", + "CY", + "CZ", + "DE", + "DG", + "DJ", + "DK", + "DM", + "DO", + "DZ", + "EA", + "EC", + "EE", + "EG", + "EH", + "ER", + "ES", + "ET", + "EU", + "EZ", + "FI", + "FJ", + "FK", + "FM", + "FO", + "FR", + "FX", + "GA", + "GB", + "GD", + "GE", + "GF", + "GG", + "GH", + "GI", + "GL", + "GM", + "GN", + "GP", + "GQ", + "GR", + "GS", + "GT", + "GU", + "GW", + "GY", + "HK", + "HM", + "HN", + "HR", + "HT", + "HU", + "IC", + "ID", + "IE", + "IL", + "IM", + "IN", + "IO", + "IQ", + "IR", + "IS", + "IT", + "JE", + "JM", + "JO", + "JP", + "KE", + "KG", + "KH", + "KI", + "KM", + "KN", + "KP", + "KR", + "KW", + "KY", + "KZ", + "LA", + "LB", + "LC", + "LI", + "LK", + "LR", + "LS", + "LT", + "LU", + "LV", + "LY", + "MA", + "MC", + "MD", + "ME", + "MF", + "MG", + "MH", + "MK", + "ML", + "MM", + "MN", + "MO", + "MP", + "MQ", + "MR", + "MS", + "MT", + "MU", + "MV", + "MW", + "MX", + "MY", + "MZ", + "NA", + "NC", + "NE", + "NF", + "NG", + "NI", + "NL", + "NO", + "NP", + "NR", + "NT", + "NU", + "NZ", + "OM", + "PA", + "PE", + "PF", + "PG", + "PH", + "PK", + "PL", + "PM", + "PN", + "PR", + "PS", + "PT", + "PW", + "PY", + "QA", + "RE", + "RO", + "RS", + "RU", + "RW", + "SA", + "SB", + "SC", + "SD", + "SE", + "SF", + "SG", + "SH", + "SI", + "SJ", + "SK", + "SL", + "SM", + "SN", + "SO", + "SR", + "SS", + "ST", + "SU", + "SV", + "SX", + "SY", + "SZ", + "TA", + "TC", + "TD", + "TF", + "TG", + "TH", + "TJ", + "TK", + "TL", + "TM", + "TN", + "TO", + "TP", + "TR", + "TT", + "TV", + "TW", + "TZ", + "UA", + "UG", + "UK", + "UM", + "US", + "UY", + "UZ", + "VA", + "VC", + "VE", + "VG", + "VI", + "VN", + "VU", + "WF", + "WS", + "XI", + "XU", + "XK", + "YE", + "YT", + "YU", + "ZA", + "ZM", + "ZR", + "ZW" + ] + }, + "language": { + "type": "string", + "enum": [ + "undefined", + "aa", + "ab", + "ae", + "af", + "ak", + "am", + "an", + "ar", + "as", + "av", + "ay", + "az", + "ba", + "be", + "bg", + "bh", + "bi", + "bm", + "bn", + "bo", + "br", + "bs", + "ca", + "ce", + "ch", + "co", + "cr", + "cs", + "cu", + "cv", + "cy", + "da", + "de", + "dv", + "dz", + "ee", + "el", + "en", + "eo", + "es", + "et", + "eu", + "fa", + "ff", + "fi", + "fj", + "fo", + "fr", + "fy", + "ga", + "gd", + "gl", + "gn", + "gu", + "gv", + "ha", + "he", + "hi", + "ho", + "hr", + "ht", + "hu", + "hy", + "hz", + "ia", + "id", + "ie", + "ig", + "ii", + "ik", + "io", + "is", + "it", + "iu", + "ja", + "jv", + "ka", + "kg", + "ki", + "kj", + "kk", + "kl", + "km", + "kn", + "ko", + "kr", + "ks", + "ku", + "kv", + "kw", + "ky", + "la", + "lb", + "lg", + "li", + "ln", + "lo", + "lt", + "lu", + "lv", + "mg", + "mh", + "mi", + "mk", + "ml", + "mn", + "mr", + "ms", + "mt", + "my", + "na", + "nb", + "nd", + "ne", + "ng", + "nl", + "nn", + "no", + "nr", + "nv", + "ny", + "oc", + "oj", + "om", + "or", + "os", + "pa", + "pi", + "pl", + "ps", + "pt", + "qu", + "rm", + "rn", + "ro", + "ru", + "rw", + "sa", + "sc", + "sd", + "se", + "sg", + "si", + "sk", + "sl", + "sm", + "sn", + "so", + "sq", + "sr", + "ss", + "st", + "su", + "sv", + "sw", + "ta", + "te", + "tg", + "th", + "ti", + "tk", + "tl", + "tn", + "to", + "tr", + "ts", + "tt", + "tw", + "ty", + "ug", + "uk", + "ur", + "uz", + "ve", + "vi", + "vo", + "wa", + "wo", + "xh", + "yi", + "yo", + "za", + "zh", + "zu" + ] + }, + "administrativeAreaLevel1": { + "type": "string" + }, + "transliteratedAbbreviations": { + "type": "string" + }, + "isActive": { + "type": "boolean" + } + }, + "description": "A legal form is a mandatory corporate legal framework by which companies can conduct business, charitable or other permissible activities." + }, + "LegalFormRequest": { + "required": [ + "isActive", + "name", + "technicalKey" + ], + "type": "object", + "properties": { + "technicalKey": { + "type": "string", + "description": "Unique key to be used for reference" + }, + "name": { + "type": "string", + "description": "Full name of the legal form" + }, + "transliteratedName": { + "type": "string", + "description": "Transliterated name of the legal form" + }, + "abbreviation": { + "type": "string", + "description": "Comma separed list of abbreviations of the legal form name" + }, + "transliteratedAbbreviations": { + "type": "string", + "description": "Transliterated abbreviations of the legal form abbreviations" + }, + "country": { + "type": "string", + "description": "The country to which this legal form belongs to", + "enum": [ + "UNDEFINED", + "AC", + "AD", + "AE", + "AF", + "AG", + "AI", + "AL", + "AM", + "AN", + "AO", + "AQ", + "AR", + "AS", + "AT", + "AU", + "AW", + "AX", + "AZ", + "BA", + "BB", + "BD", + "BE", + "BF", + "BG", + "BH", + "BI", + "BJ", + "BL", + "BM", + "BN", + "BO", + "BQ", + "BR", + "BS", + "BT", + "BU", + "BV", + "BW", + "BY", + "BZ", + "CA", + "CC", + "CD", + "CF", + "CG", + "CH", + "CI", + "CK", + "CL", + "CM", + "CN", + "CO", + "CP", + "CR", + "CS", + "CU", + "CV", + "CW", + "CX", + "CY", + "CZ", + "DE", + "DG", + "DJ", + "DK", + "DM", + "DO", + "DZ", + "EA", + "EC", + "EE", + "EG", + "EH", + "ER", + "ES", + "ET", + "EU", + "EZ", + "FI", + "FJ", + "FK", + "FM", + "FO", + "FR", + "FX", + "GA", + "GB", + "GD", + "GE", + "GF", + "GG", + "GH", + "GI", + "GL", + "GM", + "GN", + "GP", + "GQ", + "GR", + "GS", + "GT", + "GU", + "GW", + "GY", + "HK", + "HM", + "HN", + "HR", + "HT", + "HU", + "IC", + "ID", + "IE", + "IL", + "IM", + "IN", + "IO", + "IQ", + "IR", + "IS", + "IT", + "JE", + "JM", + "JO", + "JP", + "KE", + "KG", + "KH", + "KI", + "KM", + "KN", + "KP", + "KR", + "KW", + "KY", + "KZ", + "LA", + "LB", + "LC", + "LI", + "LK", + "LR", + "LS", + "LT", + "LU", + "LV", + "LY", + "MA", + "MC", + "MD", + "ME", + "MF", + "MG", + "MH", + "MK", + "ML", + "MM", + "MN", + "MO", + "MP", + "MQ", + "MR", + "MS", + "MT", + "MU", + "MV", + "MW", + "MX", + "MY", + "MZ", + "NA", + "NC", + "NE", + "NF", + "NG", + "NI", + "NL", + "NO", + "NP", + "NR", + "NT", + "NU", + "NZ", + "OM", + "PA", + "PE", + "PF", + "PG", + "PH", + "PK", + "PL", + "PM", + "PN", + "PR", + "PS", + "PT", + "PW", + "PY", + "QA", + "RE", + "RO", + "RS", + "RU", + "RW", + "SA", + "SB", + "SC", + "SD", + "SE", + "SF", + "SG", + "SH", + "SI", + "SJ", + "SK", + "SL", + "SM", + "SN", + "SO", + "SR", + "SS", + "ST", + "SU", + "SV", + "SX", + "SY", + "SZ", + "TA", + "TC", + "TD", + "TF", + "TG", + "TH", + "TJ", + "TK", + "TL", + "TM", + "TN", + "TO", + "TP", + "TR", + "TT", + "TV", + "TW", + "TZ", + "UA", + "UG", + "UK", + "UM", + "US", + "UY", + "UZ", + "VA", + "VC", + "VE", + "VG", + "VI", + "VN", + "VU", + "WF", + "WS", + "XI", + "XU", + "XK", + "YE", + "YT", + "YU", + "ZA", + "ZM", + "ZR", + "ZW" + ] + }, + "language": { + "type": "string", + "description": "The language of the legal form's name", + "enum": [ + "undefined", + "aa", + "ab", + "ae", + "af", + "ak", + "am", + "an", + "ar", + "as", + "av", + "ay", + "az", + "ba", + "be", + "bg", + "bh", + "bi", + "bm", + "bn", + "bo", + "br", + "bs", + "ca", + "ce", + "ch", + "co", + "cr", + "cs", + "cu", + "cv", + "cy", + "da", + "de", + "dv", + "dz", + "ee", + "el", + "en", + "eo", + "es", + "et", + "eu", + "fa", + "ff", + "fi", + "fj", + "fo", + "fr", + "fy", + "ga", + "gd", + "gl", + "gn", + "gu", + "gv", + "ha", + "he", + "hi", + "ho", + "hr", + "ht", + "hu", + "hy", + "hz", + "ia", + "id", + "ie", + "ig", + "ii", + "ik", + "io", + "is", + "it", + "iu", + "ja", + "jv", + "ka", + "kg", + "ki", + "kj", + "kk", + "kl", + "km", + "kn", + "ko", + "kr", + "ks", + "ku", + "kv", + "kw", + "ky", + "la", + "lb", + "lg", + "li", + "ln", + "lo", + "lt", + "lu", + "lv", + "mg", + "mh", + "mi", + "mk", + "ml", + "mn", + "mr", + "ms", + "mt", + "my", + "na", + "nb", + "nd", + "ne", + "ng", + "nl", + "nn", + "no", + "nr", + "nv", + "ny", + "oc", + "oj", + "om", + "or", + "os", + "pa", + "pi", + "pl", + "ps", + "pt", + "qu", + "rm", + "rn", + "ro", + "ru", + "rw", + "sa", + "sc", + "sd", + "se", + "sg", + "si", + "sk", + "sl", + "sm", + "sn", + "so", + "sq", + "sr", + "ss", + "st", + "su", + "sv", + "sw", + "ta", + "te", + "tg", + "th", + "ti", + "tk", + "tl", + "tn", + "to", + "tr", + "ts", + "tt", + "tw", + "ty", + "ug", + "uk", + "ur", + "uz", + "ve", + "vi", + "vo", + "wa", + "wo", + "xh", + "yi", + "yo", + "za", + "zh", + "zu" + ] + }, + "administrativeAreaLevel1": { + "type": "string", + "description": "The administrative area level 1 this legal form belongs to" + }, + "isActive": { + "type": "boolean", + "description": "Whether this legal form is considered as active according to GLEIF" + } + }, + "description": "New legal form record to be referenced by business partners" + }, + "LogisticAddressDto": { + "required": [ + "confidenceCriteria", + "identifiers", + "physicalPostalAddress", + "states" + ], + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The name of the address. This is not according to official registers but according to the name the sharing member chooses." + }, + "states": { + "type": "array", + "description": "The list of (temporary) states of the address.", + "items": { + "$ref": "#/components/schemas/AddressStateDto" + } + }, + "identifiers": { + "type": "array", + "description": "The list of identifiers of the address.", + "items": { + "$ref": "#/components/schemas/AddressIdentifierDto" + } + }, + "physicalPostalAddress": { + "$ref": "#/components/schemas/PhysicalPostalAddressDto" + }, + "alternativePostalAddress": { + "$ref": "#/components/schemas/AlternativePostalAddressDto" + }, + "confidenceCriteria": { + "$ref": "#/components/schemas/ConfidenceCriteriaDto" + } + }, + "description": "In general, an address is a collection of information to describe a physical location, using a street name with a house number and/or a post office box as reference. In addition, an address consists of several postal attributes, such as country, region (state), county, township, city, district, or postal code, which help deliver mail.In Catena-X, an address is a type of business partner representing the legal address of a legal entity, and/or the main address of a site, or any additional address of a legal entity or site (such as different gates).An address is owned by a legal entity. Thus, exactly one legal entity is assigned to an address. An address can belong to a site. Thus, one or no site is assigned to an address. An address is uniquely identified by the BPNA." + }, + "LogisticAddressVerboseDto": { + "required": [ + "bpna", + "confidenceCriteria", + "createdAt", + "identifiers", + "isCatenaXMemberData", + "physicalPostalAddress", + "states", + "updatedAt" + ], + "type": "object", + "properties": { + "bpna": { + "type": "string", + "description": "A BPNA represents and uniquely identifies an address, which can be the legal address of a legal entity, and/or the main address of a site, or any additional address of a legal entity or site (such as different gates). It is important to note that only the BPNL must be used to uniquely identify a legal entity. Even in the case that the BPNA represents the legal address of the legal entity, it shall not be used to uniquely identify the legal entity." + }, + "name": { + "type": "string", + "description": "The name of the address. This is not according to official registers but according to the name the sharing member chooses." + }, + "states": { + "type": "array", + "description": "The list of (temporary) states of the address.", + "items": { + "$ref": "#/components/schemas/AddressStateVerboseDto" + } + }, + "identifiers": { + "type": "array", + "description": "The list of identifiers of the address.", + "items": { + "$ref": "#/components/schemas/AddressIdentifierVerboseDto" + } + }, + "physicalPostalAddress": { + "$ref": "#/components/schemas/PhysicalPostalAddressVerboseDto" + }, + "alternativePostalAddress": { + "$ref": "#/components/schemas/AlternativePostalAddressVerboseDto" + }, + "bpnLegalEntity": { + "type": "string", + "description": "The BPNL of the legal entity owning the address." + }, + "bpnSite": { + "type": "string", + "description": "The BPNS of the site the address belongs to." + }, + "isCatenaXMemberData": { + "type": "boolean", + "description": "Indicates whether the address is owned and thus provided by a Catena-X Member." + }, + "createdAt": { + "type": "string", + "description": "The date when the data record has been created.", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "description": "The date when the data record has been last updated.", + "format": "date-time" + }, + "confidenceCriteria": { + "$ref": "#/components/schemas/ConfidenceCriteriaDto" + }, + "addressType": { + "type": "string", + "description": "Indicates the address type, the legal address to a legal entity or the main address to a site, an additional address, or both legal and site address.The site main address is where typically the main entrance or the reception is located, or where the mail is delivered to.", + "enum": [ + "LegalAndSiteMainAddress", + "LegalAddress", + "SiteMainAddress", + "AdditionalAddress" + ] + } + }, + "description": "In general, an address is a collection of information to describe a physical location, using a street name with a house number and/or a post office box as reference. In addition, an address consists of several postal attributes, such as country, region (state), county, township, city, district, or postal code, which help deliver mail.In Catena-X, an address is a type of business partner representing the legal address of a legal entity, and/or the main address of a site, or any additional address of a legal entity or site (such as different gates).An address is owned by a legal entity. Thus, exactly one legal entity is assigned to an address. An address can belong to a site. Thus, one or no site is assigned to an address. An address is uniquely identified by the BPNA." + }, + "PageDtoChangelogEntryVerboseDto": { + "required": [ + "content", + "contentSize", + "page", + "totalElements", + "totalPages" ], "type": "object", "properties": { @@ -4419,6 +5491,46 @@ }, "description": "Paginated collection of results" }, + "PageDtoCxMembershipDto": { + "required": [ + "content", + "contentSize", + "page", + "totalElements", + "totalPages" + ], + "type": "object", + "properties": { + "totalElements": { + "type": "integer", + "description": "Total number of all results in all pages", + "format": "int64" + }, + "totalPages": { + "type": "integer", + "description": "Total number pages", + "format": "int32" + }, + "page": { + "type": "integer", + "description": "Current page number", + "format": "int32" + }, + "contentSize": { + "type": "integer", + "description": "Number of results in the page", + "format": "int32" + }, + "content": { + "type": "array", + "description": "Collection of results in the page", + "items": { + "$ref": "#/components/schemas/CxMembershipDto" + } + } + }, + "description": "Paginated collection of results" + }, "PageDtoIdentifierTypeDto": { "required": [ "content", @@ -5433,11 +6545,11 @@ "$ref": "#/components/schemas/ErrorInfoSiteCreateError" } }, - "entityCount": { + "errorCount": { "type": "integer", "format": "int32" }, - "errorCount": { + "entityCount": { "type": "integer", "format": "int32" } @@ -5498,11 +6610,11 @@ "$ref": "#/components/schemas/ErrorInfoSiteUpdateError" } }, - "entityCount": { + "errorCount": { "type": "integer", "format": "int32" }, - "errorCount": { + "entityCount": { "type": "integer", "format": "int32" } @@ -6025,7 +7137,8 @@ "type": "oauth2", "flows": { "clientCredentials": { - "tokenUrl": "http://localhost:8180/realms/CX-Central/protocol/openid-connect/token" + "tokenUrl": "http://localhost:8180/realms/CX-Central/protocol/openid-connect/token", + "scopes": {} }, "authorizationCode": { "authorizationUrl": "http://localhost:8180/realms/CX-Central/protocol/openid-connect/auth", diff --git a/docs/api/pool.yaml b/docs/api/pool.yaml index d5f720770..fd6b320b2 100644 --- a/docs/api/pool.yaml +++ b/docs/api/pool.yaml @@ -214,6 +214,56 @@ paths: $ref: '#/components/schemas/LegalEntityPartnerCreateResponseWrapper' '400': description: On malformed requests + /v6/cx-memberships: + get: + tags: + - cx-membership-controller + operationId: get + parameters: + - name: bpnLs + in: query + required: false + schema: + type: array + items: + type: string + - name: page + in: query + description: Number of page to get results from + required: false + schema: + minimum: 0 + type: string + default: '0' + - name: size + in: query + description: Size of each page + required: false + schema: + maximum: 100 + minimum: 0 + type: string + default: '10' + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/PageDtoCxMembershipDto' + put: + tags: + - cx-membership-controller + operationId: put + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CxMembershipUpdateRequest' + required: true + responses: + '200': + description: OK /v6/addresses: get: tags: @@ -1632,10 +1682,10 @@ components: type: array items: $ref: '#/components/schemas/ErrorInfoAddressCreateError' - entityCount: + errorCount: type: integer format: int32 - errorCount: + entityCount: type: integer format: int32 description: Holds information about successfully and failed entities after the creating/updating of several objects @@ -1674,10 +1724,10 @@ components: type: array items: $ref: '#/components/schemas/ErrorInfoAddressUpdateError' - entityCount: + errorCount: type: integer format: int32 - errorCount: + entityCount: type: integer format: int32 description: Holds information about successfully and failed entities after the creating/updating of several objects @@ -2466,6 +2516,25 @@ components: type: string description: The name of the country subdivision according to ISO 3166-2 description: Country subdivision + CxMembershipDto: + required: + - bpnL + - isCatenaXMember + type: object + properties: + bpnL: + type: string + isCatenaXMember: + type: boolean + CxMembershipUpdateRequest: + required: + - memberships + type: object + properties: + memberships: + type: array + items: + $ref: '#/components/schemas/CxMembershipDto' ErrorInfoAddressCreateError: title: ErrorInfo required: @@ -2913,15 +2982,15 @@ components: longitude: type: number description: Longitude coordinate - format: float + format: double latitude: type: number description: Latitude coordinate - format: float + format: double altitude: type: number description: Altitude, if applicable - format: float + format: double description: The exact location of the physical postal address in latitude, longitude, and altitude. IdentifierTypeDetailDto: required: @@ -3295,10 +3364,10 @@ components: type: array items: $ref: '#/components/schemas/ErrorInfoLegalEntityCreateError' - entityCount: + errorCount: type: integer format: int32 - errorCount: + entityCount: type: integer format: int32 description: Holds information about successfully and failed entities after the creating/updating of several objects @@ -3344,10 +3413,10 @@ components: type: array items: $ref: '#/components/schemas/ErrorInfoLegalEntityUpdateError' - entityCount: + errorCount: type: integer format: int32 - errorCount: + entityCount: type: integer format: int32 description: Holds information about successfully and failed entities after the creating/updating of several objects @@ -3372,6 +3441,7 @@ components: description: In general, a legal entity is a juridical person that has legal rights and duties related to contracts, agreements, and obligations. The term especially applies to any kind of organization (such as an enterprise or company, university, association, etc.) established under the law applicable to a country.In Catena-X, a legal entity is a type of business partner representing a legally registered organization with its official registration information, such as legal name (including legal form, if registered), legal address and tax number.A legal entity has exactly one legal address, but it is possible to specify additional addresses that a legal entity owns. Thus, at least one address is assigned to a legal entity. A legal entity can own sites. Thus, many or no sites are assigned to a legal entity. A legal entity is uniquely identified by the BPNL. LegalFormDto: required: + - isActive - name - technicalKey type: object @@ -3382,196 +3452,1176 @@ components: name: type: string description: The name of legal form according to ISO 20275. - abbreviation: - type: string - description: The abbreviated name of the legal form, such as AG for German Aktiengesellschaft. - description: A legal form is a mandatory corporate legal framework by which companies can conduct business, charitable or other permissible activities. - LegalFormRequest: - required: - - name - - technicalKey - type: object - properties: - technicalKey: - type: string - description: Unique key to be used for reference - name: + transliteratedName: type: string - description: Full name of the legal form abbreviation: type: string - description: Abbreviation of the legal form name - description: New legal form record to be referenced by business partners - LogisticAddressDto: - required: - - confidenceCriteria - - identifiers - - physicalPostalAddress - - states - type: object - properties: - name: - type: string - description: The name of the address. This is not according to official registers but according to the name the sharing member chooses. - states: - type: array - description: The list of (temporary) states of the address. - items: - $ref: '#/components/schemas/AddressStateDto' - identifiers: - type: array - description: The list of identifiers of the address. - items: - $ref: '#/components/schemas/AddressIdentifierDto' - physicalPostalAddress: - $ref: '#/components/schemas/PhysicalPostalAddressDto' - alternativePostalAddress: - $ref: '#/components/schemas/AlternativePostalAddressDto' - confidenceCriteria: - $ref: '#/components/schemas/ConfidenceCriteriaDto' - description: In general, an address is a collection of information to describe a physical location, using a street name with a house number and/or a post office box as reference. In addition, an address consists of several postal attributes, such as country, region (state), county, township, city, district, or postal code, which help deliver mail.In Catena-X, an address is a type of business partner representing the legal address of a legal entity, and/or the main address of a site, or any additional address of a legal entity or site (such as different gates).An address is owned by a legal entity. Thus, exactly one legal entity is assigned to an address. An address can belong to a site. Thus, one or no site is assigned to an address. An address is uniquely identified by the BPNA. - LogisticAddressVerboseDto: - required: - - bpna - - confidenceCriteria - - createdAt - - identifiers - - isCatenaXMemberData - - physicalPostalAddress - - states - - updatedAt - type: object - properties: - bpna: - type: string - description: A BPNA represents and uniquely identifies an address, which can be the legal address of a legal entity, and/or the main address of a site, or any additional address of a legal entity or site (such as different gates). It is important to note that only the BPNL must be used to uniquely identify a legal entity. Even in the case that the BPNA represents the legal address of the legal entity, it shall not be used to uniquely identify the legal entity. - name: - type: string - description: The name of the address. This is not according to official registers but according to the name the sharing member chooses. - states: - type: array - description: The list of (temporary) states of the address. - items: - $ref: '#/components/schemas/AddressStateVerboseDto' - identifiers: - type: array - description: The list of identifiers of the address. - items: - $ref: '#/components/schemas/AddressIdentifierVerboseDto' - physicalPostalAddress: - $ref: '#/components/schemas/PhysicalPostalAddressVerboseDto' - alternativePostalAddress: - $ref: '#/components/schemas/AlternativePostalAddressVerboseDto' - bpnLegalEntity: - type: string - description: The BPNL of the legal entity owning the address. - bpnSite: - type: string - description: The BPNS of the site the address belongs to. - isCatenaXMemberData: - type: boolean - description: Indicates whether the address is owned and thus provided by a Catena-X Member. - createdAt: - type: string - description: The date when the data record has been created. - format: date-time - updatedAt: - type: string - description: The date when the data record has been last updated. - format: date-time - confidenceCriteria: - $ref: '#/components/schemas/ConfidenceCriteriaDto' - addressType: + description: The abbreviated name of the legal form, such as AG for German Aktiengesellschaft. + country: type: string - description: Indicates the address type, the legal address to a legal entity or the main address to a site, an additional address, or both legal and site address.The site main address is where typically the main entrance or the reception is located, or where the mail is delivered to. enum: - - LegalAndSiteMainAddress - - LegalAddress - - SiteMainAddress - - AdditionalAddress - description: In general, an address is a collection of information to describe a physical location, using a street name with a house number and/or a post office box as reference. In addition, an address consists of several postal attributes, such as country, region (state), county, township, city, district, or postal code, which help deliver mail.In Catena-X, an address is a type of business partner representing the legal address of a legal entity, and/or the main address of a site, or any additional address of a legal entity or site (such as different gates).An address is owned by a legal entity. Thus, exactly one legal entity is assigned to an address. An address can belong to a site. Thus, one or no site is assigned to an address. An address is uniquely identified by the BPNA. - PageDtoChangelogEntryVerboseDto: - required: - - content - - contentSize - - page - - totalElements - - totalPages - type: object - properties: - totalElements: - type: integer - description: Total number of all results in all pages - format: int64 - totalPages: - type: integer - description: Total number pages - format: int32 - page: - type: integer - description: Current page number - format: int32 - contentSize: - type: integer - description: Number of results in the page - format: int32 - content: - type: array - description: Collection of results in the page - items: - $ref: '#/components/schemas/ChangelogEntryVerboseDto' - description: Paginated collection of results - PageDtoCountrySubdivisionDto: - required: - - content - - contentSize - - page - - totalElements - - totalPages - type: object - properties: - totalElements: - type: integer - description: Total number of all results in all pages - format: int64 - totalPages: - type: integer - description: Total number pages - format: int32 - page: - type: integer - description: Current page number - format: int32 - contentSize: - type: integer - description: Number of results in the page - format: int32 - content: - type: array - description: Collection of results in the page - items: - $ref: '#/components/schemas/CountrySubdivisionDto' - description: Paginated collection of results - PageDtoIdentifierTypeDto: - required: - - content - - contentSize - - page - - totalElements - - totalPages - type: object - properties: - totalElements: - type: integer - description: Total number of all results in all pages - format: int64 - totalPages: - type: integer - description: Total number pages - format: int32 - page: - type: integer - description: Current page number + - UNDEFINED + - AC + - AD + - AE + - AF + - AG + - AI + - AL + - AM + - AN + - AO + - AQ + - AR + - AS + - AT + - AU + - AW + - AX + - AZ + - BA + - BB + - BD + - BE + - BF + - BG + - BH + - BI + - BJ + - BL + - BM + - BN + - BO + - BQ + - BR + - BS + - BT + - BU + - BV + - BW + - BY + - BZ + - CA + - CC + - CD + - CF + - CG + - CH + - CI + - CK + - CL + - CM + - CN + - CO + - CP + - CR + - CS + - CU + - CV + - CW + - CX + - CY + - CZ + - DE + - DG + - DJ + - DK + - DM + - DO + - DZ + - EA + - EC + - EE + - EG + - EH + - ER + - ES + - ET + - EU + - EZ + - FI + - FJ + - FK + - FM + - FO + - FR + - FX + - GA + - GB + - GD + - GE + - GF + - GG + - GH + - GI + - GL + - GM + - GN + - GP + - GQ + - GR + - GS + - GT + - GU + - GW + - GY + - HK + - HM + - HN + - HR + - HT + - HU + - IC + - ID + - IE + - IL + - IM + - IN + - IO + - IQ + - IR + - IS + - IT + - JE + - JM + - JO + - JP + - KE + - KG + - KH + - KI + - KM + - KN + - KP + - KR + - KW + - KY + - KZ + - LA + - LB + - LC + - LI + - LK + - LR + - LS + - LT + - LU + - LV + - LY + - MA + - MC + - MD + - ME + - MF + - MG + - MH + - MK + - ML + - MM + - MN + - MO + - MP + - MQ + - MR + - MS + - MT + - MU + - MV + - MW + - MX + - MY + - MZ + - NA + - NC + - NE + - NF + - NG + - NI + - NL + - 'NO' + - NP + - NR + - NT + - NU + - NZ + - OM + - PA + - PE + - PF + - PG + - PH + - PK + - PL + - PM + - PN + - PR + - PS + - PT + - PW + - PY + - QA + - RE + - RO + - RS + - RU + - RW + - SA + - SB + - SC + - SD + - SE + - SF + - SG + - SH + - SI + - SJ + - SK + - SL + - SM + - SN + - SO + - SR + - SS + - ST + - SU + - SV + - SX + - SY + - SZ + - TA + - TC + - TD + - TF + - TG + - TH + - TJ + - TK + - TL + - TM + - TN + - TO + - TP + - TR + - TT + - TV + - TW + - TZ + - UA + - UG + - UK + - UM + - US + - UY + - UZ + - VA + - VC + - VE + - VG + - VI + - VN + - VU + - WF + - WS + - XI + - XU + - XK + - YE + - YT + - YU + - ZA + - ZM + - ZR + - ZW + language: + type: string + enum: + - undefined + - aa + - ab + - ae + - af + - ak + - am + - an + - ar + - as + - av + - ay + - az + - ba + - be + - bg + - bh + - bi + - bm + - bn + - bo + - br + - bs + - ca + - ce + - ch + - co + - cr + - cs + - cu + - cv + - cy + - da + - de + - dv + - dz + - ee + - el + - en + - eo + - es + - et + - eu + - fa + - ff + - fi + - fj + - fo + - fr + - fy + - ga + - gd + - gl + - gn + - gu + - gv + - ha + - he + - hi + - ho + - hr + - ht + - hu + - hy + - hz + - ia + - id + - ie + - ig + - ii + - ik + - io + - is + - it + - iu + - ja + - jv + - ka + - kg + - ki + - kj + - kk + - kl + - km + - kn + - ko + - kr + - ks + - ku + - kv + - kw + - ky + - la + - lb + - lg + - li + - ln + - lo + - lt + - lu + - lv + - mg + - mh + - mi + - mk + - ml + - mn + - mr + - ms + - mt + - my + - na + - nb + - nd + - ne + - ng + - nl + - nn + - 'no' + - nr + - nv + - ny + - oc + - oj + - om + - or + - os + - pa + - pi + - pl + - ps + - pt + - qu + - rm + - rn + - ro + - ru + - rw + - sa + - sc + - sd + - se + - sg + - si + - sk + - sl + - sm + - sn + - so + - sq + - sr + - ss + - st + - su + - sv + - sw + - ta + - te + - tg + - th + - ti + - tk + - tl + - tn + - to + - tr + - ts + - tt + - tw + - ty + - ug + - uk + - ur + - uz + - ve + - vi + - vo + - wa + - wo + - xh + - yi + - yo + - za + - zh + - zu + administrativeAreaLevel1: + type: string + transliteratedAbbreviations: + type: string + isActive: + type: boolean + description: A legal form is a mandatory corporate legal framework by which companies can conduct business, charitable or other permissible activities. + LegalFormRequest: + required: + - isActive + - name + - technicalKey + type: object + properties: + technicalKey: + type: string + description: Unique key to be used for reference + name: + type: string + description: Full name of the legal form + transliteratedName: + type: string + description: Transliterated name of the legal form + abbreviation: + type: string + description: Comma separed list of abbreviations of the legal form name + transliteratedAbbreviations: + type: string + description: Transliterated abbreviations of the legal form abbreviations + country: + type: string + description: The country to which this legal form belongs to + enum: + - UNDEFINED + - AC + - AD + - AE + - AF + - AG + - AI + - AL + - AM + - AN + - AO + - AQ + - AR + - AS + - AT + - AU + - AW + - AX + - AZ + - BA + - BB + - BD + - BE + - BF + - BG + - BH + - BI + - BJ + - BL + - BM + - BN + - BO + - BQ + - BR + - BS + - BT + - BU + - BV + - BW + - BY + - BZ + - CA + - CC + - CD + - CF + - CG + - CH + - CI + - CK + - CL + - CM + - CN + - CO + - CP + - CR + - CS + - CU + - CV + - CW + - CX + - CY + - CZ + - DE + - DG + - DJ + - DK + - DM + - DO + - DZ + - EA + - EC + - EE + - EG + - EH + - ER + - ES + - ET + - EU + - EZ + - FI + - FJ + - FK + - FM + - FO + - FR + - FX + - GA + - GB + - GD + - GE + - GF + - GG + - GH + - GI + - GL + - GM + - GN + - GP + - GQ + - GR + - GS + - GT + - GU + - GW + - GY + - HK + - HM + - HN + - HR + - HT + - HU + - IC + - ID + - IE + - IL + - IM + - IN + - IO + - IQ + - IR + - IS + - IT + - JE + - JM + - JO + - JP + - KE + - KG + - KH + - KI + - KM + - KN + - KP + - KR + - KW + - KY + - KZ + - LA + - LB + - LC + - LI + - LK + - LR + - LS + - LT + - LU + - LV + - LY + - MA + - MC + - MD + - ME + - MF + - MG + - MH + - MK + - ML + - MM + - MN + - MO + - MP + - MQ + - MR + - MS + - MT + - MU + - MV + - MW + - MX + - MY + - MZ + - NA + - NC + - NE + - NF + - NG + - NI + - NL + - 'NO' + - NP + - NR + - NT + - NU + - NZ + - OM + - PA + - PE + - PF + - PG + - PH + - PK + - PL + - PM + - PN + - PR + - PS + - PT + - PW + - PY + - QA + - RE + - RO + - RS + - RU + - RW + - SA + - SB + - SC + - SD + - SE + - SF + - SG + - SH + - SI + - SJ + - SK + - SL + - SM + - SN + - SO + - SR + - SS + - ST + - SU + - SV + - SX + - SY + - SZ + - TA + - TC + - TD + - TF + - TG + - TH + - TJ + - TK + - TL + - TM + - TN + - TO + - TP + - TR + - TT + - TV + - TW + - TZ + - UA + - UG + - UK + - UM + - US + - UY + - UZ + - VA + - VC + - VE + - VG + - VI + - VN + - VU + - WF + - WS + - XI + - XU + - XK + - YE + - YT + - YU + - ZA + - ZM + - ZR + - ZW + language: + type: string + description: The language of the legal form's name + enum: + - undefined + - aa + - ab + - ae + - af + - ak + - am + - an + - ar + - as + - av + - ay + - az + - ba + - be + - bg + - bh + - bi + - bm + - bn + - bo + - br + - bs + - ca + - ce + - ch + - co + - cr + - cs + - cu + - cv + - cy + - da + - de + - dv + - dz + - ee + - el + - en + - eo + - es + - et + - eu + - fa + - ff + - fi + - fj + - fo + - fr + - fy + - ga + - gd + - gl + - gn + - gu + - gv + - ha + - he + - hi + - ho + - hr + - ht + - hu + - hy + - hz + - ia + - id + - ie + - ig + - ii + - ik + - io + - is + - it + - iu + - ja + - jv + - ka + - kg + - ki + - kj + - kk + - kl + - km + - kn + - ko + - kr + - ks + - ku + - kv + - kw + - ky + - la + - lb + - lg + - li + - ln + - lo + - lt + - lu + - lv + - mg + - mh + - mi + - mk + - ml + - mn + - mr + - ms + - mt + - my + - na + - nb + - nd + - ne + - ng + - nl + - nn + - 'no' + - nr + - nv + - ny + - oc + - oj + - om + - or + - os + - pa + - pi + - pl + - ps + - pt + - qu + - rm + - rn + - ro + - ru + - rw + - sa + - sc + - sd + - se + - sg + - si + - sk + - sl + - sm + - sn + - so + - sq + - sr + - ss + - st + - su + - sv + - sw + - ta + - te + - tg + - th + - ti + - tk + - tl + - tn + - to + - tr + - ts + - tt + - tw + - ty + - ug + - uk + - ur + - uz + - ve + - vi + - vo + - wa + - wo + - xh + - yi + - yo + - za + - zh + - zu + administrativeAreaLevel1: + type: string + description: The administrative area level 1 this legal form belongs to + isActive: + type: boolean + description: Whether this legal form is considered as active according to GLEIF + description: New legal form record to be referenced by business partners + LogisticAddressDto: + required: + - confidenceCriteria + - identifiers + - physicalPostalAddress + - states + type: object + properties: + name: + type: string + description: The name of the address. This is not according to official registers but according to the name the sharing member chooses. + states: + type: array + description: The list of (temporary) states of the address. + items: + $ref: '#/components/schemas/AddressStateDto' + identifiers: + type: array + description: The list of identifiers of the address. + items: + $ref: '#/components/schemas/AddressIdentifierDto' + physicalPostalAddress: + $ref: '#/components/schemas/PhysicalPostalAddressDto' + alternativePostalAddress: + $ref: '#/components/schemas/AlternativePostalAddressDto' + confidenceCriteria: + $ref: '#/components/schemas/ConfidenceCriteriaDto' + description: In general, an address is a collection of information to describe a physical location, using a street name with a house number and/or a post office box as reference. In addition, an address consists of several postal attributes, such as country, region (state), county, township, city, district, or postal code, which help deliver mail.In Catena-X, an address is a type of business partner representing the legal address of a legal entity, and/or the main address of a site, or any additional address of a legal entity or site (such as different gates).An address is owned by a legal entity. Thus, exactly one legal entity is assigned to an address. An address can belong to a site. Thus, one or no site is assigned to an address. An address is uniquely identified by the BPNA. + LogisticAddressVerboseDto: + required: + - bpna + - confidenceCriteria + - createdAt + - identifiers + - isCatenaXMemberData + - physicalPostalAddress + - states + - updatedAt + type: object + properties: + bpna: + type: string + description: A BPNA represents and uniquely identifies an address, which can be the legal address of a legal entity, and/or the main address of a site, or any additional address of a legal entity or site (such as different gates). It is important to note that only the BPNL must be used to uniquely identify a legal entity. Even in the case that the BPNA represents the legal address of the legal entity, it shall not be used to uniquely identify the legal entity. + name: + type: string + description: The name of the address. This is not according to official registers but according to the name the sharing member chooses. + states: + type: array + description: The list of (temporary) states of the address. + items: + $ref: '#/components/schemas/AddressStateVerboseDto' + identifiers: + type: array + description: The list of identifiers of the address. + items: + $ref: '#/components/schemas/AddressIdentifierVerboseDto' + physicalPostalAddress: + $ref: '#/components/schemas/PhysicalPostalAddressVerboseDto' + alternativePostalAddress: + $ref: '#/components/schemas/AlternativePostalAddressVerboseDto' + bpnLegalEntity: + type: string + description: The BPNL of the legal entity owning the address. + bpnSite: + type: string + description: The BPNS of the site the address belongs to. + isCatenaXMemberData: + type: boolean + description: Indicates whether the address is owned and thus provided by a Catena-X Member. + createdAt: + type: string + description: The date when the data record has been created. + format: date-time + updatedAt: + type: string + description: The date when the data record has been last updated. + format: date-time + confidenceCriteria: + $ref: '#/components/schemas/ConfidenceCriteriaDto' + addressType: + type: string + description: Indicates the address type, the legal address to a legal entity or the main address to a site, an additional address, or both legal and site address.The site main address is where typically the main entrance or the reception is located, or where the mail is delivered to. + enum: + - LegalAndSiteMainAddress + - LegalAddress + - SiteMainAddress + - AdditionalAddress + description: In general, an address is a collection of information to describe a physical location, using a street name with a house number and/or a post office box as reference. In addition, an address consists of several postal attributes, such as country, region (state), county, township, city, district, or postal code, which help deliver mail.In Catena-X, an address is a type of business partner representing the legal address of a legal entity, and/or the main address of a site, or any additional address of a legal entity or site (such as different gates).An address is owned by a legal entity. Thus, exactly one legal entity is assigned to an address. An address can belong to a site. Thus, one or no site is assigned to an address. An address is uniquely identified by the BPNA. + PageDtoChangelogEntryVerboseDto: + required: + - content + - contentSize + - page + - totalElements + - totalPages + type: object + properties: + totalElements: + type: integer + description: Total number of all results in all pages + format: int64 + totalPages: + type: integer + description: Total number pages + format: int32 + page: + type: integer + description: Current page number + format: int32 + contentSize: + type: integer + description: Number of results in the page + format: int32 + content: + type: array + description: Collection of results in the page + items: + $ref: '#/components/schemas/ChangelogEntryVerboseDto' + description: Paginated collection of results + PageDtoCountrySubdivisionDto: + required: + - content + - contentSize + - page + - totalElements + - totalPages + type: object + properties: + totalElements: + type: integer + description: Total number of all results in all pages + format: int64 + totalPages: + type: integer + description: Total number pages + format: int32 + page: + type: integer + description: Current page number + format: int32 + contentSize: + type: integer + description: Number of results in the page + format: int32 + content: + type: array + description: Collection of results in the page + items: + $ref: '#/components/schemas/CountrySubdivisionDto' + description: Paginated collection of results + PageDtoCxMembershipDto: + required: + - content + - contentSize + - page + - totalElements + - totalPages + type: object + properties: + totalElements: + type: integer + description: Total number of all results in all pages + format: int64 + totalPages: + type: integer + description: Total number pages + format: int32 + page: + type: integer + description: Current page number + format: int32 + contentSize: + type: integer + description: Number of results in the page + format: int32 + content: + type: array + description: Collection of results in the page + items: + $ref: '#/components/schemas/CxMembershipDto' + description: Paginated collection of results + PageDtoIdentifierTypeDto: + required: + - content + - contentSize + - page + - totalElements + - totalPages + type: object + properties: + totalElements: + type: integer + description: Total number of all results in all pages + format: int64 + totalPages: + type: integer + description: Total number pages + format: int32 + page: + type: integer + description: Current page number format: int32 contentSize: type: integer @@ -4449,10 +5499,10 @@ components: type: array items: $ref: '#/components/schemas/ErrorInfoSiteCreateError' - entityCount: + errorCount: type: integer format: int32 - errorCount: + entityCount: type: integer format: int32 description: Holds information about successfully and failed entities after the creating/updating of several objects @@ -4495,10 +5545,10 @@ components: type: array items: $ref: '#/components/schemas/ErrorInfoSiteUpdateError' - entityCount: + errorCount: type: integer format: int32 - errorCount: + entityCount: type: integer format: int32 description: Holds information about successfully and failed entities after the creating/updating of several objects @@ -4953,6 +6003,7 @@ components: flows: clientCredentials: tokenUrl: http://localhost:8180/realms/CX-Central/protocol/openid-connect/token + scopes: {} authorizationCode: authorizationUrl: http://localhost:8180/realms/CX-Central/protocol/openid-connect/auth tokenUrl: http://localhost:8180/realms/CX-Central/protocol/openid-connect/token