Files
accounting_dev_v2/application/controllers/Employees.php
T
2026-09-14 11:14:25 +07:00

518 lines
15 KiB
PHP

<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Employees extends MY_Controller {
public function __construct()
{
parent::__construct();
$this->load->database();
$this->load->helper(['url', 'file']);
if (!$this->session->userdata('logged_in')) {
redirect('auth');
}
date_default_timezone_set('Asia/Jakarta');
}
// =========================================================
// INDEX
// =========================================================
public function index()
{
$data = [
"active_menu" => "employees",
"can_manage_all_salary" => $this->canManageAllSalary(),
"employee_permissions" => array(
'create'=>$this->canEmployee('can_create'),
'update'=>$this->canEmployee('can_update'),
'delete'=>$this->canEmployee('can_delete')
)
];
$data['departments'] = $this->db
->where('is_active',1)
->order_by('department_name','ASC')
->get('k_departments')
->result();
$data['positions'] = $this->db
->where('is_active',1)
->order_by('position_name','ASC')
->get('k_positions')
->result();
$data['branches'] = $this->db
->order_by('branch_name','ASC')
->get('k_branches')
->result();
$this->load->view('partials/header', $data);
$this->load->view('employees/employees', $data);
$this->load->view('partials/footer');
}
// =========================================================
// GET ALL
// =========================================================
public function getAll()
{
try {
$query = $this->db
->select("
e.*,
d.department_name,
p.position_name,
b.branch_name
")
->from('k_employees e')
->join(
'k_departments d',
'd.id = e.department_id',
'left'
)
->join(
'k_positions p',
'p.id = e.position_id',
'left'
)
->join(
'k_branches b',
'b.id = e.branch_id',
'left'
)
->order_by('e.department_id','ASC');
if ($this->db->field_exists('company_id','k_employees')) $query->where('e.company_id',(int)$this->session->userdata('company_id'));
$data = $query->get()->result();
foreach ($data as $employee) $this->maskRestrictedSalary($employee);
return $this->json([
'status' => true,
'data' => $data
]);
} catch (Exception $e) {
return $this->json([
'status' => false,
'message' => $e->getMessage(),
'data' => []
]);
}
}
// =========================================================
// DETAIL
// =========================================================
public function detail($id = null)
{
try {
$data = $this->db
->select("
e.*,
d.department_name,
p.position_name,
b.branch_name
")
->from('k_employees e')
->join(
'k_departments d',
'd.id = e.department_id',
'left'
)
->join(
'k_positions p',
'p.id = e.position_id',
'left'
)
->join(
'k_branches b',
'b.id = e.branch_id',
'left'
)
->where('e.id',$id);
if ($this->db->field_exists('company_id','k_employees')) $this->db->where('e.company_id',(int)$this->session->userdata('company_id'));
$data = $this->db
->get()
->row();
if (!$data) {
return $this->json([
'status' => false,
'message' => 'Data tidak ditemukan'
]);
}
$this->maskRestrictedSalary($data);
return $this->json([
'status' => true,
'data' => $data
]);
} catch (Exception $e) {
return $this->json([
'status' => false,
'message' => $e->getMessage()
]);
}
}
// =========================================================
// STORE
// =========================================================
public function store()
{
try {
if (empty(trim($this->input->post('full_name')))) {
return $this->json([
'status' => false,
'message'=> 'Nama wajib diisi'
]);
}
if (empty($this->input->post('join_date'))) {
return $this->json([
'status' => false,
'message'=> 'Tanggal masuk wajib diisi'
]);
}
$employee_code = $this->generateEmployeeCode();
$photo = $this->uploadPhoto();
$data = $this->prepareData();
$data['employee_code'] = $employee_code;
$data['photo'] = $photo;
if ($this->db->field_exists('company_id','k_employees')) $data['company_id']=(int)$this->session->userdata('company_id');
$this->db->insert('k_employees',$data);
$employee_id = $this->db->insert_id();
log_activity(
'employees',
'create',
'Menambah karyawan: '.$data['full_name'].' (ID: '.$employee_id.')',
'success'
);
return $this->json([
'status' => true,
'message' => 'Berhasil simpan data'
]);
} catch (Exception $e) {
return $this->json([
'status' => false,
'message' => $e->getMessage()
]);
}
}
// =========================================================
// UPDATE
// =========================================================
public function update($id = null)
{
try {
$employee = $this->db
->get_where('k_employees',['id'=>$id])
->row();
if (!$employee) {
return $this->json([
'status' => false,
'message' => 'Data tidak ditemukan'
]);
}
if (!empty($employee->salary_restricted) && !$this->canManageAllSalary()) {
return $this->json(['status'=>false,'message'=>'Gaji karyawan ini bersifat terbatas. Anda memerlukan permission Manage All Gaji untuk mengubah datanya.']);
}
$data = $this->prepareData();
if (!empty($_FILES['photo_file']['name'])) {
$photo = $this->uploadPhoto();
if (
!empty($employee->photo)
&&
file_exists(FCPATH . $employee->photo)
) {
unlink(FCPATH . $employee->photo);
}
$data['photo'] = $photo;
}
$this->db
->where('id',$id)
->update('k_employees',$data);
log_activity(
'employees',
'update',
'Update karyawan ID: '.$id.' Nama: '.($data['full_name'] ?? '-'),
'success'
);
return $this->json([
'status' => true,
'message' => 'Berhasil update data'
]);
} catch (Exception $e) {
return $this->json([
'status' => false,
'message' => $e->getMessage()
]);
}
}
// =========================================================
// DELETE
// =========================================================
public function delete($id = null)
{
try {
$employee = $this->db
->get_where('k_employees',['id'=>$id])
->row();
if (!$employee) {
return $this->json([
'status' => false,
'message' => 'Data tidak ditemukan'
]);
}
if (!empty($employee->salary_restricted) && !$this->canManageAllSalary()) {
return $this->json(['status'=>false,'message'=>'Karyawan dengan gaji terbatas hanya dapat dihapus oleh pengguna dengan permission Manage All Gaji.']);
}
if (
!empty($employee->photo)
&&
file_exists(FCPATH . $employee->photo)
) {
unlink(FCPATH . $employee->photo);
}
$this->db->delete('k_employees',[
'id'=>$id
]);
log_activity(
'employees',
'delete',
'Hapus karyawan ID: '.$id.' Nama: '.($employee->full_name ?? '-'),
'success'
);
return $this->json([
'status' => true,
'message' => 'Berhasil hapus data'
]);
} catch (Exception $e) {
return $this->json([
'status' => false,
'message' => $e->getMessage()
]);
}
}
// =========================================================
// GENERATE CODE
// =========================================================
private function generateEmployeeCode()
{
$last = $this->db
->order_by('id','DESC')
->get('k_employees')
->row();
$number = $last ? $last->id + 1 : 1;
return 'RJN-' . str_pad($number,5,'0',STR_PAD_LEFT);
}
// =========================================================
// UPLOAD PHOTO
// =========================================================
private function uploadPhoto()
{
if (empty($_FILES['photo_file']['name'])) {
return null;
}
$path = FCPATH . 'uploads/karyawan/';
if (!is_dir($path)) {
mkdir($path,0777,true);
}
$config['upload_path'] = './uploads/karyawan/';
$config['allowed_types'] = 'jpg|jpeg|png|webp';
$config['max_size'] = 2048;
$config['encrypt_name'] = true;
$this->load->library('upload',$config);
if (!$this->upload->do_upload('photo_file')) {
throw new Exception(
strip_tags(
$this->upload->display_errors()
)
);
}
$upload = $this->upload->data();
return 'uploads/karyawan/' . $upload['file_name'];
}
// =========================================================
// PREPARE DATA
// =========================================================
private function prepareData()
{
$data = [
'nik' => trim($this->input->post('nik')),
'full_name' => trim(
$this->input->post('full_name')
),
'gender' => $this->input->post('gender'),
'birth_place' => trim(
$this->input->post('birth_place')
),
'birth_date' => $this->input->post('birth_date'),
'phone' => trim(
$this->input->post('phone')
),
'email' => trim(
$this->input->post('email')
),
'address' => trim(
$this->input->post('address')
),
'join_date' => $this->input->post('join_date'),
'resign_date' => $this->input->post('resign_date'),
'employment_status' => $this->input->post('employment_status'),
'marital_status' => $this->input->post('marital_status'),
'religion' => trim(
$this->input->post('religion')
),
'department_id' => $this->input->post('department_id'),
'position_id' => $this->input->post('position_id'),
'branch_id' => $this->input->post('branch_id'),
'bank_name' => trim(
$this->input->post('bank_name')
),
'bank_account_number' => trim(
$this->input->post('bank_account_number')
),
'bank_account_name' => trim(
$this->input->post('bank_account_name')
),
'bpjs_kesehatan_number' => trim(
$this->input->post('bpjs_kesehatan_number')
),
'bpjs_ketenagakerjaan_number' => trim(
$this->input->post('bpjs_ketenagakerjaan_number')
),
'fingerprint_user_id' => trim(
$this->input->post('fingerprint_user_id')
),
'is_active' => $this->input->post('is_active') === '0' ? 0 : 1
];
if ($this->db->field_exists('salary_restricted','k_employees') && $this->canManageAllSalary()) {
$data['salary_restricted'] = $this->input->post('salary_restricted') ? 1 : 0;
}
return $data;
}
private function canManageAllSalary()
{
return is_master_admin_user() || check_permission('payroll','can_manage_all_salary');
}
private function canEmployee($action)
{
return is_master_admin_user() || check_permission('hr_employees',$action) || check_permission('employees',$action);
}
private function maskRestrictedSalary($employee)
{
if (!$employee || empty($employee->salary_restricted) || $this->canManageAllSalary()) return;
$employee->basic_salary = null;
$employee->bank_name = null;
$employee->bank_account_number = null;
$employee->bank_account_name = null;
$employee->salary_hidden = true;
}
// =========================================================
// JSON
// =========================================================
private function json($data)
{
return $this->output
->set_content_type('application/json')
->set_output(json_encode($data));
}
}