44 Commits

Author SHA1 Message Date
dhanabalan
11c3dbf3bc Changed logic in post api and get api of process order
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 14s
Gemini PR Review / Gemini PR Review (pull_request) Successful in 20s
Laravel Pint / pint (pull_request) Failing after 2m33s
Laravel Larastan / larastan (pull_request) Failing after 3m29s
2026-09-23 08:36:42 +05:30
dhanabalan
fef4c64542 Added process order relation in line model file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 17s
Gemini PR Review / Gemini PR Review (pull_request) Successful in 23s
Laravel Pint / pint (pull_request) Failing after 2m45s
Laravel Larastan / larastan (pull_request) Failing after 6m7s
2026-09-22 09:57:27 +05:30
dhanabalan
c0df7b7a4e Added process order relation in item model file
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
2026-09-22 09:56:18 +05:30
dhanabalan
61c714331b Added product char master relation in work group master model file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Gemini PR Review / Gemini PR Review (pull_request) Successful in 16s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Laravel Pint / pint (pull_request) Failing after 2m29s
Laravel Larastan / larastan (pull_request) Failing after 2m33s
2026-09-20 15:25:22 +05:30
dhanabalan
44c658dbbc Added product char master relation in item model file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Successful in 18s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Laravel Larastan / larastan (pull_request) Failing after 4m42s
Laravel Pint / pint (pull_request) Failing after 3m46s
2026-09-20 15:24:08 +05:30
dhanabalan
665bac1bff Added product char master relation in line model file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Successful in 17s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Laravel Pint / pint (pull_request) Failing after 4m39s
Laravel Larastan / larastan (pull_request) Failing after 8m41s
2026-09-20 15:22:47 +05:30
dhanabalan
98cd3b90f8 changed logic in sticker master importer
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Successful in 16s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Laravel Larastan / larastan (pull_request) Failing after 3m38s
Laravel Pint / pint (pull_request) Failing after 5m45s
2026-09-20 15:19:21 +05:30
dhanabalan
1663a7f3f8 changed logic in item importer
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Successful in 16s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Laravel Larastan / larastan (pull_request) Failing after 3m6s
Laravel Pint / pint (pull_request) Failing after 3m32s
2026-09-20 15:16:56 +05:30
dhanabalan
973a69c944 Added product char master relation in plant model
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Gemini PR Review / Gemini PR Review (pull_request) Successful in 16s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Laravel Larastan / larastan (pull_request) Failing after 4m45s
Laravel Pint / pint (pull_request) Failing after 5m18s
2026-09-20 15:12:57 +05:30
dhanabalan
4118c26397 Changed logic in product chjaracteristic master exporter
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Gemini PR Review / Gemini PR Review (pull_request) Successful in 15s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Laravel Larastan / larastan (pull_request) Failing after 2m26s
Laravel Pint / pint (pull_request) Failing after 2m32s
2026-09-20 15:06:26 +05:30
dhanabalan
6489a25ef1 changed the logic in product characteristic master importer
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Successful in 16s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 14s
Laravel Pint / pint (pull_request) Failing after 2m48s
Laravel Larastan / larastan (pull_request) Failing after 4m27s
2026-09-20 15:04:22 +05:30
dhanabalan
1d0d3052dc Added all the process order logic in product characteristic master resource page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 14s
Gemini PR Review / Gemini PR Review (pull_request) Successful in 18s
Laravel Pint / pint (pull_request) Failing after 2m40s
Laravel Larastan / larastan (pull_request) Failing after 2m45s
2026-09-20 15:02:21 +05:30
dhanabalan
a3e48ef7e4 Added characteristics values route in api page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
Gemini PR Review / Gemini PR Review (pull_request) Successful in 15s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Laravel Larastan / larastan (pull_request) Failing after 2m50s
Laravel Pint / pint (pull_request) Failing after 2m41s
2026-09-20 14:59:28 +05:30
dhanabalan
60d5b9ca6b Added all the process order related logic in characteristics controller
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Gemini PR Review / Gemini PR Review (pull_request) Successful in 17s
Laravel Larastan / larastan (pull_request) Failing after 3m16s
Laravel Pint / pint (pull_request) Failing after 3m41s
2026-09-20 14:56:19 +05:30
dhanabalan
94584d8270 Added all teh process order logic
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Gemini PR Review / Gemini PR Review (pull_request) Successful in 15s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Laravel Pint / pint (pull_request) Failing after 2m23s
Laravel Larastan / larastan (pull_request) Failing after 2m41s
2026-09-20 14:54:40 +05:30
dhanabalan
d8f770cce6 Added machine relation in line model file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Gemini PR Review / Gemini PR Review (pull_request) Successful in 15s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Laravel Larastan / larastan (pull_request) Failing after 4m12s
Laravel Pint / pint (pull_request) Failing after 5m13s
2026-09-20 14:34:49 +05:30
dhanabalan
371052d9c2 Changed machine exporter logic
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Gemini PR Review / Gemini PR Review (pull_request) Successful in 15s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Laravel Larastan / larastan (pull_request) Failing after 4m33s
Laravel Pint / pint (pull_request) Failing after 4m58s
2026-09-20 14:27:19 +05:30
dhanabalan
793a98484b changed machine importer logic
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 13s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Gemini PR Review / Gemini PR Review (pull_request) Successful in 17s
Laravel Pint / pint (pull_request) Failing after 2m24s
Laravel Larastan / larastan (pull_request) Failing after 3m29s
2026-09-20 14:24:51 +05:30
dhanabalan
659fa9e550 Added machine relation in work group master model file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
Gemini PR Review / Gemini PR Review (pull_request) Successful in 18s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 14s
Laravel Pint / pint (pull_request) Failing after 3m39s
Laravel Larastan / larastan (pull_request) Failing after 3m47s
2026-09-20 12:51:37 +05:30
dhanabalan
cd43e338d7 Added machine relation in model file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Successful in 16s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Laravel Larastan / larastan (pull_request) Failing after 2m54s
Laravel Pint / pint (pull_request) Failing after 3m3s
2026-09-20 12:50:18 +05:30
dhanabalan
c70c37bfcf changed logic in machine page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Successful in 17s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Laravel Larastan / larastan (pull_request) Failing after 4m24s
Laravel Pint / pint (pull_request) Failing after 4m26s
2026-09-20 12:47:24 +05:30
dhanabalan
494184d5bc changed logic in work group master exporter page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Successful in 16s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Laravel Larastan / larastan (pull_request) Failing after 4m3s
Laravel Pint / pint (pull_request) Failing after 3m38s
2026-09-20 12:44:13 +05:30
dhanabalan
632e3e12fe changed logic in work group master importer logic
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Successful in 17s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Laravel Larastan / larastan (pull_request) Failing after 6m3s
Laravel Pint / pint (pull_request) Failing after 4m39s
2026-09-20 12:42:31 +05:30
dhanabalan
8947eeff7f Changed logic in work group master page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Successful in 15s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Laravel Larastan / larastan (pull_request) Failing after 4m0s
Laravel Pint / pint (pull_request) Failing after 4m46s
2026-09-20 12:40:50 +05:30
dhanabalan
0cd8e3590d Changed logic in line exporter
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Successful in 16s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Laravel Larastan / larastan (pull_request) Failing after 3m42s
Laravel Pint / pint (pull_request) Failing after 14m25s
2026-09-20 12:35:35 +05:30
dhanabalan
13cc730471 Added lofic in line importer
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Successful in 17s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Laravel Pint / pint (pull_request) Failing after 2m39s
Laravel Larastan / larastan (pull_request) Failing after 7m0s
2026-09-20 12:34:17 +05:30
dhanabalan
44ea179b7d Added filter in line resource page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Successful in 16s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Laravel Larastan / larastan (pull_request) Failing after 2m34s
Laravel Pint / pint (pull_request) Failing after 4m3s
2026-09-20 12:32:40 +05:30
dhanabalan
595f383247 Added created by an updated by in sticker master model file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Gemini PR Review / Gemini PR Review (pull_request) Successful in 17s
Laravel Larastan / larastan (pull_request) Failing after 4m44s
Laravel Pint / pint (pull_request) Failing after 5m19s
2026-09-20 12:31:00 +05:30
dhanabalan
c3d80fc950 Added created by and updated by in sticker master table
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 15s
Gemini PR Review / Gemini PR Review (pull_request) Successful in 21s
Laravel Pint / pint (pull_request) Failing after 4m18s
Laravel Larastan / larastan (pull_request) Failing after 4m54s
2026-09-20 12:01:08 +05:30
dhanabalan
81e7c2ef49 Added line capacity column in lines table
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 14s
Gemini PR Review / Gemini PR Review (pull_request) Successful in 18s
Laravel Pint / pint (pull_request) Failing after 4m0s
Laravel Larastan / larastan (pull_request) Failing after 4m39s
2026-09-20 11:38:54 +05:30
dhanabalan
ab179d0128 Added characteristic value relation in plant model file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Gemini PR Review / Gemini PR Review (pull_request) Successful in 18s
Laravel Larastan / larastan (pull_request) Failing after 2m42s
Laravel Pint / pint (pull_request) Failing after 3m29s
2026-09-20 11:29:36 +05:30
dhanabalan
4ccdf4de73 Added characteristic value policy file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 14s
Gemini PR Review / Gemini PR Review (pull_request) Successful in 18s
Laravel Larastan / larastan (pull_request) Failing after 4m37s
Laravel Pint / pint (pull_request) Failing after 4m51s
2026-09-20 11:25:33 +05:30
dhanabalan
48571cfe79 Added characteristic value importer and exporter
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
2026-09-20 11:25:00 +05:30
dhanabalan
8f3432b57a Added characteristics values resource pages
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
2026-09-20 11:24:25 +05:30
dhanabalan
d1462c1539 Added characteristic value model file
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
2026-09-20 11:21:47 +05:30
dhanabalan
46df0ef93a Added characteristic value migration file
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 16s
2026-09-20 11:20:33 +05:30
dhanabalan
eda4648741 Added process order relation in plant model file
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 14s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Gemini PR Review / Gemini PR Review (pull_request) Successful in 19s
Laravel Pint / pint (pull_request) Failing after 2m58s
Laravel Larastan / larastan (pull_request) Failing after 3m44s
2026-09-20 11:05:50 +05:30
dhanabalan
c1231df86e Added process order resource page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 14s
Gemini PR Review / Gemini PR Review (pull_request) Successful in 18s
Laravel Larastan / larastan (pull_request) Failing after 2m42s
Laravel Pint / pint (pull_request) Failing after 4m26s
2026-09-20 10:59:21 +05:30
dhanabalan
dc95259fc5 fix conflict issue in sticker pdf service
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 12s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 13s
Gemini PR Review / Gemini PR Review (pull_request) Successful in 20s
Laravel Pint / pint (pull_request) Failing after 2m32s
Laravel Larastan / larastan (pull_request) Failing after 5m36s
2026-09-20 10:50:49 +05:30
dhanabalan
6b3c693b5e Merge remote-tracking branch 'origin/ranjith-dev' into ranjith-dev
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 16s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 1m6s
Gemini PR Review / Gemini PR Review (pull_request) Successful in 1m14s
Laravel Pint / pint (pull_request) Failing after 2m50s
Laravel Larastan / larastan (pull_request) Failing after 4m56s
2026-09-20 10:25:53 +05:30
dhanabalan
b6b5ef744d Added al columns in process order 2026-09-20 10:19:32 +05:30
dhanabalan
666c219b71 Added all pending columns in process order table 2026-09-20 09:36:44 +05:30
dhanabalan
abcedb5aa4 removed readOnly in user page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 16s
Gemini PR Review / Gemini PR Review (pull_request) Successful in 17s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 18s
Laravel Pint / pint (pull_request) Failing after 2m6s
Laravel Larastan / larastan (pull_request) Failing after 2m10s
2026-07-29 12:38:40 +05:30
dhanabalan
ea7c1d90d0 Added forgot passowrd logic in qds filament login
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 22s
Gemini PR Review / Gemini PR Review (pull_request) Successful in 20s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 19s
Laravel Pint / pint (pull_request) Failing after 2m5s
Laravel Larastan / larastan (pull_request) Failing after 2m10s
2026-07-29 12:20:43 +05:30
82 changed files with 9278 additions and 3057 deletions

View File

@@ -34,6 +34,7 @@ class ProductionPlanExport implements FromArray, WithHeadings, WithMapping
// Add dynamic headings for each date: Target / Produced
foreach ($this->dates as $date) {
$headings[] = $date . ' - Line Capacity';
$headings[] = $date . ' - Target Plan';
$headings[] = $date . ' - Produced Quantity';
}
@@ -43,19 +44,17 @@ class ProductionPlanExport implements FromArray, WithHeadings, WithMapping
public function map($row): array
{
$mapped = [
$mapped = [
$row['plant_name'] ?? '',
$row['line_name'] ?? '',
$row['item_code'] ?? '',
];
// Add daily target and produced quantity for each date
foreach ($this->dates as $date) {
// $mapped[] = $row['daily_target_dynamic'] ?? 0;
$mapped[] = $row['daily_line_capacity'][$date] ?? '-';
$mapped[] = $row['daily_target_dynamic'][$date] ?? '-';
$mapped[] = $row['produced_quantity'][$date] ?? 0;
$mapped[] = $row['produced_quantity'][$date] ?? '-';
}
return $mapped;
}

View File

@@ -0,0 +1,81 @@
<?php
namespace App\Filament\Exports;
use App\Models\CharacteristicValue;
use App\Models\ProductCharacteristicsMaster;
use Filament\Actions\Exports\ExportColumn;
use Filament\Actions\Exports\Exporter;
use Filament\Actions\Exports\Models\Export;
class CharacteristicValueExporter extends Exporter
{
protected static ?string $model = CharacteristicValue::class;
public static function getColumns(): array
{
static $rowNumber = 0;
return [
ExportColumn::make('no')
->label('NO')
->state(function ($record) use (&$rowNumber) {
// Increment and return the row number
return ++$rowNumber;
}),
ExportColumn::make('plant.code')
->label('PLANT CODE'),
ExportColumn::make('line.name')
->label('LINE NAME'),
ExportColumn::make('item.code')
->label('ITEM CODE'),
ExportColumn::make('item.description')
->label('DESCRIPTION'),
ExportColumn::make('machine.work_center')
->label('WORK CENTER'),
ExportColumn::make('process_order')
->label('PROCESS ORDER'),
ExportColumn::make('coil_number')
->label('COIL NUMBER'),
ExportColumn::make('status')
->label('STATUS'),
ExportColumn::make('spec_value')
->label('Spec. Value')
->formatStateUsing(function ($record) {
$specVal = ProductCharacteristicsMaster::where('plant_id', $record->plant_id)
->where('item_id', $record->item_id)
->where('line_id', $record->line_id)
->where('machine_id', $record->machine_id)
->first();
return $specVal?->lower . ' - ' . $specVal?->upper;
}),
ExportColumn::make('observed_value')
->label('OBSERVED VALUE'),
ExportColumn::make('created_at')
->label('CREATED AT'),
ExportColumn::make('created_by')
->label('CREATED BY'),
ExportColumn::make('updated_at')
->label('UPDATED AT'),
ExportColumn::make('updated_by')
->label('UPDATED BY'),
ExportColumn::make('deleted_at')
->enabledByDefault(false)
->label('DELETED AT'),
];
}
public static function getCompletedNotificationBody(Export $export): string
{
$body = 'Your characteristic value 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

@@ -24,12 +24,12 @@ class LineExporter extends Exporter
// Increment and return the row number
return ++$rowNumber;
}),
ExportColumn::make('plant.name')
->label('PLANT'),
ExportColumn::make('plant.code')
->label('PLANT CODE'),
ExportColumn::make('name')
->label('NAME'),
->label('LINE NAME'),
ExportColumn::make('type')
->label('TYPE'),
->label('LINE TYPE'),
ExportColumn::make('no_of_operation')
->label('NO OF OPERATION'),
ExportColumn::make('workGroup1.name')
@@ -84,10 +84,10 @@ class LineExporter extends Exporter
public static function getCompletedNotificationBody(Export $export): string
{
$body = 'Your line export has completed and ' . number_format($export->successful_rows) . ' ' . str('row')->plural($export->successful_rows) . ' exported.';
$body = 'Your line 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.';
$body .= ' '.number_format($failedRowsCount).' '.str('row')->plural($failedRowsCount).' failed to export.';
}
return $body;

View File

@@ -22,16 +22,16 @@ class MachineExporter extends Exporter
// Increment and return the row number
return ++$rowNumber;
}),
ExportColumn::make('plant.name')
->label('PLANT'),
ExportColumn::make('plant.code')
->label('PLANT CODE'),
ExportColumn::make('line.name')
->label('LINE'),
->label('LINE NAME'),
ExportColumn::make('name')
->label('MACHINE'),
->label('DESCRIPTION'),
ExportColumn::make('work_center')
->label('WORK CENTER'),
ExportColumn::make('workGroupMaster.name')
->label('WORK GROUP CENTER'),
->label('GROUP WORK CENTER'),
ExportColumn::make('created_at')
->label('CREATED AT'),
ExportColumn::make('updated_at')
@@ -44,10 +44,10 @@ class MachineExporter extends Exporter
public static function getCompletedNotificationBody(Export $export): string
{
$body = 'Your machine export has completed and ' . number_format($export->successful_rows) . ' ' . str('row')->plural($export->successful_rows) . ' exported.';
$body = 'Your machine 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.';
$body .= ' '.number_format($failedRowsCount).' '.str('row')->plural($failedRowsCount).' failed to export.';
}
return $body;

View File

@@ -24,32 +24,41 @@ class ProcessOrderExporter extends Exporter
}),
ExportColumn::make('plant.code')
->label('PLANT CODE'),
ExportColumn::make('line.name')
->label('LINE NAME'),
ExportColumn::make('item.code')
->label('ITEM CODE'),
ExportColumn::make('item.description')
->label('ITEM DESCRIPTION'),
ExportColumn::make('process_order')
->label('PROCESS ORDER'),
ExportColumn::make('coil_number')
->label('COIL NUMBER'),
ExportColumn::make('order_quantity')
->label('ORDER QUANTITY'),
ExportColumn::make('updated_order_quantity')
->label('UPDATED ORDER QUANTITY'),
ExportColumn::make('received_quantity')
->label('RECEIVED QUANTITY'),
ExportColumn::make('sfg_number')
->label('SFG NUMBER'),
ExportColumn::make('machine_name')
->label('MACHINE ID'),
->label('MACHINE NAME'),
ExportColumn::make('scrap_quantity')
->label('SCRAP QUANTITY'),
ExportColumn::make('rework_status')
->label('REWORK STATUS'),
ExportColumn::make('created_at')
->label('CREATED AT'),
ExportColumn::make('updated_at')
->label('UPDATED AT'),
ExportColumn::make('created_by')
->label('CREATED BY'),
ExportColumn::make('updated_at')
->label('UPDATED AT'),
ExportColumn::make('updated_by')
->label('UPDATED BY'),
ExportColumn::make('deleted_at')
->enabledByDefault(false)
->label('DELETED AT'),
];
}

View File

@@ -14,6 +14,7 @@ class ProductCharacteristicsMasterExporter extends Exporter
public static function getColumns(): array
{
static $rowNumber = 0;
return [
ExportColumn::make('no')
->label('NO')
@@ -21,28 +22,32 @@ class ProductCharacteristicsMasterExporter extends Exporter
// Increment and return the row number
return ++$rowNumber;
}),
ExportColumn::make('plant.name')
->label('PLANT'),
ExportColumn::make('plant.code')
->label('PLANT CODE'),
ExportColumn::make('item.code')
->label('ITEM CODE'),
ExportColumn::make('item.description')
->label('ITEM DESCRIPTION'),
ExportColumn::make('line.name')
->label('LINE NAME'), //machine.workGroupMaster.name
->label('LINE NAME'), // machine.workGroupMaster.name
ExportColumn::make('machine.workGroupMaster.name')
->label('WORK GROUP MASTER'),
->label('GROUP WORK CENTER'),
ExportColumn::make('machine.work_center')
->label('WORK CENTER'),
ExportColumn::make('characteristics_type')
->label('CHARACTERISTICS TYPE'),
ExportColumn::make('name')
->label('NAME'),
->label('CHARACTERISTICS NAME'),
ExportColumn::make('category')
->label('CATEGORY'),
ExportColumn::make('inspection_type')
->label('INSPECTION TYPE'),
ExportColumn::make('upper')
->label('UPPER'),
ExportColumn::make('lower')
->label('LOWER'),
ExportColumn::make('middle')
->label('MIDDLE'),
ExportColumn::make('upper')
->label('UPPER'),
ExportColumn::make('created_at')
->label('CREATED AT'),
ExportColumn::make('updated_at')
@@ -59,10 +64,10 @@ class ProductCharacteristicsMasterExporter extends Exporter
public static function getCompletedNotificationBody(Export $export): string
{
$body = 'Your product characteristics master export has completed and ' . number_format($export->successful_rows) . ' ' . str('row')->plural($export->successful_rows) . ' exported.';
$body = 'Your product characteristics master 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.';
$body .= ' '.number_format($failedRowsCount).' '.str('row')->plural($failedRowsCount).' failed to export.';
}
return $body;

View File

@@ -14,6 +14,7 @@ class WorkGroupMasterExporter extends Exporter
public static function getColumns(): array
{
static $rowNumber = 0;
return [
ExportColumn::make('no')
->label('NO')
@@ -21,32 +22,32 @@ class WorkGroupMasterExporter extends Exporter
// Increment and return the row number
return ++$rowNumber;
}),
ExportColumn::make('plant.name')
->label('PLANT'),
ExportColumn::make('plant.code')
->label('PLANT CODE'),
ExportColumn::make('name')
->label('NAME'),
->label('GROUP WORK CENTER'),
ExportColumn::make('description')
->label('DESCRIPTION'),
->label('DESCRIPTION'),
ExportColumn::make('operation_number')
->label('OPERATION NUMBER'),
ExportColumn::make('created_by')
->label('CREATED BY'),
->label('OPERATION NUMBER'),
ExportColumn::make('created_at')
->label('CREATED AT'),
->label('CREATED AT'),
ExportColumn::make('created_by')
->label('CREATED BY'),
ExportColumn::make('updated_at')
->label('UPDATED AT'),
->label('UPDATED AT'),
ExportColumn::make('deleted_at')
->label('DELETED AT')
->enabledByDefault(false),
->label('DELETED AT')
->enabledByDefault(false),
];
}
public static function getCompletedNotificationBody(Export $export): string
{
$body = 'Your work group master export has completed and ' . number_format($export->successful_rows) . ' ' . str('row')->plural($export->successful_rows) . ' exported.';
$body = 'Your work group master 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.';
$body .= ' '.number_format($failedRowsCount).' '.str('row')->plural($failedRowsCount).' failed to export.';
}
return $body;

View File

