40 Commits

Author SHA1 Message Date
dhanabalan
db9185f7e0 designed chart fr production quantity 2025-05-12 20:11:25 +05:30
dhanabalan
5718db1399 designed production quantity reports table 2025-05-12 20:10:58 +05:30
dhanabalan
74ef122ee9 designed chart 2025-05-12 20:10:27 +05:30
dhanabalan
a72840d4a3 Removed space 2025-05-12 20:09:25 +05:30
dhanabalan
8368099b93 Removed unwanted plugin data js code 2025-05-12 20:07:27 +05:30
dhanabalan
21ce9c76e8 Updated session plant and line and overriding issue solved 2025-05-12 20:05:54 +05:30
dhanabalan
e198b6e613 Updated session plant and line and overriding issue solved 2025-05-12 20:03:52 +05:30
dhanabalan
fe55962670 Commented unused code 2025-05-12 20:01:46 +05:30
dhanabalan
79be8aec91 Updated session forget func. and recent_qr func. and added sap_msg_status, sap_msg_description columns 2025-05-12 19:56:09 +05:30
dhanabalan
25f13a6d49 Removed updateOrCreate 'admin' user from userSeeder 2025-05-12 19:53:05 +05:30
dhanabalan
1842b525a6 Added import / export button and manualy created productionQuantities page permissions 2025-05-12 19:51:33 +05:30
dhanabalan
efde2c357a Added adminSeeder call method into databaseSeeder 2025-05-12 19:50:07 +05:30
dhanabalan
3f7d1b28f0 Added admin user within adminSeeder page 2025-05-12 19:49:25 +05:30
dhanabalan
b81d0a0de0 Added block_reference column and updated sample data and updated validation func. on import 2025-05-12 19:48:05 +05:30
dhanabalan
fb3ce483c7 Added production_order, uom, sap_msg_status, sap_msg_description, operator_id column 2025-05-12 19:44:18 +05:30
dhanabalan
7d5371cac4 Updated validation func. on import 2025-05-12 19:41:46 +05:30
dhanabalan
db08e07e48 Added uom column and updated validation func. on import 2025-05-12 19:40:33 +05:30
dhanabalan
6f22d0baf0 Added uom column and disabled 'deleted_at' column by default 2025-05-12 19:39:50 +05:30
dhanabalan
401edadee7 Added uom column and updated columnSpan alignments 2025-05-12 19:38:36 +05:30
dhanabalan
fe94bfa109 Commented 'chart-js-plugins' codes 2025-05-12 19:37:00 +05:30
dhanabalan
a57c53ae9f Updated notification duration and Added sap_msg_status, sap_msg_description columns in create production quantity page 2025-05-12 19:35:59 +05:30
dhanabalan
877a4a4696 Updated getRedirectUrl func. in create quality_validations page 2025-05-12 19:33:15 +05:30
dhanabalan
76b17d4abc Added create, edit, list, view pages to weight_validations resource 2025-05-12 19:31:49 +05:30
dhanabalan
2855622746 Added uom column into items model and hasMany relation to productionQuantities 2025-05-12 19:28:56 +05:30
dhanabalan
956c3466f9 Added importer and exporter for quality_validations page 2025-05-12 19:26:37 +05:30
dhanabalan
8d872498f4 Added uom, sap_msg_status, sap_msg_description, serial_number columns into quality_validations resource page and updated scanned serial number comparison func. using serial_number column and updated filter func. 2025-05-12 19:23:26 +05:30
dhanabalan
96d6398f59 Added uom, sap_msg_status, sap_msg_description, serial_number columns into quality_validations model 2025-05-12 19:19:50 +05:30
dhanabalan
fce8620087 Added weight_validations model and resource page 2025-05-12 19:18:51 +05:30
dhanabalan
80c65e6a32 Added sap_msg_status, sap_msg_description columns in create page and Added uom column, report filter func. 2025-05-12 19:16:40 +05:30
dhanabalan
e6563c9e31 Removed searchable and added report filter func. and visible rights added for import / export buttons and readonly mode updated to production_quantity control 2025-05-12 19:11:11 +05:30
dhanabalan
e86abbc88e Updated report filter func. and visible rights added for import / export buttons 2025-05-12 19:06:52 +05:30
dhanabalan
bf4304cacf Removed unwanted space 2025-05-12 19:00:56 +05:30
dhanabalan
b062239007 Added weight_validations migration 2025-05-12 18:58:31 +05:30
dhanabalan
6f5e1f708c Added sap_msg_status, sap_msg_description columns into production_quantities table 2025-05-12 18:57:37 +05:30
dhanabalan
ae902267ef Added uom column into items table 2025-05-12 18:56:38 +05:30
dhanabalan
0334adb52c Added uom, sap_msg_status, sap_msg_description, serial_number columns into quality_validations table 2025-05-12 18:55:50 +05:30
dhanabalan
0b82f33837 Updated import validation (get block_id if plant exist otherwise ignore) 2025-05-10 11:28:18 +05:30
dhanabalan
0ea9d49ead Added import validation functionality and block_reference column and Updated sample data 2025-05-10 11:25:25 +05:30
dhanabalan
7c9c2672a2 Added operator_id column on export 2025-05-10 10:24:49 +05:30
dhanabalan
6b057ed2c4 Added operator_id column on exporter 2025-05-10 09:37:17 +05:30
45 changed files with 2972 additions and 717 deletions

View File

@@ -22,6 +22,8 @@ class ItemExporter extends Exporter
->label('DESCRIPTION'), ->label('DESCRIPTION'),
ExportColumn::make('hourly_quantity') ExportColumn::make('hourly_quantity')
->label('HOURLY QUANTITY'), ->label('HOURLY QUANTITY'),
ExportColumn::make('uom')
->label('UNIT OF MEASURE'),
ExportColumn::make('plant.name') ExportColumn::make('plant.name')
->label('PLANT'), ->label('PLANT'),
ExportColumn::make('created_at') ExportColumn::make('created_at')
@@ -29,7 +31,7 @@ class ItemExporter extends Exporter
ExportColumn::make('updated_at') ExportColumn::make('updated_at')
->label('UPDATED AT'), ->label('UPDATED AT'),
ExportColumn::make('deleted_at') ExportColumn::make('deleted_at')
// ->enabledByDefault(false) ->enabledByDefault(false)
->label('DELETED AT'), ->label('DELETED AT'),
]; ];
} }

View File

@@ -39,7 +39,10 @@ class ProductionLineStopExporter extends Exporter
ExportColumn::make('updated_at') ExportColumn::make('updated_at')
->label('UPDATED AT'), ->label('UPDATED AT'),
ExportColumn::make('deleted_at') ExportColumn::make('deleted_at')
->enabledByDefault(false)
->label('DELETED AT'), ->label('DELETED AT'),
ExportColumn::make('operator_id')
->label('OPERATOR ID'),
]; ];
} }

View File

@@ -31,7 +31,10 @@ class ProductionPlanExporter extends Exporter
ExportColumn::make('updated_at') ExportColumn::make('updated_at')
->label('UPDATED AT'), ->label('UPDATED AT'),
ExportColumn::make('deleted_at') ExportColumn::make('deleted_at')
->enabledByDefault(false)
->label('DELETED AT'), ->label('DELETED AT'),
ExportColumn::make('operator_id')
->label('OPERATOR ID'),
]; ];
} }

View File

@@ -16,22 +16,33 @@ class ProductionQuantityExporter extends Exporter
return [ return [
ExportColumn::make('id') ExportColumn::make('id')
->label('ID'), ->label('ID'),
ExportColumn::make('item.code') ExportColumn::make('production_order')
->label('ITEM CODE'), ->label('PRODUCTION ORDER'),
ExportColumn::make('serial_number') ExportColumn::make('serial_number')
->label('SERIAL NUMBER'), ->label('SERIAL NUMBER'),
ExportColumn::make('item.code')
->label('ITEM CODE'),
ExportColumn::make('item.uom')
->label('UNIT OF MEASURE'),
ExportColumn::make('line.name') ExportColumn::make('line.name')
->label('LINE'), ->label('LINE'),
ExportColumn::make('shift.name') ExportColumn::make('shift.name')
->label('SHIFT'), ->label('SHIFT'),
ExportColumn::make('plant.name') ExportColumn::make('plant.name')
->label('PLANT'), ->label('PLANT'),
ExportColumn::make('sap_msg_status')
->label('SAP MESSAGE STATUS'),
ExportColumn::make('sap_msg_description')
->label('SAP MESSAGE DESCRIPTION'),
ExportColumn::make('created_at') ExportColumn::make('created_at')
->label('CREATED AT'), ->label('CREATED AT'),
ExportColumn::make('updated_at') ExportColumn::make('updated_at')
->label('UPDATED AT'), ->label('UPDATED AT'),
ExportColumn::make('deleted_at') ExportColumn::make('deleted_at')
->label('DELETED AT'), ->label('DELETED AT')
->enabledByDefault(false),
ExportColumn::make('operator_id')
->label('OPERATOR ID'),
]; ];
} }

View File

@@ -0,0 +1,91 @@
<?php
namespace App\Filament\Exports;
use App\Models\QualityValidation;
use Filament\Actions\Exports\ExportColumn;
use Filament\Actions\Exports\Exporter;
use Filament\Actions\Exports\Models\Export;
class QualityValidationExporter extends Exporter
{
protected static ?string $model = QualityValidation::class;
public static function getColumns(): array
{
return [
ExportColumn::make('id')
->label('ID'),
ExportColumn::make('plant.name')
->label('PLANT'),
ExportColumn::make('production_order')
->label('PRODUCTION ORDER'),
ExportColumn::make('serial_number')
->label('SERIAL NUMBER'),
ExportColumn::make('stickerMaster.item.code')
->label('ITEM CODE'),
ExportColumn::make('uom')
->label('UNIT OF MEASURE'),
ExportColumn::make('serial_number_motor')
->label('SERIAL NUMBER MOTOR'),
ExportColumn::make('serial_number_pump')
->label('SERIAL NUMBER PUMP'),
ExportColumn::make('serial_number_pumpset')
->label('SERIAL NUMBER PUMPSET'),
ExportColumn::make('pack_slip_motor')
->label('PACK SLIP MOTOR'),
ExportColumn::make('pack_slip_pump')
->label('PACK SLIP PUMP'),
ExportColumn::make('pack_slip_pumpset')
->label('PACK SLIP PUMPSET'),
ExportColumn::make('name_plate_motor')
->label('NAME PLATE MOTOR'),
ExportColumn::make('name_plate_pump')
->label('NAME PLATE PUMP'),
ExportColumn::make('name_plate_pumpset')
->label('NAME PLATE PUMPSET'),
ExportColumn::make('tube_sticker_motor')
->label('TUBE STICKER MOTOR'),
ExportColumn::make('tube_sticker_pump')
->label('TUBE STICKER PUMP'),
ExportColumn::make('tube_sticker_pumpset')
->label('TUBE STICKER PUMPSET'),
ExportColumn::make('warranty_card')
->label('WARRANTY CARD'),
ExportColumn::make('part_validation1')
->label('PART VALIDATION 1'),
ExportColumn::make('part_validation2')
->label('PART VALIDATION 2'),
ExportColumn::make('part_validation3')
->label('PART VALIDATION 3'),
ExportColumn::make('part_validation4')
->label('PART VALIDATION 4'),
ExportColumn::make('part_validation5')
->label('PART VALIDATION 5'),
ExportColumn::make('sap_msg_status')
->label('SAP MESSAGE STATUS'),
ExportColumn::make('sap_msg_description')
->label('SAP MESSAGE DESCRIPTION'),
ExportColumn::make('created_at')
->label('CREATED AT'),
ExportColumn::make('updated_at')
->label('UPDATED AT'),
ExportColumn::make('deleted_at')
->label('DELETED AT')
->enabledByDefault(false),
ExportColumn::make('operator_id')
->label('OPERATOR ID'),
];
}
public static function getCompletedNotificationBody(Export $export): string
{
$body = 'Your quality validation export has completed and ' . number_format($export->successful_rows) . ' ' . str('row')->plural($export->successful_rows) . ' exported.';
if ($failedRowsCount = $export->getFailedRowsCount()) {
$body .= ' ' . number_format($failedRowsCount) . ' ' . str('row')->plural($failedRowsCount) . ' failed to export.';
}
return $body;
}
}

View File

