Files
aeroresolve_backend/src/modules/cohort/cohort.service.ts
T

154 lines
4.6 KiB
TypeScript

import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, DeepPartial } from 'typeorm';
import { getTenantId } from '../../common/tenant/tenant.context';
import { Cohort } from './cohort.entity';
import { CreateCohortDto } from './dto/create-cohort.dto';
import { UpdateCohortDto } from './dto/update-cohort.dto';
import { AuditLogService } from '../audit-log/audit-log.service';
@Injectable()
export class CohortService {
constructor(
@InjectRepository(Cohort)
private readonly cohortRepository: Repository<Cohort>,
private readonly auditLogService: AuditLogService,
) {}
private mapDtoToEntity(dto: CreateCohortDto | UpdateCohortDto) {
const {
cabinClassIds,
passengerTypeIds,
ancillaryPurchaseIds,
loyaltyTierIds,
revenueSegmentIds,
regionIds,
tripPurposeIds,
originAirports,
destinationAirports,
...rest
} = dto;
const mapping: any = { ...rest };
if (cabinClassIds) mapping.cabinClasses = cabinClassIds.map(id => ({ id }));
if (passengerTypeIds) mapping.passengerTypes = passengerTypeIds.map(id => ({ id }));
if (ancillaryPurchaseIds) mapping.ancillaryPurchases = ancillaryPurchaseIds.map(id => ({ id }));
if (loyaltyTierIds) mapping.loyaltyTiers = loyaltyTierIds.map(id => ({ id }));
if (revenueSegmentIds) mapping.revenueSegments = revenueSegmentIds.map(id => ({ id }));
if (regionIds) mapping.regions = regionIds.map(id => ({ id }));
if (tripPurposeIds) mapping.tripPurposes = tripPurposeIds.map(id => ({ id }));
if (originAirports !== undefined) mapping.originAirport = originAirports;
if (destinationAirports !== undefined) mapping.destinationAirport = destinationAirports;
return mapping as DeepPartial<Cohort>;
}
private getRelations() {
return {
cabinClasses: true,
passengerTypes: true,
ancillaryPurchases: true,
loyaltyTiers: true,
revenueSegments: true,
regions: true,
tripPurposes: true
};
}
async create(createCohortDto: CreateCohortDto): Promise<Cohort> {
const mappedData = this.mapDtoToEntity(createCohortDto);
const cohort = this.cohortRepository.create({
...mappedData,
tenantId: getTenantId(),
});
return this.cohortRepository.save(cohort);
}
async findAll(page: number = 1, limit: number = 10) {
const skip = (page - 1) * limit;
const tenantId = getTenantId();
const [data, total] = await this.cohortRepository.findAndCount({
where: { tenantId },
skip,
take: limit,
order: { createdAt: 'DESC' },
relations: this.getRelations(),
});
return {
data,
total,
page,
limit,
totalPages: Math.ceil(total / limit),
};
}
async findOne(id: string): Promise<Cohort> {
const cohort = await this.cohortRepository.findOne({
where: { id, tenantId: getTenantId() },
relations: this.getRelations(),
});
if (!cohort) {
throw new NotFoundException(`Cohort with ID ${id} not found`);
}
return cohort;
}
async update(id: string, updateCohortDto: UpdateCohortDto): Promise<Cohort> {
const cohort = await this.findOne(id);
const beforeSnapshot = { ...cohort };
const mappedData = this.mapDtoToEntity(updateCohortDto);
Object.assign(cohort, mappedData);
const after = await this.cohortRepository.save(cohort);
await this.auditLogService.log({
module: 'cohort',
action: 'UPDATE',
entityId: id,
entityLabel: cohort.name,
before: beforeSnapshot,
after: { ...after },
performedBy: getTenantId(),
});
return after;
}
async updateStatus(id: string, status: string): Promise<Cohort> {
const cohort = await this.findOne(id);
const beforeStatus = cohort.status;
cohort.status = status;
const after = await this.cohortRepository.save(cohort);
await this.auditLogService.log({
module: 'cohort',
action: 'STATUS_CHANGE',
entityId: id,
entityLabel: cohort.name,
before: { status: beforeStatus },
after: { status },
performedBy: getTenantId(),
});
return after;
}
async remove(id: string): Promise<void> {
const cohort = await this.findOne(id);
const beforeSnapshot = { ...cohort };
await this.cohortRepository.remove(cohort);
await this.auditLogService.log({
module: 'cohort',
action: 'DELETE',
entityId: id,
entityLabel: beforeSnapshot.name,
before: beforeSnapshot,
after: undefined,
performedBy: getTenantId(),
});
}
}