Files
MileageTraker/Web/Controllers/CreateLogController.cs
T

367 lines
10 KiB
C#

using System;
using System.Collections.Generic;
using System.Data.Entity.Validation;
using System.IO;
using System.Linq;
using System.Security;
using System.Web.Mvc;
using System.Web.Routing;
using MileageTraker.Web.Attributes;
using MileageTraker.Web.DAL;
using MileageTraker.Web.Models;
using MileageTraker.Web.ViewModels;
using MileageTraker.Web.ViewModels.CreateLog;
namespace MileageTraker.Web.Controllers
{
[Authorize(Roles = "Driver, Administrator, Developer")]
public class CreateLogController : ControllerBase
{
private const string CookeNameVehicleid = "mr_vehicleId";
private const string CookieKeyLogtype = "mr_logType";
public ViewResult Index()
{
var createLogModel = NewCreateLogModel();
return View(createLogModel);
}
[HttpPost]
public ActionResult Index(CreateLogViewModel model)
{
if (ModelState.IsValid)
{
var confirmCreateLogViewModel = new ConfirmCreateLogViewModel(model);
confirmCreateLogViewModel.Purpose.Available = GetPurposeTypesSelectList();
return View("Confirm", confirmCreateLogViewModel);
}
model.Purpose.Available = GetPurposeTypesSelectList();
return View(model);
}
[LogOwnerAuthorize]
public ActionResult EditPast(int id)
{
var log = DataService.GetLog(id);
var viewModel = new EditPastViewModel(log)
{
Purpose = { Available = GetPurposeTypesSelectList() }
};
return View(viewModel);
}
[HttpPost]
[ActionLog]
public ActionResult EditPast(EditPastViewModel viewModel)
{
if (ModelState.IsValid)
{
var log = DataService.GetLog(viewModel.LogId);
if (log.User.Username != User.Identity.Name)
throw new SecurityException();
viewModel.SetProperties(log);
log.Vehicle = DataService.GetVehicle(viewModel.VehicleId);
if (viewModel.Purpose != null)
log.Purpose =
DataService.GetPurposeTypes()
.First(pt => pt.PurposeTypeId == viewModel.Purpose.Selected);
DataService.UpdateLog(log);
SetStatusMessage(@"You've successfully updated an entry
traveling to <strong>" + viewModel.CityName + @"</strong>
for <strong>" + log.Purpose.Purpose + @"</strong>
on <strong>" + viewModel.Date.ToShortDateString() + @"</strong>
in Vehicle Id <strong>" + viewModel.VehicleId + @"</strong>
ending in <strong>" + viewModel.EndOdometer + @"</strong>
miles on the odometer.", StatusType.Success);
return RedirectToAction("Index");
}
viewModel.Purpose.Available = GetPurposeTypesSelectList();
return View(viewModel);
}
[HttpParamAction]
[HttpPost]
public ViewResult Edit(CreateLogViewModel model)
{
model.Purpose.Available = GetPurposeTypesSelectList();
return View("Index", model);
}
[HttpParamAction]
[HttpPost]
[ActionLog]
public ActionResult Confirm(CreateLogViewModel model)
{
if (ModelState.IsValid)
{
SetCookieValue(CookieKeyLogtype, model.LogType.Enum.ToString());
SetCookieValue(CookeNameVehicleid, model.VehicleId);
// Save the new log
var log = model.GetLog();
log.Vehicle = DataService.GetVehicle(model.VehicleId);
log.User = DataService.FindUserByUsername(User.Identity.Name);
log.Source = HttpContext.Request.Url.AbsolutePath;
log.UserHostAddress = HttpContext.Request.UserHostAddress;
log.UserAgent = HttpContext.Request.UserAgent;
log.Purpose =
DataService.GetPurposeTypes()
.First(pt => pt.PurposeTypeId == model.Purpose.Selected);
DataService.AddLog(log);
var editLink = Url.Action("EditPast", "CreateLog", new {id = log.LogId});
SetStatusMessage(
@"You've successfully created an entry
traveling to <strong>" + model.CityName + @"</strong>
for <strong>" + log.Purpose.Purpose + @"</strong>
on <strong>" + model.Date.ToShortDateString() + @"</strong>
in Vehicle Id <strong>" + model.VehicleId + @"</strong>
ending in <strong>" + model.EndOdometer + @"</strong>
miles on the odometer. " +
@"<a href='" + editLink + @"' class='btn btn-mini btn-success'>Edit</a>",
StatusType.Success);
return RedirectToAction("Index");
}
model.Purpose.Available = GetPurposeTypesSelectList();
return View("Index", model);
}
public PartialViewResult RecentLogs()
{
var username = User.Identity.Name;
var user = DataService.FindUserByUsername(username);
var logs = DataService.GetRecentLogsByUsername(user.Username);
ViewData["name"] = user.FullName;
return PartialView(logs);
}
private CreateLogViewModel NewCreateLogModel()
{
MileageLogType logType;
Enum.TryParse(GetCookieValue(CookieKeyLogtype), true, out logType);
var vehicleId = GetCookieValue(CookeNameVehicleid);
return new CreateLogViewModel
{
LogType = logType,
VehicleId = vehicleId,
Date = DateTime.Today,
Purpose =
new SelectListViewModel
{
Available =
GetPurposeTypesSelectList()
}
};
}
#region Import
public ActionResult ImportUpload()
{
return View();
}
[HttpPost]
public ActionResult Import(ImportUploadViewModel viewModel)
{
if (ModelState.IsValid && viewModel.File != null && viewModel.File.ContentLength > 0)
{
var fileName = Path.GetFileName(viewModel.File.FileName);
var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
viewModel.File.SaveAs(path);
try
{
var logImports = LogImporter.Import(path);
// todo: delete file?
return View(logImports.ToList());
}
catch (OutOfMemoryException)
{
SetStatusMessage(
"Problem reading excel document - please verify that the document is in Excel 97-2003 Workbook (.xls) format", StatusType.Error);
}
catch (Exception ex)
{
SetStatusMessage("Problem reading excel document: " + ex.Message, StatusType.Error);
}
}
return RedirectToAction("ImportUpload");
}
enum ImportStatus
{
Success,
Failure,
Duplicate
}
[HttpPost]
[ActionLog]
public ActionResult ImportCreate(ImportLogViewModel viewModel)
{
var buttonAttributes = new Dictionary<string, object> { { "class", "btn btn-mini" }, { "target", "_blank" } };
try
{
// verify purpose
var purposeType = DataService.FindPurposeType(viewModel.Purpose);
if (purposeType == null)
{
return Json(new
{
Status = ImportStatus.Failure.ToString(),
Message = "Invalid Purpose: " + viewModel.Purpose,
Action = GetFixLink(viewModel)
}, JsonRequestBehavior.AllowGet);
}
if (!ModelState.IsValid)
{
var errorList = GetModelStateErrorList(ModelState);
// remove the object name from the errors
errorList = errorList.Select(s => s.Replace("viewModel.", ""));
return Json(new
{
Status = ImportStatus.Failure.ToString(),
Message = string.Join(", ", errorList),
Action = GetFixLink(viewModel)
}, JsonRequestBehavior.AllowGet);
}
var log = viewModel.GetLog();
log.Vehicle = DataService.GetVehicle(viewModel.VehicleId);
log.User = DataService.FindUserByUsername(User.Identity.Name);
log.Source = HttpContext.Request.Url.AbsolutePath;
log.UserHostAddress = HttpContext.Request.UserHostAddress;
log.UserAgent = HttpContext.Request.UserAgent;
log.Purpose = purposeType;
// check duplicate
var duplicateLogs = DataService.GetDuplicateLogs(log).ToList();
if (duplicateLogs.Any())
{
var link = HtmlHelper.GenerateLink(
ControllerContext.RequestContext, RouteTable.Routes,
"Edit", "Default", "EditPast", "CreateLog",
new RouteValueDictionary(new { id = duplicateLogs.First().LogId }),
buttonAttributes);
return Json(new
{
Status = ImportStatus.Duplicate.ToString(),
Message = "This log has been previously entered",
//Action = link
}, JsonRequestBehavior.AllowGet);
}
// verify vehicle exists
if (log.Vehicle == null)
{
return Json(new
{
Status = ImportStatus.Failure.ToString(),
Message = "Vehile with supplied ID does not exist",
Action = GetFixLink(viewModel)
}, JsonRequestBehavior.AllowGet);
}
// verify city exists
if (DataService.FindCityByName(log.CityName) == null)
{
return Json(new
{
Status = ImportStatus.Failure.ToString(),
Message = "City must exist in system",
Action = GetFixLink(viewModel)
}, JsonRequestBehavior.AllowGet);
}
// SAVE IT!
DataService.AddLog(log);
var successLink = HtmlHelper.GenerateLink(
ControllerContext.RequestContext, RouteTable.Routes,
"Edit", "Default", "EditPast", "CreateLog",
new RouteValueDictionary(new { id = log.LogId }),
buttonAttributes);
return Json(new
{
Status = ImportStatus.Success.ToString(),
Action = successLink
}, JsonRequestBehavior.AllowGet);
}
catch (DbEntityValidationException ex)
{
// Retrieve the error messages as a list of strings.
var errorMessages = ex.EntityValidationErrors
.SelectMany(x => x.ValidationErrors)
.Select(x => x.ErrorMessage);
// Join the list to a single string.
var fullErrorMessage = string.Join(", ", errorMessages);
return Json(new
{
Status = ImportStatus.Failure.ToString(),
Message = fullErrorMessage,
Action = GetFixLink(viewModel)
},
JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
var message = ex.Message;
return Json(new
{
Status = ImportStatus.Failure.ToString(),
Message = message,
Action = GetFixLink(viewModel)
}, JsonRequestBehavior.AllowGet);
}
}
private string GetFixLink(ImportLogViewModel viewModel)
{
try
{
viewModel.GetCreateLogViewModel();
}
catch
{
return string.Empty;
}
return RenderRazorViewToString("ImportFix", viewModel);
}
[HttpPost]
public ActionResult ImportFix(ImportLogViewModel viewModel)
{
var createGetLogViewModel = viewModel.GetCreateLogViewModel();
createGetLogViewModel.Purpose = new SelectListViewModel
{
Available = GetPurposeTypesSelectList()
};
return View("Index", createGetLogViewModel);
}
public ActionResult ImportTemplate()
{
var template = LogImportTemplateWriter.Write();
return File(template, "application/ms-excel", "MileageTraker_ImportTemplate.xls");
}
#endregion
}
}