/// <inheritdoc /> public Account CreateAccount(AccountType type, string description, string iconPack, string iconName, string iconColor) { description = this.validator.Description(description); this.validator.Icon(iconPack, iconName, iconColor); return(this.ConcurrentInvoke(() => { if (this.Context.Accounts.Any(a => a.Description == description && !a.IsObsolete)) { throw new ValidationException($"An active account with description \"{description}\" already exists."); } if (type == AccountType.Splitwise && this.Context.Accounts.Any(a => a.Type == AccountType.Splitwise && !a.IsObsolete)) { throw new ValidationException($"An active Splitwise account already exists."); } var entity = new DailyBalanceEntity { Date = this.Context.CreationTime.ToLocalDate(), Balance = 0, Account = new AccountEntity { Type = type, Description = description, IsDefault = false, IsObsolete = false, Icon = new IconEntity { Pack = iconPack, Name = iconName, Color = iconColor, }, }, }; this.Context.DailyBalances.Add(entity); this.Context.SaveChanges(); return entity.Account.AsAccount(); })); }
/// <summary> /// Gets the historical balance entries which should be edited based on a date. If the date has no entry, /// a new historical entry will be created and inserted in history. /// </summary> /// <param name="accountId">The account identifier for which to check the historical entries.</param> /// <param name="date">The date from which should be checked.</param> /// <param name="addedDailyBalances">The daily balances that were already added. This is needed since the /// context does not contain already added entities, resulting in possible double daily balances which results /// in an error.</param> /// <returns>A tuple containing the list of to be updated entities and optionally the newly created daily /// balance.</returns> private (List <DailyBalanceEntity>, Maybe <DailyBalanceEntity>) GetBalanceEntriesToEdit( int accountId, LocalDate date, Maybe <List <DailyBalanceEntity> > addedDailyBalances = default) { var balanceEntries = addedDailyBalances .ValueOrElse(new List <DailyBalanceEntity>()) .Where(db => db.AccountId == accountId) .Concat(this.Context.DailyBalances .Where(db => db.AccountId == accountId)) .ToList(); var balanceEntriesAfterDate = balanceEntries .Where(hb => hb.Date >= date) .OrderBy(hb => hb.Date) .ToList(); // If date already has historical entry, just alter that and later entries. var balanceEntryOnSameDate = balanceEntries.SingleOrNone(hb => hb.Date == date); if (balanceEntryOnSameDate.IsSome) { return(balanceEntriesAfterDate, Maybe <DailyBalanceEntity> .None); } // Get last entity before date var lastEntry = balanceEntries .Where(hb => hb.Date < date) .OrderBy(hb => hb.Date) .LastOrNone(); var newBalanceEntry = new DailyBalanceEntity { AccountId = accountId, Balance = lastEntry.Select(e => e.Balance).ValueOrElse(0), Date = date, }; this.Context.DailyBalances.Add(newBalanceEntry); // Return all entries after the date + the new entry return(newBalanceEntry.Enumerate() .Concat(balanceEntriesAfterDate) .ToList(), newBalanceEntry); }