ubl2cii 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 68bc2e8c31e1a17603f44aa80f368556abde55d3effc219bb24ee5d1b5bebb0e
4
+ data.tar.gz: '0884d09700c2272b8dc9b6f6d3fc8343af8bb149f37460cc305a2ea20b189831'
5
+ SHA512:
6
+ metadata.gz: 99b41bd3a25d7f2fea9c4eea8ee2e3997e543d95174ed32ae9d2af94d27d6fcc4608e7efb9830f6234247631d9efeabfad5be8c5a973b13b09ed2cfcec68d328
7
+ data.tar.gz: ab99056e35f4a08a71eeea02f4a00d0227564ab844fd6ce0c0362f05cc6f2309923011dfcad1e95165368750b0c74592401c9c7acc00852a3ec96b90a0e242ce
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "ubl2cii"
6
+
7
+ puts "Enter the path to the UBL XML file:"
8
+ ubl_file_path = gets.chomp
9
+
10
+ ubl_xml = File.read(ubl_file_path)
11
+ converter = Ubl2Cii::Converter.new(ubl_xml)
12
+ cii_xml = converter.convert
13
+
14
+ puts "Converted CII XML content:"
15
+ puts cii_xml
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ubl2Cii
4
+ REQUIRED_ELEMENTS = %w[ExchangedDocumentContext].freeze
5
+
6
+ FORMATABLE_ELEMENTS = %w[DateTimeString].freeze
7
+
8
+ # XML Namespace URIs
9
+ NAMESPACE_RSM = 'urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100'
10
+ NAMESPACE_RAM = 'urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100'
11
+ NAMESPACE_UDT = 'urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100'
12
+ NAMESPACE_QDT = 'urn:un:unece:uncefact:data:standard:QualifiedDataType:100'
13
+ NAMESPACE_CBC = 'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2'
14
+ NAMESPACE_CAC = 'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2'
15
+
16
+ PREFIX_RSM = 'rsm'
17
+ PREFIX_RAM = 'ram'
18
+ PREFIX_UDT = 'udt'
19
+ PREFIX_CBC = 'cbc'
20
+ PREFIX_CAC = 'cac'
21
+ PREFIX_QDT = 'qdt'
22
+
23
+ OUTPUT_ENCODING = 'UTF-8'
24
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'nokogiri'
4
+ require 'date'
5
+
6
+ module Ubl2Cii
7
+ class Converter
8
+ def initialize(xml)
9
+ @document = Document.new(xml)
10
+ end
11
+
12
+ def convert_to_cii
13
+ builder = Nokogiri::XML::Builder.new(encoding: OUTPUT_ENCODING) do |xml|
14
+ xml[PREFIX_RSM].CrossIndustryInvoice(namespaces) do
15
+ Mapper::Cii.new.process(xml, @document)
16
+ end
17
+ end
18
+ clean_empty_elements(builder.doc)
19
+ builder.to_xml.force_encoding(OUTPUT_ENCODING)
20
+ end
21
+
22
+ private
23
+
24
+ def clean_empty_elements(node)
25
+ pending = node.children.to_a
26
+ while element = pending.pop
27
+ pending.concat(element.children.to_a)
28
+
29
+ next if !element.element? || REQUIRED_ELEMENTS.include?(element.name)
30
+
31
+ element.remove if element.children.empty? && element.attributes.empty?
32
+ end
33
+ node
34
+ end
35
+
36
+ def namespaces
37
+ @namespaces ||= {
38
+ "xmlns:#{PREFIX_QDT}" => NAMESPACE_QDT,
39
+ "xmlns:#{PREFIX_RSM}" => NAMESPACE_RSM,
40
+ "xmlns:#{PREFIX_UDT}" => NAMESPACE_UDT,
41
+ "xmlns:#{PREFIX_RAM}" => NAMESPACE_RAM
42
+ }
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'nokogiri'
4
+
5
+ module Ubl2Cii
6
+ class Document
7
+ attr_reader :node, :namespaces
8
+
9
+ def initialize(xml)
10
+ @doc = Nokogiri::XML(xml, nil, OUTPUT_ENCODING)
11
+ @node = @doc
12
+ @namespaces = {
13
+ PREFIX_RSM => NAMESPACE_RSM,
14
+ PREFIX_RAM => NAMESPACE_RAM,
15
+ PREFIX_UDT => NAMESPACE_UDT,
16
+ PREFIX_CBC => NAMESPACE_CBC,
17
+ PREFIX_CAC => NAMESPACE_CAC
18
+ }
19
+ end
20
+
21
+ def xpath(path, multiple: false)
22
+ return unless @node
23
+
24
+ if multiple
25
+ @node.xpath(path, @namespaces)
26
+ else
27
+ @node.at_xpath(path, @namespaces)
28
+ end
29
+ end
30
+
31
+ alias_method :at_xpath, :xpath
32
+
33
+ def content_at(path)
34
+ xpath(path)&.content
35
+ end
36
+
37
+ def attribute_at(path, attr)
38
+ xpath(path)&.[](attr)
39
+ end
40
+
41
+ def map_nodes(path, &)
42
+ xpath(path, multiple: true).map(&)
43
+ end
44
+
45
+ def self.new_from_node(node, namespaces)
46
+ doc = Document.allocate
47
+ doc.instance_variable_set(:@node, node)
48
+ doc.instance_variable_set(:@doc, node)
49
+ doc.instance_variable_set(:@namespaces, namespaces)
50
+ doc
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,394 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ubl2Cii
4
+ module Mapper
5
+ class Dsl
6
+ def self.element(name, options={}, &)
7
+ element_def = {name: name}.merge(options)
8
+ if block_given?
9
+ new_class = Class.new(NestedMapping)
10
+ new_class.class_eval(&)
11
+ element_def[:children] = new_class
12
+ end
13
+ elements << element_def
14
+ end
15
+
16
+ def self.elements
17
+ @elements ||= []
18
+ end
19
+
20
+ def self.collection(name, options={}, &)
21
+ collection_def = {name: name, collection: true}.merge(options)
22
+ if block_given?
23
+ new_class = Class.new(NestedMapping)
24
+ new_class.class_eval(&)
25
+ collection_def[:item_mapping] = new_class
26
+ end
27
+ elements << collection_def
28
+ end
29
+
30
+ def process(xml, document, parent_prefix=nil)
31
+ self.class.elements.each do |element_def|
32
+ if element_def[:collection]
33
+ build_collection(xml, document, element_def, parent_prefix)
34
+ else
35
+ build_element(xml, document, element_def, parent_prefix)
36
+ end
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def build_element(xml, document, element_def, parent_prefix)
43
+ prefix = element_def[:prefix] || parent_prefix || PREFIX_RAM
44
+ attributes = build_attributes(document, element_def)
45
+
46
+ if element_def[:children]
47
+ build_nested_element(xml, document, element_def, prefix)
48
+ else
49
+ build_simple_element(xml, document, element_def, prefix, attributes)
50
+ end
51
+ end
52
+
53
+ def build_attributes(document, element_def)
54
+ attributes = {}
55
+ if element_def[:source_properties]
56
+ attributes.merge!(handle_properties(element_def[:source_properties], element_def[:source], document))
57
+ end
58
+ attributes.merge!(handle_properties(element_def[:properties], document)) if element_def[:properties]
59
+ attributes
60
+ end
61
+
62
+ def build_nested_element(xml, document, element_def, prefix)
63
+ source_doc = element_def[:source] ? extract_node(document, element_def[:source]) : document
64
+ xml[prefix].send(element_def[:name]) do
65
+ element_def[:children].new.process(xml, source_doc, prefix)
66
+ end
67
+ end
68
+
69
+ def build_simple_element(xml, document, element_def, prefix, attributes)
70
+ value = extract_value(document, element_def[:source])
71
+ value = handle_value_format(value, element_def[:name]) if FORMATABLE_ELEMENTS.include?(element_def[:name])
72
+ xml[prefix].send(element_def[:name], value, attributes)
73
+ end
74
+
75
+ def handle_properties(properties, source = nil, document)
76
+ resolved_properties = {}
77
+ properties.each do |key, value|
78
+ resolved_properties[key] = if value.is_a?(Proc)
79
+ extract_value(document, value.call)
80
+ else
81
+ document.attribute_at(source, key) || value
82
+ end
83
+ end
84
+ resolved_properties
85
+ end
86
+
87
+ def handle_value_format(value, element_name)
88
+ return unless value
89
+
90
+ case element_name
91
+ when 'DateTimeString'
92
+ date_value = begin
93
+ DateTime.parse(value)
94
+ rescue StandardError
95
+ nil
96
+ end
97
+ date_value&.strftime('%Y%m%d')
98
+ else
99
+ value
100
+ end
101
+ end
102
+
103
+ def build_collection(xml, document, element_def, parent_prefix)
104
+ prefix = element_def[:prefix] || parent_prefix || PREFIX_RAM
105
+ items = extract_nodeset(document, element_def[:source]) || []
106
+
107
+ items.each do |item|
108
+ xml[prefix].send(element_def[:name]) do
109
+ element_def[:item_mapping]&.new&.process(xml, item, prefix)
110
+ end
111
+ end
112
+ end
113
+
114
+ def extract_nodeset(document, source)
115
+ return nil unless source
116
+
117
+ document.map_nodes(source) {|node| Document.new_from_node(node, document.namespaces) }
118
+ end
119
+
120
+ def extract_node(document, source)
121
+ return nil unless source
122
+
123
+ Document.new_from_node(document.at_xpath(source), document.namespaces)
124
+ end
125
+
126
+ def extract_value(document, source)
127
+ return nil unless source
128
+
129
+ case source
130
+ when String
131
+ document.content_at(source)
132
+ when Proc
133
+ source.call(document)
134
+ when Symbol
135
+ document.send(source) if document.respond_to?(source)
136
+ end
137
+ end
138
+ end
139
+
140
+ # For nested mappings within elements
141
+ class NestedMapping < Dsl
142
+ end
143
+
144
+ class Cii < Dsl
145
+ element 'ExchangedDocumentContext', prefix: PREFIX_RSM do
146
+ element 'GuidelineSpecifiedDocumentContextParameter', prefix: PREFIX_RAM do
147
+ element 'ID', source: '//cbc:CustomizationID', prefix: PREFIX_RAM
148
+ end
149
+ end
150
+
151
+ element 'ExchangedDocument', prefix: PREFIX_RSM do
152
+ element 'ID', source: '//cbc:ID', prefix: PREFIX_RAM
153
+ element 'TypeCode', source: '//cbc:InvoiceTypeCode', prefix: PREFIX_RAM
154
+ element 'IssueDateTime', prefix: PREFIX_RAM do
155
+ element 'DateTimeString', source: '//cbc:IssueDate', properties: {format: '102'}, prefix: PREFIX_UDT
156
+ end
157
+ element 'IncludedNote', prefix: PREFIX_RAM do
158
+ element 'Content', source: '//cbc:Note'
159
+ end
160
+ end
161
+
162
+ element 'SupplyChainTradeTransaction', prefix: PREFIX_RSM do
163
+ collection 'IncludedSupplyChainTradeLineItem', source: '//cac:InvoiceLine', prefix: PREFIX_RAM do
164
+ element 'AssociatedDocumentLineDocument' do
165
+ element 'LineID', source: 'cbc:ID'
166
+ element 'IncludedNote', prefix: PREFIX_RAM do
167
+ element 'Content', source: 'cbc:Note'
168
+ end
169
+ end
170
+
171
+ element 'SpecifiedTradeProduct', source: 'cac:Item' do
172
+ element 'GlobalID', source: 'cac:StandardItemIdentification//cbc:ID', source_properties: [:schemeID]
173
+ element 'SellerAssignedID', source: 'cac:SellersItemIdentification//cbc:ID'
174
+ element 'Name', source: 'cbc:Name'
175
+ element 'Description', source: 'cbc:Description'
176
+ collection 'ApplicableProductCharacteristic', source: 'cac:AdditionalItemProperty', prefix: PREFIX_RAM do
177
+ element 'Description', source: 'cbc:Name'
178
+ element 'Value', source: 'cbc:Value'
179
+ end
180
+
181
+ collection 'DesignatedProductClassification', source: 'cac:CommodityClassification', prefix: PREFIX_RAM do
182
+ element 'ClassCode', source: 'cbc:ItemClassificationCode', source_properties: [:listID]
183
+ end
184
+ end
185
+
186
+ element 'SpecifiedLineTradeAgreement' do
187
+ element 'BuyerOrderReferencedDocument' do
188
+ element 'LineID', source: 'cac:OrderLineReference//cbc:LineID'
189
+ end
190
+ element 'NetPriceProductTradePrice' do
191
+ element 'ChargeAmount', source: 'cac:Price//cbc:PriceAmount', source_properties: [:currencyID]
192
+ end
193
+ end
194
+
195
+ element 'SpecifiedLineTradeDelivery' do
196
+ element 'BilledQuantity', source: 'cbc:InvoicedQuantity', source_properties: [:unitCode]
197
+ end
198
+
199
+ element 'SpecifiedLineTradeSettlement' do
200
+ element 'ApplicableTradeTax', source: 'cac:Item//cac:ClassifiedTaxCategory' do
201
+ element 'TypeCode', source: 'cac:TaxScheme//cbc:ID'
202
+ element 'CategoryCode', source: 'cbc:ID'
203
+ element 'RateApplicablePercent', source: 'cbc:Percent'
204
+ end
205
+ element 'SpecifiedTradeSettlementLineMonetarySummation' do
206
+ element 'LineTotalAmount', source: 'cbc:LineExtensionAmount', source_properties: [:currencyID]
207
+ end
208
+ element 'ReceivableSpecifiedTradeAccountingAccount' do
209
+ element 'ID', source: 'cbc:AccountingCost'
210
+ end
211
+ end
212
+ end
213
+ element 'ApplicableHeaderTradeAgreement', prefix: PREFIX_RAM do
214
+ element 'SellerTradeParty', source: '//cac:AccountingSupplierParty//cac:Party' do
215
+ element 'ID', source: 'cac:PartyIdentification//cbc:ID', source_properties: [:schemeID]
216
+ element 'Name', source: 'cac:PartyName//cbc:Name'
217
+ element 'SpecifiedLegalOrganization', source: 'cac:PartyLegalEntity' do
218
+ element 'ID', source: 'cbc:CompanyID', source_properties: [:schemeID]
219
+ element 'TradingBusinessName', source: 'cbc:RegistrationName'
220
+ element 'PostalTradeAddress', source: 'cac:RegistrationAddress' do
221
+ element 'CityName', source: 'cbc:CityName'
222
+ element 'CountryID', source: 'cac:Country//cbc:IdentificationCode'
223
+ element 'CountrySubDivisionName', source: 'cbc:CountrySubentity'
224
+ end
225
+ end
226
+ element 'PostalTradeAddress', source: 'cac:PostalAddress' do
227
+ element 'PostcodeCode', source: 'cbc:PostalZone'
228
+ element 'LineOne', source: 'cbc:StreetName'
229
+ element 'LineTwo', source: 'cbc:AdditionalStreetName'
230
+ element 'CityName', source: 'cbc:CityName'
231
+ element 'CountryID', source: 'cac:Country//cbc:IdentificationCode'
232
+ element 'CountrySubDivisionName', source: 'cbc:CountrySubentity'
233
+ end
234
+ element 'URIUniversalCommunication' do
235
+ element 'URIID', source: 'cbc:EndpointID', source_properties: [:schemeID]
236
+ end
237
+
238
+ element 'SpecifiedTaxRegistration', source: 'cac:PartyTaxScheme' do
239
+ element 'ID', source: 'cbc:CompanyID', properties: {schemeID: -> { 'cac:TaxScheme//cbc:ID' }}
240
+ end
241
+ end
242
+ element 'BuyerTradeParty', source: '//cac:AccountingCustomerParty//cac:Party' do
243
+ element 'ID', source: 'cac:PartyIdentification//cbc:ID', source_properties: [:schemeID]
244
+ element 'Name', source: 'cac:PartyName//cbc:Name'
245
+ element 'SpecifiedLegalOrganization', source: 'cac:PartyLegalEntity' do
246
+ element 'ID', source: 'cbc:CompanyID', source_properties: [:schemeID]
247
+ element 'TradingBusinessName', source: 'cbc:RegistrationName'
248
+ element 'PostalTradeAddress', source: 'cac:RegistrationAddress' do
249
+ element 'CityName', source: 'cbc:CityName'
250
+ element 'CountryID', source: 'cac:Country//cbc:IdentificationCode'
251
+ element 'CountrySubDivisionName', source: 'cbc:CountrySubentity'
252
+ end
253
+ end
254
+ element 'PostalTradeAddress', source: 'cac:PostalAddress' do
255
+ element 'PostcodeCode', source: 'cbc:PostalZone'
256
+ element 'LineOne', source: 'cbc:StreetName'
257
+ element 'LineTwo', source: 'cbc:AdditionalStreetName'
258
+ element 'CityName', source: 'cbc:CityName'
259
+ element 'CountryID', source: 'cac:Country//cbc:IdentificationCode'
260
+ element 'CountrySubDivisionName', source: 'cbc:CountrySubentity'
261
+ end
262
+ element 'URIUniversalCommunication' do
263
+ element 'URIID', source: 'cbc:EndpointID', source_properties: [:schemeID]
264
+ end
265
+
266
+ element 'SpecifiedTaxRegistration', source: 'cac:PartyTaxScheme' do
267
+ element 'ID', source: 'cbc:CompanyID', properties: {schemeID: -> { 'cac:TaxScheme//cbc:ID' }}
268
+ end
269
+ end
270
+ element 'PayeeTradeParty', source: '//cac:PayeeParty' do
271
+ element 'ID', source: 'cac:PartyIdentification//cbc:ID', source_properties: [:schemeID]
272
+ element 'Name', source: 'cac:PartyName//cbc:Name'
273
+ element 'SpecifiedLegalOrganization', source: 'cac:PartyLegalEntity' do
274
+ element 'ID', source: 'cbc:CompanyID', source_properties: [:schemeID]
275
+ end
276
+ end
277
+ element 'BuyerOrderReferencedDocument' do
278
+ element 'IssuerAssignedID', source: '//cac:OrderReference//cbc:ID'
279
+ end
280
+ element 'ContractReferencedDocument' do
281
+ element 'IssuerAssignedID', source: '//cac:ContractDocumentReference//cbc:ID'
282
+ end
283
+ element 'SellerTaxRepresentativeTradeParty', source: '//cac:TaxRepresentativeParty' do
284
+ element 'Name', source: 'cac:PartyName//cbc:Name'
285
+ element 'SpecifiedTaxRegistration', source: 'cac:PartyTaxScheme' do
286
+ element 'ID', source: 'cbc:CompanyID', properties: {schemeID: -> { 'cac:TaxScheme//cbc:ID' }}
287
+ end
288
+ element 'PostalTradeAddress', source: 'cac:PostalAddress' do
289
+ element 'PostcodeCode', source: 'cbc:PostalZone'
290
+ element 'LineOne', source: 'cbc:StreetName'
291
+ element 'LineTwo', source: 'cbc:AdditionalStreetName'
292
+ element 'CityName', source: 'cbc:CityName'
293
+ element 'CountryID', source: 'cac:Country//cbc:IdentificationCode'
294
+ element 'CountrySubDivisionName', source: 'cbc:CountrySubentity'
295
+ end
296
+ end
297
+ collection 'AdditionalReferencedDocument', source: '//cac:AdditionalDocumentReference' do
298
+ element 'IssuerAssignedID', source: 'cbc:ID'
299
+ element 'URIID', source: 'cac:Attachment//cac:ExternalReference//cbc:URI'
300
+ element 'TypeCode', source: 'cbc:DocumentTypeCode'
301
+ element 'Name', source: 'cbc:DocumentDescription'
302
+ element 'AttachmentBinaryObject', source: 'cac:Attachment//cbc:EmbeddedDocumentBinaryObject'
303
+ end
304
+ end
305
+ element 'ApplicableHeaderTradeDelivery', source: '//cac:Delivery', prefix: PREFIX_RAM do
306
+ element 'ShipToTradeParty' do
307
+ element 'ID', source: 'cac:DeliveryLocation//cbc:ID', source_properties: [:schemeID]
308
+ element 'PostalTradeAddress', source: 'cac:DeliveryLocation//cac:Address' do
309
+ element 'PostcodeCode', source: 'cbc:PostalZone'
310
+ element 'LineOne', source: 'cbc:StreetName'
311
+ element 'LineTwo', source: 'cbc:AdditionalStreetName'
312
+ element 'CityName', source: 'cbc:CityName'
313
+ element 'CountryID', source: 'cac:Country//cbc:IdentificationCode'
314
+ element 'CountrySubDivisionName', source: 'cbc:CountrySubentity'
315
+ end
316
+ end
317
+ element 'ActualDeliverySupplyChainEvent' do
318
+ element 'OccurrenceDateTime' do
319
+ element 'DateTimeString', source: 'cbc:ActualDeliveryDate', properties: {format: '102'},
320
+ prefix: PREFIX_UDT
321
+ end
322
+ end
323
+ end
324
+ element 'ApplicableHeaderTradeSettlement', prefix: PREFIX_RAM do
325
+ element 'PaymentReference', source: '//cac:PaymentMeans//cbc:PaymentID'
326
+ element 'InvoiceCurrencyCode', source: '//cbc:DocumentCurrencyCode'
327
+ element 'PayeeTradeParty', source: '//cac:PayeeParty' do
328
+ element 'ID', source: 'cac:PartyIdentification//cbc:ID', source_properties: [:schemeID]
329
+ element 'Name', source: 'cac:PartyName//cbc:Name'
330
+ element 'SpecifiedLegalOrganization', source: 'cac:PartyLegalEntity' do
331
+ element 'ID', source: 'cbc:CompanyID', source_properties: [:schemeID]
332
+ end
333
+ end
334
+ collection 'SpecifiedTradeSettlementPaymentMeans', source: '//cac:PaymentMeans' do
335
+ element 'TypeCode', source: 'cbc:PaymentMeansCode'
336
+ element 'PayeePartyCreditorFinancialAccount', source: 'cac:PayeeFinancialAccount' do
337
+ element 'IBANID', source: 'cbc:ID'
338
+ element 'AccountName', source: 'cbc:Name'
339
+ end
340
+ end
341
+ element 'ApplicableTradeTax', source: '//cac:TaxTotal//cac:TaxSubtotal' do
342
+ element 'CalculatedAmount', source: 'cbc:TaxAmount', source_properties: [:currencyID]
343
+ element 'TypeCode', source: 'cac:TaxCategory//cbc:ID'
344
+ element 'BasisAmount', source: 'cbc:TaxableAmount', source_properties: [:currencyID]
345
+ element 'RateApplicablePercent', source: 'cac:TaxCategory//cbc:Percent'
346
+ end
347
+ element 'BillingSpecifiedPeriod', source: '//cac:InvoicePeriod' do
348
+ element 'StartDateTime' do
349
+ element 'DateTimeString', source: 'cbc:StartDate', properties: {format: '102'}, prefix: PREFIX_UDT
350
+ end
351
+ element 'EndDateTime' do
352
+ element 'DateTimeString', source: 'cbc:EndDate', properties: {format: '102'}, prefix: PREFIX_UDT
353
+ end
354
+ end
355
+ collection 'SpecifiedTradeAllowanceCharge', source: '//cac:AllowanceCharge' do
356
+ element 'ChargeIndicator' do
357
+ element 'Indicator', source: 'cbc:ChargeIndicator', prefix: PREFIX_UDT
358
+ end
359
+ element 'ActualAmount', source: 'cbc:Amount'
360
+ element 'Reason', source: 'cbc:AllowanceChargeReason'
361
+ end
362
+ element 'SpecifiedTradePaymentTerms' do
363
+ element 'Description', source: '//cac:PaymentTerms//cbc:Note'
364
+ element 'DueDateDateTime', source: '//cac:PaymentMeans' do
365
+ element 'DateTimeString', source: 'cbc:PaymentDueDate', properties: {format: '102'}, prefix: PREFIX_UDT
366
+ end
367
+ end
368
+ element 'SpecifiedTradeSettlementHeaderMonetarySummation' do
369
+ element 'LineTotalAmount', source: '//cac:LegalMonetaryTotal//cbc:LineExtensionAmount',
370
+ source_properties: [:currencyID]
371
+ element 'ChargeTotalAmount', source: '//cac:LegalMonetaryTotal//cbc:ChargeTotalAmount',
372
+ source_properties: [:currencyID]
373
+ element 'AllowanceTotalAmount', source: '//cac:LegalMonetaryTotal//cbc:AllowanceTotalAmount',
374
+ source_properties: [:currencyID]
375
+ element 'TaxBasisTotalAmount', source: '//cac:LegalMonetaryTotal//cbc:TaxExclusiveAmount',
376
+ source_properties: [:currencyID]
377
+ element 'TaxTotalAmount', source: '//cac:TaxTotal//cbc:TaxAmount', source_properties: [:currencyID]
378
+ element 'RoundingAmount', source: '//cac:LegalMonetaryTotal//cbc:PayableRoundingAmount',
379
+ source_properties: [:currencyID]
380
+ element 'GrandTotalAmount', source: '//cac:LegalMonetaryTotal//cbc:TaxInclusiveAmount',
381
+ source_properties: [:currencyID]
382
+ element 'TotalPrepaidAmount', source: '//cac:LegalMonetaryTotal//cbc:PrepaidAmount',
383
+ source_properties: [:currencyID]
384
+ element 'DuePayableAmount', source: '//cac:LegalMonetaryTotal//cbc:PayableAmount',
385
+ source_properties: [:currencyID]
386
+ end
387
+ element 'ReceivableSpecifiedTradeAccountingAccount' do
388
+ element 'ID', source: '//cbc:AccountingCost'
389
+ end
390
+ end
391
+ end
392
+ end
393
+ end
394
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ubl2Cii
4
+ VERSION = '0.1.0'
5
+ end
data/lib/ubl2cii.rb ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ubl2_cii/version'
4
+ require 'ubl2_cii/constants'
5
+ require 'ubl2_cii/document'
6
+ require 'ubl2_cii/mapper'
7
+ require 'ubl2_cii/converter'
8
+
9
+ module Ubl2Cii
10
+ end
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ubl2cii
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Wolfgang Fournes
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 2025-04-26 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: nokogiri
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '1.18'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '1.18'
26
+ - !ruby/object:Gem::Dependency
27
+ name: bundler
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '2.0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '2.0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: pry
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: rake
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '13.0'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '13.0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: rspec
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '3.0'
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '3.0'
82
+ description: This Gem provides a simple way to convert UBL XML files to CII XML files.
83
+ email:
84
+ - w.wohanka@gmail.com
85
+ executables:
86
+ - console
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - bin/console
91
+ - lib/ubl2_cii/constants.rb
92
+ - lib/ubl2_cii/converter.rb
93
+ - lib/ubl2_cii/document.rb
94
+ - lib/ubl2_cii/mapper.rb
95
+ - lib/ubl2_cii/version.rb
96
+ - lib/ubl2cii.rb
97
+ homepage: https://rubygems.org/gems/ubl2cii
98
+ licenses:
99
+ - MIT
100
+ metadata:
101
+ rubygems_mfa_required: 'true'
102
+ rdoc_options: []
103
+ require_paths:
104
+ - lib
105
+ required_ruby_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ required_rubygems_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ requirements: []
116
+ rubygems_version: 3.6.2
117
+ specification_version: 4
118
+ summary: A Ruby Gem to convert UBL XML files to CII XML files
119
+ test_files: []