174 lines
5.2 KiB
C#
174 lines
5.2 KiB
C#
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<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; }
|
|
}
|
|
}
|
|
} |