Ajout endpoint mise à jour de solde
This commit is contained in:
parent
7fd2c4d7fe
commit
6a0b4049b6
@ -6,10 +6,11 @@ import { AuthModule } from './auth/auth.module'
|
|||||||
import { GeolocationsModule } from './geolocations/geolocations.module'
|
import { GeolocationsModule } from './geolocations/geolocations.module'
|
||||||
import { ChallengesModule } from './challenges/challenges.module'
|
import { ChallengesModule } from './challenges/challenges.module'
|
||||||
import { ChallengeActionsModule } from './challenge-actions/challenge-actions.module'
|
import { ChallengeActionsModule } from './challenge-actions/challenge-actions.module'
|
||||||
import { TrainsModule } from './trains/trains.module';
|
import { TrainsModule } from './trains/trains.module'
|
||||||
|
import { MoneyUpdatesModule } from './money-updates/money-updates.module'
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [PrismaModule, UsersModule, AuthModule, GeolocationsModule, ChallengesModule, ChallengeActionsModule, TrainsModule],
|
imports: [PrismaModule, UsersModule, AuthModule, GeolocationsModule, ChallengesModule, ChallengeActionsModule, TrainsModule, MoneyUpdatesModule],
|
||||||
providers: [PrismaService],
|
providers: [PrismaService],
|
||||||
})
|
})
|
||||||
export class AppModule {}
|
export class AppModule {}
|
||||||
|
31
server/src/money-updates/dto/create-money-update.dto.ts
Normal file
31
server/src/money-updates/dto/create-money-update.dto.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { ApiProperty } from "@nestjs/swagger"
|
||||||
|
import { MoneyUpdateType } from "@prisma/client"
|
||||||
|
import { Type } from "class-transformer"
|
||||||
|
import { IsEnum, IsInt, IsOptional, IsUUID } from "class-validator"
|
||||||
|
|
||||||
|
export class CreateMoneyUpdateDto {
|
||||||
|
@IsInt()
|
||||||
|
@Type(() => Number)
|
||||||
|
@ApiProperty({ description: "Solde avant modification" })
|
||||||
|
before: number
|
||||||
|
|
||||||
|
@IsInt()
|
||||||
|
@Type(() => Number)
|
||||||
|
@ApiProperty({ description: "Solde après modification" })
|
||||||
|
after: number
|
||||||
|
|
||||||
|
@IsEnum(MoneyUpdateType)
|
||||||
|
@ApiProperty({ description: "Type de modification de solde" })
|
||||||
|
reason: MoneyUpdateType
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsInt()
|
||||||
|
@Type(() => Number)
|
||||||
|
@ApiProperty({ description: "Identifiant de la réalisation de défi, si la mise à jour est liée à un défi", nullable: true })
|
||||||
|
actionId?: number
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsUUID()
|
||||||
|
@ApiProperty({ description: "Identifiant du trajet acheté, si la mise à jour est liée à la réservation d'un train", nullable: true })
|
||||||
|
tripId?: string
|
||||||
|
}
|
4
server/src/money-updates/dto/update-money-update.dto.ts
Normal file
4
server/src/money-updates/dto/update-money-update.dto.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
import { PartialType } from '@nestjs/swagger'
|
||||||
|
import { CreateMoneyUpdateDto } from './create-money-update.dto'
|
||||||
|
|
||||||
|
export class UpdateMoneyUpdateDto extends PartialType(CreateMoneyUpdateDto) {}
|
30
server/src/money-updates/entities/money-update.entity.ts
Normal file
30
server/src/money-updates/entities/money-update.entity.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import { ApiProperty } from "@nestjs/swagger"
|
||||||
|
import { MoneyUpdate, MoneyUpdateType } from "@prisma/client"
|
||||||
|
import { IsOptional } from "class-validator"
|
||||||
|
|
||||||
|
export class MoneyUpdateEntity implements MoneyUpdate {
|
||||||
|
constructor (partial: Partial<MoneyUpdateEntity>) {
|
||||||
|
Object.assign(this, partial)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiProperty({ description: "Identifiant unique de la mise à jour de solde" })
|
||||||
|
id: number
|
||||||
|
|
||||||
|
@ApiProperty({ description: "Utilisateur⋅rice concerné⋅e par la mise à jour de solde" })
|
||||||
|
userId: number
|
||||||
|
|
||||||
|
@ApiProperty({ description: "Solde avant modification" })
|
||||||
|
before: number
|
||||||
|
|
||||||
|
@ApiProperty({ description: "Solde après modification" })
|
||||||
|
after: number
|
||||||
|
|
||||||
|
@ApiProperty({ description: "Type de modification de solde" })
|
||||||
|
reason: MoneyUpdateType
|
||||||
|
|
||||||
|
@ApiProperty({ description: "Identifiant de la réalisation de défi, si la mise à jour est liée à un défi", nullable: true })
|
||||||
|
actionId: number
|
||||||
|
|
||||||
|
@ApiProperty({ description: "Identifiant du trajet acheté, si la mise à jour est liée à la réservation d'un train", nullable: true })
|
||||||
|
tripId: string
|
||||||
|
}
|
20
server/src/money-updates/money-updates.controller.spec.ts
Normal file
20
server/src/money-updates/money-updates.controller.spec.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { Test, TestingModule } from '@nestjs/testing'
|
||||||
|
import { MoneyUpdatesController } from './money-updates.controller'
|
||||||
|
import { MoneyUpdatesService } from './money-updates.service'
|
||||||
|
|
||||||
|
describe('MoneyUpdatesController', () => {
|
||||||
|
let controller: MoneyUpdatesController
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
controllers: [MoneyUpdatesController],
|
||||||
|
providers: [MoneyUpdatesService],
|
||||||
|
}).compile()
|
||||||
|
|
||||||
|
controller = module.get<MoneyUpdatesController>(MoneyUpdatesController)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(controller).toBeDefined()
|
||||||
|
})
|
||||||
|
})
|
76
server/src/money-updates/money-updates.controller.ts
Normal file
76
server/src/money-updates/money-updates.controller.ts
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
import { Controller, Get, Post, Body, Patch, Param, Delete, HttpCode, UseGuards, Query, NotFoundException, ParseIntPipe, Req } from '@nestjs/common'
|
||||||
|
import { MoneyUpdatesService } from './money-updates.service'
|
||||||
|
import { CreateMoneyUpdateDto } from './dto/create-money-update.dto'
|
||||||
|
import { UpdateMoneyUpdateDto } from './dto/update-money-update.dto'
|
||||||
|
import { AuthenticatedRequest, JwtAuthGuard } from 'src/auth/jwt-auth.guard'
|
||||||
|
import { ApiBearerAuth, ApiCreatedResponse, ApiForbiddenResponse, ApiNotFoundResponse, ApiOkResponse, ApiUnauthorizedResponse } from '@nestjs/swagger'
|
||||||
|
import { MoneyUpdateEntity } from './entities/money-update.entity'
|
||||||
|
import { ApiOkResponsePaginated, paginateOutput } from 'src/common/utils/pagination.utils'
|
||||||
|
import { QueryPaginationDto } from 'src/common/dto/pagination-query.dto'
|
||||||
|
import { UserFilterDto } from 'src/common/dto/user_filter.dto'
|
||||||
|
import { PaginateOutputDto } from 'src/common/dto/pagination-output.dto'
|
||||||
|
|
||||||
|
@Controller('money-updates')
|
||||||
|
export class MoneyUpdatesController {
|
||||||
|
constructor(private readonly moneyUpdatesService: MoneyUpdatesService) {}
|
||||||
|
|
||||||
|
@Post()
|
||||||
|
@HttpCode(201)
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@ApiBearerAuth()
|
||||||
|
@ApiCreatedResponse({ type: MoneyUpdateEntity, description: "Objet créé avec succès" })
|
||||||
|
@ApiUnauthorizedResponse({ description: "Non authentifié⋅e" })
|
||||||
|
@ApiForbiddenResponse({ description: "Permission refusée" })
|
||||||
|
async create(@Req() request: AuthenticatedRequest, @Body() createMoneyUpdateDto: CreateMoneyUpdateDto): Promise<MoneyUpdateEntity> {
|
||||||
|
const moneyUpdate = await this.moneyUpdatesService.create(request.user, createMoneyUpdateDto)
|
||||||
|
return new MoneyUpdateEntity(moneyUpdate)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get()
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@ApiBearerAuth()
|
||||||
|
@ApiOkResponsePaginated(MoneyUpdateEntity)
|
||||||
|
@ApiUnauthorizedResponse({ description: "Non authentifié⋅e" })
|
||||||
|
@ApiForbiddenResponse({ description: "Permission refusée" })
|
||||||
|
async findAll(@Query() queryPagination: QueryPaginationDto, @Query() userFilter: UserFilterDto): Promise<PaginateOutputDto<MoneyUpdateEntity>> {
|
||||||
|
const [trains, total] = await this.moneyUpdatesService.findAll(queryPagination, userFilter)
|
||||||
|
return paginateOutput<MoneyUpdateEntity>(trains.map(train => new MoneyUpdateEntity(train)), total, queryPagination)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get(':id')
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@ApiBearerAuth()
|
||||||
|
@ApiOkResponse({ type: MoneyUpdateEntity })
|
||||||
|
@ApiUnauthorizedResponse({ description: "Non authentifié⋅e" })
|
||||||
|
@ApiForbiddenResponse({ description: "Permission refusée" })
|
||||||
|
@ApiNotFoundResponse({ description: "Objet non trouvé" })
|
||||||
|
async findOne(@Param('id', ParseIntPipe) id: number): Promise<MoneyUpdateEntity> {
|
||||||
|
const train = await this.moneyUpdatesService.findOne(id)
|
||||||
|
if (!train)
|
||||||
|
throw new NotFoundException(`Trajet en train inexistant avec l'identifiant ${id}`)
|
||||||
|
return new MoneyUpdateEntity(train)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch(':id')
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@ApiBearerAuth()
|
||||||
|
@ApiOkResponse({ type: MoneyUpdateEntity })
|
||||||
|
@ApiUnauthorizedResponse({ description: "Non authentifié⋅e" })
|
||||||
|
@ApiForbiddenResponse({ description: "Permission refusée" })
|
||||||
|
@ApiNotFoundResponse({ description: "Objet non trouvé" })
|
||||||
|
async update(@Param('id', ParseIntPipe) id: number, @Body() updateMoneyUpdateDto: UpdateMoneyUpdateDto) {
|
||||||
|
return await this.moneyUpdatesService.update(id, updateMoneyUpdateDto)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Delete(':id')
|
||||||
|
@HttpCode(204)
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@ApiBearerAuth()
|
||||||
|
@ApiOkResponse({ type: MoneyUpdateEntity })
|
||||||
|
@ApiUnauthorizedResponse({ description: "Non authentifié⋅e" })
|
||||||
|
@ApiForbiddenResponse({ description: "Permission refusée" })
|
||||||
|
@ApiNotFoundResponse({ description: "Objet non trouvé" })
|
||||||
|
async remove(@Param('id', ParseIntPipe) id: number) {
|
||||||
|
await this.moneyUpdatesService.remove(id)
|
||||||
|
}
|
||||||
|
}
|
11
server/src/money-updates/money-updates.module.ts
Normal file
11
server/src/money-updates/money-updates.module.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { Module } from '@nestjs/common'
|
||||||
|
import { MoneyUpdatesService } from './money-updates.service'
|
||||||
|
import { MoneyUpdatesController } from './money-updates.controller'
|
||||||
|
import { PrismaModule } from 'src/prisma/prisma.module'
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
controllers: [MoneyUpdatesController],
|
||||||
|
providers: [MoneyUpdatesService],
|
||||||
|
imports: [PrismaModule],
|
||||||
|
})
|
||||||
|
export class MoneyUpdatesModule {}
|
18
server/src/money-updates/money-updates.service.spec.ts
Normal file
18
server/src/money-updates/money-updates.service.spec.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { Test, TestingModule } from '@nestjs/testing'
|
||||||
|
import { MoneyUpdatesService } from './money-updates.service'
|
||||||
|
|
||||||
|
describe('MoneyUpdatesService', () => {
|
||||||
|
let service: MoneyUpdatesService
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
providers: [MoneyUpdatesService],
|
||||||
|
}).compile()
|
||||||
|
|
||||||
|
service = module.get<MoneyUpdatesService>(MoneyUpdatesService)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(service).toBeDefined()
|
||||||
|
})
|
||||||
|
})
|
53
server/src/money-updates/money-updates.service.ts
Normal file
53
server/src/money-updates/money-updates.service.ts
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import { Injectable } from '@nestjs/common'
|
||||||
|
import { CreateMoneyUpdateDto } from './dto/create-money-update.dto'
|
||||||
|
import { UpdateMoneyUpdateDto } from './dto/update-money-update.dto'
|
||||||
|
import { PrismaService } from 'src/prisma/prisma.service'
|
||||||
|
import { MoneyUpdate, User } from '@prisma/client'
|
||||||
|
import { QueryPaginationDto } from 'src/common/dto/pagination-query.dto'
|
||||||
|
import { UserFilterDto } from 'src/common/dto/user_filter.dto'
|
||||||
|
import { paginate } from 'src/common/utils/pagination.utils'
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class MoneyUpdatesService {
|
||||||
|
constructor(private prisma: PrismaService) { }
|
||||||
|
|
||||||
|
async create(user: User, createMoneyUpdateDto: CreateMoneyUpdateDto): Promise<MoneyUpdate> {
|
||||||
|
return await this.prisma.moneyUpdate.create({
|
||||||
|
data: {
|
||||||
|
...createMoneyUpdateDto,
|
||||||
|
userId: user.id,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async findAll(queryPagination: QueryPaginationDto, userFilter: UserFilterDto): Promise<[MoneyUpdate[], number]> {
|
||||||
|
return [
|
||||||
|
await this.prisma.moneyUpdate.findMany({
|
||||||
|
where: userFilter,
|
||||||
|
...paginate(queryPagination),
|
||||||
|
}),
|
||||||
|
await this.prisma.moneyUpdate.count({
|
||||||
|
where: userFilter,
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
async findOne(id: number): Promise<MoneyUpdate> {
|
||||||
|
return await this.prisma.moneyUpdate.findUnique({
|
||||||
|
where: { id },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async update(id: number, updateMoneyUpdateDto: UpdateMoneyUpdateDto): Promise<MoneyUpdate> {
|
||||||
|
return await this.prisma.moneyUpdate.update({
|
||||||
|
where: { id },
|
||||||
|
data: updateMoneyUpdateDto,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async remove(id: number): Promise<MoneyUpdate> {
|
||||||
|
return await this.prisma.moneyUpdate.delete({
|
||||||
|
where: { id },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import { PartialType } from '@nestjs/swagger';
|
import { PartialType } from '@nestjs/swagger'
|
||||||
import { CreateTrainDto } from './create-train.dto';
|
import { CreateTrainDto } from './create-train.dto'
|
||||||
|
|
||||||
export class UpdateTrainDto extends PartialType(CreateTrainDto) {}
|
export class UpdateTrainDto extends PartialType(CreateTrainDto) {}
|
||||||
|
@ -59,8 +59,8 @@ export class TrainsController {
|
|||||||
@ApiUnauthorizedResponse({ description: "Non authentifié⋅e" })
|
@ApiUnauthorizedResponse({ description: "Non authentifié⋅e" })
|
||||||
@ApiForbiddenResponse({ description: "Permission refusée" })
|
@ApiForbiddenResponse({ description: "Permission refusée" })
|
||||||
@ApiNotFoundResponse({ description: "Objet non trouvé" })
|
@ApiNotFoundResponse({ description: "Objet non trouvé" })
|
||||||
async update(@Param('id') id: string, @Body() updateChallengeDto: UpdateTrainDto) {
|
async update(@Param('id') id: string, @Body() updateTrainDto: UpdateTrainDto) {
|
||||||
return await this.trainsService.update(id, updateChallengeDto)
|
return await this.trainsService.update(id, updateTrainDto)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Delete(':id')
|
@Delete(':id')
|
||||||
|
Loading…
Reference in New Issue
Block a user