Skip to content

Instantly share code, notes, and snippets.

@dachinat
Created December 3, 2021 17:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dachinat/4df603b6912574ca5e964daeb2c702bd to your computer and use it in GitHub Desktop.
Save dachinat/4df603b6912574ca5e964daeb2c702bd to your computer and use it in GitHub Desktop.
InvoiceItem model from one of my projects
class InvoiceItem < ApplicationRecord
# Constants
# Includes
# include AccountScope
include AASM
aasm column: "status", requires_lock: true do
state :pending, initial: true
state :closed
event :close do
transitions from: :pending, to: :closed
end
end
# Serialization
# Associations
belongs_to :billed_item, polymorphic: true, optional: true
belongs_to :invoice
# Delegations
# Callbacks
# Validations
validates :name, presence: true
validates :unit_price, presence: true,
numericality: {
greater_than_or_equal_to: 0.000001,
less_than_or_equal_to: 999999.999999
}
validates_numericality_of :units, only_integer: true, allow_nil: true
validates :units, presence: true, allow_nil: true
validates :total, presence: true,
numericality: {
greater_than_or_equal_to: 0,
less_than_or_equal_to: 999999.9999
}, allow_nil: true
validates :started_at, presence: true, datetime: true
validates :ended_at, datetime: true
validates :status, length: { minimum: 1, maximum: 64 }, allow_blank: false
# Named Scopes
scope :pending_state, ->() { where(status: "pending") }
scope :for_item, ->(billed_item) { where(billed_item: billed_item) }
# Class Methods
# Instance Methods
def calculated_units
hours = units || (((ended_at || Time.zone.now) - self.started_at) / 3600).to_f.ceil
[730, hours].min
end
def calculated_total
total || (calculated_units * unit_price).round(2)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment