Skip to content

Commit

Permalink
Revert Back to Original Approach
Browse files Browse the repository at this point in the history
Apparently our approach from many months ago (with the exception of SignedProperties spacing) works fine, ZATCA says they did not change anything on their end but suddenly that approach is passing their validator.
  • Loading branch information
obahareth committed Oct 24, 2023
1 parent b4a4507 commit 1bea6e6
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 15 deletions.
20 changes: 12 additions & 8 deletions lib/zatca/ubl/builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,25 +51,25 @@ def apply_qualifying_properties_hacks(invoice, xml)
# C14N 1.1 then manually adds back the whitespace in the format that ZATCA
# expects.
def canonicalized_xml(builder:)
return builder.doc.canonicalize(Nokogiri::XML::XML_C14N_1_1)

# TODO: In case ZATCA ever asks us to use their whitespace format again.
# In some meetings they say we have to use it, in some meetings they say
# we don't. The simpler approach is that we don't use it.
#
# ZATCA's docs specifically state we must use C14N 1.1 canonicalization.
xml = uncanonicalized_xml(builder: builder, spaces: 4)
xml_doc = Nokogiri::XML(xml)

canonical_xml = xml_doc.canonicalize(Nokogiri::XML::XML_C14N_1_1)

require "byebug"
byebug

canonical_xml
end

def uncanonicalized_xml(builder:, spaces: 4)
xml = builder.to_xml(indent: spaces.to_i)

xml = match_xml_string_to_zatca_whitespaces(xml)

require "byebug"
byebug
# xml = match_xml_string_to_zatca_whitespaces(xml)

xml
end
Expand All @@ -95,9 +95,13 @@ def match_xml_string_to_zatca_whitespaces(xml)
# This part is not clear, ZATCA shared documents with us that use CRLF
# but the samples in the SDK use LF, so we're not sure which one is correct.
# ZATCA wants CRLF (\r\n) in their canonicalized form instead of just LF (\n)
# xml.gsub!("\n", "\r\n")
xml.gsub!("\n", "\r\n")

xml
end

# Not sure if this is needed, in some meetings ZATCA says you have to match
# their whitspace exactly and in some meetings they say you don't.
# HACK: This is really hacky, using regexes or XPaths would be better, but
# that wasn't easy to build and maintain, so we're using this if/until we run
# into issues.
Expand Down
6 changes: 3 additions & 3 deletions lib/zatca/ubl/invoice.rb
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ def generate_hash
# When submitting to ZATCA, we need to submit the XML in Base64 format, and it
# needs to be pretty-printed matching their indentation style.
# The canonicalized option here is left only for debugging purposes.
def to_base64(canonicalized: false)
def to_base64(canonicalized: true)
canonicalized_xml_with_hacks_applied = generate_xml(
canonicalized: canonicalized,
apply_invoice_hacks: true,
Expand All @@ -195,7 +195,7 @@ def to_base64(canonicalized: false)
# an after_initialize callback. We just need to set the qualifying properties
# at any point before generating the XML.
def generate_xml(
canonicalized: false,
canonicalized: true,
spaces: 4,
apply_invoice_hacks: true,
remove_root_xml_tag: false
Expand All @@ -216,7 +216,7 @@ def generate_xml(
end

def generate_unsigned_xml(
canonicalized: false,
canonicalized: true,
apply_invoice_hacks: false,
remove_root_xml_tag: false
)
Expand Down
8 changes: 4 additions & 4 deletions spec/lib/zatca/ubl/invoice_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def clear_dynamic_values_from_xml(xml)
invoice = construct_simplified_invoice
zatca_xml = read_xml_fixture("simplified_invoice_signed.xml")

expect(invoice.generate_xml).to eq(zatca_xml)
expect(invoice.generate_xml(canonicalized: false, spaces: 2)).to eq(zatca_xml)
end

it "should be able to create an unsigned invoice qr-less invoice then add them later" do
Expand Down Expand Up @@ -56,7 +56,7 @@ def clear_dynamic_values_from_xml(xml)

zatca_xml = read_xml_fixture("simplified_invoice_signed.xml")

generated_xml = invoice.generate_xml(canonicalized: true)
generated_xml = invoice.generate_xml(canonicalized: false, spaces: 2)

# TODO: Remove these once done testing
File.write("TEST_ME_WITH_ZATCA.xml", generated_xml)
Expand Down Expand Up @@ -100,7 +100,7 @@ def clear_dynamic_values_from_xml(xml)
invoice = construct_signed_standard_invoice
zatca_xml = read_xml_fixture("standard_invoice.xml")

expect(invoice.generate_xml).to eq(zatca_xml)
expect(invoice.generate_xml(canonicalized: false, spaces: 2)).to eq(zatca_xml)
end

it "should be able to generate an unsigned qr-less standard invoice" do
Expand All @@ -117,7 +117,7 @@ def clear_dynamic_values_from_xml(xml)
.gsub(/\s*<cac:AdditionalDocumentReference>\s*<cbc:ID>QR<\/cbc:ID>.*<\/cac:AdditionalDocumentReference>/m, "")

File.write("STANDARD_UNSIGNED_TEST_WITH_ZATCA.xml", invoice.generate_xml)
expect(invoice.generate_xml).to eq(zatca_xml)
expect(invoice.generate_xml(canonicalized: false, spaces: 2)).to eq(zatca_xml)
end
end
end

0 comments on commit 1bea6e6

Please sign in to comment.