From 307aa50f5d64777a32175a7784be8fd55a63b978 Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Tue, 2 Feb 2021 23:01:48 +0000 Subject: [PATCH] --- .../DataListSqlFilterCriteriaBuilder.cs | 384 ++++++++++++++++++ 1 file changed, 384 insertions(+) diff --git a/server/AyaNova/DataList/DataListSqlFilterCriteriaBuilder.cs b/server/AyaNova/DataList/DataListSqlFilterCriteriaBuilder.cs index 4416489f..55469986 100644 --- a/server/AyaNova/DataList/DataListSqlFilterCriteriaBuilder.cs +++ b/server/AyaNova/DataList/DataListSqlFilterCriteriaBuilder.cs @@ -426,6 +426,390 @@ namespace AyaNova.DataList //listOptions.ClientTimeStamp.DateTime contains the exact client time and date as expected //################################################################################################################## + + +/* +Last working server date token filter code from revision 2612 feb 7 2020 + + + //HOWEVER, if it's a relative date filter TOKEN like "nextMonth" then the users time zone offset will be taken into consideration + + //So this is the core date time to work off of + DateTime RelativeToday = DateTime.Today; + DateTime RelativeNow = DateTime.Now; + // ILogger log = AyaNova.Util.ApplicationLogging.CreateLogger("FilterSqlCriteriaBuilder::DataFilterToColumnCriteria"); + // log.LogInformation("RelativeToday (before adjustment):"); + // log.LogInformation(RelativeToday.ToString()); + // log.LogInformation("RelativeNow (before adjustment):"); + // log.LogInformation(RelativeNow.ToString()); + + + if (sValue.StartsWith("{[") && sValue.EndsWith("]}")) + { + + + //Need to adjust RelativeToday to users time frame + //Fetch useroptions object and relative time offset + //See servers spec doc core-locale-currency-numbers-time-and-dates.txt for details about why this is necessary to be done this way + AyaNova.Models.AyContext ct = AyaNova.Util.ServiceProviderProvider.DBContext; + var u = ct.User.AsNoTracking().Where(a => a.Id == userId).Select(m => new { tz = m.UserOptions.TimeZoneOffset }).First(); + + //Add this value to any time's hours to convert to user local time + Double TimeZoneAdjustment = ((double)u.tz) * -1; + + //Stock times used for many of the tokens: + RelativeToday = RelativeToday.AddHours(TimeZoneAdjustment);//flip the sign to adjust towards UTC + RelativeNow = RelativeNow.AddHours(TimeZoneAdjustment);//flip the sign to adjust towards UTC + + //TESTING: + //LOG THE CRIT AND QUERY + // ILogger log = AyaNova.Util.ApplicationLogging.CreateLogger("FilterSqlCriteriaBuilder::DataFilterToColumnCriteria"); + // log.LogInformation("RelativeToday (adjusted):"); + // log.LogInformation(RelativeToday.ToString()); + // log.LogInformation("RelativeNow (adjusted):"); + // log.LogInformation(RelativeNow.ToString()); + // log.LogInformation("Offset used:"); + // log.LogInformation(u.tz.ToString()); + + #region Build criteria for date RANGE TOKEN specified + //Used as the basis point + System.DateTime dtAfter; + System.DateTime dtBefore; + switch (sValue) + { + //Case 402 + case DataListFilterSpecialToken.Yesterday: + //Between Day before yesterday at midnight and yesterday at midnight + dtAfter = RelativeToday.AddDays(-1); + dtAfter = dtAfter.AddSeconds(-1); + dtBefore = RelativeToday;//.AddDays(-1); + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + + case DataListFilterSpecialToken.Today: + //Between yesterday at midnight and tommorow at midnight + dtAfter = RelativeToday.AddSeconds(-1); + dtBefore = RelativeToday.AddDays(1); + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + case DataListFilterSpecialToken.Tomorrow: + //Between Tonight at midnight and day after tommorow at midnight + dtAfter = RelativeToday.AddDays(1); + dtAfter = dtAfter.AddSeconds(-1); + dtBefore = RelativeToday.AddDays(2); + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + + //Case 402 + case DataListFilterSpecialToken.LastWeek: + //Between two Sundays ago at midnight and last sunday at midnight + dtAfter = RelativeToday; + + //go back a week + dtAfter = dtAfter.AddDays(-7); + + //go backwards to Sunday + while (dtAfter.DayOfWeek != DayOfWeek.Sunday) + dtAfter = dtAfter.AddDays(-1); + + //go to very start of eighth dayahead + dtBefore = dtAfter.AddDays(8); + + dtAfter = dtAfter.AddSeconds(-1); + + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + + + case DataListFilterSpecialToken.ThisWeek: + //Between Sunday at midnight and Next sunday at midnight + dtAfter = RelativeToday; + //go backwards to monday + while (dtAfter.DayOfWeek != DayOfWeek.Monday) + dtAfter = dtAfter.AddDays(-1); + + //Now go back to sunday last second + dtAfter = dtAfter.AddSeconds(-1); + + + + dtBefore = RelativeToday; + //go forwards to monday + if (RelativeToday.DayOfWeek == DayOfWeek.Monday) + { + //Monday today? then go to next monday + dtBefore = dtBefore.AddDays(7); + } + else + { + while (dtBefore.DayOfWeek != DayOfWeek.Monday) + dtBefore = dtBefore.AddDays(1); + } + + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + case DataListFilterSpecialToken.NextWeek: + //Between Next Sunday at midnight and Next Next sunday at midnight + dtAfter = RelativeToday; + + //If today is monday skip over it first + if (dtAfter.DayOfWeek == DayOfWeek.Monday) + dtAfter = dtAfter.AddDays(1); + + //go forwards to next monday + while (dtAfter.DayOfWeek != DayOfWeek.Monday) + dtAfter = dtAfter.AddDays(1); + + //Now go back to sunday last second + dtAfter = dtAfter.AddDays(-1); + + //go seven days ahead + dtBefore = dtAfter.AddDays(7); + + //case 1155 + dtAfter = dtAfter.AddSeconds(-1); + + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + case DataListFilterSpecialToken.LastMonth: + //start with the first day of this month + dtAfter = new DateTime(RelativeToday.Year, RelativeToday.Month, 1, RelativeToday.Hour, RelativeToday.Minute, 00); + //subtract a Month + dtAfter = dtAfter.AddMonths(-1); + + //Add one month to dtAfter to get end date + dtBefore = dtAfter.AddMonths(1); + + //case 1155 + dtAfter = dtAfter.AddSeconds(-1); + + // 'yyyy-mm-ddTHH:MM:SS' + + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + case DataListFilterSpecialToken.ThisMonth: + //start with the first day of this month + dtAfter = new DateTime(RelativeToday.Year, RelativeToday.Month, 1, RelativeToday.Hour, RelativeToday.Minute, 00); + + //Add one month to dtAfter to get end date + dtBefore = dtAfter.AddMonths(1); + + //case 1155 + dtAfter = dtAfter.AddSeconds(-1); + + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + + case DataListFilterSpecialToken.NextMonth: + //start with the first day of this month + dtAfter = new DateTime(RelativeToday.Year, RelativeToday.Month, 1, RelativeToday.Hour, RelativeToday.Minute, 00); + //Add a Month + dtAfter = dtAfter.AddMonths(1); + + //Add one month to dtAfter to get end date + dtBefore = dtAfter.AddMonths(1); + + //case 1155 + dtAfter = dtAfter.AddSeconds(-1); + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + case DataListFilterSpecialToken.FourteenDayWindow: + //start with today zero hour + dtAfter = new DateTime(RelativeToday.Year, RelativeToday.Month, RelativeToday.Day, RelativeToday.Hour, RelativeToday.Minute, 00); + dtAfter = dtAfter.AddDays(-7); + + //Add 15 days to get end date (zero hour so not really 15 full days) + dtBefore = dtAfter.AddDays(15); + + //case 1155 + dtAfter = dtAfter.AddSeconds(-1); + + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + + + //case 2067 ADDITIONAL DATE RANGES ************ + + case DataListFilterSpecialToken.Past: + //Forever up to Now + dtAfter = new DateTime(1753, 1, 2, 00, 00, 00); + dtBefore = DateTime.UtcNow; + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + + case DataListFilterSpecialToken.Future: + //From Now to forever (999 years from now) + dtAfter = DateTime.UtcNow; + dtBefore = DateTime.UtcNow.AddYears(999); + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + + case DataListFilterSpecialToken.LastYear: + //From zero hour january 1 a year ago + dtAfter = new DateTime(RelativeNow.AddYears(-1).Year, 1, 1, 0, 0, 00).AddSeconds(-1).AddHours(TimeZoneAdjustment); + //To zero hour January 1 this year + dtBefore = new DateTime(RelativeNow.Year, 1, 1, 0, 0, 00).AddHours(TimeZoneAdjustment); + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + + case DataListFilterSpecialToken.ThisYear: + //From zero hour january 1 this year + dtAfter = new DateTime(RelativeNow.Year, 1, 1, 00, 00, 00).AddSeconds(-1).AddHours(TimeZoneAdjustment); + //To zero hour Jan 1 next year + dtBefore = new DateTime(RelativeNow.AddYears(1).Year, 1, 1, 00, 00, 00).AddHours(TimeZoneAdjustment); + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + + case DataListFilterSpecialToken.InTheLast3Months: + //From Now minus 3 months + dtAfter = DateTime.UtcNow.AddMonths(-3); + //To Now + dtBefore = DateTime.UtcNow; + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + + case DataListFilterSpecialToken.InTheLast6Months: + //From Now minus 6 months + dtAfter = DateTime.UtcNow.AddMonths(-6); + //To Now + dtBefore = DateTime.UtcNow; + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + + case DataListFilterSpecialToken.InTheLastYear: + //From Now minus 365 days + dtAfter = DateTime.UtcNow.AddDays(-365); + //To Now + dtBefore = DateTime.UtcNow; + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + + //======================= + //NEW ONES FOR RAVEN + + + case DataListFilterSpecialToken.YearToDate: + //From zero hour january 1 this year + dtAfter = new DateTime(RelativeNow.Year, 1, 1, 00, 00, 00).AddSeconds(-1).AddHours(TimeZoneAdjustment); ; + //To now + dtBefore = RelativeNow; + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + + case DataListFilterSpecialToken.Past90Days: + //From Now minus 90 days + dtAfter = DateTime.UtcNow.AddDays(-90); + //To Now + dtBefore = DateTime.UtcNow; + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + case DataListFilterSpecialToken.Past30Days: + //From Now minus 30 days + dtAfter = DateTime.UtcNow.AddDays(-30); + //To Now + dtBefore = DateTime.UtcNow; + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + case DataListFilterSpecialToken.Past24Hours: + //From Now minus 24 hours + dtAfter = DateTime.UtcNow.AddHours(-24); + //To Now + dtBefore = DateTime.UtcNow; + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + + case DataListFilterSpecialToken.January: + //From zero hour january 1 this year + dtAfter = new DateTime(RelativeNow.Year, 1, 1, 00, 00, 00).AddSeconds(-1).AddHours(TimeZoneAdjustment); + //To zero hour feb 1 this year + dtBefore = new DateTime(RelativeNow.Year, 2, 1, 00, 00, 00).AddHours(TimeZoneAdjustment); + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + + case DataListFilterSpecialToken.February: + dtAfter = new DateTime(RelativeNow.Year, 2, 1, 00, 00, 00).AddSeconds(-1).AddHours(TimeZoneAdjustment); + dtBefore = new DateTime(RelativeNow.Year, 3, 1, 00, 00, 00).AddHours(TimeZoneAdjustment); + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + + case DataListFilterSpecialToken.March: + dtAfter = new DateTime(RelativeNow.Year, 3, 1, 00, 00, 00).AddSeconds(-1).AddHours(TimeZoneAdjustment); + dtBefore = new DateTime(RelativeNow.Year, 4, 1, 00, 00, 00).AddHours(TimeZoneAdjustment); + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + + case DataListFilterSpecialToken.April: + dtAfter = new DateTime(RelativeNow.Year, 4, 1, 00, 00, 00).AddSeconds(-1).AddHours(TimeZoneAdjustment); + dtBefore = new DateTime(RelativeNow.Year, 5, 1, 00, 00, 00).AddHours(TimeZoneAdjustment); + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + + case DataListFilterSpecialToken.May: + dtAfter = new DateTime(RelativeNow.Year, 5, 1, 00, 00, 00).AddSeconds(-1).AddHours(TimeZoneAdjustment); + dtBefore = new DateTime(RelativeNow.Year, 6, 1, 00, 00, 00).AddHours(TimeZoneAdjustment); + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + + case DataListFilterSpecialToken.June: + dtAfter = new DateTime(RelativeNow.Year, 6, 1, 00, 00, 00).AddSeconds(-1).AddHours(TimeZoneAdjustment); + dtBefore = new DateTime(RelativeNow.Year, 7, 1, 00, 00, 00).AddHours(TimeZoneAdjustment); + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + + case DataListFilterSpecialToken.July: + dtAfter = new DateTime(RelativeNow.Year, 7, 1, 00, 00, 00).AddSeconds(-1).AddHours(TimeZoneAdjustment); + dtBefore = new DateTime(RelativeNow.Year, 8, 1, 00, 00, 00).AddHours(TimeZoneAdjustment); + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + + case DataListFilterSpecialToken.August: + dtAfter = new DateTime(RelativeNow.Year, 8, 1, 00, 00, 00).AddSeconds(-1).AddHours(TimeZoneAdjustment); + dtBefore = new DateTime(RelativeNow.Year, 9, 1, 00, 00, 00).AddHours(TimeZoneAdjustment); + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + + case DataListFilterSpecialToken.September: + dtAfter = new DateTime(RelativeNow.Year, 9, 1, 00, 00, 00).AddSeconds(-1).AddHours(TimeZoneAdjustment); + dtBefore = new DateTime(RelativeNow.Year, 10, 1, 00, 00, 00).AddHours(TimeZoneAdjustment); + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + + case DataListFilterSpecialToken.October: + dtAfter = new DateTime(RelativeNow.Year, 10, 1, 00, 00, 00).AddSeconds(-1).AddHours(TimeZoneAdjustment); + dtBefore = new DateTime(RelativeNow.Year, 11, 1, 00, 00, 00).AddHours(TimeZoneAdjustment); + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + + case DataListFilterSpecialToken.November: + dtAfter = new DateTime(RelativeNow.Year, 11, 1, 00, 00, 00).AddSeconds(-1).AddHours(TimeZoneAdjustment); + dtBefore = new DateTime(RelativeNow.Year, 12, 1, 00, 00, 00).AddHours(TimeZoneAdjustment); + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + + case DataListFilterSpecialToken.December: + //From zero hour dec 1 this year + dtAfter = new DateTime(RelativeNow.Year, 12, 1, 00, 00, 00).AddSeconds(-1).AddHours(TimeZoneAdjustment); + //To zero hour Jan 1 next year + dtBefore = new DateTime(RelativeNow.AddYears(1).Year, 1, 1, 00, 00, 00).AddHours(TimeZoneAdjustment); + BuildBetweenTwoDatesFragment(SqlColumnNameToFilter, sb, dtAfter, dtBefore); + break; + + default: + throw new System.ArgumentOutOfRangeException("TOKEN", sOperator, "DataListSqlFilterCriteriaBuilder invalid filter TOKEN type [" + sValue + "] IN DATE_TIME"); + + //----- + } + + #endregion + } + else + { +*/ + + + + + //Note: it is assumed all dates come into here from the CLIENT in UTC iso8601 format //suitable for the database to handle as all database dates are in UTC //Local display and parsing will be considered a CLIENT issue at all times