rename to core
This commit is contained in:
126
core/racing/domain/entities/LeagueWallet.ts
Normal file
126
core/racing/domain/entities/LeagueWallet.ts
Normal file
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
* Domain Entity: LeagueWallet
|
||||
*
|
||||
* Represents a league's financial wallet.
|
||||
* Aggregate root for managing league finances and transactions.
|
||||
*/
|
||||
|
||||
import { RacingDomainValidationError, RacingDomainInvariantError } from '../errors/RacingDomainError';
|
||||
import type { IEntity } from '@gridpilot/shared/domain';
|
||||
|
||||
import type { Money } from '../value-objects/Money';
|
||||
import type { Transaction } from './Transaction';
|
||||
|
||||
export interface LeagueWalletProps {
|
||||
id: string;
|
||||
leagueId: string;
|
||||
balance: Money;
|
||||
transactionIds: string[];
|
||||
createdAt: Date;
|
||||
}
|
||||
|
||||
export class LeagueWallet implements IEntity<string> {
|
||||
readonly id: string;
|
||||
readonly leagueId: string;
|
||||
readonly balance: Money;
|
||||
readonly transactionIds: string[];
|
||||
readonly createdAt: Date;
|
||||
|
||||
private constructor(props: LeagueWalletProps) {
|
||||
this.id = props.id;
|
||||
this.leagueId = props.leagueId;
|
||||
this.balance = props.balance;
|
||||
this.transactionIds = props.transactionIds;
|
||||
this.createdAt = props.createdAt;
|
||||
}
|
||||
|
||||
static create(props: Omit<LeagueWalletProps, 'createdAt' | 'transactionIds'> & {
|
||||
createdAt?: Date;
|
||||
transactionIds?: string[];
|
||||
}): LeagueWallet {
|
||||
this.validate(props);
|
||||
|
||||
return new LeagueWallet({
|
||||
...props,
|
||||
createdAt: props.createdAt ?? new Date(),
|
||||
transactionIds: props.transactionIds ?? [],
|
||||
});
|
||||
}
|
||||
|
||||
private static validate(props: Omit<LeagueWalletProps, 'createdAt' | 'transactionIds'>): void {
|
||||
if (!props.id || props.id.trim().length === 0) {
|
||||
throw new RacingDomainValidationError('LeagueWallet ID is required');
|
||||
}
|
||||
|
||||
if (!props.leagueId || props.leagueId.trim().length === 0) {
|
||||
throw new RacingDomainValidationError('LeagueWallet leagueId is required');
|
||||
}
|
||||
|
||||
if (!props.balance) {
|
||||
throw new RacingDomainValidationError('LeagueWallet balance is required');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add funds to wallet (from sponsorship or membership payments)
|
||||
*/
|
||||
addFunds(netAmount: Money, transactionId: string): LeagueWallet {
|
||||
if (this.balance.currency !== netAmount.currency) {
|
||||
throw new RacingDomainInvariantError('Cannot add funds with different currency');
|
||||
}
|
||||
|
||||
const newBalance = this.balance.add(netAmount);
|
||||
|
||||
return new LeagueWallet({
|
||||
...this,
|
||||
balance: newBalance,
|
||||
transactionIds: [...this.transactionIds, transactionId],
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Withdraw funds from wallet
|
||||
* Domain rule: Cannot withdraw if insufficient balance
|
||||
*/
|
||||
withdrawFunds(amount: Money, transactionId: string): LeagueWallet {
|
||||
if (this.balance.currency !== amount.currency) {
|
||||
throw new RacingDomainInvariantError('Cannot withdraw funds with different currency');
|
||||
}
|
||||
|
||||
if (!this.balance.isGreaterThan(amount) && !this.balance.equals(amount)) {
|
||||
throw new RacingDomainInvariantError('Insufficient balance for withdrawal');
|
||||
}
|
||||
|
||||
const newBalance = this.balance.subtract(amount);
|
||||
|
||||
return new LeagueWallet({
|
||||
...this,
|
||||
balance: newBalance,
|
||||
transactionIds: [...this.transactionIds, transactionId],
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if wallet can withdraw a specific amount
|
||||
*/
|
||||
canWithdraw(amount: Money): boolean {
|
||||
if (this.balance.currency !== amount.currency) {
|
||||
return false;
|
||||
}
|
||||
return this.balance.isGreaterThan(amount) || this.balance.equals(amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current balance
|
||||
*/
|
||||
getBalance(): Money {
|
||||
return this.balance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all transaction IDs
|
||||
*/
|
||||
getTransactionIds(): string[] {
|
||||
return [...this.transactionIds];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user