@@ -3,9 +3,12 @@
namespace App\Filament\Imports; namespace App\Filament\Imports;
use App\Models\Item; use App\Models\Item;
use App\Models\Plant;
use Filament\Actions\Imports\Exceptions\RowImportFailedException;
use Filament\Actions\Imports\ImportColumn; use Filament\Actions\Imports\ImportColumn;
use Filament\Actions\Imports\Importer; use Filament\Actions\Imports\Importer;
use Filament\Actions\Imports\Models\Import; use Filament\Actions\Imports\Models\Import;
use Str;
class ItemImporter extends Importer class ItemImporter extends Importer
{ {
@@ -33,6 +36,11 @@ class ItemImporter extends Importer
->label('Hourly Quantity') ->label('Hourly Quantity')
->numeric() ->numeric()
->rules(['required', 'integer']), ->rules(['required', 'integer']),
ImportColumn::make('uom')
->requiredMapping()
->exampleHeader('Unit of Measure')
->example('EA')
->label('Unit of Measure'),
ImportColumn::make('plant') ImportColumn::make('plant')
->requiredMapping() ->requiredMapping()
->exampleHeader('Plant Name') ->exampleHeader('Plant Name')
@@ -45,9 +53,25 @@ class ItemImporter extends Importer
public function resolveRecord(): ?Item public function resolveRecord(): ?Item
{ {
$plant = \App\Models\Plant::where('name', $this->data['plant'])->first(); $warnMsg = [];
$plant = Plant::where('name', $this->data['plant'])->first();
if (!$plant) { if (!$plant) {
return null; $warnMsg[] = "Plant not found"; // '" . $this->data['plant'] . "'
}
if (Str::length($this->data['code']) < 6 || !ctype_alnum($this->data['code'])) {
$warnMsg[] = "Invalid item code found";
}
// if (Str::length($this->data['uom']) <= 0) {
// $warnMsg[] = "Invalid unit of measure found";
// }
if (Str::length($this->data['description']) < 5) {
$warnMsg[] = "Invalid description found";
}
if (Str::length($this->data['hourly_quantity']) < 0 || !is_numeric($this->data['hourly_quantity']) || $this->data['hourly_quantity'] <= 0) {
$warnMsg[] = "Invalid hourly quantity found";
}
if (!empty($warnMsg)) {
throw new RowImportFailedException(implode(', ', $warnMsg));
} }
return Item::updateOrCreate([ return Item::updateOrCreate([
'code' => $this->data['code'], 'code' => $this->data['code'],
@@ -55,7 +79,8 @@ class ItemImporter extends Importer
], ],
[ [
'description' => $this->data['description'], 'description' => $this->data['description'],
'hourly_quantity' => $this->data['hourly_quantity'] 'hourly_quantity' => $this->data['hourly_quantity'],
'uom' => $this->data['uom']
] ]
); );
// return new Item; // return new Item;

View File

@@ -2,10 +2,19 @@
namespace App\Filament\Imports; namespace App\Filament\Imports;
use App\Models\Block;
use App\Models\Line;
use App\Models\LineStop;
use App\Models\Plant;
use App\Models\ProductionLineStop; use App\Models\ProductionLineStop;
use App\Models\Shift;
use App\Models\User;
use Carbon\Carbon;
use Filament\Actions\Imports\Exceptions\RowImportFailedException;
use Filament\Actions\Imports\ImportColumn; use Filament\Actions\Imports\ImportColumn;
use Filament\Actions\Imports\Importer; use Filament\Actions\Imports\Importer;
use Filament\Actions\Imports\Models\Import; use Filament\Actions\Imports\Models\Import;
use Filament\Facades\Filament;
class ProductionLineStopImporter extends Importer class ProductionLineStopImporter extends Importer
{ {
@@ -17,61 +26,67 @@ class ProductionLineStopImporter extends Importer
ImportColumn::make('from_datetime') ImportColumn::make('from_datetime')
->requiredMapping() ->requiredMapping()
->exampleHeader('From DateTime') ->exampleHeader('From DateTime')
->example('06-02-2025 00:00:00') ->example(['01-01-2025 00:00:00', '01-01-2025 20:00:00'])
->label('From DateTime') ->label('From DateTime')
->rules(['required']), ->rules(['required']), //, 'date_format:"d-m-Y H:i:s"'
ImportColumn::make('to_datetime') ImportColumn::make('to_datetime')
->requiredMapping() ->requiredMapping()
->exampleHeader('To DateTime') ->exampleHeader('To DateTime')
->example('06-02-2025 01:25:00') ->example(['01-01-2025 01:25:00', '01-01-2025 21:00:00'])
->label('To DateTime') ->label('To DateTime')
->rules(['required']), ->rules(['required']),
ImportColumn::make('stop_hour') ImportColumn::make('stop_hour')
->requiredMapping() ->requiredMapping()
->exampleHeader('Stop Hour') ->exampleHeader('Stop Hour')
->example('1') ->example(['1', '1'])
->label('Stop Hour') ->label('Stop Hour')
->numeric() ->numeric()
->rules(['required', 'integer']), ->rules(['required', 'integer']),
ImportColumn::make('stop_min') ImportColumn::make('stop_min')
->requiredMapping() ->requiredMapping()
->exampleHeader('Stop Min') ->exampleHeader('Stop Min')
->example('25') ->example(['25','0'])
->label('Stop Min') ->label('Stop Min')
->numeric() ->numeric()
->rules(['required', 'integer']), ->rules(['required', 'integer']),
ImportColumn::make('linestop') ImportColumn::make('linestop')
->requiredMapping() ->requiredMapping()
->exampleHeader('Line Stop Code') ->exampleHeader('Line Stop Code')
->example('A7R') ->example(['A7R', 'A1R'])
->label('Line Stop Code') ->label('Line Stop Code')
->relationship(resolveUsing:'code') ->relationship(resolveUsing:'code')
->rules(['required']), ->rules(['required']),
ImportColumn::make('line') ImportColumn::make('line')
->requiredMapping() ->requiredMapping()
->exampleHeader('Line Name') ->exampleHeader('Line Name')
->example('4 inch pump line') ->example(['4 inch pump line', '4 inch pump line'])
->label('Line Name') ->label('Line Name')
->relationship(resolveUsing:'name') ->relationship(resolveUsing:'name')
->rules(['required']), ->rules(['required']),
ImportColumn::make('block_reference')
->requiredMapping() // Or optionalMapping() if not always present
->exampleHeader('Block Name')
->example(['Block A', 'Block A'])
->label('Block Name')
->rules(['required']), // Or remove if not required
ImportColumn::make('shift') ImportColumn::make('shift')
->requiredMapping() ->requiredMapping()
->exampleHeader('Shift Name') ->exampleHeader('Shift Name')
->example('Day') ->example(['Day', 'Night'])
->label('Shift Name') ->label('Shift Name')
->relationship(resolveUsing:'name') ->relationship(resolveUsing: 'name')
->rules(['required']), ->rules(['required']),
ImportColumn::make('plant') ImportColumn::make('plant')
->requiredMapping() ->requiredMapping()
->exampleHeader('Plant Name') ->exampleHeader('Plant Name')
->example('Ransar Industries-I') ->example(['Ransar Industries-I', 'Ransar Industries-I'])
->label('Plant Name') ->label('Plant Name')
->relationship(resolveUsing:'name') ->relationship(resolveUsing:'name')
->rules(['required']), ->rules(['required']),
ImportColumn::make('operator_id') ImportColumn::make('operator_id')
->requiredMapping() ->requiredMapping()
->exampleHeader('Operator ID') ->exampleHeader('Operator ID')
->example('admin') ->example([Filament::auth()->user()->name, Filament::auth()->user()->name])
->label('Operator ID') ->label('Operator ID')
->rules(['required']), ->rules(['required']),
]; ];
@@ -79,12 +94,138 @@ class ProductionLineStopImporter extends Importer
public function resolveRecord(): ?ProductionLineStop public function resolveRecord(): ?ProductionLineStop
{ {
$warnMsg = [];
$plant = Plant::where('name', $this->data['plant'])->first();
$line = null;
$block = null;
if (!$plant) {
$warnMsg[] = "Plant not found";
}
else {
$line = Line::where('name', $this->data['line'])->where('plant_id', $plant->id)->first();
//block_reference
$block = Block::where('name', $this->data['block_reference'])->where('plant_id', $plant->id)->first();
}
if (!$line) {
$warnMsg[] = "Line not found";
}
$shift = null;
if (!$block) {
$warnMsg[] = "Block not found";
}
else {
$shift = Shift::where('name', $this->data['shift'])->where('plant_id', $plant->id)->where('block_id', $block->id)->first();
}
//$shift = Shift::where('id', $this->data['shift'])->where('plant_id', $plant->id)->first();
if (!$shift) {
$warnMsg[] = "Shift not found";
}
$linestop = LineStop::where('code', $this->data['linestop'])->first();
if (!$linestop) {
$warnMsg[] = "Line stop code not found";
}
$stophour = is_numeric($this->data['stop_hour']) && $this->data['stop_hour'] >= 0;
$stopmin = is_numeric($this->data['stop_min']) && $this->data['stop_min'] >= 0 && $this->data['stop_min'] <= 60;
if (!$stophour && !$stopmin) {
$warnMsg[] = "Invalid stop hour/minute found";
}
else if (!$stophour) {
$warnMsg[] = "Invalid stop hour found";
}
else if (!$stopmin) {
$warnMsg[] = "Invalid stop min found";
}
else {
$stophour = (int)$this->data['stop_hour'];
$stopmin = (int)$this->data['stop_min'];
if ($stophour == 0 && $stopmin == 0) {
$warnMsg[] = "Invalid stop hour/minute found";
}
}
$validHourMin = ($stophour == 0 && $stopmin == 0) ? false : true;
if (!$validHourMin) {
$warnMsg[] = "Invalid stop hour/minute found";
}
$fromDate = $this->data['from_datetime'];
$toDate = $this->data['to_datetime'];
$formats = ['d-m-Y H:i', 'd-m-Y H:i:s']; //'07-05-2025 08:00' or '07-05-2025 08:00:00'
$fdateTime = null;
$tdateTime = null;
// Try parsing with multiple formats
foreach ($formats as $format) {
try {
$fdateTime = Carbon::createFromFormat($format, $fromDate);
break;
} catch (\Exception $e) {
// Optionally collect warning messages
// $warnMsg[] = "Date format mismatch with format: $format";
}
}
foreach ($formats as $format) {
try {
$tdateTime = Carbon::createFromFormat($format, $toDate);
break;
} catch (\Exception $e) {
// Optionally collect warning messages
// $warnMsg[] = "Date format mismatch with format: $format";
}
}
// $fDateOnly = '';
if (!isset($fdateTime)) {
// throw new \Exception('Invalid date time format');
$warnMsg[] = "Invalid 'From DateTime' format. Expected DD-MM-YYYY HH:MM:SS";
}
// else {
// $fDateOnly = $fdateTime->toDateString();
// }
if (!isset($tdateTime)) {
$warnMsg[] = "Invalid 'To DateTime' format. Expected DD-MM-YYYY HH:MM:SS";
}
if (isset($fdateTime) && isset($tdateTime)) {
if ($fdateTime->greaterThan($tdateTime)) {
$warnMsg[] = "'From DataTime' is greater than 'To DateTime'.";
}
}
// if (!$fromDate) { // || $fromDate->format('d-m-Y H:i') !== $from)
// $warnMsg[] = "Invalid 'From DateTime' format. Expected DD-MM-YYYY HH:MM:SS";
// }
// else if (!$toDate) { // || $toDate->format('d-m-Y H:i') !== $to
// $warnMsg[] = "Invalid 'To DateTime' format. Expected DD-MM-YYYY HH:MM:SS";
// }
$user = User::where('name', $this->data['operator_id'])->first();
if (!$user) {
$warnMsg[] = "Operator ID not found";
}
if (!empty($warnMsg)) {
throw new RowImportFailedException(implode(', ', $warnMsg));
}
ProductionLineStop::updateOrCreate([
'plant_id' => $plant->id,
'line_id' => $line->id,
'shift_id' => $shift->id,
'linestop_id' => $linestop->id,
'from_datetime' => $fdateTime->format('Y-m-d H:i:s'),//$this->data['from_datetime'],
'to_datetime' => $tdateTime->format('Y-m-d H:i:s'),//$this->data['to_datetime'],
'stop_hour' => (int)$this->data['stop_hour'],
'stop_min' => (int)$this->data['stop_min'],
'operator_id' => $this->data['operator_id'],
]);
return null;
// return ProductionLineStop::firstOrNew([ // return ProductionLineStop::firstOrNew([
// // Update existing records, matching them by `$this->data['column_name']` // // Update existing records, matching them by `$this->data['column_name']`
// 'email' => $this->data['email'], // 'email' => $this->data['email'],
// ]); // ]);
return new ProductionLineStop(); // return new ProductionLineStop();
} }
public static function getCompletedNotificationBody(Import $import): string public static function getCompletedNotificationBody(Import $import): string

View File

@@ -89,15 +89,19 @@ class ProductionPlanImporter extends Importer
{ {
$warnMsg = []; $warnMsg = [];
$plant = Plant::where('name', $this->data['plant'])->first(); $plant = Plant::where('name', $this->data['plant'])->first();
$line = null;
$block = null;
if (!$plant) { if (!$plant) {
$warnMsg[] = "Plant not found"; $warnMsg[] = "Plant not found";
} }
$line = Line::where('name', $this->data['line'])->where('plant_id', $plant->id)->first(); else {
$line = Line::where('name', $this->data['line'])->where('plant_id', $plant->id)->first();
//block_reference
$block = Block::where('name', $this->data['block_reference'])->where('plant_id', $plant->id)->first();
}
if (!$line) { if (!$line) {
$warnMsg[] = "Line not found"; $warnMsg[] = "Line not found";
} }
//block_reference
$block = Block::where('name', $this->data['block_reference'])->where('plant_id', $plant->id)->first();
$shift = null; $shift = null;
if (!$block) { if (!$block) {
$warnMsg[] = "Block not found"; $warnMsg[] = "Block not found";

View File

@@ -2,11 +2,21 @@
namespace App\Filament\Imports; namespace App\Filament\Imports;
use App\Models\Block;
use App\Models\Item;
use App\Models\Line;
use App\Models\Plant;
use App\Models\ProductionQuantity; use App\Models\ProductionQuantity;
use App\Models\Shift;
use App\Models\User;
use Carbon\Carbon;
use Filament\Actions\Imports\Exceptions\RowImportFailedException;
use Filament\Actions\Imports\ImportColumn; use Filament\Actions\Imports\ImportColumn;
use Filament\Actions\Imports\Importer; use Filament\Actions\Imports\Importer;
use Filament\Actions\Imports\Models\Import; use Filament\Actions\Imports\Models\Import;
use Filament\Facades\Filament;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Str;
class ProductionQuantityImporter extends Importer class ProductionQuantityImporter extends Importer
{ {
@@ -18,59 +28,65 @@ class ProductionQuantityImporter extends Importer
ImportColumn::make('created_at') ImportColumn::make('created_at')
->requiredMapping() ->requiredMapping()
->exampleHeader('Created DateTime') ->exampleHeader('Created DateTime')
->example('12-02-2025 15:51:00') ->example(['01-01-2025 08:00:00', '01-01-2025 19:30:00'])
->label('Created DateTime') ->label('Created DateTime')
->rules(['required']), ->rules(['required']),
ImportColumn::make('production_order') ImportColumn::make('production_order')
->requiredMapping() ->requiredMapping()
->exampleHeader('Production Order') ->exampleHeader('Production Order')
->example('1234567') ->example(['1234567', '1234567'])
->label('Production Order') ->label('Production Order')
->numeric(), ->numeric(),
ImportColumn::make('item') ImportColumn::make('item')
->requiredMapping() ->requiredMapping()
->exampleHeader('Item Code') ->exampleHeader('Item Code')
->example('123456') ->example(['123456', '123456'])
->label('Item Code') ->label('Item Code')
->relationship(resolveUsing:'code') ->relationship(resolveUsing:'code')
->rules(['required']), ->rules(['required']),
ImportColumn::make('serial_number') ImportColumn::make('serial_number')
->requiredMapping() ->requiredMapping()
->exampleHeader('Serial Number') ->exampleHeader('Serial Number')
->example('12345678901234') ->example(['12345678901234', '12345678902234'])
->label('Serial Number') ->label('Serial Number')
->rules(['required']), ->rules(['required']),
ImportColumn::make('line') ImportColumn::make('line')
->requiredMapping() ->requiredMapping()
->exampleHeader('Line Name') ->exampleHeader('Line Name')
->example('4 inch pump line') ->example(['4 inch pump line', '4 inch pump line'])
->label('Line Name') ->label('Line Name')
->relationship(resolveUsing:'name') ->relationship(resolveUsing:'name')
->rules(['required']), ->rules(['required']),
ImportColumn::make('block_reference')
->requiredMapping() // Or optionalMapping() if not always present
->exampleHeader('Block Name')
->example(['Block A', 'Block A'])
->label('Block Name')
->rules(['required']), // Or remove if not required
ImportColumn::make('shift') ImportColumn::make('shift')
->requiredMapping() ->requiredMapping()
->exampleHeader('Shift Name') ->exampleHeader('Shift Name')
->example('Day') ->example(['Day', 'Night'])
->label('Shift Name') ->label('Shift Name')
->relationship(resolveUsing:'name') ->relationship(resolveUsing:'name')
->rules(['required']), ->rules(['required']),
ImportColumn::make('plant') ImportColumn::make('plant')
->requiredMapping() ->requiredMapping()
->exampleHeader('Plant Name') ->exampleHeader('Plant Name')
->example('Ransar Industries-I') ->example(['Ransar Industries-I', 'Ransar Industries-I'])
->label('Plant Name') ->label('Plant Name')
->relationship(resolveUsing:'name') ->relationship(resolveUsing:'name')
->rules(['required']), ->rules(['required']),
ImportColumn::make('updated_at') ImportColumn::make('updated_at')
->requiredMapping() ->requiredMapping()
->exampleHeader('Updated DateTime') ->exampleHeader('Updated DateTime')
->example('12-02-2025 15:51:00') ->example(['01-01-2025 08:00:00', '01-01-2025 19:30:00'])
->label('Updated DateTime') ->label('Updated DateTime')
->rules(['required']), ->rules(['required']),
ImportColumn::make('operator_id') ImportColumn::make('operator_id')
->requiredMapping() ->requiredMapping()
->exampleHeader('Operator ID') ->exampleHeader('Operator ID')
->example('admin') ->example([Filament::auth()->user()->name, Filament::auth()->user()->name])
->label('Operator ID') ->label('Operator ID')
->rules(['required']), ->rules(['required']),
]; ];
@@ -78,31 +94,142 @@ class ProductionQuantityImporter extends Importer
public function resolveRecord(): ?ProductionQuantity public function resolveRecord(): ?ProductionQuantity
{ {
$plant = \App\Models\Plant::where('name', $this->data['plant'])->first(); $warnMsg = [];
$item = \App\Models\Item::where('code', $this->data['item'])->where('plant_id', $plant->id)->first(); $plant = Plant::where('name', $this->data['plant'])->first();
$line = \App\Models\Line::where('name', $this->data['line'])->where('plant_id', $plant->id)->first(); $line = null;
$shift = \App\Models\Shift::where('name', $this->data['shift'])->where('plant_id', $plant->id)->first(); $block = null;
if (!$plant || !$item || !$line || !$shift) { if (!$plant) {
// Optionally handle missing plant/item/line/shift $warnMsg[] = "Plant not found";
return null;
} }
return ProductionQuantity::updateOrCreate([ else {
'serial_number' => $this->data['serial_number'], $line = Line::where('name', $this->data['line'])->where('plant_id', $plant->id)->first();
'plant_id' => $plant->id, //block_reference
], $block = Block::where('name', $this->data['block_reference'])->where('plant_id', $plant->id)->first();
[ }
'shift_id' => $shift->id, if (!$line) {
'line_id' => $line->id, $warnMsg[] = "Line not found";
'item_id' => $item->id, }
'production_order' => $this->data['production_order'] ?? null, $shift = null;
'created_at' => $this->data['created_at'], if (!$block) {
'updated_at' => $this->data['updated_at'] $warnMsg[] = "Block not found";
] }
); else {
// return ProductionQuantity::firstOrNew([ $shift = Shift::where('name', $this->data['shift'])->where('plant_id', $plant->id)->where('block_id', $block->id)->first();
// // Update existing records, matching them by `$this->data['column_name']` }
// 'email' => $this->data['email'], //$shift = Shift::where('id', $this->data['shift'])->where('plant_id', $plant->id)->first();
if (!$shift) {
$warnMsg[] = "Shift not found";
}
$item = null;
if (!$plant) {
$item = Item::where('code', $this->data['item'])->where('plant_id', $plant->id)->first();
}
if (!$item) {
$warnMsg[] = "Item not found";
}
if (Str::length($this->data['serial_number']) < 9 || !ctype_alnum($this->data['serial_number'])) {
$warnMsg[] = "Invalid serial number found";
}
if (Str::length($this->data['production_order']) > 0 && (Str::length($this->data['production_order']) < 7 || !is_numeric($this->data['production_order']))) {
$warnMsg[] = "Invalid production order found";
}
$fromDate = $this->data['created_at'];
$toDate = $this->data['updated_at'];
$formats = ['d-m-Y H:i', 'd-m-Y H:i:s']; //'07-05-2025 08:00' or '07-05-2025 08:00:00'
$fdateTime = null;
$tdateTime = null;
// Try parsing with multiple formats
foreach ($formats as $format) {
try {
$fdateTime = Carbon::createFromFormat($format, $fromDate);
break;
} catch (\Exception $e) {
// Optionally collect warning messages
// $warnMsg[] = "Date format mismatch with format: $format";
}
}
foreach ($formats as $format) {
try {
$tdateTime = Carbon::createFromFormat($format, $toDate);
break;
} catch (\Exception $e) {
// Optionally collect warning messages
// $warnMsg[] = "Date format mismatch with format: $format";
}
}
// $fDateOnly = '';
if (!isset($fdateTime)) {
// throw new \Exception('Invalid date time format');
$warnMsg[] = "Invalid 'Created DateTime' format. Expected DD-MM-YYYY HH:MM:SS";
}
// else {
// $fDateOnly = $fdateTime->toDateString();
// }
if (!isset($tdateTime)) {
$warnMsg[] = "Invalid 'Updated DateTime' format. Expected DD-MM-YYYY HH:MM:SS";
}
if (isset($fdateTime) && isset($tdateTime)) {
if ($fdateTime->greaterThan($tdateTime)) {
$warnMsg[] = "'Created DataTime' is greater than 'Updated DateTime'.";
}
}
// if (!$fromDate) {
// $warnMsg[] = "Invalid 'Created DateTime' format. Expected DD-MM-YYYY HH:MM:SS";
// }
// else if (!$toDate) {
// $warnMsg[] = "Invalid 'Updated DateTime' format. Expected DD-MM-YYYY HH:MM:SS";
// }
$user = User::where('name', $this->data['operator_id'])->first();
if (!$user) {
$warnMsg[] = "Operator ID not found";
}
if (!empty($warnMsg)) {
throw new RowImportFailedException(implode(', ', $warnMsg));
}
else { //if (empty($warnMsg))
$productionQuan = ProductionQuantity::where('plant_id', $plant->id)
->where('serial_number', $this->data['serial_number'])
->latest()
->first();
if ($productionQuan) {
throw new RowImportFailedException("Serial number already exist!");
}
}
ProductionQuantity::updateOrCreate([
'serial_number' => $this->data['serial_number'],
'plant_id' => $plant->id,
'shift_id' => $shift->id,
'line_id' => $line->id,
'item_id' => $item->id,
'production_order' => $this->data['production_order'] ?? null,
'created_at' => $fdateTime->format('Y-m-d H:i:s'),//$this->data['created_at'],
'updated_at' => $tdateTime->format('Y-m-d H:i:s'),//$this->data['updated_at'],
'operator_id' => $this->data['operator_id'],
]);
// ProductionQuantity::updateOrCreate([
// 'serial_number' => $this->data['serial_number'],
// 'plant_id' => $plant->id,
// ],
// [
// 'shift_id' => $shift->id,
// 'line_id' => $line->id,
// 'item_id' => $item->id,
// 'production_order' => $this->data['production_order'] ?? null,
// 'created_at' => $fdateTime->format('Y-m-d H:i:s'),//$this->data['created_at'],
// 'updated_at' => $tdateTime->format('Y-m-d H:i:s'),//$this->data['updated_at'],
// 'operator_id' => $this->data['operator_id'],
// ]); // ]);
return null;
// return new ProductionQuantity(); // return new ProductionQuantity();
} }
@@ -145,21 +272,21 @@ class ProductionQuantityImporter extends Importer
// Relationship resolvers // Relationship resolvers
private function resolveItemId(string $code): int private function resolveItemId(string $code): int
{ {
return \App\Models\Item::where('code', $code)->first()->id; return Item::where('code', $code)->first()->id;
} }
private function resolveLineId(string $name): int private function resolveLineId(string $name): int
{ {
return \App\Models\Line::where('name', $name)->first()->id; return Line::where('name', $name)->first()->id;
} }
private function resolveShiftId(string $name): int private function resolveShiftId(string $name): int
{ {
return \App\Models\Shift::where('name', $name)->first()->id; return Shift::where('name', $name)->first()->id;
} }
private function resolvePlantId(string $name): int private function resolvePlantId(string $name): int
{ {
return \App\Models\Plant::where('name', $name)->first()->id; return Plant::where('name', $name)->first()->id;
} }
} }

View File

@@ -0,0 +1,310 @@
<?php
namespace App\Filament\Imports;
use App\Models\Item;
use App\Models\Plant;
use App\Models\QualityValidation;
use App\Models\StickerMaster;
use App\Models\User;
use Carbon\Carbon;
use Filament\Actions\Imports\Exceptions\RowImportFailedException;
use Filament\Actions\Imports\ImportColumn;
use Filament\Actions\Imports\Importer;
use Filament\Actions\Imports\Models\Import;
use Filament\Facades\Filament;
use Illuminate\Validation\Rule;
use Str;
class QualityValidationImporter extends Importer
{
protected static ?string $model = QualityValidation::class;
public static function getColumns(): array
{
return [
ImportColumn::make('created_at')
->requiredMapping()
->exampleHeader('Created DateTime')
->example('12-02-2025 15:51:00')
->label('Created DateTime')
->rules(['required']),
ImportColumn::make('plant')
->requiredMapping()
->exampleHeader('Plant Name')
->example('Ransar Industries-I')
->label('Plant Name')
->relationship(resolveUsing:'name')
->rules(['required']),
ImportColumn::make('sticker_master_id') // stickerMaster.item
->requiredMapping()
->exampleHeader('Item Code')
->example('123456')
->label('Item Code')
->relationship(
name: 'stickerMaster',
resolveUsing: function ($state) {
$state = trim($state);
$item = Item::where('code', $state)->first();
return $item
? StickerMaster::where('item_id', $item->id)->value('id')
: null;
}
),
ImportColumn::make('production_order')
->requiredMapping()
->exampleHeader('Production Order')
->example('1234567')
->label('Production Order')
->rules(['required']),
ImportColumn::make('serial_number')
->requiredMapping()
->exampleHeader('Serial Number')
->example('1234567890123')
->label('Serial Number'),
ImportColumn::make('serial_number_motor')
->requiredMapping()
->exampleHeader('Serial Number Motor')
->example('1')
->label('Serial Number Motor'),
ImportColumn::make('serial_number_pump')
->requiredMapping()
->exampleHeader('Serial Number Pump')
->example('1')
->label('Serial Number Pump'),
ImportColumn::make('serial_number_pumpset')
->requiredMapping()
->exampleHeader('Serial Number PumpSet')
->example('1')
->label('Serial Number PumpSet'),
ImportColumn::make('pack_slip_motor')
->requiredMapping()
->exampleHeader('Pack Slip Motor')
->example('1')
->label('Pack Slip Motor'),
ImportColumn::make('pack_slip_pump')
->requiredMapping()
->exampleHeader('Pack Slip Pump')
->example('1')
->label('Pack Slip Pump'),
ImportColumn::make('pack_slip_pumpset')
->requiredMapping()
->exampleHeader('Pack Slip PumpSet')
->example('1')
->label('Pack Slip PumpSet'),
ImportColumn::make('name_plate_motor')
->requiredMapping()
->exampleHeader('Name Plate Motor')
->example('1')
->label('Name Plate Motor'),
ImportColumn::make('name_plate_pump')
->requiredMapping()
->exampleHeader('Name Plate Pump')
->example('1')
->label('Name Plate Pump'),
ImportColumn::make('name_plate_pumpset')
->requiredMapping()
->exampleHeader('Name Plate PumpSet')
->example('1')
->label('Name Plate PumpSet'),
ImportColumn::make('tube_sticker_motor')
->requiredMapping()
->exampleHeader('Tube Sticker Motor')
->example('1')
->label('Tube Sticker Motor'),
ImportColumn::make('tube_sticker_pump')
->requiredMapping()
->exampleHeader('Tube Sticker Pump')
->example('1')
->label('Tube Sticker Pump'),
ImportColumn::make('tube_sticker_pumpset')
->requiredMapping()
->exampleHeader('Tube Sticker PumpSet')
->example('1')
->label('Tube Sticker PumpSet'),
ImportColumn::make('warranty_card')
->requiredMapping()
->exampleHeader('Warranty Card')
->example('1')
->label('Warranty Card'),
ImportColumn::make('part_validation1')
->requiredMapping()
->exampleHeader('Part Validation 1')
->example('12345')
->label('Part Validation 1'),
ImportColumn::make('part_validation2')
->requiredMapping()
->exampleHeader('Part Validation 2')
->example('54321')
->label('Part Validation 2'),
ImportColumn::make('part_validation3')
->requiredMapping()
->exampleHeader('Part Validation 3')
->example('12345')
->label('Part Validation 3'),
ImportColumn::make('part_validation4')
->requiredMapping()
->exampleHeader('Part Validation 4')
->example('')
->label('Part Validation 4'),
ImportColumn::make('part_validation5')
->requiredMapping()
->exampleHeader('Part Validation 5')
->example('')
->label('Part Validation 5'),
ImportColumn::make('uom')
->requiredMapping()
->exampleHeader('Unit of Measure')
->example('EA')
->label('Unit of Measure'),
ImportColumn::make('updated_at')
->requiredMapping()
->exampleHeader('Updated DateTime')
->example('12-02-2025 15:51:00')
->label('Updated DateTime')
->rules(['required']),
ImportColumn::make('operator_id')
->requiredMapping()
->exampleHeader('Operator ID')
->example(Filament::auth()->user()->name)
->label('Operator ID')
->rules(['required']),
];
}
public function resolveRecord(): ?QualityValidation
{
$warnMsg = [];
$plant = Plant::where('name', $this->data['plant'])->first();
if (!$plant) {
$warnMsg[] = "Plant not found";
}
$uniqueCode = trim($this->data['sticker_master_id']);// stickerMaster.item
$stickMaster = StickerMaster::select('id')->with('item')
->whereHas('item', function ($query) use ($uniqueCode, $plant) {
$query->where('code', $uniqueCode)->where('plant_id', $plant->id);
})->value('id');
if (!$stickMaster) {
$warnMsg[] = "Sticker item code not found";
}
if (!is_numeric($this->data['production_order']) || Str::length($this->data['production_order']) < 7) {
$warnMsg[] = "Invalid production order found";
}
if (!ctype_alnum($this->data['serial_number']) || Str::length($this->data['serial_number']) < 9) {
$warnMsg[] = "Invalid serial number found";
}
// if (Str::length($this->data['uom']) < 1) {
// $warnMsg[] = "Invalid unit of measure found";
// }
$user = User::where('name', $this->data['operator_id'])->first();
if (!$user) {
$warnMsg[] = "Operator ID not found";
}
$fromDate = $this->data['created_at'];
$toDate = $this->data['updated_at'];
$formats = ['d-m-Y H:i', 'd-m-Y H:i:s']; //'07-05-2025 08:00' or '07-05-2025 08:00:00'
$fdateTime = null;
$tdateTime = null;
// Try parsing with multiple formats
foreach ($formats as $format) {
try {
$fdateTime = Carbon::createFromFormat($format, $fromDate);
break;
} catch (\Exception $e) {
// Optionally collect warning messages
// $warnMsg[] = "Date format mismatch with format: $format";
}
}
foreach ($formats as $format) {
try {
$tdateTime = Carbon::createFromFormat($format, $toDate);
break;
} catch (\Exception $e) {
// Optionally collect warning messages
// $warnMsg[] = "Date format mismatch with format: $format";
}
}
// $fDateOnly = '';
if (!isset($fdateTime)) {
// throw new \Exception('Invalid date time format');
$warnMsg[] = "Invalid 'Created DateTime' format. Expected DD-MM-YYYY HH:MM:SS";
}
// else {
// $fDateOnly = $fdateTime->toDateString();
// }
if (!isset($tdateTime)) {
$warnMsg[] = "Invalid 'Updated DateTime' format. Expected DD-MM-YYYY HH:MM:SS";
}
if (isset($fdateTime) && isset($tdateTime)) {
if ($fdateTime->greaterThan($tdateTime)) {
$warnMsg[] = "'Created DataTime' is greater than 'Updated DateTime'.";
}
}
// if (!$fromDate) {
// $warnMsg[] = "Invalid 'Created DateTime' format. Expected DD-MM-YYYY HH:MM:SS";
// }
// else if (!$toDate) {
// $warnMsg[] = "Invalid 'Updated DateTime' format. Expected DD-MM-YYYY HH:MM:SS";
// }
if (!empty($warnMsg)) {
throw new RowImportFailedException(implode(', ', $warnMsg));
}
return QualityValidation::updateOrCreate([
'plant_id' => $plant->id,
'sticker_master_id' => $stickMaster,//->id
'uom' => $this->data['uom'],
'production_order' => $this->data['production_order'],
'serial_number' => $this->data['serial_number'],
'serial_number_motor' => $this->data['serial_number_motor'],
'serial_number_pump' => $this->data['serial_number_pump'],
'serial_number_pumpset' => $this->data['serial_number_pumpset'],
'pack_slip_motor' => $this->data['pack_slip_motor'],
'pack_slip_pump' => $this->data['pack_slip_pump'],
'pack_slip_pumpset' => $this->data['pack_slip_pumpset'],
'name_plate_motor' => $this->data['name_plate_motor'],
'name_plate_pump' => $this->data['name_plate_pump'],
'name_plate_pumpset' => $this->data['name_plate_pumpset'],
'tube_sticker_motor' => $this->data['tube_sticker_motor'],
'tube_sticker_pump' => $this->data['tube_sticker_pump'],
'tube_sticker_pumpset' => $this->data['tube_sticker_pumpset'],
'warranty_card' => $this->data['warranty_card'],
'part_validation1' => $this->data['part_validation1'],
'part_validation2' => $this->data['part_validation2'],
'part_validation3' => $this->data['part_validation3'],
'part_validation4' => $this->data['part_validation4'],
'part_validation5' => $this->data['part_validation5'],
'created_at' => $fdateTime->format('Y-m-d H:i:s'),//$this->data['created_at'],
'updated_at' => $tdateTime->format('Y-m-d H:i:s'),//$this->data['updated_at'],
'operator_id' => $this->data['operator_id'],
]);
// return QualityValidation::firstOrNew([
// // Update existing records, matching them by `$this->data['column_name']`
// 'email' => $this->data['email'],
// ]);
// return new QualityValidation();
}
public static function getCompletedNotificationBody(Import $import): string
{
$body = 'Your quality validation import has completed and ' . number_format($import->successful_rows) . ' ' . str('row')->plural($import->successful_rows) . ' imported.';
if ($failedRowsCount = $import->getFailedRowsCount()) {
$body .= ' ' . number_format($failedRowsCount) . ' ' . str('row')->plural($failedRowsCount) . ' failed to import.';
}
return $body;
}
}

View File

@@ -2,10 +2,14 @@
namespace App\Filament\Imports; namespace App\Filament\Imports;
use App\Models\Block;
use App\Models\Plant;
use App\Models\Shift; use App\Models\Shift;
use Filament\Actions\Imports\Exceptions\RowImportFailedException;
use Filament\Actions\Imports\ImportColumn; use Filament\Actions\Imports\ImportColumn;
use Filament\Actions\Imports\Importer; use Filament\Actions\Imports\Importer;
use Filament\Actions\Imports\Models\Import; use Filament\Actions\Imports\Models\Import;
use Str;
class ShiftImporter extends Importer class ShiftImporter extends Importer
{ {
@@ -64,12 +68,30 @@ class ShiftImporter extends Importer
public function resolveRecord(): ?Shift public function resolveRecord(): ?Shift
{ {
$plant = \App\Models\Plant::where('name', $this->data['plant'])->first(); $warnMsg = [];
$block = \App\Models\Block::where('name', $this->data['block'])->where('plant_id', $plant->id)->first(); $plant = Plant::where('name', $this->data['plant'])->first();
if (!$plant) {
$warnMsg[] = "Plant not found";
}
$block = Block::where('name', $this->data['block'])->where('plant_id', $plant->id)->first();
if (!$block) {
$warnMsg[] = "Block not found";
}
if (Str::length($this->data['duration']) < 0 || !is_numeric($this->data['duration'])) {
$warnMsg[] = "Invalid duration found";
}
if (Str::length($this->data['start_time']) < 0) {
$warnMsg[] = "Invalid start time found";
}
if (Str::length($this->data['end_time']) < 0) {
$warnMsg[] = "Invalid end time found";
}
if (Str::length($this->data['status']) < 0 || $this->data['status'] != 'Active') {
$warnMsg[] = "Invalid shift status found";
}
if (!$plant || !$block) { if (!empty($warnMsg)) {
// Optionally handle missing plant/block throw new RowImportFailedException(implode(', ', $warnMsg));
return null;
} }
$shift = Shift::where('name', $this->data['name']) $shift = Shift::where('name', $this->data['name'])

View File

@@ -9,8 +9,9 @@ use Filament\Pages\Dashboard\Concerns\HasFiltersForm;
use Filament\Pages\Page; use Filament\Pages\Page;
use Filament\Tables\Concerns\HasFilters; use Filament\Tables\Concerns\HasFilters;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use Filament\Pages\Dashboard;
class HourlyProduction extends Page class HourlyProduction extends page
{ {
protected static ?string $navigationIcon = 'heroicon-o-document-text'; protected static ?string $navigationIcon = 'heroicon-o-document-text';
@@ -22,11 +23,15 @@ class HourlyProduction extends Page
public function mount(): void public function mount(): void
{ {
session()->forget(['selected_plant', 'selected_line']); 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);
$this->filtersForm->fill([ $this->filtersForm->fill([
//'plant' => Plant::first()?->id // Default to first plant //'plant' => Plant::first()?->id // Default to first plant
'plant' => null, 'plant' => $plantId,
'line' => null, 'line' => $lineId,
]); ]);
} }
@@ -43,7 +48,7 @@ class HourlyProduction extends Page
->afterStateUpdated(function ($state) { ->afterStateUpdated(function ($state) {
session(['selected_plant' => $state]); session(['selected_plant' => $state]);
// Clear production quantity Dashboard session keys to avoid conflict // Clear production quantity Dashboard session keys to avoid conflict
session()->forget(['select_plant', 'select_line']); //session()->forget(['select_plant', 'select_line']);
$this->triggerChartUpdate(); $this->triggerChartUpdate();
}), }),
@@ -79,4 +84,11 @@ class HourlyProduction extends Page
{ {
return Auth::check() && Auth::user()->can('view production dashboard'); return Auth::check() && Auth::user()->can('view production dashboard');
} }
public function getWidgets(): array
{
return [
\App\Filament\Widgets\ItemOverview::class,
];
}
} }

View File

@@ -37,7 +37,7 @@ class ProductionQuantityPage extends Page implements HasForms
public $qrData, $pId, $bId, $sId, $lId, $iId, $succId, $sNoId, $succStat, $recQr, $prodOrder; public $qrData, $pId, $bId, $sId, $lId, $iId, $succId, $sNoId, $succStat, $recQr, $prodOrder;
public $recent_qr, $clear_qr; // public $recent_qr, $clear_qr;
use HasFiltersForm; use HasFiltersForm;
@@ -45,6 +45,7 @@ class ProductionQuantityPage extends Page implements HasForms
public function mount(): void public function mount(): void
{ {
session()->forget(['select_plant', 'select_line']); session()->forget(['select_plant', 'select_line']);
session()->forget(['selected_plant', 'selected_line']);
$this->filtersForm->fill([ $this->filtersForm->fill([
'plant' => null, 'plant' => null,
'line' => null, 'line' => null,
@@ -71,7 +72,7 @@ class ProductionQuantityPage extends Page implements HasForms
padding: 0 !important; padding: 0 !important;
max-width: 100% !important; max-width: 100% !important;
/* overflow-y: auto; Allow vertical scrolling */ /* overflow-y: auto; Allow vertical scrolling */
height: 100vh; /* Ensure full height of the viewport */ height: 100vh;
} }
/* Expand page area fully */ /* Expand page area fully */
@@ -80,6 +81,22 @@ class ProductionQuantityPage extends Page implements HasForms
max-width: 100% !important; max-width: 100% !important;
} }
/* Expand main container to full screen but add margin */
/* .fi-main {
margin: 0.5rem -0.5rem !important; Top/Bottom: 0.5rem, Left/Right: 0.2rem
padding: 0rem !important;
max-width: calc(100% - 0.1rem) !important; /* Matches horizontal margin
height: calc(100vh - 1rem); Matches vertical margin
box-sizing: border-box;
}*/
/* Expand page area fully within the main container */
/* .fi-main > .fi-page {
padding: 0.2rem !important;
max-width: calc(100% - 0.1rem) !important;
box-sizing: border-box;
} */
/* Allow scroll on body again */ /* Allow scroll on body again */
body { body {
overflow: auto; overflow: auto;
@@ -125,8 +142,6 @@ class ProductionQuantityPage extends Page implements HasForms
session(['select_plant' => $state]); session(['select_plant' => $state]);
session()->forget(['selected_plant', 'selected_line']);
if (!$plantId) if (!$plantId)
{ {
$set('pqPlantError', 'Please select a plant first.'); $set('pqPlantError', 'Please select a plant first.');
@@ -339,11 +354,14 @@ class ProductionQuantityPage extends Page implements HasForms
->required(), ->required(),
Hidden::make('success_msg') Hidden::make('success_msg')
->required(), ->required(),
Hidden::make('item_id')
->required(),
Hidden::make('sap_msg_status'),
Hidden::make('sap_msg_description'),
TextInput::make('recent_qr') TextInput::make('recent_qr')
->label('Last scanned QR') ->label('Last scanned QR')
->reactive() ->reactive()
->live()
->columnSpan(1) ->columnSpan(1)
// ->default(function () { // ->default(function () {
// // Get the latest 'item_id' foreign key from 'production_quantities' table // // Get the latest 'item_id' foreign key from 'production_quantities' table
@@ -358,12 +376,14 @@ class ProductionQuantityPage extends Page implements HasForms
// // Get the latest 'serial_number' from 'production_quantities' table // // Get the latest 'serial_number' from 'production_quantities' table
// $serialNumber = $latestProductionQuantity->serial_number; // $serialNumber = $latestProductionQuantity->serial_number;
// dd($itemCode, $serialNumber);
// // Combine 'code' and 'serial_number' into the desired format // // Combine 'code' and 'serial_number' into the desired format
// return $itemCode && $serialNumber ? "{$itemCode} | {$serialNumber}" : null; // // return $itemCode && $serialNumber ? "{$itemCode} | {$serialNumber}" : null;
// $this->recQr = $itemCode && $serialNumber ? "{$itemCode} | {$serialNumber}" : null;
// }) // })
// ->default(fn () => $this->recent_qr) ->default(fn () => $this->recQr)
->readOnly(true), ->readOnly(true),
TextInput::make('id') TextInput::make('id')
@@ -383,7 +403,7 @@ class ProductionQuantityPage extends Page implements HasForms
//dd($formQRData); //dd($formQRData);
//$formValues = []; //$formValues = [];
// This will get all form data from the request // This will get all form data from the request
$this->clear_qr = null; //$this->clear_qr = null;
$this->qrData = null; $this->qrData = null;
$this->iId = null; $this->iId = null;
$this->succId = null; $this->succId = null;
@@ -428,6 +448,15 @@ class ProductionQuantityPage extends Page implements HasForms
// return; // return;
// } // }
$latestProductionQuantity = ProductionQuantity::latest()->first();
if ($latestProductionQuantity) {
$itemCode = optional(Item::find($latestProductionQuantity->item_id))->code;
$serialNumber = $latestProductionQuantity->serial_number;
$this->recQr = $itemCode && $serialNumber ? "{$itemCode} | {$serialNumber}" : null;
}
if (empty($formQRData)) { if (empty($formQRData)) {
$this->form->fill([ $this->form->fill([
'plant_id'=> $this->pId, 'plant_id'=> $this->pId,
@@ -438,9 +467,12 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
Notification::make() Notification::make()
->title('Invalid QR') ->title('Invalid QR')
->body("Scan the valid QR code.<br>(Ex: Item_Code|Serial_Number )") ->body("Scan the valid QR code.<br>(Ex: Item_Code|Serial_Number )")
@@ -460,6 +492,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> null, 'production_order'=> null,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -480,6 +514,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> null, 'production_order'=> null,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -500,6 +536,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> null, 'production_order'=> null,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -520,6 +558,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> null, 'production_order'=> null,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -540,6 +580,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> null, 'production_order'=> null,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -561,6 +603,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> null, 'production_order'=> null,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -583,6 +627,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> null, 'production_order'=> null,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -637,6 +683,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -659,6 +707,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -704,6 +754,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -741,6 +793,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -766,6 +820,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -814,6 +870,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -858,6 +916,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -883,6 +943,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -909,6 +971,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -925,6 +989,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -952,6 +1018,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -973,6 +1041,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -994,6 +1064,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -1016,6 +1088,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -1039,6 +1113,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -1061,6 +1137,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -1084,6 +1162,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -1113,6 +1193,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> 'Y', 'success_msg'=> 'Y',
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -1130,6 +1212,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -1152,6 +1236,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -1174,6 +1260,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -1219,6 +1307,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $itemCode.' | '.$this->sNoId, 'recent_qr' => $itemCode.' | '.$this->sNoId,
]); ]);

View File

@@ -111,6 +111,7 @@ class ItemResource extends Resource
->label('Hourly Quantity') ->label('Hourly Quantity')
->placeholder('Scan the valid quantity') ->placeholder('Scan the valid quantity')
->integer() ->integer()
->default(1)
->minValue(1) ->minValue(1)
->reactive() ->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) { ->afterStateUpdated(function ($state, callable $set, callable $get) {
@@ -135,15 +136,22 @@ class ItemResource extends Resource
]) ])
->hint(fn ($get) => $get('iHourQuanError') ? $get('iHourQuanError') : null) ->hint(fn ($get) => $get('iHourQuanError') ? $get('iHourQuanError') : null)
->hintColor('danger'), ->hintColor('danger'),
Forms\Components\Textarea::make('description') Forms\Components\TextInput::make('uom')
->required() ->required()
->placeholder('Scan the valid description'), ->label('Unit of Measure')
->placeholder('Scan the valid uom'),
Forms\Components\TextInput::make('description')
->placeholder('Scan the valid description')
->required()
->minLength(5)
->columnSpan(['default' => 1, 'sm' => 2]),
// ->columnSpanFull(), // ->columnSpanFull(),
Forms\Components\TextInput::make('id') Forms\Components\TextInput::make('id')
->hidden() ->hidden()
->readOnly(), ->readOnly(),
]) ])
->columns(2), ->columns(3),
]); ]);
} }
@@ -162,8 +170,14 @@ class ItemResource extends Resource
->sortable() ->sortable()
->searchable(), ->searchable(),
Tables\Columns\TextColumn::make('hourly_quantity') Tables\Columns\TextColumn::make('hourly_quantity')
->label('Hourly Quantity')
->alignCenter()
->numeric() ->numeric()
->sortable(), ->sortable(),
Tables\Columns\TextColumn::make('uom')
->label('Unit of Measure')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('plant.name') Tables\Columns\TextColumn::make('plant.name')
->sortable() ->sortable()
->searchable(), ->searchable(),

View File

@@ -9,6 +9,7 @@ use App\Filament\Resources\ProductionLineStopResource\Pages;
use App\Filament\Resources\ProductionLineStopResource\RelationManagers; use App\Filament\Resources\ProductionLineStopResource\RelationManagers;
use App\Models\Block; use App\Models\Block;
use App\Models\Line; use App\Models\Line;
use App\Models\LineStop;
use App\Models\Plant; use App\Models\Plant;
use App\Models\ProductionLineStop; use App\Models\ProductionLineStop;
use App\Models\Shift; use App\Models\Shift;
@@ -368,10 +369,12 @@ class ProductionLineStopResource extends Resource
->sortable(), ->sortable(),
Tables\Columns\TextColumn::make('stop_hour') Tables\Columns\TextColumn::make('stop_hour')
->label('Stop Hour') ->label('Stop Hour')
->alignCenter()
->numeric() ->numeric()
->sortable(), ->sortable(),
Tables\Columns\TextColumn::make('stop_min') Tables\Columns\TextColumn::make('stop_min')
->label('Stop Minute') ->label('Stop Minute')
->alignCenter()
->numeric() ->numeric()
->sortable(), ->sortable(),
Tables\Columns\TextColumn::make('line.name') Tables\Columns\TextColumn::make('line.name')
@@ -404,118 +407,132 @@ class ProductionLineStopResource extends Resource
]) ])
->filters([ ->filters([
Tables\Filters\TrashedFilter::make(),
Filter::make('advanced_filters')
->label('Advanced Filters')
->form([
Tables\Filters\TrashedFilter::make(), //plant
Filter::make('advanced_filters') Select::make('Plant')
->label('Advanced Filters') ->label('Select Plant')
->form([ ->nullable()
->options(function () {
return Plant::pluck('name', 'id'); // Assuming 'name' is the column you want to display
})
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('Line', null);
$set('Block', null);
$set('Shift', null);
$set('line_stop_id', null);
}),
Select::make('Plant') //line
->label('Select Plant') Select::make('Line')
->options(function () { ->label('Select line')
return Plant::pluck('name', 'id'); // Assuming 'name' is the column you want to display ->nullable()
}), ->options(function (callable $get) {
$plantId = $get('Plant');
//block if (!$plantId ) {
Select::make('Block') return [];
->label('Select Block') }
->options(fn (callable $get) => return Line::where('plant_id', $plantId)
$get('Plant') ->pluck('name', 'id');
? Block::where('plant_id', $get('Plant'))->pluck('name', 'id') })
: [] ->reactive(),
)
->reactive(),
//shift //block
Select::make('Shift') Select::make('Block')
->label('Select Shift') ->label('Select Block')
->options(function (callable $get) { ->nullable()
$plantId = $get('Plant'); ->options(function (callable $get) {
$blockId = $get('Block'); $plantId = $get('Plant');
if (!$plantId || !$blockId) { if (!$plantId ) {
return []; // Return empty if plant or block is not selected return [];
} }
return Block::where('plant_id', $get('Plant'))->pluck('name', 'id');
})
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('Shift', null);
}),
return Shift::where('plant_id', $plantId) //shift
Select::make('Shift')
->label('Select Shift')
->nullable()
->options(function (callable $get) {
$plantId = $get('Plant');
$blockId = $get('Block');
if (!$plantId || !$blockId) {
return []; // Return empty if plant or block is not selected
}
return Shift::where('plant_id', $plantId)
->where('block_id', $blockId) ->where('block_id', $blockId)
->pluck('name', 'id'); ->pluck('name', 'id');
}) })
->reactive(), ->reactive(),
//line Select::make('line_stop_id') //linestop_id
Select::make('line') ->label('Search by Line Stop Code')
->label('Select line') ->nullable()
->options(function (callable $get) { // ->options(fn () => LineStop::orderBy('code')->whereHas('productionLineStops')->pluck('code', 'id'))
$plantId = $get('Plant'); ->options(function (callable $get) {
$pId = $get('Plant');
return LineStop::orderBy('code')->whereHas('productionLineStops', function ($query) use ($pId) {
if ($pId) {
$query->where('plant_id', $pId);
}
})->pluck('code', 'id');
})
->searchable()
->reactive(),
if (!$plantId ) { DateTimePicker::make(name: 'created_from')
return []; ->label('Created From')
} ->placeholder(placeholder: 'Select From DateTime')
return Line::where('plant_id', $plantId) ->reactive()
->pluck('name', 'id'); ->native(false),
})
->reactive(),
TextInput::make('Line Stop Code'), DateTimePicker::make('created_to')
->label('Created To')
->placeholder(placeholder: 'Select To DateTime')
// Select::make('reason') ->reactive()
// ->label('Filter by Stop Reason') ->native(false),
// ->options(function () {
// return \App\Models\Item::whereHas('stickerMasters', function ($query) {
// $query->whereHas('qualityValidations');
// })->pluck('code', 'id');
// })
// ->searchable(),
DateTimePicker::make(name: 'created_from')
->label('Created From')
->reactive()
->native(false),
DateTimePicker::make('created_to')
->label('Created To')
->reactive()
->native(false),
]) ])
->query(function ($query, array $data) { ->query(function ($query, array $data) {
if (empty($data['Plant']) && empty($data['Shift']) && empty($data['Line']) && empty($data['created_from']) && empty($data['created_to']) && empty($data['line_stop_id'])) {
return $query->whereRaw('1 = 0');
}
if ($plant = $data['Plant'] ?? null) { if ($plant = $data['Plant'] ?? null) {
$query->where('plant_id', $plant); $query->where('plant_id', $plant);
} }
// Filter by Shift
if ($shift = $data['Shift'] ?? null) { if ($shift = $data['Shift'] ?? null) {
// Get shift data here, if needed, but no block_id filtering yet
$query->where('shift_id', $shift); $query->where('shift_id', $shift);
} }
if ($block = $data['Block'] ?? null) { if ($line = $data['Line'] ?? null) {
// Use whereHas to filter by block_id in the Shift table
$query->whereHas('shift', function ($query) use ($block) {
$query->where('block_id', $block);
});
}
if ($line = $data['line'] ?? null) {
$query->where('line_id', $line); $query->where('line_id', $line);
} }
if ($code = $data['Line Stop Code'] ?? null) { if ($code = $data['line_stop_id'] ?? null) {
// Find the linestop_id by code entered // Find the linestop_id by code entered
$lineStop = \App\Models\LineStop::where('code', 'like', "%{$code}%")->first(); // $lineStop = \App\Models\LineStop::where('code', 'like', "%{$code}%")->first();
// If we find a matching LineStop, use its id to filter production_line_stops // // If we find a matching LineStop, use its id to filter production_line_stops
if ($lineStop) { // if ($lineStop) {
$query->where('linestop_id', $lineStop->id); // $query->where('linestop_id', $lineStop->id);
} else { // } else {
// If no match found, you can either handle it as an error or return no results // // If no match found, you can either handle it as an error or return no results
$query->where('linestop_id', null); // This will return no results if no match // $query->where('linestop_id', null); // This will return no results if no match
} // }
} $query->where('linestop_id', $code);
if ($reason = $data['reason'] ?? null) {
$query->where('reason_id', $reason);
} }
if ($from = $data['created_from'] ?? null) { if ($from = $data['created_from'] ?? null) {
@@ -525,12 +542,39 @@ class ProductionLineStopResource extends Resource
if ($to = $data['created_to'] ?? null) { if ($to = $data['created_to'] ?? null) {
$query->where('created_at', '<=', $to); $query->where('created_at', '<=', $to);
} }
// return $query;
return $query;
}) })
->indicateUsing(function (array $data) {
$indicators = [];
if (!empty($data['Plant'])) {
$indicators[] = 'Plant: ' . Plant::where('id', $data['Plant'])->value('name');
}
if (!empty($data['Shift'])) {
$indicators[] = 'Shift: ' . Shift::where('id', $data['Shift'])->value('name');
}
if (!empty($data['Line'])) {
$indicators[] = 'Line: ' . Line::where('id', $data['Line'])->value('name');
}
if (!empty($data['created_from'])) {
$indicators[] = 'From: ' . $data['created_from'];
}
if (!empty($data['created_to'])) {
$indicators[] = 'To: ' . $data['created_to'];
}
if (!empty($data['line_stop_id'])) {
$lineStopCod = LineStop::find($data['line_stop_id'])->code ?? 'Unknown';
$indicators[] = 'Line Stop Code: ' . $lineStopCod;
}
return $indicators;
})
]) ])
->filtersFormMaxHeight('280px') ->filtersFormMaxHeight('280px')
->actions([ ->actions([
Tables\Actions\ViewAction::make(), Tables\Actions\ViewAction::make(),
@@ -546,10 +590,15 @@ class ProductionLineStopResource extends Resource
]) ])
->headerActions([ ->headerActions([
ImportAction::make() ImportAction::make()
->importer(ProductionLineStopImporter::class) ->importer(ProductionLineStopImporter::class)
->maxRows(100000), ->visible(function() {
ExportAction::make() return Filament::auth()->user()->can('view import production line stop');
->exporter(ProductionLineStopExporter::class), }),
ExportAction::make()
->exporter(ProductionLineStopExporter::class)
->visible(function() {
return Filament::auth()->user()->can('view export production line stop');
}),
]); ]);
} }

