using AutoMapper; using PowderCoating.Core.Entities; using PowderCoating.Application.DTOs.Appointment; namespace PowderCoating.Application.Mappings; public class AppointmentProfile : Profile { public AppointmentProfile() { // Appointment to AppointmentDto - Map all lookup properties from navigation CreateMap() // Customer mappings (nullable for internal appointments) .ForMember(dest => dest.CustomerName, opt => opt.MapFrom(src => src.Customer != null ? (!string.IsNullOrWhiteSpace(src.Customer.CompanyName) ? src.Customer.CompanyName : $"{src.Customer.ContactFirstName} {src.Customer.ContactLastName}".Trim()) : null)) .ForMember(dest => dest.CustomerPhone, opt => opt.MapFrom(src => src.Customer != null ? src.Customer.Phone : null)) .ForMember(dest => dest.CustomerEmail, opt => opt.MapFrom(src => src.Customer != null ? src.Customer.Email : null)) // Job mappings (optional) .ForMember(dest => dest.JobNumber, opt => opt.MapFrom(src => src.Job != null ? src.Job.JobNumber : null)) // Worker assignment .ForMember(dest => dest.AssignedWorkerName, opt => opt.MapFrom(src => src.AssignedUser != null ? src.AssignedUser.FullName : null)) // Appointment Type lookup mappings .ForMember(dest => dest.AppointmentTypeId, opt => opt.MapFrom(src => src.AppointmentTypeId)) .ForMember(dest => dest.TypeCode, opt => opt.MapFrom(src => src.AppointmentType.TypeCode)) .ForMember(dest => dest.TypeDisplayName, opt => opt.MapFrom(src => src.AppointmentType.DisplayName)) .ForMember(dest => dest.TypeColorClass, opt => opt.MapFrom(src => src.AppointmentType.ColorClass)) .ForMember(dest => dest.TypeIconClass, opt => opt.MapFrom(src => src.AppointmentType.IconClass)) .ForMember(dest => dest.TypeRequiresJobLink, opt => opt.MapFrom(src => src.AppointmentType.RequiresJobLink)) // Appointment Status lookup mappings .ForMember(dest => dest.AppointmentStatusId, opt => opt.MapFrom(src => src.AppointmentStatusId)) .ForMember(dest => dest.StatusCode, opt => opt.MapFrom(src => src.AppointmentStatus.StatusCode)) .ForMember(dest => dest.StatusDisplayName, opt => opt.MapFrom(src => src.AppointmentStatus.DisplayName)) .ForMember(dest => dest.StatusColorClass, opt => opt.MapFrom(src => src.AppointmentStatus.ColorClass)) .ForMember(dest => dest.StatusIconClass, opt => opt.MapFrom(src => src.AppointmentStatus.IconClass)) .ForMember(dest => dest.StatusIsTerminal, opt => opt.MapFrom(src => src.AppointmentStatus.IsTerminalStatus)); // Appointment to AppointmentListDto - Lightweight for grid views CreateMap() .ForMember(dest => dest.CustomerName, opt => opt.MapFrom(src => src.Customer != null ? (!string.IsNullOrWhiteSpace(src.Customer.CompanyName) ? src.Customer.CompanyName : $"{src.Customer.ContactFirstName} {src.Customer.ContactLastName}".Trim()) : null)) .ForMember(dest => dest.AssignedWorkerName, opt => opt.MapFrom(src => src.AssignedUser != null ? src.AssignedUser.FullName : null)) // Type lookup mappings .ForMember(dest => dest.TypeDisplayName, opt => opt.MapFrom(src => src.AppointmentType.DisplayName)) .ForMember(dest => dest.TypeColorClass, opt => opt.MapFrom(src => src.AppointmentType.ColorClass)) // Status lookup mappings .ForMember(dest => dest.StatusDisplayName, opt => opt.MapFrom(src => src.AppointmentStatus.DisplayName)) .ForMember(dest => dest.StatusColorClass, opt => opt.MapFrom(src => src.AppointmentStatus.ColorClass)); // Appointment to CalendarEventDto - For calendar JSON API CreateMap() .ForMember(dest => dest.Start, opt => opt.MapFrom(src => src.ScheduledStartTime.ToString("yyyy-MM-ddTHH:mm:ss"))) .ForMember(dest => dest.End, opt => opt.MapFrom(src => src.ScheduledEndTime.ToString("yyyy-MM-ddTHH:mm:ss"))) .ForMember(dest => dest.AllDay, opt => opt.MapFrom(src => src.IsAllDay)) .ForMember(dest => dest.CustomerName, opt => opt.MapFrom(src => src.Customer != null ? (!string.IsNullOrWhiteSpace(src.Customer.CompanyName) ? src.Customer.CompanyName : $"{src.Customer.ContactFirstName} {src.Customer.ContactLastName}".Trim()) : "Internal")) .ForMember(dest => dest.TypeDisplayName, opt => opt.MapFrom(src => src.AppointmentType.DisplayName)) .ForMember(dest => dest.StatusCode, opt => opt.MapFrom(src => src.AppointmentStatus.StatusCode)) // Calendar colors based on appointment type color class .ForMember(dest => dest.BackgroundColor, opt => opt.MapFrom(src => GetBootstrapColor(src.AppointmentType.ColorClass))) .ForMember(dest => dest.BorderColor, opt => opt.MapFrom(src => GetBootstrapColor(src.AppointmentType.ColorClass))) .ForMember(dest => dest.TextColor, opt => opt.MapFrom(src => "#ffffff")); // CreateAppointmentDto to Appointment CreateMap() .ForMember(dest => dest.AppointmentNumber, opt => opt.Ignore()) // Generated by system .ForMember(dest => dest.AppointmentStatusId, opt => opt.Ignore()) // Set to default "SCHEDULED" by controller .ForMember(dest => dest.AppointmentStatus, opt => opt.Ignore()) // Will be set by FK .ForMember(dest => dest.AppointmentType, opt => opt.Ignore()); // Will be set by FK // QuickCreateAppointmentDto to Appointment (for calendar quick create) CreateMap() .ForMember(dest => dest.AppointmentNumber, opt => opt.Ignore()) .ForMember(dest => dest.AppointmentStatusId, opt => opt.Ignore()) .ForMember(dest => dest.AppointmentStatus, opt => opt.Ignore()) .ForMember(dest => dest.AppointmentType, opt => opt.Ignore()) .ForMember(dest => dest.Description, opt => opt.MapFrom(src => (string?)null)) .ForMember(dest => dest.Location, opt => opt.MapFrom(src => (string?)null)) .ForMember(dest => dest.Notes, opt => opt.MapFrom(src => (string?)null)) .ForMember(dest => dest.IsReminderEnabled, opt => opt.MapFrom(src => true)) .ForMember(dest => dest.ReminderMinutesBefore, opt => opt.MapFrom(src => 30)); // UpdateAppointmentDto to Appointment CreateMap() .ForMember(dest => dest.AppointmentNumber, opt => opt.Ignore()) // Cannot be changed .ForMember(dest => dest.AppointmentStatus, opt => opt.Ignore()) // Will be set by FK .ForMember(dest => dest.AppointmentType, opt => opt.Ignore()); // Will be set by FK // Appointment to UpdateAppointmentDto (needed for Edit GET action) CreateMap() .ForMember(dest => dest.AppointmentStatusId, opt => opt.MapFrom(src => src.AppointmentStatusId)) .ForMember(dest => dest.AppointmentTypeId, opt => opt.MapFrom(src => src.AppointmentTypeId)); } /// /// Maps Bootstrap color class names to hex color codes for calendar events /// private static string GetBootstrapColor(string colorClass) { return colorClass.ToLower() switch { "primary" => "#0d6efd", "secondary" => "#6c757d", "success" => "#198754", "danger" => "#dc3545", "warning" => "#ffc107", "info" => "#0dcaf0", "light" => "#f8f9fa", "dark" => "#212529", // Custom color names for appointment types "purple" => "#6f42c1", "green" => "#198754", "blue" => "#0d6efd", "orange" => "#fd7e14", "red" => "#dc3545", "yellow" => "#ffc107", "cyan" => "#0dcaf0", "pink" => "#d63384", "gray" => "#6c757d", _ => "#0d6efd" // Default to primary blue }; } }