=== ZATCA OFFLINE XML GENERATION PATH AUDIT ===

==============================================================================================================
FILE=fatoora-zatca/src/Helpers/EgsSerialNumber.php
==============================================================================================================

------------------------------------------------------------------------------------------
METHOD=generate
------------------------------------------------------------------------------------------
    public static function generate(): string
    {
        $egs  = [];

        for($i = 1; $i <= 3; $i++) {

            $seed = str_split('ABCDEFGHIJKLMNOPQRSTUVWXYZ');

            shuffle($seed);

            $randKeys = array_rand($seed, 3);

            $chars = '';

            foreach($randKeys as $key) {

                $chars .= $seed[$key];

            }

            $egs[] = "{$i}-{$chars}";
        }

        return implode('|', $egs);
    }
==============================================================================================================
FILE=fatoora-zatca/src/Invoices/B2B.php
==============================================================================================================
MATCHED_CLASSES=class B2B

------------------------------------------------------------------------------------------
METHOD=report
------------------------------------------------------------------------------------------
    public function report(): self
    {
        $this->setResult(Zatca::reportStandardInvoice($this->seller, $this->invoice, $this->client));
        return $this;
    }
==============================================================================================================
FILE=fatoora-zatca/src/Invoices/B2C.php
==============================================================================================================
MATCHED_CLASSES=class B2C

------------------------------------------------------------------------------------------
METHOD=report
------------------------------------------------------------------------------------------
    public function report(): self
    {
        $this->setResult(Zatca::reportSimplifiedInvoice($this->seller, $this->invoice, $this->client));
        return $this;
    }
==============================================================================================================
FILE=fatoora-zatca/src/Invoices/Invoiceable.php
==============================================================================================================

------------------------------------------------------------------------------------------
METHOD=getInvoiceHash
------------------------------------------------------------------------------------------
    public function getInvoiceHash(): string
    {
        return $this->getResult()['invoiceHash'] ?? '';
    }
==============================================================================================================
FILE=fatoora-zatca/src/Services/Invoice/HashInvoiceService.php
==============================================================================================================
MATCHED_CLASSES=class HashInvoiceService

------------------------------------------------------------------------------------------
METHOD=generate
------------------------------------------------------------------------------------------
    public function generate(string $document_type): string
    {
        $this->documentType = $document_type;

        $this->invoiceXml = GetXmlFileAction::handle('xml_to_hash');

        $this->invoiceXml = str_replace("\r", "", $this->invoiceXml);

        $this->xmlGenerator();

        // Eliminate Additional Signed Tags
        $invoice = str_replace('SET_XML_ENCODING', '', $this->invoiceXml);

        $invoice = str_replace('SET_UBL_EXTENSIONS_FOR_SIGNED', "    ", $invoice);

        $invoice = str_replace('SET_QR_AND_SIGNATURE_FOR_SIGNED', "    \n    ", $invoice);

        $invoiceHash = hash('sha256', $invoice, true);

        return base64_encode($invoiceHash);
    }
==============================================================================================================
FILE=fatoora-zatca/src/Services/Invoice/SignInvoiceService.php
==============================================================================================================
MATCHED_CLASSES=class SignInvoiceService

------------------------------------------------------------------------------------------
METHOD=generate
------------------------------------------------------------------------------------------
    public function generate(): string
    {
        $this->setUp();

        $this->invoiceXml = str_replace('SET_XML_ENCODING', '<?xml version="1.0" encoding="UTF-8"?>', $this->invoiceXml);

        $this->invoiceXml = str_replace(
            'SET_UBL_EXTENSIONS_FOR_SIGNED',
            $this->getUBLExtensions(),
            $this->invoiceXml
        );

        $this->invoiceXml = str_replace(
            'SET_QR_AND_SIGNATURE_FOR_SIGNED',
            $this->getQRCodeData(),
            $this->invoiceXml
        );

        return base64_encode($this->invoiceXml);
    }
==============================================================================================================
FILE=fatoora-zatca/src/Services/Invoice/TLVProtocolService.php
==============================================================================================================

