Skip to content

Instantly share code, notes, and snippets.

@joepuzzo
Created March 3, 2021 20:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joepuzzo/6cfe73bbe714fdd7013d15b3be3d5842 to your computer and use it in GitHub Desktop.
Save joepuzzo/6cfe73bbe714fdd7013d15b3be3d5842 to your computer and use it in GitHub Desktop.
const s1 = [
{ id: 1, key: 'a', value: 20 }, // --- a
{ id: 2, key: 'b', value: 50 },
{ id: 3, key: 'c', value: 30 }, // ------ c
{ id: 4, key: 'd', value: 40 }, // ------------------ d
];
const s2 = [
{ id: 5, key: 'a', value: 10 }, // --- a
{ id: 6, key: 'c', value: 70 }, // ----- c
{ id: 7, key: 'e', value: 15 }, // ---------- e
{ id: 8, key: 'd', value: 55 }, // ------------------ d
];
const s3 = [
{ id: 9, key: 'e', value: 25 }, // ---------- e
{ id: 10, key: 'f', value: 15 },
{ id: 11, key: 'd', value: 35 }, // ----------------- d
];
const setCompare = (a, b) => a.key === b.key;
// Example output -----------------------
const exampleConflicts = [
{
resolutions: [
{ id: 1, key: 'a', value: 20 }, // X
{ id: 5, key: 'a', value: 10 },
]
},
{
resolutions: [
{ id: 3, key: 'c', value: 30 },
{ id: 6, key: 'c', value: 70 }, // X
]
},
{
resolutions: [
{ id: 4, key: 'd', value: 40 }, // X
{ id: 8, key: 'd', value: 55 },
{ id: 11, key: 'd', value: 35 }, // X
]
},
{
resolutions: [
{ id: 7, key: 'e', value: 15 },
{ id: 9, key: 'e', value: 25 },
]
},
]
// --------------------------------------
const findConflicts = ( sets, compareFunction ) => {
const conflicts = [];
// Combine sets into one single set
const set = sets.flat().map( e => ({ value: e, stored: false }));
// Go through each element in the set and find duplicates
for( let i = 0; i < set.length; i++ ){
// Foucus on the current element
const matcher = set[i];
const resolutions = [];
// We have already found logically equivalent things so don't do it again
if( !matcher.stored ){
// Search the rest of the array for matches
for( let j = i + 1; j < set.length; j++ ){
// Get the guy we want to compare
const current = set[j];
// Check to see if he matches
if( compareFunction(current.value, matcher.value) ){
// If this is the first conflict found for this matcher then push that on as well
if( !matcher.stored ){
matcher.stored = true;
resolutions.push(matcher.value);
}
// We have already found logically equivalent things so update this flag
current.stored = true;
// Push this onto the resolutions for this conflict
resolutions.push(current.value);
}
}
// Only add conflict if we found one
if( resolutions.length > 0 ){
conflicts.push({ resolutions });
}
}
}
return conflicts;
};
console.log(JSON.stringify(findConflicts([s1, s2, s3], setCompare), null, 2));
const changeset1 = {
priceAdjustments: [
{ market: { code: "US" }, partNumber: "1063260-00-C", value: 100 },
{ market: { code: "US" }, partNumber: "1063260-00-D", value: 200 },
{ market: { code: "US" }, partNumber: "1063260-00-E", value: 300 },
],
marginRules: [
{
marginPercent: .5,
conditions: [{ scope: 2, type: "Market", comparator: "CONTAINS_ANY", value: "CO,CN,CA" }]
},
{
marginPercent: .6, operator: "OR",
conditions: [{ scope: 2, type: "Market", comparator: "EQUAL", value: "CO" }, { scope: 2, type: "Market", comparator: "EQUAL", value: "CN" }]
},
{
marginPercent: .6, operator: "AND",
conditions: [{ scope: 2, type: "Market", comparator: "EQUAL", value: "CN" }, { scope: 3, type: "Model", comparator: "EQUAL", value: "MS" }]
},
{
marginPercent: .7, operator: "AND",
conditions: [{ scope: 2, type: "Market", comparator: "EQUAL", value: "CN" }, { scope: 8, type: "PartNumber", comparator: "EQUAL", value: "123" }]
},
{
marginPercent: .3, operator: "AND",
conditions: [{ scope: 3, type: "Model", comparator: "EQUAL", value: "MX" }]
}
]
}
const changeset2 = {
priceAdjustments: [
{ market: { code: "US" }, partNumber: "1063260-00-C", value: 200 },
{ market: { code: "US" }, partNumber: "1063260-00-D", value: 200 },
{ market: { code: "US" }, partNumber: "1063260-00-F", value: 400 }, // <<< Model X part
],
marginRules: [
{
marginPercent: .7, operator: "AND",
conditions: [{ scope: 2, type: "Market", comparator: "CONTAINS_ANY", value: "CO,CN" }]
},
{
marginPercent: .1, operator: "AND",
conditions: [{ scope: 8, type: "PartNumber", comparator: "EQUAL", value: "1063260-00-E" }]
}
]
}
// EXAMPLE Resolution object
const resolution = {
changesets: ['1', '2', '3'],
actions: [
{ type: 'DELETE', context: 'PRICE_ADJUSTMENT', id: '3124'},
{ type: 'DELETE', context: 'MARGIN_RULE', id: '7465'},
]
}
// Above we have
// 1. Two price adjustments that directly conflict with one another
// 2. A Model X Margin rule that technically speaking conflicts with a price adjustment
// 3. A Margin rule that technically speaking conflicts with a price adjustment
// 4. Two margin rules in changeset1 that conflict with a margin rule in changeset2
/* ------------------ Price Adjustment Compare ----------------- */
/**
* Goal determine if priceAdjustments are equal
*
* @param {*} a
* @param {*} b
*/
const comparePriceAdjustments = (a, b) => {
const marketsMatch = a.market.code === b.market.code;
const numbersMatch = a.partNumber === b.partNumber;
return marketsMatch && numbersMatch;
};
/* -------------------- Margin Rule Compare -------------------- */
const compareMarketMarginCondition = ( a, b ) => {
const comparatorMatch = a.comparator === b.comparator;
// 'CN,CA,FR' ---> [ 'CN', 'CA', 'FR' ]
const v1 = a.value.split(',');
const v2 = b.value.split(',');
}
/* -------------------- Helpers -------------------- */
const findHighestScope = ( arr ) => {
// Check for empty array
let largest = arr.length > 0 ? arr[0].scope : 0;
for( let i = 1; i < arr.length; i++ ){
if( arr[i].scope > largest ){
largest = arr[i].scope;
}
}
return largest;
}
console.log('Largest [7]', findHighestScope([]));
console.log('Largest [7]', findHighestScope([{ scope: 7}]));
console.log('Largest [1, 7]', findHighestScope([{scope: 1},{ scope: 7}]));
console.log('Largest [1, 7, 5]', findHighestScope([{scope: 1},{ scope: 7}, { scope: 5}]));
// 8 7 6 5 4 3 2 1
// 64 32 16 8 4 2 1
// [ 1, 4 ] == 0 0 0 0 1 0 0 1
// [ 2, 3 ] 0 0 0 0 0 1 1 0
// [ 2, 3 ] 0 0 0 0 0 1 1 0
const determineSpecificity = () => {
// 8 7 6 5 4 3 2 1
const specificity = [0, 0, 0, 0, 0, 0, 0, 0]
}
/**
* Goal determine if margin are equal
*
* Facts:
* 1. Margin rules can only conflict if they have the same specificity
*
* @param {*} a
* @param {*} b
*/
const compareMarginRules = (a, b) => {
//
};
const conflicts = {
priceAdjustments: findConflicts([changeset1.priceAdjustments, changeset2.priceAdjustments], comparePriceAdjustments),
marginRules: findConflicts([changeset1.marginRules, changeset2.marginRules], compareMarginRules)
}
console.log('conflicts:', JSON.stringify(conflicts, null, 2));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment