using PowderCoating.Core.Enums;
namespace PowderCoating.Core.Entities;
public class Vendor : BaseEntity
{
public string CompanyName { get; set; } = string.Empty;
public string? ContactName { get; set; }
public string? Email { get; set; }
public string? Phone { get; set; }
public string? Address { get; set; }
public string? City { get; set; }
public string? State { get; set; }
public string? ZipCode { get; set; }
public string? Country { get; set; } = "USA";
public string? Website { get; set; }
// Business Information
public string? AccountNumber { get; set; }
public string? TaxId { get; set; }
public string? PaymentTerms { get; set; }
public decimal? CreditLimit { get; set; }
public string? Notes { get; set; }
public bool IsActive { get; set; } = true;
public bool IsPreferred { get; set; } = false;
// Accounts Payable tracking
/// Running AP balance: increases with new bills, decreases with payments.
public decimal CurrentBalance { get; set; } = 0;
/// Balance owed at go-live (for migrating existing vendors).
public decimal OpeningBalance { get; set; } = 0;
public DateTime? OpeningBalanceDate { get; set; }
/// Default expense account pre-filled on new bill line items for this vendor.
public int? DefaultExpenseAccountId { get; set; }
// Navigation
public virtual ICollection InventoryItems { get; set; } = new List();
public virtual ICollection Bills { get; set; } = new List();
public virtual ICollection BillPayments { get; set; } = new List();
public virtual ICollection Expenses { get; set; } = new List();
public virtual Account? DefaultExpenseAccount { get; set; }
}
public class InventoryTransaction : BaseEntity
{
public int InventoryItemId { get; set; }
public InventoryTransactionType TransactionType { get; set; }
public decimal Quantity { get; set; }
public decimal UnitCost { get; set; }
public decimal TotalCost { get; set; }
public DateTime TransactionDate { get; set; } = DateTime.UtcNow;
public string? Reference { get; set; } // PO number, Job number, etc.
public string? Notes { get; set; }
public decimal BalanceAfter { get; set; }
// Optional FK to the PO that generated this purchase transaction
public int? PurchaseOrderId { get; set; }
public virtual PurchaseOrder? PurchaseOrder { get; set; }
// Optional FK to the job this material was used on (set by QR scan / manual log)
public int? JobId { get; set; }
public virtual Job? Job { get; set; }
public virtual InventoryItem InventoryItem { get; set; } = null!;
}
public class JobPhoto : BaseEntity
{
public int JobId { get; set; }
public virtual Job Job { get; set; } = null!;
///
/// Relative path from media folder (e.g., "1/job-photos/5/1.jpg")
///
public string FilePath { get; set; } = string.Empty;
///
/// Original filename when uploaded
///
public string FileName { get; set; } = string.Empty;
///
/// File size in bytes
///
public long FileSize { get; set; }
///
/// Content type (e.g., "image/jpeg")
///
public string ContentType { get; set; } = string.Empty;
///
/// User-provided caption/note for the photo
///
public string? Caption { get; set; }
///
/// Type of photo (Before, After, Progress, QualityCheck, Issue, Completed)
///
public JobPhotoType PhotoType { get; set; } = JobPhotoType.Progress;
///
/// Display order for sorting photos
///
public int DisplayOrder { get; set; }
///
/// User who uploaded the photo
///
public string UploadedById { get; set; } = string.Empty;
public virtual ApplicationUser? UploadedBy { get; set; }
public DateTime UploadedDate { get; set; } = DateTime.UtcNow;
///
/// Comma-separated tags for this photo (e.g., colors used, finish type)
///
public string? Tags { get; set; }
///
/// True for photos copied from an AI quote analysis — excluded from subscription photo limits.
///
public bool IsAiAnalysisPhoto { get; set; }
}
public class JobNote : BaseEntity
{
public int JobId { get; set; }
public string Note { get; set; } = string.Empty;
public bool IsImportant { get; set; }
public bool IsInternal { get; set; } = true; // Don't show to customer
public virtual Job Job { get; set; } = null!;
}
public class CustomerNote : BaseEntity
{
public int CustomerId { get; set; }
public string Note { get; set; } = string.Empty;
public bool IsImportant { get; set; }
public virtual Customer Customer { get; set; } = null!;
}
public class JobStatusHistory : BaseEntity
{
public int JobId { get; set; }
// Lookup foreign keys (replacing enums)
public int FromStatusId { get; set; }
public int ToStatusId { get; set; }
public DateTime ChangedDate { get; set; } = DateTime.UtcNow;
public string? Notes { get; set; }
// Navigation properties
public virtual Job Job { get; set; } = null!;
public virtual JobStatusLookup FromStatus { get; set; } = null!;
public virtual JobStatusLookup ToStatus { get; set; } = null!;
}
public class PricingTier : BaseEntity
{
public string TierName { get; set; } = string.Empty;
public string? Description { get; set; }
public decimal DiscountPercent { get; set; }
public bool IsActive { get; set; } = true;
public virtual ICollection Customers { get; set; } = new List();
}