invoiceModel->update($invoiceId, ['status' => 'submitting']); // 2. Fetch Invoice $db = \App\Core\Database::getInstance(); $stmt = $db->prepare("SELECT * FROM invoices WHERE id = ? LIMIT 1"); $stmt->execute([$invoiceId]); $invoice = $stmt->fetch(); if (!$invoice) { throw new \Exception("Invoice not found."); } // 3. Fetch Company Credentials $credentials = $this->companyService->getJoFotaraCredentials($invoice['company_id']); if (empty($credentials['clientId']) || empty($credentials['secretKey'])) { throw new \Exception("Company is not linked to JoFotara."); } // 4. Fetch Invoice Lines $stmt = $db->prepare("SELECT * FROM invoice_lines WHERE invoice_id = ?"); $stmt->execute([$invoiceId]); $lines = $stmt->fetchAll(); // 5. Generate UBL XML $xmlString = $this->ublGenerator->generate($invoice, $lines); $xmlBase64 = base64_encode($xmlString); // 6. Submit to JoFotara $response = $this->jofotaraGateway->submitInvoice($invoice['company_id'], $xmlBase64, $credentials); // 7. Process Response // Assuming response contains a success boolean and possibly qr_code if (isset($response['success']) && $response['success']) { $this->invoiceModel->update($invoiceId, [ 'status' => 'approved', 'qr_code' => $response['qr_code'] ?? null, 'jofotara_response' => json_encode($response, JSON_UNESCAPED_UNICODE) ]); } else { $this->invoiceModel->update($invoiceId, [ 'status' => 'rejected', 'jofotara_response' => json_encode($response, JSON_UNESCAPED_UNICODE) ]); } } catch (Throwable $e) { $this->invoiceModel->update($invoiceId, [ 'status' => 'validation_failed', 'validation_errors' => json_encode([['message_ar' => 'فشل الإرسال: ' . $e->getMessage()]], JSON_UNESCAPED_UNICODE) ]); throw $e; } } }