kawayanmedia / government
Government domain data access layer for the HRIS payroll system
Requires
- php: ^8.3
- laravel/framework: ^11.0|^12.0|^13.0
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Data access layer for the Government domain of a Philippine HRIS/payroll system.
This package gives you Eloquent models and read/write services for:
- Salary grades and salary steps
- Plantilla items and plantilla assignments
- NOSA / NOSI step increments
- NOSA / NOSI PDF generation (optional HTTP routes)
- Service records
- Applicants and job vacancies
- Schedule adjustment requests
- Offices, employees, and users used by the domain
It intentionally contains no Filament resources, pages, widgets, or Livewire components. Your application keeps its own UI layer and calls these services for the data work. The only HTTP endpoints are the optional NOSA/NOSI PDF routes, which the service provider registers automatically.
Requirements
| Requirement | Version |
|---|---|
| PHP | 8.3+ |
| Laravel | 11, 12, or 13 (laravel/framework) |
| Database | Any Eloquent-supported database with the HRIS tables |
The package requires laravel/framework plus setasign/fpdi and setasign/fpdf
for PDF generation, so it works inside a full Laravel application and also in
plain PHP scripts that boot Eloquent through the framework's Capsule manager.
Installation
Laravel (from GitHub)
{
"repositories": [
{
"type": "vcs",
"url": "https://github.com/kawayanmedia/government.git"
}
],
"require": {
"kawayanmedia/government": "^1.0"
}
}
composer update kawayanmedia/government
The package is auto-discovered. If your application has
"laravel": { "dont-discover": [] }, no extra provider registration is needed.
Laravel (local path during development)
{
"repositories": [
{
"type": "path",
"url": "./kawayanmedia/government"
}
],
"require": {
"kawayanmedia/government": "@dev"
}
}
composer update kawayanmedia/government
Plain PHP
composer require kawayanmedia/government
Plain PHP needs request and config bound in the container because the
tenancy scopes use them. docs/php.md contains a complete
bootstrap script.
Quick start (Laravel)
use KawayanMedia\Government\Services\ApplicantService; class ApplicantController extends Controller { public function index(ApplicantService $applicants) { return view('applicants.index', [ 'applicants' => $applicants->paginate( filters: ['search' => request('search')], perPage: 25, ), ]); } }
use KawayanMedia\Government\Services\NosaService; public function promote(Employee $employee, NosaService $nosa) { $record = $nosa->recordStepIncrement($employee, [ 'from_salary_grade' => 11, 'from_step' => 1, 'from_salary_grade_year' => 2024, 'to_salary_grade' => 11, 'to_step' => 2, 'to_salary_grade_year' => 2024, 'effective_date' => '2026-01-05', ]); return response()->json($record); }
NOSA / NOSI PDFs
The service provider registers two routes automatically:
| Method | URI | Route name |
|---|---|---|
GET |
nosa/{id} |
government.nosa.show |
GET |
nosi/{id} |
government.nosi.show |
Both render the form for the given nosas record and return it inline as
application/pdf. Configure the prefix, middleware, route names, and template
paths in config/government.php under pdf:
'pdf' => [ 'route_prefix' => '', 'middleware' => ['web'], 'route_names' => [ 'nosa' => 'government.nosa.show', 'nosi' => 'government.nosi.show', ], 'templates' => [ 'nosa' => null, // null = package resources/pdf/nosa.pdf 'nosi' => null, ], ],
Publish the templates when you want to customise them:
php artisan vendor:publish --tag=government-pdf-templates
Then point the config at the published copies, for example
'nosa' => public_path('vendor/government/pdf/nosa.pdf').
Quick start (plain PHP)
require __DIR__ . '/vendor/autoload.php'; require __DIR__ . '/bootstrap.php'; // see docs/php.md $applicants = $services->get(\KawayanMedia\Government\Services\ApplicantService::class); $page = $applicants->paginate(['search' => 'Maria'], 10); foreach ($page as $applicant) { echo $applicant->name . PHP_EOL; }
Domains and models
| Domain | Models | Table(s) |
|---|---|---|
| Recruitment | Applicant, JobVacancy |
applicants, job_vacancies |
| Plantilla | PlantillaItem, EmployeePlantilla |
plantilla_items, employees_plantilla |
| Compensation | SalaryGrade |
salary_grades |
| NOSA / NOSI | Nosa, ServiceRecord |
nosas, service_records |
| Requests | ScheduleAdjustmentRequest |
schedule_adjustment_requests |
| Shared | Employee, Office, User |
employees, offices, users |
Full column, relation, accessor, and hook reference: docs/models.md.
Services
| Service | Read | Write | Domain operations |
|---|---|---|---|
ApplicantService |
paginate, find, query |
create, update, delete |
search across name, email, position, telephone |
EmployeePlantillaService |
paginate, find, query |
create, update, delete |
filter by office, employee, year, active |
NosaService |
paginate, find, query |
create, update, delete |
recordStepIncrement() |
PlantillaItemService |
paginate, find, query |
create, update, delete |
assignEmployee() |
SalaryGradeService |
paginate, find, query |
updateSteps() |
filter by year and salary grade type |
ScheduleAdjustmentRequestService |
paginate, find, query |
create, update, delete |
forEmployee() |
Full signatures, parameter tables, return values, and examples: docs/services.md.
Example data
The docs use one consistent sample dataset (three offices, four employees, six plantilla items, 2024 salary grades, applicants, NOSA records, service records, and schedule requests) so every example can be traced end to end:
- docs/example-data.md — all tables and expected results.
Configuration
Publish the config file:
php artisan vendor:publish --tag=government-config
// config/government.php return [ 'models' => [ 'applicant' => \KawayanMedia\Government\Models\Applicant::class, 'employee' => \KawayanMedia\Government\Models\Employee::class, // … 'company' => \App\Models\Company::class, 'department' => \App\Models\Department::class, 'employment_type' => \App\Models\EmploymentType::class, 'position' => \App\Models\Position::class, 'payroll_group' => \App\Models\PayrollGroup::class, ], ];
Package models are used by default. Entities outside the Government domain are resolved lazily from this map, so an application can swap in its own classes without touching the package.
Documentation
| Document | Contents |
|---|---|
| docs/installation.md | Laravel, path-repository, plain PHP, Octane, verification |
| docs/models.md | Every model: table, columns, casts, relations, accessors, scopes, hooks |
| docs/services.md | Every service method with parameters and examples |
| docs/laravel.md | Controllers, form requests, API resources, Filament integration, transactions, testing |
| docs/php.md | Standalone Eloquent bootstrap and runnable examples |
| docs/example-data.md | The full sample dataset and operation results |
| docs/testing.md | Feature tests, factories, fakes, database isolation |
Runnable scripts live in examples/.
Behaviour notes
- Company scoping.
Office,Employee,JobVacancy, andScheduleAdjustmentRequesthave a global scope that filters on the authenticated user'scompany_id, falling back to1. In console or plain PHP contexts where no user is resolved, records from company1are returned. - Timestamps. Records created through the package take their timestamps
from the application clock (
now()), matching the original domain code. - Money columns.
Employeesalary fields andPlantillaItemannual salary fields are stored in centavos and exposed divided by 100. - Plantilla updates. Saving a
PlantillaItemwith anemployee_idcreates the matchingEmployeePlantillarow. - NOSA increments.
recordStepIncrement()closes the latest service record and opens a new one exactly as the original UI action did. - Employee model. The packaged
Employeeis a Government-domain slice of the application model. Relations used only by payroll/PDS keep resolving through the config map; media-library integration is not included.
License
MIT. See LICENSE.