// GET: Expenses/Report/5
        public async Task<ActionResult> ViewReport(int? id)
        {
            var employee = await this.GetEmployee();
            var employeeId = employee.Item1;
            ViewBag.UserName = employee.Item2;

            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            DbExpenseReport dbReport = await db.Reports.FindAsync(id);
            if (dbReport == null)
            {
                return HttpNotFound();
            }

            var associatedCharges = await db.Charges
                .Where(c => c.EmployeeId == employeeId && c.ExpenseReportId.HasValue && c.ExpenseReportId.Value == id)
                .ToListAsync();

            var outstandingCharges = await db.Charges
                .Where(c => c.EmployeeId == employeeId && !c.ExpenseReportId.HasValue)
                .ToListAsync();

            var report = new ExpenseReportModel(dbReport);
            report.EmployeeId = employeeId;
            report.AssociatedCharges = associatedCharges.Select(c => new ChargeModel(c)).ToList();
            report.OutstandingCharges = outstandingCharges.Select(c => new ChargeModel(c)).ToList();

            return View(report);
        }
        public async Task<ActionResult> NewReport(
            ExpenseReportModel expenseReportModel,
            string associatedChargesIds,
            string outstandingChargesIds,
            int? addCharge,
            int? removeCharge)
        {
            var employee = await db.Employees.FirstOrDefaultAsync(e => e.Alias == ExpensesDemoData.DefaultEmployeeAlias);
            var employeeId = employee.EmployeeId;
            ViewBag.UserName = employee.Name;

            expenseReportModel.AssociatedCharges = await GetChargesFromSerializedIdList(associatedChargesIds, employeeId);
            expenseReportModel.OutstandingCharges = await GetChargesFromSerializedIdList(outstandingChargesIds, employeeId);

            if (addCharge.HasValue)
            {
                // the request was to add a charge to the report
                ReplaceChargeObjectBetweenLists(addCharge.Value, expenseReportModel.OutstandingCharges, expenseReportModel.AssociatedCharges);
            }
            else if (removeCharge.HasValue)
            {
                // the request was to remove a charge from the report
                ReplaceChargeObjectBetweenLists(removeCharge.Value, expenseReportModel.AssociatedCharges, expenseReportModel.OutstandingCharges);
            }
            else
            {
                // Submit request
                if (ModelState.IsValid)
                {
                    expenseReportModel.EmployeeId = employeeId;
                    var dbExpenseReport = new DbExpenseReport()
                        {
                            Amount = expenseReportModel.Amount,
                            Approver = expenseReportModel.Approver,
                            Charges = expenseReportModel.AssociatedCharges.Select(c => c.ConvertToDbCharge(employeeId)).ToList(),
                            CostCenter = expenseReportModel.CostCenter,
                            DateResolved = expenseReportModel.DateResolved,
                            DateSubmitted = expenseReportModel.DateSubmitted,
                            Employee = employee,
                            EmployeeId = expenseReportModel.EmployeeId,
                            ExpenseReportId = expenseReportModel.Id,
                            Notes = expenseReportModel.Notes,
                            Status = (DbExpenseReportStatus)expenseReportModel.Status,
                        };
                    db.Reports.Add(dbExpenseReport);
                    await db.SaveChangesAsync();

                    // add charges to report
                    foreach (var c in expenseReportModel.AssociatedCharges)
                    {
                        var dbCharge = await db.Charges.FindAsync(c.Id);
                        dbCharge.ExpenseReportId = dbExpenseReport.ExpenseReportId;
                        db.Entry(dbCharge).State = EntityState.Modified;
                    }

                    await db.SaveChangesAsync();

                    return RedirectToAction("Report", new { id = dbExpenseReport.ExpenseReportId });
                }
            }

            // This is required to update hidden fields in the view.
            ModelState.Clear();

            // Recalculate the total expense amount, since we have added or removed some charges.
            expenseReportModel.Amount = expenseReportModel.AssociatedCharges.Sum(c => c.BilledAmount);

            return View(expenseReportModel);
        }
        public async Task<ActionResult> Report(
            ExpenseReportModel expenseReportModel,
            string associatedChargesIds,
            string outstandingChargesIds,
            string command,
            int? addCharge,
            int? removeCharge)
        {
            var employee = await db.Employees.FirstOrDefaultAsync(e => e.Alias == ExpensesDemoData.DefaultEmployeeAlias);
            var employeeId = employee.EmployeeId;
            ViewBag.UserName = employee.Name;

            expenseReportModel.AssociatedCharges = await GetChargesFromSerializedIdList(associatedChargesIds, employeeId);
            expenseReportModel.OutstandingCharges = await GetChargesFromSerializedIdList(outstandingChargesIds, employeeId);

            if (addCharge.HasValue)
            {
                // the request was to add a charge to the report
                ReplaceChargeObjectBetweenLists(addCharge.Value, expenseReportModel.OutstandingCharges, expenseReportModel.AssociatedCharges);
                expenseReportModel.HasUnsavedChanges = true;
            }
            else if (removeCharge.HasValue)
            {
                // the request was to remove a charge from the report
                ReplaceChargeObjectBetweenLists(removeCharge.Value, expenseReportModel.AssociatedCharges, expenseReportModel.OutstandingCharges);
                expenseReportModel.HasUnsavedChanges = true;
            }
            else if (!String.IsNullOrEmpty(command) && command == "Save")
            {
                // Submit request
                if (ModelState.IsValid)
                {
                    var dbExpenseReport = await db.Reports.FindAsync(expenseReportModel.Id);
                    dbExpenseReport.Amount = expenseReportModel.Amount;
                    dbExpenseReport.Notes = expenseReportModel.Notes;
                    db.Entry(dbExpenseReport).State = EntityState.Modified;

                    // add charges to report
                    foreach (var c in expenseReportModel.AssociatedCharges)
                    {
                        var dbCharge = await db.Charges.FindAsync(c.Id);
                        dbCharge.ExpenseReportId = dbExpenseReport.ExpenseReportId;
                        db.Entry(dbCharge).State = EntityState.Modified;
                    }

                    // remove charges from report
                    foreach (var c in expenseReportModel.OutstandingCharges)
                    {
                        var dbCharge = await db.Charges.FindAsync(c.Id);
                        dbCharge.ExpenseReportId = null;
                        db.Entry(dbCharge).State = EntityState.Modified;
                    }

                    await db.SaveChangesAsync();

                    expenseReportModel.HasUnsavedChanges = false;
                }
            }
            else if (!String.IsNullOrEmpty(command) && command == "SubmitForApproval")
            {
                // Submit request
                if (ModelState.IsValid)
                {
                    var dbExpenseReport = await db.Reports.FindAsync(expenseReportModel.Id);

                    if (dbExpenseReport.Status != DbExpenseReportStatus.Saved)
                    {
                        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
                    }

                    dbExpenseReport.Amount = expenseReportModel.Amount;
                    dbExpenseReport.Notes = expenseReportModel.Notes;
                    dbExpenseReport.Status = DbExpenseReportStatus.Submitted;
                    dbExpenseReport.DateSubmitted = DateTime.Today;
                    db.Entry(dbExpenseReport).State = EntityState.Modified;

                    await db.SaveChangesAsync();

                    expenseReportModel.DateSubmitted = DateTime.Today;
                    expenseReportModel.Status = ExpenseReportStatus.Submitted;
                    expenseReportModel.HasUnsavedChanges = false;
                }
            }
            else if (!String.IsNullOrEmpty(command) && command == "Cancel")
            {
                return RedirectToAction("Reports");
            }

            // This is required to update hidden fields in the view.
            ModelState.Clear();

            // Recalculate the total expense amount, since we have added or removed some charges.
            expenseReportModel.Amount = expenseReportModel.AssociatedCharges.Sum(c => c.BilledAmount);

            return View(expenseReportModel);
        }
        // GET: Expenses/NewReport
        public async Task<ActionResult> NewReport()
        {
            var employee = await db.Employees.FirstOrDefaultAsync(e => e.Alias == ExpensesDemoData.DefaultEmployeeAlias);
            var employeeId = employee.EmployeeId;
            var manager = employee.Manager;
            ViewBag.UserName = employee.Name;

            var outstandingCharges = await db.Charges
                .Where(c => c.EmployeeId == employeeId && !c.ExpenseReportId.HasValue)
                .ToListAsync();

            var newReport = new ExpenseReportModel()
            {
                Approver = manager,
                CostCenter = 1055,
                EmployeeId = employeeId,
                OutstandingCharges = outstandingCharges.Select(c => new ChargeModel(c)).ToList(),
            };

            return View(newReport);
        }