- Implemented stock transfer creation and management with Livewire components. - Created StockTransfer and StockTransferItem models with necessary relationships. - Added migration files for stock_transfers and stock_transfer_items tables. - Developed traits for handling stock transfer items (add, delete, update). - Integrated stock transfer logging in StockActivityLogService. - Updated ViewServiceProvider to include stock transfer permissions and routes. - Created frontend views for stock transfer form and index with appropriate UI components. - Added role permissions for stock transfer actions in RolePermissionSeeder.
214 lines
11 KiB
PHP
214 lines
11 KiB
PHP
<flux:main>
|
|
<div class="flex justify-between items-center">
|
|
<div>
|
|
<flux:heading size="xl">{{ $pageTitle }}</flux:heading>
|
|
</div>
|
|
<div>
|
|
<flux:button href="{{ route('studio.manage.stock_transfer.index') }}" wire:navigate class="text-sm">
|
|
Kembali
|
|
</flux:button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mt-6">
|
|
<flux:callout icon="megaphone" color="blue" class="mb-6">
|
|
<flux:callout.heading>Informasi Transfer Stok</flux:callout.heading>
|
|
<flux:callout.text>
|
|
Proses transfer stok akan **mengurangi** stok di Outlet Asal dan **menambah** stok di Outlet Tujuan yang dipilih.
|
|
</flux:callout.text>
|
|
</flux:callout>
|
|
|
|
<div class="flex flex-col lg:flex-row gap-4">
|
|
<div class="w-full lg:w-3/4 space-y-4">
|
|
<flux:card class="space-y-6 p-6">
|
|
<flux:input label="Catatan" placeholder="Transfer stok antar outlet" wire:model="form.note"
|
|
autocomplete="off" />
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
|
<flux:field>
|
|
<flux:label>Tanggal Transfer <span class="text-red-500 ms-1">*</span></flux:label>
|
|
<flux:date-picker with-today wire:model="form.transfer_date" placeholder="Pilih Tanggal"
|
|
autocomplete="off" locale="id-ID" selectable-header />
|
|
<flux:error name="form.transfer_date" />
|
|
</flux:field>
|
|
|
|
<flux:field>
|
|
<flux:label>Outlet Asal <span class="text-red-500 ms-1">*</span></flux:label>
|
|
<flux:select variant="listbox" searchable placeholder="Pilih Outlet Asal"
|
|
wire:model.live="form.source_outlet_id">
|
|
@foreach ($sourceOutlets as $key => $value)
|
|
<flux:select.option value="{{ $key }}">{{ $value }}
|
|
</flux:select.option>
|
|
@endforeach
|
|
</flux:select>
|
|
<flux:error name="form.source_outlet_id" />
|
|
</flux:field>
|
|
|
|
<flux:field>
|
|
<flux:label>Outlet Tujuan <span class="text-red-500 ms-1">*</span></flux:label>
|
|
<flux:select variant="listbox" searchable placeholder="Pilih Outlet Tujuan"
|
|
wire:model.live="form.destination_outlet_id">
|
|
@foreach ($destinationOutlets as $key => $value)
|
|
<flux:select.option value="{{ $key }}">{{ $value }}
|
|
</flux:select.option>
|
|
@endforeach
|
|
</flux:select>
|
|
<flux:error name="form.destination_outlet_id" />
|
|
</flux:field>
|
|
</div>
|
|
</flux:card>
|
|
|
|
@if ($form->source_outlet_id && $form->destination_outlet_id)
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
<flux:card class="space-y-6 p-6">
|
|
<flux:select label="Parfum" variant="listbox" searchable placeholder="Cari parfum..."
|
|
wire:model="form.perfume_id">
|
|
@foreach ($perfumes as $key => $perfume)
|
|
<flux:select.option value="{{ $key }}">{{ $perfume }}
|
|
</flux:select.option>
|
|
@endforeach
|
|
</flux:select>
|
|
<flux:input label="Kuantitas" placeholder="500" wire:model="form.quantity_perfume"
|
|
autocomplete="off" x-mask:dynamic="$money($input, ',')" />
|
|
|
|
<div class="flex justify-end">
|
|
<flux:button variant="primary" color="zinc" wire:click="addItem('parfum')">
|
|
Tambah
|
|
</flux:button>
|
|
</div>
|
|
</flux:card>
|
|
|
|
<flux:card class="space-y-6 p-6">
|
|
<flux:select label="Produk" variant="listbox" searchable placeholder="Cari produk..."
|
|
wire:model="form.product_id">
|
|
@foreach ($products as $key => $product)
|
|
<flux:select.option value="{{ $key }}">{{ $product }}
|
|
</flux:select.option>
|
|
@endforeach
|
|
</flux:select>
|
|
<flux:input label="Kuantitas" placeholder="10" wire:model="form.quantity_product"
|
|
autocomplete="off" x-mask:dynamic="$money($input, ',')" />
|
|
|
|
<div class="flex justify-end">
|
|
<flux:button variant="primary" color="zinc" wire:click="addItem('produk')">
|
|
Tambah
|
|
</flux:button>
|
|
</div>
|
|
</flux:card>
|
|
|
|
<flux:card class="space-y-6 p-6">
|
|
<flux:select label="Botol" variant="listbox" searchable placeholder="Cari botol..."
|
|
wire:model="form.bottle_id">
|
|
@foreach ($bottles as $key => $bottle)
|
|
<flux:select.option value="{{ $key }}">{{ $bottle }}
|
|
</flux:select.option>
|
|
@endforeach
|
|
</flux:select>
|
|
<flux:input label="Kuantitas" placeholder="50" wire:model="form.quantity_bottle"
|
|
autocomplete="off" x-mask:dynamic="$money($input, ',')" />
|
|
|
|
<div class="flex justify-end">
|
|
<flux:button variant="primary" color="zinc" wire:click="addItem('botol')">
|
|
Tambah
|
|
</flux:button>
|
|
</div>
|
|
</flux:card>
|
|
</div>
|
|
@else
|
|
<flux:card class="p-6 text-center text-zinc-500 italic">
|
|
Silakan pilih Outlet Asal dan Outlet Tujuan terlebih dahulu untuk menampilkan daftar item.
|
|
</flux:card>
|
|
@endif
|
|
</div>
|
|
|
|
<div class="w-full lg:w-1/3 space-y-4">
|
|
<flux:card class="space-y-6 p-6">
|
|
<div class="space-y-3">
|
|
<h3 class="text-sm font-medium">Gambar</h3>
|
|
<div class="dropzone-wrapper">
|
|
<livewire:dropzone wire:model="form.image" :rules="['image', 'mimes:png,jpeg', 'max:10420']" :max-files="1"
|
|
:key="'image'" :files="$form->image" />
|
|
@error('form.image')
|
|
<div class="mt-3 text-sm font-medium text-red-500 dark:text-red-400">
|
|
{{ $message }}
|
|
</div>
|
|
@enderror
|
|
</div>
|
|
</div>
|
|
</flux:card>
|
|
<flux:card class="space-y-6 p-6">
|
|
<h3 class="text-sm font-medium">Keranjang Transfer Stok</h3>
|
|
|
|
<div class="divide-y text-sm">
|
|
<flux:table>
|
|
<flux:table.columns>
|
|
<flux:table.column>Item</flux:table.column>
|
|
<flux:table.column>Qty</flux:table.column>
|
|
<flux:table.column>Aksi</flux:table.column>
|
|
</flux:table.columns>
|
|
|
|
<flux:table.rows>
|
|
@forelse($stockTransferItems as $item)
|
|
<flux:table.row>
|
|
<flux:table.cell>
|
|
<flux:heading>
|
|
<div>{{ $item->transferable->name }}</div>
|
|
</flux:heading>
|
|
</flux:table.cell>
|
|
<flux:table.cell>
|
|
{{ formatCurrencyNumber($item->quantity, '') }}
|
|
</flux:table.cell>
|
|
<flux:table.cell class="space-x-2">
|
|
<flux:modal.trigger name="form-modal">
|
|
<flux:tooltip content="Ubah">
|
|
<flux:button variant="primary" color="yellow" icon="pencil-square"
|
|
size="sm"
|
|
wire:click="$dispatch('modal:open', {'item': '{{ $item->id }}'})">
|
|
</flux:button>
|
|
</flux:tooltip>
|
|
</flux:modal.trigger>
|
|
|
|
<flux:button variant="danger" icon="trash" size="sm"
|
|
wire:click="deleteItem('{{ $item->id }}')">
|
|
</flux:button>
|
|
</flux:table.cell>
|
|
</flux:table.row>
|
|
@empty
|
|
<flux:table.row>
|
|
<flux:table.cell colspan="3" class="text-center">
|
|
<span class="text-sm text-zinc-500 italic">Keranjang Kosong...</span>
|
|
</flux:table.cell>
|
|
</flux:table.row>
|
|
@endforelse
|
|
</flux:table.rows>
|
|
</flux:table>
|
|
</div>
|
|
</flux:card>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex justify-start mt-4">
|
|
<flux:button variant="primary" class="sm:w-auto cursor-pointer" wire:click="save">
|
|
Simpan
|
|
</flux:button>
|
|
</div>
|
|
</div>
|
|
|
|
<flux:modal name="form-modal" class="w-[95%] max-w-sm md:max-w-xl mx-auto" @close="closeModal('form-modal')">
|
|
<div class="p-4 space-y-6">
|
|
<flux:heading size="lg">Ubah {{ $modalTitle }}</flux:heading>
|
|
|
|
<flux:input label="Kuantitas" placeholder="Masukkan kuantitas" wire:model="form.quantity_edit"
|
|
autocomplete="off" x-mask:dynamic="$money($input, ',')" />
|
|
|
|
<div class="flex">
|
|
<flux:spacer />
|
|
<flux:button variant="primary" color="zinc" class="sm:w-auto cursor-pointer"
|
|
wire:click="updateItem">
|
|
Perbarui
|
|
</flux:button>
|
|
</div>
|
|
</div>
|
|
</flux:modal>
|
|
</flux:main>
|