Skip to content

Commit 8d7f07b

Browse files
ahmedm10halfbyte
authored andcommitted
delete quantity and use basis_quantity and billed_quantity
1 parent c8974c5 commit 8d7f07b

File tree

2 files changed

+43
-11
lines changed

2 files changed

+43
-11
lines changed

lib/secretariat/invoice.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,11 @@ def taxes
8282
line_items.each do |line_item|
8383
if line_item.tax_percent.nil?
8484
taxes['0'] = Tax.new(tax_percent: BigDecimal(0), tax_category: line_item.tax_category, tax_amount: BigDecimal(0)) if taxes['0'].nil?
85-
taxes['0'].base_amount += BigDecimal(line_item.net_amount) * line_item.quantity
85+
taxes['0'].base_amount += BigDecimal(line_item.net_amount) * line_item.billed_quantity
8686
else
8787
taxes[line_item.tax_percent] = Tax.new(tax_percent: BigDecimal(line_item.tax_percent), tax_category: line_item.tax_category) if taxes[line_item.tax_percent].nil?
8888
taxes[line_item.tax_percent].tax_amount += BigDecimal(line_item.tax_amount)
89-
taxes[line_item.tax_percent].base_amount += BigDecimal(line_item.net_amount) * line_item.quantity
89+
taxes[line_item.tax_percent].base_amount += BigDecimal(line_item.net_amount) * line_item.billed_quantity
9090
end
9191
end
9292

@@ -140,7 +140,7 @@ def valid?
140140
return false
141141
end
142142
line_item_sum = line_items.inject(BigDecimal(0)) do |m, item|
143-
m + BigDecimal(item.quantity.negative? ? -item.charge_amount : item.charge_amount)
143+
m + BigDecimal(item.billed_quantity.negative? ? -item.charge_amount : item.charge_amount)
144144
end
145145
if line_item_sum != basis
146146
@errors << "Line items do not add up to basis amount #{line_item_sum} / #{basis}"

lib/secretariat/line_item.rb

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ module Secretariat
2020

2121
LineItem = Struct.new('LineItem',
2222
:name,
23-
:quantity,
23+
:billed_quantity,
2424
:unit,
2525
:gross_amount,
2626
:net_amount,
@@ -34,11 +34,36 @@ module Secretariat
3434
:currency_code,
3535
:service_period_start, # if start present start & end are required
3636
:service_period_end, # end has to be on or after start (secretariat does not validate this)
37+
:basis_quantity,
3738
keyword_init: true
3839
) do
3940

4041
include Versioner
4142

43+
def initialize(**kwargs)
44+
if kwargs.key?(:quantity) && !kwargs.key?(:billed_quantity)
45+
kwargs[:billed_quantity] = kwargs.delete(:quantity)
46+
end
47+
super(**kwargs)
48+
end
49+
50+
def quantity
51+
warn_once_quantity
52+
billed_quantity
53+
end
54+
55+
def quantity=(val)
56+
warn_once_quantity
57+
self.billed_quantity = val
58+
end
59+
60+
def warn_once_quantity
61+
unless @__warned_quantity
62+
Kernel.warn("[secretariat] LineItem#quantity is deprecated; use #billed_quantity")
63+
@__warned_quantity = true
64+
end
65+
end
66+
4267
def errors
4368
@errors
4469
end
@@ -49,7 +74,7 @@ def valid?
4974
gross_price = BigDecimal(gross_amount)
5075
charge_price = BigDecimal(charge_amount)
5176
tax = BigDecimal(tax_amount)
52-
unit_price = net_price * BigDecimal(quantity.abs)
77+
unit_price = net_price * BigDecimal(billed_quantity.abs)
5378

