Skip to content

Commit

Permalink
Fixed outcome logic for string and arrays. Loosened roomType mapping
Browse files Browse the repository at this point in the history
  • Loading branch information
SuperOuss committed Mar 29, 2024
1 parent 6b2abd9 commit 9d1b708
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 44 deletions.
Binary file modified .DS_Store
Binary file not shown.
108 changes: 78 additions & 30 deletions functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,58 +9,102 @@ export function calculateMatchOutcome(refRoom, supplierRoom) {


// Room Type Comparison
outcome.matchedRoomType = compareWithSupplierInfo(refRoom.roomType, supplierRoom.roomType);
outcome.matchedRoomType = compareStringAttributes(refRoom.roomType, supplierRoom.roomType);
//console.log("refRoomType:", refRoom.roomType, "supplierRoomType:", supplierRoom.roomType);
//console.log(outcome.matchedRoomType);

// Room Category Comparison
outcome.matchedRoomCategory = compareWithSupplierInfo(refRoom.roomCategory, supplierRoom.roomCategory);
outcome.matchedRoomCategory = compareArrayAttributes(refRoom.roomCategory, supplierRoom.roomCategory);
//console.log("refRoomCategory:", refRoom.roomCategory, "supplierRoomCategory:", supplierRoom.roomCategory);
//console.log(outcome.matchedRoomCategory);

// View Comparison
outcome.matchedView = compareWithSupplierInfo(refRoom.view, supplierRoom.view);
outcome.matchedView = compareStringAttributes(refRoom.view, supplierRoom.view);

// Assumed logic for matchedAmenities, needs specific comparison logic
outcome.matchedAmenities = compareWithSupplierInfo(refRoom.amenities, supplierRoom.amenities);
outcome.matchedAmenities = compareArrayAttributes(refRoom.amenities, supplierRoom.amenities);

// Bed Type Comparison
outcome.bedTypes = calculateBedTypeOutcome(refRoom.bedType, supplierRoom.bedType);
//console.log("refBedtype:", refRoom.bedType, "supplierBedType:", supplierRoom.bedType);
//console.log(outcome.bedTypes)
return outcome;
}

