public ViewModels.Billing.GroupInvoiceViewModel BuildGroupInvoiceViewModel(int id, DateTime?startDate = null, DateTime?stopDate = null, string rateFrom = null)
        {
            Common.Models.Billing.BillingRate        billingRate = null;
            Common.Models.Billing.BillingGroup       billingGroup;
            ViewModels.Billing.GroupInvoiceViewModel viewModel       = new ViewModels.Billing.GroupInvoiceViewModel();
            Common.Models.Billing.Invoice            previousInvoice = null;
            List <Common.Models.Matters.Matter>      mattersList;

            if (!string.IsNullOrEmpty(Request["StartDate"]))
            {
                startDate = DateTime.Parse(Request["StartDate"]);
            }
            if (!string.IsNullOrEmpty(Request["StopDate"]))
            {
                stopDate = DateTime.Parse(Request["StopDate"]);
            }

            billingGroup    = Data.Billing.BillingGroup.Get(id);
            previousInvoice = Data.Billing.Invoice.GetMostRecentInvoiceForContact(billingGroup.BillTo.Id.Value);

            billingGroup.NextRun = new DateTime(DateTime.Now.Year, DateTime.Now.Month + 1, 1);

            viewModel.Id           = Guid.NewGuid();
            viewModel.BillTo       = Mapper.Map <ViewModels.Contacts.ContactViewModel>(Data.Contacts.Contact.Get(billingGroup.BillTo.Id.Value));
            viewModel.Date         = DateTime.Now;
            viewModel.Due          = DateTime.Now.AddDays(30);
            viewModel.BillingGroup = Mapper.Map <ViewModels.Billing.BillingGroupViewModel>(billingGroup);

            if (previousInvoice == null)
            {
                viewModel.BillTo_NameLine1 = viewModel.BillTo.DisplayName;
                if (string.IsNullOrEmpty(viewModel.BillTo.Address1AddressPostOfficeBox))
                {
                    viewModel.BillTo_AddressLine1 = viewModel.BillTo.Address1AddressStreet;
                }
                else
                {
                    viewModel.BillTo_AddressLine1 = "P.O. Box " + viewModel.BillTo.Address1AddressPostOfficeBox;
                }
                viewModel.BillTo_City  = viewModel.BillTo.Address1AddressCity;
                viewModel.BillTo_State = viewModel.BillTo.Address1AddressStateOrProvince;
                viewModel.BillTo_Zip   = viewModel.BillTo.Address1AddressPostalCode;
            }
            else
            {
                viewModel.BillTo_NameLine1    = previousInvoice.BillTo_NameLine1;
                viewModel.BillTo_NameLine2    = previousInvoice.BillTo_NameLine2;
                viewModel.BillTo_AddressLine1 = previousInvoice.BillTo_AddressLine1;
                viewModel.BillTo_AddressLine2 = previousInvoice.BillTo_AddressLine2;
                viewModel.BillTo_City         = previousInvoice.BillTo_City;
                viewModel.BillTo_State        = previousInvoice.BillTo_State;
                viewModel.BillTo_Zip          = previousInvoice.BillTo_Zip;
            }

            // Get list of matters for the group
            mattersList = Data.Billing.BillingGroup.ListMattersForGroup(billingGroup.Id.Value);

            for (int i = 0; i < mattersList.Count; i++)
            {
                ViewModels.Billing.GroupInvoiceItemViewModel giivm = new ViewModels.Billing.GroupInvoiceItemViewModel();
                Common.Models.Matters.Matter matter = mattersList[i];

                giivm.Matter = Mapper.Map <ViewModels.Matters.MatterViewModel>(matter);

                Data.Timing.Time.ListUnbilledAndBillableTimeForMatter(matter.Id.Value, startDate, stopDate).ForEach(x =>
                {
                    ViewModels.Billing.InvoiceTimeViewModel vm = new ViewModels.Billing.InvoiceTimeViewModel()
                    {
                        //Invoice = viewModel,
                        Time    = Mapper.Map <ViewModels.Timing.TimeViewModel>(x),
                        Details = x.Details
                    };
                    if (x.Stop.HasValue)
                    {
                        vm.Duration = x.Stop.Value - x.Start;
                    }
                    else
                    {
                        vm.Duration = new TimeSpan(0);
                    }

                    if (string.IsNullOrEmpty(Request["RateFrom"]))
                    { // Not specified in URL
                        if (matter.OverrideMatterRateWithEmployeeRate)
                        {
                            Common.Models.Contacts.Contact contact = Data.Contacts.Contact.Get(x.Worker.Id.Value);
                            if (contact.BillingRate != null && contact.BillingRate.Id.HasValue)
                            {
                                billingRate = Data.Billing.BillingRate.Get(contact.BillingRate.Id.Value);
                            }
                        }
                    }
                    else
                    { // Overridden by current user in URL
                        if (Request["RateFrom"] == "Employee")
                        {
                            Common.Models.Contacts.Contact contact = Data.Contacts.Contact.Get(x.Worker.Id.Value);
                            if (contact.BillingRate != null && contact.BillingRate.Id.HasValue)
                            {
                                billingRate = Data.Billing.BillingRate.Get(contact.BillingRate.Id.Value);
                            }
                        }
                    }

                    if (billingRate != null)
                    {
                        vm.PricePerHour = billingRate.PricePerUnit;
                    }

                    giivm.Times.Add(vm);
                });

                Data.Billing.Expense.ListUnbilledExpensesForMatter(matter.Id.Value, startDate, stopDate).ForEach(x =>
                {
                    giivm.Expenses.Add(new ViewModels.Billing.InvoiceExpenseViewModel()
                    {
                        //Invoice = viewModel,
                        Expense = Mapper.Map <ViewModels.Billing.ExpenseViewModel>(x),
                        Details = x.Details,
                        Amount  = x.Amount
                    });
                });

                Data.Billing.Fee.ListUnbilledFeesForMatter(matter.Id.Value, startDate, stopDate).ForEach(x =>
                {
                    giivm.Fees.Add(new ViewModels.Billing.InvoiceFeeViewModel()
                    {
                        //Invoice = viewModel,
                        Fee     = Mapper.Map <ViewModels.Billing.FeeViewModel>(x),
                        Details = x.Details,
                        Amount  = x.Amount
                    });
                });

                if ((giivm.Times.Count > 0) ||
                    (giivm.Expenses.Count > 0) ||
                    (giivm.Fees.Count > 0))
                {
                    viewModel.Matters.Add(giivm);
                }
            }

            ViewData["FirmName"]    = Common.Settings.Manager.Instance.System.BillingFirmName;
            ViewData["FirmAddress"] = Common.Settings.Manager.Instance.System.BillingFirmAddress;
            ViewData["FirmCity"]    = Common.Settings.Manager.Instance.System.BillingFirmCity;
            ViewData["FirmState"]   = Common.Settings.Manager.Instance.System.BillingFirmState;
            ViewData["FirmZip"]     = Common.Settings.Manager.Instance.System.BillingFirmZip;
            ViewData["FirmPhone"]   = Common.Settings.Manager.Instance.System.BillingFirmPhone;
            ViewData["FirmWeb"]     = Common.Settings.Manager.Instance.System.BillingFirmWeb;

            return(viewModel);
        }
        public ActionResult SingleGroupBill(int id, ViewModels.Billing.GroupInvoiceViewModel viewModel)
        {
            // Create Invoice
            // Loop Matters
            // Loop Expenses
            // Loop Fees
            // Loop Times
            // Redirect to invoice viewing
            DateTime?start = null, stop = null;

            Common.Models.Account.Users                 currentUser;
            Common.Models.Billing.BillingGroup          billingGroup;
            ViewModels.Billing.GroupInvoiceViewModel    builtGroupInvoice;
            ViewModels.Billing.InvoiceExpenseViewModel  ievm;
            ViewModels.Billing.InvoiceFeeViewModel      ifvm;
            ViewModels.Billing.InvoiceTimeViewModel     itvm;
            List <Common.Models.Billing.InvoiceExpense> invoiceExpenseList;
            List <Common.Models.Billing.InvoiceFee>     invoiceFeeList;
            List <Common.Models.Billing.InvoiceTime>    invoiceTimeList;

            if (!string.IsNullOrEmpty(Request["StartDate"]))
            {
                start = DateTime.Parse(Request["StartDate"]);
            }
            if (!string.IsNullOrEmpty(Request["StopDate"]))
            {
                stop = DateTime.Parse(Request["StopDate"]);
            }

            currentUser          = Data.Account.Users.Get(User.Identity.Name);
            billingGroup         = Data.Billing.BillingGroup.Get(id);
            billingGroup.Amount  = viewModel.BillingGroup.Amount;
            billingGroup.NextRun = viewModel.BillingGroup.NextRun;

            builtGroupInvoice = BuildGroupInvoiceViewModel(id, start, stop, Request["rateFrom"]);

            // Validation

            // Loop for each matter
            for (int j = 0; j < viewModel.Matters.Count; j++)
            {
                ViewModels.Billing.GroupInvoiceItemViewModel giivm =
                    builtGroupInvoice.Matters.Single(x => x.Matter.Id.Value == viewModel.Matters[j].Matter.Id.Value);

                for (int i = 0; i < viewModel.Matters[j].Expenses.Count; i++)
                {
                    ievm = giivm.Expenses.Single(x => x.Expense.Id.Value == viewModel.Matters[j].Expenses[i].Expense.Id.Value);
                    viewModel.Matters[j].Expenses[i].Expense = ievm.Expense;
                    if (string.IsNullOrEmpty(viewModel.Matters[j].Expenses[i].Details))
                    {
                        ModelState.AddModelError(string.Format("Matters[{0}].Expenses[{1}].Details", j, i), "Required");
                    }
                }
                ;
                for (int i = 0; i < viewModel.Matters[j].Fees.Count; i++)
                {
                    ifvm = giivm.Fees.Single(x => x.Fee.Id.Value == viewModel.Matters[j].Fees[i].Fee.Id.Value);
                    viewModel.Matters[j].Fees[i].Fee = ifvm.Fee;
                    if (string.IsNullOrEmpty(viewModel.Matters[j].Fees[i].Details))
                    {
                        ModelState.AddModelError(string.Format("Matters[{0}].Fees[{1}].Details", j, i), "Required");
                    }
                }
                ;
                for (int i = 0; i < viewModel.Matters[j].Times.Count; i++)
                {
                    itvm = giivm.Times.Single(x => x.Time.Id.Value == viewModel.Matters[j].Times[i].Time.Id);
                    viewModel.Matters[j].Times[i].Time = itvm.Time;
                    if (string.IsNullOrEmpty(viewModel.Matters[j].Times[i].Details))
                    {
                        ModelState.AddModelError(string.Format("Matters[{0}].Times[{1}].Details", j, i), "Required");
                    }
                }
                ;
            }

            ModelState["id"].Errors.Clear();
            if (!ModelState.IsValid)
            {
                // Errors - do nothing, but tell user and show again for fixing
                ViewData["FirmName"]    = Common.Settings.Manager.Instance.System.BillingFirmName;
                ViewData["FirmAddress"] = Common.Settings.Manager.Instance.System.BillingFirmAddress;
                ViewData["FirmCity"]    = Common.Settings.Manager.Instance.System.BillingFirmCity;
                ViewData["FirmState"]   = Common.Settings.Manager.Instance.System.BillingFirmState;
                ViewData["FirmZip"]     = Common.Settings.Manager.Instance.System.BillingFirmZip;
                ViewData["FirmPhone"]   = Common.Settings.Manager.Instance.System.BillingFirmPhone;
                ViewData["FirmWeb"]     = Common.Settings.Manager.Instance.System.BillingFirmWeb;
                return(View(viewModel));
            }

            Common.Models.Billing.Invoice invoice = new Common.Models.Billing.Invoice()
            {
                Id                  = viewModel.Id,
                BillTo              = Mapper.Map <Common.Models.Contacts.Contact>(viewModel.BillTo),
                Date                = viewModel.Date,
                Due                 = viewModel.Due,
                Subtotal            = viewModel.Subtotal,
                TaxAmount           = viewModel.TaxAmount,
                Total               = viewModel.Total,
                ExternalInvoiceId   = viewModel.ExternalInvoiceId,
                BillTo_NameLine1    = viewModel.BillTo_NameLine1,
                BillTo_NameLine2    = viewModel.BillTo_NameLine2,
                BillTo_AddressLine1 = viewModel.BillTo_AddressLine1,
                BillTo_AddressLine2 = viewModel.BillTo_AddressLine2,
                BillTo_City         = viewModel.BillTo_City,
                BillTo_State        = viewModel.BillTo_State,
                BillTo_Zip          = viewModel.BillTo_Zip,
                BillingGroup        = new Common.Models.Billing.BillingGroup()
                {
                    Id = id
                }
            };

            invoiceExpenseList = new List <Common.Models.Billing.InvoiceExpense>();
            invoiceFeeList     = new List <Common.Models.Billing.InvoiceFee>();
            invoiceTimeList    = new List <Common.Models.Billing.InvoiceTime>();

            viewModel.Matters.ForEach(matterVM =>
            {
                matterVM.Expenses.ForEach(vm =>
                {
                    invoiceExpenseList.Add(new Common.Models.Billing.InvoiceExpense()
                    {
                        Invoice = invoice,
                        Expense = new Common.Models.Billing.Expense()
                        {
                            Id = vm.Expense.Id
                        },
                        Amount  = vm.Amount,
                        Details = vm.Details
                    });
                });

                matterVM.Fees.ForEach(vm =>
                {
                    invoiceFeeList.Add(new Common.Models.Billing.InvoiceFee()
                    {
                        Invoice = invoice,
                        Fee     = new Common.Models.Billing.Fee()
                        {
                            Id = vm.Fee.Id
                        },
                        Amount  = vm.Amount,
                        Details = vm.Details
                    });
                });

                matterVM.Times.ForEach(vm =>
                {
                    invoiceTimeList.Add(new Common.Models.Billing.InvoiceTime()
                    {
                        Invoice = invoice,
                        Time    = new Common.Models.Timing.Time()
                        {
                            Id = vm.Time.Id
                        },
                        Duration     = vm.Duration,
                        PricePerHour = vm.PricePerHour,
                        Details      = vm.Details
                    });
                });
            });

            invoice = Data.Billing.Billing.SingleGroupBill(
                billingGroup,
                invoice,
                invoiceExpenseList,
                invoiceFeeList,
                invoiceTimeList,
                currentUser,
                null, true);

            return(RedirectToAction("GroupDetails", "Invoices", new { id = invoice.Id }));
        }
        public ActionResult GroupDetails(Guid id)
        {
            Common.Models.Billing.BillingGroup billingGroup;
            ViewModels.Billing.GroupInvoiceViewModel viewModel = new ViewModels.Billing.GroupInvoiceViewModel();
            List<Common.Models.Matters.Matter> mattersList;
            Common.Models.Billing.Invoice invoice = null;

            invoice = Data.Billing.Invoice.Get(id);
            billingGroup = Data.Billing.BillingGroup.Get(invoice.BillingGroup.Id.Value);

            viewModel = new ViewModels.Billing.GroupInvoiceViewModel()
            {
                Id = invoice.Id,
                BillTo = new ViewModels.Contacts.ContactViewModel() { Id = invoice.BillTo.Id },
                Date = invoice.Date,
                Due = invoice.Due,
                Subtotal = invoice.Subtotal,
                TaxAmount = invoice.TaxAmount,
                Total = invoice.Total,
                ExternalInvoiceId = invoice.ExternalInvoiceId,
                BillTo_NameLine1 = invoice.BillTo_NameLine1,
                BillTo_NameLine2 = invoice.BillTo_NameLine2,
                BillTo_AddressLine1 = invoice.BillTo_AddressLine1,
                BillTo_AddressLine2 = invoice.BillTo_AddressLine2,
                BillTo_City = invoice.BillTo_City,
                BillTo_State = invoice.BillTo_State,
                BillTo_Zip = invoice.BillTo_Zip,
                BillingGroup = Mapper.Map<ViewModels.Billing.BillingGroupViewModel>(billingGroup)
            };

            mattersList = Data.Billing.BillingGroup.ListMattersForGroup(billingGroup.Id.Value);

            for (int i = 0; i < mattersList.Count; i++)
            {
                ViewModels.Billing.GroupInvoiceItemViewModel giivm = new ViewModels.Billing.GroupInvoiceItemViewModel();
                giivm.Matter = Mapper.Map<ViewModels.Matters.MatterViewModel>(mattersList[i]);

                Data.Billing.InvoiceExpense.ListForMatterAndInvoice(id, mattersList[i].Id.Value).ForEach(x =>
                {
                    ViewModels.Billing.InvoiceExpenseViewModel vm = Mapper.Map<ViewModels.Billing.InvoiceExpenseViewModel>(x);
                    vm.Expense = Mapper.Map<ViewModels.Billing.ExpenseViewModel>(Data.Billing.Expense.Get(vm.Expense.Id.Value));
                    giivm.ExpensesSum += vm.Amount;
                    giivm.Expenses.Add(vm);
                });

                Data.Billing.InvoiceFee.ListForMatterAndInvoice(id, mattersList[i].Id.Value).ForEach(x =>
                {
                    ViewModels.Billing.InvoiceFeeViewModel vm = Mapper.Map<ViewModels.Billing.InvoiceFeeViewModel>(x);
                    vm.Fee = Mapper.Map<ViewModels.Billing.FeeViewModel>(Data.Billing.Fee.Get(vm.Fee.Id.Value));
                    giivm.FeesSum += vm.Amount;
                    giivm.Fees.Add(vm);
                });

                Data.Billing.InvoiceTime.ListForMatterAndInvoice(id, mattersList[i].Id.Value).ForEach(x =>
                {
                    ViewModels.Billing.InvoiceTimeViewModel vm = Mapper.Map<ViewModels.Billing.InvoiceTimeViewModel>(x);
                    vm.Time = Mapper.Map<ViewModels.Timing.TimeViewModel>(Data.Timing.Time.Get(vm.Time.Id.Value));
                    giivm.TimeSum = giivm.TimeSum.Add(vm.Duration);
                    giivm.TimeSumMoney += vm.PricePerHour * (decimal)vm.Duration.TotalHours;
                    giivm.Times.Add(vm);
                });

                if ((giivm.Times.Count > 0) ||
                    (giivm.Expenses.Count > 0) ||
                    (giivm.Fees.Count > 0))
                viewModel.Matters.Add(giivm);
            }

            ViewData["FirmName"] = Common.Settings.Manager.Instance.System.BillingFirmName;
            ViewData["FirmAddress"] = Common.Settings.Manager.Instance.System.BillingFirmAddress;
            ViewData["FirmCity"] = Common.Settings.Manager.Instance.System.BillingFirmCity;
            ViewData["FirmState"] = Common.Settings.Manager.Instance.System.BillingFirmState;
            ViewData["FirmZip"] = Common.Settings.Manager.Instance.System.BillingFirmZip;
            ViewData["FirmPhone"] = Common.Settings.Manager.Instance.System.BillingFirmPhone;
            ViewData["FirmWeb"] = Common.Settings.Manager.Instance.System.BillingFirmWeb;

            return View(viewModel);
        }
        public ActionResult GroupDetails(Guid id)
        {
            Common.Models.Billing.BillingGroup billingGroup;
            ViewModels.Billing.GroupInvoiceViewModel viewModel = new ViewModels.Billing.GroupInvoiceViewModel();
            List<Common.Models.Matters.Matter> mattersList;
            Common.Models.Billing.Invoice invoice = null;

            using (IDbConnection conn = Data.Database.Instance.GetConnection())
            {
                invoice = Data.Billing.Invoice.Get(id, conn, false);
                billingGroup = Data.Billing.BillingGroup.Get(invoice.BillingGroup.Id.Value, conn, false);

                viewModel = new ViewModels.Billing.GroupInvoiceViewModel()
                {
                    Id = invoice.Id,
                    BillTo = new ViewModels.Contacts.ContactViewModel() { Id = invoice.BillTo.Id },
                    Date = invoice.Date,
                    Due = invoice.Due,
                    Subtotal = invoice.Subtotal,
                    TaxAmount = invoice.TaxAmount,
                    Total = invoice.Total,
                    ExternalInvoiceId = invoice.ExternalInvoiceId,
                    BillTo_NameLine1 = invoice.BillTo_NameLine1,
                    BillTo_NameLine2 = invoice.BillTo_NameLine2,
                    BillTo_AddressLine1 = invoice.BillTo_AddressLine1,
                    BillTo_AddressLine2 = invoice.BillTo_AddressLine2,
                    BillTo_City = invoice.BillTo_City,
                    BillTo_State = invoice.BillTo_State,
                    BillTo_Zip = invoice.BillTo_Zip,
                    BillingGroup = Mapper.Map<ViewModels.Billing.BillingGroupViewModel>(billingGroup)
                };

                mattersList = Data.Billing.BillingGroup.ListMattersForGroup(billingGroup.Id.Value, conn, false);

                for (int i = 0; i < mattersList.Count; i++)
                {
                    ViewModels.Billing.GroupInvoiceItemViewModel giivm = new ViewModels.Billing.GroupInvoiceItemViewModel();
                    giivm.Matter = Mapper.Map<ViewModels.Matters.MatterViewModel>(mattersList[i]);

                    Data.Billing.InvoiceExpense.ListForMatterAndInvoice(id, mattersList[i].Id.Value, conn, false).ForEach(x =>
                    {
                        ViewModels.Billing.InvoiceExpenseViewModel vm = Mapper.Map<ViewModels.Billing.InvoiceExpenseViewModel>(x);
                        vm.Expense = Mapper.Map<ViewModels.Billing.ExpenseViewModel>(
                            Data.Billing.Expense.Get(vm.Expense.Id.Value, conn, false));
                        giivm.ExpensesSum += vm.Amount;
                        giivm.Expenses.Add(vm);
                    });

                    Data.Billing.InvoiceFee.ListForMatterAndInvoice(id, mattersList[i].Id.Value, conn, false).ForEach(x =>
                    {
                        ViewModels.Billing.InvoiceFeeViewModel vm = Mapper.Map<ViewModels.Billing.InvoiceFeeViewModel>(x);
                        vm.Fee = Mapper.Map<ViewModels.Billing.FeeViewModel>(
                            Data.Billing.Fee.Get(vm.Fee.Id.Value, conn, false));
                        giivm.FeesSum += vm.Amount;
                        giivm.Fees.Add(vm);
                    });

                    Data.Billing.InvoiceTime.ListForMatterAndInvoice(id, mattersList[i].Id.Value, conn, false).ForEach(x =>
                    {
                        ViewModels.Billing.InvoiceTimeViewModel vm = Mapper.Map<ViewModels.Billing.InvoiceTimeViewModel>(x);
                        vm.Time = Mapper.Map<ViewModels.Timing.TimeViewModel>(
                            Data.Timing.Time.Get(vm.Time.Id.Value, conn, false));
                        
                        ViewModels.Billing.InvoiceTimeGroupViewModel timeGroup;
                        if (vm.Time.TimeCategory == null || !vm.Time.TimeCategory.Id.HasValue)
                            timeGroup = giivm.TimeGroups.SingleOrDefault(y => y.Id == 0);
                        else
                            timeGroup = giivm.TimeGroups.SingleOrDefault(y => y.Id == vm.Time.TimeCategory.Id);
                        if (timeGroup == null || timeGroup.Id == -1)
                        {
                            Common.Models.Timing.TimeCategory tc = Data.Timing.TimeCategory.Get(vm.Time.TimeCategory.Id.Value, conn, false);
                            timeGroup = new ViewModels.Billing.InvoiceTimeGroupViewModel()
                            {
                                Id = tc.Id.Value,
                                GroupName = tc.Title,
                                Times = new List<ViewModels.Billing.InvoiceTimeViewModel>()
                            };
                            timeGroup.Times.Add(vm);
                            giivm.TimeGroups.Add(timeGroup);
                        }
                        else
                            timeGroup.Times.Add(vm);

                        giivm.TimeSum = giivm.TimeSum.Add(vm.Duration);
                        giivm.TimeSumMoney += vm.PricePerHour * (decimal)vm.Duration.TotalHours;
                    });

                    if (((giivm.TimeGroups.Count > 0) && (giivm.TimeGroups.Count(x => x.Times.Count > 0) > 0)) ||
                        (giivm.Expenses.Count > 0) ||
                        (giivm.Fees.Count > 0))
                        viewModel.Matters.Add(giivm);
                }
            }

            ViewBag.Invoice = Mapper.Map<ViewModels.Billing.InvoiceViewModel>(invoice);
            ViewBag.BillingGroup = Mapper.Map<ViewModels.Billing.BillingGroupViewModel>(billingGroup);
            ViewData["FirmName"] = Common.Settings.Manager.Instance.System.BillingFirmName;
            ViewData["FirmAddress"] = Common.Settings.Manager.Instance.System.BillingFirmAddress;
            ViewData["FirmCity"] = Common.Settings.Manager.Instance.System.BillingFirmCity;
            ViewData["FirmState"] = Common.Settings.Manager.Instance.System.BillingFirmState;
            ViewData["FirmZip"] = Common.Settings.Manager.Instance.System.BillingFirmZip;
            ViewData["FirmPhone"] = Common.Settings.Manager.Instance.System.BillingFirmPhone;
            ViewData["FirmWeb"] = Common.Settings.Manager.Instance.System.BillingFirmWeb;

            return View(viewModel);
        }
        public ViewModels.Billing.GroupInvoiceViewModel BuildGroupInvoiceViewModel(int id, IDbConnection conn, bool closeConnection, DateTime? startDate = null, DateTime? stopDate = null, string rateFrom = null)
        {
            Common.Models.Billing.BillingRate billingRate = null;
            Common.Models.Billing.BillingGroup billingGroup;
            ViewModels.Billing.GroupInvoiceViewModel viewModel = new ViewModels.Billing.GroupInvoiceViewModel();
            Common.Models.Billing.Invoice previousInvoice = null;
            List<Common.Models.Matters.Matter> mattersList;

            if (!string.IsNullOrEmpty(Request["StartDate"]))
                startDate = DateTime.Parse(Request["StartDate"]);
            if (!string.IsNullOrEmpty(Request["StopDate"]))
                stopDate = DateTime.Parse(Request["StopDate"]);
            
            billingGroup = Data.Billing.BillingGroup.Get(id, conn, false);
            previousInvoice = Data.Billing.Invoice.GetMostRecentInvoiceForContact(billingGroup.BillTo.Id.Value, conn, false);

            billingGroup.NextRun = new DateTime(DateTime.Now.Year, DateTime.Now.AddMonths(1).Month, 1);

            viewModel.Id = Guid.NewGuid();
            viewModel.BillTo = Mapper.Map<ViewModels.Contacts.ContactViewModel>(Data.Contacts.Contact.Get(billingGroup.BillTo.Id.Value, conn, false));
            viewModel.Date = DateTime.Now;
            viewModel.Due = DateTime.Now.AddDays(30);
            viewModel.BillingGroup = Mapper.Map<ViewModels.Billing.BillingGroupViewModel>(billingGroup);

            if (previousInvoice == null)
            {
                viewModel.BillTo_NameLine1 = viewModel.BillTo.DisplayName;
                if (string.IsNullOrEmpty(viewModel.BillTo.Address1AddressPostOfficeBox))
                    viewModel.BillTo_AddressLine1 = viewModel.BillTo.Address1AddressStreet;
                else
                    viewModel.BillTo_AddressLine1 = "P.O. Box " + viewModel.BillTo.Address1AddressPostOfficeBox;
                viewModel.BillTo_City = viewModel.BillTo.Address1AddressCity;
                viewModel.BillTo_State = viewModel.BillTo.Address1AddressStateOrProvince;
                viewModel.BillTo_Zip = viewModel.BillTo.Address1AddressPostalCode;
            }
            else
            {
                viewModel.BillTo_NameLine1 = previousInvoice.BillTo_NameLine1;
                viewModel.BillTo_NameLine2 = previousInvoice.BillTo_NameLine2;
                viewModel.BillTo_AddressLine1 = previousInvoice.BillTo_AddressLine1;
                viewModel.BillTo_AddressLine2 = previousInvoice.BillTo_AddressLine2;
                viewModel.BillTo_City = previousInvoice.BillTo_City;
                viewModel.BillTo_State = previousInvoice.BillTo_State;
                viewModel.BillTo_Zip = previousInvoice.BillTo_Zip;
            }

            // Get list of matters for the group
            mattersList = Data.Billing.BillingGroup.ListMattersForGroup(billingGroup.Id.Value, conn, false);

            for (int i = 0; i < mattersList.Count; i++)
            {
                ViewModels.Billing.GroupInvoiceItemViewModel giivm = new ViewModels.Billing.GroupInvoiceItemViewModel();
                Common.Models.Matters.Matter matter = mattersList[i];

                giivm.Matter = Mapper.Map<ViewModels.Matters.MatterViewModel>(matter);

                Data.Timing.Time.ListUnbilledAndBillableTimeForMatter(matter.Id.Value, startDate, stopDate, conn, false).ForEach(x =>
                {
                    ViewModels.Billing.InvoiceTimeViewModel vm = new ViewModels.Billing.InvoiceTimeViewModel()
                    {
                        //Invoice = viewModel,
                        Time = Mapper.Map<ViewModels.Timing.TimeViewModel>(x),
                        Details = x.Details
                    };
                    if (x.Stop.HasValue)
                        vm.Duration = x.Stop.Value - x.Start;
                    else
                        vm.Duration = new TimeSpan(0);

                    if (string.IsNullOrEmpty(Request["RateFrom"]))
                    { // Not specified in URL
                    if (matter.OverrideMatterRateWithEmployeeRate)
                        {
                            Common.Models.Contacts.Contact contact = Data.Contacts.Contact.Get(x.Worker.Id.Value, conn, false);
                            if (contact.BillingRate != null && contact.BillingRate.Id.HasValue)
                                billingRate = Data.Billing.BillingRate.Get(contact.BillingRate.Id.Value, conn, false);
                        }
                    }
                    else
                    { // Overridden by current user in URL
                    if (Request["RateFrom"] == "Employee")
                        {
                            Common.Models.Contacts.Contact contact = Data.Contacts.Contact.Get(x.Worker.Id.Value, conn, false);
                            if (contact.BillingRate != null && contact.BillingRate.Id.HasValue)
                                billingRate = Data.Billing.BillingRate.Get(contact.BillingRate.Id.Value, conn, false);
                        }
                    }

                    if (billingRate != null)
                        vm.PricePerHour = billingRate.PricePerUnit;
                    ViewModels.Billing.InvoiceTimeGroupViewModel timeGroup;
                    if (x.TimeCategory == null || !x.TimeCategory.Id.HasValue)
                        timeGroup = giivm.TimeGroups.SingleOrDefault(y => y.Id == 0);
                    else
                        timeGroup = giivm.TimeGroups.SingleOrDefault(y => y.Id == x.TimeCategory.Id);
                    if (timeGroup == null || timeGroup.Id == -1)
                    {
                        Common.Models.Timing.TimeCategory tc = Data.Timing.TimeCategory.Get(x.TimeCategory.Id.Value, conn, false);
                        timeGroup = new ViewModels.Billing.InvoiceTimeGroupViewModel()
                        {
                            Id = tc.Id.Value,
                            GroupName = tc.Title,
                            Times = new List<ViewModels.Billing.InvoiceTimeViewModel>()
                        };
                        timeGroup.Times.Add(vm);
                        giivm.TimeGroups.Add(timeGroup);
                    }
                    else
                        timeGroup.Times.Add(vm);
                });

                Data.Billing.Expense.ListUnbilledExpensesForMatter(matter.Id.Value, startDate, stopDate, conn, false).ForEach(x =>
                {
                    giivm.Expenses.Add(new ViewModels.Billing.InvoiceExpenseViewModel()
                    {
                    //Invoice = viewModel,
                    Expense = Mapper.Map<ViewModels.Billing.ExpenseViewModel>(x),
                        Details = x.Details,
                        Amount = x.Amount
                    });
                });

                Data.Billing.Fee.ListUnbilledFeesForMatter(matter.Id.Value, startDate, stopDate, conn, false).ForEach(x =>
                {
                    giivm.Fees.Add(new ViewModels.Billing.InvoiceFeeViewModel()
                    {
                    //Invoice = viewModel,
                    Fee = Mapper.Map<ViewModels.Billing.FeeViewModel>(x),
                        Details = x.Details,
                        Amount = x.Amount
                    });
                });

                if ((giivm.TimeGroups.Count(x => x.Times.Count > 0) > 0) ||
                    (giivm.Expenses.Count > 0) ||
                    (giivm.Fees.Count > 0))
                    viewModel.Matters.Add(giivm);
            }

            ViewData["FirmName"] = Common.Settings.Manager.Instance.System.BillingFirmName;
            ViewData["FirmAddress"] = Common.Settings.Manager.Instance.System.BillingFirmAddress;
            ViewData["FirmCity"] = Common.Settings.Manager.Instance.System.BillingFirmCity;
            ViewData["FirmState"] = Common.Settings.Manager.Instance.System.BillingFirmState;
            ViewData["FirmZip"] = Common.Settings.Manager.Instance.System.BillingFirmZip;
            ViewData["FirmPhone"] = Common.Settings.Manager.Instance.System.BillingFirmPhone;
            ViewData["FirmWeb"] = Common.Settings.Manager.Instance.System.BillingFirmWeb;

            return viewModel;
        }
