feat(goods): membuat handle untuk show price

This commit is contained in:
Yoga Pangestu 2025-10-29 10:32:26 +07:00
parent fdfae01130
commit 714e140a55
9 changed files with 140 additions and 6 deletions

View File

@ -4,6 +4,7 @@
use App\Models\Bottle;
use App\Traits\WithConfirmation;
use App\Traits\WithShowPrice;
use App\Traits\WithToast;
use Flux\Flux;
use Livewire\Attributes\Title;
@ -12,7 +13,7 @@
#[Title('Botol')]
class Index extends Component
{
use WithConfirmation, WithToast;
use WithConfirmation, WithShowPrice, WithToast;
public function delete(Bottle $bottle)
{

View File

@ -4,6 +4,7 @@
use App\Models\Perfume;
use App\Traits\WithConfirmation;
use App\Traits\WithShowPrice;
use App\Traits\WithToast;
use Flux\Flux;
use Livewire\Attributes\Title;
@ -12,7 +13,7 @@
#[Title('Parfum')]
class Index extends Component
{
use WithConfirmation, WithToast;
use WithConfirmation, WithShowPrice, WithToast;
public function delete(Perfume $perfume)
{

View File

@ -4,6 +4,7 @@
use App\Models\Product;
use App\Traits\WithConfirmation;
use App\Traits\WithShowPrice;
use App\Traits\WithToast;
use Flux\Flux;
use Livewire\Attributes\Title;
@ -12,7 +13,7 @@
#[Title('Produk')]
class Index extends Component
{
use WithConfirmation, WithToast;
use WithConfirmation, WithShowPrice,WithToast;
public function delete(Product $product)
{

View File

@ -0,0 +1,104 @@
<?php
namespace App\Traits;
use App\Models\Bottle;
use App\Models\Perfume;
use App\Models\PriceRequest;
use App\Models\Product;
use App\Models\User;
use App\Models\Whatsapp;
use Flux\Flux;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\URL;
trait WithShowPrice
{
public function requestPrice(string $module)
{
switch ($module) {
case 'perfume':
$label = 'parfum';
$model = Perfume::class;
break;
case 'product':
$label = 'produk';
$model = Product::class;
break;
default:
$label = 'botol';
$model = Bottle::class;
break;
}
$recentRequest = PriceRequest::where('user_id', auth()->id())
->where('model', $model)
->where('created_at', '>', now()->subMinutes(30))
->exists();
if ($recentRequest) {
$this->toast('Kamu baru saja mengajukan permintaan, tautan persetujuan masih berlaku selama 30 menit.', 'Peringatan', 'warning');
Flux::modal('show-price')->close();
return;
}
$whatsapp = Whatsapp::first();
$owner = User::role('owner')->with('employee')->first();
if (! $owner) {
$this->toast('Owner belum terdaftar, silakan hubungi Admin', 'Gagal', 'danger');
Flux::modal('show-price')->close();
return;
}
$phoneNumber = formatPhoneNumber($owner->employee?->phone_number, '62');
try {
$priceRequest = PriceRequest::create([
'user_id' => auth()->id(),
'model' => $model,
'expires_at' => now()->addMinutes(30),
]);
$signedUrl = URL::temporarySignedRoute(
'price-request.approve',
$priceRequest->expires_at,
['priceRequest' => $priceRequest->hash]
);
$priceRequest->update([
'signature' => hash('sha256', $signedUrl),
]);
$causerName = auth()->user()->employee?->full_name;
$response = Http::withHeaders([
'id' => $whatsapp->zawa_id,
'session-id' => $whatsapp->session_id,
'Content-Type' => 'application/json',
])->post(config('services.zawa.url').'/message', [
'phone' => $phoneNumber,
'type' => 'text',
'text' => "Haloo {$owner->employee?->full_name}, saya {$causerName}, "
."saya ingin mengajukan permintaan persetujuan untuk mengakses data harga beli {$label}."
."\n\nSilakan klik tautan berikut untuk menyetujui:\n\n{$signedUrl}",
]);
if ($response->successful()) {
$this->toast('Permintaan persetujuan berhasil dikirim.');
} else {
$this->toast('Permintaan persetujuan gagal dikirim, silakan coba lagi.', 'Gagal', 'danger');
}
} catch (\Throwable $th) {
Log::error($th->getMessage());
$this->toast('Opps, terjadi kesalahan. Silakan coba lagi dan jika masih terjadi, hubungi Administrator.', 'Gagal', 'danger');
}
Flux::modal('show-price')->close();
}
}

View File

@ -0,0 +1,19 @@
<flux:modal name="show-price" class="w-[22rem]">
<div class="space-y-6">
<div>
<flux:heading size="lg">Konfirmasi</flux:heading>
<flux:text class="mt-2">Apakah Anda ingin mengajukan permintaan persetujuan kepada owner untuk
mengakses data harga beli?</flux:text>
</div>
<div class="flex gap-2">
<flux:spacer />
<flux:modal.close>
<flux:button variant="ghost">Batal</flux:button>
</flux:modal.close>
<flux:button type="submit" variant="primary"
wire:click="requestPrice('{{ $module }}')">
Ya, Ajukan
</flux:button>
</div>
</div>
</flux:modal>

View File

@ -3,7 +3,7 @@
<div>
<flux:heading size="xl">{{ $pageTitle }}</flux:heading>
</div>
@can ('create bottle')
@can('create bottle')
<div>
<flux:button href="{{ route('studio.catalog.bottle.create') }}" variant="primary" wire:navigate.hover
class="text-sm">
@ -18,4 +18,5 @@ class="text-sm">
</div>
@include('components.confirmation.delete')
@include('components.confirmation.show-price', ['module' => 'bottle'])
</flux:main>

View File

@ -3,7 +3,7 @@
<div>
<flux:heading size="xl">{{ $pageTitle }}</flux:heading>
</div>
@can ('create perfume')
@can('create perfume')
<div>
<flux:button href="{{ route('studio.catalog.perfume.create') }}" variant="primary" wire:navigate.hover
class="text-sm">
@ -18,4 +18,5 @@ class="text-sm">
</div>
@include('components.confirmation.delete')
@include('components.confirmation.show-price', ['module' => 'perfume'])
</flux:main>

View File

@ -3,7 +3,7 @@
<div>
<flux:heading size="xl">{{ $pageTitle }}</flux:heading>
</div>
@can ('create product')
@can('create product')
<div>
<flux:button href="{{ route('studio.catalog.product.create') }}" variant="primary" wire:navigate.hover
class="text-sm">
@ -18,4 +18,5 @@ class="text-sm">
</div>
@include('components.confirmation.delete')
@include('components.confirmation.show-price', ['module' => 'product'])
</flux:main>

View File

@ -1,5 +1,6 @@
<?php
use App\Http\Controllers\Studio\PriceRequestController;
use App\Livewire\Studio\Catalog\Bottle\Create as BottleCreate;
use App\Livewire\Studio\Catalog\Bottle\Edit as BottleEdit;
use App\Livewire\Studio\Catalog\Bottle\Index as BottleIndex;
@ -162,3 +163,7 @@
Route::get('/settings/applications', ApplicationComponent::class)->name('studio.setting.application')->middleware('can:view application settings');
Route::get('/settings/whatsapp', WhatsappComponent::class)->name('studio.setting.whatsapp')->middleware('can:view whatsapp settings');
});
Route::get('/price-request/{priceRequest}/approve', [PriceRequestController::class, 'approve'])
->name('price-request.approve')
->middleware('signed');