Module: HrLite::Calculators::ProfessionalTax

Defined in:
app/services/hr_lite/calculators/professional_tax.rb

Overview

State-slab professional tax on earned gross. Slabs may carry a feb_extra for the states that top up the last month's deduction.

Slabs come from hr_lite_professional_tax_slabs, dated per state, falling back to whatever rates hash the caller passes for a host that has not seeded yet. A state nobody configured yields zero — and unconfigured? is how payroll gets to SAY so, because a confident zero is the failure mode here, not an exception.

Class Method Summary collapse

Class Method Details

.call(state:, gross_earned:, period_month:, rates: {}) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'app/services/hr_lite/calculators/professional_tax.rb', line 12

def self.call(state:, gross_earned:, period_month:, rates: {})
  slabs = slabs_for(state, period_month, rates)
  earned = Money.d(gross_earned)

  # `from:` is an INCLUSIVE lower bound — ₹25,000 is taxed, ₹24,999.50 is
  # not. The older exclusive `above:` form still works so a host's own
  # slab table keeps functioning, but it cannot express that boundary on
  # a decimal amount: `above: 24999` taxed a prorated ₹24,999.50.
  slab = slabs.reverse.find { |row| row[:from] ? earned >= row[:from] : earned > row[:above] }
  return BigDecimal(0) unless slab

  amount = slab[:monthly]
  amount += slab[:feb_extra] if slab[:feb_extra] && period_month.month == 2
  Money.round_rupee(amount)
end

.slabs_for(state, period_month, rates = {}) ⇒ Object



28
29
30
31
32
33
# File 'app/services/hr_lite/calculators/professional_tax.rb', line 28

def self.slabs_for(state, period_month, rates = {})
  stored = stored_slabs(state, period_month)
  return stored if stored.present?

  rates[state.to_s] || []
end

.stored_slabs(state, period_month) ⇒ Object



45
46
47
48
49
50
# File 'app/services/hr_lite/calculators/professional_tax.rb', line 45

def self.stored_slabs(state, period_month)
  ProfessionalTaxSlab.table_for(state, period_month)
rescue ActiveRecord::ActiveRecordError
  # Host mid-migration: gem upgraded, db:migrate not yet run.
  []
end

.unconfigured?(state, period_month, rates = {}) ⇒ Boolean

A state with no stored slabs and none in the fallback table. That is NOT the same as a state with no professional tax: Karnataka was the only state ever entered in code, so every other one deducted nothing and nothing said so.

Returns:

  • (Boolean)


39
40
41
42
43
# File 'app/services/hr_lite/calculators/professional_tax.rb', line 39

def self.unconfigured?(state, period_month, rates = {})
  return false if state.to_s == ProfessionalTaxSlab::NO_LEVY

  slabs_for(state, period_month, rates).empty?
end