Files
accounting_dev/application/views/items/layout.php
T
2026-06-30 11:16:31 +07:00

924 lines
23 KiB
PHP

<div class="container mt-4">
<div class="card modern-card shadow-sm border-0 rounded-4">
<div class="card-body p-4">
<div class="d-flex justify-content-between mb-3">
<h5>Data Barang</h5>
<div class="text-end">
<button class="btn btn-add bg-danger btn-out mr-2">Pengeluaran</button>
<!-- <button class="btn btn-warning btn-add btn-add-item mr-2">Tambah Barang</button> -->
</div>
</div>
<div class="table-responsive">
<table id="tableItems" class="table modern-table w-100">
<thead>
<tr>
<th>No</th>
<th>Tanggal Beli</th>
<th>Kode Barang</th>
<th>Nama</th>
<th style="max-width: 150px;">Gudang</th>
<th>Stok</th>
<th>Harga Beli</th>
<th>Harga Jual</th>
<th>Create at</th>
<th>Aksi</th>
</tr>
</thead>
</table>
</div>
</div>
</div>
</div>
<!-- MODAL -->
<div class="modal fade" id="modalItem">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header bg-warning text-white">
<h5>Item</h5>
</div>
<div class="modal-body">
<input type="hidden" id="id">
<div id="group_tanggal">
<label>Tanggal Pembelian</label>
<input type="date" id="tanggal_beli" class="form-control">
</div>
<div id="group_kode">
<label class="mt-2">Kode Barang</label>
<select id="kode_barang" class="form-control select-search"></select>
</div>
<label>Nama Barang</label>
<input type="text" id="nama_barang" class="form-control">
<div id="group_qty">
<label class="mt-2">Jumlah Barang</label>
<input type="number" id="qty" class="form-control">
</div>
<label class="mt-2">Harga Beli</label>
<input type="text" id="harga_beli" class="form-control format-rupiah">
<label class="mt-2">Harga Jual</label>
<input type="text" id="harga_jual" class="form-control format-rupiah">
<div id="group_warehouse">
<label class="mt-2">Gudang</label>
<select id="warehouse_id" class="form-control"></select>
</div>
<div id="group_account">
<label class="mt-2">Akun Kas</label>
<select id="account_kas" class="form-control"></select>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-warning" id="btnSimpan">Simpan</button>
</div>
</div>
</div>
</div>
<!-- MODAL BARANAG KELUAR -->
<div class="modal fade" id="modalKeluar">
<div class="modal-dialog modal-dialog-centered modal-lg">
<div class="modal-content">
<div class="modal-header bg-danger text-white">
<h5>Barang Keluar</h5>
</div>
<div class="modal-body">
<center>
<div id="scannerArea">
<input
type="text"
id="serial_number"
class="form-control form-control-lg text-center"
placeholder="Scan QR Barang"
autocomplete="off"
autofocus>
<small class="scan-note">
Scanner akan otomatis menyimpan.
</small><br>
<button
type="button"
class="btn btn-warning btn-block camera-btn mt-4"
id="btnCamera">
<i class="fa fa-camera mr-2"></i>
Scan dengan Kamera
</button>
</div>
<div id="cameraArea" style="display:none;">
<div id="reader"></div>
<small class="scan-note d-block mt-2">
Arahkan QR Code ke kamera.
</small>
<button
type="button"
class="btn btn-secondary btn-block mt-3"
id="btnCloseCamera">
Tutup Kamera
</button>
</div>
</center>
<div id="tableBarcode"></div>
<hr>
<div id="group_account_biaya">
<label class="mt-2">Akun Biaya</label>
<select id="account_biaya" class="form-control"></select>
</div>
<div>
<label>Tanggal</label>
<input type="date" id="tanggal_keluar" class="form-control">
</div>
<!-- <div>
<label class="mt-2">Gudang</label>
<select id="warehouse_id_keluar" class="form-control"></select>
</div>
<div class="d-none" id="group_barang_keluar">
<label class="mt-2">Barang</label>
<select id="barang_id" class="form-control select-search"></select>
</div>
<div class="d-none" id="group_qty_keluar">
<label class="mt-2">Jumlah Barang</label>
<input type="number" id="qty_keluar" class="form-control">
</div> -->
<div class="mb-2" id="group_keterangan">
<label for="keterangan" class="form-label">Keterangan</label>
<textarea class="form-control" id="keterangan_keluar" rows="3"></textarea>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-danger" id="btnKeluar">Keluarkan</button>
</div>
</div>
</div>
</div>
<!-- MODAL DETAIL -->
<div class="modal fade" id="modalDetail">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header bg-warning text-white">
<h5>Detail Item</h5>
</div>
<div class="modal-body" id="detailContent"></div>
</div>
</div>
</div>
<div class="modal fade" id="modalAdjust">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header bg-warning">
<h5>Penyesuaian Stok</h5>
</div>
<div class="modal-body">
<input type="hidden" id="adjust_item_id">
<label>Qty Adjustment</label>
<input type="number" id="adjust_qty" class="form-control">
<small>Gunakan minus (-) jika mengurangi</small>
<label class="mt-2">Gudang</label>
<select id="adjust_warehouse" class="form-control"></select>
<label class="mt-2">Keterangan</label>
<input type="text" id="adjust_ket" class="form-control">
</div>
<div class="modal-footer">
<button class="btn btn-warning" id="btnAdjust">Simpan</button>
</div>
</div>
</div>
</div>
<script>
// URUSAN BARCODE INPUT DAN CAMSCANNER
let daftarBarang = [];
let isSaving = false;
$(document).ready(function () {
$("#serial_number").focus();
$("#serial_number").keypress(function(e){
if(e.which==13){
e.preventDefault();
if(!isSaving){
getBarcodeId();
}
}
});
});
function getBarcodeId(){
let barcode = ($("#serial_number").val() || "").trim();
if(barcode==""){
return;
}
$.post(
"<?=base_url('items/get_barcode_item');?>",
{
barcode:barcode
},
function(r){
if(!r.status){
Swal.fire({
icon:"error",
title:"Oops...",
text:r.message
});
$("#serial_number").val("").focus();
return;
}
let exist = daftarBarang.find(function(v){
return v.barcode_id == r.data.barcode_id;
});
if(exist){
Swal.fire({
icon: "warning",
title: "Barcode sudah discan",
timer: 1000,
showConfirmButton: false
});
$("#serial_number").val("").focus();
return;
}
daftarBarang.push(r.data);
renderTable();
$("#serial_number").val("").focus();
},
"json"
);
}
function renderTable(){
let html='';
html+='<div class="table-responsive">';
html+='<table class="table table-bordered table-hover table-sm mb-0">';
html+='<thead>';
html+='<tr>';
html+='<th width="50">No</th>';
html+='<th width="180">Barcode</th>';
html+='<th width="150">Kode Barang</th>';
html+='<th>Nama Barang</th>';
html+='<th width="180">Serial Number</th>';
html+='<th width="80" class="text-center">Action</th>';
html+='</tr>';
html+='</thead>';
html+='<tbody>';
if(daftarBarang.length==0){
html+='<tr>';
html+='<td colspan="6" class="text-center text-muted py-4">';
html+='Belum ada barcode yang discan.';
html+='</td>';
html+='</tr>';
}else{
$.each(daftarBarang,function(i,v){
html+='<tr>';
html+='<td>'+(i+1)+'</td>';
html+='<td><strong>'+v.barcode+'</strong></td>';
html+='<td>'+v.kode_detail+'</td>';
html+='<td>'+v.nama_barang+'</td>';
html+='<td>'+(v.serial_number?v.serial_number:'-')+'</td>';
html+='<td class="text-center">';
html+='<button class="btn btn-sm btn-outline-danger btnRemove" data-id="'+v.barcode_id+'">';
html+='<i class="bi bi-trash"></i>';
html+='</button>';
html+='</td>';
html+='</tr>';
});
}
html+='</tbody>';
html+='</table>';
html+='</div>';
$("#tableBarcode").html(html);
}
$(document).on("click",".btnRemove",function(){
let id=$(this).data("id");
daftarBarang=daftarBarang.filter(function(v){
return v.barcode_id!=id;
});
renderTable();
$("#serial_number").focus();
});
let html5QrCode=null;
$("#btnCamera").click(function(){
$("#scannerArea").hide();
$("#cameraArea").show();
html5QrCode=new Html5Qrcode("reader");
html5QrCode.start(
{
facingMode:"environment"
},
{
fps:10,
qrbox:220
},
function(decodedText){
html5QrCode.stop().then(function(){
$("#cameraArea").hide();
$("#scannerArea").show();
$("#serial_number")
.val(decodedText);
saveSerial();
});
}
);
});
$("#btnCloseCamera").click(function(){
if(html5QrCode){
html5QrCode.stop().then(function(){
$("#cameraArea").hide();
$("#scannerArea").show();
$("#serial_number").focus();
});
}
});
// URUSAN BARCODE INPUT DAN CAMSCANNER
$(function(){
let action = 'add';
let selectedItemId = null;
// ================= DATATABLE =================
let table = $('#tableItems').DataTable({
ajax: {
url: "<?= base_url('items/get_data'); ?>",
data: function (d) {
d.s = `active`;
}
}
});
// ================= LOAD AKUN KAS =================
function loadKas(){
$.get("<?= base_url('items/get_accounts'); ?>",res=>{
let opt='<option value="">-- PILIH KAS --</option>';
res.forEach(a=>{
opt += `<option value="${a.id}">${a.nama_akun}</option>`;
});
$('#account_kas').html(opt);
},'json');
}
// ================= LOAD AKUN KAS =================
function loadKasOut(){
$.get("<?= base_url('items/get_accounts_biaya'); ?>",res=>{
let opt='<option value="">-- PILIH KAS --</option>';
res.forEach(a=>{
opt += `<option value="${a.id}">${a.nama_akun}</option>`;
});
$('#account_biaya').html(opt);
},'json');
}
// ================= LOAD GUDANG =================
function loadGudang(){
$.get("<?= base_url('warehouses/list'); ?>",res=>{
let opt='<option value="">-- PILIH GUDANG --</option>';
res.forEach(w=>{
opt += `<option value="${w.id}">${w.nama}</option>`;
});
$('#warehouse_id, #adjust_warehouse').html(opt);
},'json');
}
// ================= LOAD GUDANG =================
function loadGudangList(){
$.get("<?= base_url('warehouses/list'); ?>",res=>{
let opt='<option value="">-- PILIH GUDANG --</option>';
res.forEach(w=>{
opt += `<option value="${w.id}">${w.nama}</option>`;
});
$('#warehouse_id_keluar').html(opt);
},'json');
}
function loadKode(){
$.get("<?= base_url('kodebarang/list'); ?>",res=>{
let opt='<option value="">-- PILIH KODE --</option>';
res.forEach(a=>{
opt += `<option value="${a.id}">${a.kode_barang} - ${a.nama}</option>`;
});
$('#kode_barang').html(opt);
},'json');
}
// ================= RESET FORM =================
function resetForm(){
$('#id').val('');
$('#nama_barang').val('');
$('#qty').val('');
$('#harga_beli').val('');
$('#harga_jual').val('');
$('#tanggal_beli').val('');
}
// ================= INIT LOAD =================
loadGudang();
loadKas();
loadKode();
// // ================= ADD =================
// $('.btn-add-item').click(function(){
// action='add';
// resetForm();
// $('#qty').closest('div').show();
// $('#kode_barang').closest('div').show();
// $('#warehouse_id').closest('div').show();
// $('#account_kas').closest('div').show();
// $('#modalItem').modal('show');
// loadGudang();
// loadKas();
// loadKode();
// });
// ================= EDIT =================
$(document).on('click','.btn-editItem',function(){
let id = $(this).data('id');
action='edit';
$.get("<?= base_url('items/detail_simple/'); ?>"+id,function(res){
$('#id').val(res.id);
$('#nama_barang').val(res.nama_barang);
$('#harga_beli').val(res.harga_beli);
$('#harga_jual').val(res.harga_jual);
// 🔥 FIX DI SINI
$('#group_qty').hide();
$('#group_account').hide();
$('#group_kode').hide();
$('#group_warehouse').hide();
$('#group_tanggal').hide();
$('#modalItem').modal('show');
},'json');
});
// ================= SAVE =================
$('#btnSimpan').click(function(){
let btn = $(this);
let data = {
id: $('#id').val(),
kode_id: $('#kode_barang').val(),
nama_barang: $('#nama_barang').val(),
qty: $('#qty').val(),
harga_beli: $('#harga_beli').val(),
harga_jual: $('#harga_jual').val(),
warehouse_id: $('#warehouse_id').val(),
account_kas: $('#account_kas').val(),
tanggal_beli: $('#tanggal_beli').val(),
status: `active`
};
let url = action==='add'
? "<?= base_url('items/save'); ?>"
: "<?= base_url('items/update'); ?>";
// 🔥 loading state
btn.prop('disabled', true).html('Menyimpan...');
$.post(url, data, function(res){
if(res.status){
$('#modalItem').modal('hide');
table.ajax.reload(null,false);
Swal.fire({
icon: 'success',
title: 'Berhasil',
text: res.message || 'Data berhasil disimpan',
timer: 1500,
showConfirmButton: false
});
}else{
Swal.fire({
icon: 'error',
title: 'Gagal',
text: res.message || 'Terjadi kesalahan'
});
}
},'json')
.fail(function(){
Swal.fire({
icon: 'error',
title: 'Error',
text: 'Koneksi ke server gagal'
});
})
.always(function(){
btn.prop('disabled', false).html('Simpan');
});
});
// =====================================================
// ================= START URUSAN KELUAR ===============
// =====================================================
// ================= RESET FORM KELUAR =================
function resetFormKeluar(){
$('#tanggal_keluar').val('');
$('#qty_keluar').val('');
$('#keterangan_keluar').val('');
}
loadKasOut();
loadGudangList();
// ================= BARANG KELUAR ================= account_biaya warehouse_id barang_id
$('.btn-out').click(function(){
// action='add';
resetFormKeluar();
$('#warehouse_id').closest('div').show();
$('#account_biaya').closest('div').show();
$('#modalKeluar').modal('show');
loadGudangList();
loadKasOut();
});
$('#modalKeluar').on('shown.bs.modal', function () {
setTimeout(function () {
$('#serial_number').trigger('focus').select();
}, 100);
});
$('#warehouse_id_keluar').on('change', function(){
let warehouse_id = $(this).val();
// $('#wrap_item_select').addClass('d-none');
$('#barang_id').html('<option value="">Loading...</option>');
loadItems(warehouse_id);
});
// ================= ITEMS =================
function loadItems(warehouse_id){
return $.get("<?= base_url('items/get_items_by_wh_id/'); ?>" + warehouse_id, function(res){
if(res && res.length){
let opt = '<option value="">-- PILIH BARANG --</option>';
res.forEach(i=>{
opt += `<option value="${i.id}">
${i.kode_detail} - ${i.nama_barang} (Stok: ${i.stok})
</option>`;
});
$('#barang_id').html(opt);
$('#group_barang_keluar').removeClass('d-none');
$('#group_qty_keluar').removeClass('d-none');
$('#group_keterangan').removeClass('d-none');
} else {
$('#barang_id').html(opt);
}
}, 'json');
}
// ================= SAVE =================
$('#btnKeluar').click(function(){
let btn = $(this);
let data = {
account_biaya: $('#account_biaya').val(),
tanggal_keluar: $('#tanggal_keluar').val(),
warehouse_id_keluar: $('#warehouse_id_keluar').val(),
barang_id: $('#barang_id').val(),
qty_keluar: $('#qty_keluar').val(),
keterangan_keluar: $('#keterangan_keluar').val()
};
let url = "<?= base_url('items/keluarkan'); ?>";
// 🔥 loading state
btn.prop('disabled', true).html('Menyimpan...');
$.post(url, data, function(res){
if(res.status){
$('#modalItem').modal('hide');
table.ajax.reload(null,false);
Swal.fire({
icon: 'success',
title: 'Berhasil',
text: res.message || 'Data berhasil disimpan',
timer: 1500,
showConfirmButton: false
});
}else{
Swal.fire({
icon: 'error',
title: 'Gagal',
text: res.message || 'Terjadi kesalahan'
});
}
},'json')
.fail(function(){
Swal.fire({
icon: 'error',
title: 'Error',
text: 'Koneksi ke server gagal'
});
})
.always(function(){
btn.prop('disabled', false).html('Keluarkan');
});
});
// =====================================================
// ================= END URUSAN KELUAR ===============
// =====================================================
// ================= DELETE =================
$(document).on('click','.btn-delete',function(){
let id = $(this).data('id');
let btn = $(this);
Swal.fire({
title: 'Hapus data?',
text: "Data tidak bisa dikembalikan!",
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#d33',
cancelButtonColor: '#3085d6',
confirmButtonText: 'Ya, hapus!',
cancelButtonText: 'Batal'
}).then((result) => {
if(result.isConfirmed){
btn.prop('disabled', true).html('Menghapus...');
$.get("<?= base_url('items/delete/'); ?>"+id,function(res){
if(res.status){
table.ajax.reload(null,false);
Swal.fire({
icon: 'success',
title: 'Berhasil',
text: res.message || 'Data berhasil dihapus',
timer: 1500,
showConfirmButton: false
});
}else{
Swal.fire({
icon: 'error',
title: 'Gagal',
text: res.message || 'Gagal menghapus data'
});
}
},'json')
.fail(function(){
Swal.fire({
icon: 'error',
title: 'Error',
text: 'Koneksi ke server gagal'
});
})
.always(function(){
btn.prop('disabled', false).html('Hapus');
});
}
});
});
// ================= DETAIL =================
$(document).on('click','.btn-detail',function(){
let id = $(this).data('id');
$.get("<?= base_url('items/detail/'); ?>"+id,function(res){
let html = `
<b>Nama :</b> ${res.item.nama_barang}<br>
<b>Harga Beli :</b> ${formatRupiah(res.item.harga_beli)}<br>
<b>Harga Jual :</b> ${formatRupiah(res.item.harga_jual)}
<hr>
<h6>Riwayat Stok</h6>
<table class="table table-sm table-bordered">
<tr>
<th>Tanggal</th>
<th>Gudang</th>
<th>Qty</th>
<th>Tipe</th>
<th>Keterangan</th>
</tr>
`;
res.logs.forEach(l=>{
html += `
<tr>
<td>${l.created_at ?? '-'}</td>
<td>${l.gudang ?? '-'}</td>
<td>${l.qty}</td>
<td>${l.tipe}</td>
<td>${l.keterangan ?? ''}</td>
</tr>`;
});
html += `</table>`;
$('#detailContent').html(html);
$('#modalDetail').modal('show');
},'json');
});
// ================= OPEN ADJUST =================
$(document).on('click','.btn-adjust',function(){
let id = $(this).data('id');
if(!id){
alert('Pilih item dari tabel (gunakan tombol Adjust di baris)');
return;
}
selectedItemId = id;
$('#adjust_item_id').val(id);
$('#adjust_qty').val('');
$('#adjust_ket').val('');
$('#modalAdjust').modal('show');
});
// ================= SAVE ADJUST =================
$('#btnAdjust').click(function(){
let btn = $(this);
let data = {
item_id: $('#adjust_item_id').val(),
qty: $('#adjust_qty').val(),
warehouse_id: $('#adjust_warehouse').val(),
keterangan: $('#adjust_ket').val()
};
// 🔥 loading state
btn.prop('disabled', true).html('Menyimpan...');
$.post("<?= base_url('items/adjust'); ?>", data, function(res){
if(res.status){
$('#modalAdjust').modal('hide');
table.ajax.reload(null,false);
Swal.fire({
icon: 'success',
title: 'Berhasil',
text: res.message || 'Stok berhasil disesuaikan',
timer: 1500,
showConfirmButton: false
});
}else{
Swal.fire({
icon: 'error',
title: 'Gagal',
text: res.message || 'Gagal melakukan penyesuaian'
});
}
},'json')
.fail(function(){
Swal.fire({
icon: 'error',
title: 'Error',
text: 'Koneksi ke server gagal'
});
})
.always(function(){
btn.prop('disabled', false).html('Simpan');
});
});
});
</script>