"Building a compensatory leave management system with multi-level approval in AppSheet."

Hello everyone,

I am currently building an AppSheet application to manage compensatory leave (time off in lieu) for employees, and I would appreciate your guidance.

:small_blue_diamond: Context:

We have two different work schedules:

1. Standard Schedule:

  • Sunday to Thursday

  • From 08:00 AM to 04:30 PM

2. Shift Schedule:

  • 2 days: 07:00 AM to 07:00 PM (day shift)

  • 2 days: 07:00 PM to 07:00 AM (night shift)

  • Followed by 4 days off


:small_blue_diamond: Compensatory Leave Rules:

For Standard Schedule employees:
They are entitled to compensatory leave if they work on:

  • Friday or Saturday

  • Public holidays (e.g., January 1st, May 1st, July 5th, November 1st)

  • Religious holidays (e.g., first 3 days of Eid al-Fitr)

For Shift Schedule employees:
They are entitled to compensatory leave under the same conditions EXCEPT:

  • Fridays and Saturdays

  • Islamic New Year (1st Muharram)


:small_blue_diamond: Approval Workflow:

The compensatory leave request must go through 3 levels of approval:

  1. Direct Manager (N+1)

  2. Department Manager

  3. HR Department (DRH)

Only after all approvals are completed, the leave should be automatically added to the employee’s balance.


:small_blue_diamond: My Questions:

  1. What is the best way to structure the database (tables/columns) in AppSheet for this scenario?

  2. How can I implement these conditional rules for eligibility (based on work schedule and dates)?

  3. What is the best approach to create a multi-level approval workflow?

  4. How can I automatically update the employee leave balance after final approval?

Any best practices, sample apps, or expression examples would be highly appreciated.

Thank you in advance!

1 Like

Hello @FAID_Seid,

Welcome back!

There are many ways to achieve what you are trying to achieve but I think automations will do.

Assuming the employee will request for the comp off:

  1. Create an entry on a request table with a β€œApproval Status” field of 0
  2. Launch an automated task to request for first level approval
  3. If approved, change the β€œApproval Status” field to 1
  4. Launch an automated task to request for second level approval, etc.
  5. Once the request is fully approved, you would increase the leave of absence balance

Again, this is just a suggestion. I’m sure you and other more experienced developers will have a better solution.

1 Like

Hello AppSheet Community! :waving_hand:

I’m building a Compensatory Leave and Overtime

Management application for an industrial company

and need expert help with complex business logic.

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

:building_construction: APP STRUCTURE:

Tables:

β€’ Employees

  • EmployeeID (Key)

  • Name

  • Department

  • Manager Email

  • SectorManagerEmail

  • WorkType (Type1 / Type2 / Type3)

  • Role (Employee / Manager / Cadre)

β€’ CompensatoryLeave

  • ID (Key) β†’ format: LCM-DR-26-001

  • EmployeeID (Ref β†’ Employees)

  • Date

  • Days

  • Reason

  • CreatedBy (USEREMAIL())

  • Requisition (File/PDF)

  • Status (Pending/SectorManager Approved/DRH Approved/Rejected)

  • SectorManagerApproval

  • DRHApproval

  • ApprovedDate

β€’ OvertimeRequests (NEW)

  • ID (Key)

  • EmployeeID (Ref β†’ Employees)

  • Date

  • StartTime

  • EndTime

  • OvertimeHours (auto-calculated)

  • OvertimeType (50% or 100% - auto-calculated)

  • CompHours (auto-calculated)

  • CompDays (auto-calculated)

β€’ LeaveBalance

  • EmployeeID (Key)

  • Balance (Virtual Column)

β€’ Holidays

  • Date

  • Name

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

:locked: SECURITY LOGIC:

:white_check_mark: Each Manager sees ONLY their employees:

Security Filter on CompensatoryLeave:

IN([EmployeeID],

SELECT(Employees[EmployeeID],

\[Manager Email\] = USEREMAIL()

)

)

