I have a recurring pattern that I see in some of the reports that I have to generate. These reports are date range based reports and need to be aggregated by different levels.
For the sake of simplicity, let's assume that this report produces a title and a quota at the leaf node level (lowest level). At the line item level (which is a collection of various leaf nodes), I would like to aggregate the Quota and provide a separate title. These line items would further roll up to another level which would again aggregate the quota and have a unique title.
So the report would be something like this:
ROOT LEVEL | Title = "Main Report" | Quota = 100
Month Level | Title = "Jan" | Quota = 100
Week Level | Title = "Week 1" | Quota = 25
Week Level | Title = "Week 2" | Quota = 75
Is there way for me to build this using a composite pattern? I have tried numerous approaches. Most of them fall short because I cannot effectively aggregate/sum up the quota to the higher level.
I can build an interface like so:
public interface IInventoryReportItem
{
string Title { get; set; }
int Quota { get; set; }
}
Then I can build a Line Item like so:
public class LineItem : IInventoryReportItem
I can also build a collection like so:
public class LineItems : IList<IInventoryReportItem>, IInventoryReportItem
{
private readonly List<IInventoryReportItem> _subLineItems;
public LineItems()
{
_subLineItems = new List<IInventoryReportItem>();
}
And my report would be like so:
public class InventoryReport
{
public DateRange DateRange { get; set; }
public LineItems LineItems { get; set; }
}
I can build the report easily in a hierarchical fashion now, but I still need to call the aggregation functions from the outside as opposed to it auto-calculating this for me:
var report = new InventoryReport();
var week1Days = new LineItems
{
new LineItem {Quota = 20, Title = "Day 1"},
new LineItem {Quota = 10, Title = "Day 2"}
};
var week2Days = new LineItems
{
new LineItem {Quota = 10, Title = "Day 1"},
new LineItem {Quota = 10, Title = "Day 2"}
};
var week1 = new LineItems {week1Days};
week1.Quota = week1.Sum(x => x.Quota);
week1.Title = "Week1";
var week2 = new LineItems {week2Days};
week2.Quota = week2.Sum(x => x.Quota);
week2.Title = "Week2";
var month1 = new LineItems(new List<IInventoryReportItem> {week1, week2});
month1.Title = "January";
month1.Quota = month1.Sum(x => x.Quota);
report.LineItems = new LineItems(new List<IInventoryReportItem> {month1});
Is there a way I can still have the flexibility of adding either a single line item or a range of items, and it also auto-calculate/aggregate the data for me using the composite?
Any help would be great!
Thank You, Anup
Aucun commentaire:
Enregistrer un commentaire