function compareWithSupplierInfo(refAttribute, supplierAttribute) {
// Check for "no information" values
function compareStringAttributes(refAttribute, supplierAttribute) {
// Helper function to check if a value is considered to have no information
const isNoInfo = (value) => [undefined, null, "", "unknown"].includes(value);
// Determine if the attributes have meaningful information
const hasRefInfo = !isNoInfo(refAttribute) && !(Array.isArray(refAttribute) && refAttribute.every(isNoInfo));
const hasSupplierInfo = !isNoInfo(supplierAttribute) && !(Array.isArray(supplierAttribute) && supplierAttribute.every(isNoInfo));
// If both attributes are arrays, compare for full and partial matches
if (Array.isArray(refAttribute) && Array.isArray(supplierAttribute)) {
const fullMatch = refAttribute.slice().sort().join(',') === supplierAttribute.slice().sort().join(',');
if (fullMatch) {
return true; // Full match found

// Determine the presence of meaningful information for each attribute
const hasRefInfo = !isNoInfo(refAttribute);
const hasSupplierInfo = !isNoInfo(supplierAttribute);

// Process according to the business rules
if (hasRefInfo && hasSupplierInfo) {
// Both have information, check if they are similar
if (refAttribute === supplierAttribute) {
return true;
}

const partialMatch = refAttribute.some(item => supplierAttribute.includes(item));
return partialMatch ? "partial" : "supplierInfo"; // Changed from false to "supplierInfo" to indicate unmatched supplier info
}
// For non-array attributes, direct comparison
else if (!Array.isArray(refAttribute) && !Array.isArray(supplierAttribute)) {
return refAttribute === supplierAttribute ? true : (hasSupplierInfo ? "supplierInfo" : false);
}
// Handling cases where one is an array and the other is not
else if (hasRefInfo && !hasSupplierInfo) {
// Check if both strings contain "room" as a fallback before returning false
const bothContainRoom = refAttribute.includes("room") && supplierAttribute.includes("room");
if (bothContainRoom) {
return "partial";
}
// If not similar and no special "room" condition met, return false
return false;
} else if (hasSupplierInfo && !hasRefInfo) {
// Only supplier attribute has information
return "supplierInfo";
} else if (!hasSupplierInfo && hasRefInfo) {
// Only reference attribute has information
return "refInfo";
} else if (!hasRefInfo && !hasSupplierInfo) {
// Both are "unknown" or don't have information
return null;
}
else if (!hasRefInfo && hasSupplierInfo) {
}


function compareArrayAttributes(refArray, supplierArray) {
// Helper function to check if an array is considered to have no information
const isNoInfoArray = (array) => array.length === 0 || array[0] === "unknown";

// Determine the presence of meaningful information for each array
const hasRefInfo = !isNoInfoArray(refArray);
const hasSupplierInfo = !isNoInfoArray(supplierArray);

// Process according to the business rules for arrays
if (hasRefInfo && hasSupplierInfo) {
// Both arrays have information, proceed with comparison
const refSet = new Set(refArray);
const supplierSet = new Set(supplierArray);
const intersection = new Set([...refArray].filter(x => supplierSet.has(x)));

if (intersection.size === refSet.size && intersection.size === supplierSet.size) {
// All values match
return true;
} else if (intersection.size > 0) {
// At least one value matches
return "partial";
} else {
// Both have info, but no matches
return false;
}
} else if (hasSupplierInfo && !hasRefInfo) {
// Only supplier array has information
return "supplierInfo";
} else if (!hasSupplierInfo && hasRefInfo) {
// Only reference array has information
return "refInfo";
} else if (!hasRefInfo && !hasSupplierInfo) {
// Both arrays are considered to have no info
return null;
}

// Default to "unknown" if neither or both are missing information
return null;
}




function calculateBedTypeOutcome(refBedTypes, supplierBedTypes) {
// Check for 'unknown' or missing information in refBedTypes
const refHasUnknownOrMissing = !refBedTypes || refBedTypes.length === 0 || refBedTypes.every(bed => bed.type === 'unknown');
Expand All @@ -72,6 +116,10 @@ function calculateBedTypeOutcome(refBedTypes, supplierBedTypes) {
if (refHasUnknownOrMissing && !supplierHasUnknownOrMissing) {
return "supplierInfo";
}
//
if (!refHasUnknownOrMissing && supplierHasUnknownOrMissing) {
return "refInfo";
}

// If both are missing or unknown, return null
if (refHasUnknownOrMissing && supplierHasUnknownOrMissing) {
Expand Down
38 changes: 24 additions & 14 deletions server.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,27 +47,31 @@ function extractRoomType(roomName) {
.trim();

if (normalizedRoomName.includes("communicating double rooms")) {
console.log("occurence detected");
let type = "connected rooms"
return type;
}
if (normalizedRoomName.includes("family")) {
console.log("occurence detected");

let type = "family room"
return type;
}

// Improved fallback logic for 'single', 'double', 'triple', 'quad'
if (/(single|double|triple|quad|twin)(?!\s+(bed|sofa|sofabed))/.test(normalizedRoomName)) {
if (/(single|double|triple|quad|)(?!\s+(bed|sofa|sofabed))/.test(normalizedRoomName)) {
// If matched at the start and not followed by bed/sofa/sofabed, return it as room type
let type = RegExp.$1 + ' ' + "room";
return type
}

if (/(|twin|)(?!\s+(bed|sofa|sofabed))/.test(normalizedRoomName)) {
// If matched at the start and not followed by bed/sofa/sofabed, return it as room type
let type = "double" + ' ' + "room";
return type
}

// Synonyms normalization, expanded to include more variations
const synonyms = {
'double-double': 'double room', // Example where room might have two double beds
'studio': 'studio room',
'accessible': 'accessible room',
'family': 'family room',
'connected': 'connected rooms',
Expand All @@ -87,7 +91,7 @@ function extractRoomType(roomName) {
'suite', 'single room', 'double room', 'triple room', 'quad room', 'family room',
'shared room', 'private room', 'studio room', 'apartment', 'villa', 'bungalow',
'king room', 'queen room', 'cottage', 'penthouse', 'loft', 'cabin', 'chalet', 'mansion',
'duplex', 'guesthouse', 'hostel', 'accessible room', 'connected rooms',
'duplex', 'guesthouse', 'hostel', 'accessible room', 'connected rooms', 'studio'
// Ensure these are already in standard form
];

Expand Down Expand Up @@ -356,6 +360,7 @@ function normalizeRoomName(roomName) {
}

function mapRooms(referenceCatalog, inputCatalog) {
const startTime = Date.now();
let results = []; // Holds structured data for matched rooms
let totalSupplierRooms = inputCatalog[0].supplierRoomInfo.length;
let mappedSupplierRoomIds = new Set(); // Tracks matched supplier rooms
Expand All @@ -368,7 +373,7 @@ function mapRooms(referenceCatalog, inputCatalog) {
.filter(refRoom => !/^Room\s*#\d+$/.test(refRoom.roomName))
.map(refRoom => ({ ...refRoom, ...normalizeRoomName(refRoom.roomName) }));

console.log(filteredReferenceRooms);
//console.log(filteredReferenceRooms);

const supplierRooms = inputCatalog[0].supplierRoomInfo
.map(room => ({ ...room, ...normalizeRoomName(room.supplierRoomName) }));
Expand All @@ -386,6 +391,9 @@ function mapRooms(referenceCatalog, inputCatalog) {
let unmappedRooms = supplierRooms.filter(room => !mappedSupplierRoomIds.has(room.supplierRoomId));
let unmappedRoomsCount = unmappedRooms.length;

const endTime = Date.now(); // Capture end time
const duration = endTime - startTime; // Calculate duration in ms

return {
Results: results,
UnmappedRooms: unmappedRooms.length > 0 ? unmappedRooms : { Message: "There are no unmapped rooms" },
Expand All @@ -395,8 +403,9 @@ function mapRooms(referenceCatalog, inputCatalog) {
SecondPassMatches: secondPassMatchCount,
thirdPassMatches: thirdPassMatchCount,
MappedSupplierRooms: firstPassMatchCount + secondPassMatchCount + thirdPassMatchCount,
UnmappedSupplierRooms: unmappedRoomsCount
}
UnmappedSupplierRooms: unmappedRoomsCount,
},
ExecutionDuration: `${duration}ms`
};
}

Expand Down Expand Up @@ -446,6 +455,7 @@ function matchRooms(referenceRooms, supplierRooms, mappedSupplierRoomIds, result

function isMatchBasedOnOutcome(outcome, pass) {
//console.log("Outcome at start:", outcome); // Print the outcome at the beginning
//console.log("pass:", pass);
let result; // Initialize a variable to hold the result
// Check conditions based on the pass
switch (pass) {
Expand All @@ -459,18 +469,18 @@ function isMatchBasedOnOutcome(outcome, pass) {

case 'Second Pass':
result = (outcome.matchedRoomType === true) &&
((outcome.matchedRoomCategory === true || outcome.matchedRoomCategory === 'partial') &&
((outcome.matchedRoomCategory === true || outcome.matchedRoomCategory === 'partial' || outcome.matchedRoomCategory === null) &&
(outcome.matchedView === true || outcome.matchedView === null) &&
(outcome.matchedAmenities === true || outcome.matchedAmenities === null || outcome.matchedAmenities === 'partial') &&
(outcome.bedTypes === true || outcome.bedTypes === 'partial' || outcome.bedTypes === null));
break;

case 'Third Pass':
result = (outcome.matchedRoomType === true) &&
(outcome.matchedRoomCategory === true || outcome.matchedRoomCategory === null || outcome.matchedRoomCategory === 'supplierInfo') &&
(outcome.matchedView === true || outcome.matchedView === null || outcome.matchedView === 'supplierInfo') &&
(outcome.matchedAmenities === true || outcome.matchedAmenities === null || outcome.matchedAmenities === 'supplierInfo' || outcome.matchedAmenities === 'partial') &&
(outcome.bedTypes === true || outcome.bedTypes === 'partial' || outcome.bedTypes === null || outcome.bedTypes === 'supplierInfo');
result = (outcome.matchedRoomType === true || outcome.matchedRoomType === 'partial') &&
(outcome.matchedRoomCategory === true || outcome.matchedRoomCategory === null || outcome.matchedRoomCategory === 'supplierInfo' || outcome.matchedRoomCategory === 'refInfo') &&
(outcome.matchedView === true || outcome.matchedView === null || outcome.matchedView === 'supplierInfo' || outcome.matchedView === 'refInfo') &&
(outcome.matchedAmenities === true || outcome.matchedAmenities === null || outcome.matchedAmenities === 'refInfo' || outcome.matchedAmenities === 'supplierInfo' || outcome.matchedAmenities === 'partial') &&
(outcome.bedTypes === true || outcome.bedTypes === 'partial' || outcome.bedTypes === null || outcome.bedTypes === 'supplierInfo' || outcome.bedTypes === 'refInfo');
break;

default:
Expand Down

0 comments on commit 9d1b708

Please sign in to comment.