52 lines
1.6 KiB
TypeScript
52 lines
1.6 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
import { InjectRepository } from '@nestjs/typeorm';
|
|
import { Between, Repository } from 'typeorm';
|
|
import { Invoice } from './entities/invoice.entity';
|
|
import { Booking } from '../bookings/entities/booking.entity';
|
|
|
|
@Injectable()
|
|
export class BillingService {
|
|
constructor(
|
|
@InjectRepository(Invoice)
|
|
private readonly invoiceRepository: Repository<Invoice>,
|
|
@InjectRepository(Booking)
|
|
private readonly bookingRepository: Repository<Booking>,
|
|
) {}
|
|
|
|
async generateMonthlyInvoices(clubId: string, month: string): Promise<Invoice[]> {
|
|
const [year, monthNum] = month.split('-').map(Number);
|
|
const start = new Date(year, monthNum - 1, 1);
|
|
const end = new Date(year, monthNum, 0, 23, 59, 59);
|
|
|
|
const bookings = await this.bookingRepository.find({
|
|
where: { clubId, createdAt: Between(start, end) },
|
|
relations: ['drink', 'user'],
|
|
});
|
|
|
|
const totalsPerUser = new Map<string, number>();
|
|
for (const booking of bookings) {
|
|
const current = totalsPerUser.get(booking.userId) ?? 0;
|
|
totalsPerUser.set(
|
|
booking.userId,
|
|
current + Number(booking.drink.price) * booking.amount,
|
|
);
|
|
}
|
|
|
|
const invoices: Invoice[] = [];
|
|
for (const [userId, total] of totalsPerUser) {
|
|
const invoice = this.invoiceRepository.create({ clubId, userId, total, month });
|
|
invoices.push(await this.invoiceRepository.save(invoice));
|
|
}
|
|
|
|
return invoices;
|
|
}
|
|
|
|
async findByClub(clubId: string): Promise<Invoice[]> {
|
|
return this.invoiceRepository.find({
|
|
where: { clubId },
|
|
relations: ['user'],
|
|
order: { createdAt: 'DESC' },
|
|
});
|
|
}
|
|
}
|