diff --git a/prisma/schema.prisma b/prisma/schema.prisma index c6ad710..5912a88 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -139,15 +139,15 @@ model User { isActive Boolean @default(true) @map("is_active") // Relations - transporter Transporter? - packages Package[] - addresses Address[] - wallet Wallet? + transporter Transporter? + packages Package[] + addresses Address[] + wallet Wallet? notifications Notification[] - createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz() - updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz() - deletedAt DateTime? @map("deleted_at") @db.Timestamptz() + createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz() + updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz() + deletedAt DateTime? @map("deleted_at") @db.Timestamptz() @@map("users") } @@ -366,6 +366,7 @@ model PackageRecipient { model Package { id String @id @default(uuid()) @db.Uuid senderId String @map("sender_id") @db.Uuid + code Int @default(autoincrement()) items Json? @map("items_description") @db.JsonB originAddressId String @map("origin_address_id") @db.Uuid recipientId String @map("recipient_id") @db.Uuid @@ -403,6 +404,7 @@ model Package { model Trip { id String @id @default(uuid()) @db.Uuid transporterId String @map("transporter_id") @db.Uuid + code Int @default(autoincrement()) originId String @map("origin_id") @db.Uuid destinationId String @map("destination_id") @db.Uuid tripType TripTypeEnum @map("trip_type") diff --git a/src/modules/notification/notification.service.ts b/src/modules/notification/notification.service.ts index 296091d..394cfba 100644 --- a/src/modules/notification/notification.service.ts +++ b/src/modules/notification/notification.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@nestjs/common'; import { PrismaService } from '../prisma/prisma.service'; import { PrismaTransaction } from '../prisma/prisma.types'; -import { formatPrismaError } from 'src/common/utilities'; +import { formatPrismaError } from '../../common/utilities'; @Injectable() export class NotificationService { diff --git a/src/modules/package/dto/package-response.dto.ts b/src/modules/package/dto/package-response.dto.ts index 1a8d227..e5104c6 100644 --- a/src/modules/package/dto/package-response.dto.ts +++ b/src/modules/package/dto/package-response.dto.ts @@ -10,6 +10,9 @@ export class PackageCompactResponseDto { @Expose() id: string; + @Expose() + code: number; + @Expose() items: string[]; diff --git a/src/modules/package/dto/tracking-response.dto.ts b/src/modules/package/dto/tracking-response.dto.ts index 6876c30..61b45ae 100644 --- a/src/modules/package/dto/tracking-response.dto.ts +++ b/src/modules/package/dto/tracking-response.dto.ts @@ -51,6 +51,9 @@ class PackageTrackingDto { @Expose() sender: SenderDto; + @Expose() + code: number; + @Type(() => RecipientDto) @Expose() recipient: RecipientDto; diff --git a/src/modules/package/package.service.ts b/src/modules/package/package.service.ts index 5a25259..b952010 100644 --- a/src/modules/package/package.service.ts +++ b/src/modules/package/package.service.ts @@ -689,6 +689,7 @@ export class PackageService { }, package: { select: { + code: true, sender: { select: { firstName: true, diff --git a/src/modules/trip/dto/matched-request-response.dto.ts b/src/modules/trip/dto/matched-request-response.dto.ts index 8b28235..04e9438 100644 --- a/src/modules/trip/dto/matched-request-response.dto.ts +++ b/src/modules/trip/dto/matched-request-response.dto.ts @@ -10,6 +10,9 @@ class MatchedPackageDto { @Expose() id: string; + @Expose() + code: number; + @Type(() => UserCompactDto) @Expose() sender: UserCompactDto; diff --git a/src/modules/trip/dto/trip-response.dto.ts b/src/modules/trip/dto/trip-response.dto.ts index 69eec26..63087e0 100644 --- a/src/modules/trip/dto/trip-response.dto.ts +++ b/src/modules/trip/dto/trip-response.dto.ts @@ -1,6 +1,6 @@ import { TripStatusEnum, TripTypeEnum } from '../../../../generated/prisma'; import { CityDto } from '../../map/dto/city.dto'; -import { Expose, Transform, Type } from 'class-transformer'; +import { Expose, Type } from 'class-transformer'; import { VehicleCompactResponseDto } from '../../vehicle/dto/vehicle-response.dto'; import { ApiProperty } from '@nestjs/swagger'; @@ -8,6 +8,9 @@ export class TripCompactResponseDto { @Expose() id: string; + @Expose() + code: number; + @ApiProperty({ type: CityDto }) @Expose() @Type(() => CityDto) diff --git a/src/modules/trip/trip.service.spec.ts b/src/modules/trip/trip.service.spec.ts index 293fec1..ba60a83 100644 --- a/src/modules/trip/trip.service.spec.ts +++ b/src/modules/trip/trip.service.spec.ts @@ -642,19 +642,55 @@ describe('TripService', () => { it('should finish trip successfully', async () => { prisma.trip.findUniqueOrThrow.mockResolvedValueOnce({ status: TripStatusEnum.in_progress, - matchedRequests: [{ deliveryTime: new Date() }] + matchedRequests: [{ deliveryTime: new Date() }], + transporter: { + id: 'transporter-123', + firstTripDate: null + } + } as any); + prisma.$transaction.mockImplementation(async (callback) => callback(prisma)); + prisma.trip.update.mockResolvedValue({ ...mockTrip, status: TripStatusEnum.completed }); + prisma.transporter.update.mockResolvedValue({} as any); + + const result = await service.finishTrip('trip-123'); + + expect(result).toEqual({ ...mockTrip, status: TripStatusEnum.completed }); + expect(prisma.transporter.update).toHaveBeenCalledWith({ + where: { id: 'transporter-123' }, + data: { firstTripDate: expect.any(Date) } + }); + }); + + it('should finish trip successfully when transporter has firstTripDate', async () => { + prisma.trip.findUniqueOrThrow.mockResolvedValueOnce({ + status: TripStatusEnum.in_progress, + matchedRequests: [{ deliveryTime: new Date() }], + transporter: { + id: 'transporter-123', + firstTripDate: new Date('2023-01-01') + } } as any); + prisma.$transaction.mockImplementation(async (callback) => callback(prisma)); prisma.trip.update.mockResolvedValue({ ...mockTrip, status: TripStatusEnum.completed }); + prisma.transporter.update.mockResolvedValue({} as any); const result = await service.finishTrip('trip-123'); expect(result).toEqual({ ...mockTrip, status: TripStatusEnum.completed }); + expect(prisma.transporter.update).toHaveBeenCalledWith({ + where: { id: 'transporter-123' }, + data: { lastTripDate: expect.any(Date) } + }); }); it('should throw when not all packages are delivered', async () => { prisma.trip.findUniqueOrThrow.mockResolvedValueOnce({ status: TripStatusEnum.in_progress, - matchedRequests: [{ deliveryTime: null }] + matchedRequests: [{ deliveryTime: null }], + transporter: { + id: 'transporter-123', + firstTripDate: null + } } as any); await expect(service.finishTrip('trip-123')).rejects.toThrow( @@ -900,6 +936,7 @@ describe('TripService', () => { package: { select: { id: true, + code: true, sender: { select: { firstName: true, @@ -908,12 +945,12 @@ describe('TripService', () => { phoneNumber: true } }, + status: true, items: true, originAddress: true, recipient: true, weight: true, dimensions: true, - status: true, packageValue: true, isFragile: true, isPerishable: true, diff --git a/src/modules/trip/trip.service.ts b/src/modules/trip/trip.service.ts index a6bcb8c..0db1062 100644 --- a/src/modules/trip/trip.service.ts +++ b/src/modules/trip/trip.service.ts @@ -476,6 +476,7 @@ export class TripService { package: { select: { id: true, + code: true, sender: { select: { firstName: true, @@ -892,7 +893,8 @@ export class TripService { } return this.prisma.$transaction(async tx => { - tx.transporter.update({ + // Update transporter + await tx.transporter.update({ where: { id: transporter.id }, data: updateTransporter });