context: using CmsData.API;
  using CmsData.Codes;
  using System;
  using System.Linq;
  using System.Linq.Expressions;
  using System.Text.RegularExpressions;
  using UtilityExtensions;
  
  namespace CmsData
  {
      public partial class Condition
      {
          public User CurrentUser
          {
              get => db.CurrentUser;            
          }        
          public string[] Roles
          {
              get => db.CurrentUser.Roles;            
          }
          public bool ValidFinanceUser(CMSDataContext db1 = null)
          {
              db = db ?? db1;
              if (!db.FromBatch)
              {
                  if (CurrentUser == null || Roles.All(rr => rr != "Finance"))
                  {
                      return false;
                  }
              }
              return true;
          }
          private Expression RecentContributionCount2(int days, int fund, int cnt, bool taxnontax)
          {
              if (!ValidFinanceUser()) return AlwaysFalse();
  
              var now = Util.Now;
              var dt = now.AddDays(-days).Date;
              IQueryable<int> q = null;
              switch (op)
              {
                  case CompareType.Greater:
                      q = from c in db.Contributions2(dt, now, 0, false, taxnontax, true, null)
                          where fund == 0 || c.FundId == fund
                          where c.Amount > 0
                          group c by c.CreditGiverId into g
                          where g.Count() > cnt
                          select g.Key ?? 0;
                      break;
                  case CompareType.GreaterEqual:
                      q = from c in db.Contributions2(dt, now, 0, false, taxnontax, true, null)
                          where fund == 0 || c.FundId == fund
                          where c.Amount > 0 || cnt == 0
                          group c by c.CreditGiverId into g
                          where g.Count() >= cnt
                          select g.Key ?? 0;
                      break;
                  case CompareType.Less:
                      q = from c in db.Contributions2(dt, now, 0, false, taxnontax, true, null)
                          where fund == 0 || c.FundId == fund
                          where c.Amount > 0
                          group c by c.CreditGiverId into g
                          where g.Count() < cnt
                          select g.Key ?? 0;
                      break;
                  case CompareType.LessEqual:
                      q = from c in db.Contributions2(dt, now, 0, false, taxnontax, true, null)
                          where fund == 0 || c.FundId == fund
                          where c.Amount > 0
                          group c by c.CreditGiverId into g
                          where g.Count() <= cnt
                          select g.Key ?? 0;
                      break;
                  case CompareType.Equal:
                      //if (cnt == 0) // This is a very special case, use different approach
                      //{
                      //    q = from pid in db.Contributions0(dt, now, fund, 0, false, taxnontax, true)
                      //        select pid.PeopleId;
                      //    Expression<Func<Person, bool>> pred0 = p => q.Contains(p.PeopleId);
                      //    Expression expr0 = System.Linq.Expressions.Expression.Invoke(pred0, parm);
                      //    return expr0;
                      //}
                      q = from c in db.Contributions2(dt, now, 0, false, taxnontax, true, null)
                          where fund == 0 || c.FundId == fund
                          where c.Amount > 0
                          group c by c.CreditGiverId into g
                          where g.Count() == cnt
                          select g.Key ?? 0;
                      break;
                  case CompareType.NotEqual:
                      q = from c in db.Contributions2(dt, now, 0, false, taxnontax, true, null)
                          where fund == 0 || c.FundId == fund
                          where c.Amount > 0
                          group c by c.CreditGiverId into g
                          where g.Count() != cnt
                          select g.Key ?? 0;
                      break;
              }
              var tag = db.PopulateTemporaryTag(q);
              Expression<Func<Person, bool>> pred = p => p.Tags.Any(t => t.Id == tag.Id);
              Expression expr = Expression.Invoke(pred, parm);
              return expr;
          }
          public Expression IsRecentGiver()
          {
              if (!ValidFinanceUser()) return AlwaysFalse();
  
              var tf = CodeIds == "1";
              var fundid = Quarters.AllDigits() ? Quarters.ToInt2() : db.Setting(Quarters, "").ToInt2();
              var q = fundid > 0
                  ? db.RecentGiverFund(Days, fundid).Select(v => v.PeopleId.Value)
                  : db.RecentGiver(Days).Select(v => v.PeopleId.Value);
              var tag = db.PopulateTemporaryTag(q);
              Expression<Func<Person, bool>> pred = null;
  
              /*
               * if (op == CompareType.Equal ^ tf)
               * IS EQUIVALENT TO AND JUST A SIMPLER WAY TO SAY
               * if ((op == CompareType.NotEqual && tf == true) || (op == CompareType.Equal && tf == false))
               * IN OTHER WORDS (not equal true) IS THE SAME AS (equal false)
               */
              if (op == CompareType.Equal ^ tf)
              {
                  pred = p => !db.TagPeople.Where(vv => vv.Id == tag.Id).Select(vv => vv.PeopleId).Contains(p.PeopleId);
              }
              else
              {
                  pred = p => db.TagPeople.Where(vv => vv.Id == tag.Id).Select(vv => vv.PeopleId).Contains(p.PeopleId);
              }
  
              Expression expr = Expression.Invoke(pred, parm);
              return expr;
          }
          public Expression IsRecentGiverFunds()
          {
              if (!ValidFinanceUser()) return AlwaysFalse();
  
              var tf = CodeIds == "1";
              var fundcsv = APIContributionSearchModel.GetCustomFundSetList(db, FundSet);
              if (fundcsv == null)
              {
                  fundcsv = db.ContributionFunds.Select(cc => cc.FundId).ToList();                
              }
              //throw new Exception($"fundset '{Quarters}' was not found");
              var fundlist = string.Join(",", fundcsv);
  
              var q = db.RecentGiverFunds(Days, fundlist, TaxNonTaxBool).Select(v => v.PeopleId.Value);
              var tag = db.PopulateTemporaryTag(q);
              Expression<Func<Person, bool>> pred = null;
  
              if (op == CompareType.Equal ^ tf)
              {
                  pred = p => !db.TagPeople.Where(vv => vv.Id == tag.Id).Select(vv => vv.PeopleId).Contains(p.PeopleId);
              }
              else
              {
                  pred = p => db.TagPeople.Where(vv => vv.Id == tag.Id).Select(vv => vv.PeopleId).Contains(p.PeopleId);
              }
  
              Expression expr = Expression.Invoke(pred, parm);
              return expr;
          }
  
          public IQueryable<int> AddContribution0(IQueryable<int> q, int? fund, bool taxnontax, DateTime fd, DateTime td, CMSDataContext db1 = null)
          {
              db = db ?? db1;
              q = q ?? (from o in db.Contributions
                        where o.ContributionDate > DateTime.Now
                        select (int)o.PeopleId);
              IQueryable<int> q0 = null;
              q0 = from pid in db.Contributions0(fd, td, fund, 0, false, taxnontax, true)
                   select pid.PeopleId.Value;
              q = q.Union(q0);
              return q;
          }
          
          private Expression RecentContributionAmount2(int days, int fund, decimal amt, bool taxnontax)
          {
              if (!ValidFinanceUser()) return AlwaysFalse();
  
              var now = Util.Now;
              var dt = now.AddDays(-days).Date;            
              IQueryable<int> q = null;
              switch (op)
              {
                  case CompareType.Greater:
                      q = from c in db.Contributions2(dt, now, 0, false, taxnontax, true, null)
                          where fund == 0 || c.FundId == fund
                          group c by c.CreditGiverId into g
                          where g.Sum(cc => cc.Amount) > amt
                          select g.Key ?? 0;
                      break;
                  case CompareType.GreaterEqual:
                      q = from c in db.Contributions2(dt, now, 0, false, taxnontax, true, null)
                          where fund == 0 || c.FundId == fund
                          group c by c.CreditGiverId into g
                          where g.Sum(cc => cc.Amount) >= amt
                          select g.Key ?? 0;
                      if (amt == 0)
                      {                        
                          q = AddContribution0(q, fund, taxnontax, dt, now);
                      }
                      break;
                  case CompareType.Less:
                          q = from c in db.Contributions2(dt, now, 0, false, taxnontax, true, null)
                              where fund == 0 || c.FundId == fund
                              where c.Amount > 0
                              group c by c.CreditGiverId into g
                              where g.Sum(cc => cc.Amount) < amt
                              select g.Key ?? 0;
                          q = AddContribution0(q, fund, taxnontax, dt, now);
                      break;                    
                  case CompareType.LessEqual:                    
                      q = from c in db.Contributions2(dt, now, 0, false, taxnontax, true, null)
                              where fund == 0 || c.FundId == fund
                              where c.Amount > 0
                              group c by c.CreditGiverId into g
                              where g.Sum(cc => cc.Amount) <= amt
                              select g.Key ?? 0;
                      q = AddContribution0(q, fund, taxnontax, dt, now);
                      break;
                  case CompareType.Equal:
                      if (amt == 0)
                      {
                          q = from pid in db.Contributions0(dt, now, fund, 0, false, taxnontax, true)
                              select pid.PeopleId.Value;
                      }
                      else
                      {
                          q = from c in db.Contributions2(dt, now, 0, false, taxnontax, true, null)
                              where fund == 0 || c.FundId == fund
                              where c.Amount > 0
                              group c by c.CreditGiverId into g
                              where g.Sum(cc => cc.Amount) == amt
                              select g.Key ?? 0;
                      }
  
                      break;
                  case CompareType.NotEqual:
                      q = from c in db.Contributions2(dt, now, 0, false, taxnontax, true, null)
                          where fund == 0 || c.FundId == fund
                          where c.Amount > 0
                          group c by c.CreditGiverId into g
                          where g.Sum(cc => cc.Amount) != amt
                          select g.Key ?? 0;
                      break;
              }
              var tag = db.PopulateTemporaryTag(q);
              Expression<Func<Person, bool>> pred = p => p.Tags.Any(t => t.Id == tag.Id);
              Expression expr = Expression.Invoke(pred, parm);
              return expr;
          }
  
          public IQueryable<int> GetContributionList(CMSDataContext db, CompareType option, DateTime? start, DateTime? end, int? fund, decimal? amt, bool nontaxded, bool useCreditor = true)
          {            
              //Get a list of Contributions filtered by fund
              var donorOnlyList = from c in db.Contributions2(start, end, 0, false, nontaxded, true, null)
                                  where c.Amount > 0
                                  where fund == 0 || c.FundId == fund || fund == null
                                  select c;
              var donorSpouseList = from c in db.Contributions2(start, end, 0, false, nontaxded, true, null)
                                    where c.Amount > 0
                                    where fund == 0 || c.FundId == fund || fund == null
                                    where c.CreditGiverId2 != null
                                    select c;
              switch (option)
              {
                  case CompareType.GreaterEqual:
                      return !useCreditor ?
                          (from c in donorOnlyList
                           group c by c.CreditGiverId into g
                           where g.Sum(cc => cc.Amount) >= (decimal?)amt.ToDouble()
                           select g.Key ?? 0) :
                          (from c in donorOnlyList
                           group c by c.CreditGiverId into g
                           where g.Sum(cc => cc.Amount) >= (decimal?)amt.ToDouble()
                           select g.Key ?? 0)
                          .Concat(from c2 in donorSpouseList
                                  group c2 by c2.CreditGiverId2 into g
                                  where g.Sum(cc => cc.Amount) >= (decimal?)amt.ToDouble()
                                  select g.Key ?? 0);
                  case CompareType.Greater:
                      return !useCreditor ?
                          (from c in donorOnlyList
                           group c by c.CreditGiverId into g
                           where g.Sum(cc => cc.Amount) > (decimal?)amt.ToDouble()
                           select g.Key ?? 0) :
                          (from c in donorOnlyList
                           group c by c.CreditGiverId into g
                           where g.Sum(cc => cc.Amount) > (decimal?)amt.ToDouble()
                           select g.Key ?? 0)
                          .Concat(from c2 in donorSpouseList
                                  group c2 by c2.CreditGiverId2 into g
                                  where g.Sum(cc => cc.Amount) > (decimal?)amt.ToDouble()
                                  select g.Key ?? 0);
                  case CompareType.LessEqual:
                      return !useCreditor ?
                          (from c in donorOnlyList
                           group c by c.CreditGiverId into g
                           where g.Sum(cc => cc.Amount) <= (decimal?)amt.ToDouble()
                           select g.Key ?? 0) :
                          (from c in donorOnlyList
                           group c by c.CreditGiverId into g
                           where g.Sum(cc => cc.Amount) <= (decimal?)amt.ToDouble()
                           select g.Key ?? 0)
                          .Concat(from c2 in donorSpouseList
                                  group c2 by c2.CreditGiverId2 into g
                                  where g.Sum(cc => cc.Amount) <= (decimal?)amt.ToDouble()
                                  select g.Key ?? 0);
                  case CompareType.Less:
                      return !useCreditor ?
                          (from c in donorOnlyList
                           group c by c.CreditGiverId into g
                           where g.Sum(cc => cc.Amount) < (decimal?)amt.ToDouble()
                           select g.Key ?? 0) :
                          (from c in donorOnlyList
                           group c by c.CreditGiverId into g
                           where g.Sum(cc => cc.Amount) < (decimal?)amt.ToDouble()
                           select g.Key ?? 0)
                          .Concat(from c2 in donorSpouseList
                                  group c2 by c2.CreditGiverId2 into g
                                  where g.Sum(cc => cc.Amount) < (decimal?)amt.ToDouble()
                                  select g.Key ?? 0);
                  case CompareType.Equal:
                      if (amt == 0) // This is a special case, use different approach
                      {
                          return from pid in db.Contributions0(start, end, fund, 0, false, nontaxded, true)
                                 select pid.PeopleId.Value;
                      }
                      else
                      {
                          return !useCreditor ? (from c in donorOnlyList
                                                 group c by c.CreditGiverId into g
                                                 where g.Sum(cc => cc.Amount) == (decimal?)amt.ToDouble()
                                                 select g.Key ?? 0) :
                          (from c in donorOnlyList
                           group c by c.CreditGiverId into g
                           where g.Sum(cc => cc.Amount) == (decimal?)amt.ToDouble()
                           select g.Key ?? 0)
                          .Concat(from c2 in donorSpouseList
                                  group c2 by c2.CreditGiverId2 into g
                                  where g.Sum(cc => cc.Amount) == (decimal?)amt.ToDouble()
                                  select g.Key ?? 0);
                      }
                  case CompareType.NotEqual:
                      return !useCreditor ? (from c in donorOnlyList
                                             group c by c.CreditGiverId into g
                                             where g.Sum(cc => cc.Amount) != (decimal?)amt.ToDouble()
                                             select g.Key ?? 0) :
                          (from c in donorOnlyList
                           group c by c.CreditGiverId into g
                           where g.Sum(cc => cc.Amount) != (decimal?)amt.ToDouble()
                           select g.Key ?? 0)
                          .Concat(from c2 in donorSpouseList
                                  group c2 by c2.CreditGiverId2 into g
                                  where g.Sum(cc => cc.Amount) != (decimal?)amt.ToDouble()
                                  select g.Key ?? 0);
              }
              return null;
          }
  
          private Expression ContributionAmount2(DateTime? start, DateTime? end, int? fund, decimal? amt, bool nontaxded, bool useCreditor = true)
          {
              if (!ValidFinanceUser()) return AlwaysFalse();
  
              IQueryable<int> q = null;
              q = GetContributionList(db, op, start, end, fund, amt, nontaxded, useCreditor );
              var tag = db.PopulateTemporaryTag(q);
              Expression<Func<Person, bool>> pred = p => p.Tags.Any(t => t.Id == tag.Id);
              Expression expr = Expression.Invoke(pred, parm);
              return expr;
          }
  
          internal Expression RecentContributionCount()
          {
              if (!ValidFinanceUser()) return AlwaysFalse();
              var fund = Quarters.AllDigits() ? Quarters.ToInt() : db.Setting(Quarters, "").ToInt();
              var cnt = TextValue.ToInt();
              return RecentContributionCount2(Days, fund, cnt, false);
          }
  
          internal Expression RecentContributionAmount()
          {
              if (!ValidFinanceUser()) return AlwaysFalse();
  
              var fund = Quarters.AllDigits() ? Quarters.ToInt() : db.Setting(Quarters, "").ToInt();
              var amt = TextValue.ToDecimal() ?? 0;
              return RecentContributionAmount2(Days, fund, amt, false);
          }
  
          internal Expression RecentContributionAmountBothJoint()
          {
              if (!ValidFinanceUser()) return AlwaysFalse();
              var now = Util.Now;
              var dt = now.AddDays(-Days).Date;
              return ContributionAmountBothJoint(dt, now);
          }
  
          internal Expression ContributionAmountBothJointHistory()
          {
              if (!ValidFinanceUser()) return AlwaysFalse();
              return ContributionAmountBothJoint(StartDate, EndDate);
          }
  
          internal Expression ContributionAmountSinceSetting()
          {
              if (!ValidFinanceUser()) return AlwaysFalse();
              var re = new Regex(@"(?<name>[^,]*)(,\s*(?<fundid>.+))?");
              var m = re.Match(Quarters);
              var name = m.Groups["name"].Value;
              var fundid = m.Groups["fundid"].Value;
              var fund = fundid.AllDigits() ? fundid.ToInt2() : db.Setting(fundid, "").ToInt2();
  
              var startdt = db.Setting(name, "").ToDate();
              var enddt = DateTime.Today.AddDays(1);
  
              return ContributionAmountBothJoint(startdt, enddt, fund);
          }
  
          private Expression ContributionAmountBothJoint(DateTime? startdt, DateTime? enddt, int? fundid = null)
          {
              if (!ValidFinanceUser()) return AlwaysFalse();
  
              var amt = TextValue.ToDecimal() ?? 0;
              var fund = fundid ?? (Quarters.AllDigits() ? Quarters.ToInt2() : db.Setting(Quarters, "").ToInt2());
                          
              IQueryable<int> q = null;
              switch (op)
              {
                  case CompareType.Greater:
                      q = from c in db.GetContributionTotalsBothIfJoint(startdt, enddt, fund)
                          where c.Amount > amt
                          select c.PeopleId.Value;
                      break;
                  case CompareType.GreaterEqual:
                      q = from c in db.GetContributionTotalsBothIfJoint(startdt, enddt, fund)
                          where c.Amount >= amt
                          select c.PeopleId.Value;
                      if (amt == 0)
                      {
                          q = AddContribution0(q, fund, false, (DateTime)startdt, (DateTime)enddt);
                      }
                      break;
                  case CompareType.Less:
                      q = from c in db.GetContributionTotalsBothIfJoint(StartDate, enddt, fund)
                          where c.Amount > 0
                          where c.Amount <= amt
                          select c.PeopleId.Value;
                      q = AddContribution0(q, fund, false, (DateTime)startdt, (DateTime)enddt);
                      break;
                  case CompareType.LessEqual:
                      q = from c in db.GetContributionTotalsBothIfJoint(startdt, enddt, fund)
                          where c.Amount > 0
                          where c.Amount <= amt
                          select c.PeopleId.Value;
                      q = AddContribution0(q, fund, false, (DateTime)startdt, (DateTime)enddt);
                      break;
                  case CompareType.Equal:
                      if (amt == 0)
                      {
                          q = from pid in db.Contributions0(startdt, enddt, fund, 0, false, false, true)
                              select pid.PeopleId.Value;                        
                      }
                      else
                      {
                          q = from c in db.GetContributionTotalsBothIfJoint(startdt, enddt, fund)
                              where c.Amount > 0
                              where c.Amount == amt
                              select c.PeopleId.Value;
                      }
  
                      break;
                  case CompareType.NotEqual:
                      q = from c in db.GetContributionTotalsBothIfJoint(startdt, enddt, fund)
                          where c.Amount > 0
                          where c.Amount != amt
                          select c.PeopleId.Value;
                      break;
              }
              var tag = db.PopulateTemporaryTag(q);
              Expression<Func<Person, bool>> pred = p => p.Tags.Any(t => t.Id == tag.Id);
              Expression expr = Expression.Invoke(pred, parm);
              return expr;
          }
  
          internal Expression RecentPledgeAmountBothJoint()
          {
              if (!ValidFinanceUser()) return AlwaysFalse();
  
              var now = Util.Now;
              var dt = now.AddDays(-Days).Date;
              return PledgeAmountBothJoint(dt, now);
          }
  
          internal Expression PledgeAmountBothJointHistory()
          {
              if (!ValidFinanceUser()) return AlwaysFalse();
  
              DateTime? enddt = null;
              if (!EndDate.HasValue && StartDate.HasValue)
              {
                  enddt = StartDate.Value.AddHours(24);
              }
  
              if (EndDate.HasValue)
              {
                  enddt = EndDate.Value.AddHours(24);
              }
  
              return PledgeAmountBothJoint(StartDate, enddt);
          }
  
          private Expression PledgeAmountBothJoint(DateTime? startdt, DateTime? enddt)
          {
              if (!ValidFinanceUser()) return AlwaysFalse();
  
              var amt = TextValue.ToDecimal() ?? 0;
              var fund = Quarters.AllDigits() ? Quarters.ToInt() : db.Setting(Quarters, "").ToInt();
  
              IQueryable<int> q = null;
              switch (op)
              {
                  case CompareType.Greater:
                      q = from c in db.GetPledgedTotalsBothIfJoint(startdt, enddt, fund)
                          where c.PledgeAmount > amt
                          select c.PeopleId.Value;
                      break;
                  case CompareType.GreaterEqual:
                      q = from c in db.GetPledgedTotalsBothIfJoint(startdt, enddt, fund)
                          where c.PledgeAmount.Value >= amt
                          select c.PeopleId.Value;
                      break;
                  case CompareType.Less:
                      q = from c in db.GetPledgedTotalsBothIfJoint(startdt, enddt, fund)
                          where c.PledgeAmount.Value > 0
                          where c.PledgeAmount.Value <= amt
                          select c.PeopleId.Value;
                      break;
                  case CompareType.LessEqual:
                      q = from c in db.GetPledgedTotalsBothIfJoint(startdt, enddt, fund)
                          where c.PledgeAmount.Value > 0
                          where c.PledgeAmount.Value <= amt
                          select c.PeopleId.Value;
                      break;
                  case CompareType.Equal:
                      if (amt == 0)
                      {
                          q = from pid in db.Pledges0(startdt, enddt, fund, 0)
                              select pid.PeopleId;
                      }
                      else
                      {
                          q = from c in db.GetPledgedTotalsBothIfJoint(startdt, enddt, fund)
                              where c.PledgeAmount.Value > 0
                              where c.PledgeAmount.Value == amt
                              select c.PeopleId.Value;
                      }
  
                      break;
                  case CompareType.NotEqual:
                      q = from c in db.GetPledgedTotalsBothIfJoint(startdt, enddt, fund)
                          where c.PledgeAmount.Value > 0
                          where c.PledgeAmount.Value != amt
                          select c.PeopleId.Value;
                      break;
              }
              var tag = db.PopulateTemporaryTag(q);
              Expression<Func<Person, bool>> pred = p => p.Tags.Any(t => t.Id == tag.Id);
              Expression expr = Expression.Invoke(pred, parm);
              return expr;
          }
  
          internal Expression PledgeBalance()
          {
              if (!ValidFinanceUser()) return AlwaysFalse();
              
              var amt = TextValue.ToDecimal() ?? 0;
              var fund = Quarters.AllDigits() ? Quarters.ToInt() : db.Setting(Quarters, "").ToInt();
  
              var startdt = DateTime.Parse("1/1/1900");
              var enddt = DateTime.Parse("1/1/2500");
  
              IQueryable<int> q = null;
              switch (op)
              {
                  case CompareType.Greater:
                      q = from c in db.GetPledgedTotalsBothIfJoint(startdt, enddt, fund)
                          where c.Balance > amt
                          select c.PeopleId.Value;
                      break;
                  case CompareType.GreaterEqual:
                      q = from c in db.GetPledgedTotalsBothIfJoint(startdt, enddt, fund)
                          where c.Balance >= amt
                          select c.PeopleId.Value;
                      break;
                  case CompareType.Less:
                      q = from c in db.GetPledgedTotalsBothIfJoint(startdt, enddt, fund)
                          where c.Balance < amt
                          select c.PeopleId.Value;
                      break;
                  case CompareType.LessEqual:
                      q = from c in db.GetPledgedTotalsBothIfJoint(startdt, enddt, fund)
                          where c.Balance <= amt
                          select c.PeopleId.Value;
                      break;
                  case CompareType.Equal:
                      q = from c in db.GetPledgedTotalsBothIfJoint(startdt, enddt, fund)
                          where c.Balance == amt
                          select c.PeopleId.Value;
                      break;
                  case CompareType.NotEqual:
                      q = from c in db.GetPledgedTotalsBothIfJoint(startdt, enddt, fund)
                          where c.Balance != amt
                          select c.PeopleId.Value;
                      break;
              }
              var tag = db.PopulateTemporaryTag(q);
              Expression<Func<Person, bool>> pred = p => p.Tags.Any(t => t.Id == tag.Id);
              Expression expr = Expression.Invoke(pred, parm);
              return expr;
          }
  
          internal Expression RecentNonTaxDedCount()
          {
              if (!ValidFinanceUser()) return AlwaysFalse();
  
              var fund = Quarters.ToInt();
              var cnt = TextValue.ToInt();
  
gt:             return RecentContributionCount2(Days, fund, cnt, true);