using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using CsvHelper; using CsvHelper.Configuration; using MileageTraker.Web.Models; using MileageTraker.Web.Utility; namespace MileageTraker.Web.DAL { public static class FuelmanCsvImporter { private sealed class FuelmanCsvClassMap : CsvClassMap { readonly string[] _dateFormats = { @"M/d/yy HH:mm", @"M/d/yyyy HH:mm" }; public FuelmanCsvClassMap() { Map(m => m.Date).ConvertUsing(row => { var date = row.GetField("CEDATE"); var time = row.GetField("CETIME"); var dttm = string.Format(@"{0} {1:00:00}", date, time); DateTime parsed; if (DateTime.TryParseExact(dttm, _dateFormats, CultureInfo.InvariantCulture, DateTimeStyles.None, out parsed)) return parsed; throw new ArgumentException(string.Format("Date in incorrect format: CEDATE:{0} CETIME:{1}", date, time)); }); Map(m => m.DriverFullName).ConvertUsing(row => { var name = row.GetField("CEEMNAME"); return NameNormalizer.Normalize(name); }); Map(m => m.TagNumber).Name("CEVEHNO"); Map(m => m.Odometer).Name("CEODOMETER"); Map(m => m.CityName).ConvertUsing(row => { var city = row.GetField("CESITCTY"); return city.ToLower().ToTitleCase(); }); Map(m => m.MPG).Name("CEMPG"); Map(m => m.GasPurchased).Name("CEQTY"); Map(m => m.TotalPrice).Name("CECUSAMT"); } } public static bool IsProbablyTabSeparated(FileInfo fileInfo) { using (var tr = File.OpenText(fileInfo.FullName)) { var line = tr.ReadLine(); var tabHeadCount = (from c in line where c == '\t' select c).Count(); // if there's more than 10 tabs in the first line, probably TSV return tabHeadCount > 10; } } public static ICollection Import(FileInfo fileInfo) { if (!fileInfo.Exists) throw new ImportException("Cannot find file '" + fileInfo.Name + "'"); var tabSeparatedValues = IsProbablyTabSeparated(fileInfo); using (var tr = File.OpenText(fileInfo.FullName)) { var csvConfiguration = new CsvConfiguration(); if (tabSeparatedValues) csvConfiguration.Delimiter = "\t"; csvConfiguration.RegisterClassMap(); var csv = new CsvReader(tr, csvConfiguration); var fuelLogs = new List(); while (csv.Read()) { try { // Skip non-FUEL entries if (csv.GetField("CEPRDTYPE") != "FUEL") continue; fuelLogs.Add(csv.GetRecord()); } catch (Exception ex) { throw new ImportException("Problem with document encountered on row " + csv.Row + ". " + ex.Message); } } return fuelLogs; } } } }