Files
2026-07-27 08:32:05 +07:00

519 lines
18 KiB
PHP

<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Teknisi extends CI_Controller {
public function __construct()
{
parent::__construct();
$this->load->model('PeralatanTeknisi_model', 'ptm');
if (!$this->session->userdata('logged_in')) {
redirect('auth');
}
}
public function index()
{
$data = [
"active_menu" => "peralatan_teknisi",
"teknisi_list" => $this->ptm->get_teknisi_list()
];
$this->load->view('partials/header', $data);
$this->load->view('peralatan_teknisi/layout', $data);
$this->load->view('partials/footer');
}
public function get_data()
{
$user_id = $this->input->get('user_id');
$status = $this->input->get('status') ?: 'active';
log_message('debug', '[get_data] user_id: ' . var_export($user_id, true) . ', status: ' . $status);
$data = $this->ptm->get_barang_dibawa($user_id, $status);
log_message('debug', '[get_data] query returned ' . count($data) . ' rows');
$result = [];
$no = 1;
foreach ($data as $row) {
$result[] = [
$no++,
htmlspecialchars($row->barcode, ENT_QUOTES, 'UTF-8'),
htmlspecialchars($row->nama_barang, ENT_QUOTES, 'UTF-8'),
htmlspecialchars($row->serial_number, ENT_QUOTES, 'UTF-8'),
];
}
log_message('debug', '[get_data] response: ' . json_encode(['data' => $result]));
echo json_encode(['data' => $result]);
}
public function scan_item()
{
$barcode = trim($this->input->get('barcode'));
if (empty($barcode)) {
echo json_encode(['status' => false, 'message' => 'QR Code tidak boleh kosong']);
return;
}
$item = $this->ptm->get_item_by_barcode($barcode);
if (!$item) {
echo json_encode(['status' => false, 'message' => 'Barcode tidak ditemukan']);
return;
}
$teknisi = $this->ptm->get_current_teknisi($item->barcode);
echo json_encode([
'status' => true,
'message' => 'Barang ditemukan',
'data' => [
'barcode' => $item->barcode,
'nama_barang' => $item->nama_barang,
'serial_number' => $item->serial_number,
'barcode_id' => $item->barcode_id,
'item_id' => $item->item_id,
'barcode_status' => $item->barcode_status,
'teknisi_id' => $teknisi ? $teknisi->user_id : null,
'teknisi_name' => $teknisi ? $teknisi->full_name : null,
'teknisi_code' => $teknisi ? $teknisi->employee_code : null
]
]);
}
function get_date_by_employee_id()
{
$user_id = (int)$this->input->get('user_id');
if (!$user_id) {
echo json_encode(['status' => false, 'message' => 'ID teknisi tidak valid']);
return;
}
$dates = $this->ptm->get_dates_by_employee_id($user_id);
echo json_encode(['status' => true, 'data' => $dates]);
}
public function batch_kembalikan()
{
$barcodes = $this->input->post('barcodes');
if (empty($barcodes) || !is_array($barcodes)) {
echo json_encode(['status' => false, 'message' => 'Tidak ada barcode yang dipilih']);
return;
}
$result = $this->ptm->batch_kembalikan($barcodes);
echo json_encode($result);
}
public function batch_dibawa()
{
$barcodes = $this->input->post('barcodes');
$user_id = (int)$this->input->post('user_id');
if (empty($barcodes) || !is_array($barcodes)) {
echo json_encode(['status' => false, 'message' => 'Tidak ada barcode yang dipilih']);
return;
}
if (empty($user_id)) {
echo json_encode(['status' => false, 'message' => 'Pilih teknisi terlebih dahulu']);
return;
}
$result = $this->ptm->batch_dibawa($barcodes, $user_id);
echo json_encode($result);
}
public function get_teknisi_table()
{
$draw = (int)$this->input->get('draw');
$start = (int)$this->input->get('start');
$length = (int)$this->input->get('length');
$search = $this->input->get('search')['value'] ?? '';
$order_col = (int)$this->input->get('order')[0]['column'] ?? 1;
$order_dir = $this->input->get('order')[0]['dir'] ?? 'asc';
$data = $this->ptm->get_teknisi_table_data($start, $length, $search, $order_col, $order_dir);
$total_filtered = $this->ptm->count_filtered_teknisi($search);
$total_all = $this->ptm->count_all_teknisi();
$result = [];
$no = $start + 1;
foreach ($data as $row) {
$item_count = (int)$row->item_count;
$item_text = $item_count . ' Item';
$aksi = '<button class="btn btn-info btn-sm btn-detail-teknisi" data-id="'.$row->id.'" title="Detail">
<i class="bi bi-eye"></i>
</button>
<button class="btn btn-warning btn-sm btn-form-barang-bawaan" data-id="'.$row->id.'" data-nama="'.htmlspecialchars($row->full_name, ENT_QUOTES, 'UTF-8').'" title="Form Barang Bawaan">
<i class="bi bi-file-earmark-text"></i>
</button>';
$result[] = [
$no++,
htmlspecialchars($row->full_name, ENT_QUOTES, 'UTF-8'),
htmlspecialchars($row->employee_code, ENT_QUOTES, 'UTF-8'),
htmlspecialchars($row->department_name, ENT_QUOTES, 'UTF-8') ?: '-',
$item_text,
$aksi
];
}
echo json_encode([
'draw' => $draw,
'recordsTotal' => $total_all,
'recordsFiltered' => $total_filtered,
'data' => $result
]);
}
public function teknisi_detail()
{
$user_id = (int)$this->input->get('user_id');
if (!$user_id) {
echo json_encode(null);
return;
}
$info = $this->ptm->get_teknisi_info($user_id);
echo json_encode($info);
}
public function get_teknisi_items()
{
$user_id = (int)$this->input->get('user_id');
$draw = (int)$this->input->get('draw');
$start = (int)$this->input->get('start');
$length = (int)$this->input->get('length');
$search = $this->input->get('search')['value'] ?? '';
$order_col = (int)$this->input->get('order')[0]['column'] ?? 2;
$order_dir = $this->input->get('order')[0]['dir'] ?? 'asc';
if (!$user_id) {
echo json_encode(['draw' => $draw, 'recordsTotal' => 0, 'recordsFiltered' => 0, 'data' => []]);
return;
}
$data = $this->ptm->get_teknisi_items_data($user_id, $start, $length, $search, $order_col, $order_dir);
$total_filtered = $this->ptm->count_filtered_teknisi_items($user_id, $search);
$total_all = $this->ptm->count_all_teknisi_items($user_id);
$result = [];
$no = $start + 1;
foreach ($data as $row) {
$badge = $row->status == 'active'
? '<span class="badge bg-success">Dibawa</span>'
: '<span class="badge bg-secondary">' . htmlspecialchars($row->status, ENT_QUOTES, 'UTF-8') . '</span>';
$result[] = [
$no++,
$row->tanggal ?? date('d/m/Y'),
htmlspecialchars($row->barcode, ENT_QUOTES, 'UTF-8'),
htmlspecialchars($row->nama_barang, ENT_QUOTES, 'UTF-8'),
htmlspecialchars($row->serial_number, ENT_QUOTES, 'UTF-8') ?: '-',
htmlspecialchars($row->qty_sisa, ENT_QUOTES, 'UTF-8') ?: '0',
$badge
];
}
echo json_encode([
'draw' => $draw,
'recordsTotal' => $total_all,
'recordsFiltered' => $total_filtered,
'data' => $result
]);
}
public function get_form_barang_bawaan_data()
{
$user_id = (int)$this->input->get('user_id');
if (!$user_id) {
echo json_encode(['status' => false, 'message' => 'ID teknisi tidak valid']);
return;
}
$info = $this->ptm->get_teknisi_info($user_id);
if (!$info) {
echo json_encode(['status' => false, 'message' => 'Teknisi tidak ditemukan']);
return;
}
$tanggal_param = $this->input->get('tanggal');
$items = [];
if ($tanggal_param) {
$items = $this->ptm->get_teknisi_items_full($user_id, $tanggal_param);
}
if ($tanggal_param) {
if ($tanggal_param === 'all') {
$noFaktur = 'GRJN/K/ALL' . date('/m/Y');
$tanggal = date('d F Y');
} else {
$ts = strtotime($tanggal_param);
$noFaktur = 'GRJN/K/' . date('d/m/Y', $ts);
$tanggal = date('d F Y', $ts);
}
} else {
$noFaktur = 'GRJN/K/' . date('d/m/Y');
$tanggal = date('d F Y');
}
$itemsData = [];
$no = 1;
foreach ($items as $item) {
$itemsData[] = [
'no' => $no++,
'tanggal' => $item->tanggal ?? date('d/m/Y'),
'barcode' => $item->barcode ?? '-',
'nama_barang' => $item->nama_barang ?? '-',
'serial_number' => $item->serial_number ?? '-',
'jumlah' => isset($item->qty_sisa) ? (int)$item->qty_sisa : 1,
'keterangan' => ''
];
}
echo json_encode([
'status' => true,
'data' => [
'no_faktur' => $noFaktur,
'tanggal' => $tanggal,
'teknisi' => $info->full_name,
'teknisi_id' => $info->id,
'employee_code' => $info->employee_code,
'position_name' => $info->position_name,
'department_name' => $info->department_name,
'total_item' => count($itemsData),
'items' => $itemsData
]
]);
}
public function generate_pdf_barang_bawaan($user_id = null)
{
$user_id = (int)$user_id;
if (!$user_id) {
show_error('ID teknisi tidak valid', 400);
}
if (ob_get_length()) {
ob_end_clean();
}
$info = $this->ptm->get_teknisi_info($user_id);
if (!$info) {
show_error('Teknisi tidak ditemukan', 404);
}
$tanggal_param = $this->input->get('tanggal');
if ($tanggal_param === 'all') {
$items = $this->ptm->get_teknisi_items_full($user_id);
$noFaktur = 'GRJN/K/ALL' . date('/m/Y');
$tanggal = 'Semua Tanggal';
} elseif ($tanggal_param) {
$ts = strtotime($tanggal_param);
$items = $this->ptm->get_teknisi_items_full($user_id, $tanggal_param);
$noFaktur = 'GRJN/K/' . date('d/m/Y', $ts);
$tanggal = date('d/m/Y', $ts);
} else {
$items = $this->ptm->get_teknisi_items_full($user_id);
$noFaktur = 'GRJN/K/' . date('d/m/Y');
$tanggal = date('d/m/Y');
}
require_once(APPPATH . 'third_party/fpdf/fpdf.php');
require_once(APPPATH . 'libraries/PDF_BarangBawaan.php');
$pdf = new PDF_BarangBawaan('L', 'mm', 'A5');
$pdf->AliasNbPages();
$pdf->SetMargins(5, 5, 5);
$pdf->SetAutoPageBreak(true, 10);
$pdf->setFormInfo($noFaktur, $tanggal, $info->full_name);
$pdf->AddPage('L', 'A5');
$pdf->BarangBawaanTable($items);
$pdf->SignatureArea();
$namaFile = 'FORM_BARANG_BAWAAN_' . str_replace(' ', '_', $info->full_name) . '_' . date('Ymd') . '.pdf';
$pdf->Output('I', $namaFile);
exit;
}
public function get_transfer_data()
{
$data = $this->ptm->get_transfer_data();
$result = [];
$no = 1;
foreach ($data as $row) {
$result[] = [
$no++,
htmlspecialchars($row->barcode, ENT_QUOTES, 'UTF-8'),
htmlspecialchars($row->nama_barang, ENT_QUOTES, 'UTF-8'),
htmlspecialchars(($row->from_code ?? '') . ' - ' . ($row->from_name ?? ''), ENT_QUOTES, 'UTF-8'),
htmlspecialchars(($row->to_code ?? '') . ' - ' . ($row->to_name ?? ''), ENT_QUOTES, 'UTF-8'),
htmlspecialchars($row->created_at, ENT_QUOTES, 'UTF-8'),
'<span class="badge bg-success">Selesai</span>'
];
}
echo json_encode(['data' => $result]);
}
public function batch_transfer()
{
$barcodes = $this->input->post('barcodes');
$from_user_id = (int)$this->input->post('from_user_id');
$to_user_id = (int)$this->input->post('to_user_id');
$technician = $this->ptm->get_teknisi_info($to_user_id);
log_message('debug', 'batch_transfer POST: ' . json_encode([
'barcodes' => $barcodes,
'from_user_id' => $from_user_id,
'to_user_id' => $to_user_id
]));
if (empty($barcodes) || !is_array($barcodes)) {
echo json_encode(['status' => false, 'message' => 'Tidak ada barcode yang dipilih']);
return;
}
if (empty($from_user_id) || empty($to_user_id)) {
echo json_encode(['status' => false, 'message' => 'Pilih teknisi asal dan tujuan']);
return;
}
if ($from_user_id == $to_user_id) {
echo json_encode(['status' => false, 'message' => 'Teknisi tujuan tidak boleh sama dengan teknisi asal']);
return;
}
$now = date('Y-m-d H:i:s');
$errors = [];
$this->db->trans_start();
foreach ($barcodes as $barcode) {
$barcode = trim($barcode);
if ($barcode == '') continue;
$item = $this->db
->select('it.*, ib.id as barcode_id, tec.full_name as teknisi_name')
->from('item_technician it')
->join('item_barcodes ib', 'ib.barcode = it.barcode', 'left')
->join('k_employees tec', 'tec.id = it.user_id', 'left')
->where('it.barcode', $barcode)
->where('it.status', 'active')
->where('it.user_id', $from_user_id)
->get()
->row();
if (!$item) {
$errors[] = "Barcode $barcode tidak ditemukan pada teknisi asal";
continue;
}
log_message('debug', 'batch_transfer item: ' . json_encode($item));
$this->db
->where('barcode', $item->barcode)
->where('user_id', $from_user_id)
->where('status', 'active')
->update('item_technician', [
'user_id' => $to_user_id
]);
$this->db->insert('item_movements', [
'item_id' => $item->item_id,
'barcode_id' => $item->barcode_id,
'qty' => 1,
'from_type' => 'technician',
'from_id' => $from_user_id,
'to_type' => 'technician',
'to_id' => $to_user_id,
'movement_type' => 'transfer',
'notes' => 'Transfer Barang dari: ' . $item->teknisi_name . ' ke ' . $technician->full_name,
'created_at' => $now
]);
}
$this->db->trans_complete();
if ($this->db->trans_status() === FALSE) {
$db_error = $this->db->error();
log_message('error', 'batch_transfer gagal: ' . json_encode($db_error));
echo json_encode([
'status' => false,
'message' => 'Gagal memproses transfer',
'debug' => $db_error['message'] ?? 'Unknown database error'
]);
return;
}
$success_count = count($barcodes) - count($errors);
$msg = "$success_count barang berhasil ditransfer";
if (count($errors) > 0) {
$msg .= '. ' . implode(', ', $errors);
}
echo json_encode(['status' => true, 'message' => $msg, 'errors' => $errors]);
}
public function get_log_data()
{
$data = $this->ptm->get_log_barang();
$result = [];
$no = 1;
foreach ($data as $row) {
$status_badge = $row->status === 'active'
? '<span class="badge bg-success">ACTIVE</span>'
: '<span class="badge bg-secondary">INACTIVE</span>';
$result[] = [
$no++,
htmlspecialchars($row->teknisi_name ?? '-', ENT_QUOTES, 'UTF-8'),
htmlspecialchars($row->item_code ?? '-', ENT_QUOTES, 'UTF-8'),
htmlspecialchars($row->barcode, ENT_QUOTES, 'UTF-8'),
htmlspecialchars($row->nama_barang ?? '-', ENT_QUOTES, 'UTF-8'),
$row->created_at ? date('d/m/Y H:i', strtotime($row->created_at)) : '-',
$row->status === 'inactive' && $row->deleted_at ? date('d/m/Y H:i', strtotime($row->deleted_at)) : '-',
$status_badge,
];
}
echo json_encode(['data' => $result]);
}
public function log_barang()
{
$data = [
"active_menu" => "peralatan_teknisi",
];
$this->load->view('partials/header', $data);
$this->load->view('peralatan_teknisi/log_barang', $data);
$this->load->view('partials/footer');
}
}