tradedoc 0.1.0
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 +7 -0
- data/.editorconfig +13 -0
- data/CHANGELOG.md +5 -0
- data/LICENSE.txt +21 -0
- data/README.md +53 -0
- data/Rakefile +10 -0
- data/lib/tradedoc/code/agency.rb +8 -0
- data/lib/tradedoc/code/document_type.rb +95 -0
- data/lib/tradedoc/code/national_clearing_system.rb +97 -0
- data/lib/tradedoc/code/payment_means_type.rb +107 -0
- data/lib/tradedoc/code/tax_category.rb +97 -0
- data/lib/tradedoc/code.rb +12 -0
- data/lib/tradedoc/format/apeh.rb +36 -0
- data/lib/tradedoc/format/cii/coder/address.rb +55 -0
- data/lib/tradedoc/format/cii/coder/big_decimal.rb +21 -0
- data/lib/tradedoc/format/cii/coder/contact.rb +43 -0
- data/lib/tradedoc/format/cii/coder/date.rb +87 -0
- data/lib/tradedoc/format/cii/coder/document_reference.rb +33 -0
- data/lib/tradedoc/format/cii/coder/exchange_rate.rb +33 -0
- data/lib/tradedoc/format/cii/coder/financial_account.rb +45 -0
- data/lib/tradedoc/format/cii/coder/financial_institution.rb +39 -0
- data/lib/tradedoc/format/cii/coder/invoice.rb +127 -0
- data/lib/tradedoc/format/cii/coder/invoice_line.rb +88 -0
- data/lib/tradedoc/format/cii/coder/monetary_total.rb +36 -0
- data/lib/tradedoc/format/cii/coder/money.rb +27 -0
- data/lib/tradedoc/format/cii/coder/payment_means.rb +49 -0
- data/lib/tradedoc/format/cii/coder/period.rb +27 -0
- data/lib/tradedoc/format/cii/coder/remittance_advice.rb +130 -0
- data/lib/tradedoc/format/cii/coder/string.rb +21 -0
- data/lib/tradedoc/format/cii/coder/tax_subtotal.rb +35 -0
- data/lib/tradedoc/format/cii/coder/trade_party.rb +29 -0
- data/lib/tradedoc/format/cii/coder.rb +27 -0
- data/lib/tradedoc/format/cii.rb +12 -0
- data/lib/tradedoc/format/facturae.rb +51 -0
- data/lib/tradedoc/format/fatturapa/coder/invoice.rb +31 -0
- data/lib/tradedoc/format/fatturapa/coder.rb +8 -0
- data/lib/tradedoc/format/fatturapa.rb +13 -0
- data/lib/tradedoc/format/isdoc.rb +40 -0
- data/lib/tradedoc/format/ksef/coder/invoice.rb +32 -0
- data/lib/tradedoc/format/ksef/coder.rb +10 -0
- data/lib/tradedoc/format/ksef.rb +17 -0
- data/lib/tradedoc/format/mydata.rb +42 -0
- data/lib/tradedoc/format/nav.rb +38 -0
- data/lib/tradedoc/format/ubl/coder/address.rb +48 -0
- data/lib/tradedoc/format/ubl/coder/big_decimal.rb +21 -0
- data/lib/tradedoc/format/ubl/coder/contact.rb +29 -0
- data/lib/tradedoc/format/ubl/coder/country.rb +27 -0
- data/lib/tradedoc/format/ubl/coder/date.rb +21 -0
- data/lib/tradedoc/format/ubl/coder/document_reference.rb +55 -0
- data/lib/tradedoc/format/ubl/coder/exchange_rate.rb +33 -0
- data/lib/tradedoc/format/ubl/coder/financial_account.rb +32 -0
- data/lib/tradedoc/format/ubl/coder/financial_institution.rb +42 -0
- data/lib/tradedoc/format/ubl/coder/invoice.rb +92 -0
- data/lib/tradedoc/format/ubl/coder/invoice_line.rb +53 -0
- data/lib/tradedoc/format/ubl/coder/monetary_total.rb +39 -0
- data/lib/tradedoc/format/ubl/coder/money.rb +22 -0
- data/lib/tradedoc/format/ubl/coder/payment_means.rb +39 -0
- data/lib/tradedoc/format/ubl/coder/period.rb +27 -0
- data/lib/tradedoc/format/ubl/coder/product.rb +37 -0
- data/lib/tradedoc/format/ubl/coder/remittance_advice.rb +91 -0
- data/lib/tradedoc/format/ubl/coder/string.rb +21 -0
- data/lib/tradedoc/format/ubl/coder/tax_breakdown.rb +27 -0
- data/lib/tradedoc/format/ubl/coder/tax_category.rb +37 -0
- data/lib/tradedoc/format/ubl/coder/tax_subtotal.rb +29 -0
- data/lib/tradedoc/format/ubl/coder/trade_party.rb +37 -0
- data/lib/tradedoc/format/ubl/coder.rb +29 -0
- data/lib/tradedoc/format/ubl.rb +13 -0
- data/lib/tradedoc/format/zugferdv1/coder/invoice.rb +33 -0
- data/lib/tradedoc/format/zugferdv1/coder.rb +8 -0
- data/lib/tradedoc/format/zugferdv1.rb +21 -0
- data/lib/tradedoc/format.rb +110 -0
- data/lib/tradedoc/model/address.rb +21 -0
- data/lib/tradedoc/model/base.rb +153 -0
- data/lib/tradedoc/model/contact.rb +9 -0
- data/lib/tradedoc/model/country.rb +8 -0
- data/lib/tradedoc/model/country_subdivision.rb +8 -0
- data/lib/tradedoc/model/document.rb +9 -0
- data/lib/tradedoc/model/document_reference.rb +11 -0
- data/lib/tradedoc/model/exchange_rate.rb +17 -0
- data/lib/tradedoc/model/financial_account.rb +19 -0
- data/lib/tradedoc/model/financial_institution.rb +11 -0
- data/lib/tradedoc/model/invoice.rb +57 -0
- data/lib/tradedoc/model/invoice_line.rb +46 -0
- data/lib/tradedoc/model/monetary_total.rb +34 -0
- data/lib/tradedoc/model/payment_means.rb +27 -0
- data/lib/tradedoc/model/period.rb +8 -0
- data/lib/tradedoc/model/price.rb +21 -0
- data/lib/tradedoc/model/product.rb +18 -0
- data/lib/tradedoc/model/remittance_advice.rb +20 -0
- data/lib/tradedoc/model/remittance_advice_line.rb +24 -0
- data/lib/tradedoc/model/tax_breakdown.rb +11 -0
- data/lib/tradedoc/model/tax_category.rb +26 -0
- data/lib/tradedoc/model/tax_subtotal.rb +13 -0
- data/lib/tradedoc/model/trade_party.rb +9 -0
- data/lib/tradedoc/model.rb +33 -0
- data/lib/tradedoc/version.rb +5 -0
- data/lib/tradedoc/xml/reader.rb +163 -0
- data/lib/tradedoc/xml/writer.rb +56 -0
- data/lib/tradedoc/xml.rb +8 -0
- data/lib/tradedoc.rb +98 -0
- data/sig/tradedoc.rbs +4 -0
- metadata +187 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Tradedoc
|
|
2
|
+
module Format
|
|
3
|
+
module UBL
|
|
4
|
+
module Coder
|
|
5
|
+
class Date
|
|
6
|
+
def self.ruby_type
|
|
7
|
+
::Date
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.dump(w, obj, as:)
|
|
11
|
+
w.add("cbc:#{as}", obj.to_date.iso8601)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.parse(r)
|
|
15
|
+
ruby_type.parse(r.text)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
module Tradedoc
|
|
2
|
+
module Format
|
|
3
|
+
module UBL
|
|
4
|
+
module Coder
|
|
5
|
+
class DocumentReference
|
|
6
|
+
DREF_SUFFIX = "DocumentReference"
|
|
7
|
+
|
|
8
|
+
# Element names are based on the document type.
|
|
9
|
+
# Map based on our internal document type IDs.
|
|
10
|
+
TYPE_MAP = {
|
|
11
|
+
commercial_invoice: "Invoice",
|
|
12
|
+
credit_note: "CreditNote",
|
|
13
|
+
debit_note: "DebitNote"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
private_constant :DREF_SUFFIX, :TYPE_MAP
|
|
17
|
+
|
|
18
|
+
def self.ruby_type
|
|
19
|
+
Model::DocumentReference
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.dump(w, obj, as:)
|
|
23
|
+
element_name_root = TYPE_MAP.fetch(obj.type.id)
|
|
24
|
+
|
|
25
|
+
w.add(as) do
|
|
26
|
+
w.add("cac:#{element_name_root}#{DREF_SUFFIX}") do
|
|
27
|
+
w.add("cbc:ID", obj.id)
|
|
28
|
+
w.add("cbc:UUID", obj.uuid)
|
|
29
|
+
w.render(obj.issue_date, as: "IssueDate")
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.parse(r)
|
|
35
|
+
# The type of the document reference is embedded in the node name, so we
|
|
36
|
+
# have to match that manually to derive the type and pick the right child node.
|
|
37
|
+
dr_node = r.node.children.detect { it.node_name.end_with?(DREF_SUFFIX) }
|
|
38
|
+
|
|
39
|
+
return if dr_node.nil?
|
|
40
|
+
|
|
41
|
+
ruby_type.new.tap do |dr|
|
|
42
|
+
dr.type = TYPE_MAP.key(dr_node.node_name.delete_suffix(DREF_SUFFIX))
|
|
43
|
+
|
|
44
|
+
r.with_node(dr_node) do
|
|
45
|
+
r.parse("cbc:ID", :String) { dr.id = it }
|
|
46
|
+
r.parse("cbc:UUID", :String) { dr.uuid = it }
|
|
47
|
+
r.parse("cbc:IssueDate", :Date) { dr.issue_date = it }
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Tradedoc
|
|
2
|
+
module Format
|
|
3
|
+
module UBL
|
|
4
|
+
module Coder
|
|
5
|
+
class ExchangeRate
|
|
6
|
+
def self.ruby_type
|
|
7
|
+
Model::ExchangeRate
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.dump(w, obj, as: "cac:ExchangeRate")
|
|
11
|
+
w.add(as) do
|
|
12
|
+
w.render(obj.source_currency_code, as: "cbc:SourceCurrencyCode")
|
|
13
|
+
w.render(obj.target_currency_code, as: "cbc:TargetCurrencyCode")
|
|
14
|
+
w.render(obj.market_id, as: "cbc:ExchangeMarketID")
|
|
15
|
+
w.render(obj.rate, as: "cbc:CalculationRate")
|
|
16
|
+
w.render(obj.date, as: "Date")
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.parse(r)
|
|
21
|
+
ruby_type.new.tap do |xr|
|
|
22
|
+
r.parse("cbc:SourceCurrencyCode", :String) { xr.source_currency_code = it }
|
|
23
|
+
r.parse("cbc:TargetCurrencyCode", :String) { xr.target_currency_code = it }
|
|
24
|
+
r.parse("cbc:CalculationRate", :BigDecimal) { xr.rate = it }
|
|
25
|
+
r.parse("cbc:ExchangeMarketID", :String) { xr.market_id = it }
|
|
26
|
+
r.parse("cbc:Date", :Date) { xr.date = it }
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module Tradedoc
|
|
2
|
+
module Format
|
|
3
|
+
module UBL
|
|
4
|
+
module Coder
|
|
5
|
+
class FinancialAccount
|
|
6
|
+
def self.ruby_type
|
|
7
|
+
Model::FinancialAccount
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.dump(w, obj, as:)
|
|
11
|
+
w.add(as) do
|
|
12
|
+
w.add("cbc:ID", obj.account_number, schemeName: obj.scheme_name)
|
|
13
|
+
w.render(obj.financial_institution)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.parse(r)
|
|
18
|
+
ruby_type.new.tap do |obj|
|
|
19
|
+
r.with_node("cbc:ID") do
|
|
20
|
+
r.parse("@schemeName", :String) { obj.scheme_name = it }
|
|
21
|
+
r.parse("text()", :String) { obj.account_number = it }
|
|
22
|
+
end
|
|
23
|
+
r.parse("cac:FinancialInstitutionBranch", :FinancialInstitution) do
|
|
24
|
+
obj.financial_institution = it
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module Tradedoc
|
|
2
|
+
module Format
|
|
3
|
+
module UBL
|
|
4
|
+
module Coder
|
|
5
|
+
class FinancialInstitution
|
|
6
|
+
def self.ruby_type
|
|
7
|
+
Model::FinancialInstitution
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.dump(w, obj, as: "cac:FinancialInstitutionBranch")
|
|
11
|
+
w.add(as) do
|
|
12
|
+
w.add("cac:FinancialInstitution") do
|
|
13
|
+
# If there's no NCS, then this is a SWIFT code
|
|
14
|
+
scheme_name = if (ncs = obj.national_clearing_system)
|
|
15
|
+
ncs.iso_code
|
|
16
|
+
else
|
|
17
|
+
"SWIFTBIC"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
w.add("cbc:ID", obj.id, schemeName: scheme_name)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.parse(r)
|
|
26
|
+
r.with_node("cac:FinancialInstitution") do
|
|
27
|
+
ruby_type.new.tap do |obj|
|
|
28
|
+
r.with_node("cbc:ID") do
|
|
29
|
+
obj.id = r.text
|
|
30
|
+
|
|
31
|
+
# Won't be present for SWIFT/BIC, and that's what we want
|
|
32
|
+
obj.national_clearing_system =
|
|
33
|
+
Tradedoc::Code::NationalClearingSystem.find_by_iso_code(r.attribute("schemeName"))
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
module Tradedoc
|
|
2
|
+
module Format
|
|
3
|
+
module UBL
|
|
4
|
+
module Coder
|
|
5
|
+
class Invoice
|
|
6
|
+
NS = {
|
|
7
|
+
"xmlns:inv" => "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2",
|
|
8
|
+
"xmlns:cac" => "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2",
|
|
9
|
+
"xmlns:cbc" => "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2",
|
|
10
|
+
"xmlns:ext" => "urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"
|
|
11
|
+
}.freeze
|
|
12
|
+
|
|
13
|
+
private_constant :NS
|
|
14
|
+
|
|
15
|
+
def self.namespaces
|
|
16
|
+
NS
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# @param xmldoc [Nokogiri::XML::Document]
|
|
20
|
+
def self.can_parse?(xmldoc)
|
|
21
|
+
xmldoc.root.namespace&.href == namespaces.fetch("xmlns:inv")
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.ruby_type
|
|
25
|
+
Model::Invoice
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def self.dump(w, obj)
|
|
29
|
+
w.add("inv:Invoice", NS) do
|
|
30
|
+
w.render(obj.specification_id, as: "cbc:CustomizationID")
|
|
31
|
+
w.render(obj.invoice_number, as: "cbc:ID")
|
|
32
|
+
w.render(obj.issue_date, as: "IssueDate")
|
|
33
|
+
w.render(obj.due_date, as: "DueDate")
|
|
34
|
+
w.render(obj.invoice_type_code, as: "cbc:InvoiceTypeCode", listAgencyID: Code::Agency::CEFACT)
|
|
35
|
+
w.render(obj.note, as: "cbc:Note")
|
|
36
|
+
w.render(obj.currency_code, as: "cbc:DocumentCurrencyCode", listAgencyID: Code::Agency::CEFACT)
|
|
37
|
+
w.render(obj.invoice_period, as: "InvoicePeriod")
|
|
38
|
+
if (po_number = obj.purchase_order_number)
|
|
39
|
+
w.add("cac:OrderReference") do
|
|
40
|
+
w.render(po_number, as: "cbc:ID")
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
if (supplier = obj.supplier)
|
|
44
|
+
w.add("cac:AccountingSupplierParty") do
|
|
45
|
+
w.render(supplier, as: "cac:Party")
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
if (buyer = obj.buyer)
|
|
49
|
+
w.add("cac:AccountingCustomerParty") do
|
|
50
|
+
w.render(buyer, as: "cac:Party")
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
w.render(obj.monetary_total&.tax_breakdown)
|
|
54
|
+
w.render(obj.monetary_total)
|
|
55
|
+
w.render_list(obj.lines)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def self.parse(r)
|
|
60
|
+
ruby_type.new.tap do |inv|
|
|
61
|
+
r.with_node("inv:Invoice") do
|
|
62
|
+
r.parse("cbc:ID", :String) { inv.invoice_number = it }
|
|
63
|
+
r.parse("cbc:IssueDate", :Date) { inv.issue_date = it }
|
|
64
|
+
r.parse("cbc:DueDate", :Date) { inv.due_date = it }
|
|
65
|
+
r.parse("cbc:InvoiceTypeCode", :String) { inv.invoice_type_code = it }
|
|
66
|
+
r.parse("cbc:Note", :String) { inv.note = it }
|
|
67
|
+
r.parse("cbc:DocumentCurrencyCode", :String) { inv.currency_code = it }
|
|
68
|
+
r.parse("cac:InvoicePeriod", :Period) { inv.invoice_period = it }
|
|
69
|
+
r.parse("cac:AccountingSupplierParty", :TradeParty) { inv.supplier = it }
|
|
70
|
+
r.parse("cac:AccountingCustomerParty", :TradeParty) { inv.buyer = it }
|
|
71
|
+
r.parse_list("cac:PaymentMeans", :PaymentMeans) { inv.payment_means = it }
|
|
72
|
+
r.parse("cac:LegalMonetaryTotal", :MonetaryTotal) { inv.monetary_total = it }
|
|
73
|
+
r.parse("cac:TaxTotal", :TaxBreakdown) { inv.monetary_total.tax_breakdown = it }
|
|
74
|
+
r.parse_list("cac:InvoiceLine", :InvoiceLine) { inv.lines = it }
|
|
75
|
+
|
|
76
|
+
r.with_node("cac:OrderReference") do
|
|
77
|
+
r.parse("cbc:ID", :String) { inv.purchase_order_number = it }
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# The due date may have been put into payment means
|
|
81
|
+
# This is allowed per the Peppol docs
|
|
82
|
+
if inv.due_date.nil?
|
|
83
|
+
r.parse("cac:PaymentMeans/cbc:PaymentDueDate", :Date) { inv.due_date = it }
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
module Tradedoc
|
|
2
|
+
module Format
|
|
3
|
+
module UBL
|
|
4
|
+
module Coder
|
|
5
|
+
class InvoiceLine
|
|
6
|
+
def self.ruby_type
|
|
7
|
+
Model::InvoiceLine
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.dump(w, obj, as: "cac:InvoiceLine")
|
|
11
|
+
w.add(as) do
|
|
12
|
+
w.render(obj.id, as: "cbc:ID")
|
|
13
|
+
w.render(obj.invoiced_quantity, as: "cbc:InvoicedQuantity")
|
|
14
|
+
w.render(obj.total_excluding_tax, as: "LineExtensionAmount")
|
|
15
|
+
if (total_tax = obj.total_tax)
|
|
16
|
+
w.add("cac:TaxTotal") do
|
|
17
|
+
w.render(total_tax, as: "TotalTax")
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
w.render(obj.product)
|
|
22
|
+
|
|
23
|
+
if (price = obj.price)
|
|
24
|
+
w.add("cac:Price") do
|
|
25
|
+
w.render(price.net, as: "PriceAmount")
|
|
26
|
+
w.render(price.base_quantity, as: "cbc:BaseQuantity")
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def self.parse(r)
|
|
33
|
+
ruby_type.new.tap do |line|
|
|
34
|
+
r.parse("cbc:ID", :String) { line.id = it }
|
|
35
|
+
r.parse("cbc:InvoicedQuantity", :BigDecimal) { line.invoiced_quantity = it }
|
|
36
|
+
r.parse("cbc:LineExtensionAmount", :Money) { line.total_excluding_tax = it }
|
|
37
|
+
r.with_node("cac:TaxTotal") do
|
|
38
|
+
r.parse("cbc:TotalTax", :Money) { line.total_tax = it }
|
|
39
|
+
end
|
|
40
|
+
r.parse("cac:Item", :Product) { line.product = it }
|
|
41
|
+
r.with_node("cac:Price") do
|
|
42
|
+
line.price = Model::Price.new.tap do |price|
|
|
43
|
+
r.parse("cbc:PriceAmount", :Money) { price.net = it }
|
|
44
|
+
r.parse("cbc:BaseQuantity", :BigDecimal) { price.base_quantity = it }
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module Tradedoc
|
|
2
|
+
module Format
|
|
3
|
+
module UBL
|
|
4
|
+
module Coder
|
|
5
|
+
class MonetaryTotal
|
|
6
|
+
def self.ruby_type
|
|
7
|
+
Model::MonetaryTotal
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.dump(w, obj, as: "cac:LegalMonetaryTotal")
|
|
11
|
+
w.add(as) do
|
|
12
|
+
w.render(obj.line_items_tax_exclusive, as: "LineExtensionAmount")
|
|
13
|
+
w.render(obj.tax_exclusive, as: "TaxExclusiveAmount")
|
|
14
|
+
w.render(obj.tax_inclusive, as: "TaxInclusiveAmount")
|
|
15
|
+
w.render(obj.discounts, as: "AllowanceTotalAmount")
|
|
16
|
+
w.render(obj.charges, as: "ChargeTotalAmount")
|
|
17
|
+
w.render(obj.prepaid, as: "PrepaidAmount")
|
|
18
|
+
w.render(obj.rounding, as: "PayableRoundingAmount")
|
|
19
|
+
w.render(obj.payable, as: "PayableAmount")
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.parse(r)
|
|
24
|
+
ruby_type.new.tap do |mt|
|
|
25
|
+
r.parse("cbc:LineExtensionAmount", :Money) { mt.line_items_tax_exclusive = it }
|
|
26
|
+
r.parse("cbc:TaxExclusiveAmount", :Money) { mt.tax_exclusive = it }
|
|
27
|
+
r.parse("cbc:TaxInclusiveAmount", :Money) { mt.tax_inclusive = it }
|
|
28
|
+
r.parse("cbc:AllowanceTotalAmount", :Money) { mt.discounts = it }
|
|
29
|
+
r.parse("cbc:ChargeTotalAmount", :Money) { mt.charges = it }
|
|
30
|
+
r.parse("cbc:PrepaidAmount", :Money) { mt.prepaid = it }
|
|
31
|
+
r.parse("cbc:PayableRoundingAmount", :Money) { mt.rounding = it }
|
|
32
|
+
r.parse("cbc:PayableAmount", :Money) { mt.payable = it }
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module Tradedoc
|
|
2
|
+
module Format
|
|
3
|
+
module UBL
|
|
4
|
+
module Coder
|
|
5
|
+
class Money
|
|
6
|
+
def self.ruby_type
|
|
7
|
+
::Money
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.dump(w, obj, as:, decimals: 2)
|
|
11
|
+
as_string = obj.to_d.round(decimals).to_s("F")
|
|
12
|
+
w.add("cbc:#{as}", as_string, currencyID: obj.currency.iso_code)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.parse(r)
|
|
16
|
+
ruby_type.from_amount(BigDecimal(r.text), r.attribute!("currencyID"))
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module Tradedoc
|
|
2
|
+
module Format
|
|
3
|
+
module UBL
|
|
4
|
+
module Coder
|
|
5
|
+
class PaymentMeans
|
|
6
|
+
def self.ruby_type
|
|
7
|
+
Model::PaymentMeans
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.dump(w, obj, as: "cac:PaymentMeans")
|
|
11
|
+
w.add(as) do
|
|
12
|
+
w.add("cbc:PaymentMeansCode", obj.type_code.code, listID: "UN/CE 4461", listAgencyID: Code::Agency::CEFACT)
|
|
13
|
+
w.render(obj.instruction_id, as: "cbc:InstructionID")
|
|
14
|
+
obj.messages.each do |msg|
|
|
15
|
+
w.add("cbc:InstructionNote", msg)
|
|
16
|
+
end
|
|
17
|
+
w.render(obj.payment_id, as: "cbc:PaymentID")
|
|
18
|
+
w.render(obj.sending_account, as: "cac:PayerFinancialAccount")
|
|
19
|
+
w.render(obj.receiving_account, as: "cac:PayeeFinancialAccount")
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.parse(r)
|
|
24
|
+
ruby_type.new.tap do |obj|
|
|
25
|
+
r.parse("cbc:PaymentMeansCode", :String) { obj.type_code = it }
|
|
26
|
+
r.parse("cbc:PaymentID", :String) { obj.payment_id = it }
|
|
27
|
+
r.parse("cbc:InstructionID", :String) { obj.instruction_id = it }
|
|
28
|
+
r.with_nodes("cbc:InstructionNote") do
|
|
29
|
+
obj.messages.push(r.text)
|
|
30
|
+
end
|
|
31
|
+
r.parse("cac:PayerFinancialAccount", :FinancialAccount) { obj.sending_account = it }
|
|
32
|
+
r.parse("cac:PayeeFinancialAccount", :FinancialAccount) { obj.receiving_account = it }
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Tradedoc
|
|
2
|
+
module Format
|
|
3
|
+
module UBL
|
|
4
|
+
module Coder
|
|
5
|
+
class Period
|
|
6
|
+
def self.ruby_type
|
|
7
|
+
Model::Period
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.dump(w, obj, as:)
|
|
11
|
+
w.add("cac:#{as}") do
|
|
12
|
+
w.render(obj.start_date, as: "StartDate")
|
|
13
|
+
w.render(obj.end_date, as: "EndDate")
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.parse(r)
|
|
18
|
+
ruby_type.new.tap do |obj|
|
|
19
|
+
r.parse("cbc:StartDate", :Date) { obj.start_date = it }
|
|
20
|
+
r.parse("cbc:EndDate", :Date) { obj.end_date = it }
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module Tradedoc
|
|
2
|
+
module Format
|
|
3
|
+
module UBL
|
|
4
|
+
module Coder
|
|
5
|
+
class Product
|
|
6
|
+
def self.ruby_type
|
|
7
|
+
Model::Product
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.dump(w, obj, as: "cac:Item")
|
|
11
|
+
w.add(as) do
|
|
12
|
+
w.render(obj.description, as: "cbc:Description")
|
|
13
|
+
w.render(obj.name, as: "cbc:Name")
|
|
14
|
+
if (id = obj.seller_assigned_id)
|
|
15
|
+
w.add("cac:SellersItemIdentification") do
|
|
16
|
+
w.render(id, as: "cbc:ID")
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
w.render(obj.tax_category, as: "cac:ClassifiedTaxCategory")
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.parse(r)
|
|
24
|
+
ruby_type.new.tap do |prod|
|
|
25
|
+
r.parse("cbc:Description", :String) { prod.description = it }
|
|
26
|
+
r.parse("cbc:Name", :String) { prod.name = it }
|
|
27
|
+
r.with_node("cac:SellersItemIdentification") do
|
|
28
|
+
r.parse("cbc:ID", :String) { prod.seller_assigned_id = it }
|
|
29
|
+
end
|
|
30
|
+
r.parse("cac:ClassifiedTaxCategory", :TaxCategory) { prod.tax_category = it }
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
module Tradedoc
|
|
2
|
+
module Format
|
|
3
|
+
module UBL
|
|
4
|
+
module Coder
|
|
5
|
+
class RemittanceAdvice
|
|
6
|
+
NS = {
|
|
7
|
+
"xmlns:rad" => "urn:oasis:names:specification:ubl:schema:xsd:RemittanceAdvice-2",
|
|
8
|
+
"xmlns:cac" => "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2",
|
|
9
|
+
"xmlns:cbc" => "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
|
|
10
|
+
}.freeze
|
|
11
|
+
|
|
12
|
+
private_constant :NS
|
|
13
|
+
|
|
14
|
+
def self.namespaces
|
|
15
|
+
NS
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# @param xmldoc [Nokogiri::XML::Document]
|
|
19
|
+
def self.can_parse?(xmldoc)
|
|
20
|
+
xmldoc.root.namespace&.href == namespaces.fetch("xmlns:rad")
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.ruby_type
|
|
24
|
+
Model::RemittanceAdvice
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.dump(w, obj)
|
|
28
|
+
w.add("rad:RemittanceAdvice", NS) do
|
|
29
|
+
w.add("cbc:ID", obj.id)
|
|
30
|
+
w.render(obj.uuid, as: "cbc:UUID")
|
|
31
|
+
w.render(obj.issue_date, as: "IssueDate")
|
|
32
|
+
w.render(obj.note, as: "cbc:Note")
|
|
33
|
+
|
|
34
|
+
w.render(obj.total_payment_amount, as: "TotalPaymentAmount")
|
|
35
|
+
w.render(obj.invoice_period, as: "InvoicePeriod")
|
|
36
|
+
|
|
37
|
+
w.add("cac:AccountingCustomerParty") do
|
|
38
|
+
w.render(obj.buyer)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
w.add("cac:AccountingSupplierParty") do
|
|
42
|
+
w.render(obj.supplier)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
w.render(obj.payment_means)
|
|
46
|
+
|
|
47
|
+
obj.lines.each do |line|
|
|
48
|
+
w.add("cac:RemittanceAdviceLine") do
|
|
49
|
+
w.add("cbc:ID", line.id)
|
|
50
|
+
w.render(line.note, as: "cbc:Note")
|
|
51
|
+
w.render(line.balance_amount, as: "BalanceAmount")
|
|
52
|
+
w.render(line.document_reference, as: "cac:BillingReference")
|
|
53
|
+
w.render(line.exchange_rate, as: "cac:ExchangeRate")
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def self.parse(r)
|
|
60
|
+
obj = ruby_type.new
|
|
61
|
+
|
|
62
|
+
r.with_node("rad:RemittanceAdvice") do
|
|
63
|
+
r.parse("cbc:ID", :String) { obj.id = it }
|
|
64
|
+
r.parse("cbc:UUID", :String) { obj.uuid = it }
|
|
65
|
+
r.parse("cbc:IssueDate", :Date) { obj.issue_date = it }
|
|
66
|
+
r.parse("cbc:Note", :String) { obj.note = it }
|
|
67
|
+
r.parse("cbc:TotalPaymentAmount", :Money) { obj.total_payment_amount = it }
|
|
68
|
+
r.parse("cac:AccountingCustomerParty", :TradeParty) { obj.buyer = it }
|
|
69
|
+
r.parse("cac:AccountingSupplierParty", :TradeParty) { obj.supplier = it }
|
|
70
|
+
r.parse("cac:PaymentMeans", :PaymentMeans) { obj.payment_means = it }
|
|
71
|
+
r.parse("cac:InvoicePeriod", :Period) { obj.invoice_period = it }
|
|
72
|
+
|
|
73
|
+
r.with_nodes("cac:RemittanceAdviceLine") do
|
|
74
|
+
line = Model::RemittanceAdviceLine.new
|
|
75
|
+
r.parse("cbc:ID", :String) { line.id = it }
|
|
76
|
+
r.parse("cbc:Note", :String) { line.note = it }
|
|
77
|
+
r.parse("cbc:BalanceAmount", :Money) { line.balance_amount = it }
|
|
78
|
+
r.parse("cac:BillingReference", :DocumentReference) { line.document_reference = it }
|
|
79
|
+
r.parse("cac:ExchangeRate", :ExchangeRate) { line.exchange_rate = it }
|
|
80
|
+
|
|
81
|
+
obj.lines.push(line)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
obj
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Tradedoc
|
|
2
|
+
module Format
|
|
3
|
+
module UBL
|
|
4
|
+
module Coder
|
|
5
|
+
class String
|
|
6
|
+
def self.ruby_type
|
|
7
|
+
::String
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.dump(w, obj, as:, **opts)
|
|
11
|
+
w.add(as, obj, **opts)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.parse(r, strip: true, nilify: true)
|
|
15
|
+
r.text(strip:, nilify:)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Tradedoc
|
|
2
|
+
module Format
|
|
3
|
+
module UBL
|
|
4
|
+
module Coder
|
|
5
|
+
class TaxBreakdown
|
|
6
|
+
def self.ruby_type
|
|
7
|
+
Model::TaxBreakdown
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.dump(w, obj, as: "cac:TaxTotal")
|
|
11
|
+
w.add(as) do
|
|
12
|
+
w.render(obj.total_tax, as: "TaxAmount")
|
|
13
|
+
w.render_list(obj.subtotals, as: "cac:TaxSubtotal")
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.parse(r)
|
|
18
|
+
ruby_type.new.tap do |tax|
|
|
19
|
+
r.parse("cbc:TaxAmount", :Money) { tax.total_tax = it }
|
|
20
|
+
r.parse_list("cac:TaxSubtotal", :TaxSubtotal) { tax.subtotals = it }
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module Tradedoc
|
|
2
|
+
module Format
|
|
3
|
+
module UBL
|
|
4
|
+
module Coder
|
|
5
|
+
class TaxCategory
|
|
6
|
+
def self.ruby_type
|
|
7
|
+
Model::TaxCategory
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.dump(w, obj, as: "cac:TaxCategory")
|
|
11
|
+
w.add(as) do
|
|
12
|
+
w.render(obj.code.edifact_id, as: "cbc:ID")
|
|
13
|
+
w.render(obj.rate_percent, as: "cbc:Percent")
|
|
14
|
+
w.render(obj.exemption_reason_code, as: "cbc:TaxExemptionReasonCode")
|
|
15
|
+
w.render(obj.exemption_reason, as: "cbc:TaxExemptionReason")
|
|
16
|
+
if (tax_scheme = obj.tax_scheme)
|
|
17
|
+
w.add("cac:TaxScheme") do
|
|
18
|
+
w.render(tax_scheme, as: "cbc:ID")
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.parse(r)
|
|
25
|
+
ruby_type.new.tap do |cat|
|
|
26
|
+
r.parse("cbc:ID", :String) { cat.code = it }
|
|
27
|
+
r.parse("cbc:Percent", :BigDecimal) { cat.rate_percent = it }
|
|
28
|
+
r.parse("cbc:TaxExemptionReason", :String) { cat.exemption_reason = it }
|
|
29
|
+
r.parse("cbc:TaxExemptionReasonCode", :String) { cat.exemption_reason_code = it }
|
|
30
|
+
r.parse("cac:TaxScheme/cbc:ID", :String) { cat.tax_scheme = it }
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|