{{-- resources/views/talenta/sandbox/employees/create.blade.php --}} @extends('layouts.app') @section('title','Sandbox – Employees') @section('page-title','Buat Karyawan (Sandbox)') @section('content') @php /** * ====== Helper: Label field yang human-friendly ====== */ function field_label(string $k): string { $map = [ 'employee_id' => 'Employee ID', 'first_name' => 'First Name', 'last_name' => 'Last Name', 'email' => 'Email', 'date_of_birth' => 'Birthdate', 'gender' => 'Gender', 'marital_status' => 'Marital Status', 'religion' => 'Religion', 'branch' => 'Branch', 'organization_name' => 'Organization', 'job_position'=> 'Job Position', 'job_level' => 'Job Level', 'employment_status' => 'Employment Status', 'join_date' => 'Join Date', 'end_employment_status_date' => 'End Employment Status Date', 'schedule' => 'Schedule', 'ptkp_status' => 'PTKP Status', 'npp_bpjs_ketenagakerjaan' => 'NPP BPJS Ketenagakerjaan', 'basic_salary'=> 'Basic Salary', 'tax_configuration' => 'Tax Configuration', 'type_salary' => 'Type Salary', 'salary_configuration' => 'Salary Configuration', 'jht_configuration' => 'JHT Configuration', 'employee_tax_status' => 'Employee Tax Status', 'jp_configuration' => 'JP Configuration', 'overtime_status' => 'Overtime', 'bpjs_kesehatan_config' => 'BPJS Kesehatan Class', ]; return $map[$k] ?? ucwords(str_replace(['_','-'],' ',$k)); } /** * ====== Helper: Humanize 1 baris error ====== * Contoh masukan: * - "email tes@gmail.com has already been taken" * - "branch Pusat doesn't exist" * - "basic_salary must be positive integer" * - "employee_id KM10001 has already been taken" * - "email, branch, job_position required" */ function humanize_line(string $line): string { $s = trim($line); // Remove noisy prefixes $s = preg_replace('~^Talenta Sandbox error:\s*~i', '', $s); // Required list seperti "email, branch required" if (preg_match('~^([a-z0-9_,\s-]+)\s+required$~i', $s, $m)) { $fields = array_map('trim', explode(',', $m[1])); $labels = array_map(fn($f)=> field_label($f), $fields); return 'Data wajib belum lengkap: ' . implode(', ', $labels) . '.'; } // "X has already been taken" if (preg_match('~^(email|employee_id)\s+(.+?)\s+has already been taken$~i', $s, $m)) { $label = field_label(strtolower($m[1])); $val = $m[2]; if (strtolower($m[1]) === 'email') { return "Email \"$val\" sudah terdaftar."; } if (strtolower($m[1]) === 'employee_id') { return "Employee ID \"$val\" sudah digunakan."; } } // "branch Pusat doesn't exist" if (preg_match('~^(branch|organization_name|job_position|job_level)\s+(.+?)\s+doesn\'?t exist$~i', $s, $m)) { $label = field_label(strtolower($m[1])); $val = $m[2]; return "{$label} \"$val\" tidak ditemukan. Pastikan pilih dari daftar."; } // "must be positive integer" if (preg_match('~^(basic_salary|employee_tax_status)\s+must be positive integer$~i', $s, $m)) { $label = field_label(strtolower($m[1])); return "{$label} harus lebih dari 0 (angka bulat)."; } // "mag: method not allowed" → hide kode teknis if (stripos($s, 'method not allowed') !== false) { return 'Aksi tidak didukung oleh server sandbox. Coba lagi dengan data yang benar.'; } // Generic English $replacements = [ "Data not valid" => "Data tidak valid.", "Missing required keys" => "Data wajib belum lengkap.", "required" => "wajib diisi.", "already been taken" => "sudah digunakan.", "doesn't exist" => "tidak ditemukan.", "must be positive integer" => "harus lebih dari 0 (angka bulat).", ]; foreach ($replacements as $k=>$v) { if (stripos($s, $k) !== false) { $s = str_ireplace($k, $v, $s); } } // Sedikit polesan umum: awali huruf besar, akhiri titik. $s = rtrim($s, " \t\n\r\0\x0B."); $s = ucfirst($s) . '.'; return $s; } /** * ====== Helper: Parse error Talenta JSON ====== * Masukan: "Talenta Sandbox error: {json...}" * Keluaran: array of humanized lines */ function parse_talenta_errors(string $raw): array { $out = []; if (preg_match('~Talenta Sandbox error:\s*(\{.*)$~s', $raw, $m)) { $json = trim($m[1]); $obj = json_decode($json, true); if (is_array($obj)) { if (!empty($obj['errors']) && is_array($obj['errors'])) { foreach ($obj['errors'] as $ln) { $out[] = humanize_line((string)$ln); } } elseif (!empty($obj['message'])) { $out[] = humanize_line((string) $obj['message']); } } } // Fallback: kalau tak bisa parse, humanize saja seluruh raw if (!$out) $out[] = humanize_line($raw); return $out; } /** * ====== Kumpulkan semua error (validator + session('error')) jadi friendly ====== */ $friendlyErrors = []; // Dari validator Laravel ($errors) if ($errors->any()) { foreach ($errors->all() as $e) { $e = (string)$e; if (stripos($e, 'Talenta Sandbox error:') !== false) { $friendlyErrors = array_merge($friendlyErrors, parse_talenta_errors($e)); } else { // Contoh validator: "employee_id wajib diisi." sudah manusiawi → tapi tetap poles sedikit $friendlyErrors[] = humanize_line($e); } } } // Dari session('error') (mis. error generik dari controller) if (session('error')) { $raw = (string) session('error'); if (stripos($raw, 'Talenta Sandbox error:') !== false) { $friendlyErrors = array_merge($friendlyErrors, parse_talenta_errors($raw)); } else { $friendlyErrors[] = humanize_line($raw); } } // Hilangkan duplikat & kosong $friendlyErrors = array_values(array_unique(array_filter(array_map('trim', $friendlyErrors)))); @endphp

Tambah Karyawan – Sandbox

Lengkapi informasi personal & employment. Kolom bertanda * wajib diisi.

← Kembali
{{-- Panel error (human-friendly) --}} @if(count($friendlyErrors))
Form belum lengkap
@endif
@csrf {{-- ================= PERSONAL ================= --}}

Informasi Personal

Data dasar karyawan.

{{-- Employee ID --}}
@error('employee_id')

{{ humanize_line($message) }}

@enderror
{{-- First Name --}}
@error('first_name')

{{ humanize_line($message) }}

@enderror
{{-- Last Name --}}
{{-- Email --}}
@error('email')

{{ humanize_line($message) }}

@enderror
{{-- Birthdate --}}
@error('date_of_birth')

{{ humanize_line($message) }}

@enderror
{{-- Gender (WAJIB) --}}
@error('gender')

{{ humanize_line($message) }}

@enderror

Wajib dipilih (Male/Female).

{{-- Marital Status --}}
@error('marital_status')

{{ humanize_line($message) }}

@enderror
{{-- Religion --}}
@error('religion')

{{ humanize_line($message) }}

@enderror
{{-- ================= EMPLOYMENT ================= --}}

Informasi Employment

Pemetaan organisasi & status kerja.

{{-- Branch --}}
@error('branch')

{{ humanize_line($message) }}

@enderror

Pilih persis “Pusat”.

{{-- Organization --}}
@error('organization_name')

{{ humanize_line($message) }}

@enderror
{{-- Job Position --}}
@error('job_position')

{{ humanize_line($message) }}

@enderror
{{-- Job Level --}}
@if(!empty($levels)) @else

Master Job Level kosong.

@endif @error('job_level')

{{ humanize_line($message) }}

@enderror
{{-- Employment Status --}}
@error('employment_status')

{{ humanize_line($message) }}

@enderror

Contract (ID=2) & Probation (ID=3) wajib isi End Employment Status Date. Permanent (ID=1) tidak perlu.

{{-- End Employment Status Date --}}
@error('end_employment_status_date')

{{ humanize_line($message) }}

@enderror
{{-- Join Date --}}
@error('join_date')

{{ humanize_line($message) }}

@enderror
{{-- Schedule --}}
@error('schedule')

{{ humanize_line($message) }}

@enderror
{{-- ================= KOMPENSASI & PAJAK ================= --}}

Kompensasi & Pajak

Saat create, kamu tidak perlu mengisi gaji pokok. Sistem akan mengirim payload tanpa field gaji & blok payroll yang diwajibkan, lalu memastikan gaji awal tersimpan sebagai 0. Kamu bisa mengisi nominal gaji kapan saja nanti melalui menu edit.

{{-- PTKP (wajib) --}}
@error('ptkp_status')

{{ humanize_line($message) }}

@enderror
{{-- NPP BPJS TK (opsional) --}}
@error('npp_bpjs_ketenagakerjaan')

{{ humanize_line($message) }}

@enderror
{{-- ================= ACTIONS ================= --}}

Pastikan data sudah benar sebelum disimpan.

Batal
{{-- SweetAlert2 + dynamic rule End Date (ID 2 & 3) --}} @endsection