From 39e5042350a95125ffdbffc38d7a98a52eb2052a Mon Sep 17 00:00:00 2001 From: Max Martens Date: Thu, 5 Feb 2026 17:42:17 +0100 Subject: [PATCH] Added feature: bulk clearing (set to null) of a given product attribute for all products in a given product tree - actually applies the modified products via PUT API --- .../ABTProductsPUTGenerator/.idea/misc.xml | 2 +- .../bin/ABTProductsPUTGenerator.jar | Bin 4551842 -> 4557157 bytes .../ABTProductsPUTGenerator/bin/README.md | 15 +- src/java/ABTProductsPUTGenerator/pom.xml | 4 +- .../ovpay/abt/ABTProductsPUTGenerator.java | 55 +++ .../main/java/nl/htm/ovpay/abt/APIHelper.java | 89 +++++ .../htm/ovpay/abt/DummyX509TrustManager.java | 38 ++ .../src/main/resources/input.json | 374 +++++++++++------- 8 files changed, 428 insertions(+), 149 deletions(-) create mode 100644 src/java/ABTProductsPUTGenerator/src/main/java/nl/htm/ovpay/abt/APIHelper.java create mode 100644 src/java/ABTProductsPUTGenerator/src/main/java/nl/htm/ovpay/abt/DummyX509TrustManager.java diff --git a/src/java/ABTProductsPUTGenerator/.idea/misc.xml b/src/java/ABTProductsPUTGenerator/.idea/misc.xml index 7ace097..82dbec8 100644 --- a/src/java/ABTProductsPUTGenerator/.idea/misc.xml +++ b/src/java/ABTProductsPUTGenerator/.idea/misc.xml @@ -8,7 +8,7 @@ - + \ No newline at end of file diff --git a/src/java/ABTProductsPUTGenerator/bin/ABTProductsPUTGenerator.jar b/src/java/ABTProductsPUTGenerator/bin/ABTProductsPUTGenerator.jar index d36d6eca869e8b74f9036825b9a48150c0093f8b..2cb678fdbd8f847b0d29cd50f4287fb6ef82e9dc 100644 GIT binary patch delta 14758 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 R2H@s%AwYc3g@9l7e*iGnxy1kg delta 9449 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 ZiwRbXmP5hpN9#vp$wPoKUzUX4`yZ+e!*Kur diff --git a/src/java/ABTProductsPUTGenerator/bin/README.md b/src/java/ABTProductsPUTGenerator/bin/README.md index 3d0dad5..9a26306 100644 --- a/src/java/ABTProductsPUTGenerator/bin/README.md +++ b/src/java/ABTProductsPUTGenerator/bin/README.md @@ -1,7 +1,9 @@ # ABTProducts PUT request body generator Simple tool to quickly edit HTM products via ABTProducts REST API. -- Requires JRE 21 +- Requires JRE 17 + +## Generating a PUT output (that you need to supply to PUT API yourself): - Run via: `java -jar ABTProductsPUTGenerator.jar` - Specify custom input/output path via: `java -jar ABTProductsPUTGenerator.jar ` - Takes a ABTProducts GET response body in JSON format (product details) @@ -10,3 +12,14 @@ Simple tool to quickly edit HTM products via ABTProducts REST API. - `curl -X PUT -H 'Content-Type: application/json' {baseUrl}/abt/abtproducts/1.0/38 --data @output.json` - Default input path: /input.json - Default output path: /output.json (output is overwritten if it exists) + +## Bulk clearing (set to null) of a certain product attribute for all productIds in a product-tree (SE product reponse) +- Run via: `java -jar ABTProductsPUTGenerator.jar clearAttribute ` +- Takes a SE GET product tree response body or ABTProducts GET response body in JSON format +- Also needs the attribute to clear and the WSO2 environment and valid WSO2 bearer token for that environment +- Performs the following operations: + - Finds all productId's in the given product(tree) and for each productId found: + - GETs productdetails via ABTProducts API + - Converts it to PUT request body using the functionality in the previous section + - Replaces with `null` + - Actually sends the modified PUT request body to ABTProducts PUT API diff --git a/src/java/ABTProductsPUTGenerator/pom.xml b/src/java/ABTProductsPUTGenerator/pom.xml index 6c41c8c..0cdc759 100644 --- a/src/java/ABTProductsPUTGenerator/pom.xml +++ b/src/java/ABTProductsPUTGenerator/pom.xml @@ -58,8 +58,8 @@ org.apache.maven.plugins maven-compiler-plugin - 21 - 21 + 17 + 17 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 b2910d3..2e53f85 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 @@ -3,8 +3,11 @@ package nl.htm.ovpay.abt; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.Scanner; +import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -19,6 +22,15 @@ public class ABTProductsPUTGenerator { private static final Logger LOGGER = LoggerFactory.getLogger(ABTProductsPUTGenerator.class); public static void main(String[] args) throws Exception { + LOGGER.info("Starting ABTProductsPUTGenerator with arguments {}", Arrays.stream(args).toList()); + if (args.length > 0 && args[0].equalsIgnoreCase("clearAttribute")) { + clearAttribute(args); + } else { + generateOutput(args); + } + } + + private static void generateOutput(String[] args) throws Exception { if (args.length != 2) { LOGGER.info("To modify input/output path, use: java -jar ABTProductsPUTGenerator.jar "); } @@ -40,6 +52,49 @@ public class ABTProductsPUTGenerator { } } + private static void clearAttribute(String[] args) throws Exception { + if (args.length != 5) { + LOGGER.error("Incorrect input parameters!"); + LOGGER.error("To clear attribute, use: java -jar ABTProductsPUTGenerator.jar clearAttribute "); + return; + } + + var inputFile = args[1]; + var attributeToClear = args[2]; + var environment = args[3]; + var wso2BearerToken = args[4]; + + try (InputStream is = getInputStream(inputFile)) { + ObjectMapper mapper = new ObjectMapper(); + JsonNode jsonNode = mapper.readTree(is); + var productIds = jsonNode.findValues("productId").stream().filter(JsonNode::isValueNode).map(JsonNode::asText).toList(); + + LOGGER.info("Found productIds to process: {}", productIds); + LOGGER.warn("Are you SURE you want to set attribute \"{}\" for all these productIds on environment {} to NULL?", attributeToClear, environment); + LOGGER.warn("Type 'yes' to continue..."); + var input = new Scanner(System.in).nextLine(); + if (!input.equalsIgnoreCase("yes")) { + LOGGER.info("Aborting..."); + return; + } + + for (var productId : productIds) { + LOGGER.info("Getting product details for product {}...", productId); + var productJsonString = APIHelper.getProductDetails(environment, productId, wso2BearerToken); + var productJsonNode = mapper.readTree(productJsonString); + var putJsonNode = processJsonNode(productJsonNode); + LOGGER.info("Clearing attribute \"{}\" from product with productId {}...", attributeToClear, productId); + ((ObjectNode)putJsonNode).putRawValue(attributeToClear, null); + + LOGGER.info("PUT product details for product with productId {} with cleared attribute \"{}\"...", productId, attributeToClear); + LOGGER.info("PUT product details with JSON body: {}", putJsonNode.toPrettyString()); + APIHelper.putProductDetails(environment, productId, putJsonNode.toString(), wso2BearerToken); + } + + LOGGER.info("DONE clearing attribute \"{}\" for productIds {}!", attributeToClear, productIds); + } + } + private static InputStream getInputStream(String filePath) throws IOException { var externalResource = new File(filePath); if (externalResource.exists()) { diff --git a/src/java/ABTProductsPUTGenerator/src/main/java/nl/htm/ovpay/abt/APIHelper.java b/src/java/ABTProductsPUTGenerator/src/main/java/nl/htm/ovpay/abt/APIHelper.java new file mode 100644 index 0000000..f1b36a0 --- /dev/null +++ b/src/java/ABTProductsPUTGenerator/src/main/java/nl/htm/ovpay/abt/APIHelper.java @@ -0,0 +1,89 @@ +package nl.htm.ovpay.abt; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.util.HashMap; +import java.util.Map; +import java.util.StringJoiner; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class APIHelper { + + private static final Logger LOGGER = LoggerFactory.getLogger(APIHelper.class); + private static final String PRODUCT_DETAILS_URI = "https://services..api.htm.nl/abt/abtproducts/1.0/products/"; + + + public static String envToUriPart(String environment) { + return switch (environment) { + case "DEV" -> "dev"; + case "ACC" -> "acc"; + case "PRD" -> ""; + default -> throw new IllegalArgumentException("Invalid environment: " + environment); + }; + } + + public static String getProductDetails(String environment, String productId, String wso2BearerToken) throws Exception { + var envUriPart = envToUriPart(environment); + var getProductDetailsUri = PRODUCT_DETAILS_URI.replace("", envUriPart).replace("", productId); + + SSLContext sc = SSLContext.getInstance("SSL"); + sc.init(null, DummyX509TrustManager.getDummyArray(), new java.security.SecureRandom()); + HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); + + URL url = new URL(getProductDetailsUri); + URLConnection con = url.openConnection(); + HttpURLConnection http = (HttpURLConnection)con; + http.setRequestMethod("GET"); + http.setDoOutput(false); + http.setRequestProperty("Authorization", "Bearer " + wso2BearerToken); + http.connect(); + + try(InputStream is = http.getInputStream()) { + return new String(is.readAllBytes(), StandardCharsets.UTF_8); + } + } + + public static void putProductDetails(String environment, String productId, String jsonBody, String wso2BearerToken) throws Exception { + var envUriPart = envToUriPart(environment); + var putProductDetailsUri = PRODUCT_DETAILS_URI.replace("", envUriPart).replace("", productId); + + LOGGER.info("PUT product details to URI: {}", putProductDetailsUri); + + SSLContext sc = SSLContext.getInstance("SSL"); + sc.init(null, DummyX509TrustManager.getDummyArray(), new java.security.SecureRandom()); + HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); + + URL url = new URL(putProductDetailsUri); + URLConnection con = url.openConnection(); + HttpURLConnection http = (HttpURLConnection)con; + http.setRequestMethod("PUT"); + http.setDoOutput(true); + http.setRequestProperty("Authorization", "Bearer " + wso2BearerToken); + http.setRequestProperty("Content-Type", "application/json"); + + byte[] out = jsonBody.getBytes(StandardCharsets.UTF_8); + int length = out.length; + http.setFixedLengthStreamingMode(length); + http.connect(); + + try(OutputStream os = http.getOutputStream()) { + os.write(out); + } + + try(InputStream is = http.getInputStream()) { + LOGGER.info("Got response from PUT API: {}", new String(is.readAllBytes(), StandardCharsets.UTF_8)); + } + } +} diff --git a/src/java/ABTProductsPUTGenerator/src/main/java/nl/htm/ovpay/abt/DummyX509TrustManager.java b/src/java/ABTProductsPUTGenerator/src/main/java/nl/htm/ovpay/abt/DummyX509TrustManager.java new file mode 100644 index 0000000..205fe6c --- /dev/null +++ b/src/java/ABTProductsPUTGenerator/src/main/java/nl/htm/ovpay/abt/DummyX509TrustManager.java @@ -0,0 +1,38 @@ +package nl.htm.ovpay.abt; + +import java.security.cert.X509Certificate; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +public final class DummyX509TrustManager implements X509TrustManager { + + private static DummyX509TrustManager INSTANCE; + + private DummyX509TrustManager() { + // prevent instantiation + } + + public static DummyX509TrustManager getInstance() { + if (INSTANCE == null) { + INSTANCE = new DummyX509TrustManager(); + } + return INSTANCE; + } + + public static TrustManager[] getDummyArray() { + if (INSTANCE == null) { + INSTANCE = new DummyX509TrustManager(); + } + return new TrustManager[] { INSTANCE }; + } + + public X509Certificate[] getAcceptedIssuers() { + return null; + } + + public void checkClientTrusted(X509Certificate[] certs, String authType) { + } + + public void checkServerTrusted(X509Certificate[] certs, String authType) { + } +} diff --git a/src/java/ABTProductsPUTGenerator/src/main/resources/input.json b/src/java/ABTProductsPUTGenerator/src/main/resources/input.json index 376fe2d..85fc22f 100644 --- a/src/java/ABTProductsPUTGenerator/src/main/resources/input.json +++ b/src/java/ABTProductsPUTGenerator/src/main/resources/input.json @@ -1,23 +1,33 @@ { - "productId": 251, - "fikoArticleNumber": null, + "productId": 663, "parentProductId": null, - "gboPackageTemplateId": "30901", + "layerInfo": { + "layerInfoId": 7, + "choiceKey": "isRenewable", + "choiceLabel": "Kies voor een doorlopend abonnement of een enkele termijn", + "isCustomChoice": false + }, + "fikoArticleNumber": null, + "gboPackageTemplateId": "30001", "tapConnectProductCode": null, - "productName": "MaxTestPOST-21-okt-test-1 edited PUT", - "productDescription": "21-okt-test-1 edited PUT - reis met 90% korting gedurende de eerste F&F pilot!", - "validityPeriod": null, - "productTranslations": null, + "productName": "Test OVPAY-2306", + "productDescription": "Test OVPAY-2306 (sellingPeriods in kindje verwijderen en later opnieuw weer kunnen toevoegen)", + "validityPeriod": { + "validityPeriodId": 782, + "fromInclusive": "2025-12-31T23:00:00.000Z", + "toInclusive": "2026-03-30T22:00:00.000Z" + }, + "productTranslations": [], + "allowedGboAgeProfiles": [], "productOwner": { "productOwnerId": 1, - "name": "Corneel Verstoep", - "organization": "HTM" + "name": "Wie dit leest", + "organization": "... is een aap." }, - "marketSegments": null, - "customerSegments": null, - "allowedGboAgeProfiles": null, + "marketSegments": [], + "customerSegments": [], "productCategory": { - "productCategoryId": 9, + "productCategoryId": 1, "isTravelProduct": true, "name": "Kortingsabonnement" }, @@ -25,32 +35,10 @@ "requiredCustomerLevelId": 1, "name": "guest" }, - "requiredProducts": null, - "incompatibleProducts": null, - "mandatoryCustomerDataItems": [ - { - "mandatoryCustomerDataItemId": 4, - "customerDataItem": "emailAddress" - }, - { - "mandatoryCustomerDataItemId": 5, - "customerDataItem": "address" - } - ], - "requiredGboPersonalAttributes": [ - { - "requiredGboPersonalAttributeId": 1, - "name": "NAME" - }, - { - "requiredGboPersonalAttributeId": 2, - "name": "BIRTHDATE" - }, - { - "requiredGboPersonalAttributeId": 3, - "name": "PHOTO" - } - ], + "requiredProducts": [], + "incompatibleProducts": [], + "mandatoryCustomerDataItems": [], + "requiredGboPersonalAttributes": [], "tokenTypes": [ { "tokenTypeId": 1, @@ -61,72 +49,36 @@ "paymentMomentId": 1, "name": "prepaid" }, - "serviceOptions": null, - "validityDuration": "P7D", - "maxStartInFutureDuration": "P6W", - "isRenewable": false, + "serviceOptions": [ + { + "serviceOptionId": 4, + "action": "cancel_notAllowed", + "description": "Stopzetting is niet toegestaan (doorgaans in combinatie met refund_notAllowed)" + }, + { + "serviceOptionId": 10, + "action": "refund_notAllowed", + "description": "Terugbetaling niet toegestaan (doorgaans in combinatie met cancel_notAllowed)" + } + ], + "validityDuration": "P1W", + "maxStartInFutureDuration": "P1W", + "isRenewable": null, "sendInvoice": false, - "imageReference": "https://www.htm.nl/media/leif2leu/htm-logo-mobile.svg", - "productPageUrl": "https://www.htm.nl/nog-onbekende-product-pagina", - "termsUrl": "https://www.htm.nl/nog-onbekende-productvoorwaarden-pagina", + "imageReference": null, + "productPageUrl": null, + "termsUrl": null, "isSellableAtHtm": true, "needsSolvencyCheckConsumer": false, "needsSolvencyCheckBusiness": false, "sellingPeriods": [ { - "sellingPeriodId": 240, - "fromInclusive": "2024-09-06T00:00:00.000+00:00", - "toInclusive": "2024-12-29T23:59:59.000+00:00", + "sellingPeriodId": 1382, + "fromInclusive": "2025-12-31T23:00:00.000Z", + "toInclusive": "2026-03-30T22:00:00.000Z", "salesTouchpoint": { - "salesTouchpointId": 6, - "name": "Service-engine", - "isActive": true, - "retailer": { - "retailerId": 1000, - "name": "HTM intern beheer", - "street": "Koningin Julianaplein", - "number": 10, - "numberAddition": null, - "postalCode": "2595 AA", - "city": "Den Haag", - "country": "Nederland", - "emailAddress": "info@htm.nl", - "phoneNumber": "070 374 9002", - "taxId": null, - "imageReference": "https://www.htm.nl/typo3conf/ext/htm_template/Resources/Public/img/logo.svg" - } - }, - "forbiddenPaymentMethods": null, - "sellingPrices": [ - { - "sellingPriceId": 318, - "taxCode": "V21", - "taxPercentage": 21.0000, - "amountExclTax": 94, - "amountInclTax": 100, - "fromInclusive": "2024-09-06T00:00:00.000+00:00", - "toInclusive": "2024-12-18T23:59:59.000+00:00", - "internalPrice": 92.0000 - }, - { - "sellingPriceId": 319, - "taxCode": "V21", - "taxPercentage": 21.0000, - "amountExclTax": 98, - "amountInclTax": 102, - "fromInclusive": "2024-12-19T00:00:00.000+00:00", - "toInclusive": "2024-12-29T23:59:59.000+00:00", - "internalPrice": 0.0000 - } - ] - }, - { - "sellingPeriodId": 241, - "fromInclusive": "2024-09-06T00:00:00.000+00:00", - "toInclusive": "2024-12-29T23:59:59.000+00:00", - "salesTouchpoint": { - "salesTouchpointId": 5, - "name": "Servicewinkel (Team Incident Masters)", + "salesTouchpointId": 3, + "name": "Website", "isActive": true, "retailer": { "retailerId": 1001, @@ -139,64 +91,196 @@ "country": "Nederland", "emailAddress": "info@htm.nl", "phoneNumber": "070 374 9002", - "taxId": null, - "imageReference": "https://www.htm.nl/typo3conf/ext/htm_template/Resources/Public/img/logo.svg" + "taxId": 572309345923, + "imageReference": "https://www.htm.nl/media/leif2leu/htm-logo-mobile.svg" } }, - "forbiddenPaymentMethods": [ + "forbiddenPaymentMethods": [], + "sellingPrices": [] + } + ], + "purchasePrices": [], + "productVariants": [ + { + "productId": 664, + "parentProductId": 663, + "layerInfo": { + "layerInfoId": null, + "choiceKey": null, + "choiceLabel": null, + "isCustomChoice": false + }, + "fikoArticleNumber": null, + "gboPackageTemplateId": "30001", + "tapConnectProductCode": null, + "productName": "Losse week - Test OVPAY-2306", + "productDescription": "Test OVPAY-2306 (sellingPeriods in kindje verwijderen en later opnieuw weer kunnen toevoegen)", + "validityPeriod": { + "validityPeriodId": 783, + "fromInclusive": "2025-12-31T23:00:00.000Z", + "toInclusive": "2026-03-30T22:00:00.000Z" + }, + "productTranslations": [], + "allowedGboAgeProfiles": [], + "productOwner": { + "productOwnerId": 1, + "name": "Wie dit leest", + "organization": "... is een aap." + }, + "marketSegments": [], + "customerSegments": [], + "productCategory": { + "productCategoryId": 1, + "isTravelProduct": true, + "name": "Kortingsabonnement" + }, + "requiredCustomerLevel": { + "requiredCustomerLevelId": 1, + "name": "guest" + }, + "requiredProducts": [], + "incompatibleProducts": [], + "mandatoryCustomerDataItems": [], + "requiredGboPersonalAttributes": [], + "tokenTypes": [ { - "forbiddenPaymentMethodId": 2, - "name": "creditcard", - "issuer": "Visa" + "tokenTypeId": 1, + "name": "EMV" } ], - "sellingPrices": [ + "paymentMoment": { + "paymentMomentId": 1, + "name": "prepaid" + }, + "serviceOptions": [ { - "sellingPriceId": 320, - "taxCode": "V21", - "taxPercentage": 21.0000, - "amountExclTax": 94, - "amountInclTax": 100, - "fromInclusive": "2024-09-06T00:00:00.000+00:00", - "toInclusive": "2024-12-18T23:59:59.000+00:00", - "internalPrice": 92.0000 + "serviceOptionId": 4, + "action": "cancel_notAllowed", + "description": "Stopzetting is niet toegestaan (doorgaans in combinatie met refund_notAllowed)" }, { - "sellingPriceId": 321, - "taxCode": "V21", - "taxPercentage": 21.0000, - "amountExclTax": 98, - "amountInclTax": 102, - "fromInclusive": "2024-12-19T00:00:00.000+00:00", - "toInclusive": "2024-12-29T23:59:59.000+00:00", - "internalPrice": 0.0000 + "serviceOptionId": 10, + "action": "refund_notAllowed", + "description": "Terugbetaling niet toegestaan (doorgaans in combinatie met cancel_notAllowed)" } - ] - } - ], - "purchasePrices": [ - { - "purchasePriceId": 184, - "taxCode": "V21", - "taxPercentage": 21.0000, - "amountExclTax": 0, - "amountInclTax": 0, - "fromInclusive": "2024-09-01T00:00:00.000+00:00", - "toInclusive": "2024-12-31T23:59:59.000+00:00" - } - ], - "auditTrail": [ - { - "auditTrailId": 228, - "action": "update", - "user": "api", - "timestamp": "2024-10-21T09:00:30.410+00:00" + ], + "validityDuration": "P1W", + "maxStartInFutureDuration": "P1W", + "isRenewable": false, + "sendInvoice": false, + "imageReference": null, + "productPageUrl": null, + "termsUrl": null, + "isSellableAtHtm": true, + "needsSolvencyCheckConsumer": false, + "needsSolvencyCheckBusiness": false, + "sellingPeriods": [ + { + "sellingPeriodId": 1384, + "fromInclusive": "2025-12-31T23:00:00.000Z", + "toInclusive": "2026-03-30T22:00:00.000Z", + "salesTouchpoint": { + "salesTouchpointId": 3, + "name": "Website", + "isActive": true, + "retailer": { + "retailerId": 1001, + "name": "HTM externe touchpoints", + "street": "Koningin Julianaplein", + "number": 10, + "numberAddition": null, + "postalCode": "2595 AA", + "city": "Den Haag", + "country": "Nederland", + "emailAddress": "info@htm.nl", + "phoneNumber": "070 374 9002", + "taxId": 572309345923, + "imageReference": "https://www.htm.nl/media/leif2leu/htm-logo-mobile.svg" + } + }, + "forbiddenPaymentMethods": [], + "sellingPrices": [] + } + ], + "purchasePrices": [], + "productVariants": [] }, { - "auditTrailId": 227, - "action": "insert", - "user": "api", - "timestamp": "2024-10-21T08:58:39.237+00:00" + "productId": 665, + "parentProductId": 663, + "layerInfo": { + "layerInfoId": null, + "choiceKey": null, + "choiceLabel": null, + "isCustomChoice": false + }, + "fikoArticleNumber": null, + "gboPackageTemplateId": "30001", + "tapConnectProductCode": null, + "productName": "Doorlopend - Test OVPAY-2306", + "productDescription": "Test OVPAY-2306 (sellingPeriods in kindje verwijderen en later opnieuw weer kunnen toevoegen)", + "validityPeriod": { + "validityPeriodId": 784, + "fromInclusive": "2025-12-31T23:00:00.000Z", + "toInclusive": "2026-03-30T22:00:00.000Z" + }, + "productTranslations": [], + "allowedGboAgeProfiles": [], + "productOwner": { + "productOwnerId": 1, + "name": "Wie dit leest", + "organization": "... is een aap." + }, + "marketSegments": [], + "customerSegments": [], + "productCategory": { + "productCategoryId": 1, + "isTravelProduct": true, + "name": "Kortingsabonnement" + }, + "requiredCustomerLevel": { + "requiredCustomerLevelId": 1, + "name": "guest" + }, + "requiredProducts": [], + "incompatibleProducts": [], + "mandatoryCustomerDataItems": [], + "requiredGboPersonalAttributes": [], + "tokenTypes": [ + { + "tokenTypeId": 1, + "name": "EMV" + } + ], + "paymentMoment": { + "paymentMomentId": 1, + "name": "prepaid" + }, + "serviceOptions": [ + { + "serviceOptionId": 4, + "action": "cancel_notAllowed", + "description": "Stopzetting is niet toegestaan (doorgaans in combinatie met refund_notAllowed)" + }, + { + "serviceOptionId": 10, + "action": "refund_notAllowed", + "description": "Terugbetaling niet toegestaan (doorgaans in combinatie met cancel_notAllowed)" + } + ], + "validityDuration": "P1W", + "maxStartInFutureDuration": "P1W", + "isRenewable": true, + "sendInvoice": false, + "imageReference": null, + "productPageUrl": null, + "termsUrl": null, + "isSellableAtHtm": true, + "needsSolvencyCheckConsumer": false, + "needsSolvencyCheckBusiness": false, + "sellingPeriods": [], + "purchasePrices": [], + "productVariants": [] } ] } \ No newline at end of file