Initial commit for new repo
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 1m4s
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 1m4s
This commit is contained in:
95
app/Filament/Pages/Dashboard.php
Normal file
95
app/Filament/Pages/Dashboard.php
Normal file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
namespace App\Filament\Pages;
|
||||
|
||||
use App\Filament\Widgets\CumulativeChart;
|
||||
use App\Filament\Widgets\ProductionQuantityStat;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Pages\Dashboard\Concerns\HasFiltersForm;
|
||||
use Filament\Tables\Filters\SelectFilter;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use App\Models\Plant;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Widgets\Widget;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class Dashboard extends \Filament\Pages\Dashboard
|
||||
{
|
||||
use HasFiltersForm;
|
||||
|
||||
protected static ?string $navigationGroup = 'Production DashBoard';
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
session()->forget(['selected_plant']);
|
||||
$this->filtersForm->fill([
|
||||
'plant' => null,
|
||||
'success_status' => null
|
||||
]);
|
||||
}
|
||||
|
||||
public function filtersForm(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->statePath('filters') // Store form state in 'filters'
|
||||
->schema([
|
||||
Select::make('plant')
|
||||
->label('Select Plant')
|
||||
->reactive()
|
||||
// ->options(Plant::pluck('name', 'id'))
|
||||
->options(function (callable $get) {
|
||||
$userHas = Filament::auth()->user()->plant_id;
|
||||
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
|
||||
})
|
||||
->afterStateUpdated(function ($state,callable $set) {
|
||||
session(['selected_plant' => $state]); // fixed typo
|
||||
//$this->dispatch('cumulativeChart'); // custom Livewire event
|
||||
// Reset success_status whenever plant changes
|
||||
$set('success_status', null);
|
||||
session()->forget('success_status');
|
||||
}),
|
||||
|
||||
Select::make('success_status')
|
||||
->label('Select Status')
|
||||
->options([
|
||||
'Ok' => 'Ok',
|
||||
'Not Ok' => 'Not Ok',
|
||||
])
|
||||
->reactive()
|
||||
->afterStateUpdated(function ($state) {
|
||||
session(['success_status' => $state]);
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
public static function getNavigationLabel(): string
|
||||
{
|
||||
return 'Production Line Count';
|
||||
}
|
||||
|
||||
public function getHeading(): string
|
||||
{
|
||||
return 'Production Line Count';
|
||||
}
|
||||
|
||||
public function getWidgets(): array
|
||||
{
|
||||
$widgets = [];
|
||||
|
||||
if (CumulativeChart::canView()) {
|
||||
$widgets[] = CumulativeChart::class;
|
||||
|
||||
}
|
||||
return $widgets;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static function canAccess(): bool
|
||||
{
|
||||
return Auth::check() && Auth::user()->can('view production line count dashboard');
|
||||
}
|
||||
|
||||
}
|
||||
363
app/Filament/Pages/DataSendToSap.php
Normal file
363
app/Filament/Pages/DataSendToSap.php
Normal file
@@ -0,0 +1,363 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Pages;
|
||||
|
||||
use App\Models\Item;
|
||||
use App\Models\Plant;
|
||||
use App\Models\ProductionQuantity;
|
||||
use App\Models\QualityValidation;
|
||||
use App\Models\StickerMaster;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Forms\Components\Actions;
|
||||
use Filament\Forms\Components\Actions\Action;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Pages\Page;
|
||||
use Filament\Forms\Concerns\InteractsWithForms;
|
||||
use Filament\Forms\Contracts\HasForms;
|
||||
use Filament\Notifications\Notification;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class DataSendToSap extends Page implements HasForms
|
||||
{
|
||||
use InteractsWithForms;
|
||||
|
||||
public $pId , $pOrder, $pUom, $pItem, $transHeadLog, $sNums = [];
|
||||
|
||||
public $scanned_quantity;
|
||||
|
||||
public array $data = []; //Required to back form state
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-document-text';
|
||||
protected static string $view = 'filament.pages.data-send-to-sap';
|
||||
|
||||
protected static ?string $navigationGroup = 'Send To SAP';
|
||||
|
||||
protected $listeners = ['updateScannedQuantity' => 'setScannedQuantity'];
|
||||
|
||||
|
||||
|
||||
public function setScannedQuantity($quantity)
|
||||
{
|
||||
// Set the scanned_quantity value in the Filament page/form
|
||||
$this->scanned_quantity = $quantity;
|
||||
$this->form->fill([
|
||||
'scanned_quantity' => $quantity,
|
||||
'production_order' => $this->pOrder,
|
||||
'plant_id' => $this->pId,
|
||||
]);
|
||||
}
|
||||
|
||||
public function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->statePath('data')
|
||||
->schema([
|
||||
Select::make('plant_id')
|
||||
->label('Plant')
|
||||
// ->options(Plant::pluck('name', 'id'))
|
||||
->options(function (callable $get) {
|
||||
$userHas = Filament::auth()->user()->plant_id;
|
||||
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
|
||||
})
|
||||
->reactive()
|
||||
->required()
|
||||
->afterStateUpdated(function ($state, $set, callable $get) {
|
||||
$plantId = $get('plant_id');
|
||||
if (!$plantId) {
|
||||
$set('pqPlantError', 'Please select a plant first.');
|
||||
$set('production_order', null);
|
||||
$set('scanned_quantity', null);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
$this->pId = $plantId;
|
||||
$set('production_order', null);
|
||||
$set('scanned_quantity', null);
|
||||
$set('validationError', null);
|
||||
$set('pqPlantError', null);
|
||||
}
|
||||
})
|
||||
->hint(fn ($get) => $get('pqPlantError') ? $get('pqPlantError') : null)
|
||||
->hintColor('danger'),
|
||||
|
||||
TextInput::make('production_order')
|
||||
->required()
|
||||
->reactive()
|
||||
->afterStateUpdated(function ($state, $set, callable $get) {
|
||||
$productionOrder = $get('production_order');
|
||||
|
||||
if (!$productionOrder) {
|
||||
$set('pqproducError', 'Please provide production order.');
|
||||
$set('production_order', null);
|
||||
$set('scanned_quantity', null);
|
||||
$this->dispatch('refreshed', $this->pId, $this->pOrder);
|
||||
|
||||
return;
|
||||
}
|
||||
else {
|
||||
$this->pOrder = null;
|
||||
$this->dispatch('refreshed', $this->pId, $this->pOrder);
|
||||
$set('scanned_quantity', null);
|
||||
$set('validationError', null);
|
||||
$set('pqproducError', null);
|
||||
}
|
||||
})
|
||||
->hint(fn ($get) => $get('pqproducError') ? $get('pqproducError') : null)
|
||||
->hintColor('danger')
|
||||
->extraAttributes([
|
||||
'wire:keydown.enter' => 'processValues($event.target.value)',
|
||||
]),
|
||||
|
||||
TextInput::make('scanned_quantity')
|
||||
->reactive() // Make it reactive to update when changed
|
||||
->afterStateUpdated(function ($state, $set, $get) {
|
||||
$this->scanned_quantity = $state;
|
||||
})
|
||||
->readOnly(),
|
||||
|
||||
// Add your custom action button here
|
||||
Actions::make([
|
||||
Action::make('send_to_sap')
|
||||
->label('Send Data to SAP')
|
||||
->action(function ($set, $get) {
|
||||
$year = date('y'); // '25' for 2025
|
||||
$month = date('m'); // '05' for May
|
||||
$plantId = $get('plant_id');
|
||||
$code = Plant::where('id', $plantId)->value('code');
|
||||
$finalBatch = $year . $month . $code;
|
||||
$transHeadLogId = $this->transHeadLog; //'3256';
|
||||
$lineItemCnt = '1'; //1 hard code
|
||||
$sapOrder = $get('production_order');
|
||||
$itemCode = $this->pItem;
|
||||
$quantity = (string)$get('scanned_quantity');
|
||||
$UOM = $this->pUom;
|
||||
$batchNumber = $finalBatch;
|
||||
$locationName = '';
|
||||
$lamiCdate = $get('lami_cdate');
|
||||
$serialNumbers = $this->sNums;
|
||||
|
||||
// dd($batchNumber);
|
||||
|
||||
$currentDateTime = date('j/n/Y h:i:s A');
|
||||
|
||||
$header = [
|
||||
'Trans_Head_Log_Id' => $transHeadLogId, //'3256',
|
||||
'Line_Item_Count' => $lineItemCnt, //'1',
|
||||
'SAP_Order_Number' => $sapOrder, //'12345678'
|
||||
'Item_Code' => $itemCode, //'6458795'
|
||||
];
|
||||
// $serialNumbers = ['12024090000142', '12024090000142', '12024090000142'];
|
||||
$Receipt = [
|
||||
// 'Receipt' => [
|
||||
[
|
||||
'Quantity' => $quantity, //'1',
|
||||
'UOM' => $UOM,
|
||||
'Batch_Number' => $batchNumber,
|
||||
'Location_Name' => $locationName,
|
||||
'LAMI_Cdate' => $currentDateTime, //'9/9/2024 10:48:37 AM',
|
||||
'Serial_Number' => array_map(function ($serial) {
|
||||
return ['Serial_Number' => $serial];
|
||||
}, $serialNumbers)
|
||||
]
|
||||
// ]
|
||||
];
|
||||
|
||||
|
||||
$payload = [
|
||||
// ...$header,
|
||||
'Receipt' => $Receipt
|
||||
];
|
||||
// dd($payload);
|
||||
|
||||
// $header = [
|
||||
// 'Trans_Head_Log_Id' => '3256',
|
||||
// 'Line_Item_Count' => '1',
|
||||
// 'SAP_Order_Number' => '12345678',
|
||||
// 'Item_Code' => '6458795'
|
||||
// ];
|
||||
// $serialNumbers = ['12024090000142'];
|
||||
// $Receipt = [
|
||||
// // 'Receipt' => [
|
||||
// [
|
||||
// 'Quantity' => '1',
|
||||
// 'UOM' => 'EA',
|
||||
// 'Batch_Number' => '',
|
||||
// 'Location_Name' => '',
|
||||
// 'LAMI_Cdate' => '9/9/2024 10:48:37 AM',
|
||||
// 'Serial_Number' => array_map(function ($serial) {
|
||||
// return ['Serial_Number' => $serial];
|
||||
// }, $serialNumbers)
|
||||
// ]
|
||||
// // ]
|
||||
// ];
|
||||
|
||||
|
||||
// $payload = [
|
||||
// // ...$header,
|
||||
// 'Receipt' => $Receipt
|
||||
// ];
|
||||
// dd($payload);
|
||||
try {
|
||||
// $response = Http::withHeaders([
|
||||
// 'Content-Type' => 'application/json',
|
||||
// 'Trans_Head_Log_Id' => '3256',//$transHeadLogId,
|
||||
// 'Line_Item_Count' => '1', // $lineItemCnt,
|
||||
// 'SAP_Order_Number' => '12345678', //$sapOrder,
|
||||
// 'Item_Code' => '6458795', //$itemCode,
|
||||
// ])
|
||||
$response = Http::withHeaders([
|
||||
'Content-Type' => 'application/json',
|
||||
'Trans_Head_Log_Id' => $transHeadLogId,
|
||||
'Line_Item_Count' => $lineItemCnt,
|
||||
'SAP_Order_Number' => $sapOrder,
|
||||
'Item_Code' => $itemCode,
|
||||
])
|
||||
|
||||
->withBasicAuth(
|
||||
env('SAP_API_USERNAME'),
|
||||
env('SAP_API_PASSWORD')
|
||||
)
|
||||
->withBody(json_encode($payload), 'application/json')
|
||||
->post(env('SAP_API_URL'), $payload);
|
||||
|
||||
$messageCode = $response->headers()['messagecode'][0] ?? null;
|
||||
|
||||
if ($messageCode && str_starts_with($messageCode, 'ERROR')) {
|
||||
|
||||
$cleanError = str_replace('ERROR:|', '', $messageCode);
|
||||
|
||||
// Update rows where plant_id and production_order match
|
||||
QualityValidation::where('plant_id', $get('plant_id'))
|
||||
->where('production_order', $get('production_order'))
|
||||
->update([
|
||||
'sap_msg_status' => 'ERROR',
|
||||
'sap_msg_description' => $cleanError,
|
||||
]);
|
||||
|
||||
Notification::make()
|
||||
->title('SAP Error')
|
||||
->body($cleanError)
|
||||
->danger()
|
||||
->send();
|
||||
$this->dispatch('loadItems', $this->pId, $this->pOrder);
|
||||
}
|
||||
else
|
||||
{
|
||||
$messageCode = $response->headers()['messagecode'][0] ?? null;
|
||||
$sapSuccessMsg = str_replace('SUCCESS:|', '', $messageCode);
|
||||
|
||||
QualityValidation::where('plant_id', $get('plant_id'))
|
||||
->where('production_order', $get('production_order'))
|
||||
->update([
|
||||
'sap_msg_status' => 'SUCCESS',
|
||||
'sap_msg_description' => $sapSuccessMsg,
|
||||
]);
|
||||
|
||||
Notification::make()
|
||||
->title('SAP Success')
|
||||
->body($sapSuccessMsg)
|
||||
->success()
|
||||
->send();
|
||||
$this->dispatch('loadItems', $this->pId, $this->pOrder);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Notification::make()
|
||||
->title('Exception')
|
||||
->body('Error sending data to SAP: ' . $e->getMessage())
|
||||
->danger()
|
||||
->send();
|
||||
}
|
||||
})
|
||||
->color('success')
|
||||
->outlined()
|
||||
->hidden(fn (callable $get) => (!$get('scanned_quantity'))) //!$get('plant_id') && !$get('production_order') &&
|
||||
->extraAttributes(['class' => 'align-to-input']),
|
||||
]),
|
||||
])
|
||||
->columns(4);
|
||||
}
|
||||
|
||||
public function processValues($value)
|
||||
{
|
||||
|
||||
$this->pOrder = $value;
|
||||
|
||||
$plantId = trim($this->form->getState()['plant_id']) ?? null;
|
||||
//$this->plantId = $plantId;
|
||||
|
||||
|
||||
// $this->pUom = QualityValidation::where('plant_id',$this->pId)
|
||||
// ->where('production_order',$this->pOrder)
|
||||
// ->latest()
|
||||
// ->first()
|
||||
// ->value('uom');
|
||||
|
||||
// $this->transHeadLog = QualityValidation::where('plant_id',$this->pId)
|
||||
// ->where('production_order',$this->pOrder)
|
||||
// ->latest()
|
||||
// ->value('id');
|
||||
|
||||
$latestValidation = QualityValidation::where('plant_id', $this->pId)
|
||||
->where('production_order', $this->pOrder)
|
||||
->latest()
|
||||
->first();
|
||||
|
||||
if (!$latestValidation) {
|
||||
Notification::make()
|
||||
->title('Invalid Production Order')
|
||||
->body('No data found for the selected plant and production order.')
|
||||
->danger()
|
||||
->send();
|
||||
|
||||
$this->dispatch('refreshed', $this->pId, $this->pOrder);
|
||||
$this->pOrder = null;
|
||||
$this->form->fill([
|
||||
'plant_id' => $this->pId,
|
||||
'production_order' => null,
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->pUom = $latestValidation->uom;
|
||||
$this->transHeadLog = $latestValidation->id;
|
||||
|
||||
$this->sNums = [];
|
||||
|
||||
if(!$this->pUom)
|
||||
{
|
||||
Notification::make()
|
||||
->title('UOM Not Found')
|
||||
->body('UOM not found for the production order')
|
||||
->icon('heroicon-o-x-circle') // optional, to force red/error-style icon
|
||||
->danger()
|
||||
->send();
|
||||
$this->dispatch('refreshed', $this->pId, $this->pOrder);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->pItem = Item::where('id', StickerMaster::where('id', QualityValidation::where('plant_id',$this->pId)->where('production_order',$this->pOrder)->latest()->first()->sticker_master_id)->value('item_id'))->value('code');
|
||||
|
||||
$this->sNums = QualityValidation::where('plant_id', $this->pId)
|
||||
->where('production_order', $this->pOrder)
|
||||
->pluck('serial_number')
|
||||
->toArray();
|
||||
|
||||
//dd($this-> pItem);
|
||||
|
||||
$this->dispatch('loadItems', $this->pId, $this->pOrder);
|
||||
}
|
||||
}
|
||||
public static function canAccess(): bool
|
||||
{
|
||||
return Auth::check() && Auth::user()->can('view quality data send to sap');
|
||||
}
|
||||
|
||||
public static function getNavigationLabel(): string
|
||||
{
|
||||
return 'Quality Data';
|
||||
}
|
||||
}
|
||||
76
app/Filament/Pages/GuardPatrolDayCount.php
Normal file
76
app/Filament/Pages/GuardPatrolDayCount.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Pages;
|
||||
|
||||
use App\Filament\Widgets\GuardPatrolDayChart;
|
||||
use App\Models\Plant;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Pages\Page;
|
||||
use Filament\Pages\Dashboard\Concerns\HasFiltersForm;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class GuardPatrolDayCount extends Page
|
||||
{
|
||||
protected static ?string $navigationIcon = 'heroicon-o-document-text';
|
||||
|
||||
protected static string $view = 'filament.pages.guard-patrol-day-count';
|
||||
|
||||
protected static ?string $navigationGroup = 'Guard DashBoard';
|
||||
|
||||
use HasFiltersForm;
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
session()->forget(['selected_plant']);
|
||||
$this->filtersForm->fill([
|
||||
'plant' => null
|
||||
]);
|
||||
}
|
||||
|
||||
public function filtersForm(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->statePath('filters')
|
||||
->schema([
|
||||
Select::make('plant')
|
||||
->label('Select Plant')
|
||||
// ->options(Plant::pluck('name', 'id'))
|
||||
->options(function (callable $get) {
|
||||
$userHas = Filament::auth()->user()->plant_id;
|
||||
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
|
||||
})
|
||||
->reactive()
|
||||
->afterStateUpdated(function ($state) {
|
||||
session(['selected_plant' => $state]);
|
||||
$this->dispatch('patrolEntryChart');
|
||||
}),
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static function getNavigationLabel(): string
|
||||
{
|
||||
return 'Guard Patrol Day Count';
|
||||
}
|
||||
|
||||
public function getHeading(): string
|
||||
{
|
||||
return 'Guard Patrol Day Chart';
|
||||
}
|
||||
|
||||
public function getWidgets(): array
|
||||
{
|
||||
return [
|
||||
GuardPatrolDayChart::class,
|
||||
];
|
||||
}
|
||||
|
||||
public static function canAccess(): bool
|
||||
{
|
||||
return Auth::check() && Auth::user()->can('view guard patrol day count dashboard');
|
||||
}
|
||||
|
||||
}
|
||||
120
app/Filament/Pages/GuardPatrolEntryDashboard.php
Normal file
120
app/Filament/Pages/GuardPatrolEntryDashboard.php
Normal file
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Pages;
|
||||
|
||||
use App\Models\GuardPatrolEntry;
|
||||
use App\Models\Plant;
|
||||
use Carbon\Carbon;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Forms\Components\DatePicker;
|
||||
use Filament\Forms\Components\DateTimePicker;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Pages\Dashboard\Concerns\HasFiltersForm;
|
||||
use Filament\Pages\Page;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class GuardPatrolEntryDashboard extends Page
|
||||
{
|
||||
use HasFiltersForm;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-document-text';
|
||||
|
||||
protected static ?string $navigationGroup = 'Guard DashBoard';
|
||||
|
||||
protected static string $view = 'filament.pages.guard-patrol-entry-dashboard';
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
// session()->forget(['select_guard_plant', 'select_guard_date']);
|
||||
$this->filtersForm->fill([
|
||||
'plant' => null,
|
||||
'date' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
public function filtersForm(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->statePath('filters') // Explicitly set where to store form data
|
||||
->schema([
|
||||
Select::make('plant')
|
||||
->label('Select Plant')
|
||||
// ->options(Plant::pluck('name', 'id'))
|
||||
->options(function (callable $get) {
|
||||
$userHas = Filament::auth()->user()->plant_id;
|
||||
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
|
||||
})
|
||||
->reactive()
|
||||
->required()
|
||||
->afterStateUpdated(function ($state, callable $set, callable $get){
|
||||
// $this->dispatch('invoiceChart');
|
||||
if(!$state)
|
||||
{
|
||||
$set('date', now()->format('Y-m-d')); // H:i:s
|
||||
// session(['select_guard_plant' => $state]);
|
||||
// session(['select_guard_date' => $get('date')]);
|
||||
} else {
|
||||
if(!$get('date'))
|
||||
{
|
||||
$set('date', now()->format('Y-m-d'));
|
||||
// session(['select_guard_plant' => $state]);
|
||||
// session(['select_guard_date' => $get('date')]);
|
||||
}
|
||||
// else {
|
||||
// session(['select_guard_plant' => $state]);
|
||||
// session(['select_guard_date' => $get('date')]);
|
||||
// }
|
||||
}
|
||||
$this->dispatch('loadGuardData', $state, $get('date')); //->format('Y-m-d')
|
||||
}),
|
||||
DatePicker::make('date')
|
||||
->label('Select Date')
|
||||
->placeholder('Select Date')
|
||||
->reactive()
|
||||
->required()
|
||||
->beforeOrEqual(now())
|
||||
->default(now()->format('Y-m-d'))
|
||||
->afterStateUpdated(function ($state, callable $set, callable $get){
|
||||
if(!$get('plant'))
|
||||
{
|
||||
$set('date', now()->format('Y-m-d'));
|
||||
// session(['select_guard_plant' => $get('plant')]);
|
||||
// session(['select_guard_date' => $state]);
|
||||
} else {
|
||||
if(!$get('date'))
|
||||
{
|
||||
$set('date', now()->format('Y-m-d'));
|
||||
// session(['select_guard_plant' => $get('plant')]);
|
||||
// session(['select_guard_date' => $state]);
|
||||
}
|
||||
// else {
|
||||
// $records = GuardPatrolEntry::whereDate('patrol_time', $state)->where('plant_id', $get('plant'))->orderBy('patrol_time', 'asc')->first(); //desc
|
||||
// //dd($get('plant'), $state, $records->patrol_time);//->toTimeString()
|
||||
// session(['select_guard_plant' => $get('plant')]);
|
||||
// session(['select_guard_date' => $state]);
|
||||
// }
|
||||
}
|
||||
// $this->dispatch('invoiceChart');
|
||||
$this->dispatch('loadGuardData', $get('plant'), $state);//->format('Y-m-d')
|
||||
})
|
||||
])
|
||||
->columns(2);
|
||||
}
|
||||
|
||||
|
||||
public static function getNavigationLabel(): string
|
||||
{
|
||||
return 'Guard Patrol Status Table';
|
||||
}
|
||||
|
||||
public function getHeading(): string
|
||||
{
|
||||
return 'Guard Patrol Entry Status';
|
||||
}
|
||||
|
||||
public static function canAccess(): bool
|
||||
{
|
||||
return Auth::check() && Auth::user()->can('view guard patrol entry status dashboard');
|
||||
}
|
||||
}
|
||||
271
app/Filament/Pages/GuardPatrolHourlyCount.php
Normal file
271
app/Filament/Pages/GuardPatrolHourlyCount.php
Normal file
@@ -0,0 +1,271 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Pages;
|
||||
|
||||
use App\Filament\Widgets\GuardPatrolHourlyChart;
|
||||
use App\Models\CheckPointName;
|
||||
use App\Models\CheckPointTime;
|
||||
use App\Models\GuardPatrolEntry;
|
||||
use App\Models\Plant;
|
||||
use Carbon\Carbon;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Pages\Page;
|
||||
use Filament\Pages\Dashboard\Concerns\HasFiltersForm;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\DatePicker;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class GuardPatrolHourlyCount extends Page
|
||||
{
|
||||
protected static ?string $navigationIcon = 'heroicon-o-document-text';
|
||||
|
||||
protected static string $view = 'filament.pages.guard-patrol-hourly-count';
|
||||
|
||||
protected static ?string $navigationGroup = 'Guard DashBoard';
|
||||
|
||||
|
||||
use HasFiltersForm;
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
session()->forget(['selected_plant']);
|
||||
session()->forget(['selected_date']);
|
||||
session()->forget(['selected_name']);
|
||||
session()->forget(['selected_time']);
|
||||
session()->forget(['valid_sessions']);
|
||||
$this->filtersForm->fill([
|
||||
'plant' => null,
|
||||
'date' => null,
|
||||
'time_range' => null,
|
||||
'guard_name' => null
|
||||
]);
|
||||
}
|
||||
|
||||
public function filtersForm(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->statePath('filters')
|
||||
->schema([
|
||||
Select::make('plant')
|
||||
->label('Select Plant')
|
||||
//->options(Plant::pluck('name', 'id'))
|
||||
->options(function (callable $get) {
|
||||
$userHas = Filament::auth()->user()->plant_id;
|
||||
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
|
||||
})
|
||||
->reactive()
|
||||
->required()
|
||||
->afterStateUpdated(function ($state,callable $set) {
|
||||
if (is_null($state)) {
|
||||
session()->forget('selected_plant');
|
||||
} else {
|
||||
session(['selected_plant' => $state]);
|
||||
}
|
||||
|
||||
session(['selected_plant' => $state]);
|
||||
|
||||
$set('date', null);
|
||||
session()->forget('selected_date');
|
||||
|
||||
$set('guard_name', null);
|
||||
session()->forget('selected_name');
|
||||
|
||||
$set('time_range', null);
|
||||
session()->forget('selected_time');
|
||||
session()->forget('valid_sessions');
|
||||
|
||||
// $this->dispatch('patrolEntryChart');
|
||||
}),
|
||||
DatePicker::make('date')
|
||||
->label('Select Date')
|
||||
->placeholder('Select Date')
|
||||
->reactive()
|
||||
->required()
|
||||
->beforeOrEqual(now())
|
||||
->default(now()->format('Y-m-d'))
|
||||
->afterStateUpdated(function ($state,callable $set) {
|
||||
session(['selected_date' => $state]);
|
||||
$set('guard_name', null);
|
||||
session()->forget('selected_name');
|
||||
$set('time_range', null);
|
||||
session()->forget('selected_time');
|
||||
session()->forget('valid_sessions');
|
||||
|
||||
// $this->dispatch('patrolEntryChart');
|
||||
}),
|
||||
Select::make('guard_name')
|
||||
->label('Guard Name')
|
||||
->options(function (callable $get) {
|
||||
$plantId = $get('plant');
|
||||
$Date = $get('date');
|
||||
if (!$plantId || !$Date) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return GuardPatrolEntry::with('guardNames')->where('plant_id', $plantId)
|
||||
->whereDate('patrol_time', $Date)->orderBy('patrol_time','asc')
|
||||
->get()
|
||||
->unique('guard_name_id')
|
||||
->pluck('guardNames.name', 'guard_name_id')
|
||||
->toArray();
|
||||
|
||||
})
|
||||
->reactive()
|
||||
->required()
|
||||
->afterStateUpdated(function ($state,callable $set)
|
||||
{
|
||||
if (is_null($state))
|
||||
{
|
||||
session()->forget('selected_name');
|
||||
}
|
||||
else
|
||||
{
|
||||
session(['selected_name' => $state]);
|
||||
}
|
||||
|
||||
// Clear the time range field and its session
|
||||
$set('time_range', null);
|
||||
session()->forget('selected_time');
|
||||
session()->forget('valid_sessions');
|
||||
}),
|
||||
|
||||
// Select::make('time_range')
|
||||
// ->label('Patrol Time Range')
|
||||
// ->options(function (callable $get) {
|
||||
// $plantId = $get('plant');
|
||||
// $guardId = $get('guard_name');
|
||||
// $date = $get('date');
|
||||
|
||||
// if (!$plantId || !$guardId || !$date) {
|
||||
// return [];
|
||||
// }
|
||||
|
||||
// $patrols = GuardPatrolEntry::where('plant_id', $plantId)
|
||||
// ->where('guard_name_id', $guardId)
|
||||
// ->whereDate('patrol_time', $date)
|
||||
// ->orderBy('patrol_time', 'asc')
|
||||
// ->get(['patrol_time']);
|
||||
|
||||
// if ($patrols->isEmpty())
|
||||
// {
|
||||
// return [];
|
||||
// }
|
||||
|
||||
// $chunkSize = CheckPointTime::where('plant_id', $plantId)->count()+ 1;;
|
||||
// $chunks = $patrols->chunk($chunkSize);
|
||||
|
||||
// $options = [];
|
||||
// foreach ($chunks as $index => $chunk) {
|
||||
// $first = $chunk->first();
|
||||
// $last = $chunk->last();
|
||||
// $start = Carbon::parse($first->patrol_time)->format('H:i:s');
|
||||
// $end = Carbon::parse($last->patrol_time)->format('H:i:s');
|
||||
// $timeRange = "$start - $end";
|
||||
// $options[$timeRange] = $timeRange;
|
||||
// }
|
||||
|
||||
// return $options;
|
||||
// })
|
||||
// ->reactive()
|
||||
// ->required()
|
||||
// ->afterStateUpdated(function ($state) {
|
||||
// session(['selected_time' => $state]);
|
||||
// })
|
||||
Select::make('time_range')
|
||||
->label('Patrol Time Range')
|
||||
->options(function (callable $get) {
|
||||
$plantId = $get('plant');
|
||||
$guardId = $get('guard_name');
|
||||
$date = $get('date');
|
||||
|
||||
if (!$plantId || !$guardId || !$date) {
|
||||
session(['valid_sessions' => []]);
|
||||
return [];
|
||||
}
|
||||
|
||||
// Get patrols with checkpoints
|
||||
$patrols = GuardPatrolEntry::where('plant_id', $plantId)
|
||||
->where('guard_name_id', $guardId)
|
||||
->whereDate('patrol_time', $date)
|
||||
->orderBy('patrol_time', 'asc')
|
||||
->get(['patrol_time', 'check_point_name_id']);
|
||||
|
||||
if ($patrols->isEmpty()) {
|
||||
session(['valid_sessions' => []]);
|
||||
return [];
|
||||
}
|
||||
|
||||
// Get checkpoint sequence
|
||||
$checkPointTimes = CheckPointTime::where('plant_id', $plantId)
|
||||
->orderBy('sequence_number')
|
||||
->get(['check_point1_id', 'check_point2_id']);
|
||||
|
||||
// Build expected sequence
|
||||
$expectedSequence = [];
|
||||
foreach ($checkPointTimes as $row) {
|
||||
$expectedSequence[] = $row->check_point1_id;
|
||||
}
|
||||
if ($checkPointTimes->isNotEmpty()) {
|
||||
$expectedSequence[] = $checkPointTimes->last()->check_point2_id;
|
||||
}
|
||||
|
||||
$chunkSize = $checkPointTimes->count() + 1;
|
||||
$chunks = $patrols->chunk($chunkSize);
|
||||
|
||||
$options = [];
|
||||
$validSessions = [];
|
||||
|
||||
foreach ($chunks as $index => $chunk) {
|
||||
$first = $chunk->first();
|
||||
$last = $chunk->last();
|
||||
$start = Carbon::parse($first->patrol_time)->format('H:i:s');
|
||||
$end = Carbon::parse($last->patrol_time)->format('H:i:s');
|
||||
$timeRange = "$start - $end";
|
||||
|
||||
// Validate sequence for this chunk
|
||||
$currentSeqIndex = 0;
|
||||
$isValid = true;
|
||||
$anyMatch = false;
|
||||
|
||||
foreach ($chunk as $patrol) {
|
||||
if ($currentSeqIndex < count($expectedSequence) &&
|
||||
$patrol->check_point_name_id == $expectedSequence[$currentSeqIndex]) {
|
||||
$currentSeqIndex++;
|
||||
$anyMatch = true;
|
||||
} else {
|
||||
$isValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Consider valid only if at least one checkpoint matches
|
||||
$isValid = $isValid && $anyMatch;
|
||||
$validSessions[$timeRange] = $isValid;
|
||||
$options[$timeRange] = $timeRange;
|
||||
}
|
||||
|
||||
session(['valid_sessions' => $validSessions]);
|
||||
return $options;
|
||||
})
|
||||
->reactive()
|
||||
->required()
|
||||
->afterStateUpdated(function ($state) {
|
||||
session(['selected_time' => $state]);
|
||||
})
|
||||
|
||||
])
|
||||
->columns(4);
|
||||
}
|
||||
|
||||
public function getWidgets(): array
|
||||
{
|
||||
return [
|
||||
GuardPatrolHourlyChart::class,
|
||||
];
|
||||
}
|
||||
|
||||
public static function canAccess(): bool
|
||||
{
|
||||
return Auth::check() && Auth::user()->can('view guard patrol hourly count dashboard');
|
||||
}
|
||||
}
|
||||
138
app/Filament/Pages/HourlyProduction.php
Normal file
138
app/Filament/Pages/HourlyProduction.php
Normal file
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Pages;
|
||||
|
||||
use App\Filament\Widgets\ItemOverview;
|
||||
use App\Models\Plant;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Pages\Dashboard\Concerns\HasFiltersForm;
|
||||
use Filament\Pages\Page;
|
||||
use Filament\Tables\Concerns\HasFilters;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Filament\Pages\Dashboard;
|
||||
|
||||
class HourlyProduction extends page
|
||||
{
|
||||
protected static ?string $navigationIcon = 'heroicon-o-document-text';
|
||||
|
||||
protected static string $view = 'filament.pages.hourly-production';
|
||||
|
||||
protected static ?string $navigationGroup = 'Production DashBoard';
|
||||
|
||||
use HasFiltersForm;
|
||||
|
||||
public $selectedPlant;
|
||||
public $selectedLine;
|
||||
public $selectedFilter = 'today';
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
//session()->forget(['selected_plant', 'selected_line','selected_status']);
|
||||
session()->forget(['selected_plant', 'selected_line']);
|
||||
session()->forget(['select_plant', 'select_line']);
|
||||
$plantId = session('selected_plant', null); // Default to the first plant if not selected
|
||||
$lineId = session('selected_line', null);
|
||||
//$successStatus = session('selected_status', null);
|
||||
|
||||
|
||||
$this->filtersForm->fill([
|
||||
//'plant' => Plant::first()?->id // Default to first plant
|
||||
'plant' => $plantId,
|
||||
'line' => $lineId,
|
||||
//'success_status' => $successStatus,
|
||||
]);
|
||||
}
|
||||
|
||||
public function filtersForm(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->statePath('filters')
|
||||
->schema([
|
||||
|
||||
Select::make('plant')
|
||||
->label('Select Plant')
|
||||
->reactive()
|
||||
//->options(Plant::pluck('name', 'id'))
|
||||
->options(function (callable $get) {
|
||||
$userHas = Filament::auth()->user()->plant_id;
|
||||
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
|
||||
})
|
||||
->afterStateUpdated(function ($state) {
|
||||
session(['selected_plant' => $state]);
|
||||
// Clear production quantity Dashboard session keys to avoid conflict
|
||||
//session()->forget(['select_plant', 'select_line']);
|
||||
$this->triggerChartUpdate();
|
||||
$this->dispatch('filtersUpdated', [
|
||||
'plant' => $state,
|
||||
'line' => session('selected_line') ?? null,
|
||||
'filter' => session('selected_filter') ?? 'today',
|
||||
]);
|
||||
}),
|
||||
|
||||
// Line Filter
|
||||
Select::make('line')
|
||||
->options(function ($get) {
|
||||
$plantId = $get('plant');
|
||||
return $plantId ? Plant::find($plantId)->getLineNames()->pluck('name', 'id') : [];
|
||||
})
|
||||
->label('Select Line')
|
||||
->reactive()
|
||||
->afterStateUpdated(function ($state) {
|
||||
session(['selected_line' => $state]);
|
||||
$this->triggerChartUpdate();
|
||||
$this->dispatch('filtersUpdated', [
|
||||
'plant' => session('selected_plant') ?? null,
|
||||
'line' => $state,
|
||||
'filter' => session('selected_filter') ?? 'today',
|
||||
]);
|
||||
}),
|
||||
|
||||
// Select::make('success_status')
|
||||
// ->label('Select Status')
|
||||
// ->options([
|
||||
// 'Ok' => 'Ok',
|
||||
// 'Not Ok' => 'Not Ok',
|
||||
// ])
|
||||
// ->reactive()
|
||||
// ->afterStateUpdated(function ($state) {
|
||||
// session(['selected_status' => $state]); // fixed typo
|
||||
// //$this->dispatch('cumulativeChart'); // custom Livewire event
|
||||
// }),
|
||||
])
|
||||
->columns(3);
|
||||
}
|
||||
|
||||
// public function triggerChartUpdate(): void
|
||||
// {
|
||||
// if (session()->has('selected_plant') && session()->has('selected_line') && session()->has('selected_status')) {
|
||||
// $this->dispatch('filtersUpdated');
|
||||
// }
|
||||
// }
|
||||
public function triggerChartUpdate(): void
|
||||
{
|
||||
if (session()->has('selected_plant') && session()->has('selected_line')) {
|
||||
$this->dispatch('filtersUpdated');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static function getNavigationLabel(): string
|
||||
{
|
||||
return 'Production Hourly Count';
|
||||
}
|
||||
|
||||
public static function canAccess(): bool
|
||||
{
|
||||
return Auth::check() && Auth::user()->can('view production hourly count dashboard');
|
||||
}
|
||||
|
||||
// public function getWidgets(): array
|
||||
// {
|
||||
// return [
|
||||
// ItemOverview::class,
|
||||
// ];
|
||||
// }
|
||||
}
|
||||
80
app/Filament/Pages/InvoiceDashboard.php
Normal file
80
app/Filament/Pages/InvoiceDashboard.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Pages;
|
||||
|
||||
|
||||
use App\Models\Plant;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Pages\Page;
|
||||
use Filament\Pages\Dashboard\Concerns\HasFiltersForm;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class InvoiceDashboard extends Page
|
||||
{
|
||||
|
||||
use HasFiltersForm;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-document-text';
|
||||
|
||||
protected static ?string $navigationGroup = 'Invoice DashBoard';
|
||||
|
||||
protected static string $view = 'filament.pages.invoice-dashboard';
|
||||
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
session()->forget(['selec_plant', 'select_invoice']);
|
||||
$this->filtersForm->fill([
|
||||
'plant' => null,
|
||||
'invoice' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
public function filtersForm(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->statePath('filters') // Explicitly set where to store form data
|
||||
->schema([
|
||||
Select::make('plant')
|
||||
->label('Select Plant')
|
||||
//->options(Plant::pluck('name', 'id'))
|
||||
->options(function (callable $get) {
|
||||
$userHas = Filament::auth()->user()->plant_id;
|
||||
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
|
||||
})
|
||||
->reactive()
|
||||
->afterStateUpdated(function ($state) {
|
||||
session(['selec_plant' => $state]);
|
||||
$this->dispatch('invoiceChart');
|
||||
}),
|
||||
Select::make('invoice')
|
||||
->options([
|
||||
'serial_invoice' => 'Serial Invoice',
|
||||
'individual_material' => 'Individual Material Invoice',
|
||||
'bundle_material' => 'Bundle Material Invoice',
|
||||
])
|
||||
->label('Select Invoice')
|
||||
->reactive()
|
||||
->default(0)
|
||||
->afterStateUpdated(function ($state) {
|
||||
session(['select_invoice' => $state]);
|
||||
$this->dispatch('invoiceChart');
|
||||
})
|
||||
])
|
||||
->columns(2);
|
||||
}
|
||||
|
||||
public static function getNavigationLabel(): string
|
||||
{
|
||||
return 'Invoice';
|
||||
}
|
||||
|
||||
public static function canAccess(): bool
|
||||
{
|
||||
return Auth::check() && Auth::user()->can('view invoice dashboard');
|
||||
}
|
||||
|
||||
}
|
||||
124
app/Filament/Pages/InvoiceDataDashboard.php
Normal file
124
app/Filament/Pages/InvoiceDataDashboard.php
Normal file
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Pages;
|
||||
|
||||
use App\Filament\Widgets\InvoiceDataChart;
|
||||
use App\Models\InvoiceDataValidation;
|
||||
use App\Models\Plant;
|
||||
use Filament\Pages\Page;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Pages\Dashboard\Concerns\HasFiltersForm;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Forms\Components\Section;
|
||||
|
||||
class InvoiceDataDashboard extends Page
|
||||
{
|
||||
use HasFiltersForm;
|
||||
protected static ?string $navigationIcon = 'heroicon-o-document-text';
|
||||
|
||||
protected static string $view = 'filament.pages.invoice-data-dashboard';
|
||||
|
||||
protected static ?string $navigationGroup = 'Invoice Management';
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
session()->forget(['selected_plant','dist_channel']);
|
||||
$this->filtersForm->fill([
|
||||
'plant' => null,
|
||||
'distribution_channel' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
public function filtersForm(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->statePath('filters') // Store form state in 'filters'
|
||||
->schema([
|
||||
Section::make('')
|
||||
->schema([
|
||||
Select::make('plant')
|
||||
->label('Select Plant')
|
||||
->reactive()
|
||||
// ->options(Plant::pluck('name', 'id'))
|
||||
->options(function (callable $get) {
|
||||
$userHas = Filament::auth()->user()->plant_id;
|
||||
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
|
||||
})
|
||||
->afterStateUpdated(function ($state,callable $set) {
|
||||
session(['selected_plant' => $state]);
|
||||
$set('distribution_channel', null);
|
||||
session()->forget('distribution_channel');
|
||||
}),
|
||||
Select::make('distribution_channel')
|
||||
->label('Distribution Channel')
|
||||
// ->options(function (callable $get) {
|
||||
// $plant = $get('plant');
|
||||
|
||||
// if (!$plant) {
|
||||
// return [];
|
||||
// }
|
||||
|
||||
// $options = InvoiceDataValidation::where('plant_id', $plant)
|
||||
// ->whereNotNull('distribution_channel_desc')
|
||||
// ->where('distribution_channel_desc', '!=', '')
|
||||
// ->select('distribution_channel_desc')
|
||||
// ->distinct()
|
||||
// ->pluck('distribution_channel_desc', 'distribution_channel_desc')
|
||||
// ->toArray();
|
||||
|
||||
// $hasEmpty = InvoiceDataValidation::where('plant_id', $plant)
|
||||
// ->where(function ($q) {
|
||||
// $q->whereNull('distribution_channel_desc')
|
||||
// ->orWhere('distribution_channel_desc', '');
|
||||
// })
|
||||
// ->exists();
|
||||
|
||||
// if ($hasEmpty) {
|
||||
// $options['Challan'] = 'Challan';
|
||||
// }
|
||||
|
||||
// return $options;
|
||||
// })
|
||||
->options(function (callable $get) {
|
||||
$plant = $get('plant');
|
||||
|
||||
if (!$plant) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Fetch unique, non-empty distribution_channel_desc values
|
||||
return InvoiceDataValidation::where('plant_id', $plant)
|
||||
->whereNotNull('distribution_channel_desc')
|
||||
->where('distribution_channel_desc', '!=', '')
|
||||
->distinct()
|
||||
->pluck('distribution_channel_desc', 'distribution_channel_desc')
|
||||
->toArray();
|
||||
})
|
||||
->afterStateUpdated(callback: function ($state,callable $set) {
|
||||
session(['dist_channel' => $state]);
|
||||
})
|
||||
->reactive(),
|
||||
])
|
||||
->columns(2),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
public static function getNavigationLabel(): string
|
||||
{
|
||||
return 'Invoice Data Dashboard';
|
||||
}
|
||||
|
||||
public function getHeading(): string
|
||||
{
|
||||
return 'Invoice Data Dashboard';
|
||||
}
|
||||
|
||||
public static function canAccess(): bool
|
||||
{
|
||||
return Auth::check() && Auth::user()->can('view invoice data dashboard');
|
||||
}
|
||||
|
||||
}
|
||||
225
app/Filament/Pages/InvoiceFinder.php
Normal file
225
app/Filament/Pages/InvoiceFinder.php
Normal file
@@ -0,0 +1,225 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Pages;
|
||||
|
||||
use App\Models\LocatorInvoiceValidation;
|
||||
use App\Models\PalletValidation;
|
||||
use App\Models\Plant;
|
||||
use Filament\Facades\Filament;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Filament\Forms\Contracts\HasForms;
|
||||
use Filament\Forms\Concerns\InteractsWithForms;
|
||||
use Filament\Pages\Page;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Forms\Components\Section;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Notifications\Notification;
|
||||
|
||||
class InvoiceFinder extends Page implements HasForms
|
||||
{
|
||||
protected static ?string $navigationIcon = 'heroicon-o-document-text';
|
||||
|
||||
protected static string $view = 'filament.pages.invoice-finder';
|
||||
|
||||
protected static ?string $navigationGroup = 'Export Dispatch';
|
||||
|
||||
protected static ?int $navigationSort = 6;
|
||||
|
||||
//use InteractsWithForms;
|
||||
|
||||
public $pId, $invoiceNumber;
|
||||
|
||||
public array $invoiceOverviewData = [];
|
||||
|
||||
public array $filters = [];
|
||||
|
||||
public function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->statePath('filters')
|
||||
->schema([
|
||||
Section::make('') // You can give your section a title or leave it blank
|
||||
->schema([
|
||||
Select::make('plant_id')
|
||||
->label('Plant')
|
||||
//->options(Plant::pluck('name', 'id'))
|
||||
->options(function (callable $get) {
|
||||
$userHas = Filament::auth()->user()->plant_id;
|
||||
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
|
||||
})
|
||||
->reactive()
|
||||
->required(),
|
||||
TextInput::make('scan_invoice')
|
||||
->label('Scan Invoice')
|
||||
->required()
|
||||
->reactive()
|
||||
->extraAttributes([
|
||||
'wire:keydown.enter' => 'processInvoiceNo($event.target.value)',
|
||||
]),
|
||||
TextInput::make('scan_quantity')
|
||||
->label('Scanned Quantity ')
|
||||
->readOnly()
|
||||
->reactive(),
|
||||
TextInput::make('pending_quantity')
|
||||
->label('Pending Quantity')
|
||||
->readOnly()
|
||||
->reactive(),
|
||||
TextInput::make('total_sno_quantity')
|
||||
->label('Invoice Quantity')
|
||||
->readOnly()
|
||||
->reactive(),
|
||||
|
||||
])
|
||||
->columns(5)
|
||||
]);
|
||||
}
|
||||
|
||||
public function processInvoiceNo($invoiceNo)
|
||||
{
|
||||
$plantId = $this->form->getState()['plant_id'];
|
||||
|
||||
if(!$invoiceNo)
|
||||
{
|
||||
Notification::make()
|
||||
->title("Invoice number '$invoiceNo' can't be empty!")
|
||||
->danger()
|
||||
->duration(5000)
|
||||
->send();
|
||||
$this->dispatch('loadData', '', [], [], [], [], $plantId);
|
||||
$this->form->fill([
|
||||
'plant_id' => $plantId,
|
||||
'scan_invoice' => $invoiceNo,
|
||||
'total_sno_quantity' => 0,
|
||||
'pending_quantity' => 0,
|
||||
'scan_quantity' => 0
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
$invoiceExists = LocatorInvoiceValidation::where('plant_id', $plantId)
|
||||
->where('invoice_number', $invoiceNo)
|
||||
->first();
|
||||
|
||||
if(!$invoiceExists)
|
||||
{
|
||||
Notification::make()
|
||||
->title("Invoice number '$invoiceNo' does not exist in locator invoice table!")
|
||||
->danger()
|
||||
->duration(5000)
|
||||
->send();
|
||||
$this->dispatch('loadData', '', [], [], [], [], $plantId);
|
||||
$this->form->fill([
|
||||
'plant_id' => $plantId,
|
||||
'scan_invoice' => null,//$invoiceNo,
|
||||
'total_sno_quantity' => 0,
|
||||
'pending_quantity' => 0,
|
||||
'scan_quantity' => 0
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
$invoiceCompleted = LocatorInvoiceValidation::where('plant_id', $plantId)
|
||||
->where('invoice_number', $invoiceNo)
|
||||
->whereNull('scanned_status')
|
||||
->orWhere('scanned_status', '=','')
|
||||
->first();
|
||||
|
||||
if(!$invoiceCompleted)
|
||||
{
|
||||
// $count = LocatorInvoiceValidation::where('invoice_number', $invoiceNo)
|
||||
// ->where('plant_id', $plantId)
|
||||
// ->count();
|
||||
Notification::make()
|
||||
->title("Invoice number '$invoiceNo' already completed the scanning process..!")
|
||||
->success()
|
||||
->duration(5000)
|
||||
->send();
|
||||
$this->dispatch('loadData', '', [], [], [], [], $plantId);
|
||||
|
||||
$this->form->fill([
|
||||
'plant_id' => $plantId,
|
||||
'scan_invoice' => null,//$invoiceNo,
|
||||
'total_sno_quantity' => 0,//$count,
|
||||
'pending_quantity' => 0,//0,
|
||||
'scan_quantity' => 0//$count
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
$serialNumbers = LocatorInvoiceValidation::where('plant_id', $plantId)
|
||||
->where('invoice_number', $invoiceNo)
|
||||
->pluck('serial_number');
|
||||
|
||||
$notFoundSerials = [];
|
||||
$incompleteSerials = [];
|
||||
$scannedSerials = [];
|
||||
$foundSerials = [];
|
||||
|
||||
foreach ($serialNumbers as $serial)
|
||||
{
|
||||
$locatorRecord = LocatorInvoiceValidation::where('serial_number', $serial)
|
||||
->where('plant_id', $plantId)
|
||||
->first();
|
||||
|
||||
//$scannedStatus = $locatorRecord->scanned_status ?? null;
|
||||
|
||||
if ($locatorRecord->scanned_status == 'Scanned')
|
||||
{
|
||||
$scannedSerials[] = $serial;
|
||||
continue;
|
||||
}
|
||||
|
||||
$palletRecord = palletValidation::where('serial_number', $serial)
|
||||
->where('plant_id', $plantId)
|
||||
->first();
|
||||
|
||||
if (!$palletRecord)
|
||||
{
|
||||
$notFoundSerials[] = $serial;
|
||||
continue;
|
||||
}
|
||||
|
||||
$palletStatus = $palletRecord->pallet_status ?? null;
|
||||
|
||||
if (strlen($palletRecord->pallet_number) > 1 && ($palletStatus == '' || $palletStatus == null))
|
||||
{
|
||||
$incompleteSerials[] = $serial;
|
||||
continue;
|
||||
}
|
||||
|
||||
$foundSerials[] = $serial;
|
||||
}
|
||||
|
||||
$count = LocatorInvoiceValidation::where('invoice_number', $invoiceNo)
|
||||
->where('plant_id', $plantId)
|
||||
->count();
|
||||
|
||||
$pendingCount = LocatorInvoiceValidation::where('invoice_number', $invoiceNo)
|
||||
->where('plant_id', $plantId)
|
||||
->whereNull('scanned_status')
|
||||
->orWhere('scanned_status', '=', '')
|
||||
->count();
|
||||
|
||||
$scannedCount = LocatorInvoiceValidation::where('invoice_number', $invoiceNo)
|
||||
->where('plant_id', $plantId)
|
||||
->where('scanned_status', '=', 'Scanned')
|
||||
->count();
|
||||
|
||||
$this->form->fill([
|
||||
'plant_id' => $plantId,
|
||||
'scan_invoice' => $invoiceNo,
|
||||
'total_sno_quantity' => $count,
|
||||
'pending_quantity' => $pendingCount,
|
||||
'scan_quantity' => $scannedCount,
|
||||
]);
|
||||
|
||||
$this->dispatch('loadData', $invoiceNo, $notFoundSerials, $incompleteSerials, $scannedSerials, $foundSerials, $plantId);
|
||||
}
|
||||
|
||||
public static function canAccess(): bool
|
||||
{
|
||||
return Auth::check() && Auth::user()->can('view invoice finder page');
|
||||
}
|
||||
|
||||
}
|
||||
75
app/Filament/Pages/InvoiceQuantityDashboard.php
Normal file
75
app/Filament/Pages/InvoiceQuantityDashboard.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Pages;
|
||||
|
||||
use App\Models\Plant;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Pages\Page;
|
||||
use Filament\Pages\Dashboard\Concerns\HasFiltersForm;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class InvoiceQuantityDashboard extends Page
|
||||
{
|
||||
use HasFiltersForm;
|
||||
protected static ?string $navigationIcon = 'heroicon-o-document-text';
|
||||
|
||||
protected static ?string $navigationGroup = 'Invoice DashBoard';
|
||||
|
||||
protected static string $view = 'filament.pages.invoice-quantity-dashboard';
|
||||
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
session()->forget(['selec_plant', 'select_invoice']);
|
||||
$this->filtersForm->fill([
|
||||
'plant' => null,
|
||||
'invoice' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
public function filtersForm(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->statePath('filters') // Explicitly set where to store form data
|
||||
->schema([
|
||||
Select::make('plant')
|
||||
->label('Select Plant')
|
||||
//->options(Plant::pluck('name', 'id'))
|
||||
->options(function (callable $get) {
|
||||
$userHas = Filament::auth()->user()->plant_id;
|
||||
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
|
||||
})
|
||||
->reactive()
|
||||
->afterStateUpdated(function ($state) {
|
||||
session(['selec_plant' => $state]);
|
||||
$this->dispatch('invoiceChart');
|
||||
}),
|
||||
Select::make('invoice')
|
||||
->options([
|
||||
'serial_invoice' => 'Serial Invoice',
|
||||
'individual_material' => 'Individual Material Invoice',
|
||||
'bundle_material' => 'Bundle Material Invoice',
|
||||
])
|
||||
->label('Select Invoice')
|
||||
->reactive()
|
||||
->default(0)
|
||||
->afterStateUpdated(function ($state) {
|
||||
session(['select_invoice' => $state]);
|
||||
$this->dispatch('invoiceChart');
|
||||
})
|
||||
])
|
||||
->columns(2);
|
||||
}
|
||||
public static function getNavigationLabel(): string
|
||||
{
|
||||
return 'Invoice Quantity';
|
||||
}
|
||||
|
||||
public static function canAccess(): bool
|
||||
{
|
||||
return Auth::check() && Auth::user()->can('view invoice serial quantity dashboard');
|
||||
}
|
||||
}
|
||||
1982
app/Filament/Pages/LocatorValidation.php
Normal file
1982
app/Filament/Pages/LocatorValidation.php
Normal file
File diff suppressed because it is too large
Load Diff
1040
app/Filament/Pages/PalletFromLocator.php
Normal file
1040
app/Filament/Pages/PalletFromLocator.php
Normal file
File diff suppressed because it is too large
Load Diff
375
app/Filament/Pages/ProductionDataSap.php
Normal file
375
app/Filament/Pages/ProductionDataSap.php
Normal file
@@ -0,0 +1,375 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Pages;
|
||||
|
||||
use App\Models\Item;
|
||||
use App\Models\Plant;
|
||||
use App\Models\ProductionQuantity;
|
||||
use App\Models\QualityValidation;
|
||||
use App\Models\StickerMaster;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Forms\Components\Actions;
|
||||
use Filament\Forms\Components\Actions\Action;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Pages\Page;
|
||||
use Filament\Forms\Concerns\InteractsWithForms;
|
||||
use Filament\Forms\Contracts\HasForms;
|
||||
use Filament\Notifications\Notification;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class ProductionDataSap extends Page implements HasForms
|
||||
{
|
||||
use InteractsWithForms;
|
||||
|
||||
public $pId , $pOrder, $pUom, $pItem, $transHeadLog, $sNums = [];
|
||||
|
||||
public $scanned_quantity;
|
||||
|
||||
public array $data = []; //Required to back form state
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-document-text';
|
||||
protected static string $view = 'filament.pages.production-data-sap';
|
||||
|
||||
protected static ?string $navigationGroup = 'Send To SAP';
|
||||
|
||||
protected $listeners = ['updateScannedQuantity' => 'setScannedQuantity'];
|
||||
|
||||
|
||||
|
||||
public function setScannedQuantity($quantity)
|
||||
{
|
||||
// Set the scanned_quantity value in the Filament page/form
|
||||
$this->scanned_quantity = $quantity;
|
||||
$this->form->fill([
|
||||
'scanned_quantity' => $quantity,
|
||||
'production_order' => $this->pOrder,
|
||||
'plant_id' => $this->pId,
|
||||
]);
|
||||
}
|
||||
|
||||
public function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->statePath('data')
|
||||
->schema([
|
||||
Select::make('plant_id')
|
||||
->label('Plant')
|
||||
->reactive()
|
||||
->required()
|
||||
//->options(Plant::pluck('name', 'id'))
|
||||
->options(function (callable $get) {
|
||||
$userHas = Filament::auth()->user()->plant_id;
|
||||
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
|
||||
})
|
||||
->afterStateUpdated(function ($state, $set, callable $get) {
|
||||
$plantId = $get('plant_id');
|
||||
if (!$plantId) {
|
||||
$set('pqPlantError', 'Please select a plant first.');
|
||||
$set('production_order', null);
|
||||
$set('scanned_quantity', null);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
$this->pId = $plantId;
|
||||
$set('production_order', null);
|
||||
$set('scanned_quantity', null);
|
||||
$set('validationError', null);
|
||||
$set('pqPlantError', null);
|
||||
}
|
||||
})
|
||||
->hint(fn ($get) => $get('pqPlantError') ? $get('pqPlantError') : null)
|
||||
->hintColor('danger'),
|
||||
|
||||
TextInput::make('production_order')
|
||||
->required()
|
||||
->reactive()
|
||||
->afterStateUpdated(function ($state, $set, callable $get) {
|
||||
$productionOrder = $get('production_order');
|
||||
|
||||
if (!$productionOrder) {
|
||||
$set('pqproducError', 'Please provide production order.');
|
||||
$set('scanned_quantity', null);
|
||||
$this->dispatch('refreshed', $this->pId, $this->pOrder);
|
||||
|
||||
return;
|
||||
}
|
||||
else {
|
||||
$this->pOrder = null;
|
||||
$this->dispatch('refreshed', $this->pId, $this->pOrder);
|
||||
$set('scanned_quantity', null);
|
||||
$set('validationError', null);
|
||||
$set('pqproducError', null);
|
||||
}
|
||||
})
|
||||
->hint(fn ($get) => $get('pqproducError') ? $get('pqproducError') : null)
|
||||
->hintColor('danger')
|
||||
->extraAttributes([
|
||||
'wire:keydown.enter' => 'processValues($event.target.value)',
|
||||
]),
|
||||
|
||||
TextInput::make('scanned_quantity')
|
||||
->reactive() // Make it reactive to update when changed
|
||||
->afterStateUpdated(function ($state, $set, $get) {
|
||||
$this->scanned_quantity = $state;
|
||||
})
|
||||
->readOnly()
|
||||
->required(),
|
||||
|
||||
// Add your custom action button here
|
||||
Actions::make([
|
||||
Action::make('send_to_sap')
|
||||
->label('Send Data to SAP')
|
||||
->action(function ($set, $get) {
|
||||
$plantId = $get('plant_id');
|
||||
$plantWarehouseCodes = [
|
||||
// plant_id => warehouse_code
|
||||
1 => '110', // Ransar I
|
||||
2 => '101', // Ransar II
|
||||
3 => '102', // Chola Pumps
|
||||
4 => '104', // Tuff Pumps
|
||||
//5 => '107', //WH-Nark
|
||||
5 => '200', // Go-flex
|
||||
//7 => '301', // Krisgo II
|
||||
];
|
||||
|
||||
$year = date('y'); // '25' for 2025
|
||||
$month = date('m'); // '05' for May
|
||||
$transHeadLogId = $this->transHeadLog; //'3256';
|
||||
$lineItemCnt = '1'; //1 hard code
|
||||
$sapOrder = $get('production_order');
|
||||
$itemCode = $this->pItem;
|
||||
$quantity = (string)$get('scanned_quantity');
|
||||
$UOM = $this->pUom;
|
||||
|
||||
$locationName = '';
|
||||
$lamiCdate = $get('lami_cdate');
|
||||
$serialNumbers = $this->sNums;
|
||||
|
||||
$warehouseCode = $plantWarehouseCodes[$plantId] ?? null;
|
||||
$finalBatch = $warehouseCode . $year . $month;
|
||||
|
||||
$batchNumber = $finalBatch;
|
||||
//dd($batchNumber);
|
||||
|
||||
$currentDateTime = date('j/n/Y h:i:s A');
|
||||
|
||||
$header = [
|
||||
'Trans_Head_Log_Id' => $transHeadLogId, //'3256',
|
||||
'Line_Item_Count' => $lineItemCnt, //'1',
|
||||
'SAP_Order_Number' => $sapOrder, //'12345678'
|
||||
'Item_Code' => $itemCode, //'6458795'
|
||||
];
|
||||
// $serialNumbers = ['12024090000142', '12024090000142', '12024090000142'];
|
||||
$Receipt = [
|
||||
// 'Receipt' => [
|
||||
[
|
||||
'Quantity' => $quantity, //'1',
|
||||
'UOM' => $UOM,
|
||||
'Batch_Number' => $batchNumber,
|
||||
'Location_Name' => $locationName,
|
||||
'LAMI_Cdate' => $currentDateTime, //'9/9/2024 10:48:37 AM',
|
||||
'Serial_Number' => array_map(function ($serial) {
|
||||
return ['Serial_Number' => $serial];
|
||||
}, $serialNumbers)
|
||||
]
|
||||
// ]
|
||||
];
|
||||
|
||||
|
||||
$payload = [
|
||||
// ...$header,
|
||||
'Receipt' => $Receipt
|
||||
];
|
||||
// dd($payload);
|
||||
|
||||
// $header = [
|
||||
// 'Trans_Head_Log_Id' => '3256',
|
||||
// 'Line_Item_Count' => '1',
|
||||
// 'SAP_Order_Number' => '12345678',
|
||||
// 'Item_Code' => '6458795'
|
||||
// ];
|
||||
// $serialNumbers = ['12024090000142'];
|
||||
// $Receipt = [
|
||||
// // 'Receipt' => [
|
||||
// [
|
||||
// 'Quantity' => '1',
|
||||
// 'UOM' => 'EA',
|
||||
// 'Batch_Number' => '',
|
||||
// 'Location_Name' => '',
|
||||
// 'LAMI_Cdate' => '9/9/2024 10:48:37 AM',
|
||||
// 'Serial_Number' => array_map(function ($serial) {
|
||||
// return ['Serial_Number' => $serial];
|
||||
// }, $serialNumbers)
|
||||
// ]
|
||||
// // ]
|
||||
// ];
|
||||
|
||||
|
||||
// $payload = [
|
||||
// // ...$header,
|
||||
// 'Receipt' => $Receipt
|
||||
// ];
|
||||
// dd($payload);
|
||||
try {
|
||||
// $response = Http::withHeaders([
|
||||
// 'Content-Type' => 'application/json',
|
||||
// 'Trans_Head_Log_Id' => '3256',//$transHeadLogId,
|
||||
// 'Line_Item_Count' => '1', // $lineItemCnt,
|
||||
// 'SAP_Order_Number' => '12345678', //$sapOrder,
|
||||
// 'Item_Code' => '6458795', //$itemCode,
|
||||
// ])
|
||||
$response = Http::withHeaders([
|
||||
'Content-Type' => 'application/json',
|
||||
'Trans_Head_Log_Id' => $transHeadLogId,
|
||||
'Line_Item_Count' => $lineItemCnt,
|
||||
'SAP_Order_Number' => $sapOrder,
|
||||
'Item_Code' => $itemCode,
|
||||
])
|
||||
->withBasicAuth(
|
||||
'sb-eba140ab-74bb-44a4-8d92-70a636940def!b1182|it-rt-dev-cri-stjllphr!b68',
|
||||
'616d8991-307b-4ab1-be37-7894a8c6db9d$0p0fE2I7w1Ve23-lVSKQF0ka3mKrTVcKPJYELr-i4nE='
|
||||
)
|
||||
->withBody(json_encode($payload), 'application/json')
|
||||
//->dump()
|
||||
|
||||
->post('https://dev-cri-stjllphr.it-cpi004-rt.cfapps.ap11.hana.ondemand.com/http/LA2CRI/GoodsReceiptAgFG', $payload);
|
||||
|
||||
// dump($response->transferStats->getRequest());
|
||||
|
||||
// dd(json_encode($payload, JSON_PRETTY_PRINT));
|
||||
//dd($response->status(), $response->body());
|
||||
|
||||
// dump($response);
|
||||
|
||||
$messageCode = $response->headers()['messagecode'][0] ?? null;
|
||||
|
||||
if ($messageCode && str_starts_with($messageCode, 'ERROR')) {
|
||||
|
||||
$cleanError = str_replace('ERROR:|', '', $messageCode);
|
||||
|
||||
// Update rows where plant_id and production_order match
|
||||
ProductionQuantity::where('plant_id', $get('plant_id'))
|
||||
->where('production_order', $get('production_order'))
|
||||
->update([
|
||||
'sap_msg_status' => 'ERROR',
|
||||
'sap_msg_description' => $cleanError,
|
||||
]);
|
||||
|
||||
Notification::make()
|
||||
->title('SAP Error')
|
||||
->body($cleanError)
|
||||
->danger()
|
||||
->send();
|
||||
$this->dispatch('loadItems', $this->pId, $this->pOrder);
|
||||
}
|
||||
else
|
||||
{
|
||||
$messageCode = $response->headers()['messagecode'][0] ?? null;
|
||||
$sapSuccessMsg = str_replace('SUCCESS:|', '', $messageCode);
|
||||
|
||||
ProductionQuantity::where('plant_id', $get('plant_id'))
|
||||
->where('production_order', $get('production_order'))
|
||||
->update([
|
||||
'sap_msg_status' => 'SUCCESS',
|
||||
'sap_msg_description' => $sapSuccessMsg,
|
||||
]);
|
||||
|
||||
Notification::make()
|
||||
->title('SAP Success')
|
||||
->body($sapSuccessMsg)
|
||||
->success()
|
||||
->send();
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Notification::make()
|
||||
->title('Exception')
|
||||
->body('Error sending data to SAP: ' . $e->getMessage())
|
||||
->danger()
|
||||
->send();
|
||||
}
|
||||
})
|
||||
->color('success')
|
||||
->outlined()
|
||||
->hidden(fn (callable $get) => (!$get('scanned_quantity'))) //!$get('plant_id') && !$get('production_order') &&
|
||||
->extraAttributes(['class' => 'align-to-input']),
|
||||
]),
|
||||
])
|
||||
->columns(4);
|
||||
}
|
||||
|
||||
public function processValues($value)
|
||||
{
|
||||
|
||||
$this->pOrder = $value;
|
||||
|
||||
$latestValidation = ProductionQuantity::where('plant_id', $this->pId)
|
||||
->where('production_order', $this->pOrder)
|
||||
->latest()
|
||||
->first();
|
||||
|
||||
if (!$latestValidation) {
|
||||
Notification::make()
|
||||
->title('Invalid Production Order')
|
||||
->body('No data found for the selected plant and production order.')
|
||||
->danger()
|
||||
->send();
|
||||
|
||||
$this->dispatch('refreshed', $this->pId, $this->pOrder);
|
||||
return;
|
||||
}
|
||||
|
||||
// $this->pUom = $latestValidation->uom;
|
||||
$this->transHeadLog = $latestValidation->id;
|
||||
|
||||
$itemId = $latestValidation->item_id;
|
||||
|
||||
$this->pUom = Item::where('id', $itemId)->value('uom');
|
||||
|
||||
$this->sNums = [];
|
||||
|
||||
if(!$this->pUom)
|
||||
{
|
||||
Notification::make()
|
||||
->title('UOM Not Found')
|
||||
->body('UOM not found for the production order')
|
||||
->icon('heroicon-o-x-circle')
|
||||
->danger()
|
||||
->send();
|
||||
$this->dispatch('refreshed', $this->pId, $this->pOrder);
|
||||
}
|
||||
else
|
||||
{
|
||||
$latestProduction = ProductionQuantity::where('plant_id', $this->pId)
|
||||
->where('production_order', $this->pOrder)
|
||||
->latest()
|
||||
->first();
|
||||
|
||||
$this->pItem = $latestProduction
|
||||
? Item::where('id', $latestProduction->item_id)->value('code')
|
||||
: null;
|
||||
|
||||
|
||||
$this->sNums = ProductionQuantity::where('plant_id', $this->pId)
|
||||
->where('production_order', $this->pOrder)
|
||||
->pluck('serial_number')
|
||||
->toArray();
|
||||
|
||||
$this->dispatch('loadItems', $this->pId, $this->pOrder);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static function canAccess(): bool
|
||||
{
|
||||
return Auth::check() && Auth::user()->can('view production data send to sap');
|
||||
}
|
||||
|
||||
public static function getNavigationLabel(): string
|
||||
{
|
||||
return 'Production Data';
|
||||
}
|
||||
}
|
||||
|
||||
74
app/Filament/Pages/ProductionLineStopCount.php
Normal file
74
app/Filament/Pages/ProductionLineStopCount.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Pages;
|
||||
|
||||
use App\Models\Plant;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Pages\Dashboard\Concerns\HasFiltersForm;
|
||||
use Filament\Pages\Page;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class ProductionLineStopCount extends Page
|
||||
{
|
||||
protected static ?string $navigationIcon = 'heroicon-o-document-text';
|
||||
|
||||
protected static string $view = 'filament.pages.production-line-stop-count';
|
||||
|
||||
protected static ?string $navigationGroup = 'Production DashBoard';
|
||||
|
||||
use HasFiltersForm;
|
||||
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
session()->forget(['selected_plant', 'selected_line']);
|
||||
$this->filtersForm->fill([
|
||||
//'plant' => Plant::first()?->id // Default to first plant
|
||||
'plant' => null,
|
||||
'line' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
public function filtersForm(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->statePath('filters')
|
||||
->schema([
|
||||
|
||||
Select::make('plant')
|
||||
->label('Select Plant')
|
||||
//->options(Plant::pluck('name', 'id'))
|
||||
->options(function (callable $get) {
|
||||
$userHas = Filament::auth()->user()->plant_id;
|
||||
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
|
||||
})
|
||||
->reactive()
|
||||
->afterStateUpdated(function ($state) {
|
||||
session(['selected_plant' => $state]);
|
||||
}),
|
||||
|
||||
// Line Filter
|
||||
Select::make('line')
|
||||
->options(function ($get) {
|
||||
$plantId = $get('plant');
|
||||
return $plantId ? Plant::find($plantId)->getLineNames()->pluck('name', 'id') : [];
|
||||
})
|
||||
->label('Select Line')
|
||||
->reactive()
|
||||
->afterStateUpdated(function ($state) {
|
||||
session(['selected_line' => $state]);
|
||||
}),
|
||||
])
|
||||
->columns(2);
|
||||
}
|
||||
|
||||
public static function canAccess(): bool
|
||||
{
|
||||
return Auth::check() && Auth::user()->can('view production line stop count dashboard');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
110
app/Filament/Pages/ProductionOrderCount.php
Normal file
110
app/Filament/Pages/ProductionOrderCount.php
Normal file
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Pages;
|
||||
|
||||
use App\Models\Plant;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Pages\Dashboard\Concerns\HasFiltersForm;
|
||||
use Filament\Pages\Page;
|
||||
use Filament\Tables\Concerns\HasFilters;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class ProductionOrderCount extends Page
|
||||
{
|
||||
protected static ?string $navigationIcon = 'heroicon-o-document-text';
|
||||
|
||||
protected static string $view = 'filament.pages.production-order-count';
|
||||
|
||||
protected static ?string $navigationGroup = 'Production DashBoard';
|
||||
|
||||
use HasFiltersForm;
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
session()->forget(['selected_plant', 'selected_line', 'selected_status', 'production_order']);
|
||||
$this->filtersForm->fill([
|
||||
'plant' => null,
|
||||
'line' => null,
|
||||
'selected_status' => null,
|
||||
'production_order' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
public function filtersForm(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->statePath('filters') // Explicitly set where to store form data
|
||||
->schema([
|
||||
Select::make('plant')
|
||||
->label('Select Plant')
|
||||
->reactive()
|
||||
//->options(Plant::pluck('name', 'id'))
|
||||
->options(function (callable $get) {
|
||||
$userHas = Filament::auth()->user()->plant_id;
|
||||
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
|
||||
})
|
||||
->afterStateUpdated(function ($state) {
|
||||
session(['selected_plant' => $state]);
|
||||
$this->triggerChartUpdate();
|
||||
}),
|
||||
// Line Filter
|
||||
Select::make('line')
|
||||
->options(function ($get) {
|
||||
$plantId = $get('plant');
|
||||
return $plantId ? Plant::find($plantId)->getLineNames()->pluck('name', 'id') : [];
|
||||
})
|
||||
->label('Select Line')
|
||||
->reactive()
|
||||
->afterStateUpdated(function ($state) {
|
||||
session(['selected_line' => $state]); // Store in session
|
||||
$this->triggerChartUpdate();
|
||||
}),
|
||||
|
||||
Select::make('success_status')
|
||||
->label('Select Status')
|
||||
->options([
|
||||
'Ok' => 'Ok',
|
||||
'Not Ok' => 'Not Ok',
|
||||
])
|
||||
->reactive()
|
||||
->afterStateUpdated(function ($state) {
|
||||
session(['selected_status' => $state]); // fixed typo
|
||||
//$this->dispatch('cumulativeChart'); // custom Livewire event
|
||||
}),
|
||||
// Production Order Text Input
|
||||
TextInput::make('production_order')
|
||||
->label('Production Order')
|
||||
->reactive()
|
||||
->afterStateUpdated(function ($state) {
|
||||
session(['production_order' => $state]);
|
||||
$this->triggerChartUpdate();
|
||||
}),
|
||||
])
|
||||
->columns(4);
|
||||
}
|
||||
|
||||
// public function triggerChartUpdate(): void
|
||||
// {
|
||||
// if (session()->has('selected_plant') && session()->has('selected_line') && session()->has('production_order')) {
|
||||
// $this->dispatch('productionOrderChart');
|
||||
// }
|
||||
// }
|
||||
|
||||
public function triggerChartUpdate(): void
|
||||
{
|
||||
$filters = $this->filtersForm->getState();
|
||||
|
||||
if (!empty($filters['plant']) && !empty($filters['line']) && !empty($filters['production_order']) && !empty($filters['success_status'])) {
|
||||
$this->dispatch('productionOrderChart', filters: $filters);
|
||||
}
|
||||
}
|
||||
|
||||
public static function canAccess(): bool
|
||||
{
|
||||
return Auth::check() && Auth::user()->can('view production order count dashboard');
|
||||
}
|
||||
}
|
||||
1469
app/Filament/Pages/ProductionQuantityPage.php
Normal file
1469
app/Filament/Pages/ProductionQuantityPage.php
Normal file
File diff suppressed because it is too large
Load Diff
1354
app/Filament/Pages/ProductionRejectReason.php
Normal file
1354
app/Filament/Pages/ProductionRejectReason.php
Normal file
File diff suppressed because it is too large
Load Diff
1452
app/Filament/Pages/StickerReprint.php
Normal file
1452
app/Filament/Pages/StickerReprint.php
Normal file
File diff suppressed because it is too large
Load Diff
133
app/Filament/Pages/TrendChartAnalys.php
Normal file
133
app/Filament/Pages/TrendChartAnalys.php
Normal file
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Pages;
|
||||
|
||||
use App\Filament\Widgets\TrendChartAnalysis;
|
||||
use App\Models\MfmMeter;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Pages\Page;
|
||||
use Filament\Pages\Dashboard\Concerns\HasFiltersForm;
|
||||
use App\Models\Plant;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Forms\Components\DateTimePicker;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class TrendChartAnalys extends Page
|
||||
{
|
||||
use HasFiltersForm;
|
||||
protected static ?string $navigationIcon = 'heroicon-o-document-text';
|
||||
|
||||
protected static string $view = 'filament.pages.trend-chart-analys';
|
||||
|
||||
protected static ?string $navigationGroup = 'EMS DashBoard';
|
||||
|
||||
// use HasFiltersForm;
|
||||
public function mount(): void
|
||||
{
|
||||
session()->forget(['selected_plant', 'selected_meter', 'from_datetime', 'to_datetime', 'parameter']);
|
||||
$this->filtersForm->fill([
|
||||
'selected_plant' => null,
|
||||
'selected_meter' => null,
|
||||
'from_datetime' => null,
|
||||
'to_datetime' => null,
|
||||
'parameter' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
public function filtersForm(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->statePath('filters')
|
||||
->schema([
|
||||
DateTimePicker::make('from_datetime')
|
||||
->label('From DateTime')
|
||||
->required()
|
||||
->before('to_datetime')
|
||||
->reactive()
|
||||
->afterStateUpdated(function ($state) {
|
||||
$formatted = \Carbon\Carbon::parse($state)->format('Y-m-d H:i:s');
|
||||
session(['from_datetime' => $formatted]);
|
||||
}),
|
||||
DateTimePicker::make('to_datetime')
|
||||
->label('To DateTime')
|
||||
->required()
|
||||
->after('from_datetime')
|
||||
->reactive()
|
||||
->afterStateUpdated(function ($state) {
|
||||
$formatted = \Carbon\Carbon::parse($state)->format('Y-m-d H:i:s');
|
||||
session(['to_datetime' => $formatted]);
|
||||
}),
|
||||
Select::make('plant')
|
||||
->label('Select Plant')
|
||||
->reactive()
|
||||
->required()
|
||||
//->options(Plant::pluck('name', 'id'))
|
||||
->options(function (callable $get) {
|
||||
$userHas = Filament::auth()->user()->plant_id;
|
||||
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
|
||||
})
|
||||
->afterStateUpdated(function ($state, callable $set) {
|
||||
session(['selected_plant' => $state]);
|
||||
// When plant changes, also reset meter_name
|
||||
$set('meter_name', null);
|
||||
session(['selected_meter' => null]);
|
||||
// dd($state);
|
||||
}),
|
||||
Select::make('meter_name')
|
||||
->options(function ($get) {
|
||||
$plantId = $get('plant');
|
||||
// Return meter name/id pairs from mfm_meters where plant_id matches selected plant
|
||||
return $plantId ? MfmMeter::where('plant_id', $plantId)->pluck('name', 'id') : [];
|
||||
})
|
||||
->label('Select Meter')
|
||||
->reactive()
|
||||
->required()
|
||||
->afterStateUpdated(function ($state) {
|
||||
session(['selected_meter' => $state]);
|
||||
}),
|
||||
Select::make('parameter')
|
||||
->options([
|
||||
'Phase Voltage' => 'Phase Voltage',
|
||||
'Line Voltage' => 'Line Voltage',
|
||||
'Current' => 'Current',
|
||||
'Active Power' => 'Active Power',
|
||||
'Power Factor' => 'Power Factor',
|
||||
'Units' => 'Units',
|
||||
])
|
||||
->label('Select Parameter')
|
||||
->reactive()
|
||||
->required()
|
||||
->afterStateUpdated(function ($state) {
|
||||
session(['parameter' => $state]);
|
||||
}),
|
||||
])
|
||||
->columns(5);
|
||||
}
|
||||
|
||||
public static function getNavigationLabel(): string
|
||||
{
|
||||
return 'Trend Chart Analysis';
|
||||
}
|
||||
|
||||
public function getHeading(): string
|
||||
{
|
||||
return 'Trend Chart Analysis';
|
||||
}
|
||||
|
||||
public function getWidgets(): array
|
||||
{
|
||||
$widgets = [];
|
||||
|
||||
if (TrendChartAnalysis::canView()) {
|
||||
$widgets[] = TrendChartAnalysis::class;
|
||||
}
|
||||
return $widgets;
|
||||
}
|
||||
|
||||
public static function canAccess(): bool
|
||||
{
|
||||
return Auth::check() && Auth::user()->can('view ems trend chart analysis dashboard');
|
||||
}
|
||||
}
|
||||
131
app/Filament/Pages/TrendLineAnalysis.php
Normal file
131
app/Filament/Pages/TrendLineAnalysis.php
Normal file
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Pages;
|
||||
|
||||
use App\Filament\Widgets\TrendLineChart;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Pages\Page;
|
||||
use Filament\Pages\Dashboard\Concerns\HasFiltersForm;
|
||||
use App\Models\Plant;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Forms\Components\DateTimePicker;
|
||||
use App\Models\MfmMeter;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class TrendLineAnalysis extends Page
|
||||
{
|
||||
use HasFiltersForm;
|
||||
protected static ?string $navigationIcon = 'heroicon-o-document-text';
|
||||
|
||||
protected static string $view = 'filament.pages.trend-line-analysis';
|
||||
|
||||
protected static ?string $navigationGroup = 'EMS DashBoard';
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
session()->forget(['selected_plant', 'selected_meter', 'from_datetime', 'to_datetime', 'parameter']);
|
||||
$this->filtersForm->fill([
|
||||
'selected_plant' => null,
|
||||
'selected_meter' => null,
|
||||
'from_datetime' => null,
|
||||
'to_datetime' => null,
|
||||
'parameter' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
public function filtersForm(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->statePath('filters')
|
||||
->schema([
|
||||
DateTimePicker::make('from_datetime')
|
||||
->label('From DateTime')
|
||||
->required()
|
||||
->before('to_datetime')
|
||||
->reactive()
|
||||
->afterStateUpdated(function ($state) {
|
||||
$formatted = \Carbon\Carbon::parse($state)->format('Y-m-d H:i:s');
|
||||
session(['from_datetime' => $formatted]);
|
||||
}),
|
||||
DateTimePicker::make('to_datetime')
|
||||
->label('To DateTime')
|
||||
->required()
|
||||
->after('from_datetime')
|
||||
->reactive()
|
||||
->afterStateUpdated(function ($state) {
|
||||
$formatted = \Carbon\Carbon::parse($state)->format('Y-m-d H:i:s');
|
||||
session(['to_datetime' => $formatted]);
|
||||
}),
|
||||
Select::make('plant')
|
||||
->label('Select Plant')
|
||||
->reactive()
|
||||
->required()
|
||||
//->options(Plant::pluck('name', 'id'))
|
||||
->options(function (callable $get) {
|
||||
$userHas = Filament::auth()->user()->plant_id;
|
||||
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
|
||||
})
|
||||
->afterStateUpdated(function ($state, callable $set) {
|
||||
session(['selected_plant' => $state]);
|
||||
// When plant changes, also reset meter_name
|
||||
$set('meter_name', null);
|
||||
session(['selected_meter' => null]);
|
||||
// dd($state);
|
||||
}),
|
||||
Select::make('meter_name')
|
||||
->options(function ($get) {
|
||||
$plantId = $get('plant');
|
||||
// Return meter name/id pairs from mfm_meters where plant_id matches selected plant
|
||||
return $plantId ? MfmMeter::where('plant_id', $plantId)->pluck('name', 'id') : [];
|
||||
})
|
||||
->label('Select Meter')
|
||||
->reactive()
|
||||
->required()
|
||||
->afterStateUpdated(function ($state) {
|
||||
session(['selected_meter' => $state]);
|
||||
}),
|
||||
Select::make('parameter')
|
||||
->options([
|
||||
'Phase Voltage' => 'Phase Voltage',
|
||||
'Line Voltage' => 'Line Voltage',
|
||||
'Current' => 'Current',
|
||||
'Active Power' => 'Active Power',
|
||||
'Power Factor' => 'Power Factor',
|
||||
'Units' => 'Units',
|
||||
])
|
||||
->label('Select Parameter')
|
||||
->reactive()
|
||||
->required()
|
||||
->afterStateUpdated(function ($state) {
|
||||
session(['parameter' => $state]);
|
||||
}),
|
||||
])
|
||||
->columns(5);
|
||||
}
|
||||
// public static function getNavigationLabel(): string
|
||||
// {
|
||||
// return 'Trend Chart Analysis';
|
||||
// }
|
||||
// public function getHeading(): string
|
||||
// {
|
||||
// return 'Trend Chart Analysis';
|
||||
// }
|
||||
|
||||
|
||||
public function getWidgets(): array
|
||||
{
|
||||
$widgets = [];
|
||||
|
||||
if (TrendLineChart::canView()) {
|
||||
$widgets[] = TrendLineChart::class;
|
||||
}
|
||||
return $widgets;
|
||||
}
|
||||
|
||||
public static function canAccess(): bool
|
||||
{
|
||||
return Auth::check() && Auth::user()->can('view ems trend line analysis dashboard');
|
||||
}
|
||||
}
|
||||
1894
app/Filament/Pages/UploadSerialLocator.php
Normal file
1894
app/Filament/Pages/UploadSerialLocator.php
Normal file
File diff suppressed because it is too large
Load Diff
516
app/Filament/Pages/WebcamCapture.php
Normal file
516
app/Filament/Pages/WebcamCapture.php
Normal file
@@ -0,0 +1,516 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Pages;
|
||||
|
||||
use App\Models\Item;
|
||||
use App\Models\Plant;
|
||||
use Filament\Pages\Page;
|
||||
use Filament\Forms\Components\FileUpload;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Concerns\InteractsWithForms;
|
||||
use Filament\Pages\Dashboard\Concerns\HasFiltersForm;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Notifications\Notification;
|
||||
use Filament\Forms\Components\Actions\Action;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Forms\Components\Actions;
|
||||
use Filament\Forms\Components\Field;
|
||||
use Filament\Forms\Components\Hidden;
|
||||
use Filament\Forms\Components\Section;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Contracts\HasForms;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Smalot\PdfParser\Parser;
|
||||
use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;
|
||||
use Storage;
|
||||
use SimpleSoftwareIO\QrCode\Facades\QrCode;
|
||||
use setasign\Fpdi\Fpdi;
|
||||
|
||||
|
||||
class WebcamCapture extends Page implements HasForms
|
||||
{
|
||||
|
||||
use InteractsWithForms;
|
||||
|
||||
use HasFiltersForm;
|
||||
protected static ?string $navigationIcon = 'heroicon-o-document-text';
|
||||
|
||||
protected static string $view = 'filament.pages.webcam-capture';
|
||||
|
||||
public $photo;
|
||||
|
||||
|
||||
// public function filtersForm(Form $form): Form
|
||||
// {
|
||||
// return $form
|
||||
// ->statePath('filters')
|
||||
// ->schema([
|
||||
// FileUpload::make('photo')
|
||||
// ->dehydrated(false)
|
||||
// ->label('Capture from Webcam')
|
||||
// ->disk('local')
|
||||
// ->directory('uploads')
|
||||
// ->preserveFilenames()
|
||||
// ->image()
|
||||
// ->helperText('You can take a picture from your webcam'),
|
||||
// Actions::make([
|
||||
// Action::make('uploadNow')
|
||||
// ->label('Upload PDF Now')
|
||||
// ->action(function ($get, callable $set) {
|
||||
// $uploadedFiles = $get('photo');
|
||||
|
||||
// if (is_array($uploadedFiles) && count($uploadedFiles) > 0)
|
||||
// {
|
||||
// $uploaded = reset($uploadedFiles);
|
||||
|
||||
// if ($uploaded instanceof TemporaryUploadedFile) {
|
||||
// $originalName = $uploaded->getClientOriginalName();
|
||||
// $path = 'uploads/OCR/' . $originalName;
|
||||
|
||||
// // Check if file already exists
|
||||
// if (Storage::disk('local')->exists($path)) {
|
||||
// Notification::make()
|
||||
// ->title('Duplicate File')
|
||||
// ->body("The file '{$originalName}' already exists in uploads/OCR.")
|
||||
// ->warning()
|
||||
// ->send();
|
||||
// return; // Stop here
|
||||
// }
|
||||
|
||||
// $storedPath = $uploaded->storeAs(
|
||||
// 'uploads/OCR',
|
||||
// $originalName,
|
||||
// 'local'
|
||||
// );
|
||||
|
||||
// // $fullPath = storage_path('app/' . $storedPath);
|
||||
// $fullPath = storage_path('app/' . $storedPath);
|
||||
|
||||
// // Parse PDF using smalot/pdfparser
|
||||
// $parser = new Parser();
|
||||
// $pdf = $parser->parseContent(file_get_contents($uploaded->getRealPath()));
|
||||
// $text = $pdf->getText();
|
||||
|
||||
// dd($text);
|
||||
|
||||
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Notification::make()
|
||||
// ->title('No file selected to upload')
|
||||
// ->warning()
|
||||
// ->send();
|
||||
// return;
|
||||
// }
|
||||
// }),
|
||||
|
||||
// Action::make('downloadAttachment')
|
||||
// ->label('Download PDF')
|
||||
// ->action(function ($get) {
|
||||
// $equipmentNumber = $get('process_order');
|
||||
|
||||
// if (!$equipmentNumber) {
|
||||
// Notification::make()
|
||||
// ->title('No process order entered')
|
||||
// ->danger()
|
||||
// ->send();
|
||||
// return;
|
||||
// }
|
||||
|
||||
// $files = Storage::disk('local')->files('uploads/ProcessOrder');
|
||||
|
||||
// $fileToDownload = null;
|
||||
// foreach ($files as $file) {
|
||||
// if (str_contains($file, $equipmentNumber)) {
|
||||
// $fileToDownload = $file;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (!$fileToDownload) {
|
||||
// Notification::make()
|
||||
// ->title('PDF not found for this process order')
|
||||
// ->danger()
|
||||
// ->send();
|
||||
// return;
|
||||
// }
|
||||
|
||||
// return response()->download(Storage::disk('local')->path($fileToDownload));
|
||||
// }),
|
||||
|
||||
// // Action::make('removeAttachment')
|
||||
// // ->label('Remove PDF')
|
||||
// // ->action(function ($get) {
|
||||
// // $equipmentNumber = $get('process_order');
|
||||
|
||||
// // if (!$equipmentNumber) {
|
||||
// // Notification::make()
|
||||
// // ->title('No process order entered')
|
||||
// // ->danger()
|
||||
// // ->send();
|
||||
// // return;
|
||||
// // }
|
||||
|
||||
// // // Get all files from uploads/temp
|
||||
// // $files = Storage::disk('local')->files('uploads/ProcessOrder');
|
||||
|
||||
// // $fileToDelete = null;
|
||||
// // foreach ($files as $file) {
|
||||
// // if (str_contains($file, $equipmentNumber)) {
|
||||
// // $fileToDelete = $file;
|
||||
// // break;
|
||||
// // }
|
||||
// // }
|
||||
|
||||
// // if (!$fileToDelete) {
|
||||
// // Notification::make()
|
||||
// // ->title('PDF not found for this process order')
|
||||
// // ->danger()
|
||||
// // ->send();
|
||||
// // return;
|
||||
// // }
|
||||
|
||||
// // // Delete the matched file
|
||||
// // Storage::disk('local')->delete($fileToDelete);
|
||||
|
||||
// // Notification::make()
|
||||
// // ->title('PDF removed successfully')
|
||||
// // ->body("File for process order {$equipmentNumber} has been deleted.")
|
||||
// // ->success()
|
||||
// // ->send();
|
||||
// // }),
|
||||
// ]),
|
||||
|
||||
// ])
|
||||
// ->columns(1);
|
||||
// }
|
||||
|
||||
public function filtersForm(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->statePath('filters')
|
||||
->schema([
|
||||
Section::make('') // You can give your section a title or leave it blank
|
||||
->schema([
|
||||
Select::make('plant_id')
|
||||
->label('Plant')
|
||||
->reactive()
|
||||
//->relationship('plant', 'name')
|
||||
->options(function (callable $get) {
|
||||
$userHas = Filament::auth()->user()->plant_id;
|
||||
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
|
||||
})
|
||||
->required(),
|
||||
Select::make('item_id')
|
||||
->label('Item Code')
|
||||
->reactive()
|
||||
->searchable()
|
||||
->options(function (callable $get) {
|
||||
if (!$get('plant_id')) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return Item::where('plant_id', $get('plant_id'))
|
||||
->pluck('code', 'id')
|
||||
->toArray();
|
||||
})
|
||||
->required(),
|
||||
TextInput::make('gr_number')
|
||||
->label('GR Number')
|
||||
->minLength(7)
|
||||
->required(),
|
||||
Actions::make([
|
||||
// Action::make('uploadNow1')
|
||||
// ->label('Upload OCR')
|
||||
// ->action(function ($get, callable $set) {
|
||||
// $uploadedFiles = $get('photo');
|
||||
// // $serialNumbers = [
|
||||
// // $get('serial_1'),
|
||||
// // $get('serial_2'),
|
||||
// // $get('serial_3'),
|
||||
// // $get('serial_4'),
|
||||
// // ];
|
||||
|
||||
// if (is_array($uploadedFiles) && count($uploadedFiles) > 0)
|
||||
// {
|
||||
// $uploaded = reset($uploadedFiles);
|
||||
|
||||
// if ($uploaded instanceof TemporaryUploadedFile) {
|
||||
// $grNumber = $get('gr_number');
|
||||
// $safeName = preg_replace('/[^A-Za-z0-9_\-]/', '_', $grNumber);
|
||||
// // $originalName = $uploaded->getClientOriginalName();
|
||||
// // $path = 'uploads/GRNumber/' . $originalName;
|
||||
// $finalFileName = $safeName . '.jpg';
|
||||
// $finalPath = 'uploads/OCR/' . $finalFileName;
|
||||
|
||||
// $storedPath = $uploaded->storeAs(
|
||||
// 'uploads/OCR',
|
||||
// $finalFileName,
|
||||
// 'local'
|
||||
// );
|
||||
|
||||
// // $storedPath = $uploaded->storeAs('uploads/OCR', $finalFileName, 'local');
|
||||
// // $fullPath = storage_path('app/' . $storedPath);
|
||||
// $storedPath = $uploaded->storeAs('uploads/OCR', $finalFileName, 'local');
|
||||
|
||||
// $fullPath = storage_path('app/private/' . $storedPath);
|
||||
|
||||
// $text = (new TesseractOCR($fullPath))->lang('eng')->run();
|
||||
|
||||
// $rawText = $text;
|
||||
|
||||
// preg_match_all('/\d+/', $rawText, $matches);
|
||||
|
||||
// $serialNumbers = $matches[0];
|
||||
|
||||
// $serialNumbers = array_slice($serialNumbers, 0, 4);
|
||||
|
||||
// //dd($serialNumbers);
|
||||
|
||||
// $processOrder = $get('gr_number');
|
||||
|
||||
// $itemId = $get('item_id');
|
||||
|
||||
// $plant = $get('plant_id');
|
||||
|
||||
// $item = Item::find($itemId);
|
||||
|
||||
// $plant = Plant::find($plant);
|
||||
|
||||
// $templatePath = storage_path('app/private/uploads/StickerTemplateOcr/multi.pdf');
|
||||
|
||||
// $outputPath = storage_path('app/private/uploads/StickerTemplateOcr/multi_filled.pdf');
|
||||
|
||||
// $storedPath = $uploaded->storeAs(
|
||||
// 'uploads/GRNumber',
|
||||
// $finalFileName,
|
||||
// 'local'
|
||||
// );
|
||||
|
||||
// $pdf = new Fpdi('P', 'mm', [90, 90]);
|
||||
|
||||
// $templateId = $pdf->setSourceFile($templatePath);
|
||||
// $templatePage = $pdf->importPage(1);
|
||||
|
||||
// $pdf->AddPage();
|
||||
// $pdf->useTemplate($templatePage, 0, 0, 90, 90);
|
||||
|
||||
// $pdf->SetFont('Helvetica', '', 10);
|
||||
// $pdf->SetTextColor(0, 0, 0);
|
||||
|
||||
// $slots = [
|
||||
// ['x' => 5.7, 'y' => 41.9, 'w' => 46.5, 'h' => 3.5], // 1st serial
|
||||
// ['x' => 50, 'y' => 41.5, 'w' => 46.6, 'h' => 3.9], // 2nd serial
|
||||
// ['x' => 5.7, 'y' => 60, 'w' => 46.5, 'h' => 3.5], // 3rd serial
|
||||
// ['x' => 50, 'y' => 60, 'w' => 46.6, 'h' => 3.5], // 4rd serial
|
||||
// ];
|
||||
|
||||
// $qrSlots = [
|
||||
// ['x' => 17.3, 'y' => 29.2, 'size' => 11.4],
|
||||
// ['x' => 61.5, 'y' => 29, 'size' => 11.5],
|
||||
// ['x' => 17.7, 'y' => 46.7, 'size' => 11.4],
|
||||
// ['x' => 61.7, 'y' => 46.7, 'size' => 11.4],
|
||||
// ];
|
||||
|
||||
// foreach ($serialNumbers as $i => $serial) {
|
||||
// if (!isset($slots[$i]) || !isset($qrSlots[$i])) continue;
|
||||
|
||||
// // Erase old QR completely (slightly larger)
|
||||
// $pdf->SetFillColor(255, 255, 255);
|
||||
// $pdf->Rect($qrSlots[$i]['x']-1, $qrSlots[$i]['y']-1, $qrSlots[$i]['size']+2, $qrSlots[$i]['size']+2, 'F');
|
||||
|
||||
// // Generate new QR code
|
||||
// $qrPath = storage_path("app/private/uploads/QR/qr_$serial.png");
|
||||
// $qrDir = storage_path('app/private/uploads/QR');
|
||||
// if (!file_exists($qrDir)) mkdir($qrDir, 0777, true);
|
||||
// QrCode::format('png')->size(100)->generate($serial, $qrPath);
|
||||
|
||||
// // Place QR code
|
||||
// $pdf->Image($qrPath, $qrSlots[$i]['x'], $qrSlots[$i]['y'], $qrSlots[$i]['size'], $qrSlots[$i]['size']);
|
||||
|
||||
// // Erase old serial
|
||||
// $pdf->SetFillColor(255, 255, 255);
|
||||
// $pdf->Rect($slots[$i]['x'], $slots[$i]['y'], $slots[$i]['w'], $slots[$i]['h'], 'F');
|
||||
|
||||
// // Write new serial
|
||||
// $pdf->SetXY($slots[$i]['x'], $slots[$i]['y']);
|
||||
// $pdf->Cell($slots[$i]['w'], $slots[$i]['h'], $serial, 0, 0, 'L');
|
||||
// }
|
||||
|
||||
// // Save the final PDF
|
||||
// $pdf->Output('F', $outputPath);
|
||||
|
||||
// // Download
|
||||
// return response()->download($outputPath);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Notification::make()
|
||||
// ->title('No file selected to upload')
|
||||
// ->warning()
|
||||
// ->send();
|
||||
// return;
|
||||
// }
|
||||
// }),
|
||||
|
||||
Action::make('uploadNow1')
|
||||
->label('Upload OCR')
|
||||
->action(function ($get, callable $set) {
|
||||
|
||||
// $serialNumbers = [
|
||||
// $get('serial_1'),
|
||||
// $get('serial_2'),
|
||||
// $get('serial_3'),
|
||||
// $get('serial_4'),
|
||||
// ];
|
||||
|
||||
// $hasSerial = collect($serialNumbers)->some(fn($s) => !empty($s));
|
||||
$serialNumbersJson = $get('serialNumbers'); // input name matches hidden input
|
||||
$serialNumbers = json_decode($serialNumbersJson, true) ?? [];
|
||||
|
||||
if (empty($serialNumbers)) {
|
||||
Notification::make()
|
||||
->title('Serial numbers cannot be empty!')
|
||||
->danger()
|
||||
->send();
|
||||
return;
|
||||
}
|
||||
|
||||
// Now you can proceed with your PDF logic
|
||||
//$serialNumbers = array_slice($serialNumbers, 0, 4);
|
||||
|
||||
$serialNumbers = array_slice($serialNumbers, 0, 4);
|
||||
|
||||
//dd($serialNumbers);
|
||||
|
||||
$itemId = $get('item_id');
|
||||
|
||||
$plant = $get('plant_id');
|
||||
|
||||
$item = Item::find($itemId);
|
||||
|
||||
$plant = Plant::find($plant);
|
||||
|
||||
$templatePath = storage_path('app/private/uploads/StickerTemplateOcr/multi.pdf');
|
||||
|
||||
$outputPath = storage_path('app/private/uploads/StickerTemplateOcr/multi_filled.pdf');
|
||||
|
||||
// $storedPath = $uploaded->storeAs(
|
||||
// 'uploads/GRNumber',
|
||||
// $finalFileName,
|
||||
// 'local'
|
||||
// );
|
||||
|
||||
$pdf = new Fpdi('P', 'mm', [90, 90]);
|
||||
|
||||
$templateId = $pdf->setSourceFile($templatePath);
|
||||
$templatePage = $pdf->importPage(1);
|
||||
|
||||
$pdf->AddPage();
|
||||
$pdf->useTemplate($templatePage, 0, 0, 90, 90);
|
||||
|
||||
$pdf->SetFont('Helvetica', '', 10);
|
||||
$pdf->SetTextColor(0, 0, 0);
|
||||
|
||||
$slots = [
|
||||
['x' => 5.7, 'y' => 41.9, 'w' => 46.5, 'h' => 3.5], // 1st serial
|
||||
['x' => 50, 'y' => 41.5, 'w' => 46.6, 'h' => 3.9], // 2nd serial
|
||||
['x' => 5.7, 'y' => 60, 'w' => 46.5, 'h' => 3.5], // 3rd serial
|
||||
['x' => 50, 'y' => 60, 'w' => 46.6, 'h' => 3.5], // 4rd serial
|
||||
];
|
||||
|
||||
$qrSlots = [
|
||||
['x' => 17.3, 'y' => 29.2, 'size' => 11.4],
|
||||
['x' => 61.5, 'y' => 29, 'size' => 11.5],
|
||||
['x' => 17.7, 'y' => 46.7, 'size' => 11.4],
|
||||
['x' => 61.7, 'y' => 46.7, 'size' => 11.4],
|
||||
];
|
||||
|
||||
foreach ($serialNumbers as $i => $serial) {
|
||||
if (!isset($slots[$i]) || !isset($qrSlots[$i])) continue;
|
||||
|
||||
// Erase old QR completely (slightly larger)
|
||||
$pdf->SetFillColor(255, 255, 255);
|
||||
$pdf->Rect($qrSlots[$i]['x']-1, $qrSlots[$i]['y']-1, $qrSlots[$i]['size']+2, $qrSlots[$i]['size']+2, 'F');
|
||||
|
||||
// Generate new QR code
|
||||
$qrPath = storage_path("app/private/uploads/QR/qr_$serial.png");
|
||||
$qrDir = storage_path('app/private/uploads/QR');
|
||||
if (!file_exists($qrDir)) mkdir($qrDir, 0777, true);
|
||||
QrCode::format('png')->size(100)->generate($serial, $qrPath);
|
||||
|
||||
// Place QR code
|
||||
$pdf->Image($qrPath, $qrSlots[$i]['x'], $qrSlots[$i]['y'], $qrSlots[$i]['size'], $qrSlots[$i]['size']);
|
||||
|
||||
// Erase old serial
|
||||
$pdf->SetFillColor(255, 255, 255);
|
||||
$pdf->Rect($slots[$i]['x'], $slots[$i]['y'], $slots[$i]['w'], $slots[$i]['h'], 'F');
|
||||
|
||||
// Write new serial
|
||||
$pdf->SetXY($slots[$i]['x'], $slots[$i]['y']);
|
||||
$pdf->Cell($slots[$i]['w'], $slots[$i]['h'], $serial, 0, 0, 'L');
|
||||
}
|
||||
|
||||
// Save the final PDF
|
||||
$pdf->Output('F', $outputPath);
|
||||
|
||||
// Download
|
||||
return response()->download($outputPath);
|
||||
|
||||
}),
|
||||
|
||||
|
||||
Action::make('downloadAttachment')
|
||||
->label('Download PDF')
|
||||
->action(function ($get) {
|
||||
$equipmentNumber = $get('gr_number');
|
||||
|
||||
if (!$equipmentNumber) {
|
||||
Notification::make()
|
||||
->title('No GR Number entered')
|
||||
->danger()
|
||||
->send();
|
||||
return;
|
||||
}
|
||||
|
||||
$files = Storage::disk('local')->files('uploads/GRNumber');
|
||||
|
||||
$fileToDownload = null;
|
||||
foreach ($files as $file) {
|
||||
if (str_contains($file, $equipmentNumber)) {
|
||||
$fileToDownload = $file;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$fileToDownload) {
|
||||
Notification::make()
|
||||
->title('PDF not found for this process order')
|
||||
->danger()
|
||||
->send();
|
||||
return;
|
||||
}
|
||||
|
||||
return response()->download(Storage::disk('local')->path($fileToDownload));
|
||||
}),
|
||||
]),
|
||||
Field::make('camera_capture')
|
||||
->view('fields.web-camera-capture'),
|
||||
Hidden::make('created_by')
|
||||
->label('Created By')
|
||||
->default(Filament::auth()->user()?->name),
|
||||
Hidden::make('updated_by')
|
||||
->default(Filament::auth()->user()?->name),
|
||||
|
||||
])->columns(1),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function canAccess(): bool
|
||||
{
|
||||
return Auth::check() && Auth::user()->can('create web capture page');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user