public static async Task <bool> MergeFamilyInvoices(int parentID) { using (var context = new OverstagContext()) { var parent = context.Accounts .Include(g => g.Subscriptions).ThenInclude(i => i.Event) .Include(h => h.Invoices).First(f => f.Id == parentID); var family = context.Families .Include(g => g.Members).ThenInclude(h => h.Subscriptions).ThenInclude(i => i.Event) .Include(g => g.Members).ThenInclude(h => h.Invoices) .First(f => f.ParentID == parent.Id); if (family.Members.Count() == 0) { return(true); } // event, (friendCount, consumptionTax) Dictionary <Event, (int, int)> Subs = new Dictionary <Event, (int, int)>(); foreach (var member in family.Members) { if (member.Invoices.Count(f => !f.Paid) == 0) { continue; } foreach (var invoice in member.Invoices.Where(f => !f.Paid)) { List <Participate> participates = new List <Participate>(); foreach (int eventID in invoice.EventIDs.Split(',').Select(f => Convert.ToInt32(f)).ToList()) { participates.Add(member.Subscriptions.First(f => f.EventID == eventID)); } foreach (var part in participates) { if (Subs.ContainsKey(part.Event)) { ValueTuple <int, int> values; Subs.TryGetValue(part.Event, out values); values.Item1 += (part.FriendCount + 1); values.Item2 += part.AdditionsCost; Subs[part.Event] = values; } else { Subs.Add(part.Event, (part.FriendCount, part.AdditionsCost)); } } context.Invoices.Remove(invoice); } } if (Subs.Count() == 0) { return(true); } List <Participate> existingSubscriptions = parent.Subscriptions.ToList(); foreach (var sub in Subs) { if (!existingSubscriptions.Any(f => f.EventID == sub.Key.Id)) { parent.Subscriptions.Add(new Participate { Event = sub.Key, FriendCount = (byte)sub.Value.Item1, AdditionsCost = sub.Value.Item2, Paid = true }); } } await context.Invoices.AddAsync(new Invoice() { AdditionsCost = Subs.Values.Sum(f => f.Item2), EventIDs = string.Join(',', Subs.Select(f => f.Key.Id)), User = parent, Paid = false, Timestamp = DateTime.Now, InvoiceID = Encryption.Random.rHash("INV" + DateTime.Now.ToLongTimeString()), Amount = (Subs.Sum(f => (f.Key.Cost * (1 + f.Value.Item1))) + Subs.Sum(f => f.Value.Item2)) }); context.Accounts.Update(parent); await context.SaveChangesAsync(); return(true); } }