diff --git a/app/Livewire/Datatable/VouchersTable.php b/app/Livewire/Datatable/VouchersTable.php
index 643d132..3e66f38 100644
--- a/app/Livewire/Datatable/VouchersTable.php
+++ b/app/Livewire/Datatable/VouchersTable.php
@@ -10,6 +10,7 @@
use Illuminate\Support\Facades\Blade;
use Rappasoft\LaravelLivewireTables\DataTableComponent;
use Rappasoft\LaravelLivewireTables\Views\Column;
+use Rappasoft\LaravelLivewireTables\Views\Columns\ArrayColumn;
class VouchersTable extends DataTableComponent
{
@@ -54,6 +55,11 @@ public function columns(): array
Column::make('Batas Per Pembali', 'limit_per_user')->searchable()->sortable(),
+ ArrayColumn::make('Outlet')
+ ->data(fn ($value, $row) => $row->outlets->pluck('name')->toArray())
+ ->outputFormat(fn ($index, $value) => Blade::render(''.$value.''))
+ ->flexRow(['class' => 'gap-2 flex-wrap']),
+
Column::make('Tanggal')
->label(function ($row) {
$startDate = formatDate($row->start_date);
@@ -105,6 +111,6 @@ public function columns(): array
public function builder(): Builder
{
- return Voucher::select('id', 'name', 'code', 'min_purchase', 'discount_amount', 'max_discount', 'quota', 'limit_per_user', 'start_date', 'end_date', 'is_active', 'type');
+ return Voucher::select('id', 'name', 'code', 'min_purchase', 'discount_amount', 'max_discount', 'quota', 'limit_per_user', 'start_date', 'end_date', 'is_active', 'type')->with('outlets');
}
}
diff --git a/app/Livewire/Forms/VoucherForm.php b/app/Livewire/Forms/VoucherForm.php
index 23f3bc7..2fb2ea5 100644
--- a/app/Livewire/Forms/VoucherForm.php
+++ b/app/Livewire/Forms/VoucherForm.php
@@ -6,6 +6,7 @@
use App\Enums\VoucherType;
use App\Models\Voucher;
use App\Rules\UnsignedInteger;
+use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule;
use Livewire\Form;
@@ -37,6 +38,8 @@ class VoucherForm extends Form
public string $is_active = '1';
+ public array $outlet_ids = [];
+
public function rules(): array
{
return [
@@ -71,6 +74,8 @@ public function rules(): array
'end_date' => ['nullable', 'date', 'after_or_equal:start_date'],
'terms_conditions' => ['nullable', 'string'],
'is_active' => ['required', Rule::in(IsActive::values())],
+ 'outlet_ids' => ['required', 'array', 'min:1'],
+ 'outlet_ids.*' => Rule::exists('outlets', 'id'),
];
}
@@ -94,6 +99,8 @@ public function validationAttributes(): array
public function setVoucher(Voucher $voucher)
{
+ $voucher->load('outlets');
+
$this->voucher = $voucher;
$this->name = $this->voucher->name;
@@ -108,6 +115,8 @@ public function setVoucher(Voucher $voucher)
$this->start_date = $this->voucher->start_date;
$this->end_date = $this->voucher->end_date;
$this->is_active = $this->voucher->is_active->value;
+
+ $this->outlet_ids = $this->voucher->outlets->pluck('id')->toArray();
}
public function store()
@@ -116,7 +125,11 @@ public function store()
$data = $this->prepareSavedData();
- Voucher::create($data);
+ DB::transaction(function () use ($data) {
+ $voucher = Voucher::create($data);
+
+ $voucher->outlets()->attach($this->outlet_ids);
+ });
}
public function update()
@@ -124,8 +137,11 @@ public function update()
$this->validate();
$data = $this->prepareSavedData();
+ DB::transaction(function () use ($data) {
+ $this->voucher->update($data);
- $this->voucher->update($data);
+ $this->voucher->outlets()->sync($this->outlet_ids);
+ });
}
private function prepareSavedData()
diff --git a/app/Livewire/Studio/Loyalty/Voucher/Create.php b/app/Livewire/Studio/Loyalty/Voucher/Create.php
index 1693f45..2c32f24 100644
--- a/app/Livewire/Studio/Loyalty/Voucher/Create.php
+++ b/app/Livewire/Studio/Loyalty/Voucher/Create.php
@@ -3,6 +3,8 @@
namespace App\Livewire\Studio\Loyalty\Voucher;
use App\Livewire\Forms\VoucherForm;
+use App\Models\Outlet;
+use App\Traits\Voucher\WithOutletSelector;
use App\Traits\WithUpdatedData;
use Flux\Flux;
use Livewire\Attributes\Title;
@@ -11,10 +13,17 @@
#[Title('Tambah Voucher')]
class Create extends Component
{
- use WithUpdatedData;
+ use WithOutletSelector, WithUpdatedData;
public VoucherForm $form;
+ public array $outlets;
+
+ public function mount()
+ {
+ $this->outlets = Outlet::pluck('name', 'id')->toArray();
+ }
+
public function save()
{
$this->form->store();
diff --git a/app/Livewire/Studio/Loyalty/Voucher/Edit.php b/app/Livewire/Studio/Loyalty/Voucher/Edit.php
index f47c82e..2597d88 100644
--- a/app/Livewire/Studio/Loyalty/Voucher/Edit.php
+++ b/app/Livewire/Studio/Loyalty/Voucher/Edit.php
@@ -3,7 +3,9 @@
namespace App\Livewire\Studio\Loyalty\Voucher;
use App\Livewire\Forms\VoucherForm;
+use App\Models\Outlet;
use App\Models\Voucher;
+use App\Traits\Voucher\WithOutletSelector;
use App\Traits\WithUpdatedData;
use Flux\Flux;
use Livewire\Attributes\Title;
@@ -12,13 +14,17 @@
#[Title('Ubah Voucher')]
class Edit extends Component
{
- use WithUpdatedData;
+ use WithOutletSelector, WithUpdatedData;
public VoucherForm $form;
+ public array $outlets;
+
public function mount(Voucher $voucher)
{
$this->form->setVoucher($voucher);
+
+ $this->outlets = Outlet::pluck('name', 'id')->toArray();
}
public function save()
diff --git a/app/Models/Outlet.php b/app/Models/Outlet.php
index a2a4a83..e29551d 100644
--- a/app/Models/Outlet.php
+++ b/app/Models/Outlet.php
@@ -47,4 +47,9 @@ public function facilities(): HasMany
{
return $this->hasMany(Facility::class);
}
+
+ public function vouchers(): BelongsToMany
+ {
+ return $this->belongsToMany(Voucher::class);
+ }
}
diff --git a/app/Models/OutletVoucher.php b/app/Models/OutletVoucher.php
new file mode 100644
index 0000000..8bbbe55
--- /dev/null
+++ b/app/Models/OutletVoucher.php
@@ -0,0 +1,12 @@
+ IsActive::class,
];
}
+
+ public function outlets(): BelongsToMany
+ {
+ return $this->belongsToMany(Outlet::class);
+ }
}
diff --git a/app/Traits/Voucher/WithOutletSelector.php b/app/Traits/Voucher/WithOutletSelector.php
new file mode 100644
index 0000000..3f09248
--- /dev/null
+++ b/app/Traits/Voucher/WithOutletSelector.php
@@ -0,0 +1,16 @@
+form->outlet_ids = array_keys($this->outlets);
+ }
+
+ public function deselectAll()
+ {
+ $this->form->outlet_ids = [];
+ }
+}
diff --git a/database/migrations/2025_09_30_015446_create_outlet_voucher_table.php b/database/migrations/2025_09_30_015446_create_outlet_voucher_table.php
new file mode 100644
index 0000000..2a8b651
--- /dev/null
+++ b/database/migrations/2025_09_30_015446_create_outlet_voucher_table.php
@@ -0,0 +1,29 @@
+id();
+ $table->foreignId('outlet_id')->constrained()->cascadeOnDelete();
+ $table->foreignId('voucher_id')->constrained()->cascadeOnDelete();
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::dropIfExists('outlet_voucher');
+ }
+};
diff --git a/database/seeders/VoucherSeeder.php b/database/seeders/VoucherSeeder.php
index 9aa42a9..0d5b9a9 100644
--- a/database/seeders/VoucherSeeder.php
+++ b/database/seeders/VoucherSeeder.php
@@ -4,6 +4,7 @@
use App\Enums\IsActive;
use App\Enums\VoucherType;
+use App\Models\Outlet;
use App\Models\Voucher;
use Illuminate\Database\Seeder;
@@ -11,7 +12,7 @@ class VoucherSeeder extends Seeder
{
public function run(): void
{
- Voucher::insert([
+ $vouchers = [
[
'name' => 'Diskon 10%',
'code' => 'DISC10',
@@ -103,6 +104,12 @@ public function run(): void
'end_date' => null,
'is_active' => IsActive::ACTIVE,
],
- ]);
+ ];
+
+ foreach ($vouchers as $voucher) {
+ $newVoucher = Voucher::create($voucher);
+
+ $newVoucher->outlets()->attach(Outlet::inRandomOrder()->first()->id);
+ }
}
}
diff --git a/resources/views/livewire/studio/loyalty/voucher/form.blade.php b/resources/views/livewire/studio/loyalty/voucher/form.blade.php
index 03a59f3..165b681 100644
--- a/resources/views/livewire/studio/loyalty/voucher/form.blade.php
+++ b/resources/views/livewire/studio/loyalty/voucher/form.blade.php
@@ -125,6 +125,20 @@ class="**:data-[slot=content]:min-h-[100px]!" />
@endforeach
+
+
+
+ Pilih Semua
+
+ Hapus Semua
+
+ @foreach ($outlets as $key => $value)
+ {{ $value }}
+
+ @endforeach
+
+