Tambahkan menu expired gudang

This commit is contained in:
Dwi Swandhana
2026-02-23 17:41:14 +07:00
parent 93c5e9ef09
commit 6d23d9c97d
4 changed files with 217 additions and 80 deletions
@@ -64,6 +64,7 @@ class GudangController extends Controller
$tasks['stat_perjenis_bulanan'] = $this->getUsagePerJenis('bulanan');
$tasks['stat_perjenis_tahunan'] = $this->getUsagePerJenis('tahunan');
$tasks['warningstok'] = $this->getLowStockWarnings();
$tasks['expiringSoon'] = $this->getExpiringSoonItems();
$tasks['jenisRows'] = $this->getJenisRows();
return view('admin.gudang', $tasks);
}
@@ -134,6 +135,7 @@ class GudangController extends Controller
'pemasukan' => number_format( $pemasukan , 0 , '.' , ',' ),
'pengeluaran' => number_format( $pengeluaran , 0 , '.' , ',' ),
'jenis' => $rdata->jenis,
'masa_expired' => $rdata->masa_expired,
'keterangan' => $rdata->keterangan,
'tgllengkap' => $tgllengkap,
'total' => $total,
@@ -142,6 +144,52 @@ class GudangController extends Controller
echo json_encode($hasil);
}
public function exportReportbhp(Request $request)
{
$bulan = strtoupper((string) $request->query('bulan', date('m')));
$tahun = strtoupper((string) $request->query('tahun', date('Y')));
if ($tahun === 'ALL'){
$bulan = date("m");
$tahun = date("Y");
$query = SIMBHPReport::where('bulan', (int) $bulan)->where('tahun', (int) $tahun);
} else {
$query = SIMBHPReport::where('tahun', (int) $tahun);
if ($bulan !== 'ALL') {
$query->where('bulan', (int) $bulan);
}
}
$rows = $query->orderBy('id', 'DESC')->get();
$filename = 'laporan-gudang-bln-'.$bulan.'_thn-'.$tahun.'.csv';
$headers = [
'Content-Type' => 'text/csv; charset=UTF-8',
'Content-Disposition' => 'attachment; filename="'.$filename.'"',
];
$callback = function () use ($rows) {
$file = fopen('php://output', 'w');
fputcsv($file, ['Tanggal', 'Bulan', 'Tahun', 'Jenis', 'Deskripsi', 'Pemasukan', 'Pengeluaran', 'Satuan Transaksi', 'Masa Expired', 'Keterangan']);
foreach ($rows as $row) {
fputcsv($file, [
$row->tanggal,
$row->bulan,
$row->tahun,
$row->jenis,
$row->deskripsi,
(int) ($row->pemasukan ?? 0),
(int) ($row->pengeluaran ?? 0),
$row->satuan_transaksi ?: '-',
$row->masa_expired ?: '-',
$row->keterangan ?: '-',
]);
}
fclose($file);
};
return response()->stream($callback, 200, $headers);
}
public function jsonReportbhpPaginated(Request $request) {
$tanggal = $request->input('tanggal');
$deskripsi = $request->input('deskripsi');
@@ -208,6 +256,7 @@ class GudangController extends Controller
'pemasukan' => number_format( $pemasukan , 0 , '.' , ',' ),
'pengeluaran' => number_format( $pengeluaran , 0 , '.' , ',' ),
'jenis' => $kodejenis,
'masa_expired' => $rdata->masa_expired,
'keterangan' => $rdata->keterangan,
'tgllengkap' => $tgllengkap,
'created_at' => $rdata->created_at,
@@ -237,6 +286,7 @@ class GudangController extends Controller
$set09 = $request->input('set09');
$set10 = $request->input('set10');
$satuanTransaksi = $request->input('set11');
$masaExpired = $this->normalizeDateInput($request->input('set12'));
if ($tanggal == '' OR is_null($tanggal)){
$tanggal = date("d-m-Y");
}
@@ -317,6 +367,7 @@ class GudangController extends Controller
'pengeluaran' => null,
'qty_base' => $qtyBase,
'satuan_transaksi' => $satuanTransaksi ?: 'besar',
'masa_expired' => $masaExpired,
'jenis' => $pos,
'keterangan' => '',
'marking' => '',
@@ -387,6 +438,7 @@ class GudangController extends Controller
'pemasukan' => $total,
'qty_base' => $qtyBaseEdit,
'satuan_transaksi' => $satuanEdit,
'masa_expired' => $masaExpired,
'keterangan' => $alasan,
'updated_at' => date("Y-m-d H:i:s")
]);
@@ -592,6 +644,50 @@ class GudangController extends Controller
return $warnings;
}
private function getExpiringSoonItems()
{
$today = date('Y-m-d');
$limitDate = date('Y-m-d', strtotime('+30 days'));
$rows = SIMBHPReport::whereNotNull('masa_expired')
->whereNotNull('pemasukan')
->where('pemasukan', '>', 0)
->where('masa_expired', '>=', $today)
->where('masa_expired', '<=', $limitDate)
->orderBy('masa_expired', 'ASC')
->orderBy('id', 'DESC')
->get();
$items = [];
foreach ($rows as $row) {
$expiredAt = (string) $row->masa_expired;
$daysLeft = (int) floor((strtotime($expiredAt) - strtotime($today)) / 86400);
if ($daysLeft < 0) {
continue;
}
$badge = 'warning';
if ($daysLeft <= 7) {
$badge = 'danger';
} elseif ($daysLeft <= 14) {
$badge = 'warning';
}
$items[] = [
'jenis' => $row->jenis ?: '-',
'deskripsi' => $row->deskripsi ?: '-',
'qty' => (int) ($row->pemasukan ?? 0),
'satuan' => $row->satuan_transaksi ?: 'besar',
'tanggal_masuk' => sprintf('%02d-%02d-%04d', (int) $row->tanggal, (int) $row->bulan, (int) $row->tahun),
'masa_expired' => date('d-m-Y', strtotime($expiredAt)),
'sisa_hari' => $daysLeft,
'badge' => $badge,
];
}
return $items;
}
private function getAggregateBaseQty($direction, $scope = 'harian')
{
$now = date('Y-m-d');
@@ -656,6 +752,25 @@ class GudangController extends Controller
return array_values($grouped);
}
private function normalizeDateInput($value)
{
$value = trim((string) $value);
if ($value === '') {
return null;
}
if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $value)) {
return $value;
}
if (preg_match('/^\d{2}-\d{2}-\d{4}$/', $value)) {
$parts = explode('-', $value);
return $parts[2].'-'.$parts[1].'-'.$parts[0];
}
return null;
}
private function getJenisRows()
{
$rows = [];
@@ -0,0 +1,26 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::table('simbhpreport', function (Blueprint $table) {
if (!Schema::hasColumn('simbhpreport', 'masa_expired')) {
$table->date('masa_expired')->nullable()->after('satuan_transaksi');
}
});
}
public function down(): void
{
Schema::table('simbhpreport', function (Blueprint $table) {
if (Schema::hasColumn('simbhpreport', 'masa_expired')) {
$table->dropColumn('masa_expired');
}
});
}
};
+75 -80
View File
@@ -76,6 +76,9 @@
<li class="nav-item">
<a href="#tab_warning" data-toggle="tab" aria-expanded="false" class="nav-link">Warning</a>
</li>
<li class="nav-item">
<a href="#tab_expired" data-toggle="tab" aria-expanded="false" class="nav-link">Mendekati Expired</a>
</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab_awal">
@@ -106,9 +109,12 @@
<div class="col-lg-4">
<input type="text" class="form-control" id="cekthn" value="{{ $tahunne }}">
</div>
<div class="col-lg-4">
<div class="col-lg-2">
<button class="btn btn-warning btn-flat" type="button" id="btnviewdata">View Report</button>
</div>
<div class="col-lg-2">
<button class="btn btn-success btn-flat" type="button" id="btnexportreport">Export</button>
</div>
</div>
</div>
<div class="form-group">
@@ -253,6 +259,47 @@
</div>
</div>
</div>
<div class="tab-pane" id="tab_expired">
<div class="row">
<div class="col-sm-12">
<div class="card-box">
<h4 class="m-t-0 m-b-15">Barang Mendekati Expired (H-30)</h4>
@if(isset($expiringSoon) && count($expiringSoon) > 0)
<div class="table-responsive">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Jenis</th>
<th>Deskripsi</th>
<th>Tanggal Masuk</th>
<th>Masa Expired</th>
<th>Jumlah</th>
<th>Satuan</th>
<th>Sisa Hari</th>
</tr>
</thead>
<tbody>
@foreach($expiringSoon as $e)
<tr>
<td>{{ $e['jenis'] }}</td>
<td>{{ $e['deskripsi'] }}</td>
<td class="text-center">{{ $e['tanggal_masuk'] }}</td>
<td class="text-center">{{ $e['masa_expired'] }}</td>
<td class="text-right">{{ number_format($e['qty'], 0, '.', ',') }}</td>
<td class="text-center">{{ strtoupper($e['satuan']) }}</td>
<td class="text-center"><span class="badge badge-{{ $e['badge'] }}">{{ $e['sisa_hari'] }} hari</span></td>
</tr>
@endforeach
</tbody>
</table>
</div>
@else
<div class="alert alert-success m-b-0">Tidak ada barang yang mendekati masa expired dalam 30 hari ke depan.</div>
@endif
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@@ -333,6 +380,10 @@
<div class="form-group">
<label>Jumlah</label>
<input type="text" id="in_total" name="in_total" class="form-control">
</div>
<div class="form-group">
<label>Masa Expired</label>
<input type="text" id="in_masa_expired" name="in_masa_expired" class="form-control" placeholder="dd-mm-yyyy">
</div>
<div class="form-group account-btn text-center m-t-10">
<div class="col-12">
@@ -419,6 +470,10 @@
<label>Total</label>
<input type="text" id="edit_total" name="edit_total" class="form-control">
</div>
<div class="form-group">
<label>Masa Expired</label>
<input type="text" id="edit_masa_expired" name="edit_masa_expired" class="form-control" placeholder="dd-mm-yyyy">
</div>
<div class="form-group">
<label>Alasan Di Edit / Di Hapus</label>
<input type="text" id="edit_alasan" name="edit_alasan" class="form-control">
@@ -446,6 +501,8 @@
$("#in_tanggal").datepicker({format: 'dd-mm-yyyy'});
$("#out_tanggal").datepicker({format: 'dd-mm-yyyy'});
$("#edit_tanggal").datepicker({format: 'dd-mm-yyyy'});
$("#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;
@@ -462,6 +519,7 @@
{ name: 'pemasukan',type: 'text'},
{ name: 'pengeluaran',type: 'text'},
{ name: 'jenis',type: 'text'},
{ name: 'masa_expired',type: 'text'},
{ name: 'keterangan',type: 'text'},
{ name: 'tgllengkap',type: 'text'},
{ name: 'total',type: 'text'},
@@ -490,7 +548,8 @@
{ text: 'Deskripsi', datafield: 'deskripsi', width: '25%', cellsalign: 'left', align: 'center' },
{ text: 'MASUK', datafield: 'pemasukan', width: '10%', cellsalign: 'right', align: 'center' },
{ text: 'KELUAR', datafield: 'pengeluaran', width: '10%', cellsalign: 'right', align: 'center' },
{ text: 'Keterangan', datafield: 'keterangan', width: '20%', cellsalign: 'right', align: 'center' },
{ text: 'Masa Expired', datafield: 'masa_expired', width: '12%', cellsalign: 'center', align: 'center' },
{ text: 'Keterangan', datafield: 'keterangan', width: '8%', cellsalign: 'right', align: 'center' },
{ text: 'Edit', columntype: 'button', width: '10%', cellsrenderer: function () { return "Edit";
}, buttonclick: function (row) {
editrow = row;
@@ -505,6 +564,7 @@
$("#edit_pos").val(dataRecord.jenis);
$("#edit_total").val(dataRecord.total);
$("#edit_tanggal").val(tulis);
$("#edit_masa_expired").val(dataRecord.masa_expired || '');
$("#modaleditor").modal('show');
}
},
@@ -613,7 +673,8 @@ $(document).ready(function() {
var val09='';
var val10='';
var val11=document.getElementById('in_satuan_transaksi').value;
$.post('simbhp/exaddbarang', { _token: token, set01: val01, set02: val02, set03: val03, set04: val04, set05: val05, set06: val06, set07: val07, set08: val08, set09: val09, set10: val10, set11: val11 },
var val12=document.getElementById('in_masa_expired').value;
$.post('simbhp/exaddbarang', { _token: token, set01: val01, set02: val02, set03: val03, set04: val04, set05: val05, set06: val06, set07: val07, set08: val08, set09: val09, set10: val10, set11: val11, set12: val12 },
function(data){
$("#modalpemasukan").modal('hide');
var status = data.status;
@@ -644,7 +705,8 @@ $(document).ready(function() {
var val09='';
var val10='';
var val11=document.getElementById('out_satuan_transaksi').value;
$.post('simbhp/exaddbarang', { _token: token, set01: val01, set02: val02, set03: val03, set04: val04, set05: val05, set06: val06, set07: val07, set08: val08, set09: val09, set10: val10, set11: val11 },
var val12='';
$.post('simbhp/exaddbarang', { _token: token, set01: val01, set02: val02, set03: val03, set04: val04, set05: val05, set06: val06, set07: val07, set08: val08, set09: val09, set10: val10, set11: val11, set12: val12 },
function(data){
$("#modalpengeluaran").modal('hide');
var status = data.status;
@@ -675,7 +737,8 @@ $(document).ready(function() {
var val09='';
var val10='';
var val11='besar';
$.post('simbhp/exaddbarang', { _token: token, set01: val01, set02: val02, set03: val03, set04: val04, set05: val05, set06: val06, set07: val07, set08: val08, set09: val09, set10: val10, set11: val11 },
var val12=document.getElementById('edit_masa_expired').value;
$.post('simbhp/exaddbarang', { _token: token, set01: val01, set02: val02, set03: val03, set04: val04, set05: val05, set06: val06, set07: val07, set08: val08, set09: val09, set10: val10, set11: val11, set12: val12 },
function(data){
$("#modaleditor").modal('hide');
var status = data.status;
@@ -706,7 +769,8 @@ $(document).ready(function() {
var val09='';
var val10='';
var val11='besar';
$.post('simbhp/exaddbarang', { _token: token, set01: val01, set02: val02, set03: val03, set04: val04, set05: val05, set06: val06, set07: val07, set08: val08, set09: val09, set10: val10, set11: val11 },
var val12='';
$.post('simbhp/exaddbarang', { _token: token, set01: val01, set02: val02, set03: val03, set04: val04, set05: val05, set06: val06, set07: val07, set08: val08, set09: val09, set10: val10, set11: val11, set12: val12 },
function(data){
$("#modaleditor").modal('hide');
var status = data.status;
@@ -730,80 +794,11 @@ $(document).ready(function() {
});
$("#in_total").autoNumeric( 'init', {aSep: ',', mDec: '0', vMax: '99999999999999999999999999'} );
$("#out_total").autoNumeric( 'init', {aSep: ',', mDec: '0', vMax: '99999999999999999999999999'} );
$('#export').click(function(){
var gridContent = $("#gridreportblnini").jqxGrid('exportdata', 'json');
data = $.parseJSON(gridContent);
var noOfContacts = data.length;
if(noOfContacts>0){
var table = document.createElement("table");
table.style.width = '100%';
table.setAttribute('border', '1');
table.setAttribute('cellspacing', '0');
table.setAttribute('cellpadding', '5');
table.setAttribute('id', 'tabelcetak');
table.setAttribute('class', 'text');
var col = [];
for (var i = 0; i < noOfContacts; i++) {
for (var key in data[i]) {
if (col.indexOf(key) === -1) {
col.push(key);
}
}
}
var tHead = document.createElement("thead");
var hRow = document.createElement("tr");
for (var i = 0; i < col.length; i++) {
var th = document.createElement("th");
th.innerHTML = col[i];
hRow.appendChild(th);
}
tHead.appendChild(hRow);
table.appendChild(tHead);
var tBody = document.createElement("tbody");
for (var i = 0; i < noOfContacts; i++) {
var bRow = document.createElement("tr");
for (var j = 0; j < col.length; j++) {
var td = document.createElement("td");
var isi = data[i][col[j]];
var isi2 = isi.toString();
var pjg = isi2.length;
if (pjg > 8){
if (pjg == 9 || pjg == 10){
if( isi2.indexOf(',') != -1 ){
var res = isi2.replace(/,/g, "");
td.innerHTML = res;
}
else {
var res = isi2;
td.setAttribute('style', 'mso-number-format: "\@";');
td.innerHTML = res;
}
}
else {
var res = isi2;
td.setAttribute('style', 'mso-number-format: "\@";');
td.innerHTML = res;
}
}
else {
var res = isi2.replace(/,/g, "");
td.innerHTML = res;
}
bRow.appendChild(td);
}
tBody.appendChild(bRow)
}
table.appendChild(tBody);
var divContainer = document.getElementById("tabel_cetak");
divContainer.innerHTML = "";
divContainer.appendChild(table);
}
$("#tabel_cetak").btechco_excelexport({
containerid: "tabel_cetak"
, datatype: $datatype.Table
});
$('#btnexportreport').click(function(){
var bln = $('#cekbln').val();
var thn = $('#cekthn').val();
var url = "{{ route('reportBHPExport') }}" + "?bulan=" + encodeURIComponent(bln) + "&tahun=" + encodeURIComponent(thn);
window.open(url, '_blank');
return false;
});
});
+1
View File
@@ -76,6 +76,7 @@ Route::group(['middleware' => 'project.ipg'], function() {
Route::post('biorepository/delete-cabinet/{id}', [BiorepositoryController::class, 'deleteCabinet'])->name('biorepository.deleteCabinet');
Route::post('simbhp/exaddbarang', [GudangController::class, 'exAddbarang'])->name('exAddBarang');
Route::post('simbhp/reportbhp', [GudangController::class, 'jsonReportbhp'])->name('reportBHP');
Route::get('simbhp/reportbhp/export', [GudangController::class, 'exportReportbhp'])->name('reportBHPExport');
Route::post('simbhp/kwitansi', [GudangController::class, 'exKwitansi'])->name('kwitansiBHP');
Route::get('simbhp/rekapbhp', [GudangController::class, 'jsonRekapbhp'])->name('rekapBHP');