View File

@@ -7,11 +7,15 @@ use App\Filament\Exports\ProductionPlanExporter;
use App\Filament\Imports\ProductionPlanImporter; use App\Filament\Imports\ProductionPlanImporter;
use App\Filament\Resources\ProductionPlanResource\Pages; use App\Filament\Resources\ProductionPlanResource\Pages;
use App\Filament\Resources\ProductionPlanResource\RelationManagers; use App\Filament\Resources\ProductionPlanResource\RelationManagers;
use App\Models\Block;
use App\Models\Line;
use App\Models\Plant;
use App\Models\ProductionPlan; use App\Models\ProductionPlan;
use App\Models\Shift; use App\Models\Shift;
use Carbon\Carbon; use Carbon\Carbon;
use Filament\Facades\Filament; use Filament\Facades\Filament;
use Filament\Forms; use Filament\Forms;
use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Form; use Filament\Forms\Form;
use Filament\Forms\Get; use Filament\Forms\Get;
use Filament\Resources\Resource; use Filament\Resources\Resource;
@@ -21,7 +25,9 @@ use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope; use Illuminate\Database\Eloquent\SoftDeletingScope;
use Filament\Forms\Components\Section; use Filament\Forms\Components\Section;
use Filament\Forms\Components\Select;
use Filament\Tables\Actions\ExportAction; use Filament\Tables\Actions\ExportAction;
use Filament\Tables\Filters\Filter;
use Illuminate\Support\Facades\Request; use Illuminate\Support\Facades\Request;
class ProductionPlanResource extends Resource class ProductionPlanResource extends Resource
@@ -78,7 +84,7 @@ class ProductionPlanResource extends Resource
return []; return [];
} }
return \App\Models\Block::where('plant_id', $get('plant_id')) return Block::where('plant_id', $get('plant_id'))
->pluck('name', 'id') ->pluck('name', 'id')
->toArray(); ->toArray();
}) })
@@ -466,7 +472,7 @@ class ProductionPlanResource extends Resource
->required() ->required()
->integer() ->integer()
->label('Production Quantity') ->label('Production Quantity')
->readOnly() ->readOnly(fn (callable $get) => !$get('id'))
->default(0), ->default(0),
Forms\Components\TextInput::make('id') Forms\Components\TextInput::make('id')
->hidden() ->hidden()
@@ -520,14 +526,11 @@ class ProductionPlanResource extends Resource
->numeric() ->numeric()
->sortable(), ->sortable(),
Tables\Columns\TextColumn::make('line.name') Tables\Columns\TextColumn::make('line.name')
->sortable() ->sortable(),// ->searchable(),
->searchable(),
Tables\Columns\TextColumn::make('shift.name') Tables\Columns\TextColumn::make('shift.name')
->sortable() ->sortable(),// ->searchable(),
->searchable(),
Tables\Columns\TextColumn::make('plant.name') Tables\Columns\TextColumn::make('plant.name')
->sortable() ->sortable(),// ->searchable(),
->searchable(),
Tables\Columns\TextColumn::make('operator_id') Tables\Columns\TextColumn::make('operator_id')
->label('Operator ID') ->label('Operator ID')
->sortable(), ->sortable(),
@@ -546,7 +549,138 @@ class ProductionPlanResource extends Resource
]) ])
->filters([ ->filters([
Tables\Filters\TrashedFilter::make(), Tables\Filters\TrashedFilter::make(),
Filter::make('advanced_filters')
->label('Advanced Filters')
->form([
//plant
Select::make('Plant')
->label('Select Plant')
->nullable()
->options(function () {
return Plant::pluck('name', 'id'); // Assuming 'name' is the column you want to display
})
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('Line', null);
$set('Block', null);
$set('Shift', null);
}),
//line
Select::make('Line')
->label('Select line')
->nullable()
->options(function (callable $get) {
$plantId = $get('Plant');
if (!$plantId ) {
return [];
}
return Line::where('plant_id', $plantId)
->pluck('name', 'id');
})
->reactive(),
//block
Select::make('Block')
->label('Select Block')
->nullable()
->options(function (callable $get) {
$plantId = $get('Plant');
if (!$plantId ) {
return [];
}
return Block::where('plant_id', $get('Plant'))->pluck('name', 'id');
})
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('Shift', null);
}),
//shift
Select::make('Shift')
->label('Select Shift')
->nullable()
->options(function (callable $get) {
$plantId = $get('Plant');
$blockId = $get('Block');
if (!$plantId || !$blockId) {
return []; // Return empty if plant or block is not selected
}
return Shift::where('plant_id', $plantId)
->where('block_id', $blockId)
->pluck('name', 'id');
})
->reactive(),
DateTimePicker::make(name: 'created_from')
->label('Created From')
->placeholder(placeholder: 'Select From DateTime')
->reactive()
->native(false),
DateTimePicker::make('created_to')
->label('Created To')
->placeholder(placeholder: 'Select To DateTime')
->reactive()
->native(false),
])
->query(function ($query, array $data) {
if (empty($data['Plant']) && empty($data['Shift']) && empty($data['Line']) && empty($data['created_from']) && empty($data['created_to'])) {
return $query->whereRaw('1 = 0');
}
if ($plant = $data['Plant'] ?? null) {
$query->where('plant_id', $plant);
}
if ($shift = $data['Shift'] ?? null) {
$query->where('shift_id', $shift);
}
if ($line = $data['Line'] ?? null) {
$query->where('line_id', $line);
}
if ($from = $data['created_from'] ?? null) {
$query->where('created_at', '>=', $from);
}
if ($to = $data['created_to'] ?? null) {
$query->where('created_at', '<=', $to);
}
return $query;
})
->indicateUsing(function (array $data) {
$indicators = [];
if (!empty($data['Plant'])) {
$indicators[] = 'Plant: ' . Plant::where('id', $data['Plant'])->value('name');
}
if (!empty($data['Shift'])) {
$indicators[] = 'Shift: ' . Shift::where('id', $data['Shift'])->value('name');
}
if (!empty($data['Line'])) {
$indicators[] = 'Line: ' . Line::where('id', $data['Line'])->value('name');
}
if (!empty($data['created_from'])) {
$indicators[] = 'From: ' . $data['created_from'];
}
if (!empty($data['created_to'])) {
$indicators[] = 'To: ' . $data['created_to'];
}
return $indicators;
})
]) ])
->filtersFormMaxHeight('280px')
->actions([ ->actions([
Tables\Actions\ViewAction::make(), Tables\Actions\ViewAction::make(),
Tables\Actions\EditAction::make(), Tables\Actions\EditAction::make(),
@@ -561,10 +695,15 @@ class ProductionPlanResource extends Resource
]) ])
->headerActions([ ->headerActions([
ImportAction::make() ImportAction::make()
->importer(ProductionPlanImporter::class) ->importer(ProductionPlanImporter::class)
->maxRows(100000), ->visible(function() {
ExportAction::make() return Filament::auth()->user()->can('view import production plan');
->exporter(ProductionPlanExporter::class), }),
ExportAction::make()
->exporter(ProductionPlanExporter::class)
->visible(function() {
return Filament::auth()->user()->can('view export production plan');
}),
]); ]);
} }

