Files
musadaq-saas/queue/Jobs/SubmitJoFotaraJob.php

82 lines
3.0 KiB
PHP

<?php
declare(strict_types=1);
namespace Queue\Jobs;
use App\Modules\Invoices\InvoiceModel;
use App\Modules\Companies\CompanyService;
use App\Services\JoFotara\JoFotaraGateway;
use App\Services\JoFotara\UBLGeneratorService;
use Throwable;
final class SubmitJoFotaraJob
{
public function __construct(
private readonly InvoiceModel $invoiceModel,
private readonly CompanyService $companyService,
private readonly UBLGeneratorService $ublGenerator,
private readonly JoFotaraGateway $jofotaraGateway
) {}
public function handle(array $payload): void
{
$invoiceId = $payload['invoice_id'];
try {
// 1. Update status to submitting
$this->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;
}
}
}