From 8a56e2f4853e94c7a3be51569c4ad10f561320ae Mon Sep 17 00:00:00 2001 From: Sendi Pebriyan Date: Sat, 18 Jul 2026 11:44:27 +0700 Subject: [PATCH] Update history peralatan di bawah teknisi --- .codegraph/.gitignore | 5 + .gitignore | 2 + application/controllers/Teknisi.php | 345 +++++ application/libraries/PDF_Neracasaldo.php | 2 +- application/models/PeralatanTeknisi_model.php | 486 +++++++ application/views/laporan/neraca_saldo.php | 11 +- application/views/partials/header.php | 8 +- .../views/peralatan_teknisi/layout.php | 1145 +++++++++++++++++ 8 files changed, 1997 insertions(+), 7 deletions(-) create mode 100644 .codegraph/.gitignore create mode 100644 application/controllers/Teknisi.php create mode 100644 application/models/PeralatanTeknisi_model.php create mode 100644 application/views/peralatan_teknisi/layout.php diff --git a/.codegraph/.gitignore b/.codegraph/.gitignore new file mode 100644 index 0000000..d20c0fe --- /dev/null +++ b/.codegraph/.gitignore @@ -0,0 +1,5 @@ +# CodeGraph data files — local to each machine, not for committing. +# Ignore everything in .codegraph/ except this file itself, so transient +# files (the database, daemon.pid, sockets, logs) never show up in git. +* +!.gitignore diff --git a/.gitignore b/.gitignore index 6e22457..0cc1c95 100644 --- a/.gitignore +++ b/.gitignore @@ -35,5 +35,7 @@ user_guide_src/cilexer/pycilexer.egg-info/* *.sublime-project /tests/tests/ /tests/results/ +/dev-docs/ +/ai-rules/ diff --git a/application/controllers/Teknisi.php b/application/controllers/Teknisi.php new file mode 100644 index 0000000..221b5df --- /dev/null +++ b/application/controllers/Teknisi.php @@ -0,0 +1,345 @@ +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, + 'teknisi_id' => $teknisi ? $teknisi->user_id : null, + 'teknisi_name' => $teknisi ? $teknisi->full_name : null, + 'teknisi_code' => $teknisi ? $teknisi->employee_code : null + ] + ]); + } + + 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 = ''; + + $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' + ? 'Dibawa' + : '' . htmlspecialchars($row->status, ENT_QUOTES, 'UTF-8') . ''; + + $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') ?: '-', + 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_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'), + 'Selesai' + ]; + } + + 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]); + } +} diff --git a/application/libraries/PDF_Neracasaldo.php b/application/libraries/PDF_Neracasaldo.php index ca8c0be..19aa6ce 100644 --- a/application/libraries/PDF_Neracasaldo.php +++ b/application/libraries/PDF_Neracasaldo.php @@ -72,7 +72,7 @@ class PDF extends FPDF // Judul $this->SetFont('Arial', 'B', 13); $this->SetTextColor(245, 140, 0); - $this->Cell(0, 7, 'LAPORAN NERACA SALDO', 0, 1, 'C'); + $this->Cell(0, 7, 'LAPORAN KEUANGAN', 0, 1, 'C'); $this->SetTextColor(0, 0, 0); // Periode diff --git a/application/models/PeralatanTeknisi_model.php b/application/models/PeralatanTeknisi_model.php new file mode 100644 index 0000000..8db874d --- /dev/null +++ b/application/models/PeralatanTeknisi_model.php @@ -0,0 +1,486 @@ +db + ->select('e.id, e.employee_code, e.full_name, p.position_name, d.department_name') + ->from('k_employees e') + ->join('k_positions p', 'p.id = e.position_id', 'left') + ->join('k_departments d', 'd.id = e.department_id', 'left') + ->where('(e.resign_date IS NULL OR e.resign_date = \'0000-00-00\')') + ->where_in('LOWER(p.position_name)', ['teknisi', 'noc']) + ->order_by('e.full_name', 'ASC') + ->get() + ->result(); + } + + public function get_barang_dibawa($user_id = null, $status = 'active') + { + $this->db + ->select(" + it.barcode, + it.user_id, + it.item_id, + it.status, + it.created_at, + ib.serial_number, + i.nama_barang, + i.kode_detail, + ke.full_name as teknisi_name, + ke.employee_code + ") + ->from('item_technician it') + ->join('item_barcodes ib', 'ib.barcode = it.barcode', 'left') + ->join('items i', 'i.id = it.item_id', 'left') + ->join('k_employees ke', 'ke.id = it.user_id', 'left'); + + if ($user_id) { + $this->db->where('it.user_id', $user_id); + } + + if ($status && in_array($status, ['active', 'inactive'])) { + $this->db->where('it.status', $status); + } + + $this->db->order_by('it.created_at', 'DESC'); + + return $this->db->get()->result(); + } + + public function get_item_by_barcode($barcode) + { + $barcode = trim($barcode); + if ($barcode == '') return null; + + $row = $this->db + ->select('ib.id as barcode_id, ib.item_id, ib.barcode, ib.serial_number, ib.qty_sisa, ib.status as barcode_status, i.nama_barang, i.kode_detail') + ->from('item_barcodes ib') + ->join('items i', 'i.id = ib.item_id', 'left') + ->where('ib.barcode', $barcode) + ->get() + ->row(); + + if (!$row) { + $row = $this->db + ->select('ib.id as barcode_id, ib.item_id, ib.barcode, ib.serial_number, ib.qty_sisa, ib.status as barcode_status, i.nama_barang, i.kode_detail') + ->from('item_barcodes ib') + ->join('items i', 'i.id = ib.item_id', 'left') + ->where('ib.serial_number', $barcode) + ->get() + ->row(); + } + + return $row; + } + + public function get_current_teknisi($barcode) + { + return $this->db + ->select('it.user_id, ke.full_name, ke.employee_code') + ->from('item_technician it') + ->join('k_employees ke', 'ke.id = it.user_id', 'left') + ->where('it.barcode', $barcode) + ->where('it.status', 'active') + ->get() + ->row(); + } + + public function batch_kembalikan(array $barcodes) + { + $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') + ->get() + ->row(); + + if (!$item) { + $errors[] = "Barcode $barcode tidak ditemukan atau sudah dikembalikan"; + continue; + } + + $this->db->insert('item_movements', [ + 'item_id' => $item->item_id, + 'barcode_id' => $item->barcode_id, + 'qty' => 1, + 'from_type' => 'technician', + 'from_id' => $item->user_id, + 'to_type' => 'warehouse', + 'to_id' => null, + 'movement_type' => 'transfer', + 'notes' => 'Pengembalian dari: ' . $item->teknisi_name . ' ke gudang', + 'created_at' => $now + ]); + + $this->db + ->where('barcode', $barcode) + ->where('status', 'active') + ->update('item_technician', [ + 'status' => 'inactive', + 'deleted_at' => $now + ]); + + if ($item->barcode_id) { + $this->db + ->where('id', $item->barcode_id) + ->update('item_barcodes', [ + 'status' => 'available' + ]); + } + } + + $this->db->trans_complete(); + + if ($this->db->trans_status() === FALSE) { + return ['status' => false, 'message' => 'Gagal memproses pengembalian']; + } + + $success_count = count($barcodes) - count($errors); + $msg = "$success_count barang berhasil dikembalikan"; + if (count($errors) > 0) { + $msg .= '. ' . implode(', ', $errors); + } + + return ['status' => true, 'message' => $msg, 'errors' => $errors]; + } + + public function batch_dibawa(array $barcodes, $user_id) + { + $now = date('Y-m-d H:i:s'); + $errors = []; + $skipped = 0; + + $technician = $this->db + ->select('id, full_name, employee_code') + ->from('k_employees') + ->where('id', $user_id) + ->get() + ->row(); + + $this->db->trans_start(); + + foreach ($barcodes as $barcode) { + $barcode = trim($barcode); + if ($barcode == '') continue; + + $barcode_row = $this->db + ->select('ib.id as barcode_id, ib.item_id, ib.barcode') + ->from('item_barcodes ib') + ->where('ib.barcode', $barcode) + ->where_not_in('ib.status', ['damaged', 'lost', 'returned_supplier', 'sold_out']) + ->get() + ->row(); + + if (!$barcode_row) { + $errors[] = "Barcode $barcode tidak valid atau tidak tersedia"; + continue; + } + + $already = $this->db + ->where('barcode', $barcode_row->barcode) + ->where('status', 'active') + ->get('item_technician') + ->row(); + + if ($already) { + if ($already->user_id == $user_id) { + $skipped++; + continue; + } + $errors[] = "Barang $barcode sedang dibawa teknisi lain"; + continue; + } + + $this->db->insert('item_technician', [ + 'user_id' => $user_id, + 'barcode' => $barcode_row->barcode, + 'item_id' => $barcode_row->item_id, + 'status' => 'active', + 'created_at' => $now + ]); + + $last_movement = $this->db + ->where('barcode_id', $barcode_row->barcode_id) + ->order_by('id', 'DESC') + ->limit(1) + ->get('item_movements') + ->row(); + + $from_type = 'warehouse'; + $from_id = null; + if ($last_movement) { + $from_type = $last_movement->to_type; + $from_id = $last_movement->to_id; + } + + $this->db->insert('item_movements', [ + 'item_id' => $barcode_row->item_id, + 'barcode_id' => $barcode_row->barcode_id, + 'qty' => 1, + 'from_type' => $from_type, + 'from_id' => $from_id, + 'to_type' => 'technician', + 'to_id' => $user_id, + 'movement_type' => 'transfer', + 'notes' => 'Dibawa oleh: ' . $technician->full_name . ' dari gudang', + 'created_at' => $now + ]); + + $this->db + ->where('id', $barcode_row->barcode_id) + ->update('item_barcodes', [ + 'status' => 'installed' + ]); + } + + $this->db->trans_complete(); + + if ($this->db->trans_status() === FALSE) { + return ['status' => false, 'message' => 'Gagal memproses penugasan barang']; + } + + $success_count = count($barcodes) - count($errors) - $skipped; + $msg = "$success_count barang berhasil ditugaskan"; + if ($skipped > 0) { + $msg .= ". $skipped barang sudah ditugaskan ke teknisi yang sama"; + } + if (count($errors) > 0) { + $msg .= '. ' . implode(', ', $errors); + } + + return ['status' => true, 'message' => $msg, 'errors' => $errors]; + } + + public function get_teknisi_table_data($start, $length, $search, $order_col, $order_dir) + { + $sort_cols = [ + 1 => 'e.full_name', + 2 => 'e.employee_code', + 3 => 'd.department_name', + 4 => 'item_count' + ]; + + $this->db + ->select(" + e.id, + e.full_name, + e.employee_code, + p.position_name, + d.department_name, + (SELECT COUNT(*) FROM item_technician it WHERE it.user_id = e.id AND it.status = 'active') as item_count + ") + ->from('k_employees e') + ->join('k_positions p', 'p.id = e.position_id', 'left') + ->join('k_departments d', 'd.id = e.department_id', 'left') + ->where('(e.resign_date IS NULL OR e.resign_date = \'0000-00-00\')') + ->where_in('LOWER(p.position_name)', ['teknisi', 'noc']); + + if (!empty($search)) { + $this->db->group_start() + ->like('LOWER(e.full_name)', strtolower($search)) + ->or_like('LOWER(e.employee_code)', strtolower($search)) + ->or_like('LOWER(d.department_name)', strtolower($search)) + ->group_end(); + } + + if (isset($sort_cols[$order_col])) { + $this->db->order_by($sort_cols[$order_col], $order_dir); + } else { + $this->db->order_by('e.full_name', 'ASC'); + } + + if ($length > 0) { + $this->db->limit($length, $start); + } + + return $this->db->get()->result(); + } + + public function count_all_teknisi() + { + $this->db + ->from('k_employees e') + ->join('k_positions p', 'p.id = e.position_id', 'left') + ->where('(e.resign_date IS NULL OR e.resign_date = \'0000-00-00\')') + ->where_in('LOWER(p.position_name)', ['teknisi', 'noc']); + + return $this->db->count_all_results(); + } + + public function count_filtered_teknisi($search) + { + $this->db + ->from('k_employees e') + ->join('k_positions p', 'p.id = e.position_id', 'left') + ->join('k_departments d', 'd.id = e.department_id', 'left') + ->where('(e.resign_date IS NULL OR e.resign_date = \'0000-00-00\')') + ->where_in('LOWER(p.position_name)', ['teknisi', 'noc']); + + if (!empty($search)) { + $this->db->group_start() + ->like('LOWER(e.full_name)', strtolower($search)) + ->or_like('LOWER(e.employee_code)', strtolower($search)) + ->or_like('LOWER(d.department_name)', strtolower($search)) + ->group_end(); + } + + return $this->db->count_all_results(); + } + + public function get_teknisi_info($user_id) + { + return $this->db + ->select('e.id, e.full_name, e.employee_code, p.position_name, d.department_name') + ->from('k_employees e') + ->join('k_positions p', 'p.id = e.position_id', 'left') + ->join('k_departments d', 'd.id = e.department_id', 'left') + ->where('e.id', $user_id) + ->get() + ->row(); + } + + public function get_teknisi_items_data($user_id, $start, $length, $search, $order_col, $order_dir) + { + $sort_cols = [ + 1 => 'it.barcode', + 2 => 'i.nama_barang', + 3 => 'ib.serial_number', + 4 => 'it.status' + ]; + + $this->db + ->select(" + it.barcode, + i.nama_barang, + ib.serial_number, + ib.qty_sisa, + it.status, + it.created_at + ") + ->from('item_technician it') + ->join('items i', 'i.id = it.item_id', 'left') + ->join('item_barcodes ib', 'ib.barcode = it.barcode', 'left') + ->where('it.user_id', $user_id) + ->where('it.status', 'active'); + + if (!empty($search)) { + $this->db->group_start() + ->like('it.barcode', $search) + ->or_like('LOWER(i.nama_barang)', strtolower($search)) + ->or_like('ib.serial_number', $search) + ->group_end(); + } + + if (isset($sort_cols[$order_col])) { + $this->db->order_by($sort_cols[$order_col], $order_dir); + } else { + $this->db->order_by('it.created_at', 'DESC'); + } + + if ($length > 0) { + $this->db->limit($length, $start); + } + + return $this->db->get()->result(); + } + + public function count_all_teknisi_items($user_id) + { + $this->db + ->from('item_technician it') + ->where('it.user_id', $user_id) + ->where('it.status', 'active'); + + return $this->db->count_all_results(); + } + + public function count_filtered_teknisi_items($user_id, $search) + { + $this->db + ->from('item_technician it') + ->join('items i', 'i.id = it.item_id', 'left') + ->join('item_barcodes ib', 'ib.barcode = it.barcode', 'left') + ->where('it.user_id', $user_id) + ->where('it.status', 'active'); + + if (!empty($search)) { + $this->db->group_start() + ->like('it.barcode', $search) + ->or_like('LOWER(i.nama_barang)', strtolower($search)) + ->or_like('ib.serial_number', $search) + ->group_end(); + } + + return $this->db->count_all_results(); + } + + public function get_transfer_data() + { + return $this->db + ->select(" + it.barcode, + i.nama_barang, + ib.serial_number, + from_ke.full_name as from_name, + from_ke.employee_code as from_code, + to_ke.full_name as to_name, + to_ke.employee_code as to_code, + im.created_at, + im.movement_type + ") + ->from('item_movements im') + ->join('items i', 'i.id = im.item_id', 'left') + ->join('item_barcodes ib', 'ib.id = im.barcode_id', 'left') + ->join('k_employees from_ke', 'from_ke.id = im.from_id', 'left') + ->join('k_employees to_ke', 'to_ke.id = im.to_id', 'left') + ->where('im.movement_type', 'installation') + ->where('im.from_type', 'technician') + ->where('im.to_type', 'technician') + ->order_by('im.created_at', 'DESC') + ->limit(200) + ->get() + ->result(); + } + + public function detail_by_barcode($barcode) + { + return $this->db + ->select(" + it.*, + ib.serial_number, + ib.qty_sisa, + ib.status as barcode_status, + i.nama_barang, + i.kode_detail, + ke.full_name as teknisi_name, + ke.employee_code + ") + ->from('item_technician it') + ->join('item_barcodes ib', 'ib.barcode = it.barcode', 'left') + ->join('items i', 'i.id = it.item_id', 'left') + ->join('k_employees ke', 'ke.id = it.user_id', 'left') + ->where('it.barcode', $barcode) + ->get() + ->row(); + } +} diff --git a/application/views/laporan/neraca_saldo.php b/application/views/laporan/neraca_saldo.php index ed0e4ec..36ced2c 100644 --- a/application/views/laporan/neraca_saldo.php +++ b/application/views/laporan/neraca_saldo.php @@ -5,9 +5,7 @@