View File

@@ -8,12 +8,16 @@ use App\Filament\Imports\ProductionQuantityImporter;
use App\Filament\Resources\ProductionQuantityResource\Pages; use App\Filament\Resources\ProductionQuantityResource\Pages;
use App\Filament\Resources\ProductionQuantityResource\RelationManagers; use App\Filament\Resources\ProductionQuantityResource\RelationManagers;
use App\Forms\Components\PlantSelect; use App\Forms\Components\PlantSelect;
use App\Models\Block;
use App\Models\Item; use App\Models\Item;
use App\Models\Line;
use App\Models\Plant;
use App\Models\ProductionQuantity; use App\Models\ProductionQuantity;
use App\Models\Shift; use App\Models\Shift;
use Carbon\Carbon; use Carbon\Carbon;
use Filament\Facades\Filament; use Filament\Facades\Filament;
use Filament\Forms; use Filament\Forms;
use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\Hidden; use Filament\Forms\Components\Hidden;
use Filament\Forms\Form; use Filament\Forms\Form;
use Filament\Forms\Get; use Filament\Forms\Get;
@@ -25,13 +29,14 @@ use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope; use Illuminate\Database\Eloquent\SoftDeletingScope;
use Filament\Forms\Components\Section; use Filament\Forms\Components\Section;
use Filament\Forms\Components\Select; use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Concerns\InteractsWithForms; use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Notifications\Notification; use Filament\Notifications\Notification;
use Filament\Tables\Actions\ExportAction; use Filament\Tables\Actions\ExportAction;
use Livewire\Livewire; use Livewire\Livewire;
// use Filament\Forms\Components\View; // use Filament\Forms\Components\View;
use Filament\Tables\Actions\FilamentExportBulkAction; use Filament\Tables\Actions\FilamentExportBulkAction;
use Filament\Tables\Filters\Filter;
class ProductionQuantityResource extends Resource class ProductionQuantityResource extends Resource
{ {
@@ -129,7 +134,7 @@ class ProductionQuantityResource extends Resource
return []; return [];
} }
return \App\Models\Block::where('plant_id', $get('plant_id')) return Block::where('plant_id', $get('plant_id'))
->pluck('name', 'id') ->pluck('name', 'id')
->toArray(); ->toArray();
}) })
@@ -235,7 +240,7 @@ class ProductionQuantityResource extends Resource
return []; return [];
} }
return \App\Models\Line::where('plant_id', $get('plant_id')) return Line::where('plant_id', $get('plant_id'))
->pluck('name', 'id') ->pluck('name', 'id')
->toArray(); ->toArray();
}) })
@@ -895,8 +900,10 @@ class ProductionQuantityResource extends Resource
->required(), ->required(),
Forms\Components\Hidden::make('success_msg') Forms\Components\Hidden::make('success_msg')
->required(), ->required(),
Forms\Components\Hidden::make('item_code') Forms\Components\Hidden::make('item_id')
->required(), ->required(),
Forms\Components\Hidden::make('sap_msg_status'),
Forms\Components\Hidden::make('sap_msg_description'),
//->unique(ignoreRecord: true), //->unique(ignoreRecord: true),
// ->autocapitalize('characters'), // ->autocapitalize('characters'),
// ->columnSpanFull(), // ->columnSpanFull(),
@@ -940,39 +947,265 @@ class ProductionQuantityResource extends Resource
->numeric() ->numeric()
->sortable(), ->sortable(),
Tables\Columns\TextColumn::make('production_order') Tables\Columns\TextColumn::make('production_order')
->sortable() ->label('Production Order')
->searchable(), ->sortable(),// ->searchable(),
Tables\Columns\TextColumn::make('item.code')
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('serial_number') Tables\Columns\TextColumn::make('serial_number')
->sortable() ->label('Serial Number')
->searchable(), ->sortable(),// ->searchable(),
Tables\Columns\TextColumn::make('item.code')
->label('Item Code')
->sortable(),// ->searchable(),
Tables\Columns\TextColumn::make('item.uom')
->alignCenter()
->label('Unit of Measure'),
Tables\Columns\TextColumn::make('line.name') Tables\Columns\TextColumn::make('line.name')
->label('Line')
->sortable(), ->sortable(),
Tables\Columns\TextColumn::make('shift.name') Tables\Columns\TextColumn::make('shift.name')
->label('Shift')
->sortable(), ->sortable(),
Tables\Columns\TextColumn::make('plant.name') Tables\Columns\TextColumn::make('plant.name')
->label('Plant')
->sortable(), ->sortable(),
Tables\Columns\TextColumn::make('operator_id') Tables\Columns\TextColumn::make('sap_msg_status')
->label('Operator ID') ->label('SAP Message Status')
->sortable(),
Tables\Columns\TextColumn::make('sap_msg_description')
->label('SAP Message Description')
->sortable(), ->sortable(),
Tables\Columns\TextColumn::make('created_at') Tables\Columns\TextColumn::make('created_at')
->label('Created At')
->dateTime() ->dateTime()
->sortable() ->sortable()
->toggleable(isToggledHiddenByDefault: true), ->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('updated_at') Tables\Columns\TextColumn::make('updated_at')
->label('Updated At')
->dateTime() ->dateTime()
->sortable() ->sortable()
->toggleable(isToggledHiddenByDefault: true), ->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('deleted_at') Tables\Columns\TextColumn::make('deleted_at')
->label('Deleted At')
->dateTime() ->dateTime()
->sortable() ->sortable()
->toggleable(isToggledHiddenByDefault: true), ->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('operator_id')
->label('Operator ID')
->sortable(),
]) ])
->filters([ ->filters([
Tables\Filters\TrashedFilter::make(), Tables\Filters\TrashedFilter::make(),
Filter::make('advanced_filters')
->label('Advanced Filters')
->form([
//plant
Select::make('Plant')
->label('Select Plant')
->nullable()
->options(function () {
return Plant::pluck('name', 'id'); // Assuming 'name' is the column you want to display
})
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('Line', null);
$set('Block', null);
$set('Shift', null);
$set('Item', null);
$set('sap_msg_status', null);
}),
//line
Select::make('Line')
->label('Select line')
->nullable()
->options(function (callable $get) {
$plantId = $get('Plant');
if (!$plantId ) {
return [];
}
return Line::where('plant_id', $plantId)
->pluck('name', 'id');
})
->reactive(),
//block
Select::make('Block')
->label('Select Block')
->nullable()
->options(function (callable $get) {
$plantId = $get('Plant');
if (!$plantId ) {
return [];
}
return Block::where('plant_id', $get('Plant'))->pluck('name', 'id');
})
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('Shift', null);
}),
//shift
Select::make('Shift')
->label('Select Shift')
->nullable()
->options(function (callable $get) {
$plantId = $get('Plant');
$blockId = $get('Block');
if (!$plantId || !$blockId) {
return []; // Return empty if plant or block is not selected
}
return Shift::where('plant_id', $plantId)
->where('block_id', $blockId)
->pluck('name', 'id');
})
->reactive(),
TextInput::make('production_order')
->label('Production Order')
->placeholder('Enter Production Order'),
TextInput::make('serial_number')
->label('Serial Number')
->placeholder(placeholder: 'Enter Serial Number'),
Select::make('Item')
->label('Search by Item Code')
->nullable()
->options(function (callable $get) {
$plantId = $get('Plant');
if (!$plantId ) {
return Item::distinct()->whereHas('productionQuantities')->pluck('code', 'id');
}
else {
return Item::where('plant_id', $plantId)->whereHas('productionQuantities')->distinct()->pluck('code', 'id');
}
// return Item::whereHas('stickerMasters', function ($query) use ($pId) {
// if ($pId) {
// $query->where('plant_id', $pId);
// }
// $query->whereHas('invoiceValidations');
// })->pluck('code', 'id');
})
->searchable()
->reactive(),
Select::make('sap_msg_status')
->label('Select SAP Message Status')
->nullable()
->options(function (callable $get) {
$plantId = $get('Plant');
if (!$plantId ) {
return ProductionQuantity::whereNotNull('sap_msg_status')->select('sap_msg_status')->distinct()->pluck('sap_msg_status', 'sap_msg_status');
}
else {
return ProductionQuantity::where('plant_id', $plantId)->whereNotNull('sap_msg_status')->select('sap_msg_status')->distinct()->pluck('sap_msg_status', 'sap_msg_status');
}
})
// ->options(QualityValidation::whereNotNull('sap_msg_status')->select('sap_msg_status')->distinct()->pluck('sap_msg_status', 'sap_msg_status'))
->reactive(),
DateTimePicker::make(name: 'created_from')
->label('Created From')
->placeholder(placeholder: 'Select From DateTime')
->reactive()
->native(false),
DateTimePicker::make('created_to')
->label('Created To')
->placeholder(placeholder: 'Select To DateTime')
->reactive()
->native(false),
])
->query(function ($query, array $data) {
if (empty($data['Plant']) && empty($data['Shift']) && empty($data['Line']) && empty($data['production_order']) && empty($data['serial_number']) && empty($data['Item']) && empty($data['sap_msg_status']) && empty($data['created_from']) && empty($data['created_to'])) {
return $query->whereRaw('1 = 0');
}
if ($plant = $data['Plant'] ?? null) {
$query->where('plant_id', $plant);
}
if ($shift = $data['Shift'] ?? null) {
$query->where('shift_id', $shift);
}
if ($line = $data['Line'] ?? null) {
$query->where('line_id', $line);
}
if (!empty($data['production_order'])) {
$query->where('production_order', 'like', '%' . $data['production_order'] . '%');
}
if (!empty($data['serial_number'])) {
$query->where('serial_number', 'like', '%' . $data['serial_number'] . '%');
}
if (!empty($data['Item'])) {
$query->where('item_id', $data['Item']);
}
if (!empty($data['sap_msg_status'])) {
$query->where('sap_msg_status', $data['sap_msg_status']);
}
if ($from = $data['created_from'] ?? null) {
$query->where('created_at', '>=', $from);
}
if ($to = $data['created_to'] ?? null) {
$query->where('created_at', '<=', $to);
}
// return $query;
})
->indicateUsing(function (array $data) {
$indicators = [];
if (!empty($data['Plant'])) {
$indicators[] = 'Plant: ' . Plant::where('id', $data['Plant'])->value('name');
}
if (!empty($data['Shift'])) {
$indicators[] = 'Shift: ' . Shift::where('id', $data['Shift'])->value('name');
}
if (!empty($data['Line'])) {
$indicators[] = 'Line: ' . Line::where('id', $data['Line'])->value('name');
}
if (!empty($data['production_order'])) {
$indicators[] = 'Production Order: ' . $data['production_order'];
}
if (!empty($data['serial_number'])) {
$indicators[] = 'Serial Number: ' . $data['serial_number'];
}
if (!empty($data['Item'])) {
$indicators[] = 'Item Code: ' . Item::where('id', $data['Item'])->value('code');
}
if (!empty($data['sap_msg_status'])) {
$indicators[] = 'SAP Message Status: ' . $data['sap_msg_status'];
}
if (!empty($data['created_from'])) {
$indicators[] = 'From: ' . $data['created_from'];
}
if (!empty($data['created_to'])) {
$indicators[] = 'To: ' . $data['created_to'];
}
return $indicators;
})
]) ])
->filtersFormMaxHeight('280px')
->actions([ ->actions([
Tables\Actions\ViewAction::make(), Tables\Actions\ViewAction::make(),
Tables\Actions\EditAction::make(), Tables\Actions\EditAction::make(),

View File

@@ -162,6 +162,7 @@ class CreateProductionQuantity extends CreateRecord
->body($e->getMessage()) ->body($e->getMessage())
->danger() ->danger()
// ->persistent() // ->persistent()
->seconds(2)
->send(); ->send();
return; return;
} }
@@ -179,6 +180,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -186,6 +189,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Invalid QR') ->title('Invalid QR')
->body("Scan the valid QR code.<br>(Ex: Item_Code|Serial_Number )") ->body("Scan the valid QR code.<br>(Ex: Item_Code|Serial_Number )")
->danger() ->danger()
->seconds(2)
->send(); ->send();
return; return;
} }
@@ -201,6 +205,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> null, 'production_order'=> null,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -208,6 +214,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Choose Plant') ->title('Choose Plant')
->body("Please select a plant first.") ->body("Please select a plant first.")
->danger() ->danger()
->seconds(2)
->send(); ->send();
return; return;
} }
@@ -221,6 +228,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> null, 'production_order'=> null,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -228,6 +237,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Choose Block') ->title('Choose Block')
->body("Please select a block first.") ->body("Please select a block first.")
->danger() ->danger()
->seconds(2)
->send(); ->send();
return; return;
} }
@@ -241,6 +251,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> null, 'production_order'=> null,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -248,6 +260,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Choose Shift') ->title('Choose Shift')
->body("Please select a shift first.") ->body("Please select a shift first.")
->danger() ->danger()
->seconds(2)
->send(); ->send();
return; return;
} }
@@ -261,6 +274,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> null, 'production_order'=> null,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -268,6 +283,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Choose Line') ->title('Choose Line')
->body("Please select a line first.") ->body("Please select a line first.")
->danger() ->danger()
->seconds(2)
->send(); ->send();
return; return;
} }
@@ -281,12 +297,15 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> null, 'production_order'=> null,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
Notification::make() Notification::make()
->title('Please scan the production order first.') ->title('Please scan the production order first.')
->danger() ->danger()
->seconds(2)
->send(); ->send();
return; return;
} }
@@ -302,6 +321,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> null, 'production_order'=> null,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -310,6 +331,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Invalid Production Order') ->title('Invalid Production Order')
->body("Must contain numeric values only.") ->body("Must contain numeric values only.")
->danger() ->danger()
->seconds(2)
->send(); ->send();
return; return;
} }
@@ -324,6 +346,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> null, 'production_order'=> null,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -332,6 +356,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Invalid Production Order') ->title('Invalid Production Order')
->body("Must contain at least 7 digits.<br>Must start with a non-zero digit.") ->body("Must contain at least 7 digits.<br>Must start with a non-zero digit.")
->danger() ->danger()
->seconds(2)
->send(); ->send();
return; return;
} }
@@ -378,6 +403,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -385,6 +412,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Invalid Shift') ->title('Invalid Shift')
->body("Please select a valid shift.") ->body("Please select a valid shift.")
->danger() ->danger()
->seconds(2)
->send(); ->send();
//$set('validationError', 'Curr.'.$currentDateTime.' (From: '.$from_dt.', To: '.$to_dt.')'); //$set('validationError', 'Curr.'.$currentDateTime.' (From: '.$from_dt.', To: '.$to_dt.')');
return; return;
@@ -400,6 +428,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -445,6 +475,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -482,6 +514,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -489,6 +523,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Plan Not Found') ->title('Plan Not Found')
->body("Please set production plan first.") ->body("Please set production plan first.")
->danger() ->danger()
->seconds(2)
->send(); ->send();
//$set('validationError', 'Curr.'.$currentDateTime.' (From: '.$from_dt.', To: '.$to_dt.')'); //$set('validationError', 'Curr.'.$currentDateTime.' (From: '.$from_dt.', To: '.$to_dt.')');
return; return;
@@ -507,6 +542,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -514,6 +551,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Invalid Shift') ->title('Invalid Shift')
->body("Please select a valid shift.") ->body("Please select a valid shift.")
->danger() ->danger()
->seconds(2)
->send(); ->send();
//$set('validationError', 'Curr.'.$currentDateTime.' (From: '.$from_dt.', To: '.$to_dt.')'); //$set('validationError', 'Curr.'.$currentDateTime.' (From: '.$from_dt.', To: '.$to_dt.')');
return; return;
@@ -555,6 +593,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -562,6 +602,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Plan Not Found') ->title('Plan Not Found')
->body("Please set production plan first.") ->body("Please set production plan first.")
->danger() ->danger()
->seconds(2)
->send(); ->send();
//$set('validationError', 'Curr.'.$currentDateTime.' (From: '.$from_dt.', To: '.$to_dt.')'); //$set('validationError', 'Curr.'.$currentDateTime.' (From: '.$from_dt.', To: '.$to_dt.')');
return; return;
@@ -599,6 +640,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -606,6 +649,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Plan Not Found') ->title('Plan Not Found')
->body("Please set production plan first.") ->body("Please set production plan first.")
->danger() ->danger()
->seconds(2)
->send(); ->send();
//$set('validationError', 'Curr.'.$currentDateTime.' (From: '.$from_dt.', To: '.$to_dt.')'); //$set('validationError', 'Curr.'.$currentDateTime.' (From: '.$from_dt.', To: '.$to_dt.')');
return; return;
@@ -624,6 +668,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -631,6 +677,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Invalid Shift') ->title('Invalid Shift')
->body("Please select a valid shift.") ->body("Please select a valid shift.")
->danger() ->danger()
->seconds(2)
->send(); ->send();
//$set('validationError', 'Curr.'.$currentDateTime.' (From: '.$from_dt.', To: '.$to_dt.')'); //$set('validationError', 'Curr.'.$currentDateTime.' (From: '.$from_dt.', To: '.$to_dt.')');
return; return;
@@ -650,6 +697,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -666,6 +715,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -674,6 +725,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Invalid QR') ->title('Invalid QR')
->body("Scan the valid QR code.<br>(Ex: Item_Code|Serial_Number )") ->body("Scan the valid QR code.<br>(Ex: Item_Code|Serial_Number )")
->danger() ->danger()
->seconds(2)
->send(); ->send();
return; return;
} }
@@ -693,6 +745,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -701,6 +755,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Invalid Item Code') ->title('Invalid Item Code')
->body("Item code must contain alpha-numeric values only.") ->body("Item code must contain alpha-numeric values only.")
->danger() ->danger()
->seconds(2)
->send(); ->send();
return; return;
} }
@@ -714,6 +769,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -722,6 +779,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Invalid Item Code') ->title('Invalid Item Code')
->body("Item code must be at least 6 digits.") ->body("Item code must be at least 6 digits.")
->danger() ->danger()
->seconds(2)
->send(); ->send();
return; return;
} }
@@ -735,6 +793,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -743,7 +803,8 @@ class CreateProductionQuantity extends CreateRecord
->title('Invalid Serial Number') ->title('Invalid Serial Number')
->body("Serial Number must contain alpha-numeric values only.") ->body("Serial Number must contain alpha-numeric values only.")
->danger() ->danger()
->duration(800) // ->duration(800)
->seconds(2)
->send(); ->send();
return; return;
} }
@@ -757,6 +818,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -765,7 +828,8 @@ class CreateProductionQuantity extends CreateRecord
->title('Invalid Serial Number') ->title('Invalid Serial Number')
->body("Serial Number must be at least 9 digits.") ->body("Serial Number must be at least 9 digits.")
->danger() ->danger()
->duration(800) // ->duration(800)
->seconds(2)
->send(); ->send();
return; return;
} }
@@ -780,6 +844,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -788,6 +854,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Invalid QR') ->title('Invalid QR')
->body("Scan the valid QR code.<br>(Ex: Item_Code|Serial_Number )") ->body("Scan the valid QR code.<br>(Ex: Item_Code|Serial_Number )")
->danger() ->danger()
->seconds(2)
->send(); ->send();
return; return;
} }
@@ -802,6 +869,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -825,6 +894,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -832,6 +903,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Unknown Item Code') ->title('Unknown Item Code')
->body("Item code does not exist in master data.") ->body("Item code does not exist in master data.")
->danger() ->danger()
->seconds(2)
->send(); ->send();
return; return;
} }
@@ -854,6 +926,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> 'Y', 'success_msg'=> 'Y',
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -871,6 +945,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -878,6 +954,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Duplicate Serial Number') ->title('Duplicate Serial Number')
->body("Serial number already exist in database for choosed plant.") ->body("Serial number already exist in database for choosed plant.")
->danger() ->danger()
->seconds(2)
->send(); ->send();
return; return;
} }
@@ -893,6 +970,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -901,6 +980,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Unknown Item Code') ->title('Unknown Item Code')
->body("Item code does not exist in master data for choosed plant.") ->body("Item code does not exist in master data for choosed plant.")
->danger() ->danger()
->seconds(2)
->send(); ->send();
return; return;
} }
@@ -915,6 +995,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $this->recQr, 'recent_qr' => $this->recQr,
]); ]);
@@ -924,6 +1006,7 @@ class CreateProductionQuantity extends CreateRecord
->body("Please, scan the valid QR code.") ->body("Please, scan the valid QR code.")
->danger() ->danger()
// ->persistent() // ->persistent()
->seconds(2)
->send(); ->send();
return; return;
} }
@@ -956,18 +1039,22 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null, 'serial_number'=> null,
'success_msg'=> null, 'success_msg'=> null,
'production_order'=> $this->prodOrder, 'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName, 'operator_id'=> $operatorName,
'recent_qr' => $itemCode.' | '.$this->sNoId, 'recent_qr' => $itemCode.' | '.$this->sNoId,
]); ]);
Notification::make() Notification::make()
->title("Valid QR Found") // {$operatorName} ->title("Valid QR Found") // {$operatorName}
->body("Valid QR code scanned: {$this->qrData}.") ->body("Valid QR code scanned:<br>{$this->qrData}")
->success() ->success()
// ->persistent() // ->persistent()
->seconds(2)
->send(); ->send();
$formQRData = null;
$this->qrData = null;
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -95,7 +95,11 @@ class CreateQualityValidation extends CreateRecord
protected function getRedirectUrl(): string protected function getRedirectUrl(): string
{ {
return $this->getResource()::getUrl('create'); // Stay on Create Page after saving //return $this->getResource()::getUrl('create'); // Stay on Create Page after saving
return $this->getResource()::getUrl('create', [
'plant_id' => $this->data['plant_id'] ?? null,
]);
} }
} }

