Vehicle cost report

This commit is contained in:
2015-10-24 14:28:13 -04:00
parent 1fb8c54076
commit ad0b04695d
11 changed files with 238 additions and 17 deletions
+33
View File
@@ -4,7 +4,9 @@ using System.Web.Mvc;
using MileageTraker.Web.Attributes;
using MileageTraker.Web.DAL;
using MileageTraker.Web.Models;
using MileageTraker.Web.Utility;
using MileageTraker.Web.ViewModels.Vehicle;
using MileageTraker.Web.ViewModels.VehicleService;
namespace MileageTraker.Web.Controllers
{
@@ -120,5 +122,36 @@ namespace MileageTraker.Web.Controllers
}
return RedirectToAction("Details", new { id });
}
public ViewResult VehicleCostIndex()
{
var vehicleCostItemsYears = DataService.GetValidVehicleCostItemsYears();
return View(vehicleCostItemsYears);
}
public ViewResult VehicleCostReport(int fiscalYear)
{
var vehicleCostItems =
DataService.GetVehicleCostItems(fiscalYear)
.OrderBy(i => i.TagNumber).ThenBy(i => i.CostType).ToList();
var vehicleCostReport = new VehicleCostReport {FiscalYear = fiscalYear, CostItems = vehicleCostItems};
return View(vehicleCostReport);
}
[ActionLog]
public ActionResult ExportVehicleCostReport(int fiscalYear)
{
var vehicleCostItems =
DataService.GetVehicleCostItems(fiscalYear)
.OrderBy(i => i.TagNumber).ThenBy(i => i.CostType).ToList();
var name = string.Format("VehicleCost_{0}", fiscalYear);
var export = ExcelWriter<VehicleCostItem>.WriteXls(vehicleCostItems, name, name);
return File(export, "application/ms-excel", name + ".xls");
}
}
}
+63
View File
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.SqlServer;
using System.Linq;
using System.Text.RegularExpressions;
using MileageTraker.Web.Context;
@@ -865,6 +866,67 @@ namespace MileageTraker.Web.DAL
#endregion
#region Vehicle Cost Report
private const int FiscalYearStartMonth = 7;
public IQueryable<VehicleCostItem> GetFuelLogCost(int fiscalYear)
{
var fiscalYearStart = new DateTime(fiscalYear - 1, FiscalYearStartMonth, 1);
var fiscalYearEnd = new DateTime(fiscalYear, FiscalYearStartMonth, 1);
return
from fuelLog in _db.FuelLogs
where fuelLog.Date >= fiscalYearStart && fuelLog.Date < fiscalYearEnd
group fuelLog by fuelLog.TagNumber
into tagGroup
let totalFuelPrice = tagGroup.Sum(i => i.TotalPrice)
select new VehicleCostItem { CostType = "Fuel", TotalPrice = totalFuelPrice, TagNumber = tagGroup.Key};
}
public IQueryable<VehicleCostItem> GetVehicleServiceCost(int fiscalYear)
{
var fiscalYearStart = new DateTime(fiscalYear - 1, FiscalYearStartMonth, 1);
var fiscalYearEnd = new DateTime(fiscalYear, FiscalYearStartMonth, 1);
return
from vehicleService in _db.VehicleServices
where vehicleService.InvoiceDate >= fiscalYearStart && vehicleService.InvoiceDate < fiscalYearEnd
group vehicleService by vehicleService.Vehicle.TagNumber
into tagGroup
let totalServicePrice = tagGroup.Sum(i => i.Price)
select new VehicleCostItem { CostType = "Service", TotalPrice = totalServicePrice, TagNumber = tagGroup.Key };
}
public IList<VehicleCostItem> GetVehicleCostItems(int fiscalYear)
{
var costItems = GetFuelLogCost(fiscalYear).Union(GetVehicleServiceCost(fiscalYear)).ToList();
foreach (var costItem in costItems)
{
costItem.VehicleId = GetVehicleIdByTag(costItem.TagNumber);
}
return costItems;
}
public IList<int> GetValidVehicleCostItemsYears()
{
var fuelYears =
(from fuelLog in _db.FuelLogs
let fiscalYear = SqlFunctions.DateAdd("month", FiscalYearStartMonth - 1, fuelLog.Date).Value.Year
select fiscalYear).Distinct();
var serviceYears =
(from vehicleService in _db.VehicleServices
let fiscalYear = SqlFunctions.DateAdd("month", FiscalYearStartMonth - 1, vehicleService.InvoiceDate).Value.Year
select fiscalYear).Distinct();
var years = fuelYears.Union(serviceYears).Distinct().OrderByDescending(y => y);
return years.ToList();
}
#endregion
#region Service Reminder
public void AddServiceReminder(ServiceReminder serviceReminder)
{
@@ -920,5 +982,6 @@ namespace MileageTraker.Web.DAL
}
#endregion
}
}
+1
View File
@@ -218,6 +218,7 @@ function addButtonIcons () {
'Purposes': 'arrow-right',
'Vehicle Service': 'wrench',
'Vehicle': 'car',
'Cost': 'money',
'Reminder': 'clock-o',
'Fuel Logs': 'tachometer',
'Users': 'users',
+16
View File
@@ -0,0 +1,16 @@
using MileageTraker.Web.Attributes;
namespace MileageTraker.Web.ViewModels.Vehicle
{
public class VehicleCostItem
{
public string VehicleId { get; set; }
public string TagNumber { get; set; }
public string CostType { get; set; }
[Currency]
public decimal TotalPrice { get; set; }
}
}
@@ -0,0 +1,16 @@
using System.Collections.Generic;
using System.Linq;
using MileageTraker.Web.Attributes;
namespace MileageTraker.Web.ViewModels.Vehicle
{
public class VehicleCostReport
{
public int FiscalYear { get; set; }
public IList<VehicleCostItem> CostItems { get; set; }
[Currency]
public decimal TotalPrice { get { return CostItems.Sum(i => i.TotalPrice); } }
}
}
+1
View File
@@ -42,6 +42,7 @@
<li>@Html.ActionLink("Vehicles", "Index", "Vehicle")</li>
<li>@Html.ActionLink("Vehicle Service", "Index", "VehicleService")</li>
<li>@Html.ActionLink("Fuel Logs", "Index", "FuelLog")</li>
<li>@Html.ActionLink("Cost Report", "VehicleCostIndex", "Vehicle")</li>
</ul>
</li>
<li id="user-nav">@Html.ActionLink("Users", "Index", "User")</li>
+15
View File
@@ -0,0 +1,15 @@
@model IList<int>
@{
ViewBag.Title = "Vehicle Cost Report";
}
@Html.Partial("_StatusMessage")
<h2 id="vehicle-title"><i class="fa fa-money"></i> @ViewBag.Title</h2>
@foreach (var item in Model) {
<p>
@Html.ActionLink("FY" + item.ToString(), "VehicleCostReport", new { fiscalYear = item }, new { @class = "btn" })
</p>
}
@@ -0,0 +1,63 @@
@using MileageTraker.Web.ViewModels.FuelLog
@using MileageTraker.Web.ViewModels.VehicleService
@model MileageTraker.Web.ViewModels.Vehicle.VehicleCostReport
@{
ViewBag.Title = "Vehicle Cost Report";
}
@Html.Partial("_StatusMessage")
<h2><i class="fa fa-money"></i> @ViewBag.Title</h2>
<div class="btn-toolbar clearfix">
@Html.ActionLink("Export", "ExportVehicleCostReport", new { fiscalYear = Model.FiscalYear }, new { @class = "btn" })
</div>
@Html.DisplayFor(m => m.FiscalYear)
<table class="table">
<tr>
<th>
Vehicle Id
</th>
<th>
Tag Number
</th>
<th>
Cost Type
</th>
<th>
Total Price
</th>
</tr>
@foreach (var item in Model.CostItems)
{
<tr>
<td>
@if(item.VehicleId != null)
{
@Html.ActionLink(item.VehicleId, "Details", new {id = item.VehicleId})
}
</td>
<td>
@Html.DisplayTextFor(i => item.TagNumber)
</td>
<td>
@Html.DisplayTextFor(i => item.CostType)
</td>
<td>
$@Html.DisplayTextFor(i => item.TotalPrice)
@*<small>@Html.ActionLink("Vehicle Services", "Index", "VehicleService",
new VehicleServiceQueryViewModel{Year = Model.FiscalYear - 1, Month = 7, MonthRange = 12}, new {@class="no-print"})</small>
<small>@Html.ActionLink("Fuel Logs", "Index", "FuelLog",
new FuelLogQueryViewModel{Year = Model.FiscalYear - 1, Month = 7, MonthRange = 12}, new {@class="no-print"})</small>*@
</td>
</tr>
}
<tfoot>
<tr>
<td colspan="3" style="text-align: right"><strong>Total:</strong></td>
<td><strong>$@Html.DisplayTextFor(m => m.TotalPrice)</strong></td>
</tr>
</tfoot>
</table>
+1 -1
View File
@@ -42,7 +42,7 @@
grid.Column("InvoiceDate", "Invoice Date", item => item.InvoiceDate.ToString("d")),
grid.Column("VehicleId", "Vehicle ID", item => Html.ActionLink((string)item.VehicleId, "DetailsPartial", "Vehicle", new { id = item.VehicleId }, new { @class = "qtip-modal" })),
grid.Column("ServiceCenterName", "Service Center Name"),
grid.Column("Price", "Price"),
grid.Column("Price", "Price", @<text>@String.Format("{0:C}", item.Price)</text>),
grid.Column("Description", "Description"),
grid.Column(format:
@<div class='btn-group'>
@@ -1,5 +1,8 @@
@model IList<MileageTraker.Web.ViewModels.ServiceReminder.ServiceReminderViewModel>
@{
const int showCount = 10;
}
<table class="table table-striped table-bordered table-hover table-condensed">
<tr>
<th>Vehicle ID</th>
@@ -9,20 +12,26 @@
<th>Description</th>
<th></th>
</tr>
@foreach (var sr in Model)
{
<tr>
<td>@Html.ActionLink(sr.VehicleId, "DetailsPartial", "Vehicle", new { id = sr.VehicleId }, new { @class = "qtip-modal" })</td>
<td>@Html.DisplayTextFor(m => sr.AssignedDriver)</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>
}
@foreach (var sr in Model.Take(showCount))
{
<tr>
<td>@Html.ActionLink(sr.VehicleId, "DetailsPartial", "Vehicle", new {id = sr.VehicleId}, new {@class = "qtip-modal"})</td>
<td>@Html.DisplayTextFor(m => sr.AssignedDriver)</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>
}
@if (Model.Count > showCount)
{
<tr>
<td colspan="6">... and @(Model.Count - showCount) additional</td>
</tr>
}
</table>
+4
View File
@@ -270,6 +270,8 @@
<Compile Include="ViewModels\VehicleService\VehicleServiceQueryViewModel.cs" />
<Compile Include="ViewModels\VehicleService\VehicleServiceResultsViewModel.cs" />
<Compile Include="ViewModels\VehicleService\VehicleServiceViewModel.cs" />
<Compile Include="ViewModels\Vehicle\VehicleCostItem.cs" />
<Compile Include="ViewModels\Vehicle\VehicleCostReport.cs" />
<Compile Include="ViewModels\Vehicle\VehicleViewModel.cs" />
<Compile Include="ViewModels\Vehicle\VehicleResultsViewModel.cs" />
<Compile Include="ViewModels\SelectListViewModel.cs" />
@@ -355,6 +357,8 @@
<Content Include="Views\ServiceReminder\ServiceReminderViewModel.cshtml" />
<Content Include="Views\VehicleService\UpdateServiceReminders.cshtml" />
<Content Include="Views\VehicleService\UpcomingServiceReminders.cshtml" />
<Content Include="Views\Vehicle\VehicleCostReport.cshtml" />
<Content Include="Views\Vehicle\VehicleCostIndex.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Content\Account.Login.css" />