diff --git a/MoneyMap/Models/Transaction.cs b/MoneyMap/Models/Transaction.cs index fad6567..c1f1249 100644 --- a/MoneyMap/Models/Transaction.cs +++ b/MoneyMap/Models/Transaction.cs @@ -5,7 +5,7 @@ using System.Transactions; namespace MoneyMap.Models; -[Index(nameof(Date), nameof(Amount), nameof(Name), nameof(Memo), nameof(CardId), nameof(AccountId), IsUnique = true)] +[Index(nameof(Date), nameof(Amount), nameof(Name), nameof(Memo), nameof(AccountId), nameof(CardId), IsUnique = true)] public class Transaction { [Key] @@ -31,37 +31,51 @@ public class Transaction public string Notes { get; set; } = string.Empty; - // Payment method - EITHER Card OR Account (not both) - // For credit/debit card transactions + // 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; } - // For bank account transactions (checking, savings) - [ForeignKey(nameof(Account))] - public int? AccountId { get; set; } - public Account? Account { 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 (replaces CardLast4) + public string? Last4 { get; set; } // parsed from Memo if present public ICollection Receipts { get; set; } = new List(); [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.Issuer} {Card.Last4}"; - if (Account != null) - return $"{Account.Institution} {Account.Last4}"; - if (!string.IsNullOrEmpty(Last4)) - return $"···· {Last4}"; - return "Unknown"; + return Card.DisplayLabel; + + // Direct account transaction (no card) + return Account?.DisplayLabel ?? $"···· {Last4}"; } } } diff --git a/MoneyMap/Pages/Transactions.cshtml b/MoneyMap/Pages/Transactions.cshtml index 78921c1..8cd1070 100644 --- a/MoneyMap/Pages/Transactions.cshtml +++ b/MoneyMap/Pages/Transactions.cshtml @@ -121,7 +121,7 @@ Memo Amount Category - Card + Payment/Account Actions @@ -164,7 +164,9 @@ @t.Category } - @t.CardLabel + + @t.CardLabel + Edit