generateZatcaQrInit method

ZatcaQr generateZatcaQrInit({
  1. required BaseInvoice invoice,
  2. required int icv,
})

/// Generates a ZATCA-compliant QR code and invoice data. /// invoiceLines - The list of invoice lines. /// invoiceType - The type of the invoice. /// invoiceRelationType - The relation type of the invoice (default is b2c). /// customer - The customer information (required for b2b invoices). /// issueDate - The issue date of the invoice. /// invoiceUUid - The unique identifier for the invoice. /// invoiceNumber - The invoice number. /// issueTime - The issue time of the invoice. /// totalWithVat - The total amount including VAT. /// totalVat - The total VAT amount. /// previousInvoiceHash - The hash of the previous invoice. /// Returns a ZatcaQr object containing the QR code and invoice data.

Implementation

///   /// Returns a `ZatcaQr` object containing the QR code and invoice data.
ZatcaQr generateZatcaQrInit({
  required BaseInvoice invoice,
  required int icv,
}) {
  if (_supplier == null ||
      _privateKeyPem == null ||
      _certificatePem == null ||
      _sellerName == null ||
      _sellerTRN == null) {
    throw Exception(
      'Supplier, private key, certificate, seller name, and seller TRN must be initialized before generating the QR code.',
    );
  }

  // if (invoice.invoiceType.invoiceRelationType == InvoiceRelationType.b2b && invoice.customer == null) {
  //   throw Exception(
  //     'customer must be initialized before generating the QR code.',
  //   );
  // }
  // final zatinvoice = ZatcaInvoice(
  //   profileID: 'reporting:1.0',
  //   invoiceNumber: invoice.invoiceNumber,
  //   uuid: invoice.uuid,
  //   issueDate: invoice.issueDate,
  //   issueTime: invoice.issueTime,
  //   invoiceType: invoice.invoiceType,
  //   currencyCode: 'SAR',
  //   taxCurrencyCode: 'SAR',
  //   supplier: _supplier!,
  //   customer:invoice.customer??
  //       Customer(
  //         companyID: ' ',
  //         registrationName: ' ',
  //         address: Address(
  //           street: ' ',
  //           building: ' ',
  //           citySubdivision: ' ',
  //           city: ' ',
  //           postalZone: ' ',
  //         ),
  //       ),
  //   invoiceLines: invoice.invoiceLines,
  //   taxAmount: invoice.taxAmount,
  //   totalAmount: invoice.totalAmount,
  //   previousInvoiceHash: invoice.previousInvoiceHash,
  //   cancellation: invoice.cancellation,
  //
  // );

  final xml = XmlUtil.generateZATCAXml(invoice, _supplier!, icv: icv);
  final xmlString = xml.toXmlString(pretty: true, indent: '    ');
  String hashableXml = xml.rootElement.toXmlString(
    pretty: true,
    indent: '    ',
  );

  hashableXml = normalizeXml(hashableXml);
  hashableXml = hashableXml.replaceFirst(
    '<cbc:ProfileID>reporting:1.0</cbc:ProfileID>',
    '\n    <cbc:ProfileID>reporting:1.0</cbc:ProfileID>',
  );
  hashableXml = hashableXml.replaceFirst(
    '<cac:AccountingSupplierParty>',
    '\n    \n    <cac:AccountingSupplierParty>',
  );

  final xmlHash = XmlUtil.generateHash(hashableXml);

  // Generate the ECDSA signature
  final signature = SignatureUtil.createInvoiceDigitalSignature(
    xmlHash,
    _privateKeyPem!,
  );
  final certificateInfo = CertificateUtil.getCertificateInfo(
    _certificatePem!,
  );
  final issueDateTime = DateTime.parse(
    '${invoice.issueDate} ${invoice.issueTime}',
  );

  return ZatcaQr(
    sellerName: _sellerName!,
    sellerTRN: _sellerTRN!,
    issueDateTime: DateFormat("yyyy-MM-dd'T'HH:mm:ss").format(issueDateTime),
    invoiceHash: xmlHash,
    digitalSignature: signature,
    publicKey: certificateInfo.publicKey,
    certificateSignature: certificateInfo.signature,
    invoiceData: invoice,
    xmlString: xmlString,
  );
}