Beispiel #1
0
        public async Task Save(IEntityRepository repository, DateTime dateTime)
        {
            var accountSettingsQueries = repository.GetQuery <AccountFlowSettings>();

            var accountIds      = Accounts.Select(x => x.Id).ToList();
            var accountSettings = await accountSettingsQueries
                                  .Where(x => accountIds.Contains(x.AccountId))
                                  .ToListAsync()
                                  .ConfigureAwait(false);

            Accounts.ForEach(x =>
            {
                var settings = accountSettings.FirstOrDefault(s => s.AccountId == x.Id);
                if (settings == null)
                {
                    settings = new AccountFlowSettings
                    {
                        AccountId = x.Id,
                        CanFlow   = x.CanFlow
                    };
                    repository.Create(settings);
                }
                else
                {
                    settings.CanFlow = x.CanFlow;
                    repository.Update(settings);
                }
            });

            var flowSettingsQueries = repository.GetQuery <ExpenseFlowSettings>();

            var flowIds      = ExpenseFlows.Select(x => x.Id).ToList();
            var flowSettings = await flowSettingsQueries
                               .Where(x => flowIds.Contains(x.ExpenseFlowId))
                               .ToListAsync()
                               .ConfigureAwait(false);

            ExpenseFlows.ForEach(x =>
            {
                var settings = flowSettings.FirstOrDefault(s => s.ExpenseFlowId == x.Id);
                if (settings == null)
                {
                    settings = new ExpenseFlowSettings
                    {
                        ExpenseFlowId = x.Id,
                        CanFlow       = x.CanFlow,
                        Rule          = x.Rule,
                        Amount        = x.Amount
                    };
                    repository.Create(settings);
                }
                else
                {
                    settings.CanFlow = x.CanFlow;
                    settings.Rule    = x.Rule;
                    settings.Amount  = x.Amount;
                    repository.Update(settings);
                }
            });

            var distribution = new DataAccess.Model.Distribution.Distribution()
            {
                DateTime = dateTime,
                SumFlow  = DistributionFlows.Sum(x => x.Amount)
            };

            repository.Create(distribution);

            var accountQueries = repository.GetQuery <Account>();
            var flowQueries    = repository.GetQuery <ExpenseFlow>();

            var accounts = await accountQueries
                           .Where(x => accountIds.Contains(x.Id))
                           .ToListAsync()
                           .ConfigureAwait(false);

            var expenseFlows = await flowQueries
                               .Where(x => flowIds.Contains(x.Id))
                               .ToListAsync()
                               .ConfigureAwait(false);

            DistributionFlows.ForEach(x =>
            {
                var flow = new Flow
                {
                    Distribution = distribution,
                    SourceId     = x.SourceId,
                    RecipientId  = x.RecipientId,
                    Amount       = x.Amount
                };
                repository.Create(flow);

                var account     = accounts.First(a => a.Id == x.SourceId);
                var expenseFlow = expenseFlows.First(f => f.Id == x.RecipientId);

                account.AvailBalance -= x.Amount;
                repository.Update(account);
                expenseFlow.Balance += x.Amount;
                repository.Update(expenseFlow);
            });

            await repository.SaveChangesAsync().ConfigureAwait(false);
        }
Beispiel #2
0
        public async Task Distribute(IEntityRepository repository, IFlowDistributor distributor)
        {
            var accountIds = Accounts.Select(x => x.Id).ToList();

            var accountsQueries = repository.GetQuery <Account>();
            var accounts        = await accountsQueries
                                  .Where(x => accountIds.Contains(x.Id))
                                  .Select(x => x.ToModel())
                                  .ToListAsync()
                                  .ConfigureAwait(false);

            accounts.ForEach(x =>
            {
                var account     = Accounts.First(a => a.Id == x.Id);
                account.Balance = x.AvailBalance;
                (x as IFlowEndPoint).FlowRule = new DistributionFlowRule
                {
                    CanFlow     = account.CanFlow,
                    Destination = FlowDestination.Source
                };
            });

            var flowIds = ExpenseFlows.Select(x => x.Id).ToList();

            var flowQueries = repository.GetQuery <ExpenseFlow>();
            var flows       = await flowQueries
                              .Where(x => flowIds.Contains(x.Id))
                              .Select(x => x.ToModel())
                              .ToListAsync()
                              .ConfigureAwait(false);

            flows.ForEach(x =>
            {
                var expenseFlow     = ExpenseFlows.First(s => s.Id == x.Id);
                expenseFlow.Balance = x.Balance;
                x.FlowRule          = new DistributionFlowRule
                {
                    CanFlow     = expenseFlow.CanFlow,
                    Destination = FlowDestination.Recipient,
                    Rule        = expenseFlow.Rule,
                    Amount      = expenseFlow.Amount
                };
            });

            var endPoints = new List <IFlowEndPoint>();

            endPoints.AddRange(accounts);
            endPoints.AddRange(flows);

            distributor.Distribute(endPoints);

            DistributionFlows = distributor.FlowRecords
                                .Select(x => new DistributionFlowModel
            {
                SourceId        = x.Source.Id,
                SourceName      = x.Source.Name,
                RecipientId     = x.Recipient.Id,
                RecipientName   = x.Recipient.Name,
                Amount          = x.Amount,
                AmountFormatted = x.Amount.ToMoney()
            }).ToList();

            Accounts.ForEach(x =>
            {
                if (!x.CanFlow)
                {
                    return;
                }
                var withdrawTotal = distributor.FlowRecords.Where(f => f.Source.Id == x.Id).Sum(f => f.Amount);
                if (withdrawTotal > 0)
                {
                    x.WithdrawTotal = $"\u2013{withdrawTotal.ToMoney()}";
                }
                x.Result = (x.Balance - withdrawTotal).ToMoney();
            });

            ExpenseFlows.ForEach(x =>
            {
                if (!x.CanFlow)
                {
                    return;
                }
                var topupTotal = distributor.FlowRecords.Where(f => f.Recipient.Id == x.Id).Sum(f => f.Amount);
                if (topupTotal > 0)
                {
                    x.TopupTotal = $"+{topupTotal.ToMoney()}";
                }
                x.Result = (x.Balance + topupTotal).ToMoney();
            });
        }