From 9f50a4635cfb6c5c2cb9776468a5be3187c39451 Mon Sep 17 00:00:00 2001 From: James Kolpack Date: Thu, 22 Sep 2016 14:14:12 -0400 Subject: [PATCH] Inventory and Type reports --- InventoryTraker.Web.Tests/App_Start/Setup.cs | 16 ++ .../InventoryTraker.Web.Tests.csproj | 2 + .../DistributionReportWriterTests.cs | 6 - .../Utilities/InventoryReportWriterTests.cs | 43 +++++ .../Utilities/MovementReportWriterTests.cs | 6 - .../Controllers/InventoryController.cs | 27 ++- .../Controllers/InventoryTypeController.cs | 22 +++ .../Controllers/ReportController.cs | 174 +----------------- .../InventoryTraker.Web.csproj | 3 + InventoryTraker.Web/Services/ReportService.cs | 174 ++++++++++++++++++ .../Utilities/DistributionReportWriter.cs | 3 +- .../Utilities/InventoryReportWriter.cs | 53 ++++++ .../Utilities/InventoryTypeReportWriter.cs | 50 +++++ .../Views/Inventory/Index.cshtml | 1 + .../Views/InventoryType/Index.cshtml | 3 +- .../js/inventory/InventoryListController.js | 11 +- .../js/inventory/inventorySvc.js | 7 +- .../inventoryType/InventoryTypeController.js | 9 +- .../js/inventoryType/inventoryTypeSvc.js | 7 +- 19 files changed, 426 insertions(+), 191 deletions(-) create mode 100644 InventoryTraker.Web.Tests/App_Start/Setup.cs create mode 100644 InventoryTraker.Web.Tests/Utilities/InventoryReportWriterTests.cs create mode 100644 InventoryTraker.Web/Services/ReportService.cs create mode 100644 InventoryTraker.Web/Utilities/InventoryReportWriter.cs create mode 100644 InventoryTraker.Web/Utilities/InventoryTypeReportWriter.cs diff --git a/InventoryTraker.Web.Tests/App_Start/Setup.cs b/InventoryTraker.Web.Tests/App_Start/Setup.cs new file mode 100644 index 0000000..7c28d75 --- /dev/null +++ b/InventoryTraker.Web.Tests/App_Start/Setup.cs @@ -0,0 +1,16 @@ +using Heroic.AutoMapper; +using InventoryTraker.Web.Core; +using NUnit.Framework; + +namespace InventoryTraker.Web.Tests +{ + [SetUpFixture] + public class Setup + { + [OneTimeSetUp] + public void S() + { + HeroicAutoMapperConfigurator.LoadMapsFromAssemblyContainingTypeAndReferencedAssemblies(); + } + } +} diff --git a/InventoryTraker.Web.Tests/InventoryTraker.Web.Tests.csproj b/InventoryTraker.Web.Tests/InventoryTraker.Web.Tests.csproj index 3058e24..5daf950 100644 --- a/InventoryTraker.Web.Tests/InventoryTraker.Web.Tests.csproj +++ b/InventoryTraker.Web.Tests/InventoryTraker.Web.Tests.csproj @@ -63,6 +63,8 @@ + + diff --git a/InventoryTraker.Web.Tests/Utilities/DistributionReportWriterTests.cs b/InventoryTraker.Web.Tests/Utilities/DistributionReportWriterTests.cs index da5eab3..d3e77e2 100644 --- a/InventoryTraker.Web.Tests/Utilities/DistributionReportWriterTests.cs +++ b/InventoryTraker.Web.Tests/Utilities/DistributionReportWriterTests.cs @@ -11,12 +11,6 @@ namespace InventoryTraker.Web.Tests.Utilities [TestFixture] public class DistributionReportWriterTests { - [OneTimeSetUp] - public void StartUp() - { - HeroicAutoMapperConfigurator.LoadMapsFromAssemblyContainingTypeAndReferencedAssemblies(); - } - private readonly DistributionReport[] _distributionReports = { new DistributionReport diff --git a/InventoryTraker.Web.Tests/Utilities/InventoryReportWriterTests.cs b/InventoryTraker.Web.Tests/Utilities/InventoryReportWriterTests.cs new file mode 100644 index 0000000..f6b307d --- /dev/null +++ b/InventoryTraker.Web.Tests/Utilities/InventoryReportWriterTests.cs @@ -0,0 +1,43 @@ +using System; +using System.IO; +using Heroic.AutoMapper; +using InventoryTraker.Web.Core; +using InventoryTraker.Web.Models; +using InventoryTraker.Web.Utilities; +using NUnit.Framework; + +namespace InventoryTraker.Web.Tests.Utilities +{ + [TestFixture] + public class InventoryReportWriterTests + { + private readonly InventoryViewModel[] _inventory = + { + new InventoryViewModel + { + + Name = "Beans", + ContainerType = "#300 cans", + UnitsPerCase = 24, + AddedDate = new DateTime(2015,3,1), + ExpirationDate = new DateTime(2017,4,1), + Quantity = 20, + Memo = "my memo", + PricePerCase = 12.12M, + WeightPerCase = 20.1, + } + }; + + [Test, Explicit] + public void Write() + { + using + (var outputFile + = new StreamWriter(Path.Combine(@"c:\temp", "InventoryReport.xlsx"))) + { + var writer = new InventoryReportWriter(); + writer.WriteStream(_inventory, outputFile.BaseStream); + } + } + } +} diff --git a/InventoryTraker.Web.Tests/Utilities/MovementReportWriterTests.cs b/InventoryTraker.Web.Tests/Utilities/MovementReportWriterTests.cs index d87daad..1621ec5 100644 --- a/InventoryTraker.Web.Tests/Utilities/MovementReportWriterTests.cs +++ b/InventoryTraker.Web.Tests/Utilities/MovementReportWriterTests.cs @@ -11,12 +11,6 @@ namespace InventoryTraker.Web.Tests.Utilities [TestFixture] public class MovementReportWriterTests { - [OneTimeSetUp] - public void StartUp() - { - HeroicAutoMapperConfigurator.LoadMapsFromAssemblyContainingTypeAndReferencedAssemblies(); - } - private readonly MovementReport _movementReport = new MovementReport { diff --git a/InventoryTraker.Web/Controllers/InventoryController.cs b/InventoryTraker.Web/Controllers/InventoryController.cs index 9ec8c75..b1fcfe8 100644 --- a/InventoryTraker.Web/Controllers/InventoryController.cs +++ b/InventoryTraker.Web/Controllers/InventoryController.cs @@ -8,6 +8,7 @@ using InventoryTraker.Web.Attributes; using InventoryTraker.Web.Core; using InventoryTraker.Web.Data; using InventoryTraker.Web.Models; +using InventoryTraker.Web.Utilities; namespace InventoryTraker.Web.Controllers { @@ -28,7 +29,7 @@ namespace InventoryTraker.Web.Controllers public JsonResult All() { var viewModels = - AllInventory() + CurrentInventory() .ProjectTo() .ToArray(); @@ -42,7 +43,7 @@ namespace InventoryTraker.Web.Controllers return BetterJson(viewModel); } - private IQueryable AllInventory() + private IQueryable CurrentInventory() { return _context .Inventories @@ -50,6 +51,26 @@ namespace InventoryTraker.Web.Controllers .OrderBy(x => x.InventoryType.Name); } + public ActionResult Export() + { + var writer = new InventoryReportWriter(); + + var viewModels = + CurrentInventory() + .ProjectTo() + .ToArray(); + + var excel = writer.Write(viewModels); + + var filename = $"Inventory{DateTime.Today:yyyyMMdd}.xlsx"; + + return + new FileContentResult(excel, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") + { + FileDownloadName = filename + }; + } + [ActionLog] public JsonResult Add(InventoryAddForm form) { @@ -134,7 +155,7 @@ namespace InventoryTraker.Web.Controllers _context.SaveChanges(); - return BetterJson(AllInventory() + return BetterJson(CurrentInventory() .ProjectTo() .ToArray()); } diff --git a/InventoryTraker.Web/Controllers/InventoryTypeController.cs b/InventoryTraker.Web/Controllers/InventoryTypeController.cs index fd7b048..4c52982 100644 --- a/InventoryTraker.Web/Controllers/InventoryTypeController.cs +++ b/InventoryTraker.Web/Controllers/InventoryTypeController.cs @@ -7,6 +7,7 @@ using AutoMapper.QueryableExtensions; using InventoryTraker.Web.Core; using InventoryTraker.Web.Data; using InventoryTraker.Web.Models; +using InventoryTraker.Web.Utilities; namespace InventoryTraker.Web.Controllers { @@ -33,6 +34,27 @@ namespace InventoryTraker.Web.Controllers return BetterJson(viewModels.ToArray()); } + public ActionResult Export() + { + var writer = new InventoryTypeReportWriter(); + + var viewModels = + _context.InventoryTypes + .OrderByDescending(x => x.Name) + .ProjectTo() + .ToArray(); + + var excel = writer.Write(viewModels); + + var filename = $"CommodityTypes{DateTime.Today:yyyyMMdd}.xlsx"; + + return + new FileContentResult(excel, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") + { + FileDownloadName = filename + }; + } + public JsonResult Add(InventoryTypeViewModel form) { if (!ModelState.IsValid) diff --git a/InventoryTraker.Web/Controllers/ReportController.cs b/InventoryTraker.Web/Controllers/ReportController.cs index dca1879..9dddd8a 100644 --- a/InventoryTraker.Web/Controllers/ReportController.cs +++ b/InventoryTraker.Web/Controllers/ReportController.cs @@ -1,23 +1,18 @@ using System; -using System.Collections.Generic; using System.Linq; using System.Web.Mvc; -using AutoMapper; -using AutoMapper.QueryableExtensions; -using InventoryTraker.Web.Core; -using InventoryTraker.Web.Data; -using InventoryTraker.Web.Models; +using InventoryTraker.Web.Services; using InventoryTraker.Web.Utilities; namespace InventoryTraker.Web.Controllers { public class ReportController : ControllerBase { - private readonly AppDbContext _context; + private readonly ReportService _reportService; - public ReportController(AppDbContext context) + public ReportController(ReportService reportService) { - _context = context; + _reportService = reportService; } [HttpGet] @@ -28,14 +23,14 @@ namespace InventoryTraker.Web.Controllers public ActionResult Distribution(DateTime startDate, DateTime endDate) { - var report = GetDistributionReport(startDate, endDate); + var report = _reportService.GetDistributionReport(startDate, endDate); return BetterJson(report.ToArray()); } public ActionResult DistributionExcel(DateTime startDate, DateTime endDate) { - var report = GetDistributionReport(startDate, endDate); + var report = _reportService.GetDistributionReport(startDate, endDate); var writer = new DistributionReportWriter(); var excel = writer.Write(report); @@ -49,37 +44,6 @@ namespace InventoryTraker.Web.Controllers }; } - private DistributionReport[] GetDistributionReport(DateTime startDate, DateTime endDate) - { - var query = - from t in _context.Transactions - where - t.TransactionType == TransactionType.Distributed - && t.TransactionDate >= startDate - && t.TransactionDate < endDate - group t by new { t.TransactionDate, t.Destination } - into g - select new - { - Date = g.Key.TransactionDate, - Destination = g.Key.Destination, - Transactions = g.ToList() - }; - - var report = - from item in query.ToArray() - select new DistributionReport - { - Date = item.Date, - Destination = item.Destination, - Transactions = - Mapper.Map, IList> - (item.Transactions).ToArray() - }; - - return report.ToArray(); - } - [HttpGet] public ActionResult Movement() { @@ -88,14 +52,14 @@ namespace InventoryTraker.Web.Controllers public ActionResult Movement(DateTime month) { - var report = GetMovementReport(month); + var report = _reportService.GetMovementReport(month); return BetterJson(report); } public ActionResult MovementExcel(DateTime month) { - var report = GetMovementReport(month); + var report = _reportService.GetMovementReport(month); var writer = new MovementReportWriter(); var excel = writer.Write(report); @@ -108,127 +72,5 @@ namespace InventoryTraker.Web.Controllers FileDownloadName = filename }; } - - private MovementReport GetMovementReport(DateTime month) - { - var startDate = month; - var endDate = startDate.AddMonths(1); - - return - new MovementReport - { - Items = GetMovementReportItems(startDate, endDate), - Month = month - }; - } - - private IEnumerable GetMovementReportItems(DateTime startDate, DateTime endDate) - { - var transactionsMostRecentBefore = - (from transaction in _context.Transactions - where - transaction.TransactionDate < startDate - group transaction by transaction.Inventory - into g - let mostRecent = - g.OrderByDescending(t => t.TransactionDate) - .ThenBy(t => t.CurrentQuantity) // for days with multiple, assume it's the smallest - .FirstOrDefault() - where mostRecent.CurrentQuantity > 0 - select mostRecent).ToList(); - - var transactionSums = - (from transaction in _context.Transactions - where - transaction.TransactionDate >= startDate - && transaction.TransactionDate < endDate - group transaction by transaction.Inventory - into g - let addedQty = g.Sum(t => t.AddedQuantity) - let distributed = g.Where(t => t.TransactionType == TransactionType.Distributed) - let distributedQty = distributed.Any() ? distributed.Sum(t => t.RemovedQuantity) : 0 - let adjustment = g.Where(t => - t.TransactionType == TransactionType.Expired - || t.TransactionType == TransactionType.Loss) - let adjustmentQty = adjustment.Any() ? adjustment.Sum(t => t.RemovedQuantity) : 0 - let endingQty = - g - .OrderByDescending(t => t.TransactionDate) - .ThenBy(t => t.CurrentQuantity) - .FirstOrDefault().CurrentQuantity - select new - { - Inventory = g.Key, - addedQty, - adjustmentQty, - distributedQty, - endingQty - }).ToList(); - - var inventoryReportItems = - transactionsMostRecentBefore.FullOuterJoin( // source - transactionSums, // inner - before => before.Inventory.Id, // fk - sums => sums.Inventory.Id, // pk - (before, sums, r) => - { - var item = new MovementReportInventoryItem(); - - if (before != null) - { - item.Inventory = before.Inventory; - item.BeginningQuantity = before.CurrentQuantity; - if (sums != null) - { - item.AddedQuantity = sums.addedQty; - item.DistributedQuantity = sums.distributedQty; - item.AdjustmentQuantity = sums.adjustmentQty; - item.EndingQuantity = sums.endingQty; - } - else // no change - { - item.EndingQuantity = item.BeginningQuantity; - } - } - else if (sums != null) // item was added in this time period - { - item.Inventory = sums.Inventory; - item.AddedQuantity = sums.addedQty; - item.DistributedQuantity = sums.distributedQty; - item.AdjustmentQuantity = sums.adjustmentQty; - item.EndingQuantity = sums.endingQty; - } - item.TotalAvailableQuantity = item.BeginningQuantity + item.AddedQuantity; - return item; - }).ToArray(); - - // group by inventory type - var inventoryTypeReportItems = - from item in inventoryReportItems - group item by item.Inventory.InventoryType - into grp - select new MovementReportItem - { - InventoryType = Mapper.Map(grp.Key), - BeginningQuantity = grp.Sum(g => g.BeginningQuantity), - AddedQuantity = grp.Sum(g => g.AddedQuantity), - TotalAvailableQuantity = grp.Sum(g => g.TotalAvailableQuantity), - DistributedQuantity = grp.Sum(g => g.DistributedQuantity), - AdjustmentQuantity = grp.Sum(g => g.AdjustmentQuantity), - EndingQuantity = grp.Sum(g => g.EndingQuantity) - }; - return inventoryTypeReportItems; - } - - private class MovementReportInventoryItem - { - public Inventory Inventory { get; set; } - public int BeginningQuantity { get; set; } - public int AddedQuantity { get; set; } - public int TotalAvailableQuantity { get; set; } - public int DistributedQuantity { get; set; } - public int AdjustmentQuantity { get; set; } - public int EndingQuantity { get; set; } - } } } \ No newline at end of file diff --git a/InventoryTraker.Web/InventoryTraker.Web.csproj b/InventoryTraker.Web/InventoryTraker.Web.csproj index e7309e5..ff03f21 100644 --- a/InventoryTraker.Web/InventoryTraker.Web.csproj +++ b/InventoryTraker.Web/InventoryTraker.Web.csproj @@ -384,7 +384,10 @@ + + + diff --git a/InventoryTraker.Web/Services/ReportService.cs b/InventoryTraker.Web/Services/ReportService.cs new file mode 100644 index 0000000..0fc6a05 --- /dev/null +++ b/InventoryTraker.Web/Services/ReportService.cs @@ -0,0 +1,174 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using AutoMapper; +using InventoryTraker.Web.Core; +using InventoryTraker.Web.Data; +using InventoryTraker.Web.Models; +using InventoryTraker.Web.Utilities; + +namespace InventoryTraker.Web.Services +{ + public class ReportService + { + private readonly AppDbContext _context; + + public ReportService(AppDbContext context) + { + _context = context; + } + + public DistributionReport[] GetDistributionReport(DateTime startDate, DateTime endDate) + { + var query = + from t in _context.Transactions + where + t.TransactionType == TransactionType.Distributed + && t.TransactionDate >= startDate + && t.TransactionDate < endDate + group t by new { t.TransactionDate, t.Destination } + into g + select new + { + Date = g.Key.TransactionDate, + Destination = g.Key.Destination, + Transactions = g.ToList() + }; + + var report = + from item in query.ToArray() + select new DistributionReport + { + Date = item.Date, + Destination = item.Destination, + Transactions = + Mapper.Map, IList> + (item.Transactions).ToArray() + }; + + return report.ToArray(); + } + + public MovementReport GetMovementReport(DateTime month) + { + var startDate = month; + var endDate = startDate.AddMonths(1); + + return + new MovementReport + { + Items = GetMovementReportItems(startDate, endDate), + Month = month + }; + } + + private IEnumerable GetMovementReportItems(DateTime startDate, DateTime endDate) + { + var transactionsMostRecentBefore = + (from transaction in _context.Transactions + where + transaction.TransactionDate < startDate + group transaction by transaction.Inventory + into g + let mostRecent = + g.OrderByDescending(t => t.TransactionDate) + .ThenBy(t => t.CurrentQuantity) // for days with multiple, assume it's the smallest + .FirstOrDefault() + where mostRecent.CurrentQuantity > 0 + select mostRecent).ToList(); + + var transactionSums = + (from transaction in _context.Transactions + where + transaction.TransactionDate >= startDate + && transaction.TransactionDate < endDate + group transaction by transaction.Inventory + into g + let addedQty = g.Sum(t => t.AddedQuantity) + let distributed = g.Where(t => t.TransactionType == TransactionType.Distributed) + let distributedQty = distributed.Any() ? distributed.Sum(t => t.RemovedQuantity) : 0 + let adjustment = g.Where(t => + t.TransactionType == TransactionType.Expired + || t.TransactionType == TransactionType.Loss) + let adjustmentQty = adjustment.Any() ? adjustment.Sum(t => t.RemovedQuantity) : 0 + let endingQty = + g + .OrderByDescending(t => t.TransactionDate) + .ThenBy(t => t.CurrentQuantity) + .FirstOrDefault().CurrentQuantity + select new + { + Inventory = g.Key, + addedQty, + adjustmentQty, + distributedQty, + endingQty + }).ToList(); + + var inventoryReportItems = + transactionsMostRecentBefore.FullOuterJoin( // source + transactionSums, // inner + before => before.Inventory.Id, // fk + sums => sums.Inventory.Id, // pk + (before, sums, r) => + { + var item = new MovementReportInventoryItem(); + + if (before != null) + { + item.Inventory = before.Inventory; + item.BeginningQuantity = before.CurrentQuantity; + if (sums != null) + { + item.AddedQuantity = sums.addedQty; + item.DistributedQuantity = sums.distributedQty; + item.AdjustmentQuantity = sums.adjustmentQty; + item.EndingQuantity = sums.endingQty; + } + else // no change + { + item.EndingQuantity = item.BeginningQuantity; + } + } + else if (sums != null) // item was added in this time period + { + item.Inventory = sums.Inventory; + item.AddedQuantity = sums.addedQty; + item.DistributedQuantity = sums.distributedQty; + item.AdjustmentQuantity = sums.adjustmentQty; + item.EndingQuantity = sums.endingQty; + } + item.TotalAvailableQuantity = item.BeginningQuantity + item.AddedQuantity; + return item; + }).ToArray(); + + // group by inventory type + var inventoryTypeReportItems = + from item in inventoryReportItems + group item by item.Inventory.InventoryType + into grp + select new MovementReportItem + { + InventoryType = Mapper.Map(grp.Key), + BeginningQuantity = grp.Sum(g => g.BeginningQuantity), + AddedQuantity = grp.Sum(g => g.AddedQuantity), + TotalAvailableQuantity = grp.Sum(g => g.TotalAvailableQuantity), + DistributedQuantity = grp.Sum(g => g.DistributedQuantity), + AdjustmentQuantity = grp.Sum(g => g.AdjustmentQuantity), + EndingQuantity = grp.Sum(g => g.EndingQuantity) + }; + return inventoryTypeReportItems; + } + + private class MovementReportInventoryItem + { + public Inventory Inventory { get; set; } + public int BeginningQuantity { get; set; } + public int AddedQuantity { get; set; } + public int TotalAvailableQuantity { get; set; } + public int DistributedQuantity { get; set; } + public int AdjustmentQuantity { get; set; } + public int EndingQuantity { get; set; } + } + } +} \ No newline at end of file diff --git a/InventoryTraker.Web/Utilities/DistributionReportWriter.cs b/InventoryTraker.Web/Utilities/DistributionReportWriter.cs index febee11..45bda44 100644 --- a/InventoryTraker.Web/Utilities/DistributionReportWriter.cs +++ b/InventoryTraker.Web/Utilities/DistributionReportWriter.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; using System.Linq; using AutoMapper; diff --git a/InventoryTraker.Web/Utilities/InventoryReportWriter.cs b/InventoryTraker.Web/Utilities/InventoryReportWriter.cs new file mode 100644 index 0000000..3625cf7 --- /dev/null +++ b/InventoryTraker.Web/Utilities/InventoryReportWriter.cs @@ -0,0 +1,53 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; +using ClosedXML.Excel; +using CsvHelper; +using CsvHelper.Configuration; +using CsvHelper.Excel; +using InventoryTraker.Web.Models; + +namespace InventoryTraker.Web.Utilities +{ + public class InventoryReportWriter + { + private sealed class InventoryViewModelMap : CsvClassMap + { + public InventoryViewModelMap() + { + Map(m => m.Name).Name("Name of Commodity"); + Map(m => m.UnitsPerCase).Name("Units per Case"); + Map(m => m.ContainerType).Name("Container Type"); + Map(m => m.Quantity).Name("Case Quantity"); + Map(m => m.ExpirationDate).Name("Expiration Date"); + Map(m => m.AddedDate).Name("Added Date"); + Map(m => m.Memo).Name("Memo"); + Map(m => m.WeightPerCase).Name("Weight per Case"); + Map(m => m.PricePerCase).Name("Price per Case"); + } + } + + public byte[] Write(IEnumerable items) + { + using (var stream = new MemoryStream()) + { + WriteStream(items, stream); + return stream.ToArray(); + } + } + + public void WriteStream(IEnumerable items, Stream stream) + { + using (var workbook = new XLWorkbook(XLEventTracking.Disabled)) + { + var worksheet = workbook.AddWorksheet("Current Inventory"); + using (var writer = new CsvWriter(new ExcelSerializer(worksheet))) + { + writer.Configuration.RegisterClassMap(new InventoryViewModelMap()); + writer.WriteRecords(items.OrderBy(i => i.Name)); + workbook.SaveAs(stream); + } + } + } + } +} \ No newline at end of file diff --git a/InventoryTraker.Web/Utilities/InventoryTypeReportWriter.cs b/InventoryTraker.Web/Utilities/InventoryTypeReportWriter.cs new file mode 100644 index 0000000..a36b376 --- /dev/null +++ b/InventoryTraker.Web/Utilities/InventoryTypeReportWriter.cs @@ -0,0 +1,50 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; +using ClosedXML.Excel; +using CsvHelper; +using CsvHelper.Configuration; +using CsvHelper.Excel; +using InventoryTraker.Web.Models; + +namespace InventoryTraker.Web.Utilities +{ + public class InventoryTypeReportWriter + { + private sealed class InventoryTypeViewModelMap : CsvClassMap + { + public InventoryTypeViewModelMap() + { + Map(m => m.Identifier).Name("Identifier"); + Map(m => m.Name).Name("Name of Commodity"); + Map(m => m.UnitsPerCase).Name("Units per Case"); + Map(m => m.ContainerType).Name("Container Type"); + Map(m => m.WeightPerCase).Name("Weight per Case"); + Map(m => m.PricePerCase).Name("Price per Case"); + } + } + + public byte[] Write(IEnumerable items) + { + using (var stream = new MemoryStream()) + { + WriteStream(items, stream); + return stream.ToArray(); + } + } + + public void WriteStream(IEnumerable items, Stream stream) + { + using (var workbook = new XLWorkbook(XLEventTracking.Disabled)) + { + var worksheet = workbook.AddWorksheet("Commodity Types"); + using (var writer = new CsvWriter(new ExcelSerializer(worksheet))) + { + writer.Configuration.RegisterClassMap(new InventoryTypeViewModelMap()); + writer.WriteRecords(items.OrderBy(i => i.Name)); + workbook.SaveAs(stream); + } + } + } + } +} \ No newline at end of file diff --git a/InventoryTraker.Web/Views/Inventory/Index.cshtml b/InventoryTraker.Web/Views/Inventory/Index.cshtml index e7f2063..e603bbd 100644 --- a/InventoryTraker.Web/Views/Inventory/Index.cshtml +++ b/InventoryTraker.Web/Views/Inventory/Index.cshtml @@ -10,6 +10,7 @@
Commodity Types diff --git a/InventoryTraker.Web/Views/InventoryType/Index.cshtml b/InventoryTraker.Web/Views/InventoryType/Index.cshtml index b1b5fe7..1f9e0cd 100644 --- a/InventoryTraker.Web/Views/InventoryType/Index.cshtml +++ b/InventoryTraker.Web/Views/InventoryType/Index.cshtml @@ -10,7 +10,8 @@
Add -
+ Export +
\ No newline at end of file diff --git a/InventoryTraker.Web/js/inventory/InventoryListController.js b/InventoryTraker.Web/js/inventory/InventoryListController.js index 5bd24cc..993666e 100644 --- a/InventoryTraker.Web/js/inventory/InventoryListController.js +++ b/InventoryTraker.Web/js/inventory/InventoryListController.js @@ -3,14 +3,14 @@ window.app.controller('InventoryListController', InventoryListController); - InventoryListController.$inject = ['$uibModal', 'inventorySvc']; - function InventoryListController($uibModal, inventorySvc) { + InventoryListController.$inject = ['$uibModal', 'inventorySvc', 'downloadSvc']; + function InventoryListController($uibModal, inventorySvc, downloadSvc) { var vm = this; vm.add = add; vm.distribute = distribute; vm.inventories = inventorySvc.inventories; - + function add() { $uibModal.open({ template: '', @@ -24,5 +24,10 @@ backdrop: 'static' }); } + + vm.export = function () { + inventorySvc.exportInventory() + .success(downloadSvc.success); + } } })(); \ No newline at end of file diff --git a/InventoryTraker.Web/js/inventory/inventorySvc.js b/InventoryTraker.Web/js/inventory/inventorySvc.js index 603ae72..212e9d4 100644 --- a/InventoryTraker.Web/js/inventory/inventorySvc.js +++ b/InventoryTraker.Web/js/inventory/inventorySvc.js @@ -15,7 +15,8 @@ inventories: inventories, get: get, refresh: refresh, - find: find + find: find, + exportInventory: exportInventory }; return svc; @@ -27,6 +28,10 @@ }); } + function exportInventory() { + return $http.post('/Inventory/Export', {}, { responseType: 'arraybuffer' }); + } + function add(inventory) { return $http.post('/Inventory/Add', inventory) .success(function(inventory) { diff --git a/InventoryTraker.Web/js/inventoryType/InventoryTypeController.js b/InventoryTraker.Web/js/inventoryType/InventoryTypeController.js index 1cce01c..7722957 100644 --- a/InventoryTraker.Web/js/inventoryType/InventoryTypeController.js +++ b/InventoryTraker.Web/js/inventoryType/InventoryTypeController.js @@ -3,8 +3,8 @@ window.app.controller('InventoryTypeController', InventoryTypeController); - InventoryTypeController.$inject = ['$uibModal', 'inventoryTypeSvc']; - function InventoryTypeController($uibModal, inventoryTypeSvc) { + InventoryTypeController.$inject = ['$uibModal', 'inventoryTypeSvc', 'downloadSvc']; + function InventoryTypeController($uibModal, inventoryTypeSvc, downloadSvc) { var vm = this; vm.add = add; @@ -24,5 +24,10 @@ backdrop: 'static' }); } + + vm.export = function () { + inventoryTypeSvc.exportInventoryTypes() + .success(downloadSvc.success); + } } })(); \ No newline at end of file diff --git a/InventoryTraker.Web/js/inventoryType/inventoryTypeSvc.js b/InventoryTraker.Web/js/inventoryType/inventoryTypeSvc.js index 138cecb..432653c 100644 --- a/InventoryTraker.Web/js/inventoryType/inventoryTypeSvc.js +++ b/InventoryTraker.Web/js/inventoryType/inventoryTypeSvc.js @@ -10,7 +10,8 @@ var svc = { add: add, update: update, - inventoryTypes: inventoryTypes + inventoryTypes: inventoryTypes, + exportInventoryTypes: exportInventoryTypes }; return svc; @@ -22,6 +23,10 @@ }); } + function exportInventoryTypes() { + return $http.post('/InventoryType/Export', {}, { responseType: 'arraybuffer' }); + } + function add(inventoryType) { return $http.post('/InventoryType/Add', inventoryType) .success(function (inventoryType) {