This commit is contained in:
Dwi Swandhana
2026-05-04 06:32:22 +07:00
parent fe89a024a1
commit 16eac8512e
11 changed files with 466 additions and 56 deletions
+254 -5
View File
@@ -25,6 +25,9 @@
<li class="nav-item">
<a href="#tab_masuk" data-toggle="tab" aria-expanded="false" class="nav-link">Stok Opname (Barang Masuk)</a>
</li>
<li class="nav-item">
<a href="#tab_hilang" data-toggle="tab" aria-expanded="false" class="nav-link">Stok Opname - Barang Hilang</a>
</li>
<li class="nav-item">
<a href="#tab_report" data-toggle="tab" aria-expanded="false" class="nav-link">Statistik / Report</a>
</li>
@@ -155,6 +158,88 @@
</div>
</div>
<div class="tab-pane" id="tab_hilang">
<div class="row">
<div class="col-lg-4">
<div class="card-box">
<h4 class="m-t-0">Stok Opname Barang Hilang</h4>
<div class="form-group">
<label>Tanggal Opname</label>
<input type="text" id="op_adj_tanggal" class="form-control" value="{{$tanggal}}">
</div>
<div class="form-group">
<label>Keterangan (opsional)</label>
<input type="text" id="op_adj_note" class="form-control" placeholder="contoh: pecah saat distribusi / tidak ditemukan saat audit">
</div>
<div class="form-group">
<label>Pilih Barang</label>
<select id="op_adj_pos" class="form-control">
<option value="" selected disabled>-- Pilih Barang --</option>
@foreach($jjenis as $rjenis)
@php($kode = ($rjenis['kodejenis'] ?? '') ?: preg_replace('/\s+/', '', (string) ($rjenis['jenis'] ?? '')))
<option value="{{ $rjenis['jenis'] }}"
data-kodejenis="{{ $kode }}"
data-jenisid="{{ $rjenis['id'] ?? '' }}"
data-satuan="{{ $rjenis['satuan'] }}"
data-satuan-kecil="{{ $rjenis['satuan_kecil'] ?? '' }}"
data-konversi="{{ $rjenis['konversi_kecil'] ?? 1 }}">{{ $kode }} - {{ $rjenis['jenis'] }} ( {{ $rjenis['satuan'] }} )</option>
@endforeach
</select>
</div>
<div class="form-group">
<label>Barcode (CODE128 - Angka)</label>
<input type="text" id="op_adj_barcode" class="form-control" placeholder="akan terisi otomatis" readonly>
</div>
<div class="form-group">
<label>Scan Barcode (CODE128)</label>
<input type="text" id="op_adj_scan" class="form-control" placeholder="scan lalu Enter">
<small class="text-muted">Scan akan otomatis memilih barang & set satuan (besar/kecil) sesuai barcode.</small>
</div>
<div class="form-group">
<label>Satuan Input</label>
<select id="op_adj_satuan_transaksi" class="form-control">
<option value="besar">Satuan Besar</option>
<option value="kecil">Satuan Kecil (Pecah Satuan)</option>
</select>
</div>
<div class="form-group">
<label>Jumlah</label>
<input type="text" id="op_adj_total" class="form-control">
</div>
<div class="form-group">
<button type="button" class="btn btn-danger btn-block" id="btn_op_adj_addline">Tambah ke Daftar Pengurangan</button>
</div>
</div>
</div>
<div class="col-lg-8">
<div class="card-box">
<h4 class="m-t-0">Daftar Barang Hilang</h4>
<div class="table-responsive">
<table class="table table-bordered table-striped m-b-0">
<thead>
<tr>
<th style="width: 110px">Kode</th>
<th>Barang</th>
<th>Keterangan</th>
<th style="width: 120px">Qty</th>
<th style="width: 120px">Satuan</th>
<th style="width: 90px">Aksi</th>
</tr>
</thead>
<tbody id="op_adj_lines">
<tr><td colspan="6" class="text-center text-muted">Belum ada item.</td></tr>
</tbody>
</table>
</div>
<small class="text-muted d-block m-t-10">Catatan: item di daftar ini akan mengurangi stok sebagai hasil opname barang hilang.</small>
<div class="text-right m-t-15">
<button type="button" class="btn btn-danger" id="btn_op_adj_commit">Simpan Semua Pengurangan Stok</button>
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane" id="tab_report">
<div class="row">
<div class="col-md-12">
@@ -675,11 +760,12 @@
$(function () {
$("#in_tanggal").datepicker({format: 'yyyy-mm-dd'});
$("#out_tanggal").datepicker({format: 'yyyy-mm-dd'});
$("#edit_tanggal").datepicker({format: 'yyyy-mm-dd'});
$("#op_in_tanggal").datepicker({format: 'yyyy-mm-dd'});
$("#in_masa_expired").datepicker({format: 'dd-mm-yyyy'});
$("#op_in_masa_expired").datepicker({format: 'dd-mm-yyyy'});
$("#edit_masa_expired").datepicker({format: 'dd-mm-yyyy'});
$("#edit_tanggal").datepicker({format: 'yyyy-mm-dd'});
$("#op_in_tanggal").datepicker({format: 'yyyy-mm-dd'});
$("#op_adj_tanggal").datepicker({format: 'yyyy-mm-dd'});
$("#in_masa_expired").datepicker({format: 'dd-mm-yyyy'});
$("#op_in_masa_expired").datepicker({format: 'dd-mm-yyyy'});
$("#edit_masa_expired").datepicker({format: 'dd-mm-yyyy'});
});
function openedpage( jQuery ){
var set01=document.getElementById('cekbln').value;
@@ -797,6 +883,7 @@
var jenisRows = @json($jenisRows ?? []);
var opInLines = [];
var opAdjLines = [];
var currentDetail = null;
function escapeHtml(value){
@@ -1032,6 +1119,15 @@
}
syncOpInSelected();
var currentAdj = $('#op_adj_pos').val();
var htmlAdj = '<option value=\"\" selected disabled>-- Pilih Barang --</option>';
items.forEach(function(r){ htmlAdj += makeOption(r); });
$('#op_adj_pos').html(htmlAdj);
if(currentAdj){
$('#op_adj_pos').val(currentAdj);
}
syncOpAdjSelected();
// Legacy selects (modal lama / editor)
var legacyIds = ['#in_pos', '#out_pos'];
legacyIds.forEach(function(sel){
@@ -1226,9 +1322,11 @@
$('#in_pos').on('change', function(){ syncSatuanMode('#in_pos', '#in_satuan_transaksi'); });
$('#out_pos').on('change', function(){ syncSatuanMode('#out_pos', '#out_satuan_transaksi'); });
$('#op_in_pos').on('change', function(){ syncSatuanMode('#op_in_pos', '#op_in_satuan_transaksi'); });
$('#op_adj_pos').on('change', function(){ syncSatuanMode('#op_adj_pos', '#op_adj_satuan_transaksi'); });
syncSatuanMode('#in_pos', '#in_satuan_transaksi');
syncSatuanMode('#out_pos', '#out_satuan_transaksi');
syncSatuanMode('#op_in_pos', '#op_in_satuan_transaksi');
syncSatuanMode('#op_adj_pos', '#op_adj_satuan_transaksi');
function syncOpInSelected(){
var val = $('#op_in_pos').val();
@@ -1260,6 +1358,19 @@
});
syncOpInSelected();
function syncOpAdjSelected(){
var selected = $('#op_adj_pos option:selected');
syncSatuanMode('#op_adj_pos', '#op_adj_satuan_transaksi');
var jenisId = parseInt(selected.data('jenisid') || 0, 10);
var mode = $('#op_adj_satuan_transaksi').val() || 'besar';
$('#op_adj_barcode').val(buildBarcodeValueById(jenisId, mode));
}
$('#op_adj_pos').on('change', function(){
syncOpAdjSelected();
});
syncOpAdjSelected();
$('#op_in_kode_barang').on('input', function(){
if($('#op_in_pos').val() !== '__NEW__'){ return; }
$(this).val(normalizeKode($(this).val()));
@@ -1287,6 +1398,13 @@
$('#op_in_barcode').val(buildBarcodeValueById(jenisId, mode));
});
$('#op_adj_satuan_transaksi').on('change', function(){
var selected = $('#op_adj_pos option:selected');
var jenisId = parseInt(selected.data('jenisid') || 0, 10);
var mode = $('#op_adj_satuan_transaksi').val() || 'besar';
$('#op_adj_barcode').val(buildBarcodeValueById(jenisId, mode));
});
$("#topbtntambahjenis").click(function(){
$("#jenis_idne").val('new');
$("#jenis_deskripsi").val('');
@@ -1594,6 +1712,7 @@
$("#in_total").autoNumeric( 'init', {aSep: ',', mDec: '0', vMax: '99999999999999999999999999'} );
$("#out_total").autoNumeric( 'init', {aSep: ',', mDec: '0', vMax: '99999999999999999999999999'} );
$("#op_in_total").autoNumeric( 'init', {aSep: ',', mDec: '0', vMax: '99999999999999999999999999'} );
$("#op_adj_total").autoNumeric( 'init', {aSep: ',', mDec: '0', vMax: '99999999999999999999999999'} );
function renderOpInLines(){
if(!opInLines.length){
@@ -1614,6 +1733,25 @@
$('#op_in_lines').html(html);
}
function renderOpAdjLines(){
if(!opAdjLines.length){
$('#op_adj_lines').html('<tr><td colspan="6" class="text-center text-muted">Belum ada item.</td></tr>');
return;
}
var html = '';
opAdjLines.forEach(function(line, idx){
html += '<tr>' +
'<td class="text-center"><code>' + (line.barcode_value || line.kode || '') + '</code></td>' +
'<td>' + escapeHtml(line.jenis || '') + '</td>' +
'<td>' + escapeHtml(line.note || '-') + '</td>' +
'<td class="text-right">' + escapeHtml(line.qty || '') + '</td>' +
'<td class="text-center">' + escapeHtml(line.satuan_transaksi || '') + '</td>' +
'<td class="text-center"><button type="button" class="btn btn-sm btn-danger btn_op_adj_remove" data-index="' + idx + '">Hapus</button></td>' +
'</tr>';
});
$('#op_adj_lines').html(html);
}
function getSelectedKode(selectId){
var selected = $(selectId).find('option:selected');
return normalizeKode(selected.data('kodejenis') || '');
@@ -1637,6 +1775,24 @@
}
});
$('#op_adj_scan').on('keypress', function(e){
if(e.which === 13){
e.preventDefault();
var scanVal = $(this).val();
var ok = setSelectByKode('#op_adj_pos', scanVal);
$(this).val('');
if(ok){
if(ok.mode){
$('#op_adj_satuan_transaksi').val(ok.mode);
}
syncOpAdjSelected();
setTimeout(function(){ $('#op_adj_total').focus(); }, 100);
}else{
$.toast({ heading: 'Gagal', text: 'Kode barang tidak ditemukan', position: 'top-right', loaderBg: '#bf441d', icon: 'error', hideAfter: 3000, stack: 1 });
}
}
});
$('#btn_op_in_addline').on('click', function(){
var jenisSelect = $('#op_in_pos').val();
var jenis = jenisSelect;
@@ -1716,6 +1872,38 @@
if(!isNaN(idx)){ opInLines.splice(idx, 1); renderOpInLines(); }
});
$('#btn_op_adj_addline').on('click', function(){
var jenis = $('#op_adj_pos').val();
var qty = $('#op_adj_total').val();
var satuanTransaksi = $('#op_adj_satuan_transaksi').val();
var note = ($('#op_adj_note').val() || '').toString().trim();
var kode = getSelectedKode('#op_adj_pos');
var selected = $('#op_adj_pos option:selected');
var jenisId = parseInt(selected.data('jenisid') || 0, 10);
var barcodeValue = buildBarcodeValueById(jenisId, satuanTransaksi);
if(!jenis || !qty){
$.toast({ heading: 'Gagal', text: 'Barang dan jumlah wajib diisi', position: 'top-right', loaderBg: '#bf441d', icon: 'error', hideAfter: 3000, stack: 1 });
return;
}
opAdjLines.push({
jenis: jenis,
kode: kode,
barcode_value: barcodeValue,
qty: qty,
satuan_transaksi: satuanTransaksi,
note: note
});
$('#op_adj_total').val('');
renderOpAdjLines();
});
$(document).on('click', '.btn_op_adj_remove', function(){
var idx = parseInt($(this).data('index'), 10);
if(!isNaN(idx)){ opAdjLines.splice(idx, 1); renderOpAdjLines(); }
});
function runBatchPost(lines, buildPayload, onDone){
var i = 0;
function next(){
@@ -1835,7 +2023,68 @@
next();
});
$('#btn_op_adj_commit').on('click', function(){
if(!opAdjLines.length){
$.toast({ heading: 'Info', text: 'Daftar pengurangan stok masih kosong', position: 'top-right', loaderBg: '#3b98b5', icon: 'info', hideAfter: 2500, stack: 1 });
return;
}
var tanggal = $('#op_adj_tanggal').val();
var $btn = $(this);
$btn.prop('disabled', true).text('Menyimpan...');
var i = 0;
function nextAdj(){
if(i >= opAdjLines.length){
$btn.prop('disabled', false).text('Simpan Semua Pengurangan Stok');
$.toast({ heading: 'Success', text: 'Pengurangan stok opname berhasil disimpan', position: 'top-right', loaderBg: '#5ba035', icon: 'success', hideAfter: 2500, stack: 1 });
opAdjLines = [];
renderOpAdjLines();
if(typeof window.gudangRefresh === 'function'){
window.gudangRefresh();
}
return;
}
var line = opAdjLines[i];
i++;
$.ajax({
url: 'simbhp/exaddbarang',
method: 'POST',
data: {
_token: token,
set01: 'hilang',
set02: line.jenis,
set03: tanggal,
set04: line.qty,
set05: 'opname_pengurangan',
set06: '',
set07: line.note,
set08: '',
set09: '',
set10: '',
set11: line.satuan_transaksi,
set12: ''
}
}).done(function(resp){
if(resp && resp.status && resp.status.toString().toLowerCase() !== 'success'){
$btn.prop('disabled', false).text('Simpan Semua Pengurangan Stok');
$.toast({ heading: 'Gagal', text: (resp && resp.message) ? resp.message : 'Gagal menyimpan', position: 'top-right', loaderBg: '#bf441d', icon: 'error', hideAfter: 4500, stack: 1 });
return;
}
nextAdj();
}).fail(function(){
$btn.prop('disabled', false).text('Simpan Semua Pengurangan Stok');
$.toast({ heading: 'Gagal', text: 'Request gagal', position: 'top-right', loaderBg: '#bf441d', icon: 'error', hideAfter: 4500, stack: 1 });
});
}
nextAdj();
});
renderOpInLines();
renderOpAdjLines();
$('#btnexportreport').click(function(){
var bln = $('#cekbln').val();
var thn = $('#cekthn').val();