Add filtering
Improve matching
This commit is contained in:
@@ -23,30 +23,17 @@ namespace MileageTraker.Web.Controllers
|
||||
// default parameter processing
|
||||
if (!query.HasParameters())
|
||||
{
|
||||
query.Year = validLogYearMonths.First().Year;
|
||||
query.FiscalYear = validLogYearMonths.First().Year;
|
||||
query.Month = validLogYearMonths.First().Month;
|
||||
}
|
||||
if (query.Year.HasValue && !query.Month.HasValue)
|
||||
{
|
||||
var validLogMonths = validLogYearMonths.Where(dt => dt.Year == query.Year).ToList();
|
||||
query.Month = validLogMonths.Min(dt => dt.Month);
|
||||
}
|
||||
|
||||
var fuelLogs = DataService.GetFuelLogs();
|
||||
|
||||
//fuelLogs.OrderBy(f => f.FuelLogId);
|
||||
|
||||
//var filteredLogs =
|
||||
// (from log in DataService.GetFuelLogIndexViewModels(DataService.FilterLogs(fuelLogs, query))
|
||||
// orderby log. descending
|
||||
// select log).ToList();
|
||||
|
||||
var flvm = from fl in fuelLogs.ToList()
|
||||
var flvm = from fl in DataService.FilterFuelLogs(fuelLogs, query).ToList()
|
||||
orderby fl.Date ascending
|
||||
select new FuelLogIndexViewModel(fl);
|
||||
|
||||
var viewModel = new ResultsViewModel(flvm, query, CustomExtensions.YearMonthList(validLogYearMonths));
|
||||
|
||||
//Session.Add("FuelLogPage", Request.Url.PathAndQuery);
|
||||
var viewModel = new FuelLogResultsViewModel(flvm, query, CustomExtensions.YearMonthList(validLogYearMonths));
|
||||
|
||||
return View(viewModel);
|
||||
}
|
||||
@@ -173,7 +160,7 @@ namespace MileageTraker.Web.Controllers
|
||||
{
|
||||
Status = MatchStatus.NoMatch.ToString(),
|
||||
Message = "Already matched to log",
|
||||
Action = RenderRazorViewToString("ImportMatchLogView", fuelLog.Log.LogId)
|
||||
Action = RenderRazorViewToString("MatchLink", new MatchLinkViewModel(fuelLog))
|
||||
|
||||
}, JsonRequestBehavior.AllowGet);
|
||||
}
|
||||
@@ -185,7 +172,8 @@ namespace MileageTraker.Web.Controllers
|
||||
return Json(new
|
||||
{
|
||||
Status = MatchStatus.NoMatch.ToString(),
|
||||
Message = "Unable to find match"
|
||||
Message = "Unable to find match",
|
||||
Action = RenderRazorViewToString("MatchLink", new MatchLinkViewModel(fuelLog))
|
||||
}, JsonRequestBehavior.AllowGet);
|
||||
}
|
||||
fuelLog.Log = matchingLog;
|
||||
@@ -193,7 +181,7 @@ namespace MileageTraker.Web.Controllers
|
||||
return Json(new
|
||||
{
|
||||
Status = MatchStatus.Match.ToString(),
|
||||
Action = RenderRazorViewToString("ImportMatchedLog", new ImportMatchedLogViewModel { LogId = fuelLog.Log.LogId })
|
||||
Action = RenderRazorViewToString("MatchLink", new MatchLinkViewModel(fuelLog))
|
||||
}, JsonRequestBehavior.AllowGet);
|
||||
}
|
||||
|
||||
|
||||
+46
-9
@@ -7,6 +7,7 @@ using MileageTraker.Web.Context;
|
||||
using MileageTraker.Web.Models;
|
||||
using MileageTraker.Web.Utility;
|
||||
using MileageTraker.Web.ViewModels;
|
||||
using MileageTraker.Web.ViewModels.FuelLog;
|
||||
using MileageTraker.Web.ViewModels.Log;
|
||||
using MileageTraker.Web.ViewModels.Vehicle;
|
||||
|
||||
@@ -658,6 +659,30 @@ namespace MileageTraker.Web.DAL
|
||||
return _db.FuelLogs.Find(id);
|
||||
}
|
||||
|
||||
public static IQueryable<FuelLog> FilterFuelLogs(IQueryable<FuelLog> fuelLogs, FuelLogQueryViewModel query)
|
||||
{
|
||||
const int fiscalYearStartMonth = 7;
|
||||
|
||||
// date filtering
|
||||
if (query.FiscalYear.HasValue & query.Month.HasValue)
|
||||
{
|
||||
var start = new DateTime(query.FiscalYear.Value, query.Month.Value, 1);
|
||||
var end = start.AddMonths(1);
|
||||
fuelLogs = fuelLogs.Where(l => l.Date >= start && l.Date < end);
|
||||
}
|
||||
else if (query.FiscalYear.HasValue)
|
||||
{
|
||||
var start = new DateTime(query.FiscalYear.Value, fiscalYearStartMonth, 1);
|
||||
var end = start.AddYears(1);
|
||||
fuelLogs = fuelLogs.Where(l => l.Date >= start && l.Date < end);
|
||||
}
|
||||
if (query.Unmatched)
|
||||
{
|
||||
fuelLogs = fuelLogs.Where(l => l.Log == null);
|
||||
}
|
||||
return fuelLogs;
|
||||
}
|
||||
|
||||
public IEnumerable<FuelLog> GetDuplicateFuelLogs(FuelLog log)
|
||||
{
|
||||
return
|
||||
@@ -671,23 +696,35 @@ namespace MileageTraker.Web.DAL
|
||||
|
||||
public Log GetMatchingLog(FuelLog fuelLog)
|
||||
{
|
||||
var logs = GetLogs();
|
||||
// add a little wiggle room for the gas - it is common to be off by a couple hundreths
|
||||
const double gasRange = .01;
|
||||
var gasMax = fuelLog.GasPurchased + gasRange;
|
||||
var gasMin = fuelLog.GasPurchased - gasRange;
|
||||
|
||||
var dateGasVehicleQuery = GetLogs();
|
||||
|
||||
// matching by Date, Gas Purchased (gallons), and Vehicle
|
||||
|
||||
var vehicle = GetVehicleByTag(fuelLog.TagNumber);
|
||||
if (vehicle != null)
|
||||
logs = logs.Where(log => log.VehicleId == vehicle.VehicleId);
|
||||
else return null;
|
||||
dateGasVehicleQuery = dateGasVehicleQuery.Where(log => log.VehicleId == vehicle.VehicleId);
|
||||
|
||||
logs = logs.Where(log =>
|
||||
dateGasVehicleQuery = dateGasVehicleQuery
|
||||
.Where(log =>
|
||||
log.Date.Year == fuelLog.Date.Year &&
|
||||
log.Date.Month == fuelLog.Date.Month &&
|
||||
log.Date.Day == fuelLog.Date.Day
|
||||
);
|
||||
logs = logs.Where(log => log.GasPurchased == fuelLog.GasPurchased);
|
||||
log.Date.Day == fuelLog.Date.Day)
|
||||
.Where(log => log.GasPurchased <= gasMax && log.GasPurchased >= gasMin);
|
||||
|
||||
return logs.FirstOrDefault();
|
||||
var dateDriverGasQuery
|
||||
= GetLogs()
|
||||
.Where(log =>
|
||||
log.Date.Year == fuelLog.Date.Year &&
|
||||
log.Date.Month == fuelLog.Date.Month &&
|
||||
log.Date.Day == fuelLog.Date.Day)
|
||||
.Where(log => log.User.FullName.Contains(fuelLog.DriverFullName))
|
||||
.Where(log => log.GasPurchased <= gasMax && log.GasPurchased >= gasMin);
|
||||
|
||||
return dateGasVehicleQuery.Union(dateDriverGasQuery).FirstOrDefault();
|
||||
}
|
||||
|
||||
public IEnumerable<Log> GetPossibleMatchingLogs(FuelLog fuelLog)
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
function importFuelLogs() {
|
||||
function matchFuelLogs() {
|
||||
$('.breadcrumb').hide();
|
||||
$('tr:not(.complete) .match-status').append('<span class="label">Pending</span');
|
||||
var total = $("#fuellogs > tbody > tr:not(.complete)").length;
|
||||
$('#page-match-status').html('<span class="label label-warning"><i class="fa fa-spinner fa-spin"></i> Matching In Progress</span> <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>');
|
||||
|
||||
submitNext();
|
||||
var failureCount = 0;
|
||||
var unmatchedCount = 0;
|
||||
var errorCount = 0;
|
||||
|
||||
function submitNext() {
|
||||
var $fuelLogs = $("#fuellogs > tbody > tr:not(.complete)");
|
||||
@@ -32,12 +33,13 @@
|
||||
else if (result.Status == "NoMatch" || result.Status == "Error") {
|
||||
if (result.Status == "NoMatch") {
|
||||
$('.match-status', $row).html('<span class="label label-warning">No Match</span>');
|
||||
unmatchedCount++;
|
||||
} else {
|
||||
$('.match-status', $row).html('<span class="label label-important">Error</span>');
|
||||
errorCount++;
|
||||
$('.progress .bar').addClass('bar-warning');
|
||||
}
|
||||
$('.match-message', $row).text(result.Message);
|
||||
failureCount++;
|
||||
$('.progress .bar').addClass('bar-warning');
|
||||
}
|
||||
if (result.Action != undefined && result.Action != null) {
|
||||
$('.match-status', $row).append(" " + result.Action);
|
||||
@@ -50,11 +52,11 @@
|
||||
$('.breadcrumb').show();
|
||||
$('.progress').removeClass('progress-striped');
|
||||
$('.progress').removeClass('active');
|
||||
if (failureCount == 0) {
|
||||
$('#page-match-status').html('<span class="label">Complete</span> with all matches.');
|
||||
if (errorCount == 0) {
|
||||
$('#page-match-status').html('<span class="label">Complete</span> ' + total + ' total with <strong>' + unmatchedCount + '</strong> left unmatched.');
|
||||
$('.progress .bar').addClass('bar-success');
|
||||
} else {
|
||||
$('#page-match-status').html('<span class="label label-warning">Complete</span> but with errors. See details below.');
|
||||
$('#page-match-status').html('<span class="label label-warning">Complete</span> with errors. See below.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,27 +5,28 @@ namespace MileageTraker.Web.ViewModels.FuelLog
|
||||
{
|
||||
public class FuelLogQueryViewModel
|
||||
{
|
||||
public int? Year { get; set; }
|
||||
public int? FiscalYear { get; set; }
|
||||
public int? Month { get; set; }
|
||||
public bool Unmatched { get; set; }
|
||||
|
||||
public string YearMonthStart {get
|
||||
{
|
||||
return string.Format("{0}-{1:00}", Year, Month);
|
||||
return string.Format("{0}-{1:00}", FiscalYear, Month);
|
||||
}}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var v = new List<string>();
|
||||
|
||||
if (Year.HasValue && Month.HasValue)
|
||||
if (FiscalYear.HasValue && Month.HasValue)
|
||||
{
|
||||
var str = YearMonthStart;
|
||||
|
||||
v.Add(str);
|
||||
}
|
||||
else if (Year.HasValue)
|
||||
else if (FiscalYear.HasValue)
|
||||
{
|
||||
v.Add(Year.ToString());
|
||||
v.Add(FiscalYear.ToString());
|
||||
}
|
||||
|
||||
return String.Join("_", v).Replace(' ', '-');
|
||||
@@ -33,7 +34,7 @@ namespace MileageTraker.Web.ViewModels.FuelLog
|
||||
|
||||
public bool HasParameters()
|
||||
{
|
||||
return Year.HasValue;
|
||||
return FiscalYear.HasValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
-6
@@ -3,27 +3,29 @@ using System.Globalization;
|
||||
|
||||
namespace MileageTraker.Web.ViewModels.FuelLog
|
||||
{
|
||||
public class ResultsViewModel
|
||||
public class FuelLogResultsViewModel
|
||||
{
|
||||
public IEnumerable<FuelLogIndexViewModel> FuelLogs { get; set; }
|
||||
public Dictionary<string, List<string>> AvailableYearMonths { get; set; }
|
||||
public IEnumerable<string> SelectedYearMonths{get
|
||||
{
|
||||
if (!string.IsNullOrEmpty(Year))
|
||||
return AvailableYearMonths[Year];
|
||||
if (!string.IsNullOrEmpty(FiscalYear))
|
||||
return AvailableYearMonths[FiscalYear];
|
||||
return new List<string>();
|
||||
}}
|
||||
|
||||
// filter parameters
|
||||
public string Year { get; set; }
|
||||
public string FiscalYear { get; set; }
|
||||
public string Month { get; set; }
|
||||
public bool Unmatched { get; set; }
|
||||
|
||||
public ResultsViewModel(IEnumerable<FuelLogIndexViewModel> fuelLogs, FuelLogQueryViewModel query, Dictionary<string, List<string>> availableYearMonths)
|
||||
public FuelLogResultsViewModel(IEnumerable<FuelLogIndexViewModel> fuelLogs, FuelLogQueryViewModel query, Dictionary<string, List<string>> availableYearMonths)
|
||||
{
|
||||
FuelLogs = fuelLogs;
|
||||
AvailableYearMonths = availableYearMonths;
|
||||
Year = query.Year.HasValue ? query.Year.Value.ToString(CultureInfo.InvariantCulture) : string.Empty;
|
||||
FiscalYear = query.FiscalYear.HasValue ? query.FiscalYear.Value.ToString(CultureInfo.InvariantCulture) : string.Empty;
|
||||
Month = query.Month.HasValue ? query.Month.Value.ToString(CultureInfo.InvariantCulture) : string.Empty;
|
||||
Unmatched = query.Unmatched;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
namespace MileageTraker.Web.ViewModels.FuelLog
|
||||
{
|
||||
public class ImportMatchedLogViewModel
|
||||
{
|
||||
public int LogId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
namespace MileageTraker.Web.ViewModels.FuelLog
|
||||
{
|
||||
public class MatchLinkViewModel
|
||||
{
|
||||
public int FuelLogId { get; set; }
|
||||
public int? LogId { get; set; }
|
||||
|
||||
public MatchLinkViewModel(Models.FuelLog fuelLog)
|
||||
{
|
||||
FuelLogId = fuelLog.FuelLogId;
|
||||
if (fuelLog.Log != null)
|
||||
LogId = fuelLog.Log.LogId;
|
||||
}
|
||||
|
||||
public MatchLinkViewModel(ImportFuelLogViewModel viewModel)
|
||||
{
|
||||
FuelLogId = viewModel.FuelLogId;
|
||||
if (viewModel.LogId != null)
|
||||
LogId = viewModel.LogId;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using MiscUtil.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MileageTraker.Web.ViewModels.Log
|
||||
{
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
}
|
||||
@if (viewModel.LogId != null)
|
||||
{
|
||||
@Html.Partial("ImportMatchedLog", new ImportMatchedLogViewModel { LogId = viewModel.LogId.Value })
|
||||
@Html.Partial("MatchLink", new MatchLinkViewModel (viewModel))
|
||||
}
|
||||
</td>
|
||||
<td class="match-message"></td>
|
||||
@@ -65,7 +65,7 @@
|
||||
<script src="@Url.Content("~/Scripts/Shared/FuelLogImport.js")" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
importFuelLogs();
|
||||
matchFuelLogs();
|
||||
});
|
||||
</script>
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
@model MileageTraker.Web.ViewModels.FuelLog.ImportMatchedLogViewModel
|
||||
@{
|
||||
Layout = null;
|
||||
}
|
||||
@Html.ActionLink("View Log", "Details", "Log", new{id=Model.LogId}, new{@class="btn btn-mini", target="_blank"})
|
||||
@@ -1,10 +1,10 @@
|
||||
@using MileageTraker.Web.Utility
|
||||
@model MileageTraker.Web.ViewModels.FuelLog.ResultsViewModel
|
||||
@model MileageTraker.Web.ViewModels.FuelLog.FuelLogResultsViewModel
|
||||
|
||||
@{
|
||||
ViewBag.Title = "Fuel Logs";
|
||||
var grid = new WebGrid(Model.FuelLogs, rowsPerPage: 45);
|
||||
var parameters = new {Model.Year, Model.Month};
|
||||
var parameters = new {Year = Model.FiscalYear, Model.Month};
|
||||
}
|
||||
@section Styles {
|
||||
<link href="@Url.Content("~/Content/VehicleColors.css")" rel="stylesheet" type="text/css" />
|
||||
@@ -12,9 +12,9 @@
|
||||
@section Scripts {
|
||||
<script type="text/javascript">
|
||||
var availableLogYearMonths = @Html.Raw(Json.Encode(Model.AvailableYearMonths));
|
||||
@if (Model.Year != null)
|
||||
@if (Model.FiscalYear != null)
|
||||
{
|
||||
<text>var selectedYear = "@Model.Year";</text>
|
||||
<text>var selectedYear = "@Model.FiscalYear";</text>
|
||||
<text>var selectedMonth = "@Model.Month";</text>
|
||||
}
|
||||
</script>
|
||||
@@ -22,12 +22,10 @@
|
||||
|
||||
@Html.Partial("_StatusMessage")
|
||||
|
||||
<div class="btn-toolbar pull-right">
|
||||
@using (Html.BeginForm("Index", "Log", FormMethod.Get, new { id = "filter", @class = "form" }))
|
||||
<div class="btn-toolbar pull-right" style="width:400px">
|
||||
@using (Html.BeginForm("Index", "FuelLog", FormMethod.Get, new { id = "filter", @class = "form" }))
|
||||
{
|
||||
<div class="">
|
||||
@*@Html.EditorForModel()*@
|
||||
</div>
|
||||
@Html.EditorForModel()
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -56,6 +54,9 @@
|
||||
htmlAttributes: new { @class = "table table-striped table-bordered table-hover table-condensed"},
|
||||
numericLinksCount: 20
|
||||
)
|
||||
<div class="center-content webgrid-footer">
|
||||
Total Results: @Model.FuelLogs.Count()
|
||||
</div>
|
||||
</div>
|
||||
@if (!Model.FuelLogs.Any())
|
||||
{
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
@model MileageTraker.Web.ViewModels.FuelLog.MatchLinkViewModel
|
||||
@{
|
||||
Layout = null;
|
||||
}
|
||||
@if (Model.LogId != null)
|
||||
{
|
||||
@Html.ActionLink("View Match", "Match", new {id = Model.FuelLogId}, new {@class = "btn btn-mini", target = "_blank"})
|
||||
}
|
||||
else
|
||||
{
|
||||
@Html.ActionLink("Match", "Match", new {id = Model.FuelLogId}, new {@class = "btn btn-warning btn-mini", target = "_blank"})
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
@using MileageTraker.Web.Models
|
||||
@using MileageTraker.Web.Utility
|
||||
@model MileageTraker.Web.ViewModels.FuelLog.FuelLogResultsViewModel
|
||||
|
||||
<div class="row-fluid">
|
||||
<div class="span4">
|
||||
@Html.Label("FiscalYear", "Fiscal Year")
|
||||
@Html.DropDownList("FiscalYear", new SelectList(Model.AvailableYearMonths.Keys, Model.FiscalYear), "Select Year", new { @class = "input-small" })
|
||||
</div>
|
||||
<div class="span3">
|
||||
@Html.Label("Month", "Month")
|
||||
@Html.DropDownList("Month", new SelectList(Model.SelectedYearMonths, Model.Month), "All Months", new { @class = "input-small" })
|
||||
</div>
|
||||
<div class="span3" >
|
||||
@Html.Label("Unmatched", "Unmatched Only", new{style = "padding-top:22px"})
|
||||
<input id="Unmatched" name="Unmatched" type="checkbox" @(Model.Unmatched ? "checked='checked'" : "" ) value="true" />
|
||||
</div>
|
||||
<div class="span2">
|
||||
<input type="submit" value="Filter" class="btn" style="margin-top:1.75em" />
|
||||
</div>
|
||||
</div>
|
||||
+4
-3
@@ -233,12 +233,12 @@
|
||||
<Compile Include="ViewModels\FuelLog\FuelLogIndexViewModel.cs" />
|
||||
<Compile Include="ViewModels\FuelLog\FuelLogViewModel.cs" />
|
||||
<Compile Include="ViewModels\FuelLog\ImportFuelLogViewModel.cs" />
|
||||
<Compile Include="ViewModels\FuelLog\ImportMatchedLogViewModel.cs" />
|
||||
<Compile Include="ViewModels\FuelLog\MatchLinkViewModel.cs" />
|
||||
<Compile Include="ViewModels\FuelLog\ImportUploadViewModel.cs" />
|
||||
<Compile Include="ViewModels\FuelLog\FuelLogQueryViewModel.cs" />
|
||||
<Compile Include="ViewModels\FuelLog\LogMatchViewModel.cs" />
|
||||
<Compile Include="ViewModels\FuelLog\MatchViewModel.cs" />
|
||||
<Compile Include="ViewModels\FuelLog\ResultsViewModel.cs" />
|
||||
<Compile Include="ViewModels\FuelLog\FuelLogResultsViewModel.cs" />
|
||||
<Compile Include="ViewModels\Log\ImportLogViewModel.cs" />
|
||||
<Compile Include="ViewModels\Log\ImportUploadViewModel.cs" />
|
||||
<Compile Include="ViewModels\Log\LogViewModel.cs" />
|
||||
@@ -307,12 +307,13 @@
|
||||
<Content Include="Views\FuelLog\ImportUpload.cshtml" />
|
||||
<Content Include="Views\FuelLog\Import.cshtml" />
|
||||
<Content Include="Views\FuelLog\Index.cshtml" />
|
||||
<Content Include="Views\FuelLog\ImportMatchedLog.cshtml" />
|
||||
<Content Include="Views\FuelLog\MatchLink.cshtml" />
|
||||
<Content Include="Views\FuelLog\Empty.cshtml" />
|
||||
<Content Include="Views\FuelLog\Details.cshtml" />
|
||||
<Content Include="Views\Log\DetailsPrevious.cshtml" />
|
||||
<Content Include="Views\FuelLog\Match.cshtml" />
|
||||
<Content Include="Views\FuelLog\MatchLogViewModelPartial.cshtml" />
|
||||
<Content Include="Views\Shared\EditorTemplates\FuelLogResultsViewModel.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Content\Account.Login.css" />
|
||||
|
||||
Reference in New Issue
Block a user