| | | 1 | | using MechanicsSoftware.Domain.Exceptions; |
| | | 2 | | |
| | | 3 | | namespace MechanicsSoftware.Domain.ValueObjects; |
| | | 4 | | |
| | 258 | 5 | | public sealed class BudgetStatus(BudgetStatus.Status value) : ValueObject |
| | | 6 | | { |
| | | 7 | | public enum Status |
| | | 8 | | { |
| | | 9 | | Pending, |
| | | 10 | | Approved, |
| | | 11 | | Rejected |
| | | 12 | | } |
| | | 13 | | |
| | 322 | 14 | | public Status Value => value; |
| | | 15 | | |
| | | 16 | | public BudgetStatus TransitionTo(Status newStatus) |
| | 78 | 17 | | { |
| | 78 | 18 | | if (Value == newStatus) |
| | 2 | 19 | | throw new DomainException($"Cannot transition from '{this}' to '{new BudgetStatus(newStatus)}': already in t |
| | | 20 | | |
| | 76 | 21 | | return (Value, newStatus) switch |
| | 76 | 22 | | { |
| | 50 | 23 | | (Status.Pending, Status.Approved) => new BudgetStatus(Status.Approved), |
| | 18 | 24 | | (Status.Pending, Status.Rejected) => new BudgetStatus(Status.Rejected), |
| | 4 | 25 | | (Status.Approved, _) => throw new DomainException("Cannot transition from 'APPROVED' state: it is terminal." |
| | 4 | 26 | | (Status.Rejected, _) => throw new DomainException("Cannot transition from 'REJECTED' state: it is terminal." |
| | 0 | 27 | | _ => throw new DomainException($"Invalid transition from '{this}' to '{new BudgetStatus(newStatus)}'.") |
| | 76 | 28 | | }; |
| | 68 | 29 | | } |
| | | 30 | | |
| | | 31 | | protected override IEnumerable<object?> GetEqualityComponents() |
| | 44 | 32 | | { |
| | 44 | 33 | | yield return Value; |
| | 16 | 34 | | } |
| | | 35 | | |
| | 102 | 36 | | public override string ToString() => Value switch |
| | 102 | 37 | | { |
| | 40 | 38 | | Status.Pending => "PENDING", |
| | 46 | 39 | | Status.Approved => "APPROVED", |
| | 16 | 40 | | Status.Rejected => "REJECTED", |
| | 0 | 41 | | _ => Value.ToString() |
| | 102 | 42 | | }; |
| | | 43 | | |
| | 116 | 44 | | public static BudgetStatus CreatePending() => new(Status.Pending); |
| | | 45 | | } |