Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions lib/secretariat/invoice.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ module Secretariat
:issue_date,
:service_period_start,
:service_period_end,
:seller,
:buyer,
:seller, # TradeParty
:buyer, # TradeParty
:ship_to, # TradeParty or nil (buyer) or false (no ShipTo)
:buyer_reference,
:line_items,
:currency_code,
Expand Down Expand Up @@ -61,6 +62,14 @@ def tax_reason_text
tax_reason || TAX_EXEMPTION_REASONS[tax_category]
end

# ship_to: nil => use buyer (backwards compatibility)
# ship_to: false => ignore
def ship_to_or_buyer
return buyer if ship_to.nil?

ship_to
end

def tax_category_code(tax, version: 2)
if version == 1
return TAX_CATEGORY_CODES_1[tax.tax_category || tax_category] || 'S'
Expand Down Expand Up @@ -245,9 +254,9 @@ def to_xml(version: 1, validate: true)
delivery = by_version(version, 'ApplicableSupplyChainTradeDelivery', 'ApplicableHeaderTradeDelivery')

xml['ram'].send(delivery) do
if version == 2
if version == 2 && ship_to_or_buyer
xml['ram'].ShipToTradeParty do
buyer.to_xml(xml, exclude_tax: true, version: version)
ship_to_or_buyer.to_xml(xml, exclude_tax: true, version: version)
end
end
xml['ram'].ActualDeliverySupplyChainEvent do
Expand Down
4 changes: 4 additions & 0 deletions lib/secretariat/trade_party.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,14 @@ module Secretariat
using ObjectExtensions

TradeParty = Struct.new('TradeParty',
:id,
:name, :street1, :street2, :city, :postal_code, :country_id, :vat_id, :global_id, :global_id_scheme_id, :tax_id,
keyword_init: true,
) do
def to_xml(xml, exclude_tax: false, version: 2)
if id && !exclude_tax
xml['ram'].ID id # BT-46
end
if global_id.present? && global_id_scheme_id.present?
xml['ram'].GlobalID(schemeID: global_id_scheme_id) do
xml.text(global_id)
Expand Down
27 changes: 26 additions & 1 deletion test/invoice_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
module Secretariat
class InvoiceTest < Minitest::Test

def make_eu_invoice(tax_category: :REVERSECHARGE)
def make_eu_invoice(tax_category: :REVERSECHARGE, ship_to: nil)
seller = TradeParty.new(
name: 'Depfu inc',
street1: 'Quickbornstr. 46',
Expand All @@ -15,6 +15,7 @@ def make_eu_invoice(tax_category: :REVERSECHARGE)
vat_id: 'DE304755032'
)
buyer = TradeParty.new(
id: 'Kunde 4711',
name: 'Depfu inc',
street1: 'Quickbornstr. 46',
city: 'Hamburg',
Expand Down Expand Up @@ -42,6 +43,7 @@ def make_eu_invoice(tax_category: :REVERSECHARGE)
service_period_end: Date.today + 30,
seller: seller,
buyer: buyer,
ship_to: ship_to,
line_items: [line_item],
currency_code: 'USD',
payment_type: :CREDITCARD,
Expand Down Expand Up @@ -367,6 +369,29 @@ def test_simple_eu_invoice_v2
assert_match(/<ram:CategoryCode>AE<\/ram:CategoryCode>/, xml)
assert_match(/<ram:ExemptionReason>Reverse Charge<\/ram:ExemptionReason>/, xml)
assert_match(/<ram:RateApplicablePercent>/, xml)
assert_match(%r{<ram:BuyerTradeParty>\s*<ram:ID>Kunde 4711</ram:ID>}, xml)

v = Validator.new(xml, version: 2)
errors = v.validate_against_schema
if !errors.empty?
puts xml
errors.each do |error|
puts error
end
end
assert_equal [], errors
rescue ValidationError => e
puts e.errors
end

def test_simple_eu_invoice_v2_without_ship_to
begin
xml = make_eu_invoice(ship_to: false).to_xml(version: 2)
rescue ValidationError => e
pp e.errors
end

refute_match(/<ram:ShipToTradeParty>/, xml)

v = Validator.new(xml, version: 2)
errors = v.validate_against_schema
Expand Down