946 lines
44 KiB
PHP
946 lines
44 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Schema;
|
|
use App\XFiles;
|
|
use App\SIMBHPJenis;
|
|
use App\SIMBHPReport;
|
|
use App\User;
|
|
use App\Ruangan;
|
|
use App\Services\SimbhpStockService;
|
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
|
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
|
use Validator;
|
|
use Session;
|
|
|
|
class GudangController extends Controller
|
|
{
|
|
public function viewGudangIndex() {
|
|
if (Session::get('previlage') == ''){
|
|
return redirect('/login');
|
|
} else {
|
|
$tasks = [];
|
|
$sekarang = date("Y-m-d");
|
|
$pegawais = User::select('id', 'nama', 'previlage')->orderBy('nama', 'ASC')->get();
|
|
$cdatane = SIMBHPJenis::all();
|
|
$cjenis = count($cdatane);
|
|
if ($cjenis == 0){
|
|
$tasks['jjenis'][0]['id'] = null;
|
|
$tasks['jjenis'][0]['jenis'] = 'Belum Ada Jenis Barang';
|
|
$tasks['jjenis'][0]['kodejenis'] = '';
|
|
$tasks['jjenis'][0]['satuan'] = '';
|
|
$tasks['jjenis'][0]['satuan_kecil'] = '';
|
|
$tasks['jjenis'][0]['konversi_kecil'] = 1;
|
|
$tasks['jjenis'][0]['stok_minimum'] = 0;
|
|
} else {
|
|
$i = 0;
|
|
foreach($cdatane as $rdata){
|
|
$tasks['jjenis'][$i]['id'] = $rdata->id;
|
|
$tasks['jjenis'][$i]['jenis'] = $rdata->jenis;
|
|
$tasks['jjenis'][$i]['kodejenis'] = $rdata->kodejenis ?? '';
|
|
$tasks['jjenis'][$i]['satuan'] = $rdata->satuan;
|
|
$tasks['jjenis'][$i]['satuan_kecil'] = $rdata->satuan_kecil ?? '';
|
|
$tasks['jjenis'][$i]['konversi_kecil'] = $rdata->konversi_kecil ?? 1;
|
|
$tasks['jjenis'][$i]['stok_minimum'] = $rdata->stok_minimum ?? 0;
|
|
$i++;
|
|
}
|
|
}
|
|
$getdebet = SIMBHPReport::select(DB::raw('SUM(pemasukan) as pemasukan'))->groupBy('marking')->first();
|
|
if (isset($getdebet->pemasukan)){
|
|
$totpemasukan = $getdebet->pemasukan;
|
|
} else { $totpemasukan = 0 ;}
|
|
$getkredit = SIMBHPReport::select(DB::raw('SUM(pengeluaran) as pengeluaran'))->groupBy('marking')->first();
|
|
if (isset($getkredit->pengeluaran)){
|
|
$totpepengeluaran = $getkredit->pengeluaran;
|
|
} else { $totpepengeluaran = 0 ;}
|
|
|
|
$tasks['masuk'] = $totpemasukan;
|
|
$tasks['keluar'] = $totpepengeluaran;
|
|
$tasks['pegawai'] = $pegawais;
|
|
$tasks['tahunne'] = date("Y");
|
|
$tasks['tanggal'] = $sekarang;
|
|
$tasks['sidebar'] = 'simbhp';
|
|
$tasks['stat_harian_masuk'] = $this->getAggregateBaseQty('pemasukan', 'harian');
|
|
$tasks['stat_harian_keluar'] = $this->getAggregateBaseQty('pengeluaran', 'harian');
|
|
$tasks['stat_bulanan_masuk'] = $this->getAggregateBaseQty('pemasukan', 'bulanan');
|
|
$tasks['stat_bulanan_keluar'] = $this->getAggregateBaseQty('pengeluaran', 'bulanan');
|
|
$tasks['stat_tahunan_masuk'] = $this->getAggregateBaseQty('pemasukan', 'tahunan');
|
|
$tasks['stat_tahunan_keluar'] = $this->getAggregateBaseQty('pengeluaran', 'tahunan');
|
|
$tasks['stat_perjenis_harian'] = $this->getUsagePerJenis('harian');
|
|
$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);
|
|
}
|
|
}
|
|
|
|
public function jsonRekapbhp() {
|
|
$arraysurat = [];
|
|
$getdata = SIMBHPJenis::all();
|
|
if (!empty($getdata)){
|
|
foreach($getdata as $hasil){
|
|
$jenis = $hasil->kodejenis;
|
|
$satuan = $hasil->satuan;
|
|
$satuanKecil = $hasil->satuan_kecil ?? '';
|
|
$konversi = (int) ($hasil->konversi_kecil ?? 1);
|
|
if ($konversi <= 0) { $konversi = 1; }
|
|
$tlsjenis = $hasil->jenis;
|
|
$saldoBase = $this->getStockBaseByJenis($tlsjenis);
|
|
$saldoakhir = $this->formatStockDisplay($saldoBase, $satuan, $satuanKecil, $konversi);
|
|
$isWarning = $saldoBase <= (int) ($hasil->stok_minimum ?? 0);
|
|
$arraysurat[] = array(
|
|
'id' => $hasil->id,
|
|
'satuan' => $satuan,
|
|
'jenis' => $jenis,
|
|
'tlsjenis' => $tlsjenis,
|
|
'saldo' => $saldoakhir,
|
|
'warning' => $isWarning ? 'YA' : 'TIDAK',
|
|
);
|
|
}
|
|
}
|
|
echo json_encode($arraysurat);
|
|
}
|
|
|
|
public function jsonSnapshot()
|
|
{
|
|
if (Session::get('previlage') == '') {
|
|
return response()->json(['message' => 'Unauthorized'], 401);
|
|
}
|
|
|
|
$jjenis = [];
|
|
$cdatane = SIMBHPJenis::orderBy('jenis', 'ASC')->get();
|
|
if ($cdatane->count() == 0) {
|
|
$jjenis[] = [
|
|
'id' => null,
|
|
'jenis' => 'Belum Ada Jenis Barang',
|
|
'kodejenis' => '',
|
|
'satuan' => '',
|
|
'satuan_kecil' => '',
|
|
'konversi_kecil' => 1,
|
|
'stok_minimum' => 0,
|
|
];
|
|
} else {
|
|
foreach ($cdatane as $rdata) {
|
|
$jjenis[] = [
|
|
'id' => $rdata->id,
|
|
'jenis' => $rdata->jenis,
|
|
'kodejenis' => $rdata->kodejenis ?? '',
|
|
'satuan' => $rdata->satuan,
|
|
'satuan_kecil' => $rdata->satuan_kecil ?? '',
|
|
'konversi_kecil' => $rdata->konversi_kecil ?? 1,
|
|
'stok_minimum' => $rdata->stok_minimum ?? 0,
|
|
];
|
|
}
|
|
}
|
|
|
|
return response()->json([
|
|
'jjenis' => $jjenis,
|
|
'jenisRows' => $this->getJenisRows(),
|
|
'warningstok' => $this->getLowStockWarnings(),
|
|
'expiringSoon' => $this->getExpiringSoonItems(),
|
|
'stat' => [
|
|
'harian' => [
|
|
'masuk' => $this->getAggregateBaseQty('pemasukan', 'harian'),
|
|
'keluar' => $this->getAggregateBaseQty('pengeluaran', 'harian'),
|
|
'perjenis' => $this->getUsagePerJenis('harian'),
|
|
],
|
|
'bulanan' => [
|
|
'masuk' => $this->getAggregateBaseQty('pemasukan', 'bulanan'),
|
|
'keluar' => $this->getAggregateBaseQty('pengeluaran', 'bulanan'),
|
|
'perjenis' => $this->getUsagePerJenis('bulanan'),
|
|
],
|
|
'tahunan' => [
|
|
'masuk' => $this->getAggregateBaseQty('pemasukan', 'tahunan'),
|
|
'keluar' => $this->getAggregateBaseQty('pengeluaran', 'tahunan'),
|
|
'perjenis' => $this->getUsagePerJenis('tahunan'),
|
|
],
|
|
],
|
|
]);
|
|
}
|
|
|
|
public function jsonReportbhp(Request $request) {
|
|
$mulai = $request->input('val01');
|
|
$akhir = $request->input('val02');
|
|
$hasil = [];
|
|
if ($mulai == $akhir OR $akhir == '' OR $akhir == null){
|
|
$getdata = SIMBHPReport::whereDate('created_at', $mulai)->orderBy('id', 'DESC')->get();
|
|
} else {
|
|
$getdata = SIMBHPReport::whereBetween('created_at', [$mulai, $akhir])->orderBy('id', 'DESC')->get();
|
|
}
|
|
|
|
foreach($getdata as $rdata){
|
|
$dd = $rdata->tanggal;
|
|
$mm = $rdata->bulan;
|
|
$yy = $rdata->tahun;
|
|
$pengeluaran = $rdata->pengeluaran;
|
|
$pemasukan = $rdata->pemasukan;
|
|
$deskripsiGabungan = trim((string) ($rdata->deskripsi ?? ''));
|
|
$keteranganGabungan = trim((string) ($rdata->keterangan ?? ''));
|
|
if ($keteranganGabungan !== '') {
|
|
$deskripsiGabungan = $deskripsiGabungan !== ''
|
|
? $deskripsiGabungan.' | '.$keteranganGabungan
|
|
: $keteranganGabungan;
|
|
}
|
|
if ($mm < 10){
|
|
$tgllengkap = $dd.'-0'.$mm.'-'.$yy;
|
|
} else {
|
|
$tgllengkap = $dd.'-'.$mm.'-'.$yy;
|
|
}
|
|
if ($pengeluaran == '' OR $pengeluaran == 0) {$total = $pemasukan;}
|
|
else { $total = $pengeluaran; }
|
|
|
|
$hasil[] = array(
|
|
'id' => $rdata->id,
|
|
'tanggal' => $rdata->tanggal,
|
|
'bulan' => $rdata->bulan,
|
|
'tahun' => $rdata->tahun,
|
|
'deskripsi' => $deskripsiGabungan,
|
|
'pemasukan' => $rdata->pemasukan ?? 0,
|
|
'pengeluaran' => $rdata->pengeluaran ?? 0,
|
|
'jenis' => $rdata->jenis,
|
|
'masa_expired' => $rdata->masa_expired,
|
|
'keterangan' => $rdata->keterangan,
|
|
'tgllengkap' => $rdata->created_at->format('m/d/Y'),
|
|
'total' => $total,
|
|
);
|
|
}
|
|
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.'.xlsx';
|
|
|
|
return response()->streamDownload(function () use ($rows) {
|
|
$spreadsheet = new Spreadsheet();
|
|
$sheet = $spreadsheet->getActiveSheet();
|
|
$sheet->setTitle('Laporan Gudang');
|
|
|
|
$headers = ['Tanggal', 'Bulan', 'Tahun', 'Jenis', 'Deskripsi', 'Pemasukan', 'Pengeluaran', 'Satuan Transaksi', 'Masa Expired', 'Keterangan'];
|
|
$sheet->fromArray($headers, null, 'A1');
|
|
|
|
$rowNumber = 2;
|
|
foreach ($rows as $row) {
|
|
$sheet->fromArray([
|
|
(int) ($row->tanggal ?? 0),
|
|
(int) ($row->bulan ?? 0),
|
|
(int) ($row->tahun ?? 0),
|
|
$row->jenis ?: '-',
|
|
$row->deskripsi ?: '-',
|
|
(int) ($row->pemasukan ?? 0),
|
|
(int) ($row->pengeluaran ?? 0),
|
|
$row->satuan_transaksi ?: '-',
|
|
$row->masa_expired ?: '-',
|
|
$row->keterangan ?: '-',
|
|
], null, 'A'.$rowNumber);
|
|
$rowNumber++;
|
|
}
|
|
|
|
foreach (range('A', 'J') as $col) {
|
|
$sheet->getColumnDimension($col)->setAutoSize(true);
|
|
}
|
|
|
|
$writer = new Xlsx($spreadsheet);
|
|
$writer->save('php://output');
|
|
$spreadsheet->disconnectWorksheets();
|
|
unset($spreadsheet);
|
|
}, $filename, [
|
|
'Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
]);
|
|
}
|
|
|
|
public function jsonReportbhpPaginated(Request $request) {
|
|
$tanggal = $request->input('tanggal');
|
|
$deskripsi = $request->input('deskripsi');
|
|
$kategori = $request->input('kategori');
|
|
$lm = 10;
|
|
$limit = ($request->input('limit') == null ? $lm : $request->input('limit'));
|
|
$order = ($request->input('order') == null ? 'id desc' : $request->input('order'));
|
|
$data = new SIMBHPReport;
|
|
if ($kategori != null AND $kategori != '') $data = $data->where('jenis', $kategori);
|
|
if ($tanggal != null AND $tanggal != '') $data = $data->where('created_at', 'LIKE', '%'.$tanggal.'%');
|
|
if ($deskripsi != null AND $deskripsi != '') $data = $data->where('deskripsi', 'LIKE', '%'.$deskripsi.'%');
|
|
$data = $data->orderByRaw($order)->paginate($limit);
|
|
$hasil = [];
|
|
$totaldata = $data->total();
|
|
$debet = 0;
|
|
$kredit = 0;
|
|
if (!empty($data)){
|
|
foreach($data as $rdata){
|
|
|
|
$pengeluaran = $rdata->pengeluaran;
|
|
$pemasukan = $rdata->pemasukan;
|
|
$deskripsi = $rdata->deskripsi;
|
|
$jenis = $rdata->jenis;
|
|
$debet = $debet + $pemasukan;
|
|
$kredit = $kredit + $pengeluaran;
|
|
$cekjenis = SIMBHPJenis::where('kodejenis', $jenis)->first();
|
|
if (isset($cekjenis->id)){
|
|
$kodejenis = $cekjenis->kodejenis;
|
|
$jenis = $cekjenis->jenis;
|
|
$satuan = $cekjenis->satuan;
|
|
} else {
|
|
$kodejenis = $jenis;
|
|
$jenis = '';
|
|
$satuan = '';
|
|
}
|
|
|
|
if ($jenis != ''){
|
|
$deskripsi = '<strong>'.$jenis.'</strong><br />'.$deskripsi;
|
|
}
|
|
|
|
|
|
if ($pengeluaran == '' OR $pengeluaran == 0) {
|
|
$total = $pemasukan;
|
|
$jentrans = 'PEMASUKAN';
|
|
}
|
|
else {
|
|
$total = $pengeluaran;
|
|
$jentrans = 'PENGELUARAN';
|
|
}
|
|
|
|
$hasil[] = array(
|
|
'id' => $rdata->id,
|
|
'tanggal' => $rdata->tanggal,
|
|
'bulan' => $rdata->bulan,
|
|
'tahun' => $rdata->tahun,
|
|
'tlsdeskripsi' => $deskripsi,
|
|
'deskripsi' => $rdata->deskripsi,
|
|
'pemasukan' => $rdata->pemasukan ?? 0,
|
|
'pengeluaran' => $rdata->pengeluaran ?? 0,
|
|
'jenis' => $kodejenis,
|
|
'masa_expired' => $rdata->masa_expired,
|
|
'keterangan' => $rdata->keterangan,
|
|
'tgllengkap' => $rdata->created_at->format('m/d/Y'),
|
|
'created_at' => $rdata->created_at,
|
|
'nominal' => $total.' '.$satuan,
|
|
'jentrans' => $jentrans,
|
|
);
|
|
}
|
|
}
|
|
|
|
$response = [
|
|
'message' => 'List Data',
|
|
'data' => $hasil,
|
|
'totaldata' => $totaldata
|
|
];
|
|
return response()->json($response, 200);
|
|
}
|
|
|
|
public function exAddbarang(Request $request) {
|
|
$deskripsi = $request->input('set01');
|
|
$pos = $request->input('set02');
|
|
$tanggal = $request->input('set03');
|
|
$jumlah = $request->input('set04');
|
|
$jenis = $request->input('set05');
|
|
$postujuan = $request->input('set06'); // also used as kodejenis when $jenis == 'jenis'
|
|
$alasan = $request->input('set07');
|
|
$set08 = $request->input('set08');
|
|
$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");
|
|
}
|
|
$total = (int)str_replace(',','',$jumlah);
|
|
if ($jenis == 'jenis'){ $jumlah = '-';}
|
|
if ($deskripsi != '' and $pos != '' and $tanggal != '' and $jumlah != '' and $jenis != ''){
|
|
if ($jenis == 'jenis'){
|
|
$jenis = $request->input('set02');
|
|
$satuan = $request->input('set03');
|
|
$idne = $request->input('set01');
|
|
$kodeInput = trim((string) $request->input('set06'));
|
|
$satuanKecil = trim((string) $set08);
|
|
$konversiKecil = (int) $set09;
|
|
if ($konversiKecil <= 0){ $konversiKecil = 1; }
|
|
$stokMinimum = (int) $set10;
|
|
if ($stokMinimum < 0){ $stokMinimum = 0; }
|
|
if ($satuanKecil === '') {
|
|
$konversiKecil = 1;
|
|
} elseif ($konversiKecil <= 1) {
|
|
return response()->json(['icon' => 'error', 'warna' => '#bf441d', 'status' => 'Gagal', 'message' => 'Jika memakai satuan kecil, konversi harus lebih dari 1']);
|
|
}
|
|
|
|
if ($kodeInput !== '') {
|
|
$kodejenis = strtoupper($kodeInput);
|
|
$kodejenis = preg_replace('/\s+/', '', $kodejenis);
|
|
$kodejenis = preg_replace('/[^A-Z0-9._-]/', '', $kodejenis);
|
|
} else {
|
|
$kodejenis = strtoupper((string) $jenis);
|
|
$kodejenis = preg_replace('/\s+/', '', $kodejenis);
|
|
$kodejenis = preg_replace('/[^A-Z0-9._-]/', '', $kodejenis);
|
|
}
|
|
|
|
if ($kodejenis === '' || strlen($kodejenis) < 2 || strlen($kodejenis) > 40) {
|
|
return response()->json(['icon' => 'error', 'warna' => '#bf441d', 'status' => 'Gagal', 'message' => 'Kode barang wajib (2-40 karakter). Gunakan huruf/angka dan simbol - _ .']);
|
|
}
|
|
|
|
if ($idne == 'new' OR $idne == ''){
|
|
$ceksudah = SIMBHPJenis::where('kodejenis', $kodejenis)->where('satuan', $satuan)->count();
|
|
if ($ceksudah != 0){
|
|
return response()->json(['icon' => 'error', 'warna' => '#bf441d', 'status' => 'Gagal', 'message' => $jenis.' Sudah Ada, Silahkan Masukkan Jenis Barang Lain']);
|
|
} else {
|
|
$input = SIMBHPJenis::create([
|
|
'kodejenis' => $kodejenis,
|
|
'jenis' => $jenis,
|
|
'satuan' => $satuan,
|
|
'satuan_kecil' => $satuanKecil,
|
|
'konversi_kecil' => $konversiKecil,
|
|
'stok_minimum' => $stokMinimum,
|
|
]);
|
|
if ($input){
|
|
if (Schema::hasColumn('simbhpjenis', 'barcode_besar')) {
|
|
$service = app(SimbhpStockService::class);
|
|
$setting = $service->getUnitSetting($input);
|
|
$input->update([
|
|
'barcode_besar' => $service->makeBarcodeValue((int) $input->id, 'besar'),
|
|
'barcode_kecil' => ($setting['has_breakdown'] ?? false) ? $service->makeBarcodeValue((int) $input->id, 'kecil') : null,
|
|
]);
|
|
}
|
|
return response()->json(['status' => 'Success', 'message' => 'Data '.$jenis.' Sukses Ditambahkan']);
|
|
} else {
|
|
return response()->json(['icon' => 'error', 'warna' => '#bf441d', 'status' => 'Gagal', 'message' => $jenis.' Gagal di masukkan, silahkan ulangi beberapa saat lagi']);
|
|
}
|
|
}
|
|
} else {
|
|
$ceksudah = SIMBHPJenis::where('id', '!=', $idne)->where('kodejenis', $kodejenis)->where('satuan', $satuan)->count();
|
|
if ($ceksudah != 0){
|
|
return response()->json(['icon' => 'error', 'warna' => '#bf441d', 'status' => 'Gagal', 'message' => $jenis.' Sudah Ada, Silahkan Masukkan Jenis Barang Lain']);
|
|
} else {
|
|
$input = SIMBHPJenis::where('id', $idne)->update([
|
|
'kodejenis' => $kodejenis,
|
|
'jenis' => $jenis,
|
|
'satuan' => $satuan,
|
|
'satuan_kecil' => $satuanKecil,
|
|
'konversi_kecil' => $konversiKecil,
|
|
'stok_minimum' => $stokMinimum,
|
|
]);
|
|
if ($input){
|
|
if (Schema::hasColumn('simbhpjenis', 'barcode_besar')) {
|
|
$row = SIMBHPJenis::find($idne);
|
|
if ($row) {
|
|
$service = app(SimbhpStockService::class);
|
|
$setting = $service->getUnitSetting($row);
|
|
$row->barcode_besar = $service->makeBarcodeValue((int) $row->id, 'besar');
|
|
$row->barcode_kecil = ($setting['has_breakdown'] ?? false) ? $service->makeBarcodeValue((int) $row->id, 'kecil') : null;
|
|
$row->save();
|
|
}
|
|
}
|
|
return response()->json(['status' => 'Success', 'message' => 'Data '.$jenis.' Sukses Diupdate']);
|
|
} else {
|
|
return response()->json(['icon' => 'error', 'warna' => '#bf441d', 'status' => 'Gagal', 'message' => $jenis.' Gagal di masukkan, silahkan ulangi beberapa saat lagi']);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
$ahrf = explode("-", $tanggal);
|
|
$tahun = $ahrf[0];
|
|
if(isset($ahrf[1])){ $wulan = (int)$ahrf[1]; } else { $wulan = (int)date("m"); }
|
|
if(isset($ahrf[2])){ $dino = (int)$ahrf[2]; } else { $dino = (int)date("d"); }
|
|
$unitSetting = $this->getJenisUnitSetting($pos);
|
|
if ($jenis == 'pemasukan'){
|
|
if (($satuanTransaksi ?: 'besar') === 'kecil' && !$unitSetting['has_breakdown']) {
|
|
return response()->json(['icon' => 'error', 'warna' => '#bf441d', 'status' => 'Gagal', 'message' => 'Barang ini belum memiliki setting pecah satuan']);
|
|
}
|
|
$qtyBase = $this->calculateBaseQty($pos, $total, $satuanTransaksi ?: 'besar');
|
|
$bayar = SIMBHPReport::create([
|
|
'tanggal' => $dino,
|
|
'bulan' => $wulan,
|
|
'tahun' => $tahun,
|
|
'deskripsi' => $deskripsi,
|
|
'pemasukan' => $total,
|
|
'pengeluaran' => null,
|
|
'qty_base' => $qtyBase,
|
|
'satuan_transaksi' => $satuanTransaksi ?: 'besar',
|
|
'masa_expired' => $masaExpired,
|
|
'jenis' => $pos,
|
|
'keterangan' => '',
|
|
'marking' => '',
|
|
]);
|
|
} else if ($jenis == 'pengeluaran'){
|
|
if (($satuanTransaksi ?: 'besar') === 'kecil' && !$unitSetting['has_breakdown']) {
|
|
return response()->json(['icon' => 'error', 'warna' => '#bf441d', 'status' => 'Gagal', 'message' => 'Pengeluaran satuan kecil tidak tersedia untuk barang ini']);
|
|
}
|
|
$getnama = User::where('id', $deskripsi)->first();
|
|
$nama = $getnama->nama ?? 'Unkown';
|
|
$deskripsi = 'Diterima oleh '.$nama;
|
|
$qtyBase = $this->calculateBaseQty($pos, $total, $satuanTransaksi ?: 'besar');
|
|
$stokSaatIni = $this->getStockBaseByJenis($pos);
|
|
if ($qtyBase > $stokSaatIni){
|
|
return response()->json(['icon' => 'error', 'warna' => '#bf441d', 'status' => 'Gagal', 'message' => 'Nominal Melebihi Stok']);
|
|
} else {
|
|
$bayar = SIMBHPReport::create([
|
|
'tanggal' => $dino,
|
|
'bulan' => $wulan,
|
|
'tahun' => $tahun,
|
|
'deskripsi' => $deskripsi,
|
|
'pemasukan' => null,
|
|
'pengeluaran' => $total,
|
|
'qty_base' => $qtyBase,
|
|
'satuan_transaksi' => $satuanTransaksi ?: 'besar',
|
|
'jenis' => $pos,
|
|
'keterangan' => '',
|
|
'marking' => '',
|
|
]);
|
|
}
|
|
|
|
} else if ($jenis == 'opname_pengurangan'){
|
|
if (($satuanTransaksi ?: 'besar') === 'kecil' && !$unitSetting['has_breakdown']) {
|
|
return response()->json(['icon' => 'error', 'warna' => '#bf441d', 'status' => 'Gagal', 'message' => 'Pengurangan satuan kecil tidak tersedia untuk barang ini']);
|
|
}
|
|
|
|
$kategori = strtolower(trim((string) $deskripsi));
|
|
if (!in_array($kategori, ['rusak', 'hilang'], true)) {
|
|
return response()->json(['icon' => 'error', 'warna' => '#bf441d', 'status' => 'Gagal', 'message' => 'Kategori opname pengurangan tidak valid']);
|
|
}
|
|
|
|
$label = ($kategori === 'hilang') ? 'Barang Hilang' : 'Barang Rusak';
|
|
$deskripsi = 'Stok Opname - ' . $label;
|
|
$qtyBase = $this->calculateBaseQty($pos, $total, $satuanTransaksi ?: 'besar');
|
|
$stokSaatIni = $this->getStockBaseByJenis($pos);
|
|
if ($qtyBase > $stokSaatIni){
|
|
return response()->json(['icon' => 'error', 'warna' => '#bf441d', 'status' => 'Gagal', 'message' => 'Nominal Melebihi Stok']);
|
|
} else {
|
|
$bayar = SIMBHPReport::create([
|
|
'tanggal' => $dino,
|
|
'bulan' => $wulan,
|
|
'tahun' => $tahun,
|
|
'deskripsi' => $deskripsi,
|
|
'pemasukan' => null,
|
|
'pengeluaran' => $total,
|
|
'qty_base' => $qtyBase,
|
|
'satuan_transaksi' => $satuanTransaksi ?: 'besar',
|
|
'jenis' => $pos,
|
|
'keterangan' => trim((string) $alasan),
|
|
'marking' => '',
|
|
]);
|
|
}
|
|
|
|
} else if ($jenis == 'editor'){
|
|
if ($alasan == ''){
|
|
return response()->json(['icon' => 'error', 'warna' => '#bf441d', 'status' => 'Gagal', 'message' => 'Alasan Perubahan Data Wajib Di Isi!!!']);
|
|
} else {
|
|
$getdebet = SIMBHPReport::select(DB::raw('SUM(pemasukan) as pemasukan'))->where('jenis', $pos)->groupBy('jenis')->first();
|
|
if (isset($getdebet->pemasukan)){ $totpemasukan = $getdebet->pemasukan; } else { $totpemasukan = 0 ;}
|
|
$getkredit = SIMBHPReport::select(DB::raw('SUM(pengeluaran) as pengeluaran'))->where('jenis', $pos)->groupBy('jenis')->first();
|
|
if (isset($getkredit->pengeluaran)){ $totpepengeluaran = $getkredit->pengeluaran; } else { $totpepengeluaran = 0 ;}
|
|
$totpepengeluaran = $totpepengeluaran + $total;
|
|
|
|
$rdatalama = SIMBHPReport::where('id', $postujuan)->first();
|
|
$ldeskripsi = $rdatalama->deskripsi;
|
|
$lpemasukan = $rdatalama->pemasukan;
|
|
$lpengeluaran = $rdatalama->pengeluaran;
|
|
$ljenis = $rdatalama->jenis;
|
|
$marking = $rdatalama->marking;
|
|
if ($lpengeluaran == '' OR $lpengeluaran == 0) {
|
|
$satuanEdit = $rdatalama->satuan_transaksi ?: 'besar';
|
|
$qtyBaseEdit = $this->calculateBaseQty($pos, $total, $satuanEdit);
|
|
$ltotal = number_format( $lpemasukan , 0 , '.' , ',' );
|
|
if ($marking != ''){
|
|
SIMBHPReport::where('marking', $marking)->whereNotIn('id', [$postujuan])->update([
|
|
'tanggal' => $dino,
|
|
'bulan' => $wulan,
|
|
'tahun' => $tahun,
|
|
'pengeluaran' => $total,
|
|
'qty_base' => $qtyBaseEdit,
|
|
'satuan_transaksi' => $satuanEdit
|
|
]);
|
|
}
|
|
$bayar = SIMBHPReport::where('id', $postujuan)->update([
|
|
'tanggal' => $dino,
|
|
'bulan' => $wulan,
|
|
'tahun' => $tahun,
|
|
'deskripsi' => $deskripsi,
|
|
'jenis' => $pos,
|
|
'pemasukan' => $total,
|
|
'qty_base' => $qtyBaseEdit,
|
|
'satuan_transaksi' => $satuanEdit,
|
|
'masa_expired' => $masaExpired,
|
|
'keterangan' => $alasan,
|
|
'updated_at' => date("Y-m-d H:i:s")
|
|
]);
|
|
} else {
|
|
$satuanEdit = $rdatalama->satuan_transaksi ?: 'kecil';
|
|
$qtyBaseEdit = $this->calculateBaseQty($pos, $total, $satuanEdit);
|
|
$totpepengeluaran = $totpepengeluaran + $total;
|
|
if ($totpepengeluaran > $totpemasukan){
|
|
return response()->json(['icon' => 'error', 'warna' => '#bf441d', 'status' => 'Gagal', 'message' => 'Nominal Melebihi Stok']);
|
|
} else {
|
|
$ltotal = number_format( $lpengeluaran , 0 , '.' , ',' );
|
|
if ($marking != ''){
|
|
SIMBHPReport::where('marking', $marking)->whereNotIn('id', [$postujuan])->update([
|
|
'tanggal' => $dino,
|
|
'bulan' => $wulan,
|
|
'tahun' => $tahun,
|
|
'pemasukan' => $total,
|
|
'qty_base' => $qtyBaseEdit,
|
|
'satuan_transaksi' => $satuanEdit
|
|
]);
|
|
}
|
|
$bayar = SIMBHPReport::where('id', $postujuan)->update([
|
|
'tanggal' => $dino,
|
|
'bulan' => $wulan,
|
|
'tahun' => $tahun,
|
|
'deskripsi' => $deskripsi,
|
|
'jenis' => $pos,
|
|
'pengeluaran' => $total,
|
|
'qty_base' => $qtyBaseEdit,
|
|
'satuan_transaksi' => $satuanEdit,
|
|
'keterangan' => $alasan,
|
|
'updated_at' => date("Y-m-d H:i:s")
|
|
]);
|
|
}
|
|
}
|
|
$baris1 = '<table class="table table-bordered table-striped"><tr><td colspan=2><p align=center><b>Data Lama</b></p></td><td colspan=2><p align=center><b>Data Perubahan</b></p></td></tr>';
|
|
$baris2 = '<tr><td>Deskripsi</td><td>'.$ldeskripsi.'</td><td><font color=red>Diubah Menjadi</font></td><td>'.$deskripsi.'</td></tr>';
|
|
$baris3 = '<tr><td>Jenis</td><td>'.$ljenis.'</td><td><font color=red>Diubah Menjadi</font></td><td>'.$pos.'</td></tr>';
|
|
$baris4 = '<tr><td>Total</td><td>'.$ltotal.'</td><td><font color=red>Diubah Menjadi</font></td><td>'.$jumlah.'</td></tr>';
|
|
$baris5 = '<tr><td><b>Dengan Alasan</b></td><td colspan=3>'.$alasan.'</td</tr>';
|
|
$baris6 = '<tr><td><b>Eksekutor</b></td><td colspan=3>'.Session('nama').'</td</tr></table>';
|
|
$perubahan = $baris1.$baris2.$baris3.$baris4.$baris5.$baris6;
|
|
Xfiles::create([
|
|
'xmarking' => 'SIMBHP-'.$postujuan.'-'.time(),
|
|
'xtabel' => 'History SIMBHP',
|
|
'xjenis' => '',
|
|
'xfile' => $perubahan
|
|
]);
|
|
}
|
|
} else {
|
|
if ($alasan == ''){
|
|
return response()->json(['icon' => 'error', 'warna' => '#bf441d', 'status' => 'Gagal', 'message' => 'Alasan Perubahan Data Wajib Di Isi!!!']);
|
|
}
|
|
else {
|
|
$rdatalama = SIMBHPReport::where('id', $postujuan)->first();
|
|
$ldeskripsi = $rdatalama->deskripsi;
|
|
$lpemasukan = $rdatalama->pemasukan;
|
|
$lpengeluaran = $rdatalama->pengeluaran;
|
|
$ljenis = $rdatalama->jenis;
|
|
$marking = $rdatalama->marking;
|
|
if ($lpengeluaran == '' or $lpengeluaran == 0) {
|
|
$ltotal = number_format( $lpemasukan , 0 , '.' , ',' );
|
|
} else {
|
|
$ltotal = number_format( $lpengeluaran , 0 , '.' , ',' );
|
|
}
|
|
$baris1 = '<table class="table table-bordered table-striped"><tr><td colspan=2><p align=center><b>Data Lama</b></p></td><td colspan=2><p align=center><b>Data Perubahan</b></p></td></tr>';
|
|
$baris2 = '<tr><td>Deskripsi</td><td>'.$ldeskripsi.'</td><td colspan=2><font color=red>DIHAPUS</font></td></tr>';
|
|
$baris3 = '<tr><td>Jenis</td><td>'.$ljenis.'</td><td colspan=2><font color=red>DIHAPUS</font></td></tr>';
|
|
$baris4 = '<tr><td>Total</td><td>'.$ltotal.'</td><td colspan=2><font color=red>DIHAPUS</font></td></tr>';
|
|
$baris5 = '<tr><td><b>Dengan Alasan</b></td><td colspan=3>'.$alasan.'</td</tr>';
|
|
$baris6 = '<tr><td><b>Eksekutor</b></td><td colspan=3>'.Session('nama').'</td</tr></table>';
|
|
$perubahan = $baris1.$baris2.$baris3.$baris4.$baris5.$baris6;
|
|
|
|
Xfiles::create([
|
|
'xmarking' => 'SIMBHP-'.$postujuan.'-'.time(),
|
|
'xtabel' => 'History SIMBHP',
|
|
'xjenis' => '',
|
|
'xfile' => $perubahan
|
|
]);
|
|
if ($marking != ''){
|
|
$bayar = SIMBHPReport::where('marking', $marking)->delete();
|
|
} else {
|
|
$bayar = SIMBHPReport::where('id', $postujuan)->delete();
|
|
}
|
|
}
|
|
}
|
|
if ($bayar){
|
|
return response()->json(['status' => 'Success', 'message' => 'Transaksi '.$jenis.' Sukses Dilaksanakan']);
|
|
} else {
|
|
return response()->json(['icon' => 'error', 'warna' => '#bf441d', 'status' => 'Gagal', 'message' => 'Update Gagal, Pastikan Data Yang anda Isi Sudah Sesuai']);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
return response()->json(['icon' => 'error', 'warna' => '#bf441d', 'status' => 'Gagal', 'message' => 'Pastikan Formnya Anda Isi dengan Lengkap']);
|
|
}
|
|
}
|
|
|
|
public function exKwitansi(Request $request)
|
|
{
|
|
return response()->json([
|
|
'status' => 'Info',
|
|
'message' => 'Fitur kwitansi gudang belum diaktifkan pada versi ini.'
|
|
]);
|
|
}
|
|
|
|
private function calculateBaseQty($jenisNama, $qtyInput, $satuanTransaksi = 'besar')
|
|
{
|
|
$qtyInput = (int) $qtyInput;
|
|
if ($qtyInput < 0) { $qtyInput = 0; }
|
|
$setting = $this->getJenisUnitSetting($jenisNama);
|
|
$konversi = (int) $setting['konversi'];
|
|
if ($konversi <= 0) { $konversi = 1; }
|
|
|
|
if ($satuanTransaksi === 'kecil') {
|
|
return $qtyInput;
|
|
}
|
|
|
|
return $qtyInput * $konversi;
|
|
}
|
|
|
|
private function getJenisUnitSetting($jenisNama)
|
|
{
|
|
$jenis = SIMBHPJenis::where('jenis', $jenisNama)->first();
|
|
$satuanKecil = trim((string) ($jenis->satuan_kecil ?? ''));
|
|
$konversi = (int) ($jenis->konversi_kecil ?? 1);
|
|
if ($konversi <= 0) { $konversi = 1; }
|
|
$hasBreakdown = ($satuanKecil !== '' && $konversi > 1);
|
|
|
|
return [
|
|
'has_breakdown' => $hasBreakdown,
|
|
'konversi' => $konversi,
|
|
'satuan_kecil' => $satuanKecil,
|
|
];
|
|
}
|
|
|
|
private function getStockBaseByJenis($jenisNama)
|
|
{
|
|
$rows = SIMBHPReport::where('jenis', $jenisNama)->get();
|
|
$masuk = 0;
|
|
$keluar = 0;
|
|
foreach ($rows as $row) {
|
|
if (!is_null($row->pemasukan) && (int)$row->pemasukan > 0) {
|
|
$masuk += $this->extractBaseQty($row, 'pemasukan');
|
|
}
|
|
if (!is_null($row->pengeluaran) && (int)$row->pengeluaran > 0) {
|
|
$keluar += $this->extractBaseQty($row, 'pengeluaran');
|
|
}
|
|
}
|
|
|
|
return $masuk - $keluar;
|
|
}
|
|
|
|
private function extractBaseQty($row, $direction = 'pemasukan')
|
|
{
|
|
if (!is_null($row->qty_base) && (int)$row->qty_base > 0) {
|
|
return (int) $row->qty_base;
|
|
}
|
|
|
|
if ($direction === 'pengeluaran') {
|
|
return (int) ($row->pengeluaran ?? 0);
|
|
}
|
|
|
|
return (int) ($row->pemasukan ?? 0);
|
|
}
|
|
|
|
private function formatStockDisplay($saldoBase, $satuanBesar, $satuanKecil, $konversi)
|
|
{
|
|
$saldoBase = (int) $saldoBase;
|
|
$konversi = (int) $konversi;
|
|
if ($konversi <= 1 || $satuanKecil == '') {
|
|
return number_format($saldoBase, 0, '.', ',').' '.$satuanBesar;
|
|
}
|
|
|
|
$besar = intdiv($saldoBase, $konversi);
|
|
$kecil = $saldoBase % $konversi;
|
|
|
|
return number_format($besar, 0, '.', ',').' '.$satuanBesar.' + '.number_format($kecil, 0, '.', ',').' '.$satuanKecil;
|
|
}
|
|
|
|
private function getLowStockWarnings()
|
|
{
|
|
$warnings = [];
|
|
$allJenis = SIMBHPJenis::orderBy('jenis', 'ASC')->get();
|
|
foreach ($allJenis as $item) {
|
|
$saldoBase = $this->getStockBaseByJenis($item->jenis);
|
|
$minimum = (int) ($item->stok_minimum ?? 0);
|
|
if ($saldoBase <= $minimum) {
|
|
$warnings[] = [
|
|
'jenis' => $item->jenis,
|
|
'saldo' => $this->formatStockDisplay(
|
|
$saldoBase,
|
|
$item->satuan,
|
|
$item->satuan_kecil ?? '',
|
|
$item->konversi_kecil ?? 1
|
|
),
|
|
'minimum' => $minimum,
|
|
'satuan_kecil' => $item->satuan_kecil ?: $item->satuan,
|
|
];
|
|
}
|
|
}
|
|
|
|
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');
|
|
$d = (int) date('d', strtotime($now));
|
|
$m = (int) date('m', strtotime($now));
|
|
$y = (int) date('Y', strtotime($now));
|
|
|
|
$query = SIMBHPReport::query();
|
|
if ($scope === 'harian') {
|
|
$query->where('tanggal', $d)->where('bulan', $m)->where('tahun', $y);
|
|
} elseif ($scope === 'bulanan') {
|
|
$query->where('bulan', $m)->where('tahun', $y);
|
|
} else {
|
|
$query->where('tahun', $y);
|
|
}
|
|
|
|
$rows = $query->get();
|
|
$total = 0;
|
|
foreach ($rows as $row) {
|
|
if ($direction === 'pemasukan' && !is_null($row->pemasukan) && (int)$row->pemasukan > 0) {
|
|
$total += $this->extractBaseQty($row, 'pemasukan');
|
|
}
|
|
if ($direction === 'pengeluaran' && !is_null($row->pengeluaran) && (int)$row->pengeluaran > 0) {
|
|
$total += $this->extractBaseQty($row, 'pengeluaran');
|
|
}
|
|
}
|
|
|
|
return $total;
|
|
}
|
|
|
|
private function getUsagePerJenis($scope = 'harian')
|
|
{
|
|
$now = date('Y-m-d');
|
|
$d = (int) date('d', strtotime($now));
|
|
$m = (int) date('m', strtotime($now));
|
|
$y = (int) date('Y', strtotime($now));
|
|
|
|
$query = SIMBHPReport::query();
|
|
if ($scope === 'harian') {
|
|
$query->where('tanggal', $d)->where('bulan', $m)->where('tahun', $y);
|
|
} elseif ($scope === 'bulanan') {
|
|
$query->where('bulan', $m)->where('tahun', $y);
|
|
} else {
|
|
$query->where('tahun', $y);
|
|
}
|
|
|
|
$rows = $query->get();
|
|
$grouped = [];
|
|
$jenisNames = [];
|
|
foreach ($rows as $row) {
|
|
$jenis = $row->jenis ?: 'Tidak Diketahui';
|
|
if (!isset($grouped[$jenis])) {
|
|
$grouped[$jenis] = ['jenis' => $jenis, 'masuk' => 0, 'keluar' => 0, 'sisa' => 0];
|
|
$jenisNames[] = $jenis;
|
|
}
|
|
if (!is_null($row->pemasukan) && (int)$row->pemasukan > 0) {
|
|
$grouped[$jenis]['masuk'] += $this->extractBaseQty($row, 'pemasukan');
|
|
}
|
|
if (!is_null($row->pengeluaran) && (int)$row->pengeluaran > 0) {
|
|
$grouped[$jenis]['keluar'] += $this->extractBaseQty($row, 'pengeluaran');
|
|
}
|
|
}
|
|
|
|
if (!empty($jenisNames)) {
|
|
$stockMap = app(SimbhpStockService::class)->getStockBaseByJenisMany($jenisNames);
|
|
foreach ($grouped as $jenis => &$item) {
|
|
$item['sisa'] = (int) ($stockMap[$jenis] ?? 0);
|
|
}
|
|
unset($item);
|
|
}
|
|
|
|
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 = [];
|
|
$items = SIMBHPJenis::orderBy('jenis', 'ASC')->get();
|
|
foreach ($items as $item) {
|
|
$saldoBase = $this->getStockBaseByJenis($item->jenis);
|
|
$konversi = (int) ($item->konversi_kecil ?? 1);
|
|
if ($konversi <= 0) { $konversi = 1; }
|
|
$rows[] = [
|
|
'id' => $item->id,
|
|
'kodejenis' => $item->kodejenis ?? '',
|
|
'jenis' => $item->jenis,
|
|
'satuan' => $item->satuan,
|
|
'satuan_kecil' => $item->satuan_kecil ?? '',
|
|
'konversi_kecil' => $konversi,
|
|
'stok_minimum' => (int) ($item->stok_minimum ?? 0),
|
|
'saldo' => $this->formatStockDisplay($saldoBase, $item->satuan, $item->satuan_kecil ?? '', $konversi),
|
|
'warning' => ($saldoBase <= (int) ($item->stok_minimum ?? 0)) ? 'YA' : 'TIDAK',
|
|
];
|
|
}
|
|
|
|
return $rows;
|
|
}
|
|
}
|