Skip to content

Commit c8974c5

Browse files
authored
Merge pull request #35 from ronald/feature/add-line-item-service-period
add fields for LineItem#service_period_start / service_period_end (BT-134, BT-135)
2 parents 186306b + 1c43705 commit c8974c5

File tree

3 files changed

+99
-0
lines changed

3 files changed

+99
-0
lines changed

lib/secretariat/constants.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ module Secretariat
6969
TAX_CALCULATION_METHODS = %i[HORIZONTAL VERTICAL NONE UNKNOWN].freeze
7070

7171
UNIT_CODES = {
72+
:YEAR => "ANN",
7273
:PIECE => "C62",
7374
:DAY => "DAY",
7475
:HECTARE => "HAR",

lib/secretariat/line_item.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ module Secretariat
3232
:charge_amount,
3333
:origin_country_code,
3434
:currency_code,
35+
:service_period_start, # if start present start & end are required
36+
:service_period_end, # end has to be on or after start (secretariat does not validate this)
3537
keyword_init: true
3638
) do
3739

@@ -181,6 +183,22 @@ def to_xml(xml, line_item_index, version: 2, validate: true)
181183
xml['ram'].send(percent,Helpers.format(tax_percent))
182184
end
183185
end
186+
187+
if version == 2 && self.service_period_start && self.service_period_end
188+
xml['ram'].BillingSpecifiedPeriod do
189+
xml['ram'].StartDateTime do
190+
xml['udt'].DateTimeString(format: '102') do
191+
xml.text(service_period_start.strftime("%Y%m%d"))
192+
end
193+
end
194+
xml['ram'].EndDateTime do
195+
xml['udt'].DateTimeString(format: '102') do
196+
xml.text(service_period_end.strftime("%Y%m%d"))
197+
end
198+
end
199+
end
200+
end
201+
184202
monetary_summation = by_version(version, 'SpecifiedTradeSettlementMonetarySummation', 'SpecifiedTradeSettlementLineMonetarySummation')
185203
xml['ram'].send(monetary_summation) do
186204
Helpers.currency_element(xml, 'ram', 'LineTotalAmount', (quantity.negative? ? -charge_amount : charge_amount), currency_code, add_currency: version == 1)

test/invoice_test.rb

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,61 @@ def make_eu_invoice(tax_category: :REVERSECHARGE)
5757
)
5858
end
5959

60+
def make_eu_invoice_with_line_item_billing_period(tax_category: :REVERSECHARGE)
61+
seller = TradeParty.new(
62+
name: 'Depfu inc',
63+
street1: 'Quickbornstr. 46',
64+
city: 'Hamburg',
65+
postal_code: '20253',
66+
country_id: 'DE',
67+
vat_id: 'DE304755032'
68+
)
69+
buyer = TradeParty.new(
70+
name: 'Depfu inc',
71+
street1: 'Quickbornstr. 46',
72+
city: 'Hamburg',
73+
postal_code: '20253',
74+
country_id: 'SE',
75+
vat_id: 'SE304755032'
76+
)
77+
line_item = LineItem.new(
78+
name: 'Depfu Premium Plan',
79+
quantity: 1,
80+
gross_amount: BigDecimal('29'),
81+
net_amount: BigDecimal('29'),
82+
unit: :YEAR,
83+
charge_amount: BigDecimal('29'),
84+
tax_category: tax_category,
85+
tax_percent: 0,
86+
tax_amount: 0,
87+
origin_country_code: 'DE',
88+
currency_code: 'EUR',
89+
service_period_start: Date.today,
90+
service_period_end: Date.today + 364,
91+
)
92+
Invoice.new(
93+
id: '12345',
94+
issue_date: Date.today,
95+
# service_period on line_item. removed here to simplify testing of BillingSpecifiedPeriod presence
96+
# service_period_start: Date.today,
97+
# service_period_end: Date.today + 30,
98+
seller: seller,
99+
buyer: buyer,
100+
line_items: [line_item],
101+
currency_code: 'USD',
102+
payment_type: :CREDITCARD,
103+
payment_text: 'Kreditkarte',
104+
tax_category: tax_category,
105+
tax_amount: 0,
106+
basis_amount: BigDecimal('29'),
107+
grand_total_amount: BigDecimal('29'),
108+
due_amount: 0,
109+
paid_amount: 29,
110+
payment_due_date: Date.today + 14,
111+
notes: "This is a test invoice",
112+
)
113+
end
114+
60115
def make_foreign_invoice(tax_category: :TAXEXEMPT)
61116
seller = TradeParty.new(
62117
name: 'Depfu inc',
@@ -381,6 +436,31 @@ def test_simple_eu_invoice_v2
381436
puts e.errors
382437
end
383438

439+
def test_simple_eu_invoice_v2_with_line_item_billing_period
440+
begin
441+
xml = make_eu_invoice_with_line_item_billing_period.to_xml(version: 2)
442+
rescue ValidationError => e
443+
pp e.errors
444+
end
445+
446+
assert_match(/<ram:CategoryCode>AE<\/ram:CategoryCode>/, xml)
447+
assert_match(/<ram:ExemptionReason>Reverse Charge<\/ram:ExemptionReason>/, xml)
448+
assert_match(/<ram:RateApplicablePercent>/, xml)
449+
assert_match(/<ram:BillingSpecifiedPeriod>/, xml)
450+
451+
v = Validator.new(xml, version: 2)
452+
errors = v.validate_against_schema
453+
if !errors.empty?
454+
puts xml
455+
errors.each do |error|
456+
puts error
457+
end
458+
end
459+
assert_equal [], errors
460+
rescue ValidationError => e
461+
puts e.errors
462+
end
463+
384464
def test_simple_foreign_invoice_v2_taxexpempt
385465
begin
386466
xml = make_foreign_invoice(tax_category: :TAXEXEMPT).to_xml(version: 2)

0 commit comments

Comments
 (0)