Files
lis/htdocs/resources/views/livewire/gudang-pos.blade.php
T
2026-05-07 19:29:23 +07:00

244 lines
12 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<div>
<div class="row">
<div class="col-lg-7">
<div class="card-box">
<div class="row">
<div class="col-md-7">
<h4 class="m-t-0">List Barang</h4>
<small class="text-muted">Scan barcode di atas list, atau klik item untuk input qty/satuan.</small>
</div>
<div class="col-md-5">
<input type="text" class="form-control" placeholder="Cari kode / nama..." wire:model.live.debounce.300ms="search">
</div>
</div>
<div class="m-t-10">
<input id="gudangpos_scan" type="text" class="form-control"
placeholder="Scan barcode lalu Enter"
wire:model.live="scan"
wire:keydown.enter.prevent="scanLookup">
</div>
<hr class="m-t-10 m-b-10">
<div class="row">
@forelse($products as $p)
@php
$saldoBase = (int) ($stockMap[$p->jenis] ?? 0);
$warning = $saldoBase <= (int) ($p->stok_minimum ?? 0);
$latestExpired = $latestExpiredMap[$p->jenis] ?? null;
@endphp
<div class="col-lg-4 col-md-6">
<div class="card-box" style="border:1px solid #eee; cursor:pointer;" wire:click="selectProduct('{{ $p->kodejenis }}')">
<div class="d-flex justify-content-between">
<div>
<div><b>{{ $p->jenis }}</b></div>
<div><span class="badge badge-success">{{ $p->kodejenis }}</span></div>
</div>
<div class="text-right">
@if($warning)
<span class="badge badge-danger">LOW</span>
@else
<span class="badge badge-info">OK</span>
@endif
</div>
</div>
<div class="m-t-10">
<small class="text-muted">Stok (base): {{ number_format($saldoBase, 0, '.', ',') }}</small>
</div>
<div class="m-t-5">
<small class="text-muted">Satuan: {{ $p->satuan }} @if(($p->satuan_kecil ?? '') !== '') / {{ $p->satuan_kecil }} @endif</small>
</div>
<div class="m-t-5">
<small class="text-muted">
Expired terakhir:
@if($latestExpired)
<span class="badge badge-{{ $latestExpired['badge_class'] }}">{{ $latestExpired['date'] }}</span>
@else
-
@endif
</small>
</div>
</div>
</div>
@empty
<div class="col-12">
<div class="alert alert-warning m-b-0">Produk tidak ditemukan.</div>
</div>
@endforelse
</div>
<div class="m-t-10">
{{ $products->links('pagination::bootstrap-4') }}
</div>
</div>
</div>
<div class="col-lg-5">
<div class="card-box">
<h4 class="m-t-0">Keranjang</h4>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label>Tanggal</label>
<input type="date" class="form-control" wire:model.live="tanggal">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label>Penerima</label>
<select class="form-control" wire:model.live="penerimaId">
@foreach($users as $u)
<option value="{{ $u->nama }}">{{ $u->nama }}</option>
@endforeach
@foreach($ruangans as $ruang)
<option value="{{ $ruang->ruangan }}">{{ $ruang->ruangan }}</option>
@endforeach
</select>
</div>
</div>
</div>
<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: 90px">Qty</th>
<th style="width: 80px">Sat</th>
<th style="width: 60px">Aksi</th>
</tr>
</thead>
<tbody>
@forelse($cart as $i => $line)
<tr>
<td class="text-center"><code>{{ $line['kode'] }}</code></td>
<td>{{ $line['jenis'] }}</td>
<td>{{ $line['keterangan'] ?: '-' }}</td>
<td class="text-right">{{ number_format((int) ($line['qty'] ?? 0), 0, '.', ',') }}</td>
<td class="text-center">{{ strtoupper($line['satuan_transaksi'] ?? '-') }}</td>
<td class="text-center">
<button type="button" class="btn btn-sm btn-danger" wire:click="removeLine({{ $i }})">X</button>
</td>
</tr>
@empty
<tr><td colspan="6" class="text-center text-muted">Keranjang masih kosong.</td></tr>
@endforelse
</tbody>
</table>
</div>
<div class="m-t-10">
<button type="button" class="btn btn-custom btn-block" wire:click="processCart" @if(count($cart)===0) disabled @endif>Proses Barang Keluar</button>
</div>
<small class="text-muted d-block m-t-10">Tidak ada pembayaran; hanya penerima barang.</small>
</div>
</div>
</div>
<div wire:ignore.self class="modal fade" id="gudangposModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Input Qty & Satuan</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<label>Kode</label>
<input type="text" class="form-control" wire:model.live="selectedKode" readonly>
</div>
@if($selectedJenis)
<div class="alert alert-info">
<div><b>{{ $selectedJenis->jenis }}</b></div>
<div>Stok: <b>{{ $selectedStockDisplay }}</b></div>
<div>
Expired terakhir:
@if($selectedLatestExpired)
<span class="badge badge-{{ $selectedLatestExpired['badge_class'] }}">{{ $selectedLatestExpired['date'] }}</span>
@else
<b>-</b>
@endif
</div>
</div>
@endif
<div class="form-group">
<label>Satuan</label>
<select class="form-control" wire:model.live="satuanTransaksi">
<option value="besar">Satuan Besar</option>
<option value="kecil" @if(!($selectedSetting['has_breakdown'] ?? false)) disabled @endif>Satuan Kecil (Pecah Satuan)</option>
</select>
</div>
<div class="form-group m-b-0">
<label>Jumlah</label>
<input id="gudangpos_qty" type="number" min="1" class="form-control" wire:model.live="qty" wire:keydown.enter.prevent="addSelected">
</div>
<div class="form-group m-t-10 m-b-0">
<label>Keterangan</label>
<input type="text" class="form-control" wire:model.live="keterangan" placeholder="opsional">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Batal</button>
<button type="button" class="btn btn-success" wire:click="addSelected">Tambah</button>
</div>
</div>
</div>
</div>
@once
@push('script')
<script>
document.addEventListener('livewire:init', () => {
Livewire.on('gudangpos-toast', (e) => {
const type = (e.type || 'info').toString();
const icon = (type === 'success') ? 'success' : (type === 'error' ? 'error' : 'info');
const loaderBg = (type === 'success') ? '#5ba035' : (type === 'error' ? '#bf441d' : '#3b98b5');
if (window.$ && $.toast) {
$.toast({
heading: type.toUpperCase(),
text: e.message || '',
position: 'top-right',
loaderBg,
icon,
hideAfter: 3500,
stack: 1
});
} else {
alert(e.message || '');
}
});
Livewire.on('gudangpos-focus', (e) => {
const field = (e.field || '').toString();
const id = (field === 'qty') ? 'gudangpos_qty' : 'gudangpos_scan';
setTimeout(() => {
const el = document.getElementById(id);
if (el) el.focus();
}, 50);
});
Livewire.on('gudangpos-open-modal', () => {
if (window.$) {
$('#gudangposModal').modal('show');
}
setTimeout(() => {
const el = document.getElementById('gudangpos_qty');
if (el) el.focus();
}, 200);
});
Livewire.on('gudangpos-close-modal', () => {
if (window.$) {
$('#gudangposModal').modal('hide');
}
});
});
</script>
@endpush
@endonce
</div>