468 lines
32 KiB
PHP
468 lines
32 KiB
PHP
@extends('layouts.app')
|
|
|
|
@section('content')
|
|
<div class="space-y-6">
|
|
<!-- Page Header -->
|
|
<div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
|
|
<h1 class="text-2xl font-bold text-gray-900">{{ __('inventory.transactions') }}</h1>
|
|
<div class="flex gap-2 flex-wrap">
|
|
<button onclick="document.getElementById('stockInModal').classList.remove('hidden')"
|
|
class="inline-flex items-center gap-2 px-4 py-2 bg-emerald-600 text-white text-sm font-medium rounded-lg hover:bg-emerald-700 transition-colors">
|
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/></svg>
|
|
{{ __('inventory.stock_in') }}
|
|
</button>
|
|
<button onclick="document.getElementById('stockOutModal').classList.remove('hidden')"
|
|
class="inline-flex items-center gap-2 px-4 py-2 bg-red-600 text-white text-sm font-medium rounded-lg hover:bg-red-700 transition-colors">
|
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 12H4"/></svg>
|
|
{{ __('inventory.stock_out') }}
|
|
</button>
|
|
<button onclick="document.getElementById('transferModal').classList.remove('hidden')"
|
|
class="inline-flex items-center gap-2 px-4 py-2 bg-purple-600 text-white text-sm font-medium rounded-lg hover:bg-purple-700 transition-colors">
|
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4"/></svg>
|
|
{{ __('inventory.transfer') ?? 'انتقال' }}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Filters -->
|
|
<div class="bg-white rounded-xl border border-gray-200 p-4">
|
|
<form method="GET" action="{{ route('inventory.transactions') }}" class="flex flex-wrap gap-3 items-end">
|
|
<div class="w-44">
|
|
<label class="block text-xs font-medium text-gray-500 mb-1">{{ __('inventory.item') }}</label>
|
|
<select name="item_id" class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-teal-500">
|
|
<option value="">{{ __('common.all') }}</option>
|
|
@foreach($items as $item)
|
|
<option value="{{ $item->id }}" {{ request('item_id') == $item->id ? 'selected' : '' }}>{{ $item->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div class="w-44">
|
|
<label class="block text-xs font-medium text-gray-500 mb-1">{{ __('inventory.warehouse') }}</label>
|
|
<select name="warehouse_id" class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-teal-500">
|
|
<option value="">{{ __('common.all') }}</option>
|
|
@foreach($warehouses as $wh)
|
|
<option value="{{ $wh->id }}" {{ request('warehouse_id') == $wh->id ? 'selected' : '' }}>{{ $wh->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div class="w-36">
|
|
<label class="block text-xs font-medium text-gray-500 mb-1">{{ __('inventory.transaction_type') }}</label>
|
|
<select name="type" class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-teal-500">
|
|
<option value="">{{ __('common.all') }}</option>
|
|
@foreach($types as $t)
|
|
<option value="{{ $t }}" {{ request('type') === $t ? 'selected' : '' }}">{{ __('inventory.type_' . $t) }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div class="w-44">
|
|
<label class="block text-xs font-medium text-gray-500 mb-1">{{ __('inventory.project') }}</label>
|
|
<select name="project_id" class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-teal-500">
|
|
<option value="">{{ __('common.all') }}</option>
|
|
@foreach($projects as $project)
|
|
<option value="{{ $project->id }}" {{ request('project_id') == $project->id ? 'selected' : '' }}>{{ $project->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div class="w-36">
|
|
<label class="block text-xs font-medium text-gray-500 mb-1">{{ __('inventory.from_date') }}</label>
|
|
<x-date-input name="from_date" :value="request('from_date')" />
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-teal-500">
|
|
</div>
|
|
<div class="w-36">
|
|
<label class="block text-xs font-medium text-gray-500 mb-1">{{ __('inventory.to_date') }}</label>
|
|
<x-date-input name="to_date" :value="request('to_date')" />
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-teal-500">
|
|
</div>
|
|
<button type="submit" class="px-4 py-2 bg-gray-100 text-gray-700 text-sm font-medium rounded-lg hover:bg-gray-200 transition-colors">
|
|
{{ __('common.filter') }}
|
|
</button>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- Transactions List -->
|
|
<div class="bg-white rounded-xl border border-gray-200 overflow-hidden">
|
|
<div class="overflow-x-auto">
|
|
<table class="w-full">
|
|
<thead class="bg-gray-50 border-b border-gray-200">
|
|
<tr>
|
|
<th class="px-5 py-3 text-start text-xs font-medium text-gray-500">{{ __('inventory.transaction_type') }}</th>
|
|
<th class="px-5 py-3 text-start text-xs font-medium text-gray-500">{{ __('inventory.item') }}</th>
|
|
<th class="px-5 py-3 text-start text-xs font-medium text-gray-500">{{ __('inventory.warehouse') }}</th>
|
|
<th class="px-5 py-3 text-start text-xs font-medium text-gray-500">{{ __('inventory.quantity') }}</th>
|
|
<th class="px-5 py-3 text-start text-xs font-medium text-gray-500">{{ __('inventory.unit_price') }}</th>
|
|
<th class="px-5 py-3 text-start text-xs font-medium text-gray-500">{{ __('inventory.total_price') }}</th>
|
|
<th class="px-5 py-3 text-start text-xs font-medium text-gray-500">{{ __('inventory.reference') }}</th>
|
|
<th class="px-5 py-3 text-start text-xs font-medium text-gray-500">{{ __('common.date') ?? 'تاریخ' }}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y divide-gray-100">
|
|
@forelse($transactions as $txn)
|
|
<tr class="hover:bg-gray-50 transition-colors">
|
|
<td class="px-5 py-3">
|
|
<span class="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium
|
|
{{ $txn->type === 'in' ? 'bg-emerald-50 text-emerald-700' :
|
|
($txn->type === 'out' ? 'bg-red-50 text-red-700' :
|
|
($txn->type === 'return' ? 'bg-sky-50 text-sky-700' :
|
|
($txn->type === 'transfer' ? 'bg-purple-50 text-purple-700' :
|
|
'bg-amber-50 text-amber-700'))) }}">
|
|
{{ __('inventory.type_' . $txn->type) }}
|
|
</span>
|
|
</td>
|
|
<td class="px-5 py-3 text-sm font-medium text-gray-900">{{ $txn->item?->name ?? '-' }}</td>
|
|
<td class="px-5 py-3 text-sm text-gray-600">{{ $txn->warehouse?->name ?? '-' }}</td>
|
|
<td class="px-5 py-3 text-sm font-medium {{ $txn->type === 'out' ? 'text-red-600' : ($txn->type === 'in' ? 'text-emerald-600' : '') }}">
|
|
{{ $txn->type === 'out' ? '-' : '+' }}{{ persian_num(number_format($txn->quantity, 2)) }}
|
|
@if($txn->item?->unit)
|
|
<span class="text-xs text-gray-400 font-normal">{{ $txn->item->unit }}</span>
|
|
@endif
|
|
</td>
|
|
<td class="px-5 py-3 text-sm text-gray-600">
|
|
@if($txn->unit_price)
|
|
{{ format_currency((float)$txn->unit_price, $txn->currency?->code) }}
|
|
@else
|
|
-
|
|
@endif
|
|
</td>
|
|
<td class="px-5 py-3 text-sm font-medium text-gray-900">
|
|
@if($txn->total_price)
|
|
{{ format_currency((float)$txn->total_price, $txn->currency?->code) }}
|
|
@else
|
|
-
|
|
@endif
|
|
</td>
|
|
<td class="px-5 py-3 text-sm text-gray-600">{{ $txn->reference_number ?? $txn->reference ?? '-' }}</td>
|
|
<td class="px-5 py-3 text-sm text-gray-400">{{ $txn->created_at ? calendar_date($txn->created_at) : '-' }}</td>
|
|
</tr>
|
|
@empty
|
|
<tr>
|
|
<td colspan="8" class="text-center py-12 text-gray-500">{{ __('inventory.no_transactions') }}</td>
|
|
</tr>
|
|
@endforelse
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Pagination -->
|
|
<div class="flex justify-center">
|
|
{{ $transactions->withQueryString()->links() }}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Stock In Modal -->
|
|
<div id="stockInModal" class="hidden fixed inset-0 z-50 overflow-y-auto">
|
|
<div class="flex items-center justify-center min-h-screen px-4 pt-4 pb-20">
|
|
<div class="fixed inset-0 bg-gray-900/50 transition-opacity" onclick="document.getElementById('stockInModal').classList.add('hidden')"></div>
|
|
<div class="relative bg-white rounded-2xl shadow-xl max-w-2xl w-full p-6 z-10">
|
|
<div class="flex items-center justify-between mb-5">
|
|
<h3 class="text-lg font-bold text-gray-900">{{ __('inventory.stock_in') }}</h3>
|
|
<button onclick="document.getElementById('stockInModal').classList.add('hidden')" class="p-1 text-gray-400 hover:text-gray-600">
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/></svg>
|
|
</button>
|
|
</div>
|
|
<form method="POST" action="{{ route('inventory.stock-in') }}" class="space-y-4">
|
|
@csrf
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('inventory.item') }} <span class="text-red-500">*</span></label>
|
|
<select name="item_id" id="stockIn_item_id" required
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-emerald-500">
|
|
<option value="">{{ __('common.select') }}</option>
|
|
@foreach($items as $item)
|
|
<option value="{{ $item->id }}">{{ $item->name }} {{ $item->code ? '(' . $item->code . ')' : '' }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('inventory.warehouse') }} <span class="text-red-500">*</span></label>
|
|
<select name="warehouse_id" id="stockIn_warehouse_id" required
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-emerald-500">
|
|
<option value="">{{ __('common.select') }}</option>
|
|
@foreach($warehouses as $wh)
|
|
<option value="{{ $wh->id }}">{{ $wh->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('inventory.quantity') }} <span class="text-red-500">*</span></label>
|
|
<input type="number" name="quantity" step="0.01" min="0.01" required
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-emerald-500">
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('inventory.unit_price') }}</label>
|
|
<input type="number" name="unit_price" step="0.01" min="0"
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-emerald-500">
|
|
</div>
|
|
@if(isset($currencies) && $currencies->count() > 0)
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('settings.currency') ?? 'ارز' }}</label>
|
|
<select name="currency_id"
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-emerald-500">
|
|
<option value="">{{ __('common.select') }}</option>
|
|
@foreach($currencies as $currency)
|
|
<option value="{{ $currency->id }}" {{ $currency->is_default ? 'selected' : '' }}>{{ $currency->name }} ({{ $currency->code }})</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
@endif
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('inventory.project') }}</label>
|
|
<select name="project_id"
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-emerald-500">
|
|
<option value="">{{ __('common.select') }}</option>
|
|
@foreach($projects as $project)
|
|
<option value="{{ $project->id }}">{{ $project->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('inventory.reference') }}</label>
|
|
<input type="text" name="reference_number"
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-emerald-500">
|
|
</div>
|
|
<div class="md:col-span-2">
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('inventory.notes') }}</label>
|
|
<textarea name="notes" rows="2"
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-emerald-500"></textarea>
|
|
</div>
|
|
</div>
|
|
<div id="stockIn_current_stock" class="hidden bg-gray-50 rounded-lg p-3 text-sm">
|
|
<span class="text-gray-600">{{ __('inventory.current_stock') }}:</span>
|
|
<span id="stockIn_stock_value" class="font-bold text-gray-900 ms-2">-</span>
|
|
</div>
|
|
<div class="flex justify-end gap-3 pt-3 border-t border-gray-200">
|
|
<button type="button" onclick="document.getElementById('stockInModal').classList.add('hidden')"
|
|
class="px-4 py-2 text-sm font-medium text-gray-700 bg-gray-100 rounded-lg hover:bg-gray-200">{{ __('common.cancel') }}</button>
|
|
<button type="submit" class="px-6 py-2 text-sm font-medium text-white bg-emerald-600 rounded-lg hover:bg-emerald-700">{{ __('inventory.stock_in') }}</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Stock Out Modal -->
|
|
<div id="stockOutModal" class="hidden fixed inset-0 z-50 overflow-y-auto">
|
|
<div class="flex items-center justify-center min-h-screen px-4 pt-4 pb-20">
|
|
<div class="fixed inset-0 bg-gray-900/50 transition-opacity" onclick="document.getElementById('stockOutModal').classList.add('hidden')"></div>
|
|
<div class="relative bg-white rounded-2xl shadow-xl max-w-2xl w-full p-6 z-10">
|
|
<div class="flex items-center justify-between mb-5">
|
|
<h3 class="text-lg font-bold text-gray-900">{{ __('inventory.stock_out') }}</h3>
|
|
<button onclick="document.getElementById('stockOutModal').classList.add('hidden')" class="p-1 text-gray-400 hover:text-gray-600">
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/></svg>
|
|
</button>
|
|
</div>
|
|
<form method="POST" action="{{ route('inventory.stock-out') }}" class="space-y-4">
|
|
@csrf
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('inventory.item') }} <span class="text-red-500">*</span></label>
|
|
<select name="item_id" id="stockOut_item_id" required
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-red-500">
|
|
<option value="">{{ __('common.select') }}</option>
|
|
@foreach($items as $item)
|
|
<option value="{{ $item->id }}">{{ $item->name }} {{ $item->code ? '(' . $item->code . ')' : '' }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('inventory.warehouse') }} <span class="text-red-500">*</span></label>
|
|
<select name="warehouse_id" id="stockOut_warehouse_id" required
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-red-500">
|
|
<option value="">{{ __('common.select') }}</option>
|
|
@foreach($warehouses as $wh)
|
|
<option value="{{ $wh->id }}">{{ $wh->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('inventory.quantity') }} <span class="text-red-500">*</span></label>
|
|
<input type="number" name="quantity" step="0.01" min="0.01" required
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-red-500">
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('inventory.unit_price') }}</label>
|
|
<input type="number" name="unit_price" step="0.01" min="0"
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-red-500">
|
|
</div>
|
|
@if(isset($currencies) && $currencies->count() > 0)
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('settings.currency') ?? 'ارز' }}</label>
|
|
<select name="currency_id"
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-red-500">
|
|
<option value="">{{ __('common.select') }}</option>
|
|
@foreach($currencies as $currency)
|
|
<option value="{{ $currency->id }}" {{ $currency->is_default ? 'selected' : '' }}>{{ $currency->name }} ({{ $currency->code }})</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
@endif
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('inventory.project') }}</label>
|
|
<select name="project_id"
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-red-500">
|
|
<option value="">{{ __('common.select') }}</option>
|
|
@foreach($projects as $project)
|
|
<option value="{{ $project->id }}">{{ $project->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('inventory.reference') }}</label>
|
|
<input type="text" name="reference_number"
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-red-500">
|
|
</div>
|
|
<div class="md:col-span-2">
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('inventory.notes') }}</label>
|
|
<textarea name="notes" rows="2"
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-red-500"></textarea>
|
|
</div>
|
|
</div>
|
|
<div id="stockOut_current_stock" class="hidden bg-gray-50 rounded-lg p-3 text-sm">
|
|
<span class="text-gray-600">{{ __('inventory.current_stock') }}:</span>
|
|
<span id="stockOut_stock_value" class="font-bold text-gray-900 ms-2">-</span>
|
|
</div>
|
|
@error('quantity')
|
|
<p class="text-sm text-red-600">{{ $message }}</p>
|
|
@enderror
|
|
<div class="flex justify-end gap-3 pt-3 border-t border-gray-200">
|
|
<button type="button" onclick="document.getElementById('stockOutModal').classList.add('hidden')"
|
|
class="px-4 py-2 text-sm font-medium text-gray-700 bg-gray-100 rounded-lg hover:bg-gray-200">{{ __('common.cancel') }}</button>
|
|
<button type="submit" class="px-6 py-2 text-sm font-medium text-white bg-red-600 rounded-lg hover:bg-red-700">{{ __('inventory.stock_out') }}</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Transfer Modal -->
|
|
<div id="transferModal" class="hidden fixed inset-0 z-50 overflow-y-auto">
|
|
<div class="flex items-center justify-center min-h-screen px-4 pt-4 pb-20">
|
|
<div class="fixed inset-0 bg-gray-900/50 transition-opacity" onclick="document.getElementById('transferModal').classList.add('hidden')"></div>
|
|
<div class="relative bg-white rounded-2xl shadow-xl max-w-2xl w-full p-6 z-10">
|
|
<div class="flex items-center justify-between mb-5">
|
|
<h3 class="text-lg font-bold text-gray-900">{{ __('inventory.transfer') ?? 'انتقال بین انبارها' }}</h3>
|
|
<button onclick="document.getElementById('transferModal').classList.add('hidden')" class="p-1 text-gray-400 hover:text-gray-600">
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/></svg>
|
|
</button>
|
|
</div>
|
|
<form method="POST" action="{{ route('inventory.transfer') }}" class="space-y-4">
|
|
@csrf
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('inventory.item') }} <span class="text-red-500">*</span></label>
|
|
<select name="item_id" id="transfer_item_id" required
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-purple-500">
|
|
<option value="">{{ __('common.select') }}</option>
|
|
@foreach($items as $item)
|
|
<option value="{{ $item->id }}">{{ $item->name }} {{ $item->code ? '(' . $item->code . ')' : '' }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('inventory.quantity') }} <span class="text-red-500">*</span></label>
|
|
<input type="number" name="quantity" step="0.01" min="0.01" required
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-purple-500">
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('inventory.from_warehouse') ?? 'انبار مبدأ' }} <span class="text-red-500">*</span></label>
|
|
<select name="from_warehouse_id" id="transfer_from_wh" required
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-purple-500">
|
|
<option value="">{{ __('common.select') }}</option>
|
|
@foreach($warehouses as $wh)
|
|
<option value="{{ $wh->id }}">{{ $wh->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('inventory.to_warehouse') ?? 'انبار مقصد' }} <span class="text-red-500">*</span></label>
|
|
<select name="to_warehouse_id" id="transfer_to_wh" required
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-purple-500">
|
|
<option value="">{{ __('common.select') }}</option>
|
|
@foreach($warehouses as $wh)
|
|
<option value="{{ $wh->id }}">{{ $wh->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('inventory.project') }}</label>
|
|
<select name="project_id"
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-purple-500">
|
|
<option value="">{{ __('common.select') }}</option>
|
|
@foreach($projects as $project)
|
|
<option value="{{ $project->id }}">{{ $project->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div class="md:col-span-2">
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">{{ __('inventory.notes') }}</label>
|
|
<textarea name="notes" rows="2"
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-purple-500"></textarea>
|
|
</div>
|
|
</div>
|
|
<div id="transfer_current_stock" class="hidden bg-gray-50 rounded-lg p-3 text-sm">
|
|
<span class="text-gray-600">{{ __('inventory.current_stock_source') ?? 'موجودی مبدأ' }}:</span>
|
|
<span id="transfer_stock_value" class="font-bold text-gray-900 ms-2">-</span>
|
|
</div>
|
|
@error('quantity')
|
|
<p class="text-sm text-red-600">{{ $message }}</p>
|
|
@enderror
|
|
<div class="flex justify-end gap-3 pt-3 border-t border-gray-200">
|
|
<button type="button" onclick="document.getElementById('transferModal').classList.add('hidden')"
|
|
class="px-4 py-2 text-sm font-medium text-gray-700 bg-gray-100 rounded-lg hover:bg-gray-200">{{ __('common.cancel') }}</button>
|
|
<button type="submit" class="px-6 py-2 text-sm font-medium text-white bg-purple-600 rounded-lg hover:bg-purple-700">{{ __('inventory.transfer') ?? 'انتقال' }}</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
@push('scripts')
|
|
<script>
|
|
async function fetchStock(itemId, warehouseId, stockDisplayId, stockValueId) {
|
|
if (!itemId || !warehouseId) return;
|
|
try {
|
|
const res = await fetch('{{ route("inventory.current-stock") }}?item_id=' + itemId + '&warehouse_id=' + warehouseId, {
|
|
headers: { 'Accept': 'application/json', 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content }
|
|
});
|
|
const data = await res.json();
|
|
document.getElementById(stockValueId).textContent = data.current_stock ?? '0';
|
|
document.getElementById(stockDisplayId).classList.remove('hidden');
|
|
} catch(e) { console.error(e); }
|
|
}
|
|
|
|
// Stock In modal
|
|
document.getElementById('stockIn_item_id')?.addEventListener('change', () => {
|
|
fetchStock(document.getElementById('stockIn_item_id').value, document.getElementById('stockIn_warehouse_id').value, 'stockIn_current_stock', 'stockIn_stock_value');
|
|
});
|
|
document.getElementById('stockIn_warehouse_id')?.addEventListener('change', () => {
|
|
fetchStock(document.getElementById('stockIn_item_id').value, document.getElementById('stockIn_warehouse_id').value, 'stockIn_current_stock', 'stockIn_stock_value');
|
|
});
|
|
|
|
// Stock Out modal
|
|
document.getElementById('stockOut_item_id')?.addEventListener('change', () => {
|
|
fetchStock(document.getElementById('stockOut_item_id').value, document.getElementById('stockOut_warehouse_id').value, 'stockOut_current_stock', 'stockOut_stock_value');
|
|
});
|
|
document.getElementById('stockOut_warehouse_id')?.addEventListener('change', () => {
|
|
fetchStock(document.getElementById('stockOut_item_id').value, document.getElementById('stockOut_warehouse_id').value, 'stockOut_current_stock', 'stockOut_stock_value');
|
|
});
|
|
|
|
// Transfer modal
|
|
document.getElementById('transfer_item_id')?.addEventListener('change', () => {
|
|
fetchStock(document.getElementById('transfer_item_id').value, document.getElementById('transfer_from_wh').value, 'transfer_current_stock', 'transfer_stock_value');
|
|
});
|
|
document.getElementById('transfer_from_wh')?.addEventListener('change', () => {
|
|
fetchStock(document.getElementById('transfer_item_id').value, document.getElementById('transfer_from_wh').value, 'transfer_current_stock', 'transfer_stock_value');
|
|
});
|
|
|
|
// Auto-show error modal
|
|
@if($errors->any() && old('_token'))
|
|
@if($errors->has('from_warehouse_id') || $errors->has('to_warehouse_id'))
|
|
document.getElementById('transferModal').classList.remove('hidden');
|
|
@else
|
|
document.getElementById('stockOutModal').classList.remove('hidden');
|
|
@endif
|
|
@endif
|
|
</script>
|
|
@endpush
|
|
@endsection
|