using GerbilManagerWebAPI.Models; namespace GerbilManagerWebAPI.Services { /// /// Central status-derivation logic. Every write path (create/update gerbil, SaleContract /// Abgabe, import, startup sweep) calls Apply() after setting the other fields so the /// derived statuses (Deceased, GivenAway) are always consistent. /// /// Precedence (highest wins): /// 1) DateOfDeath set → Deceased (explicit, always) /// 2) Abgabe (ReceiverContactId set) → GivenAway /// 3) Age > MaxAgeYears without a death date or Abgabe → Deceased (presumed) /// 4) User-supplied {Breeding, Pet, ForSale}; defaults Breeding if invalid /// /// Age-based death is time-dependent. The stored column is kept up-to-date by: /// a) Apply() on every write (catches the animal at write time) /// b) A startup sweep in Program.cs (catches animals that silently crossed the threshold) /// Gridify filters on the stored value, so status==Breeding never surfaces >7y animals. /// public static class GerbilStatusService { public const int MaxAgeYears = 7; /// Derives and sets g.Status using the gerbil's current field values. /// Must be called AFTER all other fields (DateOfDeath, ReceiverContactId, DateOfBirth) /// have been applied. today = DateOnly.FromDateTime(DateTime.UtcNow). public static void Apply(Gerbil g, DateOnly today) { g.Status = Derive(g.Status, g.DateOfBirth, g.DateOfDeath, isAbgegeben: g.ReceiverContactId is not null, today); } /// Pure derivation — useful for tests and the migration backfill. public static GerbilStatus Derive( GerbilStatus requested, DateOnly? dateOfBirth, DateOnly? dateOfDeath, bool isAbgegeben, DateOnly today) { if (dateOfDeath is not null) return GerbilStatus.Deceased; if (isAbgegeben) return GerbilStatus.GivenAway; if (dateOfBirth is not null && IsOlderThan(dateOfBirth.Value, MaxAgeYears, today)) return GerbilStatus.Deceased; return requested is GerbilStatus.Breeding or GerbilStatus.Pet or GerbilStatus.ForSale ? requested : GerbilStatus.Breeding; } private static bool IsOlderThan(DateOnly dob, int years, DateOnly today) => today >= dob.AddYears(years); } }