Module: Finrb::Accounting
- Defined in:
- lib/finrb/accounting.rb,
sig/finrb.rbs
Overview
Inventory costing and depreciation calculations.
Class Method Summary collapse
-
.cogs(uinv:, pinv:, units:, price:, sinv:, method: 'FIFO') ⇒ inventory_result
Cost of goods sold and ending inventory under three methods (FIFO,LIFO,Weighted average).
-
.ddb(cost:, rv:, t:) ⇒ { t: Array[Integer], ddb: Array[decimal] }
Depreciation Expense Recognition -- double-declining balance (DDB), the most common declining balance method, which applies two times the straight-line rate to the declining balance.
-
.slde(cost:, rv:, t:) ⇒ decimal
Depreciation Expense Recognition -- Straight-line depreciation (SL) allocates an equal amount of depreciation each year over the asset's useful life.
Class Method Details
.cogs(uinv:, pinv:, units:, price:, sinv:, method: 'FIFO') ⇒ inventory_result
Cost of goods sold and ending inventory under three methods (FIFO,LIFO,Weighted average)
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/finrb/accounting.rb', line 37 def self.cogs(uinv:, pinv:, units:, price:, sinv:, method: 'FIFO') uinv, pinv, units, price, sinv, method = inventory_inputs(uinv:, pinv:, units:, price:, sinv:, method:) n = units.size cost_of_goods = Flt::DecNum(0) ending_inventory = Flt::DecNum(0) case method when 'FIFO' if sinv <= uinv cost_of_goods = sinv * pinv ending_inventory = (uinv - sinv) * pinv (0...n).each do |i| ending_inventory += (units[i] * price[i]) end else cost_of_goods = uinv * pinv sinv -= uinv (0...n).each do |i| if sinv <= units[i] cost_of_goods += (sinv * price[i]) ending_inventory = (units[i] - sinv) * price[i] if i < n temp = i + 1 (temp...n).each do |j| ending_inventory += (units[j] * price[j]) end end sinv = 0 break else cost_of_goods += (units[i] * price[i]) sinv -= units[i] end end raise(DomainError, 'Available inventory is insufficient for the requested sale.') if sinv.positive? end when 'WAC' ending_inventory = uinv * pinv tu = uinv (0...n).each do |i| ending_inventory += (units[i] * price[i]) tu += units[i] end if tu.zero? && sinv.zero? cost_of_goods = Flt::DecNum(0) ending_inventory = Flt::DecNum(0) elsif tu >= sinv cost_of_goods = ending_inventory / tu * sinv ending_inventory = ending_inventory / tu * (tu - sinv) else raise(DomainError, 'Available inventory is insufficient for the requested sale.') end when 'LIFO' (n - 1).downto(0).each do |i| if sinv <= units[i] cost_of_goods += (sinv * price[i]) ending_inventory = (units[i] - sinv) * price[i] if i.positive? temp = i - 1 temp.downto(0).each do |j| ending_inventory += (units[j] * price[j]) end end ending_inventory += (uinv * pinv) sinv = 0 break else cost_of_goods += (units[i] * price[i]) sinv -= units[i] end end if sinv.positive? if sinv <= uinv cost_of_goods += (sinv * pinv) ending_inventory += ((uinv - sinv) * pinv) else raise(DomainError, 'Available inventory is insufficient for the requested sale.') end end end { cost_of_goods:, ending_inventory: } end |
.ddb(cost:, rv:, t:) ⇒ { t: Array[Integer], ddb: Array[decimal] }
Depreciation Expense Recognition -- double-declining balance (DDB), the most common declining balance method, which applies two times the straight-line rate to the declining balance.
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/finrb/accounting.rb', line 146 def self.ddb(cost:, rv:, t:) cost = Validation.non_negative_decimal(cost, name: 'asset cost') rv = residual_value(rv, cost:) t = Validation.positive_integer(t, name: 'useful life') raise(DomainError, 'Useful life must be at least 2 periods for double-declining depreciation.') if t < 2 ddb = [Flt::DecNum(0)] * t ddb[0] = cost * 2 / t if cost - ddb.first <= rv ddb[0] = cost - rv else cost -= ddb.first (1...t).each do |i| ddb[i] = cost * 2 / t if cost - ddb[i] <= rv ddb[i] = cost - rv break else cost -= ddb[i] end end end { t: (0...t).to_a, ddb: } end |
.slde(cost:, rv:, t:) ⇒ decimal
Depreciation Expense Recognition -- Straight-line depreciation (SL) allocates an equal amount of depreciation each year over the asset's useful life
178 179 180 181 182 183 184 |
# File 'lib/finrb/accounting.rb', line 178 def self.slde(cost:, rv:, t:) cost = Validation.non_negative_decimal(cost, name: 'asset cost') rv = residual_value(rv, cost:) t = Validation.positive_decimal(t, name: 'useful life', error: DomainError) ((cost - rv) / t) end |