Added sticker print page #881
441
app/Filament/Pages/StickerPrint.php
Normal file
441
app/Filament/Pages/StickerPrint.php
Normal file
@@ -0,0 +1,441 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Pages;
|
||||||
|
|
||||||
|
use App\Models\Item;
|
||||||
|
use App\Models\ItemCharacteristic;
|
||||||
|
use App\Models\Machine;
|
||||||
|
use App\Models\Plant;
|
||||||
|
use App\Models\ProductionOrder;
|
||||||
|
use App\Models\StickerDetail;
|
||||||
|
use App\Models\StickerMappingMaster;
|
||||||
|
use App\Models\StickerStructureDetail;
|
||||||
|
use App\Models\StickerValidation;
|
||||||
|
use App\Services\StickerPdfService;
|
||||||
|
use Filament\Facades\Filament;
|
||||||
|
use Filament\Notifications\Notification;
|
||||||
|
use Filament\Pages\Page;
|
||||||
|
use Filament\Forms\Contracts\HasForms;
|
||||||
|
use Filament\Forms\Form;
|
||||||
|
use Filament\Forms\Components\Section;
|
||||||
|
use Filament\Forms\Components\Select;
|
||||||
|
use Filament\Forms\Components\TextInput;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
|
class StickerPrint extends Page implements HasForms
|
||||||
|
{
|
||||||
|
protected static ?string $navigationIcon = 'heroicon-o-document-text';
|
||||||
|
|
||||||
|
protected static string $view = 'filament.pages.sticker-print';
|
||||||
|
|
||||||
|
protected static ?string $navigationGroup = 'Customized Sticker Printing';
|
||||||
|
|
||||||
|
public array $filters = [];
|
||||||
|
|
||||||
|
public $serNo;
|
||||||
|
|
||||||
|
public $ref_number;
|
||||||
|
|
||||||
|
//public $workCenter;
|
||||||
|
|
||||||
|
public function form(Form $form): Form
|
||||||
|
{
|
||||||
|
return $form
|
||||||
|
->statePath('filters')
|
||||||
|
->schema([
|
||||||
|
Section::make('')
|
||||||
|
->schema([
|
||||||
|
Select::make('plant_id')
|
||||||
|
->label('Plant')
|
||||||
|
->reactive()
|
||||||
|
->options(function(){
|
||||||
|
|
||||||
|
$plantId = Filament::auth()->user()->plant_id;
|
||||||
|
|
||||||
|
return $plantId
|
||||||
|
? Plant::where('id',$plantId)
|
||||||
|
->pluck('name','id')
|
||||||
|
: Plant::pluck('name','id');
|
||||||
|
|
||||||
|
})
|
||||||
|
->required(),
|
||||||
|
Select::make('machine_id')
|
||||||
|
->label('Work Center')
|
||||||
|
->reactive()
|
||||||
|
->options(function(callable $get){
|
||||||
|
|
||||||
|
$plantId = $get('plant_id');
|
||||||
|
if (empty($plantId)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return Machine::where('plant_id', $plantId)->pluck('work_center', 'id');
|
||||||
|
|
||||||
|
})
|
||||||
|
->required(),
|
||||||
|
TextInput::make('production_order')
|
||||||
|
->label('Production Order')
|
||||||
|
->reactive()
|
||||||
|
->required(),
|
||||||
|
TextInput::make('serial_number')
|
||||||
|
->label('Serial Number')
|
||||||
|
->reactive()
|
||||||
|
->extraAttributes([
|
||||||
|
'wire:keydown.enter' => 'processSnoNo($event.target.value)',
|
||||||
|
]),
|
||||||
|
])
|
||||||
|
->columns(4),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function processSnoNo($qrcode)
|
||||||
|
{
|
||||||
|
|
||||||
|
$parts = explode('|', $qrcode, 2);
|
||||||
|
|
||||||
|
$itemCode = $parts[0] ?? null;
|
||||||
|
$serialNumber = $parts[1] ?? null;
|
||||||
|
|
||||||
|
$plantId = $this->form->getState()['plant_id'];
|
||||||
|
|
||||||
|
$plantId = trim($plantId) ?? null;
|
||||||
|
|
||||||
|
$workCenter = $this->form->getState()['machine_id'];
|
||||||
|
|
||||||
|
$prodOrderNo= $this->form->getState()['production_order'];
|
||||||
|
|
||||||
|
$prodOrderNo = trim($prodOrderNo) ?? null;
|
||||||
|
|
||||||
|
|
||||||
|
if (!$qrcode || !preg_match('/^\d+\|\d+$/', $qrcode)) {
|
||||||
|
Notification::make()
|
||||||
|
->title('Invalid QR Code')
|
||||||
|
->body('QR code format should be like: 123456|12456456464')
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
|
||||||
|
$this->form->fill([
|
||||||
|
'plant_id' => $plantId,
|
||||||
|
'machine_id' => $workCenter,
|
||||||
|
'production_order' => $prodOrderNo,
|
||||||
|
'serial_number' => null,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
elseif (!preg_match('/^[A-Za-z0-9]+$/', $itemCode)) {
|
||||||
|
Notification::make()
|
||||||
|
->title('Invalid Item Code')
|
||||||
|
->body('Item code should contain only alpha-numeric values.')
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
|
||||||
|
$this->form->fill([
|
||||||
|
'plant_id' => $plantId,
|
||||||
|
'machine_id' => $workCenter,
|
||||||
|
'production_order' => $prodOrderNo,
|
||||||
|
'serial_number' => null,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
elseif (!preg_match('/^[A-Za-z0-9]+$/', $serialNumber)) {
|
||||||
|
Notification::make()
|
||||||
|
->title('Invalid Serial Number')
|
||||||
|
->body('Serial number should contain only alpha-numeric values.')
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
|
||||||
|
$this->form->fill([
|
||||||
|
'plant_id' => $plantId,
|
||||||
|
'machine_id' => $workCenter,
|
||||||
|
'production_order' => $prodOrderNo,
|
||||||
|
'serial_number' => null,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$plant = Plant::find($plantId);
|
||||||
|
|
||||||
|
$plantName = $plant ? $plant->name : null;
|
||||||
|
|
||||||
|
$pOrderExist = ProductionOrder::where('plant_id', $plantId)
|
||||||
|
->where('production_order', $prodOrderNo)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if(!$pOrderExist){
|
||||||
|
Notification::make()
|
||||||
|
->title('Unknown Production Order')
|
||||||
|
->body("Production Order not found against plant '$plantName'.")
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
|
||||||
|
$this->form->fill([
|
||||||
|
'plant_id' => $plantId,
|
||||||
|
'machine_id' => $workCenter,
|
||||||
|
'production_order' => $prodOrderNo,
|
||||||
|
'serial_number' => null,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$itemExist = Item::where('code', $itemCode)->first();
|
||||||
|
|
||||||
|
$itemAgaPlant = Item::where('code', $itemCode)->where('plant_id', $plantId)->first();
|
||||||
|
|
||||||
|
if(!$itemExist){
|
||||||
|
Notification::make()
|
||||||
|
->title('Unknown Item Code')
|
||||||
|
->body("Item code '$itemCode' not found.")
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
|
||||||
|
$this->form->fill([
|
||||||
|
'plant_id' => $plantId,
|
||||||
|
'machine_id' => $workCenter,
|
||||||
|
'production_order' => $prodOrderNo,
|
||||||
|
'serial_number' => null,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
elseif(!$itemAgaPlant){
|
||||||
|
Notification::make()
|
||||||
|
->title('Unknown Item Code')
|
||||||
|
->body("Item code '$itemCode' not found against the the plant '$plantName'.")
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
|
||||||
|
$this->form->fill([
|
||||||
|
'plant_id' => $plantId,
|
||||||
|
'machine_id' => $workCenter,
|
||||||
|
'production_order' => $prodOrderNo,
|
||||||
|
'serial_number' => null,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
elseif ($itemAgaPlant->id != $pOrderExist->item_id) {
|
||||||
|
Notification::make()
|
||||||
|
->title('Item Code Mismatch')
|
||||||
|
->body("Item code '$itemCode' does not match the item associated with production order '$prodOrderNo'.")
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
|
||||||
|
$this->form->fill([
|
||||||
|
'plant_id' => $plantId,
|
||||||
|
'machine_id' => $workCenter,
|
||||||
|
'production_order' => $prodOrderNo,
|
||||||
|
'serial_number' => null,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$productionOrders = ProductionOrder::where('plant_id', $plantId)
|
||||||
|
->where('production_order', $prodOrderNo)
|
||||||
|
->where('item_id', $itemAgaPlant->id)
|
||||||
|
->get();
|
||||||
|
|
||||||
|
$serialExist = null;
|
||||||
|
|
||||||
|
foreach ($productionOrders as $productionOrder) {
|
||||||
|
|
||||||
|
for (
|
||||||
|
$serial = (int) $productionOrder->from_serial_number;
|
||||||
|
$serial <= (int) $productionOrder->to_serial_number;
|
||||||
|
$serial++
|
||||||
|
) {
|
||||||
|
if ($serial == (int) $serialNumber) {
|
||||||
|
$serialExist = $productionOrder;
|
||||||
|
break 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$serialExist){
|
||||||
|
Notification::make()
|
||||||
|
->title('Serial Number Not Found')
|
||||||
|
->body("Serial number '$serialNumber' not found for production order '$prodOrderNo', item '$itemCode' and plant '$plantName'.")
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
|
||||||
|
$this->form->fill([
|
||||||
|
'plant_id' => $plantId,
|
||||||
|
'machine_id' => $workCenter,
|
||||||
|
'production_order' => $prodOrderNo,
|
||||||
|
'serial_number' => null,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//..Generate Sticker PDF and download it
|
||||||
|
|
||||||
|
$this->ref_number = $this->form->getState()['production_order'];
|
||||||
|
|
||||||
|
$this->serNo = $serialNumber;
|
||||||
|
|
||||||
|
$user = Filament::auth()->user();
|
||||||
|
|
||||||
|
$operatorName = $user->name;
|
||||||
|
|
||||||
|
$duplicate = StickerValidation::where('plant_id', $plantId)
|
||||||
|
->where('production_order', $this->ref_number)
|
||||||
|
->where('serial_number', $serialNumber)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if ($duplicate) {
|
||||||
|
Notification::make()
|
||||||
|
->danger()
|
||||||
|
->title('Duplicate Serial Number')
|
||||||
|
->body("Serial number $serialNumber already exists for this plant and production order!")
|
||||||
|
->seconds(3)
|
||||||
|
->send();
|
||||||
|
|
||||||
|
$this->form->fill([
|
||||||
|
'plant_id' => $plantId,
|
||||||
|
'machine_id' => $workCenter,
|
||||||
|
'production_order' => $this->ref_number,
|
||||||
|
'serial_number' => null,
|
||||||
|
]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$itemC = Item::where('code', $itemCode)
|
||||||
|
->where('plant_id',$plantId)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
$itemId = $itemC->id;
|
||||||
|
|
||||||
|
$item = ItemCharacteristic::where('item_id', $itemId)
|
||||||
|
->where('plant_id',$plantId)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
$itemI = $item->id;
|
||||||
|
|
||||||
|
$mapping = StickerMappingMaster::where('plant_id', $plantId)
|
||||||
|
->where('item_characteristic_id', $itemI)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if (!$mapping) {
|
||||||
|
Notification::make()
|
||||||
|
->danger()
|
||||||
|
->title('Sticker Mapping Not Found')
|
||||||
|
->body("No sticker mapping found for this item and plant.")
|
||||||
|
->send();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stickers = [];
|
||||||
|
|
||||||
|
for ($i = 1; $i <= 8; $i++) {
|
||||||
|
$machineColumn = "sticker{$i}_machine_id";
|
||||||
|
$ipColumn = "sticker{$i}_print_ip";
|
||||||
|
$stickerColumn = "sticker_structure{$i}_id";
|
||||||
|
$itemColumn = "item_characteristic_id";
|
||||||
|
|
||||||
|
if (
|
||||||
|
!empty($mapping->$machineColumn) &&
|
||||||
|
!empty($mapping->$stickerColumn)
|
||||||
|
) {
|
||||||
|
$stickers[] = [
|
||||||
|
'machine_id' => $mapping->$machineColumn,
|
||||||
|
'sticker_id' => $mapping->$stickerColumn,
|
||||||
|
'item_characteristic' => $mapping->$itemColumn,
|
||||||
|
'print_ip' => $mapping->$ipColumn,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($stickers)) {
|
||||||
|
Notification::make()
|
||||||
|
->danger()
|
||||||
|
->title('No Sticker Configuration Found')
|
||||||
|
->body('No sticker and machine mappings configured for this item and plant.')
|
||||||
|
->send();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
StickerValidation::create([
|
||||||
|
'plant_id' => $plantId,
|
||||||
|
'machine_id' => $workCenter,
|
||||||
|
'production_order' => $this->ref_number ?? null,
|
||||||
|
'serial_number' => $serialNumber,
|
||||||
|
'status' => 'Printed',
|
||||||
|
// 'sticker_id' => $matchedSticker,
|
||||||
|
'created_by' => $operatorName,
|
||||||
|
'created_at' => now(),
|
||||||
|
'updated_at' => now(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
Notification::make()
|
||||||
|
->success()
|
||||||
|
->title('Sticker Recorded')
|
||||||
|
->body("Item: $itemCode, Serial: $serialNumber recorded successfully!")
|
||||||
|
->seconds(3)
|
||||||
|
->send();
|
||||||
|
|
||||||
|
$this->form->fill([
|
||||||
|
'plant_id' => $plantId,
|
||||||
|
'machine_id' => $workCenter,
|
||||||
|
'production_order' => $this->ref_number,
|
||||||
|
'serial_number' => null,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$pdfUrls = [];
|
||||||
|
|
||||||
|
foreach ($stickers as $sticker)
|
||||||
|
{
|
||||||
|
|
||||||
|
$structure = StickerStructureDetail::findOrFail($sticker['sticker_id']);
|
||||||
|
|
||||||
|
$itemCharacteristic = ItemCharacteristic::where('plant_id', $plantId)
|
||||||
|
->where('id', $sticker['item_characteristic'])
|
||||||
|
->firstOrFail();
|
||||||
|
|
||||||
|
$dynamicElements = StickerDetail::where(
|
||||||
|
'sticker_structure_detail_id',
|
||||||
|
$structure->id
|
||||||
|
)->where('element_type', 'Dynamic')->get();
|
||||||
|
|
||||||
|
$pdfContent = (new StickerPdfService())->generatePdf1(
|
||||||
|
$structure->sticker_id,
|
||||||
|
$dynamicElements,
|
||||||
|
$itemCharacteristic,
|
||||||
|
$serialNumber,
|
||||||
|
$itemCode,
|
||||||
|
$plantId
|
||||||
|
);
|
||||||
|
|
||||||
|
$tempPdfPath = storage_path('app/temp_sticker_' . uniqid() . '.pdf');
|
||||||
|
|
||||||
|
file_put_contents($tempPdfPath, $pdfContent);
|
||||||
|
|
||||||
|
// $pdfUrl = route('sticker.preview', [
|
||||||
|
// 'path' => basename($tempPdfPath),
|
||||||
|
// ]);
|
||||||
|
$pdfUrls[] = route('sticker.preview', ['path' => basename($tempPdfPath)]);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->dispatch('open-sticker-pdf', urls: $pdfUrls);
|
||||||
|
|
||||||
|
Notification::make()
|
||||||
|
->success()
|
||||||
|
->title('Sticker Printed')
|
||||||
|
->body("Sticker for Serial Number: $serialNumber printed successfully!")
|
||||||
|
->seconds(3)
|
||||||
|
->send();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function canAccess(): bool
|
||||||
|
{
|
||||||
|
return Auth::check() && Auth::user()->can('view sticker print page');
|
||||||
|
}
|
||||||
|
}
|
||||||
28
resources/views/filament/pages/sticker-print.blade.php
Normal file
28
resources/views/filament/pages/sticker-print.blade.php
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<x-filament-panels::page>
|
||||||
|
|
||||||
|
|
||||||
|
{{ $this->form }}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener('livewire:init', () => {
|
||||||
|
|
||||||
|
Livewire.on('open-sticker-pdf', (event) => {
|
||||||
|
|
||||||
|
console.log('PDF EVENT RECEIVED', event);
|
||||||
|
|
||||||
|
const urls = event.urls;
|
||||||
|
|
||||||
|
console.log('PDF URLs:', urls);
|
||||||
|
|
||||||
|
urls.forEach(url => {
|
||||||
|
window.open(url, '_blank');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</x-filament-panels::page>
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user