/// <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();
            }));
        }
示例#2
0
        /// <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);
        }