示例#1
0
        public async Task LogNewSpending(long userId, DaoSpending newSpending)
        {
            dynamic historyEntry = new ExpandoObject();

            // SpendingId
            historyEntry.SpendingId = newSpending.Id;

            // Name
            historyEntry.Name = newSpending.Name;

            // Money
            historyEntry.Money = newSpending.MoneyOwed;

            // Debtors
            var debtors = newSpending.Debtors
                          .Select(x => new
            {
                id   = x.DebtorUserId,
                debt = x.Debt
            });

            historyEntry.Debtors = debtors;

            // Log
            await LogHistory(userId, newSpending.GroupId, debtors.Select(x => x.id).ToArray(), DaoLogType.Type.CREATE, DaoLogSubType.Type.SPENDING, historyEntry);
        }
示例#2
0
        public async Task CreateNewSpending(long userId, NewSpending newSpending)
        {
            var daoGroup = await GroupService.GetGroupOfUser(userId, newSpending.GroupId);

            if (!newSpending.Debtors.All(x => daoGroup.Members.Any(m => m.UserId == x.DebtorId)))
            {
                throw new BusinessException("debtor_not_member");
            }

            if (newSpending.Debtors.Any(x => x.DebtorId == userId))
            {
                throw new BusinessException("self_debt");
            }

            using (var transaction = Context.Database.BeginTransaction())
            {
                try
                {
                    DaoSpending spending = new DaoSpending()
                    {
                        Name           = newSpending.Name,
                        MoneyOwed      = newSpending.MoneySpent,
                        CreditorUserId = userId,
                        GroupId        = daoGroup.Id,
                        Creditor       = await UserService.GetUser(userId),
                        Group          = daoGroup
                    };

                    spending.Debtors = newSpending.Debtors.Select(x => new DaoDebtor()
                    {
                        Spending     = spending,
                        DebtorUserId = x.DebtorId,
                        Debt         = x.Debt
                    }).ToList();

                    await Context.Spendings.AddAsync(spending);

                    await OptimizedService.OptimizeForNewSpending(userId, newSpending);

                    await Context.SaveChangesAsync();

                    // Call log AFTER saving, so ID is present
                    await HistoryService.LogNewSpending(userId, spending);

                    await Context.SaveChangesAsync();


                    transaction.Commit();
                }
                catch
                {
                    transaction.Rollback();
                    throw;
                }
            }
        }
示例#3
0
        public async Task LogRemoveSpending(long userId, long groupId, DaoSpending deletedSpending, HashSet <long> affectedUsers)
        {
            dynamic historyEntry = new ExpandoObject();

            // Removed spending
            historyEntry.DeletedSpending = new
            {
                Name      = deletedSpending.Name,
                MoneyOwed = deletedSpending.MoneyOwed,
                Debtors   = deletedSpending.Debtors.Select(d => new
                {
                    DebtorId = d.DebtorUserId,
                    Debt     = d.Debt
                })
            };

            await LogHistory(userId, groupId, affectedUsers.ToArray(), DaoLogType.Type.REMOVE, DaoLogSubType.Type.MEMBER, historyEntry);
        }
示例#4
0
 public SpendingData ToSpendingData(DaoSpending daoSpending)
 {
     return(new SpendingData()
     {
         Name = daoSpending.Name,
         Creditor = new UserData()
         {
             Id = daoSpending.Creditor.Id,
             Name = daoSpending.Creditor.DisplayName
         },
         CreditorUserId = daoSpending.CreditorUserId,
         Id = daoSpending.Id,
         MoneyOwed = daoSpending.MoneyOwed,
         Debtors = daoSpending.Debtors.Select(daoDebtor => new DebtorData()
         {
             Id = daoDebtor.DebtorUserId,
             Name = daoDebtor.Debtor.DisplayName,
             Debt = daoDebtor.Debt
         }).ToList()
     });
 }
