From 17892603e8e38c03364f280a13e2dfcde550aaef Mon Sep 17 00:00:00 2001 From: dhilanradya Date: Thu, 11 Sep 2025 16:50:00 +0700 Subject: [PATCH] [feet] struk(blm clear) --- app/Http/Controllers/TransaksiController.php | 93 ++++---- app/Models/Item.php | 1 + app/Models/ItemTransaksi.php | 4 +- resources/js/components/KasirForm.vue | 75 ++++++- resources/js/components/StrukOverlay.vue | 219 +++++++++++++++---- resources/js/pages/Kasir.vue | 21 +- 6 files changed, 322 insertions(+), 91 deletions(-) diff --git a/app/Http/Controllers/TransaksiController.php b/app/Http/Controllers/TransaksiController.php index f79d172..2628dbb 100644 --- a/app/Http/Controllers/TransaksiController.php +++ b/app/Http/Controllers/TransaksiController.php @@ -42,51 +42,64 @@ class TransaksiController extends Controller } // Membuat transaksi baru - public function store(Request $request) - { - $request->validate([ - 'id_kasir' => 'required|exists:akun,id', - 'id_sales' => 'nullable|exists:sales,id', - 'nama_sales' => 'nullable|string', - 'no_hp' => 'nullable|string', - 'alamat' => 'nullable|string', - 'ongkos_bikin' => 'nullable|numeric', - 'total_harga' => 'required|numeric', - 'items' => 'required|array', - 'items.*.id_item' => 'required|exists:item,id', - 'items.*.harga_deal' => 'required|numeric', + public function store(Request $request) +{ + // Ambil user yang login via Sanctum + $kasir = $request->user(); // user authenticated + if (!$kasir) { + return response()->json(['error' => 'Unauthorized'], 401); + } + + // Validasi request (id_kasir dihapus karena otomatis dari token) + $request->validate([ + 'id_sales' => 'nullable|exists:sales,id', + 'nama_sales' => 'required|string', + 'no_hp' => 'required|string', + 'alamat' => 'required|string', + 'ongkos_bikin' => 'nullable|numeric|min:0', + 'total_harga' => 'required|numeric', + 'items' => 'required|array', + 'items.*.id_item' => 'required|exists:items,id', + 'items.*.harga_deal' => 'required|numeric', + ]); + + DB::beginTransaction(); + try { + $transaksi = Transaksi::create([ + 'id_kasir' => $kasir->id, // ambil dari token + 'id_sales' => $request->id_sales, + 'nama_sales' => $request->nama_sales, + 'no_hp' => $request->no_hp, + 'alamat' => $request->alamat, + 'ongkos_bikin' => $request->ongkos_bikin ?? 0, + 'total_harga' => $request->total_harga, ]); - DB::beginTransaction(); - try { - $transaksi = Transaksi::create([ - 'id_kasir' => $request->id_kasir, - 'id_sales' => $request->id_sales, - 'nama_sales' => $request->nama_sales, - 'no_hp' => $request->no_hp, - 'alamat' => $request->alamat, - 'ongkos_bikin' => $request->ongkos_bikin, - 'total_harga' => $request->total_harga, + foreach ($request->items as $it) { + ItemTransaksi::create([ + 'id_transaksi' => $transaksi->id, + 'id_item' => $it['id_item'], + 'harga_deal' => $it['harga_deal'], ]); - foreach ($request->items as $it) { - ItemTransaksi::create([ - 'id_transaksi' => $transaksi->id, - 'id_item' => $it['id_item'], - 'harga_deal' => $it['harga_deal'], - ]); - - Item::where('id', $it['id_item'])->update(['is_sold' => true]); - } - - DB::commit(); - return response()->json($transaksi->load('items'), 201); - - } catch (\Exception $e) { - DB::rollBack(); - return response()->json(['error' => $e->getMessage()], 500); + Item::where('id', $it['id_item'])->update(['is_sold' => true]); } - } + + DB::commit(); + return response()->json( + $transaksi->load(['itemTransaksi.item.produk.foto', 'kasir', 'sales']), + 201 + ); + + } catch (\Exception $e) { + DB::rollBack(); + return response()->json([ + 'error' => $e->getMessage(), + 'trace' => $e->getTrace() + ], 500); +} +} + // Update transaksi public function update(Request $request, $id) diff --git a/app/Models/Item.php b/app/Models/Item.php index fb02e07..ab88fe7 100644 --- a/app/Models/Item.php +++ b/app/Models/Item.php @@ -8,6 +8,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; class Item extends Model { use HasFactory; + protected $table = 'items'; protected $fillable = [ 'id_produk', diff --git a/app/Models/ItemTransaksi.php b/app/Models/ItemTransaksi.php index 994e6e2..b596de9 100644 --- a/app/Models/ItemTransaksi.php +++ b/app/Models/ItemTransaksi.php @@ -11,8 +11,8 @@ class ItemTransaksi extends Model use HasFactory; protected $fillable = [ - 'id_transaksi', - 'id_item', + 'id_transaksi', + 'id_item', 'harga_deal', 'posisi_asal' ]; diff --git a/resources/js/components/KasirForm.vue b/resources/js/components/KasirForm.vue index d3f8345..ddb81ac 100644 --- a/resources/js/components/KasirForm.vue +++ b/resources/js/components/KasirForm.vue @@ -8,6 +8,17 @@ @cancel="closeDeleteModal" /> + + + +
@@ -151,6 +162,9 @@ import { ref, computed } from "vue"; import InputField from "./InputField.vue"; import axios from "axios"; import ConfirmDeleteModal from "./ConfirmDeleteModal.vue"; +// ==== TAMBAHAN: Import StrukOverlay ==== +import StrukOverlay from "./StrukOverlay.vue"; +// ==== END TAMBAHAN ==== const kodeItem = ref(""); const info = ref(""); @@ -162,6 +176,14 @@ const pesanan = ref([]); const showDeleteModal = ref(false) const deleteIndex = ref(null) +// ==== TAMBAHAN: State untuk struk ==== +const showStruk = ref(false); +// ==== END TAMBAHAN ==== + +// ==== TAMBAHAN: Emit untuk parent component ==== +const emit = defineEmits(['transaksi-saved']); +// ==== END TAMBAHAN ==== + let errorTimeout = null; let infoTimeout = null; @@ -259,7 +281,7 @@ const hapusPesanan = () => { closeDeleteModal() } - +// ==== MODIFIKASI: konfirmasiPenjualan sekarang menampilkan struk ==== const konfirmasiPenjualan = () => { if (pesanan.value.length === 0) { error.value = "Belum ada item yang dipesan."; @@ -270,9 +292,56 @@ const konfirmasiPenjualan = () => { return; } - // Todo: Implementasi konfirmasi penjualan - alert("Penjualan dikonfirmasi! (Implementasi lebih lanjut diperlukan)"); + // Tampilkan struk overlay + showStruk.value = true; }; +// ==== END MODIFIKASI ==== + +// ==== TAMBAHAN: Fungsi untuk menutup struk ==== +const closeStruk = () => { + showStruk.value = false; +}; +// ==== END TAMBAHAN ==== + +// ==== TAMBAHAN: Fungsi untuk menyimpan transaksi ==== +const simpanTransaksi = async (dataTransaksi) => { + try { + // Siapkan data untuk API + const transaksiData = { + id_kasir: localStorage.getItem('user_id'), // Asumsi user_id disimpan di localStorage + id_sales: dataTransaksi.selectedSales?.id || null, + nama_sales: dataTransaksi.namaPembeli, + no_hp: dataTransaksi.nomorTelepon, + alamat: dataTransaksi.alamat, + ongkos_bikin: dataTransaksi.ongkosBikin || 0, + total_harga: total.value + (dataTransaksi.ongkosBikin || 0), + items: pesanan.value.map(item => ({ + id_item: item.id, + harga_deal: item.harga_deal + })) + }; + + const response = await axios.post('/api/transaksi', transaksiData, { + headers: { + Authorization: `Bearer ${localStorage.getItem("token")}`, + }, + }); + + // Reset form setelah berhasil + pesanan.value = []; + showStruk.value = false; + + // Emit ke parent untuk refresh data transaksi + emit('transaksi-saved', response.data); + + alert('Transaksi berhasil disimpan!'); + + } catch (error) { + console.error('Error saving transaksi:', error); + alert('Error menyimpan transaksi: ' + (error.response?.data?.message || error.message)); + } +}; +// ==== END TAMBAHAN ==== const total = computed(() => { let sum = 0; diff --git a/resources/js/components/StrukOverlay.vue b/resources/js/components/StrukOverlay.vue index 5f058cf..945c693 100644 --- a/resources/js/components/StrukOverlay.vue +++ b/resources/js/components/StrukOverlay.vue @@ -1,7 +1,7 @@ - - + + diff --git a/resources/js/pages/Kasir.vue b/resources/js/pages/Kasir.vue index 0020cd0..5c7cba4 100644 --- a/resources/js/pages/Kasir.vue +++ b/resources/js/pages/Kasir.vue @@ -10,7 +10,9 @@ class="bg-white rounded-xl shadow-lg border border-B overflow-hidden h-auto lg:h-full" >
- + + +
@@ -82,7 +84,8 @@ import KasirTransaksiList from "../components/KasirTransaksiList.vue"; const transaksi = ref([]); const loading = ref(true); -onMounted(async () => { +// ==== TAMBAHAN: Fungsi untuk fetch transaksi (dipindah ke fungsi terpisah) ==== +const fetchTransaksi = async () => { try { loading.value = true; const res = await axios.get("/api/transaksi?limit=10", { @@ -97,8 +100,22 @@ onMounted(async () => { } finally { loading.value = false; } +}; +// ==== END TAMBAHAN ==== + +onMounted(async () => { + // ==== MODIFIKASI: Panggil fungsi fetchTransaksi ==== + await fetchTransaksi(); + // ==== END MODIFIKASI ==== }); +// ==== TAMBAHAN: Handle ketika transaksi baru disimpan ==== +const handleTransaksiSaved = async (newTransaksi) => { + // Refresh daftar transaksi + await fetchTransaksi(); +}; +// ==== END TAMBAHAN ==== + const lihatDetail = (trx) => { alert(`Detail transaksi: ${trx.kode}`); };