mirror of
https://github.com/HamzaSha1/zod-backend.git
synced 2025-08-25 13:49:40 +00:00
111 lines
4.7 KiB
TypeScript
111 lines
4.7 KiB
TypeScript
import { BadRequestException, Injectable, Logger } from '@nestjs/common';
|
|
import moment from 'moment';
|
|
import { PageOptionsRequestDto } from '~/core/dtos';
|
|
import { OciService } from '~/document/services';
|
|
import { JuniorService } from '~/junior/services';
|
|
import { CreateAllowanceRequestDto } from '../dtos/request';
|
|
import { Allowance } from '../entities';
|
|
import { AllowancesRepository } from '../repositories';
|
|
|
|
@Injectable()
|
|
export class AllowancesService {
|
|
private readonly logger = new Logger(AllowancesService.name);
|
|
constructor(
|
|
private readonly allowancesRepository: AllowancesRepository,
|
|
private readonly juniorService: JuniorService,
|
|
private readonly ociService: OciService,
|
|
) {}
|
|
|
|
async createAllowance(guardianId: string, body: CreateAllowanceRequestDto) {
|
|
this.logger.log(`Creating allowance for junior ${body.juniorId} by guardian ${guardianId}`);
|
|
if (moment(body.startDate).isBefore(moment().startOf('day'))) {
|
|
this.logger.error(`Start date ${body.startDate} is before today`);
|
|
throw new BadRequestException('ALLOWANCE.START_DATE_BEFORE_TODAY');
|
|
}
|
|
if (moment(body.startDate).isAfter(body.endDate)) {
|
|
this.logger.error(`Start date ${body.startDate} is after end date ${body.endDate}`);
|
|
throw new BadRequestException('ALLOWANCE.START_DATE_AFTER_END_DATE');
|
|
}
|
|
|
|
const doesJuniorBelongToGuardian = await this.juniorService.doesJuniorBelongToGuardian(guardianId, body.juniorId);
|
|
|
|
if (!doesJuniorBelongToGuardian) {
|
|
this.logger.error(`Junior ${body.juniorId} does not belong to guardian ${guardianId}`);
|
|
throw new BadRequestException('JUNIOR.DOES_NOT_BELONG_TO_GUARDIAN');
|
|
}
|
|
|
|
const allowance = await this.allowancesRepository.createAllowance(guardianId, body);
|
|
|
|
this.logger.log(`Allowance ${allowance.id} created successfully`);
|
|
return this.findAllowanceById(allowance.id);
|
|
}
|
|
|
|
async findAllowanceById(allowanceId: string, guardianId?: string) {
|
|
this.logger.log(`Finding allowance ${allowanceId} ${guardianId ? `by guardian ${guardianId}` : ''}`);
|
|
const allowance = await this.allowancesRepository.findAllowanceById(allowanceId, guardianId);
|
|
|
|
if (!allowance) {
|
|
this.logger.error(`Allowance ${allowanceId} not found ${guardianId ? `for guardian ${guardianId}` : ''}`);
|
|
throw new BadRequestException('ALLOWANCE.NOT_FOUND');
|
|
}
|
|
await this.prepareAllowanceDocuments([allowance]);
|
|
this.logger.log(`Allowance ${allowanceId} found successfully`);
|
|
return allowance;
|
|
}
|
|
|
|
async findAllowances(guardianId: string, query: PageOptionsRequestDto): Promise<[Allowance[], number]> {
|
|
this.logger.log(`Finding allowances for guardian ${guardianId}`);
|
|
const [allowances, itemCount] = await this.allowancesRepository.findAllowances(guardianId, query);
|
|
await this.prepareAllowanceDocuments(allowances);
|
|
this.logger.log(`Returning allowances for guardian ${guardianId}`);
|
|
return [allowances, itemCount];
|
|
}
|
|
|
|
async deleteAllowance(guardianId: string, allowanceId: string) {
|
|
this.logger.log(`Deleting allowance ${allowanceId} for guardian ${guardianId}`);
|
|
const { affected } = await this.allowancesRepository.deleteAllowance(guardianId, allowanceId);
|
|
|
|
if (!affected) {
|
|
this.logger.error(`Allowance ${allowanceId} not found`);
|
|
throw new BadRequestException('ALLOWANCE.NOT_FOUND');
|
|
}
|
|
this.logger.log(`Allowance ${allowanceId} deleted successfully`);
|
|
}
|
|
|
|
async validateAllowanceForJunior(juniorId: string, allowanceId: string) {
|
|
this.logger.log(`Validating allowance ${allowanceId} for junior ${juniorId}`);
|
|
const allowance = await this.allowancesRepository.findAllowanceById(allowanceId);
|
|
|
|
if (!allowance) {
|
|
this.logger.error(`Allowance ${allowanceId} not found`);
|
|
throw new BadRequestException('ALLOWANCE.NOT_FOUND');
|
|
}
|
|
|
|
if (allowance.juniorId !== juniorId) {
|
|
this.logger.error(`Allowance ${allowanceId} does not belong to junior ${juniorId}`);
|
|
throw new BadRequestException('ALLOWANCE.DOES_NOT_BELONG_TO_JUNIOR');
|
|
}
|
|
|
|
return allowance;
|
|
}
|
|
|
|
async findAllowancesChunks(chunkSize: number) {
|
|
this.logger.log(`Finding allowances chunks`);
|
|
const allowances = await this.allowancesRepository.findAllowancesChunks(chunkSize);
|
|
this.logger.log(`Returning allowances chunks`);
|
|
return allowances;
|
|
}
|
|
|
|
private async prepareAllowanceDocuments(allowance: Allowance[]) {
|
|
this.logger.log(`Preparing document for allowances`);
|
|
await Promise.all(
|
|
allowance.map(async (allowance) => {
|
|
const profilePicture = allowance.junior.customer.profilePicture;
|
|
if (profilePicture) {
|
|
profilePicture.url = await this.ociService.generatePreSignedUrl(profilePicture);
|
|
}
|
|
}),
|
|
);
|
|
}
|
|
}
|