View File

@@ -0,0 +1,129 @@
<?php
namespace App\Filament\Resources;
use App\Filament\Resources\WeightValidationResource\Pages;
use App\Filament\Resources\WeightValidationResource\RelationManagers;
use App\Models\WeightValidation;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
class WeightValidationResource extends Resource
{
protected static ?string $model = WeightValidation::class;
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
protected static ?string $navigationGroup = 'Weight';
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Select::make('plant_id')
->relationship('plant', 'name')
->required(),
Forms\Components\Select::make('item_id')
->relationship('item', 'code')
->label('Item Code')
->searchable()
->required(),
Forms\Components\TextInput::make('obd_number')
->label('OBD Number')
->required(),
Forms\Components\TextInput::make('line_number')
->label('Line Number')
->required(),
Forms\Components\TextInput::make('batch_number')
->label('Batch Number')
->required(),
Forms\Components\TextInput::make('heat_number')
->label('Heat Number')
->required(),
Forms\Components\TextInput::make('obd_weight')
->label('OBD Weight')
->required(),
Forms\Components\TextInput::make('vehicle_number')
->label('Vehicle Number'),
Forms\Components\TextInput::make('bundle_number')
->label('Bundle Number'),
Forms\Components\TextInput::make('picked_weight')
->label('Picked Weight'),
Forms\Components\TextInput::make('scanned_by')
->label('Scanned By')
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('id')
->label('ID')
->numeric()
->sortable(),
Tables\Columns\TextColumn::make('item.id')
->numeric()
->sortable(),
Tables\Columns\TextColumn::make('plant.name')
->numeric()
->sortable(),
Tables\Columns\TextColumn::make('created_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('updated_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('deleted_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
->filters([
Tables\Filters\TrashedFilter::make(),
])
->actions([
Tables\Actions\ViewAction::make(),
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
Tables\Actions\ForceDeleteBulkAction::make(),
Tables\Actions\RestoreBulkAction::make(),
]),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListWeightValidations::route('/'),
'create' => Pages\CreateWeightValidation::route('/create'),
'view' => Pages\ViewWeightValidation::route('/{record}'),
'edit' => Pages\EditWeightValidation::route('/{record}/edit'),
];
}
public static function getEloquentQuery(): Builder
{
return parent::getEloquentQuery()
->withoutGlobalScopes([
SoftDeletingScope::class,
]);
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace App\Filament\Resources\WeightValidationResource\Pages;
use App\Filament\Resources\WeightValidationResource;
use Filament\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateWeightValidation extends CreateRecord
{
protected static string $resource = WeightValidationResource::class;
}

View File

@@ -0,0 +1,22 @@
<?php
namespace App\Filament\Resources\WeightValidationResource\Pages;
use App\Filament\Resources\WeightValidationResource;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;
class EditWeightValidation extends EditRecord
{
protected static string $resource = WeightValidationResource::class;
protected function getHeaderActions(): array
{
return [
Actions\ViewAction::make(),
Actions\DeleteAction::make(),
Actions\ForceDeleteAction::make(),
Actions\RestoreAction::make(),
];
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\WeightValidationResource\Pages;
use App\Filament\Resources\WeightValidationResource;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;
class ListWeightValidations extends ListRecords
{
protected static string $resource = WeightValidationResource::class;
protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\WeightValidationResource\Pages;
use App\Filament\Resources\WeightValidationResource;
use Filament\Actions;
use Filament\Resources\Pages\ViewRecord;
class ViewWeightValidation extends ViewRecord
{
protected static string $resource = WeightValidationResource::class;
protected function getHeaderActions(): array
{
return [
Actions\EditAction::make(),
];
}
}

View File

@@ -3,7 +3,10 @@
namespace App\Filament\Widgets; namespace App\Filament\Widgets;
use Filament\Notifications\Notification; use Filament\Notifications\Notification;
use Filament\Support\Assets\Js;
use Filament\Support\RawJs;
use Filament\Widgets\ChartWidget; use Filament\Widgets\ChartWidget;
use Illuminate\Contracts\View\View;
class ItemOverview extends ChartWidget class ItemOverview extends ChartWidget
{ {
@@ -16,162 +19,166 @@ class ItemOverview extends ChartWidget
protected $listeners = ['filtersUpdated' => '$refresh']; protected $listeners = ['filtersUpdated' => '$refresh'];
protected function getData(): array public function getData(): array
{
$activeFilter = $this->filter;
$selectedPlant = session('selected_plant') ?? session('select_plant');
$selectedLine = session('selected_line') ?? session('select_line');
if (!$selectedPlant || !$selectedLine)
{ {
return [ $activeFilter = $this->filter;
'datasets' => [],
'labels' => [],
];
}
if ($activeFilter === 'yesterday') { $selectedPlant = session('selected_plant') ?? session('select_plant');
$startDate = now()->subDay()->setTime(8, 0, 0); // Yesterday 8:00 AM $selectedLine = session('selected_line') ?? session('select_line');
$endDate = now()->setTime(8, 0, 0); // Today 8:00 AM
$groupBy = 'EXTRACT(HOUR FROM production_quantities.created_at)';
}
else if ($activeFilter === 'this_week') { if (!$selectedPlant || !$selectedLine)
// Monday 8:00 AM of the current week {
$startDate = now()->startOfWeek()->setTime(8, 0, 0); return [
'datasets' => [],
$endDate = now()->endOfWeek()->addDay()->setTime(8, 0, 0); 'labels' => [],
$groupBy = 'EXTRACT(DOW FROM production_quantities.created_at)'; // Group by day of week
}
else if ($activeFilter === 'this_month') {
$startDate = now()->startOfMonth();
$endDate = now()->endOfMonth();
$groupBy = "FLOOR((EXTRACT(DAY FROM production_quantities.created_at) - 1) / 7) + 1";
}
else
{
$startDate = now()->setTime(8, 0, 0); // today at 8:00 AM
$endDate = now()->copy()->addDay()->setTime(8, 0, 0); // tomorrow at 8:00 AM
$groupBy = 'EXTRACT(HOUR FROM production_quantities.created_at)';
}
$query = \DB::table('production_quantities')
->join('plants', 'production_quantities.plant_id', '=', 'plants.id') //inner join
->join('lines', 'production_quantities.line_id', '=', 'lines.id')
->selectRaw("$groupBy AS time_unit, count(*) AS total_quantity")
//->whereBetween('production_quantities.created_at', [$startDate, $endDate])
->where('production_quantities.created_at', '>=', $startDate) // $startDate should be >=
->where('production_quantities.created_at', '<', $endDate) // $endDate should be <
->when($selectedPlant, function ($q) use ($selectedPlant) {
return $q->where('plants.id', $selectedPlant);
})
->when($selectedLine, function ($q) use ($selectedLine) {
return $q->where('lines.id', $selectedLine);
})
->groupByRaw($groupBy)
->orderByRaw($groupBy)
->pluck('total_quantity', 'time_unit')
->toArray();
if ($activeFilter === 'this_month') {
$weeksCount = ceil($endDate->day / 7); // Calculate total weeks dynamically
$allWeeks = array_fill(1, $weeksCount, 0); // Initialize all weeks with 0
$data = array_replace($allWeeks, $query); // Fill missing weeks with 0
// Generate dynamic week labels
$labels = [];
for ($i = 1; $i <= $weeksCount; $i++) {
$weekStart = $startDate->copy()->addDays(($i - 1) * 7)->format('d M');
$weekEnd = $startDate->copy()->addDays($i * 7 - 1)->min($endDate)->format('d M');
$labels[] = "Week $i ($weekStart - $weekEnd)";
}
$orderedData = array_values($data);
}
else if ($activeFilter === 'this_week') {
// Correct week labels: ['Mon', 'Tue', ..., 'Sun']
$labels = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
// Initialize default data for all 7 days
$data = array_fill(0, 7, 0);
// Fill in data from query results
foreach ($query as $dow => $count) {
$data[$dow] = $count;
}
// Ensure days are ordered from Monday to Sunday
$orderedData = [
$data[1] ?? 0, // Monday
$data[2] ?? 0, // Tuesday
$data[3] ?? 0, // Wednesday
$data[4] ?? 0, // Thursday
$data[5] ?? 0, // Friday
$data[6] ?? 0, // Saturday
$data[0] ?? 0, // Sunday (move to last)
]; ];
} }
else if($activeFilter === 'yesterday')
if ($activeFilter === 'yesterday') {
$startDate = now()->subDay()->setTime(8, 0, 0); // Yesterday 8:00 AM
$endDate = now()->setTime(8, 0, 0); // Today 8:00 AM
$groupBy = 'EXTRACT(HOUR FROM production_quantities.created_at)';
}
else if ($activeFilter === 'this_week') {
// Monday 8:00 AM of the current week
$startDate = now()->startOfWeek()->setTime(8, 0, 0);
$endDate = now()->endOfWeek()->addDay()->setTime(8, 0, 0);
$groupBy = 'EXTRACT(DOW FROM production_quantities.created_at)'; // Group by day of week
}
else if ($activeFilter === 'this_month') {
$startDate = now()->startOfMonth();
$endDate = now()->endOfMonth();
$groupBy = "FLOOR((EXTRACT(DAY FROM production_quantities.created_at) - 1) / 7) + 1";
}
else
{
$startDate = now()->setTime(8, 0, 0); // today at 8:00 AM
$endDate = now()->copy()->addDay()->setTime(8, 0, 0); // tomorrow at 8:00 AM
$groupBy = 'EXTRACT(HOUR FROM production_quantities.created_at)';
}
$query = \DB::table('production_quantities')
->join('plants', 'production_quantities.plant_id', '=', 'plants.id') //inner join
->join('lines', 'production_quantities.line_id', '=', 'lines.id')
->selectRaw("$groupBy AS time_unit, count(*) AS total_quantity")
//->whereBetween('production_quantities.created_at', [$startDate, $endDate])
->where('production_quantities.created_at', '>=', $startDate) // $startDate should be >=
->where('production_quantities.created_at', '<', $endDate) // $endDate should be <
->when($selectedPlant, function ($q) use ($selectedPlant) {
return $q->where('plants.id', $selectedPlant);
})
->when($selectedLine, function ($q) use ($selectedLine) {
return $q->where('lines.id', $selectedLine);
})
->groupByRaw($groupBy)
->orderByRaw($groupBy)
->pluck('total_quantity', 'time_unit')
->toArray();
if ($activeFilter === 'this_month') {
$weeksCount = ceil($endDate->day / 7); // Calculate total weeks dynamically
$allWeeks = array_fill(1, $weeksCount, 0); // Initialize all weeks with 0
$data = array_replace($allWeeks, $query); // Fill missing weeks with 0
// Generate dynamic week labels
$labels = [];
for ($i = 1; $i <= $weeksCount; $i++) {
$weekStart = $startDate->copy()->addDays(($i - 1) * 7)->format('d M');
$weekEnd = $startDate->copy()->addDays($i * 7 - 1)->min($endDate)->format('d M');
$labels[] = "Week $i ($weekStart - $weekEnd)";
}
$orderedData = array_values($data);
}
else if ($activeFilter === 'this_week') {
// Correct week labels: ['Mon', 'Tue', ..., 'Sun']
$labels = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
// Initialize default data for all 7 days
$data = array_fill(0, 7, 0);
// Fill in data from query results
foreach ($query as $dow => $count) {
$data[$dow] = $count;
}
// Ensure days are ordered from Monday to Sunday
$orderedData = [
$data[1] ?? 0, // Monday
$data[2] ?? 0, // Tuesday
$data[3] ?? 0, // Wednesday
$data[4] ?? 0, // Thursday
$data[5] ?? 0, // Friday
$data[6] ?? 0, // Saturday
$data[0] ?? 0, // Sunday (move to last)
];
}
else if($activeFilter === 'yesterday')
{
// Hourly data (same as before)
$allHours = array_fill(0, 24, 0);
$data = array_replace($allHours, $query);
// Shift hours for proper display (8 AM to 7 AM)
$shiftedKeys = array_merge(range(8, 23), range(0, 7));
$orderedData = array_map(fn($hour) => $data[$hour], $shiftedKeys);
// Labels: ["8 AM", "9 AM", ..., "7 AM"]
$labels = array_map(fn ($hour) => date("g A", strtotime("$hour:00")), $shiftedKeys);
}
else
{ {
// Hourly data (same as before) // Hourly data (same as before)
$allHours = array_fill(0, 24, 0); $allHours = array_fill(0, 24, 0);
$data = array_replace($allHours, $query); $data = array_replace($allHours, $query);
// Shift hours for proper display (8 AM to 7 AM) // Shift hours for proper display (8 AM to 7 AM)
$shiftedKeys = array_merge(range(8, 23), range(0, 7)); $shiftedKeys = array_merge(range(8, 23), range(0, 7));
$orderedData = array_map(fn($hour) => $data[$hour], $shiftedKeys); $orderedData = array_map(fn($hour) => $data[$hour], $shiftedKeys);
// Labels: ["8 AM", "9 AM", ..., "7 AM"] // Labels: ["8 AM", "9 AM", ..., "7 AM"]
$labels = array_map(fn ($hour) => date("g A", strtotime("$hour:00")), $shiftedKeys); $labels = array_map(fn ($hour) => date("g A", strtotime("$hour:00")), $shiftedKeys);
} }
else
{
// Hourly data (same as before)
$allHours = array_fill(0, 24, 0);
$data = array_replace($allHours, $query);
// Shift hours for proper display (8 AM to 7 AM)
$shiftedKeys = array_merge(range(8, 23), range(0, 7));
$orderedData = array_map(fn($hour) => $data[$hour], $shiftedKeys);
// Labels: ["8 AM", "9 AM", ..., "7 AM"]
$labels = array_map(fn ($hour) => date("g A", strtotime("$hour:00")), $shiftedKeys);
}
return [ return [
'datasets' => [ 'datasets' => [
[ [
'label' => match ($activeFilter) { 'label' => match ($activeFilter) {
'this_week' => "Daily Production This Week", 'this_week' => "Daily Production This Week",
'this_month' => "Weekly Production This Month", // Updated Label 'this_month' => "Weekly Production This Month", // Updated Label
'yesterday' => "Yesterday's Hourly Production", 'yesterday' => "Yesterday's Hourly Production",
default => "Today's Hourly Production", default => "Today's Hourly Production",
}, },
'data' => $orderedData, 'data' => $orderedData,
'borderColor' => 'rgba(75, 192, 192, 1)', 'interaction' => [
'backgroundColor' => 'rgba(75, 192, 192, 0.2)', 'mode' => 'nearest',
'fill' => false, 'axis' => 'x',
'tension' => 0.3, 'intersect' => false,
],
'borderColor' => 'rgba(75, 192, 192, 1)',
'backgroundColor' => 'rgba(75, 192, 192, 0.2)',
'fill' => false,
'tension' => 0.3,
],
], ],
], 'labels' => $labels,
'labels' => $labels, ];
]; }
}
protected function getType(): string protected function getType(): string
{ {
return 'line'; return 'line';
} }
protected function getOptions(): array protected function getOptions(): array
{ {
return [ return [
@@ -187,6 +194,33 @@ class ItemOverview extends ChartWidget
]; ];
} }
// protected function getOptions(): array
// {
// return [
// 'plugins' => [
// 'datalabels' => [
// 'color' => '#3490dc',
// 'font' => [
// 'weight' => 'bold',
// 'size' => 14,
// ],
// 'backgroundColor' => 'rgba(255,255,255,0.8)',
// 'borderRadius' => 4,
// 'formatter' => \Illuminate\Support\Js::from(
// new Js('function(value, context) {
// if (Number(value) === 0) {
// return null;
// }
// return "Count: " + value;
// }')
// ),
// ]
// ]
// ];
// }
protected function getFilters(): ?array protected function getFilters(): ?array
{ {
return [ return [
@@ -199,7 +233,6 @@ class ItemOverview extends ChartWidget
public static function canView(): bool public static function canView(): bool
{ {
// Only show on HourlyProduction page
return request()->routeIs([ return request()->routeIs([
'filament.pages.hourly-production', 'filament.pages.hourly-production',
'filament.admin.resources.production-quantities.create', 'filament.admin.resources.production-quantities.create',

View File

@@ -175,30 +175,6 @@ class ProductionLineStopChart extends ChartWidget
'display' => false, // Disable y-axis 'display' => false, // Disable y-axis
], ],
], ],
'elements' => [
'arc' => [
'hover' => [
'scale' => 1.1, // Increase the slice size by 10% on hover
'borderWidth' => 3, // Optionally increase border width on hover
'offset' => 10, // Make the slice move outside of the pie chart on hover
],
// This ensures that animation and hover effects work as expected
'animation' => [
'duration' => 500, // Duration for the hover animation (smooth pop)
'easing' => 'easeOutQuad', // Smooth easing for pop-up effect
],
],
],
'hover' => [
'mode' => 'nearest', // Hover mode: nearest slice
'intersect' => true, // Only trigger hover if intersecting a slice
'animationDuration' => 500, // Duration of hover animation
],
'animation' => [
'duration' => 1000, // Overall animation duration
'easing' => 'easeInOutQuart', // Easing function for smooth transition
],
'maintainAspectRatio' => false,
]; ];
} }

View File

@@ -15,6 +15,7 @@ class Item extends Model
'code', 'code',
'description', 'description',
'hourly_quantity', 'hourly_quantity',
'uom',
]; ];
public function plant(): BelongsTo public function plant(): BelongsTo
@@ -26,4 +27,9 @@ class Item extends Model
{ {
return $this->hasMany(StickerMaster::class, 'item_id', 'id'); return $this->hasMany(StickerMaster::class, 'item_id', 'id');
} }
public function productionQuantities()
{
return $this->hasMany(ProductionQuantity::class);
}
} }

View File

@@ -33,6 +33,10 @@ class QualityValidation extends Model
'part_validation4', 'part_validation4',
'part_validation5', 'part_validation5',
'operator_id', 'operator_id',
'uom',
'serial_number',
'sap_msg_status',
'sap_msg_description',
]; ];
public function stickerMaster(): BelongsTo public function stickerMaster(): BelongsTo

View File

@@ -0,0 +1,36 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
class WeightValidation extends Model
{
use SoftDeletes;
protected $fillable = [
'plant_id',
'item_id',
'obd_number',
'line_number',
'batch_number',
'heat_number',
'obd_weight',
'vehicle_number',
'bundle_number',
'picked_weight',
'scanned_by',
];
public function plant(): BelongsTo
{
return $this->belongsTo(Plant::class);
}
public function item(): BelongsTo
{
return $this->belongsTo(Item::class);
}
}

View File

@@ -9,6 +9,9 @@ use App\Policies\RolePolicy;
use App\Policies\PermissionPolicy; use App\Policies\PermissionPolicy;
use Spatie\Permission\Models\Role; use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission; use Spatie\Permission\Models\Permission;
use Filament\Support\Facades\FilamentAsset;
use Filament\Support\Assets\Js;
use Illuminate\Support\Facades\Vite;
// use Doctrine\DBAL\Types\Type; // use Doctrine\DBAL\Types\Type;
@@ -35,6 +38,10 @@ class AppServiceProvider extends ServiceProvider
return $user->isSuperAdmin() ? true: null; return $user->isSuperAdmin() ? true: null;
}); });
// FilamentAsset::register([
// Js::make('chart-js-plugins', Vite::asset('resources/js/filament-chart-js-plugins.js'))->module(),
// ]);
// URL::forceScheme('https'); // URL::forceScheme('https');
// if (!Type::hasType('citext')) { // if (!Type::hasType('citext')) {

