Added production checklist livewire pages
Some checks failed
Gemini PR Review / Gemini PR Review (pull_request) Waiting to run
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Waiting to run
Laravel Larastan / larastan (pull_request) Waiting to run
Laravel Pint / pint (pull_request) Waiting to run
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Some checks failed
Gemini PR Review / Gemini PR Review (pull_request) Waiting to run
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Waiting to run
Laravel Larastan / larastan (pull_request) Waiting to run
Laravel Pint / pint (pull_request) Waiting to run
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
This commit is contained in:
268
app/Livewire/ProductionCheckList.php
Normal file
268
app/Livewire/ProductionCheckList.php
Normal file
@@ -0,0 +1,268 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Livewire;
|
||||||
|
|
||||||
|
use App\Mail\InvalidQualityMail;
|
||||||
|
use App\Models\AlertMailRule;
|
||||||
|
use App\Models\Item;
|
||||||
|
use App\Models\Line;
|
||||||
|
use App\Models\Plant;
|
||||||
|
use App\Models\ProductCharacteristicsMaster;
|
||||||
|
use App\Models\ProductionCharacteristic;
|
||||||
|
use App\Models\QualityValidation;
|
||||||
|
use Filament\Facades\Filament;
|
||||||
|
use Filament\Notifications\Notification;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Facades\Mail;
|
||||||
|
use Livewire\Component;
|
||||||
|
use Livewire\Attributes\On;
|
||||||
|
|
||||||
|
|
||||||
|
class ProductionCheckList extends Component
|
||||||
|
{
|
||||||
|
|
||||||
|
public $records = [];
|
||||||
|
|
||||||
|
public $existingRecords = [];
|
||||||
|
|
||||||
|
public bool $shouldSkipChecklist = false;
|
||||||
|
|
||||||
|
public array $checklist = [];
|
||||||
|
|
||||||
|
public $showChecklist = false;
|
||||||
|
|
||||||
|
public $skipChecklistValidation = false;
|
||||||
|
|
||||||
|
protected $listeners = ['focus-item-id' => 'handleFocus', 'trigger-create' => 'doCreate',];
|
||||||
|
|
||||||
|
public $data =
|
||||||
|
[
|
||||||
|
'item_id' => '',
|
||||||
|
'plant_id' => '',
|
||||||
|
];
|
||||||
|
|
||||||
|
public $data1 = [
|
||||||
|
'checklist' => [],
|
||||||
|
];
|
||||||
|
|
||||||
|
#[On('focus-item-id')]
|
||||||
|
public function handleFocus()
|
||||||
|
{
|
||||||
|
$this->dispatch('focus-input');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function doCreate()
|
||||||
|
{
|
||||||
|
$this->create();
|
||||||
|
|
||||||
|
$this->shouldSkipChecklist = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function mount($records = [])
|
||||||
|
{
|
||||||
|
$this->records = collect($records);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function cancel()
|
||||||
|
{
|
||||||
|
$this->dispatch('checklist-cancelled');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function saveChecklist()
|
||||||
|
{
|
||||||
|
if (empty($this->checklist) || count($this->checklist) != count($this->records)) {
|
||||||
|
Notification::make()
|
||||||
|
->title('Incomplete Checklist')
|
||||||
|
->body('Please complete all checklist fields before submitting.')
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$item = Item::where('code', $this->data['item_id'])->first();
|
||||||
|
|
||||||
|
if (! $item) {
|
||||||
|
Notification::make()
|
||||||
|
->title('Invalid Item Code')
|
||||||
|
->body('Item not found for given code.')
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$itemAgaPlant = Item::where('code', $this->data['item_id'])->where('plant_id', $this->data['plant_id'])->first();
|
||||||
|
|
||||||
|
$plant = Plant::find($this->data['plant_id']);
|
||||||
|
|
||||||
|
if (! $itemAgaPlant) {
|
||||||
|
Notification::make()
|
||||||
|
->title('Invalid Item Code')
|
||||||
|
->body("Item code '$this->data['item_id']' not found for given plant code '{$plant?->code}'.")
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$itemId = $itemAgaPlant->id;
|
||||||
|
|
||||||
|
$exists = QualityValidation::where('plant_id', $this->data['plant_id'] ?? null)
|
||||||
|
->where('serial_number', $this->data['serial_number'] ?? null)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
$plan = Plant::find($this->data['plant_id']);
|
||||||
|
|
||||||
|
if ($exists) {
|
||||||
|
Notification::make()
|
||||||
|
->title('Duplicate Serial Number')
|
||||||
|
->body("serial number {$this->data['serial_number']} already exists for the selected plant $plan->code.")
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$qualityValidation = QualityValidation::create([
|
||||||
|
'plant_id' => $this->data['plant_id'] ?? null,
|
||||||
|
'line_id' => $this->data['line_id'] ?? null,
|
||||||
|
'sticker_master_id' => $this->data['sticker_master_id'] ?? null,
|
||||||
|
'production_order' => $this->data['production_order'] ?? null,
|
||||||
|
'serial_number_motor' => $this->data['serial_number_motor'] ?? null,
|
||||||
|
'serial_number_pump' => $this->data['serial_number_pump'] ?? null,
|
||||||
|
'serial_number_pumpset' => $this->data['serial_number_pumpset'] ?? null,
|
||||||
|
'pack_slip_motor' => $this->data['pack_slip_motor'] ?? null,
|
||||||
|
'pack_slip_pump' => $this->data['pack_slip_pump'] ?? null,
|
||||||
|
'pack_slip_pumpset' => $this->data['pack_slip_pumpset'] ?? null,
|
||||||
|
'name_plate_motor' => $this->data['name_plate_motor'] ?? null,
|
||||||
|
'name_plate_pump' => $this->data['name_plate_pump'] ?? null,
|
||||||
|
'name_plate_pumpset' => $this->data['name_plate_pumpset'] ?? null,
|
||||||
|
'tube_sticker_motor' => $this->data['tube_sticker_motor'] ?? null,
|
||||||
|
'tube_sticker_pump' => $this->data['tube_sticker_pump'] ?? null,
|
||||||
|
'tube_sticker_pumpset' => $this->data['tube_sticker_pumpset'] ?? null,
|
||||||
|
'warranty_card' => $this->data['warranty_card'] ?? null,
|
||||||
|
'part_validation1' => $this->data['part_validation1'] ?? null,
|
||||||
|
'part_validation2' => $this->data['part_validation2'] ?? null,
|
||||||
|
'part_validation3' => $this->data['part_validation3'] ?? null,
|
||||||
|
'part_validation4' => $this->data['part_validation4'] ?? null,
|
||||||
|
'part_validation5' => $this->data['part_validation5'] ?? null,
|
||||||
|
'operator_id' => $this->data['operator_id'] ?? null,
|
||||||
|
'uom' => $this->data['uom'] ?? null,
|
||||||
|
'serial_number' => $this->data['serial_number'] ?? null,
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (! $qualityValidation || ! $qualityValidation->exists) {
|
||||||
|
Notification::make()
|
||||||
|
->title('Failed to save Quality Validation')
|
||||||
|
->body('Something went wrong while inserting data.')
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$hasNotOk = collect($this->checklist)->contains(function ($val) {
|
||||||
|
return $val != 'ok';
|
||||||
|
});
|
||||||
|
|
||||||
|
$finalInspectionStatus = $hasNotOk ? 'NotOk' : 'Ok';
|
||||||
|
|
||||||
|
foreach ($this->checklist as $characteristicId => $value) {
|
||||||
|
|
||||||
|
$characteristic = ProductCharacteristicsMaster::find($characteristicId);
|
||||||
|
|
||||||
|
ProductionCharacteristic::create([
|
||||||
|
'plant_id' => $this->data['plant_id'] ?? null,
|
||||||
|
'item_id' => $itemId ?? null,
|
||||||
|
'line_id' => $this->data['line_id'] ?? null,
|
||||||
|
'machine_id' => $characteristic?->machine_id ?? null,
|
||||||
|
'production_order' => $this->data['production_order'] ?? null,
|
||||||
|
'serial_number' => $this->data['serial_number'] ?? null,
|
||||||
|
'characteristic_name' => $characteristic?->name ?? null,
|
||||||
|
'observed_value' => $this->data['observed_value'] ?? null,
|
||||||
|
'status' => $value == 'ok' ? 'Ok' : 'NotOk',
|
||||||
|
'inspection_status' => $finalInspectionStatus ?? null,
|
||||||
|
'created_by' => $this->data['operator_id'] ?? null,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($finalInspectionStatus == 'NotOk') {
|
||||||
|
|
||||||
|
$mailData = \App\Filament\Resources\QualityValidationResource::getMailData($this->data['plant_id']);
|
||||||
|
|
||||||
|
$mPlantName = $mailData['plant_name'];
|
||||||
|
$emails = $mailData['emails'];
|
||||||
|
$mUserName = Filament::auth()->user()->name;
|
||||||
|
$itemCode = $this->data['item_id'] ?? null;
|
||||||
|
$sNo = $this->data['serial_number'] ?? null;
|
||||||
|
$mPorder = $this->data['production_order'] ?? null;
|
||||||
|
$mLinePart = Line::where('id', $this->data['line_id'] ?? null)
|
||||||
|
->value('name');
|
||||||
|
$mExpectedValue = null; // optional
|
||||||
|
$state = $itemCode . '|' . $sNo;
|
||||||
|
|
||||||
|
if (!empty($emails)) {
|
||||||
|
Mail::to($emails)->queue(
|
||||||
|
new InvalidQualityMail(
|
||||||
|
$state,
|
||||||
|
$mPorder,
|
||||||
|
$mPlantName,
|
||||||
|
$mLinePart,
|
||||||
|
$mUserName,
|
||||||
|
$mExpectedValue,
|
||||||
|
'FinalInspectionNotOk'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
\Log::warning("No emails configured for plant: {$mPlantName}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->showChecklist = false;
|
||||||
|
|
||||||
|
$this->dispatch('checklist-saved');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getMailData($plantId)
|
||||||
|
{
|
||||||
|
$globalEmails = AlertMailRule::where('plant', 0)
|
||||||
|
->where('module', 'QualityValidation')
|
||||||
|
->where('rule_name', 'QualityMail')
|
||||||
|
->where(fn ($q) => $q->whereNull('schedule_type')->orWhere('schedule_type', ''))
|
||||||
|
->pluck('email')
|
||||||
|
->toArray();
|
||||||
|
|
||||||
|
if (! empty($globalEmails)) {
|
||||||
|
return [
|
||||||
|
'plant_id' => 0,
|
||||||
|
'plant_name' => 'All Plants',
|
||||||
|
'emails' => $globalEmails,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$mPlantName = Plant::where('id', $plantId)->value('name');
|
||||||
|
|
||||||
|
$emails = AlertMailRule::where('plant', $plantId)
|
||||||
|
->where('module', 'QualityValidation')
|
||||||
|
->where('rule_name', 'QualityMail')
|
||||||
|
->where(fn ($q) => $q->whereNull('schedule_type')->orWhere('schedule_type', ''))
|
||||||
|
->pluck('email')
|
||||||
|
->toArray();
|
||||||
|
|
||||||
|
return [
|
||||||
|
'plant_id' => $plantId,
|
||||||
|
'plant_name' => $mPlantName,
|
||||||
|
'emails' => $emails,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updatedDataChecklist()
|
||||||
|
{
|
||||||
|
$this->dispatch('checklistUpdated', $this->data['checklist']);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
return view('livewire.production-check-list');
|
||||||
|
}
|
||||||
|
}
|
||||||
65
resources/views/livewire/production-check-list.blade.php
Normal file
65
resources/views/livewire/production-check-list.blade.php
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
<div class="fixed inset-0 flex items-center justify-center z-50">
|
||||||
|
|
||||||
|
<div class="bg-white max-h-[80vh] overflow-hidden p-6 rounded-lg shadow-lg pointer-events-auto"
|
||||||
|
style="width:30vw !important; max-width:none !important;">
|
||||||
|
|
||||||
|
@if($records && $records->count())
|
||||||
|
<div style="max-height:250px; overflow-y:auto; border:1px solid #ccc;">
|
||||||
|
|
||||||
|
{{-- <table class="min-w-full border"> --}}
|
||||||
|
<table class="w-full table-fixed border text-sm">
|
||||||
|
<thead>
|
||||||
|
<tr class="bg-gray-100">
|
||||||
|
<th class="border px-2 py-1 w-2/3">Characteristics</th>
|
||||||
|
<th class="border px-2 py-1 w-1/6">OK</th>
|
||||||
|
<th class="border px-2 py-1 w-1/6">Not OK</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach($records as $record)
|
||||||
|
<tr>
|
||||||
|
<td class="border p-2">
|
||||||
|
{{ $record['name'] }}
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="border text-center">
|
||||||
|
<input type="radio"
|
||||||
|
wire:model="checklist.{{ $record['id'] }}"
|
||||||
|
value="ok">
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="border text-center">
|
||||||
|
<input type="radio"
|
||||||
|
wire:model="checklist.{{ $record['id'] }}"
|
||||||
|
value="not_ok">
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
@else
|
||||||
|
<p>No records found.</p>
|
||||||
|
@endif
|
||||||
|
<div class="border-t mt-6 pt-4 flex justify-end gap-3">
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
wire:click="cancel"
|
||||||
|
style="background-color:#dc2626; color:white;"
|
||||||
|
class="px-6 py-2 rounded-lg shadow-md"
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
wire:click="saveChecklist"
|
||||||
|
style="background-color:#16a34a; color:white;"
|
||||||
|
class="px-6 py-2 rounded-lg shadow-md"
|
||||||
|
>
|
||||||
|
Save
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
Reference in New Issue
Block a user