@@ -0,0 +1,372 @@
<?php
namespace App\Filament\Imports;
use App\Models\CharacteristicValue;
use App\Models\Item;
use App\Models\Line;
use App\Models\Machine;
use App\Models\Plant;
use App\Models\ProcessOrder;
use App\Models\ProductCharacteristicsMaster;
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 Str;
class CharacteristicValueImporter extends Importer
{
protected static ?string $model = CharacteristicValue::class;
public static function getColumns(): array
{
return [
ImportColumn::make('plant')
->requiredMapping()
->exampleHeader('Plant Code')
->example('1000')
->label('Plant Code')
->relationship(resolveUsing: 'code')
->rules(['required']),
ImportColumn::make('line')
->requiredMapping()
->exampleHeader('Line Name')
->example('4 inch pump line')
->label('Line Name')
->relationship(resolveUsing: 'name')
->rules(['required']),
ImportColumn::make('item')
->requiredMapping()
->exampleHeader('Item Code')
->example('123456')
->label('Item Code')
->relationship(resolveUsing: 'code')
->rules(['required']),
ImportColumn::make('machine')
->requiredMapping()
->exampleHeader('Work Center')
->example('RMGS09745')
->label('Work Center')
->relationship(resolveUsing: 'work_center')
->rules(['required']),
ImportColumn::make('process_order')
->requiredMapping()
->exampleHeader('Process Order')
->example('23455256352')
->label('Process Order'),
ImportColumn::make('coil_number')
->requiredMapping()
->exampleHeader('Coil Number')
->example('0')
->label('Coil Number'),
ImportColumn::make('status')
->requiredMapping()
->exampleHeader('Status')
->example('Ok')
->label('Status'),
ImportColumn::make('observed_value')
->requiredMapping()
->exampleHeader('Observed Value')
->example('RAW01234')
->label('Observed Value'),
ImportColumn::make('created_by')
->requiredMapping()
->exampleHeader('Created By')
->example('RAW01234')
->label('Created By'),
ImportColumn::make('created_at')
->requiredMapping()
->exampleHeader('Created DateTime')
->example('01-01-2025 08:00:00')
->label('Created DateTime')
->rules(['required']),
ImportColumn::make('updated_at')
->requiredMapping()
->exampleHeader('Updated DateTime')
->example('01-01-2025 08:00:00')
->label('Updated DateTime')
->rules(['required']),
];
}
public function resolveRecord(): ?CharacteristicValue
{
// return CharacteristicValue::firstOrNew([
// // Update existing records, matching them by `$this->data['column_name']`
// 'email' => $this->data['email'],
// ]);
$warnMsg = [];
$plantId = null;
$itemId = null;
$lineId = null;
$machineId = null;
// $itemAgainstPlant = null;
$plantCode = $this->data['plant'];
$processOrder = trim($this->data['process_order'] ?? '');
$iCode = trim($this->data['item']);
$workCenter = trim($this->data['machine']);
$lineName = trim($this->data['line']);
$coilNo = trim($this->data['coil_number']);
$obserVal = trim($this->data['observed_value']);
$status = trim($this->data['status']);
$createdBy = trim($this->data['created_by']);
if ($plantCode == null || $plantCode == '') {
$warnMsg[] = 'Plant code cannot be empty';
} elseif ($iCode == null || $iCode == '') {// process_order
$warnMsg[] = 'Item code cannot be empty';
} elseif ($processOrder == null || $processOrder == '') {//
$warnMsg[] = 'Process Order cannot be empty';
} elseif ($workCenter == null || $workCenter == '') {
$warnMsg[] = 'Work center cannot be empty';
} elseif ($lineName == null || $lineName == '') {
$warnMsg[] = 'Line name cannot be empty';
} elseif ($coilNo == null || $coilNo == '') {
$warnMsg[] = 'Coil number cannot be empty';
} elseif ($obserVal == null || $obserVal == '') {
$warnMsg[] = 'Observed value cannot be empty';
} elseif ($status == null || $status == '') {
$warnMsg[] = 'Status cannot be empty';
}
if (Str::length($plantCode) > 0 && (Str::length($plantCode) < 4 || ! is_numeric($plantCode) || ! preg_match('/^[1-9]\d{3,}$/', $plantCode))) {
$warnMsg[] = 'Invalid plant code found';
} else {
$plant = Plant::where('code', $plantCode)->first();
if (! $plant) {
$warnMsg[] = 'Plant not found';
} else {
$plantId = $plant->id;
}
}
if (Str::length($iCode) > 0 && (Str::length($iCode) < 6 || ! ctype_alnum($iCode))) {
$warnMsg[] = 'Invalid item code found';
} else {
$itemCode = Item::where('code', $iCode)->first();
if (! $itemCode) {
$warnMsg[] = 'Item code not found';
} else {
if ($plantId) {
$itemCode = Item::where('code', $iCode)->where('plant_id', $plantId)->first();
if (! $itemCode) {
$warnMsg[] = 'Item code not found for the given plant';
} else {
$itemId = $itemCode->id;
}
}
}
}
$lineExists = Line::where('name', $lineName)->first();
if (! $lineExists) {
$warnMsg[] = 'Line name not found';
} else {
if ($plantId) {
$lineAgainstPlant = Line::where('name', $lineName)->where('plant_id', $plantId)->first();
if (! $lineAgainstPlant) {
$warnMsg[] = 'Line name not found for the given plant';
} else {
$lineId = $lineAgainstPlant->id;
}
}
}
$workCenterExist = Machine::where('work_center', $workCenter)->first();
if (! $workCenterExist) {
$warnMsg[] = 'Work Center not found';
}
// $workCenterAgainstPlant = Machine::where('work_center', $workCenter)
// ->where('plant_id', $plantId)
// ->first();
// if (!$workCenterAgainstPlant) {
// $warnMsg[] = 'Work center not found for the given plant';
// } else {
// $MachineId = $workCenterAgainstPlant->id;
// }
if ($plantId != null && $lineId != null) {
$machineAgaPlantLine = Machine::where('plant_id', $plantId)
->where('line_id', $lineId)
->where('work_center', $workCenter)
->first();
if (! $machineAgaPlantLine) {
$warnMsg[] = 'Work center not found for the given plant and line';
} else {
$machineId = $machineAgaPlantLine->id;
}
}
if (Str::length($coilNo) > 0 && ! is_numeric($coilNo)) {
$warnMsg[] = 'Coil number should contain only numeric values!';
}
if (Str::length($obserVal) > 0 && ! is_numeric($obserVal)) {
$warnMsg[] = 'Observed value should contain only numeric values!';
}
if (Str::length($status) > 0 && ! in_array($status, ['Ok', 'NotOk'], true)) {
$warnMsg[] = "Status must be either 'Ok' or 'NotOk'!";
}
// else {
// if (Str::length($status) <= 0 || ! is_numeric($status) || ! preg_match('/^\d+(\.\d+)?$/', $status)
// ) {
// $status = 'NotOk';
// } else {
// $specVal = ProductCharacteristicsMaster::where('plant_id', $plantId)->where('item_id', $itemId)->where('line_id', $lineId)->where('machine_id', $machineId)->first();
// if (! $specVal) {
// $status = 'NotOk';
// }
// $lowLimit = $specVal?->lower ?? 0;
// $uppLimit = $specVal?->upper ?? 0;
// if (Str::length($lowLimit) <= 0 || ! is_numeric($lowLimit) || ! preg_match('/^\d+(\.\d+)?$/', $lowLimit)
// ) {
// $status = 'NotOk';
// } elseif (Str::length($uppLimit) <= 0 || ! is_numeric($uppLimit) || ! preg_match('/^\d+(\.\d+)?$/', $uppLimit)
// ) {
// $status = 'NotOk';
// }
// if (($lowLimit == 0 && $uppLimit == 0) || ($uppLimit == 0)) {
// $status = 'NotOk';
// }
// if ($lowLimit > $obserVal || $uppLimit < $obserVal) {
// $status = 'NotOk';
// }
// $status = 'Ok';
// }
// }
if ($createdBy == null || $createdBy == '' || ! $createdBy) {
$warnMsg[] = 'Created By cannot be empty';
}
if ($plantId) {
$user = User::where('name', $createdBy)->first();
$userPlant = User::where('name', $createdBy)->where('plant_id', $plantId)->first();
if (! $user) {
$warnMsg[] = 'Created By user name not found!';
} elseif (! $userPlant && ! $user->hasRole('Super Admin')) {
$warnMsg[] = "Created By user '{$createdBy}' not found for Plant '{$plantCode}'!";
} elseif (! $user->hasRole(['Super Admin', 'Process Quality Manager', 'Process Manager', 'Process Supervisor', 'Process Employee'])) {
$warnMsg[] = 'Created By user does not have rights!';
}
}
if ($plantId && $processOrder) {
$existing = CharacteristicValue::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('coil_number', $coilNo)
->first();
if ($existing) {
$warnMsg[] = "Coil number '{$coilNo}' already exists for Plant '{$plantCode}' and Process Order '{$processOrder}'.";
}
}
if ($plant && $itemCode && $processOrder != '' && $processOrder != null) {
$existingOrder = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->first();
if ($existingOrder && $existingOrder->item_id !== ($itemId ?? null)) {
$warnMsg[] = 'Same Process Order already exists for this Plant with a different Item Code';
}
}
$updatedBy = Filament::auth()->user()->name; // ?? 'Admin'
if (! $updatedBy) {
$warnMsg[] = 'Invalid updated by user name 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) {
// $warnMsg[] = "Date format mismatch with format: $format";
}
}
foreach ($formats as $format) {
try {
$tdateTime = Carbon::createFromFormat($format, $toDate);
break;
} catch (\Exception $e) {
// $warnMsg[] = "Date format mismatch with format: $format";
}
}
if (! isset($fdateTime)) {
$warnMsg[] = "Invalid 'Created DateTime' format. Expected DD-MM-YYYY HH:MM:SS";
}
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 (! empty($warnMsg)) {
throw new RowImportFailedException(implode(', ', $warnMsg));
}
return CharacteristicValue::updateOrCreate([
'plant_id' => $plantId,
'process_order' => $processOrder,
'coil_number' => $coilNo,
],
[
'item_id' => $itemId,
'line_id' => $lineId,
'machine_id' => $machineId,
'status' => $status,
'observed_value' => $obserVal,
'created_by' => $createdBy,
'updated_by' => $updatedBy,
'created_at' => $fdateTime->format('Y-m-d H:i:s'),
'updated_at' => $tdateTime->format('Y-m-d H:i:s'),
]);
// return null;
// return new CharacteristicValue;
}
public static function getCompletedNotificationBody(Import $import): string
{
$body = 'Your characteristic value 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

@@ -8,7 +8,8 @@ use Filament\Actions\Imports\Exceptions\RowImportFailedException;
use Filament\Actions\Imports\ImportColumn;
use Filament\Actions\Imports\Importer;
use Filament\Actions\Imports\Models\Import;
use Str;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
class ItemImporter extends Importer
{
@@ -48,10 +49,10 @@ class ItemImporter extends Importer
->label('Unit of Measure'),
ImportColumn::make('plant')
->requiredMapping()
->exampleHeader('Plant Name')
->example('Ransar Industries-I')
->label('Plant Name')
->relationship(resolveUsing: 'name')
->exampleHeader('Plant Code')
->example('1000')
->label('Plant Code')
->relationship(resolveUsing: 'code') // Lookup Plant by code column
->rules(['required']),
];
}
@@ -59,36 +60,46 @@ class ItemImporter extends Importer
public function resolveRecord(): ?Item
{
$warnMsg = [];
$plantCod = $this->data['plant'];
$plant = null;
Log::info('ResolveRecord triggered', $this->data);
$iCode = trim($this->data['code']);
$description = trim($this->data['description']);
$plant = Plant::where('name', $this->data['plant'])->first();
if (!$plant) {
$warnMsg[] = "Plant not found"; // '" . $this->data['plant'] . "'
if (Str::length($plantCod) < 4 || ! is_numeric($plantCod) || ! preg_match('/^[1-9]\d{3,}$/', $plantCod)) {
$warnMsg[] = 'Invalid plant code found';
} else {
$plant = Plant::where('code', $plantCod)->first();
if (! $plant) {
$warnMsg[] = 'Plant not found'; // '" . $plantCod . "'
}
}
if (Str::length($iCode) < 6 || !ctype_alnum($iCode)) {
$warnMsg[] = "Invalid item code found";
if (Str::length($iCode) < 6 || ! ctype_alnum($iCode)) {
$warnMsg[] = 'Invalid item code found';
}
// if (Str::length($this->data['uom']) <= 0) {
// $warnMsg[] = "Invalid unit of measure found";
// }
if (Str::length($description) < 5) {
$warnMsg[] = "Invalid description found";
$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 (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)) {
if (! empty($warnMsg)) {
throw new RowImportFailedException(implode(', ', $warnMsg));
}
return Item::updateOrCreate([
'code' => $iCode,
'plant_id' => $plant->id
],
'code' => $iCode,
'plant_id' => $plant->id,
],
[
'category' => trim($this->data['category']),
'description' => $description,
'hourly_quantity' => $this->data['hourly_quantity'],
'uom' => trim($this->data['uom'])
'uom' => trim($this->data['uom']),
]
);
// return new Item;

View File

@@ -87,10 +87,10 @@ class LineImporter extends Importer
->label('Work Group Center 10'),
ImportColumn::make('plant')
->requiredMapping()
->exampleHeader('Plant Name')
->example('Ransar Industries-I')
->label('Plant Name')
->relationship(resolveUsing:'name')
->exampleHeader('Plant Code')
->example('1000')
->label('Plant Code')
->relationship(resolveUsing: 'code')
->rules(['required']),
];
}
@@ -98,28 +98,33 @@ class LineImporter extends Importer
public function resolveRecord(): ?Line
{
$warnMsg = [];
$plantCod = $this->data['plant'];
$plant = null;
$plant = Plant::where('name', $this->data['plant'])->first();
if (!$plant) {
throw new RowImportFailedException("Plant '{$this->data['plant']}' not found");
if (Str::length($plantCod) < 4 || ! is_numeric($plantCod) || ! preg_match('/^[1-9]\d{3,}$/', $plantCod)) {
$warnMsg[] = 'Invalid plant code found';
} else {
$plant = Plant::where('code', $plantCod)->first();
if (! $plant) {
throw new RowImportFailedException('Plant not found');
}
}
if (Str::length($this->data['name'] ?? '') <= 0) {
throw new RowImportFailedException("Line name not found");
throw new RowImportFailedException('Line name not found');
}
if (Str::length($this->data['type'] ?? '') <= 0) {
throw new RowImportFailedException("Line type not found");
throw new RowImportFailedException('Line type not found');
}
$noOfOps = (int) ($this->data['no_of_operation'] ?? 0);
if (($noOfOps == null || $noOfOps == '' || !is_numeric($noOfOps)) && $noOfOps != 0) {
if (($noOfOps == null || $noOfOps == '' || ! is_numeric($noOfOps)) && $noOfOps != 0) {
throw new RowImportFailedException("'No of Operation' is required and must be a number $noOfOps");
}
if ($noOfOps > 10)
{
if ($noOfOps > 10) {
throw new RowImportFailedException("Invalid 'No Of Operation' value: {$noOfOps}, maximum allowed is 10");
}
@@ -130,28 +135,28 @@ class LineImporter extends Importer
$missingGroups[] = "work_group{$i}_id";
}
}
if (!empty($missingGroups)) {
if (! empty($missingGroups)) {
throw new RowImportFailedException(
"Invalid data: Required work groups missing values in: " . implode(', ', $missingGroups)
'Invalid data: Required work groups missing values in: '.implode(', ', $missingGroups)
);
}
// Ensure no extra work groups are filled
$invalidGroups = [];
for ($i = $noOfOps + 1; $i <= 10; $i++) {
if (!empty($this->data["work_group{$i}_id"])) {
if (! empty($this->data["work_group{$i}_id"])) {
$invalidGroups[] = "work_group{$i}_id";
}
}
if (!empty($invalidGroups)) {
if (! empty($invalidGroups)) {
throw new RowImportFailedException(
"Invalid data: Only first {$noOfOps} work groups should be filled, but values found in: " . implode(', ', $invalidGroups)
"Invalid data: Only first {$noOfOps} work groups should be filled, but values found in: ".implode(', ', $invalidGroups)
);
}
for ($i = 1; $i <= 10; $i++) {
$workGroupName = $this->data["work_group{$i}_id"] ?? null;
if (!$workGroupName) {
if (! $workGroupName) {
continue;
}
@@ -159,8 +164,8 @@ class LineImporter extends Importer
->where('plant_id', $plant->id)
->first();
if (!$workGroupRecord) {
throw new RowImportFailedException("Work group '{$workGroupName}' not found in plant '{$this->data['plant']}'");
if (! $workGroupRecord) {
throw new RowImportFailedException("Work group '{$workGroupName}' not found in plant '{$plantCod}'");
}
$existsInLines = Line::where('plant_id', $plant->id)
@@ -169,35 +174,34 @@ class LineImporter extends Importer
->first();
if ($existsInLines) {
$warnMsg[] = "Work group '{$workGroupName}' is already assigned to another line in plant '{$this->data['plant']}'";
$warnMsg[] = "Work group '{$workGroupName}' is already assigned to another line in plant '{$plantCod}'";
}
$this->data["work_group{$i}_id"] = $workGroupRecord->id;
}
if (!empty($warnMsg))
{
if (! empty($warnMsg)) {
throw new RowImportFailedException(implode(', ', $warnMsg));
}
Line::updateOrCreate(
[
'name' => $this->data['name'],
'plant_id' => $plant->id
'plant_id' => $plant->id,
],
[
'type' => $this->data['type'],
'no_of_operation' => $noOfOps,
'work_group1_id' => $this->data['work_group1_id'] ?? null,
'work_group2_id' => $this->data['work_group2_id'] ?? null,
'work_group3_id' => $this->data['work_group3_id'] ?? null,
'work_group4_id' => $this->data['work_group4_id'] ?? null,
'work_group5_id' => $this->data['work_group5_id'] ?? null,
'work_group6_id' => $this->data['work_group6_id'] ?? null,
'work_group7_id' => $this->data['work_group7_id'] ?? null,
'work_group8_id' => $this->data['work_group8_id'] ?? null,
'work_group9_id' => $this->data['work_group9_id'] ?? null,
'work_group10_id' => $this->data['work_group10_id'] ?? null,
'work_group1_id' => $this->data['work_group1_id'] ?? null,
'work_group2_id' => $this->data['work_group2_id'] ?? null,
'work_group3_id' => $this->data['work_group3_id'] ?? null,
'work_group4_id' => $this->data['work_group4_id'] ?? null,
'work_group5_id' => $this->data['work_group5_id'] ?? null,
'work_group6_id' => $this->data['work_group6_id'] ?? null,
'work_group7_id' => $this->data['work_group7_id'] ?? null,
'work_group8_id' => $this->data['work_group8_id'] ?? null,
'work_group9_id' => $this->data['work_group9_id'] ?? null,
'work_group10_id' => $this->data['work_group10_id'] ?? null,
]
);
@@ -206,10 +210,10 @@ class LineImporter extends Importer
public static function getCompletedNotificationBody(Import $import): string
{
$body = 'Your line import has completed and ' . number_format($import->successful_rows) . ' ' . str('row')->plural($import->successful_rows) . ' imported.';
$body = 'Your line 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.';
$body .= ' '.number_format($failedRowsCount).' '.str('row')->plural($failedRowsCount).' failed to import.';
}
return $body;

View File

@@ -21,36 +21,36 @@ class MachineImporter extends Importer
return [
ImportColumn::make('name')
->requiredMapping()
->exampleHeader('Machine')
->exampleHeader('DESCRIPTION')
->example(['1600251'])
->label('Machine')
->label('DESCRIPTION')
->rules(['required']),
ImportColumn::make('work_center')
->requiredMapping()
->exampleHeader('Work Center')
->exampleHeader('WORK CENTER')
->example('RMGCE001')
->label('Work Center')
->label('WORK CENTER')
->rules(['required']),
ImportColumn::make('workGroupMaster')
->requiredMapping()
->relationship(resolveUsing: 'name')
->exampleHeader('Work Group Center')
->exampleHeader('GROUP WORK CENTER')
->example(['RMGCGABC'])
->label('Work Group Center')
->label('GROUP WORK CENTER')
->rules(['required']),
ImportColumn::make('line')
->requiredMapping()
->relationship(resolveUsing: 'name')
->exampleHeader('Line')
->exampleHeader('LINE NAME')
->example(['4 inch pump line'])
->label('Line')
->label('LINE NAME')
->rules(['required']),
ImportColumn::make('plant')
->requiredMapping()
->relationship(resolveUsing: 'name')
->exampleHeader('Plant')
->example(['Ransar Industries-I'])
->label('Plant')
->relationship(resolveUsing: 'code')
->exampleHeader('PLANT CODE')
->example(['1000'])
->label('PLANT CODE')
->rules(['required']),
];
}
@@ -58,74 +58,79 @@ class MachineImporter extends Importer
public function resolveRecord(): ?Machine
{
$warnMsg = [];
$plant = Plant::where('name', $this->data['plant'])->first();
$plantCod = $this->data['plant'];
$plant = null;
$line = null;
$lineNam = $this->data['line'];
$machine = $this->data['name'];
$workCenter = $this->data['work_center'];
$groupWorkCenter = WorkGroupMaster::where('name', $this->data['workGroupMaster'])->first();
if (!$plant) {
$warnMsg[] = "Plant not found!";
}
else {
$groupWorkCenter = WorkGroupMaster::where('name', $this->data['workGroupMaster'])->where('plant_id', $plant->id)->first();
$line = Line::where('name', $this->data['line'])->where('plant_id', $plant->id)->first();
if ($line) {
$grpWrkCnr = $line->no_of_operation;
if (!$grpWrkCnr || $grpWrkCnr < 1)//Str::length($grpWrkCnr) < 1)
{
$warnMsg[] = "Group work center line not found!";
}
else if (!$groupWorkCenter) {
$warnMsg[] = "Group work center not found!";
}
else {
$dupMachine = Machine::where('plant_id', $plant->id)->where('work_center', '!=', $workCenter)->where('name', $machine)->first();
if ($dupMachine) {
$warnMsg[] = "Duplicate machine name found!";
}
else {
$isValidGroupWork = false;
for ($i = 1; $i <= $line->no_of_operation; $i++) {
$column = "work_group{$i}_id";
if (!empty($line->$column)) {
if ($line->$column == $groupWorkCenter->id) {
$isValidGroupWork = true;
break;
$workGroupCenter = $this->data['workGroupMaster'];
if (Str::length($plantCod) < 4 || ! is_numeric($plantCod) || ! preg_match('/^[1-9]\d{3,}$/', $plantCod)) {
$warnMsg[] = 'Invalid plant code found';
} elseif (Str::length($lineNam) <= 0) {
$warnMsg[] = "Line name can't be empty!";
} elseif (Str::length($machine) <= 0) {
$warnMsg[] = "Description can't be empty!";
} elseif (Str::length($workCenter) <= 0) {
$warnMsg[] = "Work center can't be empty!";
} elseif (Str::length($workGroupCenter) <= 0) {
$warnMsg[] = "Group work center can't be empty!";
} else {
$plant = Plant::where('code', $plantCod)->first();
if (! $plant) {
$warnMsg[] = 'Plant not found!';
} else {
$groupWorkCenter = WorkGroupMaster::where('name', $workGroupCenter)->where('plant_id', $plant->id)->first();
$line = Line::where('name', $lineNam)->where('plant_id', $plant->id)->first();
if ($line) {
$grpWrkCnr = $line->no_of_operation;
if (! $grpWrkCnr || $grpWrkCnr < 1) {// Str::length($grpWrkCnr) < 1)
$warnMsg[] = 'Group work center line not found!';
} elseif (! $groupWorkCenter) {
$warnMsg[] = 'Group work center not found!';
} else {
$dupMachine = Machine::where('plant_id', $plant->id)->where('work_center', '!=', $workCenter)->where('name', $machine)->first();
if ($dupMachine) {
$warnMsg[] = 'Duplicate machine name found!';
} else {
$isValidGroupWork = false;
for ($i = 1; $i <= $line->no_of_operation; $i++) {
$column = "work_group{$i}_id";
if (! empty($line->$column)) {
if ($groupWorkCenter->id == $line->$column) {
$isValidGroupWork = true;
break;
}
}
}
}
if (!$isValidGroupWork) {
$warnMsg[] = "Group work center does not match with line!";
if (! $isValidGroupWork) {
$warnMsg[] = 'Group work center does not match with line!';
}
}
}
} else {
$warnMsg[] = 'Line not found!';
}
}
else
{
$warnMsg[] = "Line not found!";
}
}
if (Str::length($machine) <= 0) {
$warnMsg[] = "Machine name not found!";
}
if (!empty($warnMsg)) {
if (! empty($warnMsg)) {
throw new RowImportFailedException(implode(', ', $warnMsg));
}
Machine::updateOrCreate(
[
'plant_id' => $plant->id,
'work_center' => $workCenter
'work_center' => $workCenter,
],
[
'line_id' => $line->id,
'name' => $machine,
'work_group_master_id' => $groupWorkCenter->id
'work_group_master_id' => $groupWorkCenter->id,
]
);
return null;
// // return Machine::firstOrNew([
// // // Update existing records, matching them by `$this->data['column_name']`
@@ -137,10 +142,10 @@ class MachineImporter extends Importer
public static function getCompletedNotificationBody(Import $import): string
{
$body = 'Your machine import has completed and ' . number_format($import->successful_rows) . ' ' . str('row')->plural($import->successful_rows) . ' imported.';
$body = 'Your machine 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.';
$body .= ' '.number_format($failedRowsCount).' '.str('row')->plural($failedRowsCount).' failed to import.';
}
return $body;

View File

@@ -3,13 +3,16 @@
namespace App\Filament\Imports;
use App\Models\Item;
use App\Models\Line;
use App\Models\Plant;
use App\Models\ProcessOrder;
use App\Models\ProductCharacteristicsMaster;
use App\Models\User;
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 Str;
class ProcessOrderImporter extends Importer
@@ -22,10 +25,15 @@ class ProcessOrderImporter extends Importer
ImportColumn::make('plant')
->requiredMapping()
->exampleHeader('PLANT CODE')
->example('1000')
->example('1200')
->label('PLANT CODE')
->relationship(resolveUsing: 'code')
->rules(['required']),
ImportColumn::make('line')
->exampleHeader('LINE NAME')
->example('Poly Wrapped Wire SFG')
->label('LINE NAME')
->relationship(resolveUsing: 'name'),
ImportColumn::make('item')
->requiredMapping()
->exampleHeader('ITEM CODE')
@@ -34,68 +42,393 @@ class ProcessOrderImporter extends Importer
->relationship(resolveUsing: 'code')
->rules(['required']),
ImportColumn::make('process_order')
->requiredMapping()
->exampleHeader('PROCESS ORDER')
->example('202500123456')
->example('202601123456')
->label('PROCESS ORDER')
->rules(['required']),
ImportColumn::make('order_quantity')
->requiredMapping()
->exampleHeader('ORDER QUANTITY')
->example('1000')
->label('ORDER QUANTITY')
->rules(['required']),
ImportColumn::make('updated_order_quantity')
->exampleHeader('UPDATED ORDER QUANTITY')
->label('UPDATED ORDER QUANTITY'),
ImportColumn::make('coil_number')
->exampleHeader('COIL NUMBER')
// ->example('01')
->label('COIL NUMBER'),
ImportColumn::make('received_quantity')
->exampleHeader('RECEIVED QUANTITY')
// ->example('01')
->label('RECEIVED QUANTITY'),
ImportColumn::make('sfg_number')
->exampleHeader('SFG NUMBER')
// ->example('200000220613-72')
->label('SFG NUMBER'),
ImportColumn::make('machine_name')
->exampleHeader('MACHINE NAME')
// ->example('WMIWRM13 - 2-L2')
->label('MACHINE NAME'),
ImportColumn::make('scrap_quantity')
->exampleHeader('SCRAP QUANTITY')
// ->example('0')
->label('SCRAP QUANTITY'),
ImportColumn::make('rework_status')
->exampleHeader('REWORK STATUS')
// ->example('0')
->label('REWORK STATUS'),
ImportColumn::make('created_at')
->exampleHeader('CREATED AT')
// ->example('2026-02-20 13:00:00')
->label('CREATED AT'),
ImportColumn::make('updated_at')
->exampleHeader('UPDATED AT')
// ->example('2026-02-20 13:00:00')
->label('UPDATED AT'),
ImportColumn::make('created_by')
->exampleHeader('CREATED BY')
->example('RAW01234')
->label('CREATED BY')
->rules(['required']),
// ->example('RAW01234')
->label('CREATED BY'),
ImportColumn::make('updated_by')
->exampleHeader('UPDATED BY')
// ->example('RAW01234')
->label('UPDATED BY'),
];
}
public function resolveRecord(): ?ProcessOrder
{
$warnMsg = [];
$plant = Plant::where('code', $this->data['plant'])->first();
$itemCode = Item::where('code', $this->data['item'])->first();
$iCode = trim($this->data['item']);
if (! $plant) {
$warnMsg[] = 'Plant not found';
} elseif (Str::length($iCode) < 6 || ! ctype_alnum($iCode)) {
$warnMsg[] = 'Invalid item code found';
} elseif (! $itemCode) {
$warnMsg[] = 'Item Code not found';
}
$plant = null;
$plantCod = trim($this->data['plant']) ?? '';
$plantId = null;
$iCode = trim($this->data['item']) ?? '';
$itemId = null;
$lineNam = trim($this->data['line']) ?? '';
$lineId = null;
$processOrder = trim($this->data['process_order'] ?? '');
$coilNo = trim($this->data['coil_number'] ?? '');
$sfgNo = trim($this->data['sfg_number'] ?? '');
$machineName = trim($this->data['machine_name'] ?? '');
$orderQuan = trim($this->data['order_quantity'] ?? '');
$updatedOrderQuan = trim($this->data['updated_order_quantity'] ?? '');
$scrapQuan = trim($this->data['scrap_quantity'] ?? '');
$reworkStatus = trim($this->data['rework_status'] ?? '');
$recQuan = trim($this->data['received_quantity'] ?? '');
$createdAt = trim($this->data['created_at'] ?? '');
$createdBy = trim($this->data['created_by'] ?? '');
$updatedAt = trim($this->data['updated_at'] ?? '');
$updatedBy = trim($this->data['updated_by'] ?? '');
// $user = Filament::auth()->user();
// $operatorName = $user->name;
if ($processOrder == '') {
$warnMsg[] = 'Process Order cannot be empty';
if ($plantCod == null || $plantCod == '') {
$warnMsg[] = "Plant code can't be empty!";
} elseif (Str::length($plantCod) < 4 || ! is_numeric($plantCod) || ! preg_match('/^[1-9]\d{3,6}$/', $plantCod)) {
$warnMsg[] = 'Invalid plant code found';
}
if ($iCode == null || $iCode == '') {
$warnMsg[] = "Item code can't be empty!";
} elseif (Str::length($iCode) < 6 || ! ctype_alnum($iCode)) {
$warnMsg[] = 'Invalid item code found!';
}
if ($machineName != null && $machineName != '' && Str::length($machineName) > 18) {
$warnMsg[] = 'Invalid machine name found!';
}
if ($processOrder == null || $processOrder == '') {
$warnMsg[] = "Process order can't be empty!";
} elseif ($processOrder && (Str::contains($processOrder, '.') || Str::contains($processOrder, 'E', ignoreCase: true))) {
$warnMsg[] = 'Invalid process order found!';
}
if ($lineNam == null || $lineNam == '') {
$warnMsg[] = "Line name can't be empty!";
}
if ($orderQuan == null || $orderQuan == '') {
$warnMsg[] = "Order quantity can't be empty!";
} elseif ($orderQuan == 0 || $orderQuan == '0') {
$warnMsg[] = "Order quantity can't be zero!";
} elseif (Str::length($orderQuan) >= 1 && ! is_numeric($orderQuan)) {
$warnMsg[] = 'Invalid order quantity found!';
}
if ($updatedOrderQuan == null || $updatedOrderQuan == '' || $updatedOrderQuan == 0 || $updatedOrderQuan == '0') {
$updatedOrderQuan = $orderQuan;
} elseif (Str::length($updatedOrderQuan) >= 1 && ! is_numeric($updatedOrderQuan)) {
$warnMsg[] = 'Invalid Updated order quantity found!';
}
$user = User::where('name', $this->data['created_by'])->first();
if (! $user) {
$warnMsg[] = 'User not found';
if ($coilNo == null || $coilNo == '') {
$coilNo = '0';
}
if ($plant && $processOrder != '') {
$existingOrder = ProcessOrder::where('plant_id', $plant->id)
->where('process_order', $processOrder)
->first();
if ($existingOrder && $existingOrder->item_id !== ($itemCode->id ?? null)) {
$warnMsg[] = 'Same Process Order already exists for this Plant with a different Item Code';
}
if ($scrapQuan == null || $scrapQuan == '') {
$scrapQuan = 0;
}
if ($recQuan == null || $recQuan == '') {
$recQuan = 0;
}
if ($reworkStatus == null || $reworkStatus = '' || $reworkStatus == 0 || $reworkStatus = '0') {
$reworkStatus = 0;
} elseif ($reworkStatus == 1 || $reworkStatus = '1') {
$reworkStatus = 1;
} else {
$warnMsg[] = 'Invalid rework status found!';
}
if (! empty($warnMsg)) {
throw new RowImportFailedException(implode(', ', $warnMsg));
}
return ProcessOrder::create([
'plant_id' => $plant->id,
'item_id' => $itemCode->id,
'process_order' => trim($this->data['process_order']),
'coil_number' => '0',
'order_quantity' => 0,
'received_quantity' => 0,
'created_by' => $user->name,
]);
$plant = Plant::where('code', $plantCod)->first();
if (! $plant) {
$warnMsg[] = 'Plant not found!';
} else {
$plantId = $plant->id;
}
// TESTING PURPOSE ONLY - TO CHECK DUPLICATE PROCESS ORDER WITH SAME COIL NUMBER FOR THE SAME PLANT
// $existing = ProcessOrder::where('plant_id', $plantId)->where('process_order', $processOrder)->first();
// if ($existing) {
// $existing = ProcessOrder::where('plant_id', $plantId)->where('process_order', $processOrder)->where('coil_number', $coilNo)->first();
// if ($existing) {
// $warnMsg[] = 'Process Order with coil number already exists!';
// } else {
// $warnMsg[] = 'Process order already exists!';
// }
// } else {
// $warnMsg[] = 'New process order found!';
// }
// if (! empty($warnMsg)) {
// throw new RowImportFailedException(implode(', ', $warnMsg));
// }
$itemCode = Item::where('code', $iCode)->first();
if (! $itemCode) {
$warnMsg[] = 'Item code not found!';
} else {
if ($plantId) {
$itemCode = Item::where('code', $iCode)->where('plant_id', $plantId)->first();
if (! $itemCode) {
$warnMsg[] = 'Item code not found for the given plant!';
} else {
$itemId = $itemCode->id;
}
}
}
$lineExists = Line::where('name', $lineNam)->first();
if (! $lineExists) {
$warnMsg[] = 'Line name not found!';
} else {
if ($plantId) {
$lineAgainstPlant = Line::where('name', $lineNam)->where('plant_id', $plantId)->first();
if (! $lineAgainstPlant) {
$warnMsg[] = 'Line name not found for the given plant!';
} else {
$lineId = $lineAgainstPlant->id;
}
}
}
if ($plantId && $itemId && $lineId && $processOrder != '') {
$existingOrder = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->first();
if ($existingOrder && $existingOrder->item_id !== ($itemId ?? null)) {
$warnMsg[] = 'Same Process Order already exists for this Plant with a different Item Code!';
}
// $masterExist = ProductCharacteristicsMaster::where('plant_id', $plantId)->where('item_id', $itemId)->first();
// if (! $masterExist) {
// $warnMsg[] = 'Characteristics master not found for the given plant!';
// } else {
// $masterExist = ProductCharacteristicsMaster::where('plant_id', $plantId)->where('line_id', $lineId)->where('item_id', $itemId)->first();
// if (! $masterExist) {
// $warnMsg[] = 'Characteristics master not found for the given line!';
// }
// }
}
// $user = User::where('name', $this->data['created_by'])->first();
// if (! $user) {
// $warnMsg[] = 'User not found!';
// }
if (! $createdBy) {
$createdBy = Filament::auth()->user()->name;
$updatedBy = Filament::auth()->user()->name;
} elseif (! $updatedBy) {
$updatedBy = Filament::auth()->user()->name;
}
if (! empty($warnMsg)) {
throw new RowImportFailedException(implode(', ', $warnMsg));
}
$existing = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
// ->where('coil_number', $coilNo)
->first();
$receivedQty = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->sum('received_quantity');
if ($existing) {
$liveOrdQuan = (float) $existing->order_quantity;
$liveUpdatedOrdQuan = (float) $existing->updated_order_quantity;
$allowedIncrease = $liveOrdQuan * 0.10;
$maxAllowedQty = $liveOrdQuan + $allowedIncrease;
$minAllowedQty = $liveOrdQuan - $allowedIncrease;
if ($liveUpdatedOrdQuan > $maxAllowedQty) {
throw new RowImportFailedException(
"Updated order quantity cannot exceed 10% of existing order quantity. Max allowed: {$maxAllowedQty}!"
);
} elseif ($liveUpdatedOrdQuan < $minAllowedQty) {
throw new RowImportFailedException(
"Updated order quantity cannot decrease -10% of existing order quantity. Min allowed: {$minAllowedQty}!"
);
} elseif ($liveUpdatedOrdQuan < $receivedQty) {
throw new RowImportFailedException(
"Updated order quantity cannot decrease below its received quantity {$receivedQty}!"
);
}
}
if ($coilNo != null && $coilNo != '' && $scrapQuan && $reworkStatus && $recQuan && $createdAt && $createdBy && $updatedAt && $updatedBy && Filament::auth()->user()->hasRole('Super Admin')) {
$existingCoil = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('line_id', $lineId)
->where('coil_number', $coilNo)
->first();
// $existingProcess = ProcessOrder::where('plant_id', $plantId)
// ->where('process_order', $processOrder)
// ->where('line_id', $lineId)
// ->first();
if ($existing) {
$existUpdateOrdQuan = $existing->updated_order_quantity;
} else {
$existUpdateOrdQuan = $updatedOrderQuan;
}
if (! $existingCoil) {
ProcessOrder::Create(
[
'plant_id' => $plantId,
'line_id' => $lineId,
'process_order' => $processOrder,
'item_id' => $itemId,
'coil_number' => $coilNo,
'order_quantity' => $orderQuan,
'updated_order_quantity' => $existUpdateOrdQuan,
'received_quantity' => $recQuan,
'scrap_quantity' => $scrapQuan,
'sfg_number' => $sfgNo,
'machine_name' => $machineName,
'rework_status' => $reworkStatus,
'created_at' => $createdAt,
'updated_at' => $updatedAt,
'created_by' => $createdBy,
'updated_by' => $updatedBy,
]
);
} else {
ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('line_id', $lineId)
->where('coil_number', $coilNo)
->update([
// 'order_quantity' => $orderQty,
'received_quantity' => $recQuan,
'scrap_quantity' => $scrapQuan,
// 'sfg_number' => $sfgNo,
// 'machine_name' => $machineId,
'rework_status' => $reworkStatus,
'updated_by' => $updatedBy,
'updated_at' => $updatedAt,
]);
}
} else {
$coilNo = '0';
// $existing = ProcessOrder::where('plant_id', $plantId)
// ->where('process_order', $processOrder)
// // ->where('coil_number', $coilNo)
// ->first();
if ($existing) {
$existUpdateOrdQuan = $existing->updated_order_quantity;
} else {
$existUpdateOrdQuan = $updatedOrderQuan;
}
if (! $existing && ($coilNo == '0' || $coilNo == 0)) {
ProcessOrder::create([
'plant_id' => $plantId,
'line_id' => $lineId,
'item_id' => $itemId,
'process_order' => $processOrder,
'coil_number' => '0',
'order_quantity' => $orderQuan,
'updated_order_quantity' => $existUpdateOrdQuan,
'received_quantity' => 0,
'scrap_quantity' => 0,
'created_by' => $createdBy,
'updated_by' => $updatedBy,
]);
} elseif (! $existing) {
ProcessOrder::Create(
[
'plant_id' => $plantId,
'line_id' => $lineId,
'item_id' => $itemId,
'process_order' => $processOrder,
'coil_number' => $coilNo,
'order_quantity' => $orderQuan,
'updated_order_quantity' => $existUpdateOrdQuan,
'received_quantity' => $recQuan,
'scrap_quantity' => $scrapQuan ?? 0,
'sfg_number' => $sfgNo,
'machine_name' => $machineName,
'rework_status' => $reworkStatus,
// 'created_at' => $createdAt,
// 'updated_at' => $updatedAt,
'created_by' => $createdBy,
'updated_by' => $updatedBy,
]
);
} else {// $coilNo = '0'
if ($existing->process_order == $processOrder) {
throw new RowImportFailedException('Process order already exist for the given plant!');
} elseif ($existing->rework_status == 1 && $reworkStatus == 0) {
throw new RowImportFailedException('Rework coil number already exist for the given Plant and Process Order!');
} else {
ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('coil_number', $coilNo)
->update([
// 'order_quantity' => $orderQty,
'received_quantity' => $recQuan,
'scrap_quantity' => $scrapQuan,
// 'sfg_number' => $sfgNo,
// 'machine_name' => $machineId,
'rework_status' => $reworkStatus,
'updated_by' => $updatedBy,
// 'updated_at' => $updatedAt,
]);
}
}
}
return null;
// return new ProcessOrder();
}

View File

@@ -9,12 +9,12 @@ use App\Models\Plant;
use App\Models\ProductCharacteristicsMaster;
use App\Models\User;
use App\Models\WorkGroupMaster;
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 Str;
use Filament\Actions\Imports\Exceptions\RowImportFailedException;
use Illuminate\Support\Facades\Auth;
class ProductCharacteristicsMasterImporter extends Importer
{
@@ -24,257 +24,305 @@ class ProductCharacteristicsMasterImporter extends Importer
{
return [
ImportColumn::make('plant')
->label('PLANT CODE')
->requiredMapping()
->exampleHeader('Plant Name')
->example('Ransar Industries-I')
->label('Plant Name')
->relationship(resolveUsing:'name')
->exampleHeader('PLANT CODE')
->example(['1000', '1000'])
->relationship(resolveUsing: 'code')
->rules(['required']),
ImportColumn::make('item')
->label('ITEM CODE')
->requiredMapping()
->exampleHeader('Item Code')
->example('630214')
->label('Item Code')
->relationship(resolveUsing:'code')
->exampleHeader('ITEM CODE')
->example(['123456', '123456'])
->relationship(resolveUsing: 'code')
->rules(['required']),
ImportColumn::make('line')
->label('LINE NAME')
->requiredMapping()
->exampleHeader('Line')
->example('4 inch pump line')
->label('Line')
->relationship(resolveUsing:'name')
->exampleHeader('LINE NAME')
->example(['4 inch pump line', '4 inch pump line'])
->relationship(resolveUsing: 'name')
->rules(['required']),
ImportColumn::make('work_group_master_id')
->label('Group Work Center')
->label('GROUP WORK CENTER')
->requiredMapping()
->exampleHeader('Group Work Center')
->example('RMGCGABC')
->relationship(resolveUsing:'name')
->exampleHeader('GROUP WORK CENTER')
->example(['RMGSTR01', 'RMGSTR01'])
->relationship(resolveUsing: 'name')
->rules(['required']),
ImportColumn::make('machine')
->label('WORK CENTER')
->requiredMapping()
->exampleHeader('Work Center')
->example('RMGCE001')
->label('Work Center')
->relationship(resolveUsing:'work_center')
->exampleHeader('WORK CENTER')
->example(['RMISTR01', 'RMISTR02'])
->relationship(resolveUsing: 'work_center')
->rules(['required']),
ImportColumn::make('characteristics_type')
->exampleHeader('Characteristics Type')
->example('Process or Product')
->label('Characteristics Type')
->label('CHARACTERISTICS TYPE')
->requiredMapping()
->exampleHeader('CHARACTERISTICS TYPE')
->example(['Product', 'Process'])
->rules(['required']),
ImportColumn::make('name')
->exampleHeader('Name')
->example('Body')
->label('Name')
->label('CHARACTERISTICS NAME')
->requiredMapping()
->exampleHeader('CHARACTERISTICS NAME')
->example(['TEST01', 'TEST02'])
->rules(['required']),
ImportColumn::make('category')
->label('CATEGORY')
->requiredMapping()
->exampleHeader('CATEGORY')
->example(['Open Pump', 'Submersible Pump']),
ImportColumn::make('inspection_type')
->exampleHeader('Inspection Type')
->example('Visual or Value')
->label('Inspection Type')
->label('INSPECTION TYPE')
->requiredMapping()
->exampleHeader('INSPECTION TYPE')
->example(['Value', 'Visual'])
->rules(['required']),
ImportColumn::make('lower')
->exampleHeader('Lower')
->example('-0.2')
->label('Lower')
->rules(['numeric']),
->label('LOWER')
->requiredMapping()
->exampleHeader('LOWER')
->example(['5', '0'])
->rules(['required']),
ImportColumn::make('middle')
->exampleHeader('Middle')
->example('1')
->label('Middle')
->numeric()
->rules(['numeric']),
->label('MIDDLE')
->requiredMapping()
->exampleHeader('MIDDLE')
->example(['10', '0'])
->rules(['required']),
ImportColumn::make('upper')
->exampleHeader('Upper')
->example('0.2')
->label('Upper')
->rules(['numeric']),
ImportColumn::make('created_by')
->exampleHeader('Created By')
->example('Admin')
->label('Created By'),
//ImportColumn::make('updated_by'),
->label('UPPER')
->requiredMapping()
->exampleHeader('UPPER')
->example(['15', '0'])
->rules(['required']),
// ImportColumn::make('created_by'),
// ImportColumn::make('updated_by'),
];
}
public function resolveRecord(): ?ProductCharacteristicsMaster
{
$warnMsg = [];
$plant = Plant::where('name', $this->data['plant'])->first();
if (!$plant) {
$warnMsg[] = "Plant not found";
$plantCod = trim($this->data['plant']) ?? null;
$itemCod = trim($this->data['item']) ?? null;
$lineNam = trim($this->data['line']) ?? null;
$groupWorkCenter = trim($this->data['work_group_master_id']) ?? null;
$workCenter = trim($this->data['machine']) ?? null;
$charTyp = trim($this->data['characteristics_type']) ?? null;
$charNam = trim($this->data['name']) ?? null;
$category = trim($this->data['category']) ?? null;
$inspectTyp = trim($this->data['inspection_type']) ?? null;
$lower = trim($this->data['lower']) ?? null;
$middle = trim($this->data['middle']) ?? null;
$upper = trim($this->data['upper']) ?? null;
$createdBy = Filament::auth()->user()->name;
$updatedBy = null;
$plantId = null;
$itemId = null;
$lineId = null;
$workGroupMasterId = null;
$machineId = null;
if ($plantCod == null || $plantCod == '') {
$warnMsg[] = "Plant code can't be empty!";
} elseif (Str::length($plantCod) < 4 || ! is_numeric($plantCod) || ! preg_match('/^[1-9]\d{3,}$/', $plantCod)) {
$warnMsg[] = 'Invalid plant code found!';
}
if ($itemCod == null || $itemCod == '') {
$warnMsg[] = "Item code can't be empty!";
} elseif (Str::length($itemCod) < 6 || ! ctype_alnum($itemCod)) {
$warnMsg[] = 'Invalid item code found!';
}
if ($lineNam == null || $lineNam == '') {
$warnMsg[] = "Line name can't be empty!";
}
if ($groupWorkCenter == null || $groupWorkCenter == '') {
$warnMsg[] = "Group work center can't be empty!";
}
if ($workCenter == null || $workCenter == '') {
$warnMsg[] = "Work center can't be empty!";
}
if ($charTyp != 'Product' && $charTyp != 'Process') {
$warnMsg[] = "Characteristics type must be either 'Product' or 'Process'!";
}
if ($charNam == null || $charNam == '') {
$warnMsg[] = "Characteristics name can't be empty!";
}
if ($inspectTyp != 'Visual' && $inspectTyp != 'Value') {
$warnMsg[] = "Inspection type must be either 'Visual' or 'Value'!";
}
if ($lower == null || $lower == '' || $middle == null || $middle == '' || $upper == null || $upper == '' || $upper == 0 || $upper == '0') {
$lower = 0;
$middle = 0;
$upper = 0;
}
$itemExists = Item::where('code', $this->data['item'])->first();
if (!$itemExists) {
$warnMsg[] = "Item not found";
}
$itemAgainstPlant = Item::where('code', $this->data['item'])
->where('plant_id', $plant->id)
->first();
if (!$itemAgainstPlant) {
$warnMsg[] = "Item code not found for the given plant";
}
else {
$itemId = $itemAgainstPlant->id;
}
$lineExists = Line::where('name', $this->data['line'])->first();
if (!$lineExists) {
$warnMsg[] = "Line not found";
}
$lineAgainstPlant = Line::where('name', $this->data['line'])
->where('plant_id', $plant->id)
->first();
if (!$lineAgainstPlant) {
$warnMsg[] = "Line not found for the given plant";
}
else
{
$LineId = $lineAgainstPlant->id;
}
$WorkgroupMaster = WorkGroupMaster::where('name', $this->data['work_group_master_id'])->where('plant_id', $plant->id)->first();
if (!$WorkgroupMaster) {
$warnMsg[] = "Work Group Master value not found";
}
else {
$workGroupMasterId = $WorkgroupMaster->id;
// 2. Now check if this WorkGroupMaster id exists in ANY of the 10 columns
$existsInLine = Line::where('plant_id', $plant->id)
->where(function ($q) use ($workGroupMasterId) {
for ($i = 1; $i <= 10; $i++) {
$q->orWhere("work_group{$i}_id", $workGroupMasterId);
}
})
->exists();
if (!$existsInLine) {
$warnMsg[] = "Work Group Master '{$WorkgroupMaster->name}' is not mapped to any line in this plant";
}
else {
$workGroupMasterId = $WorkgroupMaster->id;
}
}
$machine = Machine::where('work_center', $this->data['machine'])->first();
if (!$machine) {
$warnMsg[] = "Work Center not found";
}
else {
$machineId = $machine->id;
}
$machineAgainstPlant = Machine::where('work_center', $this->data['machine'])
->where('plant_id', $plant->id)
->first();
if (!$machineAgainstPlant) {
$warnMsg[] = "Work Center not found for the given plant";
}
else
{
$machineId = $machineAgainstPlant->id;
}
$user = User::where('name', $this->data['created_by'])->first();
if (!$user) {
$warnMsg[] = "Operator ID not found";
}
if (($this->data['inspection_type'] ?? null) == 'Value') {
$upper = $this->data['upper'] ?? null;
$lower = $this->data['lower'] ?? null;
$middle = $this->data['middle'] ?? null;
if (is_null($upper) || is_null($lower) || is_null($middle)) {
$warnMsg[] = "For 'Value' inspection type, Upper, Lower, and Middle values are required.";
} elseif (!is_numeric($upper) || !is_numeric($lower) || !is_numeric($middle)) {
$warnMsg[] = "Upper, Lower, and Middle values must be numeric.";
} elseif (!($lower <= $middle && $middle <= $upper)) {
$warnMsg[] = "For 'Value' inspection type, values must satisfy: Lower ≤ Middle ≤ Upper.";
}
}
if (!empty($warnMsg)) {
if (! empty($warnMsg)) {
throw new RowImportFailedException(implode(', ', $warnMsg));
}
else
{
$record = ProductCharacteristicsMaster::firstOrNew([
'plant_id' => $plant->id,
'item_id' => $itemId,
'line_id' => $LineId,
'work_group_master_id' => $workGroupMasterId,
'machine_id' => $machineId,
]);
$currentUser = Auth::check() ? Auth::user()->name : ($this->data['created_by'] ?? 'System');
// If record is new, fill all fields
if (!$record->exists) {
$record->name = $this->data['name'];
$record->characteristics_type = $this->data['characteristics_type'];
$record->inspection_type = $this->data['inspection_type'];
$record->upper = $this->data['upper'] ?? null;
$record->lower = $this->data['lower'] ?? null;
$record->middle = $this->data['middle'] ?? null;
$record->created_by = $currentUser;
$plant = Plant::where('code', $plantCod)->first();
if (! $plant) {
$warnMsg[] = 'Plant code not found!';
} else {
$plantId = $plant->id;
$itemExists = Item::where('code', $itemCod)->first();
if (! $itemExists) {
$warnMsg[] = 'Item code not found!';
} else {
// Record exists → update only updated_by and updated_at
$record->updated_by = $currentUser;
$record->touch();
$itemAgainstPlant = Item::where('code', $itemCod)->where('plant_id', $plantId)->first();
if (! $itemAgainstPlant) {
$warnMsg[] = 'Item code not found for the given plant!';
} else {
$itemId = $itemAgainstPlant->id;
}
}
$record->save();
$lineExists = Line::where('name', $lineNam)->first();
if (! $lineExists) {
$warnMsg[] = 'Line name not found!';
} else {
$lineAgainstPlant = Line::where('name', $lineNam)->where('plant_id', $plantId)->first();
if (! $lineAgainstPlant) {
$warnMsg[] = 'Line name not found for the given plant!';
} else {
$lineId = $lineAgainstPlant->id;
return null;
$WorkgroupMaster = WorkGroupMaster::where('name', $groupWorkCenter)->first();
if (! $WorkgroupMaster) {
$warnMsg[] = 'Group work center not found!';
} else {
$WorkgroupMaster = WorkGroupMaster::where('name', $groupWorkCenter)->where('plant_id', $plantId)->first();
if (! $WorkgroupMaster) {
$warnMsg[] = 'Group work center not found for the given plant!';
} else {
$workGroupMasterId = $WorkgroupMaster->id;
// 2. Now check if this WorkGroupMaster id exists in ANY of the 10 columns
$existsInLine = Line::where('plant_id', $plantId)->where('id', $lineId)
->where(function ($q) use ($workGroupMasterId) {
for ($i = 1; $i <= 10; $i++) {
$q->orWhere("work_group{$i}_id", $workGroupMasterId);
}
})
->exists();
if (! $existsInLine) {
$workGroupMasterId = null;
$warnMsg[] = "Group work center '{$WorkgroupMaster->name}' is not mapped for the given line!";
} else {
$workGroupMasterId = $WorkgroupMaster->id;
$machine = Machine::where('work_center', $workCenter)->first();
if (! $machine) {
$warnMsg[] = 'Work center not found!';
} else {
$machine = Machine::where('work_center', $workCenter)->where('plant_id', $plantId)->first();
if (! $machine) {
$warnMsg[] = 'Work center not found for the given plant!';
} else {
$machine = Machine::where('work_center', $workCenter)->where('plant_id', $plantId)->where('line_id', $lineId)->first();
if (! $machine) {
$warnMsg[] = "Work center '{$workCenter}' is not mapped for the given line!";
} else {
$machine = Machine::where('work_center', $workCenter)->where('plant_id', $plantId)->where('line_id', $lineId)->where('work_group_master_id', $workGroupMasterId)->first();
if (! $machine) {
$warnMsg[] = "Work center '{$workCenter}' is not mapped for the given group work center!";
} else {
$machineId = $machine->id;
}
}
}
}
}
}
}
}
}
$user = User::where('name', $createdBy)->first();
if (! $user) {
$warnMsg[] = 'Created by user not found!';
} else {
$updatedBy = $createdBy;
}
if ($inspectTyp == 'Value') {
if (is_null($upper) || is_null($lower) || is_null($middle)) {
$warnMsg[] = 'Upper, Lower, and Middle values are required.';
} elseif (! is_numeric($upper) || ! is_numeric($lower) || ! is_numeric($middle)) {
$warnMsg[] = 'Upper, Lower, and Middle values must be numeric.';
} else {
$lower = (float) $lower;
$middle = (float) $middle;
$upper = (float) $upper;
if ($lower == $upper) {
if ($lower != $middle) {
$warnMsg[] = "For 'Value' inspection type, values must satisfy: Lower = Middle = Upper.";
}
} elseif (! ($lower < $middle && $middle < $upper)) {
$warnMsg[] = "For 'Value' inspection type, values must satisfy: Lower < Middle < Upper.";
}
}
} else {
$lower = 0;
$middle = 0;
$upper = 0;
}
}
// else
// {
// ProductCharacteristicsMaster::updateOrCreate(
// [
// 'plant_id' => $plant->id,
// 'item_id' => $itemId,
// 'line_id' => $LineId,
// 'work_group_master_id' => $workGroupMasterId,
// 'machine_id'=> $machineId,
// ],
// [
// 'name' => $this->data['name'],
// 'characteristics_type' => $this->data['characteristics_type'],
// 'inspection_type' => $this->data['inspection_type'],
// 'upper' => $this->data['upper'] ?? null,
// 'lower' => $this->data['lower'] ?? null,
// 'middle' => $this->data['middle'] ?? null,
// //'created_by' => user ?? $this->data['created_by'],
// 'created_by' => Auth::check() ? Auth::user()->name :($this->data['created_by'] ?? null)
// ]
// );
if (! empty($warnMsg)) {
throw new RowImportFailedException(implode(', ', $warnMsg));
}
// return null;
// }
if ($machineId) {
$record = ProductCharacteristicsMaster::where('plant_id', $plantId)->where('line_id', $lineId)->where('work_group_master_id', $workGroupMasterId)->where('machine_id', $machineId)->where('item_id', $itemId)->where('characteristics_type', $charTyp)->where('name', $charNam)->first();
if ($record) {
$createdBy = $record->created_by ?? $createdBy;
}
//return new WorkGroupMaster();
ProductCharacteristicsMaster::updateOrCreate(
[
'plant_id' => $plantId,
'item_id' => $itemId,
'line_id' => $lineId,
'work_group_master_id' => $workGroupMasterId,
'machine_id' => $machineId,
'characteristics_type' => $charTyp,
'name' => $charNam,
],
[
'category' => $category,
'inspection_type' => $inspectTyp,
'lower' => $lower,
'middle' => $middle,
'upper' => $upper,
'created_by' => $createdBy,
'updated_by' => $updatedBy,
]);
}
// return new ProductCharacteristicsMaster();
return null;
// return new WorkGroupMaster();
// return new ProductCharacteristicsMaster();
}
public static function getCompletedNotificationBody(Import $import): string
{
$body = 'Your product characteristics master import has completed and ' . number_format($import->successful_rows) . ' ' . str('row')->plural($import->successful_rows) . ' imported.';
$body = 'Your product characteristics master 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.';
$body .= ' '.number_format($failedRowsCount).' '.str('row')->plural($failedRowsCount).' failed to import.';
}
return $body;

View File

@@ -9,6 +9,7 @@ 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 Str;
class StickerMasterImporter extends Importer
@@ -151,10 +152,10 @@ class StickerMasterImporter extends Importer
->example(''),
ImportColumn::make('plant')
->requiredMapping()
->exampleHeader('Plant Name')
->example('Ransar Industries-I')
->label('PLANT NAME')
->relationship(resolveUsing: 'name')
->exampleHeader('Plant Code')
->example('1000')
->label('PLANT CODE')
->relationship(resolveUsing: 'code')
->rules(['required']),
];
}
@@ -162,107 +163,198 @@ class StickerMasterImporter extends Importer
public function resolveRecord(): ?StickerMaster
{
$warnMsg = [];
$plantCod = trim($this->data['plant']);
$itemCod = trim($this->data['item']);
$panelCod = trim($this->data['panel_box_code']);
$plant = null;
$item = null;
$plant = Plant::where('name', $this->data['plant'])->first();
if (!$plant) {
$warnMsg[] = "Plant not found";
$plantId = null;
$itemId = null;
$parts = null;
$validParts = null;
$part1 = trim($this->data['part_validation1']);
$part2 = trim($this->data['part_validation2']);
$part3 = trim($this->data['part_validation3']);
$part4 = trim($this->data['part_validation4']);
$part5 = trim($this->data['part_validation5']);
$laserPart1 = trim($this->data['laser_part_validation1']);
$laserPart2 = trim($this->data['laser_part_validation2']);
$SerialNumberMotor = trim($this->data['serial_number_motor']) ?? null;
$SerialNumberMotor = ($SerialNumberMotor == '0') ? null : $SerialNumberMotor;
$SerialNumberPump = trim($this->data['serial_number_pump']) ?? null;
$SerialNumberPump = ($SerialNumberPump == '0') ? null : $SerialNumberPump;
$SerialNumberPumpSet = trim($this->data['serial_number_pumpset']) ?? null;
$SerialNumberPumpSet = ($SerialNumberPumpSet == '0') ? null : $SerialNumberPumpSet;
$PackSlipMotor = trim($this->data['pack_slip_motor']) ?? null;
$PackSlipMotor = ($PackSlipMotor == '0') ? null : $PackSlipMotor;
$PackSlipPump = trim($this->data['pack_slip_pump']) ?? null;
$PackSlipPump = ($PackSlipPump == '0') ? null : $PackSlipPump;
$PackSlipPumpSet = trim($this->data['pack_slip_pumpset']) ?? null;
$PackSlipPumpSet = ($PackSlipPumpSet == '0') ? null : $PackSlipPumpSet;
$NamePlateMotor = trim($this->data['name_plate_motor']) ?? null;
$NamePlateMotor = ($NamePlateMotor == '0') ? null : $NamePlateMotor;
$NamePlatePump = trim($this->data['name_plate_pump']) ?? null;
$NamePlatePump = ($NamePlatePump == '0') ? null : $NamePlatePump;
$NamePlatePumpSet = trim($this->data['name_plate_pumpset']) ?? null;
$NamePlatePumpSet = ($NamePlatePumpSet == '0') ? null : $NamePlatePumpSet;
$TubeStickMotor = trim($this->data['tube_sticker_motor']) ?? null;
$TubeStickMotor = ($TubeStickMotor == '0') ? null : $TubeStickMotor;
$TubeStickPump = trim($this->data['tube_sticker_pump']) ?? null;
$TubeStickPump = ($TubeStickPump == '0') ? null : $TubeStickPump;
$TubeStickPumpSet = trim($this->data['tube_sticker_pumpset']) ?? null;
$TubeStickPumpSet = ($TubeStickPumpSet == '0') ? null : $TubeStickPumpSet;
$WarrantyCard = trim($this->data['warranty_card']) ?? null;
$WarrantyCard = ($WarrantyCard == '0') ? null : $WarrantyCard;
$LoadRate = $this->data['load_rate'] ?? 0;
$BundleQuantity = $this->data['bundle_quantity'] ?? null;
$MaterialType = $this->data['material_type'] ?? null;
$createdBy = Filament::auth()->user()->name;
$updatedBy = Filament::auth()->user()->name;
if ($plantCod == null || $plantCod == '') {
$warnMsg[] = "Plant code can't be empty!";
} elseif (! is_numeric($plantCod)) {
$warnMsg[] = 'Plant code should contain only numeric values!';
} elseif (Str::length($plantCod) < 4 || Str::length($plantCod) > 7) {
$warnMsg[] = 'Plant code must be between 4 and 7 digits only!';
} elseif (! preg_match('/^[1-9]\d{3,6}$/', $plantCod)) {
$warnMsg[] = 'Invalid plant code found!';
} else {
$plant = Plant::where('code', $plantCod)->first();
}
else
{
$item = Item::where('code', $this->data['item'])->where('plant_id', $plant->id)->first();
if (!$item) {
$warnMsg[] = "Item code not found";
}
else
{
if (Str::length($this->data['serial_number_motor']) > 0 && $this->data['serial_number_motor'] != '1') {
$warnMsg[] = "Serial number motor must be 1 or empty";
}
if (Str::length($this->data['serial_number_pump']) > 0 && $this->data['serial_number_pump'] != '1') {
$warnMsg[] = "Serial number pump must be 1 or empty";
}
if (Str::length($this->data['serial_number_pumpset']) > 0 && $this->data['serial_number_pumpset'] != '1') {
$warnMsg[] = "Serial number pumpset must be 1 or empty";
}
if (Str::length($this->data['pack_slip_motor']) > 0 && $this->data['pack_slip_motor'] != '1') {
$warnMsg[] = "Pack slip motor must be 1 or empty";
}
if (Str::length($this->data['pack_slip_pump']) > 0 && $this->data['pack_slip_pump'] != '1') {
$warnMsg[] = "Pack slip pump must be 1 or empty";
}
if (Str::length($this->data['pack_slip_pumpset']) > 0 && $this->data['pack_slip_pumpset'] != '1') {
$warnMsg[] = "Pack slip pumpset must be 1 or empty";
}
if (Str::length($this->data['name_plate_motor']) > 0 && $this->data['name_plate_motor'] != '1') {
$warnMsg[] = "Name plate motor must be 1 or empty";
}
if (Str::length($this->data['name_plate_pump']) > 0 && $this->data['name_plate_pump'] != '1') {
$warnMsg[] = "Name plate pump must be 1 or empty";
}
if (Str::length($this->data['name_plate_pumpset']) > 0 && $this->data['name_plate_pumpset'] != '1') {
$warnMsg[] = "Name plate pumpset must be 1 or empty";
}
if (Str::length($this->data['tube_sticker_motor']) > 0 && $this->data['tube_sticker_motor'] != '1') {
$warnMsg[] = "Tube sticker motor must be 1 or empty";
}
if (Str::length($this->data['tube_sticker_pump']) > 0 && $this->data['tube_sticker_pump'] != '1') {
$warnMsg[] = "Tube sticker pump must be 1 or empty";
}
if (Str::length($this->data['tube_sticker_pumpset']) > 0 && $this->data['tube_sticker_pumpset'] != '1') {
$warnMsg[] = "Tube sticker pumpset must be 1 or empty";
}
if (Str::length($this->data['warranty_card']) > 0 && $this->data['warranty_card'] != '1') {
$warnMsg[] = "Warranty card must be 1 or empty";
}
if (Str::length($this->data['panel_box_code']) > 0 && (Str::length($this->data['panel_box_code']) < 6 || !ctype_alnum($this->data['panel_box_code']))) {
$warnMsg[] = "Invalid panel box code found";
}
if (Str::length($this->data['load_rate']) < 0 || !is_numeric($this->data['load_rate']) || $this->data['load_rate'] < 0) {
$warnMsg[] = "Load rate must be greater than or equal to 0";
}
if (Str::length($this->data['bundle_quantity']) > 0 && (!is_numeric($this->data['bundle_quantity']) || $this->data['bundle_quantity'] <= 1)) {
$warnMsg[] = "Bundle quantity must be greater than or equal to '2' or empty";
}
if (Str::length($this->data['material_type']) > 0 && $this->data['material_type'] != '1' && $this->data['material_type'] != '2' && $this->data['material_type'] != '3') { //($this->data['material_type'] != null) &&
$warnMsg[] = "Material type must be 1 or 2 or 3 or empty";
if (! $plant) {
$warnMsg[] = 'Plant not found!';
} else {
$plantId = $plant->id;
if (Str::length($itemCod) < 6 || ! ctype_alnum($itemCod)) {
$warnMsg[] = 'Invalid item code found!';
} else {
$item = Item::where('code', $itemCod)->first();
if (! $item) {
$warnMsg[] = 'Item code not found!';
} else {
$item = Item::where('code', $itemCod)->where('plant_id', $plantId)->first();
if (! $item) {
$warnMsg[] = 'Item code not found for the plant!';
} else {
$itemId = $item->id;
if (! $laserPart1 && ! (Str::length($laserPart2) == 1 && is_numeric($laserPart2))) {
$laserPart1 = $laserPart2;
$laserPart2 = null;
}
if (Str::length($panelCod) > 0 && (Str::length($panelCod) < 6 || ! ctype_alnum($panelCod))) {
$warnMsg[] = 'Invalid panel box code found!';
} elseif ($panelCod) {
$parts = [$part1, $part2, $part3, $part4];
$validParts = array_values(array_filter($parts, fn ($p) => ! empty($p)));
[$part1, $part2, $part3, $part4] = array_pad($validParts, 4, '');
} else {
$parts = [$part1, $part2, $part3, $part4, $part5];
$validParts = array_values(array_filter($parts, fn ($p) => ! empty($p)));
[$part1, $part2, $part3, $part4, $part5] = array_pad($validParts, 5, '');
}
if (Str::length($SerialNumberMotor) > 0 && (! is_numeric($SerialNumberMotor) || $SerialNumberMotor < 1)) {
$warnMsg[] = "Serial number motor must be greater than or equal to '1' or empty!";
}
if (Str::length($SerialNumberPump) > 0 && (! is_numeric($SerialNumberPump) || $SerialNumberPump < 1)) {
$warnMsg[] = "Serial number pump must be greater than or equal to '1' or empty!";
}
if (Str::length($SerialNumberPumpSet) > 0 && (! is_numeric($SerialNumberPumpSet) || $SerialNumberPumpSet < 1)) {
$warnMsg[] = "Serial number pumpset must be greater than or equal to '1' or empty!";
}
if (Str::length($PackSlipMotor) > 0 && (! is_numeric($PackSlipMotor) || $PackSlipMotor < 1)) {
$warnMsg[] = "Pack slip motor must be greater than or equal to '1' or empty!";
}
if (Str::length($PackSlipPump) > 0 && (! is_numeric($PackSlipPump) || $PackSlipPump < 1)) {
$warnMsg[] = "Pack slip pump must be greater than or equal to '1' or empty!";
}
if (Str::length($PackSlipPumpSet) > 0 && (! is_numeric($PackSlipPumpSet) || $PackSlipPumpSet < 1)) {
$warnMsg[] = "Pack slip pumpset must be greater than or equal to '1' or empty!";
}
if (Str::length($NamePlateMotor) > 0 && (! is_numeric($NamePlateMotor) || $NamePlateMotor < 1)) {
$warnMsg[] = "Name plate motor must be greater than or equal to '1' or empty!";
}
if (Str::length($NamePlatePump) > 0 && (! is_numeric($NamePlatePump) || $NamePlatePump < 1)) {
$warnMsg[] = "Name plate pump must be greater than or equal to '1' or empty!";
}
if (Str::length($NamePlatePumpSet) > 0 && (! is_numeric($NamePlatePumpSet) || $NamePlatePumpSet < 1)) {
$warnMsg[] = "Name plate pumpset must be greater than or equal to '1' or empty!";
}
if (Str::length($TubeStickMotor) > 0 && (! is_numeric($TubeStickMotor) || $TubeStickMotor < 1)) {
$warnMsg[] = "Tube sticker motor must be greater than or equal to '1' or empty!";
}
if (Str::length($TubeStickPump) > 0 && (! is_numeric($TubeStickPump) || $TubeStickPump < 1)) {
$warnMsg[] = "Tube sticker pump must be greater than or equal to '1' or empty!";
}
if (Str::length($TubeStickPumpSet) > 0 && (! is_numeric($TubeStickPumpSet) || $TubeStickPumpSet < 1)) {
$warnMsg[] = "Tube sticker pumpset must be greater than or equal to '1' or empty!";
}
if (Str::length($WarrantyCard) > 0 && (! is_numeric($WarrantyCard) || $WarrantyCard < 1)) {
$warnMsg[] = "Warranty card must be greater than or equal to '1' or empty!";
}
if (Str::length($LoadRate) < 0 || ! is_numeric($LoadRate) || $LoadRate < 0) {
$warnMsg[] = "Load rate must be greater than or equal to '0'!";
}
if (Str::length($BundleQuantity) > 0 && (! is_numeric($BundleQuantity) || $BundleQuantity <= 1)) {
$warnMsg[] = "Bundle quantity must be greater than or equal to '2' or empty!";
}
if (Str::length($MaterialType) > 0 && $MaterialType != '1' && $MaterialType != '2' && $MaterialType != '3' && $MaterialType != '4') { // ($this->data['material_type'] != null) &&
$warnMsg[] = "Material type must be '1' or '2' or '3' or '4' or empty!";
}
if (empty($warnMsg)) {
$recExist = StickerMaster::where('item_id', $itemId)->where('plant_id', $plantId)->first()?->created_by;
if ($recExist) {
$createdBy = $recExist;
}
}
}
}
}
}
if (!empty($warnMsg)) {
if (! empty($warnMsg)) {
throw new RowImportFailedException(implode(', ', $warnMsg));
}
StickerMaster::updateOrCreate([
'item_id' => $item->id,
'plant_id' => $plant->id
'item_id' => $itemId,
'plant_id' => $plantId,
],
[
'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'],
'laser_part_validation1' => $this->data['laser_part_validation1'],
'laser_part_validation2' => $this->data['laser_part_validation2'],
'panel_box_code' => $this->data['panel_box_code'],
'load_rate' => $this->data['load_rate'],
'bundle_quantity' => $this->data['bundle_quantity'],
'material_type' => $this->data['material_type']
]);
[
'serial_number_motor' => $SerialNumberMotor,
'serial_number_pump' => $SerialNumberPump,
'serial_number_pumpset' => $SerialNumberPumpSet,
'pack_slip_motor' => $PackSlipMotor,
'pack_slip_pump' => $PackSlipPump,
'pack_slip_pumpset' => $PackSlipPumpSet,
'name_plate_motor' => $NamePlateMotor,
'name_plate_pump' => $NamePlatePump,
'name_plate_pumpset' => $NamePlatePumpSet,
'tube_sticker_motor' => $TubeStickMotor,
'tube_sticker_pump' => $TubeStickPump,
'tube_sticker_pumpset' => $TubeStickPumpSet,
'warranty_card' => $WarrantyCard,
'part_validation1' => $part1,
'part_validation2' => $part2,
'part_validation3' => $part3,
'part_validation4' => $part4,
'part_validation5' => $part5,
'laser_part_validation1' => $laserPart1,
'laser_part_validation2' => $laserPart2,
'panel_box_code' => $panelCod,
'load_rate' => $LoadRate,
'material_type' => $MaterialType,
'bundle_quantity' => $BundleQuantity,
'created_by' => $createdBy,
'updated_by' => $updatedBy,
]);
return null;
// return StickerMaster::firstOrNew([
// // Update existing records, matching them by `$this->data['column_name']`
@@ -274,10 +366,10 @@ class StickerMasterImporter extends Importer
public static function getCompletedNotificationBody(Import $import): string
{
$body = 'Your sticker master import has completed and ' . number_format($import->successful_rows) . ' ' . str('row')->plural($import->successful_rows) . ' imported.';
$body = 'Your sticker master 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.';
$body .= ' '.number_format($failedRowsCount).' '.str('row')->plural($failedRowsCount).' failed to import.';
}
return $body;

View File

@@ -20,16 +20,16 @@ class WorkGroupMasterImporter extends Importer
return [
ImportColumn::make('plant')
->requiredMapping()
->exampleHeader('Plant Name')
->example('Ransar Industries-I')
->label('Plant Name')
->relationship(resolveUsing:'name')
->exampleHeader('Plant Code')
->example('1000')
->label('Plant Code')
->relationship(resolveUsing: 'code')
->rules(['required']),
ImportColumn::make('name')
->requiredMapping()
->exampleHeader('Name')
->exampleHeader('Group Work Center')
->example('RMGCEABC')
->label('Name')
->label('Group Work Center')
->rules(['required']),
ImportColumn::make('description')
->requiredMapping()
@@ -52,8 +52,6 @@ class WorkGroupMasterImporter extends Importer
];
}
public function resolveRecord(): ?WorkGroupMaster
{
// return WorkGroupMaster::firstOrNew([
@@ -61,92 +59,105 @@ class WorkGroupMasterImporter extends Importer
// 'email' => $this->data['email'],
// ]);
$warnMsg = [];
$plant = Plant::where('name', $this->data['plant'])->first();
if (!$plant) {
$warnMsg[] = "Plant not found";
}
if (Str::length($this->data['name']) <= 0) { //|| !ctype_alnum($this->data['description'])
$warnMsg[] = "Invalid name found";
}
if (Str::length(trim($this->data['description'])) <= 0) {
$warnMsg[] = "Invalid description found";
}
$plantCod = $this->data['plant'];
$createdBy = $this->data['created_by'];
$groupWorkCenter = $this->data['name'];
$desc = trim($this->data['description']);
$opNo = $this->data['operation_number'];
$plantId = null;
if (! $plantCod || $plantCod == null || $plantCod == '') {
$warnMsg[] = "Plant code can't be empty!";
} elseif (Str::length($plantCod) < 4 || ! is_numeric($plantCod) || ! preg_match('/^[1-9]\d{3,}$/', $plantCod)) {
$warnMsg[] = "Invalid plant code '{$plantCod}' found!";
} else {
$plant = Plant::where('code', $plantCod)->first();
if (! $plant) {
$warnMsg[] = "Plant code '{$plantCod}' not found!";
} else {
$plantId = $plant->id;
}
}
if (Str::length($groupWorkCenter) <= 0) { // || !ctype_alnum($desc)
$warnMsg[] = 'Invalid group work center found!';
}
if (Str::length(trim($desc)) <= 0) {
$warnMsg[] = 'Invalid description found!';
}
if (Str::length($desc) > 44) {
$warnMsg[] = "Description should be less than 44 digits.";
$warnMsg[] = 'Description should be less than 44 digits.';
}
if (Str::length($this->data['operation_number']) <= 0) {
$warnMsg[] = "Invalid operation number found";
if (Str::length($opNo) <= 0) {
$warnMsg[] = 'Invalid operation number found!';
}
if(!is_numeric($this->data['operation_number']))
{
$warnMsg[] = "Invalid operation number found must be numeric";
if (! is_numeric($opNo)) {
$warnMsg[] = 'Operation number must be numeric values only.';
}
$user = User::where('name', $this->data['created_by'])->first();
if (!$user) {
$warnMsg[] = "Operator ID not found";
$user = User::where('name', $createdBy)->first();
if (! $user) {
$warnMsg[] = "Operator ID '{$createdBy}' not found!";
}
if (!empty($warnMsg)) {
if (! empty($warnMsg)) {
throw new RowImportFailedException(implode(', ', $warnMsg));
}
else
{
//Check (plant_id, name)
$existingByName = WorkGroupMaster::where('plant_id', $plant->id)
->where('name', $this->data['name'])
->first();
} else {
// Check (plant_id, name)
// $existingByName = WorkGroupMaster::where('plant_id', $plantId)
// ->where('name', $groupWorkCenter)
// ->first();
if ($existingByName) {
throw new RowImportFailedException("Work group name already exists for this plant!");
}
// if ($existingByName) {
// throw new RowImportFailedException('Group work center already exists for this plant!');
// }
//Check (plant_id, operation_number)
$existingByOpNum = WorkGroupMaster::where('plant_id', $plant->id)
->where('operation_number', $this->data['operation_number'])
->where('name', $this->data['name'])
->first();
// Check (plant_id, operation_number)
// $existingByOpNum = WorkGroupMaster::where('plant_id', $plantId)
// ->where('operation_number', $opNo)
// ->where('name', $groupWorkCenter)
// ->first();
if ($existingByOpNum) {
throw new RowImportFailedException("Operation number already exists for this plant!");
}
// if ($existingByOpNum) {
// throw new RowImportFailedException('Operation number already exists for this plant!');
// }
//Check (plant_id)
$existingByOperator = WorkGroupMaster::where('plant_id', $plant->id)
->where('name', $this->data['name'])
// Check (plant_id)
$existingByOperator = WorkGroupMaster::whereNot('plant_id', $plantId)
->where('name', $groupWorkCenter)
->first();
if ($existingByOperator) {
throw new RowImportFailedException("Already work group name assigned to another plant!");
throw new RowImportFailedException('Already group work center assigned to another plant!');
}
}
WorkGroupMaster::updateOrCreate([
'plant_id' => $plant->id,
'name' => $this->data['name'],
'description' => $this->data['description'],
'operation_number' => $this->data['operation_number'],
'created_by' => $this->data['created_by'],
]);
'plant_id' => $plantId,
'name' => $groupWorkCenter,
],
[
'description' => $desc,
'operation_number' => $opNo,
'created_by' => $createdBy,
]
);
return null;
//return new WorkGroupMaster();
// return new WorkGroupMaster();
}
public static function getCompletedNotificationBody(Import $import): string
{
$body = 'Your work group master import has completed and ' . number_format($import->successful_rows) . ' ' . str('row')->plural($import->successful_rows) . ' imported.';
$body = 'Your work group master 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.';
$body .= ' '.number_format($failedRowsCount).' '.str('row')->plural($failedRowsCount).' failed to import.';
}
return $body;

File diff suppressed because it is too large Load Diff

View File

@@ -19,6 +19,7 @@ use Filament\Forms\Components\ViewField;
use Filament\Notifications\Notification;
use Filament\Forms\Components\Actions\Action;
use Filament\Forms\Components\Hidden;
use Illuminate\Support\Facades\Auth;
class ProductionCalender extends Page
{
@@ -160,4 +161,9 @@ class ProductionCalender extends Page
}
}
public static function canAccess(): bool
{
return Auth::check() && Auth::user()->can('view production calender page');
}
}

View File

@@ -403,6 +403,9 @@ class ProductionQuantityPage extends Page implements HasForms
public function processMachine($value)
{
$plantId = $this->pId;
$plantCode = Plant::find($plantId);
$PlaCo = $plantCode->code;
$this->mNam = $value;
$now = Carbon::now()->format('H:i:s');
@@ -412,6 +415,72 @@ class ProductionQuantityPage extends Page implements HasForms
$machine = Machine::where('plant_id', $plantId)->where('work_center', $this->mNam)->with('line.block')->first();
$machinenotAgaPlant = Machine::where('work_center', $this->mNam)->first();
$machineAgaPlant = Machine::where('plant_id', $plantId)->where('work_center', $this->mNam)->first();
if (!$machinenotAgaPlant) {
Notification::make()
->title('Unknown WorkCenter')
->body("Work Center not found")
->danger()
->send();
$this->form->fill([
'plant_id' => $this->pId,
'machine_id' => $this->mNam,
'block_name' => $this->bNam,
'shift_id' => $this->sNam,
'line_id' => $this->lNam,
'item_id' => null,
'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,
]);
return;
}
else if (!$machineAgaPlant) {
Notification::make()
->title('Unknown WorkCenter')
->body("Work Center not found against plant code $PlaCo")
->danger()
->send();
$this->form->fill([
'plant_id' => $this->pId,
'machine_id' => $this->mNam,
'block_name' => $this->bNam,
'shift_id' => $this->sNam,
'line_id' => $this->lNam,
'item_id' => null,
'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,
]);
return;
}
$rec = ProductionQuantity::where('plant_id', $plantId)->where('machine_id', $machineAgaPlant->id)->latest()->first();
if($rec)
{
$item = Item::where('id', $rec->item_id)->where('plant_id', $plantId)->first();
$itemCode = $item?->code ?? '';
$serialNo = $rec->serial_number ?? '';
$this->recQr = $itemCode . ' | ' . $serialNo;
}
if ($machine) {
$this->lNam = Line::where('id', $machine->line_id)->value('name');
$this->bNam = $machine->line->block->name ?? null;
@@ -436,15 +505,6 @@ class ProductionQuantityPage extends Page implements HasForms
'recent_qr' => $this->recQr,
]);
$this->triggerChartUpdate();
} else {
Notification::make()
->title('Unknown WorkCenter')
->body('Work Center not found')
->danger()
->send();
return;
}
}
@@ -1065,46 +1125,6 @@ class ProductionQuantityPage extends Page implements HasForms
$iCode = trim($splits[0]);
$sNumber = isset($splits[1]) ? trim($splits[1]) : null;
// $machine = Machine::where('work_center', $this->mNam)->where('plant_id', $this->pId)->first();
// $this->mId = $machine->id;
// $lineId = $machine->line_id;
// $this->lId = $lineId;
// $line = Line::find($lineId);
// if (! $line) {
// Notification::make()
// ->title('Invalid Line')
// ->body('Line associated with the machine not found.')
// ->danger()
// ->send();
// return;
// }
// $blockId = $line->block_id;
// $this->bId = $blockId;
// $shift = Shift::where('block_id', $blockId)->first();
// if (! $shift) {
// Notification::make()
// ->title('No Shift Found')
// ->body('No shift associated with this block.')
// ->danger()
// ->send();
// return;
// }
// $shiftId = $shift->id;
// $this->sId = $shiftId;
// $line = Line::with('block')->find($lineId);
// $lineName = $line?->name;
// $blockName = $line?->block?->name;
// $shiftName = $shift?->name;
if (! ctype_alnum($iCode)) {
@@ -1121,7 +1141,7 @@ class ProductionQuantityPage extends Page implements HasForms
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id' => $operatorName,
'recent_qr' => $this->recent_qr,
'recent_qr' => $this->recQr,
]);
Notification::make()
@@ -1145,7 +1165,7 @@ class ProductionQuantityPage extends Page implements HasForms
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id' => $operatorName,
'recent_qr' => $this->recent_qr,
'recent_qr' => $this->recQr,
]);
Notification::make()
@@ -1169,7 +1189,7 @@ class ProductionQuantityPage extends Page implements HasForms
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id' => $operatorName,
'recent_qr' => $this->recent_qr,
'recent_qr' => $this->recQr,
]);
Notification::make()
@@ -1194,7 +1214,7 @@ class ProductionQuantityPage extends Page implements HasForms
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id' => $operatorName,
'recent_qr' => $this->recent_qr,
'recent_qr' => $this->recQr,
]);
Notification::make()
@@ -1221,7 +1241,7 @@ class ProductionQuantityPage extends Page implements HasForms
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id' => $operatorName,
'recent_qr' => $this->recent_qr,
'recent_qr' => $this->recQr,
]);
Notification::make()
@@ -1376,13 +1396,10 @@ class ProductionQuantityPage extends Page implements HasForms
->title('Invalid QR Found') // {$operatorName}
->body('Please, scan the valid QR code.')
->danger()
// ->persistent()
->send();
return;
} else {
// // Perform any additional processing or database operations
// $this->saveFormData($formValues);
$parts = explode('|', $this->qrData);
$itemCode = trim($parts[0]);
@@ -1467,7 +1484,7 @@ class ProductionQuantityPage extends Page implements HasForms
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id' => $operatorName,
'recent_qr' => $this->recent_qr,
'recent_qr' => $this->recQr,
]);
return;
@@ -1489,7 +1506,6 @@ class ProductionQuantityPage extends Page implements HasForms
// $this->recent_qr = $itemCode.' | '.$this->sNoId;
// after success insertion
$this->form->fill([
'plant_id' => $this->pId,
'machine_id' => $this->mNam,
'block_name' => $this->bNam,
@@ -1502,7 +1518,7 @@ class ProductionQuantityPage extends Page implements HasForms
'sap_msg_status' => null,
'sap_msg_description' => null,
'operator_id' => $operatorName,
'recent_qr' => $this->recent_qr,
'recent_qr' => $itemCode.' | '.$this->sNoId,
]);
Notification::make()

File diff suppressed because it is too large Load Diff

View File

@@ -11,6 +11,7 @@ use Filament\Forms\Components\Section;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Notifications\Notification;
use Illuminate\Support\Facades\Auth;
class ProductionTarget extends Page
{
@@ -30,13 +31,16 @@ class ProductionTarget extends Page
->schema([
Select::make('plant_id')
->label('Plant')
->relationship('plant', 'name')
->reactive()
// ->searchable()
->options(function (callable $get) {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
})
->required()
->afterStateUpdated(function ($state, callable $get, $set) {
// dd($state);
$set('line_id', null);
$set('year', null);
$set('month', null);
@@ -45,6 +49,8 @@ class ProductionTarget extends Page
Select::make('line_id')
->label('Line')
->required()
->relationship('line', 'name')
// ->searchable()
->columnSpan(1)
->options(function (callable $get) {
if (!$get('plant_id')) {
@@ -58,6 +64,8 @@ class ProductionTarget extends Page
->reactive()
->afterStateUpdated(function ($state, callable $get, $set) {
$plantId = $get('plant_id');
$set('year', null);
$set('month', null);
$this->dispatch('loadData',$plantId, $state, '', '');
@@ -65,7 +73,9 @@ class ProductionTarget extends Page
Select::make('year')
->label('Year')
->reactive()
// ->searchable()
->options([
'2025' => '2025',
'2026' => '2026',
'2027' => '2027',
'2028' => '2028',
@@ -93,6 +103,7 @@ class ProductionTarget extends Page
Select::make('month')
->label('Month')
->reactive()
// ->searchable()
->options([
'01' => 'January',
'02' => 'February',
@@ -170,4 +181,9 @@ class ProductionTarget extends Page
$this->dispatch('loadData1' ,$plantId, $lineId, $year, $month);
}
public static function canAccess(): bool
{
return Auth::check() && Auth::user()->can('view production target page');
}
}

View File

@@ -61,14 +61,55 @@ class RfqDashboard extends Page
// session()->forget('rfq_number');
// }),
// Select::make('rfq_number')
// ->label('Select RFQ Number')
// ->reactive()
// ->options(function (callable $get) {
// return RequestQuotation::orderBy('rfq_number')
// ->pluck('rfq_number', 'id')
// ->toArray();
// })
// ->afterStateUpdated(function ($state, callable $set) {
// session(['rfq_id' => $state]);
// $set('transport_name', null);
// session()->forget('transport_name');
// }),
Select::make('rfq_number')
->label('Select RFQ Number')
->reactive()
->options(function (callable $get) {
->options(function () {
return RequestQuotation::orderBy('rfq_number')
->pluck('rfq_number', 'id')
->toArray();
$user = Filament::auth()->user();
if ($user?->hasAnyRole(['Super Admin', 'RFQ Supervisor'])) {
return RequestQuotation::orderBy('rfq_number')
->pluck('rfq_number', 'id')
->toArray();
}
$userName = $user?->name;
$masterIds = \App\Models\SpotRateTransportMaster::whereRaw(
"user_name::jsonb @> ?",
[json_encode([$userName])]
)
->pluck('id')
->unique()
->toArray();
if (empty($masterIds)) {
return [];
}
return RequestQuotation::whereIn(
'spot_rate_transport_master_id',
$masterIds
)
->orderBy('rfq_number')
->pluck('rfq_number', 'id')
->toArray();
})
->afterStateUpdated(function ($state, callable $set) {
session(['rfq_id' => $state]);

View File

@@ -10,6 +10,8 @@ class Welcome extends Page
protected static string $view = 'filament.pages.welcome';
protected static ?string $navigationGroup = 'IIOT';
public function getHeading(): string
{
return '';

View File

@@ -0,0 +1,703 @@
<?php
namespace App\Filament\Resources;
use App\Filament\Exports\CharacteristicValueExporter;
use App\Filament\Imports\CharacteristicValueImporter;
use App\Filament\Resources\CharacteristicValueResource\Pages;
use App\Models\CharacteristicValue;
use App\Models\Item;
use App\Models\Line;
use App\Models\Machine;
use App\Models\Plant;
use App\Models\ProductCharacteristicsMaster;
use Filament\Facades\Filament;
use Filament\Forms;
use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Forms\Get;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Actions\ExportAction;
use Filament\Tables\Actions\ImportAction;
use Filament\Tables\Filters\Filter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Illuminate\Validation\Rule;
use Str;
class CharacteristicValueResource extends Resource
{
protected static ?string $model = CharacteristicValue::class;
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
protected static ?string $navigationGroup = 'Process Order';
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Select::make('plant_id')
->label('Plant Name')
->nullable()
->searchable()
->reactive()
->relationship('plant', 'name')
->options(function (callable $get) {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::orderBy('code')->pluck('name', 'id')->toArray();
})
->disabled(fn (Get $get) => ! empty($get('id')))
->default(function () {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? $userHas : optional(CharacteristicValue::latest()->first())->plant_id;
})
->afterStateUpdated(function ($state, $set, callable $get) {
$plantId = $get('plant_id');
$set('line_id', null);
$set('item_id', null);
$set('machine_id', null);
$set('process_order', null);
$set('coil_number', null);
$set('observed_value', null);
$set('status', 'NotOk');
$set('updated_by', Filament::auth()->user()?->name);
if (! $plantId) {
$set('poPlantError', 'Please select a plant first.');
}
})
->extraAttributes(fn ($get) => [
'class' => $get('poPlantError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('poPlantError') ? $get('poPlantError') : null)
->hintColor('danger')
->required(),
Forms\Components\Select::make('line_id')
->label('Line Name')
->nullable()
->searchable()
->reactive()
->options(function (callable $get) {
if (! $get('plant_id')) {
return [];
}
return Line::where('plant_id', $get('plant_id'))
->pluck('name', 'id')
->toArray();
})
->disabled(fn (Get $get) => ! empty($get('id')))
->afterStateUpdated(function ($state, $set, callable $get) {
$plantId = $get('plant_id');
$set('item_id', null);
$set('machine_id', null);
$set('process_order', null);
$set('coil_number', null);
$set('observed_value', null);
$set('status', 'NotOk');
$set('updated_by', Filament::auth()->user()?->name);
if (! $plantId) {
$set('line_id', null);
$set('poPlantError', 'Please select a plant first.');
}
})
->required(),
Forms\Components\Select::make('item_id')
->label('Item Code')
->nullable()
->searchable()
->reactive()
->options(function (callable $get) {
if (! $get('plant_id') || ! $get('line_id')) {
return [];
}
return Item::where('plant_id', $get('plant_id'))
->pluck('code', 'id')
->toArray();
})
->disabled(fn (Get $get) => ! empty($get('id')))
->afterStateUpdated(function ($state, $set, callable $get) {
$plantId = $get('plant_id');
$set('machine_id', null);
$set('process_order', null);
$set('coil_number', null);
$set('observed_value', null);
$set('status', 'NotOk');
$set('updated_by', Filament::auth()->user()?->name);
if (! $plantId) {
$set('item_id', null);
$set('poPlantError', 'Please select a plant first.');
}
})
->required(),
Forms\Components\Select::make('machine_id')
->label('Work Center')
->nullable()
->searchable()
->reactive()
->options(function (callable $get) {
if (! $get('plant_id') || ! $get('line_id') || ! $get('item_id')) {
return [];
}
return Machine::where('plant_id', $get('plant_id'))
->where('line_id', $get('line_id'))
->pluck('work_center', 'id')
->toArray();
})
->disabled(fn (Get $get) => ! empty($get('id')))
->afterStateUpdated(function ($state, $set, callable $get) {
$plantId = $get('plant_id');
$set('process_order', null);
$set('coil_number', null);
$set('observed_value', null);
$set('status', 'NotOk');
$set('updated_by', Filament::auth()->user()?->name);
if (! $plantId) {
$set('machine_id', null);
$set('poPlantError', 'Please select a plant first.');
}
})
->required(),
Forms\Components\TextInput::make('process_order')
->label('Process Order')
->reactive()
->afterStateUpdated(function ($state, $set, callable $get) {
$plantId = $get('plant_id');
$set('coil_number', null);
$set('observed_value', null);
$set('status', 'NotOk');
$set('updated_by', Filament::auth()->user()?->name);
if (! $plantId) {
$set('process_order', null);
$set('poPlantError', 'Please select a plant first.');
}
})
->required(),
Forms\Components\TextInput::make('coil_number')
->label('Coil Number')
// ->reactive()
// ->afterStateUpdated(function ($state, $set, callable $get) {
// $plantId = $get('plant_id');
// $set('status', 'NotOk');
// if (! $plantId) {
// $set('poPlantError', 'Please select a plant first.');
// }
// })
// ->required(),
->label('Coil Number')
->default('0')
->numeric()
->reactive()
->afterStateUpdated(function ($state, $set, callable $get, $livewire) {
$plantId = $get('plant_id');
$processOrder = $get('process_order');
// $coilNo = $get('coil_number');
$set('poPlantError', null);
$set('observed_value', null);
$set('status', 'NotOk');
$set('coilNumberError', null);
$set('updated_by', Filament::auth()->user()?->name);
if (! $plantId) {
$set('coil_number', null);
$set('poPlantError', 'Please select a plant first.');
} elseif (! $processOrder) {
$set('coil_number', null);
}
// elseif ($coilNo || $coilNo == '0') {
// $existing = CharacteristicValue::where('plant_id', $plantId)
// ->where('process_order', $processOrder)
// ->where('coil_number', $coilNo)
// ->first();
// if ($existing && ! $get('id')) {
// // $set('coil_number', null);
// $set('coilNumberError', "Duplicate Coil : '{$coilNo}' found!");
// } else {
// $set('coilNumberError', null);
// }
// }
})
->extraAttributes(fn ($get) => [
'class' => $get('coilNumberError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('coilNumberError') ? $get('coilNumberError') : null)
->hintColor('danger')
->rule(function (callable $get) {
return Rule::unique('characteristic_values', 'coil_number')
->where('plant_id', $get('plant_id'))
->where('process_order', $get('process_order'))
->ignore($get('id')); // Ignore current record during updates
})
->required(),
Forms\Components\TextInput::make('observed_value')
->label('Observed Value')
->reactive()
->afterStateUpdated(function ($state, $set, callable $get) {
$plantId = $get('plant_id');
$itemId = $get('item_id');
$lineId = $get('line_id');
$machineId = $get('machine_id');
$set('updated_by', Filament::auth()->user()?->name);
if (! $plantId || ! $itemId || ! $lineId || ! $machineId) {
$set('observed_value', null);
$set('status', 'NotOk');
return;
}
if (Str::length($state) <= 0 || ! is_numeric($state) || ! preg_match('/^\d+(\.\d+)?$/', $state)
) {
$set('status', 'NotOk');
return;
}
$specVal = ProductCharacteristicsMaster::where('plant_id', $plantId)->where('item_id', $itemId)->where('line_id', $lineId)->where('machine_id', $machineId)->first();
if (! $specVal) {
$set('status', 'NotOk');
return;
}
$lowLimit = $specVal?->lower ?? 0;
$uppLimit = $specVal?->upper ?? 0;
if (Str::length($lowLimit) <= 0 || ! is_numeric($lowLimit) || ! preg_match('/^\d+(\.\d+)?$/', $lowLimit)
) {
$set('status', 'NotOk');
return;
} elseif (Str::length($uppLimit) <= 0 || ! is_numeric($uppLimit) || ! preg_match('/^\d+(\.\d+)?$/', $uppLimit)
) {
$set('status', 'NotOk');
return;
}
if (($lowLimit == 0 && $uppLimit == 0) || ($uppLimit == 0)) {
$set('status', 'NotOk');
return;
}
if ($lowLimit > $state || $uppLimit < $state) {
$set('status', 'NotOk');
return;
}
$set('status', 'Ok');
})
->required(),
Forms\Components\TextInput::make('status')// Select
->label('Status')
// ->options([
// 'Ok' => 'OK',
// 'NotOk' => 'Not Ok',
// ])
->reactive()
->default('NotOk')
->readOnly()
->required(),
Forms\Components\Hidden::make('created_by')
->label('Created By')
->default(Filament::auth()->user()?->name),
Forms\Components\Hidden::make('updated_by')
->label('Updated By')
->default(Filament::auth()->user()?->name),
Forms\Components\TextInput::make('id')
->hidden()
->readOnly(),
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('No.')
->label('No.')
->getStateUsing(function ($record, $livewire, $column, $rowLoop) {
$paginator = $livewire->getTableRecords();
$perPage = method_exists($paginator, 'perPage') ? $paginator->perPage() : 10;
$currentPage = method_exists($paginator, 'currentPage') ? $paginator->currentPage() : 1;
return ($currentPage - 1) * $perPage + $rowLoop->iteration;
}),
Tables\Columns\TextColumn::make('plant.name')
->label('Plant Name')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('line.name')
->label('Line Name')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('item.code')
->label('Item Code')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('item.description')
->label('Item Description')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('machine.work_center')
->label('Work Center')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('process_order')
->label('Process Order')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('coil_number')
->label('Coil Number')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('machine.name')
->label('Spec. Value')
// ->searchable()
->formatStateUsing(function ($record) {
$specVal = ProductCharacteristicsMaster::where('plant_id', $record->plant_id)->where('item_id', $record->item_id)->where('line_id', $record->line_id)->where('machine_id', $record->machine_id)->first();
// return $record?->plant_id.'-'.$record?->item_id.'-'.$record->line_id.'-'.$record?->machine_id;
return $specVal?->lower.' - '.$specVal?->upper;
})
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('observed_value')
->label('Observed value')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('status')
->label('Status')
->searchable()
// ->formatStateUsing(function ($record) {
// return empty($record->status == 'Ok') ? 'Ok' : 'Not Ok';
// })
->color(fn (string $state): string => match ($state) {
'Ok' => 'success',
'Not Ok' => 'danger',
'NotOk' => 'danger',
default => 'gray',
})
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('created_at')
->label('Created At')
->alignCenter()
->dateTime()
->sortable(),
Tables\Columns\TextColumn::make('created_by')
->label('Created By')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('updated_at')
->label('Updated At')
->alignCenter()
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('updated_by')
->label('Updated By')
->alignCenter()
->searchable()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('deleted_at')
->label('Deleted At')
->alignCenter()
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
// ->filters([
// Tables\Filters\TrashedFilter::make(),
// ])
->filters([
Tables\Filters\TrashedFilter::make(),
Filter::make('advanced_filters')
->label('Advanced Filters')
->form([
Select::make('Plant')
->label('Search by Plant Name')
->nullable()
->searchable()
->reactive()
->options(function (callable $get) {
$userHas = Filament::auth()->user()->plant_id;
if ($userHas && strlen($userHas) > 0) {
return Plant::where('id', $userHas)->pluck('name', 'id')->toArray();
} else {
return Plant::whereHas('characteristicValues', function ($query) {
$query->whereNotNull('id');
})->orderBy('code')->pluck('name', 'id');
}
// return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::orderBy('code')->pluck('name', 'id')->toArray();
})
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('Item', null);
$set('Machine', null);
}),
Select::make('Line')
->label('Search by Line Name')
->nullable()
->searchable()
->reactive()
->options(function (callable $get) {
$plantId = $get('Plant');
if (empty($plantId)) {
return [];
}
return Line::whereHas('characteristicValues', function ($query) use ($plantId) {
if ($plantId) {
$query->where('plant_id', $plantId);
}
})->pluck('name', 'id');
// return $plantId ? Item::where('plant_id', $plantId)->pluck('code', 'id') : [];
})
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('Item', null);
$set('Machine', null);
}),
Select::make('Item')
->label('Search by Item Code')
->nullable()
->searchable()
->reactive()
->options(function (callable $get) {
$plantId = $get('Plant');
if (empty($plantId)) {
return [];
}
return Item::whereHas('characteristicValues', function ($query) use ($plantId) {
if ($plantId) {
$query->where('plant_id', $plantId);
}
})->pluck('code', 'id');
// return $plantId ? Item::where('plant_id', $plantId)->pluck('code', 'id') : [];
})
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('process_order', null);
}),
Select::make('Machine')
->label('Search by Work Center')
->nullable()
->searchable()
->reactive()
->options(function (callable $get) {
$plantId = $get('Plant');
$lineId = $get('Line');
if (empty($plantId) || empty($lineId)) {
return [];
}
return Machine::whereHas('characteristicValues', function ($query) use ($plantId, $lineId) {
if ($plantId && $lineId) {
$query->where('plant_id', $plantId)->where('line_id', $lineId);
}
})->pluck('work_center', 'id');
// return $plantId ? Item::where('plant_id', $plantId)->pluck('code', 'id') : [];
})
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('process_order', null);
}),
TextInput::make('process_order')
->label('Process Order')
->placeholder('Enter Process Order'),
TextInput::make('coil_number')
->label('Coil Number')
->placeholder(placeholder: 'Enter Coil Number'),
Select::make('status')
->label('Status')
->options([
'Ok' => 'OK',
'NotOk' => 'Not Ok',
]),
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) {
// Hide all records initially if no filters are applied
if (empty($data['Plant']) && empty($data['Line']) && empty($data['Item']) && empty($data['Machine']) && empty($data['process_order']) && empty($data['coil_number']) && empty($data['status']) && empty($data['created_from']) && empty($data['created_to'])) {
return $query->whereRaw('1 = 0');
}
if (! empty($data['Plant'])) {
$query->where('plant_id', $data['Plant']);
} else {
$userHas = Filament::auth()->user()->plant_id;
if ($userHas && strlen($userHas) > 0) {
return $query->whereRaw('1 = 0');
}
}
if (! empty($data['Line'])) {
$query->where('line_id', $data['Line']);
}
if (! empty($data['Item'])) {
$query->where('item_id', $data['Item']);
}
if (! empty($data['Machine'])) {
$query->where('machine_id', $data['Machine']);
}
if (! empty($data['process_order'])) {
$query->where('process_order', 'like', '%'.$data['process_order'].'%');
}
if (! empty($data['coil_number'])) {
$query->where('coil_number', 'like', '%'.$data['coil_number'].'%');
}
if (! empty($data['status'])) {
$query->where('status', $data['status']);
}
if (! empty($data['created_from'])) {
$query->where('created_at', '>=', $data['created_from']);
}
if (! empty($data['created_to'])) {
$query->where('created_at', '<=', $data['created_to']);
}
// $query->orderBy('created_at', 'asc');
})
->indicateUsing(function (array $data) {
$indicators = [];
if (! empty($data['Plant'])) {
$indicators[] = 'Plant Name: '.Plant::where('id', $data['Plant'])->value('name');
} else {
$userHas = Filament::auth()->user()->plant_id;
if ($userHas && strlen($userHas) > 0) {
return 'Plant: Choose plant to filter records.';
}
}
if (! empty($data['Line'])) {
$indicators[] = 'Line Name: '.Line::where('id', $data['Line'])->value('name');
}
if (! empty($data['Item'])) {
$indicators[] = 'Item Code: '.Item::where('id', $data['Item'])->value('code');
}
if (! empty($data['Machine'])) {
$indicators[] = 'Work Center: '.Machine::where('id', $data['Machine'])->value('work_center');
}
if (! empty($data['process_order'])) {
$indicators[] = 'Process Order: '.$data['process_order'];
}
if (! empty($data['coil_number'])) {
$indicators[] = 'Coil Number: '.$data['coil_number'];
}
if (! empty($data['status'])) {
$indicators[] = 'Status: '.$data['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(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
Tables\Actions\ForceDeleteBulkAction::make(),
Tables\Actions\RestoreBulkAction::make(),
]),
])
->headerActions([
ImportAction::make()
->importer(CharacteristicValueImporter::class)
->label('Import Characteristic Value')
->color('warning')
->visible(function () {
return Filament::auth()->user()->can('view import characteristic value');
}),
ExportAction::make()
->exporter(CharacteristicValueExporter::class)
->label('Export Characteristic Value')
->color('warning')
->visible(function () {
return Filament::auth()->user()->can('view export characteristic value');
}),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListCharacteristicValues::route('/'),
'create' => Pages\CreateCharacteristicValue::route('/create'),
'view' => Pages\ViewCharacteristicValue::route('/{record}'),
'edit' => Pages\EditCharacteristicValue::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\CharacteristicValueResource\Pages;
use App\Filament\Resources\CharacteristicValueResource;
use Filament\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateCharacteristicValue extends CreateRecord
{
protected static string $resource = CharacteristicValueResource::class;
}

View File

@@ -0,0 +1,22 @@
<?php
namespace App\Filament\Resources\CharacteristicValueResource\Pages;
use App\Filament\Resources\CharacteristicValueResource;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;
class EditCharacteristicValue extends EditRecord
{
protected static string $resource = CharacteristicValueResource::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\CharacteristicValueResource\Pages;
use App\Filament\Resources\CharacteristicValueResource;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;
class ListCharacteristicValues extends ListRecords
{
protected static string $resource = CharacteristicValueResource::class;
protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}

View File

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

View File

@@ -139,7 +139,7 @@ class CreateInvoiceValidation extends CreateRecord
$user1 = Filament::auth()->user();
$user1->notify(new PushAlertNotification());
// $user1->notify(new PushAlertNotification());
$this->form->fill([
'plant_id' => $plantId,

View File

@@ -2,6 +2,8 @@
namespace App\Filament\Resources;
use App\Filament\Exports\ItemCharacteristicExporter;
use App\Filament\Imports\ItemCharacteristicImporter;
use App\Filament\Resources\ItemCharacteristicResource\Pages;
use App\Filament\Resources\ItemCharacteristicResource\RelationManagers;
use App\Models\Item;
@@ -15,6 +17,8 @@ use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Filament\Tables\Actions\ExportAction;
use Filament\Tables\Actions\ImportAction;
class ItemCharacteristicResource extends Resource
{
@@ -924,6 +928,22 @@ class ItemCharacteristicResource extends Resource
Tables\Actions\ForceDeleteBulkAction::make(),
Tables\Actions\RestoreBulkAction::make(),
]),
])
->headerActions([
ImportAction::make()
->label('Import Item Characteristics')
->color('warning')
->importer(ItemCharacteristicImporter::class)
->visible(function() {
return Filament::auth()->user()->can('view import item characteristics');
}),
ExportAction::make()
->label('Export Item Characteristics')
->color('warning')
->exporter(ItemCharacteristicExporter::class)
->visible(function() {
return Filament::auth()->user()->can('view export item characteristics');
}),
]);
}

View File

@@ -82,9 +82,6 @@ class ItemResource extends Resource
Forms\Components\TextInput::make('category')
->label('Category')
->placeholder('Scan the Category'),
Forms\Components\TextInput::make('category')
->label('Category')
->placeholder('Scan the Category'),
Forms\Components\TextInput::make('code')
->required()
->placeholder('Scan the valid code')

View File

@@ -6,6 +6,7 @@ use App\Filament\Exports\LineExporter;
use App\Filament\Imports\LineImporter;
use App\Filament\Resources\LineResource\Pages;
use App\Models\Block;
use App\Models\Item;
use App\Models\Line;
use App\Models\Plant;
use App\Models\WorkGroupMaster;
@@ -24,6 +25,11 @@ use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\Unique;
use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Tables\Filters\Filter;
class LineResource extends Resource
{
@@ -75,7 +81,7 @@ class LineResource extends Resource
Forms\Components\Select::make('block_id')
->label('Block')
->relationship('block', 'name')
->required()
// ->required()
// ->nullable(),
->reactive()
->options(function (callable $get) {
@@ -94,7 +100,6 @@ class LineResource extends Resource
$blockId = $get('block_id');
if (! $blockId) {
$set('lblockError', 'Please select a Block first.');
return;
} else {
$set('lblockError', null);
@@ -1185,7 +1190,210 @@ class LineResource extends Resource
])
->filters([
Tables\Filters\TrashedFilter::make(),
Filter::make('advanced_filters')
->label('Advanced Filters')
->form([
Select::make('Plant')
->label('Search by Plant Name')
->nullable()
->options(function (callable $get) {
$userHas = Filament::auth()->user()->plant_id;
// return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::orderBy('code')->pluck('name', 'id')->toArray();
if ($userHas && strlen($userHas) > 0) {
return Plant::where('id', $userHas)->pluck('name', 'id')->toArray();
} else {
return Plant::whereHas('lines', function ($query) {
$query->whereNotNull('id');
})->orderBy('code')->pluck('name', 'id')->toArray();
}
})
->searchable()
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get): void {
$set('name', null);
$set('type', null);
$set('work_group_id', null);
$set('created_from', null);
$set('created_to', null);
}),
Select::make('name')
->label('Search by Line Name')
->nullable()
->options(function (callable $get) {
$plantId = $get('Plant');
return $plantId ? Line::where('plant_id', $plantId)->pluck('name', 'id') : [];
})
->searchable()
->reactive(),
Select::make('type')
->label('Search by Line Type')
->nullable()
->options(function (callable $get) {
$plantId = $get('Plant');
return $plantId ? Line::where('plant_id', $plantId)->distinct()->pluck('type', 'type')->toArray(): [];
})
->searchable()
->reactive(),
Select::make('work_group_id')
->label('Search by WorkGroupCenter')
->nullable()
->options(function (callable $get) {
$plantId = $get('Plant');
$workGroupIds = Line::where('plant_id', $plantId)
->get([
'work_group1_id',
'work_group2_id',
'work_group3_id',
'work_group4_id',
'work_group5_id',
'work_group6_id',
'work_group7_id',
'work_group8_id',
'work_group9_id',
'work_group10_id',
])
->flatMap(function ($line) {
return [
$line->work_group1_id,
$line->work_group2_id,
$line->work_group3_id,
$line->work_group4_id,
$line->work_group5_id,
$line->work_group6_id,
$line->work_group7_id,
$line->work_group8_id,
$line->work_group9_id,
$line->work_group10_id,
];
})
->filter()
->unique()
->values()
->toArray();
return WorkGroupMaster::whereIn('id', $workGroupIds)
->pluck('name', 'id')
->toArray();
})
->searchable()
->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) {
// Hide all records initially if no filters are applied
if (empty($data['Plant']) && empty($data['name']) && empty($data['type']) && empty($data['work_group_id']) && empty($data['created_from']) && empty($data['created_to']) && empty($data['updated_from']) && empty($data['updated_to'])) {
// return $query->whereRaw('1 = 0');
}
if (! empty($data['Plant'])) { // $plant = $data['Plant'] ?? null
$query->where('plant_id', $data['Plant']);
} else {
$userHas = Filament::auth()->user()->plant_id;
if ($userHas && strlen($userHas) > 0) {
return $query->whereRaw('1 = 0');
}
}
if (! empty($data['name'])) {
$query->where('id', $data['name']);
}
if (! empty($data['type'])) {
$query->where('type', $data['type']);
}
// if (! empty($data['work_group_id'])) {
// $query->where('name', $data['work_group_id']);
// }
if (! empty($data['work_group_id'])) {
$query->where(function ($q) use ($data) {
$q->where('work_group1_id', $data['work_group_id'])
->orWhere('work_group2_id', $data['work_group_id'])
->orWhere('work_group3_id', $data['work_group_id'])
->orWhere('work_group4_id', $data['work_group_id'])
->orWhere('work_group5_id', $data['work_group_id'])
->orWhere('work_group6_id', $data['work_group_id'])
->orWhere('work_group7_id', $data['work_group_id'])
->orWhere('work_group8_id', $data['work_group_id'])
->orWhere('work_group9_id', $data['work_group_id'])
->orWhere('work_group10_id', $data['work_group_id']);
});
}
if (! empty($data['created_from'])) {
$query->where('created_at', '>=', $data['created_from']);
}
if (! empty($data['created_to'])) {
$query->where('created_at', '<=', $data['created_to']);
}
})
->indicateUsing(function (array $data) {
$indicators = [];
if (! empty($data['Plant'])) {
$indicators[] = 'Plant: '.Plant::where('id', $data['Plant'])->value('name');
} else {
$userHas = Filament::auth()->user()->plant_id;
if ($userHas && strlen($userHas) > 0) {
return 'Plant: Choose plant to filter records.';
}
}
if (! empty($data['name'])) {
$indicators[] = 'Line Name: '.Line::where('id', $data['name'])->value('name');
}
if (! empty($data['type'])) {
$indicators[] = 'Line Type: '.Line::where('type', $data['type'])->value('type');
}
if (! empty($data['work_group_id'])) {
$indicators[] = 'Work Group: ' .
WorkGroupMaster::where('id', $data['work_group_id'])->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['updated_from'])) {
$indicators[] = 'From: '.$data['updated_from'];
}
if (! empty($data['updated_to'])) {
$indicators[] = 'To: '.$data['updated_to'];
}
return $indicators;
}),
])
->filtersFormMaxHeight('280px')
->actions([
Tables\Actions\ViewAction::make(),
Tables\Actions\EditAction::make(),

View File

@@ -5,22 +5,26 @@ namespace App\Filament\Resources;
use App\Filament\Exports\MachineExporter;
use App\Filament\Imports\MachineImporter;
use App\Filament\Resources\MachineResource\Pages;
use App\Filament\Resources\MachineResource\RelationManagers;
use App\Models\Line;
use App\Models\Machine;
use App\Models\Plant;
use App\Models\WorkGroupMaster;
use Filament\Facades\Filament;
use Filament\Forms;
use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Forms\Get;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Actions\ExportAction;
use Filament\Tables\Actions\ImportAction;
use Filament\Tables\Filters\Filter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Filament\Tables\Actions\ImportAction;
use Filament\Tables\Actions\ExportAction;
use Illuminate\Validation\Rule;
use Str;
@@ -38,149 +42,163 @@ class MachineResource extends Resource
{
return $form
->schema([
Forms\Components\Select::make('plant_id')
->label('Plant')
->relationship('plant', 'name')
->required()
->reactive()
->options(function (callable $get) {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
})
->default(function () {
return optional(Machine::latest()->first())->plant_id;
})
->disabled(fn (Get $get) => !empty($get('id')))
->afterStateUpdated(function ($state, callable $set, callable $get) {
$plantId = $get('plant_id');
if (!$plantId) {
$set('mPlantError', 'Please select a plant first.');
$set('line_id', null);
$set('work_group_master_id', null);
return;
}
else
{
$set('mPlantError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('mPlantError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('mPlantError') ? $get('mPlantError') : null)
->hintColor('danger'),
Forms\Components\Select::make('line_id')
->label('Line')
->relationship('line', 'name')
->required()
->reactive()
->options(function (callable $get) {
if (!$get('plant_id')) {
return [];
}
Section::make('')
->schema([
Forms\Components\Select::make('plant_id')
->label('Plant Name')
->relationship('plant', 'name')
->searchable()
->required()
->columnSpan(1)
->reactive()
->options(function (callable $get) {
$userHas = Filament::auth()->user()->plant_id;
return Line::where('plant_id', $get('plant_id'))->where('no_of_operation', '>', 0)->pluck('name', 'id')->toArray();
})
->default(function () {
return optional(Machine::latest()->first())->line_id;
})
->disabled(fn (Get $get) => !empty($get('id')))
->afterStateUpdated(function ($state, callable $set, callable $get) {
$lineId = $get('line_id');
if (!$lineId) {
$set('mLineError', 'Please select a line first.');
$set('work_group_master_id', null);
return;
}
else
{
// $grpWrkCnr = Line::find($lineId)->group_work_center;
// if (!$grpWrkCnr || Str::length($grpWrkCnr) < 1)
// {
// $set('mLineError', 'Please select a group work center line.');
// $set('line_id', null);
// return;
// }
$set('mLineError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('mLineError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('mLineError') ? $get('mLineError') : null)
->hintColor('danger'),
Forms\Components\Select::make('work_group_master_id')
->label('Group Work Center')
->relationship('workGroupMaster', 'name')
->required()
->reactive()
->options(function (callable $get) {
if (!$get('plant_id') || !$get('line_id')) {
return [];
}
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::orderBy('code')->pluck('name', 'id')->toArray();
})
->default(function () {
return optional(Machine::latest()->first())->plant_id;
})
->disabled(fn (Get $get) => ! empty($get('id')))
->afterStateUpdated(function ($state, callable $set, callable $get) {
$plantId = $get('plant_id');
if (! $plantId) {
$set('mPlantError', 'Please select a plant first.');
$set('line_id', null);
$set('work_group_master_id', null);
$line = Line::find($get('line_id'));
$workGroupIds = [];
for ($i = 1; $i <= $line->no_of_operation; $i++) {
$column = "work_group{$i}_id";
if (!empty($line->$column)) {
$workGroupIds[] = $line->$column;
}
}
return;
} else {
$set('mPlantError', null);
$set('line_id', null);
$set('work_group_master_id', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('mPlantError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('mPlantError') ? $get('mPlantError') : null)
->hintColor('danger'),
Forms\Components\Select::make('line_id')
->label('Line Name')
// ->relationship('line', 'name')
->searchable()
->required()
->columnSpan(1)
->reactive()
->options(function (callable $get) {
if (! $get('plant_id')) {
return [];
}
return WorkGroupMaster::where('plant_id', $get('plant_id'))->whereIn('id', $workGroupIds)->pluck('name', 'id')->toArray();
})
->default(function () {
return optional(Machine::latest()->first())->work_group_master_id;
})
->disabled(fn (Get $get) => !empty($get('id')))
->afterStateUpdated(function ($state, callable $set, callable $get) {
$lineId = $get('line_id');
if (!$lineId) {
$set('mGroupWorkError', 'Please select a line first.');
return;
}
else
{
// $grpWrkCnr = Line::find($lineId)->group_work_center;
// if (!$grpWrkCnr || Str::length($grpWrkCnr) < 1)
// {
// $set('mGroupWorkError', 'Please select a group work center line.');
// $set('line_id', null);
// return;
// }
$set('mGroupWorkError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('mGroupWorkError') ? 'border-red-500' : '',
return Line::where('plant_id', $get('plant_id'))->where('no_of_operation', '>', 0)->pluck('name', 'id')->toArray();
})
->default(function () {
return optional(Machine::latest()->first())->line_id;
})
->disabled(fn (Get $get) => ! empty($get('id')))
->afterStateUpdated(function ($state, callable $set, callable $get) {
$lineId = $get('line_id');
if (! $lineId) {
$set('mLineError', 'Please select a line first.');
$set('work_group_master_id', null);
return;
} else {
// $grpWrkCnr = Line::find($lineId)->group_work_center;
// if (!$grpWrkCnr || Str::length($grpWrkCnr) < 1)
// {
// $set('mLineError', 'Please select a group work center line.');
// $set('line_id', null);
// return;
// }
$set('mLineError', null);
$set('work_group_master_id', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('mLineError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('mLineError') ? $get('mLineError') : null)
->hintColor('danger'),
Forms\Components\Select::make('work_group_master_id')
->label('Group Work Center')
// ->relationship('workGroupMaster', 'name')
->searchable()
->required()
->columnSpan(1)
->reactive()
->options(function (callable $get) {
if (! $get('plant_id') || ! $get('line_id')) {
return [];
}
$line = Line::find($get('line_id'));
$workGroupIds = [];
for ($i = 1; $i <= $line->no_of_operation; $i++) {
$column = "work_group{$i}_id";
if (! empty($line->$column)) {
$workGroupIds[] = $line->$column;
}
}
return WorkGroupMaster::where('plant_id', $get('plant_id'))->whereIn('id', $workGroupIds)->pluck('name', 'id')->toArray();
})
->default(function () {
return optional(Machine::latest()->first())->work_group_master_id;
})
->disabled(fn (Get $get) => ! empty($get('id')))
->afterStateUpdated(function ($state, callable $set, callable $get) {
$lineId = $get('line_id');
if (! $lineId) {
$set('mGroupWorkError', 'Please select a line first.');
$set('work_group_master_id', null);
return;
} else {
// $grpWrkCnr = Line::find($lineId)->group_work_center;
// if (!$grpWrkCnr || Str::length($grpWrkCnr) < 1)
// {
// $set('mGroupWorkError', 'Please select a group work center line.');
// $set('line_id', null);
// return;
// }
$set('mGroupWorkError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('mGroupWorkError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('mGroupWorkError') ? $get('mGroupWorkError') : null)
->hintColor('danger'),
Forms\Components\TextInput::make('work_center')
->label('Work Center')
->minLength(6)
->placeholder('Scan the valid Work Center')
->columnSpan(1)
->required()
->rule(function (callable $get) {
return Rule::unique('machines', 'work_center')
->where('plant_id', $get('plant_id'))
->ignore($get('id')); // Ignore current record during updates
}),
Forms\Components\TextInput::make('name')
->label('Description')
->minLength(5)
->placeholder('Scan the valid Description')
->columnSpan(['default' => 1, 'sm' => 2])
->required()
->rule(function (callable $get) {
return Rule::unique('machines', 'name')
// ->where('line_id', $get('line_id'))
->where('plant_id', $get('plant_id'))
->ignore($get('id')); // Ignore current record during updates
}),
Forms\Components\TextInput::make('id')
->hidden()
->readOnly(),
])
->hint(fn ($get) => $get('mGroupWorkError') ? $get('mGroupWorkError') : null)
->hintColor('danger'),
Forms\Components\TextInput::make('name')
->label('Name')
->minLength(5)
->placeholder('Scan the valid Machine Name')
->required()
->rule(function (callable $get) {
return Rule::unique('machines', 'name')
//->where('line_id', $get('line_id'))
->where('plant_id', $get('plant_id'))
->ignore($get('id')); // Ignore current record during updates
}),
Forms\Components\TextInput::make('work_center')
->label('Work Center')
->minLength(6)
->placeholder('Scan the valid Work Center')
->required()
->rule(function (callable $get) {
return Rule::unique('machines', 'work_center')
->where('plant_id', $get('plant_id'))
->ignore($get('id')); // Ignore current record during updates
}),
Forms\Components\TextInput::make('id')
->hidden()
->readOnly(),
->columns(['default' => 1, 'sm' => 2]),
]);
}
@@ -194,18 +212,19 @@ class MachineResource extends Resource
$paginator = $livewire->getTableRecords();
$perPage = method_exists($paginator, 'perPage') ? $paginator->perPage() : 10;
$currentPage = method_exists($paginator, 'currentPage') ? $paginator->currentPage() : 1;
return ($currentPage - 1) * $perPage + $rowLoop->iteration;
}),
Tables\Columns\TextColumn::make('plant.name')
->label('Plant')
->label('Plant Name')
->alignCenter()
->searchable(),
Tables\Columns\TextColumn::make('line.name')
->label('Line')
->label('Line Name')
->alignCenter()
->searchable(),
Tables\Columns\TextColumn::make('name')
->label('Name')
->label('Description')
->alignCenter()
->searchable(),
Tables\Columns\TextColumn::make('work_center')
@@ -214,7 +233,7 @@ class MachineResource extends Resource
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('workGroupMaster.name')
->label('Work Group Center')
->label('Group Work Center')
->alignCenter()
->searchable()
->sortable(),
@@ -237,7 +256,177 @@ class MachineResource extends Resource
])
->filters([
Tables\Filters\TrashedFilter::make(),
Filter::make('advanced_filters')
->label('Advanced Filters')
->form([
Select::make('Plant')
->label('Search by Plant Name')
->nullable()
->options(function (callable $get) {
$userHas = Filament::auth()->user()->plant_id;
// return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::orderBy('code')->pluck('name', 'id')->toArray();
if ($userHas && strlen($userHas) > 0) {
return Plant::where('id', $userHas)->pluck('name', 'id')->toArray();
} else {
return Plant::whereHas('machines', function ($query) {
$query->whereNotNull('id');
})->orderBy('code')->pluck('name', 'id')->toArray();
}
})
->searchable()
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get): void {
$set('code', null);
$set('operator_id', null);
}),
Select::make('Line')
->label('Search by Line')
->searchable()
->options(function (callable $get) {
$plantId = $get('Plant');
if (empty($plantId)) {
return [];
}
return Line::whereHas('machines', function ($query) use ($plantId) {
if ($plantId) {
$query->where('plant_id', $plantId);
}
})->pluck('name', 'id');
})
->searchable()
->reactive(),
TextInput::make('name')
->label('Description')
->reactive(),
Select::make('work_group_master')
->label('Search by Work Group Center')
->options(function (callable $get) {
$plantId = $get('Plant');
return WorkGroupMaster::whereHas('machines', function ($query) use ($plantId) {
if ($plantId) {
$query->where('plant_id', $plantId);
}
})
->pluck('name', 'id')
->toArray();
})
->searchable()
->reactive(),
Select::make('work_center')
->label('Search by Work Center')
->options(function (callable $get) {
$plantId = $get('Plant');
$workGroupMasterId = $get('work_group_master');
if (! $workGroupMasterId) {
return [];
}
return Machine::query()
->when($plantId, fn ($q) => $q->where('plant_id', $plantId))
->where('work_group_master_id', $workGroupMasterId)
->pluck('work_center', 'work_center')
->toArray();
})
->searchable()
->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) {
// Hide all records initially if no filters are applied
if (empty($data['Plant']) && empty($data['Line']) && empty($data['name']) && empty($data['work_group_master']) && empty($data['created_from']) && empty($data['created_to']) && empty($data['updated_from']) && empty($data['updated_to'])) {
// return $query->whereRaw('1 = 0');
}
if (! empty($data['Plant'])) { // $plant = $data['Plant'] ?? null
$query->where('plant_id', $data['Plant']);
} else {
$userHas = Filament::auth()->user()->plant_id;
if ($userHas && strlen($userHas) > 0) {
return $query->whereRaw('1 = 0');
}
}
if (! empty($data['Line'])) {
$query->where('line_id', $data['Line']);
}
if (! empty($data['name'])) {
$query->where('name', $data['name']);
}
if (! empty($data['work_group_master'])) {
$query->where('work_group_master_id', $data['work_group_master']);
}
if (! empty($data['work_center'])) {
$query->where('work_center', $data['work_center']);
}
if (! empty($data['created_from'])) {
$query->where('created_at', '>=', $data['created_from']);
}
if (! empty($data['created_to'])) {
$query->where('created_at', '<=', $data['created_to']);
}
})
->indicateUsing(function (array $data) {
$indicators = [];
if (! empty($data['Plant'])) {
$indicators[] = 'Plant: '.Plant::where('id', $data['Plant'])->value('name');
} else {
$userHas = Filament::auth()->user()->plant_id;
if ($userHas && strlen($userHas) > 0) {
return 'Plant: Choose plant to filter records.';
}
}
if (! empty($data['Line'])) {
$indicators[] = 'Line Name: '.Line::where('id', $data['Line'])->value('name');
}
if (! empty($data['name'])) {
$indicators[] = 'Description: '.$data['name'];
}
if (! empty($data['work_group_master'])) {
$indicators[] = 'Work Group Center: '.WorkGroupMaster::where('id', $data['work_group_master'])->value('name');
}
if (! empty($data['work_center'])) {
$indicators[] = 'Work Center: '.Machine::where('work_center', $data['work_center'])->value('work_center');
}
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(),
@@ -254,14 +443,14 @@ class MachineResource extends Resource
->label('Import Machines')
->color('warning')
->importer(MachineImporter::class)
->visible(function() {
->visible(function () {
return Filament::auth()->user()->can('view import machine');
}),
ExportAction::make()
->label('Export Machines')
->color('warning')
->exporter(MachineExporter::class)
->visible(function() {
->visible(function () {
return Filament::auth()->user()->can('view export machine');
}),
]);

File diff suppressed because it is too large Load Diff

View File

@@ -3,10 +3,28 @@
namespace App\Filament\Resources\ProcessOrderResource\Pages;
use App\Filament\Resources\ProcessOrderResource;
use App\Models\ProcessOrder;
use Filament\Actions;
use Filament\Facades\Filament;
use Filament\Notifications\Notification;
use Filament\Resources\Pages\CreateRecord;
class CreateProcessOrder extends CreateRecord
{
protected static string $resource = ProcessOrderResource::class;
protected function afterCreate(): void
{
$plantId = $this->data['plant_id'];
$processOrder = $this->data['process_order'];
$updatedQty = (float) $this->data['updated_order_quantity'];
ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->update([
'updated_order_quantity' => $updatedQty,
'updated_by' => Filament::auth()->user()->name,
]);
}
}

View File

@@ -3,13 +3,78 @@
namespace App\Filament\Resources\ProcessOrderResource\Pages;
use App\Filament\Resources\ProcessOrderResource;
use App\Models\ProcessOrder;
use Filament\Actions;
use Filament\Facades\Filament;
use Filament\Notifications\Notification;
use Filament\Resources\Pages\EditRecord;
class EditProcessOrder extends EditRecord
{
protected static string $resource = ProcessOrderResource::class;
protected function beforeSave(): void
{
$plantId = $this->data['plant_id'] ?? null;
$processOrder = $this->data['process_order'] ?? null;
$extraQty = (float) ($this->data['updated_order_quantity'] ?? 0);
$extraQtyRaw = $this->data['updated_order_quantity'] ?? '';
if (!preg_match('/^\d+(\.\d{1,3})?$/', $extraQtyRaw)) {
Notification::make()
->title('Invalid Quantity')
->body('Only positive numbers with up to 3 decimal places are allowed.')
->danger()
->send();
$this->halt(); // stop save
}
if ($extraQty < 0)
{
Notification::make()
->title('Invalid Quantity')
->body('Negative values are not allowed.')
->danger()
->send();
$this->halt();
}
if ($extraQty > 0) {
$order = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->first();
if ($order) {
$baseQty = (float) $order->order_quantity;
$maxAllowed = $baseQty * 0.10;
$maxFinalQty = $baseQty + $maxAllowed;
if ($extraQty > $maxFinalQty) {
Notification::make()
->title('Limit Exceeded')
->body("You can only increase the order by 10% (Max allowed: {$maxFinalQty}).")
->danger()
->send();
$this->halt(); // stops save
}
ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->update([
'updated_order_quantity' => $extraQty,
'updated_by' => Filament::auth()->user()?->name,
]);
}
}
}
protected function getHeaderActions(): array
{
return [

View File

@@ -5,48 +5,70 @@ namespace App\Filament\Resources;
use App\Filament\Exports\ProductCharacteristicsMasterExporter;
use App\Filament\Imports\ProductCharacteristicsMasterImporter;
use App\Filament\Resources\ProductCharacteristicsMasterResource\Pages;
use App\Filament\Resources\ProductCharacteristicsMasterResource\RelationManagers;
use App\Models\Item;
use App\Models\Line;
use App\Models\Machine;
use App\Models\Plant;
use App\Models\ProductCharacteristicsMaster;
use App\Models\WorkGroupMaster;
use Closure;
use Filament\Facades\Filament;
use Filament\Forms;
use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Forms\Get;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Actions\ExportAction;
use Filament\Tables\Actions\ImportAction;
use Filament\Tables\Filters\Filter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Filament\Tables\Actions\ImportAction;
use Filament\Tables\Actions\ExportAction;
use Illuminate\Validation\Rule;
use Str;
class ProductCharacteristicsMasterResource extends Resource
{
protected static ?string $model = ProductCharacteristicsMaster::class;
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
protected static ?string $navigationGroup = 'Process Order';
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Select::make('plant_id')
->label('Plant')
->label('Plant Name')
->relationship('plant', 'name')
->searchable()
->options(function (callable $get) {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::orderBy('code')->pluck('name', 'id')->toArray();
})
->disabled(fn (Get $get) => ! empty($get('id')))
->default(function () {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? $userHas : optional(ProductCharacteristicsMaster::latest()->first())->plant_id;
})
->afterStateUpdated(function ($state, callable $set) {
$set('updated_by', Filament::auth()->user()?->name);
$set('item_id', null);
$set('line_id', null);
$set('work_group_master_id', null);
$set('machine_id', null);
})
->reactive()
->required(),
Forms\Components\Select::make('item_id')
->label('Item Code')
//->relationship('item', 'code')
// ->relationship('item', 'code')
->searchable()
->reactive()
->options(function (callable $get) {
@@ -54,34 +76,64 @@ class ProductCharacteristicsMasterResource extends Resource
if (empty($plantId)) {
return [];
}
return \App\Models\Item::where('plant_id', $plantId)->pluck('code', 'id');
return Item::where('plant_id', $plantId)->pluck('code', 'id');
})
->disabled(fn (Get $get) => ! empty($get('id')))
->afterStateUpdated(function ($state, callable $set) {
$set('updated_by', Filament::auth()->user()?->name);
$set('line_id', null);
$set('work_group_master_id', null);
$set('machine_id', null);
})
->rules([
function (callable $get) {
return Rule::unique('product_characteristics_masters', 'item_id')
->where('plant_id', $get('plant_id'))
->where('line_id', $get('line_id'))
->where('work_group_master_id', $get('work_group_master_id'))
->where('machine_id', $get('machine_id'))
->where('characteristics_type', $get('characteristics_type'))
->where('name', $get('name'))
->ignore($get('id'));
},
// function (callable $get): Closure {
// return function (string $attribute, $value, Closure $fail) use ($get) {
// $rework = $get('rework_status');
// if ($value && Str::contains($value, '.') && $rework == 0) {
// $fail("Rework status should be 'Yes' for rework coil number '{$value}'!");
// }
// };
// },
])
->required(),
Forms\Components\Select::make('line_id')
->label('Line')
->label('Line Name')
->reactive()
->searchable()
->options(function (callable $get) {
$plantId = $get('plant_id');
if (empty($plantId)) {
return [];
}
return Line::where('plant_id', $plantId)->pluck('name', 'id');
})
// ->disabled(fn (Get $get) => ! empty($get('id')))
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('updated_by', Filament::auth()->user()?->name);
$set('work_group_master_id', null);
$set('machine_id', null);
if (!$get('work_group_master_id')) {
$set('machine_id', null);
}
})
// ->relationship('line', 'name'),
->required(),
// ->relationship('line', 'name'),
Forms\Components\Select::make('work_group_master_id')
->label('Group Work Center')
->required()
->reactive()
->searchable()
->options(function (callable $get) {
if (!$get('plant_id') || !$get('line_id')) {
if (! $get('plant_id') || ! $get('line_id')) {
return [];
}
@@ -89,23 +141,23 @@ class ProductCharacteristicsMasterResource extends Resource
$workGroupIds = [];
for ($i = 1; $i <= $line->no_of_operation; $i++) {
$column = "work_group{$i}_id";
if (!empty($line->$column)) {
if (! empty($line->$column)) {
$workGroupIds[] = $line->$column;
}
}
return WorkGroupMaster::where('plant_id', $get('plant_id'))->whereIn('id', $workGroupIds)->pluck('name', 'id')->toArray();
})
->disabled(fn (Get $get) => !empty($get('id')))
// ->disabled(fn (Get $get) => ! empty($get('id')))
->afterStateUpdated(function ($state, callable $set, callable $get) {
$lineId = $get('line_id');
if (!$lineId) {
$set('updated_by', Filament::auth()->user()?->name);
$set('machine_id', null);
if (! $lineId) {
$set('mGroupWorkError', 'Please select a line first.');
$set('machine_id', null);
return;
}
else
{
} else {
// $grpWrkCnr = Line::find($lineId)->group_work_center;
// if (!$grpWrkCnr || Str::length($grpWrkCnr) < 1)
// {
@@ -114,20 +166,19 @@ class ProductCharacteristicsMasterResource extends Resource
// return;
// }
$set('mGroupWorkError', null);
$set('machine_id', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('mGroupWorkError') ? 'border-red-500' : '',
])
// ->dehydrateStateUsing(fn ($state) => null)
// ->dehydrateStateUsing(fn ($state) => null)
->hint(fn ($get) => $get('mGroupWorkError') ? $get('mGroupWorkError') : null)
->hintColor('danger'),
Forms\Components\Select::make('machine_id')
->label('Work Center')
//->relationship('machine', 'name'),
->searchable()
// ->relationship('machine', 'name'),
->reactive()
->searchable()
->options(function (callable $get) {
$plantId = $get('plant_id');
$lineId = $get('line_id');
@@ -142,30 +193,60 @@ class ProductCharacteristicsMasterResource extends Resource
->where('work_group_master_id', $workGroupId)
->pluck('work_center', 'id');
})
// ->disabled(fn (Get $get) => ! empty($get('id')))
->afterStateUpdated(function ($state, callable $set, callable $get) {
if (!$get('plant_id') || !$get('line_id') || !$get('work_group_master_id')) {
if (! $get('plant_id') || ! $get('line_id') || ! $get('work_group_master_id')) {
$set('machine_id', null);
}
$set('updated_by', Filament::auth()->user()?->name);
})
->required(),
Forms\Components\Select::make('characteristics_type')
->label('Characteristics Type')
->options([
'Product' => 'Product',
'Process' => 'Process',
'Process' => 'Process',
])
->reactive()
->searchable()
// ->preload()
->disabled(fn (Get $get) => ! empty($get('id') && ! Filament::auth()->user()->hasRole('Super Admin')))
->afterStateUpdated(function ($state, callable $set) {
$set('updated_by', Filament::auth()->user()?->name);
})
->required(),
Forms\Components\TextInput::make('name')
->label('Name'),
->label('Characteristics Name')
->reactive()
->afterStateUpdated(function ($state, callable $set) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\TextInput::make('category')
->label('Category')
->reactive()
->afterStateUpdated(function ($state, callable $set) {
$set('updated_by', Filament::auth()->user()?->name);
}),
Forms\Components\Select::make('inspection_type')
->label('Inspection Type')
->searchable()
->options([
'Visual' => 'Visual',
'Value' => 'Value',
'Value' => 'Value',
])
->reactive()
// ->preload()
->disabled(fn (Get $get) => ! empty($get('id') && ! Filament::auth()->user()->hasRole('Super Admin')))
->afterStateUpdated(function ($state, callable $set) {
if ($state == 'Visual') {
$set('lower', 0);
$set('middle', 0);
$set('upper', 0);
}
$set('updated_by', Filament::auth()->user()?->name);
})
->required(),
// Forms\Components\Select::make('result')
// ->label('Visual Type')
// ->reactive()
@@ -183,38 +264,68 @@ class ProductCharacteristicsMasterResource extends Resource
// session()->put('temp_result', $state);
// })
// ->hidden(fn (callable $get) => $get('inspection_type') != 'Visual'),
Forms\Components\TextInput::make('upper')
->label('Upper')
->numeric()
->default(0.0)
->visible(fn (callable $get) => $get('inspection_type') == 'Value'),
Forms\Components\TextInput::make('lower')
->label('Lower')
->numeric()
->reactive()
->default(0.0)
->visible(fn (callable $get) => $get('inspection_type') == 'Value'),
->minValue(0.0)
->maxValue(fn (Get $get) => $get('upper') ?? PHP_INT_MAX)
// ->afterStateUpdated(fn ($state, callable $set, callable $get) => $set('middle', ($state + $get('upper')) / 2))
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('middle', ($state + $get('upper')) / 2);
$set('updated_by', Filament::auth()->user()?->name);
})
// ->visible(fn (callable $get) => $get('inspection_type') == 'Value')
->readOnly(fn (callable $get) => $get('inspection_type') != 'Value'),
Forms\Components\TextInput::make('upper')
->label('Upper')
->numeric()
->reactive()
->default(0.0)
->minValue(fn (Get $get) => $get('lower') ?? 0)
->maxValue(PHP_INT_MAX)
// ->afterStateUpdated(fn ($state, callable $set, callable $get) => $set('middle', ($get('lower') + $state) / 2))
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('middle', ($get('lower') + $state) / 2);
$set('updated_by', Filament::auth()->user()?->name);
})
// ->visible(fn (callable $get) => $get('inspection_type') == 'Value')
->readOnly(fn (callable $get) => $get('inspection_type') != 'Value'),
Forms\Components\TextInput::make('middle')
->label('Middle')
->readOnly()
->numeric()
->visible(fn (callable $get) => $get('inspection_type') == 'Value')
->rule(function (callable $get) {
return function (string $attribute, $value, \Closure $fail) use ($get) {
$lower = $get('lower');
$upper = $get('upper');
$middle = $value;
->reactive()
->default(0.0)
// ->rule(function (callable $get) {
// return function (string $attribute, $value, Closure $fail) use ($get) {
// $lower = $get('lower');
// $upper = $get('upper');
// $middle = $value;
if (!is_null($lower) && !is_null($upper) && !is_null($middle)) {
if (!($lower <= $middle && $middle <= $upper)) {
$fail("Middle must be between Lower and Upper (Lower ≤ Middle ≤ Upper).");
}
}
};
// if (! is_null($lower) && ! is_null($upper) && ! is_null($middle)) {
// if ((($lower <= $middle || $middle >= $upper) && $lower != $upper) || (($lower < $middle || $middle > $upper) && $lower == $upper)) {
// $fail('Middle must be between Lower and Upper (Lower ≤ Middle ≤ Upper).');
// }
// }
// };
// })
->dehydrateStateUsing(fn ($state, Get $get) => ($get('lower') + $get('upper')) / 2)
->afterStateUpdated(function ($state, callable $set) {
$set('updated_by', Filament::auth()->user()?->name);
}),
// ->visible(fn (callable $get) => $get('inspection_type') == 'Value'),
Forms\Components\Hidden::make('created_by')
->label('Created By')
->default(Filament::auth()->user()?->name),
Forms\Components\Hidden::make('updated_by')
->label('Updated By'),
->label('Updated By')
->default(Filament::auth()->user()?->name),
Forms\Components\TextInput::make('id')
->hidden()
->readOnly(),
]);
}
@@ -228,61 +339,83 @@ class ProductCharacteristicsMasterResource extends Resource
$paginator = $livewire->getTableRecords();
$perPage = method_exists($paginator, 'perPage') ? $paginator->perPage() : 10;
$currentPage = method_exists($paginator, 'currentPage') ? $paginator->currentPage() : 1;
return ($currentPage - 1) * $perPage + $rowLoop->iteration;
}),
Tables\Columns\TextColumn::make('plant.name')
->label('Plant')
->label('Plant Name')
->searchable()
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('item.code')
->label('Item Code')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('item.description')
->label('Item Description')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('category')
->label('Category')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('line.name')
->label('Line')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('characteristics_type')
->label('Characteristics Type')
->label('Line Name')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('workGroupMaster.name')
->label('Group Work Center')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('machine.work_center')
->label('Work Center')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('machine.work_center')
->label('Work Center')
Tables\Columns\TextColumn::make('characteristics_type')
->label('Characteristics Type')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('name')
->label('Characteristics Name')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('inspection_type')
->label('Inspection Type')
->alignCenter()
->sortable(),
Tables\Columns\TextColumn::make('upper')
->label('Upper')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('lower')
->label('Lower')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('middle')
->label('Middle')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('upper')
->label('Upper')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('created_at')
->label('Created At')
->alignCenter()
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
->sortable(),
Tables\Columns\TextColumn::make('created_by')
->label('Created By')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('updated_at')
->label('Updated At')
@@ -293,6 +426,7 @@ class ProductCharacteristicsMasterResource extends Resource
Tables\Columns\TextColumn::make('updated_by')
->label('Updated By')
->alignCenter()
->searchable()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('deleted_at')
@@ -304,7 +438,265 @@ class ProductCharacteristicsMasterResource extends Resource
])
->filters([
Tables\Filters\TrashedFilter::make(),
Filter::make('advanced_filters')
->label('Advanced Filters')
->form([
Select::make('Plant')
->label('Search by Plant Name')
->nullable()
->searchable()
->reactive()
->options(function (callable $get) {
$userHas = Filament::auth()->user()->plant_id;
if ($userHas && strlen($userHas) > 0) {
return Plant::where('id', $userHas)->pluck('name', 'id')->toArray();
} else {
return Plant::whereHas('productCharacteristicsMasters', function ($query) {
$query->whereNotNull('id');
})->orderBy('code')->pluck('name', 'id');
}
// return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::orderBy('code')->pluck('name', 'id')->toArray();
})
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('Item', null);
$set('Line', null);
$set('work_group_master', null);
$set('Machine', null);
}),
Select::make('Line')
->label('Search by Line Name')
->nullable()
->searchable()
->reactive()
->options(function (callable $get) {
$plantId = $get('Plant');
if (empty($plantId)) {
return [];
}
return Line::whereHas('productCharacteristicsMasters', function ($query) use ($plantId) {
if ($plantId) {
$query->where('plant_id', $plantId);
}
})->pluck('name', 'id');
})
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('work_group_master', null);
$set('Machine', null);
}),
Select::make('Item')
->label('Search by Item Code')
->nullable()
->searchable()
->reactive()
->options(function (callable $get) {
$plantId = $get('Plant');
if (empty($plantId)) {
return [];
}
return Item::whereHas('productCharacteristicsMasters', function ($query) use ($plantId) {
if ($plantId) {
$query->where('plant_id', $plantId);
}
})->pluck('code', 'id');
}),
// ->afterStateUpdated(function ($state, callable $set, callable $get) {
// $set('process_order', null);
// }),
Select::make('work_group_master')
->label('Search by Group Work Center')
->nullable()
->searchable()
->reactive()
->options(function (callable $get) {
$plantId = $get('Plant');
if (empty($plantId)) {
return [];
}
return WorkGroupMaster::whereHas('productCharacteristicsMasters', function ($query) use ($plantId) {
if ($plantId) {
$query->where('plant_id', $plantId);
}
})->pluck('name', 'id');
// return $plantId ? Item::where('plant_id', $plantId)->pluck('code', 'id') : [];
})
->afterStateUpdated(function ($state, callable $set, callable $get) {
$set('Machine', null);
}),
Select::make('Machine')
->label('Search by Work Center')
->nullable()
->searchable()
->reactive()
->options(function (callable $get) {
$plantId = $get('Plant');
$lineId = $get('Line');
$workGroupMasterId = $get('work_group_master');
if (empty($plantId) || empty($lineId) || empty($workGroupMasterId)) {
return [];
}
return Machine::whereHas('productCharacteristicsMasters', function ($query) use ($plantId, $lineId, $workGroupMasterId) {
if ($plantId && $lineId && $workGroupMasterId) {
$query->where('plant_id', $plantId)->where('line_id', $lineId)->where('work_group_master_id', $workGroupMasterId);
}
})->pluck('work_center', 'id');
// return $plantId ? Item::where('plant_id', $plantId)->pluck('code', 'id') : [];
}),
// ->afterStateUpdated(function ($state, callable $set, callable $get) {
// $set('process_order', null);
// }),
// TextInput::make('process_order')
// ->label('Process Order')
// ->placeholder('Enter Process Order'),
TextInput::make('name')
->label('characteristics Name')
->reactive()
->placeholder(placeholder: 'Enter characteristics Name'),
Select::make('characteristics_type')
->label('Search by Characteristics Type')
->nullable()
->searchable()
->reactive()
->options([
'Product' => 'Product',
'Process' => 'Process',
]),
Select::make('inspection_type')
->label('Search by Inspection Type')
->nullable()
->searchable()
->reactive()
->options([
'Visual' => 'Visual',
'Value' => 'Value',
]),
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) {
// Hide all records initially if no filters are applied
if (empty($data['Plant']) && empty($data['Line']) && empty($data['Item']) && empty($data['work_group_master']) && empty($data['Machine']) && empty($data['name']) && empty($data['characteristics_type']) && empty($data['inspection_type']) && empty($data['created_from']) && empty($data['created_to'])) {
return $query->whereRaw('1 = 0');
}
if (! empty($data['Plant'])) {
$query->where('plant_id', $data['Plant']);
} else {
$userHas = Filament::auth()->user()->plant_id;
if ($userHas && strlen($userHas) > 0) {
return $query->whereRaw('1 = 0');
}
}
if (! empty($data['Line'])) {
$query->where('line_id', $data['Line']);
}
if (! empty($data['Item'])) {
$query->where('item_id', $data['Item']);
}
if (! empty($data['work_group_master'])) {
$query->where('work_group_master_id', $data['work_group_master']);
}
if (! empty($data['Machine'])) {
$query->where('machine_id', $data['Machine']);
}
if (! empty($data['name'])) {
$query->where('name', 'like', '%'.$data['name'].'%');
}
if (! empty($data['characteristics_type'])) {
$query->where('characteristics_type', $data['characteristics_type']);
}
if (! empty($data['inspection_type'])) {
$query->where('inspection_type', $data['inspection_type']);
}
if (! empty($data['created_from'])) {
$query->where('created_at', '>=', $data['created_from']);
}
if (! empty($data['created_to'])) {
$query->where('created_at', '<=', $data['created_to']);
}
// $query->orderBy('created_at', 'asc');
})
->indicateUsing(function (array $data) {
$indicators = [];
if (! empty($data['Plant'])) {
$indicators[] = 'Plant Name: '.Plant::where('id', $data['Plant'])->value('name');
} else {
$userHas = Filament::auth()->user()->plant_id;
if ($userHas && strlen($userHas) > 0) {
return 'Plant: Choose plant to filter records.';
}
}
if (! empty($data['Line'])) {
$indicators[] = 'Line Name: '.Line::where('id', $data['Line'])->value('name');
}
if (! empty($data['Item'])) {
$indicators[] = 'Item Name: '.Item::where('id', $data['Item'])->value('code');
}
if (! empty($data['work_group_master'])) {
$indicators[] = 'Group Work Center: '.WorkGroupMaster::where('id', $data['work_group_master'])->value('name');
}
if (! empty($data['Machine'])) {
$indicators[] = 'Work Center: '.Machine::where('id', $data['Machine'])->value('work_center');
}
if (! empty($data['name'])) {
$indicators[] = 'Characteristics Name: '.$data['name'];
}
if (! empty($data['characteristics_type'])) {
$indicators[] = 'Characteristics Type: '.$data['characteristics_type'];
}
if (! empty($data['inspection_type'])) {
$indicators[] = 'Inspection Type: '.$data['inspection_type'];
}
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(),
@@ -321,14 +713,14 @@ class ProductCharacteristicsMasterResource extends Resource
->label('Import Product Characteristics Masters')
->color('warning')
->importer(ProductCharacteristicsMasterImporter::class)
->visible(function() {
->visible(function () {
return Filament::auth()->user()->can('view import product characteristics master');
}),
ExportAction::make()
->label('Export Product Characteristics Masters')
->color('warning')
->exporter(ProductCharacteristicsMasterExporter::class)
->visible(function() {
->visible(function () {
return Filament::auth()->user()->can('view export product characteristics master');
}),
]);

View File

@@ -437,7 +437,7 @@ class ProductionPlanResource extends Resource
->sortable()
->searchable(),
Tables\Columns\TextColumn::make('line.name')
->label('Plant')
->label('Line')
->alignCenter()
->sortable()
->searchable(),
@@ -476,7 +476,6 @@ class ProductionPlanResource extends Resource
// ->label('Shift')
// ->alignCenter()
// ->sortable(), // ->searchable(),
Tables\Columns\TextColumn::make('created_at')
->label('Created At')
->dateTime()

View File

@@ -158,9 +158,6 @@ class EditRfqTransporterBid extends EditRecord
$body
));
}
}
protected function getHeaderActions(): array

View File

@@ -15,6 +15,9 @@ use Storage;
use Maatwebsite\Excel\Facades\Excel;
use Livewire\Livewire;
use Str;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
class CreateSerialValidation extends CreateRecord
{
@@ -67,6 +70,8 @@ class CreateSerialValidation extends CreateRecord
$invoiceNumber = trim($invoiceNumber);
$parts = explode('.', $invoiceNumber);
$this->showCapacitorInput = false;
$user = Filament::auth()->user();
@@ -90,9 +95,60 @@ class CreateSerialValidation extends CreateRecord
//..GET SERIAL INVOICE API
// $decodedJwt = JWT::decode($invoiceNumber, new Key('dummy_key', 'HS256')); // replace 'dummy_key' with actual key if needed
// if (!$decodedJwt || !isset($decodedJwt->data)) {
// Notification::make()
// ->title("Invalid e-Invoice QR data or format received...")
// ->info()
// ->seconds(1)
// ->send();
// return;
// }
// $documentData = $decodedJwt->data; // This should be JSON string containing DocNo
// // Extract DocNo using regex
// preg_match('/"DocNo"\s*:\s*"([^"]+)"/', $documentData, $matches);
// if (isset($matches[1])) {
// $this->invoiceNumber = $matches[1];
// } else {
// Notification::make()
// ->title("DocNo not found in QR data...")
// ->info()
// ->seconds(1)
// ->send();
// return;
// }
//..
// Decode JWT payload
$payloadJson = base64_decode(strtr($parts[1], '-_', '+/'));
$payload = json_decode($payloadJson, true);
if (!isset($payload['data'])) {
throw new \Exception('Invalid payload');
}
$documentData = $payload['data'];
// Extract DocNo
preg_match('/"DocNo"\s*:\s*"([^"]+)"/', $documentData, $matches);
if (!isset($matches[1])) {
// throw new \Exception('DocNo not found');
}
if (isset($matches[1])) {
$invoiceNumber = $matches[1];
//dd($invoiceNumber);
}
$updateStatus = $this->form->getState()['update_invoice'] ?? null;
$this->invoiceNumber = trim($this->form->getState()['invoice_number']) ?? $invoiceNumber;

View File

@@ -124,36 +124,57 @@ class StickerStructureDetailResource extends Resource
{
return $table
->columns([
Tables\Columns\TextColumn::make('id')
->label('ID')
->numeric()
->sortable(),
Tables\Columns\TextColumn::make('No.')
->label('No.')
->getStateUsing(function ($record, $livewire, $column, $rowLoop) {
$paginator = $livewire->getTableRecords();
$perPage = method_exists($paginator, 'perPage') ? $paginator->perPage() : 10;
$currentPage = method_exists($paginator, 'currentPage') ? $paginator->currentPage() : 1;
return ($currentPage - 1) * $perPage + $rowLoop->iteration;
}),
Tables\Columns\TextColumn::make('plant.code')
->label('Plant Code')
->alignCenter(),
Tables\Columns\TextColumn::make('itemCharacteristic.item.code')
->label('Item')
->alignCenter(),
Tables\Columns\TextColumn::make('sticker_id')
->label('Sticker ID'),
->label('Sticker ID')
->alignCenter(),
Tables\Columns\TextColumn::make('sticker_width')
->label('Sticker Width'),
->label('Sticker Width')
->alignCenter(),
Tables\Columns\TextColumn::make('sticker_height')
->label('Sticker Height'),
->label('Sticker Height')
->alignCenter(),
Tables\Columns\TextColumn::make('sticker_lmargin')
->label('Sticker Left Margin'),
->label('Sticker Left Margin')
->alignCenter(),
Tables\Columns\TextColumn::make('sticker_rmargin')
->label('Sticker Right Margin'),
->label('Sticker Right Margin')
->alignCenter(),
Tables\Columns\TextColumn::make('sticker_tmargin')
->label('Sticker Top Margin'),
->label('Sticker Top Margin')
->alignCenter(),
Tables\Columns\TextColumn::make('sticker_bmargin')
->label('Sticker Bottom Margin'),
->label('Sticker Bottom Margin')
->alignCenter(),
Tables\Columns\TextColumn::make('created_at')
->label('Created At')
->alignCenter()
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('updated_at')
->label('Updated At')
->alignCenter()
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('deleted_at')
->label('Deleted At')
->alignCenter()
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),

View File

@@ -387,20 +387,179 @@ class CreateStickerValidation extends CreateRecord
// ]);
}
// foreach ($stickers as $sticker) {
// // $printerName = $this->getCupsPrinterNameByIp($sticker['print_ip']);
// \Log::info("Looking up printer for IP: " . $sticker['print_ip']);
// $printerName = $this->getCupsPrinterNameByIp($sticker['print_ip']);
// \Log::info("Found printer: " . ($printerName ?? 'NULL'));
// if (! $printerName) {
// Notification::make()
// ->danger()
// ->title('Printer Not Found')
// ->body("No CUPS printer configured for IP: {$sticker['print_ip']}")
// ->send();
// return;
// }
// $structure = StickerStructureDetail::findOrFail($sticker['sticker_id']);
// $itemCharacteristic = ItemCharacteristic::where('plant_id', $this->plantId)
// ->where('id', $sticker['item_characteristic'])
// ->firstOrFail();
// $dynamicElements = StickerDetail::where(
// 'sticker_structure_detail_id',
// $structure->id
// )->where('element_type', 'Dynamic')->get();
// /** STEP 3: Stream PDF to CUPS (STDIN) */
// $process = proc_open(
// 'lp -d ' . escapeshellarg($printerName) . ' -o fit-to-page -',
// [
// ['pipe', 'r'], // STDIN
// ['pipe', 'w'], // STDOUT
// ['pipe', 'w'], // STDERR
// ],
// $pipes
// );
// if (! is_resource($process)) {
// Notification::make()
// ->danger()
// ->title('Print Failed')
// ->body('Unable to start CUPS print process.')
// ->send();
// return;
// // continue;
// }
// $pdfContent = (new StickerPdfService())->generatePdf1(
// $structure->sticker_id,
// $dynamicElements,
// $itemCharacteristic,
// $serialNumber,
// $serNo
// );
// fwrite($pipes[0], $pdfContent);
// fclose($pipes[0]);
// $stderr = stream_get_contents($pipes[2]);
// fclose($pipes[1]);
// fclose($pipes[2]);
// $status = proc_close($process);
// if ($status != 0) {
// Notification::make()
// ->danger()
// ->title('Print Failed')
// ->body("CUPS error: {$stderr}")
// ->send();
// return;
// }
// }
foreach ($stickers as $sticker)
{
\Log::info("Looking up printer for IP: " . $sticker['print_ip']);
$printerName = $this->getCupsPrinterNameByIp($sticker['print_ip']);
\Log::info("Found printer: " . ($printerName ?? 'NULL'));
if (! $printerName) {
Notification::make()
->danger()
->title('Printer Not Found')
->body("No CUPS printer configured for IP: {$sticker['print_ip']}")
->send();
return;
}
$structure = StickerStructureDetail::findOrFail($sticker['sticker_id']);
$itemCharacteristic = ItemCharacteristic::where('plant_id', $this->plantId)
->where('id', $sticker['item_characteristic'])
->firstOrFail();
$dynamicElements = StickerDetail::where(
'sticker_structure_detail_id',
$structure->id
)->where('element_type', 'Dynamic')->get();
$pdfContent = (new StickerPdfService())->generatePdf1(
$structure->sticker_id,
$dynamicElements,
$itemCharacteristic,
$serialNumber,
$serNo
);
$tempPdfPath = storage_path('app/temp_sticker_' . uniqid() . '.pdf');
file_put_contents($tempPdfPath, $pdfContent);
exec(
"lp -d " . escapeshellarg($printerName) . " " . escapeshellarg($tempPdfPath),
$output,
$status
);
\Log::info("LP Output:", $output);
\Log::info("LP Status: " . $status);
if ($status != 0) {
Notification::make()
->danger()
->title('Print Failed')
->body("CUPS error while printing.")
->send();
if (file_exists($tempPdfPath)) {
unlink($tempPdfPath);
}
return;
}
if (file_exists($tempPdfPath)) {
unlink($tempPdfPath);
}
}
Notification::make()
->success()
->title('Sticker Printed')
->body("Sticker for Serial Number: $serialNumber printed successfully!")
->seconds(3)
->send();
// [$itemCode, $serialNumber] = explode('|', $serNo);
// $this->dispatch('open-sticker-pdf', [
// 'url' => url("/sticker/pdf/{$itemCode}/{$serialNumber}/$this->plantId/$this->ref_number")
// ]);
}
protected function getCupsPrinterNameByIp(string $ip): ?string
{
// exec('lpstat -v 2>&1', $output, $status);
exec('lpstat -h cups:631 -v 2>&1', $output, $status);
if ($status != 0 || empty($output)) {
return null;
}
foreach ($output as $line){
foreach ($output as $line) {
$parts = explode(':', $line, 2);
if (count($parts) < 2) continue;
@@ -411,6 +570,7 @@ class CreateStickerValidation extends CreateRecord
return $printerName;
}
}
return null;
}
}

View File

@@ -52,7 +52,6 @@ class UserResource extends Resource
// ->email()
->unique(ignoreRecord: true)
->required()
->readOnly()
// ->rule(function (callable $get) {
// return Rule::unique('users', 'email')
// ->ignore($get('id')); // Ignore current record during updates

View File

@@ -5,22 +5,27 @@ namespace App\Filament\Resources;
use App\Filament\Exports\WorkGroupMasterExporter;
use App\Filament\Imports\WorkGroupMasterImporter;
use App\Filament\Resources\WorkGroupMasterResource\Pages;
use App\Filament\Resources\WorkGroupMasterResource\RelationManagers;
use App\Models\Line;
use App\Models\Plant;
use App\Models\WorkGroupMaster;
use Filament\Facades\Filament;
use Filament\Forms;
use Filament\Forms\Components\Section;
use Filament\Forms\Form;
use Filament\Forms\Get;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Actions\ExportAction;
use Filament\Tables\Actions\ImportAction;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Filament\Forms\Components\Section;
use Filament\Facades\Filament;
use Filament\Tables\Actions\ImportAction;
use Filament\Tables\Actions\ExportAction;
use Illuminate\Validation\Rule;
use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Tables\Filters\Filter;
class WorkGroupMasterResource extends Resource
{
@@ -37,68 +42,76 @@ class WorkGroupMasterResource extends Resource
return $form
->schema([
Section::make('')
->schema([
Forms\Components\Select::make('plant_id')
->label('Plant')
->relationship('plant', 'name')
->reactive()
->columnSpan(1)
->required()
->options(function (callable $get) {
$userHas = Filament::auth()->user()->plant_id;
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::pluck('name', 'id')->toArray();
})
->afterStateUpdated(function ($state, $set, callable $get) {
$plantId = $get('plant_id');
->schema([
Forms\Components\Select::make('plant_id')
->label('Plant Name')
->relationship('plant', 'name')
->searchable()
->reactive()
->columnSpan(1)
->required()
->options(function (callable $get) {
$userHas = Filament::auth()->user()->plant_id;
if (!$plantId) {
$set('pqPlantError', 'Please select a plant first.');
$set('name', null);
$set('description', null);
$set('operation_number', null);
return;
}
return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::orderBy('code')->pluck('name', 'id')->toArray();
})
->default(function () {
return optional(WorkGroupMaster::latest()->first())->plant_id;
})
->disabled(fn (Get $get) => ! empty($get('id')))
->afterStateUpdated(function ($state, $set, callable $get) {
$plantId = $get('plant_id');
$set('validationError', null);
$set('pqPlantError', null);
$set('name', null);
$set('description', null);
$set('operation_number', null);
})
->hint(fn ($get) => $get('pqPlantError') ? $get('pqPlantError') : null)
->hintColor('danger'),
Forms\Components\TextInput::make('name')
->label('Name')
->required()
->minLength(6)
->columnSpan(1)
->reactive()
->rule(function (callable $get) {
return Rule::unique('work_group_masters', 'name')
->where('plant_id', $get('plant_id'))
->ignore($get('id'));
}),
Forms\Components\TextInput::make('operation_number')
->label('Operation Number')
->numeric()
->columnSpan(1)
->reactive()
->required()
->rule(function (callable $get) {
return Rule::unique('work_group_masters', 'operation_number')
->where('plant_id', $get('plant_id'))
->ignore($get('id'));
}),
Forms\Components\TextInput::make('description')
->label('Description')
->required()
->minLength(5)
->reactive()
->columnSpan(['default' => 1, 'sm' => 3]),
Forms\Components\Hidden::make('created_by')
->default(Filament::auth()->user()?->name),
])
->columns(['default' => 1, 'sm' => 3]),
$set('wgmPlantError', null);
$set('name', null);
$set('description', null);
$set('operation_number', null);
if (! $plantId) {
$set('wgmPlantError', 'Please select a plant first.');
return;
}
})
->extraAttributes(fn ($get) => [
'class' => $get('wgmPlantError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('wgmPlantError') ? $get('wgmPlantError') : null)
->hintColor('danger'),
Forms\Components\TextInput::make('name')
->label('Group Work Center')
->required()
->minLength(6)
->columnSpan(1)
->reactive()
->rule(function (callable $get) {
return Rule::unique('work_group_masters', 'name')
->where('plant_id', $get('plant_id'))
->ignore($get('id'));
}),
Forms\Components\TextInput::make('operation_number')
->label('Operation Number')
->numeric()
->columnSpan(1)
->reactive()
->required(),
// ->rule(function (callable $get) {
// return Rule::unique('work_group_masters', 'operation_number')
// ->where('plant_id', $get('plant_id'))
// ->ignore($get('id'));
// }),
Forms\Components\TextInput::make('description')
->label('Description')
->required()
->minLength(5)
->reactive()
->columnSpan(['default' => 1, 'sm' => 3]),
Forms\Components\Hidden::make('created_by')
->default(Filament::auth()->user()?->name),
Forms\Components\TextInput::make('id')
->hidden()
->readOnly(),
])
->columns(['default' => 1, 'sm' => 3]),
]);
}
@@ -112,15 +125,16 @@ class WorkGroupMasterResource extends Resource
$paginator = $livewire->getTableRecords();
$perPage = method_exists($paginator, 'perPage') ? $paginator->perPage() : 10;
$currentPage = method_exists($paginator, 'currentPage') ? $paginator->currentPage() : 1;
return ($currentPage - 1) * $perPage + $rowLoop->iteration;
}),
Tables\Columns\TextColumn::make('plant.name')
->label('Plant')
->label('Plant Name')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('name')
->label('Name')
->label('Group Work Center')
->alignCenter()
->searchable()
->sortable(),
@@ -134,23 +148,21 @@ class WorkGroupMasterResource extends Resource
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('created_at')
->label('Created At')
->alignCenter()
->dateTime()
->sortable(),
Tables\Columns\TextColumn::make('created_by')
->label('Created By')
->alignCenter()
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('created_at')
->label('Created At')
->alignCenter()
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('updated_at')
->label('Updated At')
->alignCenter()
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
->sortable(),
Tables\Columns\TextColumn::make('deleted_at')
->label('Deleted At')
->alignCenter()
@@ -160,7 +172,136 @@ class WorkGroupMasterResource extends Resource
])
->filters([
Tables\Filters\TrashedFilter::make(),
Filter::make('advanced_filters')
->label('Advanced Filters')
->form([
Select::make('Plant')
->label('Search by Plant Name')
->nullable()
->options(function (callable $get) {
$userHas = Filament::auth()->user()->plant_id;
// return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::orderBy('code')->pluck('name', 'id')->toArray();
if ($userHas && strlen($userHas) > 0) {
return Plant::where('id', $userHas)->pluck('name', 'id')->toArray();
} else {
return Plant::whereHas('workGroupMasters', function ($query) {
$query->whereNotNull('id');
})->orderBy('code')->pluck('name', 'id')->toArray();
}
})
->searchable()
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get): void {
$set('code', null);
$set('operator_id', null);
}),
Select::make('name')
->label('Search by Work Group Center')
->searchable()
->options(function (callable $get) {
$plantId = $get('Plant');
if(!$plantId){
return [];
}
else{
return $plantId ? WorkGroupMaster::where('plant_id', $plantId)->distinct()->pluck('name', 'name')->toArray(): [];
}
})
->searchable()
->reactive(),
TextInput::make('description')
->label('Description')
->reactive(),
TextInput::make('operation_number')
->label('Operation Number')
->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) {
// Hide all records initially if no filters are applied
if (empty($data['Plant']) && empty($data['name']) && empty($data['description']) && empty($data['operation_number']) && empty($data['created_from']) && empty($data['created_to']) && empty($data['updated_from']) && empty($data['updated_to'])) {
// return $query->whereRaw('1 = 0');
}
if (! empty($data['Plant'])) { // $plant = $data['Plant'] ?? null
$query->where('plant_id', $data['Plant']);
} else {
$userHas = Filament::auth()->user()->plant_id;
if ($userHas && strlen($userHas) > 0) {
return $query->whereRaw('1 = 0');
}
}
if (! empty($data['name'])) {
$query->where('name', $data['name']);
}
if (! empty($data['description'])) {
$query->where('description', $data['description']);
}
if (! empty($data['operation_number'])) {
$query->where('operation_number', $data['operation_number']);
}
if (! empty($data['created_from'])) {
$query->where('created_at', '>=', $data['created_from']);
}
if (! empty($data['created_to'])) {
$query->where('created_at', '<=', $data['created_to']);
}
})
->indicateUsing(function (array $data) {
$indicators = [];
if (! empty($data['Plant'])) {
$indicators[] = 'Plant: '.Plant::where('id', $data['Plant'])->value('name');
} else {
$userHas = Filament::auth()->user()->plant_id;
if ($userHas && strlen($userHas) > 0) {
return 'Plant: Choose plant to filter records.';
}
}
if (! empty($data['name'])) {
$indicators[] = 'Work Group Name: ' . $data['name'];
}
if (! empty($data['description'])) {
$indicators[] = 'Description: ' . $data['description'];
}
if (! empty($data['operation_number'])) {
$indicators[] = 'Operation Number: ' . $data['operation_number'];
}
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(),
@@ -177,14 +318,14 @@ class WorkGroupMasterResource extends Resource
->label('Import Work Group Masters')
->color('warning')
->importer(WorkGroupMasterImporter::class)
->visible(function() {
->visible(function () {
return Filament::auth()->user()->can('view import work group master');
}),
ExportAction::make()
->label('Export Work Group Masters')
->color('warning')
->exporter(WorkGroupMasterExporter::class)
->visible(function() {
->visible(function () {
return Filament::auth()->user()->can('view export work group master');
}),
]);

View File

@@ -2,6 +2,7 @@
namespace App\Http\Controllers;
use App\Models\CharacteristicValue;
use App\Models\ClassCharacteristic;
use App\Models\Item;
use App\Models\Line;
@@ -1989,7 +1990,6 @@ class CharacteristicsController extends Controller
public function getCharMaster(Request $request)
{
$expectedUser = env('API_AUTH_USER');
$expectedPw = env('API_AUTH_PW');
$header_auth = $request->header('Authorization');
@@ -1999,7 +1999,7 @@ class CharacteristicsController extends Controller
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Invalid authorization token!',
], 403);
], 401);
}
$plantCode = $request->header('plant-code');
@@ -2007,36 +2007,66 @@ class CharacteristicsController extends Controller
$lineName = $request->header('line-name');
$workCenter = $request->header('work-center');
if ($plantCode == null || $plantCode == '') {
if ($plantCode == null || $plantCode == '' || ! $plantCode) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Plant code can't be empty!",
], 400);
} elseif (Str::length($plantCode) < 4 || ! is_numeric($plantCode) || ! preg_match('/^[1-9]\d{3,}$/', $plantCode)) {
} elseif (! is_numeric($plantCode)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Invalid plant code found!',
'status_description' => "Plant code '{$plantCode}' should contain only numeric values!",
], 400);
} elseif ($itemCode == null || $itemCode == '') {
} elseif (Str::length($plantCode) < 4 || Str::length($plantCode) > 7) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item Code can't be empty!",
'status_description' => "Plant code '{$plantCode}' must be between 4 and 7 digits only!",
], 400);
} elseif (Str::length($itemCode) < 6 || ! ctype_alnum($itemCode)) {
} elseif (! preg_match('/^[1-9]\d{3,6}$/', $plantCode)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Invalid item code found!',
'status_description' => "Invalid plant code '{$plantCode}' found!",
], 400);
} elseif ($lineName == null || $lineName == '') {
} elseif ($itemCode == null || $itemCode == '' || ! $itemCode) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item code can't be empty!",
], 404);
} elseif (Str::length($itemCode) < 6) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item code '{$itemCode}' should contain minimum 6 digits!",
], 404);
} elseif (! ctype_alnum($itemCode)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item code '{$itemCode}' should contain only alpha-numeric values!",
], 404);
} elseif (! preg_match('/^[a-zA-Z1-9][a-zA-Z0-9]{5,}$/', $itemCode)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item code '{$itemCode}' should not begin with '0'!",
], 404);
} elseif ($lineName == null || $lineName == '' || ! $lineName) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Line name can't be empty!",
], 400);
} elseif ($workCenter == null || $workCenter == '') {
], 404);
} elseif ($workCenter == null || $workCenter == '' || ! $workCenter) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Work center can't be empty!",
], 400);
], 404);
} elseif (Str::length($workCenter) < 6) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Work center '{$workCenter}' should contain minimum 6 characters!",
], 404);
} elseif (! ctype_alnum($workCenter)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Work center '{$workCenter}' should contain only alpha-numeric values!",
], 404);
}
$plant = Plant::where('code', $plantCode)->first();
@@ -2044,97 +2074,374 @@ class CharacteristicsController extends Controller
if (! $plant) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Plant not found!',
], 400);
'status_description' => "Plant code '{$plantCode}' not found in plants table!",
], 404);
}
$plantId = $plant->id;
$plantName = $plant->name;
$item = Item::where('code', $itemCode)->first();
if (! $item) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Item Code not found in item table!',
'status_description' => "Item Code '{$itemCode}' not found in items table!",
], 404);
}
$item = Item::where('plant_id', $plantId)->where('code', $itemCode)->first();
$item = Item::where('code', $itemCode)->where('plant_id', $plantId)->first();
if (! $item) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item Code not found in item table for the plant : '$plant->name'!",
'status_description' => "Item Code '{$itemCode}' not found for the plant name '{$plantName}' in items table!",
], 404);
}
$itemId = $item->id;
$line = Line::where('name', $lineName)->first();
if (! $line) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Line not found in lines table!',
'status_description' => "Line name '{$lineName}' not found in lines table!",
], 404);
}
$lineAgaPlant = Line::where('plant_id', $plantId)->where('name', $lineName)->first();
$line = Line::where('name', $lineName)->where('plant_id', $plantId)->first();
if (! $lineAgaPlant) {
if (! $line) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Line Name not found in lines table for the plant : '$plant->name'!",
'status_description' => "Line name '{$lineName}' not found for the plant name '{$plantName}' in lines table!",
], 404);
}
$work = Machine::where('work_center', $workCenter)->first();
$lineId = $line->id;
if (! $work) {
$machine = Machine::where('work_center', $workCenter)->first();
if (! $machine) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Work Center not found in machines table!',
'status_description' => "Work center '{$workCenter}' not found in machines table!",
], 404);
}
$workAgaPlant = Machine::where('plant_id', $plantId)->where('work_center', $workCenter)->first();
$machine = Machine::where('work_center', $workCenter)->where('plant_id', $plantId)->first();
if (! $workAgaPlant) {
if (! $machine) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Work center not found in machines table for the plant : '$plant->name'!",
'status_description' => "Work center '{$workCenter}' not found for the plant name '{$plantName}' in machines table!",
], 404);
}
$machine = Machine::where('line_id', $lineId)->where('work_center', $workCenter)->where('plant_id', $plantId)->first();
if (! $machine) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Work center '{$workCenter}' is not mapped for the given line name '{$lineName}' in machines table!",
], 404);
}
$machineId = $machine->id;
// $description = $item ? $item->description : '';
// $uom = $item ? $item->uom : '';
// $category = $item ? $item->category : '';
$charMaster = ProductCharacteristicsMaster::where('plant_id', $plantId)->where('item_id', $item->id)
->where('line_id', $lineAgaPlant->id)->where('machine_id', $workAgaPlant->id)
->first();
$charMasters = ProductCharacteristicsMaster::with('workGroupMaster')->where('item_id', $itemId)->where('line_id', $lineId)->where('machine_id', $machineId)->where('plant_id', $plantId)->get(); // ->select(['name', 'characteristics_type', 'inspection_type', 'lower', 'middle', 'upper', 'work_group_master_id'])
if (! $charMaster) {
if ($charMasters->count() <= 0) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Characteristics not found in product master table for the plant : '$plant->name'!",
'status_description' => "Characteristics not found for the plant name '{$plantName}' in product master table!",
], 404);
} else {
if ($charMasters->count() == 1) {
$charMasters = ProductCharacteristicsMaster::with('workGroupMaster')->where('item_id', $itemId)->where('line_id', $lineId)->where('machine_id', $machineId)->where('plant_id', $plantId)->first();
// $workGroup = WorkGroupMaster::find($charMasters->work_group_master_id);
// $workGroupName = $workGroup?->name ?? '';
$output = [
'work_group_master' => $charMasters?->workGroupMaster->name ?? '', // $workGroupName ?? '',
'name' => $charMasters?->name ?? '',
'characteristics_type' => $charMasters?->characteristics_type ?? '',
'inspection_type' => $charMasters?->inspection_type ?? '',
'lower' => (string) $charMasters?->lower ?? '',
'middle' => (string) $charMasters?->middle ?? '',
'upper' => (string) $charMasters?->upper ?? '',
];
} else {
$output = $charMasters->map(function ($charMast) {
$charMaster = [
'work_group_master' => $charMast?->workGroupMaster->name ?? '', // optional($charMast->workGroupMaster)->name ?? '',
'name' => $charMast?->name ?? '',
'characteristics_type' => $charMast?->characteristics_type ?? '',
'inspection_type' => $charMast?->inspection_type ?? '',
'lower' => (string) $charMast?->lower ?? '',
'middle' => (string) $charMast?->middle ?? '',
'upper' => (string) $charMast?->upper ?? '',
];
return $charMaster;
});
}
}
return response()->json($output, 200);
}
public function storeCharValues(Request $request)
{
$expectedUser = env('API_AUTH_USER');
$expectedPw = env('API_AUTH_PW');
$headerAuth = $request->header('Authorization');
$expectedToken = 'Bearer '.$expectedUser.':'.$expectedPw;
if ($headerAuth != $expectedToken) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Invalid authorization token!',
], 401);
}
$plantCode = $request->header('plant-code');
$itemCode = $request->header('item-code');
$lineName = $request->header('line-name');
$workCenter = $request->header('work-center');
if ($plantCode == null || $plantCode == '' || ! $plantCode) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Plant code can't be empty!",
], 400);
} elseif (! is_numeric($plantCode)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Plant code '{$plantCode}' should contain only numeric values!",
], 400);
} elseif (Str::length($plantCode) < 4 || Str::length($plantCode) > 7) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Plant code '{$plantCode}' must be between 4 and 7 digits only!",
], 400);
} elseif (! preg_match('/^[1-9]\d{3,6}$/', $plantCode)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Invalid plant code '{$plantCode}' found!",
], 400);
}
$plant = Plant::where('code', $plantCode)->first();
if (! $plant) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Plant code '{$plantCode}' not found in plants table!",
], 404);
}
$workGroup = WorkGroupMaster::find($charMaster->work_group_master_id);
$workGroupName = $workGroup?->name ?? '';
$plantId = $plant->id;
$plantName = $plant->name;
$output = [
'work_group_master' => $workGroupName ?? '',
'name' => $charMaster?->name ?? '',
'inspection_type' => $charMaster?->inspection_type ?? '',
'characteristics_type' => $charMaster?->characteristics_type ?? '',
'upper' => (string) $charMaster?->upper ?? '',
'lower' => (string) $charMaster?->lower ?? '',
'middle' => (string) $charMaster?->middle ?? '',
];
if ($lineName == null || $lineName == '' || ! $lineName) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Line name can't be empty!",
], 404);
}
return response()->json($output, 200);
$line = Line::where('name', $lineName)->first();
if (! $line) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Line '{$lineName}' not found in lines table!",
], 404);
}
$line = Line::where('name', $lineName)->where('plant_id', $plantId)->first();
if (! $line) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Line '{$lineName}' not found for the plant name '{$plantName}' in lines table!",
], 404);
}
$lineId = $line->id;
if ($itemCode == null || $itemCode == '' || ! $itemCode) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item code can't be empty!",
], 404);
}
$item = Item::where('code', $itemCode)->first();
if (! $item) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item Code '{$itemCode}' not found in items table!",
], 404);
}
$item = Item::where('code', $itemCode)->where('plant_id', $plantId)->first();
if (! $item) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item code '{$itemCode}' not found for the plant name '{$plantName}' in items table!",
], 404);
}
$itemId = $item->id;
if ($workCenter == null || $workCenter == '' || ! $workCenter) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Work center can't be empty!",
], 404);
} elseif (Str::length($workCenter) < 6) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Work center '{$workCenter}' should contain minimum 6 characters!",
], 404);
} elseif (! ctype_alnum($workCenter)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Work center '{$workCenter}' should contain only alpha-numeric values!",
], 404);
}
$machine = Machine::where('work_center', $workCenter)->first();
if (! $machine) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Work center '{$workCenter}' not found in machines table!",
], 404);
}
$machine = Machine::where('work_center', $workCenter)->where('plant_id', $plantId)->first();
if (! $machine) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Work center '{$workCenter}' not found for the plant name '{$plantName}' in machines table!",
], 404);
}
$machine = Machine::where('line_id', $lineId)->where('work_center', $workCenter)->where('plant_id', $plantId)->first();
if (! $machine) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Work center '{$workCenter}' is not mapped for the given line name '{$lineName}' in machines table!",
], 404);
}
$machineId = $machine->id;
$data = $request->all();
$processOrder = $data['process_order'] ?? '';
$coilNo = $data['coil_number'] ?? '';
$status = $data['status'] ?? '';
$obsValue = $data['observed_value'] ?? '';
$createdBy = $data['created_by'] ?? '';
if ($processOrder == null || $processOrder == '' || ! $processOrder) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Process order can't be empty!",
], 404);
} elseif (Str::length($processOrder) < 9) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Process order '{$processOrder}' should contain minimum 9 digits!",
], 404);
}
if ($coilNo == null || $coilNo == '' || ! $coilNo) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Coil number can't be empty!",
], 404);
} elseif (! is_numeric($coilNo)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Coil number '{$coilNo}' should contain only numeric values!",
], 404);
} elseif (Str::length($coilNo) > 1 && ! Str::contains($coilNo, '.') && ! preg_match('/^[1-9][0-9]*$/', $coilNo)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Coil number '{$coilNo}' should not begin with '0'!",
], 404);
}
if ($status == null || $status == '' || ! $status) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Status can't be empty!",
], 404);
} elseif (! in_array($status, ['Ok', 'NotOk'], true)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Status must be either 'Ok' or 'NotOk'!",
], 404);
}
if ($obsValue == null || $obsValue == '' || ! $obsValue) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Observed value can't be empty!",
], 404);
}
if ($createdBy == null || $createdBy == '' || ! $createdBy) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Created by can't be empty!",
], 404);
}
$existing = CharacteristicValue::where('process_order', $processOrder)->where('item_id', '!=', $itemId)->where('plant_id', $plantId)->first();
if ($existing) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Process order '{$processOrder}' already has item_code '{$existing->item->code}' for the plant name '{$plantName}'!",
], 404);
}
$existing = CharacteristicValue::where('process_order', $processOrder)->where('coil_number', $coilNo)->where('plant_id', $plantId)->first();
if ($existing) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Process order '{$processOrder}' with coil number '{$coilNo}' already exist for the plant name '{$plantName}'!",
], 404);
}
CharacteristicValue::create([
'plant_id' => $plantId,
'line_id' => $lineId,
'item_id' => $itemId,
'machine_id' => $machineId,
'process_order' => $processOrder,
'coil_number' => $coilNo,
'status' => $status,
'observed_value' => $obsValue,
'created_by' => $createdBy,
]);
return response()->json([
'status_code' => 'SUCCESS',
'status_description' => 'Characteristics values inserted successfully.',
], 200);
}
/**

View File

@@ -2,6 +2,7 @@
namespace App\Http\Controllers;
use App\Models\ItemCharacteristic;
use App\Models\Line;
use App\Models\Machine;
use App\Models\Plant;
@@ -33,29 +34,28 @@ class MachineController extends Controller
public function get_all_data(Request $request)
{
$expectedUser = env('API_AUTH_USER');
$expectedPw = env('API_AUTH_PW');
$header_auth = $request->header('Authorization');
$expectedToken = $expectedUser . ':' . $expectedPw;
$expectedPw = env('API_AUTH_PW');
$header_auth = $request->header('Authorization');
$expectedToken = $expectedUser.':'.$expectedPw;
if ("Bearer " . $expectedToken != $header_auth)
{
if ('Bearer '.$expectedToken != $header_auth) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Invalid authorization token!'
'status_description' => 'Invalid authorization token!',
], 403);
}
$machines = Machine::with('plant')->with('workGroupMaster')->orderBy('plant_id')->get();
$machinesData = $machines->map(function($machine) {
$machines = ItemCharacteristic::with('plant')->with('workGroupMaster')->orderBy('plant_id')->get();
$machinesData = $machines->map(function ($machine) {
return [
'plant_code' => $machine->plant ? (String)$machine->plant->code : "",
'group_work_center' => $machine->workGroupMaster ? (String)$machine->workGroupMaster->name : "",
'work_center' => $machine->work_center ?? "",
'plant_code' => $machine->plant ? (string) $machine->plant->code : '',
'group_work_center' => $machine->workGroupMaster ? (string) $machine->workGroupMaster->name : '',
'work_center' => $machine->work_center ?? '',
];
});
return response()->json([
'machines' => $machinesData
'machines' => $machinesData,
]);
}
@@ -65,80 +65,70 @@ class MachineController extends Controller
public function get_data(Request $request)
{
$expectedUser = env('API_AUTH_USER');
$expectedPw = env('API_AUTH_PW');
$header_auth = $request->header('Authorization');
$expectedToken = $expectedUser . ':' . $expectedPw;
$expectedPw = env('API_AUTH_PW');
$header_auth = $request->header('Authorization');
$expectedToken = $expectedUser.':'.$expectedPw;
if ("Bearer " . $expectedToken != $header_auth)
{
if ('Bearer '.$expectedToken != $header_auth) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Invalid authorization token!'
'status_description' => 'Invalid authorization token!',
], 403);
}
$plantCode = $request->header('plant-code');
$lineName = $request->header('line-name');
if ($plantCode == null || $plantCode == '')
{
if ($plantCode == null || $plantCode == '') {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Plant code can't be empty!"
'status_description' => "Plant code can't be empty!",
], 400);
}
else if (Str::length($plantCode) < 4 || !is_numeric($plantCode) || !preg_match('/^[1-9]\d{3,}$/', $plantCode))
{
} elseif (Str::length($plantCode) < 4 || ! is_numeric($plantCode) || ! preg_match('/^[1-9]\d{3,}$/', $plantCode)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Invalid plant code found!"
'status_description' => 'Invalid plant code found!',
], 400);
}
else if ($lineName == null || $lineName == '' || Str::length($lineName) <= 0)
{
} elseif ($lineName == null || $lineName == '' || Str::length($lineName) <= 0) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Line name can't be empty!"
'status_description' => "Line name can't be empty!",
], 400);
}
$plant = Plant::where('code', $plantCode)->first();
if (!$plant)
{
if (! $plant) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Plant Code '{$plantCode}' not found!"
'status_description' => "Plant Code '{$plantCode}' not found!",
], 400);
}
$plantId = $plant->id;
$line = Line::where('name', $lineName)->first();
if (!$line)
{
if (! $line) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Line Name '{$lineName}' not found!"
'status_description' => "Line Name '{$lineName}' not found!",
], 400);
}
$line = Line::where('name', $lineName)->where('plant_id', $plantId)->first();
if (!$line)
{
if (! $line) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Line Name '{$lineName}' not found for the plant!"
'status_description' => "Line Name '{$lineName}' not found for the plant!",
], 400);
}
$lineId = $line->id;//no_of_operation
$lineId = $line->id; // no_of_operation
$lineWorkGroup1Id = $line->work_group1_id;
$lineWorkGroup2Id = $line->work_group2_id;
if ($line->no_of_operation == null || $line->no_of_operation == '' || $line->no_of_operation == 0 || !is_numeric($line->no_of_operation))
{
if ($line->no_of_operation == null || $line->no_of_operation == '' || $line->no_of_operation == 0 || ! is_numeric($line->no_of_operation)) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Group work center not found for the plant & line!"
'status_description' => 'Group work center not found for the plant & line!',
], 400);
}
@@ -146,26 +136,22 @@ class MachineController extends Controller
$lineWorkGroupIds = [];
for ($i = 1; $i <= $line->no_of_operation; $i++) {
$curWorkGroupId = $line->{"work_group{$i}_id"};
if (in_array($curWorkGroupId, $lineWorkGroupIds))
{
if (in_array($curWorkGroupId, $lineWorkGroupIds)) {
continue;
}
else
{
} else {
$lineWorkGroupIds[] = $curWorkGroupId;
}
$test[] = [
'group_work_center' => WorkGroupMaster::where('id', $curWorkGroupId)->first()->name ?? "",
'operation_number' => WorkGroupMaster::where('id', $curWorkGroupId)->first()->operation_number ?? "",
'group_work_center' => WorkGroupMaster::where('id', $curWorkGroupId)->first()->name ?? '',
'operation_number' => WorkGroupMaster::where('id', $curWorkGroupId)->first()->operation_number ?? '',
'work_centers' => Machine::where('plant_id', $plantId)->where('work_group_master_id', $curWorkGroupId)->orderBy('work_center')->pluck('work_center')->toArray() ?? [],
];
}
if($lineWorkGroupIds)
{
if ($lineWorkGroupIds) {
return response()->json([
'machines' => $test
'machines' => $test,
]);
}
// $machines = Machine::with('plant')->with('workGroupMaster')->orderBy('plant_id')->get();
@@ -203,7 +189,7 @@ class MachineController extends Controller
/**
* Update the specified resource in storage.
*/
*/
public function update(Request $request, string $id)
{
//

View File

@@ -2,9 +2,12 @@
namespace App\Http\Controllers;
use App\Models\CharacteristicValue;
use App\Models\GrMaster;
use App\Models\Item;
use App\Models\ItemCharacteristic;
use App\Models\Line;
use App\Models\Machine;
use App\Models\Plant;
use App\Models\ProcessOrder;
use App\Models\StickerDetail;
@@ -538,6 +541,8 @@ class PdfController extends Controller
$processOrder = $request->header('process-order');
$machineName = $request->header('machine-name');
if (! $plantCode) {
return response()->json([
'status_code' => 'ERROR',
@@ -571,6 +576,7 @@ class PdfController extends Controller
$proOrdAgPlant = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->latest()
->first();
if (! $proOrdAgPlant) {
@@ -580,46 +586,185 @@ class PdfController extends Controller
], 404);
}
$item = $proOrdAgPlant->item;
$coil = $proOrdAgPlant->coil_number;
$processOrderRecords = ProcessOrder::with('item')
->where('plant_id', $plant->id)
if($coil != 0){
$proOrdAgPlantMachine = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->get();
$lastRecord = ProcessOrder::with('item')
->where('plant_id', $plant->id)
->where('process_order', $processOrder)
->orderBy('id', 'desc')
->where('machine_name', $machineName)
->first();
$totalReceivedQty = $processOrderRecords->sum('received_quantity');
// $lastRecord = $processOrderRecords->first();
$item = $lastRecord->item;
if (!$proOrdAgPlantMachine) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Machine name not found in process order!',
], 404);
}
$item = $proOrdAgPlant->item;
$processOrderRecords = ProcessOrder::with('item')
->where('plant_id', $plant->id)
->where('process_order', $processOrder)
->where('machine_name', $machineName)
->get();
$lastRecord = ProcessOrder::with('item')
->where('plant_id', $plant->id)
->where('process_order', $processOrder)
->where('machine_name', $machineName)
->orderBy('id', 'desc')
->first();
$lastRecord1 = ProcessOrder::with('item')
->where('plant_id', $plant->id)
->where('process_order', $processOrder)
->where('machine_name', $machineName)
->where('rework_status', 0)
->orderBy('id', 'desc')
->first();
$totalReceivedQty = $processOrderRecords->sum('received_quantity');
// $lastRecord = $processOrderRecords->first();
$item = $lastRecord->item;
if ($totalReceivedQty == $proOrdAgPlant->order_quantity) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Process order '{$processOrder}' for plant '{$plantCode}' has already reached its order quantity.",
], 404);
}
$itemId = $lastRecord->item_id;
$line = ProcessOrder::where('plant_id', $plantId)->where('process_order', $processOrder)->where('item_id',$itemId)->first();
$lineId = $line->line_id;
$lineName = Line::where('plant_id', $plantId)->where('id', $lineId)->value('name');
// $workCenter = Machine::where('plant_id', $plantId)->where('work_center', $machineName)->first();
$currentCoil = ($lastRecord->rework_status == 1) ? (string) $lastRecord1->coil_number : (string) $lastRecord->coil_number;
$machine = Machine::where('plant_id', $plantId)->where('line_id', $lineId)->where('work_center', $machineName)->first();
$machineId = $machine->id;
if(!$machine){
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Machine not found in machine table.",
], 404);
}
// if ($totalReceivedQty > $proOrdAgPlant->order_quantity) {
// return responses()->json([
// 'status_code' => 'ERROR',
// 'status_description' => "Process order '{$processOrder}' for plant '{$plantCode}' received quantity is more than its order quantity."
// ], 404);
// }
$okQty = CharacteristicValue::where('plant_id', $plant->id)->where('process_order', $processOrder)->where('machine_id', $machineId)->where('status', 'Ok')->get()->count();
$notOkQty = CharacteristicValue::where('plant_id', $plant->id)->where('process_order', $processOrder)->where('machine_id', $machineId)->where('status', 'NotOk')->get()->count();
$currentCoil = ($lastRecord->rework_status == 1) ? (string) $lastRecord1->coil_number : (string) $lastRecord->coil_number;
if ($totalReceivedQty == $proOrdAgPlant->order_quantity) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Process order '{$processOrder}' for plant '{$plantCode}' has already reached its order quantity.",
], 404);
'item_code' => $item?->code ?? '',
'description' => $item?->description ?? '',
'line_name' => $lineName ?? '',
// 'coil_number' => $proOrdAgPlant->coil_number ?? "",
// 'order_quantity' => (string)$proOrdAgPlant->order_quantity ?? "",
'coil_number' => $currentCoil,
'order_quantity' => (string) $lastRecord->updated_order_quantity ?? '0.000',
'ok_quantity' => (string) $okQty ?? '0',
'not_ok_quantity' => (string) $notOkQty ?? '0',
'received_quantity' => (string) (($totalReceivedQty == 0) ? '0.000' : $totalReceivedQty) ?? '0.000',
]);
}
else{
$proOrdAgPlant = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->first();
if (!$proOrdAgPlant) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'process order not found!',
], 404);
}
$item = $proOrdAgPlant->item;
$processOrderRecords = ProcessOrder::with('item')
->where('plant_id', $plant->id)
->where('process_order', $processOrder)
->get();
$lastRecord = ProcessOrder::with('item')
->where('plant_id', $plant->id)
->where('process_order', $processOrder)
->orderBy('id', 'desc')
->first();
$lastRecord1 = ProcessOrder::with('item')
->where('plant_id', $plant->id)
->where('process_order', $processOrder)
->where('rework_status', 0)
->orderBy('id', 'desc')
->first();
$totalReceivedQty = $processOrderRecords->sum('received_quantity');
// $lastRecord = $processOrderRecords->first();
$item = $lastRecord->item;
if ($totalReceivedQty == $proOrdAgPlant->order_quantity) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Process order '{$processOrder}' for plant '{$plantCode}' has already reached its order quantity.",
], 404);
}
$itemId = $lastRecord->item_id;
$line = ProcessOrder::where('plant_id', $plantId)->where('process_order', $processOrder)->where('item_id',$itemId)->first();
$lineId = $line->line_id;
$lineName = Line::where('plant_id', $plantId)->where('id', $lineId)->value('name');
$currentCoil = ($lastRecord->rework_status == 1) ? (string) $lastRecord1->coil_number : (string) $lastRecord->coil_number;
// if ($totalReceivedQty > $proOrdAgPlant->order_quantity) {
// return responses()->json([
// 'status_code' => 'ERROR',
// 'status_description' => "Process order '{$processOrder}' for plant '{$plantCode}' received quantity is more than its order quantity."
// ], 404);
// }
$okQty = CharacteristicValue::where('plant_id', $plant->id)->where('process_order', $processOrder)->where('status', 'Ok')->get()->count();
$notOkQty = CharacteristicValue::where('plant_id', $plant->id)->where('process_order', $processOrder)->where('status', 'NotOk')->get()->count();
$currentCoil = ($lastRecord->rework_status == 1) ? (string) $lastRecord1->coil_number : (string) $lastRecord->coil_number;
return response()->json([
'item_code' => $item?->code ?? '',
'description' => $item?->description ?? '',
'line_name' => $lineName ?? '',
// 'coil_number' => $proOrdAgPlant->coil_number ?? "",
// 'order_quantity' => (string)$proOrdAgPlant->order_quantity ?? "",
'coil_number' => $currentCoil,
'order_quantity' => (string) $lastRecord->updated_order_quantity ?? '0.000',
'ok_quantity' => (string) $okQty ?? '0',
'not_ok_quantity' => (string) $notOkQty ?? '0',
'received_quantity' => (string) (($totalReceivedQty == 0) ? '0.000' : $totalReceivedQty) ?? '0.000',
]);
}
// if ($totalReceivedQty > $proOrdAgPlant->order_quantity) {
// return response()->json([
// 'status_code' => 'ERROR',
// 'status_description' => "Process order '{$processOrder}' for plant '{$plantCode}' received quantity is more than its order quantity."
// ], 404);
// }
return response()->json([
'item_code' => $item?->code ?? '',
'description' => $item?->description ?? '',
// 'coil_number' => $proOrdAgPlant->coil_number ?? "",
// 'order_quantity' => (string)$proOrdAgPlant->order_quantity ?? "",
'coil_number' => $lastRecord->coil_number ?? '',
'order_quantity' => (string) $lastRecord->order_quantity ?? '',
'received_quantity' => (string) $totalReceivedQty ?? '',
]);
}
public function storeProcessOrderData(Request $request)
@@ -672,23 +817,17 @@ class PdfController extends Controller
$plantId = $plant->id;
$itemCode = $data['item_code'] ?? '';
// $lineName = $data['line_name'] ?? '';
$coilNo = $data['coil_number'] ?? '';
$orderQty = $data['order_quantity'] ?? 0;
$updatedOrderQty = $data['order_quantity'] ?? 0;
$receivedQty = $data['received_quantity'] ?? 0;
$scrapQty = $data['scrap_quantity'] ?? 0;
$sfgNo = $data['sfg_number'] ?? '';
$machineId = $data['machine_id'] ?? '';
$rework = $data['rework'] ?? '';
$operationNo = $data['operation_number'] ?? '';
$createdBy = $data['created_by'] ?? '';
// $validated = $request->validate([
// 'item_code' => 'nullable|integer',
// 'coil_number' => 'nullable|string',
// 'order_quantity' => 'nullable|integer',
// 'received_quantity' => 'nullable|numeric',
// 'sfg_number' => 'nullable|string',
// 'machine_id' => 'nullable|string',
// 'created_by' => 'nullable|string',
// ]);
if ($itemCode == null || $itemCode == '' || ! $itemCode) {
return response()->json([
'status_code' => 'ERROR',
@@ -706,31 +845,69 @@ class PdfController extends Controller
], 404);
}
$item = Item::where('plant_id', $plantId)->where('code', $itemCode)->first();
if(!$item){
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Item Code not found!",
], 404);
}
if($item){
$lineIdExist = $item->line_id ?? '';
if ($lineIdExist) {
$line = Line::where('id', $lineIdExist)->where('plant_id', $plantId)->first();
if ($line) {
$lineId = $line->id;
} else {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Line not found!",
], 404);
}
} else {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Line not mapped for item code '$itemCode'!",
], 404);
}
}
if ($scrapQty == null || $scrapQty == '') {
$scrapQty = 0;
}
if ($rework == null || $rework == '' || ! $rework) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Rework value can't be empty!",
], 404);
}
if ($coilNo == null || $coilNo == '') {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Coil number can't be empty!",
], 404);
} elseif (! is_numeric($coilNo) || Str::length($coilNo) <= 0 || ! preg_match('/^\d{1,}$/', $coilNo)) { // !ctype_digit($data['plant_code'])
} elseif (! is_numeric($coilNo) || Str::length($coilNo) <= 0 || ! preg_match('/^\d+(\.\d+)?$/', $coilNo)
) { // !ctype_digit($data['plant_code'])
return response()->json([
'status_code' => 'ERROR',
'status_description' => 'Invalid coil number found!',
], 404);
}
// if ($sfgNo == null || $sfgNo == '' || ! $sfgNo) {
// return response()->json([
// 'status_code' => 'ERROR',
// 'status_description' => "SFG number can't be empty!",
// ], 404);
// }
// if ($machineId == null || $machineId == '' || ! $machineId) {
// return response()->json([
// 'status_code' => 'ERROR',
// 'status_description' => "Machine ID can't be empty!",
// ], 404);
// }
if ($operationNo == null || $operationNo == '' || ! $operationNo) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Operation Number can't be empty!",
], 404);
}
if ($createdBy == null || $createdBy == '' || ! $createdBy) {
return response()->json([
@@ -811,58 +988,280 @@ class PdfController extends Controller
], 404);
}
$existing = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('coil_number', $coilNo)
->first();
if ($existing) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Process order '{$processOrder}' with coil number '{$coilNo}' already exist for the plant code '{$plantCode}'!",
], 404);
}
$alreadyReceived = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('machine_name', $machineId)
->where('item_id', $itemId)
->sum('received_quantity');
if ($orderQty == 0) {
$orderQty = ProcessOrder::where('plant_id', $plantId)
$orderQty = 0;
if ($updatedOrderQty == 0) {
$orderExist = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('item_id', $itemId)
->value('order_quantity') ?? 0;
->where('item_id', $itemId)->latest()->first();
// ->value('order_quantity') ?? 0;
if ($orderExist) {
$orderQty = $orderExist->order_quantity ?? 0;
$updatedOrderQty = $orderExist->updated_order_quantity ?? 0;
} else {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Order quantity can't be '0'",
], 404);
}
} else {
$orderExist = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('item_id', $itemId)->latest()->first();
// ->value('order_quantity') ?? 0;
if ($orderExist) {
// $existOrderQty = $orderExist->updated_order_quantity ?? 0;
$orderQty = $orderExist->order_quantity ?? 0;
$existUpdatedOrdQuan = $orderExist->updated_order_quantity ?? 0;
if ($existUpdatedOrdQuan != $updatedOrderQty) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Order quantity doesn't equal to exist process order '{$processOrder}'",
], 404);
}
}
}
$total = $alreadyReceived + $receivedQty;
if ($total > $orderQty) {
if ($rework != 'Yes' && $rework != 'No') {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Received quantity should not exceed order quantity! Order Qty = {$orderQty}, Already Received Qty = {$alreadyReceived}, Trying to Insert Qty = {$receivedQty}",
'status_description' => "Rework value should be either 'Yes' or 'No'!",
], 404);
} elseif ($rework == 'No') {
if ($scrapQty != 0) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Scrap Quanity value should be '0'!",
], 404);
}
}
try {
ProcessOrder::Create(
[
'plant_id' => $plantId,
'process_order' => $processOrder,
'item_id' => $itemId,
'coil_number' => $coilNo,
'order_quantity' => $orderQty,
'received_quantity' => $receivedQty,
'sfg_number' => $sfgNo,
'machine_name' => $machineId,
'created_by' => $createdBy,
]
);
$coilNo = (string) $coilNo;
return response()->json([
'status_code' => 'SUCCESS',
'status_description' => 'Record Inserted Successfully',
]);
try {
if ($rework == 'Yes') {
if ($coilNo && Str::contains($coilNo, '.')) {
// Contains dot
$coilMain = explode('.', $coilNo)[0]; // 333
$existingCoil = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('line_id', $lineId)
->where('coil_number', $coilMain)
->first();
if (! $existingCoil) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Coil number '{$coilMain}' not exist against plant code '{$plantCode}' and process order '{$processOrder}'!",
], 404);
} elseif ($existingCoil->rework_status == 0) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Rework coil number '{$coilMain}' not exist against plant code '{$plantCode}' and process order '{$processOrder}'!",
], 404);
}
if ($total > $updatedOrderQty) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Rework received quantity should not exceed exist order quantity! Exist Order Qty = '{$updatedOrderQty}', Already Exist Total Received Qty = '{$alreadyReceived}', Trying to Insert Rework Received Qty = '{$receivedQty}'",
], 404);
}
$existingCoil = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('line_id', $lineId)
->where('coil_number', $coilNo)
->first();
if (! $existingCoil) {
ProcessOrder::Create(
[
'plant_id' => $plantId,
'line_id' => $lineId,
'process_order' => $processOrder,
'item_id' => $itemId,
'coil_number' => $coilNo,
'order_quantity' => $orderQty,
'updated_order_quantity' => $updatedOrderQty,
'received_quantity' => $receivedQty,
'scrap_quantity' => $scrapQty,
'sfg_number' => $sfgNo,
'machine_name' => $machineId,
'operation_number' => $operationNo,
'rework_status' => 1,
'created_by' => $createdBy,
]
);
return response()->json([
'status_code' => 'SUCCESS',
'status_description' => 'Record Updated Successfully (Rework).',
]);
} else {
$updated = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('line_id', $lineId)
->where('coil_number', $coilNo)
->update([
// 'order_quantity' => $orderQty,
'received_quantity' => $receivedQty,
'scrap_quantity' => $scrapQty,
'operation_number' => $operationNo,
// 'sfg_number' => $sfgNo,
// 'machine_name' => $machineId,
'rework_status' => 1,
'updated_by' => $createdBy,
'updated_at' => now(),
]);
}
} else {
// if ($coilNo > 1) {
// $prevCoilNo = (string) ($coilNo - 1);
// $existPrevCoil = ProcessOrder::where('plant_id', $plantId)
// ->where('process_order', $processOrder)
// ->where('coil_number', $prevCoilNo)
// ->first();
// if (! $existPrevCoil) {
// return response()->json([
// 'status_code' => 'ERROR',
// 'status_description' => "Previous coil number '{$prevCoilNo}' not exist against plant code '{$plantCode}' and process order '{$processOrder}'!",
// ], 404);
// }
// }
$existingCoil = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('line_id', $lineId)
->where('coil_number', $coilNo)
->first();
if (! $existingCoil) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Coil number '{$coilNo}' not exist against plant code '{$plantCode}' and process order '{$processOrder}'!",
], 404);
}
$existPrevCoil = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('item_id', $itemId)
->where('coil_number', $coilNo)
->first();
if ($existPrevCoil->received_quantity < $receivedQty) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Rework received quantity should not exceed exist received quantity! Exist Received Qty = '{$existPrevCoil->received_quantity}', Trying to Insert Rework Received Qty = '{$receivedQty}'",
], 404);
}
$updated = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('line_id', $lineId)
->where('coil_number', $coilNo)
->update([
// 'order_quantity' => $orderQty,
'received_quantity' => $receivedQty,
'scrap_quantity' => $scrapQty,
'operation_number' => $operationNo,
// 'sfg_number' => $sfgNo,
// 'machine_name' => $machineId,
'rework_status' => 1,
'updated_by' => $createdBy,
'updated_at' => now(),
]);
}
if ($updated == 0) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "No matching record found for rework coil number '{$coilNo}'!",
], 404);
} else {
return response()->json([
'status_code' => 'SUCCESS',
'status_description' => 'Record Updated Successfully (Rework).',
]);
}
} else {
if ($coilNo && Str::contains($coilNo, '.')) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Rework value should be 'Yes' for rework coil number '{$coilNo}'!",
], 404);
}
$existing = ProcessOrder::where('plant_id', $plantId)
->where('process_order', $processOrder)
->where('coil_number', $coilNo)
->first();
if ($existing) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Coil number '{$coilNo}' already exist against plant code '{$plantCode}' and process order '{$processOrder}'!",
], 404);
}
// if ($coilNo > 1) {
// $prevCoilNo = (string) ($coilNo - 1);
// $existPrevCoil = ProcessOrder::where('plant_id', $plantId)
// ->where('process_order', $processOrder)
// ->where('coil_number', $prevCoilNo)
// ->first();
// if (! $existPrevCoil) {
// return response()->json([
// 'status_code' => 'ERROR',
// 'status_description' => "Previous coil number '{$prevCoilNo}' not exist against plant code '{$plantCode}' and process order '{$processOrder}'!",
// ], 404);
// }
// }
if ($total > $updatedOrderQty) {
return response()->json([
'status_code' => 'ERROR',
'status_description' => "Received quantity should not exceed exist order quantity! Exist Order Qty = '{$updatedOrderQty}', Already Exist Total Received Qty = '{$alreadyReceived}', Trying to Insert Received Qty = '{$receivedQty}'",
], 404);
}
ProcessOrder::Create(
[
'plant_id' => $plantId,
'line_id' => $lineId,
'process_order' => $processOrder,
'item_id' => $itemId,
'coil_number' => $coilNo,
'order_quantity' => $orderQty,
'updated_order_quantity' => $updatedOrderQty,
'received_quantity' => $receivedQty,
'scrap_quantity' => $scrapQty,
'sfg_number' => $sfgNo,
'machine_name' => $machineId,
'operation_number' => $operationNo,
'rework_status' => 0,
'created_by' => $createdBy,
]
);
return response()->json([
'status_code' => 'SUCCESS',
'status_description' => 'Record Inserted Successfully.',
]);
}
} catch (\Exception $e) {
return response()->json([
'status_code' => 'ERROR',
@@ -1015,34 +1414,4 @@ class PdfController extends Controller
// }
// }
public function generatePdf(Request $request, $stickerId)
{
$plantId = $request->query('plant_id');
$itemCharacteristicId = $request->query('item_characteristic_id');
$serialNumber = $request->query('serial_number');
if ($plantId && $itemCharacteristicId) {
$structure = StickerStructureDetail::findOrFail($stickerId);
$dynamicElements = StickerDetail::where(
'sticker_structure_detail_id',
$structure->id
)->where('element_type', 'Dynamic')->get();
$itemCharacteristic = ItemCharacteristic::where('plant_id', $plantId)
->where('id', $itemCharacteristicId)
->first();
return (new StickerPdfService())->generatePdf1(
$structure->sticker_id,
$dynamicElements,
$itemCharacteristic,
$serialNumber
);
}
return abort(404);
}
}

View File

@@ -44,8 +44,139 @@ class ProductionTargetPlan extends Component
return $dates;
}
public function loadProductionData($plantId, $lineId, $month, $year){
// public function loadProductionData($plantId, $lineId, $month, $year){
// if (!$plantId || !$lineId || !$month || !$year) {
// $this->records = [];
// $this->dates = [];
// $this->leaveDates = [];
// return;
// }
// $this->dates = $this->getMonthDates($month, $year);
// $data = ProductionPlan::query()
// ->join('items', 'items.id', '=', 'production_plans.item_id')
// ->join('lines', 'lines.id', '=', 'production_plans.line_id')
// ->join('plants', 'plants.id', '=', 'production_plans.plant_id')
// ->where('production_plans.plant_id', $plantId)
// ->where('production_plans.line_id', $lineId)
// ->whereMonth('production_plans.created_at', $month)
// ->whereYear('production_plans.created_at', $year)
// ->select(
// 'production_plans.created_at',
// 'production_plans.operator_id',
// 'plants.name as plant',
// 'items.code as item_code',
// 'items.description as item_description',
// 'lines.name as line_name',
// 'production_plans.leave_dates'
// )
// ->first();
// if ($data && $data->leave_dates) {
// $this->leaveDates = array_map('trim', explode(',', $data->leave_dates));
// }
// $producedData = ProductionQuantity::selectRaw("
// plant_id,
// line_id,
// item_id,
// DATE(created_at) as prod_date,
// COUNT(*) as total_qty
// ")
// ->where('plant_id', $plantId)
// ->where('line_id', $lineId)
// ->whereMonth('created_at', $month)
// ->whereYear('created_at', $year)
// ->groupBy('plant_id', 'line_id', 'item_id', DB::raw('DATE(created_at)'))
// ->get()
// ->groupBy(function ($row) {
// return $row->plant_id . '_' . $row->line_id . '_' . $row->item_id;
// })
// ->map(function ($group) {
// return $group->keyBy('prod_date');
// });
// $this->records = ProductionPlan::query()
// ->join('items', 'items.id', '=', 'production_plans.item_id')
// ->join('lines', 'lines.id', '=', 'production_plans.line_id')
// ->join('plants', 'plants.id', '=', 'production_plans.plant_id')
// ->where('production_plans.plant_id', $plantId)
// ->where('production_plans.line_id', $lineId)
// ->whereMonth('production_plans.created_at', $month)
// ->whereYear('production_plans.created_at', $year)
// ->select(
// 'production_plans.item_id',
// 'production_plans.plant_id',
// 'production_plans.line_id',
// 'production_plans.plan_quantity',
// 'production_plans.working_days',
// 'items.code as item_code',
// 'items.description as item_description',
// 'lines.name as line_name',
// 'plants.name as plant_name'
// )
// ->get()
// ->map(function ($row) use ($producedData) {
// $row = $row->toArray();
// $remainingQty = $row['plan_quantity'];
// // $remainingDays = $row['working_days'];
// $remainingDays = (int) ($row['working_days'] ?? 0);
// $row['daily_target_dynamic'] = [];
// $row['produced_quantity'] = [];
// $key = $row['plant_id'].'_'.$row['line_id'].'_'.$row['item_id'];
// foreach ($this->dates as $date) {
// // Skip leave dates
// if (in_array($date, $this->leaveDates)) {
// $row['daily_target_dynamic'][$date] = '-';
// $row['produced_quantity'][$date] = '-';
// continue;
// }
// $todayTarget = $remainingDays > 0
// ? round($remainingQty / $remainingDays, 2)
// : 0;
// //$todayTarget = $remainingDays > 0
// // ? $remainingQty / $remainingDays
// // : 0;
// $producedQty = isset($producedData[$key][$date])
// ? $producedData[$key][$date]->total_qty
// : 0;
// $row['daily_target_dynamic'][$date] = $todayTarget;
// $row['produced_quantity'][$date] = $producedQty;
// // Carry forward pending
// $remainingQty -= $producedQty;
// if ($remainingQty < 0) {
// $remainingQty = 0;
// }
// if ($remainingDays > 0) {
// $remainingDays--;
// }
// // $remainingDays--;
// }
// return $row;
// })
// ->toArray();
// }
public function loadProductionData($plantId, $lineId, $month, $year)
{
if (!$plantId || !$lineId || !$month || !$year) {
$this->records = [];
$this->dates = [];
@@ -53,52 +184,10 @@ class ProductionTargetPlan extends Component
return;
}
$this->dates = $this->getMonthDates($month, $year);
$dates = $this->getMonthDates($month, $year);
$this->dates = $dates;
$data = ProductionPlan::query()
->join('items', 'items.id', '=', 'production_plans.item_id')
->join('lines', 'lines.id', '=', 'production_plans.line_id')
->join('plants', 'plants.id', '=', 'production_plans.plant_id')
->where('production_plans.plant_id', $plantId)
->where('production_plans.line_id', $lineId)
->whereMonth('production_plans.created_at', $month)
->whereYear('production_plans.created_at', $year)
->select(
'production_plans.created_at',
'production_plans.operator_id',
'plants.name as plant',
'items.code as item_code',
'items.description as item_description',
'lines.name as line_name',
'production_plans.leave_dates'
)
->first();
if ($data && $data->leave_dates) {
$this->leaveDates = array_map('trim', explode(',', $data->leave_dates));
}
$producedData = ProductionQuantity::selectRaw("
plant_id,
line_id,
item_id,
DATE(created_at) as prod_date,
COUNT(*) as total_qty
")
->where('plant_id', $plantId)
->where('line_id', $lineId)
->whereMonth('created_at', $month)
->whereYear('created_at', $year)
->groupBy('plant_id', 'line_id', 'item_id', DB::raw('DATE(created_at)'))
->get()
->groupBy(function ($row) {
return $row->plant_id . '_' . $row->line_id . '_' . $row->item_id;
})
->map(function ($group) {
return $group->keyBy('prod_date');
});
$this->records = ProductionPlan::query()
$plans = ProductionPlan::query()
->join('items', 'items.id', '=', 'production_plans.item_id')
->join('lines', 'lines.id', '=', 'production_plans.line_id')
->join('plants', 'plants.id', '=', 'production_plans.plant_id')
@@ -112,111 +201,96 @@ class ProductionTargetPlan extends Component
'production_plans.line_id',
'production_plans.plan_quantity',
'production_plans.working_days',
'production_plans.leave_dates',
'items.code as item_code',
'items.description as item_description',
'lines.name as line_name',
'lines.line_capacity as line_capacity',
'plants.name as plant_name'
)
->get();
$leaveDates = [];
if ($plans->isNotEmpty() && $plans[0]->leave_dates) {
$leaveDates = array_map('trim', explode(',', $plans[0]->leave_dates));
}
$this->leaveDates = $leaveDates;
$producedData = ProductionQuantity::selectRaw("
plant_id,
line_id,
item_id,
DATE(created_at) as prod_date,
COUNT(*) as total_qty
")
->where('plant_id', $plantId)
->where('line_id', $lineId)
->whereMonth('created_at', $month)
->whereYear('created_at', $year)
->groupBy('plant_id', 'line_id', 'item_id', DB::raw('DATE(created_at)'))
->get()
// ->map(function ($row) use ($producedData) {
// $row = $row->toArray();
->groupBy(fn($row) =>
$row->plant_id . '_' . $row->line_id . '_' . $row->item_id
)
->map(fn($group) => $group->keyBy('prod_date'));
// $row['daily_target'] = ($row['working_days'] > 0)
// ? round($row['plan_quantity'] / $row['working_days'], 2)
// : 0;
// // $key = $row['plant_id'].'_'.$row['line_id'].'_'.$row['item_id'];
$records = [];
// // foreach ($this->dates as $date) {
// // $found = $producedData[$key][$date] ?? null;
// // $row['produced_quantity'][$date] = $found->total_qty ?? 0;
// // }
foreach ($plans as $plan) {
// $remainingDays = $row['working_days'];
// $pendingQty = 0;
$row = $plan->toArray();
// $row['daily_target_dynamic'] = [];
// $row['produced_quantity'] = [];
$remainingQty = (float) $row['plan_quantity'];
$remainingDays = (int) ($row['working_days'] ?? 0);
// $key = $row['plant_id'].'_'.$row['line_id'].'_'.$row['item_id'];
$lineCapacity = (float) ($row['line_capacity'] ?? 0);
$dailyLineCapacity = (float) ($row['line_capacity'] ?? 0);
// foreach ($this->dates as $date) {
// $found = $producedData[$key][$date] ?? null;
// $producedQty = $found->total_qty ?? 0;
$row['daily_line_capacity'] = [];
$row['daily_target_dynamic'] = [];
$row['produced_quantity'] = [];
// // today's adjusted target
// $todayTarget = $baseDailyTarget;
$key = $row['plant_id'].'_'.$row['line_id'].'_'.$row['item_id'];
// if ($remainingDays > 1 && $pendingQty > 0) {
// $todayTarget += $pendingQty / $remainingDays;
// }
foreach ($dates as $date) {
// $row['daily_target_dynamic'][$date] = round($todayTarget, 2);
// $row['produced_quantity'][$date] = $producedQty;
// // calculate today's shortfall
// $pendingQty += ($todayTarget - $producedQty);
// if ($pendingQty < 0) {
// $pendingQty = 0;
// }
// $remainingDays--;
// }
// return $row;
// })
->map(function ($row) use ($producedData) {
$row = $row->toArray();
$remainingQty = $row['plan_quantity'];
$remainingDays = $row['working_days'];
$row['daily_target_dynamic'] = [];
$row['produced_quantity'] = [];
$key = $row['plant_id'].'_'.$row['line_id'].'_'.$row['item_id'];
foreach ($this->dates as $date) {
// Skip leave dates
if (in_array($date, $this->leaveDates)) {
$row['daily_target_dynamic'][$date] = '-';
$row['produced_quantity'][$date] = '-';
continue;
}
$todayTarget = $remainingDays > 0
? round($remainingQty / $remainingDays, 2)
: 0;
//$todayTarget = $remainingDays > 0
// ? $remainingQty / $remainingDays
// : 0;
$producedQty = isset($producedData[$key][$date])
? $producedData[$key][$date]->total_qty
: 0;
$row['daily_target_dynamic'][$date] = $todayTarget;
$row['produced_quantity'][$date] = $producedQty;
// Carry forward pending
$remainingQty -= $producedQty;
if ($remainingQty < 0) {
$remainingQty = 0;
}
$remainingDays--;
// Skip leave dates fast
if (isset($leaveDates) && in_array($date, $leaveDates)) {
$row['daily_line_capacity'][$date] = '-';
$row['daily_target_dynamic'][$date] = '-';
$row['produced_quantity'][$date] = '-';
continue;
}
return $row;
})
->toArray();
$todayTarget = $remainingDays > 0
? round($remainingQty / $remainingDays, 2)
: 0;
$producedQty = $producedData[$key][$date]->total_qty ?? 0;
$row['daily_target_dynamic'][$date] = $todayTarget;
$row['produced_quantity'][$date] = $producedQty;
$row['daily_line_capacity'][$date] = $dailyLineCapacity;
// Carry forward remaining qty
$remainingQty = max(0, $remainingQty - $producedQty);
if ($remainingDays > 0) {
$remainingDays--;
}
}
$records[] = $row;
}
$this->records = $records;
}
public function exportProductionData()
{
return Excel::download(

View File

@@ -0,0 +1,47 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
class CharacteristicValue extends Model
{
use SoftDeletes;
protected $fillable = [
'plant_id',
'line_id',
'item_id',
'machine_id',
'process_order',
'coil_number',
'status',
'observed_value',
'created_at',
'updated_at',
'created_by',
'updated_by',
];
public function plant(): BelongsTo
{
return $this->belongsTo(Plant::class);
}
public function line(): BelongsTo
{
return $this->belongsTo(Line::class);
}
public function item(): BelongsTo
{
return $this->belongsTo(Item::class);
}
public function machine(): BelongsTo
{
return $this->belongsTo(Machine::class);
}
}

View File

@@ -55,4 +55,14 @@ class Item extends Model
{
return $this->hasMany(ItemCharacteristic::class, 'item_id', 'id');
}
public function productCharacteristicsMasters()
{
return $this->hasMany(ProductCharacteristicsMaster::class);
}
public function processOrders()
{
return $this->hasMany(ProcessOrder::class);
}
}

View File

@@ -16,6 +16,7 @@ class Line extends Model
"block_id",
"name",
"type",
"line_capacity",
"group_work_center",
"no_of_operation",
"work_group1_id",
@@ -150,6 +151,21 @@ class Line extends Model
return $this->hasMany(WorkGroupMaster::class, 'work_group10_id', 'id');
}
public function machines()
{
return $this->hasMany(Machine::class);
}
public function productCharacteristicsMasters()
{
return $this->hasMany(ProductCharacteristicsMaster::class);
}
public function processOrders()
{
return $this->hasMany(ProcessOrder::class);
}
// public function rejectReasons()
// {
// return $this->hasMany(RejectReason::class, 'line_id', 'id');

View File

@@ -107,4 +107,24 @@ class Plant extends Model
{
return $this->hasMany(ItemCharacteristic::class, 'plant_id', 'id');
}
public function processOrders()
{
return $this->hasMany(ProcessOrder::class, 'plant_id', 'id');
}
public function characteristicValues()
{
return $this->hasMany(CharacteristicValue::class, 'plant_id', 'id');
}
public function machines()
{
return $this->hasMany(Machine::class, 'plant_id', 'id');
}
public function productCharacteristicsMasters()
{
return $this->hasMany(ProductCharacteristicsMaster::class, 'plant_id', 'id');
}
}

View File

@@ -12,17 +12,21 @@ class ProcessOrder extends Model
protected $fillable = [
'plant_id',
'line_id',
'item_id',
'process_order',
'coil_number',
'order_quantity',
'received_quantity',
'updated_order_quantity',
'sfg_number',
'machine_name',
'scrap_quantity',
'rework_status',
'created_at',
'created_by',
'updated_by',
'updated_at',
'updated_by',
];
public function plant(): BelongsTo
@@ -30,7 +34,12 @@ class ProcessOrder extends Model
return $this->belongsTo(Plant::class);
}
public function item()
public function line(): BelongsTo
{
return $this->belongsTo(Line::class);
}
public function item(): BelongsTo
{
return $this->belongsTo(Item::class, 'item_id');
}

View File

@@ -23,7 +23,8 @@ class ProductionQuantity extends Model
"serial_number",
"production_order",
"operator_id",
// "success_status",
"success_status",
"reject_reason",
// "no_of_employee",
// "list_of_employee",
"created_at",

View File

@@ -37,6 +37,8 @@ class StickerMaster extends Model
'load_rate',
'bundle_quantity',
'material_type',
'created_by',
'updated_by'
];
public function item()

View File

@@ -37,4 +37,9 @@ class StickerStructureDetail extends Model
return $this->belongsTo(ItemCharacteristic::class, 'item_characteristic_id');
}
public function item(): BelongsTo
{
return $this->belongsTo(Item::class, 'item_id');
}
}

View File

@@ -25,6 +25,16 @@ class WorkGroupMaster extends Model
return $this->belongsTo(Plant::class);
}
public function machines()
{
return $this->hasMany(Machine::class, 'work_group_master_id');
}
public function productCharacteristicsMasters()
{
return $this->hasMany(ProductCharacteristicsMaster::class);
}
// public function rejectReasons()
// {
// return $this->hasMany(RejectReason::class, 'work_group_master_id', 'id');

View File

@@ -0,0 +1,106 @@
<?php
namespace App\Policies;
use Illuminate\Auth\Access\Response;
use App\Models\CharacteristicValue;
use App\Models\User;
class CharacteristicValuePolicy
{
/**
* Determine whether the user can view any models.
*/
public function viewAny(User $user): bool
{
return $user->checkPermissionTo('view-any CharacteristicValue');
}
/**
* Determine whether the user can view the model.
*/
public function view(User $user, CharacteristicValue $characteristicvalue): bool
{
return $user->checkPermissionTo('view CharacteristicValue');
}
/**
* Determine whether the user can create models.
*/
public function create(User $user): bool
{
return $user->checkPermissionTo('create CharacteristicValue');
}
/**
* Determine whether the user can update the model.
*/
public function update(User $user, CharacteristicValue $characteristicvalue): bool
{
return $user->checkPermissionTo('update CharacteristicValue');
}
/**
* Determine whether the user can delete the model.
*/
public function delete(User $user, CharacteristicValue $characteristicvalue): bool
{
return $user->checkPermissionTo('delete CharacteristicValue');
}
/**
* Determine whether the user can delete any models.
*/
public function deleteAny(User $user): bool
{
return $user->checkPermissionTo('delete-any CharacteristicValue');
}
/**
* Determine whether the user can restore the model.
*/
public function restore(User $user, CharacteristicValue $characteristicvalue): bool
{
return $user->checkPermissionTo('restore CharacteristicValue');
}
/**
* Determine whether the user can restore any models.
*/
public function restoreAny(User $user): bool
{
return $user->checkPermissionTo('restore-any CharacteristicValue');
}
/**
* Determine whether the user can replicate the model.
*/
public function replicate(User $user, CharacteristicValue $characteristicvalue): bool
{
return $user->checkPermissionTo('replicate CharacteristicValue');
}
/**
* Determine whether the user can reorder the models.
*/
public function reorder(User $user): bool
{
return $user->checkPermissionTo('reorder CharacteristicValue');
}
/**
* Determine whether the user can permanently delete the model.
*/
public function forceDelete(User $user, CharacteristicValue $characteristicvalue): bool
{
return $user->checkPermissionTo('force-delete CharacteristicValue');
}
/**
* Determine whether the user can permanently delete any models.
*/
public function forceDeleteAny(User $user): bool
{
return $user->checkPermissionTo('force-delete-any CharacteristicValue');
}
}

