@extends('backend.layouts.app') @section('title', 'Import Staff') @section('content') @php $pageTitle = 'Import Staff'; $indexRoute = 'content-directory-staff.index'; $indexLabel = 'Staff'; @endphp @include('backend.layouts.partials._page_header')

Import Staff from Excel / CSV

Upload a file to preview and validate rows before inserting or updating staff.

@if ($errors->any())
{{ $errors->first() }}
@endif

How this import works

1. Download

Use the Excel or CSV template so the headers match exactly.

2. Fill rows

One staff member per row. Name is required; department uses an existing department code or name.

3. Preview

The system validates every row, including email, status and department matching.

4. Confirm

Only valid files can be imported. All rows are saved in one database transaction.

Important rules

  • Positions come from the Parameters module (ref table, cat DIRECTORY_STAFF_POSITION), matched in this order: position_code → position_bm → position_en.@if (auth('admin')->user()?->can('ref.view')) Open Parameters@endif
  • You do not have to create positions first. Tick Create missing positions below and any new position is added to the Parameters module when you confirm the import.
  • Auto-generated position codes are acronyms of the BM name — e.g. Pegawai Tadbir → PT. If the acronym already exists, a suffix is added (PT_2).
  • Departments must already exist — matched by department code, BM name or EN name.
  • Staff are matched by email: an existing email updates that staff member; a blank email always inserts a new one.
  • All-or-nothing: if one row is invalid, nothing is written to the database.

1. Download template

Use the template so the column names and sample rows are correct.

The sample rows use departments BPM and SDPI from the Department import template, and leave position_code blank so the code is generated automatically — tick Create missing positions when you test it.

2. Prepare your file

  • Use .xlsx or .csv only. Convert old .xls files first.
  • name is required. All other columns are optional.
  • department must match an existing department code, BM name or EN name.
  • position_code / position_bm / position_en must match a position in the Parameters module (cat DIRECTORY_STAFF_POSITION) — unless Create missing positions is ticked below. Codes are acronyms, e.g. Pegawai Tadbir → PT.
  • Existing emails are updated; blank emails always insert a new staff member.
  • The template sample department values (BPM, SDPI) come from the Department import template — import departments first so those codes exist.
  • Phone numbers can use spaces, hyphens and +60, e.g. 03-8091 7245.
  • Maximum 5,000 rows and 200MB per file.
@csrf
@include('backend.layouts.partials._upload-hint', ['text' => 'XLSX or CSV - Max 200MB']) @error('file')

{{ $message }}

@enderror

The first worksheet is read. The first row must be the header row.

Cancel

File format

Column Required What it means Example
name Yes Staff name. Maximum 255 characters. Ahmad Ali
email No Optional. No strict email format and no @ required. Used to match and update existing staff. Blank inserts a new staff member. ahmad@example.com
phone No Phone number. Accepts local or international formats such as 03-8091 7245 or +60 12-345 6789. Set the column as Text if Excel changes the value. 03-8091 7245
position_code No Optional. Short position code in the Parameters module (cat DIRECTORY_STAFF_POSITION). Leave blank to auto-generate an acronym from the BM name — e.g. Pegawai Tadbir → PT. A code that does not exist in Parameters makes the row Invalid. PT
position_bm No Position name (BM). Matched against descr in the Parameters module. The legacy position column is accepted as an alias. Pegawai Tadbir
position_en No Position name (EN). Matched against descr_en in the Parameters module. Used when the BM name is not provided. Administrative Officer
department No Existing department code (recommended), BM name or EN name. Blank means no department. Unknown or ambiguous values are rejected. BTM
sort No Display order. Blank is saved as 0. 1
status No Active/Inactive, Aktif/Tidak Aktif, 1/0. Blank is saved as Active. Active

Existing staff are matched by email and updated. Rows without an email are inserted as new staff. Department values are looked up from the Department module; staff import never creates departments. If any row is invalid, nothing will be imported.

@endsection @push('scripts') @endpush