Exemple #6
0
        public ActionResult SingleGroupBill(int id, ViewModels.Billing.GroupInvoiceViewModel viewModel)
        {
            // Create Invoice
            // Loop Matters
            // Loop Expenses
            // Loop Fees
            // Loop Times
            // Redirect to invoice viewing
            DateTime?start = null, stop = null;

            Common.Models.Account.Users                 currentUser;
            Common.Models.Billing.BillingGroup          billingGroup;
            ViewModels.Billing.GroupInvoiceViewModel    builtGroupInvoice;
            ViewModels.Billing.InvoiceExpenseViewModel  ievm;
            ViewModels.Billing.InvoiceFeeViewModel      ifvm;
            ViewModels.Billing.InvoiceTimeViewModel     itvm;
            List <Common.Models.Billing.InvoiceExpense> invoiceExpenseList;
            List <Common.Models.Billing.InvoiceFee>     invoiceFeeList;
            List <Common.Models.Billing.InvoiceTime>    invoiceTimeList;

            Common.Models.Billing.Invoice invoice = null;

            if (!string.IsNullOrEmpty(Request["StartDate"]))
            {
                start = DateTime.Parse(Request["StartDate"]);
            }
            if (!string.IsNullOrEmpty(Request["StopDate"]))
            {
                stop = DateTime.Parse(Request["StopDate"]);
            }

            using (Data.Transaction trans = Data.Transaction.Create(true))
            {
                try
                {
                    currentUser          = Data.Account.Users.Get(trans, User.Identity.Name);
                    billingGroup         = Data.Billing.BillingGroup.Get(trans, id);
                    billingGroup.Amount  = viewModel.BillingGroup.Amount;
                    billingGroup.NextRun = viewModel.BillingGroup.NextRun;

                    builtGroupInvoice = BuildGroupInvoiceViewModel(id, trans.Connection, false, start, stop, Request["rateFrom"]);

                    // Validation

                    // Loop for each matter
                    for (int i = 0; i < viewModel.Matters.Count; i++)
                    {
                        ViewModels.Billing.GroupInvoiceItemViewModel giivm =
                            builtGroupInvoice.Matters.Single(x => x.Matter.Id.Value == viewModel.Matters[i].Matter.Id.Value);

                        for (int j = 0; j < viewModel.Matters[i].Expenses.Count; j++)
                        {
                            ievm = giivm.Expenses.Single(x => x.Expense.Id.Value == viewModel.Matters[i].Expenses[j].Expense.Id.Value);
                            viewModel.Matters[i].Expenses[j].Expense = ievm.Expense;
                            if (string.IsNullOrEmpty(viewModel.Matters[i].Expenses[j].Details))
                            {
                                ModelState.AddModelError(string.Format("Matters[{0}].Expenses[{1}].Details", i, j), "Required");
                            }
                        }
                        ;
                        for (int j = 0; j < viewModel.Matters[i].Fees.Count; j++)
                        {
                            ifvm = giivm.Fees.Single(x => x.Fee.Id.Value == viewModel.Matters[i].Fees[j].Fee.Id.Value);
                            viewModel.Matters[i].Fees[j].Fee = ifvm.Fee;
                            if (string.IsNullOrEmpty(viewModel.Matters[i].Fees[j].Details))
                            {
                                ModelState.AddModelError(string.Format("Matters[{0}].Fees[{1}].Details", i, j), "Required");
                            }
                        }
                        ;
                        for (int j = 0; j < viewModel.Matters[i].TimeGroups.Count; j++)
                        {
                            if (viewModel.Matters[i].TimeGroups[j] != null)
                            {
                                for (int k = 0; k < viewModel.Matters[i].TimeGroups[j].Times.Count; k++)
                                {
                                    itvm = giivm.TimeGroups[j].Times.Single(x => x.Time.Id.Value == viewModel.Matters[i].TimeGroups[j].Times[k].Time.Id);
                                    viewModel.Matters[i].TimeGroups[j].Times[k].Time = itvm.Time;
                                    if (string.IsNullOrEmpty(viewModel.Matters[i].TimeGroups[j].Times[k].Details))
                                    {
                                        ModelState.AddModelError(string.Format("Matters[{0}].TimeGroups[{1}].Times[{2}].Details", i, j, k), "Required");
                                    }
                                }
                            }
                        }
                    }

                    ModelState["id"].Errors.Clear();
                    if (!ModelState.IsValid)
                    {
                        // Errors - do nothing, but tell user and show again for fixing
                        ViewData["FirmName"]    = Common.Settings.Manager.Instance.System.BillingFirmName;
                        ViewData["FirmAddress"] = Common.Settings.Manager.Instance.System.BillingFirmAddress;
                        ViewData["FirmCity"]    = Common.Settings.Manager.Instance.System.BillingFirmCity;
                        ViewData["FirmState"]   = Common.Settings.Manager.Instance.System.BillingFirmState;
                        ViewData["FirmZip"]     = Common.Settings.Manager.Instance.System.BillingFirmZip;
                        ViewData["FirmPhone"]   = Common.Settings.Manager.Instance.System.BillingFirmPhone;
                        ViewData["FirmWeb"]     = Common.Settings.Manager.Instance.System.BillingFirmWeb;


                        IEnumerator <KeyValuePair <string, System.Web.Mvc.ModelState> > en = ModelState.GetEnumerator();
                        while (en.MoveNext())
                        {
                            if (en.Current.Value.Errors.Count > 0)
                            {
                                string     a  = en.Current.Key;
                                ModelState ms = en.Current.Value;
                            }
                        }

                        return(View(viewModel));
                    }

                    invoice = new Common.Models.Billing.Invoice()
                    {
                        Id                  = viewModel.Id,
                        BillTo              = Mapper.Map <Common.Models.Contacts.Contact>(viewModel.BillTo),
                        Date                = viewModel.Date,
                        Due                 = viewModel.Due,
                        Subtotal            = viewModel.Subtotal,
                        TaxAmount           = viewModel.TaxAmount,
                        Total               = viewModel.Total,
                        ExternalInvoiceId   = viewModel.ExternalInvoiceId,
                        BillTo_NameLine1    = viewModel.BillTo_NameLine1,
                        BillTo_NameLine2    = viewModel.BillTo_NameLine2,
                        BillTo_AddressLine1 = viewModel.BillTo_AddressLine1,
                        BillTo_AddressLine2 = viewModel.BillTo_AddressLine2,
                        BillTo_City         = viewModel.BillTo_City,
                        BillTo_State        = viewModel.BillTo_State,
                        BillTo_Zip          = viewModel.BillTo_Zip,
                        BillingGroup        = new Common.Models.Billing.BillingGroup()
                        {
                            Id = id
                        }
                    };

                    invoiceExpenseList = new List <Common.Models.Billing.InvoiceExpense>();
                    invoiceFeeList     = new List <Common.Models.Billing.InvoiceFee>();
                    invoiceTimeList    = new List <Common.Models.Billing.InvoiceTime>();

                    viewModel.Matters.ForEach(matterVM =>
                    {
                        matterVM.Expenses.ForEach(vm =>
                        {
                            invoiceExpenseList.Add(new Common.Models.Billing.InvoiceExpense()
                            {
                                Invoice = invoice,
                                Expense = new Common.Models.Billing.Expense()
                                {
                                    Id = vm.Expense.Id
                                },
                                Amount  = vm.Amount,
                                Details = vm.Details
                            });
                        });

                        matterVM.Fees.ForEach(vm =>
                        {
                            invoiceFeeList.Add(new Common.Models.Billing.InvoiceFee()
                            {
                                Invoice = invoice,
                                Fee     = new Common.Models.Billing.Fee()
                                {
                                    Id = vm.Fee.Id
                                },
                                Amount  = vm.Amount,
                                Details = vm.Details
                            });
                        });

                        matterVM.TimeGroups.ForEach(tg =>
                        {
                            tg.Times.ForEach(vm =>
                            {
                                invoiceTimeList.Add(new Common.Models.Billing.InvoiceTime()
                                {
                                    Invoice = invoice,
                                    Time    = new Common.Models.Timing.Time()
                                    {
                                        Id           = vm.Time.Id,
                                        TimeCategory = new Common.Models.Timing.TimeCategory()
                                        {
                                            Id    = tg.Id,
                                            Title = tg.GroupName
                                        }
                                    },
                                    Duration     = vm.Duration,
                                    PricePerHour = vm.PricePerHour,
                                    Details      = vm.Details
                                });
                            });
                        });
                    });

                    invoice = Data.Billing.Billing.SingleGroupBill(
                        billingGroup,
                        invoice,
                        invoiceExpenseList,
                        invoiceFeeList,
                        invoiceTimeList,
                        currentUser,
                        trans);

                    trans.Commit();
                }
                catch (Exception ex)
                {
                    trans.Rollback();
                    throw ex;
                }
            }

            return(RedirectToAction("GroupDetails", "Invoices", new { id = invoice.Id }));
        }