示例#5
0
        public async Task LogSpendingUpdate(long userId, DaoSpending oldSpending, SpendingUpdate newSpending)
        {
            dynamic historyEntry = new ExpandoObject();

            // Make name delta
            if (oldSpending.Name != newSpending.Name)
            {
                historyEntry.oldName = oldSpending.Name;
                historyEntry.newName = newSpending.Name;
            }

            // Make money delta
            if (oldSpending.MoneyOwed != newSpending.MoneySpent)
            {
                historyEntry.oldMoney = oldSpending.MoneyOwed;
                historyEntry.newMoney = newSpending.MoneySpent;
            }

            // Record removed debts
            var removedDebts = oldSpending.Debtors
                               .Select(x => x.DebtorUserId)
                               .Except(newSpending.Debtors.Select(x => x.DebtorId))
                               .Join(oldSpending.Debtors.Select(x => (x.Debt, x.DebtorUserId)),
                                     (oldD) => oldD,
                                     (newD) => newD.DebtorUserId,
                                     (id, olddebt) => new
            {
                id   = id,
                debt = olddebt.Debt
            });

            if (removedDebts.Any())
            {
                historyEntry.removedDebts = removedDebts;
            }

            // Record added debts
            var addedDebts = newSpending.Debtors
                             .Select(x => x.DebtorId)
                             .Except(oldSpending.Debtors.Select(x => x.DebtorUserId))
                             .Join(newSpending.Debtors.Select(x => (x.Debt, x.DebtorId)),
                                   (oldD) => oldD,
                                   (newD) => newD.DebtorId,
                                   (id, olddebt) => new
            {
                id   = id,
                debt = olddebt.Debt
            });

            if (addedDebts.Any())
            {
                historyEntry.addedDebts = addedDebts;
            }

            // Record updated debts
            var updatedDebts = newSpending.Debtors
                               .Select(x => (x.Debt, x.DebtorId))
                               .Join(oldSpending.Debtors.Select(x => (x.Debt, x.DebtorUserId)),
                                     (oldD) => oldD.DebtorId,
                                     (newD) => newD.DebtorUserId,
                                     (newdebt, olddebt) => new
            {
                id      = olddebt.DebtorUserId,                // should be same as newdebt.DebtorUserId!
                oldDebt = olddebt.Debt,
                newDebt = newdebt.Debt
            })
                               .Where(x => x.oldDebt != x.newDebt);

            if (updatedDebts.Any())
            {
                historyEntry.updatedDebts = updatedDebts;
            }

            // Log
            await LogHistory(userId, oldSpending.GroupId, oldSpending.Debtors.Select(x => x.DebtorUserId).Union(newSpending.Debtors.Select(x => x.DebtorId)).ToArray(), DaoLogType.Type.UPDATE, DaoLogSubType.Type.SPENDING, historyEntry);
        }
示例#6
0
        public async Task CreateNewSpending(NewSpending newSpending, long userId)
        {
            var currentUser = await DbContext.Users.FindAsync(userId);

            if (currentUser == null)
            {
                throw new ResourceGoneException("current_user_gone");
            }

            var currentGroup = await DbContext.Groups
                               .Include(x => x.Members)
                               .SingleOrDefaultAsync(x => x.Id == newSpending.GroupId);

            if (currentGroup == null)
            {
                throw new ResourceGoneException("group_gone");
            }

            if (newSpending.Debtors.Any(x => newSpending.Debtors.Count(d => d.DebtorId == x.DebtorId) > 1))
            {
                throw new BusinessException("duplicate_debtor_id_found");
            }

            if (!currentGroup.Members.Any(x => x.UserId == userId))
            {
                throw new ResourceForbiddenException("user_not_member");
            }

            if (newSpending.Debtors.Any() &&
                !newSpending.Debtors.All(x => currentGroup.Members.Any(m => m.UserId == x.DebtorId)))
            {
                throw new BusinessException("not_all_debtors_are_members");
            }

            if (newSpending.Debtors.Any() &&
                !newSpending.Debtors.All(x => DbContext.Users.Find(x.DebtorId) != null))
            {
                throw new ResourceGoneException("debtor_gone");
            }


            DaoSpending spending = new DaoSpending()
            {
                Name           = newSpending.Name,
                MoneyOwed      = newSpending.MoneySpent,
                Group          = currentGroup,
                GroupId        = currentGroup.Id,
                Creditor       = currentUser,
                CreditorUserId = currentUser.Id
            };

            var nonSpecifiedCount = newSpending.Debtors.Any()
                ? newSpending.Debtors.Count(s => !s.Debt.HasValue)
                : currentGroup.Members.Count();

            var autoCalculatedIndividualDebt = nonSpecifiedCount == 0
                ? 0
                : (newSpending.MoneySpent - newSpending.Debtors.Sum(x => x.Debt ?? 0)) / nonSpecifiedCount;

            var debtors = newSpending.Debtors.Select(x => new DaoDebtor()
            {
                Spending     = spending,
                DebtorUserId = x.DebtorId,
                Debt         = x.Debt ?? autoCalculatedIndividualDebt
            }).ToList();

            // If there were no debtors, populate it from group members
            if (!debtors.Any())
            {
                debtors = currentGroup.Members.Select(x => new DaoDebtor()
                {
                    Spending     = spending,
                    DebtorUserId = x.UserId,
                    Debt         = autoCalculatedIndividualDebt
                }).ToList();
            }

            spending.Debtors = debtors.ToList();

            var insertCount = 1 + spending.Debtors.Count;
            await DbContext.Spendings.AddAsync(spending);

            if (await DbContext.SaveChangesAsync() != insertCount)
            {
                throw new DatabaseException("spending_not_inserted");
            }
        }