View File

@@ -2,10 +2,13 @@
namespace App\Providers;
use App\Filament\Pages\NotificationSettings;
use App\Models\AlertMailRule;
use App\Models\User;
use App\Policies\PermissionPolicy;
use App\Policies\RolePolicy;
use DB;
use Filament\Facades\Filament;
use Filament\Support\Assets\Js;
use Filament\Support\Facades\FilamentAsset;
use Illuminate\Console\Scheduling\Schedule;
@@ -40,6 +43,16 @@ class AppServiceProvider extends ServiceProvider
// $view->with('forgotPasswordUrl', route('password.request'));
// });
DB::listen(function ($query) {
if ($query->time > 1000) { // > 1 sec
logger()->warning('Slow query', [
'sql' => $query->sql,
'time' => $query->time
]);
}
});
Gate::before(function (User $user, string $ability) {
return $user->isSuperAdmin() ? true : null;
});

View File

@@ -30,6 +30,8 @@ use App\Filament\Pages\CustomLogin;
use Filament\View\PanelsRenderHook;
use Filament\Support\Facades\FilamentView;
use Illuminate\Support\Facades\Blade;
use Filament\Pages\Auth\PasswordReset\RequestPasswordReset;
use Filament\Pages\Auth\PasswordReset\ResetPassword;
class AdminPanelProvider extends PanelProvider
@@ -42,6 +44,10 @@ class AdminPanelProvider extends PanelProvider
->id('admin')
->path('admin')
->login()
->passwordReset(
RequestPasswordReset::class,
ResetPassword::class,
)
//->maxContentWidth(MaxWidth::Small)
//->simplePageMaxContentWidth(MaxWidth::Medium)

