public ActionResult <Expense> Post([FromBody] RegisterExpense expense)
        {
            if (ModelState.IsValid)
            {
                #region Validate Payee
                var roommate = _roommates.GetById(expense.PayeeId);
                if (roommate == null)
                {
                    ModelState.AddModelError("PayeeId", "The specified PayeeId is not valid or does not represent a registered Roommate.");
                    return(null);
                }
                var payee = new Payee {
                    Id = roommate.Id, Name = roommate.Name
                };
                #endregion

                var result = _registerExpense(this, expense, payee);
                if (result != null)
                {
                    return(result);
                }
            }

            return(BadRequest(ModelState));
        }
Ejemplo n.º 2
0
        public IAggregate Handle(RegisterExpense command)
        {
            var associateAccount = _domainRepository.GetById <AssociateAccount>(command.CorrelationId.ToString());

            associateAccount.RegisterExpense(command.Value, command.Description);
            return(associateAccount);
        }
        private Expense RegisterSimpleExpense(RegisterExpense simpleExpense, Payee payee)
        {
            var entity = (SimpleExpense)simpleExpense;

            entity.Payee = payee;

            #region Validations
            if (simpleExpense.Payers?.Any() != true)
            {
                ModelState.AddModelError("Payers", "When registering a Simple Expense, you must specify at least one Payer.");
                return(null);
            }

            #region Validate Payers
            // TODO: validate duplications before calling the database
            var payers = _roommates.GetByIds(simpleExpense.Payers.Select(x => x.Id).Distinct());
            if (payers.Count() != simpleExpense.Payers.Count())
            {
                ModelState.AddModelError("Payers", "At least one Payer is invalid, does not represent a registered Roommate, or is duplicated.");
                return(null);
            }
            else if (payers.Count() == 1 && payers.First().Id == payee.Id)
            {
                ModelState.AddModelError("Payers", "At this moment, self expenses are not supported. Please consider other alternatives.");
                return(null);
            }
            var sum = simpleExpense.Payers.Sum(x => x.Amount * (decimal)x.Multiplier);
            if (sum > 0)
            {
                ModelState.AddModelError("Payers", "An Expense cannot be proportional and even at the same time. Amount and Multiplier cannot be filled at the same time. Please, select only one.");
                return(null);
            }
            entity.Payers = simpleExpense.Payers.Select(x => new Payer
            {
                Id     = x.Id,
                Amount = simpleExpense.Distribution.GetAmount(simpleExpense, x),
                Name   = payers.Single(p => p.Id == x.Id).Name
            });
            var total = entity.Payers.Sum(x => x.Amount);
            if (total != simpleExpense.Total)
            {
                ModelState.AddModelError("Payers", "The total amount for this expense and the total amount by payers' distribution differ.");
                return(null);
            }
            #endregion
            #endregion

            var result = _expenses.Add(entity);
            if (result != null)
            {
                UpdateBalances(entity.Payers, entity.Payee, entity.Total);
            }

            return(result);
        }
 internal static decimal GetAmount(this ExpenseDistribution distribution, RegisterExpense expense, RegisterExpensePayer payer)
 => GetAmount(distribution, expense.Total, payer.Multiplier, expense.Payers.Count(), payer.Amount);
        private Expense RegisterDetailedExpense(RegisterExpense detailedExpense, Payee payee)
        {
            var entity = (DetailedExpense)detailedExpense;

            entity.Payee = payee;

            #region Validations
            if (detailedExpense.Items?.Any() != true)
            {
                ModelState.AddModelError("Payers", "When registering a Detailed Expense, you must specify at least one Item.");
                return(null);
            }

            #region Validate Payers
            // TODO: validate duplications before calling the database
            var ids    = detailedExpense.Items.SelectMany(i => i.Payers.Select(p => p.Id));
            var payers = _roommates.GetByIds(ids.Distinct());
            if (payers.Count() != ids.Count())
            {
                ModelState.AddModelError("Payers", "At least one Payer is invalid or does not represent a registered Roommate, or is duplicated.");
                return(null);
            }
            else if (payers.Count() == 1 && payers.First().Id == payee.Id)
            {
                ModelState.AddModelError("Payers", "At this moment, self expenses are not supported. Please consider other alternatives.");
                return(null);
            }
            var sum = detailedExpense.Items.Sum(i => i.Payers.Sum(p => p.Amount * (decimal)p.Multiplier));
            if (sum > 0)
            {
                ModelState.AddModelError("Payers", "An Item cannot be proportional and even at the same time. Amount and Multiplier cannot be filled at the same time. Please, select only one.");
                return(null);
            }
            entity.Items = detailedExpense.Items.Select(i =>
            {
                var item    = (ExpenseItem)i;
                item.Payers = i.Payers.Select(p => new Payer
                {
                    Id     = p.Id,
                    Name   = payers.Single(x => x.Id == p.Id).Name,
                    Amount = i.Distribution.GetAmount(i, p)
                });
                return(item);
            });
            var itemsTotal = entity.Items.Sum(x => x.Total);
            if (itemsTotal != entity.Total)
            {
                ModelState.AddModelError("Items", "The total amount for this expense and the total amount by items differ.");
                return(null);
            }
            var total = entity.Items.Sum(i => i.Payers.Sum(p => p.Amount));
            if (total != detailedExpense.Total)
            {
                ModelState.AddModelError("Payer", "The  total amount for this expense and the total amount by payers' distribution differ.");
                return(null);
            }
            #endregion
            #endregion

            var result = _expenses.Add(entity);
            if (result != null)
            {
                UpdateBalances(entity.Items.SelectMany(x => x.Payers), entity.Payee, entity.Total);
            }

            return(result);
        }