------------------------------------------------------------------------------------------
METHOD=generate
------------------------------------------------------------------------------------------
    protected function generate(): void
    {
        foreach($this->data as $key => $value) {

            $tag    = $key + 1;

            $length = strlen($value);

            $this->tlv .= $this->__toHex($tag) . $this->__toHex($length) . ($value);

        }
    }
==============================================================================================================
FILE=fatoora-zatca/src/Services/Invoice/XmlInvoiceItemsService.php
==============================================================================================================

------------------------------------------------------------------------------------------
METHOD=generate
------------------------------------------------------------------------------------------
    public function generate(string &$invoice_content): void
    {
        $invoice_content = str_replace('SET_TAX_TOTALS', $this->getTaxTotalXmlContent(), $invoice_content);

        // ? total tax of invoice itself.
        $invoice_content = str_replace(
            'TOTAL_TAX_AMOUNT',
            PriceFormat::transform($this->invoice->tax),
            $invoice_content
        );

        // <cac:LegalMonetaryTotal>
        $invoice_content = str_replace(
            'SET_LINE_EXTENSION_AMOUNT',
            PriceFormat::transform($this->invoice->price),
            $invoice_content
        );
        $invoice_content = str_replace(
            'SET_NET_TOTAL',
            PriceFormat::transform($this->invoice->total),
            $invoice_content
        );

        $invoice_content = str_replace(
            'SET_PREPAID_AMOUNT',
            PriceFormat::transform(
                $this->invoice->prepaid_amount ?? 0
            ),
            $invoice_content
        );

        $invoice_content = str_replace(
            'SET_PAYABLE_ROUNDING_AMOUNT',
            PriceFormat::transform(
                $this->invoice->payable_rounding_amount
                    ?? 0
            ),
            $invoice_content
        );

        $invoice_content = str_replace(
            'SET_PAYABLE_AMOUNT',
            PriceFormat::transform(
                $this->invoice->payable_amount
                    ?? $this->invoice->total
            ),
            $invoice_content
        );
        // $invoice_content = str_replace(
        //     'SET_ALLOWANCE_TOTAL_AMOUNT',
        //     0,
        //     $invoice_content
        // );

        // TODO : handle multiple taxes & discounts. (must edit invoice_items).
        $invoice_content = str_replace('SET_INVOICE_LINES', $this->getInvoiceLineXmlContent(), $invoice_content);
        // dd($this->getInvoiceLineXmlContent());
        // dd($invoice_content);
    }
==============================================================================================================
FILE=fatoora-zatca/src/Services/ReportInvoiceService.php
==============================================================================================================

------------------------------------------------------------------------------------------
METHOD=report
------------------------------------------------------------------------------------------
    public function report(string $route, string $document_type): array
    {
        $calculateInvoice = $this->calculate($document_type);

        $USERPWD = $this->seller->certificate . ':' . $this->seller->secret;

        $response = (new PostRequestAction)->handle($route,
        [
            'invoiceHash' => $calculateInvoice['invoiceHash'], # hashed invoice in base64 format
            'uuid' => $this->invoice->invoice_uuid,
            'invoice' => $calculateInvoice['clearedInvoice'], # signed invoice in base64 format
        ],
        [
            'Content-Type: application/json',
            'Accept-Language: en',
            'Accept-Version: V2',
            'Clearance-Status: 1'
        ],
            $USERPWD
        );

        return array_merge($response, $calculateInvoice);
    }

------------------------------------------------------------------------------------------
METHOD=clearance
------------------------------------------------------------------------------------------
    public function clearance(): array
    {
        $route = '/invoices/clearance/single';

        return $this->report($route, DocumentType::STANDARD);
    }
==============================================================================================================
FILE=fatoora-zatca/src/Services/SettingService.php
==============================================================================================================

------------------------------------------------------------------------------------------
METHOD=generate
------------------------------------------------------------------------------------------
    public function generate(): object
    {
        $this->setUp();

        $this->generateCnfFile();

        $this->generateKeys();

        $this->generateCert509();

        return $this->settings;
    }