Exemple #7
0
        public ViewModels.Billing.GroupInvoiceViewModel BuildGroupInvoiceViewModel(int id, IDbConnection conn, bool closeConnection, DateTime?startDate = null, DateTime?stopDate = null, string rateFrom = null)
        {
            Common.Models.Billing.BillingRate        billingRate = null;
            Common.Models.Billing.BillingGroup       billingGroup;
            ViewModels.Billing.GroupInvoiceViewModel viewModel       = new ViewModels.Billing.GroupInvoiceViewModel();
            Common.Models.Billing.Invoice            previousInvoice = null;
            List <Common.Models.Matters.Matter>      mattersList;

            if (!string.IsNullOrEmpty(Request["StartDate"]))
            {
                startDate = DateTime.Parse(Request["StartDate"]);
            }
            if (!string.IsNullOrEmpty(Request["StopDate"]))
            {
                stopDate = DateTime.Parse(Request["StopDate"]);
            }

            billingGroup    = Data.Billing.BillingGroup.Get(id, conn, false);
            previousInvoice = Data.Billing.Invoice.GetMostRecentInvoiceForContact(billingGroup.BillTo.Id.Value, conn, false);

            billingGroup.NextRun = new DateTime(DateTime.Now.Year, DateTime.Now.AddMonths(1).Month, 1);

            viewModel.Id           = Guid.NewGuid();
            viewModel.BillTo       = Mapper.Map <ViewModels.Contacts.ContactViewModel>(Data.Contacts.Contact.Get(billingGroup.BillTo.Id.Value, conn, false));
            viewModel.Date         = DateTime.Now;
            viewModel.Due          = DateTime.Now.AddDays(30);
            viewModel.BillingGroup = Mapper.Map <ViewModels.Billing.BillingGroupViewModel>(billingGroup);

            if (previousInvoice == null)
            {
                viewModel.BillTo_NameLine1 = viewModel.BillTo.DisplayName;
                if (string.IsNullOrEmpty(viewModel.BillTo.Address1AddressPostOfficeBox))
                {
                    viewModel.BillTo_AddressLine1 = viewModel.BillTo.Address1AddressStreet;
                }
                else
                {
                    viewModel.BillTo_AddressLine1 = "P.O. Box " + viewModel.BillTo.Address1AddressPostOfficeBox;
                }
                viewModel.BillTo_City  = viewModel.BillTo.Address1AddressCity;
                viewModel.BillTo_State = viewModel.BillTo.Address1AddressStateOrProvince;
                viewModel.BillTo_Zip   = viewModel.BillTo.Address1AddressPostalCode;
            }
            else
            {
                viewModel.BillTo_NameLine1    = previousInvoice.BillTo_NameLine1;
                viewModel.BillTo_NameLine2    = previousInvoice.BillTo_NameLine2;
                viewModel.BillTo_AddressLine1 = previousInvoice.BillTo_AddressLine1;
                viewModel.BillTo_AddressLine2 = previousInvoice.BillTo_AddressLine2;
                viewModel.BillTo_City         = previousInvoice.BillTo_City;
                viewModel.BillTo_State        = previousInvoice.BillTo_State;
                viewModel.BillTo_Zip          = previousInvoice.BillTo_Zip;
            }

            // Get list of matters for the group
            mattersList = Data.Billing.BillingGroup.ListMattersForGroup(billingGroup.Id.Value, conn, false);

            for (int i = 0; i < mattersList.Count; i++)
            {
                ViewModels.Billing.GroupInvoiceItemViewModel giivm = new ViewModels.Billing.GroupInvoiceItemViewModel();
                Common.Models.Matters.Matter matter = mattersList[i];

                giivm.Matter = Mapper.Map <ViewModels.Matters.MatterViewModel>(matter);

                Data.Timing.Time.ListUnbilledAndBillableTimeForMatter(matter.Id.Value, startDate, stopDate, conn, false).ForEach(x =>
                {
                    ViewModels.Billing.InvoiceTimeViewModel vm = new ViewModels.Billing.InvoiceTimeViewModel()
                    {
                        //Invoice = viewModel,
                        Time    = Mapper.Map <ViewModels.Timing.TimeViewModel>(x),
                        Details = x.Details
                    };
                    if (x.Stop.HasValue)
                    {
                        vm.Duration = x.Stop.Value - x.Start;
                    }
                    else
                    {
                        vm.Duration = new TimeSpan(0);
                    }

                    if (string.IsNullOrEmpty(Request["RateFrom"]))
                    { // Not specified in URL
                        if (matter.OverrideMatterRateWithEmployeeRate)
                        {
                            Common.Models.Contacts.Contact contact = Data.Contacts.Contact.Get(x.Worker.Id.Value, conn, false);
                            if (contact.BillingRate != null && contact.BillingRate.Id.HasValue)
                            {
                                billingRate = Data.Billing.BillingRate.Get(contact.BillingRate.Id.Value, conn, false);
                            }
                        }
                    }
                    else
                    { // Overridden by current user in URL
                        if (Request["RateFrom"] == "Employee")
                        {
                            Common.Models.Contacts.Contact contact = Data.Contacts.Contact.Get(x.Worker.Id.Value, conn, false);
                            if (contact.BillingRate != null && contact.BillingRate.Id.HasValue)
                            {
                                billingRate = Data.Billing.BillingRate.Get(contact.BillingRate.Id.Value, conn, false);
                            }
                        }
                    }

                    if (billingRate != null)
                    {
                        vm.PricePerHour = billingRate.PricePerUnit;
                    }

                    ViewModels.Billing.InvoiceTimeGroupViewModel timeGroup;
                    if (x.TimeCategory == null || !x.TimeCategory.Id.HasValue)
                    {
                        timeGroup = giivm.TimeGroups.SingleOrDefault(y => y.Id == 0);
                    }
                    else
                    {
                        timeGroup = giivm.TimeGroups.SingleOrDefault(y => y.Id == x.TimeCategory.Id);
                    }
                    if (timeGroup == null || timeGroup.Id == -1)
                    {
                        Common.Models.Timing.TimeCategory tc = Data.Timing.TimeCategory.Get(x.TimeCategory.Id.Value, conn, false);
                        timeGroup = new ViewModels.Billing.InvoiceTimeGroupViewModel()
                        {
                            Id        = tc.Id.Value,
                            GroupName = tc.Title,
                            Times     = new List <ViewModels.Billing.InvoiceTimeViewModel>()
                        };
                        timeGroup.Times.Add(vm);
                        giivm.TimeGroups.Add(timeGroup);
                    }
                    else
                    {
                        timeGroup.Times.Add(vm);
                    }
                });
                // On instantiation, GroupInvoiceItemViewModel.TimeGroups has the first element created as "Standard"
                // if it is not used, we need to drop it
                if (giivm.TimeGroups.Count > 1 && giivm.TimeGroups[0].Times.Count == 0)
                {
                    giivm.TimeGroups.RemoveAt(0);
                }

                Data.Billing.Expense.ListUnbilledExpensesForMatter(matter.Id.Value, startDate, stopDate, conn, false).ForEach(x =>
                {
                    giivm.Expenses.Add(new ViewModels.Billing.InvoiceExpenseViewModel()
                    {
                        //Invoice = viewModel,
                        Expense = Mapper.Map <ViewModels.Billing.ExpenseViewModel>(x),
                        Details = x.Details,
                        Amount  = x.Amount
                    });
                });

                Data.Billing.Fee.ListUnbilledFeesForMatter(matter.Id.Value, startDate, stopDate, conn, false).ForEach(x =>
                {
                    giivm.Fees.Add(new ViewModels.Billing.InvoiceFeeViewModel()
                    {
                        //Invoice = viewModel,
                        Fee     = Mapper.Map <ViewModels.Billing.FeeViewModel>(x),
                        Details = x.Details,
                        Amount  = x.Amount
                    });
                });

                if ((giivm.TimeGroups.Count(x => x.Times.Count > 0) > 0) ||
                    (giivm.Expenses.Count > 0) ||
                    (giivm.Fees.Count > 0))
                {
                    viewModel.Matters.Add(giivm);
                }
            }

            ViewData["FirmName"]    = Common.Settings.Manager.Instance.System.BillingFirmName;
            ViewData["FirmAddress"] = Common.Settings.Manager.Instance.System.BillingFirmAddress;
            ViewData["FirmCity"]    = Common.Settings.Manager.Instance.System.BillingFirmCity;
            ViewData["FirmState"]   = Common.Settings.Manager.Instance.System.BillingFirmState;
            ViewData["FirmZip"]     = Common.Settings.Manager.Instance.System.BillingFirmZip;
            ViewData["FirmPhone"]   = Common.Settings.Manager.Instance.System.BillingFirmPhone;
            ViewData["FirmWeb"]     = Common.Settings.Manager.Instance.System.BillingFirmWeb;

            return(viewModel);
        }
        public ActionResult GroupDetails(Guid id)
        {
            Common.Models.Billing.BillingGroup       billingGroup;
            ViewModels.Billing.GroupInvoiceViewModel viewModel = new ViewModels.Billing.GroupInvoiceViewModel();
            List <Common.Models.Matters.Matter>      mattersList;

            Common.Models.Billing.Invoice invoice = null;

            using (IDbConnection conn = Data.Database.Instance.GetConnection())
            {
                invoice      = Data.Billing.Invoice.Get(id, conn, false);
                billingGroup = Data.Billing.BillingGroup.Get(invoice.BillingGroup.Id.Value, conn, false);

                viewModel = new ViewModels.Billing.GroupInvoiceViewModel()
                {
                    Id     = invoice.Id,
                    BillTo = new ViewModels.Contacts.ContactViewModel()
                    {
                        Id = invoice.BillTo.Id
                    },
                    Date                = invoice.Date,
                    Due                 = invoice.Due,
                    Subtotal            = invoice.Subtotal,
                    TaxAmount           = invoice.TaxAmount,
                    Total               = invoice.Total,
                    ExternalInvoiceId   = invoice.ExternalInvoiceId,
                    BillTo_NameLine1    = invoice.BillTo_NameLine1,
                    BillTo_NameLine2    = invoice.BillTo_NameLine2,
                    BillTo_AddressLine1 = invoice.BillTo_AddressLine1,
                    BillTo_AddressLine2 = invoice.BillTo_AddressLine2,
                    BillTo_City         = invoice.BillTo_City,
                    BillTo_State        = invoice.BillTo_State,
                    BillTo_Zip          = invoice.BillTo_Zip,
                    BillingGroup        = Mapper.Map <ViewModels.Billing.BillingGroupViewModel>(billingGroup)
                };

                mattersList = Data.Billing.BillingGroup.ListMattersForGroup(billingGroup.Id.Value, conn, false);

                for (int i = 0; i < mattersList.Count; i++)
                {
                    ViewModels.Billing.GroupInvoiceItemViewModel giivm = new ViewModels.Billing.GroupInvoiceItemViewModel();
                    giivm.Matter = Mapper.Map <ViewModels.Matters.MatterViewModel>(mattersList[i]);

                    Data.Billing.InvoiceExpense.ListForMatterAndInvoice(id, mattersList[i].Id.Value, conn, false).ForEach(x =>
                    {
                        ViewModels.Billing.InvoiceExpenseViewModel vm = Mapper.Map <ViewModels.Billing.InvoiceExpenseViewModel>(x);
                        vm.Expense = Mapper.Map <ViewModels.Billing.ExpenseViewModel>(
                            Data.Billing.Expense.Get(vm.Expense.Id.Value, conn, false));
                        giivm.ExpensesSum += vm.Amount;
                        giivm.Expenses.Add(vm);
                    });

                    Data.Billing.InvoiceFee.ListForMatterAndInvoice(id, mattersList[i].Id.Value, conn, false).ForEach(x =>
                    {
                        ViewModels.Billing.InvoiceFeeViewModel vm = Mapper.Map <ViewModels.Billing.InvoiceFeeViewModel>(x);
                        vm.Fee = Mapper.Map <ViewModels.Billing.FeeViewModel>(
                            Data.Billing.Fee.Get(vm.Fee.Id.Value, conn, false));
                        giivm.FeesSum += vm.Amount;
                        giivm.Fees.Add(vm);
                    });

                    Data.Billing.InvoiceTime.ListForMatterAndInvoice(id, mattersList[i].Id.Value, conn, false).ForEach(x =>
                    {
                        ViewModels.Billing.InvoiceTimeViewModel vm = Mapper.Map <ViewModels.Billing.InvoiceTimeViewModel>(x);
                        vm.Time = Mapper.Map <ViewModels.Timing.TimeViewModel>(
                            Data.Timing.Time.Get(vm.Time.Id.Value, conn, false));

                        ViewModels.Billing.InvoiceTimeGroupViewModel timeGroup;
                        if (vm.Time.TimeCategory == null || !vm.Time.TimeCategory.Id.HasValue)
                        {
                            timeGroup = giivm.TimeGroups.SingleOrDefault(y => y.Id == 0);
                        }
                        else
                        {
                            timeGroup = giivm.TimeGroups.SingleOrDefault(y => y.Id == vm.Time.TimeCategory.Id);
                        }
                        if (timeGroup == null || timeGroup.Id == -1)
                        {
                            Common.Models.Timing.TimeCategory tc = Data.Timing.TimeCategory.Get(vm.Time.TimeCategory.Id.Value, conn, false);
                            timeGroup = new ViewModels.Billing.InvoiceTimeGroupViewModel()
                            {
                                Id        = tc.Id.Value,
                                GroupName = tc.Title,
                                Times     = new List <ViewModels.Billing.InvoiceTimeViewModel>()
                            };
                            timeGroup.Times.Add(vm);
                            giivm.TimeGroups.Add(timeGroup);
                        }
                        else
                        {
                            timeGroup.Times.Add(vm);
                        }

                        giivm.TimeSum       = giivm.TimeSum.Add(vm.Duration);
                        giivm.TimeSumMoney += vm.PricePerHour * (decimal)vm.Duration.TotalHours;
                    });

                    if (((giivm.TimeGroups.Count > 0) && (giivm.TimeGroups.Count(x => x.Times.Count > 0) > 0)) ||
                        (giivm.Expenses.Count > 0) ||
                        (giivm.Fees.Count > 0))
                    {
                        viewModel.Matters.Add(giivm);
                    }
                }
            }

            ViewBag.Invoice         = Mapper.Map <ViewModels.Billing.InvoiceViewModel>(invoice);
            ViewBag.BillingGroup    = Mapper.Map <ViewModels.Billing.BillingGroupViewModel>(billingGroup);
            ViewData["FirmName"]    = Common.Settings.Manager.Instance.System.BillingFirmName;
            ViewData["FirmAddress"] = Common.Settings.Manager.Instance.System.BillingFirmAddress;
            ViewData["FirmCity"]    = Common.Settings.Manager.Instance.System.BillingFirmCity;
            ViewData["FirmState"]   = Common.Settings.Manager.Instance.System.BillingFirmState;
            ViewData["FirmZip"]     = Common.Settings.Manager.Instance.System.BillingFirmZip;
            ViewData["FirmPhone"]   = Common.Settings.Manager.Instance.System.BillingFirmPhone;
            ViewData["FirmWeb"]     = Common.Settings.Manager.Instance.System.BillingFirmWeb;

            return(View(viewModel));
        }
        public ActionResult GroupDetails(Guid id)
        {
            Common.Models.Billing.BillingGroup       billingGroup;
            ViewModels.Billing.GroupInvoiceViewModel viewModel = new ViewModels.Billing.GroupInvoiceViewModel();
            List <Common.Models.Matters.Matter>      mattersList;

            Common.Models.Billing.Invoice invoice = null;

            invoice      = Data.Billing.Invoice.Get(id);
            billingGroup = Data.Billing.BillingGroup.Get(invoice.BillingGroup.Id.Value);

            viewModel = new ViewModels.Billing.GroupInvoiceViewModel()
            {
                Id     = invoice.Id,
                BillTo = new ViewModels.Contacts.ContactViewModel()
                {
                    Id = invoice.BillTo.Id
                },
                Date                = invoice.Date,
                Due                 = invoice.Due,
                Subtotal            = invoice.Subtotal,
                TaxAmount           = invoice.TaxAmount,
                Total               = invoice.Total,
                ExternalInvoiceId   = invoice.ExternalInvoiceId,
                BillTo_NameLine1    = invoice.BillTo_NameLine1,
                BillTo_NameLine2    = invoice.BillTo_NameLine2,
                BillTo_AddressLine1 = invoice.BillTo_AddressLine1,
                BillTo_AddressLine2 = invoice.BillTo_AddressLine2,
                BillTo_City         = invoice.BillTo_City,
                BillTo_State        = invoice.BillTo_State,
                BillTo_Zip          = invoice.BillTo_Zip,
                BillingGroup        = Mapper.Map <ViewModels.Billing.BillingGroupViewModel>(billingGroup)
            };

            mattersList = Data.Billing.BillingGroup.ListMattersForGroup(billingGroup.Id.Value);

            for (int i = 0; i < mattersList.Count; i++)
            {
                ViewModels.Billing.GroupInvoiceItemViewModel giivm = new ViewModels.Billing.GroupInvoiceItemViewModel();
                giivm.Matter = Mapper.Map <ViewModels.Matters.MatterViewModel>(mattersList[i]);

                Data.Billing.InvoiceExpense.ListForMatterAndInvoice(id, mattersList[i].Id.Value).ForEach(x =>
                {
                    ViewModels.Billing.InvoiceExpenseViewModel vm = Mapper.Map <ViewModels.Billing.InvoiceExpenseViewModel>(x);
                    vm.Expense         = Mapper.Map <ViewModels.Billing.ExpenseViewModel>(Data.Billing.Expense.Get(vm.Expense.Id.Value));
                    giivm.ExpensesSum += vm.Amount;
                    giivm.Expenses.Add(vm);
                });

                Data.Billing.InvoiceFee.ListForMatterAndInvoice(id, mattersList[i].Id.Value).ForEach(x =>
                {
                    ViewModels.Billing.InvoiceFeeViewModel vm = Mapper.Map <ViewModels.Billing.InvoiceFeeViewModel>(x);
                    vm.Fee         = Mapper.Map <ViewModels.Billing.FeeViewModel>(Data.Billing.Fee.Get(vm.Fee.Id.Value));
                    giivm.FeesSum += vm.Amount;
                    giivm.Fees.Add(vm);
                });

                Data.Billing.InvoiceTime.ListForMatterAndInvoice(id, mattersList[i].Id.Value).ForEach(x =>
                {
                    ViewModels.Billing.InvoiceTimeViewModel vm = Mapper.Map <ViewModels.Billing.InvoiceTimeViewModel>(x);
                    vm.Time             = Mapper.Map <ViewModels.Timing.TimeViewModel>(Data.Timing.Time.Get(vm.Time.Id.Value));
                    giivm.TimeSum       = giivm.TimeSum.Add(vm.Duration);
                    giivm.TimeSumMoney += vm.PricePerHour * (decimal)vm.Duration.TotalHours;
                    giivm.Times.Add(vm);
                });

                if ((giivm.Times.Count > 0) ||
                    (giivm.Expenses.Count > 0) ||
                    (giivm.Fees.Count > 0))
                {
                    viewModel.Matters.Add(giivm);
                }
            }

            ViewData["FirmName"]    = Common.Settings.Manager.Instance.System.BillingFirmName;
            ViewData["FirmAddress"] = Common.Settings.Manager.Instance.System.BillingFirmAddress;
            ViewData["FirmCity"]    = Common.Settings.Manager.Instance.System.BillingFirmCity;
            ViewData["FirmState"]   = Common.Settings.Manager.Instance.System.BillingFirmState;
            ViewData["FirmZip"]     = Common.Settings.Manager.Instance.System.BillingFirmZip;
            ViewData["FirmPhone"]   = Common.Settings.Manager.Instance.System.BillingFirmPhone;
            ViewData["FirmWeb"]     = Common.Settings.Manager.Instance.System.BillingFirmWeb;

            return(View(viewModel));
        }