Add additional lint rules
This commit is contained in:
parent
02d782c3da
commit
420b18eb78
67 changed files with 3686 additions and 1415 deletions
|
|
@ -3,7 +3,8 @@ import type { RegimensService } from '../regimens/regimens.service.js';
|
|||
import type { CabinetRepository } from '../cabinet/cabinet.repository.js';
|
||||
import type { CabinetService } from '../cabinet/cabinet.service.js';
|
||||
import type { MedicinePricesRepository } from '../medicine-prices/medicine-prices.repository.js';
|
||||
import type { PurchasesRepository } from '../purchases/purchases.repository.js';
|
||||
import type { ShoppingListsRepository } from '../shopping-lists/shopping-lists.repository.js';
|
||||
import type { RefillListDocument } from '../../schemas/refill-list.schema.js';
|
||||
import type {
|
||||
CreateRefillListInput,
|
||||
UpdateRefillListInput,
|
||||
|
|
@ -19,7 +20,46 @@ interface Deps {
|
|||
cabinetRepository: CabinetRepository;
|
||||
cabinetService: CabinetService;
|
||||
medicinePricesRepository: MedicinePricesRepository;
|
||||
purchasesRepository: PurchasesRepository;
|
||||
shoppingListsRepository: ShoppingListsRepository;
|
||||
}
|
||||
|
||||
interface RefillAlert {
|
||||
medicineId: string;
|
||||
medicineName: string;
|
||||
medicineStrength: number;
|
||||
medicineStrengthUnit: string;
|
||||
daysUntilEmpty: number;
|
||||
dailyConsumption: number;
|
||||
currentStock: number;
|
||||
pendingOrderStock: number;
|
||||
daysUntilEmptyWithOrders: number | null;
|
||||
suggestedQuantity: number;
|
||||
lastKnownPrice?: {
|
||||
price: number;
|
||||
pricePerUnit: number;
|
||||
storeName: string;
|
||||
storeId: string;
|
||||
date: Date;
|
||||
};
|
||||
cheapestOption?: {
|
||||
price: number;
|
||||
pricePerUnit: number;
|
||||
storeName: string;
|
||||
storeId: string;
|
||||
date: Date;
|
||||
};
|
||||
}
|
||||
|
||||
interface CabinetAggregateSummaryGroup {
|
||||
_id: string;
|
||||
medicineName: string;
|
||||
medicineStrength: number;
|
||||
medicineStrengthUnit: string;
|
||||
medicineForm: string;
|
||||
totalQuantity: number;
|
||||
unit: string;
|
||||
earliestExpiry: Date | null;
|
||||
itemCount: number;
|
||||
}
|
||||
|
||||
export class RefillsService {
|
||||
|
|
@ -28,7 +68,7 @@ export class RefillsService {
|
|||
private readonly cabinetRepository: CabinetRepository;
|
||||
private readonly cabinetService: CabinetService;
|
||||
private readonly medicinePricesRepository: MedicinePricesRepository;
|
||||
private readonly purchasesRepository: PurchasesRepository;
|
||||
private readonly shoppingListsRepository: ShoppingListsRepository;
|
||||
|
||||
public constructor({
|
||||
refillsRepository,
|
||||
|
|
@ -36,17 +76,21 @@ export class RefillsService {
|
|||
cabinetRepository,
|
||||
cabinetService,
|
||||
medicinePricesRepository,
|
||||
purchasesRepository,
|
||||
shoppingListsRepository,
|
||||
}: Deps) {
|
||||
this.refillsRepository = refillsRepository;
|
||||
this.regimensService = regimensService;
|
||||
this.cabinetRepository = cabinetRepository;
|
||||
this.cabinetService = cabinetService;
|
||||
this.medicinePricesRepository = medicinePricesRepository;
|
||||
this.purchasesRepository = purchasesRepository;
|
||||
this.shoppingListsRepository = shoppingListsRepository;
|
||||
}
|
||||
|
||||
public async getAlerts(householdId: string, userId: string, thresholdDays = 7) {
|
||||
public async getAlerts(
|
||||
householdId: string,
|
||||
userId: string,
|
||||
thresholdDays = 7,
|
||||
): Promise<RefillAlert[]> {
|
||||
const burnRates = await this.regimensService.calculateBurnRates(householdId, userId);
|
||||
|
||||
const triggered = burnRates.filter(
|
||||
|
|
@ -56,23 +100,36 @@ export class RefillsService {
|
|||
if (triggered.length === 0) return [];
|
||||
|
||||
// Get strength data from cabinet aggregate
|
||||
const summaries = await this.cabinetRepository.getAggregateSummary(householdId);
|
||||
const summariesRaw = await this.cabinetRepository.getAggregateSummary(householdId);
|
||||
const summaries = summariesRaw as unknown as CabinetAggregateSummaryGroup[];
|
||||
const summaryMap = new Map<
|
||||
string,
|
||||
{ medicineStrength: number; medicineStrengthUnit: string }
|
||||
>();
|
||||
for (const s of summaries) {
|
||||
summaryMap.set(s._id as string, {
|
||||
medicineStrength: s.medicineStrength as number,
|
||||
medicineStrengthUnit: s.medicineStrengthUnit as string,
|
||||
summaryMap.set(s._id, {
|
||||
medicineStrength: s.medicineStrength,
|
||||
medicineStrengthUnit: s.medicineStrengthUnit,
|
||||
});
|
||||
}
|
||||
|
||||
// Get pending stock from ordered purchases
|
||||
const pendingStockRows = await this.purchasesRepository.getPendingMedicineStock(householdId);
|
||||
// Get pending stock from active shopping lists
|
||||
const activeLists = await this.shoppingListsRepository.findActiveByHousehold(householdId);
|
||||
const pendingStockMap = new Map<string, number>();
|
||||
for (const row of pendingStockRows) {
|
||||
pendingStockMap.set(row.medicineId, row.totalUnits);
|
||||
for (const list of activeLists) {
|
||||
if (list.items) {
|
||||
for (const item of list.items) {
|
||||
const itemAny = item as unknown as {
|
||||
productId?: string;
|
||||
quantity: number;
|
||||
checked: boolean;
|
||||
};
|
||||
if (itemAny.productId && !itemAny.checked) {
|
||||
const currentQty = pendingStockMap.get(itemAny.productId) ?? 0;
|
||||
pendingStockMap.set(itemAny.productId, currentQty + itemAny.quantity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const alerts = await Promise.all(
|
||||
|
|
@ -94,7 +151,7 @@ export class RefillsService {
|
|||
medicineId: br.medicineId,
|
||||
medicineName: br.medicineName,
|
||||
medicineStrength: summary?.medicineStrength ?? 0,
|
||||
medicineStrengthUnit: (summary?.medicineStrengthUnit ?? 'mg') as never,
|
||||
medicineStrengthUnit: summary?.medicineStrengthUnit ?? 'mg',
|
||||
daysUntilEmpty: br.daysUntilEmpty as number,
|
||||
dailyConsumption: br.dailyConsumption,
|
||||
currentStock: br.totalInCabinet,
|
||||
|
|
@ -103,11 +160,11 @@ export class RefillsService {
|
|||
suggestedQuantity,
|
||||
lastKnownPrice: latestRecord
|
||||
? {
|
||||
price: latestRecord.price as number,
|
||||
pricePerUnit: latestRecord.pricePerUnit as number,
|
||||
storeName: latestRecord.storeName as string,
|
||||
storeId: latestRecord.storeId as string,
|
||||
date: latestRecord.date as Date,
|
||||
price: latestRecord.price,
|
||||
pricePerUnit: latestRecord.pricePerUnit,
|
||||
storeName: latestRecord.storeName,
|
||||
storeId: latestRecord.storeId,
|
||||
date: latestRecord.date,
|
||||
}
|
||||
: undefined,
|
||||
cheapestOption:
|
||||
|
|
@ -127,7 +184,11 @@ export class RefillsService {
|
|||
return alerts;
|
||||
}
|
||||
|
||||
public async createList(data: CreateRefillListInput, householdId: string, userId: string) {
|
||||
public async createList(
|
||||
data: CreateRefillListInput,
|
||||
householdId: string,
|
||||
userId: string,
|
||||
): Promise<RefillListDocument> {
|
||||
let items: Array<{
|
||||
medicineId: string;
|
||||
medicineName: string;
|
||||
|
|
@ -144,7 +205,7 @@ export class RefillsService {
|
|||
medicineId: alert.medicineId,
|
||||
medicineName: alert.medicineName,
|
||||
quantity: alert.suggestedQuantity,
|
||||
unit: 'tablet' as string,
|
||||
unit: 'tablet',
|
||||
estimatedPrice: alert.cheapestOption?.price ?? alert.lastKnownPrice?.price,
|
||||
storeId: alert.cheapestOption?.storeId ?? alert.lastKnownPrice?.storeId,
|
||||
}));
|
||||
|
|
@ -153,7 +214,7 @@ export class RefillsService {
|
|||
medicineId: item.medicineId,
|
||||
medicineName: item.medicineName,
|
||||
quantity: item.quantity,
|
||||
unit: item.unit as string,
|
||||
unit: item.unit,
|
||||
estimatedPrice: item.estimatedPrice,
|
||||
storeId: item.storeId,
|
||||
notes: item.notes,
|
||||
|
|
@ -176,17 +237,27 @@ export class RefillsService {
|
|||
});
|
||||
}
|
||||
|
||||
public async list(householdId: string, query: RefillListQueryInput) {
|
||||
public async list(
|
||||
householdId: string,
|
||||
query: RefillListQueryInput,
|
||||
): Promise<{
|
||||
data: RefillListDocument[];
|
||||
pagination: { cursor: string | null; hasMore: boolean };
|
||||
}> {
|
||||
return this.refillsRepository.findByHousehold(householdId, query);
|
||||
}
|
||||
|
||||
public async getById(id: string, householdId: string) {
|
||||
public async getById(id: string, householdId: string): Promise<RefillListDocument> {
|
||||
const list = await this.refillsRepository.findById(id, householdId);
|
||||
if (!list) throw new NotFoundError('Refill list not found');
|
||||
return list;
|
||||
}
|
||||
|
||||
public async updateList(id: string, householdId: string, data: UpdateRefillListInput) {
|
||||
public async updateList(
|
||||
id: string,
|
||||
householdId: string,
|
||||
data: UpdateRefillListInput,
|
||||
): Promise<RefillListDocument> {
|
||||
await this.getById(id, householdId);
|
||||
const updated = await this.refillsRepository.update(id, householdId, data);
|
||||
if (!updated) throw new NotFoundError('Refill list not found');
|
||||
|
|
@ -198,7 +269,7 @@ export class RefillsService {
|
|||
householdId: string,
|
||||
itemId: string,
|
||||
data: UpdateRefillListItemInput,
|
||||
) {
|
||||
): Promise<RefillListDocument> {
|
||||
await this.getById(listId, householdId);
|
||||
|
||||
const updateData: UpdateRefillListItemInput & { checkedAt?: Date } = { ...data };
|
||||
|
|
@ -216,7 +287,11 @@ export class RefillsService {
|
|||
return updated;
|
||||
}
|
||||
|
||||
public async addToCabinet(listId: string, householdId: string, userId: string) {
|
||||
public async addToCabinet(
|
||||
listId: string,
|
||||
householdId: string,
|
||||
userId: string,
|
||||
): Promise<{ addedCount: number; priceRecordsCreated: number }> {
|
||||
const list = await this.getById(listId, householdId);
|
||||
|
||||
const checkedItems = (
|
||||
|
|
@ -266,7 +341,23 @@ export class RefillsService {
|
|||
return { addedCount, priceRecordsCreated: 0 };
|
||||
}
|
||||
|
||||
public async getStoreComparison(listId: string, householdId: string) {
|
||||
public async getStoreComparison(
|
||||
listId: string,
|
||||
householdId: string,
|
||||
): Promise<
|
||||
Array<{
|
||||
medicineId: string;
|
||||
storeOptions: Array<{
|
||||
storeId: string;
|
||||
storeName: string;
|
||||
latestPrice: number;
|
||||
latestPricePerUnit: number;
|
||||
currency: string;
|
||||
date: Date;
|
||||
isInsurancePrice: boolean;
|
||||
}>;
|
||||
}>
|
||||
> {
|
||||
const list = await this.getById(listId, householdId);
|
||||
|
||||
const medicineIds = [
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue