Commit fc229f20 authored by Mahmoud Aglan's avatar Mahmoud Aglan

feat(hr): implement إدارة→قسم→موظف two-level department hierarchy

Adds department_type column (idara/qism) to hr_departments. Idaras are
top-level administrations; aqsam (sections) belong to an idara via
parent_id. Employees are assigned to a qism.

Cascading changes across 14 files:
- Migration adds department_type with CHECK constraint
- Model: allIdaras(), allAqsam(), getAqsamByIdara() helpers
- Controller: type-aware CRUD, validation (qism requires parent)
- Views: cascading إدارة→قسم dropdowns in employee form, type badges
  in department list, grouped optgroups in employee filters
- Reports: headcount groups by idara
- Routes: new /hr/departments/{id}/aqsam-json endpoint
- Bootstrap: updated Arabic labels
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent 982aa243
...@@ -17,8 +17,10 @@ class DepartmentController extends Controller ...@@ -17,8 +17,10 @@ class DepartmentController extends Controller
public function index(Request $request): Response public function index(Request $request): Response
{ {
$filters = [ $filters = [
'q' => trim((string) $request->get('q', '')), 'q' => trim((string) $request->get('q', '')),
'branch_id' => trim((string) $request->get('branch_id', '')), 'branch_id' => trim((string) $request->get('branch_id', '')),
'department_type' => trim((string) $request->get('department_type', '')),
'parent_id' => trim((string) $request->get('parent_id', '')),
]; ];
$page = max(1, (int) $request->get('page', 1)); $page = max(1, (int) $request->get('page', 1));
...@@ -26,25 +28,27 @@ class DepartmentController extends Controller ...@@ -26,25 +28,27 @@ class DepartmentController extends Controller
$db = App::getInstance()->db(); $db = App::getInstance()->db();
$branches = $db->select("SELECT id, name_ar FROM branches WHERE is_active = 1 ORDER BY name_ar"); $branches = $db->select("SELECT id, name_ar FROM branches WHERE is_active = 1 ORDER BY name_ar");
$idaras = HrDepartment::allIdaras();
return $this->view('HR.Views.departments.index', [ return $this->view('HR.Views.departments.index', [
'departments' => $result['data'], 'departments' => $result['data'],
'pagination' => $result['pagination'], 'pagination' => $result['pagination'],
'filters' => $filters, 'filters' => $filters,
'branches' => $branches, 'branches' => $branches,
'idaras' => $idaras,
]); ]);
} }
public function create(Request $request): Response public function create(Request $request): Response
{ {
$db = App::getInstance()->db(); $db = App::getInstance()->db();
$departments = HrDepartment::allActive(); $idaras = HrDepartment::allIdaras();
$branches = $db->select("SELECT id, name_ar FROM branches WHERE is_active = 1 ORDER BY name_ar"); $branches = $db->select("SELECT id, name_ar FROM branches WHERE is_active = 1 ORDER BY name_ar");
$employees = HrEmployeeProfile::getActiveIds(); $employees = HrEmployeeProfile::getActiveIds();
return $this->view('HR.Views.departments.form', [ return $this->view('HR.Views.departments.form', [
'department' => null, 'department' => null,
'departments' => $departments, 'idaras' => $idaras,
'branches' => $branches, 'branches' => $branches,
'employees' => $employees, 'employees' => $employees,
]); ]);
...@@ -114,13 +118,13 @@ class DepartmentController extends Controller ...@@ -114,13 +118,13 @@ class DepartmentController extends Controller
} }
$db = App::getInstance()->db(); $db = App::getInstance()->db();
$departments = HrDepartment::allActive(); $idaras = HrDepartment::allIdaras();
$branches = $db->select("SELECT id, name_ar FROM branches WHERE is_active = 1 ORDER BY name_ar"); $branches = $db->select("SELECT id, name_ar FROM branches WHERE is_active = 1 ORDER BY name_ar");
$employees = HrEmployeeProfile::getActiveIds(); $employees = HrEmployeeProfile::getActiveIds();
return $this->view('HR.Views.departments.form', [ return $this->view('HR.Views.departments.form', [
'department' => $department, 'department' => $department,
'departments' => $departments, 'idaras' => $idaras,
'branches' => $branches, 'branches' => $branches,
'employees' => $employees, 'employees' => $employees,
]); ]);
...@@ -265,13 +269,25 @@ class DepartmentController extends Controller ...@@ -265,13 +269,25 @@ class DepartmentController extends Controller
return $this->redirect('/hr/departments/' . $id . '/positions')->withSuccess('تم حذف الوظيفة المعتمدة بنجاح'); return $this->redirect('/hr/departments/' . $id . '/positions')->withSuccess('تم حذف الوظيفة المعتمدة بنجاح');
} }
public function aqsamJson(Request $request, string $id): Response
{
$aqsam = HrDepartment::getAqsamByIdara((int) $id);
return $this->json(['results' => $aqsam]);
}
private function extractData(Request $request): array private function extractData(Request $request): array
{ {
$type = trim((string) $request->post('department_type', 'qism'));
if (!in_array($type, ['idara', 'qism'], true)) {
$type = 'qism';
}
return [ return [
'name_ar' => trim((string) $request->post('name_ar', '')), 'name_ar' => trim((string) $request->post('name_ar', '')),
'name_en' => trim((string) $request->post('name_en', '')) ?: null, 'name_en' => trim((string) $request->post('name_en', '')) ?: null,
'department_code' => strtoupper(trim((string) $request->post('department_code', ''))), 'department_code' => strtoupper(trim((string) $request->post('department_code', ''))),
'parent_id' => ((int) $request->post('parent_id', 0)) ?: null, 'department_type' => $type,
'parent_id' => $type === 'qism' ? (((int) $request->post('parent_id', 0)) ?: null) : null,
'manager_employee_id' => ((int) $request->post('manager_employee_id', 0)) ?: null, 'manager_employee_id' => ((int) $request->post('manager_employee_id', 0)) ?: null,
'branch_id' => ((int) $request->post('branch_id', 0)) ?: null, 'branch_id' => ((int) $request->post('branch_id', 0)) ?: null,
'staffing_capacity' => ((int) $request->post('staffing_capacity', 0)) ?: null, 'staffing_capacity' => ((int) $request->post('staffing_capacity', 0)) ?: null,
...@@ -282,11 +298,15 @@ class DepartmentController extends Controller ...@@ -282,11 +298,15 @@ class DepartmentController extends Controller
private function validateInput(array $data): array private function validateInput(array $data): array
{ {
$errors = []; $errors = [];
$typeLabel = $data['department_type'] === 'idara' ? 'الإدارة' : 'القسم';
if ($data['name_ar'] === '' || mb_strlen($data['name_ar']) < 2) { if ($data['name_ar'] === '' || mb_strlen($data['name_ar']) < 2) {
$errors[] = 'اسم القسم بالعربي مطلوب (حرفان على الأقل)'; $errors[] = "اسم {$typeLabel} بالعربي مطلوب (حرفان على الأقل)";
} }
if ($data['department_code'] === '') { if ($data['department_code'] === '') {
$errors[] = 'كود القسم مطلوب'; $errors[] = "كود {$typeLabel} مطلوب";
}
if ($data['department_type'] === 'qism' && empty($data['parent_id'])) {
$errors[] = 'يجب اختيار الإدارة التابع لها القسم';
} }
return $errors; return $errors;
} }
......
...@@ -60,6 +60,7 @@ class EmployeeProfileController extends Controller ...@@ -60,6 +60,7 @@ class EmployeeProfileController extends Controller
return $this->view('HR.Views.employees.form', [ return $this->view('HR.Views.employees.form', [
'profile' => null, 'profile' => null,
'unlinked' => $unlinked, 'unlinked' => $unlinked,
'idaras' => HrDepartment::allIdaras(),
'departments' => HrDepartment::allActive(), 'departments' => HrDepartment::allActive(),
'jobTitles' => HrJobTitle::allActive(), 'jobTitles' => HrJobTitle::allActive(),
'structures' => HrSalaryStructure::allActive(), 'structures' => HrSalaryStructure::allActive(),
...@@ -118,6 +119,10 @@ class EmployeeProfileController extends Controller ...@@ -118,6 +119,10 @@ class EmployeeProfileController extends Controller
? HrDepartment::find((int) $profile->department_id) ? HrDepartment::find((int) $profile->department_id)
: null; : null;
$idara = ($department && $department->parent_id)
? HrDepartment::find((int) $department->parent_id)
: null;
$jobTitle = $profile->job_title_id $jobTitle = $profile->job_title_id
? HrJobTitle::find((int) $profile->job_title_id) ? HrJobTitle::find((int) $profile->job_title_id)
: null; : null;
...@@ -154,6 +159,7 @@ class EmployeeProfileController extends Controller ...@@ -154,6 +159,7 @@ class EmployeeProfileController extends Controller
return $this->view('HR.Views.employees.show', [ return $this->view('HR.Views.employees.show', [
'profile' => $profile, 'profile' => $profile,
'department' => $department, 'department' => $department,
'idara' => $idara,
'jobTitle' => $jobTitle, 'jobTitle' => $jobTitle,
'structure' => $structure, 'structure' => $structure,
'activeContract' => $activeContract, 'activeContract' => $activeContract,
...@@ -182,6 +188,7 @@ class EmployeeProfileController extends Controller ...@@ -182,6 +188,7 @@ class EmployeeProfileController extends Controller
return $this->view('HR.Views.employees.form', [ return $this->view('HR.Views.employees.form', [
'profile' => $profile, 'profile' => $profile,
'unlinked' => [], 'unlinked' => [],
'idaras' => HrDepartment::allIdaras(),
'departments' => HrDepartment::allActive(), 'departments' => HrDepartment::allActive(),
'jobTitles' => HrJobTitle::allActive(), 'jobTitles' => HrJobTitle::allActive(),
'structures' => HrSalaryStructure::allActive(), 'structures' => HrSalaryStructure::allActive(),
......
...@@ -21,7 +21,7 @@ class HrReportController extends Controller ...@@ -21,7 +21,7 @@ class HrReportController extends Controller
$db = App::getInstance()->db(); $db = App::getInstance()->db();
$byDepartment = $db->select( $byDepartment = $db->select(
"SELECT d.name_ar as department_name, "SELECT d.name_ar as department_name, COALESCE(ida.name_ar, d.name_ar) as idara_name,
COUNT(hp.id) as total, COUNT(hp.id) as total,
SUM(CASE WHEN hp.gender = 'male' THEN 1 ELSE 0 END) as male_count, SUM(CASE WHEN hp.gender = 'male' THEN 1 ELSE 0 END) as male_count,
SUM(CASE WHEN hp.gender = 'female' THEN 1 ELSE 0 END) as female_count, SUM(CASE WHEN hp.gender = 'female' THEN 1 ELSE 0 END) as female_count,
...@@ -29,9 +29,10 @@ class HrReportController extends Controller ...@@ -29,9 +29,10 @@ class HrReportController extends Controller
SUM(CASE WHEN hp.employment_type = 'part_time' THEN 1 ELSE 0 END) as part_time SUM(CASE WHEN hp.employment_type = 'part_time' THEN 1 ELSE 0 END) as part_time
FROM hr_employee_profiles hp FROM hr_employee_profiles hp
LEFT JOIN hr_departments d ON d.id = hp.department_id LEFT JOIN hr_departments d ON d.id = hp.department_id
LEFT JOIN hr_departments ida ON ida.id = d.parent_id AND ida.department_type = 'idara'
WHERE hp.employment_status = 'active' AND hp.is_archived = 0 WHERE hp.employment_status = 'active' AND hp.is_archived = 0
GROUP BY hp.department_id, d.name_ar GROUP BY hp.department_id, d.name_ar, ida.name_ar
ORDER BY total DESC" ORDER BY idara_name ASC, total DESC"
); );
$totals = $db->selectOne( $totals = $db->selectOne(
......
...@@ -16,7 +16,7 @@ class HrDepartment extends Model ...@@ -16,7 +16,7 @@ class HrDepartment extends Model
protected static bool $autoTrackAuthor = true; protected static bool $autoTrackAuthor = true;
protected static array $fillable = [ protected static array $fillable = [
'department_code', 'name_ar', 'name_en', 'parent_id', 'manager_employee_id', 'department_code', 'department_type', 'name_ar', 'name_en', 'parent_id', 'manager_employee_id',
'branch_id', 'description_ar', 'is_active', 'sort_order', 'staffing_capacity', 'branch_id', 'description_ar', 'is_active', 'sort_order', 'staffing_capacity',
]; ];
...@@ -28,6 +28,34 @@ class HrDepartment extends Model ...@@ -28,6 +28,34 @@ class HrDepartment extends Model
->get(); ->get();
} }
public static function allIdaras(): array
{
return static::query()
->where('is_active', '=', 1)
->where('department_type', '=', 'idara')
->orderBy('name_ar', 'ASC')
->get();
}
public static function allAqsam(): array
{
return static::query()
->where('is_active', '=', 1)
->where('department_type', '=', 'qism')
->orderBy('name_ar', 'ASC')
->get();
}
public static function getAqsamByIdara(int $idaraId): array
{
return static::query()
->where('is_active', '=', 1)
->where('department_type', '=', 'qism')
->where('parent_id', '=', $idaraId)
->orderBy('name_ar', 'ASC')
->get();
}
public static function getTree(): array public static function getTree(): array
{ {
$all = static::allActive(); $all = static::allActive();
...@@ -65,6 +93,14 @@ class HrDepartment extends Model ...@@ -65,6 +93,14 @@ class HrDepartment extends Model
$where .= ' AND d.branch_id = ?'; $where .= ' AND d.branch_id = ?';
$params[] = (int) $filters['branch_id']; $params[] = (int) $filters['branch_id'];
} }
if (!empty($filters['department_type'])) {
$where .= ' AND d.department_type = ?';
$params[] = $filters['department_type'];
}
if (!empty($filters['parent_id'])) {
$where .= ' AND d.parent_id = ?';
$params[] = (int) $filters['parent_id'];
}
if (isset($filters['is_active']) && $filters['is_active'] !== '') { if (isset($filters['is_active']) && $filters['is_active'] !== '') {
$where .= ' AND d.is_active = ?'; $where .= ' AND d.is_active = ?';
$params[] = (int) $filters['is_active']; $params[] = (int) $filters['is_active'];
...@@ -80,7 +116,7 @@ class HrDepartment extends Model ...@@ -80,7 +116,7 @@ class HrDepartment extends Model
LEFT JOIN hr_departments p ON p.id = d.parent_id LEFT JOIN hr_departments p ON p.id = d.parent_id
LEFT JOIN branches b ON b.id = d.branch_id LEFT JOIN branches b ON b.id = d.branch_id
WHERE {$where} WHERE {$where}
ORDER BY d.name_ar ASC ORDER BY d.department_type ASC, d.name_ar ASC
LIMIT {$perPage} OFFSET {$offset}", LIMIT {$perPage} OFFSET {$offset}",
$params $params
); );
......
...@@ -163,9 +163,10 @@ class HrEmployeeProfile extends Model ...@@ -163,9 +163,10 @@ class HrEmployeeProfile extends Model
$offset = ($page - 1) * $perPage; $offset = ($page - 1) * $perPage;
$rows = $db->select( $rows = $db->select(
"SELECT p.*, d.name_ar as department_name, j.name_ar as job_title_name "SELECT p.*, d.name_ar as department_name, d.department_type, ida.name_ar as idara_name, j.name_ar as job_title_name
FROM hr_employee_profiles p FROM hr_employee_profiles p
LEFT JOIN hr_departments d ON d.id = p.department_id LEFT JOIN hr_departments d ON d.id = p.department_id
LEFT JOIN hr_departments ida ON ida.id = d.parent_id AND ida.department_type = 'idara'
LEFT JOIN hr_job_titles j ON j.id = p.job_title_id LEFT JOIN hr_job_titles j ON j.id = p.job_title_id
WHERE {$where} WHERE {$where}
ORDER BY p.first_name_ar ASC ORDER BY p.first_name_ar ASC
......
...@@ -14,6 +14,8 @@ return [ ...@@ -14,6 +14,8 @@ return [
['POST', '/hr/departments/{id:\d+}/positions', 'HR\Controllers\DepartmentController@storePosition', ['auth', 'csrf'], 'hr.department.manage'], ['POST', '/hr/departments/{id:\d+}/positions', 'HR\Controllers\DepartmentController@storePosition', ['auth', 'csrf'], 'hr.department.manage'],
['POST', '/hr/departments/{id:\d+}/positions/{posId:\d+}/delete', 'HR\Controllers\DepartmentController@deletePosition', ['auth', 'csrf'], 'hr.department.manage'], ['POST', '/hr/departments/{id:\d+}/positions/{posId:\d+}/delete', 'HR\Controllers\DepartmentController@deletePosition', ['auth', 'csrf'], 'hr.department.manage'],
['GET', '/hr/departments/{id:\d+}/aqsam-json', 'HR\Controllers\DepartmentController@aqsamJson', ['auth'], 'hr.department.view'],
// ── Job Titles ── // ── Job Titles ──
['GET', '/hr/job-titles', 'HR\Controllers\JobTitleController@index', ['auth'], 'hr.job_title.view'], ['GET', '/hr/job-titles', 'HR\Controllers\JobTitleController@index', ['auth'], 'hr.job_title.view'],
['GET', '/hr/job-titles/create', 'HR\Controllers\JobTitleController@create', ['auth'], 'hr.job_title.manage'], ['GET', '/hr/job-titles/create', 'HR\Controllers\JobTitleController@create', ['auth'], 'hr.job_title.manage'],
......
<?php $__template->layout('Layout.main'); ?> <?php $__template->layout('Layout.main'); ?>
<?php $isEdit = $department !== null; ?> <?php $isEdit = $department !== null; ?>
<?php $__template->section('title'); ?><?= $isEdit ? 'تعديل القسم' : 'إضافة قسم جديد' ?><?php $__template->endSection(); ?> <?php $currentType = old('department_type') ?? ($isEdit ? ($department->department_type ?? 'qism') : 'qism'); ?>
<?php $__template->section('title'); ?><?= $isEdit ? ($currentType === 'idara' ? 'تعديل الإدارة' : 'تعديل القسم') : 'إضافة إدارة / قسم' ?><?php $__template->endSection(); ?>
<?php $__template->section('page_actions'); ?> <?php $__template->section('page_actions'); ?>
<a href="/hr/departments" class="btn btn-secondary">رجوع</a> <a href="/hr/departments" class="btn btn-secondary">رجوع</a>
...@@ -11,26 +12,46 @@ ...@@ -11,26 +12,46 @@
<?= csrf_field() ?> <?= csrf_field() ?>
<div class="card" style="margin-bottom:20px;"> <div class="card" style="margin-bottom:20px;">
<div style="padding:16px;border-bottom:1px solid #E5E7EB;"> <div style="padding:16px;border-bottom:1px solid #E5E7EB;">
<h3 style="margin:0;font-size:16px;">بيانات القسم</h3> <h3 style="margin:0;font-size:16px;">نوع الوحدة التنظيمية</h3>
</div>
<div style="padding:16px;">
<div style="display:flex;gap:20px;">
<label style="display:flex;align-items:center;gap:8px;cursor:pointer;padding:12px 20px;border:2px solid #E5E7EB;border-radius:8px;" id="label_idara">
<input type="radio" name="department_type" value="idara" <?= $currentType === 'idara' ? 'checked' : '' ?> onchange="toggleType()">
<span style="font-weight:600;font-size:15px;">إدارة</span>
<span style="color:#6B7280;font-size:13px;">(المستوى الأعلى)</span>
</label>
<label style="display:flex;align-items:center;gap:8px;cursor:pointer;padding:12px 20px;border:2px solid #E5E7EB;border-radius:8px;" id="label_qism">
<input type="radio" name="department_type" value="qism" <?= $currentType === 'qism' ? 'checked' : '' ?> onchange="toggleType()">
<span style="font-weight:600;font-size:15px;">قسم</span>
<span style="color:#6B7280;font-size:13px;">(تابع لإدارة)</span>
</label>
</div>
</div>
</div>
<div class="card" style="margin-bottom:20px;">
<div style="padding:16px;border-bottom:1px solid #E5E7EB;">
<h3 style="margin:0;font-size:16px;" id="formTitle"><?= $currentType === 'idara' ? 'بيانات الإدارة' : 'بيانات القسم' ?></h3>
</div> </div>
<div style="padding:16px;display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:16px;"> <div style="padding:16px;display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:16px;">
<div> <div>
<label style="display:block;margin-bottom:4px;font-size:13px;">اسم القسم بالعربي <span style="color:#DC2626;">*</span></label> <label style="display:block;margin-bottom:4px;font-size:13px;" id="nameLabel"><?= $currentType === 'idara' ? 'اسم الإدارة بالعربي' : 'اسم القسم بالعربي' ?> <span style="color:#DC2626;">*</span></label>
<input type="text" name="name_ar" value="<?= e(old('name_ar') ?? ($isEdit ? $department->name_ar : '')) ?>" class="form-control" required> <input type="text" name="name_ar" value="<?= e(old('name_ar') ?? ($isEdit ? $department->name_ar : '')) ?>" class="form-control" required>
</div> </div>
<div> <div>
<label style="display:block;margin-bottom:4px;font-size:13px;">اسم القسم بالإنجليزي</label> <label style="display:block;margin-bottom:4px;font-size:13px;" id="nameEnLabel"><?= $currentType === 'idara' ? 'اسم الإدارة بالإنجليزي' : 'اسم القسم بالإنجليزي' ?></label>
<input type="text" name="name_en" value="<?= e(old('name_en') ?? ($isEdit ? $department->name_en : '')) ?>" class="form-control"> <input type="text" name="name_en" value="<?= e(old('name_en') ?? ($isEdit ? $department->name_en : '')) ?>" class="form-control">
</div> </div>
<div> <div>
<label style="display:block;margin-bottom:4px;font-size:13px;">الكود <span style="color:#DC2626;">*</span></label> <label style="display:block;margin-bottom:4px;font-size:13px;">الكود <span style="color:#DC2626;">*</span></label>
<input type="text" name="department_code" value="<?= e(old('department_code') ?? ($isEdit ? $department->department_code : '')) ?>" class="form-control" required> <input type="text" name="department_code" value="<?= e(old('department_code') ?? ($isEdit ? $department->department_code : '')) ?>" class="form-control" required>
</div> </div>
<div> <div id="parentField" style="<?= $currentType === 'idara' ? 'display:none;' : '' ?>">
<label style="display:block;margin-bottom:4px;font-size:13px;">القسم الأب</label> <label style="display:block;margin-bottom:4px;font-size:13px;">الإدارة التابع لها <span style="color:#DC2626;">*</span></label>
<select name="parent_id" class="form-control"> <select name="parent_id" class="form-control" id="parentSelect">
<option value="">-- بدون --</option> <option value="">-- اختر الإدارة --</option>
<?php foreach ($departments as $d): ?> <?php foreach ($idaras as $d): ?>
<?php if ($isEdit && (int) $d['id'] === (int) $department->id) continue; ?> <?php if ($isEdit && (int) $d['id'] === (int) $department->id) continue; ?>
<option value="<?= (int) $d['id'] ?>" <?= (old('parent_id') ?? ($isEdit ? $department->parent_id : '')) == $d['id'] ? 'selected' : '' ?>><?= e($d['name_ar']) ?></option> <option value="<?= (int) $d['id'] ?>" <?= (old('parent_id') ?? ($isEdit ? $department->parent_id : '')) == $d['id'] ? 'selected' : '' ?>><?= e($d['name_ar']) ?></option>
<?php endforeach; ?> <?php endforeach; ?>
...@@ -72,5 +93,18 @@ ...@@ -72,5 +93,18 @@
<button type="submit" class="btn btn-primary"><?= $isEdit ? 'تحديث' : 'حفظ' ?></button> <button type="submit" class="btn btn-primary"><?= $isEdit ? 'تحديث' : 'حفظ' ?></button>
</div> </div>
</form> </form>
<script>if(typeof lucide!=='undefined')lucide.createIcons();</script> <script>
function toggleType() {
var isIdara = document.querySelector('input[name="department_type"]:checked').value === 'idara';
document.getElementById('parentField').style.display = isIdara ? 'none' : '';
document.getElementById('formTitle').textContent = isIdara ? 'بيانات الإدارة' : 'بيانات القسم';
document.getElementById('nameLabel').innerHTML = (isIdara ? 'اسم الإدارة بالعربي' : 'اسم القسم بالعربي') + ' <span style="color:#DC2626;">*</span>';
document.getElementById('nameEnLabel').textContent = isIdara ? 'اسم الإدارة بالإنجليزي' : 'اسم القسم بالإنجليزي';
document.getElementById('label_idara').style.borderColor = isIdara ? '#2563EB' : '#E5E7EB';
document.getElementById('label_qism').style.borderColor = isIdara ? '#E5E7EB' : '#2563EB';
if (isIdara) document.getElementById('parentSelect').value = '';
}
toggleType();
if(typeof lucide!=='undefined')lucide.createIcons();
</script>
<?php $__template->endSection(); ?> <?php $__template->endSection(); ?>
<?php $__template->layout('Layout.main'); ?> <?php $__template->layout('Layout.main'); ?>
<?php $__template->section('title'); ?>الأقسام<?php $__template->endSection(); ?> <?php $__template->section('title'); ?>الإدارات والأقسام<?php $__template->endSection(); ?>
<?php $__template->section('page_actions'); ?> <?php $__template->section('page_actions'); ?>
<?php if (can('hr.department.manage')): ?> <?php if (can('hr.department.manage')): ?>
<a href="/hr/departments/create" class="btn btn-primary" style="display:inline-flex;align-items:center;gap:6px;"> <a href="/hr/departments/create" class="btn btn-primary" style="display:inline-flex;align-items:center;gap:6px;">
<i data-lucide="plus" style="width:16px;height:16px;"></i> إضافة قسم <i data-lucide="plus" style="width:16px;height:16px;"></i> إضافة إدارة / قسم
</a> </a>
<?php endif; ?> <?php endif; ?>
<?php $__template->endSection(); ?> <?php $__template->endSection(); ?>
...@@ -14,14 +14,31 @@ ...@@ -14,14 +14,31 @@
<form method="GET" action="/hr/departments" style="display:flex;gap:10px;flex-wrap:wrap;align-items:end;padding:16px;"> <form method="GET" action="/hr/departments" style="display:flex;gap:10px;flex-wrap:wrap;align-items:end;padding:16px;">
<div style="flex:1;min-width:200px;"> <div style="flex:1;min-width:200px;">
<label style="display:block;margin-bottom:4px;font-size:13px;color:#6B7280;">بحث</label> <label style="display:block;margin-bottom:4px;font-size:13px;color:#6B7280;">بحث</label>
<input type="text" name="q" value="<?= e($filters['q']) ?>" placeholder="اسم أو كود القسم..." class="form-control"> <input type="text" name="q" value="<?= e($filters['q']) ?>" placeholder="اسم أو كود..." class="form-control">
</div>
<div style="min-width:140px;">
<label style="display:block;margin-bottom:4px;font-size:13px;color:#6B7280;">النوع</label>
<select name="department_type" class="form-control">
<option value="">الكل</option>
<option value="idara" <?= ($filters['department_type'] ?? '') === 'idara' ? 'selected' : '' ?>>إدارة</option>
<option value="qism" <?= ($filters['department_type'] ?? '') === 'qism' ? 'selected' : '' ?>>قسم</option>
</select>
</div>
<div style="min-width:160px;">
<label style="display:block;margin-bottom:4px;font-size:13px;color:#6B7280;">الإدارة</label>
<select name="parent_id" class="form-control">
<option value="">الكل</option>
<?php foreach ($idaras as $ida): ?>
<option value="<?= (int) $ida['id'] ?>" <?= ($filters['parent_id'] ?? '') == $ida['id'] ? 'selected' : '' ?>><?= e($ida['name_ar']) ?></option>
<?php endforeach; ?>
</select>
</div> </div>
<div style="min-width:160px;"> <div style="min-width:160px;">
<label style="display:block;margin-bottom:4px;font-size:13px;color:#6B7280;">الفرع</label> <label style="display:block;margin-bottom:4px;font-size:13px;color:#6B7280;">الفرع</label>
<select name="branch_id" class="form-control"> <select name="branch_id" class="form-control">
<option value="">الكل</option> <option value="">الكل</option>
<?php foreach ($branches as $b): ?> <?php foreach ($branches as $b): ?>
<option value="<?= (int) $b['id'] ?>" <?= $filters['branch_id'] == $b['id'] ? 'selected' : '' ?>><?= e($b['name_ar']) ?></option> <option value="<?= (int) $b['id'] ?>" <?= ($filters['branch_id'] ?? '') == $b['id'] ? 'selected' : '' ?>><?= e($b['name_ar']) ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
</div> </div>
...@@ -35,8 +52,9 @@ ...@@ -35,8 +52,9 @@
<thead> <thead>
<tr> <tr>
<th>الكود</th> <th>الكود</th>
<th>اسم القسم</th> <th>النوع</th>
<th>القسم الأب</th> <th>الاسم</th>
<th>الإدارة التابع لها</th>
<th>الفرع</th> <th>الفرع</th>
<th>الحالة</th> <th>الحالة</th>
<th>إجراءات</th> <th>إجراءات</th>
...@@ -44,11 +62,18 @@ ...@@ -44,11 +62,18 @@
</thead> </thead>
<tbody> <tbody>
<?php if (empty($departments)): ?> <?php if (empty($departments)): ?>
<tr><td colspan="6" style="text-align:center;padding:40px;color:#9CA3AF;">لا توجد أقسام</td></tr> <tr><td colspan="7" style="text-align:center;padding:40px;color:#9CA3AF;">لا توجد إدارات أو أقسام</td></tr>
<?php else: ?> <?php else: ?>
<?php foreach ($departments as $dept): ?> <?php foreach ($departments as $dept): ?>
<tr> <tr>
<td><code><?= e($dept['department_code']) ?></code></td> <td><code><?= e($dept['department_code']) ?></code></td>
<td>
<?php if (($dept['department_type'] ?? 'qism') === 'idara'): ?>
<span style="display:inline-block;padding:2px 8px;border-radius:9999px;font-size:12px;background:#DBEAFE;color:#1E40AF;">إدارة</span>
<?php else: ?>
<span style="display:inline-block;padding:2px 8px;border-radius:9999px;font-size:12px;background:#F3E8FF;color:#6B21A8;">قسم</span>
<?php endif; ?>
</td>
<td><a href="/hr/departments/<?= (int) $dept['id'] ?>"><?= e($dept['name_ar']) ?></a></td> <td><a href="/hr/departments/<?= (int) $dept['id'] ?>"><?= e($dept['name_ar']) ?></a></td>
<td><?= e($dept['parent_name'] ?? '-') ?></td> <td><?= e($dept['parent_name'] ?? '-') ?></td>
<td><?= e($dept['branch_name'] ?? '-') ?></td> <td><?= e($dept['branch_name'] ?? '-') ?></td>
......
<?php $__template->layout('Layout.main'); ?> <?php $__template->layout('Layout.main'); ?>
<?php $__template->section('title'); ?>القسم: <?= e($department->name_ar) ?><?php $__template->endSection(); ?> <?php $isIdara = ($department->department_type ?? 'qism') === 'idara'; ?>
<?php $__template->section('title'); ?><?= $isIdara ? 'الإدارة' : 'القسم' ?>: <?= e($department->name_ar) ?><?php $__template->endSection(); ?>
<?php $__template->section('page_actions'); ?> <?php $__template->section('page_actions'); ?>
<?php if (can('hr.department.manage')): ?> <?php if (can('hr.department.manage')): ?>
...@@ -14,14 +15,23 @@ ...@@ -14,14 +15,23 @@
<div class="card" style="margin-bottom:20px;"> <div class="card" style="margin-bottom:20px;">
<div style="padding:16px;border-bottom:1px solid #E5E7EB;"> <div style="padding:16px;border-bottom:1px solid #E5E7EB;">
<h3 style="margin:0;font-size:16px;display:flex;align-items:center;gap:8px;"> <h3 style="margin:0;font-size:16px;display:flex;align-items:center;gap:8px;">
<i data-lucide="building-2" style="width:18px;height:18px;color:#6B7280;"></i> بيانات القسم <i data-lucide="building-2" style="width:18px;height:18px;color:#6B7280;"></i> بيانات <?= $isIdara ? 'الإدارة' : 'القسم' ?>
</h3> </h3>
</div> </div>
<div style="padding:16px;display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:16px;"> <div style="padding:16px;display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:16px;">
<div><span style="color:#6B7280;font-size:13px;">الكود</span><div style="font-weight:600;"><?= e($department->department_code) ?></div></div> <div><span style="color:#6B7280;font-size:13px;">الكود</span><div style="font-weight:600;"><?= e($department->department_code) ?></div></div>
<div><span style="color:#6B7280;font-size:13px;">النوع</span><div>
<?php if ($isIdara): ?>
<span style="display:inline-block;padding:2px 8px;border-radius:9999px;font-size:12px;background:#DBEAFE;color:#1E40AF;">إدارة</span>
<?php else: ?>
<span style="display:inline-block;padding:2px 8px;border-radius:9999px;font-size:12px;background:#F3E8FF;color:#6B21A8;">قسم</span>
<?php endif; ?>
</div></div>
<div><span style="color:#6B7280;font-size:13px;">الاسم بالعربي</span><div style="font-weight:600;"><?= e($department->name_ar) ?></div></div> <div><span style="color:#6B7280;font-size:13px;">الاسم بالعربي</span><div style="font-weight:600;"><?= e($department->name_ar) ?></div></div>
<div><span style="color:#6B7280;font-size:13px;">الاسم بالإنجليزي</span><div><?= e($department->name_en ?? '-') ?></div></div> <div><span style="color:#6B7280;font-size:13px;">الاسم بالإنجليزي</span><div><?= e($department->name_en ?? '-') ?></div></div>
<div><span style="color:#6B7280;font-size:13px;">القسم الأب</span><div><?= $parent ? '<a href="/hr/departments/' . (int) $parent->id . '">' . e($parent->name_ar) . '</a>' : '-' ?></div></div> <?php if (!$isIdara): ?>
<div><span style="color:#6B7280;font-size:13px;">الإدارة التابع لها</span><div><?= $parent ? '<a href="/hr/departments/' . (int) $parent->id . '">' . e($parent->name_ar) . '</a>' : '-' ?></div></div>
<?php endif; ?>
<div><span style="color:#6B7280;font-size:13px;">المدير</span><div><?= $manager ? e($manager['first_name_ar'] . ' ' . $manager['last_name_ar']) : '-' ?></div></div> <div><span style="color:#6B7280;font-size:13px;">المدير</span><div><?= $manager ? e($manager['first_name_ar'] . ' ' . $manager['last_name_ar']) : '-' ?></div></div>
<div><span style="color:#6B7280;font-size:13px;">الفرع</span><div><?= $branch ? e($branch['name_ar']) : '-' ?></div></div> <div><span style="color:#6B7280;font-size:13px;">الفرع</span><div><?= $branch ? e($branch['name_ar']) : '-' ?></div></div>
<div><span style="color:#6B7280;font-size:13px;">عدد الموظفين</span><div style="font-weight:600;"><?= $employeeCount ?></div></div> <div><span style="color:#6B7280;font-size:13px;">عدد الموظفين</span><div style="font-weight:600;"><?= $employeeCount ?></div></div>
...@@ -116,7 +126,7 @@ ...@@ -116,7 +126,7 @@
<?php if (!empty($children)): ?> <?php if (!empty($children)): ?>
<div class="card" style="margin-bottom:20px;"> <div class="card" style="margin-bottom:20px;">
<div style="padding:16px;border-bottom:1px solid #E5E7EB;"> <div style="padding:16px;border-bottom:1px solid #E5E7EB;">
<h3 style="margin:0;font-size:16px;">الأقسام الفرعية (<?= count($children) ?>)</h3> <h3 style="margin:0;font-size:16px;"><?= $isIdara ? 'الأقسام التابعة' : 'الأقسام الفرعية' ?> (<?= count($children) ?>)</h3>
</div> </div>
<div class="table-responsive"> <div class="table-responsive">
<table class="data-table"> <table class="data-table">
...@@ -136,9 +146,9 @@ ...@@ -136,9 +146,9 @@
<?php if (can('hr.department.manage')): ?> <?php if (can('hr.department.manage')): ?>
<div style="display:flex;gap:10px;justify-content:flex-end;"> <div style="display:flex;gap:10px;justify-content:flex-end;">
<form method="POST" action="/hr/departments/<?= (int) $department->id ?>/archive" onsubmit="return confirm('هل أنت متأكد من حذف هذا القسم؟');"> <form method="POST" action="/hr/departments/<?= (int) $department->id ?>/archive" onsubmit="return confirm('هل أنت متأكد من حذف <?= $isIdara ? 'هذه الإدارة' : 'هذا القسم' ?>؟');">
<?= csrf_field() ?> <?= csrf_field() ?>
<button type="submit" class="btn btn-danger">حذف القسم</button> <button type="submit" class="btn btn-danger">حذف <?= $isIdara ? 'الإدارة' : 'القسم' ?></button>
</form> </form>
</div> </div>
<?php endif; ?> <?php endif; ?>
......
...@@ -142,12 +142,23 @@ ...@@ -142,12 +142,23 @@
<label style="display:block;margin-bottom:4px;font-size:13px;">كود البصمة</label> <label style="display:block;margin-bottom:4px;font-size:13px;">كود البصمة</label>
<input type="text" name="fingerprint_code" value="<?= e(old('fingerprint_code') ?? ($isEdit ? $profile->fingerprint_code : '')) ?>" class="form-control" placeholder="رقم الموظف في جهاز البصمة"> <input type="text" name="fingerprint_code" value="<?= e(old('fingerprint_code') ?? ($isEdit ? $profile->fingerprint_code : '')) ?>" class="form-control" placeholder="رقم الموظف في جهاز البصمة">
</div> </div>
<div>
<label style="display:block;margin-bottom:4px;font-size:13px;">الإدارة</label>
<select id="idara_select" class="form-control" onchange="loadAqsam()">
<option value="">-- اختر الإدارة --</option>
<?php foreach ($idaras as $ida): ?>
<option value="<?= (int) $ida['id'] ?>" <?= (old('idara_id') ?? ($isEdit ? ($profile->idara_id ?? '') : '')) == $ida['id'] ? 'selected' : '' ?>><?= e($ida['name_ar']) ?></option>
<?php endforeach; ?>
</select>
</div>
<div> <div>
<label style="display:block;margin-bottom:4px;font-size:13px;">القسم</label> <label style="display:block;margin-bottom:4px;font-size:13px;">القسم</label>
<select name="department_id" class="form-control"> <select name="department_id" id="qism_select" class="form-control">
<option value="">-- اختر --</option> <option value="">-- اختر القسم --</option>
<?php foreach ($departments as $d): ?> <?php foreach ($departments as $d): ?>
<option value="<?= (int) $d['id'] ?>" <?= (old('department_id') ?? ($isEdit ? $profile->department_id : '')) == $d['id'] ? 'selected' : '' ?>><?= e($d['name_ar']) ?></option> <?php if (($d['department_type'] ?? '') === 'qism'): ?>
<option value="<?= (int) $d['id'] ?>" data-idara="<?= (int) ($d['parent_id'] ?? 0) ?>" <?= (old('department_id') ?? ($isEdit ? $profile->department_id : '')) == $d['id'] ? 'selected' : '' ?>><?= e($d['name_ar']) ?></option>
<?php endif; ?>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
</div> </div>
...@@ -275,6 +286,31 @@ ...@@ -275,6 +286,31 @@
</div> </div>
</form> </form>
<script>
function loadAqsam() {
var idaraId = document.getElementById('idara_select').value;
var qismSelect = document.getElementById('qism_select');
var options = qismSelect.querySelectorAll('option[data-idara]');
var currentVal = qismSelect.value;
options.forEach(function(opt) {
if (!idaraId) { opt.style.display = ''; return; }
opt.style.display = opt.getAttribute('data-idara') === idaraId ? '' : 'none';
if (opt.style.display === 'none' && opt.value === currentVal) qismSelect.value = '';
});
}
document.addEventListener('DOMContentLoaded', function() {
var qismSelect = document.getElementById('qism_select');
var idaraSelect = document.getElementById('idara_select');
var selectedQism = qismSelect.value;
if (selectedQism) {
var opt = qismSelect.querySelector('option[value="' + selectedQism + '"]');
if (opt && opt.getAttribute('data-idara')) {
idaraSelect.value = opt.getAttribute('data-idara');
}
}
loadAqsam();
});
</script>
<script> <script>
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
var nidInput = document.getElementById('nidInput'); var nidInput = document.getElementById('nidInput');
......
...@@ -21,7 +21,15 @@ ...@@ -21,7 +21,15 @@
<select name="department_id" class="form-control"> <select name="department_id" class="form-control">
<option value="">الكل</option> <option value="">الكل</option>
<?php foreach ($departments as $d): ?> <?php foreach ($departments as $d): ?>
<option value="<?= (int) $d['id'] ?>" <?= $filters['department_id'] == $d['id'] ? 'selected' : '' ?>><?= e($d['name_ar']) ?></option> <?php if (($d['department_type'] ?? '') === 'idara'): ?>
<optgroup label="<?= e($d['name_ar']) ?>">
<?php foreach ($departments as $sub): ?>
<?php if (($sub['department_type'] ?? '') === 'qism' && (int)($sub['parent_id'] ?? 0) === (int)$d['id']): ?>
<option value="<?= (int) $sub['id'] ?>" <?= $filters['department_id'] == $sub['id'] ? 'selected' : '' ?>><?= e($sub['name_ar']) ?></option>
<?php endif; ?>
<?php endforeach; ?>
</optgroup>
<?php endif; ?>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
</div> </div>
...@@ -51,17 +59,18 @@ ...@@ -51,17 +59,18 @@
<div class="table-responsive"> <div class="table-responsive">
<table class="data-table"> <table class="data-table">
<thead> <thead>
<tr><th>رقم وظيفي</th><th>الاسم</th><th>القسم</th><th>المسمى الوظيفي</th><th>تاريخ التعيين</th><th>الحالة</th><th>إجراءات</th></tr> <tr><th>رقم وظيفي</th><th>الاسم</th><th>الإدارة</th><th>القسم</th><th>المسمى الوظيفي</th><th>تاريخ التعيين</th><th>الحالة</th><th>إجراءات</th></tr>
</thead> </thead>
<tbody> <tbody>
<?php if (empty($employees)): ?> <?php if (empty($employees)): ?>
<tr><td colspan="7" style="text-align:center;padding:40px;color:#9CA3AF;">لا يوجد موظفين</td></tr> <tr><td colspan="8" style="text-align:center;padding:40px;color:#9CA3AF;">لا يوجد موظفين</td></tr>
<?php else: ?> <?php else: ?>
<?php foreach ($employees as $emp): ?> <?php foreach ($employees as $emp): ?>
<tr> <tr>
<td><code><?= e($emp['employee_number']) ?></code></td> <td><code><?= e($emp['employee_number']) ?></code></td>
<td><a href="/hr/employees/<?= (int) $emp['id'] ?>"><?= e($emp['first_name_ar'] . ' ' . $emp['last_name_ar']) ?></a></td> <td><a href="/hr/employees/<?= (int) $emp['id'] ?>"><?= e($emp['first_name_ar'] . ' ' . $emp['last_name_ar']) ?></a></td>
<td><?= e($emp['department_name'] ?? '-') ?></td> <td><?= e($emp['idara_name'] ?? '-') ?></td>
<td><?= e(($emp['department_type'] ?? '') === 'qism' ? ($emp['department_name'] ?? '-') : '-') ?></td>
<td><?= e($emp['job_title_name'] ?? '-') ?></td> <td><?= e($emp['job_title_name'] ?? '-') ?></td>
<td><?= e($emp['hire_date'] ?? '-') ?></td> <td><?= e($emp['hire_date'] ?? '-') ?></td>
<td> <td>
......
...@@ -47,7 +47,8 @@ $sc = $statusColors[$profile->employment_status] ?? '#E5E7EB;color:#374151'; ...@@ -47,7 +47,8 @@ $sc = $statusColors[$profile->employment_status] ?? '#E5E7EB;color:#374151';
</h3> </h3>
</div> </div>
<div style="padding:16px;display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px;"> <div style="padding:16px;display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px;">
<div><span style="color:#6B7280;font-size:13px;">القسم</span><div><?= $department ? '<a href="/hr/departments/' . (int) $department->id . '">' . e($department->name_ar) . '</a>' : '-' ?></div></div> <div><span style="color:#6B7280;font-size:13px;">الإدارة</span><div><?= ($department && $department->parent_id) ? '<a href="/hr/departments/' . (int) $department->parent_id . '">' . e($idara->name_ar ?? '-') . '</a>' : ($department && ($department->department_type ?? '') === 'idara' ? '<a href="/hr/departments/' . (int) $department->id . '">' . e($department->name_ar) . '</a>' : '-') ?></div></div>
<div><span style="color:#6B7280;font-size:13px;">القسم</span><div><?= ($department && ($department->department_type ?? '') === 'qism') ? '<a href="/hr/departments/' . (int) $department->id . '">' . e($department->name_ar) . '</a>' : '-' ?></div></div>
<div><span style="color:#6B7280;font-size:13px;">المسمى الوظيفي</span><div><?= $jobTitle ? e($jobTitle->name_ar) : '-' ?></div></div> <div><span style="color:#6B7280;font-size:13px;">المسمى الوظيفي</span><div><?= $jobTitle ? e($jobTitle->name_ar) : '-' ?></div></div>
<div><span style="color:#6B7280;font-size:13px;">تاريخ التعيين</span><div><?= e($profile->hire_date) ?></div></div> <div><span style="color:#6B7280;font-size:13px;">تاريخ التعيين</span><div><?= e($profile->hire_date) ?></div></div>
<div><span style="color:#6B7280;font-size:13px;">سنوات الخدمة</span><div style="font-weight:600;"><?= number_format($yearsOfService, 1) ?> سنة</div></div> <div><span style="color:#6B7280;font-size:13px;">سنوات الخدمة</span><div style="font-weight:600;"><?= number_format($yearsOfService, 1) ?> سنة</div></div>
......
...@@ -12,8 +12,8 @@ use App\Modules\HR\Services\AttendanceViolationService; ...@@ -12,8 +12,8 @@ use App\Modules\HR\Services\AttendanceViolationService;
PermissionRegistry::register('hr', [ PermissionRegistry::register('hr', [
// Department // Department
'hr.department.view' => ['ar' => 'عرض الأقسام والإدارات', 'en' => 'View Departments'], 'hr.department.view' => ['ar' => 'عرض الإدارات والأقسام', 'en' => 'View Departments'],
'hr.department.manage' => ['ar' => 'إدارة الأقسام والإدارات', 'en' => 'Manage Departments'], 'hr.department.manage' => ['ar' => 'إدارة الإدارات والأقسام', 'en' => 'Manage Departments'],
// Job Title // Job Title
'hr.job_title.view' => ['ar' => 'عرض المسميات الوظيفية', 'en' => 'View Job Titles'], 'hr.job_title.view' => ['ar' => 'عرض المسميات الوظيفية', 'en' => 'View Job Titles'],
...@@ -118,7 +118,7 @@ MenuRegistry::register('hr', [ ...@@ -118,7 +118,7 @@ MenuRegistry::register('hr', [
'order' => 500, 'order' => 500,
'children' => [ 'children' => [
['label_ar' => 'الموظفون', 'label_en' => 'Employees', 'route' => '/hr/employees', 'permission' => 'hr.employee.view', 'order' => 1], ['label_ar' => 'الموظفون', 'label_en' => 'Employees', 'route' => '/hr/employees', 'permission' => 'hr.employee.view', 'order' => 1],
['label_ar' => 'الأقسام والإدارات', 'label_en' => 'Departments', 'route' => '/hr/departments', 'permission' => 'hr.department.view', 'order' => 2], ['label_ar' => 'الإدارات والأقسام', 'label_en' => 'Departments', 'route' => '/hr/departments', 'permission' => 'hr.department.view', 'order' => 2],
['label_ar' => 'المسميات الوظيفية', 'label_en' => 'Job Titles', 'route' => '/hr/job-titles', 'permission' => 'hr.job_title.view', 'order' => 3], ['label_ar' => 'المسميات الوظيفية', 'label_en' => 'Job Titles', 'route' => '/hr/job-titles', 'permission' => 'hr.job_title.view', 'order' => 3],
['label_ar' => 'العقود', 'label_en' => 'Contracts', 'route' => '/hr/contracts', 'permission' => 'hr.contract.view', 'order' => 4], ['label_ar' => 'العقود', 'label_en' => 'Contracts', 'route' => '/hr/contracts', 'permission' => 'hr.contract.view', 'order' => 4],
['label_ar' => 'الهيكل الراتبي', 'label_en' => 'Salary Structures', 'route' => '/hr/salary-structures', 'permission' => 'hr.employee.view_salary','order' => 5], ['label_ar' => 'الهيكل الراتبي', 'label_en' => 'Salary Structures', 'route' => '/hr/salary-structures', 'permission' => 'hr.employee.view_salary','order' => 5],
......
<?php
declare(strict_types=1);
return [
'up' => "
ALTER TABLE hr_departments ADD COLUMN department_type VARCHAR(10) NOT NULL DEFAULT 'qism' COMMENT 'idara=إدارة (top-level), qism=قسم (under idara)' AFTER department_code;
ALTER TABLE hr_departments ADD CONSTRAINT chk_hr_dept_type CHECK (department_type IN ('idara', 'qism'))
",
'down' => "
ALTER TABLE hr_departments DROP CONSTRAINT chk_hr_dept_type;
ALTER TABLE hr_departments DROP COLUMN department_type
",
];
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment