Skip to main content
sameeru0003
July 14, 2023
Question

Count number of days excluding holidays without workday function.

  • July 14, 2023
  • 5 replies
  • 0 views

Hi,

worday function is used when weekends are need to be excluded to calculate workdays. We have requirement to calculate including weekend. Below is our expression we need help to calculate finaldate when include weekend is true. here expectedholidays is list of holidays.

a!localVariables(
  local!expectedDays: if(ri!days > 0, ri!days, 0),
  local!exceptedHolidays: if(isnull(ri!holidays), {}, ri!holidays),
  local!startDate: today() - 1,
  local!initialEndDate: local!startDate + local!expectedDays,
  local!FinalEndDate: a!forEach(
    items: enumerate(local!expectedDays)+2,
    expression: if(
      contains(local!exceptedHolidays,local!FinalEndDate),
      local!initialEndDate+1,
      local!initialEndDate
    )
  ),
  local!exceptedDeadline: if(
    ri!days > 0,
    if(
      ri!excludeWeekends,
      workday(
        today() - 1,
        local!expectedDays,
        local!exceptedHolidays
      ),
      local!FinalEndDate
    ),
    cons!CORE_MAX_DATE
  ),
  local!exceptedDeadline
)

5 replies

stefanhelzle0001
Brainy
July 14, 2023

This is confusing ?!?!

And the lines 5-13 are nonsense. As Appian expressions follow a functional paradigm, local variables are immutable and cannot be changed in a foreach.

stefanhelzle0001
Brainy
July 14, 2023

The following code finds the holidays falling into the range and adds them on top of the initial number of days. This might completely miss your requirements and contain some edge cases I did not check for.

a!localVariables(
  local!holidays: {date(2023,5,15), date(2023,6,20), date(2023,6,25), date(2023,12,24)},
  local!start: date(2023, 6, 10),
  local!days: 20,
  local!additionalDays: count(
    intersection(
      local!holidays,
      local!start + enumerate(local!days)
    )
  ),
  local!start + local!days + local!additionalDays
)

sameeru0003
July 14, 2023

in the above expression if i pass the dates as below its giving 7/20/2023 which is a holiday. Result should be 7/21/2023

a!localVariables(
  local!holidays: {date(2023,07,15), date(2023,07,17), date(2023,07,20)},
  local!start: today()-1,
  local!days: 5,
  local!additionalDays: count(
    intersection(
      local!holidays,
      local!start + enumerate(local!days)
    )
  ),
  local!start + local!days + local!additionalDays
)

stefanhelzle0001
Brainy
July 14, 2023

That's the edge case I mentioned. Challenge accepted. I changed that code to use the reduce() function to iterate on the list of holidays and whenever a holiday is in the range of days, I add one days.

This is not simple code and not optimized in any way, and there might be more edge cases.

if(
  ri!isRecursive,
  a!map(
    start: ri!data.start,
    days: if(
      contains(ri!data.start + 1 + enumerate(ri!data.days), ri!holiday),
      ri!data.days + 1,
      ri!data.days
    )
  ),
  a!localVariables(
    local!holidays: {date(2023,07,15), date(2023,07,17), date(2023,07,20)},
    local!start: today()-1,
    local!days: 5,
    local!result: reduce(
      rule!SSH_HolidayCalculator(
        data:_,
        holiday:_,
        isRecursive: true
      ),
      a!map(
        start: local!start,
        days: local!days,
        additionalDays: 0
      ),
      local!holidays
    ),
    local!start + local!result.days
  )
)