Class: Tax

Inherits:
Ekylibre::Record::Base show all
Defined in:
app/models/tax.rb

Overview

Informations

License

Ekylibre - Simple agricultural ERP Copyright (C) 2008-2009 Brice Texier, Thibaud Merigon Copyright (C) 2010-2012 Brice Texier Copyright (C) 2012-2019 Brice Texier, David Joulin

This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License along with this program. If not, see www.gnu.org/licenses.

Table: taxes

active                            :boolean          default(FALSE), not null
amount                            :decimal(19, 4)   default(0.0), not null
collect_account_id                :integer
country                           :string           not null
created_at                        :datetime         not null
creator_id                        :integer
deduction_account_id              :integer
description                       :text
fixed_asset_collect_account_id    :integer
fixed_asset_deduction_account_id  :integer
id                                :integer          not null, primary key
intracommunity                    :boolean          default(FALSE), not null
intracommunity_payable_account_id :integer
lock_version                      :integer          default(0), not null
name                              :string           not null
nature                            :string           not null
reference_name                    :string
updated_at                        :datetime         not null
updater_id                        :integer

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Ekylibre::Record::Base

#already_updated?, #check_if_destroyable?, #check_if_updateable?, columns_definition, #customizable?, customizable?, #customized?, #destroyable?, #editable?, has_picture, #human_attribute_name, nomenclature_reflections, #old_record, #others, refers_to, #unsuppress, #updateable?

Methods included from Userstamp::Stampable

included

Methods included from Userstamp::Stamper

included

Class Method Details

.available_naturesObject

Returns TaxNature items which are used by recorded taxes


98
99
100
101
102
103
104
# File 'app/models/tax.rb', line 98

def available_natures
  Nomen::TaxNature.select do |item|
    references = Nomen::Tax.list.keep_if { |tax| tax.nature.to_s == item.name.to_s }
    taxes = Tax.where(reference_name: references.map(&:name))
    taxes.any?
  end
end

.clean!Object


106
107
108
109
110
# File 'app/models/tax.rb', line 106

def clean!
  Tax.find_each do |tax|
    tax.destroy if tax.destroyable?
  end
end

.import_all_from_nomenclature(options = {}) ⇒ Object

Load all tax from tax nomenclature by country


150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'app/models/tax.rb', line 150

def import_all_from_nomenclature(options = {})
  country = options[:country] || Preference[:country]
  today = Time.zone.today
  Nomen::Tax.where(country: country.to_sym).find_each do |tax|
    if options[:active]
      if tax.started_on
        next unless today > tax.started_on
      end
      if tax.stopped_on
        next unless today < tax.stopped_on
      end
    end
    import_from_nomenclature(tax.name, true)
  end
end

.import_from_nomenclature(reference_name, active = nil) ⇒ Object

Load a tax from tax nomenclature


113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'app/models/tax.rb', line 113

def import_from_nomenclature(reference_name, active = nil)
  unless item = Nomen::Tax.find(reference_name)
    raise ArgumentError, "The tax #{reference_name.inspect} is not known"
  end
  tax = Tax.find_by(amount: item.amount, nature: item.nature, country: item.country)
  tax ||= Tax.find_by(reference_name: reference_name)

  if tax
    tax.update_column(:active, active) unless active.nil?
    return tax
  end
  nature = Nomen::TaxNature.find(item.nature)
  if nature.computation_method != :percentage
    raise StandardError, 'Can import only percentage computed taxes'
  end
  attributes = {
    amount: item.amount,
    name: item.human_name,
    nature: item.nature,
    country: item.country,
    active: (active.nil? ? true : active),
    reference_name: item.name
  }
  %i[deduction collect fixed_asset_deduction fixed_asset_collect].each do ||
    next unless name = nature.send("#{}_account")
    tax_radical = Account.find_or_import_from_nomenclature(name)
    # find if already account tax  by number was created
     = Account.find_or_create_by_number("#{tax_radical.number}#{nature.suffix}") do |a|
      a.name = "#{tax_radical.name} - #{item.human_name}"
      a.usages = tax_radical.usages
    end
    attributes["#{}_account_id"] = .id
  end
  Tax.create!(attributes)
end

.load_defaultsObject

Load default taxes of instance country


167
168
169
# File 'app/models/tax.rb', line 167

def load_defaults
  import_all_from_nomenclature(country: Preference[:country].to_sym)
end

.used_for_untaxed_dealsObject


93
94
95
# File 'app/models/tax.rb', line 93

def used_for_untaxed_deals
  where(amount: 0).reorder(:id).first
end

Instance Method Details

#amount_of(pretax_amount) ⇒ Object

Returns the amount of a pretax amount


197
198
199
# File 'app/models/tax.rb', line 197

def amount_of(pretax_amount)
  (pretax_amount.to_d * coefficient)
end

#coefficientObject

Returns the matching coefficient k of the percentage where pretax_amount * k = amount_with_tax


208
209
210
# File 'app/models/tax.rb', line 208

def coefficient
  (100 + usable_amount) / 100
end

#compute(amount, *args) ⇒ Object

Compute the tax amount If with_taxes is true, it's considered that the given amount is an amount with tax


175
176
177
178
179
180
181
182
183
184
# File 'app/models/tax.rb', line 175

def compute(amount, *args)
  options = args.extract_options!
  all_taxes_included = args.shift || options[:all_taxes_included] || false
  percentage = (options[:intracommunity] ? self.amount : usable_amount).to_d / 100
  if all_taxes_included
    amount.to_d * percentage / (1 + percentage)
  else
    amount.to_d * percentage
  end
end

#intracommunity_amount_of(pretax_amount) ⇒ Object

Returns the intracommunity tax amount used in purchase reverse-charge


187
188
189
# File 'app/models/tax.rb', line 187

def intracommunity_amount_of(pretax_amount)
  pretax_amount + compute(pretax_amount, intracommunity: true)
end

#null_amount?Boolean

Returns true if amount is equal to 0

Returns:

  • (Boolean)

202
203
204
# File 'app/models/tax.rb', line 202

def null_amount?
  amount.zero?
end

#pretax_amount_of(with_tax_amount) ⇒ Object

Returns the pretax amount of an amount


192
193
194
# File 'app/models/tax.rb', line 192

def pretax_amount_of(with_tax_amount)
  (with_tax_amount.to_d / coefficient)
end

#short_labelObject

Returns the short label of a tax


219
220
221
# File 'app/models/tax.rb', line 219

def short_label
  "#{amount.l(precision: 0)}% (#{country}) #{nature.l}"
end

#usable_amountObject

Returns a usable amount for sale and purchase i.e. amount when tax is not selected as intracommunity tax


214
215
216
# File 'app/models/tax.rb', line 214

def usable_amount
  intracommunity ? 0 : amount
end