Files
pds/app/Filament/Imports/ProductionOrderImporter.php
dhanabalan 7e1fea11c6
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Has been cancelled
Gemini PR Review / Gemini PR Review (pull_request) Has been cancelled
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Has been cancelled
Laravel Larastan / larastan (pull_request) Has been cancelled
Laravel Pint / pint (pull_request) Has been cancelled
Updated validation logics for resource, importer, exporter, create files and Added columns in model file
2026-05-02 18:57:13 +05:30

308 lines
12 KiB
PHP

<?php
namespace App\Filament\Imports;
use App\Models\Item;
use App\Models\Plant;
use App\Models\ProductionOrder;
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 ProductionOrderImporter extends Importer
{
protected static ?string $model = ProductionOrder::class;
public static function getColumns(): array
{
return [
ImportColumn::make('plant')
->requiredMapping()
->label('PLANT CODE')
->exampleHeader('PLANT CODE')
->example('1000')
->relationship(resolveUsing: 'code')
->rules(['required']),
ImportColumn::make('item')
->requiredMapping()
->label('ITEM CODE')
->exampleHeader('ITEM CODE')
->example('123456')
->relationship(resolveUsing: 'code')
->rules(['required']),
ImportColumn::make('quantity')
->requiredMapping()
->label('QUANTITY')
->exampleHeader('QUANTITY')
->example('1')
->rules(['required']),
ImportColumn::make('start_date')
->requiredMapping()
->label('START DATE')
->exampleHeader('START DATE')
->example('30-01-2026') // 00:00:00
->rules(['required']),
ImportColumn::make('end_date')
->requiredMapping()
->label('END DATE')
->exampleHeader('END DATE')
->example('30-01-2026') // 00:00:00
->rules(['required']),
ImportColumn::make('production_order')
->label('PRODUCTION ORDER')
->exampleHeader('PRODUCTION ORDER'),
// ->example('260116180001')
// ImportColumn::make('from_serial_number')
// ->label('FROM SERIAL NUMBER')
// // ->exampleHeader('FROM SERIAL NUMBER')
// // ->example('1000211260400001')
// ->rules(['required']),
// ImportColumn::make('to_serial_number')
// ->label('TO SERIAL NUMBER')
// // ->exampleHeader('TO SERIAL NUMBER')
// // ->example('1000211260400003')
// ->rules(['required']),
// ImportColumn::make('created_by')
// ->label('CREATED BY')
// // ->exampleHeader('CREATED BY')
// // ->example('USER00001')
// ->rules(['required']),
// ImportColumn::make('updated_by')
// ->label('UPDATED BY')
// // ->exampleHeader('UPDATED BY')
// // ->example('USER00001')
// ->rules(['required']),
];
}
public function resolveRecord(): ?ProductionOrder
{
$warnMsg = [];
$plant = null;
$plantCod = trim($this->data['plant']) ?? '';
$plantId = null;
$item = null;
$itemCod = trim($this->data['item']) ?? '';
$itemId = null;
$qnty = trim($this->data['quantity']) ?? '';
$startAt = trim($this->data['start_date']) ?? '';
$endAt = trim($this->data['end_date']) ?? '';
$prodOrd = trim($this->data['production_order']) ?? '';
$createdBy = Filament::auth()->user()?->name ?? '';
$updatedBy = $createdBy;
$qValid = false;
$oValid = false;
$dValid = false;
if ($plantCod == null || $plantCod == '' || ! $plantCod) {
$warnMsg[] = "Plant code can't be empty!";
} elseif (! is_numeric($plantCod)) {
$warnMsg[] = "Plant code '{$plantCod}' should contain only numeric values!";
} elseif (Str::length($plantCod) < 4 || Str::length($plantCod) > 7) {
$warnMsg[] = "Plant code '{$plantCod}' must be between 4 and 7 digits only!";
} elseif (! preg_match('/^[1-9]\d{3,6}$/', $plantCod)) {
$warnMsg[] = "Invalid plant code '{$plantCod}' found!";
} else {
$plant = Plant::where('code', $plantCod)->first();
if (! $plant) {
$warnMsg[] = 'Plant not found!';
} else {
$plantId = $plant->id;
}
}
if ($itemCod == null || $itemCod == '') {
$warnMsg[] = "Item code can't be empty!";
} elseif (! ctype_alnum($itemCod)) {
$warnMsg[] = "Item code '{$itemCod}' should contain only alpha-numeric values!";
} elseif (Str::length($itemCod) < 6) {
$warnMsg[] = "Item code '{$itemCod}' should contain minimum 6 digits!";
} else {
$item = Item::where('code', $itemCod)->first();
if (! $item) {
$warnMsg[] = 'Item code not found!';
} else {
if ($plantId) {
$item = Item::where('code', $itemCod)->where('plant_id', $plantId)->first();
if (! $item) {
$warnMsg[] = 'Item code not found for the given plant!';
} else {
$itemId = $item->id;
}
}
}
}
if ($qnty == null || $qnty == '' || $qnty == '0') {
$warnMsg[] = "Quantity can't be empty or zero!";
} elseif (! is_numeric($qnty)) {
$warnMsg[] = "Quantity '{$qnty}' should contain only numeric values!";
} else {
$qValid = true;
}
if ($prodOrd == null || $prodOrd == '' || ! $prodOrd) {
$oValid = true;
} elseif (! is_numeric($prodOrd)) {
$warnMsg[] = "Production order '{$prodOrd}' should contain only numeric values!";
} elseif (Str::length($prodOrd) < 7 || Str::length($prodOrd) > 12) {
$warnMsg[] = "Production order '{$prodOrd}' must be between 7 and 12 digits only!";
} else {
$oValid = true;
}
if (! $startAt) {
$warnMsg[] = "Start date can't be empty!";
}
if (! $endAt) {
$warnMsg[] = "End date can't be empty!";
}
if ($startAt && $endAt) {
$formats = ['d-m-Y', 'd-m-Y H:i', 'd-m-Y H:i:s'];
$cDateTime = null;
$uDateTime = null;
foreach ($formats as $format) {
try {
$cDateTime = Carbon::createFromFormat($format, $startAt);
if ($format === 'd-m-Y' || $format === 'd-m-Y H:i' || $format === 'd-m-Y H:i:s') {
$cDateTime = $cDateTime->startOfDay();
}
break;
} catch (\Exception $e) {
// $warnMsg[] = "Date format mismatch with format: $format";
}
}
foreach ($formats as $format) {
try {
$uDateTime = Carbon::createFromFormat($format, $endAt);
if ($format === 'd-m-Y' || $format === 'd-m-Y H:i' || $format === 'd-m-Y H:i:s') {
$uDateTime = $uDateTime->endOfDay();
}
break;
} catch (\Exception $e) {
// $warnMsg[] = "Date format mismatch with format: $format";
}
}
if (! isset($cDateTime)) {
$warnMsg[] = "Invalid 'Start Date' format. Expected DD-MM-YYYY"; // DD-MM-YYYY HH:MM:SS
}
if (! isset($uDateTime)) {
$warnMsg[] = "Invalid 'End Date' format. Expected DD-MM-YYYY";
}
if (isset($cDateTime) && isset($uDateTime)) {
if ($cDateTime->greaterThan($uDateTime)) {
$warnMsg[] = "'Start Date' is greater than 'End Date'.";
} else {
$dValid = true;
}
}
}
if ($plantId && $itemId && $qValid && $oValid && $dValid) {
$now = Carbon::now();
$year = $now->format('y'); // Year (last 2 digits)
$month = $now->format('m');
if ($prodOrd) {
$dupProd = ProductionOrder::where('plant_id', $plantId)->where('production_order', $prodOrd)->first();
if ($dupProd) {
$warnMsg[] = "Production Order '{$prodOrd}' already exists in database for the given plant!";
} else {
$dupProd = ProductionOrder::where('production_order', $prodOrd)->first();
if ($dupProd) {
$warnMsg[] = "Production Order '{$prodOrd}' already exists in database!";
}
}
if (! empty($warnMsg)) {
throw new RowImportFailedException(implode(', ', $warnMsg));
}
} else {
$monthText = strtoupper($now->format('M')); // APR
$monthNumber = '';
foreach (str_split($monthText) as $char) {
$curSeq = ord($char) - 64;
$monthNumber .= str_pad($curSeq, 2, '0', STR_PAD_LEFT);
}
$prefix = $year.$monthNumber;
$last = ProductionOrder::where('production_order', 'like', "{$prefix}%")->orderByDesc('production_order')->first(); // ProductionOrder::where('production_order', 'like', $prefix.'%')->orderBy('production_order', 'desc')->first();
if ($last) {
$lastSeq = substr($last->production_order, -4);
$nextSeq = str_pad(((int) $lastSeq + 1), 4, '0', STR_PAD_LEFT);
} else {
$nextSeq = '0001';
}
$prodOrd = $prefix.$nextSeq;
}
$prefixSerial = $plantCod.$year.$month;
$last = ProductionOrder::where('to_serial_number', 'like', "{$prefixSerial}%")->orderByDesc('to_serial_number')->first();
if ($last) {
$lastSeq = (int) substr($last->to_serial_number, -6);
$startSeq = str_pad(($lastSeq + 1), 6, '0', STR_PAD_LEFT);
$endSeq = str_pad(($lastSeq + $qnty), 6, '0', STR_PAD_LEFT);
} else {
$startSeq = '000001';
$endSeq = str_pad($qnty, 6, '0', STR_PAD_LEFT);
}
// $endSeq = $startSeq + $qnty - 1;
$fromSerial = $prefixSerial.$startSeq; // str_pad($startSeq, 6, '0', STR_PAD_LEFT)
$toSerial = $prefixSerial.$endSeq; // str_pad($endSeq, 6, '0', STR_PAD_LEFT)
ProductionOrder::create([
'plant_id' => $plantId ?? null,
'item_id' => $itemId ?? null,
'quantity' => $qnty ?? null,
'start_date' => $cDateTime->format('Y-m-d H:i:s'),
'end_date' => $uDateTime->format('Y-m-d H:i:s'),
'production_order' => $prodOrd ?? null,
'from_serial_number' => $fromSerial ?? null,
'to_serial_number' => $toSerial ?? null,
'created_by' => $createdBy ?? null,
'updated_by' => $updatedBy ?? null,
]);
} else {
if (! empty($warnMsg)) {
throw new RowImportFailedException(implode(', ', $warnMsg));
}
}
// return ProductionOrder::firstOrNew([
// // Update existing records, matching them by `$this->data['column_name']`
// 'email' => $this->data['email'],
// ]);
return null;
// return new ProductionOrder;
}
public static function getCompletedNotificationBody(Import $import): string
{
$body = 'Your production order 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;
}
}