url = $urlOrPath; $this->isUrl = $isUrl; $this->filePath = $urlOrPath; } public function handle() { try { if ($this->isUrl) { $this->processZipFromUrl(); } else { $this->processSingleFile($this->filePath); } } catch (\Exception $e) { Log::error('Error in ImportRiksdagDataJob: '.$e->getMessage()); throw $e; } } protected function processZipFromUrl() { Log::info('Starting download from: '.$this->url); // Download the ZIP file $response = Http::timeout(300)->get($this->url); if (! $response->successful()) { throw new \Exception('Failed to download ZIP file from: '.$this->url); } // Create temporary directory $tempDir = storage_path('app/temp/riksdag_import_'.time()); $zipPath = $tempDir.'/download.zip'; if (! is_dir($tempDir)) { mkdir($tempDir, 0755, true); } // Save ZIP file file_put_contents($zipPath, $response->body()); Log::info('ZIP file downloaded to: '.$zipPath); // Extract ZIP file $extractPath = $tempDir.'/extracted'; $this->extractZipFile($zipPath, $extractPath); // Process all JSON files in extracted directory $this->processJsonFiles($extractPath); // Clean up temporary files $this->cleanupTempDirectory($tempDir); Log::info('ZIP processing completed successfully'); } protected function extractZipFile($zipPath, $extractPath) { $zip = new ZipArchive; $result = $zip->open($zipPath); if ($result !== true) { throw new \Exception('Failed to open ZIP file: '.$zipPath.' (Error code: '.$result.')'); } if (! is_dir($extractPath)) { mkdir($extractPath, 0755, true); } $zip->extractTo($extractPath); $zip->close(); Log::info('ZIP file extracted to: '.$extractPath); } protected function processJsonFiles($directory) { $jsonFiles = glob($directory.'/*.json'); if (empty($jsonFiles)) { // Check subdirectories $subdirs = glob($directory.'/*', GLOB_ONLYDIR); foreach ($subdirs as $subdir) { $jsonFiles = array_merge($jsonFiles, glob($subdir.'/*.json')); } } Log::info('Found '.count($jsonFiles).' JSON files to process'); foreach ($jsonFiles as $jsonFile) { Log::info('Processing file: '.basename($jsonFile)); $this->processSingleFile($jsonFile); } } protected function cleanupTempDirectory($tempDir) { $this->deleteDirectory($tempDir); Log::info('Temporary directory cleaned up: '.$tempDir); } protected function deleteDirectory($dir) { if (! is_dir($dir)) { return; } $files = array_diff(scandir($dir), ['.', '..']); foreach ($files as $file) { $path = $dir.'/'.$file; is_dir($path) ? $this->deleteDirectory($path) : unlink($path); } rmdir($dir); } protected function processSingleFile($filePath) { try { $jsonContent = file_get_contents($filePath); $data = json_decode($jsonContent, true); if (json_last_error() !== JSON_ERROR_NONE) { throw new \Exception('Invalid JSON format: '.json_last_error_msg()); } DB::beginTransaction(); // Handle new JSON structure with dokumentstatus wrapper if (isset($data['dokumentstatus'])) { $this->processDocumentStatus($data['dokumentstatus']); } // Legacy support for old structure elseif (isset($data['dokumentlista'])) { $this->importDokumentData($data['dokumentlista']); } elseif (isset($data['personlista'])) { $this->importPersonData($data['personlista']); } elseif (isset($data['organlista'])) { $this->importOrganData($data['organlista']); } // Handle single document structure elseif (isset($data['dokument'])) { $this->importSingleDokument($data['dokument']); } DB::commit(); Log::info('Successfully imported data from: '.$filePath); } catch (\Exception $e) { DB::rollBack(); Log::error("Error importing data from {$filePath}: ".$e->getMessage()); throw $e; } } protected function processDocumentStatus($dokumentStatus) { // Process the main document if (isset($dokumentStatus['dokument'])) { $this->processDokument($dokumentStatus['dokument']); } // Get hangar_id for related data processing $hangarId = $dokumentStatus['dokument']['hangar_id'] ?? null; if (! $hangarId) { throw new \Exception('No hangar_id found in document data'); } // Process document proposals (forslag) if (isset($dokumentStatus['dokforslag']['forslag']) && is_array($dokumentStatus['dokforslag']['forslag'])) { $this->processForslag($hangarId, $dokumentStatus['dokforslag']['forslag']); } // Process document activities (aktivitet) if (isset($dokumentStatus['dokaktivitet']['aktivitet']) && is_array($dokumentStatus['dokaktivitet']['aktivitet'])) { $this->processAktiviteter($hangarId, $dokumentStatus['dokaktivitet']['aktivitet']); } // Process document interested parties (intressent) if (isset($dokumentStatus['dokintressent']['intressent']) && is_array($dokumentStatus['dokintressent']['intressent'])) { $this->processIntressenter($hangarId, $dokumentStatus['dokintressent']['intressent']); } // Process document information (uppgift) if (isset($dokumentStatus['dokuppgift']['uppgift']) && is_array($dokumentStatus['dokuppgift']['uppgift'])) { $this->processUppgifter($hangarId, $dokumentStatus['dokuppgift']['uppgift']); } // Process document attachments (bilaga) if (isset($dokumentStatus['dokbilaga']['bilaga']) && is_array($dokumentStatus['dokbilaga']['bilaga'])) { $this->processBilagor($hangarId, $dokumentStatus['dokbilaga']['bilaga']); } // Process document references (referens) if (isset($dokumentStatus['dokreferens']['referens']) && is_array($dokumentStatus['dokreferens']['referens'])) { $this->processReferenser($hangarId, $dokumentStatus['dokreferens']['referens']); } } protected function importDokumentData($dokumentData) { $documents = isset($dokumentData['dokument']) ? $dokumentData['dokument'] : []; // Handle both single document and array of documents if (! is_array($documents) || (isset($documents['hangar_id']) && ! is_numeric(array_keys($documents)[0]))) { $documents = [$documents]; } foreach ($documents as $dokData) { $this->processDokument($dokData); } } protected function processDokument($dokData) { // Create main document $dokument = Dokument::updateOrCreate( ['dok_id' => $dokData['dok_id'] ?? null], [ 'hangar_id' => $dokData['hangar_id'] ?? null, 'rm' => $dokData['rm'] ?? null, 'beteckning' => $dokData['beteckning'] ?? null, 'typ' => $dokData['typ'] ?? null, 'subtyp' => $dokData['subtyp'] ?? null, 'doktyp' => $dokData['doktyp'] ?? null, 'typrubrik' => $dokData['typrubrik'] ?? null, 'dokumentnamn' => $dokData['dokumentnamn'] ?? null, 'debattnamn' => $dokData['debattnamn'] ?? null, 'tempbeteckning' => $dokData['tempbeteckning'] ?? null, 'organ' => $dokData['organ'] ?? null, 'mottagare' => $dokData['mottagare'] ?? null, 'nummer' => $dokData['nummer'] ?? null, 'slutnummer' => $dokData['slutnummer'] ?? null, 'datum' => isset($dokData['datum']) ? $this->parseDate($dokData['datum']) : null, 'systemdatum' => isset($dokData['systemdatum']) ? $this->parseDate($dokData['systemdatum']) : null, 'publicerad' => isset($dokData['publicerad']) ? $this->parseDate($dokData['publicerad']) : null, 'titel' => $dokData['titel'] ?? null, 'subtitel' => $dokData['subtitel'] ?? null, 'status' => $dokData['status'] ?? null, 'htmlformat' => $dokData['htmlformat'] ?? null, 'relaterat_id' => $dokData['relaterat_id'] ?? null, 'source' => $dokData['source'] ?? null, 'sourceid' => $dokData['sourceid'] ?? null, 'dokument_url_text' => $dokData['dokument_url_text'] ?? null, 'dokument_url_html' => $dokData['dokument_url_html'] ?? null, 'dokumentstatus_url_xml' => $dokData['dokumentstatus_url_xml'] ?? null, 'utskottsforslag_url_xml' => $dokData['utskottsforslag_url_xml'] ?? null, ] ); // Process related data if (isset($dokData['aktivitet']) && is_array($dokData['aktivitet'])) { $this->processAktiviteter($dokument->hangar_id, $dokData['aktivitet']); } if (isset($dokData['intressent']) && is_array($dokData['intressent'])) { $this->processIntressenter($dokument->hangar_id, $dokData['intressent']); } if (isset($dokData['bilaga']) && is_array($dokData['bilaga'])) { $this->processBilagor($dokument->hangar_id, $dokData['bilaga']); } if (isset($dokData['forslag']) && is_array($dokData['forslag'])) { $this->processForslag($dokument->hangar_id, $dokData['forslag']); } if (isset($dokData['uppgift']) && is_array($dokData['uppgift'])) { $this->processUppgifter($dokument->hangar_id, $dokData['uppgift']); } if (isset($dokData['referens']) && is_array($dokData['referens'])) { $this->processReferenser($dokument->hangar_id, $dokData['referens']); } } protected function processAktiviteter($hangarId, $aktiviteter) { foreach ($aktiviteter as $aktivitet) { DokAktivitet::updateOrCreate( [ 'hangar_id' => $hangarId, 'kod' => $aktivitet['kod'] ?? null, 'datum' => isset($aktivitet['datum']) ? $this->parseDate($aktivitet['datum']) : null, ], [ 'namn' => $aktivitet['namn'] ?? null, 'status' => $aktivitet['status'] ?? null, 'ordning' => $aktivitet['ordning'] ?? null, 'process' => $aktivitet['process'] ?? null, ] ); } } protected function processIntressenter($hangarId, $intressenter) { foreach ($intressenter as $intressent) { dump($intressent); DokIntressent::updateOrCreate( [ 'hangar_id' => $hangarId, 'intressent_id' => $intressent['intressent_id'] ?? null, ], [ 'namn' => $intressent['namn'] ?? null, 'partibet' => $intressent['partibet'] ?? null, 'ordning' => $intressent['ordning'] ?? null, 'roll' => $intressent['roll'] ?? null, ] ); } } protected function processBilagor($hangarId, $bilagor) { foreach ($bilagor as $bilaga) { DokBilaga::updateOrCreate( [ 'hangar_id' => $hangarId, 'dok_id' => $bilaga['dok_id'] ?? null, 'filnamn' => $bilaga['filnamn'] ?? null, ], [ 'titel' => $bilaga['titel'] ?? null, 'subtitel' => $bilaga['subtitel'] ?? null, 'filstorlek' => $bilaga['filstorlek'] ?? null, 'filtyp' => $bilaga['filtyp'] ?? null, 'fil_url' => $bilaga['fil_url'] ?? null, ] ); } } protected function processForslag($hangarId, $forslag) { foreach ($forslag as $forslagItem) { DokForslag::updateOrCreate( [ 'hangar_id' => $hangarId, 'nummer' => $forslagItem['nummer'] ?? null, ], [ 'beteckning' => $forslagItem['beteckning'] ?? null, 'lydelse' => $forslagItem['lydelse'] ?? null, 'lydelse2' => $forslagItem['lydelse2'] ?? null, 'utskottet' => $forslagItem['utskottet'] ?? null, 'kammaren' => $forslagItem['kammaren'] ?? null, 'behandlas_i' => $forslagItem['behandlas_i'] ?? null, 'behandlas_i_punkt' => $forslagItem['behandlas_i_punkt'] ?? null, 'kammarbeslutstyp' => $forslagItem['kammarbeslutstyp'] ?? null, 'intressent' => $forslagItem['intressent'] ?? null, 'avsnitt' => $forslagItem['avsnitt'] ?? null, 'grundforfattning' => $forslagItem['grundforfattning'] ?? null, 'andringsforfattning' => $forslagItem['andringsforfattning'] ?? null, ] ); } } protected function processUppgifter($hangarId, $uppgifter) { foreach ($uppgifter as $uppgift) { DokUppgift::updateOrCreate( [ 'hangar_id' => $hangarId, 'kod' => $uppgift['kod'] ?? null, ], [ 'namn' => $uppgift['namn'] ?? null, 'text' => $uppgift['text'] ?? null, 'dok_id' => $uppgift['dok_id'] ?? null, 'systemdatum' => isset($uppgift['systemdatum']) ? $this->parseDate($uppgift['systemdatum']) : null, ] ); } } protected function processReferenser($hangarId, $referenser) { foreach ($referenser as $referens) { DokReferens::updateOrCreate( [ 'hangar_id' => $hangarId, 'referenstyp' => $referens['referenstyp'] ?? null, 'ref_dok_id' => $referens['ref_dok_id'] ?? null, ], [ 'uppgift' => $referens['uppgift'] ?? null, 'ref_dok_typ' => $referens['ref_dok_typ'] ?? null, 'ref_dok_rm' => $referens['ref_dok_rm'] ?? null, 'ref_dok_bet' => $referens['ref_dok_bet'] ?? null, 'ref_dok_titel' => $referens['ref_dok_titel'] ?? null, 'ref_dok_subtitel' => $referens['ref_dok_subtitel'] ?? null, 'ref_dok_subtyp' => $referens['ref_dok_subtyp'] ?? null, 'ref_dok_dokumentnamn' => $referens['ref_dok_dokumentnamn'] ?? null, ] ); } } protected function importPersonData($personData) { $persons = isset($personData['person']) ? $personData['person'] : []; // Handle both single person and array of persons if (! is_array($persons) || (isset($persons['intressent_id']) && ! is_numeric(array_keys($persons)[0]))) { $persons = [$persons]; } foreach ($persons as $personInfo) { $this->processPerson($personInfo); } } protected function processPerson($personInfo) { $person = Person::updateOrCreate( ['intressent_id' => $personInfo['intressent_id'] ?? null], [ 'född_år' => $personInfo['fodd_ar'] ?? $personInfo['född_år'] ?? null, 'kön' => $personInfo['kon'] ?? $personInfo['kön'] ?? null, 'efternamn' => $personInfo['efternamn'] ?? null, 'tilltalsnamn' => $personInfo['tilltalsnamn'] ?? null, 'sorteringsnamn' => $personInfo['sorteringsnamn'] ?? null, 'iort' => $personInfo['iort'] ?? null, 'parti' => $personInfo['parti'] ?? null, 'valkrets' => $personInfo['valkrets'] ?? null, 'status' => $personInfo['status'] ?? null, ] ); // Process person assignments if (isset($personInfo['personuppdrag']['uppdrag']) && is_array($personInfo['personuppdrag']['uppdrag'])) { $this->processPersonUppdrag($person->intressent_id, $personInfo['personuppdrag']['uppdrag']); } // Process person information if (isset($personInfo['personuppgift']['uppgift']) && is_array($personInfo['personuppgift']['uppgift'])) { $this->processPersonUppgift($person->intressent_id, $personInfo['personuppgift']['uppgift']); } } protected function processPersonUppdrag($intressentId, $uppdragList) { foreach ($uppdragList as $uppdrag) { PersonUppdrag::updateOrCreate( [ 'intressent_id' => $intressentId, 'organ_kod' => $uppdrag['organ_kod'] ?? null, 'roll_kod' => $uppdrag['roll_kod'] ?? null, 'ordningsnummer' => $uppdrag['ordningsnummer'] ?? null, ], [ 'status' => $uppdrag['status'] ?? null, 'typ' => $uppdrag['typ'] ?? null, 'from' => isset($uppdrag['from']) ? $this->parseDate($uppdrag['from']) : null, 'tom' => isset($uppdrag['tom']) ? $this->parseDate($uppdrag['tom']) : null, 'uppgift' => $uppdrag['uppgift'] ?? null, ] ); } } protected function processPersonUppgift($intressentId, $uppgiftList) { foreach ($uppgiftList as $uppgift) { PersonUppgift::updateOrCreate( [ 'intressent_id' => $intressentId, 'uppgift_kod' => $uppgift['kod'] ?? null, ], [ 'uppgift' => $uppgift['uppgift'] ?? null, 'uppgift_typ' => $uppgift['typ'] ?? null, ] ); } } protected function importOrganData($organData) { $organs = isset($organData['organ']) ? $organData['organ'] : []; // Handle both single organ and array of organs if (! is_array($organs) || (isset($organs['id']) && ! is_numeric(array_keys($organs)[0]))) { $organs = [$organs]; } foreach ($organs as $organInfo) { Organ::updateOrCreate( ['id' => $organInfo['id'] ?? null], [ 'kod' => $organInfo['kod'] ?? null, 'namn' => $organInfo['namn'] ?? null, 'typ' => $organInfo['typ'] ?? null, 'status' => $organInfo['status'] ?? null, 'sortering' => $organInfo['sortering'] ?? null, 'namn_en' => $organInfo['namn_en'] ?? null, 'domän' => $organInfo['doman'] ?? $organInfo['domän'] ?? null, 'beskrivning' => $organInfo['beskrivning'] ?? null, ] ); } } protected function importSingleDokument($dokument) { $this->processDokument($dokument); } protected function parseDate($dateString) { if (empty($dateString)) { return null; } try { return \Carbon\Carbon::parse($dateString); } catch (\Exception $e) { Log::warning("Could not parse date: {$dateString}"); return null; } } }