-
Notifications
You must be signed in to change notification settings - Fork 113
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: onboard new destination rakuten_advertising
- Loading branch information
1 parent
db2c170
commit a42bef3
Showing
9 changed files
with
1,068 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
const { getMappingConfig } = require('../../../../v0/util'); | ||
|
||
const ConfigCategories = { | ||
TRACK: { | ||
type: 'track', | ||
name: 'propertiesMapping', | ||
}, | ||
}; | ||
const mappingConfig = getMappingConfig(ConfigCategories, __dirname); | ||
// Following contains the keys at item level mapping where key can be considered as destkey and value can be considered as sourcekey | ||
const productProperties = { | ||
skulist: 'sku', | ||
qlist: 'quantity', | ||
namelist: 'name', | ||
brandlist: 'brand', | ||
couponlist: 'coupon', | ||
catidlist: 'categoryId', | ||
catlist: 'category', | ||
disamtlist: 'discountAmount', | ||
distypelist: 'discountType', | ||
isclearancelist: 'isClearance', | ||
ismarketplacelist: 'isMarketPlace', | ||
issalelist: 'isSale', | ||
itmstatuslist: 'itmStatus', | ||
marginlist: 'margin', | ||
markdownlist: 'markdown', | ||
shipidlist: 'shipId', | ||
shipbylist: 'shipBy', | ||
taxexemptlist: 'taxExempt', | ||
sequencelist: 'sequence', | ||
}; | ||
module.exports = { ConfigCategories, mappingConfig, productProperties }; |
101 changes: 101 additions & 0 deletions
101
src/cdk/v2/destinations/rakuten/data/propertiesMapping.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
[ | ||
{ | ||
"sourceKeys": "properties.orderId", | ||
"required": true, | ||
"destKey": "ord" | ||
}, | ||
{ | ||
"sourceKeys": ["properties.tr", "properties.ranSiteID"], | ||
"required": true, | ||
"destKey": "tr" | ||
}, | ||
{ | ||
"sourceKeys": ["properties.land", "properties.landTime"], | ||
"required": true, | ||
"destKey": "land" | ||
}, | ||
{ | ||
"sourceKeys": ["properties.date", "properties.orderCompletedTime"], | ||
"destKey": "date" | ||
}, | ||
{ | ||
"sourceKeys": ["properties.altord", "properties.alterOrderId"], | ||
"destKey": "altord" | ||
}, | ||
{ | ||
"sourceKeys": "properties.currency", | ||
"destKey": "cur" | ||
}, | ||
{ | ||
"sourceKeys": "properties.creditCardType", | ||
"destKey": "cc" | ||
}, | ||
{ | ||
"sourceKeys": "properties.commReason", | ||
"destKey": "commreason" | ||
}, | ||
{ | ||
"sourceKeys": "properties.isComm", | ||
"destKey": "iscomm" | ||
}, | ||
{ | ||
"sourceKeys": "properties.consumed", | ||
"destKey": "consumed" | ||
}, | ||
{ | ||
"sourceKeys": "properties.coupon", | ||
"destKey": "coupon" | ||
}, | ||
{ | ||
"sourceKeys": ["properties.custId", "properties.customerId", "properties.userId"], | ||
"destKey": "custid" | ||
}, | ||
{ | ||
"sourceKeys": ["properties.custScore", "properties.customerScore"], | ||
"destKey": "custscore" | ||
}, | ||
{ | ||
"sourceKeys": ["properties.custStatus", "properties.customerStatus"], | ||
"destKey": "custstatus" | ||
}, | ||
{ | ||
"sourceKeys": ["properties.dId", "properties.advertisingId"], | ||
"destKey": "did" | ||
}, | ||
{ | ||
"sourceKeys": ["properties.disamt", "properties.discountAmout"], | ||
"destKey": "disamt" | ||
}, | ||
{ | ||
"sourceKeys": ["properties.ordStatus", "properties.orderStatus"], | ||
"destKey": "ordstatus" | ||
}, | ||
{ | ||
"sourceKeys": "properties.segment", | ||
"destKey": "segment" | ||
}, | ||
{ | ||
"sourceKeys": "properties.shipcountry", | ||
"destKey": "shipcountry" | ||
}, | ||
{ | ||
"sourceKeys": "properties.shipped", | ||
"destKey": "shipped" | ||
}, | ||
{ | ||
"sourceKeys": "properties.sitename", | ||
"destKey": "sitename" | ||
}, | ||
{ | ||
"sourceKeys": "properties.storeId", | ||
"destKey": "storeid" | ||
}, | ||
{ | ||
"sourceKeys": ["properties.storecat", "properties.storeCategory"], | ||
"destKey": "storecat" | ||
}, | ||
{ | ||
"sourceKeys": "properties.currency", | ||
"destKey": "cur" | ||
} | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
bindings: | ||
- name: EventType | ||
path: ../../../../constants | ||
- path: ../../bindings/jsontemplate | ||
- name: defaultRequestConfig | ||
path: ../../../../v0/util | ||
- name: removeUndefinedAndNullValues | ||
path: ../../../../v0/util | ||
- path: ./utils | ||
|
||
steps: | ||
- name: messageType | ||
template: | | ||
.message.type.toLowerCase(); | ||
- name: validateInput | ||
template: | | ||
let messageType = $.outputs.messageType; | ||
$.assert(messageType, "message Type is not present. Aborting"); | ||
$.assert(messageType in {{$.EventType.([.TRACK])}}, "message type " + messageType + " is not supported"); | ||
$.assertConfig(.destination.Config.mid, "Merchant ID is not present. Aborting"); | ||
- name: prepareTrackPayload | ||
condition: $.outputs.messageType === {{$.EventType.TRACK}} | ||
template: | | ||
const properties = $.constructProperties(.message); | ||
const lineItems = $.constructLineItems(.message.properties) | ||
$.context.payload = {...properties,...lineItems,xml:1, mid:.destination.Config.mid} | ||
$.context.payload = $.removeUndefinedAndNullValues($.context.payload); | ||
- name: buildResponse | ||
template: | | ||
console.log("$.context.payload2",$.context.payload) | ||
const response = $.defaultRequestConfig(); | ||
response.params = $.context.payload; | ||
response.method = "GET"; | ||
response.endpoint = "https://track.linksynergy.com/ep"; | ||
response.headers = { | ||
"accept": "application/json", | ||
"content-type": "application/json" | ||
}; | ||
console.log("responseBidy",response) | ||
response |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
const { InstrumentationError } = require('@rudderstack/integrations-lib'); | ||
const { mappingConfig, ConfigCategories, productProperties } = require('./config'); | ||
const { constructPayload } = require('../../../../v0/util'); | ||
|
||
/** | ||
* This fucntion constructs payloads based upon mappingConfig for Track call type | ||
* @param {*} message | ||
* @returns | ||
*/ | ||
const constructProperties = (message) => { | ||
const payload = constructPayload(message, mappingConfig[ConfigCategories.TRACK.name]); | ||
return payload; | ||
}; | ||
|
||
/** | ||
* This fucntion build the item level list | ||
* @param {*} properties | ||
* @returns | ||
*/ | ||
const constructLineItems = (properties) => { | ||
if (!Array.isArray(properties?.products) || properties?.products.length < 1) { | ||
throw new InstrumentationError('Either properties.product is not an array or is empty'); | ||
} | ||
const productList = {}; | ||
// mapping all the properties leaving amount as for amount we need to do some calculations | ||
Object.keys(productProperties).forEach((property) => { | ||
const propertyKey = productProperties[property]; | ||
const values = properties.products.map((product) => product?.[propertyKey] || ''); | ||
if (values.some((element) => element !== '')) { | ||
productList[property] = values.join('|'); | ||
} | ||
}); | ||
// mapping amount list | ||
const amountList = properties.products.map((product) => { | ||
if (!product.amount) { | ||
if (product?.price) { | ||
return (product.quantity || 1) * product.price * 100; | ||
} | ||
throw new InstrumentationError('Either amount or price is required for every product'); | ||
} | ||
return product.amount * 100; | ||
}); | ||
productList.amtlist = amountList.join('|'); | ||
return productList; | ||
}; | ||
|
||
module.exports = { constructProperties, constructLineItems }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
const { constructLineItems } = require('./utils'); | ||
describe('constructLineItems', () => { | ||
it('should return a non-empty object when given a valid properties object with at least one product', () => { | ||
const properties = { | ||
products: [ | ||
{ | ||
name: 'Product 1', | ||
price: 10, | ||
quantity: 2, | ||
amount: 20, | ||
}, | ||
], | ||
}; | ||
const result = constructLineItems(properties); | ||
const expectedObj = { | ||
namelist: 'Product 1', | ||
qlist: '2', | ||
amtlist: '2000', | ||
}; | ||
expect(result).toEqual(expectedObj); | ||
}); | ||
|
||
it('should include all mapped properties in the returned object when present in at least one product', () => { | ||
const properties = { | ||
products: [ | ||
{ | ||
name: 'Product 1', | ||
category: 'Category 1', | ||
brand: 'Brand 1', | ||
price: 10, | ||
quantity: 2, | ||
amount: 20, | ||
}, | ||
], | ||
}; | ||
|
||
const result = constructLineItems(properties); | ||
|
||
const expectedObj = { | ||
namelist: 'Product 1', | ||
catlist: 'Category 1', | ||
brandlist: 'Brand 1', | ||
qlist: '2', | ||
amtlist: '2000', | ||
}; | ||
expect(result).toEqual(expectedObj); | ||
}); | ||
|
||
it('should include amtlist property in the returned object with calculated values', () => { | ||
const properties = { | ||
products: [ | ||
{ | ||
name: 'Product 1', | ||
price: 10, | ||
quantity: 2, | ||
}, | ||
{ | ||
name: 'Product 2', | ||
price: 5, | ||
quantity: 3, | ||
}, | ||
], | ||
}; | ||
|
||
const result = constructLineItems(properties); | ||
|
||
expect(result).toHaveProperty('amtlist'); | ||
expect(result.amtlist).toBe('2000|1500'); | ||
}); | ||
|
||
it('should throw an InstrumentationError when properties object is missing or has an empty products array', () => { | ||
const properties = {}; | ||
|
||
expect(() => constructLineItems(properties)).toThrow( | ||
'Either properties.product is not an array or is empty', | ||
); | ||
|
||
properties.products = []; | ||
|
||
expect(() => constructLineItems(properties)).toThrow( | ||
'Either properties.product is not an array or is empty', | ||
); | ||
}); | ||
|
||
it('should throw an InstrumentationError when a product is missing both amount and price/quantity properties', () => { | ||
const properties = { | ||
products: [ | ||
{ | ||
name: 'Product 1', | ||
}, | ||
], | ||
}; | ||
|
||
expect(() => constructLineItems(properties)).toThrow( | ||
'Either amount or price is required for every product', | ||
); | ||
}); | ||
}); |
65 changes: 65 additions & 0 deletions
65
test/integrations/destinations/rakuten/processor/commonConfig.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
export const destination = { | ||
ID: 'random_id', | ||
Name: 'rakuten', | ||
DestinationDefinition: { | ||
Config: { | ||
cdkV2Enabled: true, | ||
}, | ||
}, | ||
Config: { | ||
mid: 'dummyMarketingId', | ||
}, | ||
}; | ||
export const endpoint = 'https://track.linksynergy.com/ep'; | ||
export const commonOutputHeaders = { | ||
accept: 'application/json', | ||
'content-type': 'application/json', | ||
}; | ||
export const singleProductWithAllProperties = { | ||
sku: 'ABC123', | ||
amount: 20, | ||
quantity: 5, | ||
name: 'SampleProduct', | ||
brand: 'SampleBrand', | ||
coupon: 'SALE20', | ||
categoryId: '12345', | ||
category: 'Electronics', | ||
discountAmount: 10.5, | ||
discountType: 'Percentage', | ||
isClearance: 'Y', | ||
isMarketPlace: 'N', | ||
isSale: 'Y', | ||
itmStatus: 'In Stock', | ||
margin: 0.15, | ||
markdown: 5.0, | ||
shipId: 'SHIP123', | ||
shipBy: 'Express', | ||
taxExempt: 'N', | ||
sequence: '123', | ||
isComm: 'Y', | ||
}; | ||
export const commonProperties = { | ||
orderId: 'SampleOrderId', | ||
tr: 'SampleRanSiteID', | ||
landTime: '20240129_1200', | ||
date: '20240129_1300', | ||
altord: 'SampleAlternateOrderId', | ||
currency: 'INR', | ||
creditCardType: 'Visa', | ||
commReason: 'SampleCommReason', | ||
isComm: 'Y', | ||
consumed: '20240129_1400', | ||
coupon: 'SampleCoupon', | ||
custId: 'SampleCustomerId', | ||
custScore: 'A', | ||
custStatus: 'New', | ||
dId: 'SampleDeviceId', | ||
disamt: '50.00', | ||
ordStatus: 'Pending', | ||
segment: 'SampleSegment', | ||
shipcountry: 'USA', | ||
shipped: '20240129_1500', | ||
sitename: 'SampleSiteName', | ||
storeId: '12345', | ||
storecat: 'Electronics', | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import { transformationFailures } from './transformationFailure'; | ||
import { trackSuccess } from './track'; | ||
export const data = [...trackSuccess, ...transformationFailures]; |
Oops, something went wrong.