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

View File

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

View File

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

View File

@@ -16,22 +16,33 @@ class ProductionQuantityExporter extends Exporter
return [
ExportColumn::make('id')
->label('ID'),
ExportColumn::make('item.code')
->label('ITEM CODE'),
ExportColumn::make('production_order')
->label('PRODUCTION ORDER'),
ExportColumn::make('serial_number')
->label('SERIAL NUMBER'),
ExportColumn::make('item.code')
->label('ITEM CODE'),
ExportColumn::make('item.uom')
->label('UNIT OF MEASURE'),
ExportColumn::make('line.name')
->label('LINE'),
ExportColumn::make('shift.name')
->label('SHIFT'),
ExportColumn::make('plant.name')
->label('PLANT'),
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'),
->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;
use App\Models\Item;
use App\Models\Plant;
use Filament\Actions\Imports\Exceptions\RowImportFailedException;
use Filament\Actions\Imports\ImportColumn;
use Filament\Actions\Imports\Importer;
use Filament\Actions\Imports\Models\Import;
use Str;
class ItemImporter extends Importer
{
@@ -33,6 +36,11 @@ class ItemImporter extends Importer
->label('Hourly Quantity')
->numeric()
->rules(['required', 'integer']),
ImportColumn::make('uom')
->requiredMapping()
->exampleHeader('Unit of Measure')
->example('EA')
->label('Unit of Measure'),
ImportColumn::make('plant')
->requiredMapping()
->exampleHeader('Plant Name')
@@ -45,9 +53,25 @@ class ItemImporter extends Importer
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) {
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([
'code' => $this->data['code'],
@@ -55,7 +79,8 @@ class ItemImporter extends Importer
],
[
'description' => $this->data['description'],
'hourly_quantity' => $this->data['hourly_quantity']
'hourly_quantity' => $this->data['hourly_quantity'],
'uom' => $this->data['uom']
]
);
// return new Item;

View File

@@ -2,10 +2,19 @@
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\Shift;
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;
class ProductionLineStopImporter extends Importer
{
@@ -17,61 +26,67 @@ class ProductionLineStopImporter extends Importer
ImportColumn::make('from_datetime')
->requiredMapping()
->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')
->rules(['required']),
->rules(['required']), //, 'date_format:"d-m-Y H:i:s"'
ImportColumn::make('to_datetime')
->requiredMapping()
->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')
->rules(['required']),
ImportColumn::make('stop_hour')
->requiredMapping()
->exampleHeader('Stop Hour')
->example('1')
->example(['1', '1'])
->label('Stop Hour')
->numeric()
->rules(['required', 'integer']),
ImportColumn::make('stop_min')
->requiredMapping()
->exampleHeader('Stop Min')
->example('25')
->example(['25','0'])
->label('Stop Min')
->numeric()
->rules(['required', 'integer']),
ImportColumn::make('linestop')
->requiredMapping()
->exampleHeader('Line Stop Code')
->example('A7R')
->example(['A7R', 'A1R'])
->label('Line Stop Code')
->relationship(resolveUsing:'code')
->rules(['required']),
ImportColumn::make('line')
->requiredMapping()
->exampleHeader('Line Name')
->example('4 inch pump line')
->example(['4 inch pump line', '4 inch pump line'])
->label('Line Name')
->relationship(resolveUsing:'name')
->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')
->requiredMapping()
->exampleHeader('Shift Name')
->example('Day')
->example(['Day', 'Night'])
->label('Shift Name')
->relationship(resolveUsing:'name')
->relationship(resolveUsing: 'name')
->rules(['required']),
ImportColumn::make('plant')
->requiredMapping()
->exampleHeader('Plant Name')
->example('Ransar Industries-I')
->example(['Ransar Industries-I', 'Ransar Industries-I'])
->label('Plant Name')
->relationship(resolveUsing:'name')
->rules(['required']),
ImportColumn::make('operator_id')
->requiredMapping()
->exampleHeader('Operator ID')
->example('admin')
->example([Filament::auth()->user()->name, Filament::auth()->user()->name])
->label('Operator ID')
->rules(['required']),
];
@@ -79,12 +94,138 @@ class ProductionLineStopImporter extends Importer
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([
// // Update existing records, matching them by `$this->data['column_name']`
// 'email' => $this->data['email'],
// ]);
return new ProductionLineStop();
// return new ProductionLineStop();
}
public static function getCompletedNotificationBody(Import $import): string

View File

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

View File

@@ -2,11 +2,21 @@
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\Shift;
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\Database\Eloquent\Model;
use Str;
class ProductionQuantityImporter extends Importer
{
@@ -18,59 +28,65 @@ class ProductionQuantityImporter extends Importer
ImportColumn::make('created_at')
->requiredMapping()
->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')
->rules(['required']),
ImportColumn::make('production_order')
->requiredMapping()
->exampleHeader('Production Order')
->example('1234567')
->example(['1234567', '1234567'])
->label('Production Order')
->numeric(),
ImportColumn::make('item')
->requiredMapping()
->exampleHeader('Item Code')
->example('123456')
->example(['123456', '123456'])
->label('Item Code')
->relationship(resolveUsing:'code')
->rules(['required']),
ImportColumn::make('serial_number')
->requiredMapping()
->exampleHeader('Serial Number')
->example('12345678901234')
->example(['12345678901234', '12345678902234'])
->label('Serial Number')
->rules(['required']),
ImportColumn::make('line')
->requiredMapping()
->exampleHeader('Line Name')
->example('4 inch pump line')
->example(['4 inch pump line', '4 inch pump line'])
->label('Line Name')
->relationship(resolveUsing:'name')
->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')
->requiredMapping()
->exampleHeader('Shift Name')
->example('Day')
->example(['Day', 'Night'])
->label('Shift Name')
->relationship(resolveUsing:'name')
->rules(['required']),
ImportColumn::make('plant')
->requiredMapping()
->exampleHeader('Plant Name')
->example('Ransar Industries-I')
->example(['Ransar Industries-I', 'Ransar Industries-I'])
->label('Plant Name')
->relationship(resolveUsing:'name')
->rules(['required']),
ImportColumn::make('updated_at')
->requiredMapping()
->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')
->rules(['required']),
ImportColumn::make('operator_id')
->requiredMapping()
->exampleHeader('Operator ID')
->example('admin')
->example([Filament::auth()->user()->name, Filament::auth()->user()->name])
->label('Operator ID')
->rules(['required']),
];
@@ -78,31 +94,142 @@ class ProductionQuantityImporter extends Importer
public function resolveRecord(): ?ProductionQuantity
{
$plant = \App\Models\Plant::where('name', $this->data['plant'])->first();
$item = \App\Models\Item::where('code', $this->data['item'])->where('plant_id', $plant->id)->first();
$line = \App\Models\Line::where('name', $this->data['line'])->where('plant_id', $plant->id)->first();
$shift = \App\Models\Shift::where('name', $this->data['shift'])->where('plant_id', $plant->id)->first();
if (!$plant || !$item || !$line || !$shift) {
// Optionally handle missing plant/item/line/shift
return null;
$warnMsg = [];
$plant = Plant::where('name', $this->data['plant'])->first();
$line = null;
$block = null;
if (!$plant) {
$warnMsg[] = "Plant not found";
}
return 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' => $this->data['created_at'],
'updated_at' => $this->data['updated_at']
]
);
// return ProductionQuantity::firstOrNew([
// // Update existing records, matching them by `$this->data['column_name']`
// 'email' => $this->data['email'],
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";
}
$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();
}
@@ -145,21 +272,21 @@ class ProductionQuantityImporter extends Importer
// Relationship resolvers
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
{
return \App\Models\Line::where('name', $name)->first()->id;
return Line::where('name', $name)->first()->id;
}
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
{
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;
use App\Models\Block;
use App\Models\Plant;
use App\Models\Shift;
use Filament\Actions\Imports\Exceptions\RowImportFailedException;
use Filament\Actions\Imports\ImportColumn;
use Filament\Actions\Imports\Importer;
use Filament\Actions\Imports\Models\Import;
use Str;
class ShiftImporter extends Importer
{
@@ -64,12 +68,30 @@ class ShiftImporter extends Importer
public function resolveRecord(): ?Shift
{
$plant = \App\Models\Plant::where('name', $this->data['plant'])->first();
$block = \App\Models\Block::where('name', $this->data['block'])->where('plant_id', $plant->id)->first();
$warnMsg = [];
$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) {
// Optionally handle missing plant/block
return null;
if (!empty($warnMsg)) {
throw new RowImportFailedException(implode(', ', $warnMsg));
}
$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\Tables\Concerns\HasFilters;
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';
@@ -22,11 +23,15 @@ class HourlyProduction extends Page
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([
//'plant' => Plant::first()?->id // Default to first plant
'plant' => null,
'line' => null,
'plant' => $plantId,
'line' => $lineId,
]);
}
@@ -43,7 +48,7 @@ class HourlyProduction extends Page
->afterStateUpdated(function ($state) {
session(['selected_plant' => $state]);
// Clear production quantity Dashboard session keys to avoid conflict
session()->forget(['select_plant', 'select_line']);
//session()->forget(['select_plant', 'select_line']);
$this->triggerChartUpdate();
}),
@@ -79,4 +84,11 @@ class HourlyProduction extends Page
{
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 $recent_qr, $clear_qr;
// public $recent_qr, $clear_qr;
use HasFiltersForm;
@@ -45,6 +45,7 @@ class ProductionQuantityPage extends Page implements HasForms
public function mount(): void
{
session()->forget(['select_plant', 'select_line']);
session()->forget(['selected_plant', 'selected_line']);
$this->filtersForm->fill([
'plant' => null,
'line' => null,
@@ -71,7 +72,7 @@ class ProductionQuantityPage extends Page implements HasForms
padding: 0 !important;
max-width: 100% !important;
/* overflow-y: auto; Allow vertical scrolling */
height: 100vh; /* Ensure full height of the viewport */
height: 100vh;
}
/* Expand page area fully */
@@ -80,6 +81,22 @@ class ProductionQuantityPage extends Page implements HasForms
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 */
body {
overflow: auto;
@@ -125,8 +142,6 @@ class ProductionQuantityPage extends Page implements HasForms
session(['select_plant' => $state]);
session()->forget(['selected_plant', 'selected_line']);
if (!$plantId)
{
$set('pqPlantError', 'Please select a plant first.');
@@ -339,11 +354,14 @@ class ProductionQuantityPage extends Page implements HasForms
->required(),
Hidden::make('success_msg')
->required(),
Hidden::make('item_id')
->required(),
Hidden::make('sap_msg_status'),
Hidden::make('sap_msg_description'),
TextInput::make('recent_qr')
->label('Last scanned QR')
->reactive()
->live()
->columnSpan(1)
// ->default(function () {
// // 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
// $serialNumber = $latestProductionQuantity->serial_number;
// dd($itemCode, $serialNumber);
// // 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),
TextInput::make('id')
@@ -383,7 +403,7 @@ class ProductionQuantityPage extends Page implements HasForms
//dd($formQRData);
//$formValues = [];
// This will get all form data from the request
$this->clear_qr = null;
//$this->clear_qr = null;
$this->qrData = null;
$this->iId = null;
$this->succId = null;
@@ -428,6 +448,15 @@ class ProductionQuantityPage extends Page implements HasForms
// 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)) {
$this->form->fill([
'plant_id'=> $this->pId,
@@ -438,9 +467,12 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
Notification::make()
->title('Invalid QR')
->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,
'success_msg'=> null,
'production_order'=> null,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -480,6 +514,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> null,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -500,6 +536,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> null,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -520,6 +558,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> null,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -540,6 +580,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> null,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -561,6 +603,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> null,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -583,6 +627,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> null,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -637,6 +683,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -659,6 +707,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -704,6 +754,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -741,6 +793,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -766,6 +820,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -814,6 +870,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -858,6 +916,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -883,6 +943,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -909,6 +971,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -925,6 +989,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -952,6 +1018,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -973,6 +1041,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -994,6 +1064,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -1016,6 +1088,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -1039,6 +1113,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -1061,6 +1137,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -1084,6 +1162,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -1113,6 +1193,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null,
'success_msg'=> 'Y',
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -1130,6 +1212,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -1152,6 +1236,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -1174,6 +1260,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -1219,6 +1307,8 @@ class ProductionQuantityPage extends Page implements HasForms
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $itemCode.' | '.$this->sNoId,
]);

View File

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

View File

@@ -9,6 +9,7 @@ use App\Filament\Resources\ProductionLineStopResource\Pages;
use App\Filament\Resources\ProductionLineStopResource\RelationManagers;
use App\Models\Block;
use App\Models\Line;
use App\Models\LineStop;
use App\Models\Plant;
use App\Models\ProductionLineStop;
use App\Models\Shift;
@@ -368,10 +369,12 @@ class ProductionLineStopResource extends Resource
->sortable(),
Tables\Columns\TextColumn::make('stop_hour')
->label('Stop Hour')
->alignCenter()
->numeric()
->sortable(),
Tables\Columns\TextColumn::make('stop_min')
->label('Stop Minute')
->alignCenter()
->numeric()
->sortable(),
Tables\Columns\TextColumn::make('line.name')
@@ -404,118 +407,132 @@ class ProductionLineStopResource extends Resource
])
->filters([
Tables\Filters\TrashedFilter::make(),
Filter::make('advanced_filters')
->label('Advanced Filters')
->form([
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('line_stop_id', null);
}),
Select::make('Plant')
->label('Select Plant')
->options(function () {
return Plant::pluck('name', 'id'); // Assuming 'name' is the column you want to display
}),
//line
Select::make('Line')
->label('Select line')
->nullable()
->options(function (callable $get) {
$plantId = $get('Plant');
//block
Select::make('Block')
->label('Select Block')
->options(fn (callable $get) =>
$get('Plant')
? Block::where('plant_id', $get('Plant'))->pluck('name', 'id')
: []
)
->reactive(),
if (!$plantId ) {
return [];
}
return Line::where('plant_id', $plantId)
->pluck('name', 'id');
})
->reactive(),
//shift
Select::make('Shift')
->label('Select Shift')
->options(function (callable $get) {
$plantId = $get('Plant');
$blockId = $get('Block');
//block
Select::make('Block')
->label('Select Block')
->nullable()
->options(function (callable $get) {
$plantId = $get('Plant');
if (!$plantId || !$blockId) {
return []; // Return empty if plant or block is not selected
}
if (!$plantId ) {
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)
->pluck('name', 'id');
})
->reactive(),
})
->reactive(),
//line
Select::make('line')
->label('Select line')
->options(function (callable $get) {
$plantId = $get('Plant');
Select::make('line_stop_id') //linestop_id
->label('Search by Line Stop Code')
->nullable()
// ->options(fn () => LineStop::orderBy('code')->whereHas('productionLineStops')->pluck('code', 'id'))
->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 ) {
return [];
}
return Line::where('plant_id', $plantId)
->pluck('name', 'id');
})
->reactive(),
DateTimePicker::make(name: 'created_from')
->label('Created From')
->placeholder(placeholder: 'Select From DateTime')
->reactive()
->native(false),
TextInput::make('Line Stop Code'),
// Select::make('reason')
// ->label('Filter by Stop Reason')
// ->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),
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']) && empty($data['line_stop_id'])) {
return $query->whereRaw('1 = 0');
}
if ($plant = $data['Plant'] ?? null) {
$query->where('plant_id', $plant);
}
// Filter by Shift
if ($shift = $data['Shift'] ?? null) {
// Get shift data here, if needed, but no block_id filtering yet
$query->where('shift_id', $shift);
}
if ($block = $data['Block'] ?? 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) {
if ($line = $data['Line'] ?? null) {
$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
$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 ($lineStop) {
$query->where('linestop_id', $lineStop->id);
} else {
// 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
}
}
if ($reason = $data['reason'] ?? null) {
$query->where('reason_id', $reason);
// // If we find a matching LineStop, use its id to filter production_line_stops
// if ($lineStop) {
// $query->where('linestop_id', $lineStop->id);
// } else {
// // 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', $code);
}
if ($from = $data['created_from'] ?? null) {
@@ -525,12 +542,39 @@ class ProductionLineStopResource extends Resource
if ($to = $data['created_to'] ?? null) {
$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')
->actions([
Tables\Actions\ViewAction::make(),
@@ -546,10 +590,15 @@ class ProductionLineStopResource extends Resource
])
->headerActions([
ImportAction::make()
->importer(ProductionLineStopImporter::class)
->maxRows(100000),
ExportAction::make()
->exporter(ProductionLineStopExporter::class),
->importer(ProductionLineStopImporter::class)
->visible(function() {
return Filament::auth()->user()->can('view import production line stop');
}),
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\Resources\ProductionPlanResource\Pages;
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\Shift;
use Carbon\Carbon;
use Filament\Facades\Filament;
use Filament\Forms;
use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Form;
use Filament\Forms\Get;
use Filament\Resources\Resource;
@@ -21,7 +25,9 @@ use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Select;
use Filament\Tables\Actions\ExportAction;
use Filament\Tables\Filters\Filter;
use Illuminate\Support\Facades\Request;
class ProductionPlanResource extends Resource
@@ -78,7 +84,7 @@ class ProductionPlanResource extends Resource
return [];
}
return \App\Models\Block::where('plant_id', $get('plant_id'))
return Block::where('plant_id', $get('plant_id'))
->pluck('name', 'id')
->toArray();
})
@@ -466,7 +472,7 @@ class ProductionPlanResource extends Resource
->required()
->integer()
->label('Production Quantity')
->readOnly()
->readOnly(fn (callable $get) => !$get('id'))
->default(0),
Forms\Components\TextInput::make('id')
->hidden()
@@ -520,14 +526,11 @@ class ProductionPlanResource extends Resource
->numeric()
->sortable(),
Tables\Columns\TextColumn::make('line.name')
->sortable()
->searchable(),
->sortable(),// ->searchable(),
Tables\Columns\TextColumn::make('shift.name')
->sortable()
->searchable(),
->sortable(),// ->searchable(),
Tables\Columns\TextColumn::make('plant.name')
->sortable()
->searchable(),
->sortable(),// ->searchable(),
Tables\Columns\TextColumn::make('operator_id')
->label('Operator ID')
->sortable(),
@@ -546,7 +549,138 @@ class ProductionPlanResource extends Resource
])
->filters([
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([
Tables\Actions\ViewAction::make(),
Tables\Actions\EditAction::make(),
@@ -561,10 +695,15 @@ class ProductionPlanResource extends Resource
])
->headerActions([
ImportAction::make()
->importer(ProductionPlanImporter::class)
->maxRows(100000),
ExportAction::make()
->exporter(ProductionPlanExporter::class),
->importer(ProductionPlanImporter::class)
->visible(function() {
return Filament::auth()->user()->can('view import production plan');
}),
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\RelationManagers;
use App\Forms\Components\PlantSelect;
use App\Models\Block;
use App\Models\Item;
use App\Models\Line;
use App\Models\Plant;
use App\Models\ProductionQuantity;
use App\Models\Shift;
use Carbon\Carbon;
use Filament\Facades\Filament;
use Filament\Forms;
use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\Hidden;
use Filament\Forms\Form;
use Filament\Forms\Get;
@@ -25,13 +29,14 @@ use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Notifications\Notification;
use Filament\Tables\Actions\ExportAction;
use Livewire\Livewire;
// use Filament\Forms\Components\View;
use Filament\Tables\Actions\FilamentExportBulkAction;
use Filament\Tables\Filters\Filter;
class ProductionQuantityResource extends Resource
{
@@ -129,7 +134,7 @@ class ProductionQuantityResource extends Resource
return [];
}
return \App\Models\Block::where('plant_id', $get('plant_id'))
return Block::where('plant_id', $get('plant_id'))
->pluck('name', 'id')
->toArray();
})
@@ -235,7 +240,7 @@ class ProductionQuantityResource extends Resource
return [];
}
return \App\Models\Line::where('plant_id', $get('plant_id'))
return Line::where('plant_id', $get('plant_id'))
->pluck('name', 'id')
->toArray();
})
@@ -895,8 +900,10 @@ class ProductionQuantityResource extends Resource
->required(),
Forms\Components\Hidden::make('success_msg')
->required(),
Forms\Components\Hidden::make('item_code')
Forms\Components\Hidden::make('item_id')
->required(),
Forms\Components\Hidden::make('sap_msg_status'),
Forms\Components\Hidden::make('sap_msg_description'),
//->unique(ignoreRecord: true),
// ->autocapitalize('characters'),
// ->columnSpanFull(),
@@ -940,39 +947,265 @@ class ProductionQuantityResource extends Resource
->numeric()
->sortable(),
Tables\Columns\TextColumn::make('production_order')
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('item.code')
->sortable()
->searchable(),
->label('Production Order')
->sortable(),// ->searchable(),
Tables\Columns\TextColumn::make('serial_number')
->sortable()
->searchable(),
->label('Serial Number')
->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')
->label('Line')
->sortable(),
Tables\Columns\TextColumn::make('shift.name')
->label('Shift')
->sortable(),
Tables\Columns\TextColumn::make('plant.name')
->label('Plant')
->sortable(),
Tables\Columns\TextColumn::make('operator_id')
->label('Operator ID')
Tables\Columns\TextColumn::make('sap_msg_status')
->label('SAP Message Status')
->sortable(),
Tables\Columns\TextColumn::make('sap_msg_description')
->label('SAP Message Description')
->sortable(),
Tables\Columns\TextColumn::make('created_at')
->label('Created At')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('updated_at')
->label('Updated At')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('deleted_at')
->label('Deleted At')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('operator_id')
->label('Operator ID')
->sortable(),
])
->filters([
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([
Tables\Actions\ViewAction::make(),
Tables\Actions\EditAction::make(),

View File

@@ -162,6 +162,7 @@ class CreateProductionQuantity extends CreateRecord
->body($e->getMessage())
->danger()
// ->persistent()
->seconds(2)
->send();
return;
}
@@ -179,6 +180,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -186,6 +189,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Invalid QR')
->body("Scan the valid QR code.<br>(Ex: Item_Code|Serial_Number )")
->danger()
->seconds(2)
->send();
return;
}
@@ -201,6 +205,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> null,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -208,6 +214,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Choose Plant')
->body("Please select a plant first.")
->danger()
->seconds(2)
->send();
return;
}
@@ -221,6 +228,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> null,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -228,6 +237,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Choose Block')
->body("Please select a block first.")
->danger()
->seconds(2)
->send();
return;
}
@@ -241,6 +251,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> null,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -248,6 +260,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Choose Shift')
->body("Please select a shift first.")
->danger()
->seconds(2)
->send();
return;
}
@@ -261,6 +274,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> null,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -268,6 +283,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Choose Line')
->body("Please select a line first.")
->danger()
->seconds(2)
->send();
return;
}
@@ -281,12 +297,15 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> null,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
Notification::make()
->title('Please scan the production order first.')
->danger()
->seconds(2)
->send();
return;
}
@@ -302,6 +321,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> null,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -310,6 +331,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Invalid Production Order')
->body("Must contain numeric values only.")
->danger()
->seconds(2)
->send();
return;
}
@@ -324,6 +346,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> null,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -332,6 +356,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Invalid Production Order')
->body("Must contain at least 7 digits.<br>Must start with a non-zero digit.")
->danger()
->seconds(2)
->send();
return;
}
@@ -378,6 +403,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -385,6 +412,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Invalid Shift')
->body("Please select a valid shift.")
->danger()
->seconds(2)
->send();
//$set('validationError', 'Curr.'.$currentDateTime.' (From: '.$from_dt.', To: '.$to_dt.')');
return;
@@ -400,6 +428,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -445,6 +475,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -482,6 +514,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -489,6 +523,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Plan Not Found')
->body("Please set production plan first.")
->danger()
->seconds(2)
->send();
//$set('validationError', 'Curr.'.$currentDateTime.' (From: '.$from_dt.', To: '.$to_dt.')');
return;
@@ -507,6 +542,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -514,6 +551,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Invalid Shift')
->body("Please select a valid shift.")
->danger()
->seconds(2)
->send();
//$set('validationError', 'Curr.'.$currentDateTime.' (From: '.$from_dt.', To: '.$to_dt.')');
return;
@@ -555,6 +593,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -562,6 +602,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Plan Not Found')
->body("Please set production plan first.")
->danger()
->seconds(2)
->send();
//$set('validationError', 'Curr.'.$currentDateTime.' (From: '.$from_dt.', To: '.$to_dt.')');
return;
@@ -599,6 +640,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -606,6 +649,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Plan Not Found')
->body("Please set production plan first.")
->danger()
->seconds(2)
->send();
//$set('validationError', 'Curr.'.$currentDateTime.' (From: '.$from_dt.', To: '.$to_dt.')');
return;
@@ -624,6 +668,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -631,6 +677,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Invalid Shift')
->body("Please select a valid shift.")
->danger()
->seconds(2)
->send();
//$set('validationError', 'Curr.'.$currentDateTime.' (From: '.$from_dt.', To: '.$to_dt.')');
return;
@@ -650,6 +697,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -666,6 +715,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -674,6 +725,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Invalid QR')
->body("Scan the valid QR code.<br>(Ex: Item_Code|Serial_Number )")
->danger()
->seconds(2)
->send();
return;
}
@@ -693,6 +745,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -701,6 +755,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Invalid Item Code')
->body("Item code must contain alpha-numeric values only.")
->danger()
->seconds(2)
->send();
return;
}
@@ -714,6 +769,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -722,6 +779,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Invalid Item Code')
->body("Item code must be at least 6 digits.")
->danger()
->seconds(2)
->send();
return;
}
@@ -735,6 +793,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -743,7 +803,8 @@ class CreateProductionQuantity extends CreateRecord
->title('Invalid Serial Number')
->body("Serial Number must contain alpha-numeric values only.")
->danger()
->duration(800)
// ->duration(800)
->seconds(2)
->send();
return;
}
@@ -757,6 +818,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -765,7 +828,8 @@ class CreateProductionQuantity extends CreateRecord
->title('Invalid Serial Number')
->body("Serial Number must be at least 9 digits.")
->danger()
->duration(800)
// ->duration(800)
->seconds(2)
->send();
return;
}
@@ -780,6 +844,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -788,6 +854,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Invalid QR')
->body("Scan the valid QR code.<br>(Ex: Item_Code|Serial_Number )")
->danger()
->seconds(2)
->send();
return;
}
@@ -802,6 +869,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -825,6 +894,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -832,6 +903,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Unknown Item Code')
->body("Item code does not exist in master data.")
->danger()
->seconds(2)
->send();
return;
}
@@ -854,6 +926,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null,
'success_msg'=> 'Y',
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -871,6 +945,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -878,6 +954,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Duplicate Serial Number')
->body("Serial number already exist in database for choosed plant.")
->danger()
->seconds(2)
->send();
return;
}
@@ -893,6 +970,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -901,6 +980,7 @@ class CreateProductionQuantity extends CreateRecord
->title('Unknown Item Code')
->body("Item code does not exist in master data for choosed plant.")
->danger()
->seconds(2)
->send();
return;
}
@@ -915,6 +995,8 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $this->recQr,
]);
@@ -924,6 +1006,7 @@ class CreateProductionQuantity extends CreateRecord
->body("Please, scan the valid QR code.")
->danger()
// ->persistent()
->seconds(2)
->send();
return;
}
@@ -956,18 +1039,22 @@ class CreateProductionQuantity extends CreateRecord
'serial_number'=> null,
'success_msg'=> null,
'production_order'=> $this->prodOrder,
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id'=> $operatorName,
'recent_qr' => $itemCode.' | '.$this->sNoId,
]);
Notification::make()
->title("Valid QR Found") // {$operatorName}
->body("Valid QR code scanned: {$this->qrData}.")
->body("Valid QR code scanned:<br>{$this->qrData}")
->success()
// ->persistent()
->seconds(2)
->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
{
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;
use Filament\Notifications\Notification;
use Filament\Support\Assets\Js;
use Filament\Support\RawJs;
use Filament\Widgets\ChartWidget;
use Illuminate\Contracts\View\View;
class ItemOverview extends ChartWidget
{
@@ -16,162 +19,166 @@ class ItemOverview extends ChartWidget
protected $listeners = ['filtersUpdated' => '$refresh'];
protected function getData(): array
{
$activeFilter = $this->filter;
$selectedPlant = session('selected_plant') ?? session('select_plant');
$selectedLine = session('selected_line') ?? session('select_line');
if (!$selectedPlant || !$selectedLine)
public function getData(): array
{
return [
'datasets' => [],
'labels' => [],
];
}
$activeFilter = $this->filter;
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)';
}
$selectedPlant = session('selected_plant') ?? session('select_plant');
$selectedLine = session('selected_line') ?? session('select_line');
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)
if (!$selectedPlant || !$selectedLine)
{
return [
'datasets' => [],
'labels' => [],
];
}
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)
$allHours = array_fill(0, 24, 0);
$data = array_replace($allHours, $query);
// 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);
// 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)
$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);
}
// Labels: ["8 AM", "9 AM", ..., "7 AM"]
$labels = array_map(fn ($hour) => date("g A", strtotime("$hour:00")), $shiftedKeys);
}
return [
'datasets' => [
[
'label' => match ($activeFilter) {
'this_week' => "Daily Production This Week",
'this_month' => "Weekly Production This Month", // Updated Label
'yesterday' => "Yesterday's Hourly Production",
default => "Today's Hourly Production",
},
'data' => $orderedData,
'borderColor' => 'rgba(75, 192, 192, 1)',
'backgroundColor' => 'rgba(75, 192, 192, 0.2)',
'fill' => false,
'tension' => 0.3,
return [
'datasets' => [
[
'label' => match ($activeFilter) {
'this_week' => "Daily Production This Week",
'this_month' => "Weekly Production This Month", // Updated Label
'yesterday' => "Yesterday's Hourly Production",
default => "Today's Hourly Production",
},
'data' => $orderedData,
'interaction' => [
'mode' => 'nearest',
'axis' => 'x',
'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
{
return 'line';
}
protected function getOptions(): array
{
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
{
return [
@@ -199,7 +233,6 @@ class ItemOverview extends ChartWidget
public static function canView(): bool
{
// Only show on HourlyProduction page
return request()->routeIs([
'filament.pages.hourly-production',
'filament.admin.resources.production-quantities.create',

View File

@@ -175,30 +175,6 @@ class ProductionLineStopChart extends ChartWidget
'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',
'description',
'hourly_quantity',
'uom',
];
public function plant(): BelongsTo
@@ -26,4 +27,9 @@ class Item extends Model
{
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_validation5',
'operator_id',
'uom',
'serial_number',
'sap_msg_status',
'sap_msg_description',
];
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 Spatie\Permission\Models\Role;
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;
@@ -35,6 +38,10 @@ class AppServiceProvider extends ServiceProvider
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');
// if (!Type::hasType('citext')) {

View File

@@ -42,8 +42,6 @@ class AdminPanelProvider extends PanelProvider
->discoverPages(in: app_path('Filament/Pages'), for: 'App\\Filament\\Pages')
->pages([
])
->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\\Filament\\Widgets')
// ->widgets([
// 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;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use App\Models\User;
use Hash;
use Illuminate\Database\Seeder;
class AdminSeeder extends Seeder
@@ -12,6 +13,24 @@ class AdminSeeder extends Seeder
*/
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
{
$this->call(RoleSeeder::class);
$this->call(AdminSeeder::class);
$this->call(UserSeeder::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 material 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' => 'view export production quantities']);
Permission::updateOrCreate(['name' => 'create ProductionQuantities']);
Permission::updateOrCreate(['name' => 'view invoice dashboard']); //invoice dashboard
Permission::updateOrCreate(['name' => 'view production dashboard']); //hourly production
Permission::updateOrCreate(['name' => 'view production line count dashboard']);
Permission::updateOrCreate(['name' => 'view production order 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
{
//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'],
// Data to update/create
[
'name' => 'Dhanabalan S',
'password' => bcrypt('SdHaNa@123'),
@@ -45,18 +22,10 @@ class UserSeeder extends Seeder
'created_at' => now()
]
);
// $user2 = User::firstOrCreate([
// 'name' => 'Dhana',
// 'email' => 'dhana@cripumps.com',
// 'password' => bcrypt('dhana@123'),
// ]);
$user2->assignRole('Super Admin');
$user1->assignRole('Super Admin');
$user3 = User::updateOrCreate(
// Unique identifier
$user2 = User::updateOrCreate(
['email' => 'ranjith@cripumps.com'],
// Data to update/create
[
'name' => 'Ranjith B',
'password' => bcrypt('Ranjii@5503'),
@@ -64,18 +33,10 @@ class UserSeeder extends Seeder
'created_at' => now()
]
);
// $user3 = User::firstOrCreate([
// 'name' => 'Ranjith',
// 'email' => 'ranjith@cripumps.com',
// 'password' => bcrypt('ranjith@123'),
// ]);
$user3->assignRole('Super Admin');
$user2->assignRole('Super Admin');
$user4 = User::updateOrCreate(
// Unique identifier
$user3 = User::updateOrCreate(
['email' => 'srimathi@cripumps.com'],
// Data to update/create
[
'name' => 'Srimathi M',
'password' => bcrypt('MsRi@123'),
@@ -83,12 +44,7 @@ class UserSeeder extends Seeder
'created_at' => now()
]
);
// $user4 = User::firstOrCreate([
// 'name' => 'Srimathi',
// 'email' => 'srimathi@cripumps.com',
// 'password' => bcrypt('srimathi@123'),
// ]);
$user4->assignRole('Super Admin');
$user3->assignRole('Super Admin');
// User::factory()->count(5)->create();
}
}

View File

@@ -3,25 +3,11 @@
{{-- Filters form --}}
{{ $this->filtersForm($this->form) }}
{{-- Chart Widget --}}
@livewire(\App\Filament\Widgets\ItemOverview::class)
{{-- Chart widget --}}
<x-filament-widgets::widgets :widgets="$this->getWidgets()" />
</div>
</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>
</x-filament-panels::page>

View File

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

View File

@@ -114,57 +114,5 @@
</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({
plugins: [
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,
}),
],