mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-25 20:46:48 +00:00
108 lines
3.8 KiB
Ruby
108 lines
3.8 KiB
Ruby
class EnterpriseRelationship < ActiveRecord::Base
|
|
belongs_to :parent, class_name: 'Enterprise', touch: true
|
|
belongs_to :child, class_name: 'Enterprise', touch: true
|
|
has_many :permissions, class_name: 'EnterpriseRelationshipPermission', dependent: :destroy
|
|
|
|
validates :parent_id, :child_id, presence: true
|
|
validates :child_id, uniqueness: {
|
|
scope: :parent_id,
|
|
message: I18n.t('validation_msg_relationship_already_established')
|
|
}
|
|
|
|
after_save :update_permissions_of_child_variant_overrides
|
|
before_destroy :revoke_all_child_variant_overrides
|
|
|
|
scope :with_enterprises, -> {
|
|
joins("
|
|
LEFT JOIN enterprises AS parent_enterprises
|
|
ON parent_enterprises.id = enterprise_relationships.parent_id").
|
|
joins("
|
|
LEFT JOIN enterprises AS child_enterprises
|
|
ON child_enterprises.id = enterprise_relationships.child_id")
|
|
}
|
|
|
|
scope :involving_enterprises, ->(enterprises) {
|
|
where('parent_id IN (?) OR child_id IN (?)', enterprises.select(&:id), enterprises.select(&:id))
|
|
}
|
|
|
|
scope :permitting, ->(enterprise_ids) { where('child_id IN (?)', enterprise_ids) }
|
|
scope :permitted_by, ->(enterprise_ids) { where('parent_id IN (?)', enterprise_ids) }
|
|
|
|
scope :with_permission, ->(permission) {
|
|
joins(:permissions).
|
|
where('enterprise_relationship_permissions.name = ?', permission)
|
|
}
|
|
|
|
scope :by_name, -> { with_enterprises.order('child_enterprises.name, parent_enterprises.name') }
|
|
|
|
# Load an array of the relatives of each enterprise (ie. any enterprise related to it in
|
|
# either direction). This array is split into distributors and producers, and has the format:
|
|
# {enterprise_id => {distributors: [id, ...], producers: [id, ...]} }
|
|
def self.relatives(activated_only = false)
|
|
relationships = EnterpriseRelationship.includes(:child, :parent)
|
|
relatives = {}
|
|
|
|
Enterprise.is_primary_producer.pluck(:id).each do |enterprise_id|
|
|
relatives[enterprise_id] ||= { distributors: Set.new, producers: Set.new }
|
|
relatives[enterprise_id][:producers] << enterprise_id
|
|
end
|
|
Enterprise.is_distributor.pluck(:id).each do |enterprise_id|
|
|
relatives[enterprise_id] ||= { distributors: Set.new, producers: Set.new }
|
|
relatives[enterprise_id][:distributors] << enterprise_id
|
|
end
|
|
|
|
relationships.each do |r|
|
|
relatives[r.parent_id] ||= { distributors: Set.new, producers: Set.new }
|
|
relatives[r.child_id] ||= { distributors: Set.new, producers: Set.new }
|
|
|
|
if !activated_only || r.child.activated?
|
|
relatives[r.parent_id][:producers] << r.child_id if r.child.is_primary_producer
|
|
relatives[r.parent_id][:distributors] << r.child_id if r.child.is_distributor
|
|
end
|
|
|
|
if !activated_only || r.parent.activated?
|
|
relatives[r.child_id][:producers] << r.parent_id if r.parent.is_primary_producer
|
|
relatives[r.child_id][:distributors] << r.parent_id if r.parent.is_distributor
|
|
end
|
|
end
|
|
|
|
relatives
|
|
end
|
|
|
|
def permissions_list=(perms)
|
|
if perms.nil?
|
|
permissions.destroy_all
|
|
else
|
|
permissions.where('name NOT IN (?)', perms).destroy_all
|
|
perms.map { |name| permissions.find_or_initialize_by name: name }
|
|
end
|
|
end
|
|
|
|
def has_permission?(name)
|
|
permissions(:reload).map(&:name).map(&:to_sym).include? name.to_sym
|
|
end
|
|
|
|
private
|
|
|
|
def update_permissions_of_child_variant_overrides
|
|
if has_permission?(:create_variant_overrides)
|
|
allow_all_child_variant_overrides
|
|
else
|
|
revoke_all_child_variant_overrides
|
|
end
|
|
end
|
|
|
|
def allow_all_child_variant_overrides
|
|
child_variant_overrides.update_all(permission_revoked_at: nil)
|
|
end
|
|
|
|
def revoke_all_child_variant_overrides
|
|
child_variant_overrides.update_all(permission_revoked_at: Time.zone.now)
|
|
end
|
|
|
|
def child_variant_overrides
|
|
VariantOverride.unscoped.for_hubs(child)
|
|
.joins(variant: :product).where("spree_products.supplier_id IN (?)", parent)
|
|
end
|
|
end
|