Add ability to fix errors during import

This commit is contained in:
2014-02-03 21:16:35 -05:00
parent 3ab80e283a
commit 8b8d82f3d3
8 changed files with 88 additions and 49 deletions
+16
View File
@@ -0,0 +1,16 @@
using System.ComponentModel.DataAnnotations;
using MileageTraker.Web.Models;
using MileageTraker.Web.Utility;
namespace MileageTraker.Web.Attributes
{
public class MileageLogTypeValid : ValidationAttribute
{
public override bool IsValid(object value)
{
if (value == null)
return false;
return typeof (MileageLogType).IsValidValue(value.ToString());
}
}
}
+27
View File
@@ -1,4 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web.Mvc;
using MileageTraker.Web.Attributes;
using MileageTraker.Web.DAL;
@@ -33,6 +36,19 @@ namespace MileageTraker.Web.Controllers
base.OnException(filterContext);
}
public string RenderRazorViewToString(string viewName, object model)
{
ViewData.Model = model;
using (var sw = new StringWriter())
{
var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
var viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
viewResult.View.Render(viewContext, sw);
viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View);
return sw.GetStringBuilder().ToString();
}
}
protected string GetCookieValue(string key)
{
return
@@ -81,5 +97,16 @@ namespace MileageTraker.Web.Controllers
var selectList = new SelectList(DataService.GetPurposeTypes(), "PurposeTypeId", "Purpose");
return selectList;
}
protected static IEnumerable<string> GetModelStateErrorList(IEnumerable<KeyValuePair<string, ModelState>> modelStateDictionary)
{
var errorList =
from kvp in modelStateDictionary
where kvp.Value.Errors.Any()
let errors = string.Join(", ", kvp.Value.Errors.Select(e => e.ErrorMessage))
let msg = kvp.Key + ": " + errors
select msg;
return errorList;
}
}
}
+24 -39
View File
@@ -7,10 +7,8 @@ using System.Web.Mvc;
using System.Web.Routing;
using MileageTraker.Web.Attributes;
using MileageTraker.Web.DAL;
using MileageTraker.Web.Models;
using MileageTraker.Web.Utility;
using MileageTraker.Web.ViewModels;
using MileageTraker.Web.ViewModels.CreateLog;
using MileageTraker.Web.ViewModels.Log;
using MileageTraker.Web.ViewModels.Vehicle;
@@ -174,13 +172,6 @@ namespace MileageTraker.Web.Controllers
return View(viewModel);
}
[HttpGet]
public ActionResult Create(LogImportViewModel viewModel)
{
// TODO: complete?
return View();
}
public ActionResult Edit(int id)
{
var log = DataService.GetLog(id);
@@ -250,7 +241,6 @@ namespace MileageTraker.Web.Controllers
return PartialView(new LogPartialDetails(log));
}
// TODO: Fix?
public ActionResult ImportUpload()
{
return View();
@@ -306,24 +296,8 @@ namespace MileageTraker.Web.Controllers
{
var buttonAttributes = new Dictionary<string, object> { { "class", "btn btn-mini" }, { "target", "_blank" } };
var correctItLink = HtmlHelper.GenerateLink(
ControllerContext.RequestContext, RouteTable.Routes,
"Correct", "Default", "Create", "Log",
null,
buttonAttributes);
try
{
// verify log type
if (!typeof (MileageLogType).IsValidValue(viewModel.LogType))
{
return Json(new
{
Status = ImportStatus.Failure.ToString(),
Message = "Invalid Log Type: \"" + viewModel.LogType + "\"",
//Action = correctItLink
}, JsonRequestBehavior.AllowGet);
}
// verify purpose
var purposeType = DataService.FindPurposeType(viewModel.Purpose);
if (purposeType == null)
@@ -332,7 +306,7 @@ namespace MileageTraker.Web.Controllers
{
Status = ImportStatus.Failure.ToString(),
Message = "Invalid Purpose: " + viewModel.Purpose,
//Action = correctItLink
Action = GetFixLink(viewModel)
}, JsonRequestBehavior.AllowGet);
}
@@ -346,7 +320,7 @@ namespace MileageTraker.Web.Controllers
{
Status = ImportStatus.Failure.ToString(),
Message = string.Join(", ", errorList),
//Action = correctItLink
Action = GetFixLink(viewModel)
}, JsonRequestBehavior.AllowGet);
}
@@ -380,7 +354,7 @@ namespace MileageTraker.Web.Controllers
{
Status = ImportStatus.Failure.ToString(),
Message = "Vehile with supplied ID does not exist",
Action = correctItLink
Action = GetFixLink(viewModel)
}, JsonRequestBehavior.AllowGet);
}
@@ -413,7 +387,7 @@ namespace MileageTraker.Web.Controllers
{
Status = ImportStatus.Failure.ToString(),
Message = fullErrorMessage,
Action = correctItLink
Action = GetFixLink(viewModel)
},
JsonRequestBehavior.AllowGet);
}
@@ -424,20 +398,31 @@ namespace MileageTraker.Web.Controllers
{
Status = ImportStatus.Failure.ToString(),
Message = message,
Action = correctItLink
Action = GetFixLink(viewModel)
}, JsonRequestBehavior.AllowGet);
}
}
private static IEnumerable<string> GetModelStateErrorList(ModelStateDictionary modelStateDictionary)
private string GetFixLink(LogImportViewModel viewModel)
{
var errorList =
from kvp in modelStateDictionary
where kvp.Value.Errors.Any()
let errors = string.Join(", ", kvp.Value.Errors.Select(e => e.ErrorMessage))
let msg = kvp.Key + ": " + errors
select msg;
return errorList;
try
{
viewModel.GetLogViewModel();
}
catch
{
return string.Empty;
}
return RenderRazorViewToString("LogImportPartial", viewModel);
}
[HttpPost]
public ActionResult ImportFix(LogImportViewModel viewModel)
{
var logViewModel = viewModel.GetLogViewModel();
logViewModel.Purpose.Available = GetPurposeTypesSelectList();
return View("Create", logViewModel);
}
public ActionResult ImportTemplate()
+1 -2
View File
@@ -4,7 +4,6 @@ using ExcelLibrary.SpreadSheet;
using MileageTraker.Web.Models;
using MileageTraker.Web.Utility;
using MileageTraker.Web.ViewModels;
using MileageTraker.Web.ViewModels.CreateLog;
namespace MileageTraker.Web.DAL
{
@@ -16,7 +15,7 @@ namespace MileageTraker.Web.DAL
new LogImportViewModel
{
CityName = "City Name",
Date = "10-20-2010",
Date = "10/20/2010",
EndOdometer = "10010",
GasPurchased = "3.141",
LogType = "Commuting",
+1 -1
View File
@@ -26,7 +26,7 @@
else if (result.Status == "Failure") {
$('.import-status', $row).html('<span class="label label-important">Failure</span');
$('.import-message', $row).text(result.Message);
//$('.import-status', $row).append(" " + result.Action);
$('.import-status', $row).append(" " + result.Action);
errorCount++;
}
else if (result.Status == "Duplicate") {
+8 -7
View File
@@ -23,6 +23,7 @@ namespace MileageTraker.Web.ViewModels
public string EndOdometer { get; set; }
[Required(ErrorMessage = "Required")]
[MileageLogTypeValid(ErrorMessage = "Invalid Log Type")]
[Display(Name = "Type")]
[HiddenInput]
public string LogType { get; set; }
@@ -58,6 +59,7 @@ namespace MileageTraker.Web.ViewModels
Mapper.CreateMap<string, double>().ConvertUsing(Convert.ToDouble);
Mapper.CreateMap<string, DateTime>().ConvertUsing(new DateTimeTypeConverter());
Mapper.CreateMap<LogImportViewModel, LogViewModel>()
.ForMember(u => u.LogType, opt => opt.Ignore())
.ForMember(u => u.Purpose, opt => opt.Ignore());
Mapper.CreateMap<LogImportViewModel, Models.Log>()
.ForMember(u => u.Purpose, opt => opt.Ignore())
@@ -73,13 +75,12 @@ namespace MileageTraker.Web.ViewModels
{
}
//public LogViewModel GetLogViewModel()
//{
// var log = new LogViewModel();
// Mapper.Map(this, log);
// return log;
//}
public LogViewModel GetLogViewModel()
{
var log = new LogViewModel();
Mapper.Map(this, log);
return log;
}
public Models.Log GetLog()
{
+9
View File
@@ -0,0 +1,9 @@
@model MileageTraker.Web.ViewModels.LogImportViewModel
@{
Layout = null;
}
@using (Html.BeginForm("ImportFix", "Log", FormMethod.Post, new{target="_blank"}))
{
@Html.EditorForModel()
<input type="submit" value="Fix" class="btn btn-mini" />
}
+2
View File
@@ -112,6 +112,7 @@
<Compile Include="Attributes\FormatHintAttribute.cs" />
<Compile Include="Attributes\HttpParamActionAttribute.cs" />
<Compile Include="Attributes\InputSizeAttribute.cs" />
<Compile Include="Attributes\MileageLogTypeValid.cs" />
<Compile Include="Attributes\LogOwnerAuthorizeAttribute.cs" />
<Compile Include="Attributes\NoEditLabelAttribute.cs" />
<Compile Include="Attributes\UnitsAttribute.cs" />
@@ -231,6 +232,7 @@
<Content Include="fonts\fontawesome-webfont.ttf" />
<Content Include="fonts\fontawesome-webfont.eot" />
<Content Include="fonts\FontAwesome.otf" />
<Content Include="Views\Log\LogImportPartial.cshtml" />
<None Include="Views\Shared\EditorTemplates\HttpPostedFileBase.cshtml" />
</ItemGroup>
<ItemGroup>