/** * 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 = { 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; } }