form barang bawaan teknisi dan fix bug draft item

This commit is contained in:
2026-07-22 21:05:37 +07:00
parent 8a56e2f485
commit aa326838fc
5 changed files with 449 additions and 7 deletions
+94
View File
@@ -142,6 +142,9 @@ class Teknisi extends CI_Controller {
$aksi = '<button class="btn btn-info btn-sm btn-detail-teknisi" data-id="'.$row->id.'" title="Detail"> $aksi = '<button class="btn btn-info btn-sm btn-detail-teknisi" data-id="'.$row->id.'" title="Detail">
<i class="bi bi-eye"></i> <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>'; </button>';
$result[] = [ $result[] = [
@@ -221,6 +224,97 @@ class Teknisi extends CI_Controller {
]); ]);
} }
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;
}
$items = $this->ptm->get_teknisi_items_full($user_id);
$noFaktur = 'GRJN/K/' . date('d/m/Y');
$tanggal = date('d F Y');
$itemsData = [];
$no = 1;
foreach ($items as $item) {
$itemsData[] = [
'no' => $no++,
'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)
{
if ($this->session->userdata('role') != 'Admin') {
show_error('Akses ditolak', 403);
}
$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);
}
$items = $this->ptm->get_teknisi_items_full($user_id);
$noFaktur = 'GRJN/K/' . date('d/m/Y');
$tanggal = date('d F 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() public function get_transfer_data()
{ {
$data = $this->ptm->get_transfer_data(); $data = $this->ptm->get_transfer_data();
+206
View File
@@ -0,0 +1,206 @@
<?php
require_once(APPPATH . 'third_party/fpdf/fpdf.php');
class PDF_BarangBawaan extends FPDF
{
private $noFaktur;
private $tanggal;
private $teknisi;
private $colWidths = [10, 28, 48, 30, 12, 62];
public function __construct($orientation = 'L', $unit = 'mm', $size = 'A5')
{
parent::__construct($orientation, $unit, $size);
$this->SetDisplayMode('fullpage');
}
function SetMargins($left, $top, $right = null)
{
parent::SetMargins(10, $top, 10);
}
public function setFormInfo($noFaktur, $tanggal, $teknisi)
{
$this->noFaktur = $noFaktur;
$this->tanggal = $tanggal;
$this->teknisi = $teknisi;
}
function Header()
{
$this->SetFont('Arial', 'B', 11);
$this->SetTextColor(245, 140, 0);
$this->Cell(0, 6, 'FORM BARANG BAWAAN TEKNISI', 0, 1, 'L');
$this->SetTextColor(0, 0, 0);
$this->Ln(2);
$this->SetFont('Arial', '', 8);
$this->Cell(0, 5, 'Tanggal : ' . $this->tanggal . ' Teknisi : ' . $this->teknisi . ' No. Faktur : ' . $this->noFaktur, 0, 1, 'C');
$this->Ln(2);
$this->_drawTableHeader();
}
function Footer()
{
$this->SetY(-8);
$this->SetFont('Arial', 'I', 7);
$this->Cell(0, 4, 'Hal ' . $this->PageNo(), 0, 0, 'C');
}
private function _drawTableHeader()
{
$startX = $this->lMargin;
$this->SetX($startX);
$this->SetFillColor(245, 140, 0);
$this->SetTextColor(255, 255, 255);
$this->SetFont('Arial', 'B', 7);
$headers = ['No', 'Barcode', 'Nama Barang', 'Serial Number', 'Jumlah', 'Keterangan'];
foreach ($headers as $i => $h) {
$this->Cell($this->colWidths[$i], 7, $h, 1, 0, 'C', true);
}
$this->Ln();
$this->SetTextColor(0, 0, 0);
}
public function BarangBawaanTable($items)
{
$this->SetFont('Arial', '', 7);
$lineH = 5.5;
$minRowH = 8;
$no = 1;
$colsMultiCell = [false, false, true, true, false, true];
$cellAligns = ['C', 'C', 'L', 'L', 'C', 'L'];
foreach ($items as $item) {
$keterangan = isset($item->keterangan) ? $item->keterangan : '';
$namaBarang = $item->nama_barang ?? '-';
$serial = $item->serial_number ?? '-';
$barcode = $item->barcode ?? '-';
$jumlah = isset($item->qty_sisa) ? (int)$item->qty_sisa : 1;
$cellValues = [
(string)$no,
$barcode,
$namaBarang,
$serial,
(string)$jumlah,
$keterangan
];
$maxLines = 1;
foreach ($cellValues as $i => $val) {
if ($colsMultiCell[$i]) {
$lines = $this->NbLines($this->colWidths[$i], $val);
if ($lines > $maxLines) {
$maxLines = $lines;
}
}
}
$rowH = max($minRowH, $maxLines * $lineH);
if ($this->GetY() + $rowH > $this->PageBreakTrigger) {
$this->AddPage();
}
$startX = $this->lMargin;
$startY = $this->GetY();
$currentX = $startX;
foreach ($this->colWidths as $i => $w) {
$this->Rect($currentX, $startY, $w, $rowH);
$currentX += $w;
}
$currentX = $startX;
foreach ($cellValues as $i => $val) {
$this->SetXY($currentX, $startY);
if ($colsMultiCell[$i]) {
$contentH = $maxLines * $lineH;
$offsetY = ($rowH - $contentH) / 2;
$this->SetXY($currentX, $startY + $offsetY);
$this->MultiCell($this->colWidths[$i], $lineH, $val, 0, $cellAligns[$i]);
} else {
$this->Cell($this->colWidths[$i], $rowH, $val, 0, 0, $cellAligns[$i]);
}
$currentX += $this->colWidths[$i];
}
$this->SetXY($startX, $startY + $rowH);
$no++;
}
}
public function SignatureArea()
{
$this->Ln(6);
$sigW = 56;
$gapW = 11;
$blockW = 3 * $sigW + 2 * $gapW;
$startX = $this->lMargin + ($this->w - $this->lMargin - $this->rMargin - $blockW) / 2;
$signatures = [
['title' => 'Admin Gudang', 'name' => 'Gono Soewisto'],
['title' => 'Leader Teknisi', 'name' => 'Chandra Nursani'],
['title' => 'Mengetahui', 'name' => 'Tito Ngudiana'],
];
$sigY = $this->GetY();
foreach ($signatures as $i => $sig) {
$x = $startX + $i * ($sigW + $gapW);
$this->SetXY($x, $sigY);
$this->SetFont('Arial', '', 8);
$this->Cell($sigW, 5, $sig['title'], 0, 1, 'C');
$this->SetX($x);
$this->Ln(10);
$this->SetX($x);
$this->SetFont('Arial', 'U', 8);
$this->Cell($sigW, 5, ' ', 0, 1, 'C');
$this->SetX($x);
$this->SetFont('Arial', 'I', 7);
$this->Cell($sigW, 4, $sig['name'], 0, 1, 'C');
}
$this->SetY($sigY + 5 + 10 + 5 + 4);
}
private function NbLines($w, $txt)
{
$cw = &$this->CurrentFont['cw'];
if ($w == 0) {
$w = $this->w - $this->rMargin - $this->x;
}
$wmax = ($w - 2 * $this->cMargin) * 1000 / $this->FontSize;
$s = str_replace("\r", '', $txt);
$nb = strlen($s);
if ($nb > 0 && $s[$nb - 1] == "\n") { $nb--; }
$sep = -1;
$i = 0;
$j = 0;
$l = 0;
$nl = 1;
while ($i < $nb) {
$c = $s[$i];
if ($c == "\n") { $i++; $sep = -1; $j = $i; $l = 0; $nl++; continue; }
if ($c == ' ') { $sep = $i; }
$l += isset($cw[ord($c)]) ? $cw[ord($c)] : 600;
if ($l > $wmax) {
if ($sep == -1) { if ($i == $j) $i++; }
else { $i = $sep + 1; }
$sep = -1; $j = $i; $l = 0; $nl++;
} else { $i++; }
}
return $nl;
}
}
@@ -483,4 +483,29 @@ class PeralatanTeknisi_model extends CI_Model {
->get() ->get()
->row(); ->row();
} }
public function get_teknisi_items_full($user_id)
{
return $this->db
->select("
it.barcode,
i.nama_barang,
ib.serial_number,
ib.qty_sisa,
it.status
")
->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')
->order_by('it.created_at', 'ASC')
->get()
->result();
}
public function generate_no_faktur()
{
return 'GRJN/K/' . date('d/m/Y');
}
} }
+4 -4
View File
@@ -811,10 +811,10 @@ function rupiahToNumber(value){
if(!value) return 0; if(!value) return 0;
return parseInt( let s = value.toString().trim();
value.toString() s = s.replace(/\.(?=\d{3}(\.|$))/g, '');
.replace(/[^\d]/g,'') s = s.replace(/,/g, '');
) || 0; return parseFloat(s) || 0;
} }
+120 -3
View File
@@ -416,7 +416,7 @@ body {
<th>Kode Karyawan</th> <th>Kode Karyawan</th>
<th>Departemen</th> <th>Departemen</th>
<th style="width:100px">Jumlah Item</th> <th style="width:100px">Jumlah Item</th>
<th style="width:80px">Aksi</th> <th style="width:140px">Aksi</th>
</tr> </tr>
</thead> </thead>
</table> </table>
@@ -494,7 +494,67 @@ body {
</div> </div>
</div> </div>
<!-- ============================================================ -->
<!-- MODAL FORM BARANG BAWAAN TEKNISI -->
<!-- ============================================================ -->
<div class="modal fade tech-modal" id="modalFormBarangBawaan" tabindex="-1" data-bs-backdrop="static">
<div class="modal-dialog modal-xl modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><i class="bi bi-file-earmark-text me-2"></i> Form Barang Bawaan Teknisi</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<!-- Header Info -->
<div class="row g-2 mb-3" id="formBarangInfo">
<div class="col-md-12">
<div class="teknisi-badge">
<div class="row">
<div class="col-md-4">
<small class="text-muted">No. Faktur</small><br>
<strong id="fbNoFaktur">-</strong>
</div>
<div class="col-md-4">
<small class="text-muted">Tanggal</small><br>
<strong id="fbTanggal">-</strong>
</div>
<div class="col-md-4">
<small class="text-muted">Teknisi</small><br>
<strong id="fbTeknisi">-</strong>
</div>
</div>
</div>
</div>
</div>
<!-- Data table -->
<h6 class="fw-bold mb-2"><i class="bi bi-box me-1"></i> Barang Bawaan</h6>
<div class="table-responsive">
<table id="tableFormBarang" class="table table-tech table-hover table-striped align-middle w-100">
<thead>
<tr>
<th style="width:50px">No</th>
<th>Barcode</th>
<th>Nama Barang</th>
<th>Serial Number</th>
<th style="width:20px">Jumlah</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" id="btnCetakPDF">
<i class="bi bi-file-pdf me-1"></i> PDF
</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Tutup</button>
</div>
</div>
</div>
</div>
<script> <script>
let kembalikanData = []; let kembalikanData = [];
@@ -688,6 +748,63 @@ $(function(){
$('#modalDetailTeknisi').modal('show'); $('#modalDetailTeknisi').modal('show');
} }
// =============================================================
// FORM BARANG BAWAAN TEKNISI
// =============================================================
let dtFormBarang;
let _formBarangUserId = null;
$(document).on('click', '.btn-form-barang-bawaan', function(){
let userId = $(this).data('id');
let nama = $(this).data('nama');
_formBarangUserId = userId;
$('#fbNoFaktur').text('Memuat...');
$('#fbTanggal').text('-');
$('#fbTeknisi').text(nama);
$.get("<?= base_url('teknisi/get_form_barang_bawaan_data'); ?>", {user_id: userId}, function(r){
if (!r.status) {
Swal.fire({icon:'error', text:r.message});
return;
}
let d = r.data;
$('#fbNoFaktur').text(d.no_faktur);
$('#fbTanggal').text(d.tanggal);
$('#fbTeknisi').text(d.teknisi);
if (dtFormBarang) {
dtFormBarang.destroy();
}
dtFormBarang = $('#tableFormBarang').DataTable({
data: d.items,
columns: [
{ data: 'no' },
{ data: 'barcode' },
{ data: 'nama_barang' },
{ data: 'serial_number' },
{ data: 'jumlah', className: 'text-center' }
],
language: { url: "//cdn.datatables.net/plug-ins/1.13.6/i18n/id.json" },
pageLength: 10,
lengthMenu: [[10, 25, 50, -1], [10, 25, 50, 'All']],
order: []
});
}, 'json');
$('#modalFormBarangBawaan').modal('show');
});
$('#btnCetakPDF').click(function(){
if (_formBarangUserId) {
let url = "<?= base_url('teknisi/generate_pdf_barang_bawaan/'); ?>" + _formBarangUserId;
window.open(url, '_blank');
}
});
// ============================================================= // =============================================================
// SCAN: MODE KEMBALIKAN // SCAN: MODE KEMBALIKAN
// ============================================================= // =============================================================
@@ -992,7 +1109,7 @@ $(function(){
Swal.fire({ Swal.fire({
title: 'Konfirmasi Transfer', title: 'Konfirmasi Transfer',
text: barcodes.length + ' barang akan ditransfer', html: barcodes.length + ' barang akan ditransfer ke teknisi<br>' + ($('#teknisiTo option:selected').text() || ''),
icon: 'question', icon: 'question',
showCancelButton: true, showCancelButton: true,
confirmButtonColor: '#007bff', confirmButtonColor: '#007bff',
@@ -1066,7 +1183,7 @@ $(function(){
Swal.fire({ Swal.fire({
title: 'Konfirmasi Penugasan', title: 'Konfirmasi Penugasan',
text: dibawaData.length + ' barang akan ditugaskan ke teknisi terpilih', html: dibawaData.length + ' barang akan ditugaskan ke teknisi<br>' + ($('#teknisiDibawa option:selected').text() || ''),
icon: 'question', icon: 'question',
showCancelButton: true, showCancelButton: true,
confirmButtonColor: '#28a745', confirmButtonColor: '#28a745',