Add vehicle active/inactive state

This commit is contained in:
2015-06-18 10:59:07 -04:00
parent c7d7fa265e
commit 5d70617194
12 changed files with 155 additions and 19 deletions
+39 -3
View File
@@ -1,4 +1,5 @@
using System; using System;
using System.Linq;
using System.Web.Mvc; using System.Web.Mvc;
using MileageTraker.Web.Attributes; using MileageTraker.Web.Attributes;
using MileageTraker.Web.DAL; using MileageTraker.Web.DAL;
@@ -10,10 +11,11 @@ namespace MileageTraker.Web.Controllers
[Authorize(Roles = "Administrator, Developer")] [Authorize(Roles = "Administrator, Developer")]
public class VehicleController : ControllerBase public class VehicleController : ControllerBase
{ {
public ViewResult Index() public ViewResult Index(bool inactive = false)
{ {
var vehicles = DataService.GetVehicles(); var vehicles = DataService.GetVehicles().Where(v => v.InactiveDate.HasValue == inactive);
return View(vehicles); var viewModel = new VehicleResultsViewModel(vehicles, inactive);
return View(viewModel);
} }
public ViewResult Details(string id) public ViewResult Details(string id)
@@ -81,5 +83,39 @@ namespace MileageTraker.Web.Controllers
var export = VehicleImporter.Export(vehicles); var export = VehicleImporter.Export(vehicles);
return File(export, "application/ms-excel", string.Format("ETHRAVehicles{0:yyyy-MM-dd}.xls", DateTime.Today)); return File(export, "application/ms-excel", string.Format("ETHRAVehicles{0:yyyy-MM-dd}.xls", DateTime.Today));
} }
[ActionLog]
public ActionResult SetInactive(string id)
{
var vehicle = DataService.GetVehicle(id);
if (vehicle.InactiveDate.HasValue)
{
TempData["StatusMessage"] = "Vehicle already inactive";
}
else
{
vehicle.InactiveDate = DateTime.Now;
DataService.UpdateVehicle(vehicle);
TempData["StatusMessage"] = string.Format("Vehicle set inactive on {0:MM/dd/yyyy}", vehicle.InactiveDate.Value);
}
return RedirectToAction("Details", new {id});
}
[ActionLog]
public ActionResult SetActive(string id)
{
var vehicle = DataService.GetVehicle(id);
if (!vehicle.InactiveDate.HasValue)
{
TempData["StatusMessage"] = "Vehicle is already active";
}
else
{
vehicle.InactiveDate = null;
DataService.UpdateVehicle(vehicle);
TempData["StatusMessage"] = string.Format("Vehicle reactivated");
}
return RedirectToAction("Details", new { id });
}
} }
} }
@@ -0,0 +1,24 @@
// <auto-generated />
namespace MileageTraker.Web.Migrations
{
using System.Data.Entity.Migrations;
using System.Data.Entity.Migrations.Infrastructure;
public sealed partial class VehicleInactiveDate : IMigrationMetadata
{
string IMigrationMetadata.Id
{
get { return "201506181329243_VehicleInactiveDate"; }
}
string IMigrationMetadata.Source
{
get { return null; }
}
string IMigrationMetadata.Target
{
get { return "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"; }
}
}
}
@@ -0,0 +1,17 @@
namespace MileageTraker.Web.Migrations
{
using System.Data.Entity.Migrations;
public partial class VehicleInactiveDate : DbMigration
{
public override void Up()
{
AddColumn("Vehicle", "InactiveDate", c => c.DateTime());
}
public override void Down()
{
DropColumn("Vehicle", "InactiveDate");
}
}
}
+7 -1
View File
@@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using MileageTraker.Web.Attributes; using MileageTraker.Web.Attributes;
@@ -57,6 +58,11 @@ namespace MileageTraker.Web.Models
[FormatHint("mm/yy")] [FormatHint("mm/yy")]
public string PurDate { get; set; } public string PurDate { get; set; }
[DataType(DataType.DateTime)]
[DisplayFormat(NullDisplayText = "Currently Active", DataFormatString = @"{0:MM/dd/yyyy}")]
[FormatHint("mm/dd/yyyy")]
public DateTime? InactiveDate { get; set; }
[Required] [Required]
[Display(Name = "Tag#")] [Display(Name = "Tag#")]
[InputSize("small")] [InputSize("small")]
+5 -1
View File
@@ -120,7 +120,11 @@ function addButtonIcons () {
'Export': 'download', 'Export': 'download',
'Import': 'upload', 'Import': 'upload',
'Driver Mileage': 'user', 'Driver Mileage': 'user',
'Vehicle Mileage': 'car' 'Vehicle Mileage': 'car',
'Show Active': 'ok-circle',
'Show Inactive': 'ban-circle',
'Set Inactive' : 'ban-circle',
'Reactivate' : 'ok-circle'
}; };
$.each(textToIcon, function(text, icon) { $.each(textToIcon, function(text, icon) {
$("a:contains('" + text + "'):not(:has(i))") $("a:contains('" + text + "'):not(:has(i))")
@@ -0,0 +1,16 @@
using System.Collections.Generic;
namespace MileageTraker.Web.ViewModels.Vehicle
{
public class VehicleResultsViewModel
{
public IEnumerable<Models.Vehicle> Vehicles { get; set; }
public bool Inactive { get; set; }
public VehicleResultsViewModel(IEnumerable<Models.Vehicle> vehicles, bool activeInactive)
{
Vehicles = vehicles;
Inactive = activeInactive;
}
}
}
@@ -1,10 +1,21 @@
@using System.Globalization @using System.Globalization
@model DateTime @model DateTime?
@{ @{
Layout = "~/Views/Shared/DisplayTemplates/_FieldLayout.cshtml"; Layout = "~/Views/Shared/DisplayTemplates/_FieldLayout.cshtml";
var val = var val =
ViewData.ModelMetadata.DisplayFormatString != null Model.HasValue
?string.Format(ViewData.ModelMetadata.DisplayFormatString, Model) ?
: Model.ToString(CultureInfo.InvariantCulture); ViewData.ModelMetadata.DisplayFormatString != null
? string.Format(ViewData.ModelMetadata.DisplayFormatString, Model)
: Model.Value.ToString(CultureInfo.InvariantCulture)
: string.Empty;
} }
@Html.Encode(val) @if (Model == null)
{
@Html.Encode(@ViewData.ModelMetadata.NullDisplayText)
}
else
{
@Html.Encode(val)
}
@@ -2,7 +2,11 @@
@{ @{
Layout = null; Layout = null;
} }
@foreach (var prop in ViewData.ModelMetadata.Properties.Where(pm => pm.ShowForDisplay && !pm.HideSurroundingHtml && !pm.ModelType.IsCollection())) @foreach (var prop in ViewData.ModelMetadata.Properties.Where(
pm => pm.ShowForDisplay
&& !pm.HideSurroundingHtml
&& !pm.ModelType.IsCollection()
))
{ {
@Html.Display(prop.PropertyName) @Html.Display(prop.PropertyName)
} }
@@ -1,13 +1,17 @@
@model DateTime @model DateTime?
@{ @{
Layout = "~/Views/Shared/EditorTemplates/_FieldLayout.cshtml"; Layout = "~/Views/Shared/EditorTemplates/_FieldLayout.cshtml";
var inputSize = (string)ViewData.ModelMetadata.AdditionalValues["InputSize"]; var inputSize = (string)ViewData.ModelMetadata.AdditionalValues["InputSize"];
var val =
Model.HasValue
? Model.Value.ToShortDateString()
: string.Empty;
} }
@if (!string.IsNullOrEmpty(inputSize)) @if (!string.IsNullOrEmpty(inputSize))
{ {
@Html.TextBox("", (Model != DateTime.MinValue ? Model.ToShortDateString() : string.Empty ), new { @class = inputSize}) @Html.TextBox("", (Model != DateTime.MinValue ? val : string.Empty ), new { @class = inputSize})
} }
else else
{ {
@Html.TextBox("", (Model != DateTime.MinValue ? Model.ToShortDateString() : string.Empty )) @Html.TextBox("", (Model != DateTime.MinValue ? val : string.Empty ))
} }
+9 -1
View File
@@ -1,7 +1,7 @@
@model MileageTraker.Web.Models.Vehicle @model MileageTraker.Web.Models.Vehicle
@{ @{
ViewBag.Title = "Vehicle Details"; ViewBag.Title = "Vehicle Details " + (!Model.InactiveDate.HasValue ? "(Active)" : "(Inactive)");
} }
@section Styles { @section Styles {
@@ -20,5 +20,13 @@
<div class="center-content btn-toolbar"> <div class="center-content btn-toolbar">
@Html.ActionLink("Edit", "Edit", new { id = Model.VehicleId }, new { @class = "btn" }) @Html.ActionLink("Edit", "Edit", new { id = Model.VehicleId }, new { @class = "btn" })
@if (!Model.InactiveDate.HasValue)
{
@Html.ActionLink("Set Inactive", "SetInactive", new {id = Model.VehicleId}, new {@class = "btn"})
}
else
{
@Html.ActionLink("Reactivate", "SetActive", new {id = Model.VehicleId}, new {@class = "btn"})
}
@Html.ActionLink("Logs", "Index", "Log", new { Model.VehicleId}, new { @class = "btn" }) @Html.ActionLink("Logs", "Index", "Log", new { Model.VehicleId}, new { @class = "btn" })
</div> </div>
+5 -4
View File
@@ -1,7 +1,7 @@
@model IEnumerable<MileageTraker.Web.Models.Vehicle> @model MileageTraker.Web.ViewModels.Vehicle.VehicleResultsViewModel
@{ @{
ViewBag.Title = "Vehicles"; ViewBag.Title = "Vehicles " + (!Model.Inactive ? "(Active)" : "(Inactive)");
} }
@section Styles { @section Styles {
@@ -14,7 +14,8 @@
<div class="btn-toolbar"> <div class="btn-toolbar">
@Html.ActionLink("Add Another Vehicle", "Create", null, new{@class="btn"}) @Html.ActionLink("Add Another Vehicle", "Create", null, new{@class="btn"})
@Html.ActionLink("Export", "Export", null, new { @class = "btn" }) @Html.ActionLink("Export All", "Export", null, new { @class = "btn" })
@Html.ActionLink(Model.Inactive ? "Show Active" : "Show Inactive", "Index", new {inactive = !Model.Inactive}, new { @class = "btn" })
</div> </div>
<table class="table table-striped table-bordered table-hover table-condensed"> <table class="table table-striped table-bordered table-hover table-condensed">
<tr> <tr>
@@ -51,7 +52,7 @@
<th></th> <th></th>
</tr> </tr>
@foreach (var item in Model) { @foreach (var item in Model.Vehicles) {
<tr> <tr>
<td> <td>
@Html.DisplayTextFor(m => item.Key) @Html.DisplayTextFor(m => item.Key)
+5
View File
@@ -188,6 +188,10 @@
<Compile Include="Migrations\201405210016138_CityFieldsRequired.Designer.cs"> <Compile Include="Migrations\201405210016138_CityFieldsRequired.Designer.cs">
<DependentUpon>201405210016138_CityFieldsRequired.cs</DependentUpon> <DependentUpon>201405210016138_CityFieldsRequired.cs</DependentUpon>
</Compile> </Compile>
<Compile Include="Migrations\201506181329243_VehicleInactiveDate.cs" />
<Compile Include="Migrations\201506181329243_VehicleInactiveDate.Designer.cs">
<DependentUpon>201506181329243_VehicleInactiveDate.cs</DependentUpon>
</Compile>
<Compile Include="Migrations\Configuration.cs" /> <Compile Include="Migrations\Configuration.cs" />
<Compile Include="Models\DomainRules.cs" /> <Compile Include="Models\DomainRules.cs" />
<Compile Include="Models\PurposeType.cs" /> <Compile Include="Models\PurposeType.cs" />
@@ -210,6 +214,7 @@
<Compile Include="ViewModels\Log\LogViewModel.cs" /> <Compile Include="ViewModels\Log\LogViewModel.cs" />
<Compile Include="ViewModels\Log\LogIndexViewModel.cs" /> <Compile Include="ViewModels\Log\LogIndexViewModel.cs" />
<Compile Include="ViewModels\Log\LogPartialDetails.cs" /> <Compile Include="ViewModels\Log\LogPartialDetails.cs" />
<Compile Include="ViewModels\Vehicle\VehicleResultsViewModel.cs" />
<Compile Include="ViewModels\SelectListViewModel.cs" /> <Compile Include="ViewModels\SelectListViewModel.cs" />
<Compile Include="ViewModels\User\ExportUserViewModel.cs" /> <Compile Include="ViewModels\User\ExportUserViewModel.cs" />
<Compile Include="ViewModels\User\SetPasswordViewModel.cs" /> <Compile Include="ViewModels\User\SetPasswordViewModel.cs" />