diff --git a/app/Http/Controllers/KategoriController.php b/app/Http/Controllers/KategoriController.php new file mode 100644 index 0000000..1dd4065 --- /dev/null +++ b/app/Http/Controllers/KategoriController.php @@ -0,0 +1,82 @@ +json( + Kategori::withCount('produk')->get() + ); + } + + /** + * Store a newly created resource in storage. + */ + public function store(Request $request) + { + $validated = $request->validate([ + 'nama' => 'required|string|max:100', + ], + [ + 'nama' => 'Nama kategori harus diisi.' + ]); + + Kategori::create($validated); + + + return response()->json([ + 'message' => 'Kategori berhasil dibuat' + ],201); + } + + /** + * Display the specified resource. + */ + public function show(int $id) + { + return response()->json( + Kategori::with('items.produk.foto')->find($id) + ); + } + + /** + * Update the specified resource in storage. + */ + public function update(Request $request, int $id) + { + $validated = $request->validate([ + 'nama' => 'required|string|max:100', + ], + [ + 'nama' => 'Nama Kategori harus diisi.' + ]); + + $Kategori = Kategori::findOrFail($id); + + $Kategori->update($validated); + + return response()->json([ + 'message' => 'Kategori berhasil diupdate' + ],200); + } + + /** + * Remove the specified resource from storage. + */ + public function destroy(int $id) + { + Kategori::findOrFail($id)->delete(); + + return response()->json([ + 'message' => 'Kategori berhasil dihapus' + ], 204); + } +} diff --git a/app/Http/Controllers/ProdukController.php b/app/Http/Controllers/ProdukController.php index 427cbbb..404dff9 100644 --- a/app/Http/Controllers/ProdukController.php +++ b/app/Http/Controllers/ProdukController.php @@ -17,7 +17,7 @@ class ProdukController extends Controller public function index() { return response()->json( - Produk::withCount('items')->with('foto')->get() + Produk::withCount('items')->with('foto', 'kategori')->get() ); } @@ -28,16 +28,16 @@ class ProdukController extends Controller { $validated = $request->validate([ 'nama' => 'required|string|max:100', - 'kategori' => 'required|in:cincin,gelang,kalung,anting', + 'id_kategori' => 'required|exists:users,id', 'berat' => 'required|numeric', 'kadar' => 'required|integer', 'harga_per_gram' => 'required|numeric', 'harga_jual' => 'required|numeric', - 'id_user' => 'nullable|exists:users,id', // untuk mengambil foto sementara + 'id_user' => 'nullable|exists:users,id', ], [ 'nama.required' => 'Nama produk harus diisi.', - 'kategori.in' => 'Kategori harus salah satu dari cincin, gelang, kalung, atau anting.', + 'id_kategori' => 'Kategori tidak valid.', 'berat.required' => 'Berat harus diisi.', 'kadar.required' => 'Kadar harus diisi', 'harga_per_gram.required' => 'Harga per gram harus diisi', @@ -49,7 +49,7 @@ class ProdukController extends Controller // Create produk $produk = Produk::create([ 'nama' => $validated['nama'], - 'kategori' => $validated['kategori'], + 'id_kategori' => $validated['id_kategori'], 'berat' => $validated['berat'], 'kadar' => $validated['kadar'], 'harga_per_gram' => $validated['harga_per_gram'], @@ -92,7 +92,7 @@ class ProdukController extends Controller */ public function show(int $id) { - $produk = Produk::with('foto', 'items')->findOrFail($id); + $produk = Produk::with('foto', 'items', 'kategori')->findOrFail($id); return response()->json($produk); } @@ -103,7 +103,7 @@ class ProdukController extends Controller { $validated = $request->validate([ 'nama' => 'required|string|max:100', - 'kategori' => 'required|in:cincin,gelang,kalung,anting', + 'id_kategori' => 'required|exists:kategoris,id', 'berat' => 'required|numeric', 'kadar' => 'required|integer', 'harga_per_gram' => 'required|numeric', @@ -113,7 +113,7 @@ class ProdukController extends Controller ], [ 'nama.required' => 'Nama produk harus diisi.', - 'kategori.in' => 'Kategori harus salah satu dari cincin, gelang, kalung, atau anting.', + 'id_kategori' => 'Kategori tidak valid.', 'berat.required' => 'Berat harus diisi.', 'kadar.required' => 'Kadar harus diisi', 'harga_per_gram.required' => 'Harga per gram harus diisi', diff --git a/app/Http/Controllers/TransaksiController.php b/app/Http/Controllers/TransaksiController.php index 055a1bb..274f123 100644 --- a/app/Http/Controllers/TransaksiController.php +++ b/app/Http/Controllers/TransaksiController.php @@ -19,10 +19,21 @@ class TransaksiController extends Controller $query->limit((int)$limit); } $transaksi = $query->get(); - $transaksi = Transaksi::with(['kasir', 'sales', 'items.item.produk'])->latest()->limit(100)->get(); - return response()->json($transaksi); + + // Mapping agar sesuai dengan kebutuhan frontend + $mapped = $transaksi->map(function ($trx) { + return [ + 'id' => $trx->id, + 'tanggal' => $trx->created_at->format('d/m/Y'), + 'kode' => 'TRX-' . str_pad($trx->id, 6, '0', STR_PAD_LEFT), + 'pendapatan'=> $trx->total_harga, + ]; + }); + + return response()->json($mapped); } + // Detail transaksi by ID public function show($id) { diff --git a/app/Models/Foto.php b/app/Models/Foto.php index 5c6561e..ffe563b 100644 --- a/app/Models/Foto.php +++ b/app/Models/Foto.php @@ -15,6 +15,8 @@ class Foto extends Model 'url', ]; + protected $hidden = ['created_at', 'updated_at', 'deleted_at']; + public function produk() { return $this->belongsTo(Produk::class, 'id_produk'); diff --git a/app/Models/FotoSementara.php b/app/Models/FotoSementara.php index 8899e53..06c5ae8 100644 --- a/app/Models/FotoSementara.php +++ b/app/Models/FotoSementara.php @@ -10,4 +10,6 @@ class FotoSementara extends Model 'id_user', 'url', ]; + + protected $hidden = ['created_at', 'updated_at', 'deleted_at']; } diff --git a/app/Models/Item.php b/app/Models/Item.php index 3c94059..337cf8a 100644 --- a/app/Models/Item.php +++ b/app/Models/Item.php @@ -16,6 +16,8 @@ class Item extends Model 'is_sold', ]; + protected $hidden = ['created_at', 'updated_at', 'deleted_at']; + public function produk() { return $this->belongsTo(Produk::class, 'id_produk'); diff --git a/app/Models/ItemTransaksi.php b/app/Models/ItemTransaksi.php index 16dd5e4..eb9f4ac 100644 --- a/app/Models/ItemTransaksi.php +++ b/app/Models/ItemTransaksi.php @@ -16,6 +16,8 @@ class ItemTransaksi extends Model 'harga_deal' ]; + protected $hidden = ['created_at', 'updated_at', 'deleted_at']; + public function transaksi() { return $this->belongsTo(Transaksi::class, 'id_transaksi'); diff --git a/app/Models/Kategori.php b/app/Models/Kategori.php new file mode 100644 index 0000000..3abc4fa --- /dev/null +++ b/app/Models/Kategori.php @@ -0,0 +1,22 @@ + */ + use HasFactory, SoftDeletes; + + protected $fillable = ['nama']; + + protected $hidden = ['created_at', 'updated_at', 'deleted_at']; + + public function produks() + { + return $this->hasMany(Produk::class, 'id_kategori'); + } +} diff --git a/app/Models/Nampan.php b/app/Models/Nampan.php index 5044fba..8288bb6 100644 --- a/app/Models/Nampan.php +++ b/app/Models/Nampan.php @@ -15,6 +15,7 @@ class Nampan extends Model ]; protected $appends = ['berat_total']; + protected $hidden = ['created_at', 'updated_at', 'deleted_at']; public function items() { diff --git a/app/Models/Produk.php b/app/Models/Produk.php index 2a4c2b9..e012c31 100644 --- a/app/Models/Produk.php +++ b/app/Models/Produk.php @@ -12,13 +12,15 @@ class Produk extends Model protected $fillable = [ 'nama', - 'kategori', + 'id_kategori', 'berat', 'kadar', 'harga_per_gram', 'harga_jual', ]; + protected $hidden = ['created_at', 'updated_at', 'deleted_at']; + public function items() { return $this->hasMany(Item::class, 'id_produk'); @@ -28,4 +30,9 @@ class Produk extends Model { return $this->hasMany(Foto::class, 'id_produk'); } + + public function kategori() + { + return $this->belongsTo(Kategori::class, 'id_kategori'); + } } diff --git a/app/Models/Sales.php b/app/Models/Sales.php index 8a5a6e0..2445601 100644 --- a/app/Models/Sales.php +++ b/app/Models/Sales.php @@ -16,6 +16,8 @@ class Sales extends Model 'alamat' ]; + protected $hidden = ['created_at', 'updated_at', 'deleted_at']; + public function transaksi() { return $this->hasMany(Transaksi::class, 'id_sales'); diff --git a/app/Models/Transaksi.php b/app/Models/Transaksi.php index 92268f8..8473e76 100644 --- a/app/Models/Transaksi.php +++ b/app/Models/Transaksi.php @@ -20,6 +20,8 @@ class Transaksi extends Model 'created_at', ]; + protected $hidden = ['updated_at', 'deleted_at']; + public function kasir() { return $this->belongsTo(User::class, 'id_kasir'); diff --git a/database/factories/KategoriFactory.php b/database/factories/KategoriFactory.php new file mode 100644 index 0000000..52dc679 --- /dev/null +++ b/database/factories/KategoriFactory.php @@ -0,0 +1,23 @@ + + */ +class KategoriFactory extends Factory +{ + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + 'nama' => $this->faker->word(), + ]; + } +} diff --git a/database/factories/ProdukFactory.php b/database/factories/ProdukFactory.php index 4618dc7..59c6fde 100644 --- a/database/factories/ProdukFactory.php +++ b/database/factories/ProdukFactory.php @@ -2,6 +2,7 @@ namespace Database\Factories; +use App\Models\Kategori; use Illuminate\Database\Eloquent\Factories\Factory; /** @@ -18,9 +19,10 @@ class ProdukFactory extends Factory { $harga_per_gram = $this->faker->numberBetween(80, 120) * 10000; $berat = $this->faker->randomFloat(2, 1, 10); + $kategoriList = Kategori::all()->pluck('id')->toArray(); return [ 'nama' => $this->faker->words(3, true), - 'kategori' => $this->faker->randomElement(['cincin', 'gelang', 'kalung', 'anting']), + 'id_kategori' => $this->faker->randomElement($kategoriList), 'berat' => $berat, 'kadar' => $this->faker->numberBetween(10, 24), 'harga_per_gram' => $harga_per_gram, diff --git a/database/migrations/2025_08_25_045903_create_kategoris_table.php b/database/migrations/2025_08_25_045903_create_kategoris_table.php new file mode 100644 index 0000000..e861fb4 --- /dev/null +++ b/database/migrations/2025_08_25_045903_create_kategoris_table.php @@ -0,0 +1,29 @@ +id(); + $table->string('nama', 100); + $table->timestamps(); + $table->softDeletes(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('kategoris'); + } +}; diff --git a/database/migrations/2025_08_25_045904_create_produks_table.php b/database/migrations/2025_08_25_045904_create_produks_table.php index 53fe7a3..b7e07ba 100644 --- a/database/migrations/2025_08_25_045904_create_produks_table.php +++ b/database/migrations/2025_08_25_045904_create_produks_table.php @@ -14,7 +14,7 @@ return new class extends Migration Schema::create('produks', function (Blueprint $table) { $table->id(); $table->string('nama', 100); - $table->enum('kategori', ['cincin', 'gelang', 'kalung', 'anting']); + $table->foreignId('id_kategori')->constrained('kategoris'); $table->float('berat'); $table->integer('kadar'); $table->double('harga_per_gram'); diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index dbec5aa..70d55af 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -3,6 +3,7 @@ namespace Database\Seeders; use App\Models\Item; +use App\Models\Kategori; use App\Models\Nampan; use App\Models\Produk; use App\Models\Sales; @@ -36,6 +37,13 @@ class DatabaseSeeder extends Seeder } } + $kategoriList = ['cincin', 'gelang', 'kalung', 'anting']; + foreach ($kategoriList as $kategori) { + Kategori::factory()->create([ + 'nama' => $kategori + ]); + } + Produk::factory(10)->create()->each(function ($produk) { // setiap produk punya 1-3 foto $jumlah_foto = rand(1, 3); diff --git a/public/images/logo.png b/public/images/logo.png new file mode 100644 index 0000000..8013d2d Binary files /dev/null and b/public/images/logo.png differ diff --git a/resources/js/components/KasirForm.vue b/resources/js/components/KasirForm.vue index 97aefbe..7d1468c 100644 --- a/resources/js/components/KasirForm.vue +++ b/resources/js/components/KasirForm.vue @@ -16,6 +16,7 @@ @@ -53,10 +54,10 @@ - - {{ index + 1 }} + + {{ index + 1 }} {{ item.kode }} - {{ item.jumlah }} + {{ item.jumlah }} Rp{{ item.harga.toLocaleString() }} Rp{{ (item.harga * item.jumlah).toLocaleString() }} @@ -73,7 +74,7 @@ import InputField from './InputField.vue' const kodeItem = ref('') - const hargaJual = ref(0) + const hargaJual = ref(null) const pesanan = ref([]) const tambahItem = () => { @@ -91,3 +92,4 @@ import InputField from './InputField.vue' pesanan.value.reduce((sum, item) => sum + item.harga * item.jumlah, 0) ) + diff --git a/resources/js/pages/Kasir.vue b/resources/js/pages/Kasir.vue index 5aa9b2d..e356c91 100644 --- a/resources/js/pages/Kasir.vue +++ b/resources/js/pages/Kasir.vue @@ -26,8 +26,8 @@ onMounted(async () => { try { - const res = await axios.get("/api/transaksi") // GANTI URL SESUAI API - + const res = await axios.get("/api/transaksi?limit=10") // GANTI URL SESUAI API + transaksi.value = res.data } catch (err) { console.error("Gagal fetch transaksi:", err)