This commit is contained in:
2025-12-21 17:05:36 +01:00
parent 08b0d59e45
commit f2d8a23583
66 changed files with 1131 additions and 1342 deletions

View File

@@ -5,13 +5,12 @@
*/
import type { IMembershipFeeRepository, IMemberPaymentRepository } from '../../domain/repositories/IMembershipFeeRepository';
import type { MemberPaymentStatus, MemberPayment } from '../../domain/entities/MemberPayment';
import type {
IUpdateMemberPaymentPresenter,
UpdateMemberPaymentResultDTO,
UpdateMemberPaymentViewModel,
} from '../presenters/IUpdateMemberPaymentPresenter';
import type { MemberPayment } from '../../domain/entities/MemberPayment';
import { MemberPaymentStatus } from '../../domain/entities/MemberPayment';
import type { UseCase } from '@core/shared/application/UseCase';
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
import { Result } from '@core/shared/application/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
const PLATFORM_FEE_RATE = 0.10;
@@ -22,25 +21,27 @@ export interface UpdateMemberPaymentInput {
paidAt?: Date | string;
}
export interface UpdateMemberPaymentResult {
payment: MemberPayment;
}
export type UpdateMemberPaymentErrorCode = 'MEMBERSHIP_FEE_NOT_FOUND';
export class UpdateMemberPaymentUseCase
implements UseCase<UpdateMemberPaymentInput, UpdateMemberPaymentResultDTO, UpdateMemberPaymentViewModel, IUpdateMemberPaymentPresenter>
implements UseCase<UpdateMemberPaymentInput, void, UpdateMemberPaymentErrorCode>
{
constructor(
private readonly membershipFeeRepository: IMembershipFeeRepository,
private readonly memberPaymentRepository: IMemberPaymentRepository,
private readonly output: UseCaseOutputPort<UpdateMemberPaymentResult>,
) {}
async execute(
input: UpdateMemberPaymentInput,
presenter: IUpdateMemberPaymentPresenter,
): Promise<void> {
presenter.reset();
async execute(input: UpdateMemberPaymentInput): Promise<Result<void, ApplicationErrorCode<UpdateMemberPaymentErrorCode>>> {
const { feeId, driverId, status, paidAt } = input;
const fee = await this.membershipFeeRepository.findById(feeId);
if (!fee) {
throw new Error('Membership fee configuration not found');
return Result.err({ code: 'MEMBERSHIP_FEE_NOT_FOUND' as const });
}
let payment = await this.memberPaymentRepository.findByFeeIdAndDriverId(feeId, driverId);
@@ -57,7 +58,7 @@ export class UpdateMemberPaymentUseCase
amount: fee.amount,
platformFee,
netAmount,
status: 'pending' as MemberPaymentStatus,
status: MemberPaymentStatus.PENDING,
dueDate: new Date(),
};
payment = await this.memberPaymentRepository.create(newPayment);
@@ -66,26 +67,14 @@ export class UpdateMemberPaymentUseCase
if (status) {
payment.status = status;
}
if (paidAt || status === ('paid' as MemberPaymentStatus)) {
if (paidAt || status === MemberPaymentStatus.PAID) {
payment.paidAt = paidAt ? new Date(paidAt as string) : new Date();
}
const updatedPayment = await this.memberPaymentRepository.update(payment);
const dto: UpdateMemberPaymentResultDTO = {
payment: {
id: updatedPayment.id,
feeId: updatedPayment.feeId,
driverId: updatedPayment.driverId,
amount: updatedPayment.amount,
platformFee: updatedPayment.platformFee,
netAmount: updatedPayment.netAmount,
status: updatedPayment.status,
dueDate: updatedPayment.dueDate,
paidAt: updatedPayment.paidAt,
},
};
this.output.present({ payment: updatedPayment });
presenter.present(dto);
return Result.ok(undefined);
}
}