View File

@@ -895,7 +895,8 @@ class StickerPdfService
if (
($row->element_type) == 'Dynamic'
) {
$qrContent = $serNo ?? '';
$qrContent = $itemCode . '|' . ($serNo ?? '');
$pdf->write2DBarcode(
$qrContent,
'QRCODE,H',
@@ -1018,22 +1019,9 @@ class StickerPdfService
}
}
// $pdfContent = $pdf->Output('', 'S'); // 'S' returns string
// // Encode as base64
// return base64_encode($pdfContent);
// $pdfContent = $pdf->Output('', 'S');
// return response($pdfContent)
// ->header('Content-Type', 'application/pdf')
// ->header('Content-Disposition', 'inline; filename="sticker.pdf"');
$pdfContent = $pdf->Output('', 'S'); // 'S' returns the PDF as a string
// Return the PDF as a response
try {
$pdfContent = $pdf->Output('', 'S'); // 'S' returns the PDF as a string
$pdfContent = $pdf->Output('', 'S');
return response($pdfContent)
->header('Content-Type', 'application/pdf')
->header('Content-Disposition', 'inline; filename="sticker.pdf"');

View File

@@ -19,7 +19,7 @@ return new class extends Migration
production_order TEXT DEFAULT NULL,
serial_number TEXT DEFAULT NULL,
status TEXT DEFAULT NULL,
sticker_id TEXT DEFAULT NULL
sticker_id TEXT DEFAULT NULL,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),

