public static IEnumerable <StatementInfoWithFund> Statements(CMSDataContext db, int?id, int[] includedFundIds = null) { if (!id.HasValue) { throw new ArgumentException("Missing id"); } var person = db.LoadPersonById(id.Value); var contributions = (from c in db.Contributions2(new DateTime(1900, 1, 1), new DateTime(3000, 12, 31), 0, false, null, true, null) where (c.PeopleId == person.PeopleId || (c.PeopleId == person.SpouseId && (person.ContributionOptionsId ?? StatementOptionCode.Joint) == StatementOptionCode.Joint)) select c).ToList(); var currentUser = db.CurrentUserPerson; if (currentUser.PeopleId != person.PeopleId) { var authorizedFunds = db.ContributionFunds.ScopedByRoleMembership(db); var authorizedContributions = from c in contributions join f in authorizedFunds on c.FundId equals f.FundId select c; contributions = authorizedContributions.ToList(); } if (includedFundIds != null) { contributions = contributions.Where(c => includedFundIds.Contains(c.FundId)).ToList(); } var shouldGroupByFunds = db.Setting("EnableContributionFundsOnStatementDisplay"); IEnumerable <StatementInfoWithFund> result; if (shouldGroupByFunds) { result = (from c in contributions group c by new { c.DateX.Value.Year, c.FundName, c.FundId } into g orderby g.Key.Year descending, g.Key.FundName ascending select new StatementInfoWithFund() { Count = g.Count(), Amount = g.Sum(cc => cc.Amount ?? 0), StartDate = new DateTime(g.Key.Year, 1, 1), EndDate = new DateTime(g.Key.Year, 12, 31), FundName = g.Key.FundName, FundId = g.Key.FundId, FundGroupName = string.Empty }).ToList(); var displayNameHelper = new CustomFundSetDisplayHelper(db); displayNameHelper.ProcessList(result); // hack: grouping done in memory since these fundids are stored as XML and not easily accessed in SQL // task: FundGrouping table to avoid using XML for this data in the future with UI to make management easier? result = (from c in result group c by new { c.StartDate.Year, c.FundGroupName } into g orderby g.Key.Year descending, g.Key.FundGroupName ascending select new StatementInfoWithFund() { Count = g.Sum(cc => cc.Count), Amount = g.Sum(cc => cc.Amount), StartDate = new DateTime(g.Key.Year, 1, 1), EndDate = new DateTime(g.Key.Year, 12, 31), FundName = "", FundId = 0, FundGroupName = g.Key.FundGroupName }).ToList(); } else { result = (from c in contributions group c by new { c.DateX.Value.Year } into g orderby g.Key.Year descending select new StatementInfoWithFund() { Count = g.Count(), Amount = g.Sum(cc => cc.Amount ?? 0), StartDate = new DateTime(g.Key.Year, 1, 1), EndDate = new DateTime(g.Key.Year, 12, 31), FundName = string.Empty, FundId = 0 }).ToList(); } return(result); }