Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow producer to edit their products on hubs' orders #13113

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions app/models/enterprise.rb
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,10 @@ def is_hub
sells == 'any'
end

def is_producer
is_primary_producer && sells == 'none'
end

# Simplify enterprise categories for frontend logic and icons, and maybe other things.
def category
# Make this crazy logic human readable so we can argue about it sanely.
Expand Down
23 changes: 21 additions & 2 deletions app/models/spree/ability.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,11 @@ def initialize(user)
add_group_management_abilities user if can_manage_groups? user
add_product_management_abilities user if can_manage_products? user
add_order_cycle_management_abilities user if can_manage_order_cycles? user
add_order_management_abilities user if can_manage_orders? user
if can_manage_orders? user
add_order_management_abilities user
elsif can_manage_line_items_in_orders? user
add_manage_line_items_abilities user
end
add_relationship_management_abilities user if can_manage_relationships? user
end

Expand Down Expand Up @@ -81,7 +85,13 @@ def can_manage_order_cycles?(user)

# Users can manage orders if they have a sells own/any enterprise.
def can_manage_orders?(user)
( user.enterprises.map(&:sells) & %w(own any) ).any?
user.can_manage_orders?
end

# Users can manage line items in orders if they have producer enterprise and
# any of order distributors allow them to edit their orders.
def can_manage_line_items_in_orders?(user)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding the same user method names here for the sake of writing ability specs to better show the assigned abilities

user.can_manage_line_items_in_orders?
end

def can_manage_relationships?(user)
Expand Down Expand Up @@ -343,6 +353,15 @@ def add_order_management_abilities(user)
end
end

def add_manage_line_items_abilities(user)
can [:admin, :read, :index], Spree::Order do |order|
if order.distributor&.enable_producers_to_edit_orders
user_enterprises_ids = user.enterprises.ids
order.variants.any? { |variant| user_enterprises_ids.include?(variant.supplier_id) }
end
end
end

def add_relationship_management_abilities(user)
can [:admin, :index, :create], EnterpriseRelationship
can [:destroy], EnterpriseRelationship do |enterprise_relationship|
Expand Down
8 changes: 8 additions & 0 deletions app/models/spree/order.rb
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,14 @@ def states
scope :invoiceable, -> { where(state: [:complete, :resumed]) }
scope :by_state, lambda { |state| where(state:) }
scope :not_state, lambda { |state| where.not(state:) }
scope :editable_by_producers, ->(enterprises) {
joins(
:distributor, line_items: :supplier
).where(
supplier: { id: enterprises.ids },
distributor: { enable_producers_to_edit_orders: true }
)
}

def initialize(*_args)
@checkout_processing = nil
Expand Down
16 changes: 16 additions & 0 deletions app/models/spree/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,22 @@ def affiliate_enterprises
Enterprise.joins(:connected_apps).merge(ConnectedApps::AffiliateSalesData.ready)
end

# Users can manage orders if they have a sells own/any enterprise. or is admin
def can_manage_orders?
@can_manage_orders ||= (enterprises.pluck(:sells).intersect?(%w(own any)) or admin?)
end

# Users can manage line items in orders if they have producer enterprise and
# any of order distributors allow them to edit their orders.
def can_manage_line_items_in_orders?
@can_manage_line_items_in_orders ||= begin
has_any_producer = enterprises.any?(&:is_producer)
has_producer_editable_orders = Spree::Order.editable_by_producers(enterprises).exists?
has_any_producer && has_producer_editable_orders
end
end


protected

def password_required?
Expand Down
20 changes: 17 additions & 3 deletions app/services/permissions/order.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,16 @@ def visible_orders

# Any orders that the user can edit
def editable_orders
orders = Spree::Order.
where(managed_orders_where_values.
or(coordinated_orders_where_values))
orders = if @user.can_manage_line_items_in_orders_only?
Spree::Order.joins(:distributor).where(
id: produced_orders.select(:id),
distributor: { enable_producers_to_edit_orders: true }
)
else
Spree::Order.where(
managed_orders_where_values.or(coordinated_orders_where_values)
)
end

filtered_orders(orders)
end
Expand Down Expand Up @@ -79,6 +86,13 @@ def coordinated_orders_where_values
reduce(:and)
end

def produced_orders
Spree::Order.with_line_items_variants_and_products_outer.
where(
spree_variants: { supplier_id: @permissions.managed_enterprises.select("enterprises.id") }
)
end

def produced_orders_where_values
Spree::Order.with_line_items_variants_and_products_outer.
where(
Expand Down
7 changes: 4 additions & 3 deletions app/views/spree/admin/orders/index.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@

- content_for :minimal_js, true

- content_for :page_actions do
%li
= button_link_to t('.new_order'), spree.new_admin_order_url, icon: 'icon-plus', id: 'admin_new_order'
- if can?(:create, Spree::Order)
- content_for :page_actions do
%li
= button_link_to t('.new_order'), spree.new_admin_order_url, icon: 'icon-plus', id: 'admin_new_order'

= render partial: 'spree/admin/shared/order_sub_menu'

Expand Down