refactor: extract Models and Data into MoneyMap.Core shared library
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
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}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user