mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 14:08:11 +00:00
Backoffice UAT results addressed, packages and other updates
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { Body, Controller, Get, Param, Post, Query, Request, UseGuards } from '@nestjs/common';
|
||||
import { Body, Controller, Get, Param, Patch, Post, Query, Request, UseGuards } from '@nestjs/common';
|
||||
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
|
||||
import { AgentsService } from './agents.service';
|
||||
import { CreateAgentBookingDto, OpenShiftDto, CloseShiftDto } from './agents.dto';
|
||||
import { CreateAgentDto, CreateAgentBookingDto, OpenShiftDto, CloseShiftDto } from './agents.dto';
|
||||
import { JwtGuard as IamJwtGuard } from '@tria-plc/api-common/modules/auth/services/jwt.guard';
|
||||
|
||||
@ApiTags('Agents')
|
||||
@@ -16,6 +16,24 @@ export class AgentsController {
|
||||
getMe(@Request() req: any) {
|
||||
return this.service.getMe(req.user?.id ?? req.user?.sub);
|
||||
}
|
||||
|
||||
@Get()
|
||||
@ApiOperation({ summary: 'List all agents' })
|
||||
findAll(@Query('search') search?: string, @Query('active') active?: string) {
|
||||
return this.service.findAll({ search, active });
|
||||
}
|
||||
|
||||
@Post()
|
||||
@ApiOperation({ summary: 'Create agent profile linked to an IAM user' })
|
||||
createAgent(@Body() dto: CreateAgentDto) {
|
||||
return this.service.createAgent(dto);
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
@ApiOperation({ summary: 'Update agent profile' })
|
||||
updateAgent(@Param('id') id: string, @Body() dto: Partial<CreateAgentDto> & { active?: boolean }) {
|
||||
return this.service.updateAgent(id, dto);
|
||||
}
|
||||
@Post('bookings')
|
||||
@ApiOperation({ summary: 'Create agent booking with cash payment' })
|
||||
createBooking(@Body() dto: CreateAgentBookingDto) {
|
||||
|
||||
@@ -2,6 +2,12 @@ import { IsString, IsInt, IsBoolean, IsOptional, IsArray, ValidateNested } from
|
||||
import { Type } from 'class-transformer';
|
||||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||
|
||||
export class CreateAgentDto {
|
||||
@ApiProperty() @IsString() iamUserId: string;
|
||||
@ApiPropertyOptional() @IsOptional() @IsString() agentCode?: string;
|
||||
@ApiPropertyOptional() @IsOptional() @IsInt() commissionRate?: number;
|
||||
}
|
||||
|
||||
export class AgentPassengerDto {
|
||||
@ApiProperty() @IsString() fullName: string;
|
||||
@ApiProperty() @IsString() phone: string;
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { Injectable, NotFoundException, BadRequestException } from '@nestjs/common';
|
||||
import { InjectDataSource } from '@nestjs/typeorm';
|
||||
import { DataSource } from 'typeorm';
|
||||
import { PrismaService } from '../../common/prisma.service';
|
||||
import { CreateAgentBookingDto, OpenShiftDto, CloseShiftDto } from './agents.dto';
|
||||
import { IdDocumentType } from '@prisma/client';
|
||||
@@ -10,7 +12,49 @@ function generateRef(): string {
|
||||
|
||||
@Injectable()
|
||||
export class AgentsService {
|
||||
constructor(private prisma: PrismaService) {}
|
||||
constructor(
|
||||
private prisma: PrismaService,
|
||||
@InjectDataSource() private readonly dataSource: DataSource,
|
||||
) {}
|
||||
|
||||
async findAll(filters: { search?: string; active?: string }) {
|
||||
const where: any = {};
|
||||
if (filters.active !== undefined && filters.active !== '') {
|
||||
where.active = filters.active === 'true';
|
||||
}
|
||||
const agents = await this.prisma.agent.findMany({
|
||||
where,
|
||||
orderBy: { createdAt: 'desc' },
|
||||
});
|
||||
// Enrich with IAM user data
|
||||
const iamUserIds = agents.map(a => a.iamUserId).filter(Boolean) as string[];
|
||||
type IamRow = { id: string; email: string; name: any; phone_number: string | null };
|
||||
const iamRows: IamRow[] = iamUserIds.length > 0
|
||||
? await this.dataSource.query<IamRow[]>(
|
||||
`SELECT id, email, name, phone_number FROM iam.users WHERE id = ANY($1)`,
|
||||
[iamUserIds],
|
||||
).catch(() => [])
|
||||
: [];
|
||||
const iamMap = new Map(iamRows.map(r => [r.id, r]));
|
||||
const items = agents
|
||||
.map(a => {
|
||||
const iam = a.iamUserId ? iamMap.get(a.iamUserId) ?? null : null;
|
||||
const fullName = iam?.name?.en ?? iam?.name?.am ?? null;
|
||||
if (filters.search) {
|
||||
const q = filters.search.toLowerCase();
|
||||
const matches = a.agentCode.toLowerCase().includes(q)
|
||||
|| (iam?.email ?? '').toLowerCase().includes(q)
|
||||
|| (fullName ?? '').toLowerCase().includes(q);
|
||||
if (!matches) return null;
|
||||
}
|
||||
return {
|
||||
...a,
|
||||
user: iam ? { fullName, email: iam.email, phone: iam.phone_number } : null,
|
||||
};
|
||||
})
|
||||
.filter(Boolean);
|
||||
return { items, total: items.length };
|
||||
}
|
||||
|
||||
async createAgentBooking(dto: CreateAgentBookingDto) {
|
||||
const agent = await this.prisma.agent.findUnique({ where: { id: dto.agentId } });
|
||||
@@ -139,4 +183,31 @@ export class AgentsService {
|
||||
if (!agent) throw new NotFoundException('No agent profile found for this user');
|
||||
return agent;
|
||||
}
|
||||
|
||||
async createAgent(dto: { iamUserId: string; agentCode?: string; commissionRate?: number }) {
|
||||
const existing = await this.prisma.agent.findUnique({ where: { iamUserId: dto.iamUserId } });
|
||||
if (existing) throw new BadRequestException('An agent profile already exists for this user');
|
||||
const agentCode = dto.agentCode || `AG${String(Date.now()).slice(-4)}`;
|
||||
return this.prisma.agent.create({
|
||||
data: {
|
||||
iamUserId: dto.iamUserId,
|
||||
agentCode,
|
||||
commissionRate: dto.commissionRate ?? 5,
|
||||
active: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async updateAgent(id: string, dto: { agentCode?: string; commissionRate?: number; active?: boolean }) {
|
||||
const agent = await this.prisma.agent.findUnique({ where: { id } });
|
||||
if (!agent) throw new NotFoundException('Agent not found');
|
||||
return this.prisma.agent.update({
|
||||
where: { id },
|
||||
data: {
|
||||
...(dto.agentCode !== undefined && { agentCode: dto.agentCode }),
|
||||
...(dto.commissionRate !== undefined && { commissionRate: dto.commissionRate }),
|
||||
...(dto.active !== undefined && { active: dto.active }),
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user