Export Distribution report
This commit is contained in:
@@ -27,6 +27,29 @@ namespace InventoryTraker.Web.Controllers
|
||||
}
|
||||
|
||||
public ActionResult Distribution(DateTime startDate, DateTime endDate)
|
||||
{
|
||||
var report = GetDistributionReport(startDate, endDate);
|
||||
|
||||
return BetterJson(report.ToArray());
|
||||
}
|
||||
|
||||
public ActionResult DistributionExcel(DateTime startDate, DateTime endDate)
|
||||
{
|
||||
var report = GetDistributionReport(startDate, endDate);
|
||||
|
||||
var writer = new DistributionReportWriter();
|
||||
var excel = writer.Write(report);
|
||||
|
||||
var filename = $"InventoryDistributionReport{startDate:yyyyMMdd}-{endDate:yyyyMMdd}.xlsx";
|
||||
|
||||
return
|
||||
new FileContentResult(excel, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
|
||||
{
|
||||
FileDownloadName = filename
|
||||
};
|
||||
}
|
||||
|
||||
private DistributionReport[] GetDistributionReport(DateTime startDate, DateTime endDate)
|
||||
{
|
||||
var query =
|
||||
from t in _context.Transactions
|
||||
@@ -54,7 +77,7 @@ namespace InventoryTraker.Web.Controllers
|
||||
(item.Transactions).ToArray()
|
||||
};
|
||||
|
||||
return BetterJson(report.ToArray());
|
||||
return report.ToArray();
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
@@ -196,16 +219,16 @@ namespace InventoryTraker.Web.Controllers
|
||||
};
|
||||
return inventoryTypeReportItems;
|
||||
}
|
||||
}
|
||||
|
||||
internal 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; }
|
||||
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; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -390,6 +390,7 @@
|
||||
<Compile Include="Utilities\InventoryTypeParser.cs" />
|
||||
<Compile Include="Utilities\DateExtensions.cs" />
|
||||
<Compile Include="Utilities\JsonExtensions.cs" />
|
||||
<Compile Include="Utilities\DistributionReportWriter.cs" />
|
||||
<Compile Include="Utilities\MovementReportWriter.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using AutoMapper;
|
||||
using ClosedXML.Excel;
|
||||
using CsvHelper;
|
||||
using CsvHelper.Configuration;
|
||||
using CsvHelper.Excel;
|
||||
using Heroic.AutoMapper;
|
||||
using InventoryTraker.Web.Models;
|
||||
|
||||
namespace InventoryTraker.Web.Utilities
|
||||
{
|
||||
public class DistributionReportWriter
|
||||
{
|
||||
public class DistributionReportExportItem : IMapFrom<TransactionViewModel>, IHaveCustomMappings
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string UnitsPerCaseContainerType { get; set; }
|
||||
public string ExpirationDate { get; set; }
|
||||
public string RemovedQuantity { get; set; }
|
||||
public string UnitQuantity { get; set; }
|
||||
public string Weight { get; set; }
|
||||
|
||||
public void CreateMappings(IMapperConfiguration configuration)
|
||||
{
|
||||
configuration.CreateMap<TransactionViewModel, DistributionReportExportItem>()
|
||||
.ForMember(d => d.Name, opt => opt.MapFrom(i => i.Name))
|
||||
.ForMember(d => d.UnitsPerCaseContainerType,
|
||||
opt => opt.MapFrom(i => $"{i.UnitsPerCase} / {i.ContainerType}"))
|
||||
.ForMember(d => d.ExpirationDate,
|
||||
opt => opt.MapFrom(i => i.ExpirationDate.ToShortDateString()))
|
||||
.ForMember(d => d.UnitQuantity,
|
||||
opt => opt.MapFrom(i => i.RemovedQuantity*i.UnitsPerCase))
|
||||
.ForMember(d => d.Weight,
|
||||
opt => opt.MapFrom(i => $"{i.WeightPerCase*i.RemovedQuantity:0} lbs"));
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class DistributionReportMap : CsvClassMap<DistributionReportExportItem>
|
||||
{
|
||||
public DistributionReportMap()
|
||||
{
|
||||
Map(m => m.Name).Name("Name of Commodity");
|
||||
Map(m => m.UnitsPerCaseContainerType).Name("Pack Size / Units per Case");
|
||||
Map(m => m.ExpirationDate).Name("Expiration Date");
|
||||
Map(m => m.RemovedQuantity).Name("Case Quantity");
|
||||
Map(m => m.UnitQuantity).Name("Unit Quantity");
|
||||
Map(m => m.Weight).Name("Weight");
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] Write(IEnumerable<DistributionReport> reports)
|
||||
{
|
||||
using (var stream = new MemoryStream())
|
||||
{
|
||||
WriteStream(reports, stream);
|
||||
return stream.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteStream(IEnumerable<DistributionReport> reports, Stream stream)
|
||||
{
|
||||
using (var workbook = new XLWorkbook(XLEventTracking.Disabled))
|
||||
{
|
||||
var worksheet = workbook.AddWorksheet("Distribution Report");
|
||||
using (var writer = new CsvWriter(new ExcelSerializer(worksheet)))
|
||||
{
|
||||
writer.Configuration.RegisterClassMap(new DistributionReportMap());
|
||||
|
||||
foreach (var report in reports)
|
||||
{
|
||||
writer.WriteField(report.Destination);
|
||||
writer.NextRecord();
|
||||
writer.WriteField(report.Date.ToShortDateString());
|
||||
writer.NextRecord();
|
||||
var items =
|
||||
Mapper.Map<IEnumerable<TransactionViewModel>, IEnumerable<DistributionReportExportItem>>
|
||||
(report.Transactions)
|
||||
.OrderBy(i => i.Name);
|
||||
writer.WriteRecords(items);
|
||||
}
|
||||
workbook.SaveAs(stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -93,9 +93,6 @@ namespace InventoryTraker.Web.Utilities
|
||||
|
||||
public void WriteStream(MovementReport report, Stream stream)
|
||||
{
|
||||
var csvConfiguration = new CsvConfiguration();
|
||||
csvConfiguration.RegisterClassMap<MovementReportMap>();
|
||||
|
||||
using (var workbook = new XLWorkbook(XLEventTracking.Disabled))
|
||||
{
|
||||
var worksheet = workbook.AddWorksheet("Monthly Inventory Report");
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
<div class="panel-body">
|
||||
<date-range-query query-fn="vm.loadData"></date-range-query>
|
||||
</div>
|
||||
<div class="panel-footer" ng-show="vm.distributionData.length">
|
||||
<button ng-click="vm.export(vm.query)"><i class="fa fa-file-excel-o" aria-hidden="true"></i> Export</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,10 +3,15 @@
|
||||
|
||||
window.app.controller('DistributionReportController', DistributionReportController);
|
||||
|
||||
DistributionReportController.$inject = ['$scope', 'reportSvc'];
|
||||
function DistributionReportController($scope, reportSvc) {
|
||||
DistributionReportController.$inject = ['$scope', 'reportSvc', 'downloadSvc'];
|
||||
function DistributionReportController($scope, reportSvc, downloadSvc) {
|
||||
var vm = this;
|
||||
vm.loadData = reportSvc.loadDistributionReport;
|
||||
vm.query = reportSvc.distributionQuery;
|
||||
vm.distributionData = reportSvc.distributionData;
|
||||
vm.export = function (params) {
|
||||
reportSvc.exportDistributionReport(params)
|
||||
.success(downloadSvc.success);
|
||||
}
|
||||
}
|
||||
})();
|
||||
@@ -4,11 +4,14 @@
|
||||
reportSvc.$inject = ['$http'];
|
||||
function reportSvc($http) {
|
||||
var distributionData = [];
|
||||
var distributionQuery = {};
|
||||
var movementData = {};
|
||||
|
||||
var svc = {
|
||||
distributionData: distributionData,
|
||||
distributionQuery: distributionQuery,
|
||||
loadDistributionReport: loadDistributionReport,
|
||||
exportDistributionReport: exportDistributionReport,
|
||||
movementData: movementData,
|
||||
loadMovementData: loadMovementData,
|
||||
exportMovementData: exportMovementData
|
||||
@@ -19,10 +22,15 @@
|
||||
function loadDistributionReport(query) {
|
||||
return $http.post('/Report/Distribution', query)
|
||||
.success(function (data) {
|
||||
distributionQuery = angular.copy(query, distributionQuery);
|
||||
angular.copy(data, distributionData);
|
||||
});
|
||||
}
|
||||
|
||||
function exportDistributionReport(query) {
|
||||
return $http.post('/Report/DistributionExcel', query, { responseType: 'arraybuffer' });
|
||||
}
|
||||
|
||||
function loadMovementData(query) {
|
||||
return $http.post('/Report/Movement', query)
|
||||
.success(function (data) {
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-md-3">Name</th>
|
||||
<th class="col-md-3">Units per Case</th>
|
||||
<th class="col-md-3">Name of Commodity</th>
|
||||
<th class="col-md-3">Units per Case / Container Type</th>
|
||||
<th class="col-md-2">Exp. Date</th>
|
||||
<th class="col-md-1">Case Qty</th>
|
||||
<th class="col-md-1">Unit Qty</th>
|
||||
@@ -19,7 +19,7 @@
|
||||
<td>{{transaction.expirationDate | date:'shortDate'}}</td>
|
||||
<td>{{transaction.removedQuantity}}</td>
|
||||
<td>{{transaction.removedQuantity * transaction.unitsPerCase}}</td>
|
||||
<td>{{transaction.weightPerCase * transaction.unitsPerCase | number:0 }} lbs</td>
|
||||
<td>{{transaction.weightPerCase * transaction.removedQuantity | number:0 }} lbs</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
Reference in New Issue
Block a user