Implement stores and refills, improve testing
This commit is contained in:
parent
9f416903ef
commit
5536acd67d
137 changed files with 21218 additions and 221 deletions
|
|
@ -0,0 +1,93 @@
|
|||
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<number | null> {
|
||||
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);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue