Admin import functional
This commit is contained in:
+32
-17
@@ -2,7 +2,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using MileageTraker.Web.Context;
|
||||
using MileageTraker.Web.Models;
|
||||
using MileageTraker.Web.Utility;
|
||||
@@ -251,27 +250,23 @@ namespace MileageTraker.Web.DAL
|
||||
if (query.LogType.HasValue)
|
||||
{
|
||||
// WTF The specified value is not an instance of type 'Edm.Int32'
|
||||
Expression<Func<Log, bool>> predicate;
|
||||
switch (query.LogType.Value)
|
||||
{
|
||||
case MileageLogType.NonCommuting:
|
||||
predicate = l => l.LogType.Value == 1;
|
||||
break;
|
||||
case MileageLogType.Commuting:
|
||||
predicate = l => l.LogType.Value == 2;
|
||||
break;
|
||||
case MileageLogType.GasPurchase:
|
||||
predicate = l => l.LogType.Value == 3;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
logs = logs.Where(predicate);
|
||||
logs = logs.Where(query.LogType.Value.GetEqualsPredicate());
|
||||
}
|
||||
|
||||
return logs;
|
||||
}
|
||||
|
||||
public IEnumerable<Log> GetDuplicateLogs(Log log)
|
||||
{
|
||||
return
|
||||
from dbLog in GetLogs().Where(log.LogType.Enum.GetEqualsPredicate())
|
||||
where
|
||||
dbLog.Date == log.Date &&
|
||||
dbLog.EndOdometer == log.EndOdometer &&
|
||||
dbLog.VehicleId == log.VehicleId
|
||||
select dbLog;
|
||||
}
|
||||
|
||||
public IEnumerable<Log> GetRecentLogsByUsername(string username)
|
||||
{
|
||||
return
|
||||
@@ -347,6 +342,26 @@ namespace MileageTraker.Web.DAL
|
||||
return GetPurposeTypes().FirstOrDefault(pt => pt.PurposeTypeId == id);
|
||||
}
|
||||
|
||||
public PurposeType FindPurposeType(string name)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
return null;
|
||||
|
||||
var mpt =
|
||||
GetPurposeTypes()
|
||||
.Select(pt =>
|
||||
Tuple.Create(pt.PurposeTypeId,
|
||||
Algorithms.Similarity(
|
||||
pt.Purpose.ToLowerInvariant(),
|
||||
name.ToLowerInvariant())))
|
||||
.OrderByDescending(tp => tp.Item2)
|
||||
.FirstOrDefault(tp => tp.Item2 > .8);
|
||||
|
||||
if (mpt != null)
|
||||
return FindPurposeType(mpt.Item1);
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Vehicle
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
|
||||
namespace MileageTraker.Web.DAL
|
||||
{
|
||||
public class LogImportException : Exception
|
||||
{
|
||||
public LogImportException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using ExcelLibrary.SpreadSheet;
|
||||
using MileageTraker.Web.Models;
|
||||
using MileageTraker.Web.Utility;
|
||||
using MileageTraker.Web.ViewModels;
|
||||
using MileageTraker.Web.ViewModels.CreateLog;
|
||||
|
||||
namespace MileageTraker.Web.DAL
|
||||
{
|
||||
public static class LogImportTemplateWriter
|
||||
{
|
||||
public static byte[] Write()
|
||||
{
|
||||
var example =
|
||||
new LogImportViewModel
|
||||
{
|
||||
CityName = "City Name",
|
||||
Date = "10-20-2010",
|
||||
EndOdometer = "10010",
|
||||
GasPurchased = "3.141",
|
||||
LogType = "Commuting",
|
||||
Notes = "Template",
|
||||
Purpose = "Training",
|
||||
VehicleId = "1000"
|
||||
};
|
||||
const string headerFormat = "[Blue]";
|
||||
|
||||
var worksheet = new Worksheet("LogImport");
|
||||
|
||||
ExcelWriter<LogImportViewModel>.WriteColumnHeaders(worksheet, formatString: headerFormat);
|
||||
ExcelWriter<LogImportViewModel>.WriteItems(worksheet, new[] { example }, 1); // write the example item
|
||||
|
||||
var propertyCount = ExcelWriter<LogImportViewModel>.GetPropertyCount();
|
||||
|
||||
worksheet.Cells[0, propertyCount + 1] = new Cell("Accepted values for fields:", headerFormat);
|
||||
|
||||
// purposes
|
||||
var dataService = new DataService();
|
||||
var puposes =
|
||||
from pt in dataService.GetPurposeTypes()
|
||||
orderby pt.SortOrder ascending
|
||||
select pt.Purpose;
|
||||
worksheet.Cells[1, propertyCount + 2] = new Cell("Purpose", headerFormat);
|
||||
ExcelWriter<string>.WriteItems(worksheet, puposes, 2, propertyCount + 2);
|
||||
|
||||
// log types
|
||||
var logTypes =
|
||||
from i in (new MileageLogType()).GetSelectListItems()
|
||||
select i.Text;
|
||||
worksheet.Cells[1, propertyCount + 1] = new Cell("Type", headerFormat);
|
||||
ExcelWriter<string>.WriteItems(worksheet, logTypes, 2, propertyCount + 1);
|
||||
|
||||
ExcelWriter<LogImportViewModel>.PadWorksheet(worksheet);
|
||||
|
||||
// save it
|
||||
var workbook = new Workbook();
|
||||
workbook.Worksheets.Add(worksheet);
|
||||
using (var stream = new MemoryStream())
|
||||
{
|
||||
workbook.Save(stream);
|
||||
return stream.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using ExcelLibrary.SpreadSheet;
|
||||
using MileageTraker.Web.Utility;
|
||||
using MileageTraker.Web.ViewModels;
|
||||
using MileageTraker.Web.ViewModels.CreateLog;
|
||||
|
||||
namespace MileageTraker.Web.DAL
|
||||
{
|
||||
public static class LogImporter
|
||||
{
|
||||
public static IEnumerable<LogImportViewModel> Import(string filename)
|
||||
{
|
||||
var fileInfo = new FileInfo(filename);
|
||||
return Import(Workbook.Load(fileInfo.FullName));
|
||||
}
|
||||
|
||||
private static IList<string> GetMissingHeaderColumns(IEnumerable<string> headerColumns)
|
||||
{
|
||||
var properties = typeof(LogImportViewModel).GetPropertyNames();
|
||||
var pset = new HashSet<string>(properties);
|
||||
var cset = new HashSet<string>(headerColumns);
|
||||
return pset.Except(cset).ToList();
|
||||
}
|
||||
|
||||
private static IEnumerable<LogImportViewModel> Import(Workbook workbook)
|
||||
{
|
||||
var sheet = workbook.Worksheets[0];
|
||||
|
||||
// get column header -> index
|
||||
const int columnCount = 8;
|
||||
var columnIndex = GetColumnIndex(sheet.Cells.GetRow(0), columnCount);
|
||||
|
||||
var missingHeaderColumns = GetMissingHeaderColumns(columnIndex.Keys);
|
||||
if (missingHeaderColumns.Any())
|
||||
{
|
||||
throw new LogImportException(string.Format("Excel document missing columns: {0}", string.Join(", ", missingHeaderColumns)));
|
||||
}
|
||||
|
||||
for (var r = 1; r <= sheet.Cells.LastRowIndex; r++)
|
||||
{
|
||||
var row = sheet.Cells.GetRow(r);
|
||||
|
||||
var emptyCells =
|
||||
Enumerable.Range(0, columnCount)
|
||||
.Select(i => row.GetCell(i).StringValue)
|
||||
.Count(s => s == "");
|
||||
|
||||
if (emptyCells > columnCount - 2)
|
||||
continue;
|
||||
|
||||
Func<string, string> getRowValue = i => row.GetCell(columnIndex[i]).StringValue.Trim();
|
||||
Func<string, string> getRowDateValue = i =>
|
||||
{
|
||||
var cell = row.GetCell(columnIndex[i]);
|
||||
if (cell.IsEmpty || cell.StringValue == "")
|
||||
return null;
|
||||
var dateTimeValue = cell.DateTimeValue;
|
||||
return dateTimeValue.ToShortDateString();
|
||||
};
|
||||
|
||||
var logImportViewModel =
|
||||
new LogImportViewModel
|
||||
{
|
||||
CityName = getRowValue("Destination City"),
|
||||
Date = getRowDateValue("Date"),
|
||||
EndOdometer = getRowValue("End Odometer"),
|
||||
GasPurchased = getRowValue("Gas Purchased"),
|
||||
LogType = getRowValue("Type"),
|
||||
Notes = getRowValue("Notes"),
|
||||
Purpose = getRowValue("Purpose"),
|
||||
VehicleId = getRowValue("Vehicle ID")
|
||||
};
|
||||
yield return logImportViewModel;
|
||||
}
|
||||
}
|
||||
|
||||
private static IDictionary<string, int> GetColumnIndex(Row headerRow, int columnCount)
|
||||
{
|
||||
var dictionary = new Dictionary<string, int>(columnCount);
|
||||
for (var i = 0; i < columnCount; i++)
|
||||
{
|
||||
var title = headerRow.GetCell(i).StringValue.Trim();
|
||||
if (string.IsNullOrEmpty(title))
|
||||
continue;
|
||||
//throw new LogImportError("Missing column in the excel document");
|
||||
dictionary.Add(title, i);
|
||||
}
|
||||
return dictionary;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using ExcelLibrary.SpreadSheet;
|
||||
@@ -15,12 +14,12 @@ namespace MileageTraker.Web.DAL
|
||||
|
||||
public static void Export(IEnumerable<Vehicle> vehicles, string filename)
|
||||
{
|
||||
ExcelWriter.WriteXls(vehicles, filename, WorksheetTitle, WorksheetName);
|
||||
ExcelWriter<Vehicle>.WriteXls(vehicles, filename, WorksheetTitle, WorksheetName);
|
||||
}
|
||||
|
||||
public static byte[] Export(IEnumerable<Vehicle> vehicles)
|
||||
{
|
||||
return ExcelWriter.WriteXls(vehicles, WorksheetTitle, WorksheetName);
|
||||
return ExcelWriter<Vehicle>.WriteXls(vehicles, WorksheetTitle, WorksheetName);
|
||||
}
|
||||
|
||||
public static IEnumerable<City> ImportCities(string filename)
|
||||
|
||||
Reference in New Issue
Block a user