Files
medassist-ng/backend/src/services/notifications/builders.ts
T
Daniel Volz c5c75f65e4 feat: add inhaler and injection package types
Closes #558

- add inhaler and injection as supported medication package types
- align refill, planner, dashboard, report, export, and notification wording for the new discrete package types
- include the validated CI repair for formatting and dashboard label parity
2026-05-11 21:29:59 +02:00

112 lines
3.9 KiB
TypeScript

import { getFooterPlain, getTranslations, type Language, t } from "../../i18n/translations.js";
import { formatPlannerQuantity } from "../planner-service.js";
export type StockReminderItem = {
name: string;
medsLeft: number;
packageType?: string;
daysLeft: number | null;
depletionDate: string | null;
isCritical?: boolean;
};
export type PrescriptionReminderItem = {
name: string;
remainingRefills: number;
};
function splitStockItems(items: StockReminderItem[]): {
emptyItems: StockReminderItem[];
criticalItems: StockReminderItem[];
lowItems: StockReminderItem[];
} {
const emptyItems = items.filter((item) => item.medsLeft <= 0);
const criticalItems = items.filter((item) => item.medsLeft > 0 && item.isCritical !== false);
const lowItems = items.filter((item) => item.medsLeft > 0 && item.isCritical === false);
return { emptyItems, criticalItems, lowItems };
}
export function buildStockReminderPushNotification(
items: StockReminderItem[],
language: Language
): { title: string; message: string } {
const tr = getTranslations(language);
const { emptyItems, criticalItems, lowItems } = splitStockItems(items);
const titleParts: string[] = [];
if (emptyItems.length > 0) titleParts.push(`🚨 ${emptyItems.length} ${tr.push.empty}`);
if (criticalItems.length > 0) titleParts.push(`🚨 ${criticalItems.length} ${tr.push.critical}`);
if (lowItems.length > 0) titleParts.push(`⚠️ ${lowItems.length} ${tr.push.lowStock}`);
const title = `MedAssist-ng: ${titleParts.join(", ")} - ${tr.push.reorderNow}`;
const messageParts: string[] = [];
if (emptyItems.length > 0) {
messageParts.push(`🚨 ${tr.push.emptySection}:`);
emptyItems.forEach((item) => messageParts.push(`${item.name}`));
}
if (criticalItems.length > 0) {
if (messageParts.length > 0) messageParts.push("");
messageParts.push(`🚨 ${tr.push.criticalSection}:`);
criticalItems.forEach((item) =>
messageParts.push(
`${item.name}: ${formatPlannerQuantity(item.packageType, item.medsLeft, tr)}, ${t(tr.push.daysLeft, { count: item.daysLeft ?? 0 })}`
)
);
}
if (lowItems.length > 0) {
if (messageParts.length > 0) messageParts.push("");
messageParts.push(`⚠️ ${tr.push.lowStockSection}:`);
lowItems.forEach((item) =>
messageParts.push(
`${item.name}: ${formatPlannerQuantity(item.packageType, item.medsLeft, tr)}, ${t(tr.push.daysLeft, { count: item.daysLeft ?? 0 })}`
)
);
}
return {
title,
message: `${messageParts.join("\n")}\n\n---\n${getFooterPlain(language)}`,
};
}
export function buildPrescriptionReminderPushNotification(
items: PrescriptionReminderItem[],
language: Language
): { title: string; message: string } {
const tr = getTranslations(language);
const emptyItems = items.filter((item) => item.remainingRefills <= 0);
const lowItems = items.filter((item) => item.remainingRefills > 0);
const titleParts: string[] = [];
if (emptyItems.length > 0) {
titleParts.push(
`🚨 ${emptyItems.length} ${emptyItems.length === 1 ? tr.prescriptionReminder.pushEmptySingle : tr.prescriptionReminder.pushEmpty}`
);
}
if (lowItems.length > 0) {
titleParts.push(
`🚨 ${lowItems.length} ${lowItems.length === 1 ? tr.prescriptionReminder.pushLowSingle : tr.prescriptionReminder.pushLow}`
);
}
const messageParts: string[] = [];
if (emptyItems.length > 0) {
messageParts.push(`🚨 ${tr.prescriptionReminder.pushEmptySection}:`);
emptyItems.forEach((item) => messageParts.push(`${item.name}`));
}
if (lowItems.length > 0) {
if (messageParts.length > 0) messageParts.push("");
messageParts.push(`🚨 ${tr.prescriptionReminder.pushLowSection}:`);
lowItems.forEach((item) =>
messageParts.push(
`${item.name}: ${t(tr.prescriptionReminder.pushRefillsLeft, { count: item.remainingRefills })}`
)
);
}
return {
title: `MedAssist-ng: ${titleParts.join(", ")} - ${tr.prescriptionReminder.pushRenewNow}`,
message: `${messageParts.join("\n")}\n\n---\n${getFooterPlain(language)}`,
};
}