Files
MoneyMap/MoneyMap.Core/Models/Transaction.cs
T
2026-04-20 18:16:33 -04:00

87 lines
2.8 KiB
C#

using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace MoneyMap.Models;
[Index(nameof(Date), nameof(Amount), nameof(Name), nameof(Memo), nameof(AccountId), nameof(CardId), IsUnique = true)]
public class Transaction
{
[Key]
public long Id { get; set; }
[Required]
public DateTime Date { get; set; }
[MaxLength(20)]
public string TransactionType { get; set; } = string.Empty; // "DEBIT"/"CREDIT" if present
[MaxLength(200)]
public string Name { get; set; } = string.Empty;
[MaxLength(500)]
public string Memo { get; set; } = string.Empty;
[Column(TypeName = "decimal(18,2)")]
public decimal Amount { get; set; } // negative = debit, positive = credit
[MaxLength(100)]
public string Category { get; set; } = string.Empty;
// Merchant relationship
[ForeignKey(nameof(Merchant))]
public int? MerchantId { get; set; }
public Merchant? Merchant { get; set; }
public string Notes { get; set; } = string.Empty;
// Primary container: Every transaction belongs to an Account (the source of CSV)
[Required]
[ForeignKey(nameof(Account))]
public int AccountId { get; set; }
public Account Account { get; set; } = null!;
// Optional: Card used for this transaction (if it was a card payment)
[ForeignKey(nameof(Card))]
public int? CardId { get; set; }
public Card? Card { get; set; }
// Optional: For transfers between accounts, this links to the destination account
// This transaction is the "source" side of the transfer (debit)
// The matching transaction in the destination account has this AccountId as its TransferToAccountId
[ForeignKey(nameof(TransferToAccount))]
public int? TransferToAccountId { get; set; }
public Account? TransferToAccount { get; set; }
[MaxLength(4)]
public string? Last4 { get; set; } // parsed from Memo if present
public ICollection<Receipt> Receipts { get; set; } = new List<Receipt>();
[NotMapped] public bool IsCredit => Amount > 0;
[NotMapped] public bool IsDebit => Amount < 0;
[NotMapped] public bool IsTransfer => TransferToAccountId.HasValue;
[NotMapped]
public string PaymentMethodLabel
{
get
{
// Handle transfers
if (IsTransfer)
{
var toLabel = TransferToAccount?.DisplayLabel ?? "Unknown";
return $"Transfer → {toLabel}";
}
// If card was used, show just the card (since account is implied)
if (Card != null)
return Card.DisplayLabel;
// Direct account transaction (no card)
return Account?.DisplayLabel ?? $"···· {Last4}";
}
}
}