Laporan Keuangan

- +
@@ -24,10 +22,13 @@ value="">
-
- +
diff --git a/application/views/partials/header.php b/application/views/partials/header.php index 873326e..2abbdce 100644 --- a/application/views/partials/header.php +++ b/application/views/partials/header.php @@ -158,7 +158,7 @@ diff --git a/application/views/peralatan_teknisi/layout.php b/application/views/peralatan_teknisi/layout.php new file mode 100644 index 0000000..0326945 --- /dev/null +++ b/application/views/peralatan_teknisi/layout.php @@ -0,0 +1,1145 @@ + + + + + +
+ + +
+
+ +
+
+
Peralatan Teknisi
+ Kelola barang bawaan, pengembalian, dan transfer antar teknisi +
+
+ +
+ + + + +
+ +
+
+ + Barang Teknisi +
+
+ + +
+ + + + + + + + +
+ + + + + + + + + + + +
+
+
+ + + Scanner akan otomatis memanggil data. + + +
+
+ +
+ + + + + + + + + + + + +
NoBarcodeNama BarangSerial NumberTeknisiAksi
+
+ + +
+ + + + +
+
+ + +
+ +
+
+ + + Scanner akan otomatis memanggil data. + + +
+
+ +
+ + + + + + + + + + + +
NoBarcodeNama BarangSerial NumberAksi
+
+ + +
+ + + + +
+
+ + +
+ +
+ + + + + + + + + + + +
NoBarcodeNama BarangSerial Number +
+ Aksi +
+ +
+
+
+
+ +
+ + +
+ + +
+ + + +
+
+ +
+ + + + +
+ +
+
+ + Daftar Teknisi +
+
+ +
+ + + + + + + + + + + +
NoNama TeknisiKode KaryawanDepartemenJumlah ItemAksi
+
+ +
+
+ +
+ +
+
+ + + + + + + + +