View File

@@ -0,0 +1,31 @@
<?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 lines
ADD COLUMN line_capacity TEXT DEFAULT NULL
SQL;
DB::statement($sql1);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// Schema::table('lines', function (Blueprint $table) {
// //
// });
}
};

View File

@@ -0,0 +1,38 @@
<?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
{
DB::statement(<<<SQL
ALTER TABLE process_orders
ALTER COLUMN received_quantity TYPE NUMERIC(10,3)
USING received_quantity::NUMERIC(10,3);
SQL);
// order_quantity → NUMERIC(10,6)
DB::statement(<<<SQL
ALTER TABLE process_orders
ALTER COLUMN order_quantity TYPE NUMERIC(10,3)
USING order_quantity::NUMERIC(10,3);
SQL);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// Schema::table('process_orders', function (Blueprint $table) {
// //
// });
}
};

View File

@@ -0,0 +1,34 @@
<?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 process_orders
ADD COLUMN line_id BIGINT DEFAULT NULL,
ADD CONSTRAINT process_orders_line_id_fkey
FOREIGN KEY (line_id) REFERENCES lines(id);
SQL;
DB::statement($sql);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// Schema::table('process_orders', function (Blueprint $table) {
// //
// });
}
};

View File

@@ -0,0 +1,29 @@
<?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
{
DB::statement('
ALTER TABLE process_orders
ADD COLUMN scrap_quantity NUMERIC(10,3)
');
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// Schema::table('process_orders', function (Blueprint $table) {
// //
// });
}
};

