import { Controller, Get, Post, Patch, Delete, Body, Param, Query, ParseUUIDPipe, HttpCode, HttpStatus } from '@nestjs/common'; import { ApiOperation, ApiTags } from '@nestjs/swagger'; import { CurrentUser } from '@edr/api-common'; import { CompaniesService } from './companies.service'; import { CreateCompanyDto } from './dto/create-company.dto'; import { UpdateCompanyDto } from './dto/update-company.dto'; import { CreateExternalProfileDto } from './dto/create-external-profile.dto'; import { CreateFFClientDto } from './dto/create-ff-client.dto'; import { CreateCompanyWithProfileDto } from './dto/create-company-with-profile.dto'; import { ResponseCompanyDto } from './dto/response-company.dto'; import { ResponseExternalProfileDto } from './dto/response-external-profile.dto'; import { ResponseFFClientDto } from './dto/response-ff-client.dto'; import { CompanyInfoResponseDto } from './dto/company-info-response.dto'; interface CurrentIamUser { id: string; name?: { en: string; am: string }; email?: string; phoneNumber?: string; } @ApiTags('Companies') @Controller('companies') export class CompaniesController { constructor(private readonly companiesService: CompaniesService) {} @Get('getInfo') @ApiOperation({ summary: 'Get company info for the current user' }) async getInfo(@CurrentUser() user: CurrentIamUser): Promise { const { profile, company } = await this.companiesService.getCompanyInfoByUserId(user.id); return new CompanyInfoResponseDto(profile, company); } @Post('create') @ApiOperation({ summary: 'Create a company with its associated external profile (onboarding)' }) async createWithProfile( @CurrentUser() user: CurrentIamUser, @Body() dto: CreateCompanyWithProfileDto, ): Promise { const nameParts = (user.name?.en ?? '').split(' '); const { profile, company } = await this.companiesService.createCompanyWithProfile( { userId: user.id, firstName: nameParts[0] || '', lastName: nameParts.slice(-1)[0] || '', email: user.email ?? '', phone: user.phoneNumber ?? '', }, dto, ); return new CompanyInfoResponseDto(profile, company); } @Post() @ApiOperation({ summary: 'Create a new company (customer, forwarder, transporter, broker)' }) async create(@Body() dto: CreateCompanyDto): Promise { const company = await this.companiesService.createCompany(dto); return new ResponseCompanyDto(company); } @Get() @ApiOperation({ summary: 'List all companies' }) async findAll(): Promise { const companies = await this.companiesService.findAllCompanies(); return companies.map((c) => new ResponseCompanyDto(c)); } @Get('type/:type') @ApiOperation({ summary: 'Find companies by type' }) async findByType(@Param('type') type: string): Promise { const companies = await this.companiesService.findAllCompanies(); return companies.filter((c) => c.type === type).map((c) => new ResponseCompanyDto(c)); } @Get('search') @ApiOperation({ summary: 'Search companies by name' }) async search(@Query('name') name: string): Promise { const companies = await this.companiesService.findAllCompanies(); return companies .filter((c) => c.name.toLowerCase().includes(name.toLowerCase())) .map((c) => new ResponseCompanyDto(c)); } @Get(':id') @ApiOperation({ summary: 'Get company by ID' }) async findById(@Param('id', ParseUUIDPipe) id: string): Promise { const company = await this.companiesService.findCompanyById(id); return new ResponseCompanyDto(company); } @Patch(':id') @ApiOperation({ summary: 'Update a company' }) async update( @Param('id', ParseUUIDPipe) id: string, @Body() dto: UpdateCompanyDto, ): Promise { const company = await this.companiesService.updateCompany(id, dto); return new ResponseCompanyDto(company); } @Delete(':id') @ApiOperation({ summary: 'Soft-delete a company' }) @HttpCode(HttpStatus.NO_CONTENT) async remove(@Param('id', ParseUUIDPipe) id: string): Promise { await this.companiesService.deleteCompany(id); } @Post(':companyId/profiles') @ApiOperation({ summary: 'Add a profile (employee) to a company' }) async createProfile( @Param('companyId', ParseUUIDPipe) companyId: string, @Body() dto: CreateExternalProfileDto, ): Promise { const profile = await this.companiesService.createProfile({ ...dto, companyId }); return new ResponseExternalProfileDto(profile); } @Get(':companyId/profiles') @ApiOperation({ summary: 'List profiles for a company' }) async listProfiles( @Param('companyId', ParseUUIDPipe) companyId: string, ): Promise { const profiles = await this.companiesService.findProfilesByCompany(companyId); return profiles.map((p) => new ResponseExternalProfileDto(p)); } @Get('profile/user/:userId') @ApiOperation({ summary: 'Get profile by IAM user ID' }) async findProfileByUser( @Param('userId', ParseUUIDPipe) userId: string, ): Promise { const profile = await this.companiesService.findProfileByUserId(userId); return new ResponseExternalProfileDto(profile); } @Post('ff-clients') @ApiOperation({ summary: 'Link a forwarder to a client company' }) async createFFClient(@Body() dto: CreateFFClientDto): Promise { const client = await this.companiesService.createFFClient(dto); return new ResponseFFClientDto(client); } @Get(':forwarderCompanyId/clients') @ApiOperation({ summary: 'List clients of a forwarder' }) async listFFClients( @Param('forwarderCompanyId', ParseUUIDPipe) forwarderCompanyId: string, ): Promise { const clients = await this.companiesService.findForwarderClients(forwarderCompanyId); return clients.map((c) => new ResponseFFClientDto(c)); } @Delete('ff-clients/:id') @ApiOperation({ summary: 'Remove a forwarder-client relationship' }) @HttpCode(HttpStatus.NO_CONTENT) async removeFFClient(@Param('id', ParseUUIDPipe) id: string): Promise { await this.companiesService.deleteFFClient(id); } }