예제 #1
0
        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);
        }
예제 #2
0
 public decimal MaxBillableHours(int userId)
 {
     return(DailyTime.Where(b => b.UserId == userId).SumOrDefault(b => b.TotalHours - b.BilledHours));
 }
예제 #3
0
        /// <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);
        }