static PriorityBonusDto GetAttendanceBonus(PriorityScope scope, int attendances)
 {
     return(new AttendancePriorityBonusDto
     {
         Type = PriorityBonusTypes.Attendance,
         Value = (int)Math.Floor((double)Math.Min(attendances, scope.ObservedAttendances) / scope.AttendancesPerPoint),
         AttendancePerPoint = scope.AttendancesPerPoint,
         Attended = attendances,
         ObservedAttendances = scope.ObservedAttendances
     });
 }
 static PriorityBonusDto GetStatusBonus(PriorityScope scope, RaidMemberStatus status)
 {
     return(new MembershipPriorityBonusDto
     {
         Type = PriorityBonusTypes.Trial,
         Value = status switch
         {
             RaidMemberStatus.HalfTrial => scope.HalfTrialPenalty,
             RaidMemberStatus.FullTrial => scope.FullTrialPenalty,
             RaidMemberStatus.Member => 0,
             _ => throw new ArgumentOutOfRangeException(nameof(status))
         },
    public static IEnumerable <PriorityBonusDto> GetListBonuses(
        PriorityScope scope,
        int attendances,
        RaidMemberStatus status,
        long donatedCopper,
        bool enchanted,
        bool prepared)
    {
        yield return(GetAttendanceBonus(scope, attendances));

        yield return(GetStatusBonus(scope, status));

        yield return(GetDonationBonus(scope, donatedCopper));

        yield return(GetEnchantedBonus(enchanted));

        yield return(GetPreparedBonus(prepared));
    public async Task <DonationMatrix> GetDonationMatrixAsync(Expression <Func <Donation, bool> > predicate, PriorityScope scope, CancellationToken cancellationToken = default)
    {
        var results = await Donations
                      .AsNoTracking()
                      .Where(d => d.RemovalId == null)
                      .Where(predicate)
                      .Select(d => new { d.DonatedAt.Year, d.DonatedAt.Month, d.CharacterId, d.CopperAmount })
                      .GroupBy(d => new { d.Year, d.Month, d.CharacterId })
                      .Select(g => new MonthDonations
        {
            CharacterId = g.Key.CharacterId,
            Donated     = g.Sum(d => d.CopperAmount),
            Month       = g.Key.Month,
            Year        = g.Key.Year,
        })
                      .OrderBy(md => md.CharacterId)
                      .ThenBy(md => md.Year)
                      .ThenBy(md => md.Month)
                      .ToListAsync(cancellationToken);

        return(new(results, scope));
    }
 public static int CalculateAttendanceBonus(int attendances, PriorityScope scope)
 {
     return((int)Math.Floor((double)Math.Min(attendances, scope.ObservedAttendances) / scope.AttendancesPerPoint));
 }
Example #6
0
    public static async Task <List <MemberDto> > GetMembersAsync(ApplicationDbContext context, TimeZoneInfo timeZone, IQueryable <Character> characterQuery, PriorityScope scope, long teamId, string teamName, bool isLeader)
    {
        var now       = timeZone.TimeZoneNow();
        var thisMonth = new DateTime(now.Year, now.Month, 1);
        var lastMonth = thisMonth.AddMonths(-1);

        var members = new List <MemberDto>();

        await foreach (var character in characterQuery
                       .Select(c => new
        {
            c.Class,
            c.Id,
            c.Name,
            c.Race,
            c.IsFemale,
            c.MemberStatus,
            c.JoinedTeamAt,
            c.Enchanted,
            c.Prepared,
            Verified = c.VerifiedById.HasValue,
            LootLists = c.CharacterLootLists.Select(l => new
            {
                l.MainSpec,
                l.ApprovedBy,
                ApprovedByName = l.ApprovedBy.HasValue ? context.Users.Where(u => u.Id == l.ApprovedBy).Select(u => u.UserName).FirstOrDefault() : null,
                l.Status,
                l.Phase
            }).ToList(),
        })
                       .AsSingleQuery()
                       .AsAsyncEnumerable())
        {
            var memberDto = new MemberDto
            {
                Character = new()
                {
                    Class    = character.Class,
                    Gender   = character.IsFemale ? Gender.Female : Gender.Male,
                    Id       = character.Id,
                    Name     = character.Name,
                    Race     = character.Race,
                    TeamId   = teamId,
                    TeamName = teamName,
                    Verified = character.Verified
                },
                Enchanted = character.Enchanted,
                JoinedAt  = character.JoinedTeamAt,
                Status    = character.MemberStatus,
                ThisMonthRequiredDonations = scope.RequiredDonationCopper,
                NextMonthRequiredDonations = scope.RequiredDonationCopper,
                Prepared = character.Prepared
            };

            foreach (var lootList in character.LootLists.OrderBy(ll => ll.Phase))
            {
                var lootListDto = new MemberLootListDto
                {
                    Status   = lootList.Status,
                    MainSpec = lootList.MainSpec,
                    Phase    = lootList.Phase
                };

                if (isLeader)
                {
                    if (lootList.ApprovedBy.HasValue)
                    {
                        lootListDto.Approved   = true;
                        lootListDto.ApprovedBy = lootList.ApprovedByName;
                    }
                    else
                    {
                        lootListDto.Approved = false;
                    }
                }

                memberDto.LootLists.Add(lootListDto);
            }

            members.Add(memberDto);
        }

        var memberIds      = members.ConvertAll(m => m.Character.Id);
        var donationMatrix = await context.GetDonationMatrixAsync(d => memberIds.Contains(d.CharacterId), scope);

        var attendanceTable = await context.GetAttendanceTableAsync(teamId, scope.ObservedAttendances);

        foreach (var member in members)
        {
            member.DonatedThisMonth = donationMatrix.GetCreditForMonth(member.Character.Id, now);
            member.DonatedNextMonth = donationMatrix.GetDonatedDuringMonth(member.Character.Id, now);

            if (member.DonatedThisMonth > scope.RequiredDonationCopper)
            {
                member.DonatedNextMonth += member.DonatedThisMonth - scope.RequiredDonationCopper;
            }

            if (attendanceTable.TryGetValue(member.Character.Id, out var attendance))
            {
                member.Attended = attendance;
            }

            member.ObservedAttendances = scope.ObservedAttendances;
        }

        return(members);
    }
}