πŸ“‹ Documentation β€” v1.0

Folio Office Management

Complete reference for installing, configuring and running Folio β€” the self-hosted HR, payroll and office management system built for multi-company organisations.

πŸ“¦ v1.0.0 🐘 PHP 7.4+ πŸ—„ SQLite 🏒 Multi-company
Get Folio β€” $149.00 β†’ ⬇ PDF User Guide ← Product Page

Live Demo

Try Folio before you buy at folio.cwfms.com. The demo resets automatically β€” feel free to explore.

RoleUsernamePasswordAccess
πŸ‘‘ Adminadminpassword123Full system
πŸ“Š Accountantmarcus.levyaccountant123Finance & reports
πŸ‘₯ HR Officederek.washingtonhroffice123Payroll & employees
πŸ§‘β€πŸ’Ό Employeekezia.campbellemployee123Personal finance
β†’ Open Live Demo

Requirements

ComponentRequirement
PHP7.4 or higher (8.x recommended)
Extensionspdo_sqlite, json, zip, mbstring
DatabaseSQLite via PDO β€” no MySQL or PostgreSQL required
Web ServerApache / LiteSpeed / Nginx with PHP. Standard shared hosting supported.
Install PathMust install at the domain root (e.g. office.yourdomain.com/). Subdirectory installs not supported.
Writable dirsdata/, uploads/, backups/, logs/ β€” set to 775

Installation

  1. Purchase and download folio-system.zip from your customer account.
  2. Upload and extract to the root of your domain β€” all files at public_html/ or equivalent, not in a subdirectory.
  3. Set directory permissions:
    chmod 775 data/
    chmod 775 uploads/
    chmod 775 backups/
    chmod 775 logs/
  4. Visit yourdomain.com/setup/install.php β€” the First-Run Setup wizard will appear.
  5. Complete setup, then activate your license. See sections below.

Database initialisation error? Delete the entire data/ folder and try again. A partially-created database from a previous failed run will repeat the error on every visit.

cPanel: Use File Manager β†’ right-click data/ β†’ Change Permissions β†’ set to 775.

First-Run Setup

On the first visit, Folio redirects to /setup/install.php. This screen appears once only.

  1. Organisation Name β€” appears in the header, reports, and exported documents.
  2. Default Theme β€” Dark or Light. Users can switch individually.
  3. Administrator Account β€” full name, email and password (min. 8 characters). Store securely.
  4. First Company β€” at least one required. More can be added after login.
  5. Click Complete Setup β€” schema migrations run and you are redirected to login.

The setup wizard permanently locks once an admin exists. To reset: delete data/app.db β€” this erases all data.

After setup, go to Admin β†’ Settings β†’ License to activate your license key.

Roles & Access Control

Folio has four fixed roles. Each user holds exactly one role assigned by the Administrator.

RoleAccessKey Capabilities
AdministratorFullAll modules, user management, settings, backups, migrations
AccountantFinancialTransactions, payroll, reports β€” scoped to assigned companies
HRPeople opsEmployees, leave management, letters, payroll view β€” no financial access
GuestView onlyRead-only dashboard and transaction list

Accountants are assigned to specific companies via Admin β†’ Users β†’ Assign Companies. They only see data for their assigned companies.

Dashboard

Each role lands on its default dashboard after login. The currency toggle in the header converts all amounts on the fly.

DashboardPathDefault for
Main/dashboard.phpAdministrator
Accountant/dashboards/accountant_dashboard.phpAccountant
Guest/dashboards/guest_dashboard.phpGuest
HR/hr/hr_main.phpHR

Transactions

The core financial ledger at /transactions.php. Every income or expense movement is recorded here with a full audit trail.

FieldDescription
DateWhen the transaction occurred
CompanyWhich entity this belongs to
AmountPositive = income, negative = expense
DescriptionFree-text summary
CategoryRevenue, OPEX, COGS, etc. with sub-category
Audit TrailEvery change logged with user ID, IP, timestamp

