forked from wangziqi/gongxue-base
refactor(deposits): remove inline installment creation
This commit is contained in:
@@ -16,7 +16,7 @@ import { Student } from '../entities/student.entity';
|
|||||||
import { DepositsService } from './deposits.service';
|
import { DepositsService } from './deposits.service';
|
||||||
import { NotificationsService } from '../notifications/notifications.service';
|
import { NotificationsService } from '../notifications/notifications.service';
|
||||||
import { NotificationType } from '../entities/notification.entity';
|
import { NotificationType } from '../entities/notification.entity';
|
||||||
import { CreateDepositDto, RefundDepositDto, CreateDepositWithInstallmentsDto } from './dto/deposit.dto';
|
import { CreateDepositDto, RefundDepositDto } from './dto/deposit.dto';
|
||||||
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
|
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
|
||||||
import { OperationLogsService } from '../operation-logs/operation-logs.service';
|
import { OperationLogsService } from '../operation-logs/operation-logs.service';
|
||||||
import { extractRequestInfo } from '../common/request-utils';
|
import { extractRequestInfo } from '../common/request-utils';
|
||||||
@@ -61,7 +61,7 @@ export class DepositsController {
|
|||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
@RequirePermission('deposit:create')
|
@RequirePermission('deposit:create')
|
||||||
async create(@Body() dto: CreateDepositDto | CreateDepositWithInstallmentsDto, @Request() req: any) {
|
async create(@Body() dto: CreateDepositDto, @Request() req: any) {
|
||||||
const { ipAddress, userAgent } = extractRequestInfo(req);
|
const { ipAddress, userAgent } = extractRequestInfo(req);
|
||||||
const result = await this.service.create(dto, req.user?.id);
|
const result = await this.service.create(dto, req.user?.id);
|
||||||
await this.logService.log({
|
await this.logService.log({
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { Deposit } from '../entities/deposit.entity';
|
|||||||
import { Student } from '../entities/student.entity';
|
import { Student } from '../entities/student.entity';
|
||||||
import { DepositInstallment } from '../entities/deposit-installment.entity';
|
import { DepositInstallment } from '../entities/deposit-installment.entity';
|
||||||
|
|
||||||
import { CreateDepositDto, RefundDepositDto, CreateDepositWithInstallmentsDto } from './dto/deposit.dto';
|
import { CreateDepositDto, RefundDepositDto } from './dto/deposit.dto';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DepositsService {
|
export class DepositsService {
|
||||||
@@ -55,17 +55,6 @@ export class DepositsService {
|
|||||||
recordedBy: userId,
|
recordedBy: userId,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (dto instanceof CreateDepositWithInstallmentsDto && dto.installments?.length) {
|
|
||||||
deposit.installments = dto.installments.map((i) => {
|
|
||||||
const inst = this.installmentRepo.create({
|
|
||||||
amount: i.amount,
|
|
||||||
dueDate: i.dueDate,
|
|
||||||
status: 'pending',
|
|
||||||
});
|
|
||||||
return inst;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.repo.save(deposit);
|
return this.repo.save(deposit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
19
apps/server/src/deposits/dto/deposit.dto.spec.ts
Normal file
19
apps/server/src/deposits/dto/deposit.dto.spec.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import 'reflect-metadata';
|
||||||
|
import { validate } from 'class-validator';
|
||||||
|
import { CreateDepositDto } from './deposit.dto';
|
||||||
|
|
||||||
|
describe('CreateDepositDto boundaries', () => {
|
||||||
|
it('removes inline installments because they are managed after deposit creation', async () => {
|
||||||
|
const dto = Object.assign(new CreateDepositDto(), {
|
||||||
|
studentId: 1,
|
||||||
|
amount: 500,
|
||||||
|
paidDate: '2026-07-13',
|
||||||
|
installments: [{ amount: 250, dueDate: '2026-08-01' }],
|
||||||
|
});
|
||||||
|
|
||||||
|
await validate(dto, { whitelist: true });
|
||||||
|
|
||||||
|
expect(dto).toMatchObject({ studentId: 1, amount: 500, paidDate: '2026-07-13' });
|
||||||
|
expect(dto).not.toHaveProperty('installments');
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
import { IsInt, IsNumber, IsString, IsOptional, ValidateNested } from 'class-validator';
|
import { IsInt, IsNumber, IsString, IsOptional } from 'class-validator';
|
||||||
import { Type } from 'class-transformer';
|
|
||||||
|
|
||||||
export class CreateDepositDto {
|
export class CreateDepositDto {
|
||||||
@IsInt()
|
@IsInt()
|
||||||
@@ -16,16 +15,6 @@ export class CreateDepositDto {
|
|||||||
notes?: string;
|
notes?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CreateInstallmentDto {
|
|
||||||
@IsNumber()
|
|
||||||
amount: number;
|
|
||||||
|
|
||||||
@IsString()
|
|
||||||
dueDate: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export class RefundDepositDto {
|
export class RefundDepositDto {
|
||||||
@IsString()
|
@IsString()
|
||||||
refundDate: string;
|
refundDate: string;
|
||||||
@@ -42,9 +31,3 @@ export class RefundDepositDto {
|
|||||||
@IsString()
|
@IsString()
|
||||||
notes?: string;
|
notes?: string;
|
||||||
}
|
}
|
||||||
export class CreateDepositWithInstallmentsDto extends CreateDepositDto {
|
|
||||||
@IsOptional()
|
|
||||||
@ValidateNested({ each: true })
|
|
||||||
@Type(() => CreateInstallmentDto)
|
|
||||||
installments?: CreateInstallmentDto[];
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user