diff --git a/app/Livewire/Forms/Studio/Stock/StockOpnameForm.php b/app/Livewire/Forms/Studio/Stock/StockOpnameForm.php index 42045e0..7ef3c12 100644 --- a/app/Livewire/Forms/Studio/Stock/StockOpnameForm.php +++ b/app/Livewire/Forms/Studio/Stock/StockOpnameForm.php @@ -54,7 +54,8 @@ public function update(): void continue; } - $item->qty_physical = str_replace('.', '', (string) $qtyPhysical); + $item->qty_physical = (int) str_replace('.', '', (string) ($qtyPhysical ?? 0)); + $item->save(); } } diff --git a/app/Livewire/Studio/Stock/StockOpname/Index.php b/app/Livewire/Studio/Stock/StockOpname/Index.php index 9f7162a..04c2c68 100644 --- a/app/Livewire/Studio/Stock/StockOpname/Index.php +++ b/app/Livewire/Studio/Stock/StockOpname/Index.php @@ -7,7 +7,9 @@ use App\Services\StockActivityLogService; use App\Traits\Components\WithConfirmation; use App\Traits\Components\WithToast; +use App\Traits\Utilities\WithRequestNotification; use Illuminate\Contracts\View\View; +use Illuminate\Support\Facades\Artisan; use Illuminate\Support\Facades\DB; use Livewire\Attributes\Title; use Livewire\Component; @@ -15,36 +17,15 @@ #[Title('Stock Opname')] class Index extends Component { - use WithConfirmation, WithToast; + use WithConfirmation, WithRequestNotification, WithToast; - public $stockOpname; - - public function mount(): void + public function generate(): void { - $this->loadItems(); - } + Artisan::call('stock-opname:generate'); - protected function loadItems(): void - { - $this->stockOpname = StockOpname::with(['outlet', 'items']) - ->where('period_month', now()->format('Y-m')) - ->get() - ->map(function ($stockOpname) { - $total = $stockOpname->items()->count(); + $periodMonth = now()->format('Y-m'); - $filled = $stockOpname->items() - ->whereNotNull('qty_physical') - ->count(); - - $percent = $total > 0 ? round(($filled / $total) * 100) : 0; - - $stockOpname->total_item = $total; - $stockOpname->progress_filled = $filled; - $stockOpname->progress_percent = $percent; - $stockOpname->period_month = formatDateLocalized($stockOpname->period_month, 'F Y'); - - return $stockOpname; - }); + $this->toast('Stock opname untuk bulan '.formatDateLocalized($periodMonth, 'F Y').' berhasil digenerate.', 'Berhasil'); } public function requestApproval(StockOpname $stockOpname): void @@ -119,8 +100,29 @@ public function approveApproval(StockOpname $stockOpname): void public function render(): View { + $stockOpname = StockOpname::with(['outlet', 'items']) + ->where('period_month', now()->format('Y-m')) + ->get() + ->map(function ($stockOpname) { + $total = $stockOpname->items()->count(); + + $filled = $stockOpname->items() + ->whereNotNull('qty_physical') + ->count(); + + $percent = $total > 0 ? round(($filled / $total) * 100) : 0; + + $stockOpname->total_item = $total; + $stockOpname->progress_filled = $filled; + $stockOpname->progress_percent = $percent; + $stockOpname->period_month = formatDateLocalized($stockOpname->period_month, 'F Y'); + + return $stockOpname; + }); + return view('livewire.studio.stock.stock-opname.index', [ 'pageTitle' => 'Stock Opname', + 'stockOpname' => $stockOpname, ]); } } diff --git a/app/Livewire/Studio/Stock/StockOpname/Manage.php b/app/Livewire/Studio/Stock/StockOpname/Manage.php index a8948ed..ce059be 100644 --- a/app/Livewire/Studio/Stock/StockOpname/Manage.php +++ b/app/Livewire/Studio/Stock/StockOpname/Manage.php @@ -10,7 +10,6 @@ use App\Traits\Components\WithConfirmation; use App\Traits\Components\WithToast; use Illuminate\Contracts\View\View; -use Illuminate\Database\Eloquent\Collection; use Livewire\Attributes\Title; use Livewire\Component; @@ -21,7 +20,7 @@ class Manage extends Component public StockOpnameForm $form; - public Collection $items; + public string $search = ''; public function mount(StockOpname $stockOpname): void { @@ -29,12 +28,12 @@ public function mount(StockOpname $stockOpname): void abort(403); } - $this->items = StockOpnameItem::with('itemable') + $items = StockOpnameItem::with('itemable') ->where('stock_opname_id', $stockOpname->id) ->get(); $outletStock = []; - foreach ($this->items as $item) { + foreach ($items as $item) { $outletStock[$item->id] = $item->qty_physical; } @@ -43,35 +42,32 @@ public function mount(StockOpname $stockOpname): void $this->form->setStockOpname($stockOpname); } - public function updated(string $propertyName, $value): void - { - $this->canOrAbort('manage stock opname'); - - if (str_starts_with($propertyName, 'form.outlet_stock.')) { - $itemId = explode('.', $propertyName)[2]; - - $item = $this->items->firstWhere('id', $itemId); - if ($item) { - $normalizedValue = str_replace('.', '', (string) $value); - $item->qty_physical = (int) $normalizedValue; - $item->difference = (int) $normalizedValue - $item->qty_system; - } - } - } - public function save(): void { $this->canOrAbort('manage stock opname'); $this->form->update(); - $this->toast('Data stock opname berhasil disimpan.', 'Berhasil'); + $this->redirectRoute('studio.stock.stock_opname.index', [ + 'notification' => 'Stock opname berhasil disimpan.', + ], navigate: true); } public function render(): View { + $items = StockOpnameItem::with('itemable') + ->where('stock_opname_id', $this->form->stockOpname->id) + ->when($this->search, function ($query) { + $query->whereHasMorph('itemable', '*', function ($query) { + $query->where('name', 'like', '%'.$this->search.'%') + ->orWhere('display_name', 'like', '%'.$this->search.'%'); + }); + }) + ->get(); + return view('livewire.studio.stock.stock-opname.manage', [ 'pageTitle' => 'Kelola Stock Opname', + 'items' => $items, ]); } } diff --git a/app/Models/StockOpnameItem.php b/app/Models/StockOpnameItem.php index 1fbe6e7..efe72cc 100644 --- a/app/Models/StockOpnameItem.php +++ b/app/Models/StockOpnameItem.php @@ -19,7 +19,7 @@ protected function casts(): array return [ 'qty_system' => 'int', 'qty_physical' => 'int', - 'differences' => 'int', + 'difference' => 'int', ]; } diff --git a/database/seeders/RolePermissionSeeder.php b/database/seeders/RolePermissionSeeder.php index 3010a99..5a3edc0 100644 --- a/database/seeders/RolePermissionSeeder.php +++ b/database/seeders/RolePermissionSeeder.php @@ -159,6 +159,7 @@ public function run(): void 'show stock opname', 'approve stock opname', 'manage stock opname', + 'generate stock opname', 'view stock history', 'show stock history', @@ -291,6 +292,7 @@ public function run(): void 'update social settings', 'approve stock opname', + 'generate stock opname', 'create tier', 'update tier', @@ -434,6 +436,7 @@ public function run(): void 'view stock opname', 'show stock opname', 'manage stock opname', + 'generate stock opname', 'view testimonial', 'delete testimonial', diff --git a/resources/views/livewire/studio/stock/stock-opname/index.blade.php b/resources/views/livewire/studio/stock/stock-opname/index.blade.php index 8759440..551bf46 100644 --- a/resources/views/livewire/studio/stock/stock-opname/index.blade.php +++ b/resources/views/livewire/studio/stock/stock-opname/index.blade.php @@ -3,10 +3,17 @@
{{ $pageTitle }}
+
+ @can('generate stock opname') + + Generate + + @endcan +
-
+
@foreach ($stockOpname as $item)
diff --git a/resources/views/livewire/studio/stock/stock-opname/manage.blade.php b/resources/views/livewire/studio/stock/stock-opname/manage.blade.php index 7900182..f12dad0 100644 --- a/resources/views/livewire/studio/stock/stock-opname/manage.blade.php +++ b/resources/views/livewire/studio/stock/stock-opname/manage.blade.php @@ -29,10 +29,11 @@ @foreach ($items as $item) - {{ $item->itemable?->display_name ?? $item->itemable?->name }} + {{ $item->itemable?->display_name ?? $item->itemable?->name }} + {{ $item->qty_system }} -