diff --git a/FakeXrmEasy.Shared/Extensions/XmlExtensionsForFetchXml.cs b/FakeXrmEasy.Shared/Extensions/XmlExtensionsForFetchXml.cs
index 93b77a03..1ed12797 100644
--- a/FakeXrmEasy.Shared/Extensions/XmlExtensionsForFetchXml.cs
+++ b/FakeXrmEasy.Shared/Extensions/XmlExtensionsForFetchXml.cs
@@ -26,7 +26,8 @@ public static class XmlExtensionsForFetchXml
ConditionOperator.LastXMonths,
ConditionOperator.LastXWeeks,
ConditionOperator.LastXYears,
- ConditionOperator.NextXWeeks
+ ConditionOperator.NextXWeeks,
+ ConditionOperator.InFiscalYear
};
public static bool IsAttributeTrue(this XElement elem, string attributeName)
@@ -520,6 +521,9 @@ public static ConditionExpression ToConditionExpression(this XElement elem, XrmF
case "next-week":
op = ConditionOperator.NextWeek;
break;
+ case "in-fiscal-year":
+ op = ConditionOperator.InFiscalYear;
+ break;
#if FAKE_XRM_EASY_9
case "contain-values":
op = ConditionOperator.ContainValues;
diff --git a/FakeXrmEasy.Shared/FakeXrmEasy.Shared.projitems b/FakeXrmEasy.Shared/FakeXrmEasy.Shared.projitems
index 464baeb3..4b29a693 100644
--- a/FakeXrmEasy.Shared/FakeXrmEasy.Shared.projitems
+++ b/FakeXrmEasy.Shared/FakeXrmEasy.Shared.projitems
@@ -68,6 +68,7 @@
+
diff --git a/FakeXrmEasy.Shared/FiscalYearSettings.cs b/FakeXrmEasy.Shared/FiscalYearSettings.cs
new file mode 100644
index 00000000..3a35c7e1
--- /dev/null
+++ b/FakeXrmEasy.Shared/FiscalYearSettings.cs
@@ -0,0 +1,25 @@
+using Microsoft.Xrm.Sdk;
+using Microsoft.Xrm.Sdk.Client;
+using System;
+
+namespace FakeXrmEasy
+{
+ [EntityLogicalName("organization")]
+ public class FiscalYearSettings
+ {
+ [AttributeLogicalName("fiscalcalendarstart")]
+ public DateTime StartDate { get; set; }
+
+ [AttributeLogicalName("fiscalperiodtype")]
+ public Template FiscalPeriodTemplate { get; set; }
+
+ public enum Template
+ {
+ Annually = 2000,
+ SemiAnnually = 2001,
+ Quarterly = 2002,
+ Monthly = 2003,
+ FourWeek = 2004
+ }
+ }
+}
diff --git a/FakeXrmEasy.Shared/XrmFakedContext.DateTime.cs b/FakeXrmEasy.Shared/XrmFakedContext.DateTime.cs
index fc053568..553afd79 100644
--- a/FakeXrmEasy.Shared/XrmFakedContext.DateTime.cs
+++ b/FakeXrmEasy.Shared/XrmFakedContext.DateTime.cs
@@ -8,6 +8,8 @@ public partial class XrmFakedContext : IXrmContext
{
public TimeZoneInfo SystemTimeZone { get; set; }
+ public FiscalYearSettings FiscalYearSettings { get; set; }
+
public Dictionary> DateBehaviour { get; set; }
private static Dictionary> DefaultDateBehaviour()
diff --git a/FakeXrmEasy.Shared/XrmFakedContext.Queries.cs b/FakeXrmEasy.Shared/XrmFakedContext.Queries.cs
index 50e50e28..c1c5eaf0 100644
--- a/FakeXrmEasy.Shared/XrmFakedContext.Queries.cs
+++ b/FakeXrmEasy.Shared/XrmFakedContext.Queries.cs
@@ -853,7 +853,8 @@ protected static Expression TranslateConditionExpression(QueryExpression qe, Xrm
case ConditionOperator.LastWeek:
case ConditionOperator.ThisWeek:
case ConditionOperator.NextWeek:
- operatorExpression = TranslateConditionExpressionBetweenDates(c, getNonBasicValueExpr, containsAttributeExpression);
+ case ConditionOperator.InFiscalYear:
+ operatorExpression = TranslateConditionExpressionBetweenDates(c, getNonBasicValueExpr, containsAttributeExpression, context);
break;
case ConditionOperator.Next7Days:
@@ -1679,7 +1680,7 @@ protected static Expression TranslateConditionExpressionLast(TypedConditionExpre
///
/// Takes a condition expression which needs translating into a 'between two dates' expression and works out the relevant dates
///
- protected static Expression TranslateConditionExpressionBetweenDates(TypedConditionExpression tc, Expression getAttributeValueExpr, Expression containsAttributeExpr)
+ protected static Expression TranslateConditionExpressionBetweenDates(TypedConditionExpression tc, Expression getAttributeValueExpr, Expression containsAttributeExpr, XrmFakedContext context)
{
var c = tc.CondExpression;
@@ -1690,6 +1691,7 @@ protected static Expression TranslateConditionExpressionBetweenDates(TypedCondit
var thisYear = today.Year;
var thisMonth = today.Month;
+
switch (c.Operator)
{
case ConditionOperator.ThisYear: // From first day of this year to last day of this year
@@ -1731,6 +1733,13 @@ protected static Expression TranslateConditionExpressionBetweenDates(TypedCondit
fromDate = today.ToFirstDayOfDeltaWeek(1);
toDate = today.ToLastDayOfDeltaWeek(1).AddDays(1);
break;
+ case ConditionOperator.InFiscalYear:
+ var fiscalYear = (int)c.Values[0];
+ c.Values.Clear();
+ var fiscalYearDate = context.FiscalYearSettings?.StartDate ?? new DateTime(fiscalYear, 4, 1);
+ fromDate = fiscalYearDate;
+ toDate = fiscalYearDate.AddYears(1).AddDays(-1);
+ break;
}
c.Values.Add(fromDate);
diff --git a/FakeXrmEasy.Tests.Shared/FakeContextTests/FetchXml/ConditionOperatorTests.cs b/FakeXrmEasy.Tests.Shared/FakeContextTests/FetchXml/ConditionOperatorTests.cs
index 1ac8a298..5380ee11 100644
--- a/FakeXrmEasy.Tests.Shared/FakeContextTests/FetchXml/ConditionOperatorTests.cs
+++ b/FakeXrmEasy.Tests.Shared/FakeContextTests/FetchXml/ConditionOperatorTests.cs
@@ -718,7 +718,7 @@ public void FetchXml_Operator_Last_Seven_Days_Translation()
";
-
+
var query = XrmFakedContext.TranslateFetchXmlToQueryExpression(ctx, fetchXml);
Assert.True(query.Criteria != null);
@@ -1300,6 +1300,37 @@ public void FetchXml_Operator_ThisYear_Execution()
Assert.Equal(((DateTime)collection.Entities[2]["anniversary"]).Year, thisYear);
}
+ [Fact]
+ public void FetchXml_Operator_InFiscalYear_Execution()
+ {
+ var today = DateTime.Today;
+ var thisYear = today.Year;
+
+ var ctx = new XrmFakedContext();
+ ctx.FiscalYearSettings = new FiscalYearSettings() { StartDate = new DateTime(thisYear, 1, 2), FiscalPeriodTemplate = FiscalYearSettings.Template.Annually };
+ var fetchXml = $@"
+
+
+
+
+
+
+ ";
+
+ var ct1 = new Contact() { Id = Guid.NewGuid(), Anniversary = new DateTime(thisYear, 1, 2) }; // Second day of this year - should be returned
+ var ct2 = new Contact() { Id = Guid.NewGuid(), Anniversary = new DateTime(thisYear, 12, 31) }; // Last day of this year - should be returned
+ var ct3 = new Contact() { Id = Guid.NewGuid(), Anniversary = new DateTime(thisYear + 1, 1, 2) }; // Second day of next year - should not be returned
+ ctx.Initialize(new[] { ct1, ct2, ct3 });
+ var service = ctx.GetOrganizationService();
+
+ var collection = service.RetrieveMultiple(new FetchExpression(fetchXml));
+
+ Assert.Equal(2, collection.Entities.Count);
+
+ Assert.Equal(((DateTime)collection.Entities[0]["anniversary"]).Year, thisYear);
+ Assert.Equal(((DateTime)collection.Entities[1]["anniversary"]).Year, thisYear);
+ }
+
[Fact]
public void FetchXml_Operator_ThisMonth_Execution()
{
@@ -1366,7 +1397,7 @@ public void FetchXml_Operator_LastMonth_Execution()
Assert.Equal(2, collection.Entities.Count);
Assert.Equal(((DateTime)collection.Entities[0]["anniversary"]).Month, lastMonth);
- Assert.Equal(((DateTime)collection.Entities[1]["anniversary"]).Month, lastMonth);
+ Assert.Equal(((DateTime)collection.Entities[1]["anniversary"]).Month, lastMonth);
}
[Fact]
@@ -1384,7 +1415,7 @@ public void FetchXml_Operator_NextMonth_Execution()
var today = DateTime.Today;
var thisYear = today.Year;
- var thisMonth = today.Month;
+ var thisMonth = today.Month;
var nextMonth = new DateTime(thisYear, thisMonth, 1).AddMonths(1).Month;
var ct1 = new Contact() { Id = Guid.NewGuid(), Anniversary = today }; // Today - Should not be returned
var ct2 = new Contact() { Id = Guid.NewGuid(), Anniversary = new DateTime(thisYear, thisMonth, 1) }; // First day of this month - should not be returned
@@ -1393,7 +1424,7 @@ public void FetchXml_Operator_NextMonth_Execution()
var ct5 = new Contact() { Id = Guid.NewGuid(), Anniversary = new DateTime(thisYear, thisMonth, 1).AddMonths(2).AddDays(-1) }; // Last day of next month - should be returned
var ct6 = new Contact() { Id = Guid.NewGuid(), Anniversary = new DateTime(thisYear, thisMonth, 1).AddDays(-1) }; // Last day of last month - should not be returned
var ct7 = new Contact() { Id = Guid.NewGuid(), Anniversary = new DateTime(thisYear, thisMonth, 1).AddMonths(-1) }; // First day of last month - should not be returned
-
+
ctx.Initialize(new[] { ct1, ct2, ct3, ct4, ct5, ct6, ct7 });
var service = ctx.GetFakedOrganizationService();
@@ -1580,9 +1611,9 @@ public void FetchXml_Operator_Next_X_Weeks_Execution()
";
var date = DateTime.Now;
- var ct1 = new Contact() { Id = Guid.NewGuid(), Anniversary = date.AddDays(7*2) }; //Should be returned
- var ct2 = new Contact() { Id = Guid.NewGuid(), Anniversary = date.AddDays(7*4) }; //Shouldnt
- ctx.Initialize(new[] { ct1, ct2});
+ var ct1 = new Contact() { Id = Guid.NewGuid(), Anniversary = date.AddDays(7 * 2) }; //Should be returned
+ var ct2 = new Contact() { Id = Guid.NewGuid(), Anniversary = date.AddDays(7 * 4) }; //Shouldnt
+ ctx.Initialize(new[] { ct1, ct2 });
var service = ctx.GetOrganizationService();
var collection = service.RetrieveMultiple(new FetchExpression(fetchXml));
@@ -1789,7 +1820,7 @@ public void FetchXml_Operator_Next_Week_Execution()
Assert.Equal(retrievedUser, ct1.Id);
}
-
+
#if FAKE_XRM_EASY_9
[Fact]
public void FetchXml_Operator_ContainValues_Translation()