mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 04:08:11 +00:00
Refactored the whole app based on the requirements shared
This commit is contained in:
131
apps/edr-passenger-api/src/modules/agents/agents.service.ts
Normal file
131
apps/edr-passenger-api/src/modules/agents/agents.service.ts
Normal file
@@ -0,0 +1,131 @@
|
||||
import { Injectable, NotFoundException, BadRequestException } from '@nestjs/common';
|
||||
import { PrismaService } from '../../common/prisma.service';
|
||||
import { CreateAgentBookingDto, OpenShiftDto, CloseShiftDto } from './agents.dto';
|
||||
|
||||
function generateRef(): string {
|
||||
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
return Array.from({ length: 6 }, () => chars[Math.floor(Math.random() * chars.length)]).join('');
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class AgentsService {
|
||||
constructor(private prisma: PrismaService) {}
|
||||
|
||||
async createAgentBooking(dto: CreateAgentBookingDto) {
|
||||
const agent = await this.prisma.agent.findUnique({ where: { id: dto.agentId }, include: { user: { include: { passenger: true } } } });
|
||||
if (!agent || !agent.active) throw new NotFoundException('Agent not found or inactive');
|
||||
if (!agent.user.passenger) throw new BadRequestException('Agent must have passenger account');
|
||||
|
||||
const trip = await this.prisma.trip.findUnique({ where: { id: dto.tripId } });
|
||||
if (!trip) throw new NotFoundException('Trip not found');
|
||||
|
||||
const seatIds = dto.passengers.map(p => p.seatId);
|
||||
const seats = await this.prisma.seat.findMany({ where: { id: { in: seatIds } } });
|
||||
if (seats.length !== seatIds.length) throw new BadRequestException('Invalid seat selection');
|
||||
|
||||
const baseFare = 45000 * dto.passengers.length;
|
||||
const totalMinor = baseFare;
|
||||
|
||||
const booking = await this.prisma.booking.create({
|
||||
data: {
|
||||
bookingRef: generateRef(),
|
||||
passengerId: agent.user.passenger.id,
|
||||
tripId: dto.tripId,
|
||||
status: dto.paymentMethod === 'CASH' ? 'CONFIRMED' : 'PENDING_PAYMENT',
|
||||
totalMinor,
|
||||
seats: {
|
||||
create: dto.passengers.map(p => ({
|
||||
seatId: p.seatId,
|
||||
passengerName: p.fullName,
|
||||
idDocumentType: p.idDocumentType,
|
||||
idDocumentNumber: p.idDocumentNumber
|
||||
}))
|
||||
}
|
||||
},
|
||||
include: { seats: true }
|
||||
});
|
||||
|
||||
await this.prisma.seat.updateMany({
|
||||
where: { id: { in: seatIds } },
|
||||
data: { status: 'BOOKED' }
|
||||
});
|
||||
|
||||
const changeGiven = dto.cashReceived ? dto.cashReceived - totalMinor : 0;
|
||||
await this.prisma.agentBooking.create({
|
||||
data: {
|
||||
agentId: dto.agentId,
|
||||
bookingId: booking.id,
|
||||
paymentMethod: dto.paymentMethod,
|
||||
cashReceived: dto.cashReceived,
|
||||
changeGiven,
|
||||
paperTicket: dto.paperTicket ?? false
|
||||
}
|
||||
});
|
||||
|
||||
const commissionAmount = Math.floor(totalMinor * agent.commissionRate / 100);
|
||||
await this.prisma.agentCommission.create({
|
||||
data: {
|
||||
agentId: dto.agentId,
|
||||
bookingId: booking.id,
|
||||
amountMinor: commissionAmount,
|
||||
rate: agent.commissionRate
|
||||
}
|
||||
});
|
||||
|
||||
return { booking, commission: commissionAmount };
|
||||
}
|
||||
|
||||
async openShift(dto: OpenShiftDto) {
|
||||
const agent = await this.prisma.agent.findUnique({ where: { id: dto.agentId } });
|
||||
if (!agent) throw new NotFoundException('Agent not found');
|
||||
|
||||
const openShift = await this.prisma.agentShift.findFirst({
|
||||
where: { agentId: dto.agentId, closedAt: null }
|
||||
});
|
||||
if (openShift) throw new BadRequestException('Shift already open');
|
||||
|
||||
return this.prisma.agentShift.create({
|
||||
data: {
|
||||
agentId: dto.agentId,
|
||||
openingBalance: dto.openingBalance ?? 0
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async closeShift(dto: CloseShiftDto) {
|
||||
const shift = await this.prisma.agentShift.findUnique({ where: { id: dto.shiftId } });
|
||||
if (!shift) throw new NotFoundException('Shift not found');
|
||||
if (shift.closedAt) throw new BadRequestException('Shift already closed');
|
||||
|
||||
return this.prisma.agentShift.update({
|
||||
where: { id: dto.shiftId },
|
||||
data: {
|
||||
closedAt: new Date(),
|
||||
closingBalance: dto.closingBalance,
|
||||
notes: dto.notes,
|
||||
reconciled: true
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async getCommissions(agentId: string, dateFrom?: Date, dateTo?: Date) {
|
||||
return this.prisma.agentCommission.findMany({
|
||||
where: {
|
||||
agentId,
|
||||
createdAt: {
|
||||
gte: dateFrom,
|
||||
lte: dateTo
|
||||
}
|
||||
},
|
||||
orderBy: { createdAt: 'desc' }
|
||||
});
|
||||
}
|
||||
|
||||
async getShifts(agentId: string) {
|
||||
return this.prisma.agentShift.findMany({
|
||||
where: { agentId },
|
||||
orderBy: { openedAt: 'desc' },
|
||||
take: 20
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user