From 359cfea905b9b3846bc30f7646190ad1258c0b74 Mon Sep 17 00:00:00 2001 From: Daeng Deni Mardaeni Date: Tue, 20 May 2025 22:06:25 +0700 Subject: [PATCH] feat(webstatement): tambahkan proses data company Menambahkan fungsi baru dan job baru untuk memproses data perusahaan (Company Data) dari file CSV. Detail perubahan: - Menambahkan import `ProcessCompanyDataJob` pada `MigrasiController`. - Menambahkan fungsi `ProcessCompanyData` di `MigrasiController` untuk memanggil job pemrosesan data perusahaan. - Mengintegrasikan pemrosesan data perusahaan ke dalam alur fungsi `processData()` di `MigrasiController`. - Membuat job baru `ProcessCompanyDataJob` untuk membaca dan memproses file `ST.COMPANY.csv`. - Job memproses file dari SFTP `sftpStatement` berdasarkan folder `periods`. - Ditambahkan validasi file, mapping data CSV ke model `Branch`, dan menyimpan atau memperbarui data ke database. - Penanganan error untuk pencatatan log pada kasus file tidak ditemukan, kesalahan kolom, atau error saat menyimpan data. - Melakukan perubahan nama file default untuk job `ProcessFtTxnTypeConditionJob` dari `TXN_TYPE_CONDITION.csv` menjadi `ST.FT.TXN.TYPE.CONDITION.csv`. Signed-off-by: Daeng Deni Mardaeni --- app/Http/Controllers/MigrasiController.php | 13 ++ app/Jobs/ProcessCompanyDataJob.php | 154 +++++++++++++++++++++ app/Jobs/ProcessFtTxnTypeConditionJob.php | 2 +- 3 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 app/Jobs/ProcessCompanyDataJob.php diff --git a/app/Http/Controllers/MigrasiController.php b/app/Http/Controllers/MigrasiController.php index d5c35cf..18c089a 100644 --- a/app/Http/Controllers/MigrasiController.php +++ b/app/Http/Controllers/MigrasiController.php @@ -9,6 +9,7 @@ use Log; use Modules\Webstatement\Jobs\ProcessAccountDataJob; use Modules\Webstatement\Jobs\ProcessArrangementDataJob; use Modules\Webstatement\Jobs\ProcessBillDetailDataJob; +use Modules\Webstatement\Jobs\ProcessCompanyDataJob; use Modules\Webstatement\Jobs\ProcessCustomerDataJob; use Modules\Webstatement\Jobs\ProcessFtTxnTypeConditionJob; use Modules\Webstatement\Jobs\ProcessFundsTransferDataJob; @@ -122,6 +123,16 @@ class MigrasiController extends Controller } + public function ProcessCompanyData($periods){ + try { + ProcessCompanyDataJob::dispatch($periods); + return response()->json(['message' => 'Data TempStmtEntry processing job has been successfully']); + } catch (Exception $e) { + return response()->json(['error' => $e->getMessage()], 500); + } + } + + public function index() { $disk = Storage::disk('sftpStatement'); @@ -156,6 +167,8 @@ class MigrasiController extends Controller $this->processFundsTransferData($periods); $this->processStmtEntryData($periods); + $this->ProcessCompanyData($periods); + return response()->json(['message' => 'Data processing job has been successfully']); } } diff --git a/app/Jobs/ProcessCompanyDataJob.php b/app/Jobs/ProcessCompanyDataJob.php new file mode 100644 index 0000000..5963be8 --- /dev/null +++ b/app/Jobs/ProcessCompanyDataJob.php @@ -0,0 +1,154 @@ +periods = $periods; + $this->filename = $filename; + } + + /** + * Execute the job. + */ + public function handle(): void + { + try { + set_time_limit(24 * 60 * 60); + $disk = Storage::disk('sftpStatement'); + $processedCount = 0; + $errorCount = 0; + + if (empty($this->periods)) { + Log::warning('No periods provided for company data processing'); + return; + } + + foreach ($this->periods as $period) { + // Skip the _parameter folder + if ($period === '_parameter') { + Log::info("Skipping _parameter folder"); + continue; + } + + // Construct the filepath based on the period folder name + $fileName = "$period.$this->filename"; + $filePath = "$period/$fileName"; + + Log::info("Processing company file: $filePath"); + + if (!$disk->exists($filePath)) { + Log::warning("File not found: $filePath"); + continue; + } + + // Create a temporary local copy of the file + $tempFilePath = storage_path("app/temp_{$this->filename}"); + file_put_contents($tempFilePath, $disk->get($filePath)); + + $handle = fopen($tempFilePath, "r"); + + if ($handle !== false) { + // CSV headers from the file + $csvHeaders = [ + 'id', 'date_time', 'company_code', 'company_name', 'name_address', + 'mnemonic', 'customer_company', 'customer_mnemonic', 'company_group', + 'curr_no', 'co_code', 'l_vendor_atm', 'l_vendor_cpc' + ]; + + // Field mapping from CSV to Branch model + $fieldMapping = [ + 'company_code' => 'code', + 'company_name' => 'name', + 'name_address' => 'address', + 'mnemonic' => 'mnemonic', + 'customer_company' => 'customer_company', + 'customer_mnemonic' => 'customer_mnemonic', + 'company_group' => 'company_group', + 'curr_no' => 'curr_no', + 'co_code' => 'co_code', + 'l_vendor_atm' => 'l_vendor_atm', + 'l_vendor_cpc' => 'l_vendor_cpc' + ]; + + $rowCount = 0; + + while (($row = fgetcsv($handle, 0, "~")) !== false) { + $rowCount++; + + // Skip header row if it exists + if ($rowCount === 1 && (strtolower($row[0]) === 'id' || strtolower($row[2]) === 'company_code')) { + continue; + } + + if (count($csvHeaders) === count($row)) { + $csvData = array_combine($csvHeaders, $row); + + // Map CSV data to Branch model fields + $branchData = []; + foreach ($fieldMapping as $csvField => $modelField) { + if (isset($csvData[$csvField])) { + // Convert string boolean values to actual booleans for boolean fields + if (in_array($modelField, ['l_vendor_atm', 'l_vendor_cpc'])) { + $branchData[$modelField] = filter_var($csvData[$csvField], FILTER_VALIDATE_BOOLEAN); + } else { + $branchData[$modelField] = $csvData[$csvField]; + } + } + } + + try { + if (!empty($branchData['code'])) { + Branch::updateOrCreate( + ['code' => $branchData['code']], + $branchData + ); + $processedCount++; + } + } catch (Exception $e) { + $errorCount++; + Log::error("Error processing Company data at row $rowCount in $filePath: " . $e->getMessage()); + } + } else { + Log::warning("Row $rowCount in $filePath has incorrect column count. Expected: " . count($csvHeaders) . ", Got: " . count($row)); + } + } + + fclose($handle); + Log::info("Completed processing $filePath. Processed $processedCount records with $errorCount errors."); + + // Clean up the temporary file + unlink($tempFilePath); + } else { + Log::error("Unable to open file: $filePath"); + } + } + + Log::info("Company data processing completed. Total processed: $processedCount, Total errors: $errorCount"); + + } catch (Exception $e) { + Log::error('Error in ProcessCompanyDataJob: ' . $e->getMessage()); + throw $e; + } + } +} diff --git a/app/Jobs/ProcessFtTxnTypeConditionJob.php b/app/Jobs/ProcessFtTxnTypeConditionJob.php index cfaac0d..5988047 100644 --- a/app/Jobs/ProcessFtTxnTypeConditionJob.php +++ b/app/Jobs/ProcessFtTxnTypeConditionJob.php @@ -22,7 +22,7 @@ class ProcessFtTxnTypeConditionJob implements ShouldQueue /** * Create a new job instance. */ - public function __construct(array $periods = [], string $filename = "TXN_TYPE_CONDITION.csv") + public function __construct(array $periods = [], string $filename = "ST.FT.TXN.TYPE.CONDITION.csv") { $this->periods = $periods; $this->filename = $filename;