
Calendar
Calendar
Abstract
The calendar provided by the ERP Core project respects most of the RFC5545. Please consult the RFC5545 for more details about the calendar functionality.
The Calendar functionality of the ERP system provides scheduled event triggers and the base functionality for other Calendar implementations. For example, you can use the Calendar base functionality to implement a reservation system in a plug-in.
The UI view of the base Calendar implementation
Being a base functionality of the system, the Admin can view all the events in the system in the same screen, even if the events are plug-in implementations.
The base Calendar’s events can be configured as follows:
- Repetition rate – configures the event’s recursion and exception rules and dates;
- Timing – configures the duration interval and time zone;
- Notification groups of identity users and roles;
- Event groups;
- Boolean operations between calendar event groups (masking) and transparency options;
- Entity Attribute Values
- Hierarchy
- Custom colors and decorations defined at Calendar or Event level
In order to allow a proper implementation, we defined some enums to handle week days, weeks, months etc. in a coherent way.
The base Calendar features a repository implementation that provides a powerful interface to create, configure and handle events.
The view of the plug-in implementation of the Calendar
1 Enums
1.1 Calendar WeekDay
The week days and some other useful day combinations are defined in the ErpCalendarWeekDay enum. The definition can be used for binary operations in order to combine multiple options (for example triggering an event on two days you apply the & operator on two options).
The definition is as follows:
namespace ErpEntity.Calendar { // // Summary: // Specifies the day of the week or combinations of days. public enum ErpCalendarWeekDay { Monday = 0x01, Tuesday = 0x02, Wednesday = 0x04, Thursday = 0x08, Friday = 0x10, Saturday = 0x20, Sunday = 0x40 } }
The database stores integer values. The system provides the integer values to the user as enum values via a proxy.
1.2 Calendar Month
The same binary logic used for ErpCalendarWeekDay is used for ErpCalendarMonth and can be used for defining combinations of months. Some default combinations are present in the enum, but the business logic must always convert them into individual month triggers.
namespace ErpEntity.Calendar { public enum ErpCalendarMonth { January = 0x01, February = 0x02, March = 0x04, April = 0x08, May = 0x10, June = 0x20, July = 0x40, August = 0x80, September = 0x100, October = 0x200, November = 0x400, December = 0x800 } }
The database stores integer values. The system provides the integer values to the user as enum values via a proxy.
1.3 Transparency type
This property defines whether or not an event is transparent to busy time searches.
namespace ErpEntity.Calendar { /// <summary> /// The TRANSP of RFC5545. /// This property defines whether or not an event is transparent to busy time searches. /// Time Transparency is the characteristic of an event /// that determines whether it appears to consume time on a calendar. /// Events that consume actual time for the individual or resource /// associated with the calendar SHOULD be recorded as OPAQUE, /// allowing them to be detected by free/busy time searches.Other /// events, which do not take up the individual's (or resource's) time /// SHOULD be recorded as TRANSPARENT, making them invisible to free/ /// busy time searches. /// </summary> public enum ErpCalendarTransparencyType { /// <summary> /// If set as inherit, the transparency type is inherited from parent to thild and from calendar to events. /// </summary> Inherit, /// <summary> /// Default value is OPAQUE. /// Events that consume actual time for the individual or resource /// associated with the calendar SHOULD be recorded as OPAQUE /// allowing them to be detected by free/busy time searches. /// </summary> Opaque, /// <summary> /// Other events, which do not take up the individual's (or resource's) time /// SHOULD be recorded as TRANSPARENT, making them invisible to free/ /// busy time searches. /// </summary> Transparent, /// <summary> /// If used, overrides the inherited transparency of calendars or events. /// Can be used for recurrence rules to override events transparency (for example alerts over opaque events) /// </summary> Override } }
1.4 Calendar Boolean Operations
Boolean operations can be applied between calendars. This can be used in combination with ErpCalendarTransparencyType. The ErpCalendarBooleanOperation enum defines those operations:
public enum ErpCalendarBooleanOperation { /// <summary> /// No Boolean action is defined. /// </summary> _ = 0, /// <summary> /// Negates the value. If an event or group of events has a NOT action, it is first /// negated before using it in the Boolean operation. /// Can be used as: result = (NOT A) AND B /// </summary> NOT, /// <summary> /// OR Boolean operation /// A B X /// 1 1 1 /// 1 0 1 /// 0 1 1 /// 0 0 0 /// </summary> OR, /// <summary> /// NOR Boolean operation /// A B X /// 1 1 0 /// 1 0 0 /// 0 1 0 /// 0 0 1 /// </summary> NOR, /// <summary> /// AND Boolean operation /// A B X /// 1 1 1 /// 1 0 0 /// 0 1 0 /// 0 0 0 /// </summary> AND, /// <summary> /// NAND Boolean operation /// A B X /// 1 1 0 /// 1 0 0 /// 0 1 0 /// 0 0 1 /// </summary> NAND, /// <summary> /// XOR Boolean operation /// A B X /// 1 1 0 /// 1 0 1 /// 0 1 1 /// 0 0 0 /// </summary> XOR, /// <summary> /// XNOR Boolean operation /// A B X /// 1 1 1 /// 1 0 0 /// 0 1 0 /// 0 0 1 /// </summary> XNOR, /// <summary> /// IMPLIES Boolean operation /// A B X /// 1 1 1 /// 1 0 0 /// 0 1 1 /// 0 0 1 /// </summary> IMPLIES }
1.5 Calendar Trigger Relation
This configuration is used to specify the relationship of the alarm trigger with respect to the start or end of the calendar component.
namespace ErpEntity.Calendar { /// <summary> /// To specify the relationship of the alarm trigger with /// respect to the start or end of the calendar component. /// This parameter can be specified on properties that /// specify an alarm trigger with a "DURATION" value type.The /// parameter specifies whether the alarm will trigger relative to the /// start or end of the calendar component.The parameter value START /// will set the alarm to trigger off the start of the calendar /// component; the parameter value END will set the alarm to trigger /// off the end of the calendar component.If the parameter is not /// specified on an allowable property, then the default is START. /// </summary> public enum ErpCalendarTriggerRelation { Start, End } }
Other data types are defined in order to allow the RFC5545 calendar functionality implementation in an ERP system that uses Entity Framework. Pleas consult the source code and the comments for more implementation details.
2 Calendars
2.1 Calendar
The ErpCalendar groups together events with similar functionality and role. For example, we can group events that trigger jobs, document generators, system jobs etc.
In case we extend the Calendar functionality, we can create a calendar for each type of extension. Let’s say we create a reservation plug-in. All reservation events can be grouped together or split into more atomic groups.
The ErpCalendar is a hierarchal type entity (TreeTypedNode). It has a Parent and many Children. This can help configure various levels regarding responsibility and triggering.
Boolean operations can be applied between ErpCalendar(s), also Boolean operations can be applied on each term before the final operation (for example NOT).
For example, if you need to know all working days, you create the basic workdays calendar with the days spanning from Monday to Friday and you create another calendar with the legal holidays. Using an ErpCalendar, you mask the workdays calendar with the holiday calendar to obtain the real working days calendar.
The NOT A AND B logic applied to mask 2 calendars
3 Defining a calendar event
3.1 Calendar Event Definition
All events are defined in the ErpCalendarEvent entity. The definition contains the following groups of configurations:
- Definition of the main event properties such as the name, description, dote, event group, status (active/inactive), event number, event index etc.;
- Repetition rate that defines the repetition rate and conditions of the event;
- Timing of the event where we configure the duration interval (day interval or all day), the validity interval (start and end validity dates) etc.;
- Notification timing configuration;
- References to other entities in the system, for example Calendar extensions, organizational entities, the notification groups, the event type, the parent and the children;
- EAVs;
- UI formatting options;
3.1.1 Definition
The definition section contains elements that define the general information about the event such as its Name, the Description, and Note.
You can configure activate or deactivate the event by changing the Status flag (drop down).
The event’s Number is an autogenerated number for easier communication (sharing of information by humans).
The OrderIndex field is used when displaying the entities in some places. The order of the entities will be influenced by the OrderIndex.
Event definitions are grouped together in calendars (ErpCalendar). Calendars define a specific role for the event, such as Jobs events, User Defined events, Reporting events etc. An event definition can belong to only one calendar. Plug-ins can reference calendars in order to mark them as extended entities. In that case, the ReferenceEntityFullTypeName and ReferenceEntityId fields must point to the entity that extends the ErpCalendar.
3.1.2 Repetition rate
Events can be configured to repeat themselves at regular intervals. The system accepts recurrence rules and dates and also exception rules and dates.
Please consult RFC5545 for more information about the recurrence patterns used.
3.1.3 Timing
This section’s configurations define the timing of the event.
If no timing configuration is set, depending on the repetition settings, the CreatedAt field of the definition might be used as the start date.
Duration
This configuration sets the event’s duration. For example, we need an event starting at 8 AM and that finishes at 3 PM or an event that spans 3 days.
When configuring events without a duration (instantaneous) the Start must be set at the event’s trigger time and the End must be set to the MinValue of the DateTimeOffset (End must be less than the Start value).
AllDay
If this is selected, the time component of the Duration is ignored and the event takes place starting at 00:00:00 on the Start selected day and ends at 23:59:59 on the last (End) selected day in the interval.
ValidityInterval
This interval configures the Start and End date/time of the event configuration. There are 4 configurations that require a little attention:
- The Start is null or Min and the End is null or Max (or the whole ValidityInterval is null): in this situation the event has no start nor end date and the event will start triggering immediately. If any configurations are made in the Repetition rate section, the event will repeat according to those configurations;
- The Start is null or Minand the End is NOT null nor Max: the event has no initial date and can start triggering immediately until the End date;
- The Start is NOT null nor Min and the End is null or Max: the event will start to trigger after the Start date and repeat according to the configurations in the Repetition rate section;
- Both the Start and End values are fully defined: the event will start triggering on the Start date and end triggering on the End date. The configurations in the Repetition rate section will be respected.
If you configure the Start less than the event’s CreatedAt field, the Start value will be ignored. The Start value must be greater or equal than the creation date in order to be taken into account.
If the End is less than the CreatedAt field, the event will not generate any events. The End value must be greater than the creation date in order to be taken into account.
TimeZoneOffset
This configures the time zone offset of the event. For example, we configure an event and we are located in New York, USA. Our computer will send our time zone configuration to the server. The server holds all the date information together with the time zone offset. But we want to trigger an event in Europe. Then we need to configure the TimeZoneOffset to Europe’s time zone.
The default configuration is the server’s time zone offset.
3.1.4 Failure of event trigger
In case of an event trigger failure, the following configurations in the Timing section will configure the re-triggering mechanism.
TriggerExpiration
This configures a time span until the triggering mechanism can trigger an event that failed triggering or was delayed. For example, if the server was turned off and an event must have been triggered during that time, this tells the system if the event must still be triggered or should be skipped. If this configuration is not null then the system will trigger the failed event immediately if the current date-time is less than the date-time when the event should have been triggered plus this configuration’s amount.
If the configuration is null or zero, then the system will trigger the event immediately regardless of this configuration, without any time limit.
4 Notification groups
4.1 Calendar Notification Group
When events are triggered or before the triggering, depending on the Notifications configurations, we can send notifications to users or groups of users (roles).
You can assign one or multiple ErpCalendarEvent entities to one or multiple ErpCalendarNotifGroup entities.
ErpCalendarNotifGroup
If you need to notify users about calendar events in the system, you create notification groups and configure them to send notifications.
A notification group can send notifications to multiple:
- ErpIdentityUser
- ErpCompositeUserRole
- ErpIdentityRole
Users can be notified using their ErpIdentityUser configuration contact data (email, phone, SMS etc.). If any other type of notifications needs to be sent, a plug-in can subscribe to EntityEvents and handle them according to the customer’s specifications.
5 Past calendar events
All triggered calendar events are saved in the database and their status history is stored.
5.1 Calendar Event occurrence
When an event is first triggered it is saved in the ErpCalendarEventOccurance entity and a reference to the ErpCalendarEvent triggering is stored.
Plug-ins that handle Calendar events must subscribe to the EntityEvent of this entity and handle the event accordingly.
5.2 Calendar Event History
The system also stores the history of an event occurrence in the ErpCalendarEventHistory entity, linked to its parent ErpCalendarEventOccurance.
When an event is first created a status is set. After each user action the new status is added. For example, we store the New status when the event is first created. If the user snoozes the notification, a Snoozed status is stored.
The status of the event is defined in the ErpCalendarEventStatus entity.
5.3 Calendar Event Status
The ErpCalendarEventStatus entity has a hierarchical structure (TreeNode) that can provide the order in which the statuses can be applied. It also has json metadata for UI formatting (icon, color etc.).
