301 lines
9.7 KiB
C#
301 lines
9.7 KiB
C#
using System.ComponentModel.DataAnnotations;
|
|
using System.ComponentModel.DataAnnotations.Schema;
|
|
using System.Text.Json.Serialization;
|
|
|
|
namespace MotoresArgentinosV2.Core.Entities;
|
|
|
|
public class Brand
|
|
{
|
|
public int BrandID { get; set; }
|
|
public int VehicleTypeID { get; set; }
|
|
public string Name { get; set; } = string.Empty;
|
|
public int? LegacyID { get; set; }
|
|
}
|
|
|
|
public class Model
|
|
{
|
|
public int ModelID { get; set; }
|
|
public int BrandID { get; set; }
|
|
public string Name { get; set; } = string.Empty;
|
|
public int? LegacyID { get; set; }
|
|
}
|
|
|
|
public enum UserMigrationStatus : byte { LegacyPending = 0, MigratedActive = 1 }
|
|
public enum AdStatusEnum
|
|
{
|
|
Draft = 1,
|
|
PaymentPending = 2,
|
|
ModerationPending = 3,
|
|
Active = 4,
|
|
Rejected = 5,
|
|
Paused = 6,
|
|
Sold = 7,
|
|
Expired = 8,
|
|
Deleted = 9,
|
|
Reserved = 10
|
|
}
|
|
|
|
public static class AdStatusHelper
|
|
{
|
|
public static string GetStatusDisplayName(int statusId)
|
|
{
|
|
return statusId switch
|
|
{
|
|
1 => "Borrador",
|
|
2 => "Pago Pendiente",
|
|
3 => "En Revisión",
|
|
4 => "Activo",
|
|
5 => "Rechazado",
|
|
6 => "Pausado",
|
|
7 => "Vendido",
|
|
8 => "Vencido",
|
|
9 => "Eliminado",
|
|
10 => "Reservado",
|
|
_ => "Desconocido"
|
|
};
|
|
}
|
|
}
|
|
|
|
public class User
|
|
{
|
|
public int UserID { get; set; }
|
|
public string UserName { get; set; } = string.Empty;
|
|
public string Email { get; set; } = string.Empty;
|
|
public string PasswordHash { get; set; } = string.Empty;
|
|
public string? PasswordSalt { get; set; }
|
|
public byte MigrationStatus { get; set; }
|
|
public string? FirstName { get; set; }
|
|
public string? LastName { get; set; }
|
|
public string? PhoneNumber { get; set; }
|
|
public byte UserType { get; set; } = 1; // 1: Particular, 3: Admin
|
|
public string? MFASecret { get; set; }
|
|
public bool IsMFAEnabled { get; set; }
|
|
|
|
// Email Verification
|
|
public bool IsEmailVerified { get; set; }
|
|
public string? VerificationToken { get; set; }
|
|
public DateTime? VerificationTokenExpiresAt { get; set; }
|
|
public DateTime? LastVerificationEmailSentAt { get; set; }
|
|
|
|
// Password Reset
|
|
public string? PasswordResetToken { get; set; }
|
|
public DateTime? PasswordResetTokenExpiresAt { get; set; }
|
|
public DateTime? LastPasswordResetEmailSentAt { get; set; }
|
|
|
|
// Para cambio de email
|
|
public string? NewEmailCandidate { get; set; }
|
|
public string? EmailChangeToken { get; set; }
|
|
public DateTime? EmailChangeTokenExpiresAt { get; set; }
|
|
|
|
// Para reset/desactivación de MFA
|
|
public string? SecurityActionToken { get; set; }
|
|
public DateTime? SecurityActionTokenExpiresAt { get; set; }
|
|
|
|
// Bloqueo de usuario
|
|
public bool IsBlocked { get; set; }
|
|
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
|
|
|
// Relación con Refresh Tokens
|
|
public ICollection<RefreshToken> RefreshTokens { get; set; } = new List<RefreshToken>();
|
|
|
|
// Notificaciones de recordatorio de mensajes no leídos
|
|
public DateTime? LastUnreadMessageReminderSentAt { get; set; }
|
|
}
|
|
|
|
public class AuditLog
|
|
{
|
|
public int AuditLogID { get; set; }
|
|
public string Action { get; set; } = string.Empty;
|
|
public string Entity { get; set; } = string.Empty;
|
|
public int EntityID { get; set; }
|
|
public int UserID { get; set; }
|
|
public string Details { get; set; } = string.Empty;
|
|
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
|
}
|
|
|
|
public class Ad
|
|
{
|
|
public int AdID { get; set; }
|
|
public int UserID { get; set; }
|
|
public User User { get; set; } = null!;
|
|
|
|
public int VehicleTypeID { get; set; }
|
|
public int BrandID { get; set; }
|
|
public Brand Brand { get; set; } = null!;
|
|
public int ModelID { get; set; }
|
|
public Model Model { get; set; } = null!;
|
|
|
|
public string? VersionName { get; set; }
|
|
public int Year { get; set; }
|
|
public int KM { get; set; }
|
|
|
|
public string? FuelType { get; set; }
|
|
public string? Color { get; set; }
|
|
public string? Segment { get; set; }
|
|
|
|
public decimal Price { get; set; }
|
|
public string Currency { get; set; } = "USD";
|
|
public string? Description { get; set; }
|
|
|
|
public string? Location { get; set; }
|
|
public string? Condition { get; set; }
|
|
public int? DoorCount { get; set; }
|
|
public string? Transmission { get; set; }
|
|
public string? Steering { get; set; }
|
|
|
|
public string? ContactPhone { get; set; }
|
|
public string? ContactEmail { get; set; }
|
|
public bool DisplayContactInfo { get; set; } = true;
|
|
|
|
public bool ShowPhone { get; set; } = true;
|
|
public bool AllowWhatsApp { get; set; } = true;
|
|
public bool ShowEmail { get; set; } = true;
|
|
|
|
public bool IsFeatured { get; set; }
|
|
|
|
public int StatusID { get; set; }
|
|
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
|
public DateTime? PublishedAt { get; set; }
|
|
public DateTime? ExpiresAt { get; set; }
|
|
public int? LegacyAdID { get; set; }
|
|
public DateTime? DeletedAt { get; set; }
|
|
public int ViewsCounter { get; set; }
|
|
|
|
public ICollection<AdPhoto> Photos { get; set; } = new List<AdPhoto>();
|
|
public ICollection<AdFeature> Features { get; set; } = new List<AdFeature>();
|
|
public ICollection<ChatMessage> Messages { get; set; } = new List<ChatMessage>();
|
|
|
|
// CAMPOS DE CONTROL DE NOTIFICACIONES
|
|
public DateTime? LastPerformanceEmailSentAt { get; set; } // Para el resumen semanal
|
|
public DateTime? PaymentReminderSentAt { get; set; } // Para carrito abandonado
|
|
public bool ExpirationWarningSent { get; set; } // Para aviso por vencer
|
|
}
|
|
|
|
public class AdPhoto
|
|
{
|
|
public int PhotoID { get; set; }
|
|
public int AdID { get; set; }
|
|
public string FilePath { get; set; } = string.Empty;
|
|
public bool IsCover { get; set; }
|
|
public int SortOrder { get; set; }
|
|
public Ad Ad { get; set; } = null!;
|
|
}
|
|
|
|
public class AdFeature
|
|
{
|
|
public int AdID { get; set; }
|
|
public string FeatureKey { get; set; } = string.Empty;
|
|
public string? FeatureValue { get; set; }
|
|
}
|
|
|
|
public class TransactionRecord
|
|
{
|
|
public int TransactionID { get; set; }
|
|
public int AdID { get; set; }
|
|
public Ad Ad { get; set; } = null!;
|
|
public string OperationCode { get; set; } = string.Empty;
|
|
public int PaymentMethodID { get; set; }
|
|
public decimal Amount { get; set; }
|
|
public string Status { get; set; } = "PENDING";
|
|
public string? ProviderPaymentId { get; set; }
|
|
public string? ProviderResponse { get; set; }
|
|
public string? SnapshotUserEmail { get; set; }
|
|
public string? SnapshotUserName { get; set; }
|
|
public string? SnapshotAdTitle { get; set; }
|
|
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
|
public DateTime? UpdatedAt { get; set; }
|
|
}
|
|
public class Favorite
|
|
{
|
|
public int UserID { get; set; }
|
|
public int AdID { get; set; }
|
|
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
|
}
|
|
|
|
public class ChatMessage
|
|
{
|
|
[Key]
|
|
public int MessageID { get; set; }
|
|
public int AdID { get; set; }
|
|
|
|
[ForeignKey("AdID")]
|
|
[JsonIgnore]
|
|
public Ad? Ad { get; set; }
|
|
|
|
public int SenderID { get; set; }
|
|
public int ReceiverID { get; set; }
|
|
public string MessageText { get; set; } = string.Empty;
|
|
public DateTime SentAt { get; set; } = DateTime.UtcNow;
|
|
public bool IsRead { get; set; } = false;
|
|
}
|
|
|
|
public class PaymentMethod
|
|
{
|
|
public int PaymentMethodID { get; set; }
|
|
public string Name { get; set; } = string.Empty;
|
|
}
|
|
|
|
public class AdViewLog
|
|
{
|
|
public int Id { get; set; }
|
|
public int AdID { get; set; }
|
|
public string IPAddress { get; set; } = string.Empty;
|
|
public DateTime ViewDate { get; set; } = DateTime.UtcNow;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Categorías de correo disponibles para preferencias de notificación.
|
|
/// </summary>
|
|
public static class NotificationCategory
|
|
{
|
|
public const string Sistema = "sistema"; // Avisos del sistema (vencimientos, pagos)
|
|
public const string Marketing = "marketing"; // Boletines y promociones
|
|
public const string Rendimiento = "rendimiento"; // Resumen semanal de visitas/favoritos
|
|
public const string Mensajes = "mensajes"; // Recordatorio de mensajes no leídos
|
|
|
|
public static readonly string[] Todos = [Sistema, Marketing, Rendimiento, Mensajes];
|
|
}
|
|
|
|
/// <summary>
|
|
/// Preferencia de notificación por email de un usuario para una categoría específica.
|
|
/// Por defecto el usuario recibe todos los correos; el registro solo se crea al DESACTIVAR.
|
|
/// </summary>
|
|
public class UserNotificationPreference
|
|
{
|
|
public int PreferenceID { get; set; }
|
|
public int UserID { get; set; }
|
|
public User User { get; set; } = null!;
|
|
|
|
// Categoría: "sistema", "marketing", "rendimiento", "mensajes"
|
|
public string Category { get; set; } = string.Empty;
|
|
|
|
// false = usuario optó por NO recibir esta categoría
|
|
public bool IsEnabled { get; set; } = true;
|
|
|
|
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Token de baja firmado con HMAC-SHA256 para darse de baja sin login.
|
|
/// El token incluye UserID + Category y es válido hasta ExpiresAt.
|
|
/// </summary>
|
|
public class UnsubscribeToken
|
|
{
|
|
public int TokenID { get; set; }
|
|
public int UserID { get; set; }
|
|
public User User { get; set; } = null!;
|
|
|
|
// Categoría a la que aplica el token
|
|
public string Category { get; set; } = string.Empty;
|
|
|
|
// Token opaco (GUID + HMAC) que va en el enlace del correo
|
|
public string Token { get; set; } = string.Empty;
|
|
|
|
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
|
|
|
// Tokens de baja expiran a los 365 días (la URL del correo puede ser vieja)
|
|
public DateTime ExpiresAt { get; set; } = DateTime.UtcNow.AddDays(365);
|
|
|
|
// true cuando ya fue utilizado para darse de baja
|
|
public bool IsUsed { get; set; } = false;
|
|
} |