View File

@@ -42,8 +42,6 @@ class AdminPanelProvider extends PanelProvider
->discoverPages(in: app_path('Filament/Pages'), for: 'App\\Filament\\Pages') ->discoverPages(in: app_path('Filament/Pages'), for: 'App\\Filament\\Pages')
->pages([ ->pages([
]) ])
->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\\Filament\\Widgets') ->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\\Filament\\Widgets')
// ->widgets([ // ->widgets([
// Widgets\AccountWidget::class, // Widgets\AccountWidget::class,

View File

@@ -0,0 +1,59 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
$sql1 = <<<'SQL'
ALTER TABLE quality_validations
ADD uom TEXT DEFAULT NULL;
SQL;
DB::statement($sql1);
$sql2 = <<<'SQL'
ALTER TABLE quality_validations
ADD sap_msg_status TEXT DEFAULT NULL;
SQL;
DB::statement($sql2);
$sql3 = <<<'SQL'
ALTER TABLE quality_validations
ADD sap_msg_description TEXT DEFAULT NULL;
SQL;
DB::statement($sql3);
$sql4 = <<<'SQL'
ALTER TABLE quality_validations
ADD serial_number TEXT DEFAULT NULL;
SQL;
DB::statement($sql4);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
}
};

View File

@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
// use Illuminate\Database\Schema\Blueprint;
// use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
$sql = <<<'SQL'
ALTER TABLE items
ADD uom TEXT DEFAULT NULL;
SQL;
DB::statement($sql);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// Schema::table('items', function (Blueprint $table) {
// //
// });
}
};

