[
    {
        "version": "prl.0.0.2",
        "date": "2026-06-02",
        "notes": [
            "Added Post button in Payroll Processing",
            "Only Admins are permitted to revert posted payroll entries",
            "Department data is now properly connected and functional",
            "SSS Contribution Table updated to include employer's share and additional fields",
            "Payroll Processing filters for Department and Status are now fully functional"
        ]
    },
    {
        "version": "prl.0.0.3",
        "date": "2026-06-05",
        "notes": [
            "Reports module is now live \u2014 Payroll Summary, Payslip Report, Employee Masterlist, Loan Ledger, 13th Month Computation, Contributions (SSS / PhilHealth / Pag-Ibig), and BIR Report tabs added",
            "Reports \u203a Payroll Summary lists all posted payroll periods with a Reprint action per period",
            "Reports \u203a Payslip Report lists all employees for a selected posted period with per-employee and batch Print actions",
            "Reports \u203a Contributions combines SSS, PhilHealth, and Pag-Ibig into a single page with inner tabs (same pattern as System Config \u203a Contributions)",
            "Reports \u203a Employee Masterlist is now live with Active/Inactive filter and CSV export",
            "Reports \u203a Loan Ledger is now live with Type and Status filters and CSV export",
            "Reports \u203a 13th Month Computation is now live with year filter and CSV export",
            "Export Summary button removed from Payroll Processing \u2014 payroll summary reports are now accessed exclusively from the Reports module",
            "Payroll Processing posted badge moved to the left side of the card header, next to the title",
            "All Payroll Processing action buttons (Process Payroll, Generate Payslips) are now disabled when the period is posted; Unpost button remains available for Admins only",
            "Pay frequency is now available as a PHP page-scope variable and as JS globals (SESSION_PAY_FREQUENCY, SESSION_IS_WEEKLY) for use across views",
            "Fixed: Payslip Report spinner was stuck on initial page load when no period was selected",
            "Fixed: Print All button animation in Payslip Report now properly resets after the file is downloaded",
            "Fixed: payslips_pdf.php now sets the download cookie so button state feedback works correctly for both batch and individual payslip prints",
            "Timecard Manager period filter (date range) is now fully functional \u2014 changing the start or end date reloads the table with the correct filtered records",
            "Employee list panel: removed h-100 stretch from LOA, Deductions, OT Approval, DTR, and Employee 201 File views",
            "DTR, OTA, LOA, and Loan/CA: employee list and detail card are now always inline (flex-nowrap) \u2014 columns no longer wrap on narrow screens",
            "DTR, OTA, LOA, and Loan/CA: detail card now clips overflow correctly and scrolls horizontally instead of bleeding outside the card",
            "Timesheet Manager, Shift and Schedule, Timecard Manager, and Payroll Processing: tables now scroll horizontally inside the card instead of overflowing it",
            "DataTables page length defaults updated \u2014 no-paging tables show all rows, Employee 201 File defaults to 30 rows, all other tables default to 15 rows with matching length-menu options",
            "Fixed: DataTables length menu dropdown no longer shows blank when page length is not a multiple of 5",
            "Fixed: Timecard Manager (and all other DT tables) no longer show phantom whitespace at the far-right end of the horizontal scroll \u2014 root cause was Bootstrap .row negative side-margins (margin-inline: -12px) extending the table row beyond its wrapper; fixed by adding .g-0 to all DT-injected rows",
            "Fixed: Employee Masterlist table was wiped on load due to DataTables search teleport targeting the table element itself instead of the filter bar placeholder",
            "Fixed: Loan Ledger, Employee Masterlist, and 13th Month report tables threw DataTables TN/4 error when switching filters \u2014 old DataTable instance was orphaned on HTML replace; resolved by explicitly destroying the existing instance before reloading",
            "Fixed: DataTables TN/4 error on empty filter results \u2014 single-cell colspan placeholder rows (PHP empty-state rows) are now stripped by sanitizeBody before DataTables initialises, falling back to the built-in empty table message",
            "Renamed rpt.js to rpt_payroll_summary.js for naming consistency across report JS files",
            "Mobile-friendly interface added \u2014 sidebar collapses into a hamburger drawer on small screens, tab bar scrolls horizontally, and all tables scroll horizontally on mobile instead of overflowing",
            "Fixed: User Management new user rows were silently dropped on Save \u2014 DataTables strips custom data attributes from <tr> elements when rendering; attributes are now restored after row.add()",
            "User Management: duplicate username validation added \u2014 real-time check on blur flags usernames already in use with Bootstrap is-invalid styling and a tooltip message; server-side pre-validation blocks save and returns the conflicting usernames",
            "Fixed: Company Profile page showed empty fields for Payroll Officer accounts \u2014 fetch endpoint was restricted to Admin only; now accessible to all non-employee roles",
            "Sidebar profile: users without an employee photo now show a role abbreviation badge (ADM, PO, TK, SV) instead of the generic account icon"
        ]
    },
    {
        "version": "prl.0.0.4",
        "date": "2026-06-06",
        "notes": [
            "Mobile UI improvements \u2014 login page no longer overlaps on input focus; inputs use font-size 16px to prevent iOS auto-zoom",
            "Mobile UI: page scrolling restored on all pages \u2014 overflow-y was previously hidden on wrappers causing content to be clipped",
            "Mobile UI: filter bar layout optimised \u2014 search box moves to its own full-width row, Last Refreshed aligns with the Filter label, selects are 100% width",
            "Mobile UI: DataTables whitespace removed \u2014 overrode Bootstrap's injected --bs-gutter-y on DT rows at mobile breakpoint",
            "Mobile UI: Employee Applications (LOA, OTA, Deductions) two-panel layout now stacks vertically on mobile with full-width panels",
            "Mobile UI: Employee 201 File two-panel layout now stacks vertically on mobile (added flex-nowrap to row, consistent with other two-panel pages)",
            "Mobile UI: DTR two-panel layout \u2014 gap added between stacked employee list and detail card",
            "Mobile UI: Timesheet Manager modal \u2014 reduced g-5 gutter to 0.75rem on mobile; ATT Records table wrapped in scroll container",
            "Mobile UI: Shift & Schedule table \u2014 added missing .ss-grid-responsive scroll wrapper around #tblSs; table now scrolls horizontally instead of overflowing",
            "Mobile UI: Biometrics modal and Payroll Processing modal \u2014 reset hardcoded pixel widths to auto on mobile",
            "Mobile UI: Payroll Summary modal \u2014 panels stack vertically on mobile; input-group checkbox spans no longer wrap to a new line; header title truncates with ellipsis",
            "Mobile UI: Pending Deduction and Biometrics modal tables wrapped in table-responsive for horizontal scroll",
            "Mobile UI: Employee 201 File \u2014 Pre-employment Docs and Employment Docs tables wrapped in table-responsive",
            "Mobile UI: System Config Contributions current active table wrapped in table-responsive",
            "Mobile UI: Timecard Manager filter bar \u2014 PERIOD and Abnormal Only controls reordered below search on mobile; Last Refreshed pinned to Filter label row",
            "CSS: removed 3 redundant rules from app.css \u2014 duplicate early .modal-header block (overridden by the correct block 840 lines later), duplicate .main-content padding inside the mobile breakpoint, and a no-op .erp-filter-bar align-items repeat inside the mobile breakpoint",
            "Payroll Processing: filter bar reordered \u2014 All Departments and All Status selects now appear above the Search box on both desktop and mobile; mobile layout pins Last Refreshed to the Filter label row, selects stack full-width below it, search appears last",
            "System Config \u203a User Management: Role Permissions matrix added \u2014 administrators can now define access levels per role (EMP, SV, TK, PO, ADM) across all system modules directly from the User Management tab",
            "Role Permissions: access levels are granular \u2014 each cell is a dropdown with three options: No Access (\u2014), View (read-only), and Edit (full access); defaults match the previous hardcoded role behaviour and take effect after the first Save Matrix",
            "Role Permissions: matrix is backed by a new role_permissions DB table; saving upserts all 125 role \u00d7 action cells in a single operation",
            "Role Permissions: role column headers show a tooltip icon (\u24d8) \u2014 hovering reveals the full role name (Employee, Supervisor, Timekeeper, Payroll Officer, Administrator)",
            "Role Permissions: legend added to the filter bar showing \u2014 No Access, View, and Edit badge indicators",
            "Role Permissions: matrix table wrapped in table-responsive for horizontal scroll on mobile devices",
            "Sidebar navigation is now driven by the Role Permissions matrix \u2014 menu items (Org Set-up, Timekeeping, Payroll Processing, Reports, System Config) show or hide based on the saved DB permissions, with hardcoded role defaults as fallback when the table is empty",
            "Org Set-up tabs (Company Profile, Employee 201 File, Department, Site, Resignation) are now individually gated by the Role Permissions matrix \u2014 users see only the tabs their role has access to",
            "View-only mode: when a role has View (level 1) but not Edit (level 2) access to a page, all write controls (buttons, inputs, selects, textareas) are automatically disabled on load and for any AJAX-injected content via MutationObserver",
            "View-only mode: a yellow banner is displayed at the top of the page reading 'View-only \u2014 you do not have permission to make changes on this page'",
            "Fixed: Timekeeping sidebar group label was hidden for roles without Timekeeping access, leaving Employee Apps with no group heading \u2014 label is now always rendered since Employee Apps is always visible beneath it"
        ]
    },
    {
        "version": "prl.0.0.5",
        "date": "2026-06-07",
        "notes": [
            "OT, LOA, and Loan/CA: period filter (date range) added inline in the card header beside the employee name and ID \u2014 defaults to the current pay period selected in Payroll Schedule, reloads the employee's records when changed",
            "Pending OT, Pending LOA, and Pending Loan/CA modals: period filter added in the modal header (far right, beside the close button) \u2014 defaults to the current pay period on open, re-fetches the pending list when changed",
            "Pending OT/LOA/Loan/CA fetch endpoints now accept date_from and date_to parameters to scope results to the selected period",
            "Pending OT, LOA, Loan/CA, and Biometrics modal bodies: removed default Bootstrap padding (p-0) so tables render flush to the modal edges",
            "Fixed: System Config (Payroll Schedule, Contributions, Rules) was not visible in the sidebar for roles with Setup & Configuration access \u2014 sidebar now shows System Config for any role that has access to at least one SC module, not just roles with User Management access",
            "Fixed: System Config sidebar link now lands on the first SC page the role actually has access to (User Management \u2192 Payroll Schedule \u2192 Contributions \u2192 Rules) instead of always linking to User Management",
            "Fixed: System Config tabs (User Management, Payroll Schedule, Contributions, Rules) are now individually gated \u2014 roles only see the tabs they have permission to access",
            "Fixed: Role Permissions edit access was not being applied correctly \u2014 the role_permissions table was missing a UNIQUE KEY on (rp_module, rp_action, rp_role), causing every Save Matrix to INSERT a new row instead of updating the existing one; duplicate rows resulted in non-deterministic permission lookups where the old value could silently override the new one",
            "Fixed: permissions SELECT query now uses MAX(rp_allowed) with GROUP BY to always resolve to the highest granted access level per cell, eliminating the race condition caused by duplicate rows",
            "Added migration: migrations/2026_06_07_role_permissions_unique_key.sql \u2014 deduplicates existing rows and adds the UNIQUE KEY so future saves correctly use ON DUPLICATE KEY UPDATE",
            "DTR table inputs now fill their entire cell \u2014 td padding removed on non-date columns, inputs are borderless and transparent at rest, and display a focused inset ring on active edit; eliminates the small fixed-width dead zones that made cells hard to click",
            "System Config \u203a System Logs tab added (Admin only) \u2014 Admins can now view payroll-errors.log and the server PHP error log directly in the browser; source toggle switches between Payroll Errors and PHP Errors; shows timestamp, type, severity badge, context (file:line for PHP errors, context tag for payroll), and message columns; severity filter options change per source (HTTP codes for payroll, Fatal / Warning / Notice / Deprecated for PHP); line-count selector (50\u20131000) and Refresh button; PHP log path resolved dynamically via ini_get; log files are never served raw",
            "Code audit \u2014 button and table consistency: btn-recalc in payroll summary modal migrated from raw $.ajax() click handler to wireAjaxFormButton; hol-delete migrated from raw $.ajax() click handler to wireAjaxFormButton; contrib-parse-btn and contrib-save-btn documented as intentional exceptions (no <form> element to serialize); btn-calc-payroll pre-check interceptor documented as intentional two-handler pattern; Pre-employment Docs and Employment Docs tables in Employee 201 File patched with table-bordered and data-dt-ignore; Contribution Deduction reference table in Payroll Schedule patched with table-bordered and data-dt-ignore"
        ]
    },
    {
        "version": "prl.0.0.6",
        "date": "2026-06-07",
        "notes": [
            "Fixed: active pay period now persists across logout \u2014 the selected cutoff start and end dates are saved to payroll_sys_config (last_cutoff_start / last_cutoff_end) whenever the Payroll Schedule settings are saved",
            "Fixed: on fresh login or session expiry, the active pay period is now restored from the last DB-saved period instead of defaulting to the current calendar week; the calendar-week fallback is now only used on first-time setup when no saved period exists",
            "Fixed: Payroll Processing RECALC confirmation dialog now shows the exact pay period dates (start \u2192 end) so users can verify they are recalculating the correct period before confirming",
            "Safety check added: Process Payroll and RECALC both now detect when the selected pay period has not ended yet (cutoff end date is in the future) and show a prominent warning before allowing the operation to proceed \u2014 prevents accidental payroll runs on incomplete or wrong periods",
            "Loan/CA: Delete is now available for all statuses (Active, Pending, Paused, Closed, Rejected, Cancelled) \u2014 PO and Admin roles can remove erroneous deduction records at any stage; for Closed deductions the server automatically reverses all ledger entries and adjusts the affected payslip CA/Loan totals and net pay; deletion is blocked if the payroll period containing the deduction is already posted",
            "Payroll Summary modal: paused deduction indicator added \u2014 when an employee has a CA or Loan in Paused status with a remaining balance, a blue info banner appears inside the Deduction card showing each paused item's type, remaining balance, and per-period amount; makes it immediately visible that the deduction was skipped for the current period",
            "Payroll Summary modal: RECALC button is now disabled when the payroll period is already posted; a lock notice ('Period is already posted \u2014 updating is not allowed.') is displayed in the modal footer to make the read-only state explicit"
        ]
    },
    {
        "version": "prl.0.0.7",
        "date": "2026-06-11",
        "notes": [
            "Quick period change shortcut added \u2014 Payroll Officers and Admins now see the active pay period badge in the topbar as a clickable button (pencil icon); clicking it opens an inline panel with Start and End date pickers and Save / Cancel actions, so the pay period can be changed without navigating to System Config \u203a Payroll Schedule",
            "Quick period panel: Save button follows the standard btn-icon-mode structure and behavior \u2014 spinner while saving, green checkmark on success, resets to idle after 1.5 s; panel stays open after a successful save so the updated badge can be confirmed before closing",
            "Quick period panel: topbar badge text updates in-place immediately after a successful save without a page reload; the panel pre-fills with the newly saved start date on next open",
            "Quick period panel: topbar badge is hidden on mobile (screen width \u2264 767 px) \u2014 the full Payroll Schedule settings remain available in System Config on all screen sizes",
            "Payroll Processing: Post button is now gated \u2014 it only appears after payroll has been generated for the period; periods with no payroll rows show neither Post nor Unpost, preventing accidental posts on empty periods",
            "System Config \u203a User Management: developer accounts (pu_dev_flag = 1) are now hidden from the user table \u2014 dev entries no longer appear in the list and cannot be edited or deleted through the UI",
            "Security: ded_counter.php, loa_counter.php, and ot_counter.php now call bootApiSession() \u2014 unauthenticated requests are rejected with HTTP 401 instead of silently serving data",
            "ot_counter.php: wrapped in try/catch so executeQuery failures return a safe fallback instead of a fatal error",
            "Fixed: loa_save.php leave-balance deduction was returning a false 409 on every approval \u2014 SELECT ROW_COUNT() after a prepared statement always returns -1; replaced with the affected-rows return value from executeQuery()",
            "Fixed: payroll_process.php deduction ledger INSERT and employee_deductions UPDATE used throwOnError=false \u2014 silent write failures inside a transaction now throw and trigger a proper rollback",
            "Fixed: timesheet_save.php delete path issued a redundant inner mysqli_begin_transaction(), which implicitly committed the outer transaction before the delete executed; redundant call removed",
            "Security: ded_approval.php and loa_approval.php no longer expose raw exception messages to the client in error responses",
            "Fixed: deduction_save.php UPDATE bind-type string had 'i' (integer) for employee_id which is a string column \u2014 corrected to 's'",
            "Security: ded_status_update.php now requires employee_id to be present \u2014 previously a missing employee_id allowed a ded_id-only lookup, enabling cross-employee status changes",
            "Fixed: pay_period.js bi-monthly cutoff end-date calculation used day <= cutoff_day_1, producing a zero-length period when the user picked exactly cutoff_day_1; corrected to day < cutoff_day_1",
            "Fixed: sc_users.js scroll-to-row animation computed NaN due to wrong operator precedence ($row.offset()?.top - 100 ?? 0); corrected to ($row.offset()?.top ?? 0) - 100",
            "Deduction status buttons (Pause/Resume/Close/Reject/Cancel) migrated from raw $.ajax() handler to wireAjaxFormButton() \u2014 gains standard spinner, success feedback, and error handling",
            "sc_logs.js: removed local esc() duplicating global escapeHtml(); all 5 call sites updated; added complete: callback so showCompleted() always fires after loadLogs() AJAX to prevent stuck processing state; renamed shadow variable const p \u2192 const parsed inside renderRows forEach",
            "Removed duplicate formatEmployeeDisplayName() from ota.js, loa.js, and deduction.js; consolidated into app.js as a single global",
            "sc_users.js renderUmDeleteBtn() replaced with a call to renderBtn() \u2014 eliminates inline button HTML duplication",
            "payroll_process.php: removed local diffMinutes(), normalizeDateTime(), addMinutes(), and fetchTimecardPunchWindow() \u2014 all were identical to attDiffMinutesBetweenTimestamps(), attNormalizeDateTimeForWorkDate(), attAddMinutesToTimestamp(), and attFetchTimecardPunchWindow() in functions.php; all call sites updated to use the global helpers",
            "functions.php: added normalizeCheckboxToInt() and mapLoaTypeToBalanceCol() as shared helpers; removed duplicate definitions from loa_save.php, ota_save.php, and loa_approval.php",
            "Shift & Schedule: schedule plotting is now locked when the active pay period is posted \u2014 all day-cell dropdowns are disabled, the Save Week, Reset View, and Plot Range buttons are disabled, and a lock banner replaces the info notice; the lock lifts automatically when the period is unposted",
            "Shift & Schedule: server-side guard added \u2014 both the Save Week (bulk grid) and single-assignment save paths reject writes with HTTP 409 if the pay period is already posted, preventing bypasses via direct POST",
            "Shift & Schedule: Department filter added to the filter bar alongside the existing search \u2014 selecting a department shows only employees in that designation; the daily headcount row updates to reflect visible employees only; selecting All Departments restores all rows",
            "Payroll Processing: Post Payroll now runs four pre-checks before allowing a post \u2014 blocks if no schedules have been plotted in Shift & Schedule, no timecards calculated, no DTR records processed, or no payslips generated; all failing checks are shown together in a dismissing warning notice above the filter bar",
            "Timecard Manager: Timesheet filter added to the filter bar \u2014 selecting a timesheet limits the table and CSV export to records assigned to that timesheet; defaults to All Timesheets",
            "System Config \u203a Leave Balances: new page for configuring annual leave allocations per leave type (SL, VL, SIL, PL, ML) \u2014 each type has an Annual Days amount, a Carry Over toggle (when on: remaining balance carries forward and annual days are added on top; when off: balance resets to the annual amount), and an Enable Refresh toggle; an Auto-Refresh Date (month + day) is configurable and stored in system settings; the refresh fires automatically on the first page load on or after the configured date each year using an atomic DB claim so it runs exactly once even under concurrent requests; a Run Refresh Now button is also available for manual runs; leave_balance_config table is created and seeded with defaults on first access",
            "Unsaved-changes guard extended system-wide \u2014 the browser confirm prompt that previously protected only the DTR form now covers Employee Information, Payroll & HR Records, Pre-employment Documents, Employment Documents, Company Profile, Payroll Rules, Payroll Period Settings, Government Contributions, Holiday Configuration, and Shift & Schedule; alert fires on tab switch, employee row click, year-filter change (holidays), and page close/navigation; each form clears its dirty flag automatically after a successful save",
            "System Config \u203a Leave Balances: annual leave amounts now split into Probationary and Regular tiers \u2014 each leave type has separate day allocations for probationary and regular employees; the refresh applies the correct amount per employment status; leave_balance_config table migrated with annual_amount_prob and annual_amount_reg columns; existing installs are upgraded and seeded automatically on first access",
            "System Config \u203a Leave Balances: Leave Balance Configuration added to the Role & Permissions matrix under Setup & Configuration so access can be granted per role",
            "System Config \u203a Leave Balances: page title now correctly resolves to System Configuration > Leave Balances via renderTitle() & setPageTitle()",
            "Fixed: Employee 201 File \u2014 Add New Employee button was accidentally removed from the employee list card header; restored and gated to Admin and Payroll Officer roles only",
            "Employee 201 File \u203a Payroll & HR: tab overhaul \u2014 Allowances card replaced the single lump-sum input with a Philippine-standard breakdown (Transportation, Meal / Food, Communication / Internet, Housing, COLA, Clothing / Uniform, Medical), each wired into payroll processing as other earnings, stored in individual columns, defaulting to 0.00, and the card is now constrained to col-lg-6 to match the other cards; a Salary History button was added that opens a modal showing Period, Net Pay, Posting Date, and Bank Reference (placeholder); Leave Balance labels (SL, VL, SIL, PL, ML) now show a tooltip icon with the full leave type name on hover; and the Payroll Details coming-soon tiles were restyled to match the Salary History button shape and size",
            "Biometric Logs modal: employee badge now shows First Name and Last Name only (middle name and suffix removed)",
            "Salary History modal: employee badge follows the same Name [ID] format as Biometric Logs",
            "System Config \u203a User Management: Role Permissions column headers (EMP, SV, TK, PO, ADM) now show a tooltip icon with the full role name on hover",
            "Code cleanup: normalized table markup system-wide \u2014 removed table-light / bg-light, text-end, text-center, text-start, text-nowrap, and small classes plus all inline styles from table elements (table, thead, tbody, tr, th, td, tfoot)",
            "Payroll Processing: Process Payroll button now runs the same pre-checks as Post Payroll before executing \u2014 warns if no schedules have been plotted in Shift & Schedule, no timecards have been calculated, or no DTR records are found for the period; user can still proceed after confirming each warning",
            "Code cleanup: replaced all custom row-top-margin-x and row-bottom-margin-x classes with Bootstrap utility classes (mt-x / mb-x) across all views, modals, and JS files; custom CSS definitions removed from app.css",
            "System Config: User Management tab is now restricted to Admin role only \u2014 Payroll Officer accounts no longer see User Management in the System Config tab bar",
            "Security: server-side page-access enforcement added \u2014 restricted pages (Organization Setup, Timekeeping, Payroll Processing, Reports, System Config) can no longer be opened by typing the URL directly; the page router now checks the same Role Permissions matrix used to render the sidebar and redirects unauthorized roles to the Dashboard (previously the sidebar only hid the links while the page still rendered)",
            "Security: all API endpoints now enforce the Role Permissions matrix server-side \u2014 fetch/save endpoints across Organization Setup, Timekeeping, Employee Applications, Payroll, Setup & Configuration, and Users & Reports were migrated from static role checks to a new requirePermission() helper (reads require View, saves / approvals / deletes require Edit), so access configured in System Config is honored at the endpoint instead of being cosmetic; editing the permission matrix itself remains hard-locked to Admin to prevent privilege escalation",
            "Security: the holiday-delete path (holidays_fetch.php) was missing both a permission check and CSRF validation \u2014 any logged-in user could delete holidays via a crafted request; deletion now requires CSRF and Edit-level Holidays permission",
            "Fixed: removed a dead permission mapping (sc_logs referenced a non-existent setup_config.system_logs action); System Logs remains Admin-only",
            "Dashboard: new landing page with at-a-glance KPI cards (pending Overtime/WDO, Leave, and Loan/CA approvals, plus active headcount), a current pay-period summary (status, payslip count, gross/net totals), and a \"Needs Your Attention\" list that links into the relevant modules; data is role-aware \u2014 Employees see their own pending items and payslip totals while approvers and Admins see organization-wide figures. The page shows the current date and is access-controlled via a new Dashboard row in the Role Permissions matrix",
            "Role Permissions matrix consolidated for clarity: Payroll Schedule is now its own action separate from Rules; Company Profile collapsed from two rows (View Company Profile / Edit Company Profile) into a single action that uses the per-cell View/Edit dropdown; Rules and Holidays merged into one action; View / Manage Users and User Access Control merged into one action; and the old \"Export Summary / Generate Payslips\" label was shortened to \"Generate Payslips\" (Export Summary now lives under Reports). Existing permissions were migrated automatically, obsolete rows cleaned up, and the matrix now always loads its current definition instead of a cached copy",
            "Timekeeping permissions are now enforced per tab \u2014 Biometric Upload, Timesheet Manager, Shift & Schedule, Timecard Manager, and Daily Time Record each honor their own matrix action for sidebar visibility, tab buttons, and page access (previously all five rode on the single Timesheet Manager permission); roles without Dashboard access now land on their first permitted page instead of a blocked Dashboard",
            "System Config \u203a Rules: Holiday Management now has a holiday-type filter (Regular / Special Non-Working) alongside the existing year filter",
            "UI: the signed-in user now appears as a top-right account menu \u2014 showing name and Employee ID / role \u2014 with Logout moved into it; the sidebar footer now displays the application version. The pay-period badge is hidden on Biometric Upload and Timesheet Manager, and its quick-edit shortcut (Payroll Officer / Admin only) no longer shows a hover tooltip"
        ]
    },
    {
        "version": "prl.0.0.8",
        "date": "2026-06-13",
        "notes": [
            "Security: login brute-force protection added \u2014 after 3 failed sign-ins an account is temporarily locked for 5 minutes, and after 6 failed sign-ins it is locked until an administrator unlocks it. System Config \u203a User Management now shows a Locked / Timed-out badge and an Unlock button per account, and every sign-in attempt is recorded for auditing",
            "Login: the username is now kept after a failed sign-in so it no longer has to be retyped, and the page shows a clear message when an account is temporarily timed out or has been locked",
            "Security hardening: removed the one-time contribution seed script from the server, blocked direct web access to the uploads and migrations folders, and stopped internal error details from being shown in the browser when Timecard Manager or Departments fail to load",
            "Account menu: the top-right dropdown now shows your avatar, and avatar badges are color-coded by role (Admin, Payroll Officer, Timekeeper, Supervisor, Employee)",
            "Tables: column headers now stay pinned to the top while scrolling long tables \u2014 applied across the data tables, the Role Permissions matrix, Government Contributions, and System Logs",
            "Mobile: the Overtime/WDO, Leave, and Loan/CA tables now scroll horizontally within their card instead of overflowing on small screens",
            "Maintenance: database schema setup was moved out of runtime code into versioned migration files, and a case where a database error while saving the weekly schedule was silently ignored has been fixed",
            "Pay period: changing the active pay period from the topbar now refreshes the current page so all period-dependent content updates immediately \u2014 the Shift & Schedule, Daily Time Record, and Payroll Processing tables, plus the posted/locked banner \u2014 instead of continuing to show the previous period",
            "Timecard Manager: the topbar pay-period selector is now hidden on this page, which has its own Period date-range filter \u2014 removing the confusion of two competing period controls"
        ]
    },
    {
        "version": "prl.0.0.9",
        "date": "2026-06-15",
        "notes": [
            "Timezone: all recorded times now display in Philippine Time (PHT) instead of the server's US time \u2014 this corrects the 'Last Refreshed' labels and other timestamps that were previously showing the wrong time",
            "Last Refreshed now shows who performed it \u2014 the Timecard Manager, Payroll Processing, and Leave Configuration pages display the user who triggered the last refresh/recalculation (e.g. '\u2026 \u00b7 by jake-01')",
            "Posted pay period lock: once a period is posted, Daily Time Record editing (Save and Recalc) is locked while the Biometrics lookup stays available, and Timecard Manager recalculation is locked",
            "Posted pay period lock: Overtime, Leave, and Loan/CA applications can no longer be approved once the period is posted (filing is still allowed) \u2014 this is enforced on both the per-record screens and the bulk Pending approval modals",
            "A 'This pay period is posted' banner now appears on the Daily Time Record, Timecard Manager, Overtime, Leave, and Loan/CA pages when the active period is posted, explaining what is locked",
            "Fixed: Process Payroll incorrectly warned 'No DTR records found for this period' even after the DTR had already been generated \u2014 the pre-check was checking the wrong table",
            "Overtime approval: approving a single OT record now applies the same TimeCard OT ceiling used by the bulk Pending OT approval \u2014 applied OT can no longer exceed the system-computed TimeCard OT",
            "Pay period: switching the active pay period from the topbar now refreshes just the current table instead of reloading the whole page \u2014 faster and less disruptive",
            "Timecard Manager: filter bar reordered on desktop to Timesheet, Search, Period, then Abnormal Only; on mobile the Period date inputs no longer overlap and the Last Refreshed label aligns with the Filter label",
            "Mobile: improved layout of the Overtime, Leave, and Loan/CA pages, and the close (X) button on their Pending approval modals now stays aligned with the modal header instead of dropping below the period filter",
            "Fixed: the close (X) button on the Timesheet Manager and Shift & Schedule modals was hard to click \u2014 a body element was overlapping the header and intercepting the click; the header close button is now reliably clickable",
            "Fixed: a JavaScript error on the Sign In page \u2014 the shared app script now skips its main-workspace startup when loaded outside the authenticated app, so the Sign In page no longer throws a console error or briefly change its title",
            "Performance: the Fira Code web font now loads via a preconnected stylesheet link instead of a render-blocking CSS import, slightly improving first-paint on the Sign In and main pages",
            "Maintenance: sidebar styles merged into the main stylesheet (one fewer file request per page), and duplicated table-reload and modal button code consolidated into shared helpers \u2014 no change to behaviour",
            "Maintenance: removed deprecated and unused files (os_dept_delete.php, sidebar.css) and standardised the mobile breakpoint for consistency",
            "Timecard Manager: removed the per-page Period date filter \u2014 the table and Recalculate now follow the top pay-period selector, consistent with Payroll Processing and the Employee Applications pages",
            "Fixed: Timecard Recalculate could recompute and overwrite dates inside an already-posted pay period when run with no/overlapping date range \u2014 recalculation now scopes to the active pay period and skips any date that belongs to a posted period"
        ]
    },
    {
        "version": "prl.0.1.0",
        "date": "2026-06-17",
        "notes": [
            "Payroll Processing: the per-row View action moved out of the separate right-most OPT column and now sits as an icon button beside the Employee ID \u2014 one fewer column and the action is reachable without scrolling across the table on mobile",
            "Reports \u203a Payroll Summary: fixed the Reprint button, which was unresponsive \u2014 its click handler was bound to a selector that never matched the rendered button",
            "Removed unused DataTables Buttons CDN scripts that were failing to load (CDN redirect loop) and producing console errors on every page"
        ]
    },
    {
        "version": "prl.0.1.1",
        "date": "2026-06-26",
        "notes": [
            "Daily Time Record Recalc now rebuilds the timecard from the raw biometric punches for the selected employee \u2014 the same calculation the Timecard Manager performs \u2014 so one employee can be fully recomputed without recalculating the whole pay period",
            "Daily Time Record Recalc now keeps approved Overtime and Leave instead of resetting them to pending, so payroll no longer silently drops them after a recalc; the only exception is overtime that is no longer eligible under a changed schedule (for example, the assigned timesheet no longer grants OT), which is reverted to pending",
            "Daily Time Record now shows a 'Last Refreshed \u00b7 by \u2026' label indicating who last recalculated the selected employee and when, matching the Timecard Manager",
            "Timecard Manager: Recalculate now shows a '\u26a0\ufe0f Warning' confirmation before recomputing a pay period that already has timecards \u2014 making it explicit that approved Overtime and Leave will be reverted to pending, and pointing to the per-employee DTR Recalculation for individual corrections; the Payroll Processing recalculation warning now uses the same heading for consistency",
            "Reports \u203a Payroll Summary: opening a posted period now shows an HR | PO tabbed view (same inner-tab pattern as Contributions). The HR tab (full summary table, signed by 'Prepared by' only) is Admin-only \u2014 Payroll Officers see the PO tab only. PO shows a NET PAY release table with blank Signed / Date Signed columns for wet signatures, plus a cash-denomination grand total (1000/500/200/100/50/20 + remainder) computed from each employee's individual breakdown \u2014 signed by 'Released by' only. The PO tab can upload the scanned signed release sheet",
            "Reports \u203a Payroll Summary: the exported HR and PO PDFs now carry a company-logo letterhead (logo with the report title beside it) and use the system's font and navy/blue color scheme (logo appears in the PDF only)",
            "Payslip PDFs now carry the company-logo letterhead too (logo beside the payroll-period title); the BIR 2316 keeps the official BIR layout, so no company letterhead is added to it",
            "Employee Portal reorganized into tabs \u2014 COE (Certificate of Employment, coming soon), Form 2316 (ITR) which hosts the existing BIR 2316 download, and Other (coming soon)",
            "BIR Form 2316 now generates on the actual official September 2021 (ENCS) BIR form (Folio / 8.5x13) \u2014 the employee's data is printed in bold directly into the correct boxes, including TIN groups, year, period, date of birth and contact number combs. Fields auto-populate from the employee record and posted payroll (TIN, name, RDO, address, birthday, MWE status; gross/taxable/non-taxable compensation, contributions, 13th-month split, and taxes withheld); untracked fields (previous employer, foreign address, de-minimis breakdown) are left blank for manual entry",
            "Reports \u203a Payroll Summary: each tab has its own PDF export (HR summary sheet / PO release sheet); the old single Reprint action is replaced by a per-period View that opens the tabs",
            "Reports \u203a Payroll Summary: the PO tab can upload a scanned, signed copy of the release sheet (PDF or image) \u2014 re-upload is allowed even after the period is posted, and the file shows who uploaded it and when",
            "Reports: all employee-listing report tables (Payslip, Masterlist, Loan Ledger, 13th Month) are now ordered by Employee ID",
            "Fixed: Daily Time Record table did not update when the active pay period was changed from the topbar \u2014 the JS cutoff date globals (SESSION_CUTOFF_START_DATE / SESSION_CUTOFF_END_DATE) were declared as const and never updated after the AJAX save, so the employee panel continued fetching DTR rows for the old period; globals are now let and are updated immediately after a successful period change",
            "Fixed: Cash Denomination breakdown in Payroll Summary PO tab was missing \u20b110, \u20b15, and \u20b11 denominations \u2014 both the on-screen table and the PDF export now include the full denomination set; the 'Remainder (<20)' row is relabeled 'Centavos (<1)' since \u20b11 coins cover all whole-peso remainders",
            "Payroll Summary \u203a PO tab: SIGNED and DATE SIGNED columns in the NET PAY release table now populate automatically when a signed release sheet has been uploaded \u2014 every employee row shows a green 'Signed' badge and the upload timestamp; columns remain blank until a signed copy is uploaded",
            "Employee 201 File: Portal Requests tab added (Admin and Payroll Officer only) \u2014 shows a per-employee log of every document downloaded from the Employee Portal, including request type, detail (e.g. tax year), and timestamp; BIR Form 2316 downloads are now logged automatically"
        ]
    },
    {
        "version": "prl.0.1.2",
        "date": "2026-07-02",
        "notes": [
            "Roles are now managed records instead of being hardcoded \u2014 System Config \u203a User Management is reorganized into three tabs: Roles, Users, and UAC (role permissions)",
            "Roles tab: define and manage each role's display name, short label, accent color, ordering, and active state in one place; role colors now flow through to user avatars and badges across the app",
            "Custom roles \u2014 Administrators can now create new roles beyond the built-in set (e.g. HR) and assign them to users; new roles appear automatically as a column in the UAC matrix and in the user role dropdowns",
            "The Administrator role is protected \u2014 it cannot be deleted or deactivated and always appears first; other roles can be renamed, reordered, deactivated, or deleted (a role still assigned to users cannot be deleted until those users are reassigned)",
            "Access control is now driven end-to-end by the UAC permission matrix rather than fixed role names \u2014 Post / Unpost Payroll, the pay-period edit shortcut, Add Employee and User Access in the 201 File, and the OT / LOA / Deduction approval controls all follow the matrix, with server-side enforcement aligned to match so access is consistent whether using the screen or a direct request",
            "Reports \u203a Payroll Summary: HR and PO tabs are now individually permission-controlled \u2014 two new actions, 'Payroll Summary \u2014 HR View' and 'Payroll Summary \u2014 PO View', let each role be limited to its own tab and PDF export (e.g. HR sees only the HR tab, PO sees only the PO tab)",
            "Fixed: opening System Config \u203a User Management could crash the page while the Users table loaded \u2014 the table loaders were targeting all three tabs at once; each tab now loads independently",
            "Fixed: long help text in the Roles and UAC information bars was being clipped on one line instead of wrapping to the next",
            "Fixed: opening the Pending OT / LOA / Deduction approval modal could freeze the page with a 'Maximum call stack size exceeded' error \u2014 the Select-all checkbox re-triggered its own change handler because the header checkbox was included in the row selection; row-checkbox handling is now scoped to the table body",
            "Fixed: approving or rejecting items in the Pending OT / LOA / Loan-CA modal now refreshes the list immediately \u2014 previously the approved or rejected rows stayed visible in the modal until it was closed or the page was reloaded",
            "Dialogs now close automatically after a successful save \u2014 filing or editing an OT, LOA, or Loan/CA request closes its dialog once saved, and the Set Password dialog now closes consistently in both User Management and the Employee 201 File",
            "Fixed: adding a new employee failed with a server error \u2014 the insert still referenced the old single 'allowances' column instead of the seven per-type allowance columns (Transport, Meal, Communication, Housing, COLA, Clothing, Medical); new employees now save correctly with their allowances",
            "Fixed: adding an employee without a birthday failed with a generic 'Failed to save employee' error \u2014 birthday is optional on the form but the database still required it; the birthday field is now optional and saves correctly when left blank",
            "Improved diagnostics \u2014 failed database operations now record the exact database error (code and message) to the server log even when the failure is handled gracefully, so issues are far faster to pinpoint; bound values are never logged, so passwords and personal data stay out of the logs",
            "Bi-monthly pay schedule now supports cross-month cut-offs \u2014 cut-off days (e.g. 5 & 20 or 15 & 30/31) are read as counting-end days, and the period before the earlier cut-off correctly wraps into the previous month (handles month-end and year-end boundaries)",
            "Timekeeping now works with bi-monthly and monthly pay periods \u2014 the Daily Time Record, Shift & Schedule, and Biometric Logs screens previously assumed a 7-day week and now adapt to the full length of the selected cut-off",
            "Fixed: Daily Time Record showed 'No attendance records' for bi-monthly and monthly periods \u2014 attendance rows were tagged to the wrong period; they now appear under the selected cut-off, and existing rows are corrected automatically when the DTR is opened",
            "Fixed: saving the Daily Time Record on a period longer than one week silently dropped the days past the first week \u2014 all days in the cut-off are now saved",
            "Late/undertime grace is now applied per week within a cut-off \u2014 bi-monthly and monthly periods grant the grace allowance for each week instead of once for the whole period, applied consistently in both the DTR summary and the payroll deduction",
            "Shift & Schedule header now labels each week ('Week N') across multi-week pay periods, with the day columns grouped under their week",
            "Topbar 'Using Pay Period' quick selector now auto-calculates the end date for bi-monthly and monthly schedules (previously only weekly) and snaps the start to a valid cut-off boundary, so a quick period change always saves correctly",
            "Saving a pay period now rejects an invalid start date \u2014 bi-monthly and monthly periods must begin on a real cut-off boundary (monthly on the 1st of the month); this prevents saving a period that the Daily Time Record and Shift & Schedule screens cannot display",
            "Fixed: two users opening the same employee's Daily Time Record or Biometric Logs at the same moment could hit a server error while the attendance rows were being created for the first time \u2014 concurrent access is now handled safely",
            "Dashboard now shows attendance charts for Timekeeper, Payroll Officer, and Admin \u2014 monthly line charts of how many employees were absent and how many were late/undertime (last 12 months), plus Top 5 Absentees and Top 5 Late/Undertime (all-time)",
            "Colour swatches are now consistent across Timekeeping \u2014 the Timesheet Manager colour column and the Shift & Schedule legend match the colour style used in System Config \u203a Roles",
            "Fixed: switching the active pay period from the topbar could leave a stale posted/locked state on Daily Time Record, Overtime, Leave, and Loan/CA \u2014 the posted banner (and DTR's Save/Recalc lock) now refresh immediately to match the newly selected period instead of showing whatever was true on the last full page load"
        ]
    },
    {
        "version": "prl.0.1.3",
        "date": "2026-07-05",
        "notes": [
            "Who's-online presence added \u2014 a small stack of user avatars now appears at the bottom-right showing everyone currently signed in, updating automatically every 30 seconds; each avatar shows the employee's photo (or a role-coloured initials badge) with their name and role on hover, and your own account is highlighted",
            "Maintenance: standardized all informational tooltips to a single Bootstrap markup (aria-label + data-bs-original-title) across Payroll Rules, Employee 201 File, Contributions, Pending OT, Reports, Roles, and User Access \u2014 consistent behaviour, no visible change",
            "Fixed: adding a user in System Config \u203a User Management reported success but was silently discarded \u2014 any user assigned a custom role (e.g. Human Resources) was dropped because the save only accepted the built-in roles, and the entered name was ignored; new users now save correctly with any active role, the Name field is now editable, and the Username is fixed once the account is created"
        ]
    },
    {
        "version": "prl.0.1.4",
        "date": "2026-07-18",
        "notes": [
            "System Config \u203a Print/Export Settings added (Admin only) \u2014 a new tab to set the default paper size (Letter, Legal, Folio, or A4) and page orientation (Portrait / Landscape) used for all PDF exports; the system now defaults to Folio, Landscape",
            "All PDF exports (Payroll Summary HR / PO sheets and Payslips) now follow the paper size and orientation configured in System Config \u203a Print/Export Settings",
            "Reports \u203a Payroll Summary: the search box is replaced with a pay-period dropdown \u2014 pick a posted period to filter the list to that period, or choose All Periods to see them all",
            "Reports \u203a Loan Ledger: a pay-period filter was added alongside the existing Type, Status, and Search controls \u2014 selecting a period lists only the loans and cash advances that had a deduction in that period and shows the amount deducted for that period (the column header changes to 'Period Deducted'); All Periods keeps the all-time totals",
            "Attendance Correction module is now live (Employee Applications \u203a Attendance Correction) \u2014 file a correction for a specific date by entering the Work Hours to credit plus a reason, and route it for approval, mirroring the OT / Leave / Loan-CA workflow",
            "Attendance Correction approvals: a pending list with a per-row REM flag lets approvers approve or reject in bulk, with a topbar Pending count; corrections shorter than a full shift can only be rejected, not approved",
            "Approved Attendance Corrections are paid as a Salary Adjustment (Work Hours \u00d7 hourly rate) in the pay period the correction is approved \u2014 the DTR itself is not modified, so a correction is never lost to a DTR recalculation",
            "Fixed: an Attendance Correction approved AFTER payroll had already been processed for that period is now picked up by Process Payroll \u2014 the Salary Adjustment is added to the existing payslip. Previously it only appeared after opening Payroll Summary and clicking Recalculate",
            "Employee Applications \u203a Attendance Correction: the 'Date Applied' column is now labelled 'Applied', matching the other Employee Applications tables",
            "Dashboard: pending Attendance Corrections now appear in the 'Needs Your Attention' list; the duplicate pending KPI tiles (OT / WDO, Leave, Loans / CA) were removed so the attention list is the single source, keeping the Active Employees tile",
            "Payroll Summary \u203a Recalculate now re-processes only the employee you are viewing, and reverts only that employee's overrides \u2014 previously it re-processed the entire pay period and reverted every employee's overrides for that cutoff",
            "Fixed: Withholding Tax was overstated for all employees. It is now computed on taxable compensation (basic pay less SSS, PhilHealth, and Pag-IBIG) instead of on gross pay, and the stored W/Tax table has been corrected to the current BIR rates effective 1 January 2023 \u2014 the table previously held the older, higher 2018-2022 rates. Re-run Process Payroll for any affected period to refresh the amounts",
            "Organization Set-up \u203a Resignation is now live \u2014 a guided per-employee offboarding tracker: HR-acknowledged resignation letter (with last day of duty), clearance, management approval, employee signing (Final Pay Acknowledgment, Quitclaim & Release, COE/2316 release log), final pay release, and automatic change of the employee's status to Resigned",
            "Resignation steps are strictly sequential \u2014 a step cannot be completed, and final pay cannot be released, until the preceding steps are done; buttons for steps that aren't reachable yet are hidden",
            "Final Pay has a Compute button that auto-calculates a breakdown (pro-rated basic + pro-rated 13th month + SIL/VL leave conversion, less outstanding loans/CA and accountabilities); the amounts remain editable before saving",
            "Resignation documents: HR uploads the acknowledged letter, an optional signed clearance form, and the signed Quitclaim; administrators upload one reusable Quitclaim template that HR downloads per employee",
            "Completing a resignation marks the employee as Resigned and deactivates the record; an in-process resignation can be cancelled, and a new one can be filed for that employee afterwards",
            "Employee 201 File \u203a Payroll & HR: added a 'Salary Base' setting (Daily or Monthly) that determines how an employee's Salary Rate is interpreted during payroll",
            "Employee 201 File \u203a Payroll & HR: removed the per-employee pay-frequency selector \u2014 pay frequency is now set once for the whole company in System Config \u203a Payroll Schedule, and the Employee Masterlist reflects that company-wide setting",
            "Payroll: for employees on a Monthly salary base, the daily rate is now computed dynamically per month \u2014 Monthly Salary \u00f7 the employee's scheduled working days in that month (rest days excluded; holidays that fall on a workday are included) \u2014 so a fully-worked month always pays exactly the monthly salary regardless of whether the month has 28, 30, or 31 days",
            "System Config \u203a Rules is now named 'Attendance Rules & Holidays'",
            "System Config \u203a Contributions: new 'Allowances & De Minimis' tab (after W/Tax). De Minimis Types moved here from Payroll Schedule, and a new company-defined Allowance Types list was added \u2014 so each company can name its own allowances (e.g. Rice Allowance, Meal Allowance) instead of using a fixed list",
            "System Config \u203a Contributions \u203a Allowances & De Minimis: the 10-item limit on both Allowance Types and De Minimis Types has been removed \u2014 you can now add as many as you need",
            "Employee 201 File \u203a Payroll & HR: the Allowances table is now driven by the Allowance Types you define in System Config \u2014 this replaces the previous fixed list (Representation, Transportation, COLA, Fixed Housing) and the 'Add Other' button. If no types are configured yet, a link takes you straight to the setup tab",
            "Please note: allowances captured under the previous fixed list are not carried over to the new configurable Allowance Types \u2014 after defining your Allowance Types, re-enter each employee's allowance amounts in the Employee 201 File",
            "Employee 201 File \u203a Payroll & HR: added a De Minimis section (in the same card as Allowances) where you enter each employee's monthly amount per configured type",
            "Employee 201 File \u203a Allowances & De Minimis: amounts are entered as monthly totals with a frequency \u2014 'Per Pay Period' spreads the amount across the company's pay periods (Weekly = \u00f74, Bi-Monthly = \u00f72, Monthly = full), while 'Monthly' pays the full amount once in the LAST pay period of the month",
            "Payroll: De Minimis is now paid to employees each cutoff. The amount up to each type's monthly threshold is non-taxable; any excess over the threshold is treated as taxable. Withholding tax per cutoff is unchanged \u2014 the taxable excess is reflected on the annual BIR 2316",
            "BIR 2316: non-taxable De Minimis is included under non-taxable benefits, and any excess over the threshold is included in taxable other income",
            "Approval audit trail added to Employee Applications \u2014 Overtime, Leave, Loan/CA and Attendance Correction now record WHO approved (or rejected) the application and WHEN. Hover the Status badge on any application to see it. Previously only a status flag was kept, so 'who approved this, and when?' could not be answered",
            "Rejections are now recorded too, not just approvals \u2014 an Attendance Correction rejection previously cleared its approval timestamp entirely, leaving no trace of the decision",
            "When a DTR recalculation revokes an Overtime or Leave approval (because the recomputed hours are no longer eligible), the approval stamp is cleared with it \u2014 a pending application can no longer still read as 'approved by' someone",
            "Fixed: rejecting an Attendance Correction failed with a database error and the rejection was not saved \u2014 the reject step still referenced an amount column that was removed when Attendance Correction moved to the Work Hours / Salary Adjustment model",
            "Employee 201 File \u203a Payroll & HR \u203a Payroll Details: the 'Attendance Issues' tile is now live \u2014 it opens a read-only list of all Attendance Corrections filed by that employee (applied date, date of error, work hours, reason, the pay period an approved correction is paid in, and status), matching the existing Salary History and Leave Records views",
            "System Config \u203a Contributions \u203a Allowances & De Minimis: saving Allowance Types or De Minimis Types now updates the table in place instead of reloading the whole page",
            "Fixed: an allowance or De Minimis whose type had been deactivated in System Config was still being paid on payroll \u2014 a deactivated type is now excluded from payroll processing (and remains hidden from the Employee 201 File editor as before). Re-run Process Payroll for any affected period to refresh the amounts",
            "Payslip: the 'Overtime / Holiday' column is now titled 'Premium Pay', and the Allowances and De Minimis rows under Other Earnings are grouped together without a dividing line",
            "Payslip: the header is now a letterhead \u2014 the company logo from Org Set-up sits to the left of the payroll period and employee details, matching the Payroll Summary export",
            "Reports \u203a Payroll Summary: the 'Back to periods' toolbar is now aligned with the card's spacing, and the Export HR / PO PDF button returns to its normal appearance after a download instead of changing style",
            "Payroll Processing can now email payslips to employees \u2014 an Email Payslips button sends the whole pay period in one go, and each row has its own envelope button to send (or resend) a single employee. Both appear only once the pay period is POSTED, since an emailed payslip cannot be recalled",
            "Emailed payslips are password-protected: the password is the first letter of the employee's first name (capitalised) followed by their birthday in MMDDYYYY format \u2014 for example, Jake born 18 June 1991 opens his payslip with J06181991. The email explains the rule without printing the password itself. Payslips downloaded from the system are not password-protected",
            "Employees with no email address on file (or no birthday, which the password is derived from) are skipped rather than sent an unprotected payslip \u2014 after each batch the skipped employees are listed by name so their Employee 201 File can be completed",
            "The envelope button on each row shows whether that employee has already been sent their payslip, and hovering it shows the address it went to and when. Every send is recorded, so it can be confirmed later whether a payslip actually went out",
            "System Config \u203a Email added (Admin only) \u2014 a new tab for the outgoing mail (SMTP) server used to send payslips: host, port, encryption, username, password, and the sender name/address, plus a Send Test Email button to confirm the settings work before any payslip goes out. For Gmail, use smtp.gmail.com on port 587 and generate a 16-character App Password (Google Account \u203a Security \u203a 2-Step Verification \u203a App passwords) \u2014 your normal Google password will be rejected. The saved password is never displayed back on the page",
            "User Access Control: a new 'Email Payslips to Employees' permission under Payroll controls who may email payslips \u2014 it is separate from 'Generate Payslips', so a role can be allowed to download payslips without being able to send them out",
            "Fixed: the two Attendance Correction permissions under User Access Control \u203a Employee Applications ('File Attendance Correction' and 'Approve / Reject Attendance Correction') could not be changed \u2014 the matrix showed both rows and saving reported success, but the changes were silently discarded and the two permissions stayed locked on their built-in defaults. They now save correctly, and the permissions the page displays and the permissions the save accepts are generated from a single definition, so a newly added permission can no longer appear in the matrix without being saveable",
            "Fixed: the OT hours shown on a payslip are now calculated using the configured OT multiplier (System Config \u203a Attendance Rules & Holidays) instead of a fixed 1.25, so they stay correct when a company sets a different OT rate",
            "Fixed: an administrator can no longer accidentally remove their own access when editing the User Access Control matrix \u2014 administrators always retain full access"
        ]
    },
    {
        "version": "prl.0.1.5",
        "date": "2026-07-29",
        "notes": [
            "Form validation is clearer across every screen and dialog \u2014 when a required field is missed, a message now appears directly beneath that field (for example 'Designation is required.') instead of only outlining the field in red; a duplicate error icon that used to appear on the Save / Confirm button has also been removed",
            "System Config \u203a Email and the Google Gemini API Key (System Config \u203a Contributions): the 'Configured' status now updates the moment you Save \u2014 no page refresh needed \u2014 and the Email page's 'a password is saved' hint refreshes in place after saving",
            "System Config \u203a Attendance Rules & Holidays: adding a holiday now opens a dedicated dialog (Date, Description, Holiday Type) with Confirm / Close buttons, matching the app's other add dialogs, instead of adding an editable row inline",
            "Daily Time Record: the 'Last Refreshed \u00b7 by \u2026' label now updates whenever a Timecard is recalculated \u2014 including recalculations that only affect non-working days (leave or day-off) \u2014 so it always reflects the most recent recompute",
            "Fixed: recalculating a Timecard now resets every approved Overtime and Leave in that pay period back to pending, so they are re-approved against the freshly recomputed attendance. Previously this was inconsistent \u2014 a leave was only reset when the employee happened to have a biometric punch on the leave day, so some approved leaves were left untouched while others were reverted. Leave balances are restored when an approval is reset, and the affected DTR days are rebuilt to match. Loan / CA applications are not affected by a Timecard recalculation",
            "Dashboard: the Pending OT / WDO, Pending Leave, and Pending Loans / CA summary tiles are back alongside Active Employees, giving an at-a-glance count of what's awaiting approval; the 'Needs Your Attention' list remains for the actionable detail"
        ]
    },
    {
        "version": "prl.0.1.6",
        "date": "2026-07-29",
        "notes": [
            "Fixed: Withholding tax (W/Tax) now uses the current BIR withholding tax table (effective January 2023 onwards). Previously it applied the older 2018\u20132022 rates and over-deducted tax from affected employees \u2014 withholding now matches the official BIR monthly table",
            "Fixed: Weekly pay frequency was over-deducting statutory items. Contributions (SSS, PhilHealth, Pag-IBIG) and W/Tax \u2014 along with monthly allowances and de minimis \u2014 are now spread across the actual number of weekly pay periods in a year, so a full year of weekly pays no longer totals more than the intended monthly amount. Monthly and semi-monthly pay frequencies were unaffected"
        ]
    },
    {
        "version": "prl.0.1.7",
        "date": "2026-07-31",
        "notes": [
            "New: System Config now has a Payroll Item Master. It is a central reference that shows how every earning and deduction is classified for reporting, including its tax treatment and where it appears on the payslip and the BIR 2316. This is a classification/reporting tool only and does not change how payroll is computed. Statutory items (basic pay, contributions, tax) are locked, while Allowances, De Minimis and Leave types are read from their existing System Config screens (blank until they are defined there).",
            "BIR 2316: allowances are now itemized on their correct lines instead of being combined into a single Others amount. Representation, Transportation, Cost of Living Allowance (COLA) and Fixed Housing appear on their dedicated lines (40 to 43), and any other allowance is listed by name under Others (line 44A / 44B). You choose which 2316 line each allowance maps to in System Config > Payroll Item Master. Basic Salary is also now classified correctly for both Minimum Wage Earners (non-taxable) and non-MWE employees (taxable).",
            "BIR 2316: corrected the on-form placement of several header fields so entries sit neatly inside their boxes: Employee Name, RDO Code, Registered Address, ZIP Code, Date of Birth and Contact Number.",
            "Employee Applications › Overtime/WDO: pending OT applications that cannot be approved (no payable TimeCard OT, or applied OT that exceeds the TimeCard) can now be rejected in bulk from the Pending OT approval list, so they can be cleared in one action instead of being deleted one at a time. Trying to approve a selection made up only of these rows now shows a clear message pointing to Reject Selected, instead of a misleading 'select at least one OT application' notice."
        ]
    },
    {
        "version": "prl.0.1.8",
        "date": "2026-08-06",
        "notes": [
            "Attendance Correction: you now enter the exact peso Amount to pay for a correction. On approval that amount is paid as-is as a Salary Adjustment (SAL ADJ) in the pay period it was approved in. Work Hours is now optional and for reference only — it no longer affects the amount paid, and the previous rule that a correction had to cover a full shift to be approved has been removed, so any amount can be approved. The Amount now appears alongside Work Hours across the correction list, the pending approval screen and the Employee 201 File history.",
            "System Config › Late Rules now has a “Deduct Late / Undertime” switch. When ON (the default), late and undertime are deducted from pay using the grace period as before. When OFF, employees are paid in full — late and undertime minutes still appear on the DTR for reference but are no longer deducted. The setting applies company-wide to payroll runs going forward."
        ]
    },
    {
        "version": "prl.0.1.9",
        "date": "2026-08-16",
        "notes": [
            "Fixed: In Payroll Processing, the Payroll Summary window now shows the exact figures that were actually paid for posted (locked) pay periods, so the Net Pay in the summary always matches the Net Pay in the payroll table. Previously the summary recalculated on the fly and could display a different Net Pay than the posted payslip for periods that were finalized before a pay-rule change (such as the weekly late-grace).",
            "Fixed: the System Config › Late Rules “Deduct Late / Undertime” switch now takes effect when turned OFF. Before, the setting could not be saved as off and always behaved as on, so late/undertime kept being deducted. Turning it off now pays employees in full on payroll runs going forward, with the minutes still shown for reference. Already-posted pay periods are not affected.",
            "The Payroll Summary preview no longer adds night-differential pay that the payroll calculation itself does not pay, so the preview and the generated payslip stay in agreement."
        ]
    }
]