Added process sftp file in commands
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 15s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 19s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Laravel Pint / pint (pull_request) Failing after 37s
Laravel Larastan / larastan (pull_request) Failing after 2m44s
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 15s
Gemini PR Review / Gemini PR Review (pull_request) Failing after 19s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 12s
Laravel Pint / pint (pull_request) Failing after 37s
Laravel Larastan / larastan (pull_request) Failing after 2m44s
This commit is contained in:
261
app/Console/Commands/ProcessSftpFiles.php
Normal file
261
app/Console/Commands/ProcessSftpFiles.php
Normal file
@@ -0,0 +1,261 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Machine;
|
||||
use App\Models\Plant;
|
||||
use App\Models\ProductionTemp;
|
||||
use Illuminate\Console\Command;
|
||||
use App\Services\SftpFileService;
|
||||
use Filament\Facades\Filament;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class ProcessSftpFiles extends Command
|
||||
{
|
||||
protected $signature = 'sftp:process-files';
|
||||
protected $description = 'Read SFTP files, insert into DB, and move to processed folder';
|
||||
|
||||
protected $sftpService;
|
||||
|
||||
public function __construct(SftpFileService $sftpService)
|
||||
{
|
||||
parent::__construct(); // calls parent class constructor
|
||||
$this->sftpService = $sftpService;
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$files = Storage::disk('ftp')->allFiles();
|
||||
|
||||
$folders = Storage::disk('ftp')->directories();
|
||||
|
||||
$allFiles = [];
|
||||
|
||||
foreach ($folders as $folder) {
|
||||
|
||||
$this->info("Checking folder: $folder");
|
||||
|
||||
try {
|
||||
|
||||
// Get files inside the current folder
|
||||
$files = Storage::disk('ftp')->files($folder);
|
||||
|
||||
foreach ($files as $file) {
|
||||
$this->info("File: " . $file);
|
||||
$allFiles[] = $file;
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
|
||||
$this->error("Cannot access folder: " . $folder);
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($allFiles)) {
|
||||
$this->info('No files to process.');
|
||||
return;
|
||||
}
|
||||
|
||||
$logMessages = [];
|
||||
|
||||
foreach ($allFiles as $file)
|
||||
{
|
||||
$this->info("Processing file: $file");
|
||||
|
||||
$folderName = explode('/', $file)[0];
|
||||
|
||||
$plant = Plant::where('code', $folderName)->first();
|
||||
|
||||
if (!$plant) {
|
||||
$this->warn("No plant found for folder: $folderName. Skipping file.");
|
||||
$logMessages[] = $folderName;
|
||||
continue;
|
||||
}
|
||||
|
||||
$plantId = $plant->id;
|
||||
|
||||
$plantCode = $plant->code ?? null;
|
||||
|
||||
$fileName = basename($file); // GMGLAS03-1818199-1.txt
|
||||
$workCenterCode = explode('-', $fileName)[0]; // GMGLAS03
|
||||
|
||||
$machine = Machine::where('work_center', $workCenterCode)->first();
|
||||
if (!$machine) {
|
||||
$message = "Machine '$workCenterCode' not found and file name '$file'";
|
||||
$logMessages[] = $message;
|
||||
continue;
|
||||
}
|
||||
|
||||
$machineAgaPlant = Machine::where('plant_id', $plantId)->where('work_center', $workCenterCode)->first();
|
||||
if (!$machineAgaPlant) {
|
||||
$message = "Machine '$workCenterCode' not found for plant code '$plantCode' and file name '$file'";
|
||||
$logMessages[] = $message;
|
||||
continue;
|
||||
}
|
||||
|
||||
$machineId = $machineAgaPlant->id;
|
||||
|
||||
$content = $this->sftpService->getFileContent($file);
|
||||
|
||||
$lines = array_filter(preg_split("/\r\n|\n|\r/", $content));
|
||||
|
||||
$headers = array_map(fn($header) => strtolower(trim($header)), str_getcsv(array_shift($lines)));
|
||||
|
||||
$dbColumns = Schema::getColumnListing('production_temps');
|
||||
|
||||
$missingColumns = array_diff($headers, $dbColumns);
|
||||
|
||||
if (!empty($missingColumns)) {
|
||||
|
||||
$message = "Skipping file: $file. The following columns do not exist in the database. Please add them to the database: " . implode(', ', $missingColumns);
|
||||
|
||||
$logMessages[] = $message;
|
||||
|
||||
$this->warn($message);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$expectedColumns = count($headers);
|
||||
$isValidFile = true;
|
||||
$isserialNotEmptyFile = true;
|
||||
|
||||
foreach ($lines as $lineNumber => $line) {
|
||||
$data = str_getcsv($line);
|
||||
|
||||
if (!empty($data[0])) {
|
||||
if (count($data) != $expectedColumns) {
|
||||
$message = "Column mismatch in file: $file at line " . ($lineNumber + 2) .
|
||||
". Expected $expectedColumns, got " . count($data);
|
||||
|
||||
$logMessages[] = $message;
|
||||
|
||||
$isValidFile = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$isValidFile) {
|
||||
$message = "Skipping entire file due to invalid column mismatch: $file";
|
||||
$logMessages[] = $message;
|
||||
continue;
|
||||
}
|
||||
else if (!$isserialNotEmptyFile) {
|
||||
$message = "serial number not found in file name $file";
|
||||
$logMessages[] = $message;
|
||||
continue;
|
||||
}
|
||||
|
||||
$rows = [];
|
||||
|
||||
// foreach ($lines as $line) {
|
||||
// $data = str_getcsv($line);
|
||||
|
||||
// if (!empty($data[0])) {
|
||||
// $row = [];
|
||||
// foreach ($headers as $index => $column) {
|
||||
// $row[$column] = isset($data[$index]) ? trim($data[$index]) : null;
|
||||
// }
|
||||
|
||||
// $row['plant_id'] = $plantId;
|
||||
// $row['machine_id'] = $machineId;
|
||||
// $row['created_at'] = now();
|
||||
// $row['updated_at'] = now();
|
||||
|
||||
// // $rows[] = $row;
|
||||
// if (!empty($row['gernr'])) {
|
||||
// $rows[] = $row;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
foreach ($lines as $line) {
|
||||
|
||||
$data = str_getcsv($line);
|
||||
|
||||
if (!empty($data[0])) {
|
||||
|
||||
$row = [];
|
||||
|
||||
foreach ($headers as $index => $column) {
|
||||
$row[$column] = isset($data[$index])
|
||||
? trim($data[$index])
|
||||
: null;
|
||||
}
|
||||
|
||||
$row['plant_id'] = $plantId;
|
||||
$row['machine_id'] = $machineId;
|
||||
$row['created_at'] = now();
|
||||
$row['updated_at'] = now();
|
||||
|
||||
if (empty($row['gernr'])) {
|
||||
$message = "serial number not found in file name $file";
|
||||
$logMessages[] = $message;
|
||||
continue;
|
||||
}
|
||||
|
||||
$gamng = (float) ($row['gamng'] ?? 0);
|
||||
$lmnga = (float) ($row['lmnga'] ?? 0);
|
||||
|
||||
$existingRecords = ProductionTemp::where('plant_id', $plantId)
|
||||
->where('aufnr', ($row['aufnr']))
|
||||
->get();
|
||||
|
||||
|
||||
$existingRecord = $existingRecords->where('gernr', $row['gernr'])->first();
|
||||
|
||||
$lastStatus = $existingRecords->max('pending_released_status');
|
||||
|
||||
if ($gamng == $lmnga) {
|
||||
|
||||
$row['pending_released_status'] = 0;
|
||||
|
||||
$this->info("Production order {$row['aufnr']} completed. " ."Serial: {$row['gernr']}. " ."GAMNG: {$row['gamng']}, LMNGA: {$row['lmnga']}. " ."pending_released_status = 0" );
|
||||
|
||||
} elseif ($existingRecord) {
|
||||
|
||||
$row['pending_released_status'] = (int) $existingRecord->pending_released_status;
|
||||
|
||||
$this->info("Same serial already exists. " ."Production order: {$row['aufnr']}. " ."Serial: {$row['gernr']}. " ."Keeping pending_released_status = {$row['pending_released_status']}");
|
||||
|
||||
} else {
|
||||
|
||||
if ($existingRecords->isEmpty()) {
|
||||
|
||||
// First release
|
||||
$row['pending_released_status'] = 0;
|
||||
|
||||
} else {
|
||||
$row['pending_released_status'] = ((int) $lastStatus) + 1;
|
||||
}
|
||||
$this->info("Production order {$row['aufnr']} pending. " ."New serial: {$row['gernr']}. " . "GAMNG: {$row['gamng']}, LMNGA: {$row['lmnga']}. " ."pending_released_status = {$row['pending_released_status']}");
|
||||
}
|
||||
|
||||
$rows[] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($rows)) {
|
||||
ProductionTemp::upsert($rows, ['plant_id', 'gernr'], array_keys($rows[0])); //(update + insert)
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($logMessages)) {
|
||||
|
||||
$content = implode(PHP_EOL, $logMessages);
|
||||
|
||||
Mail::raw('Please find attached machine error logs.', function ($message) use ($content) {
|
||||
$message->to(env('ERROR_LOG_MAIL'))
|
||||
->subject('Machine Error Logs')
|
||||
->attachData($content, 'machine_errors.txt', [
|
||||
'mime' => 'text/plain',
|
||||
]);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user