View File

@@ -0,0 +1,31 @@
<?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 process_orders
ADD COLUMN rework_status INT NOT NULL DEFAULT (0)
SQL;
DB::statement($sql1);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// Schema::table('process_orders', function (Blueprint $table) {
// //
// });
}
};

View File

@@ -0,0 +1,31 @@
<?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 process_orders
ADD COLUMN updated_order_quantity NUMERIC(10,3) NULL
SQL;
DB::statement($sql1);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// Schema::table('process_orders', function (Blueprint $table) {
// //
// });
}
};

View File

@@ -0,0 +1,48 @@
<?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 characteristic_values (
id BIGINT GENERATED always AS IDENTITY PRIMARY KEY,
plant_id BIGINT NOT NULL,
line_id BIGINT NOT NULL,
item_id BIGINT NOT NULL,
machine_id BIGINT NOT NULL,
process_order TEXT DEFAULT NULL,
coil_number TEXT DEFAULT NULL,
status TEXT DEFAULT NULL,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
created_by TEXT DEFAULT NULL,
updated_by TEXT DEFAULT NULL,
deleted_at TIMESTAMP,
FOREIGN KEY (plant_id) REFERENCES plants (id),
FOREIGN KEY (line_id) REFERENCES lines (id),
FOREIGN KEY (item_id) REFERENCES items (id),
FOREIGN KEY (machine_id) REFERENCES machines (id)
);
SQL;
DB::statement($sql);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('characteristic_values');
}
};

