public decimal CalculateInvoiceSum(int userId, decimal hours) { var sum = 0M; var nonBilledHours = hours; var dailyTime = DailyTime.Where(t => t.UserId == userId) .Where(t => t.TotalHours - t.BilledHours > 0) .OrderBy(t => t.Date); foreach (var time in dailyTime) { var billingHours = Math.Min(nonBilledHours, time.TotalHours - time.BilledHours); sum += billingHours * time.HourlyRate; nonBilledHours -= billingHours; if (nonBilledHours == 0) { break; } } return(sum); }
public decimal MaxBillableHours(int userId) { return(DailyTime.Where(b => b.UserId == userId).SumOrDefault(b => b.TotalHours - b.BilledHours)); }
/// <summary> /// Recalculate billable hours for one user. /// </summary> private void UpdateUserBilling(int userId) { var result = new List <Billing>(); var dailyTimeToBill = DailyTime.Where(t => t.UserId == userId).OrderBy(t => t.Date).ToArray(); // reset hours info foreach (var time in dailyTimeToBill) { time.BilledHours = 0; time.PaidHours = 0; } using (var invoices = Invoices.Where(i => !i.IsCancelled) .Where(i => i.UserId == userId) .OrderBy(i => i.At) .GetEnumerator()) { if (!invoices.MoveNext()) { return; } var invoiceHours = invoices.Current.Hours; foreach (var time in dailyTimeToBill) { var hoursToBill = time.TotalHours; var lastInvoice = false; while (hoursToBill > 0) { var billedHours = Math.Min(hoursToBill, invoiceHours); result.Add(new Billing { At = time.Date, Hours = billedHours, InvoiceNum = invoices.Current.InvoiceNum, IsPaid = invoices.Current.IsPaid, Rate = time.HourlyRate, UserId = userId }); time.BilledHours += billedHours; time.PaidHours += invoices.Current.IsPaid ? billedHours : 0; hoursToBill -= billedHours; invoiceHours -= billedHours; if (invoiceHours == 0) { if (invoices.MoveNext()) { invoiceHours = invoices.Current.Hours; } else { lastInvoice = true; break; } } } if (lastInvoice) { break; } } } // replace user billing with new result _billing.RemoveAll(b => b.UserId == userId); _billing.AddRange(result); }