:white_check_mark: Dropdown filtered by Manager:

Valid If on EmployeeID:

SELECT(Employees[EmployeeID],

[Manager Email] = USEREMAIL()

)

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

:white_check_mark: WORKFLOW (already working):

:one: Manager adds compensatory leave

  ↓ Email notification

:two: SectorManager approves/rejects

  ↓ Email notification

:three: DRH approves/rejects

  ↓ Balance updated automatically

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

:red_question_mark: ISSUE 1 β€” Custom Sequential ID:

I need IDs in this format: LCM-DR-26-001

β€’ LCM = site name (fixed)

β€’ DR = Demande de RΓ©cupΓ©ration (fixed)

β€’ 26 = current year last 2 digits (automatic)

β€’ 001 = sequential number per year

I tried:

β€œLCM-DR-” & TEXT(YEAR(TODAY())-2000,β€œ00”)

& β€œ-” & TEXT(COUNT(SELECT(

CompensatoryLeave[ID],

YEAR([Date])=YEAR(TODAY())

))+1,β€œ000”)

Is this correct? Any better approach?

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

:red_question_mark: ISSUE 2 β€” Overtime Auto-Calculation:

Business Rules:

β€’ ONLY Type1 employees are eligible

(Sunday→Thursday, 08:00→16:30)

β€’ Cadre, Type2, Type3 = NOT eligible

50% Overtime hours:

‒ Sunday→Thursday: 16:30→21:00

‒ Sunday→Thursday: 05:00→08:00

β€’ Saturday: 05:00β†’21:00

100% Overtime hours:

β€’ Every day: 21:00β†’05:00

β€’ Friday: all day

β€’ National & Religious holidays: all day

Compensation calculation:

β€’ 50% β†’ 1 hour worked = 1.5 hours compensation

β€’ 100% β†’ 1 hour worked = 2 hours compensation

β€’ 1 working day = 8 hours

β€’ Minimum entry = 0.5 hour

Example:

4 hours at 100% = 8 compensation hours = 1 day off

Input by Manager:

β€’ Date

β€’ Start Time

β€’ End Time

β†’ App calculates everything automatically

My formula for OvertimeType:

IF(

OR(

WEEKDAY(\[Date\]) = 6,

IN(\[Date\], Holidays\[Date\])

),

β€œ100%”,

IF(

AND(

  MOD((\[StartTime\]-0.875)\*24,24) >= 21,

  MOD((\[EndTime\]-0.875)\*24,24) <= 5

),

"100%",

"50%"

)

)

Questions:

1. Is this formula correct for time comparison

in AppSheet?

2. How to handle shifts that cross midnight

(e.g., 22:00 β†’ 03:00)?

3. How to split mixed shifts automatically?

(e.g., 18:00β†’23:00 = 2.5h at 50% + 2h at 100%)

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

:red_question_mark: ISSUE 3 β€” Hide fields in Form View only:

I want to hide these fields ONLY in Form View

(hide when adding, show in Detail View):

β€’ Status

β€’ SectorManagerApproval

β€’ DRHApproval

β€’ ApprovedDate

I used Show_If = FALSE but this hides them

everywhere. How to show them only in Detail View?

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

:red_question_mark: ISSUE 4 β€” Balance Virtual Column:

I’m using this formula in LeaveBalance table:

SUM(SELECT(CompensatoryLeave[Days],

AND(

\[EmployeeID\] = \[EmployeeID\],

\[Status\] = "DRH Approved"

)

))

Is Virtual Column the best approach or should

I use Automation Bot to update the balance?

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

:paperclip: Additional Info:

β€’ Data source: Google Sheets

β€’ Users: ~50 managers + sector managers + DRH

β€’ Platform: Mobile + Desktop

β€’ Industry: Industrial/Manufacturing (Holcim)

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Any help would be greatly appreciated! :folded_hands:

Thank you in advance.

1 Like