Calendar and business day computations

In an enterprise application, many business transactions may require business day computations, eg an Invoice due date may be 14 business days from billing date.

A Calendar in Maymyo will specify 2 things, its rest days in a week and its Holidays. When we compute business days, we will omit counting these.

Methods available using Calendars

We provide the following for each calendar. Some are class instance methods and others are normal functions where the calendar is passed in as a parameter.

Class instance methods defined in infra/models/calendar.py

  • Is holiday - class instance method, returns True or False for an input date
  • Is rest day - class instance method, returns True or False for an input date
  • Is business day - class instance method, returns True or False for an input date, ie is either a rest day or holiday.

Normal functions, in infra/objects/app_calendar.py

  • Last Day in the month for an input date
  • First Day in the month for an input date
  • Add Months for an input date. A second parameter is an integer for the number of months. When negative then the result will be the number of months in the past.
  • Return the Application default calendar. This is maintained in the Application Registry with the key DEFAULT-CALENDAR. All methods that compute business days will use this when its optional Calendar is not passed in.
  • Compute Business Days between 2 dates. An optional Calendar can be passed in, will use Application default when not passed in.
  • Get next Business Date for an input date and number of days. The number of days when negative will compute an earlier date. This is the most often used to compute due dates.
  • Get the Month’s first business day for an input date and optional Calendar.
  • Get the Month’s last business day for an input date and optional Calendar.
  • Get the Year’s first business day for an input date and optional Calendar.
  • Get the Year’s last business day for an input date and optional Calendar.
  • Get a Quarter’s canonical number for an input date, ie 1 to 4.
  • Get a Quarter start or end date for an input date.

How we use calendars

First of all, when computing business days or deciding if a date is a business day or not, we need a Calendar. Calendars are attached to the following :-

  • Business Unit, eg all Users must belong to one, so to decide if a user is logging in on a rest day or not, her Business Unit’s calendar is used. Also all Branches are also Business Units, so any business transactions arising from it will use its Calendar.
  • Scheduled Job - we have a scheduler daemon that can automatically start Application Jobs. If a Job is to be run on the last business day of the month, then we will use the Scheduled Job’s Calendar, which when not defined, we will use its Job Owner’s Business Unit’s Calendar. When all else fails, then the Application default. If a Scheduled Job does not use any business day computation, then the Calendar is ignored.
  • Workflow Type - when using Duration Type of BUSINESS-DAY, then we need a calendar. We will use its Calendar, failing which the Application Default.

You may also use Calendar in your models. An example of how we use it is in our Billing module, which uses the Party model from the Common module. Each Party (ie a person or company who is a Customer or Vendor) must have a home Branch and Payment Term for each Billing Type (for Invoices or Debit Notes). If a Payment Term uses Business Day computation, then we will use the Party’s home Branch’s Calendar.