using System.ComponentModel.DataAnnotations; namespace JobsMedical.Web.Models; /// /// An open shift at a facility. The heart of the platform. /// Dates are stored as UTC / and displayed as Jalali. /// public class Shift { public int Id { get; set; } public int FacilityId { get; set; } public Facility Facility { get; set; } = null!; public int RoleId { get; set; } // نقش مورد نیاز (پزشک/پرستار/ماما/...) public Role Role { get; set; } = null!; public DateOnly Date { get; set; } // تاریخ شیفت (در نمایش به شمسی تبدیل می‌شود) public TimeOnly StartTime { get; set; } // ساعت شروع public TimeOnly EndTime { get; set; } // ساعت پایان [MaxLength(100)] public string SpecialtyRequired { get; set; } = "پزشک عمومی"; public ShiftType ShiftType { get; set; } = ShiftType.Day; public long? PayAmount { get; set; } // مبلغ (تومان)؛ null یعنی توافقی public PayType PayType { get; set; } = PayType.PerShift; [MaxLength(1500)] public string? Description { get; set; } // توضیحات public ShiftStatus Status { get; set; } = ShiftStatus.Open; public ShiftSource Source { get; set; } = ShiftSource.Admin; [MaxLength(500)] public string? SourceUrl { get; set; } // لینک منبع در صورت جمع‌آوری از کانال public DateTime CreatedAt { get; set; } = DateTime.UtcNow; public ICollection Applications { get; set; } = new List(); // Transient: distance (km) from the visitor when "near me" is active. Not persisted. [System.ComponentModel.DataAnnotations.Schema.NotMapped] public double? DistanceKm { get; set; } // Convenience (not mapped): duration in hours, handles overnight shifts. public double DurationHours { get { var span = EndTime.ToTimeSpan() - StartTime.ToTimeSpan(); if (span <= TimeSpan.Zero) span += TimeSpan.FromDays(1); // شیفت شب که به روز بعد می‌رسد return span.TotalHours; } } }