ubl 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +14 -0
- data/lib/ubl/builder.rb +2 -5
- data/lib/ubl/constants.rb +6 -0
- data/lib/ubl/validate.rb +78 -0
- data/lib/ubl/version.rb +1 -1
- data/lib/ubl.rb +29 -0
- data/xsd/common/CCTS_CCT_SchemaModule-2.1.xsd +731 -0
- data/xsd/common/UBL-CommonAggregateComponents-2.1.xsd +39799 -0
- data/xsd/common/UBL-CommonBasicComponents-2.1.xsd +5389 -0
- data/xsd/common/UBL-CommonExtensionComponents-2.1.xsd +223 -0
- data/xsd/common/UBL-CommonSignatureComponents-2.1.xsd +101 -0
- data/xsd/common/UBL-CoreComponentParameters-2.1.xsd +63 -0
- data/xsd/common/UBL-ExtensionContentDataType-2.1.xsd +89 -0
- data/xsd/common/UBL-QualifiedDataTypes-2.1.xsd +69 -0
- data/xsd/common/UBL-SignatureAggregateComponents-2.1.xsd +138 -0
- data/xsd/common/UBL-SignatureBasicComponents-2.1.xsd +78 -0
- data/xsd/common/UBL-UnqualifiedDataTypes-2.1.xsd +553 -0
- data/xsd/common/UBL-XAdESv132-2.1.xsd +476 -0
- data/xsd/common/UBL-XAdESv141-2.1.xsd +25 -0
- data/xsd/common/UBL-xmldsig-core-schema-2.1.xsd +330 -0
- data/xsd/maindoc/UBL-ApplicationResponse-2.1.xsd +362 -0
- data/xsd/maindoc/UBL-AttachedDocument-2.1.xsd +416 -0
- data/xsd/maindoc/UBL-AwardedNotification-2.1.xsd +418 -0
- data/xsd/maindoc/UBL-BillOfLading-2.1.xsd +540 -0
- data/xsd/maindoc/UBL-CallForTenders-2.1.xsd +513 -0
- data/xsd/maindoc/UBL-Catalogue-2.1.xsd +565 -0
- data/xsd/maindoc/UBL-CatalogueDeletion-2.1.xsd +465 -0
- data/xsd/maindoc/UBL-CatalogueItemSpecificationUpdate-2.1.xsd +533 -0
- data/xsd/maindoc/UBL-CataloguePricingUpdate-2.1.xsd +532 -0
- data/xsd/maindoc/UBL-CatalogueRequest-2.1.xsd +571 -0
- data/xsd/maindoc/UBL-CertificateOfOrigin-2.1.xsd +417 -0
- data/xsd/maindoc/UBL-ContractAwardNotice-2.1.xsd +493 -0
- data/xsd/maindoc/UBL-ContractNotice-2.1.xsd +459 -0
- data/xsd/maindoc/UBL-CreditNote-2.1.xsd +951 -0
- data/xsd/maindoc/UBL-DebitNote-2.1.xsd +916 -0
- data/xsd/maindoc/UBL-DespatchAdvice-2.1.xsd +482 -0
- data/xsd/maindoc/UBL-DocumentStatus-2.1.xsd +350 -0
- data/xsd/maindoc/UBL-DocumentStatusRequest-2.1.xsd +348 -0
- data/xsd/maindoc/UBL-ExceptionCriteria-2.1.xsd +417 -0
- data/xsd/maindoc/UBL-ExceptionNotification-2.1.xsd +403 -0
- data/xsd/maindoc/UBL-Forecast-2.1.xsd +454 -0
- data/xsd/maindoc/UBL-ForecastRevision-2.1.xsd +453 -0
- data/xsd/maindoc/UBL-ForwardingInstructions-2.1.xsd +517 -0
- data/xsd/maindoc/UBL-FreightInvoice-2.1.xsd +867 -0
- data/xsd/maindoc/UBL-FulfilmentCancellation-2.1.xsd +471 -0
- data/xsd/maindoc/UBL-GoodsItemItinerary-2.1.xsd +431 -0
- data/xsd/maindoc/UBL-GuaranteeCertificate-2.1.xsd +481 -0
- data/xsd/maindoc/UBL-InstructionForReturns-2.1.xsd +383 -0
- data/xsd/maindoc/UBL-InventoryReport-2.1.xsd +401 -0
- data/xsd/maindoc/UBL-Invoice-2.1.xsd +1002 -0
- data/xsd/maindoc/UBL-ItemInformationRequest-2.1.xsd +402 -0
- data/xsd/maindoc/UBL-Order-2.1.xsd +891 -0
- data/xsd/maindoc/UBL-OrderCancellation-2.1.xsd +416 -0
- data/xsd/maindoc/UBL-OrderChange-2.1.xsd +869 -0
- data/xsd/maindoc/UBL-OrderResponse-2.1.xsd +956 -0
- data/xsd/maindoc/UBL-OrderResponseSimple-2.1.xsd +486 -0
- data/xsd/maindoc/UBL-PackingList-2.1.xsd +432 -0
- data/xsd/maindoc/UBL-PriorInformationNotice-2.1.xsd +441 -0
- data/xsd/maindoc/UBL-ProductActivity-2.1.xsd +387 -0
- data/xsd/maindoc/UBL-Quotation-2.1.xsd +583 -0
- data/xsd/maindoc/UBL-ReceiptAdvice-2.1.xsd +485 -0
- data/xsd/maindoc/UBL-Reminder-2.1.xsd +759 -0
- data/xsd/maindoc/UBL-RemittanceAdvice-2.1.xsd +567 -0
- data/xsd/maindoc/UBL-RequestForQuotation-2.1.xsd +519 -0
- data/xsd/maindoc/UBL-RetailEvent-2.1.xsd +515 -0
- data/xsd/maindoc/UBL-SelfBilledCreditNote-2.1.xsd +918 -0
- data/xsd/maindoc/UBL-SelfBilledInvoice-2.1.xsd +933 -0
- data/xsd/maindoc/UBL-Statement-2.1.xsd +600 -0
- data/xsd/maindoc/UBL-StockAvailabilityReport-2.1.xsd +403 -0
- data/xsd/maindoc/UBL-Tender-2.1.xsd +464 -0
- data/xsd/maindoc/UBL-TenderReceipt-2.1.xsd +398 -0
- data/xsd/maindoc/UBL-TendererQualification-2.1.xsd +401 -0
- data/xsd/maindoc/UBL-TendererQualificationResponse-2.1.xsd +399 -0
- data/xsd/maindoc/UBL-TradeItemLocationProfile-2.1.xsd +415 -0
- data/xsd/maindoc/UBL-TransportExecutionPlan-2.1.xsd +769 -0
- data/xsd/maindoc/UBL-TransportExecutionPlanRequest-2.1.xsd +696 -0
- data/xsd/maindoc/UBL-TransportProgressStatus-2.1.xsd +396 -0
- data/xsd/maindoc/UBL-TransportProgressStatusRequest-2.1.xsd +345 -0
- data/xsd/maindoc/UBL-TransportServiceDescription-2.1.xsd +430 -0
- data/xsd/maindoc/UBL-TransportServiceDescriptionRequest-2.1.xsd +363 -0
- data/xsd/maindoc/UBL-TransportationStatus-2.1.xsd +566 -0
- data/xsd/maindoc/UBL-TransportationStatusRequest-2.1.xsd +484 -0
- data/xsd/maindoc/UBL-UnawardedNotification-2.1.xsd +415 -0
- data/xsd/maindoc/UBL-UtilityStatement-2.1.xsd +490 -0
- data/xsd/maindoc/UBL-Waybill-2.1.xsd +501 -0
- metadata +96 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5c951c7c837dfd7a900976e605a78832e0bf2bfd15733c4877f045df4bf0214e
|
4
|
+
data.tar.gz: bceb1d66414fe51ae67db3c15ad0e60f6e127834dfc7f587781f9464a430364c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f94eccdd50a880d39a67ab3fcfa102ff6115792fc06f94c6fc0c9702797902e3975e75c532d0512ee4ea9c58f05042b07cb2419703a5955be3cf19dabd30ffb3
|
7
|
+
data.tar.gz: 3ced736e13ab314f47aea124fdea03188512b659e8f1579500d60a4ddf3d11a1f32f2b52573e54bc526c9494d50e9ca692818f1d8c1afbc0bc8570e2fc2a7d09
|
data/README.md
CHANGED
@@ -51,6 +51,20 @@ invoice.add_line(name: "Software License", quantity: 1, unit_price: 500.0, tax_r
|
|
51
51
|
invoice.build
|
52
52
|
```
|
53
53
|
|
54
|
+
If you need the UBL.BE version:
|
55
|
+
```ruby
|
56
|
+
invoice = Ubl::Invoice.new("UBL_BE")
|
57
|
+
```
|
58
|
+
|
59
|
+
You can also validate the result.
|
60
|
+
You need Docker for the schematron validation.
|
61
|
+
With `schematron: false` you can disable this and only the xsd validation will run.
|
62
|
+
```ruby
|
63
|
+
Tempfile.create("invoice.xml") do |invoice_file|
|
64
|
+
File.write(invoice_file, content)
|
65
|
+
p Ubl.validate_invoice(invoice_file.path, extension: "UBL_BE", schematron: true)
|
66
|
+
end
|
67
|
+
```
|
54
68
|
|
55
69
|
## development
|
56
70
|
|
data/lib/ubl/builder.rb
CHANGED
@@ -3,18 +3,15 @@
|
|
3
3
|
require "nokogiri"
|
4
4
|
require "date"
|
5
5
|
require "base64"
|
6
|
+
require_relative "constants"
|
6
7
|
|
7
8
|
module Ubl
|
8
9
|
class UblBuilder
|
9
10
|
attr_accessor :invoice_nr, :issue_date, :due_date, :currency, :supplier,
|
10
11
|
:customer, :invoice_lines, :tax_total, :legal_monetary_total, :pdffile
|
11
12
|
|
12
|
-
CUSTOMIZATION_ID = "urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0"
|
13
|
-
CUSTOMIZATION_UBL_BE = "urn:cen.eu:en16931:2017#conformant#urn:UBL.BE:1.0.0.20180214"
|
14
|
-
PROFILE_ID = "urn:fdc:peppol.eu:2017:poacc:billing:01:1.0"
|
15
|
-
|
16
13
|
def initialize(extension = nil)
|
17
|
-
@ubl_be = extension ==
|
14
|
+
@ubl_be = extension == UBL_BE
|
18
15
|
@issue_date = Date.today
|
19
16
|
@due_date = @issue_date + 30
|
20
17
|
@currency = "EUR"
|
@@ -0,0 +1,6 @@
|
|
1
|
+
module Ubl
|
2
|
+
CUSTOMIZATION_ID = "urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0"
|
3
|
+
CUSTOMIZATION_UBL_BE = "urn:cen.eu:en16931:2017#conformant#urn:UBL.BE:1.0.0.20180214"
|
4
|
+
PROFILE_ID = "urn:fdc:peppol.eu:2017:poacc:billing:01:1.0"
|
5
|
+
UBL_BE = "UBL_BE"
|
6
|
+
end
|
data/lib/ubl/validate.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
require "nokogiri"
|
2
|
+
require "date"
|
3
|
+
require "fileutils"
|
4
|
+
require "colorize"
|
5
|
+
require_relative "constants"
|
6
|
+
|
7
|
+
module Ubl
|
8
|
+
class Validator
|
9
|
+
def initialize(extension: nil, schematron: true)
|
10
|
+
@ubl_be = extension == UBL_BE
|
11
|
+
@schematron = schematron
|
12
|
+
end
|
13
|
+
|
14
|
+
def validate_invoice(path)
|
15
|
+
xsd = File.join(__dir__, "../../xsd/maindoc/UBL-Invoice-2.1.xsd")
|
16
|
+
validate(path, xsd)
|
17
|
+
end
|
18
|
+
|
19
|
+
def validate_credit_note(path)
|
20
|
+
xsd = File.join(__dir__, "../../xsd/maindoc/UBL-CreditNote-2.1.xsd")
|
21
|
+
validate(path, xsd)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def validate(path, xsd)
|
27
|
+
ubl_content = File.read(path)
|
28
|
+
errors = validate_xsd(ubl_content, xsd)
|
29
|
+
return errors if errors.any?
|
30
|
+
|
31
|
+
errors = validate_schematron(path) if @schematron
|
32
|
+
|
33
|
+
errors
|
34
|
+
end
|
35
|
+
|
36
|
+
def validate_xsd(xml_content, xsd)
|
37
|
+
return ["XSD not found: #{xsd}"] unless File.exist?(xsd)
|
38
|
+
|
39
|
+
begin
|
40
|
+
xml_doc = Nokogiri::XML(xml_content)
|
41
|
+
xsd_doc = Nokogiri::XML::Schema(File.open(xsd))
|
42
|
+
errors = xsd_doc.validate(xml_doc)
|
43
|
+
errors.map(&:message)
|
44
|
+
rescue => e
|
45
|
+
["XSD validation error: #{e.message}"]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def validate_schematron(invoice_file)
|
50
|
+
env = @ubl_be ? "-e UBL_BE=true" : ""
|
51
|
+
cmd = "docker run --rm #{env} -v #{invoice_file}:/app/invoice.xml:ro ghcr.io/roel4d/peppol_schematron:latest 2>/dev/null"
|
52
|
+
# puts cmd
|
53
|
+
svrl_content = `#{cmd}`
|
54
|
+
parse_svrl_errors(svrl_content)
|
55
|
+
end
|
56
|
+
|
57
|
+
def get_svrl_errors(svrl_doc, flag, color)
|
58
|
+
errors = []
|
59
|
+
svrl_doc.xpath("//failed-assert[@flag=\"#{flag}\"]").each do |node|
|
60
|
+
test = node["test"].squeeze(" ")
|
61
|
+
# location = node['location']
|
62
|
+
text = node.xpath("text").map(&:content).join(" ").tr("\n", " ").squeeze(" ").strip
|
63
|
+
errors << flag.colorize(color) + ": #{text}\n #{test.colorize(:grey)}"
|
64
|
+
end
|
65
|
+
errors
|
66
|
+
end
|
67
|
+
|
68
|
+
# Parse SVRL (Schematron Validation Report Language) output for errors
|
69
|
+
def parse_svrl_errors(svrl_content)
|
70
|
+
svrl_doc = Nokogiri::XML(svrl_content)
|
71
|
+
svrl_doc.remove_namespaces!
|
72
|
+
errors = []
|
73
|
+
errors << get_svrl_errors(svrl_doc, "fatal", :red)
|
74
|
+
errors << get_svrl_errors(svrl_doc, "warning", :light_red)
|
75
|
+
errors.flatten
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/lib/ubl/version.rb
CHANGED
data/lib/ubl.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative "ubl/builder"
|
2
|
+
require_relative "ubl/validate"
|
2
3
|
|
3
4
|
##
|
4
5
|
# Generate UBL (Universal Business Language) documents,
|
@@ -69,4 +70,32 @@ module Ubl
|
|
69
70
|
builder.to_xml
|
70
71
|
end
|
71
72
|
end
|
73
|
+
|
74
|
+
##
|
75
|
+
# Validate an invoice
|
76
|
+
#
|
77
|
+
# == Parameters
|
78
|
+
# * +path+ - The path to the XML invoice that needs validation.
|
79
|
+
# * +extension+ - Set to +"UBL_BE"+ to generate UBL.BE compliant documents.
|
80
|
+
# Defaults to +nil+ for standard PEPPOL format.
|
81
|
+
# * +schematron+ - If +true+, run a Schematron validation using Docker.
|
82
|
+
# Requires Docker to be installed and running. Defaults to +true+.
|
83
|
+
def self.validate_invoice(path, extension: nil, schematron: true)
|
84
|
+
validator = Validator.new(extension:, schematron:)
|
85
|
+
validator.validate_invoice(path)
|
86
|
+
end
|
87
|
+
|
88
|
+
##
|
89
|
+
# Validate a credit note
|
90
|
+
#
|
91
|
+
# == Parameters
|
92
|
+
# * +path+ - The path to the XML credit note that needs validation.
|
93
|
+
# * +extension+ - Set to +"UBL_BE"+ to generate UBL.BE compliant documents.
|
94
|
+
# Defaults to +nil+ for standard PEPPOL format.
|
95
|
+
# * +schematron+ - If +true+, run a Schematron validation using Docker.
|
96
|
+
# Requires Docker to be installed and running. Defaults to +true+.
|
97
|
+
def self.validate_credit_note(path, extension: nil, schematron: true)
|
98
|
+
validator = Validator.new(extension:, schematron:)
|
99
|
+
validator.validate_credit_note(path)
|
100
|
+
end
|
72
101
|
end
|