View File

@@ -0,0 +1,40 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
$sql1 = <<<'SQL'
ALTER TABLE production_quantities
ADD sap_msg_status TEXT DEFAULT NULL;
SQL;
DB::statement($sql1);
$sql2 = <<<'SQL'
ALTER TABLE production_quantities
ADD sap_msg_description TEXT DEFAULT NULL;
SQL;
DB::statement($sql2);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
}
};

View File

@@ -0,0 +1,52 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
$sql = <<<'SQL'
CREATE TABLE weight_validations (
id BIGINT GENERATED always AS IDENTITY PRIMARY KEY,
item_id BIGINT NOT NULL,
plant_id BIGINT NOT NULL,
obd_number TEXT NOT NULL,
line_number TEXT DEFAULT NULL,
batch_number TEXT DEFAULT NULL,
heat_number TEXT DEFAULT NULL,
obd_weight TEXT DEFAULT NULL,
vehicle_number TEXT DEFAULT NULL,
bundle_number TEXT DEFAULT NULL,
picked_weight TEXT DEFAULT NULL,
scanned_by TEXT DEFAULT NULL,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
deleted_at TIMESTAMP,
FOREIGN KEY (item_id) REFERENCES items (id),
FOREIGN KEY (plant_id) REFERENCES plants (id)
);
SQL;
DB::statement($sql);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('weight_validations');
}
};

