Files
gridpilot.gg/packages/racing/domain/value-objects/MembershipFee.ts
2025-12-11 11:25:22 +01:00

76 lines
1.7 KiB
TypeScript

/**
* Value Object: MembershipFee
* Represents membership fee configuration for league drivers
*/
import { RacingDomainValidationError } from '../errors/RacingDomainError';
import type { Money } from './Money';
export type MembershipFeeType = 'season' | 'monthly' | 'per_race';
export interface MembershipFeeProps {
type: MembershipFeeType;
amount: Money;
}
export class MembershipFee {
readonly type: MembershipFeeType;
readonly amount: Money;
private constructor(props: MembershipFeeProps) {
this.type = props.type;
this.amount = props.amount;
}
static create(type: MembershipFeeType, amount: Money): MembershipFee {
if (!type) {
throw new RacingDomainValidationError('MembershipFee type is required');
}
if (!amount) {
throw new RacingDomainValidationError('MembershipFee amount is required');
}
if (amount.amount < 0) {
throw new RacingDomainValidationError('MembershipFee amount cannot be negative');
}
return new MembershipFee({ type, amount });
}
/**
* Get platform fee for this membership fee
*/
getPlatformFee(): Money {
return this.amount.calculatePlatformFee();
}
/**
* Get net amount after platform fee
*/
getNetAmount(): Money {
return this.amount.calculateNetAmount();
}
/**
* Check if this is a recurring fee
*/
isRecurring(): boolean {
return this.type === 'monthly';
}
/**
* Get display name for fee type
*/
getDisplayName(): string {
switch (this.type) {
case 'season':
return 'Season Fee';
case 'monthly':
return 'Monthly Subscription';
case 'per_race':
return 'Per-Race Fee';
}
}
}