5479
if charge_price != unit_price
5580
@errors << "charge price and gross price times quantity deviate: #{charge_price} / #{unit_price}"
@@ -67,7 +92,7 @@ def valid?
6792
self.tax_percent ||= BigDecimal(0)
6893
calculated_tax = charge_price * BigDecimal(tax_percent) / BigDecimal(100)
6994
calculated_tax = calculated_tax.round(2)
70-
calculated_tax = -calculated_tax if quantity.negative?
95+
calculated_tax = -calculated_tax if billed_quantity.negative?
7196
if calculated_tax != tax
7297
@errors << "Tax and calculated tax deviate: #{tax} / #{calculated_tax}"
7398
return false
@@ -80,6 +105,13 @@ def unit_code
80105
UNIT_CODES[unit] || 'C62'
81106
end
82107

108+
# If not provided, BasisQuantity should be 1.0 (price per 1 unit)
109+
def effective_basis_quantity
110+
q = basis_quantity.nil? ? BigDecimal("1.0") : BigDecimal(basis_quantity.to_s)
111+
raise ArgumentError, "basis_quantity must be > 0" if q <= 0
112+
q
113+
end
114+
83115
def tax_category_code(version: 2)
84116
if version == 1
85117
return TAX_CATEGORY_CODES_1[tax_category] || 'S'
@@ -105,7 +137,7 @@ def to_xml(xml, line_item_index, version: 2, validate: true)
105137
if net_price&.negative?
106138
# Zugferd doesn't allow negative amounts at the item level.
107139
# Instead, a negative quantity is used.
108-
self.quantity = -quantity
140+
self.billed_quantity = -billed_quantity
109141
self.gross_amount = gross_price&.abs
110142
self.net_amount = net_price&.abs
111143
self.charge_amount = charge_price&.abs
@@ -134,7 +166,7 @@ def to_xml(xml, line_item_index, version: 2, validate: true)
134166
Helpers.currency_element(xml, 'ram', 'ChargeAmount', gross_amount, currency_code, add_currency: version == 1, digits: 4)
135167
if version == 2 && discount_amount
136168
xml['ram'].BasisQuantity(unitCode: unit_code) do
137-
xml.text(Helpers.format(quantity, digits: 4))
169+
xml.text(Helpers.format(effective_basis_quantity, digits: 4))
138170
end
139171
xml['ram'].AppliedTradeAllowanceCharge do
140172
xml['ram'].ChargeIndicator do
@@ -158,7 +190,7 @@ def to_xml(xml, line_item_index, version: 2, validate: true)
158190
Helpers.currency_element(xml, 'ram', 'ChargeAmount', net_amount, currency_code, add_currency: version == 1, digits: 4)
159191
if version == 2
160192
xml['ram'].BasisQuantity(unitCode: unit_code) do
161-
xml.text(Helpers.format(quantity, digits: 4))
193+
xml.text(Helpers.format(effective_basis_quantity, digits: 4))
162194
end
163195
end
164196
end
@@ -168,7 +200,7 @@ def to_xml(xml, line_item_index, version: 2, validate: true)
168200

169201
xml['ram'].send(delivery) do
170202
xml['ram'].BilledQuantity(unitCode: unit_code) do
171-
xml.text(Helpers.format(quantity, digits: 4))
203+
xml.text(Helpers.format(billed_quantity, digits: 4))
172204
end
173205
end
174206

@@ -201,7 +233,7 @@ def to_xml(xml, line_item_index, version: 2, validate: true)
201233

202234
monetary_summation = by_version(version, 'SpecifiedTradeSettlementMonetarySummation', 'SpecifiedTradeSettlementLineMonetarySummation')
203235
xml['ram'].send(monetary_summation) do
204-
Helpers.currency_element(xml, 'ram', 'LineTotalAmount', (quantity.negative? ? -charge_amount : charge_amount), currency_code, add_currency: version == 1)
236+
Helpers.currency_element(xml, 'ram', 'LineTotalAmount', (billed_quantity.negative? ? -charge_amount : charge_amount), currency_code, add_currency: version == 1)
205237
end
206238
end
207239

0 commit comments

Comments
 (0)