import type { MedicinePricesRepository } from './medicine-prices.repository.js'; import type { MedicineProductsRepository } from '../medicine-products/medicine-products.repository.js'; import type { StoresRepository } from '../stores/stores.repository.js'; import type { CreateMedicinePriceRecordInput, MedicinePriceHistoryQueryInput, MedicinePriceAnalyticsQueryInput, } from '@meshitrack/shared'; import { NotFoundError } from '../../common/errors.js'; interface Deps { medicinePricesRepository: MedicinePricesRepository; medicineProductsRepository: MedicineProductsRepository; storesRepository: StoresRepository; } export class MedicinePricesService { private readonly medicinePricesRepository: MedicinePricesRepository; private readonly medicineProductsRepository: MedicineProductsRepository; private readonly storesRepository: StoresRepository; public constructor({ medicinePricesRepository, medicineProductsRepository, storesRepository, }: Deps) { this.medicinePricesRepository = medicinePricesRepository; this.medicineProductsRepository = medicineProductsRepository; this.storesRepository = storesRepository; } public async recordPrice( data: CreateMedicinePriceRecordInput, householdId: string, userId: string, ) { const product = await this.medicineProductsRepository.findById( data.medicineProductId, householdId, ); if (!product) throw new NotFoundError('Medicine product not found'); const store = await this.storesRepository.findById(data.storeId, householdId); if (!store) throw new NotFoundError('Store not found'); const pricePerUnit = data.price / data.quantity; const date = data.date ? new Date(data.date) : new Date(); return this.medicinePricesRepository.create({ householdId, medicineProductId: data.medicineProductId, medicineProductBrand: product.brand ?? product.medicineName, medicineId: data.medicineId, medicineName: product.medicineName, storeId: data.storeId, storeName: store.name, price: data.price, currency: data.currency, quantity: data.quantity, unit: data.unit, pricePerUnit, date, isInsurancePrice: data.isInsurancePrice, notes: data.notes, createdBy: userId, }); } public async getPriceHistory( householdId: string, medicineId: string, query: MedicinePriceHistoryQueryInput, ) { return this.medicinePricesRepository.findByMedicine(householdId, medicineId, query); } public async compareStores(householdId: string, medicineId: string) { return this.medicinePricesRepository.compareStores(householdId, medicineId); } public async estimatePrice( householdId: string, medicineId: string, storeId?: string, ): Promise { const record = await this.medicinePricesRepository.getLatestForMedicine( householdId, medicineId, storeId, ); return record ? (record.pricePerUnit as number) : null; } public async getAnalytics(householdId: string, query: MedicinePriceAnalyticsQueryInput) { return this.medicinePricesRepository.getAnalytics(householdId, query); } }