web-dinda-private/app/Http/Controllers/TransaksiController.php

388 lines
15 KiB
PHP

<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;
use App\Models\Transaksi;
use App\Models\Barang;
use App\Models\BarangProduk;
use App\Models\BarangPendukung;
use App\Models\Supplier;
use App\Models\Pemasukan;
use App\Models\Pengeluaran;
use Illuminate\Http\Request;
use App\Exports\LaporanTransaksiExport;
use Maatwebsite\Excel\Facades\Excel;
use Barryvdh\DomPDF\Facade\Pdf;
class TransaksiController extends Controller
{
public function index(Request $request)
{
$query = Transaksi::with([
'barang.produk',
'barang.pendukung',
'supplier',
'pemasukan',
'pengeluaran',
'historyGajiKloter',
]);
// filter tanggal jika diisi
if ($request->filled('tanggal_mulai') && $request->filled('tanggal_akhir')) {
$query->whereBetween('waktu_transaksi', [
$request->tanggal_mulai . ' 00:00:00',
$request->tanggal_akhir . ' 23:59:59'
]);
// lanjutkan kebawah nya jika ingin menganti default dengan bulan ini
// } else {
// // Default: bulan ini
// $query->whereBetween('waktu_transaksi', [
// now()->startOfMonth(),
// now()->endOfMonth()
// ]);
}
$transaksis = $query->orderBy('waktu_transaksi')->get(); // Di urut dari terlama ke terbaru
// $transaksis = $query->latest('waktu_transaksi')->get(); // Di urut dari terbaru ke terlama
$totalSebelumnya = 0;
$data = $transaksis->map(function ($trx) use (&$totalSebelumnya) {
$kodeBarang = $trx->barang->produk->kode ?? $trx->barang->pendukung->kode ?? '-';
$masuk = $trx->pemasukan_id ? $trx->jumlahRp : 0;
$keluar = $trx->pengeluaran_id ? $trx->jumlahRp : 0;
$totalSekarang = $totalSebelumnya + $masuk - $keluar;
$totalSebelumnya = $totalSekarang;
// Jika transaksi berasal dari history gaji kloter
$namaTransaksi = $trx->historyGajiKloter
? 'Pembayaran Gaji Kloter #' . $trx->historyGajiKloter->id
: ($trx->barang->nama_barang ?? '-');
return [
'id' => $trx->id,
'barang_id' => $trx->barang_id,
// 'transaksi_id' => $trx->id,
'supplier_id' => $trx->supplier_id,
'pemasukan_id' => $trx->pemasukan_id,
'pengeluaran_id' => $trx->pengeluaran_id,
'kategori' => $trx->kategori,
'waktu' => $trx->waktu_transaksi,
'kode_transaksi' => $trx->pemasukan->kode ?? $trx->pengeluaran->kode ?? '-',
'kode_barang' => $kodeBarang,
'supplier' => $trx->supplier->nama ?? '-',
'barangs' => $namaTransaksi,
'nama_barang' => $namaTransaksi,
'qty' => $trx->qtyHistori ?? 0, // akan mengambil dari qtyHistori pada tb transaksi
'masuk' => $masuk,
'keluar' => $keluar,
'total' => $totalSekarang,
'jumlahRp' => $trx->jumlahRp,
'satuan' => $trx->satuan,
'waktu_transaksi' => $trx->waktu_transaksi,
];
})->reverse()->values(); //akan membalik urutan perhitungan total data transaksi
// kategori dan tipe barang
$kategori = $request->input('kategori', 'pengeluaran'); // default ke pemasukan
$tipe = $kategori === 'pengeluaran' ? 'pendukung' : 'produk'; // otomatis
// $barangs = Barang::with($tipe)->whereHas($tipe)->get(); // ambil semua barang sesuai tipe
$barangs = Barang::with(['produk', 'pendukung'])->get()->map(function ($b) {
// Tentukan tipe berdasarkan relasi yang ada
if ($b->produk) {
$b->tipe = 'produk';
} elseif ($b->pendukung) {
$b->tipe = 'pendukung';
} else {
$b->tipe = null;
}
return $b;
});
$suppliers = Supplier::with(['pemasok', 'konsumen'])->get(); // ambil semua supplier
$pemasoks = Supplier::whereHas('pemasok')->get();
$konsumens = Supplier::whereHas('konsumen')->get();
$kardusList = Barang::with('kardus')->get()->flatMap(function ($barang) {
return $barang->kardus;
});
// dd($kategori, $tipe, $barangs->pluck('nama_barang')); // debug untuk melihat kategori, tipe, dan nama barang
return view('operator.transaksi.index', [
'data' => $data,
'barangs' => $barangs,
'suppliers' => $suppliers,
'pemasoks' => $pemasoks,
'konsumens' => $konsumens,
'kardusList' => $kardusList,
]);
}
public function store(Request $request)
{
$request->validate([
'kategori' => 'required|in:pemasukan,pengeluaran',
'barang_id' => 'required|exists:barangs,id',
'supplier_id' => 'required|exists:suppliers,id',
'qtyHistori' => 'required|numeric|min:1',
'jumlahRp' => 'nullable|numeric|min:0',
'satuan' => 'required|in:ton,kg,g,liter,paket',
'jenis_kardus' => 'nullable|exists:barangs,id',
'jumlah_kardus' => 'nullable|numeric|min:0',
]);
DB::beginTransaction();
try {
$barang = Barang::findOrFail($request->barang_id);
$kategori = $request->kategori;
$qtyHistori = $request->qtyHistori;
$jumlahRp = $request->jumlahRp;
$satuan = $request->satuan;
$waktu = Carbon::now();
// Konversi satuan ke KG
$qty_kg = match($satuan) {
'ton' => $qtyHistori * 1000,
'kg' => $qtyHistori,
'g' => $qtyHistori / 1000,
default => $qtyHistori // liter dan paket tidak dikonversi
};
$hargaKardus = 0;
if ($request->filled('jenis_kardus') && $request->jumlah_kardus > 0) {
$kardus = Barang::find($request->jenis_kardus);
if ($kardus) {
$hargaKardus = $kardus->harga * $request->jumlah_kardus;
// Kurangi stok kardus
$kardus->qty -= $request->jumlah_kardus;
$kardus->save();
}
}
// Variabel untuk ID
$pemasukan_id = null;
$pengeluaran_id = null;
if ($kategori === 'pemasukan') {
// Buat kode pemasukan
$last = Pemasukan::latest('id')->first();
$nextNumber = $last ? $last->id + 1 : 1;
$kode = 'MSK' . str_pad($nextNumber, 3, '0', STR_PAD_LEFT);
$pemasukan = Pemasukan::create(['kode' => $kode]);
$pemasukan_id = $pemasukan->id;
// Barang dikurangi
$barang->qty -= $qty_kg;
$barang->save();
// Cek stok cukup
if ($barang->qty < $qty_kg) {
return back()->withInput()->withErrors(['qtyHistori' => 'Stok barang tidak mencukupi.']);
}
// Hitung jumlahRp jika kosong
$jumlahRp = $jumlahRp ?: ($barang->harga * $qty_kg);
$jumlahRp += $hargaKardus;
} elseif ($kategori === 'pengeluaran') {
// Buat kode pengeluaran
$last = Pengeluaran::latest('id')->first();
$nextNumber = $last ? $last->id + 1 : 1;
$kode = 'KLR' . str_pad($nextNumber, 3, '0', STR_PAD_LEFT);
$pengeluaran = Pengeluaran::create(['kode' => $kode]);
$pengeluaran_id = $pengeluaran->id;
// Barang dikurangi
$barang->qty += $qty_kg;
$barang->save();
// if ($jumlahRp && $qty_kg > 0) {
// $barang->harga = $jumlahRp / $qty_kg;
// $barang->save();
// }
if ($jumlahRp && $qty_kg > 0) {
$hargaBarangSaja = $jumlahRp - $hargaKardus;
if ($hargaBarangSaja > 0) {
$barang->harga = $hargaBarangSaja / $qty_kg;
$barang->save();
}
}
}
// Simpan transaksi
Transaksi::create([
'kategori' => $kategori,
'barang_id' => $barang->id,
'supplier_id' => $request->supplier_id,
'pemasukan_id' => $pemasukan_id,
'pengeluaran_id' => $pengeluaran_id,
'qtyHistori' => $qty_kg,
'jumlahRp' => $jumlahRp,
'satuan' => $satuan,
'waktu_transaksi' => $waktu,
'keterangan' => json_encode([
'jenis_kardus_id' => $request->jenis_kardus,
'jumlah_kardus' => $request->jumlah_kardus,
]),
]);
DB::commit();
return redirect()->route('operator.transaksi.index')->with('success', 'Transaksi berhasil disimpan.');
} catch (\Throwable $th) {
DB::rollBack();
return back()->withInput()->withErrors(['error' => 'Gagal menyimpan transaksi: ' . $th->getMessage()]);
}
}
public function update(Request $request, $id)
{
$request->validate([
'kategori' => 'required|in:pemasukan,pengeluaran',
'barang_id' => 'required|exists:barangs,id',
'supplier_id' => 'required|exists:suppliers,id',
'qtyHistori' => 'required|numeric|min:1',
'jumlahRp' => 'nullable|numeric|min:0',
'waktu_transaksi' => 'nullable|date',
'satuan' => 'required|in:ton,kg,g,liter,paket',
'jenis_kardus' => 'nullable|exists:barangs,id',
'jumlah_kardus' => 'nullable|numeric|min:0',
]);
DB::beginTransaction();
try {
$transaksi = Transaksi::findOrFail($id);
$barang = Barang::findOrFail($request->barang_id);
// Kembalikan stok barang sebelumnya
if ($transaksi->kategori === 'pengeluaran') {
$barang->qty -= $transaksi->qtyHistori;
} else {
$barang->qty += $transaksi->qtyHistori;
}
// Ambil data kardus lama dari keterangan dan kembalikan stok
$keteranganLama = json_decode($transaksi->keterangan, true) ?? [];
$jenisKardusLamaId = $keteranganLama['jenis_kardus_id'] ?? null;
$jumlahKardusLama = $keteranganLama['jumlah_kardus'] ?? 0;
if ($jenisKardusLamaId && $jumlahKardusLama > 0) {
Barang::where('id', $jenisKardusLamaId)->increment('qty', $jumlahKardusLama);
}
// Hitung qty dalam kg
$qty = $request->qtyHistori;
$satuan = $request->satuan;
$qty_kg = match($satuan) {
'ton' => $qty * 1000,
'kg' => $qty,
'g' => $qty / 1000,
default => $qty,
};
// Hitung harga kardus baru
$hargaKardus = 0;
if ($request->filled('jenis_kardus') && $request->jumlah_kardus > 0) {
$kardusBaru = Barang::find($request->jenis_kardus);
if ($kardusBaru) {
$hargaKardus = $kardusBaru->harga * $request->jumlah_kardus;
$kardusBaru->qty -= $request->jumlah_kardus;
$kardusBaru->save();
}
}
// Hitung ulang stok & harga barang
if ($request->kategori === 'pengeluaran') {
$barang->qty += $qty_kg;
} else {
if ($barang->qty < $qty_kg) {
return back()->withErrors(['qtyHistori' => 'Stok barang tidak mencukupi untuk pemasukan.']);
}
$barang->qty -= $qty_kg;
// Hitung harga barang (tidak termasuk kardus)
if ($request->jumlahRp && $qty_kg > 0) {
$hargaBarangSaja = $request->jumlahRp - $hargaKardus;
if ($hargaBarangSaja > 0) {
$barang->harga = $hargaBarangSaja / $qty_kg;
}
}
}
$barang->save();
// Hitung total jumlah Rp termasuk kardus
$jumlahRp = $request->jumlahRp ?: ($barang->harga * $qty_kg);
$jumlahRp += $hargaKardus;
// Simpan perubahan transaksi
$transaksi->update([
'barang_id' => $barang->id,
'supplier_id' => $request->supplier_id,
'kategori' => $request->kategori,
'jumlahRp' => $jumlahRp,
'qtyHistori' => $qty,
'satuan' => $satuan,
'waktu_transaksi' => $request->waktu_transaksi,
'keterangan' => json_encode([
'jenis_kardus_id' => $request->jenis_kardus,
'jumlah_kardus' => $request->jumlah_kardus,
])
]);
DB::commit();
return redirect()->route('operator.transaksi.index')->with('success', 'Transaksi berhasil diperbarui.');
} catch (\Throwable $th) {
DB::rollBack();
return back()->withInput()->withErrors(['error' => 'Gagal memperbarui transaksi: ' . $th->getMessage()]);
}
}
public function destroy($id)
{
$transaksi = Transaksi::findOrFail($id);
$transaksi->delete();
return redirect()->route('operator.transaksi.index')->with('success', 'Data transaksi berhasil dihapus.');
}
public function exportExcel(Request $request)
{
$tanggalMulai = $request->tanggal_mulai;
$tanggalAkhir = $request->tanggal_akhir;
$q = $request->q; // Optional, untuk pencarian
$filename = 'laporan_transaksi_operator_' . now()->format('Ymd_His') . '.xlsx';
return Excel::download(new LaporanTransaksiExport($tanggalMulai, $tanggalAkhir, $q), $filename);
}
public function exportPDF(Request $request)
{
$tanggalMulai = $request->tanggal_mulai;
$tanggalAkhir = $request->tanggal_akhir;
$q = $request->q;
// Ambil data transaksi dengan class export
$export = new LaporanTransaksiExport($tanggalMulai, $tanggalAkhir, $q);
$data = $export->collection(); // Ini sudah dalam format collection map
$pdf = Pdf::loadView('operator.transaksi.pdf', [
'data' => $data,
'tanggalMulai' => $tanggalMulai,
'tanggalAkhir' => $tanggalAkhir,
'q' => $q
])->setPaper('a4', 'landscape');
return $pdf->download('laporan_transaksi_operator_' . now()->format('Ymd_His') . '.pdf');
}
}