public ActionResult AddEditProject(int clientID, int projectID, string projectName)
        {
            try{
            var db = new ExpenseDb();

            if (projectID == 0)
            {
                // add a new project
                var project = new Project { ClientID = clientID, ProjectName = projectName };

                db.Project.Add(project);
                db.SaveChanges();
            }
            else// this is an edit of an existing Client
            {
               // db.Clients.Where(c => c.Id == intClientID).FirstOrDefault().ClientName = clientName;
                db.Project.Where(p => p.Id == projectID).FirstOrDefault().ProjectName = projectName;
                //db change tracker
                db.SaveChanges();

            }

            // get list of Projects
            var projects = getProjects(clientID);

            return PartialView("_ProjectTable", projects);
               }
               catch (Exception ex)
               {

               return ThrowJSONError(ex);
               }
        }
        public ActionResult Index()
        {
            var db = new ExpenseDb();// this is our access to the data base

            var reports = db.Reports.ToArray();

               ViewBag.Message = string.Format("You have {0} reports", reports.Length);

            return View();
        }
        public ActionResult AddEditReport(ReportViewModel model)
        {
            if (ModelState.IsValid)
            {
                // do good stuff
            }
            else
            {
                // make sure you return the bad model to the view... otherwise the model errors get wiped out
                // and your validation helpers don't work
            }
            var db = new ExpenseDb();
            if (model.ReportID > 0)
            {
                // this is an update
                //db.EstablishmentTBL.Where(e => e.Id == establishmentID).FirstOrDefault().EstablishmentName = establishmentName;
               var report= db.Reports.Where(e => e.Id == model.ReportID).FirstOrDefault();
               report.MonthYear = model.MonthYearInput;
               report.Billable = model.BillableInput;
               report.EmpName = model.EmpNameInput;
               report.EmpTitle = model.EmpTitleInput;
               report.ErNumber = model.ErNumberInput != null ? model.ErNumberInput : -1;
               report.ProjectID = model.SelectedProjectID;

                db.SaveChanges();

            }
            else {
                // this is a new report
                var report = new Report { Billable = model.BillableInput, EmpName = model.EmpNameInput, EmpTitle = model.EmpTitleInput, MonthYear = (DateTime)model.MonthYearInput, ErNumber = model.ErNumberInput != null ? model.ErNumberInput : 0, ProjectID = model.SelectedProjectID };
                db.Reports.Add(report);
                db.SaveChanges();

            }

            // add a new client
            // var client = new Client { ClientName = clientName };
            // db.Clients.Add(client);

            var reports = GetReports(db);

            model.Reports = reports;

            return PartialView("_ReportsTable", model);
        }
        public ActionResult AddEditClient(string clientID, string clientName)
        {
            try
            {
                int intClientID = Convert.ToInt32(clientID);
                var db = new ExpenseDb();

                if (intClientID <= 0)
                {
                    // add a new client
                    var client = new Client { ClientName = clientName };
                    db.Clients.Add(client);
                    db.SaveChanges();
                }
                else// this is an edit of an existing Client
                {
                    db.Clients.Where(c => c.Id == intClientID).FirstOrDefault().ClientName = clientName;
                    //db change tracker
                    db.SaveChanges();

                    // how to update using Fluent syntax
                   // db.Clients.Add(clinet);
                   // db.SaveChanges();

                }

                // get list of Clients
                var clients = GetClients();

                return PartialView("_ClientTable", clients);

            }
            catch (Exception ex)
            {

                return ThrowJSONError(ex);
            }
        }
        /// <summary>
        /// This action will be used to send a new/eddited establishment to the DB
        /// </summary>
        /// <param name="establishmentName"></param>
        /// <param name="establishmentID"></param>
        /// <returns></returns>
        public ActionResult AddEditEstablishment(string establishmentName, int establishmentID)
        {
            var db = new ExpenseDb();

            if (establishmentID <= 0) /// we add a new est to the DB
            {
                var establishment = new Establishment { EstablishmentName = establishmentName };
                db.EstablishmentTBL.Add(establishment);
                db.SaveChanges();

            }
            else // we edit the Est on the DB
            {
                db.EstablishmentTBL.Where(e => e.Id == establishmentID).FirstOrDefault().EstablishmentName = establishmentName;
                db.SaveChanges();

            }

            // here we return an updated list of the Establishments
            EstablishmentViewModel model = GetEstablishments(db);

            return PartialView("_EstablishmentTable", model);
        }
        public ActionResult AddEditExpense(ExpenseDetailsViewModel viewModel)
        {
            var db = new ExpenseDb();
            // get expense ID if < 0 then it is a new report
            if (viewModel.ExpenseInput.ExpenseID <= 0)
            {
                // this is a new expense
                var expense = new ExpenseDetail
                {
                    DateIncurred = viewModel.ExpenseInput.DateIncurred,
                    ReceiptEntry = viewModel.ExpenseInput.ReceiptEntry,
                    NumberOfGuest = viewModel.ExpenseInput.NumberOfGuest,
                    GuestNames = viewModel.ExpenseInput.GuestNames,
                    Establishment = viewModel.ExpenseInput.Establishment,
                    Expensecategory = viewModel.ExpenseInput.Expensecategory,
                    Reason = viewModel.ExpenseInput.Reason,
                    Amount = viewModel.ExpenseInput.Amount,
                    AmountPerPerson = viewModel.ExpenseInput.AmountPerPerson,
                    ReportID = viewModel.ExpenseInput.ReportID,
                    Notes =viewModel.ExpenseInput.Notes

                };
                db.ExpenseDetail.Add(expense);
                db.SaveChanges();

            }
            else // it is an edit to an existing report
            {
                // update an expense
                //db.ExpenseDetail.Where(e => e.Id == viewModel.ExpenseInput.ExpenseID).FirstOrDefault()
               // var expense = db.ExpenseDetail.Find(viewModel.ExpenseInput.ExpenseID);

               // db.Clients.Where(c => c.Id == intClientID).FirstOrDefault()
                var expense = db.ExpenseDetail.Where(e => e.Id == viewModel.ExpenseInput.ExpenseID).FirstOrDefault();
                expense.DateIncurred = viewModel.ExpenseInput.DateIncurred;
                expense.ReceiptEntry = viewModel.ExpenseInput.ReceiptEntry;
                expense.NumberOfGuest = viewModel.ExpenseInput.NumberOfGuest;
                expense.GuestNames = viewModel.ExpenseInput.GuestNames;
                expense.Establishment = viewModel.ExpenseInput.Establishment;
                expense.Expensecategory = viewModel.ExpenseInput.Expensecategory;
                expense.Reason = viewModel.ExpenseInput.Reason;
                expense.Notes = viewModel.ExpenseInput.Notes;
                expense.Amount = viewModel.ExpenseInput.Amount;
                expense.AmountPerPerson = viewModel.ExpenseInput.AmountPerPerson;
                expense.ReportID = viewModel.ExpenseInput.ReportID;
                //db.ExpenseDetail.Add(expense); when doing an update no need to do the add

                db.SaveChanges();// just by doing the saveChanges it knows it is an update

                    //.ClientName = clientName;
                //db change tracker
                db.SaveChanges();

                //db.Clients.Where(c => c.Id == intClientID).FirstOrDefault().ClientName = clientName;
                //db change tracker
                db.SaveChanges();

            }

            var establishments = GetEstablishments(db);// gets a list of Establishemnts

            var report = GetReportDetails(viewModel.ExpenseInput.ReportID, db);// gets the details of a single reports

            var expenses = GetReportExpenses(viewModel.ExpenseInput.ReportID, db);

            // ViewBag.ListOfEst = establishments;// this is putting a list of establishments in the View bag to then be retrieved from the JS

            viewModel.Establishments = establishments;
            viewModel.Report = report;
            viewModel.ListOfExpenses = expenses;
            if (report == null)
            {
                return View("Error");
            }
            else
            {
                return PartialView("_ExpenseDetails", viewModel);
                //return View("Index",viewModel);
            }
        }
        public ActionResult DeleteProject(int projectID, int clientID)
        {
            var db = new ExpenseDb();
            var project = db.Project.Find(projectID);
            db.Project.Remove(project);
            db.SaveChanges();

            // get list of Clients
            var projects = getProjects(clientID);

            return PartialView("_ProjectTable", projects);
        }
        //------------------------------Custom Methods-------------------------------------------
        // method to regenerate the list of Clients
        private static List<ClientViewModel> GetClients()
        {
            ExpenseDb db = new ExpenseDb();

            var clients = db.Clients
                .OrderBy(n =>n.ClientName)
                .Select(x => new ClientViewModel()
                {
                    ClientName = x.ClientName,
                    ClientId = x.Id,

                }).ToList();

            return clients;
        }
 /// <summary>
 /// Method used to get the list of common Establishemnts 
 /// </summary>
 /// <param name="db"></param>
 /// <returns></returns>
 private static List<EstablishmentInput> GetEstablishments(ExpenseDb db)
 {
     var establishments = db.EstablishmentTBL
         .OrderBy(e => e.EstablishmentName)
         .Select(e => new EstablishmentInput
         {
             EstablishmentName = e.EstablishmentName,
             // Id= e.Id
         }).ToList();
     return establishments;
 }
        /// <summary>
        /// This action will remove a given Est. from the DB 
        /// </summary>
        /// <param name="establishmentID"></param>
        /// <returns> an updated list of the EST. </returns>
        public ActionResult DeleteEstablishment(int establishmentID)
        {
            var db = new ExpenseDb();

            var establishment = db.EstablishmentTBL.Find(establishmentID);
            db.EstablishmentTBL.Remove(establishment);
            db.SaveChanges();

            // here we return an updated list of the Establishments
            EstablishmentViewModel model = GetEstablishments(db);

            return PartialView("_EstablishmentTable", model);
        }
        //
        // GET: /Report/
        public ActionResult Index(int reportID)
        {
            try
            {

            var viewModel = new ExpenseDetailsViewModel();

            var db = new ExpenseDb();

            var establishments = GetEstablishments(db);// gets a list of Establishemnts

            var report = GetReportDetails(reportID, db);// gets the details of a single reports

            var expenses = GetReportExpenses(reportID, db);

               // ViewBag.ListOfEst = establishments;// this is putting a list of establishments in the View bag to then be retrieved from the JS

            viewModel.Establishments = establishments;
            viewModel.Report = report;
            viewModel.ListOfExpenses = expenses;
            if (report == null)
            {
                return View("Error");
            }
            else {
                return View(viewModel);
            }

            }
            catch (Exception)
            {

                throw;
            }
        }
        ///////---------------------------------- Establishment Actions : 
        /////////////////----------------------- Shared methods to repopulate page
        /// <summary>
        /// Gets the Expenses for a given expense 
        /// </summary>
        /// <param name="reportID"></param>
        /// <param name="db"></param>
        /// <returns></returns>
        private static List<ExpenseDetails> GetReportExpenses(int reportID, ExpenseDb db)
        {
            var expenses = db.ExpenseDetail
                .Where(e => e.ReportID == reportID)
                .Select(e => new ExpenseDetails
                {

                    DateIncurred = e.DateIncurred,
                    ReceiptEntry= e.ReceiptEntry,
                    Establishment = e.Establishment,
                    Expensecategory = e.Expensecategory,
                    NumberOfGuest = e.NumberOfGuest,
                    GuestNames = e.GuestNames,
                    Amount = e.Amount,
                    AmountPerPerson = (e.Amount / (e.NumberOfGuest == 0 ? 1 : e.NumberOfGuest)),// here i get the amount per person server side
                    Reason = e.Reason,
                    Notes = e.Notes,
                    ReportID = e.ReportID,
                    ExpenseID = e.Id
                }).ToList();

            return expenses;
        }
        public ActionResult DeleteExpense(int expenseID, int reportID)
        {
            var viewModel = new ExpenseDetailsViewModel();

            var db = new ExpenseDb();

            // delete expense
            var expense = db.ExpenseDetail.Find(expenseID);
            db.ExpenseDetail.Remove(expense);
            db.SaveChanges();

            // re-render Partial
            var establishments = GetEstablishments(db);// gets a list of Establishemnts

            var report = GetReportDetails(reportID, db);// gets the details of a single reports

            var expenses = GetReportExpenses(reportID, db);

            // ViewBag.ListOfEst = establishments;// this is putting a list of establishments in the View bag to then be retrieved from the JS

            viewModel.Establishments = establishments;
            viewModel.Report = report;
            viewModel.ListOfExpenses = expenses;
            if (report == null)
            {
                return View("Error");
            }
            else {
                return PartialView("_ExpenseDetails", viewModel);
                //return View("Index", viewModel);
            }
        }
        //
        // GET: /ReportsList/
        public ActionResult Index()
        {
            // generate a list of all the expense Reports

            // send that list as a model to the view

            var db = new ExpenseDb();

            //var query = from r in db.Reports
            //            join p in db.Project on r.ProjectID equals p.Id
            //            join ed in db.ExpenseDetail on r.Id equals ed.ReportID
            //            group new {r,p,ed} by new {r.MonthYear,r.Billable, p.ProjectName}into g
            //            select new ReportDetails
            //            {
            //                MonthYear = g.Key.MonthYear,
            //                Billable = g.Key.Billable,
            //                ProjectName= g.Key.ProjectName,
            //                Total = g.Sum(a=> a.ed.Amount)
            //            };

            var reports = GetReports(db);

            //Reports.Select(r => new { r.Id, r.EmpName, r.MonthYear, Total = r.ReportExpenseDetails.Sum(e => e.Amount) });

            var clients = db.Clients

                .Select(c => new ClientListDetails
                {
                    ClientID = c.Id,
                    ClientName = c.ClientName
                }).ToList();

            // empty prj list, os the view will not get a null ref exception
            var tempPrjList = db.Project
            .Select(p => new ProjectListDetails
            {
            }).ToList();

            ReportViewModel model = new ReportViewModel();

            model.Reports = reports;
            model.Clients = clients;
            model.Projects = tempPrjList;

            return View("Index", model);
        }
        /// <summary>
        /// returns the list of the selected Clients projects used to populate a Drop down list 
        /// -- update both the Client and proejct DLL are passed in to the view model in order to keep 
        /// </summary>
        /// <param name="clientID"></param>
        /// <returns></returns>
        public ActionResult GetProjects(int clientID)
        {
            ExpenseDb db = new ExpenseDb();

            ReportViewModel viewModel = new ReportViewModel();

            var clients = db.Clients

                .Select(c => new ClientListDetails
                {
                    ClientID = c.Id,
                    ClientName = c.ClientName
                }).ToList();

            var projects = db.Project
                .Where(x => x.ClientID == clientID)
                .Select(x => new ProjectListDetails

                {
                    ProjectID = x.Id != null ? x.Id : -1,
                    ProjectName = x.ProjectName != null ? x.ProjectName: "No Projects Found"
                }).ToList();

            viewModel.Projects = projects;
            viewModel.Clients = clients;
            viewModel.SelectedClientID = clientID;

            return PartialView("_ProjectDDL", viewModel);
        }
        public ActionResult GetReportDetailsForEdit(int projectID)
        {
            ExpenseDb db = new ExpenseDb();

            ReportViewModel viewModel = new ReportViewModel();

            var projectValues = db.Project
                .Where(p => p.Id == projectID)
                .Select(p => new SelectedReportDetails
                {
                     ClientID = p.ClientID,
                     ClientName = p.Client.ClientName,
                     ProjectID = p.Id != null ? p.Id : -1,
                     ProjectName = p.ProjectName != null ? p.ProjectName : "No Projects Found"
                }).SingleOrDefault();

            /// gets the list of all the projects and clients, since they are both in the same partial view they both need to be loaded
            var projects = db.Project
               .Where(x => x.ClientID == projectValues.ClientID)
               .Select(x => new ProjectListDetails

               {
                   ProjectID = x.Id,
                   ProjectName = x.ProjectName
               }).ToList();

            var clients = db.Clients

               .Select(c => new ClientListDetails
               {
                   ClientID = c.Id,
                   ClientName = c.ClientName
               }).ToList();

            /// add the elements to the View Model
            viewModel.Projects = projects;
            viewModel.Clients = clients;
            viewModel.SelectedClientID = projectValues.ClientID;
            viewModel.SelectedClientName = projectValues.ClientName;
            viewModel.SelectedProjectID = projectValues.ProjectID;
            viewModel.SelectedProjectName = projectValues.ProjectName;

            return PartialView("_ProjectDDL", viewModel);
        }
        ///------------------------------------------------------------------- Establishment Functions :
        //
        public ActionResult EstablishmentView()
        {
            // Est are just used as an auto fill not a FK of any table

            var db = new ExpenseDb();
            EstablishmentViewModel model = GetEstablishments(db);

            return View(model);
        }
        /// <summary>
        /// this is the method removes a given report from the DB
        /// </summary>
        /// <param name="ReportID"></param>
        /// <returns></returns>
        public ActionResult DeleteReport(int reportID)
        {
            var model = new ReportViewModel();
            var db = new ExpenseDb();

            //delete the give report by report ID
            var report = db.Reports.Find(reportID);
            db.Reports.Remove(report);
            db.SaveChanges();

            var reports = GetReports(db);

            model.Reports = reports;
            return PartialView("_ReportsTable", model);
        }
        ///////------------------------------------------- Establishment Actions : 
        public ActionResult AddEstablishment(string establishmentName)
        {
            // in this instance we dont have Access to the Id's so we will only compare the stirngs client side
            // so we will always be creating a new Establishment

            var db = new ExpenseDb();

                var establishment = new Establishment { EstablishmentName = establishmentName };
                db.EstablishmentTBL.Add(establishment);

                db.SaveChanges();

            // here we return an updated list of the Establishments
            var establishments = GetEstablishments(db);

            var viewModel = new ExpenseDetailsViewModel();
            viewModel.Establishments = establishments;

            return PartialView("_EstablishmentTxt",viewModel);
        }
        // method used to get list of Projects
        private static List<ClientViewModel> getProjects(int clientID)
        {
            ExpenseDb db = new ExpenseDb();
            ClientViewModel viewModel = new ClientViewModel();

            var projects = db.Project
                .Where(x => x.ClientID == clientID)
                .Select(x => new ClientViewModel()

                {
                    ProjectId = x.Id,
                    ProjectName = x.ProjectName
                }).ToList();
            return projects;
        }
        /// <summary>
        /// This method is used to get a list of all the expenses
        /// </summary>
        /// <param name="db"></param>
        /// <returns></returns>
        private static List<ReportDetails> GetReports(ExpenseDb db)
        {
            var reports = db.Reports

                .Select(r => new ReportDetails
                {
                    ReportID = r.Id,
                    MonthYear = r.MonthYear,
                    Billable = r.Billable,
                    EmpName = r.EmpName,
                    EmpTitle = r.EmpTitle,
                    ErNumber = r.ErNumber,
                    ProjectID = r.ProjectID,
                    ProjectName = r.Project.ProjectName,// with in out report model there is an object of Project that is how it knows what project it is associated to
                    Total = r.ExpenseDetails.Sum(e => e.Amount) != null ? r.ExpenseDetails.Sum(e => e.Amount) : 0.0,
                    numberOfExpenses = r.ExpenseDetails.Count
                    //Score = (int?)(from v in e.Votes
                    //where v.VoterID == voterID
                    //select v.Score).FirstOrDefault()

                }).ToList();
            return reports;
        }
        // used to config the display so both pannels would show ------ Test Method
        private static List<ClientViewModel> TestGetClients()
        {
            ExpenseDb db = new ExpenseDb();
            ClientViewModel viewModel = new ClientViewModel();

            var clients = db.Clients
                .Join(db.Project, a => a.Id, b => b.ClientID, (a, b) => new { a = a, b = b })
                .Where(x => x.a.Id == 1)
                .Select(x => new ClientViewModel() {
                ClientName = x.a.ClientName,
                ClientId = x.b.ClientID,
                ProjectName= x.b.ProjectName,
                ProjectId=x.b.Id
                }).ToList();

            return clients;
        }
        // returns a list of all the establishemtns in a Model object
        private EstablishmentViewModel GetEstablishments(ExpenseDb db)
        {
            var est = from e in db.EstablishmentTBL
                      orderby e.EstablishmentName
                      select new EstablishmentDetails
                      {
                          EstablishmentName = e.EstablishmentName,
                          Id = e.Id
                      };

            EstablishmentViewModel model = new EstablishmentViewModel();
            model.Establishments = est.ToList();
            return model;
        }
        public ActionResult DeleteClient(int clientID)
        {
            var db = new ExpenseDb();
            var client = db.Clients.Find(clientID);
            db.Clients.Remove(client);
            db.SaveChanges();

            // get list of Clients
            var clients = GetClients();

            return PartialView("_ClientTable", clients);
        }
        /// <summary>
        ///  Method used to get a single reports's details 
        /// </summary>
        /// <param name="reportID"></param>
        /// <param name="db"></param>
        /// <returns></returns>
        private static ReportDisplay GetReportDetails(int reportID, ExpenseDb db)
        {
            var report = db.Reports
                .Where(r => r.Id == reportID)
                .Select(r => new ReportDisplay
                {
                    MonthYear = r.MonthYear,
                    ReportID = r.Id,
                    Billable = r.Billable,
                    EmpName = r.EmpName,
                    EmpTitle = r.EmpTitle,
                    ErNumber = r.ErNumber,
                    ProjectID = r.ProjectID,
                    ClientName = r.Project.Client.ClientName,
                    ProjectName = r.Project.ProjectName,// with in out report model there is an object of Project that is how it knows what project it is associated to
                    Total = r.ExpenseDetails.Sum(e => e.Amount) != null ? r.ExpenseDetails.Sum(e => e.Amount) : 0.0,
                    numberOfExpenses = r.ExpenseDetails.Count

                }).FirstOrDefault();
            return report;
        }