From 2ea91d90c243d18c7aab65de1c6fa6689dd0c94e Mon Sep 17 00:00:00 2001 From: shani Date: Tue, 15 Oct 2024 13:32:53 +0200 Subject: [PATCH 1/5] feat(SFI-954): analytics event logging --- .../meta/custom-objecttype-definitions.xml | 113 ++++++++++++++++++ .../adyen_checkout/checkoutConfiguration.js | 10 +- .../adyen_checkout/renderGiftcardComponent.js | 5 +- .../adyen/analytics/analyticsEvents.js | 50 ++++++++ .../cartridge/adyen/analytics/constants.js | 21 ++++ 5 files changed, 193 insertions(+), 6 deletions(-) create mode 100644 src/cartridges/int_adyen_SFRA/cartridge/adyen/analytics/analyticsEvents.js create mode 100644 src/cartridges/int_adyen_SFRA/cartridge/adyen/analytics/constants.js diff --git a/metadata/site_import/meta/custom-objecttype-definitions.xml b/metadata/site_import/meta/custom-objecttype-definitions.xml index e5badcbd5..ebcd979a4 100644 --- a/metadata/site_import/meta/custom-objecttype-definitions.xml +++ b/metadata/site_import/meta/custom-objecttype-definitions.xml @@ -198,4 +198,117 @@ + + Adyen Analytics Events + Adyen Analytics Event Queue + no-staging + site + 3 + + string + 0 + + + + ReferenceId + string + false + false + false + 0 + + + Event Code + enum-of-string + false + false + false + + + ERROR + error + + + INFO + info + + + LOG + log + + + + + Event Processing Status + enum-of-string + false + false + false + + + NOT PROCESSED + NOT_PROCESSED + + + PROCESSED + PROCESSED + + + SKIPPED + SKIPPED + + + + + Event Source + string + false + false + false + 0 + + + Event Type + enum-of-string + false + true + false + + + START + START + + + END + END + + + + + Event Status + enum-of-string + false + true + false + + + EXPECTED + EXPECTED + + + UNEXPECTED + UNEXPECTED + + + + + Message + string + false + false + false + 0 + + + diff --git a/src/cartridges/app_adyen_SFRA/cartridge/client/default/js/adyen_checkout/checkoutConfiguration.js b/src/cartridges/app_adyen_SFRA/cartridge/client/default/js/adyen_checkout/checkoutConfiguration.js index d2c968fcf..0f428d395 100644 --- a/src/cartridges/app_adyen_SFRA/cartridge/client/default/js/adyen_checkout/checkoutConfiguration.js +++ b/src/cartridges/app_adyen_SFRA/cartridge/client/default/js/adyen_checkout/checkoutConfiguration.js @@ -192,8 +192,9 @@ function getGiftCardConfig() { async: false, success: (data) => { giftcardBalance = data.balance; - document.querySelector('button[value="submit-payment"]').disabled = - false; + document.querySelector( + 'button[value="submit-payment"]', + ).disabled = false; if (data.resultCode === constants.SUCCESS) { const { giftCardsInfoMessageContainer, @@ -219,8 +220,9 @@ function getGiftCardConfig() { initialPartialObject.totalDiscountedAmount; }); - document.querySelector('button[value="submit-payment"]').disabled = - true; + document.querySelector( + 'button[value="submit-payment"]', + ).disabled = true; giftCardsInfoMessageContainer.innerHTML = ''; giftCardsInfoMessageContainer.classList.remove( 'gift-cards-info-message-container', diff --git a/src/cartridges/app_adyen_SFRA/cartridge/client/default/js/adyen_checkout/renderGiftcardComponent.js b/src/cartridges/app_adyen_SFRA/cartridge/client/default/js/adyen_checkout/renderGiftcardComponent.js index e2f73a19b..dc16d6139 100644 --- a/src/cartridges/app_adyen_SFRA/cartridge/client/default/js/adyen_checkout/renderGiftcardComponent.js +++ b/src/cartridges/app_adyen_SFRA/cartridge/client/default/js/adyen_checkout/renderGiftcardComponent.js @@ -98,8 +98,9 @@ function removeGiftCards() { giftCardsInfoMessageContainer.classList.remove( 'gift-cards-info-message-container', ); - document.querySelector('button[value="submit-payment"]').disabled = - false; + document.querySelector( + 'button[value="submit-payment"]', + ).disabled = false; if (res.resultCode === constants.RECEIVED) { document diff --git a/src/cartridges/int_adyen_SFRA/cartridge/adyen/analytics/analyticsEvents.js b/src/cartridges/int_adyen_SFRA/cartridge/adyen/analytics/analyticsEvents.js new file mode 100644 index 000000000..c10d25502 --- /dev/null +++ b/src/cartridges/int_adyen_SFRA/cartridge/adyen/analytics/analyticsEvents.js @@ -0,0 +1,50 @@ +const CustomObjectMgr = require('dw/object/CustomObjectMgr'); +const UUIDUtils = require('dw/util/UUIDUtils'); +const Transaction = require('dw/system/Transaction'); +const constants = require('./constants'); + +function createAnalyticsEvent(referenceId, eventType, eventStatus, eventCode) { + Transaction.wrap(() => { + const uuid = UUIDUtils.createUUID(); + const customObj = CustomObjectMgr.createCustomObject( + constants.analyticsEventObjectId, + uuid, + ); + customObj.custom.referenceId = referenceId; + customObj.custom.eventType = eventType; + customObj.custom.eventStatus = eventStatus; + customObj.custom.eventCode = eventCode; + }); +} + +function deleteAnalyticsEvent(keyValue) { + Transaction.wrap(() => { + const customObj = CustomObjectMgr.getCustomObject( + constants.analyticsEventObjectId, + keyValue, + ); + if (customObj) { + CustomObjectMgr.remove(customObj); + } + }); +} + +function updateAnalyticsEvent(keyValue, attributes) { + Transaction.wrap(() => { + const customObj = CustomObjectMgr.getCustomObject( + constants.analyticsEventObjectId, + keyValue, + ); + Object.entries(attributes).forEach(([key, value]) => { + if (Object.hasOwn(customObj.custom, key)) { + customObj.custom[key] = value; + } + }); + }); +} + +module.exports = { + createAnalyticsEvent, + deleteAnalyticsEvent, + updateAnalyticsEvent, +}; diff --git a/src/cartridges/int_adyen_SFRA/cartridge/adyen/analytics/constants.js b/src/cartridges/int_adyen_SFRA/cartridge/adyen/analytics/constants.js new file mode 100644 index 000000000..64142b308 --- /dev/null +++ b/src/cartridges/int_adyen_SFRA/cartridge/adyen/analytics/constants.js @@ -0,0 +1,21 @@ +module.exports = { + analyticsEventObjectId: 'AdyenAnalyticsEvents', + eventType: { + START: 'START', + END: 'END', + }, + eventStatus: { + EXPECTED: 'EXPECTED', + UNEXPECTED: 'UNEXPECTED', + }, + eventCode: { + ERROR: 'error', + INFO: 'info', + LOG: 'log', + }, + processingStatus: { + NOT_PROCESSED: 'NOT_PROCESSED', + PROCESSED: 'PROCESSED', + SKIPPED: 'SKIPPED', + }, +}; From bc53b8abce0c8503848f16d86ce9841d576ab2d7 Mon Sep 17 00:00:00 2001 From: shani Date: Thu, 17 Oct 2024 09:48:36 +0200 Subject: [PATCH 2/5] feat(SFI-954): analytics event logging --- .../meta/custom-objecttype-definitions.xml | 14 ++++++++++++++ .../adyen/analytics/analyticsEvents.js | 9 ++++++++- .../{scripts => }/analytics/analyticsService.js | 0 .../scripts/payments/adyenGetPaymentMethods.js | 17 ++++++++++++++++- .../cartridge/adyen/utils/adyenHelper.js | 4 +++- 5 files changed, 41 insertions(+), 3 deletions(-) rename src/cartridges/int_adyen_SFRA/cartridge/adyen/{scripts => }/analytics/analyticsService.js (100%) diff --git a/metadata/site_import/meta/custom-objecttype-definitions.xml b/metadata/site_import/meta/custom-objecttype-definitions.xml index ebcd979a4..4b32cc96c 100644 --- a/metadata/site_import/meta/custom-objecttype-definitions.xml +++ b/metadata/site_import/meta/custom-objecttype-definitions.xml @@ -310,5 +310,19 @@ 0 + + + analyticsEvent + + + + + + + + + + + diff --git a/src/cartridges/int_adyen_SFRA/cartridge/adyen/analytics/analyticsEvents.js b/src/cartridges/int_adyen_SFRA/cartridge/adyen/analytics/analyticsEvents.js index c10d25502..9a613d530 100644 --- a/src/cartridges/int_adyen_SFRA/cartridge/adyen/analytics/analyticsEvents.js +++ b/src/cartridges/int_adyen_SFRA/cartridge/adyen/analytics/analyticsEvents.js @@ -3,7 +3,13 @@ const UUIDUtils = require('dw/util/UUIDUtils'); const Transaction = require('dw/system/Transaction'); const constants = require('./constants'); -function createAnalyticsEvent(referenceId, eventType, eventStatus, eventCode) { +function createAnalyticsEvent( + referenceId, + eventSource, + eventType, + eventStatus, + eventCode, +) { Transaction.wrap(() => { const uuid = UUIDUtils.createUUID(); const customObj = CustomObjectMgr.createCustomObject( @@ -11,6 +17,7 @@ function createAnalyticsEvent(referenceId, eventType, eventStatus, eventCode) { uuid, ); customObj.custom.referenceId = referenceId; + customObj.custom.eventSource = eventSource; customObj.custom.eventType = eventType; customObj.custom.eventStatus = eventStatus; customObj.custom.eventCode = eventCode; diff --git a/src/cartridges/int_adyen_SFRA/cartridge/adyen/scripts/analytics/analyticsService.js b/src/cartridges/int_adyen_SFRA/cartridge/adyen/analytics/analyticsService.js similarity index 100% rename from src/cartridges/int_adyen_SFRA/cartridge/adyen/scripts/analytics/analyticsService.js rename to src/cartridges/int_adyen_SFRA/cartridge/adyen/analytics/analyticsService.js diff --git a/src/cartridges/int_adyen_SFRA/cartridge/adyen/scripts/payments/adyenGetPaymentMethods.js b/src/cartridges/int_adyen_SFRA/cartridge/adyen/scripts/payments/adyenGetPaymentMethods.js index cbb857ad7..17cbf7cd5 100644 --- a/src/cartridges/int_adyen_SFRA/cartridge/adyen/scripts/payments/adyenGetPaymentMethods.js +++ b/src/cartridges/int_adyen_SFRA/cartridge/adyen/scripts/payments/adyenGetPaymentMethods.js @@ -25,13 +25,21 @@ const AdyenConfigs = require('*/cartridge/adyen/utils/adyenConfigs'); const constants = require('*/cartridge/adyen/config/constants'); const blockedPayments = require('*/cartridge/adyen/config/blockedPaymentMethods.json'); const AdyenLogs = require('*/cartridge/adyen/logs/adyenCustomLogs'); +const analyticsEvent = require('*/cartridge/adyen/analytics/analyticsEvents'); +const analyticsConstants = require('*/cartridge/adyen/analytics/constants'); // eslint-disable-next-line complexity function getMethods(basket, customer, countryCode) { try { let paymentAmount; let currencyCode; - + analyticsEvent.createAnalyticsEvent( + session.sessionID, + constants.SERVICE.CHECKOUTPAYMENTMETHODS, + analyticsConstants.eventType.START, + analyticsConstants.eventStatus.EXPECTED, + analyticsConstants.eventCode.INFO, + ); // paymentMethods call from checkout if (basket) { currencyCode = basket.currencyCode; @@ -81,6 +89,13 @@ function getMethods(basket, customer, countryCode) { paymentMethodsRequest, ); } catch (error) { + analyticsEvent.createAnalyticsEvent( + session.sessionID, + constants.SERVICE.CHECKOUTPAYMENTMETHODS, + analyticsConstants.eventType.END, + analyticsConstants.eventStatus.UNEXPECTED, + analyticsConstants.eventCode.INFO, + ); AdyenLogs.fatal_log('/paymentMethods call failed', error); return { error: true }; } diff --git a/src/cartridges/int_adyen_SFRA/cartridge/adyen/utils/adyenHelper.js b/src/cartridges/int_adyen_SFRA/cartridge/adyen/utils/adyenHelper.js index fd8a2d25e..790a75bf9 100644 --- a/src/cartridges/int_adyen_SFRA/cartridge/adyen/utils/adyenHelper.js +++ b/src/cartridges/int_adyen_SFRA/cartridge/adyen/utils/adyenHelper.js @@ -38,6 +38,8 @@ const collections = require('*/cartridge/scripts/util/collections'); const constants = require('*/cartridge/adyen/config/constants'); const AdyenConfigs = require('*/cartridge/adyen/utils/adyenConfigs'); const AdyenLogs = require('*/cartridge/adyen/logs/adyenCustomLogs'); +const analyticsEvent = require('*/cartridge/adyen/analytics/analyticsEvents'); +const analyticsConstants = require('*/cartridge/adyen/analytics/constants'); /* eslint no-var: off */ let adyenHelperObj = { @@ -973,7 +975,7 @@ let adyenHelperObj = { if (!resultObject || !resultObject.getText()) { throw new Error(`No correct response from ${serviceType} service call`); } - + analyticsEvent.createAnalyticsEvent(session.sessionID, serviceType, analyticsConstants.eventType.END, analyticsConstants.eventStatus.EXPECTED, analyticsConstants.eventCode.INFO); return JSON.parse(resultObject.getText()); }, }; From 380e607586e77637160f7ab7dfde81002fc115e1 Mon Sep 17 00:00:00 2001 From: shani Date: Thu, 17 Oct 2024 09:56:15 +0200 Subject: [PATCH 3/5] chore(SFI-954): add mocks --- jest/sfccPathSetup.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/jest/sfccPathSetup.js b/jest/sfccPathSetup.js index 9ddc8e915..420c6d53b 100644 --- a/jest/sfccPathSetup.js +++ b/jest/sfccPathSetup.js @@ -71,10 +71,10 @@ jest.mock( ); jest.mock( - '*/cartridge/models/shipping/shippingMethod', - () => require('../cartridge/models/shipping/shippingMethod'), - { virtual: true }, - ); + '*/cartridge/models/shipping/shippingMethod', + () => require('../cartridge/models/shipping/shippingMethod'), + { virtual: true }, +); jest.mock( '*/cartridge/adyen/scripts/partialPayments/partialPaymentsOrder', @@ -464,3 +464,10 @@ jest.mock( require('../src/cartridges/int_adyen_SFRA/cartridge/adyen/utils/giftCardsHelper'), { virtual: true }, ); + +jest.mock( + '*/cartridge/adyen/analytics/analyticsService', + () => + require('../src/cartridges/int_adyen_SFRA/cartridge/adyen/analytics/analyticsService'), + { virtual: true }, +); From 62952bf0569b8ecb98775dad31f21ba5dc22e2c4 Mon Sep 17 00:00:00 2001 From: shani Date: Thu, 17 Oct 2024 09:58:31 +0200 Subject: [PATCH 4/5] chore(SFI-954): add mocks --- jest/sfccPathSetup.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/jest/sfccPathSetup.js b/jest/sfccPathSetup.js index 420c6d53b..750370e46 100644 --- a/jest/sfccPathSetup.js +++ b/jest/sfccPathSetup.js @@ -471,3 +471,10 @@ jest.mock( require('../src/cartridges/int_adyen_SFRA/cartridge/adyen/analytics/analyticsService'), { virtual: true }, ); + +jest.mock( + '*/cartridge/adyen/analytics/analyticsEvents', + () => + require('../src/cartridges/int_adyen_SFRA/cartridge/adyen/analytics/analyticsEvents'), + { virtual: true }, +); From e6614b6fc8be45c4326db2d5fd9ee66c7fa8db70 Mon Sep 17 00:00:00 2001 From: shani Date: Thu, 17 Oct 2024 10:11:27 +0200 Subject: [PATCH 5/5] chore(SFI-954): add mocks --- jest/__mocks__/dw/object/CustomObjectMgr.js | 4 ++++ jest/sfccPathSetup.js | 7 +++++++ 2 files changed, 11 insertions(+) create mode 100644 jest/__mocks__/dw/object/CustomObjectMgr.js diff --git a/jest/__mocks__/dw/object/CustomObjectMgr.js b/jest/__mocks__/dw/object/CustomObjectMgr.js new file mode 100644 index 000000000..0fef7af55 --- /dev/null +++ b/jest/__mocks__/dw/object/CustomObjectMgr.js @@ -0,0 +1,4 @@ +export const createCustomObject = jest.fn(() => ({ + custom: {}, +})); +export const remove = jest.fn(); diff --git a/jest/sfccPathSetup.js b/jest/sfccPathSetup.js index 750370e46..082d63b87 100644 --- a/jest/sfccPathSetup.js +++ b/jest/sfccPathSetup.js @@ -478,3 +478,10 @@ jest.mock( require('../src/cartridges/int_adyen_SFRA/cartridge/adyen/analytics/analyticsEvents'), { virtual: true }, ); + +jest.mock( + '*/cartridge/adyen/analytics/constants', + () => + require('../src/cartridges/int_adyen_SFRA/cartridge/adyen/analytics/constants'), + { virtual: true }, +);