Separa heatmap mobile/desktop, opt-out analytics per operatori, dashboard costi con KPI e trend mensili. Co-authored-by: Cursor <cursoragent@cursor.com>
52 lines
1.2 KiB
Ruby
52 lines
1.2 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class PlatformCostEntry < ApplicationRecord
|
|
DEFAULT_LABEL = "Piattaforma produzione"
|
|
|
|
validates :month, presence: true
|
|
validates :label, presence: true, length: { maximum: 120 }
|
|
validates :amount_cents, numericality: { only_integer: true, greater_than: 0 }
|
|
|
|
before_validation :normalize_month
|
|
|
|
scope :for_month, ->(date) { where(month: date.to_date.beginning_of_month) }
|
|
scope :ordered, -> { order(month: :desc, created_at: :desc) }
|
|
|
|
def month=(value)
|
|
if value.is_a?(String) && value.match?(/\A\d{4}-\d{2}\z/)
|
|
super(Date.strptime(value, "%Y-%m"))
|
|
else
|
|
super(value)
|
|
end
|
|
end
|
|
|
|
def amount_euros
|
|
amount_cents.to_f / 100.0
|
|
end
|
|
|
|
private
|
|
|
|
def normalize_month
|
|
return if month.blank?
|
|
|
|
parsed =
|
|
case month
|
|
when Date
|
|
month
|
|
when Time, ActiveSupport::TimeWithZone
|
|
month.to_date
|
|
when String
|
|
if month.match?(/\A\d{4}-\d{2}\z/)
|
|
Date.strptime(month, "%Y-%m")
|
|
else
|
|
Date.parse(month)
|
|
end
|
|
else
|
|
Date.parse(month.to_s)
|
|
end
|
|
self.month = parsed.beginning_of_month
|
|
rescue ArgumentError, TypeError
|
|
errors.add(:month, :invalid)
|
|
end
|
|
end
|