Added random serial number list livewire pages
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
This commit is contained in:
238
app/Livewire/RandomSerialNumberList.php
Normal file
238
app/Livewire/RandomSerialNumberList.php
Normal file
@@ -0,0 +1,238 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use App\Models\ClassCharacteristic;
|
||||
use App\Models\StickerStructureDetail;
|
||||
use App\Models\Item;
|
||||
use App\Models\StickerMappingMaster;
|
||||
use Filament\Notifications\Notification;
|
||||
use Livewire\Component;
|
||||
use Livewire\Attributes\Reactive;
|
||||
|
||||
class RandomSerialNumberList extends Component
|
||||
{
|
||||
|
||||
public bool $showMultipleSerials = false;
|
||||
|
||||
public array $serialNumbers = [''];
|
||||
|
||||
#[Reactive]
|
||||
public $plantId = null;
|
||||
|
||||
#[Reactive]
|
||||
public $machineId = null;
|
||||
|
||||
public function updatedShowMultipleSerials($value): void
|
||||
{
|
||||
$this->serialNumbers = collect($this->serialNumbers)
|
||||
->filter(fn ($serial) => trim($serial) !== '')
|
||||
->values()
|
||||
->toArray();
|
||||
// Clear all values whenever the checkbox changes
|
||||
$this->serialNumbers = [''];
|
||||
}
|
||||
|
||||
public function splitSerialNumbers(string $text): void
|
||||
{
|
||||
$serials = preg_split('/[\r\n\t ,;]+/', trim($text));
|
||||
|
||||
$this->serialNumbers = collect($serials)
|
||||
->filter(fn ($serial) => $serial !== '')
|
||||
->values()
|
||||
->toArray();
|
||||
|
||||
if (empty($this->serialNumbers)) {
|
||||
$this->serialNumbers = [''];
|
||||
}
|
||||
|
||||
$plantId = $this->plantId;
|
||||
$machineId = $this->machineId;
|
||||
|
||||
if (!$plantId) {
|
||||
Notification::make()
|
||||
->danger()
|
||||
->title('Plant Not Selected')
|
||||
->body('Please select a plant before pasting serial numbers.')
|
||||
->send();
|
||||
$this->dispatch('sticker-options-clear', stickerOptions: '');
|
||||
$this->dispatch('production-order-clear', productionOrder: '');
|
||||
return;
|
||||
}
|
||||
|
||||
$serialNumbersArray = array_values(
|
||||
array_filter(
|
||||
array_map('trim', $this->serialNumbers),
|
||||
fn ($serial) => $serial !== ''
|
||||
)
|
||||
);
|
||||
|
||||
if (count($serialNumbersArray) > 50) {
|
||||
Notification::make()
|
||||
->title('Too Many Serial Numbers')
|
||||
->body('You can enter a maximum of 50 serial numbers.')
|
||||
->danger()
|
||||
->send();
|
||||
$this->dispatch('sticker-options-clear', stickerOptions: '');
|
||||
$this->dispatch('production-order-clear', productionOrder: '');
|
||||
$this->serialNumbers = [''];
|
||||
return;
|
||||
}
|
||||
|
||||
$records = ClassCharacteristic::where('plant_id', $plantId)->whereIn('gernr', $serialNumbersArray)->get();
|
||||
|
||||
$foundSerialNumbers = $records->pluck('gernr')
|
||||
->map(fn ($serial) => trim((string) $serial))
|
||||
->unique()
|
||||
->toArray();
|
||||
|
||||
$missingSerialNumbers = array_values(
|
||||
array_diff($serialNumbersArray, $foundSerialNumbers)
|
||||
);
|
||||
|
||||
if (!empty($missingSerialNumbers)) {
|
||||
Notification::make()
|
||||
->danger()
|
||||
->title('Serial Numbers Not Found')
|
||||
->body('The following serial numbers do not exist for the selected plant: '. implode(', ', $missingSerialNumbers))
|
||||
->send();
|
||||
return;
|
||||
}
|
||||
|
||||
$productionOrder = $records->first()->aufnr;
|
||||
|
||||
$invalidSerialNumbers = $productionOrder
|
||||
? $records->filter(
|
||||
fn ($record) => $record->aufnr != $productionOrder
|
||||
)->pluck('gernr')->unique()->values()->toArray()
|
||||
: [];
|
||||
|
||||
if (!empty($invalidSerialNumbers)) {
|
||||
Notification::make()
|
||||
->danger()
|
||||
->title('Invalid Serial Numbers')
|
||||
->body('The following serial numbers belong to a different production order: '. implode(', ', $invalidSerialNumbers))
|
||||
->send();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$record = $records->first();
|
||||
$itemId = $record->item_id;
|
||||
|
||||
$item = Item::find($itemId);
|
||||
|
||||
if (! $item) {
|
||||
Notification::make()
|
||||
->title('Item not found')
|
||||
->body("Item code '{$itemId}' was not found in item master.")
|
||||
->danger()
|
||||
->send();
|
||||
$this->dispatch('sticker-options-clear', stickerOptions: '');
|
||||
$this->dispatch('production-order-clear', productionOrder: '');
|
||||
return;
|
||||
}
|
||||
|
||||
$itemCode = $item->code;
|
||||
|
||||
$item = Item::where('code', $itemCode)->where('plant_id', $plantId)->first();
|
||||
|
||||
if (! $item) {
|
||||
Notification::make()
|
||||
->title('Item not found')
|
||||
->body("Item '{$itemCode}' was not found for the selected plant.")
|
||||
->danger()
|
||||
->send();
|
||||
$this->dispatch('sticker-options-clear', stickerOptions: '');
|
||||
$this->dispatch('production-order-clear', productionOrder: '');
|
||||
return;
|
||||
}
|
||||
|
||||
$itemCharacteristic = ClassCharacteristic::where('plant_id', $plantId)->where('item_id', $item->id)->first();
|
||||
|
||||
if (! $itemCharacteristic) {
|
||||
Notification::make()
|
||||
->title('Class characteristic not found')
|
||||
->body("No class characteristic found for item '{$itemCode}'.")
|
||||
->danger()
|
||||
->send();
|
||||
return;
|
||||
}
|
||||
|
||||
// $itemCharacteristicId = $itemCharacteristic->id;
|
||||
|
||||
$stickerMappings = StickerMappingMaster::where('plant_id', $plantId)
|
||||
->where('item_id', $item->id)
|
||||
->get();
|
||||
|
||||
if (! $stickerMappings) {
|
||||
Notification::make()
|
||||
->title('Sticker mapping not found')
|
||||
->body("No sticker mapping found for this plant and item '$itemCode'.")
|
||||
->danger()
|
||||
->send();
|
||||
return;
|
||||
}
|
||||
|
||||
$stickerOptions = [];
|
||||
|
||||
foreach ($stickerMappings as $stickerMapping) {
|
||||
|
||||
for ($i = 1; $i <= 8; $i++) {
|
||||
|
||||
$machineColumn = "sticker{$i}_machine_id";
|
||||
|
||||
$stickerMachineId = $stickerMapping->$machineColumn;
|
||||
|
||||
if ((string) $stickerMachineId != (string) $machineId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$structureColumn = "sticker_structure{$i}_id";
|
||||
|
||||
$stickerStructureId = $stickerMapping->$structureColumn;
|
||||
|
||||
if (empty($stickerStructureId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$detail = StickerStructureDetail::find($stickerStructureId);
|
||||
|
||||
if ($detail && $detail->sticker_id) {
|
||||
|
||||
$stickerOptions[$detail->sticker_id] =
|
||||
$detail->sticker_id;
|
||||
}
|
||||
|
||||
$this->dispatch('sticker-structure-updated', stickerStructureId: $stickerStructureId);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$this->dispatch('sticker-options', stickerOptions: $stickerOptions);
|
||||
|
||||
$this->dispatch('production-order-updated', productionOrder: $productionOrder);
|
||||
}
|
||||
|
||||
public function generate(): void
|
||||
{
|
||||
$serialNumbersString = implode(',', array_filter(
|
||||
$this->serialNumbers,
|
||||
fn ($serial) => trim($serial) !== ''
|
||||
));
|
||||
|
||||
$this->dispatch('generate-sticker-id', serialNumbers: $serialNumbersString);
|
||||
|
||||
}
|
||||
|
||||
public function clear(){
|
||||
$this->serialNumbers = [''];
|
||||
$this->dispatch('sticker-options-clear', stickerOptions: '');
|
||||
$this->dispatch('production-order-clear', productionOrder: '');
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.random-serial-number-list');
|
||||
}
|
||||
}
|
||||
76
resources/views/livewire/random-serial-number-list.blade.php
Normal file
76
resources/views/livewire/random-serial-number-list.blade.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<div class="w-fit rounded-xl bg-white p-4 shadow-sm ring-1 ring-gray-950/5">
|
||||
<label class="flex items-center gap-2 mt-4">
|
||||
<input
|
||||
type="checkbox"
|
||||
wire:model.live="showMultipleSerials"
|
||||
class="rounded border-gray-300 text-primary-600"
|
||||
>
|
||||
<span class="text-sm font-medium">
|
||||
Show Multiple Serial Numbers
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
wire:click="generate"
|
||||
class="mt-2 rounded bg-primary-600 px-4 py-1 text-white"
|
||||
>
|
||||
Generate
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
wire:click="clear"
|
||||
class="mt-2 rounded bg-primary-600 px-4 py-1 text-white"
|
||||
>
|
||||
Clear
|
||||
</button>
|
||||
|
||||
@if ($showMultipleSerials)
|
||||
<div class="mt-4 overflow-x-auto">
|
||||
<div class="flex justify-end mb-2">
|
||||
<span class="text-sm font-medium">
|
||||
Total Count:
|
||||
<span class="text-primary-600 font-bold">
|
||||
{{ count(array_filter($serialNumbers, fn ($serial) => trim($serial) !== '')) }}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<table class="w-1/2 border-collapse border border-gray-300 text-sm">
|
||||
<thead>
|
||||
<tr class="bg-gray-100">
|
||||
<th class="border px-3 py-2">S.No</th>
|
||||
<th class="border px-3 py-2">Serial Number</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
@foreach ($serialNumbers as $index => $serial)
|
||||
<tr wire:key="serial-row-{{ $index }}">
|
||||
<td class="border px-3 py-2 text-center">
|
||||
{{ $index + 1 }}
|
||||
</td>
|
||||
|
||||
<td class="border px-3 py-2">
|
||||
<input
|
||||
type="text"
|
||||
{{-- wire:model="serialNumbers.{{ $index }}" --}}
|
||||
wire:model.live="serialNumbers.{{ $index }}"
|
||||
@if ($index === 0)
|
||||
x-data
|
||||
@paste.prevent="
|
||||
const text = $event.clipboardData.getData('text');
|
||||
$wire.splitSerialNumbers(text);
|
||||
"
|
||||
@endif
|
||||
class="w-full rounded border-gray-300"
|
||||
placeholder="Paste serial numbers here"
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
Reference in New Issue
Block a user