==============================================================================================================
FILE=fatoora-zatca/src/Services/Settings/Cert509Service.php
==============================================================================================================

------------------------------------------------------------------------------------------
METHOD=generate
------------------------------------------------------------------------------------------
    public function generate(object &$settings): void
    {
        // (new VerifyAppKeyAction)->handle();

        $this->handleComplianceMode($settings);

        $privateKey     = $settings->private_key;
        $certificate    = $settings->cert_compliance;
        $secret         = $settings->secret_compliance;

        // Send the 6 test invoices for the production certificate...
        if(ConfigHelper::hasComplaintsCheck()) {
            if(InvoiceReportType::isStandard($this->seller->invoiceType)) {
                StandardCompliantService::verify($this->seller, $privateKey, $certificate, $secret);
                StandardCreditNoteCompliantService::verify($this->seller, $privateKey, $certificate, $secret);
                StandardDebitNoteCompliantService::verify($this->seller, $privateKey, $certificate, $secret);
            }

            if(InvoiceReportType::isSimplified($this->seller->invoiceType)) {
                SimplifiedCompliantService::verify($this->seller, $privateKey, $certificate, $secret);
                SimplifiedCreditNoteCompliantService::verify($this->seller, $privateKey, $certificate, $secret);
                SimplifiedDebitNoteCompliantService::verify($this->seller, $privateKey, $certificate, $secret);
            }
        }

        $this->handleProductionMode($settings);

    }
==============================================================================================================
FILE=fatoora-zatca/src/Services/Settings/CnfFileService.php
==============================================================================================================

------------------------------------------------------------------------------------------
METHOD=generate
------------------------------------------------------------------------------------------
    public function generate(): string
    {
        $this->setCertificateTemplateName();

        $this->setCnfFileData();

        return base64_encode($this->cnf);
    }
==============================================================================================================
FILE=fatoora-zatca/src/Services/Settings/KeysService.php
==============================================================================================================

------------------------------------------------------------------------------------------
METHOD=generate
------------------------------------------------------------------------------------------
    public function generate(): array
    {
        $this->setUpConig();

        $this->generateKeys();

        $this->generateCsr();

        $this->removeTmpFile();

        return [

            base64_encode($this->privateKey),

            base64_encode($this->publicKey),

            base64_encode($this->csr)

        ];
    }
==============================================================================================================
FILE=app/Services/Zatca/FatooraInvoiceService.php
==============================================================================================================

------------------------------------------------------------------------------------------
METHOD=makeSeller
------------------------------------------------------------------------------------------
    protected function makeSeller(ZatcaCredential $credential): Seller
    {
        $addr = $this->decodeAddress($credential->registered_address);
        $street = $addr['street_name'] ?? 'NA';
        $building = $addr['building_number'] ?? '0000';
        $plot = $addr['plot_identification'] ?? '0000';
        $district = $addr['city_subdivision_name'] ?? 'NA';
        $city = $addr['city'] ?? 'NA';
        $postal = $addr['postal_number'] ?? '00000';
        $country = $addr['country'] ?? 'SA';

        return new Seller(
            (string) ($credential->registration_number ?: '0000000000'),
            $street,
            $building,
            $plot,
            $district,
            $city,
            $postal,
            (string) $credential->tax_number,
            (string) $credential->organization_name,
            (string) $credential->private_key,
            (string) $credential->certificate,
            (string) $credential->secret,
            $country
        );
    }

------------------------------------------------------------------------------------------
METHOD=makeClient
------------------------------------------------------------------------------------------
    protected function makeClient($person): Client
    {
        $addr = $this->decodeAddress($person->national_address ?? null);
        $street = $addr['street_name'] ?? ($person->address ?: 'NA');
        $building = $addr['building_number'] ?? '0000';
        $plot = $addr['plot_identification'] ?? '0000';
        $district = $addr['city_subdivision_name'] ?? 'NA';
        $city = $addr['city'] ?? optional($person->region)->name ?? 'NA';
        $postal  = preg_replace('/\D/', '', (string) ($addr['postal_number'] ?? ''));
        $postal  = str_pad(substr($postal, 0, 5), 5, '0', STR_PAD_LEFT) ?: '00000';
        $country = $addr['country'] ?? 'SA';
        $digits             = preg_replace('/\D/', '', (string) $person->taxnumber);
        $registrationNumber = trim((string) ($person->registration_number ?? ''));

        return new Client(
            (string) $person->name,
            $digits,
            $postal,
            $street,
            $building,
            $plot,
            $district,
            $city,
            $country,
            $registrationNumber
        );
    }

