From 89e5e8a30345080dd9586f97d7ff78498fb49346 Mon Sep 17 00:00:00 2001 From: Kris Forbes Date: Mon, 12 Jan 2026 08:34:18 -0500 Subject: [PATCH] feat: add reporting pay type and logic --- ...19000_update_time_entries_reporting_pay.js | 19 +++++++++++++++++++ .../src/components/TimeEntry/EntryForm.jsx | 2 ++ frontend/src/lib/time-rules.js | 9 +++++++++ frontend/src/locales/translations.js | 4 ++++ 4 files changed, 34 insertions(+) create mode 100644 backend/pb_migrations/1736619000_update_time_entries_reporting_pay.js diff --git a/backend/pb_migrations/1736619000_update_time_entries_reporting_pay.js b/backend/pb_migrations/1736619000_update_time_entries_reporting_pay.js new file mode 100644 index 0000000..30f0f60 --- /dev/null +++ b/backend/pb_migrations/1736619000_update_time_entries_reporting_pay.js @@ -0,0 +1,19 @@ +migrate((db) => { + const dao = new Dao(db) + const collection = dao.findCollectionByNameOrId("time_entries") + + const typeField = collection.schema.getFieldByName("type") + // Add reporting_pay to the existing values + typeField.options.values = ["regular", "overtime", "standby", "callback", "non_contiguous", "reporting_pay"] + + return dao.saveCollection(collection) +}, (db) => { + const dao = new Dao(db) + const collection = dao.findCollectionByNameOrId("time_entries") + + const typeField = collection.schema.getFieldByName("type") + // Revert back to previous list + typeField.options.values = ["regular", "overtime", "standby", "callback", "non_contiguous"] + + return dao.saveCollection(collection) +}) diff --git a/frontend/src/components/TimeEntry/EntryForm.jsx b/frontend/src/components/TimeEntry/EntryForm.jsx index 0583b37..caa7558 100644 --- a/frontend/src/components/TimeEntry/EntryForm.jsx +++ b/frontend/src/components/TimeEntry/EntryForm.jsx @@ -152,7 +152,9 @@ const EntryForm = ({ onEntryAdded }) => { + + diff --git a/frontend/src/lib/time-rules.js b/frontend/src/lib/time-rules.js index f9b717b..d267c19 100644 --- a/frontend/src/lib/time-rules.js +++ b/frontend/src/lib/time-rules.js @@ -60,6 +60,15 @@ export const calculateBankedHours = (duration, type, dayType) => { return Math.max(minPay, workedValue); } + // --- REPORTING PAY --- + if (type === 'reporting_pay') { + // Article 9.03 (a): Minimum 4 hours pay at straight time rates + // OR time worked at applicable overtime rate, whichever is greater. + let workedValue = calculateOvertimeValue(hours, dayType); + const minPay = 4.0; + return Math.max(minPay, workedValue); + } + // --- REGULAR / OVERTIME --- if (type === 'overtime' || type === 'regular') { // "Regular" on a Time Tracker for Overtime usually implies "Regular Overtime" unless it is standard hours? diff --git a/frontend/src/locales/translations.js b/frontend/src/locales/translations.js index 3b18ed2..ac758c9 100644 --- a/frontend/src/locales/translations.js +++ b/frontend/src/locales/translations.js @@ -37,7 +37,9 @@ export const translations = { 'type.regular': 'Regular', 'type.standby': 'Standby', 'type.callback': 'Call-back', + 'type.callback': 'Call-back', 'type.non_contiguous': 'Non-Contiguous Hours', + 'type.reporting_pay': 'Reporting Pay', // Day Types 'day.workday': 'Normal Workday', @@ -123,7 +125,9 @@ export const translations = { 'type.regular': 'Régulier', 'type.standby': 'Disponibilité', 'type.callback': 'Rappel au travail', + 'type.callback': 'Rappel au travail', 'type.non_contiguous': 'Heures non contiguës', + 'type.reporting_pay': 'Indemnité de rentrée', // Day Types 'day.workday': 'Jour normal',