View File

@@ -2,7 +2,8 @@
namespace Database\Seeders; namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents; use App\Models\User;
use Hash;
use Illuminate\Database\Seeder; use Illuminate\Database\Seeder;
class AdminSeeder extends Seeder class AdminSeeder extends Seeder
@@ -12,6 +13,24 @@ class AdminSeeder extends Seeder
*/ */
public function run(): void public function run(): void
{ {
// //updateOrCreate
$user1 = User::updateOrCreate(
// Unique identifier
['email' => 'admin@cripumps.com'],
// Data to update/create
[
'name' => 'Admin',
'password' => Hash::make('jOtHi$9000'),
'updated_at' => now(),
'created_at' => now()
]
);
// $user1 = User::firstOrCreate([
// 'name' => 'Admin',
// 'email' => 'admin@cripumps.com',
// 'password' => bcrypt('admin'),
// ]);
$user1->assignRole('Super Admin');
} }
} }

View File

@@ -13,6 +13,7 @@ class DatabaseSeeder extends Seeder
public function run(): void public function run(): void
{ {
$this->call(RoleSeeder::class); $this->call(RoleSeeder::class);
$this->call(AdminSeeder::class);
$this->call(UserSeeder::class); $this->call(UserSeeder::class);
$this->call(PermissionSeeder::class); $this->call(PermissionSeeder::class);
} }

View File

@@ -36,15 +36,22 @@ class PermissionSeeder extends Seeder
Permission::updateOrCreate(['name' => 'view import serial invoice']); Permission::updateOrCreate(['name' => 'view import serial invoice']);
Permission::updateOrCreate(['name' => 'view import material invoice']); Permission::updateOrCreate(['name' => 'view import material invoice']);
Permission::updateOrCreate(['name' => 'view export invoice']); Permission::updateOrCreate(['name' => 'view export invoice']);
Permission::updateOrCreate(['name' => 'view invoice dashboard']); //invoice dashboard
Permission::updateOrCreate(['name' => 'view import production quantities']); Permission::updateOrCreate(['name' => 'create ProductionQuantities']);
Permission::updateOrCreate(['name' => 'view export production quantities']);
Permission::updateOrCreate(['name' => 'view invoice dashboard']); //invoice dashboard
Permission::updateOrCreate(['name' => 'view production dashboard']); //hourly production Permission::updateOrCreate(['name' => 'view production dashboard']); //hourly production
Permission::updateOrCreate(['name' => 'view production line count dashboard']); Permission::updateOrCreate(['name' => 'view production line count dashboard']);
Permission::updateOrCreate(['name' => 'view production order count dashboard']); Permission::updateOrCreate(['name' => 'view production order count dashboard']);
Permission::updateOrCreate(['name' => 'view production line stop count dashboard']); Permission::updateOrCreate(['name' => 'view production line stop count dashboard']);
Permission::updateOrCreate(['name' => 'create ProductionQuantities']); Permission::updateOrCreate(['name' => 'view import production quantities']);
Permission::updateOrCreate(['name' => 'view export production quantities']);
Permission::updateOrCreate(['name' => 'view import production line stop']);
Permission::updateOrCreate(['name' => 'view export production line stop']);
Permission::updateOrCreate(['name' => 'view import production plan']);
Permission::updateOrCreate(['name' => 'view export production plan']);
Permission::updateOrCreate(['name' => 'view import quality validation']);
Permission::updateOrCreate(['name' => 'view export quality validation']);
} }
} }

View File

@@ -13,31 +13,8 @@ class UserSeeder extends Seeder
*/ */
public function run(): void public function run(): void
{ {
//updateOrCreate
$user1 = User::updateOrCreate( $user1 = User::updateOrCreate(
// Unique identifier
['email' => 'admin@cripumps.com'],
// Data to update/create
[
'name' => 'Admin',
'password' => Hash::make('jOtHi$9000'),
'updated_at' => now(),
'created_at' => now()
]
);
// $user1 = User::firstOrCreate([
// 'name' => 'Admin',
// 'email' => 'admin@cripumps.com',
// 'password' => bcrypt('admin'),
// ]);
$user1->assignRole('Super Admin');
$user2 = User::updateOrCreate(
// Unique identifier
['email' => 'dhanabalan@cripumps.com'], ['email' => 'dhanabalan@cripumps.com'],
// Data to update/create
[ [
'name' => 'Dhanabalan S', 'name' => 'Dhanabalan S',
'password' => bcrypt('SdHaNa@123'), 'password' => bcrypt('SdHaNa@123'),
@@ -45,18 +22,10 @@ class UserSeeder extends Seeder
'created_at' => now() 'created_at' => now()
] ]
); );
// $user2 = User::firstOrCreate([ $user1->assignRole('Super Admin');
// 'name' => 'Dhana',
// 'email' => 'dhana@cripumps.com',
// 'password' => bcrypt('dhana@123'),
// ]);
$user2->assignRole('Super Admin');
$user3 = User::updateOrCreate( $user2 = User::updateOrCreate(
// Unique identifier
['email' => 'ranjith@cripumps.com'], ['email' => 'ranjith@cripumps.com'],
// Data to update/create
[ [
'name' => 'Ranjith B', 'name' => 'Ranjith B',
'password' => bcrypt('Ranjii@5503'), 'password' => bcrypt('Ranjii@5503'),
@@ -64,18 +33,10 @@ class UserSeeder extends Seeder
'created_at' => now() 'created_at' => now()
] ]
); );
// $user3 = User::firstOrCreate([ $user2->assignRole('Super Admin');
// 'name' => 'Ranjith',
// 'email' => 'ranjith@cripumps.com',
// 'password' => bcrypt('ranjith@123'),
// ]);
$user3->assignRole('Super Admin');
$user4 = User::updateOrCreate( $user3 = User::updateOrCreate(
// Unique identifier
['email' => 'srimathi@cripumps.com'], ['email' => 'srimathi@cripumps.com'],
// Data to update/create
[ [
'name' => 'Srimathi M', 'name' => 'Srimathi M',
'password' => bcrypt('MsRi@123'), 'password' => bcrypt('MsRi@123'),
@@ -83,12 +44,7 @@ class UserSeeder extends Seeder
'created_at' => now() 'created_at' => now()
] ]
); );
// $user4 = User::firstOrCreate([ $user3->assignRole('Super Admin');
// 'name' => 'Srimathi',
// 'email' => 'srimathi@cripumps.com',
// 'password' => bcrypt('srimathi@123'),
// ]);
$user4->assignRole('Super Admin');
// User::factory()->count(5)->create(); // User::factory()->count(5)->create();
} }
} }

View File

@@ -3,25 +3,11 @@
{{-- Filters form --}} {{-- Filters form --}}
{{ $this->filtersForm($this->form) }} {{ $this->filtersForm($this->form) }}
{{-- Chart Widget --}} {{-- Chart widget --}}
@livewire(\App\Filament\Widgets\ItemOverview::class) <x-filament-widgets::widgets :widgets="$this->getWidgets()" />
</div> </div>
</x-filament-panels::page> </x-filament-panels::page>
{{-- <x-filament-panels::page>
<div x-data x-init="
window.addEventListener('filtersUpdated', () => {
Livewire.emit('filtersUpdated');
});
" class="space-y-4">
{{-- Filters form --}}
{{-- {{ $this->filtersForm($this->form) }} --}}
{{-- Chart Widget --}}
{{-- @livewire(\App\Filament\Widgets\ItemOverview::class) --}}
{{-- </div>
</x-filament-panels::page> --}}

View File

@@ -14,4 +14,5 @@
</div> </div>
</div> </div>
</x-filament-panels::page> </x-filament-panels::page>

View File

@@ -9,7 +9,6 @@
<div class="bg-white shadow rounded-xl p-4"> <div class="bg-white shadow rounded-xl p-4">
<livewire:select-plant /> <livewire:select-plant />
</div> </div>
{{-- Actions --}} {{-- Actions --}}
<div class="filament-actions mt-6"> <div class="filament-actions mt-6">
<x-filament::actions> <x-filament::actions>

View File

@@ -114,57 +114,5 @@
</div> </div>
{{-- //..perfect logic --}}
{{-- <div class="flex space-x-4 w-full">
<!-- First Table: 08:00 AM to 07:00 PM -->
<div class="w-full px-2">
<table class="w-full divide-y divide-gray-200 border-1 rounded-lg border-black overflow-hidden">
<thead class="bg-gray-100">
<tr>
<th class="px-3 py-3 border text-center text-xs font-bold text-gray-700 uppercase tracking-wider">No</th>
<th class="px-3 py-3 border text-center text-xs font-bold text-gray-700 uppercase tracking-wider">Time Range</th>
<th class="px-3 py-3 border text-center text-xs font-bold text-gray-700 uppercase tracking-wider">Production Quantity</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
@foreach ($hourlyData as $index => $data)
@if ($index < 12) <!-- First 12 time ranges (AM) -->
<tr>
<td class="px-3 py-2 border text-center text-xs whitespace-nowrap">{{ $index + 1 }}</td>
<td class="px-3 py-2 border text-center text-xs whitespace-nowrap">{{ $data['time'] }}</td>
<td class="px-3 py-2 border text-center text-xs whitespace-nowrap">{{ $data['quantity'] ?: '0' }}</td> <!-- Show 0 if no data -->
</tr>
@endif
@endforeach
</tbody>
</table>
</div>
<!-- Second Table: 08:00 PM to 08:00 AM -->
<div class="w-full px-2">
<table class="w-full divide-y divide-gray-200 border-1 rounded-lg overflow-hidden">
<thead class="bg-gray-100">
<tr>
<th class="px-3 py-3 border text-center text-xs font-bold text-gray-700 uppercase tracking-wider">No</th>
<th class="px-3 py-3 border text-center text-xs font-bold text-gray-700 uppercase tracking-wider">Time Range</th>
<th class="px-3 py-3 border text-center text-xs font-bold text-gray-700 uppercase tracking-wider">Production Quantity</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
@foreach ($hourlyData as $index => $data)
@if ($index >= 12) <!-- Last 12 time ranges (PM to AM) -->
<tr>
<td class="px-3 py-2 border text-center text-xs whitespace-nowrap">{{ $index + 1 }}</td>
<td class="px-3 py-2 border text-center text-xs whitespace-nowrap">{{ $data['time'] }}</td>
<td class="px-3 py-2 border text-center text-xs whitespace-nowrap">{{ $data['quantity'] ?: '0' }}</td> <!-- Show 0 if no data -->
</tr>
@endif
@endforeach
</tbody>
</table>
</div>
</div> --}}

View File

@@ -4,7 +4,8 @@ import laravel from 'laravel-vite-plugin';
export default defineConfig({ export default defineConfig({
plugins: [ plugins: [
laravel({ laravel({
input: ['resources/css/app.css', 'resources/js/app.js'], //input: ['resources/css/app.css', 'resources/js/app.js', 'resources/js/filament-chart-js-plugins.js', 'resources/css/filament/admin/theme.css', 'resources/js/hourly-production-chart.js', ],
input: ['resources/css/app.css', 'resources/js/app.js',],
refresh: true, refresh: true,
}), }),
], ],