------------------------------------------------------------------------------------------
METHOD=assessSubmissionResult
------------------------------------------------------------------------------------------
    protected function assessSubmissionResult($reporter): array
    {
        $reportingStatus = strtoupper(trim(
            (string) $reporter->getReportingStatus()
        ));

        $validationStatus = strtoupper(trim(
            (string) $reporter->getValidationResultStatus()
        ));

        $warnings = $this->normalizeReporterMessages(
            $reporter->getWarningMessages()
        );

        $errors = $this->normalizeReporterMessages(
            $reporter->getErrorMessages()
        );

        $validation = $this->normalizeReporterMessages(
            $reporter->getValidationResults()
        );

        $info = $this->normalizeReporterMessages(
            $reporter->getInfoMessages()
        );

        $qr = (string) $reporter->getQr();
        $xml = (string) $reporter->getXmlInvoice();
        $invoiceHash = (string) $reporter->getInvoiceHash();

        $accepted = in_array(
            $reportingStatus,
            ['CLEARED', 'REPORTED'],
            true
        );

        $artifactsComplete =
            $qr !== ''
            && $xml !== ''
            && $invoiceHash !== '';

        $strictPass =
            $accepted
            && $validationStatus === 'PASS'
            && count($warnings) === 0
            && count($errors) === 0
            && $artifactsComplete;

        if ($strictPass) {
            $classification = 'STRICT_PASS';
            $message =
                'تم قبول المستند واجتاز التحقق دون تحذيرات أو أخطاء.';
        } elseif ($accepted) {
            $classification = 'ACCEPTED_WITH_WARNING';
            $message =
                'قُبل المستند لدى ZATCA، لكنه لم يحقق التحقق الصارم. '
                . 'تم حفظ XML وHash وتحديث PIH، وأُوقف الطابور للمراجعة.';
        } else {
            $classification = 'REJECTED';
            $message =
                'لم تقبل ZATCA المستند. لم يتم تحديث submitted_at أو PIH.';
        }

        return [
            'accepted' => $accepted,
            'strict_pass' => $strictPass,
            'classification' => $classification,
            'reporting_status' => $reportingStatus,
            'validation_status' => $validationStatus,
            'warnings' => $warnings,
            'errors' => $errors,
            'validation' => $validation,
            'info' => $info,
            'qr' => $qr,
            'xml' => $xml,
            'invoice_hash' => $invoiceHash,
            'artifacts_complete' => $artifactsComplete,
            'message' => $message,
        ];
    }

=== NETWORK CALL SEARCH ===

FILE=fatoora-zatca/src/Actions/PostRequestAction.php
23: $ch     = curl_init($portal . $route);
25: curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
28: curl_setopt($ch, CURLOPT_USERPWD,  $USERPWD);
32: curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
34: curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
36: curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
39: $response = curl_exec($ch);
41: $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
42: $curlError = curl_error($ch);
43: $curlErrno = curl_errno($ch);
44: $curlInfo = curl_getinfo($ch);
52: 'curl_errno' => $curlErrno,
53: 'curl_error' => $curlError,
63: curl_close($ch);

FILE=fatoora-zatca/src/Invoices/Invoiceable.php
40: // B2C reporting endpoint returns 'reportingStatus'; B2B clearance endpoint returns 'clearanceStatus'
41: return $result['reportingStatus'] ?? $result['clearanceStatus'] ?? 'UNKNOWN';

