1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2024-12-11 22:24:21 +01:00
fab-manager/app/models/plan.rb

147 lines
5.5 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
# Plan is a generic description of a subscription plan, which can be subscribed by a member to benefit from advantageous prices.
# Subscribers can also get some Credits for some reservable items
2020-03-25 10:16:47 +01:00
class Plan < ApplicationRecord
2016-03-23 18:39:41 +01:00
belongs_to :group
2021-06-08 16:32:19 +02:00
belongs_to :plan_category
2016-03-23 18:39:41 +01:00
has_many :credits, dependent: :destroy
has_many :training_credits, -> { where(creditable_type: 'Training') }, class_name: 'Credit', dependent: :destroy, inverse_of: :plan
has_many :machine_credits, -> { where(creditable_type: 'Machine') }, class_name: 'Credit', dependent: :destroy, inverse_of: :plan
has_many :space_credits, -> { where(creditable_type: 'Space') }, class_name: 'Credit', dependent: :destroy, inverse_of: :plan
has_many :subscriptions, dependent: :nullify
2016-03-23 18:39:41 +01:00
has_one :plan_file, as: :viewable, dependent: :destroy
has_many :prices, dependent: :destroy
has_one :payment_gateway_object, -> { order id: :desc }, inverse_of: :plan, as: :item, dependent: :destroy
2016-03-23 18:39:41 +01:00
2022-12-28 17:51:27 +01:00
has_many :cart_item_machine_reservations, class_name: 'CartItem::MachineReservation', dependent: :destroy
has_many :cart_item_space_reservations, class_name: 'CartItem::SpaceReservation', dependent: :destroy
has_many :cart_item_training_reservations, class_name: 'CartItem::TrainingReservation', dependent: :destroy
has_many :cart_item_subscriptions, class_name: 'CartItem::Subscription', dependent: :destroy
has_many :cart_item_payment_schedules, class_name: 'CartItem::PaymentSchedule', dependent: :destroy
2017-01-09 10:54:30 +01:00
extend FriendlyId
friendly_id :base_name, use: :slugged
2017-01-09 10:54:30 +01:00
2016-03-23 18:39:41 +01:00
accepts_nested_attributes_for :prices
accepts_nested_attributes_for :plan_file, allow_destroy: true, reject_if: :all_blank
has_one :advanced_accounting, as: :accountable, dependent: :destroy
accepts_nested_attributes_for :advanced_accounting, allow_destroy: true
2016-03-23 18:39:41 +01:00
after_create :create_machines_prices
2017-03-01 16:45:05 +01:00
after_create :create_spaces_prices
2016-03-23 18:39:41 +01:00
after_create :create_statistic_type
after_create :set_name
after_create :update_gateway_product
after_update :update_gateway_product, if: :saved_change_to_base_name?
2016-03-23 18:39:41 +01:00
validates :amount, :group, :base_name, presence: true
validates :interval_count, numericality: { only_integer: true, greater_than_or_equal_to: 1 }
validates :interval_count, numericality: { less_than: 13 }, if: proc { |plan| plan.interval == 'month' }
validates :interval_count, numericality: { less_than: 53 }, if: proc { |plan| plan.interval == 'week' }
validates :interval, inclusion: { in: %w[year month week] }
validates :base_name, :slug, presence: true
2016-03-23 18:39:41 +01:00
def self.create_for_all_groups(plan_params)
plans = []
Group.where(disabled: [nil, false]).find_each do |group|
plan = if plan_params[:type] == 'PartnerPlan'
PartnerPlan.new(plan_params.except(:group_id, :type))
else
Plan.new(plan_params.except(:group_id, :type))
end
2016-03-23 18:39:41 +01:00
plan.group = group
if plan.save
plans << plan
else
plans.each(&:destroy)
return false
end
end
plans
2016-03-23 18:39:41 +01:00
end
def destroyable?
subscriptions.empty?
end
def create_machines_prices
Machine.all.find_each do |machine|
default_price = Price.find_by(priceable: machine, plan: nil, group_id: group_id)&.amount || 0
Price.create(priceable: machine, plan: self, group_id: group_id, amount: default_price)
2016-03-23 18:39:41 +01:00
end
end
2017-03-01 16:45:05 +01:00
def create_spaces_prices
Space.all.find_each do |space|
default_price = Price.find_by(priceable: space, plan: nil, group_id: group_id)&.amount || 0
Price.create(priceable: space, plan: self, group_id: group_id, amount: default_price)
2017-03-01 16:45:05 +01:00
end
end
2016-03-23 18:39:41 +01:00
def duration
interval_count.send(interval)
end
def human_readable_duration
i18n_key = "duration.#{interval}"
I18n.t(i18n_key, count: interval_count).to_s
2016-03-23 18:39:41 +01:00
end
def human_readable_name(opts = {})
result = base_name.to_s
2016-03-23 18:39:41 +01:00
result += " - #{group.slug}" if opts[:group]
result + " - #{human_readable_duration}"
end
# must be publicly accessible for the migration
def create_statistic_type
stat_index = StatisticIndex.where(es_type_key: 'subscription')
type = find_statistic_type
if type.nil?
type = StatisticType.create!(
statistic_index_id: stat_index.first.id,
key: duration.to_i,
label: "#{I18n.t('statistics.duration')} : #{human_readable_duration}",
graph: true,
simple: true
)
2016-03-23 18:39:41 +01:00
end
subtype = create_statistic_subtype
create_statistic_association(type, subtype)
end
def find_statistic_type
stat_index = StatisticIndex.where(es_type_key: 'subscription')
type = StatisticType.find_by(statistic_index_id: stat_index.first.id, key: duration.to_i)
return type if type
StatisticType.where(statistic_index_id: stat_index.first.id).where('label LIKE ?', "%#{human_readable_duration}%").first
end
2016-03-23 18:39:41 +01:00
private
2016-03-23 18:39:41 +01:00
def create_statistic_subtype
StatisticSubType.create!(key: slug, label: name)
2016-03-23 18:39:41 +01:00
end
def create_statistic_association(stat_type, stat_subtype)
if !stat_type.nil? && !stat_subtype.nil?
StatisticTypeSubType.create!(statistic_type: stat_type, statistic_sub_type: stat_subtype)
2016-03-23 18:39:41 +01:00
else
Rails.logger.error 'Unable to create the statistics association for the new plan. ' \
'Possible causes: the type or the subtype were not created successfully.'
2016-03-23 18:39:41 +01:00
end
end
def set_name
update_columns(name: human_readable_name) # rubocop:disable Rails/SkipsModelValidations
end
def update_gateway_product
2021-11-10 17:06:21 +01:00
PaymentGatewayService.new.create_or_update_product(Plan.name, id)
end
2016-03-23 18:39:41 +01:00
end