Compute Dates from Periodicities
This workflow is included in the Scheduling package.
Description
Outputs dates matching periodicities given a range specified by start date and either an end date or a number of dates.
Properties
This workflow has the following properties.
| Property | Value |
|---|---|
| Name | Compute Dates from Periodicities |
| Code | workflows_computeDatesFromPeriodicities_8e453842273351d387ab2939 |
| Type | Workflow |
| Context | Package |
| Enabled | Yes |
| Tags | Causeway |
| Log retention | 7 days |
Trigger
A user triggers this workflow on demand, or another workflow runs it (via an MWR). It works on the items of the design below.
| Property | Value |
|---|---|
| Workflow type | Manual workflow |
| Applies to | Periodicities |
| Output mode | ManyItems (Runs once for all items) |
| Parameters design | MTP - Compute Dates from Periodicities |
| Output action | The Output action highlighted in the diagram below |
Actions
This workflow runs 4 actions, in the order shown in this simplified diagram. Every action's full settings are in the configuration below.
Configuration
The full configuration of this workflow, including every action's parameters.
Show configuration (300 lines)
{
"trigger": {
"dodiCode": "designInterfaces_periodicity_68109e5096e0ec0345072f8a",
"parametersDesignCode": "designs_computeDatesFromPeriodicities_874950917130ef4b6ae2e28c",
"outputActionId": "82a1a421812ef49e2976533c",
"outputMode": "ManyItems"
},
"actions": [
{
"actionId": "68261b9ca71675a82f2ee892",
"designCode": "designs_workflowFilterAction",
"description": "if it's a normal periodicity....",
"parameters": [
{
"attribute": {
"attributeCode": "attributes_workflowFilterActionsAqsQuery",
"value": {
"type": "Query",
"properties": {
"dodiCode": "designs_periodicity_8f3183380533b281ac719c10",
"collectionCode": "Live",
"attributes": [
"attributes_itemsTitle",
"attributes_itemsSubtitle"
]
}
},
"attributeType": "Aqs"
}
}
],
"variables": [],
"actions": []
},
{
"actionId": "68261ba28d57c1b3124ec4d2",
"designCode": "designs_workflowFilterAction",
"description": "if it's a periodicity for relative schedule....",
"parameters": [
{
"attribute": {
"attributeCode": "attributes_workflowFilterActionsAqsQuery",
"value": {
"type": "Query",
"properties": {
"dodiCode": "designs_periodicityWithoutDateRange_68132f2da41c45eca2072f8a",
"collectionCode": "Live",
"attributes": [
"attributes_itemsTitle",
"attributes_itemsSubtitle"
]
}
},
"attributeType": "Aqs"
}
}
],
"variables": [],
"actions": []
},
{
"actionId": "682700fc420340e3121c01b0",
"designCode": "designs_workflowOutputAction",
"comments": "Compute schedule's matching dates",
"parameters": [
{
"attributeCode": "attributes_workflowOutputActionData",
"value": {
"script": "var relativeStart = relativePeriodicityItemId.Any() && lastCompletion != null ? new []{ Json(new { dates = new [] { Date(firstPossibleNext) }.ToArray() }) }.ToArray() : List<JObject>().ToArray(); \r\n\r\nvar allStartsOns = relativePeriodicityItemId.Any() ? relativeStart : Variables.cyclicalPeriodicityStartsOn.AllValues.Values.Select(x => x.SingleValue).ToArray();\r\nvar allEndsOns = relativePeriodicityItemId.Any() ? relativeStart.Select(x => Date(Now.AddYears(1000))).ToArray() : Variables.cyclicalPeriodicityEndsOn.AllValues.Values.Select(x => x.SingleValue).ToArray();\r\n var allRepeats = (relativePeriodicityItemId.Any() ? Variables.relativePeriodicityRepeat : Variables.cyclicalPeriodicityRepeat).AllValues.Values.Select(x => x.SingleValue).ToArray();\r\n var allValidOns = (relativePeriodicityItemId.Any() ? Variables.relativePeriodicityValidOn : Variables.cyclicalPeriodicityValidOn).AllValues.Values.Select(x => x.SingleValue).ToArray();\r\n var allNextDates = (relativePeriodicityItemId.Any() ? Variables.relativePeriodicityNextDate : Variables.cyclicalPeriodicityNextDate).AllValues.Values.Select(x => x.SingleValue).ToArray();\r\n var allData = Enumerable.Range(0, allStartsOns.Length).Select(i => new object[] { allStartsOns[i], allEndsOns[i], allRepeats[i], allValidOns[i], allNextDates[i] }).ToArray();\r\n return Json(new { items = \r\n allData.Select(x =>\r\n new {\r\n attributes_periodicityStartsOnInclusive_863726baef05061cd5adad15 = x[0],\r\n attributes_periodicityEndsOnExclusive_897d0b7250920fc60c072bf1 = x[1],\r\n attributes_periodicityRepeat_8e35bd9dad29336f460f2acd = x[2],\r\n attributes_periodicityValidOn_80a6a695435acd16e0b4d317 = x[3],\r\n attributes_periodicityNextDate_8b766935838e7116fb62e7c0 = x[4] }).ToArray()\r\n });\r\n "
},
"attributeType": "Json"
},
{
"attribute": {
"attributeCode": "attributes_workflowOutputActionDodiCode",
"attributeType": "String",
"value": "designs_periodicity_8f3183380533b281ac719c10"
}
},
{
"attribute": {
"attributeCode": "attributes_workflowOutputActionSingleInstance",
"value": false
}
}
],
"variables": [
{
"name": "lastCompletion",
"value": {
"parameterCode": "attributes_computeDatesFromPeriodicitiesPeriodStartDate_682622f2a2dfdc1bec786d3e",
"inputMode": "Each"
},
"attributeType": "Date"
},
{
"name": "firstPossibleNext",
"value": {
"script": "var freqInterval = relativePeriodicityRepeat != null ? (int)relativePeriodicityRepeat[\"interval\"] : 0; var freqUnit = relativePeriodicityRepeat != null ? (string)relativePeriodicityRepeat[\"unit\"] : \"Days\"; return freqUnit == \"Days\" ? lastCompletion?.Value.AddDays(freqInterval) : freqUnit == \"Weeks\" ? lastCompletion?.Value.AddDays(freqInterval * 7) : freqUnit == \"Months\" ? lastCompletion?.Value.AddMonths(freqInterval) : lastCompletion?.Value.AddYears(freqInterval);"
},
"attributeType": "DateTime"
},
{
"name": "relativePeriodicityItemId",
"value": {
"outputAction": "68261ba28d57c1b3124ec4d2",
"itemValue": {
"property": "ItemId"
},
"outputMode": "Input"
},
"attributeType": "String"
},
{
"name": "cyclicalPeriodicityStartsOn",
"value": {
"outputAction": "68261b9ca71675a82f2ee892",
"itemValue": {
"attributeCode": "attributes_periodicityStartsOnInclusive_863726baef05061cd5adad15"
},
"outputMode": "Input"
},
"attributeType": "Json"
},
{
"name": "cyclicalPeriodicityEndsOn",
"value": {
"outputAction": "68261b9ca71675a82f2ee892",
"itemValue": {
"attributeCode": "attributes_periodicityEndsOnExclusive_897d0b7250920fc60c072bf1"
},
"outputMode": "Input"
},
"attributeType": "Date"
},
{
"name": "cyclicalPeriodicityValidOn",
"value": {
"outputAction": "68261b9ca71675a82f2ee892",
"itemValue": {
"attributeCode": "attributes_periodicityValidOn_80a6a695435acd16e0b4d317"
},
"outputMode": "Input"
},
"attributeType": "Json"
},
{
"name": "cyclicalPeriodicityRepeat",
"value": {
"outputAction": "68261b9ca71675a82f2ee892",
"itemValue": {
"attributeCode": "attributes_periodicityRepeat_8e35bd9dad29336f460f2acd"
},
"outputMode": "Input"
},
"attributeType": "Json"
},
{
"name": "cyclicalPeriodicityNextDate",
"value": {
"outputAction": "68261b9ca71675a82f2ee892",
"itemValue": {
"attributeCode": "attributes_periodicityNextDate_8b766935838e7116fb62e7c0"
},
"outputMode": "Input"
},
"attributeType": "Date"
},
{
"name": "relativePeriodicityValidOn",
"value": {
"outputAction": "68261ba28d57c1b3124ec4d2",
"itemValue": {
"attributeCode": "attributes_periodicityValidOn_80a6a695435acd16e0b4d317"
},
"outputMode": "Input"
},
"attributeType": "Json"
},
{
"name": "relativePeriodicityRepeat",
"value": {
"outputAction": "68261ba28d57c1b3124ec4d2",
"itemValue": {
"attributeCode": "attributes_periodicityRepeat_8e35bd9dad29336f460f2acd"
},
"outputMode": "Input"
},
"attributeType": "Json"
},
{
"name": "relativePeriodicityNextDate",
"value": {
"outputAction": "68261ba28d57c1b3124ec4d2",
"itemValue": {
"attributeCode": "attributes_periodicityNextDate_8b766935838e7116fb62e7c0"
},
"outputMode": "Input"
},
"attributeType": "Date"
}
],
"actions": [
{
"actionId": "82a1a421812ef49e2976533c",
"designCode": "designs_workflowOutputAction",
"comments": "Compute matching dates for periodicities",
"parameters": [
{
"attributeCode": "attributes_workflowOutputActionData",
"value": {
"script": "var freqEndDtRawClamp = argDateRangeEnd?.Value < freqEndDtRaw?.Value ? argDateRangeEnd?.Value : freqEndDtRaw?.Value;\r\nvar freqStartDtms = freqStartDtmsRaw[\"dates\"].Values<DateTime>().Where(dt => dt < freqEndDtRawClamp).OrderBy(i => i).ToList() ?? List<DateTime>();\r\nvar freqValidDaysOfWeek = freqValidOn?[\"daysOfWeek\"]?.Values<int>().OrderBy(i => i).ToList() ?? List<int>();\r\nvar freqValidDaysOfMonth = freqValidOn?[\"daysOfMonth\"]?.Values<int>().OrderBy(i => i).ToList() ?? List<int>();\r\nvar freqValidDaysOfYear = freqValidOn?[\"daysOfYear\"]?.Values<int>().OrderBy(i => i).ToList() ?? List<int>();\r\nvar freqValidWeeksOfMonth = freqValidOn?[\"weeksOfMonth\"]?.Values<int>().OrderBy(i => i).ToList() ?? List<int>();\r\nvar freqValidWeeksOfYear = freqValidOn?[\"weeksOfYear\"]?.Values<int>().OrderBy(i => i).ToList() ?? List<int>();\r\nvar freqValidMonthsOfYear = freqValidOn?[\"monthsOfYear\"]?.Values<int>().OrderBy(i => i).ToList() ?? List<int>();\r\nvar freqValidYears = freqValidOn?[\"years\"]?.Values<int>().OrderBy(i => i).ToList() ?? List<int>();\r\n\r\nvar freqInterval = (int)freq[\"interval\"];\r\nvar freqUnit = (string)freq[\"unit\"];\r\n\r\nIEnumerable<DateTime> result = List<DateTime>();\r\n\r\nFunc<int, int> DayOfWeekStartingMondayBase1 = sys => sys == 0 ? 7 : sys;\r\n\r\nif (freqInterval > 0 && freqUnit != null && freqStartDtms.Count > 0 && freqEndDtRawClamp != null)\r\n{\r\n if (freqUnit == \"Days\")\r\n {\r\n result = freqStartDtms.SelectMany(x => Enumerable.Range(0, (int)(freqEndDtRawClamp.Value.Subtract(x).TotalDays % 1 > 0 ? 1 + freqEndDtRawClamp.Value.Subtract(x).TotalDays : freqEndDtRawClamp.Value.Subtract(x).TotalDays)).Where(i => i % freqInterval == 0).Select(offset => x.AddDays(offset)));\r\n }\r\n else if (freqUnit == \"Weeks\")\r\n {\r\n result = freqStartDtms.SelectMany(x => Enumerable.Range(0, (int)((freqEndDtRawClamp.Value.Subtract(x).TotalDays / 7.0) % 1 > 0 ? 1 + (freqEndDtRawClamp.Value.Subtract(x).TotalDays / 7.0) : (freqEndDtRawClamp.Value.Subtract(x).TotalDays / 7.0))).Where(i => i % freqInterval == 0).Select(offset => x.AddDays(offset * 7)));\r\n }\r\n else if (freqUnit == \"Months\")\r\n {\r\n result = freqStartDtms.SelectMany(d => Enumerable.Range(0, Enumerable.Range(0, 1 + (int)(Math.Ceiling(freqEndDtRawClamp.Value.Subtract(d).TotalDays / 28.0) + 1)).OrderBy(i => i).FirstOrDefault(x => d.AddMonths(x) >= freqEndDtRawClamp.Value)).Where(i => i % freqInterval == 0).Select(offset => d.AddMonths(offset)));\r\n }\r\n else if (freqUnit == \"Years\")\r\n {\r\n result = freqStartDtms.SelectMany(d => Enumerable.Range(0, Enumerable.Range(0, 1 + (int)(Math.Ceiling(freqEndDtRawClamp.Value.Subtract(d).TotalDays / 365.0) + 1)).OrderBy(i => i).FirstOrDefault(x => d.AddYears(x) >= freqEndDtRawClamp.Value)).Where(i => i % freqInterval == 0).Select(offset => d.AddYears(offset)));\r\n }\r\n\r\n result = result.Where(d => (freqValidDaysOfWeek.Count == 0 || freqValidDaysOfWeek.Contains(DayOfWeekStartingMondayBase1((int)d.DayOfWeek))));\r\n result = result.Where(d => (freqValidDaysOfMonth.Count == 0 || freqValidDaysOfMonth.Contains(d.Day)));\r\n result = result.Where(d => (freqValidDaysOfYear.Count == 0 || freqValidDaysOfYear.Contains(d.DayOfYear)));\r\n result = result.Where(d => (freqValidWeeksOfMonth.Count == 0 || freqValidWeeksOfMonth.Contains(1 + ((d.Day-1) / 7))));\r\n result = result.Where(d => (freqValidWeeksOfYear.Count == 0 || freqValidWeeksOfYear.Contains(Calendar.GetWeekOfYear(d, CalendarWeekRule.FirstFullWeek, DayOfWeek.Monday))));\r\n result = result.Where(d => (freqValidMonthsOfYear.Count == 0 || freqValidMonthsOfYear.Contains(d.Month)));\r\n result = result.Where(d => (freqValidYears.Count == 0 || (freqValidYears.Count > 0 && freqValidYears.Contains(d.Year))));\r\n}\r\n\r\nresult = result.Distinct().OrderBy(d => d);\r\n\r\nif (argDateRangeStart != null)\r\n{\r\n result = result.Where(x => x >= argDateRangeStart.Value);\r\n}\r\n\r\nif (argLimit != null)\r\n{\r\n result = result.Take((int)argLimit.Value);\r\n}\r\n\r\nreturn Json(new { items = result.Select(x => new { attributes_computeDatesFromPeriodicitiesOutputDateOccurance_8ad5639456d15a25d67516c5 = x }).ToArray() });"
},
"attributeType": "Json"
},
{
"attribute": {
"attributeCode": "attributes_workflowOutputActionDodiCode",
"value": "designs_computeDatesFromPeriodicitiesOutput_8c05e8b036adaaba582068a2"
}
},
{
"attribute": {
"attributeCode": "attributes_workflowOutputActionSingleInstance",
"value": false
}
}
],
"variables": [
{
"name": "argDateRangeStart",
"value": {
"parameterCode": "attributes_computeDatesFromPeriodicitiesDateRangeStart_800d6f68feb01147ef0d2035",
"inputMode": "Each"
},
"attributeType": "Date"
},
{
"name": "argDateRangeEnd",
"value": {
"parameterCode": "attributes_computeDatesFromPeriodicitiesDateRangeEnd_81c4dd81e998b56ddfe158ab",
"inputMode": "Each"
},
"attributeType": "Date"
},
{
"name": "argLimit",
"value": {
"parameterCode": "attributes_computeDatesFromPeriodicitiesLimit_8f4d17da8e3a79f4d3fa840b",
"inputMode": "Each"
},
"attributeType": "Number"
},
{
"name": "freqValidOn",
"value": {
"inputParent": 0,
"itemValue": {
"attributeCode": "attributes_periodicityValidOn_80a6a695435acd16e0b4d317"
}
},
"attributeType": "Json"
},
{
"name": "freq",
"value": {
"inputParent": 0,
"itemValue": {
"attributeCode": "attributes_periodicityRepeat_8e35bd9dad29336f460f2acd"
}
},
"attributeType": "Number"
},
{
"name": "freqEndDtRaw",
"value": {
"inputParent": 0,
"itemValue": {
"attributeCode": "attributes_periodicityEndsOnExclusive_897d0b7250920fc60c072bf1"
}
},
"attributeType": "Date"
},
{
"name": "freqStartDtmsRaw",
"value": {
"inputParent": 0,
"itemValue": {
"attributeCode": "attributes_periodicityStartsOnInclusive_863726baef05061cd5adad15"
}
},
"attributeType": "Json"
}
],
"actions": []
}
]
}
]
}