using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Schaad.Accounting.Interfaces; using Schaad.Accounting.Models; namespace Schaad.Accounting.Repositories { public class TransactionRepository : BaseRepository, ITransactionRepository { private readonly IAccountRepository accountRepository; private readonly string TRANSACTIONS = "Transactions.xml"; public TransactionRepository(ISettingsService settingsService, RepositoryCache cache, IAccountRepository accountRepository, ILogger logger) : base(settingsService, cache, logger) { this.accountRepository = accountRepository; } public Task> GetTransactionListAsync() => LoadListAsync(TRANSACTIONS); public async Task SaveTransactionAsync(Transaction transaction) { transaction.Value = Math.Abs(transaction.Value); var originIsFx = (await accountRepository.GetAccountAsync(transaction.OriginAccountId)).IsFxAccount; var targetIsFx = (await accountRepository.GetAccountAsync(transaction.TargetAccountId)).IsFxAccount; var isFxAccount = originIsFx || targetIsFx; // user enters amount in the foreign account's currency -> convert to CHF for storage if (isFxAccount && transaction.FxRate != 0) { transaction.Value = transaction.Value * transaction.FxRate.Value; } if (!isFxAccount) { transaction.FxRate = null; } if (transaction.BookingDate <= DateTime.MinValue) { transaction.BookingDate = transaction.ValueDate; } var transactionList = await GetTransactionListAsync(); var idx = transactionList.FindIndex(t => t.Id == transaction.Id); if (idx >= 0) { transactionList[idx] = transaction; } else { transaction.Id = Guid.NewGuid().ToString(); transactionList.Add(transaction); } await SaveAsync(transactionList, TRANSACTIONS); } public async Task GetTransactionAsync(string id) { var transactions = await GetTransactionListAsync(); var stored = transactions.FirstOrDefault(t => t.Id == id); if (stored == null) { return null; } var result = stored.Clone(); // value is stored in CHF -> convert back to foreign currency for display/editing var isFxAccount = (await accountRepository.GetAccountAsync(result.OriginAccountId)).IsFxAccount || (await accountRepository.GetAccountAsync(result.TargetAccountId)).IsFxAccount; if (isFxAccount && result.FxRate != 0) { result.Value = result.Value / result.FxRate.Value; } return result; } public async Task DeleteTransactionAsync(string id) { var transactions = await GetTransactionListAsync(); transactions.RemoveAll(t => t.Id == id); await SaveAsync(transactions, TRANSACTIONS); } } }