Skip to content

Commit

Permalink
Merge pull request #1192 from Adyen/feature/SFI-954-events-logging
Browse files Browse the repository at this point in the history
saving analytics events as custom objects
  • Loading branch information
shanikantsingh authored Oct 18, 2024
2 parents ea48bc7 + e6614b6 commit 9360b8a
Show file tree
Hide file tree
Showing 10 changed files with 262 additions and 12 deletions.
4 changes: 4 additions & 0 deletions jest/__mocks__/dw/object/CustomObjectMgr.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export const createCustomObject = jest.fn(() => ({
custom: {},
}));
export const remove = jest.fn();
29 changes: 25 additions & 4 deletions jest/sfccPathSetup.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -464,3 +464,24 @@ 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 },
);

jest.mock(
'*/cartridge/adyen/analytics/analyticsEvents',
() =>
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 },
);
127 changes: 127 additions & 0 deletions metadata/site_import/meta/custom-objecttype-definitions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -198,4 +198,131 @@
</attribute-group>
</group-definitions>
</custom-type>
<custom-type type-id="AdyenAnalyticsEvents">
<display-name xml:lang="x-default">Adyen Analytics Events</display-name>
<description xml:lang="x-default">Adyen Analytics Event Queue</description>
<staging-mode>no-staging</staging-mode>
<storage-scope>site</storage-scope>
<retention-days>3</retention-days>
<key-definition attribute-id="eventId">
<type>string</type>
<min-length>0</min-length>
</key-definition>
<attribute-definitions>
<attribute-definition attribute-id="referenceId">
<display-name xml:lang="x-default">ReferenceId</display-name>
<type>string</type>
<localizable-flag>false</localizable-flag>
<mandatory-flag>false</mandatory-flag>
<externally-managed-flag>false</externally-managed-flag>
<min-length>0</min-length>
</attribute-definition>
<attribute-definition attribute-id="eventCode">
<display-name xml:lang="x-default">Event Code</display-name>
<type>enum-of-string</type>
<localizable-flag>false</localizable-flag>
<mandatory-flag>false</mandatory-flag>
<externally-managed-flag>false</externally-managed-flag>
<value-definitions>
<value-definition>
<display xml:lang="x-default">ERROR</display>
<value>error</value>
</value-definition>
<value-definition default="true">
<display xml:lang="x-default">INFO</display>
<value>info</value>
</value-definition>
<value-definition>
<display xml:lang="x-default">LOG</display>
<value>log</value>
</value-definition>
</value-definitions>
</attribute-definition>
<attribute-definition attribute-id="processingStatus">
<display-name xml:lang="x-default">Event Processing Status</display-name>
<type>enum-of-string</type>
<localizable-flag>false</localizable-flag>
<mandatory-flag>false</mandatory-flag>
<externally-managed-flag>false</externally-managed-flag>
<value-definitions>
<value-definition default="true">
<display xml:lang="x-default">NOT PROCESSED</display>
<value>NOT_PROCESSED</value>
</value-definition>
<value-definition>
<display xml:lang="x-default">PROCESSED</display>
<value>PROCESSED</value>
</value-definition>
<value-definition>
<display xml:lang="x-default">SKIPPED</display>
<value>SKIPPED</value>
</value-definition>
</value-definitions>
</attribute-definition>
<attribute-definition attribute-id="eventSource">
<display-name xml:lang="x-default">Event Source</display-name>
<type>string</type>
<localizable-flag>false</localizable-flag>
<mandatory-flag>false</mandatory-flag>
<externally-managed-flag>false</externally-managed-flag>
<min-length>0</min-length>
</attribute-definition>
<attribute-definition attribute-id="eventType">
<display-name xml:lang="x-default">Event Type</display-name>
<type>enum-of-string</type>
<localizable-flag>false</localizable-flag>
<mandatory-flag>true</mandatory-flag>
<externally-managed-flag>false</externally-managed-flag>
<value-definitions>
<value-definition>
<display xml:lang="x-default">START</display>
<value>START</value>
</value-definition>
<value-definition>
<display xml:lang="x-default">END</display>
<value>END</value>
</value-definition>
</value-definitions>
</attribute-definition>
<attribute-definition attribute-id="eventStatus">
<display-name xml:lang="x-default">Event Status</display-name>
<type>enum-of-string</type>
<localizable-flag>false</localizable-flag>
<mandatory-flag>true</mandatory-flag>
<externally-managed-flag>false</externally-managed-flag>
<value-definitions>
<value-definition>
<display xml:lang="x-default">EXPECTED</display>
<value>EXPECTED</value>
</value-definition>
<value-definition>
<display xml:lang="x-default">UNEXPECTED</display>
<value>UNEXPECTED</value>
</value-definition>
</value-definitions>
</attribute-definition>
<attribute-definition attribute-id="message">
<display-name xml:lang="x-default">Message</display-name>
<type>string</type>
<localizable-flag>false</localizable-flag>
<mandatory-flag>false</mandatory-flag>
<externally-managed-flag>false</externally-managed-flag>
<min-length>0</min-length>
</attribute-definition>
</attribute-definitions>
<group-definitions>
<attribute-group group-id="analyticsEvent">
<display-name xml:lang="x-default">analyticsEvent</display-name>
<attribute attribute-id="eventCode"/>
<attribute attribute-id="eventStatus"/>
<attribute attribute-id="creationDate" system="true"/>
<attribute attribute-id="eventType"/>
<attribute attribute-id="referenceId"/>
<attribute attribute-id="message"/>
<attribute attribute-id="eventSource"/>
<attribute attribute-id="processingStatus"/>
<attribute attribute-id="lastModified" system="true"/>
</attribute-group>
</group-definitions>
</custom-type>
</metadata>
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
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,
eventSource,
eventType,
eventStatus,
eventCode,
) {
Transaction.wrap(() => {
const uuid = UUIDUtils.createUUID();
const customObj = CustomObjectMgr.createCustomObject(
constants.analyticsEventObjectId,
uuid,
);
customObj.custom.referenceId = referenceId;
customObj.custom.eventSource = eventSource;
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,
};
Original file line number Diff line number Diff line change
@@ -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',
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 };
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down Expand Up @@ -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());
},
};
Expand Down

0 comments on commit 9360b8a

Please sign in to comment.