The transaction list supports filtering by company, date range, amount, category and payment method. A running total displays in the selected currency at the bottom.

Companies

Manage legal entities at /admin/companies.php. Supports parent–child structures (holding company β†’ subsidiaries). Inactive companies preserve all data but are hidden from dropdowns and reports.

FieldDescription
NameFull legal name of the entity
CodeShort identifier (e.g. ACME). Appears in exports and reports.
Short CodeOptional abbreviated code for tight layouts
ParentSet for subsidiary relationships. Leave blank for top-level entities.
ActiveToggle visibility β€” inactive companies preserve all data

Employees & HR

Employee Profiles

Full records at /admin/employees.php β€” name, position, department, salary, hire date, tax ID, and document uploads (IDs, contracts, certificates with category tags and expiry reminders).

Leave Management

  • Leave Types β€” Configurable categories with default allocation days at /hr/leave_types.php
  • Leave Requests β€” Submit and approve at /hr/leave_requests.php. Approval auto-decrements balance.
  • Leave Balances β€” Per-employee, per-type, per-year with carry-over at /hr/leave_balances.php
  • Leave Calendar β€” Visual calendar of all approved leave at /hr/leave_calendar.php

HR Policies

Internal policy documents at /hr/policies.php. Default policies (Code of Conduct, Leave Policy, Remote Work) seeded at install time. Administrators and HR managers can add, edit, or delete policies.

Payroll

Process payroll at /payroll/payroll.php. Each entry covers one employee for one pay period.

FieldDescription
Gross PayTotal before deductions
DeductionsTax, NIS, pension β€” with optional line-item breakdown
Net PayCalculated automatically (gross βˆ’ deductions)
StatusUnpaid / Paid β€” marking Paid creates an expense transaction automatically

Exports

  • PDF payslips at /payroll/payslip_pdf.php?id=N
  • Payroll Report by company/year β€” /payroll/payroll_report.php
  • Monthly summary and top earners β€” /payroll/summary.php
  • Overview by pay period β€” /payroll/overview.php

If you also use CWFMS, marking a payroll run as Paid can automatically post the expense there β€” no double entry. See CWFMS Integration.

Reports

The Reports Hub at /reports/hub.php consolidates all exports: payroll reports, employee lists (CSV + PDF), and financial summaries β€” all filterable by company.

Guest Export: Enable in Admin β†’ Settings β†’ Allow Guest Export to permit guest-role users to download CSV exports. Disabled by default.

Admin Panel

Accessible only to Administrators at /admin/settings.php.

SettingDescription
Organisation NameAppears in header, all reports, exports and letters
LogosLight/dark, desktop/mobile variants (PNG, JPG, SVG)
Base CurrencyStorage currency β€” change with care, existing values are not converted
Exchange RatesManual or auto-refreshed from exchangerate.host
Letter FooterDefault footer for generated letters β€” supports {COMPANY}, {DATE}, {USER}
BackupsRolling backups at /admin/backup_logs.php with SHA-256 integrity checks
User ManagementCreate, edit, deactivate, assign companies β€” at /admin/users.php

License Activation

Folio requires a license key purchased from cwfms.com. The key is validated against the license API and the result cached locally for 48 hours β€” no call is made on every page load.

First-Time Activation

  1. After setup, navigate to any page β€” the License Required screen appears if no key is cached.
  2. Enter your key in format CWFMS-XXXX-XXXX-XXXX-XXXX from your purchase email or customer account.
  3. Click Activate License. Folio contacts the license server and caches the result for 48 hours.

Managing via Admin

Go to Admin β†’ Settings β†’ License to view status, force re-validation, or clear the cache.

Firewall note: Folio must reach cwfms.com over HTTPS (port 443) for validation. The 48-hour cache means only one outbound request every two days.

CWFMS Integration

