feat: implement core material requisition, project management, and daily reporting modules with workflow validation and automated documentation support.
Some checks failed
Tests / PHP 8.3 (push) Has been cancelled
Tests / PHP 8.4 (push) Has been cancelled
Tests / PHP 8.5 (push) Has been cancelled

This commit is contained in:
2026-08-01 15:38:57 +08:00
parent 4fc58bb979
commit 42ba980f7a
36 changed files with 1588 additions and 150 deletions

View File

@@ -48,10 +48,20 @@ class UserController extends Controller
public function create(): Response
{
$isPlatformAdmin = is_null(auth()->user()->contractor_id);
$isSuperAdmin = auth()->user()->hasRole('Super Admin');
// Auto-generate the next employee code (EMP-XXXX)
$last = EmployeeProfile::where('employee_code', 'like', 'EMP-%')
->orderByRaw("CAST(SUBSTR(employee_code, 5) AS INTEGER) DESC")
->value('employee_code');
$nextNumber = $last ? ((int) substr($last, 4)) + 1 : 1;
$nextCode = 'EMP-' . str_pad($nextNumber, 4, '0', STR_PAD_LEFT);
return Inertia::render('UserManagement::Users/Create', [
'contractors' => $isPlatformAdmin
'isSuperAdmin' => $isSuperAdmin,
'nextEmployeeCode' => $nextCode,
'contractors' => $isSuperAdmin
? Contractor::where('status', 'active')
->orderBy('company_name')
->get(['id', 'company_name', 'type'])
@@ -59,11 +69,12 @@ class UserController extends Controller
]);
}
public function store(Request $request): RedirectResponse
{
$isPlatformAdmin = is_null(auth()->user()->contractor_id);
$isSuperAdmin = auth()->user()->hasRole('Super Admin');
$allowedRoles = $isPlatformAdmin ? ['admin', 'contractor', 'employee', 'customer'] : ['contractor', 'employee', 'customer'];
$allowedRoles = $isSuperAdmin ? ['admin', 'contractor', 'employee', 'customer'] : ['contractor', 'employee', 'customer'];
$validated = $request->validate([
'name' => ['required', 'string', 'max:255'],
@@ -74,7 +85,7 @@ class UserController extends Controller
'auto_password' => ['nullable', 'boolean'],
'password' => ['nullable', 'string', 'min:8', 'confirmed', 'required_if:auto_password,false'],
// Platform admin only: pick the contractor for this user
'contractor_id' => $isPlatformAdmin ? ['nullable', 'exists:contractors,id'] : ['prohibited'],
'contractor_id' => $isSuperAdmin ? ['nullable', 'exists:contractors,id'] : ['prohibited'],
// Employee fields
'department' => ['nullable', 'string', 'max:255'],
'position' => ['nullable', 'string', 'max:255'],
@@ -91,7 +102,7 @@ class UserController extends Controller
// Resolve contractor_id: contractor admins always use their own;
// platform admins use the one selected in the form (null = platform user)
$contractorId = $isPlatformAdmin
$contractorId = $isSuperAdmin
? ($validated['contractor_id'] ?? null)
: auth()->user()->contractor_id;
@@ -438,11 +449,19 @@ class UserController extends Controller
private function createProfile(User $user, array $validated): void
{
if (in_array($validated['user_type'], ['admin', 'employee', 'contractor'])) {
// Server-side strict generation & lock for employee_code
$last = EmployeeProfile::where('employee_code', 'like', 'EMP-%')
->orderByRaw("CAST(SUBSTR(employee_code, 5) AS INTEGER) DESC")
->value('employee_code');
$nextNumber = $last ? ((int) substr($last, 4)) + 1 : 1;
$employeeCode = 'EMP-' . str_pad($nextNumber, 4, '0', STR_PAD_LEFT);
$profile = EmployeeProfile::create([
'user_id' => $user->id,
'department' => $validated['department'] ?? null,
'position' => $validated['position'] ?? null,
'employee_code' => $validated['employee_code'] ?? null,
'employee_code' => $employeeCode,
'hire_date' => $validated['hire_date'] ?? null,
'phone' => $validated['phone'] ?? null,
'address' => $validated['address'] ?? null,