diff --git a/src/java/ABTProductsPUTGenerator/bin/ABTProductsPUTGenerator.jar b/src/java/ABTProductsPUTGenerator/bin/ABTProductsPUTGenerator.jar index 2a3b03c..eb23d37 100644 Binary files a/src/java/ABTProductsPUTGenerator/bin/ABTProductsPUTGenerator.jar and b/src/java/ABTProductsPUTGenerator/bin/ABTProductsPUTGenerator.jar differ diff --git a/src/java/ABTProductsPUTGenerator/bin/input.json b/src/java/ABTProductsPUTGenerator/bin/input.json index 2873379..051b8a0 100644 --- a/src/java/ABTProductsPUTGenerator/bin/input.json +++ b/src/java/ABTProductsPUTGenerator/bin/input.json @@ -1,57 +1,54 @@ { - "productId": 38, - "parentProductId": null, - "productCode": "30901-WA", - "gboPackageTemplateId": "30901", + "productId": 151, + "fikoArticleNumber": null, + "parentProductId": 114, + "gboPackageTemplateId": "33629", "tapConnectProductCode": null, - "productGroupMetadata": null, - "productName": "HTM P1W Prolongatie-Test 90% Korting", - "productDescription": "Reis je regelmatig met HTM? Activeer dan HTM 90% Korting op je betaalpas of credit card en reis met korting!", + "productName": "HTM Regio Vrij - Voltarief - Losse Maand - HL62", + "productDescription": "Voor een vast bedrag onbeperkt reizen met EBS, HTM en RET in gebied HL62", "validityPeriod": { - "validityPeriodId": 148, - "fromInclusive": "2023-12-31T23:00:00.000+00:00", - "toInclusive": "2029-12-08T04:00:00.000+00:00" + "validityPeriodId": 262, + "fromInclusive": "2024-09-30T23:00:00.000+00:00", + "toInclusive": "2099-12-30T23:00:00.000+00:00" }, "productTranslations": [ { "language": "en", - "name": "HTM Prolongation-Test 90% Discount", - "description": "Are you a regular traveler? Activate HTM 90% discount on your EMV card!" + "name": "HTM Regio Free - Full Fare - 1 Month - HL62", + "description": "For a fixed amount unlimited travel with EBS, HTM and RET in region HL62" } ], "productOwner": { - "productOwnerId": 17, - "name": "Corneel Verstoep", - "organization": "HTM" + "productOwnerId": 19, + "name": "MRDH", + "organization": "MRDH" }, - "marketSegments": [ + "marketSegments": null, + "customerSegments": null, + "allowedGboAgeProfiles": [ { - "marketSegmentId": 1, - "name": "B2C" - } - ], - "customerSegments": [ - { - "customerSegmentId": 2, - "name": "Kind (4-11)" + "gboAgeProfileId": 1, + "name": "Baby/peuter (0 t/m 3 jaar)", + "ageFromInclusive": 0, + "ageToInclusive": 3 }, { - "customerSegmentId": 3, - "name": "Jongere (12-18)" + "gboAgeProfileId": 4, + "name": "Volwassene (19 t/m 64 jaar)", + "ageFromInclusive": 19, + "ageToInclusive": 64 }, { - "customerSegmentId": 4, - "name": "Volwassene (19-64)" - }, - { - "customerSegmentId": 5, - "name": "Oudere (65+)" + "gboAgeProfileId": 5, + "name": "Oudere (65 jaar of ouder)", + "ageFromInclusive": 65, + "ageToInclusive": 999 } ], "productCategory": { - "productCategoryId": 1, + "productCategoryId": 3, "isTravelProduct": true, - "name": "Kortingsabonnement" + "name": "Afgekocht reisrecht" }, "requiredCustomerLevel": { "requiredCustomerLevelId": 3, @@ -73,11 +70,24 @@ "customerDataItem": "emailAddress" }, { - "mandatoryCustomerDataItemId": 5, - "customerDataItem": "address" + "mandatoryCustomerDataItemId": 8, + "customerDataItem": "padBirthDate" + } + ], + "requiredGboPersonalAttributes": [ + { + "requiredGboPersonalAttributeId": 1, + "name": "NAME" + }, + { + "requiredGboPersonalAttributeId": 2, + "name": "BIRTHDATE" + }, + { + "requiredGboPersonalAttributeId": 3, + "name": "PHOTO" } ], - "requiredGboPersonalAttributes": null, "tokenTypes": [ { "tokenTypeId": 1, @@ -89,21 +99,21 @@ "name": "prepaid" }, "serviceOptions": null, - "validityDuration": "P1W", + "validityDuration": "P1M", "maxStartInFutureDuration": "P6W", - "isRenewable": true, - "sendInvoice": true, + "isRenewable": false, + "sendInvoice": false, "imageReference": "https://web.acc.cloud.htm.nl/media/leif2leu/htm-logo-mobile.svg", - "productPageUrl": "https://web.acc.cloud.htm.nl/webshop/htm-90-korting/", - "termsUrl": "https://web.acc.cloud.htm.nl/reisproducten/productvoorwaarden/htm-90-korting/", + "productPageUrl": "https://web.acc.cloud.htm.nl/webshop/htm-regio-vrij", + "termsUrl": "https://web.acc.cloud.htm.nl/reisproducten/productvoorwaarden/htm-regio-vrij/", "isSellableAtHtm": true, "needsSolvencyCheckConsumer": false, "needsSolvencyCheckBusiness": false, "sellingPeriods": [ { - "sellingPeriodId": 89, - "fromInclusive": "2024-09-30T23:00:00.000+00:00", - "toInclusive": "2029-12-01T23:00:00.000+00:00", + "sellingPeriodId": 214, + "fromInclusive": "2024-10-30T23:00:00.000+00:00", + "toInclusive": "2029-12-30T23:00:00.000+00:00", "salesTouchpoint": { "salesTouchpointId": 3, "name": "Website (Perplex)", @@ -126,18 +136,14 @@ "forbiddenPaymentMethods": null, "sellingPrices": [ { - "sellingPriceId": 82, - "amountExclTax": 92, - "amountInclTax": 100, - "fromInclusive": "2024-09-30T23:00:00.000+00:00", + "sellingPriceId": 195, + "taxCode": "V09", + "taxPercentage": 9.0000, + "amountExclTax": 13486, + "amountInclTax": 14700, + "fromInclusive": "2024-10-30T23:00:00.000+00:00", "toInclusive": "2029-12-01T23:00:00.000+00:00", - "internalPrice": 0.0000, - "taxMetadata": { - "taxMetadataId": "47C8972E-A730-4032-9BDA-AF0A5BCB2C85", - "taxCode": "V09", - "taxPercentageAmount": 9, - "description": "BTW VERKOOP LAAG 9%" - } + "internalPrice": 0.0000 } ] } @@ -145,10 +151,10 @@ "purchasePrices": null, "auditTrail": [ { - "auditTrailId": 162, + "auditTrailId": 475, "action": "insert", "user": "api", - "timestamp": "2024-11-25T08:39:36.793+00:00" + "timestamp": "2025-05-07T14:05:43.213+00:00" } ] } \ No newline at end of file diff --git a/src/java/ABTProductsPUTGenerator/bin/output.json b/src/java/ABTProductsPUTGenerator/bin/output.json index 070aba6..df4e037 100644 --- a/src/java/ABTProductsPUTGenerator/bin/output.json +++ b/src/java/ABTProductsPUTGenerator/bin/output.json @@ -1,57 +1,58 @@ { - "parentProductId" : null, - "productCode" : "30901-WA", - "gboPackageTemplateId" : "30901", + "fikoArticleNumber" : null, + "parentProductId" : 114, + "gboPackageTemplateId" : "33629", "tapConnectProductCode" : null, - "productGroupMetadata" : null, - "productName" : "HTM P1W Prolongatie-Test 90% Korting", - "productDescription" : "Reis je regelmatig met HTM? Activeer dan HTM 90% Korting op je betaalpas of credit card en reis met korting!", + "productName" : "HTM Regio Vrij - Voltarief - Losse Maand - HL62", + "productDescription" : "Voor een vast bedrag onbeperkt reizen met EBS, HTM en RET in gebied HL62", "validityPeriod" : { - "validityPeriodId" : 148, - "fromInclusive" : "2023-12-31T23:00:00.000+00:00", - "toInclusive" : "2029-12-08T04:00:00.000+00:00" + "validityPeriodId" : 262, + "fromInclusive" : "2024-09-30T23:00:00.000+00:00", + "toInclusive" : "2099-12-30T23:00:00.000+00:00" }, "productTranslations" : [ { "language" : "en", - "name" : "HTM Prolongation-Test 90% Discount", - "description" : "Are you a regular traveler? Activate HTM 90% discount on your EMV card!" + "name" : "HTM Regio Free - Full Fare - 1 Month - HL62", + "description" : "For a fixed amount unlimited travel with EBS, HTM and RET in region HL62" } ], - "productOwnerId" : 17, - "marketSegmentIds" : [ 1 ], - "customerSegmentIds" : [ 2, 3, 4, 5 ], - "productCategoryId" : 1, + "productOwnerId" : 19, + "marketSegmentIds" : null, + "customerSegmentIds" : null, + "allowedGboAgeProfileIds" : [ 1, 4, 5 ], + "productCategoryId" : 3, "requiredCustomerLevelId" : 3, "requiredProducts" : null, "incompatibleProducts" : null, - "mandatoryCustomerDataItemIds" : [ 1, 2, 4, 5 ], - "requiredGboPersonalAttributes" : null, + "mandatoryCustomerDataItemIds" : [ 1, 2, 4, 8 ], + "requiredGboPersonalAttributeIds" : [ 1, 2, 3 ], "tokenTypeIds" : [ 1 ], "paymentMomentId" : 1, - "serviceOptions" : null, - "validityDuration" : "P1W", + "serviceOptionIds" : null, + "validityDuration" : "P1M", "maxStartInFutureDuration" : "P6W", - "isRenewable" : true, - "sendInvoice" : true, + "isRenewable" : false, + "sendInvoice" : false, "imageReference" : "https://web.acc.cloud.htm.nl/media/leif2leu/htm-logo-mobile.svg", - "productPageUrl" : "https://web.acc.cloud.htm.nl/webshop/htm-90-korting/", - "termsUrl" : "https://web.acc.cloud.htm.nl/reisproducten/productvoorwaarden/htm-90-korting/", + "productPageUrl" : "https://web.acc.cloud.htm.nl/webshop/htm-regio-vrij", + "termsUrl" : "https://web.acc.cloud.htm.nl/reisproducten/productvoorwaarden/htm-regio-vrij/", "isSellableAtHtm" : true, "needsSolvencyCheckConsumer" : false, "needsSolvencyCheckBusiness" : false, "sellingPeriods" : [ { - "sellingPeriodId" : 89, - "fromInclusive" : "2024-09-30T23:00:00.000+00:00", - "toInclusive" : "2029-12-01T23:00:00.000+00:00", + "sellingPeriodId" : 214, + "fromInclusive" : "2024-10-30T23:00:00.000+00:00", + "toInclusive" : "2029-12-30T23:00:00.000+00:00", "salesTouchpointId" : 3, "forbiddenPaymentMethodIds" : null, "sellingPrices" : [ { - "sellingPriceId" : 82, - "amountExclTax" : 92, - "amountInclTax" : 100, - "fromInclusive" : "2024-09-30T23:00:00.000+00:00", + "sellingPriceId" : 195, + "taxCode" : "V09", + "taxPercentage" : 9.0, + "amountExclTax" : 13486, + "amountInclTax" : 14700, + "fromInclusive" : "2024-10-30T23:00:00.000+00:00", "toInclusive" : "2029-12-01T23:00:00.000+00:00", - "internalPrice" : 0.0, - "taxMetadataId" : "47C8972E-A730-4032-9BDA-AF0A5BCB2C85" + "internalPrice" : 0.0 } ] } ], "purchasePrices" : null diff --git a/src/java/ABTProductsPUTGenerator/src/main/java/nl/htm/ovpay/abt/ABTProductsPUTGenerator.java b/src/java/ABTProductsPUTGenerator/src/main/java/nl/htm/ovpay/abt/ABTProductsPUTGenerator.java index 3246d16..69426ac 100644 --- a/src/java/ABTProductsPUTGenerator/src/main/java/nl/htm/ovpay/abt/ABTProductsPUTGenerator.java +++ b/src/java/ABTProductsPUTGenerator/src/main/java/nl/htm/ovpay/abt/ABTProductsPUTGenerator.java @@ -100,8 +100,8 @@ public class ABTProductsPUTGenerator { ((ObjectNode)newJsonNode).putRawValue("customerSegmentIds", null); } case "allowedGboAgeProfiles" -> { - LOGGER.info("Rewriting null allowedGboAgeProfiles to allowedGboAgeProfilesIds..."); - ((ObjectNode)newJsonNode).putRawValue("allowedGboAgeProfilesIds", null); + LOGGER.info("Rewriting null allowedGboAgeProfiles to allowedGboAgeProfileIds..."); + ((ObjectNode)newJsonNode).putRawValue("allowedGboAgeProfileIds", null); } case "mandatoryCustomerDataItems" -> { LOGGER.info("Rewriting null mandatoryCustomerDataItems to mandatoryCustomerDataItemIds..."); @@ -283,7 +283,8 @@ public class ABTProductsPUTGenerator { ((ObjectNode)sellingPeriod).putRawValue("forbiddenPaymentMethodIds", null); } } - if (sellingPeriod.get("sellingPrices") != null) { + if (!sellingPeriod.get("sellingPrices").isNull()) { + LOGGER.info("Deep-copying sellingPrices..."); ArrayNode sellingPrices = ((ArrayNode)sellingPeriod.get("sellingPrices")).deepCopy(); ((ObjectNode)sellingPeriod).remove("sellingPrices"); if (!sellingPrices.isEmpty()) { @@ -299,8 +300,8 @@ public class ABTProductsPUTGenerator { } } case "purchasePrices" -> { - LOGGER.info("Rewriting taxMetadata in purchasePrices to taxMetadataId..."); - if (jsonField.getValue() != null) { + LOGGER.info("Deep-copying purchasePrices..."); + if (!jsonField.getValue().isNull()) { ArrayNode purchasePrices = ((ArrayNode)jsonField.getValue()).deepCopy(); ((ObjectNode)newJsonNode).putArray("purchasePrices").addAll(purchasePrices); } else { diff --git a/src/openapi/apim/TP-PAD.yaml b/src/openapi/apim/TP-PAD.yaml index fe2ae98..5c522d7 100644 --- a/src/openapi/apim/TP-PAD.yaml +++ b/src/openapi/apim/TP-PAD.yaml @@ -1,8 +1,8 @@ openapi: 3.0.1 info: - title: Personal Account Data (PAD) APIs for touchpoints + title: Personal Account Data (PAD) APIs for touchpoints and Service Engine description: |- - APIs for touchpoints to manage Personal Account Data (PAD) on OVpay tokens (xTATs).\ + APIs for touchpoints and Service Engine to manage Personal Account Data (PAD) on OVpay tokens (xTATs).\ These APIs connect directly to the PADP APIs in GBO APIM and are implemented in Logic Apps in the Integration Layer. version: '1.0' @@ -11,6 +11,8 @@ servers: tags: - name: Personal Data APIs for touchpoints description: Personal Data APIs for touchpoints, no Service Engine in between! + - name: Personal Data APIs for Service Engine + description: Personal Data APIs for Service Engine, not to be exposed to touchpoints! paths: /personal-data/{xtat}: post: @@ -230,8 +232,189 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorResponse' + /personal-data/{xtat}/administrative-data: + get: + tags: + - Personal Data APIs for Service Engine + summary: API 1211 - Get Administrative Data + description: Integration Layer utilizes PAD management V2 in GBO APIM (`/pad-management/v2/..`) + operationId: GetAdministrativeData + parameters: + - name: xtat + description: xTAT to get administrative data for + in: path + required: true + schema: + type: string + format: uuid + example: 'c3a6c0f2-3b6a-4b9a-9c5d-5d9c6b3a4c5d' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: "#/components/schemas/AdministrativeData" + examples: + Valid and complete PAD: + summary: Valid and complete PAD + value: + name: + inaccuracyFlag: false + inaccuracyFlagReason: null + inaccuracyFlagCounter: 0 + changeCounter: 0 + maxUpdatesVerificationCount: 1 + lastChangeDate: "2025-03-26T10:18:42.947" + isValidated: false + photo: + inaccuracyFlag: false + inaccuracyFlagReason: null + inaccuracyFlagCounter: 0 + changeCounter: 0 + maxUpdatesVerificationCount: 5 + lastChangeDate: "2025-03-26T10:18:42.947" + isValidated: false + birthdate: + inaccuracyFlag: false + inaccuracyFlagReason: null + inaccuracyFlagCounter: 0 + changeCounter: 0 + maxUpdatesVerificationCount: 3 + lastChangeDate: "2025-03-26T10:18:42.947" + isValidated: false + Partially filled PAD (no photo): + summary: Partially filled PAD (no photo) + value: + name: + inaccuracyFlag: false + inaccuracyFlagReason: null + inaccuracyFlagCounter: 0 + changeCounter: 0 + maxUpdatesVerificationCount: 1 + lastChangeDate: "2025-03-26T10:18:42.947" + isValidated: false + photo: null + birthdate: + inaccuracyFlag: false + inaccuracyFlagReason: null + inaccuracyFlagCounter: 0 + changeCounter: 0 + maxUpdatesVerificationCount: 3 + lastChangeDate: "2025-03-26T10:18:42.947" + isValidated: false + Flagged PAD: + summary: Flagged PAD + value: + name: + inaccuracyFlag: true + inaccuracyFlagReason: "Invalid name" + inaccuracyFlagCounter: 1 + changeCounter: 1 + maxUpdatesVerificationCount: 1 + lastChangeDate: "2025-03-26T10:18:42.947" + isValidated: false + photo: + inaccuracyFlag: true + inaccuracyFlagReason: "Invalid photo" + inaccuracyFlagCounter: 1 + changeCounter: 0 + maxUpdatesVerificationCount: 5 + lastChangeDate: "2025-03-26T10:18:42.947" + isValidated: false + birthdate: + inaccuracyFlag: true + inaccuracyFlagReason: "Invalid birthdate" + inaccuracyFlagCounter: 1 + changeCounter: 2 + maxUpdatesVerificationCount: 3 + lastChangeDate: "2025-03-26T10:18:42.947" + isValidated: false + "400": + description: Bad Request + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + examples: + Invalid UUID: + summary: Invalid UUID + value: + errors: + code: "0x03000103" + data: [ + "geen-uuid" + ] + message: "The provided scTat is not a valid UUID" + exceptionClassName: "PadpConstraintViolationException" + exceptionStackTrace: "not available because debug mode is turned off" + "404": + description: Not Found + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + examples: + No PAD found for xTAT: + summary: No PAD found for xTAT + value: + errors: + code: "0x03000105" + data: [] + message: "Transit account not found" + exceptionClassName: "PadpEntityNotFoundException" + exceptionStackTrace: "not available because debug mode is turned off" + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + examples: + Unknown xTAT: + summary: Unknown xTAT + value: + errors: + code: "0x00000001" + data: null + message: "400 : \"{\"errorMessage\":{\"referenceId\":\"076f0de4-df33-42a3-add0-def971ab6679\",\"message\":\"Unknown external transit account token.\"},\"businessExceptions\":[{\"code\":\"TM0207\",\"message\":\"Unknown external transit account token.\"}]}\"" + exceptionClassName: "BadRequest" + exceptionStackTrace: "not available because debug mode is turned off" components: schemas: + AdministrativeData: + type: object + properties: + name: + $ref: '#/components/schemas/AdministrativeDataElement' + photo: + $ref: '#/components/schemas/AdministrativeDataElement' + birthdate: + $ref: '#/components/schemas/AdministrativeDataElement' + additionalProperties: false + AdministrativeDataElement: + type: object + properties: + inaccuracyFlag: + type: boolean + inaccuracyFlagReason: + type: string + nullable: true + inaccuracyFlagCounter: + type: integer + format: int32 + changeCounter: + type: integer + format: int32 + maxUpdatesVerificationCount: + type: integer + format: int32 + lastChangeDate: + type: string + format: date-time + isValidated: + type: boolean + additionalProperties: false DecryptedData: type: object properties: