# frozen_string_literal: true module OpenFoodNetwork class Permissions def initialize(user) @user = user end def can_manage_complex_order_cycles? managed_and_related_enterprises_granting(:add_to_order_cycle).any? do |e| e.sells == 'any' end end # Enterprises that an admin is allowed to add to an order cycle def visible_enterprises_for_order_reports managed_and_related_enterprises_with :add_to_order_cycle end # Enterprises that the user manages and those that have granted P-OC to managed enterprises def visible_enterprises managed_and_related_enterprises_granting :add_to_order_cycle end # Enterprises for which an admin is allowed to edit their profile def editable_enterprises managed_and_related_enterprises_granting :edit_profile end def variant_override_hubs managed_enterprises.is_distributor end def variant_override_producers producer_ids = variant_override_enterprises_per_hub.values.flatten.uniq Enterprise.where(id: producer_ids) end # For every hub that an admin manages, show all the producers for which that hub may # override variants # {hub1_id => [producer1_id, producer2_id, ...], ...} def variant_override_enterprises_per_hub hubs = variant_override_hubs # Permissions granted by create_variant_overrides relationship from producer to hub permissions = EnterpriseRelationship. permitting(hubs.select("enterprises.id")). with_permission(:create_variant_overrides). group_by(&:child_id). transform_values { |ers| ers.map(&:parent_id) } # Allow a producer hub to override it's own products without explicit permission hubs.is_primary_producer.each do |hub| permissions[hub.id] ||= [] permissions[hub.id] |= [hub.id] end permissions end def editable_products return Spree::Product.all if admin? product_with_variants.where(spree_variants: { supplier_id: @user.enterprises }).or( product_with_variants.where( spree_variants: { supplier_id: related_enterprises_granting(:manage_products) } ) ) end def visible_products return Spree::Product.all if admin? product_with_variants.where(spree_variants: { supplier_id: @user.enterprises }).or( product_with_variants.where( spree_variants: { supplier_id: related_enterprises_granting(:manage_products) | related_enterprises_granting(:add_to_order_cycle) } ) ) end def managed_product_enterprises managed_and_related_enterprises_granting :manage_products end def manages_one_enterprise? @user.enterprises.length == 1 end def editable_schedules Schedule. joins(:order_cycles). where(order_cycles: { id: OrderCycle.managed_by(@user).select("order_cycles.id") }). select("DISTINCT schedules.*") end def visible_schedules Schedule. joins(:order_cycles). where(order_cycles: { id: OrderCycle.managed_by(@user).select("order_cycles.id") }). select("DISTINCT schedules.*") end def editable_subscriptions Subscription.where(shop_id: managed_enterprises) end def visible_subscriptions editable_subscriptions end def managed_enterprises return Enterprise.all if admin? @user.enterprises end def coordinated_order_cycles return @coordinated_order_cycles unless @coordinated_order_cycles.nil? @coordinated_order_cycles = OrderCycle.managed_by(@user) end def related_enterprises_granting(permission, options = {}) parent_ids = EnterpriseRelationship. permitting(options[:to] || managed_enterprises.select("enterprises.id")). with_permission(permission). select(:parent_id) (options[:scope] || Enterprise).where(id: parent_ids).select("enterprises.id") end def related_enterprises_granted(permission, options = {}) child_ids = EnterpriseRelationship. permitted_by(options[:by] || managed_enterprises.select("enterprises.id")). with_permission(permission). select(:child_id) (options[:scope] || Enterprise).where(id: child_ids).select("enterprises.id") end private def admin? @user.admin? end def managed_and_related_enterprises_granting(permission) if admin? Enterprise.where(nil) else Enterprise.where( id: managed_enterprises.select("enterprises.id") | related_enterprises_granting(permission) ) end end def managed_and_related_enterprises_with(permission) if admin? Enterprise.where(nil) else managed_enterprise_ids = managed_enterprises.select("enterprises.id") granting_enterprise_ids = related_enterprises_granting(permission) granted_enterprise_ids = related_enterprises_granted(permission) Enterprise.where( id: managed_enterprise_ids | granting_enterprise_ids | granted_enterprise_ids ) end end def managed_enterprise_products Spree::Product.managed_by(@user) end def product_with_variants Spree::Product.joins(:variants) end end end