View File

@@ -0,0 +1,29 @@
<?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
{
DB::statement(<<<SQL
ALTER TABLE characteristic_values
ADD COLUMN observed_value NUMERIC(10,3);
SQL);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// Schema::table('characteristic_values', function (Blueprint $table) {
// //
// });
}
};

View File

@@ -0,0 +1,38 @@
<?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 sticker_masters
ADD COLUMN created_by TEXT DEFAULT NULL
SQL;
DB::statement($sql1);
$sql2 = <<<'SQL'
ALTER TABLE sticker_masters
ADD COLUMN updated_by TEXT DEFAULT NULL
SQL;
DB::statement($sql2);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// Schema::table('sticker_masters', function (Blueprint $table) {
// //
// });
}
};

View File

@@ -171,5 +171,17 @@ class PermissionSeeder extends Seeder
Permission::updateOrCreate(['name' => 'view import sticker printing']);
Permission::updateOrCreate(['name' => 'view export sticker printing']);
Permission::updateOrCreate(['name' => 'view import request quotation']);
Permission::updateOrCreate(['name' => 'view export request quotation']);
Permission::updateOrCreate(['name' => 'view rfq dashboard']);
Permission::updateOrCreate(['name' => 'view rfq overview dashboard']);
Permission::updateOrCreate(['name' => 'view production calender page']);
Permission::updateOrCreate(['name' => 'view production target page']);
}
}

915
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -6,6 +6,7 @@
"dev": "vite"
},
"devDependencies": {
"@vitejs/plugin-react": "^5.1.2",
"autoprefixer": "^10.4.20",
"axios": "^1.7.4",
"chartjs-plugin-datalabels": "^2.2.0",
@@ -14,5 +15,9 @@
"postcss": "^8.4.47",
"tailwindcss": "^3.4.13",
"vite": "^6.0.11"
},
"dependencies": {
"react": "^19.2.3",
"react-dom": "^19.2.3"
}
}

View File

@@ -115,3 +115,5 @@ $sticker_id = $attributes->get('sticker_id');

View File

@@ -1,19 +1,96 @@
<x-filament-panels::page>
<h1 class="text-3xl font-bold mb-6">Welcome to CRI Digital Manufacturing IIOT</h1>
<!-- HEADER -->
<div class="mb-8">
<h1 class="text-4xl font-bold tracking-tight">
CRI Digital Manufacturing IIoT Platform
</h1>
<p class="text-lg text-gray-600 mt-2">
Complete visibility, traceability, and control across your manufacturing operations
</p>
</div>
<div class="w-full overflow-hidden rounded-xl shadow">
<img
src="{{ asset('images/iiot-banner.jpg') }}"
alt="CRI Digital Manufacturing IIoT"
class="w-full h-64 object-cover"
>
</div>
<!-- BANNER -->
<div class="w-full overflow-hidden rounded-2xl shadow mb-10">
<img
src="{{ asset('images/iiot-banner.jpg') }}"
alt="CRI Digital Manufacturing IIoT"
class="w-full h-72 object-cover"
>
</div>
<p class="text-lg text-gray-600 mb-6">
This dashboard provides real-time visibility into your manufacturing operations,
enabling you to monitor production, track performance, and make data-driven decisions
across plants and lines—all from one centralized platform.
</p>
<!-- INTRO -->
<div class="max-w-4xl mb-10">
<p class="text-lg text-gray-700 mb-4">
CRI Digital Manufacturing IIoT is built to deliver
<strong>end-to-end traceability, real-time insights, and operational transparency</strong>
across plants, lines, and production processes.
</p>
<p class="text-lg text-gray-700">
The platform ensures <strong>right quality and on-time delivery</strong> by enabling
complete tracking of materials, production orders, and finished goods—helping teams
make faster, data-driven decisions with confidence.
</p>
</div>
<!-- KEY PILLARS -->
<div class="grid grid-cols-1 md:grid-cols-4 gap-6 mb-10">
<div class="bg-white rounded-xl border p-6 shadow-sm">
<h3 class="text-lg font-semibold mb-2">🔍 Traceability</h3>
<p class="text-gray-600">
Track materials, batches, and serials from input to dispatch.
</p>
</div>
<div class="bg-white rounded-xl border p-6 shadow-sm">
<h3 class="text-lg font-semibold mb-2">✅ Quality Assurance</h3>
<p class="text-gray-600">
Validate process data and ensure first-time-right production.
</p>
</div>
<div class="bg-white rounded-xl border p-6 shadow-sm">
<h3 class="text-lg font-semibold mb-2">⏱ On-Time Delivery</h3>
<p class="text-gray-600">
Identify delays early and meet production commitments.
</p>
</div>
<div class="bg-white rounded-xl border p-6 shadow-sm">
<h3 class="text-lg font-semibold mb-2">📊 Real-Time Insights</h3>
<p class="text-gray-600">
Monitor performance and take quick corrective actions.
</p>
</div>
</div>
<!-- SUPPORT -->
<div class="bg-white rounded-xl border p-6 shadow-sm">
<h2 class="text-2xl font-semibold mb-3">24×7 Support</h2>
<p class="text-gray-700 mb-2">
Our dedicated IIoT support team is available round-the-clock to ensure
uninterrupted operations and quick issue resolution.
</p>
<p class="text-lg font-medium text-gray-900">
📞 Support Contact: <span class="font-semibold">+91 8925899458 / +91 8925899459</span>
</p>
{{-- <p class="text-lg font-medium text-gray-900">
📞 Technical Support Contact: <span class="font-semibold">9952468104 / 9100832269</span>
</p> --}}
</div>
<!-- TEAM -->
<div class="bg-white rounded-xl border p-6 shadow-sm">
<h2 class="text-2xl font-semibold mb-4">Our Team</h2>
<div class="grid grid-cols-2 md:grid-cols-3 gap-4 text-gray-700">
<div class="flex items-center gap-2">👤 Jothikumar</div>
<div class="flex items-center gap-2">👤 Dhanabalan</div>
<div class="flex items-center gap-2">👤 Shibu</div>
<div class="flex items-center gap-2">👤 Ranjith</div>
<div class="flex items-center gap-2">👤 Srimathi</div>
<div class="flex items-center gap-2">👤 Gokul</div>
</div>
</div>
</x-filament-panels::page>

View File

@@ -67,3 +67,29 @@ window.addEventListener('open-stickers-sequence', async (event) => {
});
</script>
<script>
window.addEventListener('open-sticker-pdf', event => {
console.log('PDF event:', event.detail);
let url = null;
// Livewire v3 wraps payload in array
if (Array.isArray(event.detail)) {
url = event.detail[0]?.url;
}
// fallback (if direct object comes)
else if (event.detail?.url) {
url = event.detail.url;
}
if (url) {
window.open(url, '_blank');
} else {
console.error('PDF URL missing', event.detail);
}
});
</script>

View File

@@ -64,88 +64,58 @@ document.addEventListener('DOMContentLoaded', function () {
});
// var calendar = new FullCalendar.Calendar(calendarEl, {
// initialView: 'dayGridMonth',
// height: 600,
// showNonCurrentDates: true,
// function updateWorkingDays(date) {
// let totalDays = new Date(
// date.getFullYear(),
// date.getMonth()+1,
// 0
// ).getDate();
// dateClick: function(info) {
// let workingDays = totalDays - selectedDates.length;
// // document.querySelector('input[name="working_days"]').value = workingDays;
// let viewMonth = calendar.view.currentStart.getMonth();
// let clickedMonth = info.date.getMonth();
// const input = document.querySelector('#working_days');
// // let month = info.date.getMonth() + 1; // JS month: 0-11 → 1-12
// // let year = info.date.getFullYear();
// input.value = workingDays;
// if (viewMonth != clickedMonth) {
// return; // Ignore next/prev month dates
// }
// input.dispatchEvent(new Event('input'));
// let dateStr = info.dateStr;
// const monthInput = document.querySelector('#month');
// monthInput.value = date.getMonth() + 1; // 1–12 month number
// monthInput.dispatchEvent(new Event('input'));
// if (selectedDates.includes(dateStr)) {
// selectedDates = selectedDates.filter(d => d !== dateStr);
// const yearInput = document.querySelector('#year');
// yearInput.value = date.getFullYear();
// yearInput.dispatchEvent(new Event('input'));
// calendar.getEvents().forEach(event => {
// if (event.startStr == dateStr) {
// event.remove();
// }
// });
// const selectedDatesInput = document.querySelector('#selected_dates');
// selectedDatesInput.value = selectedDates.join(',');
// selectedDatesInput.dispatchEvent(new Event('input'));
// } else {
// selectedDates.push(dateStr);
// calendar.addEvent({
// start: dateStr,
// display: 'background',
// color: '#f03f17'
// });
// }
// updateWorkingDays(info.date);
// }
// });
// yearSelect.addEventListener('change', function () {
// let year = this.value;
// if (!year) return;
// let currentDate = calendar.getDate();
// let newDate = new Date(year, currentDate.getMonth(), 1);
// calendar.gotoDate(newDate);
// });
// }
function updateWorkingDays(date) {
let totalDays = new Date(
date.getFullYear(),
date.getMonth()+1,
date.getMonth() + 1,
0
).getDate();
let workingDays = totalDays - selectedDates.length;
// document.querySelector('input[name="working_days"]').value = workingDays;
const input = document.querySelector('#working_days');
input.value = workingDays;
input.dispatchEvent(new Event('input'));
const monthInput = document.querySelector('#month');
monthInput.value = date.getMonth() + 1; // 1–12 month number
monthInput.dispatchEvent(new Event('input'));
const yearInput = document.querySelector('#year');
yearInput.value = date.getFullYear();
yearInput.dispatchEvent(new Event('input'));
const selectedDatesInput = document.querySelector('#selected_dates');
selectedDatesInput.value = selectedDates.join(',');
selectedDatesInput.dispatchEvent(new Event('input'));
// Set values only
document.querySelector('#working_days').value = workingDays;
document.querySelector('#month').value = date.getMonth() + 1;
document.querySelector('#year').value = date.getFullYear();
document.querySelector('#selected_dates').value = selectedDates.join(',');
// Trigger only ONE update (important)
document
.querySelector('#selected_dates')
.dispatchEvent(new Event('input'));
}
calendar.render();
});
</script>

View File

@@ -4,17 +4,6 @@
</h2>
<div class="overflow-x-auto rounded-lg shadow">
<table class="w-full divide-y divide-gray-200 text-sm text-center">
{{-- <thead class="bg-gray-100 text-s font-semibold uppercase text-gray-700">
<tr>
<th class="border px-4 py-2">No</th>
<th class="border px-4 py-2">Created Datetime</th>
<th class="border px-4 py-2 whitespace-nowrap">Created By</th>
<th class="border px-4 py-2 whitespace-nowrap">Plant</th>
<th class="border px-4 py-2">Line</th>
<th class="border px-4 py-2 whitespace-nowrap">Item Code</th>
<th class="border px-4 py-2">Production Plan Dates</th>
</tr>
</thead> --}}
<thead class="bg-gray-100 text-s font-semibold uppercase text-gray-700">
<tr>
<th class="border px-4 py-2" rowspan="3">No</th>
@@ -22,21 +11,29 @@
<th class="border px-4 py-2 whitespace-nowrap" rowspan="3">Line</th>
<th class="border px-4 py-2 whitespace-nowrap" rowspan="3">Item Code</th>
<th class="border px-4 py-2 whitespace-nowrap" colspan="{{ count($dates) * 2 }}" class="text-center">
<th class="border px-4 py-2 whitespace-nowrap" colspan="{{ count($dates) * 3 }}" class="text-center">
Production Plan Dates
</th>
</tr>
<tr>
@foreach($dates as $date)
<th colspan="2" class="text-center">
{{-- <th colspan="3" class="text-center">
{{ $date }}
</th> --}}
<th colspan="3" class="text-center border-r-4 border-gray-400">
{{ $date }}
</th>
@endforeach
</tr>
<tr>
@foreach($dates as $date)
<th class="border px-4 py-2 whitespace-nowrap">Line Capacity</th>
<th class="border px-4 py-2 whitespace-nowrap">Target Plan</th>
<th class="border px-4 py-2 whitespace-nowrap">Produced Quantity</th>
<th class="border px-4 py-2 whitespace-nowrap border-r-4 border-gray-400">
Produced Quantity
</th>
{{-- <th class="border px-4 py-2 whitespace-nowrap">Produced Quantity</th> --}}
@endforeach
</tr>
</thead>
@@ -58,8 +55,12 @@
@if(in_array($date, $leaveDates))
<td class="border px-4 py-2 whitespace-nowrap">-</td>
<td class="border px-4 py-2 whitespace-nowrap">-</td>
<td class="border px-4 py-2 whitespace-nowrap">-</td>
@else
{{-- <td class="border px-4 py-2 whitespace-nowrap">{{ $record['daily_target'] ?? '-' }}</td> --}}
<td class="border px-4 py-2 whitespace-nowrap">
{{ $record['daily_line_capacity'][$date] ?? '-' }}
</td>
<td class="border px-4 py-2 whitespace-nowrap">
{{ $record['daily_target_dynamic'][$date] ?? '-' }}
</td>
@@ -72,7 +73,7 @@
</tr>
@empty
<tr>
<td colspan="9" class="px-4 py-4 text-center text-gray-500">
<td colspan="10" class="px-4 py-4 text-center text-gray-500">
No production plan data found.
</td>
</tr>

View File

@@ -12,7 +12,7 @@
<thead class="bg-gray-100 text-xs">
<tr>
<th class="border p-2">No</th>
<th class="border p-2">Sticker ID</th>
{{-- <th class="border p-2">Sticker ID</th> --}}
<th class="border p-2">Production Order</th>
<th class="border p-2">Serial Number</th>
<th class="border p-2">Status</th>
@@ -24,7 +24,7 @@
@forelse($records as $index => $record)
<tr>
<td class="border p-2 text-center">{{ $index + 1 }}</td>
<td class="border p-2 text-center">{{ $record->sticker_id }}</td>
{{-- <td class="border p-2 text-center">{{ $record->sticker_id }}</td> --}}
<td class="border p-2 text-center">{{ $refNumber }}</td>
<td class="border p-2 text-center">{{ $record['serial_number'] }}</td>
<td class="border p-2 text-center">{{ $record->status }}</td>
@@ -32,7 +32,7 @@
</tr>
@empty
<tr>
<td class="border p-2 text-center" colspan="6">No serial numbers found.</td>
<td class="border p-2 text-center" colspan="5">No serial numbers found.</td>
</tr>
@endforelse
</tbody>

View File

@@ -151,11 +151,13 @@ Route::post('testing/reading/store-data', [TestingPanelController::class, 'store
Route::get('get-pdf', [PdfController::class, 'getPdf']);
//..Process Order
Route::get('process-order/details', [PdfController::class, 'getProcessOrderData']);
Route::post('process-order', [PdfController::class, 'storeProcessOrderData']);
Route::get('sap/files', [SapFileController::class, 'readFiles']);
Route::post('characteristics/values', [CharacteristicsController::class, 'storeCharValues']);
//..Laser Marking - Characteristics
@@ -192,42 +194,6 @@ Route::post('file/store', [SapFileController::class, 'store'])->name('file.store
Route::post('/print-pdf', [PrintController::class, 'print']);
Route::get('/sticker/preview/{serial}', [PrintController::class, 'preview']);
Route::post('/push/subscribe', function (Request $request) {
$user = Filament::auth()->user();
abort_if(!$user, 401);
$request->validate([
'endpoint' => 'required|string',
'keys.p256dh' => 'required|string',
'keys.auth' => 'required|string',
]);
// WebPushSubscription::updateOrCreate(
// ['endpoint' => $request->endpoint],
// [
// 'subscribable_type' => get_class($user),
// 'subscribable_id' => $user->id,
// 'public_key' => $request->keys['p256dh'],
// 'auth_token' => $request->keys['auth'],
// 'content_encoding' => $request->contentEncoding ?? 'aesgcm',
// ]
// );
WebPushSubscription::updateOrCreate(
[
'endpoint' => $request->endpoint,
'subscribable_type' => get_class($user),
'subscribable_id' => $user->id,
],
[
'public_key' => $request->keys['p256dh'],
'auth_token' => $request->keys['auth'],
'content_encoding' => $request->contentEncoding ?? 'aesgcm',
]
);
return response()->json(['success' => true]);
});
Route::get('sap/files', [SapFileController::class, 'readFiles']);

View File

@@ -12,7 +12,7 @@ Artisan::command('inspire', function () {
Artisan::command('auto:scheduler', function () {
$this->call('custom:scheduler');
})->everyMinute();
})->everyMinute()->withoutOverlapping();
// Schedule::command('send:invoice-report');

View File

@@ -1,12 +1,32 @@
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [
laravel({
input: ['resources/css/app.css', 'resources/js/app.js', 'resources/js/filament-chart-js-plugins.js', 'resources/css/filament/admin/theme.css',],
input: ['resources/css/app.css', 'resources/js/app.js', 'resources/js/filament-chart-js-plugins.js', 'resources/css/filament/admin/theme.css'],
// input: ['resources/css/app.css', 'resources/js/app.js',],
refresh: true,
}),
],
});
// export default defineConfig({
// server: {
// host: '127.0.0.1',
// port: 5173,
// },
// plugins: [
// laravel({
// input: [
// 'resources/css/app.css',
// 'resources/js/app.jsx',
// 'resources/js/filament-chart-js-plugins.js',
// 'resources/css/filament/admin/theme.css',
// ],
// refresh: true,
// }),
// react(),
// ],
// })