Skip to content

Commit

Permalink
Merge pull request #5 from UNICEFECAR/organizations
Browse files Browse the repository at this point in the history
Organizations
  • Loading branch information
georgipavlov-7DIGIT authored Sep 19, 2024
2 parents 9d7a68b + 3091906 commit 0086c6a
Show file tree
Hide file tree
Showing 13 changed files with 455 additions and 82 deletions.
78 changes: 64 additions & 14 deletions service/controllers/availability.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export const updateAvailabilitySingleWeek = async ({
startDate,
slot,
campaignId,
organizationId,
}) => {
if (!checkSlotsWithinWeek(startDate, [slot]))
throw slotsNotWithinWeek(language);
Expand Down Expand Up @@ -83,7 +84,7 @@ export const updateAvailabilitySingleWeek = async ({
startDate,
})
.then(async (res) => {
if (res.slots.length === 0 && res.campaign_slots.length === 0) {
if (res.is_empty) {
await addAvailabilityRowQuery({
poolCountry: country,
provider_id,
Expand All @@ -95,14 +96,44 @@ export const updateAvailabilitySingleWeek = async ({

// Check if the slot already exists in the availability
// and compare the campaignId's if it's a campaign slot
const slotsToCheck = campaignId ? res.campaign_slots : res.slots;
const slotsToCheck = campaignId
? res.campaign_slots
: organizationId
? res.organization_slots
: res.slots;

const slotExists = slotsToCheck.some((s) => {
const slotToCheck = campaignId
? new Date(s.time).getTime()
: new Date(s).getTime();
return slotToCheck === slot * 1000 && s.campaign_id === campaignId;
const slotToCheck =
campaignId || organizationId
? new Date(s.time).getTime()
: new Date(s).getTime();
return (
slotToCheck === slot * 1000 &&
((campaignId && s.campaign_id === campaignId) ||
(organizationId && s.organization_id === organizationId))
);
});

const slotAvailableForOrg = organizationId
? slotsToCheck.find((x) => {
const slotToCheck = new Date(x.time).getTime();
return slotToCheck === slot * 1000;
})
: null;

// If the slot is already available for another organization, delete it
if (slotAvailableForOrg) {
await deleteAvailabilitySingleWeekQuery({
poolCountry: country,
provider_id,
startDate,
slot,
organizationId: slotAvailableForOrg.organization_id,
}).catch((err) => {
throw err;
});
}

if (slotExists) {
throw slotAlreadyExists(language);
}
Expand All @@ -113,6 +144,7 @@ export const updateAvailabilitySingleWeek = async ({
startDate,
slot,
campaignId,
organizationId,
}).catch((err) => {
throw err;
});
Expand All @@ -130,13 +162,15 @@ export const deleteAvailabilitySingleWeek = async ({
startDate,
slot,
campaignId,
organizationId,
}) => {
await deleteAvailabilitySingleWeekQuery({
poolCountry: country,
provider_id,
startDate,
slot,
campaignId,
organizationId,
}).catch((err) => {
throw err;
});
Expand Down Expand Up @@ -271,19 +305,18 @@ export const getAvailabilitySingleDay = async ({

const slotsToLoopThrough = campaignId
? threeWeeksSlots.campaign_slots
: threeWeeksSlots.slots;
: [...threeWeeksSlots.slots, ...threeWeeksSlots.organization_slots];
// Get slots for the day before the given day, the day, and the day after the given day
// Exclude slots that are in the past
// Exlude slots that are less than 24 hours from now
// Exclude slots that are pending, scheduled, or suggested
slotsToLoopThrough.forEach((slot) => {
let slotTimestamp;
if (campaignId) {
if (slot.time) {
slotTimestamp = new Date(slot.time).getTime() / 1000;
} else {
slotTimestamp = new Date(slot).getTime() / 1000;
}

if (
slotTimestamp > now &&
slotTimestamp >= previousDayTimestamp &&
Expand All @@ -297,11 +330,18 @@ export const getAvailabilitySingleDay = async ({
});

// Sort slots in ascending order
if (campaignId) {
slots.sort((a, b) => new Date(a.time) - new Date(b.time));
} else {
slots.sort((a, b) => a - b);
}
slots.sort((a, b) => {
// sort by time asc
if (a.time && b.time) {
return new Date(a.time) - new Date(b.time);
} else if (a.time && !b.time) {
return new Date(a.time) - new Date(b);
} else if (!a.time && b.time) {
return new Date(a) - new Date(b.time);
}

return new Date(a) - new Date(b);
});

return slots;
};
Expand All @@ -312,6 +352,7 @@ export const clearAvailabilitySlot = async ({
startDate,
slot,
campaignIds,
organizationId,
}) => {
const args = {
poolCountry: country,
Expand All @@ -329,6 +370,15 @@ export const clearAvailabilitySlot = async ({
);
});

if (organizationId) {
queries.push(
deleteAvailabilitySingleWeekQuery({
...args,
organizationId,
})
);
}

await Promise.all(queries);
return { success: true };
};
22 changes: 22 additions & 0 deletions service/controllers/consultation.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ import {
bookingNotAllowed,
providerNotFound,
} from "#utils/errors";
import { getOrganizationsByIdsQuery } from "#queries/organization";

export const getAllConsultationsCount = async ({ country, providerId }) => {
return await getAllConsultationsCountQuery({
Expand Down Expand Up @@ -264,6 +265,7 @@ export const getAllConsultationsSingleWeek = async ({
sponsor_image: sponsorImage,
campaign_id: campaignId,
sponsor_name: sponsorName,
organization_id: consultation.organization_id,
});
}

Expand Down Expand Up @@ -353,6 +355,7 @@ export const getAllConsultationsSingleDay = async ({
time: consultation.time,
status: consultation.status,
price: consultation.price,
organization_id: consultation.organization_id,
};

if (campaignData) {
Expand Down Expand Up @@ -424,6 +427,17 @@ export const getAllPastConsultations = async ({ country, providerId }) => {
throw err;
});

const organizationIds = Array.from(
new Set(consultations.map((consultation) => consultation.organization_id))
);

const organizationsData = await getOrganizationsByIdsQuery({
poolCountry: country,
organizationIds,
}).then((res) => {
return res.rows || [];
});

let response = [];

for (let i = 0; i < consultations.length; i++) {
Expand All @@ -434,13 +448,19 @@ export const getAllPastConsultations = async ({ country, providerId }) => {
const clientSurname = client.surname;
const clientNickname = client.nickname;
const campaignId = consultation.campaign_id;
const organizationId = consultation.organization_id;

const campaignData = campaignCouponPrices.find(
(x) => x.campaign_id === campaignId
);

const organizationData = organizationsData.find(
(x) => x.organization_id === organizationId
);

const couponPrice = campaignData?.price_per_coupon;
const sponsorImage = campaignData?.image;
const organizationName = organizationData?.name;

const oneHourBeforeNow = new Date();
oneHourBeforeNow.setHours(oneHourBeforeNow.getHours() - 1);
Expand All @@ -460,6 +480,7 @@ export const getAllPastConsultations = async ({ country, providerId }) => {
time: consultation.time,
status: consultation.status,
price: consultation.price,
organization_name: organizationName,
};

if (campaignData) {
Expand Down Expand Up @@ -677,6 +698,7 @@ export const addConsultationAsPending = async ({
time: typeof time === "object" ? time.time : time,
price: campaignId ? campaignData.price_per_coupon : consultationPrice,
campaignId,
organizationId: isSlotAvailable?.organization_id || null,
})
.then((raw) => {
if (raw.rowCount === 0) {
Expand Down
58 changes: 53 additions & 5 deletions service/controllers/providers.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ import {
getLatestAvailableSlot,
} from "#utils/helperFunctions";
import { deleteCacheItem } from "#utils/cache";
import {
assignOrganizationsToProviderQuery,
removeOrganizationsFromProviderQuery,
} from "#queries/organization";
import { getUserIdsByProviderIdsQuery } from "#queries/users";

const AWS_ACCESS_KEY_ID = process.env.AWS_ACCESS_KEY_ID;
const AWS_SECRET_ACCESS_KEY = process.env.AWS_SECRET_ACCESS_KEY;
Expand Down Expand Up @@ -305,6 +310,8 @@ export const updateProviderData = async ({
currentWorkWithIds,
languageIds,
currentLanguageIds,
organizationIds,
currentOrganizationIds,
videoLink,
}) => {
// Check if email is changed
Expand Down Expand Up @@ -409,6 +416,31 @@ export const updateProviderData = async ({
});
});

// Insert new organizations and delete missing ones
const organizationsToInsert = organizationIds?.filter(
(id) => !currentOrganizationIds.includes(id)
);

const organizationsToDelete = currentOrganizationIds?.filter(
(id) => !organizationIds.includes(id)
);

await assignOrganizationsToProviderQuery({
organizationIds: organizationsToInsert,
providerDetailId: provider_id,
poolCountry: country,
}).catch((err) => {
throw err;
});

await removeOrganizationsFromProviderQuery({
organizationIds: organizationsToDelete,
providerDetailId: provider_id,
poolCountry: country,
}).catch((err) => {
throw err;
});

const cacheKey = `provider_${country}_${user_id}`;
await deleteCacheItem(cacheKey);

Expand Down Expand Up @@ -757,11 +789,7 @@ export const getActivities = async ({ country, providerId }) => {
return activities;
};

export const getRandomProviders = async ({
country,
language,
numberOfProviders,
}) => {
export const getRandomProviders = async ({ country, numberOfProviders }) => {
let providers = await getAllActiveProvidersQuery({
poolCountry: country,
limit: numberOfProviders || 3,
Expand Down Expand Up @@ -1016,3 +1044,23 @@ export const addProviderRating = async ({
throw err;
});
};

export const removeProvidersCache = async ({ country, providerIds }) => {
const promises = [];

const userIds = await getUserIdsByProviderIdsQuery({
country,
providerIds,
}).then((res) => {
return res.rows.map((x) => x.user_id);
});

userIds.forEach((userId) => {
const cacheKey = `provider_${country}_${userId}`;
promises.push(deleteCacheItem(cacheKey));
});

await Promise.all(promises);

return { success: true };
};
Loading

0 comments on commit 0086c6a

Please sign in to comment.