Admin analytics: heatmap per device, anteprima staff e analisi costi.
Separa heatmap mobile/desktop, opt-out analytics per operatori, dashboard costi con KPI e trend mensili. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user