Service reminder implemented.
This commit is contained in:
@@ -21,22 +21,6 @@ namespace MileageTraker.Web.Controllers
|
||||
return View(viewModel);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[RequireRequestValue("vehicleId")]
|
||||
public ActionResult Create(string vehicleId)
|
||||
{
|
||||
var viewModel = new ServiceReminderViewModel
|
||||
{
|
||||
VehicleId = vehicleId,
|
||||
};
|
||||
|
||||
var vehicle = DataService.GetVehicle(vehicleId);
|
||||
if (vehicle.CurrentOdometer.HasValue)
|
||||
viewModel.TargetOdometer = (int) (Math.Ceiling((decimal) ((vehicle.CurrentOdometer.Value + 3000)/1000))*1000);
|
||||
|
||||
return View(viewModel);
|
||||
}
|
||||
|
||||
public ActionResult Delete(int id)
|
||||
{
|
||||
var serviceReminder = DataService.GetServiceReminder(id);
|
||||
@@ -45,6 +29,24 @@ namespace MileageTraker.Web.Controllers
|
||||
return RedirectToAction("Index", new { vehicleId });
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[RequireRequestValue("vehicleId")]
|
||||
public ActionResult Create(string vehicleId)
|
||||
{
|
||||
var vehicle = DataService.GetVehicle(vehicleId);
|
||||
|
||||
var viewModel = new ServiceReminderViewModel
|
||||
{
|
||||
VehicleId = vehicleId,
|
||||
CurrentOdometer = vehicle.CurrentOdometer
|
||||
};
|
||||
|
||||
if (vehicle.CurrentOdometer.HasValue)
|
||||
viewModel.TargetOdometer = vehicle.CurrentOdometer.Value + 4000;
|
||||
|
||||
return View(viewModel);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ActionLog]
|
||||
public ActionResult Create(ServiceReminderViewModel viewModel)
|
||||
@@ -54,6 +56,7 @@ namespace MileageTraker.Web.Controllers
|
||||
var serviceReminder = viewModel.GetServiceReminder();
|
||||
|
||||
serviceReminder.Vehicle = DataService.GetVehicle(viewModel.VehicleId);
|
||||
|
||||
DataService.AddServiceReminder(serviceReminder);
|
||||
|
||||
SetStatusMessage(
|
||||
@@ -63,5 +66,33 @@ namespace MileageTraker.Web.Controllers
|
||||
|
||||
return View(viewModel);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public ActionResult Edit(int id)
|
||||
{
|
||||
var serviceReminder = DataService.GetServiceReminder(id);
|
||||
var viewModel = new ServiceReminderViewModel(serviceReminder);
|
||||
return View(viewModel);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ActionLog]
|
||||
public ActionResult Edit(ServiceReminderViewModel viewModel)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
var serviceReminder = viewModel.GetServiceReminder();
|
||||
|
||||
serviceReminder.Vehicle = DataService.GetVehicle(viewModel.VehicleId);
|
||||
|
||||
DataService.UpdateServiceReminder(serviceReminder);
|
||||
|
||||
SetStatusMessage(
|
||||
string.Format("Service Reminder at {0} miles updated", viewModel.TargetOdometer), StatusType.Success);
|
||||
return RedirectToAction("Index", new {vehicleId = viewModel.VehicleId});
|
||||
}
|
||||
|
||||
return View(viewModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,11 @@ namespace MileageTraker.Web.Controllers
|
||||
{
|
||||
public ViewResult Index(bool inactive = false)
|
||||
{
|
||||
var vehicles = DataService.GetVehicles().Where(v => inactive == (v.InactiveDate.HasValue && v.InactiveDate.Value < DateTime.Today.AddDays(1)));
|
||||
var vehicles =
|
||||
(from v in DataService.GetVehicles().ToList()
|
||||
where inactive == (v.InactiveDate.HasValue && v.InactiveDate.Value < DateTime.Today.AddDays(1))
|
||||
select new VehicleViewModel(v)).ToList();
|
||||
|
||||
var viewModel = new VehicleResultsViewModel(vehicles, inactive);
|
||||
return View(viewModel);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using MileageTraker.Web.Attributes;
|
||||
using MileageTraker.Web.DAL;
|
||||
using MileageTraker.Web.Models;
|
||||
using MileageTraker.Web.Utility;
|
||||
using MileageTraker.Web.ViewModels;
|
||||
using MileageTraker.Web.ViewModels.ServiceReminder;
|
||||
using MileageTraker.Web.ViewModels.VehicleService;
|
||||
|
||||
namespace MileageTraker.Web.Controllers
|
||||
@@ -23,10 +26,16 @@ namespace MileageTraker.Web.Controllers
|
||||
|
||||
var vehicleServices = DataService.FilterVehicleServices(DataService.GetVehicleServices(), query).ToList();
|
||||
|
||||
var upcomingServiceReminders =
|
||||
DataService.GetUpcomingServiceReminders().ToList()
|
||||
.Select(sr => new ServiceReminderViewModel(sr)).ToList();
|
||||
upcomingServiceReminders.Sort();
|
||||
|
||||
var viewModel = new VehicleServiceResultsViewModel(
|
||||
vehicleServices.Select(s => new VehicleServiceViewModel(s)),
|
||||
query,
|
||||
CustomExtensions.YearMonthList(validVehicleServiceYearMonths));
|
||||
vehicleServices.Select(s => new VehicleServiceViewModel(s)),
|
||||
upcomingServiceReminders,
|
||||
query,
|
||||
CustomExtensions.YearMonthList(validVehicleServiceYearMonths));
|
||||
|
||||
return View(viewModel);
|
||||
}
|
||||
@@ -78,18 +87,104 @@ namespace MileageTraker.Web.Controllers
|
||||
{
|
||||
var vehicleService = viewModel.GetVehicleService();
|
||||
|
||||
|
||||
vehicleService.Vehicle = DataService.GetVehicle(viewModel.VehicleId);
|
||||
DataService.AddVehicleService(vehicleService);
|
||||
|
||||
SetStatusMessage(
|
||||
string.Format("Vehicle Service for vehicle {0} created", viewModel.VehicleId), StatusType.Success);
|
||||
return RedirectToAction("UpdateServiceReminders", new {vehicleId = viewModel.VehicleId});
|
||||
}
|
||||
|
||||
return View(viewModel);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public ActionResult UpdateServiceReminders(string vehicleId)
|
||||
{
|
||||
var vehicle = DataService.GetVehicle(vehicleId);
|
||||
|
||||
var viewModel = new UpdateServiceRemindersViewModel { VehicleId = vehicleId };
|
||||
|
||||
RefreshServiceReminderViewModel(viewModel, vehicle, true);
|
||||
|
||||
if (vehicle.CurrentOdometer.HasValue)
|
||||
viewModel.TargetOdometer = vehicle.CurrentOdometer.Value + 4000;
|
||||
|
||||
return View(viewModel);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ActionLog]
|
||||
public ActionResult UpdateServiceReminders(UpdateServiceRemindersViewModel viewModel)
|
||||
{
|
||||
var vehicle = DataService.GetVehicle(viewModel.VehicleId);
|
||||
|
||||
RefreshServiceReminderViewModel(viewModel, vehicle); // this data doesn't get posted back
|
||||
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
var serviceReminder = viewModel.GetServiceReminder();
|
||||
|
||||
var status = new List<string>();
|
||||
|
||||
// handle the new service reminder
|
||||
if (serviceReminder != null)
|
||||
{
|
||||
serviceReminder.Vehicle = vehicle;
|
||||
|
||||
DataService.AddServiceReminder(serviceReminder);
|
||||
status.Add(string.Format("Service Reminder at {0} miles created", viewModel.TargetOdometer));
|
||||
}
|
||||
|
||||
// handle any deletion
|
||||
if (viewModel.DeleteServiceReminders != null
|
||||
&& viewModel.DeleteServiceReminders.Selected != null
|
||||
&& viewModel.DeleteServiceReminders.Selected.Length > 0)
|
||||
{
|
||||
var serviceReminders =
|
||||
(from sr in vehicle.ServiceReminders
|
||||
select new { format = UpdateServiceRemindersViewModel.FormatServiceReminder(sr), id = sr.ServiceReminderId })
|
||||
.ToDictionary(o => o.format);
|
||||
|
||||
foreach (var selected in viewModel.DeleteServiceReminders.Selected)
|
||||
{
|
||||
DataService.DeleteServiceReminder(serviceReminders[selected].id);
|
||||
}
|
||||
status.Add(string.Format("Selected {0} service reminders deleted", viewModel.DeleteServiceReminders.Selected.Count()));
|
||||
}
|
||||
|
||||
if (status.Count > 0)
|
||||
{
|
||||
SetStatusMessage(string.Join(", ", status), StatusType.Success);
|
||||
}
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
|
||||
return View(viewModel);
|
||||
}
|
||||
|
||||
private void RefreshServiceReminderViewModel(
|
||||
UpdateServiceRemindersViewModel viewModel, Vehicle vehicle, bool setDefaultSelectedServiceReminders = false)
|
||||
{
|
||||
if (viewModel.DeleteServiceReminders == null)
|
||||
viewModel.DeleteServiceReminders = new CheckBoxViewModel();
|
||||
|
||||
var existingServiceReminders =
|
||||
(from sr in vehicle.ServiceReminders
|
||||
select UpdateServiceRemindersViewModel.FormatServiceReminder(sr)).ToArray();
|
||||
|
||||
viewModel.DeleteServiceReminders.Available = existingServiceReminders;
|
||||
viewModel.CurrentOdometer = vehicle.CurrentOdometer;
|
||||
|
||||
if (vehicle.CurrentOdometer.HasValue && setDefaultSelectedServiceReminders)
|
||||
{
|
||||
viewModel.DeleteServiceReminders.Selected =
|
||||
(from sr in vehicle.ServiceReminders
|
||||
where sr.TargetOdometer <= vehicle.CurrentOdometer.Value
|
||||
select UpdateServiceRemindersViewModel.FormatServiceReminder(sr)).ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public ActionResult Edit(int id)
|
||||
{
|
||||
var vehicleService = DataService.GetVehicleService(id);
|
||||
|
||||
+23
-1
@@ -407,7 +407,7 @@ namespace MileageTraker.Web.DAL
|
||||
_db.SaveChanges();
|
||||
}
|
||||
|
||||
public IEnumerable<Vehicle> GetVehicles()
|
||||
public IQueryable<Vehicle> GetVehicles()
|
||||
{
|
||||
var vehicles = _db.Vehicles;
|
||||
return vehicles;
|
||||
@@ -901,6 +901,17 @@ namespace MileageTraker.Web.DAL
|
||||
return _db.ServiceReminders.Find(id);
|
||||
}
|
||||
|
||||
public ServiceReminder FindDuplicateServiceReminder(string vehicleId, int targetOdometer, string description)
|
||||
{
|
||||
return
|
||||
(from sr in _db.ServiceReminders
|
||||
where
|
||||
sr.Vehicle.VehicleId == vehicleId &&
|
||||
sr.TargetOdometer == targetOdometer &&
|
||||
sr.Description == description
|
||||
select sr).FirstOrDefault();
|
||||
}
|
||||
|
||||
public void DeleteServiceReminder(int id)
|
||||
{
|
||||
var serviceReminder = _db.ServiceReminders.Find(id);
|
||||
@@ -909,6 +920,17 @@ namespace MileageTraker.Web.DAL
|
||||
_db.SaveChanges();
|
||||
}
|
||||
|
||||
public IQueryable<ServiceReminder> GetUpcomingServiceReminders()
|
||||
{
|
||||
const int mileageThreshold = 500;
|
||||
return
|
||||
from sr in _db.ServiceReminders
|
||||
where
|
||||
sr.Vehicle.CurrentOdometer.HasValue
|
||||
&& sr.Vehicle.CurrentOdometer.Value > (sr.TargetOdometer - mileageThreshold)
|
||||
select sr;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,8 @@ namespace MileageTraker.Web.Models
|
||||
public virtual Vehicle Vehicle { get; set; }
|
||||
|
||||
[InputSize("small")]
|
||||
public int TargetOdometer { get; set; }
|
||||
[Range(1, 500000, ErrorMessage = "Between 1 and 500k")]
|
||||
public int TargetOdometer { get; set; }
|
||||
|
||||
[StringLength(64)]
|
||||
public string Description { get; set; }
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
$('#page-match-status').html('<span class="label label-warning"><i class="fa fa-spinner fa-spin"></i> Matching In Progress</span> for ' + total + ' fuel logs. <strong>Keep page open until complete.</strong>');
|
||||
$('#page-match-status').after('<div class="progress progress-striped active"><div class="bar" style="width:0%"></div><div>');
|
||||
|
||||
$(".match-status a").addClass('pull-right');
|
||||
|
||||
submitNext();
|
||||
var unmatchedCount = 0;
|
||||
var errorCount = 0;
|
||||
@@ -41,10 +43,11 @@
|
||||
}
|
||||
$('.match-message', $row).text(result.Message);
|
||||
}
|
||||
|
||||
if (result.Action != undefined && result.Action != null) {
|
||||
$('.match-status', $row).append(" " + result.Action);
|
||||
var $action = $("a[matchcount]", $row);
|
||||
matchCountFunc.apply($action);
|
||||
$("a", $row).addClass('pull-right');
|
||||
matchCountFunc.apply($("a[matchcount]", $row));
|
||||
}
|
||||
|
||||
submitNext();
|
||||
|
||||
+78
-11
@@ -75,7 +75,7 @@ $(function () {
|
||||
var $recentLogs = $("#RecentLogs");
|
||||
if ($recentLogs.length > 0) {
|
||||
$.ajax({
|
||||
url: "/FuelLog/RecentLogs",
|
||||
url: "/CreateLog/RecentLogs",
|
||||
success: function (data) {
|
||||
$recentLogs.append(data);
|
||||
}
|
||||
@@ -83,12 +83,69 @@ $(function () {
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
Ability to run the defered promises in sequence
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
var copy = function (a) {
|
||||
return Array.prototype.slice.call(a);
|
||||
};
|
||||
|
||||
/**
|
||||
Handle a sequence of methods, stopping on failure by default
|
||||
@param Array<Function> chain List of methods to execute. Non-deferred return values will be treated as successful deferreds.
|
||||
@param Boolean continueOnFailure Continue executing even if one of the returned deferreds fails.
|
||||
@returns Deferred
|
||||
*/
|
||||
$.sequence = function (chain, continueOnFailure) {
|
||||
var handleStep, handleResult,
|
||||
steps = copy(chain),
|
||||
def = new $.Deferred(),
|
||||
defs = [],
|
||||
results = [];
|
||||
handleStep = function () {
|
||||
if (!steps.length) {
|
||||
def.resolveWith(defs, [results]);
|
||||
return;
|
||||
}
|
||||
var step = steps.shift(),
|
||||
result = step; // used to be step();, but we're already dealing with promises
|
||||
handleResult(
|
||||
$.when(result).always(function () {
|
||||
defs.push(this);
|
||||
}).done(function () {
|
||||
results.push({ resolved: copy(arguments) });
|
||||
}).fail(function () {
|
||||
results.push({ rejected: copy(arguments) });
|
||||
})
|
||||
);
|
||||
};
|
||||
handleResult = continueOnFailure ?
|
||||
function (result) {
|
||||
result.always(function () {
|
||||
handleStep();
|
||||
});
|
||||
} :
|
||||
function (result) {
|
||||
result.done(handleStep)
|
||||
.fail(function () {
|
||||
def.rejectWith(defs, [results]);
|
||||
});
|
||||
};
|
||||
handleStep();
|
||||
return def.promise();
|
||||
};
|
||||
}(this.jQuery));
|
||||
|
||||
var matchCountFunc = function() {
|
||||
var $link = $(this);
|
||||
var url = $link.attr("matchcount");
|
||||
$link.append(' <span class="badge"><i class="fa fa-spinner fa-spin"></i></span>');
|
||||
return $.ajax({
|
||||
url: url,
|
||||
success: function(matchcount) {
|
||||
success: function (matchcount) {
|
||||
$('span', $link).remove();
|
||||
if (matchcount > 0) {
|
||||
$link.append(" <span class='badge badge-info'>" + matchcount + "</span>");
|
||||
} else {
|
||||
@@ -101,7 +158,7 @@ var matchCountFunc = function() {
|
||||
// add get match count for all the current items
|
||||
$(function () {
|
||||
var $requests = $("a[matchcount]").map(matchCountFunc);
|
||||
$.when.apply($, $requests);
|
||||
$.sequence($requests);
|
||||
});
|
||||
|
||||
$(function() {
|
||||
@@ -124,7 +181,7 @@ $(function() {
|
||||
var idNavActiveRegex = {
|
||||
'fuellog-nav': /\/fuellog/i,
|
||||
'log-nav': /\/log/i,
|
||||
'vehicle-nav': /\/vehicle/i,
|
||||
'vehicle-nav': /\/vehicle|\/servicereminder/i,
|
||||
'user-nav': /\/user/i,
|
||||
'config-nav': /\/City|\/Purpose/i
|
||||
};
|
||||
@@ -142,23 +199,33 @@ $(function() {
|
||||
|
||||
function addButtonIcons () {
|
||||
var textToIcon = {
|
||||
'Edit': 'edit',
|
||||
'Enter Log': 'plus',
|
||||
'Edit': 'edit',
|
||||
'Filter': 'filter',
|
||||
'Details' : 'zoom-in',
|
||||
'Details': 'info-circle',
|
||||
'Delete': 'trash',
|
||||
'Add': 'plus',
|
||||
'Export': 'download',
|
||||
'Import': 'upload',
|
||||
'Driver Mileage': 'user',
|
||||
'Vehicle Mileage': 'car',
|
||||
'Show Active': 'ok-circle',
|
||||
'Show Inactive': 'ban-circle',
|
||||
'Set Inactive' : 'ban-circle',
|
||||
'Reactivate' : 'ok-circle'
|
||||
'Show Active': 'check-circle',
|
||||
'Show Inactive': 'ban',
|
||||
'Set Inactive' : 'ban',
|
||||
'Reactivate': 'check-circle',
|
||||
'Config': 'cog',
|
||||
'Cities': 'map',
|
||||
'Purposes': 'arrow-right',
|
||||
'Vehicle Service': 'wrench',
|
||||
'Vehicle': 'car',
|
||||
'Reminder': 'clock-o',
|
||||
'Fuel Logs': 'tachometer',
|
||||
'Users': 'user',
|
||||
'Logs': 'road'
|
||||
};
|
||||
$.each(textToIcon, function(text, icon) {
|
||||
$("a:contains('" + text + "'):not(:has(i))")
|
||||
.prepend('<i class="icon-' + icon + '" /> ');
|
||||
.prepend('<i class="fa fa-'+ icon +'"></i> ');
|
||||
});
|
||||
|
||||
$(".navbar-inverse a[title='Manage']:not(:has(i))")
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Web.Mvc;
|
||||
using AutoMapper;
|
||||
using MileageTraker.Web.Attributes;
|
||||
using MileageTraker.Web.DAL;
|
||||
|
||||
namespace MileageTraker.Web.ViewModels.ServiceReminder
|
||||
{
|
||||
public class ServiceReminderViewModel
|
||||
public class ServiceReminderViewModel : IComparable<ServiceReminderViewModel>, IValidatableObject
|
||||
{
|
||||
[HiddenInput(DisplayValue = false)]
|
||||
public int? ServiceReminderId { get; set; }
|
||||
@@ -19,17 +22,28 @@ namespace MileageTraker.Web.ViewModels.ServiceReminder
|
||||
[InputSize("mini")]
|
||||
public string VehicleId { get; set; }
|
||||
|
||||
[HiddenInput(DisplayValue = false)]
|
||||
public int? CurrentOdometer { get; set; }
|
||||
|
||||
[InputSize("small")]
|
||||
public int TargetOdometer { get; set; }
|
||||
[Range(1, 500000, ErrorMessage = "Between 1 and 500k")]
|
||||
public int TargetOdometer { get; set; }
|
||||
|
||||
[StringLength(64)]
|
||||
public string Description { get; set; }
|
||||
|
||||
[HiddenInput(DisplayValue = false)]
|
||||
public bool IsServiceOverdue { get { return ServiceDueInMiles <= 0; } }
|
||||
|
||||
[HiddenInput(DisplayValue = false)]
|
||||
public int ServiceDueInMiles { get { return CurrentOdometer.HasValue ? TargetOdometer - CurrentOdometer.Value : int.MaxValue; } }
|
||||
|
||||
static ServiceReminderViewModel()
|
||||
{
|
||||
Mapper.CreateMap<ServiceReminderViewModel, Models.ServiceReminder>();
|
||||
Mapper.CreateMap<Models.ServiceReminder, ServiceReminderViewModel>()
|
||||
.ForMember(dest => dest.VehicleId, opt => opt.MapFrom(src => src.Vehicle.VehicleId));
|
||||
.ForMember(dest => dest.VehicleId, opt => opt.MapFrom(src => src.Vehicle.VehicleId))
|
||||
.ForMember(dest => dest.CurrentOdometer, opt => opt.MapFrom(src => src.Vehicle.CurrentOdometer));
|
||||
}
|
||||
|
||||
public ServiceReminderViewModel(Models.ServiceReminder serviceReminder)
|
||||
@@ -47,5 +61,32 @@ namespace MileageTraker.Web.ViewModels.ServiceReminder
|
||||
Mapper.Map(this, serviceReminder);
|
||||
return serviceReminder;
|
||||
}
|
||||
|
||||
public int CompareTo(ServiceReminderViewModel other)
|
||||
{
|
||||
return ServiceDueInMiles - other.ServiceDueInMiles;
|
||||
}
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
using (var dataService = new DataService())
|
||||
{
|
||||
var duplicateServiceReminder = dataService.FindDuplicateServiceReminder(VehicleId, TargetOdometer, Description);
|
||||
|
||||
if (duplicateServiceReminder != null)
|
||||
yield return new ValidationResult("Exact duplicate of this reminder already exists");
|
||||
|
||||
var vehicle = dataService.GetVehicle(VehicleId);
|
||||
|
||||
if (vehicle.InactiveDate.HasValue)
|
||||
yield return new ValidationResult("Vehicle is inactive, no service reminder permitted");
|
||||
|
||||
// no reminders for mileage less than the current odometer
|
||||
if (vehicle.CurrentOdometer.HasValue && TargetOdometer <= vehicle.CurrentOdometer)
|
||||
yield return new ValidationResult(
|
||||
string.Format("Target odometer {0} must be greater than current odometer {1}",
|
||||
TargetOdometer, vehicle.CurrentOdometer.Value), new[]{"TargetOdometer"});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,10 @@ namespace MileageTraker.Web.ViewModels.Vehicle
|
||||
{
|
||||
public class VehicleResultsViewModel
|
||||
{
|
||||
public IEnumerable<Models.Vehicle> Vehicles { get; set; }
|
||||
public IEnumerable<VehicleViewModel> Vehicles { get; set; }
|
||||
public bool Inactive { get; set; }
|
||||
|
||||
public VehicleResultsViewModel(IEnumerable<Models.Vehicle> vehicles, bool activeInactive)
|
||||
public VehicleResultsViewModel(IEnumerable<VehicleViewModel> vehicles, bool activeInactive)
|
||||
{
|
||||
Vehicles = vehicles;
|
||||
Inactive = activeInactive;
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using AutoMapper;
|
||||
using MileageTraker.Web.Attributes;
|
||||
|
||||
namespace MileageTraker.Web.ViewModels.Vehicle
|
||||
{
|
||||
public class VehicleViewModel
|
||||
{
|
||||
[Required]
|
||||
[InputSize("mini")]
|
||||
public int Key { get; set; }
|
||||
|
||||
[Key]
|
||||
[Required]
|
||||
[StringLength(6, MinimumLength = 4, ErrorMessage = "Must be at least a 4 digit number")]
|
||||
[Display(Name = "EHTRA ID")]
|
||||
[RegularExpression(@"\d+", ErrorMessage = "Vehicle ID must be all numbers")]
|
||||
[InputSize("mini")]
|
||||
public string VehicleId { get; set; }
|
||||
|
||||
[Required]
|
||||
[RegularExpression(@"\d{4}", ErrorMessage = "Must be 4 numbers")]
|
||||
[InputSize("mini")]
|
||||
public string ModelYear { get; set; }
|
||||
|
||||
[Required]
|
||||
[InputSize("medium")]
|
||||
public string Make { get; set; }
|
||||
|
||||
[Display(Name = "Model")]
|
||||
[Required]
|
||||
[InputSize("medium")]
|
||||
public string CarModel { get; set; }
|
||||
|
||||
[InputSize("small")]
|
||||
public string Color { get; set; }
|
||||
|
||||
[Required]
|
||||
[RegularExpression(@"Car|Truck|SUV|Van", ErrorMessage = "Must be Car, Truck, SUV, or Van")]
|
||||
[FormatHint("Car, Truck, SUV or Van")]
|
||||
[InputSize("mini")]
|
||||
public string Type { get; set; }
|
||||
|
||||
[Required]
|
||||
[Display(Name = "VIN")]
|
||||
[RegularExpression(@"[0-9A-HJ-NPR-Z]{17}", ErrorMessage = "VIN must be 17-characters, not including letters I, O or Q")]
|
||||
[InputSize("large")]
|
||||
public string Vin { get; set; }
|
||||
|
||||
[Required]
|
||||
[InputSize("small")]
|
||||
[Currency]
|
||||
public decimal Price { get; set; }
|
||||
|
||||
[Required]
|
||||
[RegularExpression(@"\d{1,2}/\d{2}", ErrorMessage = "PurDate must be in mm/yy format")]
|
||||
[InputSize("small")]
|
||||
[FormatHint("mm/yy")]
|
||||
public string PurDate { get; set; }
|
||||
|
||||
[DataType(DataType.DateTime)]
|
||||
[DisplayFormat(NullDisplayText = "Currently Active", DataFormatString = @"{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
|
||||
[InputSize("small")]
|
||||
[FormatHint("mm/dd/yyyy")]
|
||||
public DateTime? InactiveDate { get; set; }
|
||||
|
||||
[Required]
|
||||
[Display(Name = "Tag#")]
|
||||
[InputSize("small")]
|
||||
public string TagNumber { get; set; }
|
||||
|
||||
[Required]
|
||||
[InputSize("medium")]
|
||||
public string Prog { get; set; }
|
||||
|
||||
[RegularExpression(@"Unassigned|[A-Za-z().]+(\s+[A-Za-z().]+)+", ErrorMessage = "Please enter the full name")]
|
||||
[DisplayFormat(NullDisplayText = "Unassigned")]
|
||||
[FormatHint("Blank for Unassigned")]
|
||||
public string Assigned { get; set; }
|
||||
|
||||
[InputSize("medium")]
|
||||
public string Notes { get; set; }
|
||||
|
||||
[Display(Name = "Current Odometer", ShortName= "ODO")]
|
||||
[DisplayFormat(NullDisplayText = "?")]
|
||||
[InputSize("small")]
|
||||
public int? CurrentOdometer { get; set; }
|
||||
|
||||
[HiddenInput(DisplayValue = true)]
|
||||
public int? NextServiceOdometer { get; set; }
|
||||
|
||||
[HiddenInput(DisplayValue = false)]
|
||||
public bool IsNextServiceOverdue
|
||||
{
|
||||
get { return NextServiceDueInMiles <= 0; }
|
||||
}
|
||||
|
||||
[HiddenInput(DisplayValue = false)]
|
||||
public int NextServiceDueInMiles
|
||||
{
|
||||
get
|
||||
{
|
||||
return CurrentOdometer.HasValue && NextServiceOdometer.HasValue
|
||||
? NextServiceOdometer.Value - CurrentOdometer.Value
|
||||
: int.MaxValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static VehicleViewModel()
|
||||
{
|
||||
Mapper.CreateMap<VehicleViewModel, Models.Vehicle>();
|
||||
Mapper.CreateMap<Models.Vehicle, VehicleViewModel>()
|
||||
.ForMember(dest => dest.NextServiceOdometer,
|
||||
opt => opt.ResolveUsing(v =>
|
||||
v.ServiceReminders
|
||||
.OrderBy(s => s.TargetOdometer)
|
||||
.Select(s => (int?) s.TargetOdometer)
|
||||
.FirstOrDefault()
|
||||
));
|
||||
}
|
||||
|
||||
public VehicleViewModel(Models.Vehicle vehicle)
|
||||
{
|
||||
Mapper.Map(vehicle, this);
|
||||
}
|
||||
|
||||
public VehicleViewModel()
|
||||
{
|
||||
}
|
||||
|
||||
public Models.Vehicle GetVehicle()
|
||||
{
|
||||
var vehicle = new Models.Vehicle();
|
||||
Mapper.Map(this, vehicle);
|
||||
return vehicle;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Web.Mvc;
|
||||
using AutoMapper;
|
||||
using MileageTraker.Web.Attributes;
|
||||
using MileageTraker.Web.DAL;
|
||||
using MileageTraker.Web.ViewModels.ServiceReminder;
|
||||
|
||||
namespace MileageTraker.Web.ViewModels.VehicleService
|
||||
{
|
||||
public class UpdateServiceRemindersViewModel : IValidatableObject
|
||||
{
|
||||
[Display(Name = "Existing Reminders")]
|
||||
public CheckBoxViewModel DeleteServiceReminders { get; set; }
|
||||
|
||||
[HiddenInput(DisplayValue = false)]
|
||||
public int? ServiceReminderId { get; set; }
|
||||
|
||||
[HiddenInput(DisplayValue = false)]
|
||||
[Required]
|
||||
[Remote("Exists", "Vehicle", ErrorMessage = "ID not found")]
|
||||
[StringLength(6, MinimumLength = 4, ErrorMessage = "Must be at least a 4 digit number")]
|
||||
[Display(Name = "Vehicle ID")]
|
||||
[RegularExpression(@"\d+", ErrorMessage = "Vehicle ID must be all numbers")]
|
||||
[InputSize("mini")]
|
||||
public string VehicleId { get; set; }
|
||||
|
||||
[HiddenInput(DisplayValue = false)]
|
||||
public int? CurrentOdometer { get; set; }
|
||||
|
||||
[InputSize("small")]
|
||||
[Range(1, 500000, ErrorMessage = "Between 1 and 500k")]
|
||||
public int? TargetOdometer { get; set; }
|
||||
|
||||
[StringLength(64)]
|
||||
public string Description { get; set; }
|
||||
|
||||
static UpdateServiceRemindersViewModel()
|
||||
{
|
||||
Mapper.CreateMap<UpdateServiceRemindersViewModel, Models.ServiceReminder>();
|
||||
}
|
||||
|
||||
public Models.ServiceReminder GetServiceReminder()
|
||||
{
|
||||
if (!TargetOdometer.HasValue || TargetOdometer.Value == 0)
|
||||
return null;
|
||||
var serviceReminder = new Models.ServiceReminder();
|
||||
Mapper.Map(this, serviceReminder);
|
||||
return serviceReminder;
|
||||
}
|
||||
|
||||
public static string FormatServiceReminder(Models.ServiceReminder serviceReminder)
|
||||
{
|
||||
var s = "Target ODO: " + serviceReminder.TargetOdometer;
|
||||
if (!string.IsNullOrEmpty(serviceReminder.Description))
|
||||
s += " Description: " + serviceReminder.Description;
|
||||
return s;
|
||||
}
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if (!TargetOdometer.HasValue) yield break;
|
||||
|
||||
using (var dataService = new DataService())
|
||||
{
|
||||
var duplicateServiceReminder = dataService.FindDuplicateServiceReminder(VehicleId, TargetOdometer.Value, Description);
|
||||
|
||||
if (duplicateServiceReminder != null)
|
||||
yield return new ValidationResult("Exact duplicate of this reminder already exists");
|
||||
|
||||
var vehicle = dataService.GetVehicle(VehicleId);
|
||||
|
||||
if (vehicle.InactiveDate.HasValue)
|
||||
yield return new ValidationResult("Vehicle is inactive, no service reminder permitted");
|
||||
|
||||
// no reminders for mileage less than the current odometer
|
||||
if (vehicle.CurrentOdometer.HasValue && TargetOdometer <= vehicle.CurrentOdometer)
|
||||
yield return new ValidationResult(
|
||||
string.Format("Target odometer {0} must be greater than current odometer {1}",
|
||||
TargetOdometer, vehicle.CurrentOdometer.Value), new[] {"TargetOdometer"});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,13 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using MileageTraker.Web.ViewModels.ServiceReminder;
|
||||
|
||||
namespace MileageTraker.Web.ViewModels.VehicleService
|
||||
{
|
||||
public class VehicleServiceResultsViewModel
|
||||
{
|
||||
public IEnumerable<VehicleServiceViewModel> ServiceItems { get; set; }
|
||||
public IList<ServiceReminderViewModel> UpcomingServiceReminders { get; set; }
|
||||
public Dictionary<string, List<string>> AvailableYearMonths { get; set; }
|
||||
public IEnumerable<string> SelectedYearMonths
|
||||
{
|
||||
@@ -24,10 +26,12 @@ namespace MileageTraker.Web.ViewModels.VehicleService
|
||||
|
||||
public VehicleServiceResultsViewModel(
|
||||
IEnumerable<VehicleServiceViewModel> serviceItems,
|
||||
IList<ServiceReminderViewModel> upcomingServiceReminders,
|
||||
VehicleServiceQueryViewModel query,
|
||||
Dictionary<string, List<string>> availableYearMonths)
|
||||
{
|
||||
ServiceItems = serviceItems;
|
||||
UpcomingServiceReminders = upcomingServiceReminders;
|
||||
AvailableYearMonths = availableYearMonths;
|
||||
Year = query.Year.HasValue ? query.Year.Value.ToString(CultureInfo.InvariantCulture) : string.Empty;
|
||||
Month = query.Month.HasValue ? query.Month.Value.ToString(CultureInfo.InvariantCulture) : string.Empty;
|
||||
|
||||
@@ -21,8 +21,10 @@ namespace MileageTraker.Web.ViewModels.VehicleService
|
||||
|
||||
[DataType(DataType.DateTime)]
|
||||
[DisplayFormatAttribute(ApplyFormatInEditMode = true, DataFormatString = "{0:d}")]
|
||||
[DenyFutureDate(ErrorMessage = "Future date")]
|
||||
[FormatHint("mm/dd/yyyy")]
|
||||
[InputSize("small")]
|
||||
[Required]
|
||||
public DateTime? InvoiceDate { get; set; }
|
||||
|
||||
[Required]
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
@model MileageTraker.Web.ViewModels.ServiceReminder.ServiceReminderViewModel
|
||||
|
||||
@{
|
||||
ViewBag.Title = "Create Vehicle Service Reminder";
|
||||
ViewBag.Title = "Create Service Reminder";
|
||||
}
|
||||
|
||||
@Html.Partial("_StatusMessage")
|
||||
|
||||
<h2 class="center-content"><i class="fa fa-clock-o"></i> @ViewBag.Title</h2>
|
||||
|
||||
@using (Html.BeginForm("Create", "ServiceReminder", FormMethod.Post, new { @class = "form-horizontal well center-content" }))
|
||||
@@ -11,6 +13,7 @@
|
||||
@Html.Partial("_ValidationSummary")
|
||||
<fieldset>
|
||||
<legend></legend>
|
||||
@Html.DisplayFor(m => m.CurrentOdometer)
|
||||
@Html.EditorForModel()
|
||||
<div class="form-actions">
|
||||
<input type="submit" value="Create" class="btn btn-primary" />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@model MileageTraker.Web.ViewModels.ServiceReminder.ServiceReminderViewModel
|
||||
|
||||
@{
|
||||
ViewBag.Title = "Vehicle Service Reminder Details" ;
|
||||
ViewBag.Title = "Service Reminder Details" ;
|
||||
}
|
||||
|
||||
@Html.Partial("_StatusMessage")
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
@model MileageTraker.Web.ViewModels.ServiceReminder.ServiceReminderViewModel
|
||||
|
||||
@{
|
||||
ViewBag.Title = "Edit Vehicle Service Reminder";
|
||||
ViewBag.Title = "Edit Service Reminder";
|
||||
}
|
||||
|
||||
@Html.Partial("_StatusMessage")
|
||||
|
||||
<h2 class="center-content"><i class="fa fa-clock-o"></i> @ViewBag.Title</h2>
|
||||
|
||||
@using (Html.BeginForm("Edit", "ServiceREminder", FormMethod.Post, new { @class = "form-horizontal well center-content" }))
|
||||
@using (Html.BeginForm("Edit", "ServiceReminder", FormMethod.Post, new { @class = "form-horizontal well center-content" }))
|
||||
{
|
||||
@Html.Partial("_ValidationSummary")
|
||||
<fieldset>
|
||||
<legend></legend>
|
||||
@Html.EditorForModel()
|
||||
@Html.DisplayFor(m => m.CurrentOdometer)
|
||||
@Html.EditorForModel()
|
||||
<div class="form-actions">
|
||||
<input type="submit" value="Save" class="btn btn-primary" />
|
||||
</div>
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
@model MileageTraker.Web.ViewModels.ServiceReminder.ServiceReminderResultsViewModel
|
||||
|
||||
@{
|
||||
ViewBag.Title = "Vehicle Service Reminders for Vehicle Id " + Model.VehicleId;
|
||||
ViewBag.Title = "Service Reminders";
|
||||
}
|
||||
|
||||
@Html.Partial("_StatusMessage")
|
||||
|
||||
<h2 id="vehicle-title"><i class="fa fa-clock-o"></i> @ViewBag.Title</h2>
|
||||
<h2 class="center-content"><i class="fa fa-clock-o"></i> @ViewBag.Title</h2>
|
||||
<h4 class="center-content">for Vehicle @Model.VehicleId</h4>
|
||||
|
||||
<div class="center-content">
|
||||
@foreach (var item in Model.ServiceReminderItems)
|
||||
@@ -16,6 +17,7 @@
|
||||
</div>
|
||||
|
||||
<div class="btn-toolbar center-content well">
|
||||
@Html.ActionLink("Add Service Reminder", "Create", new { vehicleId = Model.VehicleId }, new{@class="btn"})
|
||||
@Html.ActionLink("Add Reminder", "Create", new { vehicleId = Model.VehicleId }, new{@class="btn"})
|
||||
@Html.ActionLink("Add Service", "Create", "VehicleService", new { vehicleId = Model.VehicleId }, new { @class = "btn" })
|
||||
@Html.ActionLink("Vehicle Details", "Details", "Vehicle", new { id = Model.VehicleId }, new{@class="btn"})
|
||||
</div>
|
||||
@@ -1,7 +1,7 @@
|
||||
@model MileageTraker.Web.ViewModels.ServiceReminder.ServiceReminderViewModel
|
||||
|
||||
<div class="well">
|
||||
<h3>Service Reminder</h3>
|
||||
<h4 class="center-content"><i class="fa fa-clock-o"></i> Service Reminder</h4>
|
||||
@Html.DisplayForModel()
|
||||
<div class='btn-toolbar'>
|
||||
@Html.ActionLink("Edit", "Edit", new { id = Model.ServiceReminderId }, new { @class = "btn" })
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@if (Session["LogPage"] != null) {
|
||||
<ul class="no-print breadcrumb">
|
||||
<li><a href="@Session["LogPage"]">← Back To Logs</a></li>
|
||||
<li><a href="@Session["LogPage"]"><i class="fa fa-arrow-circle-left"></i> Back To Logs</a></li>
|
||||
</ul>
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
<ul class="no-print breadcrumb">
|
||||
<li>
|
||||
<a href="@Url.Action("Index", "User")">← Back to Users</a>
|
||||
<a href="@Url.Action("Index", "User")"><i class="fa fa-arrow-circle-left"></i> Back to Users</a>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -1,5 +1,5 @@
|
||||
<ul class="no-print breadcrumb">
|
||||
<li>
|
||||
<a href="@Url.Action("Index", "Vehicle")">← Back to Vehicles</a>
|
||||
<a href="@Url.Action("Index", "Vehicle")"><i class="fa fa-arrow-circle-left"></i> Back to Vehicles</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -34,10 +34,10 @@
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li>
|
||||
@Html.ActionLink("View Service Reminders", "Index", "ServiceReminder", new { VehicleId = Model.VehicleId }, null)
|
||||
@Html.ActionLink("View Reminders", "Index", "ServiceReminder", new { VehicleId = Model.VehicleId }, null)
|
||||
</li>
|
||||
<li>
|
||||
@Html.ActionLink("Add Completed Service", "Create", "VehicleService", new { VehicleId = Model.VehicleId }, null)
|
||||
@Html.ActionLink("Add Service", "Create", "VehicleService", new { VehicleId = Model.VehicleId }, null)
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<h2 id="vehicle-title"><i class="fa fa-car"></i> @ViewBag.Title</h2>
|
||||
|
||||
<div class="btn-toolbar">
|
||||
@Html.ActionLink("Add Another Vehicle", "Create", null, new{@class="btn"})
|
||||
@Html.ActionLink("Add Vehicle", "Create", 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>
|
||||
@@ -26,13 +26,7 @@
|
||||
Ethra Id
|
||||
</th>
|
||||
<th>
|
||||
Model Yr
|
||||
</th>
|
||||
<th>
|
||||
Make
|
||||
</th>
|
||||
<th>
|
||||
Model
|
||||
Year, Make, Model
|
||||
</th>
|
||||
<th>
|
||||
Type
|
||||
@@ -46,9 +40,12 @@
|
||||
<th>
|
||||
Assigned
|
||||
</th>
|
||||
<th>
|
||||
ODO
|
||||
</th>
|
||||
<th>
|
||||
ODO
|
||||
</th>
|
||||
<th>
|
||||
Next Service
|
||||
</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
|
||||
@@ -61,13 +58,7 @@
|
||||
@Html.DisplayTextFor(m => item.VehicleId)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayTextFor(m => item.ModelYear)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayTextFor(m => item.Make)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayTextFor(m => item.CarModel)
|
||||
@Html.DisplayTextFor(m => item.ModelYear) @Html.DisplayTextFor(m => item.Make) @Html.DisplayTextFor(m => item.CarModel)
|
||||
</td>
|
||||
<td>
|
||||
<span class="label @item.Color">
|
||||
@@ -85,13 +76,20 @@
|
||||
<small class="muted"><em>@Html.DisplayTextFor(m => item.Notes)</em></small>
|
||||
}
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayTextFor(m => item.CurrentOdometer)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayTextFor(m => item.CurrentOdometer)
|
||||
</td>
|
||||
<td>
|
||||
@Html.DisplayTextFor(m => item.NextServiceOdometer)
|
||||
@if (item.IsNextServiceOverdue)
|
||||
{
|
||||
<span class="badge badge-warning" title="overdue @(-item.NextServiceDueInMiles) miles">!</span>
|
||||
}
|
||||
@Html.ActionLink("Reminder", "Index", "ServiceReminder", new { vehicleId = item.VehicleId }, new { @class = "btn btn-mini pull-right" })
|
||||
</td>
|
||||
<td>
|
||||
<div class='btn-group'>
|
||||
@Html.ActionLink("Details", "Details", new { id = item.VehicleId }, new { @class = "btn btn-mini" })
|
||||
@Html.ActionLink("Svc Reminder", "Index", "ServiceReminder", new { vehicleId = item.VehicleId }, new { @class = "btn btn-mini" })
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -26,22 +26,50 @@
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="pull-right" style="width:400px">
|
||||
<h4>Upcoming Services</h4>
|
||||
<table class="table table-striped table-bordered table-hover table-condensed">
|
||||
<tr>
|
||||
<th>Vehicle ID</th>
|
||||
<th>ODO</th>
|
||||
<th>Next Service</th>
|
||||
<th>Description</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
@foreach (var sr in Model.UpcomingServiceReminders)
|
||||
{
|
||||
<tr>
|
||||
<td>@Html.DisplayTextFor(m => sr.VehicleId)</td>
|
||||
<td>@Html.DisplayTextFor(m => sr.CurrentOdometer)</td>
|
||||
<td>@Html.DisplayTextFor(m => sr.TargetOdometer)
|
||||
@if (sr.IsServiceOverdue)
|
||||
{
|
||||
<span class="badge badge-warning" title="overdue @(-sr.ServiceDueInMiles) miles">!</span>
|
||||
}
|
||||
</td>
|
||||
<td>@Html.DisplayTextFor(m => sr.Description)</td>
|
||||
<td>@Html.ActionLink("Add Service", "Create", "VehicleService", new { vehicleId = sr.VehicleId }, new { @class = "btn btn-mini" })</td>
|
||||
</tr>
|
||||
}
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h2 id="vehicle-title"><i class="fa fa-wrench"></i> @ViewBag.Title</h2>
|
||||
|
||||
<div class="btn-toolbar pull-left">
|
||||
@Html.ActionLink("Add Service", "Create", null, new{@class="btn"})
|
||||
@Html.ActionLink("Export", "Export", queryParams, new{@class="btn"})
|
||||
@Html.ActionLink("Add Service", "Create", null, new { @class = "btn" })
|
||||
@Html.ActionLink("Export", "Export", queryParams, new { @class = "btn" })
|
||||
</div>
|
||||
|
||||
@grid.GetHtml(columns:
|
||||
grid.Columns(
|
||||
grid.Column("InvoiceDate", "Invoice Date", item => item.InvoiceDate.ToString("d")),
|
||||
grid.Column("VehicleID", "Vehicle Id"),
|
||||
grid.Column("ServiceCenterName", "Service Center Name"),
|
||||
grid.Column("Price", "Price"),
|
||||
grid.Column("Description", "Description"),
|
||||
grid.Column(format:
|
||||
@<div class='btn-group'>
|
||||
grid.Columns(
|
||||
grid.Column("InvoiceDate", "Invoice Date", item => item.InvoiceDate.ToString("d")),
|
||||
grid.Column("VehicleID", "Vehicle Id"),
|
||||
grid.Column("ServiceCenterName", "Service Center Name"),
|
||||
grid.Column("Price", "Price"),
|
||||
grid.Column("Description", "Description"),
|
||||
grid.Column(format:
|
||||
@<div class='btn-group'>
|
||||
@Html.ActionLink("Details", "Details", new { id = item.VehicleServiceId }, new { @class = "btn btn-mini" })
|
||||
</div>)
|
||||
),
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
@model MileageTraker.Web.ViewModels.VehicleService.UpdateServiceRemindersViewModel
|
||||
|
||||
@{
|
||||
ViewBag.Title = "Update Service Reminders";
|
||||
}
|
||||
|
||||
@Html.Partial("_StatusMessage")
|
||||
|
||||
<h2 class="center-content"><i class="fa fa-clock-o"></i> @ViewBag.Title</h2>
|
||||
<h5 class="center-content">Add the next service for this vehicle and remove existing reminders.</h5>
|
||||
|
||||
@using (Html.BeginForm("UpdateServiceReminders", "VehicleService", FormMethod.Post, new { @class = "form-horizontal well center-content" }))
|
||||
{
|
||||
@Html.Partial("_ValidationSummary")
|
||||
@Html.HiddenFor(m => m.VehicleId)
|
||||
if (Model.DeleteServiceReminders.Available.Count > 0)
|
||||
{
|
||||
<fieldset>
|
||||
<legend>Delete Reminders for this Vehicle?</legend>
|
||||
@Html.EditorFor(m => m.DeleteServiceReminders)
|
||||
</fieldset>
|
||||
}
|
||||
<fieldset>
|
||||
<legend>Add a new Reminder?</legend>
|
||||
@Html.DisplayFor(m => m.CurrentOdometer)
|
||||
@Html.EditorFor(m => m.TargetOdometer)
|
||||
@Html.EditorFor(m => m.Description)
|
||||
</fieldset>
|
||||
<div class="form-actions">
|
||||
<input type="submit" value="Update" class="btn btn-primary" />
|
||||
</div>
|
||||
}
|
||||
@@ -146,6 +146,7 @@
|
||||
<Compile Include="Controllers\AccountController.cs" />
|
||||
<Compile Include="Controllers\CityController.cs" />
|
||||
<Compile Include="Controllers\ControllerBase.cs" />
|
||||
<Compile Include="ViewModels\VehicleService\UpdateServiceRemindersViewModel.cs" />
|
||||
<Compile Include="Controllers\FuelLogController.cs" />
|
||||
<Compile Include="Controllers\ServiceReminderController.cs" />
|
||||
<Compile Include="Controllers\VehicleServiceController.cs" />
|
||||
@@ -268,6 +269,7 @@
|
||||
<Compile Include="ViewModels\VehicleService\VehicleServiceQueryViewModel.cs" />
|
||||
<Compile Include="ViewModels\VehicleService\VehicleServiceResultsViewModel.cs" />
|
||||
<Compile Include="ViewModels\VehicleService\VehicleServiceViewModel.cs" />
|
||||
<Compile Include="ViewModels\Vehicle\VehicleViewModel.cs" />
|
||||
<Compile Include="ViewModels\Vehicle\VehicleResultsViewModel.cs" />
|
||||
<Compile Include="ViewModels\SelectListViewModel.cs" />
|
||||
<Compile Include="ViewModels\User\ExportUserViewModel.cs" />
|
||||
@@ -350,6 +352,7 @@
|
||||
<Content Include="Views\ServiceReminder\Edit.cshtml" />
|
||||
<Content Include="Views\ServiceReminder\Index.cshtml" />
|
||||
<Content Include="Views\ServiceReminder\ServiceReminderViewModel.cshtml" />
|
||||
<Content Include="Views\VehicleService\UpdateServiceReminders.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Content\Account.Login.css" />
|
||||
|
||||
Reference in New Issue
Block a user