update
This commit is contained in:
@@ -347,6 +347,238 @@ class GudangController extends Controller
|
||||
return response()->json($response, 200);
|
||||
}
|
||||
|
||||
public function jsonExpiredBatches(Request $request)
|
||||
{
|
||||
if (Session::get('previlage') == '') {
|
||||
return response()->json(['message' => 'Unauthorized'], 401);
|
||||
}
|
||||
|
||||
$jenis = trim((string) $request->query('jenis', ''));
|
||||
$query = SIMBHPReport::whereNotNull('pemasukan')
|
||||
->where('pemasukan', '>', 0);
|
||||
|
||||
if ($jenis !== '') {
|
||||
$query->where('jenis', $jenis);
|
||||
}
|
||||
|
||||
$rows = $query->orderByRaw('masa_expired IS NULL ASC')
|
||||
->orderBy('masa_expired', 'ASC')
|
||||
->orderBy('id', 'DESC')
|
||||
->limit(100)
|
||||
->get();
|
||||
|
||||
$items = [];
|
||||
foreach ($rows as $row) {
|
||||
$items[] = [
|
||||
'id' => $row->id,
|
||||
'jenis' => $row->jenis,
|
||||
'deskripsi' => $row->deskripsi ?: '-',
|
||||
'tanggal_masuk' => sprintf('%02d-%02d-%04d', (int) $row->tanggal, (int) $row->bulan, (int) $row->tahun),
|
||||
'qty' => (int) ($row->pemasukan ?? 0),
|
||||
'satuan' => $row->satuan_transaksi ?: 'besar',
|
||||
'masa_expired' => $row->masa_expired ? date('d-m-Y', strtotime((string) $row->masa_expired)) : '',
|
||||
];
|
||||
}
|
||||
|
||||
return response()->json(['data' => $items]);
|
||||
}
|
||||
|
||||
public function updateExpiredBatch(Request $request)
|
||||
{
|
||||
if (Session::get('previlage') == '') {
|
||||
return response()->json(['message' => 'Unauthorized'], 401);
|
||||
}
|
||||
|
||||
$batchId = (int) $request->input('batch_id');
|
||||
$masaExpired = $this->normalizeDateInput($request->input('masa_expired'));
|
||||
$alasan = trim((string) $request->input('alasan', 'Update expired barang terbuka'));
|
||||
|
||||
if ($batchId <= 0 || is_null($masaExpired)) {
|
||||
return response()->json(['icon' => 'error', 'warna' => '#bf441d', 'status' => 'Gagal', 'message' => 'Batch dan tanggal expired baru wajib diisi']);
|
||||
}
|
||||
|
||||
$row = SIMBHPReport::where('id', $batchId)
|
||||
->whereNotNull('pemasukan')
|
||||
->where('pemasukan', '>', 0)
|
||||
->first();
|
||||
|
||||
if (!$row) {
|
||||
return response()->json(['icon' => 'error', 'warna' => '#bf441d', 'status' => 'Gagal', 'message' => 'Batch barang masuk tidak ditemukan']);
|
||||
}
|
||||
|
||||
$oldExpired = $row->masa_expired;
|
||||
$keterangan = trim((string) ($row->keterangan ?? ''));
|
||||
$suffix = 'Expired dibuka: '.($oldExpired ?: '-').' -> '.$masaExpired;
|
||||
if ($alasan !== '') {
|
||||
$suffix .= ' | '.$alasan;
|
||||
}
|
||||
|
||||
$row->masa_expired = $masaExpired;
|
||||
$row->keterangan = $keterangan !== '' ? $keterangan.' | '.$suffix : $suffix;
|
||||
$row->updated_at = date("Y-m-d H:i:s");
|
||||
$row->save();
|
||||
|
||||
return response()->json(['status' => 'Success', 'message' => 'Masa expired batch berhasil diupdate']);
|
||||
}
|
||||
|
||||
public function storeRacikan(Request $request)
|
||||
{
|
||||
if (Session::get('previlage') == '') {
|
||||
return response()->json(['message' => 'Unauthorized'], 401);
|
||||
}
|
||||
|
||||
$tanggal = trim((string) $request->input('tanggal', date('Y-m-d')));
|
||||
$namaRacikan = trim((string) $request->input('nama_racikan', 'Racikan'));
|
||||
$statusRacikan = strtolower(trim((string) $request->input('status_racikan', 'berhasil')));
|
||||
$bahan = $request->input('bahan', []);
|
||||
if (is_string($bahan)) {
|
||||
$decoded = json_decode($bahan, true);
|
||||
$bahan = is_array($decoded) ? $decoded : [];
|
||||
}
|
||||
|
||||
if ($tanggal === '') {
|
||||
$tanggal = date('Y-m-d');
|
||||
}
|
||||
if ($namaRacikan === '') {
|
||||
$namaRacikan = 'Racikan';
|
||||
}
|
||||
if (!in_array($statusRacikan, ['berhasil', 'rusak'], true)) {
|
||||
return response()->json(['icon' => 'error', 'warna' => '#bf441d', 'status' => 'Gagal', 'message' => 'Status racikan tidak valid']);
|
||||
}
|
||||
if (!is_array($bahan) || count($bahan) === 0) {
|
||||
return response()->json(['icon' => 'error', 'warna' => '#bf441d', 'status' => 'Gagal', 'message' => 'Minimal satu bahan racikan wajib diisi']);
|
||||
}
|
||||
|
||||
$parts = explode('-', $tanggal);
|
||||
$tahun = (int) ($parts[0] ?? date('Y'));
|
||||
$wulan = (int) ($parts[1] ?? date('m'));
|
||||
$dino = (int) ($parts[2] ?? date('d'));
|
||||
$marking = 'RACIK-'.date('YmdHis').'-'.random_int(100, 999);
|
||||
|
||||
try {
|
||||
DB::transaction(function () use ($request, $bahan, $statusRacikan, $namaRacikan, $marking, $dino, $wulan, $tahun) {
|
||||
$service = app(SimbhpStockService::class);
|
||||
$prepared = [];
|
||||
$requiredByJenis = [];
|
||||
|
||||
foreach ($bahan as $line) {
|
||||
$jenisNama = trim((string) ($line['jenis'] ?? ''));
|
||||
$qty = (int) str_replace(',', '', (string) ($line['qty'] ?? 0));
|
||||
$satuanTransaksi = (string) ($line['satuan_transaksi'] ?? 'besar');
|
||||
if (!in_array($satuanTransaksi, ['besar', 'kecil'], true)) {
|
||||
$satuanTransaksi = 'besar';
|
||||
}
|
||||
if ($jenisNama === '' || $qty <= 0) {
|
||||
throw new \InvalidArgumentException('Bahan dan jumlah wajib diisi');
|
||||
}
|
||||
|
||||
$jenis = SIMBHPJenis::where('jenis', $jenisNama)->first();
|
||||
if (!$jenis) {
|
||||
throw new \InvalidArgumentException('Bahan '.$jenisNama.' tidak ditemukan');
|
||||
}
|
||||
$setting = $service->getUnitSetting($jenis);
|
||||
if ($satuanTransaksi === 'kecil' && !($setting['has_breakdown'] ?? false)) {
|
||||
throw new \InvalidArgumentException('Satuan kecil tidak tersedia untuk '.$jenisNama);
|
||||
}
|
||||
|
||||
$qtyBase = $service->calculateBaseQty($jenis, $qty, $satuanTransaksi);
|
||||
$requiredByJenis[$jenisNama] = ($requiredByJenis[$jenisNama] ?? 0) + $qtyBase;
|
||||
$prepared[] = [
|
||||
'jenis' => $jenis,
|
||||
'qty' => $qty,
|
||||
'qty_base' => $qtyBase,
|
||||
'satuan_transaksi' => $satuanTransaksi,
|
||||
'batch_id' => (int) ($line['batch_id'] ?? 0),
|
||||
'expired_baru' => $this->normalizeDateInput($line['expired_baru'] ?? null),
|
||||
];
|
||||
}
|
||||
|
||||
foreach ($requiredByJenis as $jenisNama => $requiredBase) {
|
||||
$stok = $service->getStockBaseByJenis($jenisNama);
|
||||
if ($requiredBase > $stok) {
|
||||
throw new \InvalidArgumentException('Stok bahan '.$jenisNama.' tidak cukup');
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($prepared as $line) {
|
||||
$keterangan = $statusRacikan === 'berhasil' ? 'Bahan racikan berhasil' : 'Bahan racikan rusak';
|
||||
if ($line['expired_baru'] && $line['batch_id'] > 0) {
|
||||
$batch = SIMBHPReport::where('id', $line['batch_id'])
|
||||
->where('jenis', $line['jenis']->jenis)
|
||||
->whereNotNull('pemasukan')
|
||||
->where('pemasukan', '>', 0)
|
||||
->first();
|
||||
if (!$batch) {
|
||||
throw new \InvalidArgumentException('Batch expired untuk '.$line['jenis']->jenis.' tidak ditemukan');
|
||||
}
|
||||
$oldExpired = $batch->masa_expired;
|
||||
$oldKeterangan = trim((string) ($batch->keterangan ?? ''));
|
||||
$expiredNote = 'Expired dibuka racikan '.$marking.': '.($oldExpired ?: '-').' -> '.$line['expired_baru'];
|
||||
$batch->masa_expired = $line['expired_baru'];
|
||||
$batch->keterangan = $oldKeterangan !== '' ? $oldKeterangan.' | '.$expiredNote : $expiredNote;
|
||||
$batch->updated_at = date("Y-m-d H:i:s");
|
||||
$batch->save();
|
||||
$keterangan .= ' | Expired dibuka: '.($oldExpired ?: '-').' -> '.$line['expired_baru'];
|
||||
}
|
||||
|
||||
SIMBHPReport::create([
|
||||
'tanggal' => $dino,
|
||||
'bulan' => $wulan,
|
||||
'tahun' => $tahun,
|
||||
'deskripsi' => 'Racikan '.$namaRacikan.' - bahan',
|
||||
'pemasukan' => null,
|
||||
'pengeluaran' => $line['qty'],
|
||||
'qty_base' => $line['qty_base'],
|
||||
'satuan_transaksi' => $line['satuan_transaksi'],
|
||||
'jenis' => $line['jenis']->jenis,
|
||||
'keterangan' => $keterangan,
|
||||
'marking' => $marking,
|
||||
]);
|
||||
}
|
||||
|
||||
if ($statusRacikan === 'berhasil') {
|
||||
$hasil = $this->resolveRacikanOutputJenis($request);
|
||||
$qtyHasil = (int) str_replace(',', '', (string) $request->input('hasil_qty', 0));
|
||||
$satuanHasil = (string) $request->input('hasil_satuan_transaksi', 'besar');
|
||||
if (!in_array($satuanHasil, ['besar', 'kecil'], true)) {
|
||||
$satuanHasil = 'besar';
|
||||
}
|
||||
if ($qtyHasil <= 0) {
|
||||
throw new \InvalidArgumentException('Jumlah hasil racikan wajib diisi');
|
||||
}
|
||||
$setting = $service->getUnitSetting($hasil);
|
||||
if ($satuanHasil === 'kecil' && !($setting['has_breakdown'] ?? false)) {
|
||||
throw new \InvalidArgumentException('Satuan kecil tidak tersedia untuk hasil racikan');
|
||||
}
|
||||
$qtyBaseHasil = $service->calculateBaseQty($hasil, $qtyHasil, $satuanHasil);
|
||||
|
||||
SIMBHPReport::create([
|
||||
'tanggal' => $dino,
|
||||
'bulan' => $wulan,
|
||||
'tahun' => $tahun,
|
||||
'deskripsi' => 'Hasil racikan '.$namaRacikan,
|
||||
'pemasukan' => $qtyHasil,
|
||||
'pengeluaran' => null,
|
||||
'qty_base' => $qtyBaseHasil,
|
||||
'satuan_transaksi' => $satuanHasil,
|
||||
'masa_expired' => $this->normalizeDateInput($request->input('hasil_masa_expired')),
|
||||
'jenis' => $hasil->jenis,
|
||||
'keterangan' => 'Hasil racikan berhasil',
|
||||
'marking' => $marking,
|
||||
]);
|
||||
}
|
||||
});
|
||||
} catch (\Throwable $e) {
|
||||
return response()->json(['icon' => 'error', 'warna' => '#bf441d', 'status' => 'Gagal', 'message' => $e->getMessage()]);
|
||||
}
|
||||
|
||||
$message = $statusRacikan === 'berhasil'
|
||||
? 'Racikan berhasil disimpan dan hasil masuk stok'
|
||||
: 'Racikan rusak disimpan sebagai pengurangan bahan';
|
||||
|
||||
return response()->json(['status' => 'Success', 'message' => $message]);
|
||||
}
|
||||
|
||||
public function exAddbarang(Request $request) {
|
||||
$deskripsi = $request->input('set01');
|
||||
$pos = $request->input('set02');
|
||||
@@ -919,6 +1151,82 @@ class GudangController extends Controller
|
||||
return null;
|
||||
}
|
||||
|
||||
private function resolveRacikanOutputJenis(Request $request): SIMBHPJenis
|
||||
{
|
||||
$mode = (string) $request->input('hasil_mode', 'existing');
|
||||
if ($mode === 'new') {
|
||||
$nama = trim((string) $request->input('hasil_new_jenis'));
|
||||
$satuan = trim((string) $request->input('hasil_new_satuan'));
|
||||
$kode = trim((string) $request->input('hasil_new_kode'));
|
||||
$satuanKecil = trim((string) $request->input('hasil_new_satuan_kecil'));
|
||||
$konversi = (int) $request->input('hasil_new_konversi', 1);
|
||||
$stokMinimum = (int) $request->input('hasil_new_stok_minimum', 0);
|
||||
|
||||
if ($nama === '' || $satuan === '') {
|
||||
throw new \InvalidArgumentException('Nama dan satuan hasil racikan baru wajib diisi');
|
||||
}
|
||||
if ($konversi <= 0) {
|
||||
$konversi = 1;
|
||||
}
|
||||
if ($stokMinimum < 0) {
|
||||
$stokMinimum = 0;
|
||||
}
|
||||
if ($satuanKecil !== '' && $konversi <= 1) {
|
||||
throw new \InvalidArgumentException('Konversi hasil racikan baru harus lebih dari 1 jika memakai satuan kecil');
|
||||
}
|
||||
|
||||
if ($kode !== '') {
|
||||
$kode = strtoupper($kode);
|
||||
$kode = preg_replace('/\s+/', '', $kode);
|
||||
$kode = preg_replace('/[^A-Z0-9._-]/', '', $kode);
|
||||
} else {
|
||||
$kode = strtoupper($nama);
|
||||
$kode = preg_replace('/\s+/', '', $kode);
|
||||
$kode = preg_replace('/[^A-Z0-9._-]/', '', $kode);
|
||||
}
|
||||
if ($kode === '' || strlen($kode) < 2 || strlen($kode) > 40) {
|
||||
throw new \InvalidArgumentException('Kode hasil racikan wajib 2-40 karakter');
|
||||
}
|
||||
|
||||
$existing = SIMBHPJenis::where('kodejenis', $kode)->first();
|
||||
if ($existing) {
|
||||
return $existing;
|
||||
}
|
||||
|
||||
$jenis = SIMBHPJenis::create([
|
||||
'kodejenis' => $kode,
|
||||
'jenis' => $nama,
|
||||
'satuan' => $satuan,
|
||||
'satuan_kecil' => $satuanKecil,
|
||||
'konversi_kecil' => $konversi,
|
||||
'stok_minimum' => $stokMinimum,
|
||||
]);
|
||||
|
||||
if (Schema::hasColumn('simbhpjenis', 'barcode_besar')) {
|
||||
$service = app(SimbhpStockService::class);
|
||||
$setting = $service->getUnitSetting($jenis);
|
||||
$jenis->update([
|
||||
'barcode_besar' => $service->makeBarcodeValue((int) $jenis->id, 'besar'),
|
||||
'barcode_kecil' => ($setting['has_breakdown'] ?? false) ? $service->makeBarcodeValue((int) $jenis->id, 'kecil') : null,
|
||||
]);
|
||||
}
|
||||
|
||||
return $jenis;
|
||||
}
|
||||
|
||||
$jenisNama = trim((string) $request->input('hasil_jenis'));
|
||||
if ($jenisNama === '') {
|
||||
throw new \InvalidArgumentException('Barang hasil racikan wajib dipilih');
|
||||
}
|
||||
|
||||
$jenis = SIMBHPJenis::where('jenis', $jenisNama)->first();
|
||||
if (!$jenis) {
|
||||
throw new \InvalidArgumentException('Barang hasil racikan tidak ditemukan');
|
||||
}
|
||||
|
||||
return $jenis;
|
||||
}
|
||||
|
||||
private function getJenisRows()
|
||||
{
|
||||
$rows = [];
|
||||
|
||||
Reference in New Issue
Block a user