xpeditis2.0/apps/backend/src/domain/value-objects/booking-status.vo.ts
David-Henri ARNAUD 1044900e98 feature phase
2025-10-08 16:56:27 +02:00

111 lines
2.5 KiB
TypeScript

/**
* BookingStatus Value Object
*
* Represents the current status of a booking
*/
import { InvalidBookingStatusException } from '../exceptions/invalid-booking-status.exception';
export type BookingStatusValue =
| 'draft'
| 'pending_confirmation'
| 'confirmed'
| 'in_transit'
| 'delivered'
| 'cancelled';
export class BookingStatus {
private static readonly VALID_STATUSES: BookingStatusValue[] = [
'draft',
'pending_confirmation',
'confirmed',
'in_transit',
'delivered',
'cancelled',
];
private static readonly STATUS_TRANSITIONS: Record<BookingStatusValue, BookingStatusValue[]> = {
draft: ['pending_confirmation', 'cancelled'],
pending_confirmation: ['confirmed', 'cancelled'],
confirmed: ['in_transit', 'cancelled'],
in_transit: ['delivered', 'cancelled'],
delivered: [],
cancelled: [],
};
private readonly _value: BookingStatusValue;
private constructor(value: BookingStatusValue) {
this._value = value;
}
get value(): BookingStatusValue {
return this._value;
}
/**
* Create BookingStatus from string
*/
static create(value: string): BookingStatus {
if (!BookingStatus.isValid(value)) {
throw new InvalidBookingStatusException(value);
}
return new BookingStatus(value as BookingStatusValue);
}
/**
* Validate status value
*/
static isValid(value: string): boolean {
return BookingStatus.VALID_STATUSES.includes(value as BookingStatusValue);
}
/**
* Check if transition to another status is allowed
*/
canTransitionTo(newStatus: BookingStatus): boolean {
const allowedTransitions = BookingStatus.STATUS_TRANSITIONS[this._value];
return allowedTransitions.includes(newStatus._value);
}
/**
* Transition to new status
*/
transitionTo(newStatus: BookingStatus): BookingStatus {
if (!this.canTransitionTo(newStatus)) {
throw new Error(
`Invalid status transition from ${this._value} to ${newStatus._value}`
);
}
return newStatus;
}
/**
* Check if booking is in a final state
*/
isFinal(): boolean {
return this._value === 'delivered' || this._value === 'cancelled';
}
/**
* Check if booking can be modified
*/
canBeModified(): boolean {
return this._value === 'draft' || this._value === 'pending_confirmation';
}
/**
* Equality check
*/
equals(other: BookingStatus): boolean {
return this._value === other._value;
}
/**
* String representation
*/
toString(): string {
return this._value;
}
}