Class: HrLite::TaxDeclaration

Inherits:
ApplicationRecord show all
Includes:
Audited
Defined in:
app/models/hr_lite/tax_declaration.rb

Overview

What an employee claims for the year, section by section, replacing the single declared_annual_deductions figure an admin used to type in.

The whole year's TDS is projected from this number, so it matters that it is broken down, that the employee submitted it themselves, and that HR can record what the proof actually supported.

Constant Summary collapse

STATUSES =
%w[draft submitted verified rejected].freeze
REGIMES =
%w[new old].freeze

Constants included from Audited

Audited::REDACTED, Audited::SKIPPED_ATTRIBUTES

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.for(user, period_month) ⇒ Object



32
33
34
# File 'app/models/hr_lite/tax_declaration.rb', line 32

def self.for(user, period_month)
  find_by(user_id: user.id, financial_year: FinancialYear.start_for(period_month))
end

Instance Method Details

#allowable_totalObject

What payroll should actually deduct against. Until HR has verified it, the declared figure stands — asking somebody to overpay tax all year because paperwork is slow is its own kind of wrong — but once verified, only what the proof supported counts.



44
45
46
47
48
# File 'app/models/hr_lite/tax_declaration.rb', line 44

def allowable_total
  return declared_total unless verified?

  tax_declaration_items.sum(BigDecimal(0)) { |i| i.verified_amount || BigDecimal(0) }
end

#declared_totalObject



38
# File 'app/models/hr_lite/tax_declaration.rb', line 38

def declared_total = tax_declaration_items.sum(BigDecimal(0)) { |i| i.declared_amount || 0 }

#labelObject



36
# File 'app/models/hr_lite/tax_declaration.rb', line 36

def label = "FY #{FinancialYear.label(financial_year)}"

#reject!(actor:, note:) ⇒ Object

Raises:

  • (ArgumentError)


72
73
74
75
76
77
78
# File 'app/models/hr_lite/tax_declaration.rb', line 72

def reject!(actor:, note:)
  raise ArgumentError, "a rejection needs a reason" if note.blank?

  update!(status: "rejected", verified_by_id: actor.id, verified_at: Time.current, note: note)
  notify_employee("Your #{label} tax declaration needs attention")
  true
end

#submit!(actor:) ⇒ Object

Raises:

  • (ActiveRecord::RecordInvalid.new(self))


50
51
52
53
54
55
56
57
58
59
60
61
# File 'app/models/hr_lite/tax_declaration.rb', line 50

def submit!(actor:)
  raise ActiveRecord::RecordInvalid.new(self), "not a draft" unless draft? || rejected?

  update!(status: "submitted", submitted_at: Time.current)
  Notifications.publish(
    "tax.declaration_submitted",
    title: "#{HrLite.display_name(user)} submitted a #{label} tax declaration",
    path: "/admin/tax_declarations/#{id}",
    bell_to: HrLite.users_holding("tax.manage").to_a
  )
  true
end

#verify!(actor:, note: nil) ⇒ Object

Raises:

  • (ActiveRecord::RecordInvalid.new(self))


63
64
65
66
67
68
69
70
# File 'app/models/hr_lite/tax_declaration.rb', line 63

def verify!(actor:, note: nil)
  raise ActiveRecord::RecordInvalid.new(self), "not submitted" unless 

  update!(status: "verified", verified_by_id: actor.id, verified_at: Time.current,
          note: note.presence)
  notify_employee("Your #{label} tax declaration was verified")
  true
end