Module: SK::Calc::Items

Defined in:
lib/sk_calc/items.rb

Overview

Calculate totals for a multiple items eg in an invoice Including class MUST respond to:

  • price_total: the sum of all items net totals, you must call #sum_items yourself to fill this and price tax

  • price_tax: the tax total for all items

  • line_items

Instance Method Summary collapse

Instance Method Details

#gross_totalRational

Gross total rounded to 2 decimals

Returns:

  • (Rational)


26
27
28
# File 'lib/sk_calc/items.rb', line 26

def gross_total
  gross_total_base.round(2)
end

#gross_total_baseRational

Gross total unrounded

Returns:

  • (Rational)


15
16
17
# File 'lib/sk_calc/items.rb', line 15

def gross_total_base
  (net_total_base || 0) + tax_total_base
end

#net_totalObject

Net total rounded to 2 decimals



20
21
22
# File 'lib/sk_calc/items.rb', line 20

def net_total
  net_total_base.round(2)
end

#net_total_baseRational

Unrounded net total which is the sum of all items net_total, the taxation base

Returns:

  • (Rational)


9
10
11
# File 'lib/sk_calc/items.rb', line 9

def net_total_base
  conv_price_total
end

#sum_items(items = nil) ⇒ Object

Save items sums of net total and summed taxes into the price_total, tax_total



44
45
46
47
48
49
50
51
# File 'lib/sk_calc/items.rb', line 44

def sum_items(items=nil)
  items ||= line_items
  # Sum up all the total prices of the items.
  # .to_a to get out of activerecord collection into enum
  self.price_total = items.to_a.sum(&:net_total_base)
  # Sum up the tax, but use the tax_grouped to prevent rounding errors
  self.price_tax = tax_grouped(items).sum { |tax_group| tax_group[1] }
end

#tax_grouped(items = nil) ⇒ Array<Array>

Sums up the tax price of the line items, grouped by tax

Sums up the price_total and calculate the tax -does not sum price_tax because of rounding errors! Returns a sorted sorted hash

{ [ 7, 3.50 ], [ 19, 47.50 ] } for each price/tax combination

So if you are using two kinds of tax (7%/19%) in an document:

0

>

[0] => 7      # the tax percentage
[1] => 14.00  # tax sum of all line item with this tax (items summ is 200.00)
1

>

[0] => 19
[1] => 57   #(items sum = 300)

Returns:

  • (Array<Array>)


71
72
73
74
75
76
77
78
79
# File 'lib/sk_calc/items.rb', line 71

def tax_grouped(items=nil)
  items ||= line_items
  result = {}
  items.group_by(&:tax).each do |tax, item_group|
    net_total_sum = item_group.to_a.sum(&:net_total_base)
    result[tax] = (net_total_sum * tax.to_r / 100.0).round(SK::Calc.precision) if tax && !tax.zero?
  end
  result.sort
end

#tax_grouped_details(items = nil) ⇒ Array<Hash<Symbol,Mixed>>

Returns:

  • (Array<Hash<Symbol,Mixed>>)


82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/sk_calc/items.rb', line 82

def tax_grouped_details(items=nil)
  items ||= line_items
  result = []
  items.group_by(&:tax).each do |tax, item_group|
    net_total_sum = item_group.to_a.sum(&:net_total_base)
    tax_total = if tax && !tax.zero?
                  (net_total_sum * tax.to_r / 100.0).round(SK::Calc.precision)
                else
                  0.0
                end
    result << {
      tax: tax,
      net_total: net_total_sum,
      gross_total: net_total_sum+tax_total,
      tax_total: tax_total,
    }
  end
  result.sort{|a,b| a[:tax] <=> b[:tax]}
end

#tax_totalRational

Tax total rounded price_tax to 2 decimals

Returns:

  • (Rational)


38
39
40
# File 'lib/sk_calc/items.rb', line 38

def tax_total
  conv_tax.round(2)
end

#tax_total_baseRational

Tax total rounded price_tax to 2 decimals

Returns:

  • (Rational)


32
33
34
# File 'lib/sk_calc/items.rb', line 32

def tax_total_base
  conv_tax
end