Folio can optionally push payroll expenses to CWFMS automatically when a payroll run is marked as paid β€” eliminating double entry between the two systems.

Completely optional. Both systems work independently. Nothing is sent unless explicitly configured. If CWFMS is unreachable, payroll mark-paid completes normally.

Setup

  1. In CWFMS: Settings β†’ Integrations β†’ enable API and copy the API key.
  2. In Folio: Admin β†’ Settings β†’ CWFMS Integration β†’ enter the CWFMS base URL and API key.
  3. Click Test Connection to confirm.
  4. In the Company Mapping table, set the CWFMS Company ID for each Folio company (visible in the CWFMS URL when viewing a company).

The push log (last 10 attempts) is visible in Admin β†’ Settings β†’ CWFMS Integration so you can confirm pushes are landing correctly.

For CWFMS documentation see the CWFMS Docs β†’

Currency Conversion

All amounts are stored in their original currency. The header toggle cycles through USD β†’ JMD β†’ KYD β†’ CAD β†’ EUR β†’ GBP and converts all displayed values on the fly β€” stored values are never modified.

Add currencies via Admin β†’ Settings β†’ Exchange Rates. To add a currency to the toggle cycle, edit the currencies array in includes/header.php.

Changing the base currency after data has been entered does not retroactively convert stored amounts β€” it only affects new entries.

Security & Best Practices

  • Passwords hashed with password_hash() / bcrypt β€” never stored in plaintext
  • Sessions regenerate on login β€” prevents session fixation attacks
  • CSRF tokens validated on every POST request
  • .htaccess blocks data/, migrations/, logs/, backups/, setup/ from web access
  • uploads/ blocks PHP execution β€” uploaded files cannot run as scripts
  • All SQL via prepared statements β€” no string interpolation
  • File uploads enforce an extension whitelist (PDF, DOC, XLS, JPG, PNG, CSV, ZIP)

Recommended Hardening

  • Enable HTTPS β€” uncomment the redirect rule in .htaccess
  • Restrict /admin by IP on public servers
  • Use a strong admin password β€” 16+ characters, mixed case and symbols
  • Run daily backups and store a copy off-server

Troubleshooting

IssueResolution
Database initialisation errorDelete entire data/ folder, re-upload fresh. Set chmod 775 data/. Stale DB from a previous failed run is the most common cause.
Blank page after loginCheck data/ is writable. Set APP_ENV=development temporarily to see PHP errors on screen.
License Required screen keeps appearingEnsure server can reach cwfms.com on port 443. Verify the key has no extra spaces. Regenerate from your customer account if needed.
CWFMS push not workingUse Test Connection in Admin β†’ CWFMS Integration. Check the push log for the error. Confirm CWFMS API is enabled in CWFMS Settings β†’ Integrations.
CWFMS company not receiving payrollSet the CWFMS Company ID in the Company Mapping table. The ID must match the folder name in the CWFMS URL.
Payroll auto-expense not createdTrigger trg_payroll_mark_paid is case-sensitive β€” value must be paid not Paid. Re-apply the master schema if the trigger is missing.
File uploads failingSet chmod 775 uploads/. Check upload_max_filesize and post_max_size in PHP INI.
DB connection failedpdo_sqlite extension not enabled. Check phpinfo() and enable in php.ini, then restart PHP-FPM.
Currency toggle does nothingCheck browser console (F12) for JS errors. Confirm exchange_rates in Admin β†’ Settings is valid JSON.
403 on /setup/install.phpConfirm .htaccess has the allow rule for install.php before the block rule for setup/.

Changelog

v1.0.0 β€” Initial Release

  • First standalone release β€” fully de-branded
  • Single consolidated schema (migrate_master_schema.php)
  • First-run setup wizard
  • License gate with 48-hour local cache β€” SQLite 3.x compatible
  • Optional CWFMS payroll push integration
  • Upload extension whitelist and PHP execution block in uploads/
  • Self-healing download fallback in CWShop