parfum/app/Livewire/Forms/PerfumeForm.php
Yoga Pangestu a0fd914af5 feat(perfume): crud parfum
-menambahkan skema model dan migrsai
-menyesuaikan relasi
-membuat enum Concentration
-mmebuat trait baru untuk handle category
2025-10-01 20:41:19 +07:00

162 lines
4.8 KiB
PHP

<?php
namespace App\Livewire\Forms;
use App\Enums\Concentration;
use App\Models\Perfume;
use App\Rules\UnsignedInteger;
use App\Traits\WithMediaHandler;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule;
use Livewire\Form;
class PerfumeForm extends Form
{
use WithMediaHandler;
public ?Perfume $perfume = null;
public string $name = '';
public string $sku = '';
public ?string $brand = null;
public string $cost_price = '';
public string $sale_price = '';
public ?string $base_notes = null;
public ?string $middle_notes = null;
public ?string $top_notes = null;
public ?string $description = null;
public string $concentration = '';
public array $category_ids = [];
public ?array $image = null;
public array $outlet_ids = [];
public function rules(): array
{
return [
'name' => ['required', 'string', 'max:50'],
'sku' => [
'required',
'string',
'max:20',
Rule::unique('perfumes', 'sku')->ignore($this->perfume),
],
'brand' => ['nullable', Rule::exists('brands', 'id')],
'cost_price' => ['required', 'numeric', new UnsignedInteger],
'sale_price' => ['required', 'numeric', new UnsignedInteger],
'base_notes' => ['nullable', 'string', 'max:255'],
'middle_notes' => ['nullable', 'string', 'max:255'],
'top_notes' => ['nullable', 'string', 'max:255'],
'description' => ['nullable', 'string'],
'concentration' => ['required', Rule::in(Concentration::values())],
'category_ids' => ['required', 'array', 'min:1'],
'category_ids.*' => Rule::exists('categories', 'id'),
'outlet_ids' => ['required', 'array', 'min:1'],
'outlet_ids.*' => Rule::exists('outlets', 'id'),
'image' => ['nullable', 'array', 'max:1'],
];
}
public function validationAttributes(): array
{
return [
'name' => 'nama',
'brand' => 'merek',
'cost_price' => 'harga beli',
'sale_price' => 'harga jual',
'description' => 'deskripsi',
'category_ids' => 'kategori',
'outlet_ids' => 'outlet',
'image' => 'gambar',
];
}
public function setPerfume(Perfume $perfume)
{
$perfume->load(['brand', 'outlets', 'categories']);
$this->perfume = $perfume;
$this->name = $perfume->name;
$this->sku = $perfume->sku;
$this->brand = $perfume->brand_id;
$this->cost_price = $perfume->cost_price;
$this->sale_price = $perfume->sale_price;
$this->base_notes = $perfume->base_notes;
$this->middle_notes = $perfume->middle_notes;
$this->top_notes = $perfume->top_notes;
$this->description = $perfume->description;
$this->concentration = $perfume->concentration->value;
$this->category_ids = $perfume->categories->pluck('id')->toArray();
$this->outlet_ids = $this->perfume->outlets->pluck('id')->toArray();
$this->image = $this->mapMediaCollection($perfume->getMedia('image'));
}
public function store()
{
$this->validate();
$data = $this->prepareSavedData();
DB::transaction(function () use ($data) {
$perfume = Perfume::create($data);
$perfume->categories()->attach($this->category_ids);
$perfume->outlets()->attach($this->outlet_ids);
if ($this->image) {
$this->image = $this->mapMediaCollection($perfume->getMedia('image'));
}
});
}
public function update()
{
$this->validate();
$data = $this->prepareSavedData();
DB::transaction(function () use ($data) {
$this->perfume->update($data);
$this->perfume->categories()->sync($this->category_ids);
$this->perfume->outlets()->sync($this->outlet_ids);
$this->syncMedia($data['image'] ?? [], $this->perfume, 'image');
$this->uploadMedia($data['image'] ?? [], $this->perfume, 'image');
});
}
private function prepareSavedData()
{
return [
'name' => $this->name,
'sku' => $this->sku,
'cost_price' => $this->cost_price,
'sale_price' => $this->sale_price,
'base_notes' => $this->base_notes,
'middle_notes' => $this->middle_notes,
'top_notes' => $this->top_notes,
'description' => $this->description,
'concentration' => $this->concentration,
'brand_id' => $this->brand,
'category_ids' => $this->category_ids,
'outlet_ids' => $this->outlet_ids,
'image' => $this->image,
];
}
}