Class: HrLite::Document

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

Overview

An employee's document: an Aadhaar scan, a PAN, an offer letter, a certificate. The FILE is the sensitive part, so visibility is a property of the row and every read goes through readable_by?.

Constant Summary collapse

VISIBILITIES =
%w[self hr money].freeze
VERIFICATIONS =
%w[pending verified rejected].freeze
SENSITIVE_CATEGORIES =

Categories the engine knows how to reason about. An install may store any string; these are the ones with an opinion attached.

%w[aadhaar pan passport bank].freeze
ALLOWED_TYPES =

Active Storage content-sniffs via Marcel, so this checks the real bytes rather than whatever the client claimed. SVG and HTML stay out — both can carry script and both render in a browser.

%w[
  application/pdf image/jpeg image/png image/heic image/webp
].freeze
MAX_BYTES =
10.megabytes

Constants included from Audited

Audited::REDACTED, Audited::SKIPPED_ATTRIBUTES

Instance Method Summary collapse

Instance Method Details

#expired?(on = Date.current) ⇒ Boolean

Returns:

  • (Boolean)


42
# File 'app/models/hr_lite/document.rb', line 42

def expired?(on = Date.current) = expires_on.present? && expires_on < on

#readable_by?(reader) ⇒ Boolean

Who may open the FILE. The owner always may; beyond that it is the permission the row's visibility names. A passport is not a payslip and neither is HR's to browse by default.

Returns:

  • (Boolean)


47
48
49
50
51
52
53
54
55
56
# File 'app/models/hr_lite/document.rb', line 47

def readable_by?(reader)
  return false if reader.nil?
  return true if reader.id == user_id

  case visibility
  when "self" then false
  when "hr" then HrLite.reaches?(reader, "document.view", user)
  when "money" then HrLite.can?(reader, "document.manage", scope: :all)
  end
end

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

Raises:

  • (ArgumentError)


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

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

  update!(verification: "rejected", verified_by_id: actor.id,
          verified_at: Time.current, verification_note: note)
end

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



58
59
60
61
# File 'app/models/hr_lite/document.rb', line 58

def verify!(actor:, note: nil)
  update!(verification: "verified", verified_by_id: actor.id,
          verified_at: Time.current, verification_note: note.presence)
end