Merge branch 'production' of https://git.abbauf.com/Magang-2025/Kasir into production
This commit is contained in:
commit
b2f93c4537
82
app/Http/Controllers/KategoriController.php
Normal file
82
app/Http/Controllers/KategoriController.php
Normal file
@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Kategori;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class KategoriController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return response()->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);
|
||||
}
|
||||
}
|
@ -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',
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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');
|
||||
|
@ -10,4 +10,6 @@ class FotoSementara extends Model
|
||||
'id_user',
|
||||
'url',
|
||||
];
|
||||
|
||||
protected $hidden = ['created_at', 'updated_at', 'deleted_at'];
|
||||
}
|
||||
|
@ -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');
|
||||
|
@ -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');
|
||||
|
22
app/Models/Kategori.php
Normal file
22
app/Models/Kategori.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Kategori extends Model
|
||||
{
|
||||
/** @use HasFactory<\Database\Factories\KategoriFactory> */
|
||||
use HasFactory, SoftDeletes;
|
||||
|
||||
protected $fillable = ['nama'];
|
||||
|
||||
protected $hidden = ['created_at', 'updated_at', 'deleted_at'];
|
||||
|
||||
public function produks()
|
||||
{
|
||||
return $this->hasMany(Produk::class, 'id_kategori');
|
||||
}
|
||||
}
|
@ -15,6 +15,7 @@ class Nampan extends Model
|
||||
];
|
||||
protected $appends = ['berat_total'];
|
||||
|
||||
protected $hidden = ['created_at', 'updated_at', 'deleted_at'];
|
||||
|
||||
public function items()
|
||||
{
|
||||
|
@ -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');
|
||||
}
|
||||
}
|
||||
|
@ -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');
|
||||
|
@ -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');
|
||||
|
23
database/factories/KategoriFactory.php
Normal file
23
database/factories/KategoriFactory.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
/**
|
||||
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Kategori>
|
||||
*/
|
||||
class KategoriFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'nama' => $this->faker->word(),
|
||||
];
|
||||
}
|
||||
}
|
@ -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,
|
||||
|
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('kategoris', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('nama', 100);
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('kategoris');
|
||||
}
|
||||
};
|
@ -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');
|
||||
|
@ -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);
|
||||
|
BIN
public/images/logo.png
Normal file
BIN
public/images/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 138 KiB |
@ -16,6 +16,7 @@
|
||||
<InputField
|
||||
v-model="hargaJual"
|
||||
type="number"
|
||||
placeholder="Masukkan Harga Jual"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@ -53,10 +54,10 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(item, index) in pesanan" :key="index" class="hover:bg-gray-50">
|
||||
<td class="border border-gray-200 p-2 text-center">{{ index + 1 }}</td>
|
||||
<tr v-for="(item, index) in pesanan" :key="index" class="hover:bg-gray-50 text-center">
|
||||
<td class="border border-gray-200 p-2">{{ index + 1 }}</td>
|
||||
<td class="border border-gray-200 p-2">{{ item.kode }}</td>
|
||||
<td class="border border-gray-200 p-2 text-center">{{ item.jumlah }}</td>
|
||||
<td class="border border-gray-200 p-2">{{ item.jumlah }}</td>
|
||||
<td class="border border-gray-200 p-2">Rp{{ item.harga.toLocaleString() }}</td>
|
||||
<td class="border border-gray-200 p-2">Rp{{ (item.harga * item.jumlah).toLocaleString() }}</td>
|
||||
</tr>
|
||||
@ -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)
|
||||
)
|
||||
</script>
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
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) {
|
||||
|
Loading…
Reference in New Issue
Block a user