FILE=fatoora-zatca/src/Services/Compliants/StandardCompliantService.php
28: $client  = new \Bl\FatooraZatca\Objects\Client(

FILE=fatoora-zatca/src/Services/Compliants/StandardCreditNoteCompliantService.php
28: $client  = new \Bl\FatooraZatca\Objects\Client(

FILE=fatoora-zatca/src/Services/Compliants/StandardDebitNoteCompliantService.php
28: $client  = new \Bl\FatooraZatca\Objects\Client(

FILE=fatoora-zatca/src/Services/ReportInvoiceService.php
56: public function reporting(): array
58: $route = '/invoices/reporting/single';
64: * clearance the invoice from zatca portal.
68: public function clearance(): array
70: $route = '/invoices/clearance/single';
76: * test reporting the invoice from zatca portal.

FILE=fatoora-zatca/src/Services/SettingService.php
59: * setUp settings data of tax payer for reporting|clearance invoices.

FILE=fatoora-zatca/src/Zatca.php
50: return (new ReportInvoiceService($seller, $invoice, $client))->clearance();
76: return (new ReportInvoiceService($seller, $invoice, $client))->reporting();

FILE=app/Services/Zatca/FatooraInvoiceService.php
125: $useB2b = $this->isB2BClient($clientPerson);
128: $fatooraClient = $this->makeClient($clientPerson);
137: $reportingStatus = $assessment['reporting_status'];
141: $order->zatca_reporting_status = $reportingStatus;
193: 'reporting_status' => $reportingStatus,
205: * @return array{success:bool,message?:string,reporting_status?:string,validation_status?:string}
325: $useB2b = $this->isB2BClient($clientPerson);
328: $fatooraClient = $this->makeClient($clientPerson);
337: $reportingStatus = $assessment['reporting_status'];
341: $return->zatca_reporting_status = $reportingStatus;
388: 'reporting_status' => $reportingStatus,
415: $reportingStatus = strtoupper(trim(
444: $reportingStatus,
480: 'reporting_status' => $reportingStatus,
818: protected function isB2BClient($person): bool
872: protected function makeClient($person): Client
886: return new Client(

FILE=app/Services/Zatca/ZatcaDocumentLock.php
67: $document->zatca_reporting_status

FILE=app/Services/Zatca/ZatcaPdfA3Service.php
246: $status    = $e($order->zatca_reporting_status ?? '');

=== LOCAL VALIDATOR SEARCH ===
app/Http/Controllers/Auth/RegisterController.php
fatoora-zatca/src/Actions/GetQrFromInvoice.php
fatoora-zatca/src/Xml/xml_signed.xml
fatoora-zatca/src/Xml/xml_to_hash.xml
fatoora-zatca/src/Xml/xml_to_hash_OLD.xml
fatoora-zatca/src/Xml/xml_ubl_extensions.xml
storage/app/returns_currency_backup_20260612_181748.json
storage/app/zatca/simplified/invoices/2026-07-20_342.xml
storage/app/zatca/standard/2026-07-20_340.xml
storage/app/zatca/standard/2026-07-20_341.xml
storage/app/zatca/standard/2026-07-20_343.xml
storage/app/zatca/standard/2026-07-20_CR-4.xml
storage/app/zatca/standard/2026-07-20_344.xml
storage/app/zatca/standard/2026-07-20_345.xml
storage/app/zatca/standard/2026-07-20_346.xml
storage/app/zatca/standard/2026-07-20_347.xml
storage/app/zatca/standard/2026-07-20_348.xml
storage/app/zatca/standard/2026-07-20_349.xml
storage/app/zatca/standard/2026-07-20_350.xml
storage/app/zatca/standard/2026-07-20_351.xml
storage/app/zatca/standard/2026-07-20_352.xml
storage/app/zatca/standard/2026-07-20_353.xml
storage/app/zatca/standard/2026-07-20_354.xml
storage/app/zatca/standard/2026-07-20_355.xml
storage/app/zatca/standard/2026-07-20_356.xml
storage/app/zatca/standard/2026-07-20_357.xml
storage/app/zatca/standard/2026-07-20_358.xml
storage/app/public/14/صبغة-جذور-فاتح.png

FILES_CHANGED=NO
DATABASE_CHANGED=NO
ZATCA_REQUEST_SENT=NO