Service reminder implemented.
This commit is contained in:
@@ -21,22 +21,6 @@ namespace MileageTraker.Web.Controllers
|
|||||||
return View(viewModel);
|
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)
|
public ActionResult Delete(int id)
|
||||||
{
|
{
|
||||||
var serviceReminder = DataService.GetServiceReminder(id);
|
var serviceReminder = DataService.GetServiceReminder(id);
|
||||||
@@ -45,6 +29,24 @@ namespace MileageTraker.Web.Controllers
|
|||||||
return RedirectToAction("Index", new { vehicleId });
|
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]
|
[HttpPost]
|
||||||
[ActionLog]
|
[ActionLog]
|
||||||
public ActionResult Create(ServiceReminderViewModel viewModel)
|
public ActionResult Create(ServiceReminderViewModel viewModel)
|
||||||
@@ -54,6 +56,7 @@ namespace MileageTraker.Web.Controllers
|
|||||||
var serviceReminder = viewModel.GetServiceReminder();
|
var serviceReminder = viewModel.GetServiceReminder();
|
||||||
|
|
||||||
serviceReminder.Vehicle = DataService.GetVehicle(viewModel.VehicleId);
|
serviceReminder.Vehicle = DataService.GetVehicle(viewModel.VehicleId);
|
||||||
|
|
||||||
DataService.AddServiceReminder(serviceReminder);
|
DataService.AddServiceReminder(serviceReminder);
|
||||||
|
|
||||||
SetStatusMessage(
|
SetStatusMessage(
|
||||||
@@ -63,5 +66,33 @@ namespace MileageTraker.Web.Controllers
|
|||||||
|
|
||||||
return View(viewModel);
|
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)
|
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);
|
var viewModel = new VehicleResultsViewModel(vehicles, inactive);
|
||||||
return View(viewModel);
|
return View(viewModel);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
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;
|
||||||
|
using MileageTraker.Web.Models;
|
||||||
using MileageTraker.Web.Utility;
|
using MileageTraker.Web.Utility;
|
||||||
|
using MileageTraker.Web.ViewModels;
|
||||||
|
using MileageTraker.Web.ViewModels.ServiceReminder;
|
||||||
using MileageTraker.Web.ViewModels.VehicleService;
|
using MileageTraker.Web.ViewModels.VehicleService;
|
||||||
|
|
||||||
namespace MileageTraker.Web.Controllers
|
namespace MileageTraker.Web.Controllers
|
||||||
@@ -23,10 +26,16 @@ namespace MileageTraker.Web.Controllers
|
|||||||
|
|
||||||
var vehicleServices = DataService.FilterVehicleServices(DataService.GetVehicleServices(), query).ToList();
|
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(
|
var viewModel = new VehicleServiceResultsViewModel(
|
||||||
vehicleServices.Select(s => new VehicleServiceViewModel(s)),
|
vehicleServices.Select(s => new VehicleServiceViewModel(s)),
|
||||||
query,
|
upcomingServiceReminders,
|
||||||
CustomExtensions.YearMonthList(validVehicleServiceYearMonths));
|
query,
|
||||||
|
CustomExtensions.YearMonthList(validVehicleServiceYearMonths));
|
||||||
|
|
||||||
return View(viewModel);
|
return View(viewModel);
|
||||||
}
|
}
|
||||||
@@ -78,18 +87,104 @@ namespace MileageTraker.Web.Controllers
|
|||||||
{
|
{
|
||||||
var vehicleService = viewModel.GetVehicleService();
|
var vehicleService = viewModel.GetVehicleService();
|
||||||
|
|
||||||
|
|
||||||
vehicleService.Vehicle = DataService.GetVehicle(viewModel.VehicleId);
|
vehicleService.Vehicle = DataService.GetVehicle(viewModel.VehicleId);
|
||||||
DataService.AddVehicleService(vehicleService);
|
DataService.AddVehicleService(vehicleService);
|
||||||
|
|
||||||
SetStatusMessage(
|
SetStatusMessage(
|
||||||
string.Format("Vehicle Service for vehicle {0} created", viewModel.VehicleId), StatusType.Success);
|
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 RedirectToAction("Index");
|
||||||
}
|
}
|
||||||
|
|
||||||
return View(viewModel);
|
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)
|
public ActionResult Edit(int id)
|
||||||
{
|
{
|
||||||
var vehicleService = DataService.GetVehicleService(id);
|
var vehicleService = DataService.GetVehicleService(id);
|
||||||
|
|||||||
+23
-1
@@ -407,7 +407,7 @@ namespace MileageTraker.Web.DAL
|
|||||||
_db.SaveChanges();
|
_db.SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Vehicle> GetVehicles()
|
public IQueryable<Vehicle> GetVehicles()
|
||||||
{
|
{
|
||||||
var vehicles = _db.Vehicles;
|
var vehicles = _db.Vehicles;
|
||||||
return vehicles;
|
return vehicles;
|
||||||
@@ -901,6 +901,17 @@ namespace MileageTraker.Web.DAL
|
|||||||
return _db.ServiceReminders.Find(id);
|
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)
|
public void DeleteServiceReminder(int id)
|
||||||
{
|
{
|
||||||
var serviceReminder = _db.ServiceReminders.Find(id);
|
var serviceReminder = _db.ServiceReminders.Find(id);
|
||||||
@@ -909,6 +920,17 @@ namespace MileageTraker.Web.DAL
|
|||||||
_db.SaveChanges();
|
_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
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -12,7 +12,8 @@ namespace MileageTraker.Web.Models
|
|||||||
public virtual Vehicle Vehicle { get; set; }
|
public virtual Vehicle Vehicle { get; set; }
|
||||||
|
|
||||||
[InputSize("small")]
|
[InputSize("small")]
|
||||||
public int TargetOdometer { get; set; }
|
[Range(1, 500000, ErrorMessage = "Between 1 and 500k")]
|
||||||
|
public int TargetOdometer { get; set; }
|
||||||
|
|
||||||
[StringLength(64)]
|
[StringLength(64)]
|
||||||
public string Description { get; set; }
|
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').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>');
|
$('#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();
|
submitNext();
|
||||||
var unmatchedCount = 0;
|
var unmatchedCount = 0;
|
||||||
var errorCount = 0;
|
var errorCount = 0;
|
||||||
@@ -41,10 +43,11 @@
|
|||||||
}
|
}
|
||||||
$('.match-message', $row).text(result.Message);
|
$('.match-message', $row).text(result.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.Action != undefined && result.Action != null) {
|
if (result.Action != undefined && result.Action != null) {
|
||||||
$('.match-status', $row).append(" " + result.Action);
|
$('.match-status', $row).append(" " + result.Action);
|
||||||
var $action = $("a[matchcount]", $row);
|
$("a", $row).addClass('pull-right');
|
||||||
matchCountFunc.apply($action);
|
matchCountFunc.apply($("a[matchcount]", $row));
|
||||||
}
|
}
|
||||||
|
|
||||||
submitNext();
|
submitNext();
|
||||||
|
|||||||
+78
-11
@@ -75,7 +75,7 @@ $(function () {
|
|||||||
var $recentLogs = $("#RecentLogs");
|
var $recentLogs = $("#RecentLogs");
|
||||||
if ($recentLogs.length > 0) {
|
if ($recentLogs.length > 0) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: "/FuelLog/RecentLogs",
|
url: "/CreateLog/RecentLogs",
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
$recentLogs.append(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 matchCountFunc = function() {
|
||||||
var $link = $(this);
|
var $link = $(this);
|
||||||
var url = $link.attr("matchcount");
|
var url = $link.attr("matchcount");
|
||||||
|
$link.append(' <span class="badge"><i class="fa fa-spinner fa-spin"></i></span>');
|
||||||
return $.ajax({
|
return $.ajax({
|
||||||
url: url,
|
url: url,
|
||||||
success: function(matchcount) {
|
success: function (matchcount) {
|
||||||
|
$('span', $link).remove();
|
||||||
if (matchcount > 0) {
|
if (matchcount > 0) {
|
||||||
$link.append(" <span class='badge badge-info'>" + matchcount + "</span>");
|
$link.append(" <span class='badge badge-info'>" + matchcount + "</span>");
|
||||||
} else {
|
} else {
|
||||||
@@ -101,7 +158,7 @@ var matchCountFunc = function() {
|
|||||||
// add get match count for all the current items
|
// add get match count for all the current items
|
||||||
$(function () {
|
$(function () {
|
||||||
var $requests = $("a[matchcount]").map(matchCountFunc);
|
var $requests = $("a[matchcount]").map(matchCountFunc);
|
||||||
$.when.apply($, $requests);
|
$.sequence($requests);
|
||||||
});
|
});
|
||||||
|
|
||||||
$(function() {
|
$(function() {
|
||||||
@@ -124,7 +181,7 @@ $(function() {
|
|||||||
var idNavActiveRegex = {
|
var idNavActiveRegex = {
|
||||||
'fuellog-nav': /\/fuellog/i,
|
'fuellog-nav': /\/fuellog/i,
|
||||||
'log-nav': /\/log/i,
|
'log-nav': /\/log/i,
|
||||||
'vehicle-nav': /\/vehicle/i,
|
'vehicle-nav': /\/vehicle|\/servicereminder/i,
|
||||||
'user-nav': /\/user/i,
|
'user-nav': /\/user/i,
|
||||||
'config-nav': /\/City|\/Purpose/i
|
'config-nav': /\/City|\/Purpose/i
|
||||||
};
|
};
|
||||||
@@ -142,23 +199,33 @@ $(function() {
|
|||||||
|
|
||||||
function addButtonIcons () {
|
function addButtonIcons () {
|
||||||
var textToIcon = {
|
var textToIcon = {
|
||||||
'Edit': 'edit',
|
'Enter Log': 'plus',
|
||||||
|
'Edit': 'edit',
|
||||||
'Filter': 'filter',
|
'Filter': 'filter',
|
||||||
'Details' : 'zoom-in',
|
'Details': 'info-circle',
|
||||||
'Delete': 'trash',
|
'Delete': 'trash',
|
||||||
'Add': 'plus',
|
'Add': 'plus',
|
||||||
'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 Active': 'check-circle',
|
||||||
'Show Inactive': 'ban-circle',
|
'Show Inactive': 'ban',
|
||||||
'Set Inactive' : 'ban-circle',
|
'Set Inactive' : 'ban',
|
||||||
'Reactivate' : 'ok-circle'
|
'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) {
|
$.each(textToIcon, function(text, icon) {
|
||||||
$("a:contains('" + text + "'):not(:has(i))")
|
$("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))")
|
$(".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 System.Web.Mvc;
|
||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using MileageTraker.Web.Attributes;
|
using MileageTraker.Web.Attributes;
|
||||||
|
using MileageTraker.Web.DAL;
|
||||||
|
|
||||||
namespace MileageTraker.Web.ViewModels.ServiceReminder
|
namespace MileageTraker.Web.ViewModels.ServiceReminder
|
||||||
{
|
{
|
||||||
public class ServiceReminderViewModel
|
public class ServiceReminderViewModel : IComparable<ServiceReminderViewModel>, IValidatableObject
|
||||||
{
|
{
|
||||||
[HiddenInput(DisplayValue = false)]
|
[HiddenInput(DisplayValue = false)]
|
||||||
public int? ServiceReminderId { get; set; }
|
public int? ServiceReminderId { get; set; }
|
||||||
@@ -19,17 +22,28 @@ namespace MileageTraker.Web.ViewModels.ServiceReminder
|
|||||||
[InputSize("mini")]
|
[InputSize("mini")]
|
||||||
public string VehicleId { get; set; }
|
public string VehicleId { get; set; }
|
||||||
|
|
||||||
|
[HiddenInput(DisplayValue = false)]
|
||||||
|
public int? CurrentOdometer { get; set; }
|
||||||
|
|
||||||
[InputSize("small")]
|
[InputSize("small")]
|
||||||
public int TargetOdometer { get; set; }
|
[Range(1, 500000, ErrorMessage = "Between 1 and 500k")]
|
||||||
|
public int TargetOdometer { get; set; }
|
||||||
|
|
||||||
[StringLength(64)]
|
[StringLength(64)]
|
||||||
public string Description { get; set; }
|
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()
|
static ServiceReminderViewModel()
|
||||||
{
|
{
|
||||||
Mapper.CreateMap<ServiceReminderViewModel, Models.ServiceReminder>();
|
Mapper.CreateMap<ServiceReminderViewModel, Models.ServiceReminder>();
|
||||||
Mapper.CreateMap<Models.ServiceReminder, ServiceReminderViewModel>()
|
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)
|
public ServiceReminderViewModel(Models.ServiceReminder serviceReminder)
|
||||||
@@ -47,5 +61,32 @@ namespace MileageTraker.Web.ViewModels.ServiceReminder
|
|||||||
Mapper.Map(this, serviceReminder);
|
Mapper.Map(this, serviceReminder);
|
||||||
return 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 class VehicleResultsViewModel
|
||||||
{
|
{
|
||||||
public IEnumerable<Models.Vehicle> Vehicles { get; set; }
|
public IEnumerable<VehicleViewModel> Vehicles { get; set; }
|
||||||
public bool Inactive { get; set; }
|
public bool Inactive { get; set; }
|
||||||
|
|
||||||
public VehicleResultsViewModel(IEnumerable<Models.Vehicle> vehicles, bool activeInactive)
|
public VehicleResultsViewModel(IEnumerable<VehicleViewModel> vehicles, bool activeInactive)
|
||||||
{
|
{
|
||||||
Vehicles = vehicles;
|
Vehicles = vehicles;
|
||||||
Inactive = activeInactive;
|
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.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using MileageTraker.Web.ViewModels.ServiceReminder;
|
||||||
|
|
||||||
namespace MileageTraker.Web.ViewModels.VehicleService
|
namespace MileageTraker.Web.ViewModels.VehicleService
|
||||||
{
|
{
|
||||||
public class VehicleServiceResultsViewModel
|
public class VehicleServiceResultsViewModel
|
||||||
{
|
{
|
||||||
public IEnumerable<VehicleServiceViewModel> ServiceItems { get; set; }
|
public IEnumerable<VehicleServiceViewModel> ServiceItems { get; set; }
|
||||||
|
public IList<ServiceReminderViewModel> UpcomingServiceReminders { get; set; }
|
||||||
public Dictionary<string, List<string>> AvailableYearMonths { get; set; }
|
public Dictionary<string, List<string>> AvailableYearMonths { get; set; }
|
||||||
public IEnumerable<string> SelectedYearMonths
|
public IEnumerable<string> SelectedYearMonths
|
||||||
{
|
{
|
||||||
@@ -24,10 +26,12 @@ namespace MileageTraker.Web.ViewModels.VehicleService
|
|||||||
|
|
||||||
public VehicleServiceResultsViewModel(
|
public VehicleServiceResultsViewModel(
|
||||||
IEnumerable<VehicleServiceViewModel> serviceItems,
|
IEnumerable<VehicleServiceViewModel> serviceItems,
|
||||||
|
IList<ServiceReminderViewModel> upcomingServiceReminders,
|
||||||
VehicleServiceQueryViewModel query,
|
VehicleServiceQueryViewModel query,
|
||||||
Dictionary<string, List<string>> availableYearMonths)
|
Dictionary<string, List<string>> availableYearMonths)
|
||||||
{
|
{
|
||||||
ServiceItems = serviceItems;
|
ServiceItems = serviceItems;
|
||||||
|
UpcomingServiceReminders = upcomingServiceReminders;
|
||||||
AvailableYearMonths = availableYearMonths;
|
AvailableYearMonths = availableYearMonths;
|
||||||
Year = query.Year.HasValue ? query.Year.Value.ToString(CultureInfo.InvariantCulture) : string.Empty;
|
Year = query.Year.HasValue ? query.Year.Value.ToString(CultureInfo.InvariantCulture) : string.Empty;
|
||||||
Month = query.Month.HasValue ? query.Month.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)]
|
[DataType(DataType.DateTime)]
|
||||||
[DisplayFormatAttribute(ApplyFormatInEditMode = true, DataFormatString = "{0:d}")]
|
[DisplayFormatAttribute(ApplyFormatInEditMode = true, DataFormatString = "{0:d}")]
|
||||||
|
[DenyFutureDate(ErrorMessage = "Future date")]
|
||||||
[FormatHint("mm/dd/yyyy")]
|
[FormatHint("mm/dd/yyyy")]
|
||||||
[InputSize("small")]
|
[InputSize("small")]
|
||||||
|
[Required]
|
||||||
public DateTime? InvoiceDate { get; set; }
|
public DateTime? InvoiceDate { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
@model MileageTraker.Web.ViewModels.ServiceReminder.ServiceReminderViewModel
|
@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>
|
<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" }))
|
@using (Html.BeginForm("Create", "ServiceReminder", FormMethod.Post, new { @class = "form-horizontal well center-content" }))
|
||||||
@@ -11,6 +13,7 @@
|
|||||||
@Html.Partial("_ValidationSummary")
|
@Html.Partial("_ValidationSummary")
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend></legend>
|
<legend></legend>
|
||||||
|
@Html.DisplayFor(m => m.CurrentOdometer)
|
||||||
@Html.EditorForModel()
|
@Html.EditorForModel()
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<input type="submit" value="Create" class="btn btn-primary" />
|
<input type="submit" value="Create" class="btn btn-primary" />
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
@model MileageTraker.Web.ViewModels.ServiceReminder.ServiceReminderViewModel
|
@model MileageTraker.Web.ViewModels.ServiceReminder.ServiceReminderViewModel
|
||||||
|
|
||||||
@{
|
@{
|
||||||
ViewBag.Title = "Vehicle Service Reminder Details" ;
|
ViewBag.Title = "Service Reminder Details" ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Html.Partial("_StatusMessage")
|
@Html.Partial("_StatusMessage")
|
||||||
|
|||||||
@@ -1,19 +1,20 @@
|
|||||||
@model MileageTraker.Web.ViewModels.ServiceReminder.ServiceReminderViewModel
|
@model MileageTraker.Web.ViewModels.ServiceReminder.ServiceReminderViewModel
|
||||||
|
|
||||||
@{
|
@{
|
||||||
ViewBag.Title = "Edit Vehicle Service Reminder";
|
ViewBag.Title = "Edit Service Reminder";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Html.Partial("_StatusMessage")
|
@Html.Partial("_StatusMessage")
|
||||||
|
|
||||||
<h2 class="center-content"><i class="fa fa-clock-o"></i> @ViewBag.Title</h2>
|
<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")
|
@Html.Partial("_ValidationSummary")
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend></legend>
|
<legend></legend>
|
||||||
@Html.EditorForModel()
|
@Html.DisplayFor(m => m.CurrentOdometer)
|
||||||
|
@Html.EditorForModel()
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<input type="submit" value="Save" class="btn btn-primary" />
|
<input type="submit" value="Save" class="btn btn-primary" />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
@model MileageTraker.Web.ViewModels.ServiceReminder.ServiceReminderResultsViewModel
|
@model MileageTraker.Web.ViewModels.ServiceReminder.ServiceReminderResultsViewModel
|
||||||
|
|
||||||
@{
|
@{
|
||||||
ViewBag.Title = "Vehicle Service Reminders for Vehicle Id " + Model.VehicleId;
|
ViewBag.Title = "Service Reminders";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Html.Partial("_StatusMessage")
|
@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">
|
<div class="center-content">
|
||||||
@foreach (var item in Model.ServiceReminderItems)
|
@foreach (var item in Model.ServiceReminderItems)
|
||||||
@@ -16,6 +17,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="btn-toolbar center-content well">
|
<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"})
|
@Html.ActionLink("Vehicle Details", "Details", "Vehicle", new { id = Model.VehicleId }, new{@class="btn"})
|
||||||
</div>
|
</div>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
@model MileageTraker.Web.ViewModels.ServiceReminder.ServiceReminderViewModel
|
@model MileageTraker.Web.ViewModels.ServiceReminder.ServiceReminderViewModel
|
||||||
|
|
||||||
<div class="well">
|
<div class="well">
|
||||||
<h3>Service Reminder</h3>
|
<h4 class="center-content"><i class="fa fa-clock-o"></i> Service Reminder</h4>
|
||||||
@Html.DisplayForModel()
|
@Html.DisplayForModel()
|
||||||
<div class='btn-toolbar'>
|
<div class='btn-toolbar'>
|
||||||
@Html.ActionLink("Edit", "Edit", new { id = Model.ServiceReminderId }, new { @class = "btn" })
|
@Html.ActionLink("Edit", "Edit", new { id = Model.ServiceReminderId }, new { @class = "btn" })
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
@if (Session["LogPage"] != null) {
|
@if (Session["LogPage"] != null) {
|
||||||
<ul class="no-print breadcrumb">
|
<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>
|
</ul>
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<ul class="no-print breadcrumb">
|
<ul class="no-print breadcrumb">
|
||||||
<li>
|
<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>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<ul class="no-print breadcrumb">
|
<ul class="no-print breadcrumb">
|
||||||
<li>
|
<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>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -34,10 +34,10 @@
|
|||||||
</a>
|
</a>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li>
|
<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>
|
||||||
<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>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
<h2 id="vehicle-title"><i class="fa fa-car"></i> @ViewBag.Title</h2>
|
<h2 id="vehicle-title"><i class="fa fa-car"></i> @ViewBag.Title</h2>
|
||||||
|
|
||||||
<div class="btn-toolbar">
|
<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("Export All", "Export", null, new { @class = "btn" })
|
||||||
@Html.ActionLink(Model.Inactive ? "Show Active" : "Show Inactive", "Index", new {inactive = !Model.Inactive}, new { @class = "btn" })
|
@Html.ActionLink(Model.Inactive ? "Show Active" : "Show Inactive", "Index", new {inactive = !Model.Inactive}, new { @class = "btn" })
|
||||||
</div>
|
</div>
|
||||||
@@ -26,13 +26,7 @@
|
|||||||
Ethra Id
|
Ethra Id
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
Model Yr
|
Year, Make, Model
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
Make
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
Model
|
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
Type
|
Type
|
||||||
@@ -46,9 +40,12 @@
|
|||||||
<th>
|
<th>
|
||||||
Assigned
|
Assigned
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
ODO
|
ODO
|
||||||
</th>
|
</th>
|
||||||
|
<th>
|
||||||
|
Next Service
|
||||||
|
</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
@@ -61,13 +58,7 @@
|
|||||||
@Html.DisplayTextFor(m => item.VehicleId)
|
@Html.DisplayTextFor(m => item.VehicleId)
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@Html.DisplayTextFor(m => item.ModelYear)
|
@Html.DisplayTextFor(m => item.ModelYear) @Html.DisplayTextFor(m => item.Make) @Html.DisplayTextFor(m => item.CarModel)
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
@Html.DisplayTextFor(m => item.Make)
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
@Html.DisplayTextFor(m => item.CarModel)
|
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<span class="label @item.Color">
|
<span class="label @item.Color">
|
||||||
@@ -85,13 +76,20 @@
|
|||||||
<small class="muted"><em>@Html.DisplayTextFor(m => item.Notes)</em></small>
|
<small class="muted"><em>@Html.DisplayTextFor(m => item.Notes)</em></small>
|
||||||
}
|
}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@Html.DisplayTextFor(m => item.CurrentOdometer)
|
@Html.DisplayTextFor(m => item.CurrentOdometer)
|
||||||
</td>
|
</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>
|
<td>
|
||||||
<div class='btn-group'>
|
<div class='btn-group'>
|
||||||
@Html.ActionLink("Details", "Details", new { id = item.VehicleId }, new { @class = "btn btn-mini" })
|
@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>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -26,22 +26,50 @@
|
|||||||
}
|
}
|
||||||
</div>
|
</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>
|
<h2 id="vehicle-title"><i class="fa fa-wrench"></i> @ViewBag.Title</h2>
|
||||||
|
|
||||||
<div class="btn-toolbar pull-left">
|
<div class="btn-toolbar pull-left">
|
||||||
@Html.ActionLink("Add Service", "Create", null, new{@class="btn"})
|
@Html.ActionLink("Add Service", "Create", null, new { @class = "btn" })
|
||||||
@Html.ActionLink("Export", "Export", queryParams, new{@class="btn"})
|
@Html.ActionLink("Export", "Export", queryParams, new { @class = "btn" })
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@grid.GetHtml(columns:
|
@grid.GetHtml(columns:
|
||||||
grid.Columns(
|
grid.Columns(
|
||||||
grid.Column("InvoiceDate", "Invoice Date", item => item.InvoiceDate.ToString("d")),
|
grid.Column("InvoiceDate", "Invoice Date", item => item.InvoiceDate.ToString("d")),
|
||||||
grid.Column("VehicleID", "Vehicle Id"),
|
grid.Column("VehicleID", "Vehicle Id"),
|
||||||
grid.Column("ServiceCenterName", "Service Center Name"),
|
grid.Column("ServiceCenterName", "Service Center Name"),
|
||||||
grid.Column("Price", "Price"),
|
grid.Column("Price", "Price"),
|
||||||
grid.Column("Description", "Description"),
|
grid.Column("Description", "Description"),
|
||||||
grid.Column(format:
|
grid.Column(format:
|
||||||
@<div class='btn-group'>
|
@<div class='btn-group'>
|
||||||
@Html.ActionLink("Details", "Details", new { id = item.VehicleServiceId }, new { @class = "btn btn-mini" })
|
@Html.ActionLink("Details", "Details", new { id = item.VehicleServiceId }, new { @class = "btn btn-mini" })
|
||||||
</div>)
|
</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\AccountController.cs" />
|
||||||
<Compile Include="Controllers\CityController.cs" />
|
<Compile Include="Controllers\CityController.cs" />
|
||||||
<Compile Include="Controllers\ControllerBase.cs" />
|
<Compile Include="Controllers\ControllerBase.cs" />
|
||||||
|
<Compile Include="ViewModels\VehicleService\UpdateServiceRemindersViewModel.cs" />
|
||||||
<Compile Include="Controllers\FuelLogController.cs" />
|
<Compile Include="Controllers\FuelLogController.cs" />
|
||||||
<Compile Include="Controllers\ServiceReminderController.cs" />
|
<Compile Include="Controllers\ServiceReminderController.cs" />
|
||||||
<Compile Include="Controllers\VehicleServiceController.cs" />
|
<Compile Include="Controllers\VehicleServiceController.cs" />
|
||||||
@@ -268,6 +269,7 @@
|
|||||||
<Compile Include="ViewModels\VehicleService\VehicleServiceQueryViewModel.cs" />
|
<Compile Include="ViewModels\VehicleService\VehicleServiceQueryViewModel.cs" />
|
||||||
<Compile Include="ViewModels\VehicleService\VehicleServiceResultsViewModel.cs" />
|
<Compile Include="ViewModels\VehicleService\VehicleServiceResultsViewModel.cs" />
|
||||||
<Compile Include="ViewModels\VehicleService\VehicleServiceViewModel.cs" />
|
<Compile Include="ViewModels\VehicleService\VehicleServiceViewModel.cs" />
|
||||||
|
<Compile Include="ViewModels\Vehicle\VehicleViewModel.cs" />
|
||||||
<Compile Include="ViewModels\Vehicle\VehicleResultsViewModel.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" />
|
||||||
@@ -350,6 +352,7 @@
|
|||||||
<Content Include="Views\ServiceReminder\Edit.cshtml" />
|
<Content Include="Views\ServiceReminder\Edit.cshtml" />
|
||||||
<Content Include="Views\ServiceReminder\Index.cshtml" />
|
<Content Include="Views\ServiceReminder\Index.cshtml" />
|
||||||
<Content Include="Views\ServiceReminder\ServiceReminderViewModel.cshtml" />
|
<Content Include="Views\ServiceReminder\ServiceReminderViewModel.cshtml" />
|
||||||
|
<Content Include="Views\VehicleService\UpdateServiceReminders.cshtml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="Content\Account.Login.css" />
|
<Content Include="Content\Account.Login.css" />
|
||||||
|
|||||||
Reference in New Issue
Block a user