Box modifications

This commit is contained in:
2016-10-18 11:10:01 -04:00
parent 3caf0bd766
commit fdc34c4ef7
109 changed files with 11033 additions and 2442 deletions
@@ -0,0 +1,24 @@
using System;
namespace InventoryTraker.Web.Services
{
public class ImportException : Exception
{
public readonly string[] Messages;
public ImportException(string message, Exception innerException) : base(message, innerException)
{
Messages = new[] { message };
}
public ImportException(string message) : base(message)
{
Messages = new [] {message};
}
public ImportException(string[] messages) : base(string.Join(Environment.NewLine, messages))
{
Messages = messages;
}
}
}
@@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using AutoMapper;
using CsvHelper;
using InventoryTraker.Web.Core;
using InventoryTraker.Web.Models;
using InventoryTraker.Web.Utilities;
namespace InventoryTraker.Web.Services
{
public class InventoryImporter
{
private readonly IMapper _mapper;
public InventoryImporter(IMapper mapper)
{
_mapper = mapper;
}
public IEnumerable<Inventory> Import(FileSystemInfo excelFile)
{
var inventoryParser = new InventoryParser(excelFile);
IList<InventoryAddForm> forms;
try
{
forms = inventoryParser.Parse();
}
catch (CsvMissingFieldException e)
{
var fieldname = Regex.Replace(e.Message, ".*'(.*)'.*", "$1");
throw new ImportException($"Cannot find required field titled '{fieldname}'", e);
}
//catch (CsvBadDataException e)
//{
// throw new ImportException(e.Message, e);
//}
//catch (CsvParserException e)
//{
// throw new ImportException(e.Message, e);
//}
//catch (CsvReaderException e)
//{
// throw new ImportException(e.Message, e);
//}
catch (Exception e)
{
throw new ImportException(e.Message, e);
}
IList<Inventory> inventories = new List<Inventory>();
var validationErrors = new List<string>();
foreach (var addForm in forms)
{
var results = new List<ValidationResult>();
var context = new ValidationContext(addForm, null, null);
if (!Validator.TryValidateObject(addForm, context, results))
{
// results will contain all the failed validation errors.
validationErrors.AddRange(
results.Select(result => $"{addForm.Id} - ${result.ErrorMessage}")
);
}
else
{
inventories.Add(_mapper.Map<Inventory>(addForm));
}
}
if (validationErrors.Any())
{
throw new ImportException(string.Join(Environment.NewLine, validationErrors));
}
return inventories;
}
}
}
@@ -1,176 +0,0 @@
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;
private readonly IMapper _mapper;
public ReportService(AppDbContext context, IMapper mapper)
{
_context = context;
_mapper = mapper;
}
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<Transaction>, IList<TransactionViewModel>>
(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<MovementReportItem> 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<InventoryTypeViewModel>(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; }
}
}
}