mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
Merge pull request #13113 from chahmedejaz/task/13031-allow-producers-to-edit-orders
Allow producer to edit their products on hubs' orders
This commit is contained in:
@@ -67,7 +67,8 @@ module Api
|
||||
def serialized_orders(orders)
|
||||
ActiveModel::ArraySerializer.new(
|
||||
orders,
|
||||
each_serializer: Api::Admin::OrderSerializer
|
||||
each_serializer: Api::Admin::OrderSerializer,
|
||||
current_user: current_api_user
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
@@ -64,7 +64,10 @@ module Spree
|
||||
end
|
||||
|
||||
def search
|
||||
scoper = OpenFoodNetwork::ScopeVariantsForSearch.new(variant_search_params)
|
||||
scoper = OpenFoodNetwork::ScopeVariantsForSearch.new(
|
||||
variant_search_params,
|
||||
spree_current_user
|
||||
)
|
||||
@variants = scoper.search
|
||||
render json: @variants, each_serializer: ::Api::Admin::VariantSerializer
|
||||
end
|
||||
|
||||
@@ -142,6 +142,32 @@ module Spree
|
||||
end
|
||||
number_field_tag :quantity, manifest_item.quantity, html_options
|
||||
end
|
||||
|
||||
def prepare_shipment_manifest(shipment)
|
||||
manifest = shipment.manifest
|
||||
|
||||
if filter_by_supplier?(shipment.order)
|
||||
supplier_ids = spree_current_user.enterprises.ids
|
||||
manifest.select! { |mi| supplier_ids.include?(mi.variant.supplier_id) }
|
||||
end
|
||||
|
||||
manifest
|
||||
end
|
||||
|
||||
def filter_by_supplier?(order)
|
||||
order.distributor&.enable_producers_to_edit_orders &&
|
||||
spree_current_user.can_manage_line_items_in_orders_only?
|
||||
end
|
||||
|
||||
def display_value_for_producer(order, value)
|
||||
return value unless filter_by_supplier?(order)
|
||||
|
||||
if order.distributor&.show_customer_names_to_suppliers
|
||||
value
|
||||
else
|
||||
t("admin.reports.hidden_field")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -381,6 +381,10 @@ class Enterprise < ApplicationRecord
|
||||
sells == 'any'
|
||||
end
|
||||
|
||||
def is_producer_only
|
||||
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.
|
||||
|
||||
@@ -47,7 +47,11 @@ module Spree
|
||||
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
|
||||
|
||||
@@ -81,7 +85,13 @@ module Spree
|
||||
|
||||
# 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)
|
||||
user.can_manage_line_items_in_orders?
|
||||
end
|
||||
|
||||
def can_manage_relationships?(user)
|
||||
@@ -343,6 +353,28 @@ module Spree
|
||||
end
|
||||
end
|
||||
|
||||
def can_edit_order(order, user)
|
||||
return unless order.distributor&.enable_producers_to_edit_orders
|
||||
|
||||
order.variants.any? { |variant| user.enterprises.ids.include?(variant.supplier_id) }
|
||||
end
|
||||
|
||||
def add_manage_line_items_abilities(user)
|
||||
can [:admin, :read, :index, :edit, :update, :bulk_management], Spree::Order do |order|
|
||||
can_edit_order(order, user)
|
||||
end
|
||||
can [:admin, :index, :create, :destroy, :update], Spree::LineItem do |item|
|
||||
can_edit_order(item.order, user)
|
||||
end
|
||||
can [:index, :create, :add, :read, :edit, :update], Spree::Shipment do |shipment|
|
||||
can_edit_order(shipment.order, user)
|
||||
end
|
||||
can [:admin, :index], OrderCycle do |order_cycle|
|
||||
can_edit_order(order_cycle.order, user)
|
||||
end
|
||||
can [:visible], Enterprise
|
||||
end
|
||||
|
||||
def add_relationship_management_abilities(user)
|
||||
can [:admin, :index, :create], EnterpriseRelationship
|
||||
can [:destroy], EnterpriseRelationship do |enterprise_relationship|
|
||||
|
||||
@@ -108,6 +108,13 @@ module Spree
|
||||
where(spree_adjustments: { id: nil })
|
||||
}
|
||||
|
||||
scope :editable_by_producers, ->(enterprises_ids) {
|
||||
joins(:variant, order: :distributor).where(
|
||||
distributor: { enable_producers_to_edit_orders: true },
|
||||
spree_variants: { supplier_id: enterprises_ids }
|
||||
)
|
||||
}
|
||||
|
||||
def copy_price
|
||||
return unless variant
|
||||
|
||||
|
||||
@@ -140,6 +140,15 @@ module Spree
|
||||
end
|
||||
}
|
||||
|
||||
scope :editable_by_producers, ->(enterprises) {
|
||||
joins(
|
||||
:distributor, line_items: :supplier
|
||||
).where(
|
||||
supplier: { id: enterprises },
|
||||
distributor: { enable_producers_to_edit_orders: true }
|
||||
)
|
||||
}
|
||||
|
||||
scope :distributed_by_user, lambda { |user|
|
||||
if user.admin?
|
||||
where(nil)
|
||||
|
||||
@@ -147,6 +147,25 @@ module Spree
|
||||
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?
|
||||
return @can_manage_line_items_in_orders if defined? @can_manage_line_items_in_orders
|
||||
|
||||
@can_manage_line_items_in_orders =
|
||||
enterprises.any?(&:is_producer_only) &&
|
||||
Spree::Order.editable_by_producers(enterprises).exists?
|
||||
end
|
||||
|
||||
def can_manage_line_items_in_orders_only?
|
||||
!can_manage_orders? && can_manage_line_items_in_orders?
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def password_required?
|
||||
|
||||
@@ -15,8 +15,14 @@ module Api
|
||||
has_one :distributor, serializer: Api::Admin::IdSerializer
|
||||
has_one :order_cycle, serializer: Api::Admin::IdSerializer
|
||||
|
||||
def full_name_for_sorting
|
||||
value = [last_name, first_name].compact_blank.join(", ")
|
||||
display_value_for_producer(object, value)
|
||||
end
|
||||
|
||||
def full_name
|
||||
object.billing_address.nil? ? "" : ( object.billing_address.full_name || "" )
|
||||
value = object.billing_address.nil? ? "" : ( object.billing_address.full_name || "" )
|
||||
display_value_for_producer(object, value)
|
||||
end
|
||||
|
||||
def first_name
|
||||
@@ -65,11 +71,12 @@ module Api
|
||||
end
|
||||
|
||||
def email
|
||||
object.email || ""
|
||||
display_value_for_producer(object, object.email || "")
|
||||
end
|
||||
|
||||
def phone
|
||||
object.billing_address.nil? ? "a" : ( object.billing_address.phone || "" )
|
||||
value = object.billing_address.nil? ? "a" : ( object.billing_address.phone || "" )
|
||||
display_value_for_producer(object, value)
|
||||
end
|
||||
|
||||
def created_at
|
||||
@@ -93,6 +100,19 @@ module Api
|
||||
def spree_routes_helper
|
||||
Spree::Core::Engine.routes.url_helpers
|
||||
end
|
||||
|
||||
def display_value_for_producer(order, value)
|
||||
filter_by_supplier =
|
||||
order.distributor&.enable_producers_to_edit_orders &&
|
||||
options[:current_user]&.can_manage_line_items_in_orders_only?
|
||||
return value unless filter_by_supplier
|
||||
|
||||
if order.distributor&.show_customer_names_to_suppliers
|
||||
value
|
||||
else
|
||||
I18n.t("admin.reports.hidden_field")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -23,9 +23,16 @@ module Permissions
|
||||
|
||||
# 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
|
||||
@@ -36,7 +43,13 @@ module Permissions
|
||||
|
||||
# Any line items that I can edit
|
||||
def editable_line_items
|
||||
Spree::LineItem.where(order_id: editable_orders.select(:id))
|
||||
if @user.can_manage_line_items_in_orders_only?
|
||||
Spree::LineItem.editable_by_producers(
|
||||
@permissions.managed_enterprises.select("enterprises.id")
|
||||
)
|
||||
else
|
||||
Spree::LineItem.where(order_id: editable_orders.select(:id))
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
@@ -79,6 +92,13 @@ module Permissions
|
||||
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(
|
||||
|
||||
@@ -39,6 +39,7 @@ module PermittedAttributes
|
||||
:preferred_product_low_stock_display,
|
||||
:hide_ofn_navigation, :white_label_logo, :white_label_logo_link,
|
||||
:hide_groups_tab, :external_billing_id,
|
||||
:enable_producers_to_edit_orders
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
@@ -123,3 +123,15 @@
|
||||
.five.columns.omega
|
||||
= f.radio_button :show_customer_contacts_to_suppliers, false
|
||||
= f.label :show_customer_contacts_to_suppliers, t('.customer_contacts_false'), value: :false
|
||||
|
||||
.row
|
||||
.three.columns.alpha
|
||||
%label= t('.producers_to_edit_orders')
|
||||
%div{'ofn-with-tip' => t('.producers_to_edit_orders_tip')}
|
||||
%a= t 'admin.whats_this'
|
||||
.three.columns
|
||||
= radio_button :enterprise, :enable_producers_to_edit_orders, true
|
||||
= label :enterprise_enable_producers_to_edit_orders, t('.producers_edit_orders_true'), value: :true
|
||||
.five.columns.omega
|
||||
= radio_button :enterprise, :enable_producers_to_edit_orders, false
|
||||
= label :enterprise_enable_producers_to_edit_orders, t('.producers_edit_orders_false'), value: :false
|
||||
|
||||
@@ -8,23 +8,24 @@
|
||||
- if @order.shipments.any?
|
||||
= render :partial => "spree/admin/orders/shipment", :collection => @order.shipments, :locals => { :order => @order }
|
||||
|
||||
- if @order.line_items.exists?
|
||||
= render partial: "spree/admin/orders/note", locals: { order: @order }
|
||||
- if spree_current_user.can_manage_orders?
|
||||
- if @order.line_items.exists?
|
||||
= render partial: "spree/admin/orders/note", locals: { order: @order }
|
||||
|
||||
= render :partial => "spree/admin/orders/_form/adjustments", :locals => { :adjustments => @order.line_item_adjustments, :title => t(".line_item_adjustments")}
|
||||
= render :partial => "spree/admin/orders/_form/adjustments", :locals => { :adjustments => order_adjustments_for_display(@order), :title => t(".order_adjustments")}
|
||||
= render :partial => "spree/admin/orders/_form/adjustments", :locals => { :adjustments => @order.line_item_adjustments, :title => t(".line_item_adjustments")}
|
||||
= render :partial => "spree/admin/orders/_form/adjustments", :locals => { :adjustments => order_adjustments_for_display(@order), :title => t(".order_adjustments")}
|
||||
|
||||
- if @order.line_items.exists?
|
||||
%fieldset#order-total.no-border-bottom.order-details-total
|
||||
%legend{ align: 'center' }= t(".order_total")
|
||||
%span.order-total= @order.display_total
|
||||
- if @order.line_items.exists?
|
||||
%fieldset#order-total.no-border-bottom.order-details-total
|
||||
%legend{ align: 'center' }= t(".order_total")
|
||||
%span.order-total= @order.display_total
|
||||
|
||||
= form_for @order, url: spree.admin_order_url(@order), method: :put do |f|
|
||||
= render partial: 'spree/admin/orders/_form/distribution_fields'
|
||||
= form_for @order, url: spree.admin_order_url(@order), method: :put do |f|
|
||||
= render partial: 'spree/admin/orders/_form/distribution_fields'
|
||||
|
||||
.filter-actions.actions{"ng-show" => "distributionChosen()"}
|
||||
= button t(:update_and_recalculate_fees), 'icon-refresh'
|
||||
= link_to_with_icon 'button icon-arrow-left', t(:back), spree.admin_orders_url
|
||||
.filter-actions.actions{"ng-show" => "distributionChosen()"}
|
||||
= button t(:update_and_recalculate_fees), 'icon-refresh'
|
||||
= link_to_with_icon 'button icon-arrow-left', t(:back), spree.admin_orders_url
|
||||
|
||||
= javascript_tag do
|
||||
var order_number = '#{@order.number}';
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
|
||||
- if shipment.fee_adjustment.present? && shipment.can_modify?
|
||||
%td.actions
|
||||
- if can? :update, shipment
|
||||
- if can? :update, shipment.shipping_method
|
||||
= link_to '', '', :class => 'edit-method icon_link icon-edit no-text with-tip', :data => { :action => 'edit' }, :title => Spree.t('edit')
|
||||
|
||||
%tr.edit-tracking.hidden.total
|
||||
@@ -86,7 +86,7 @@
|
||||
= Spree.t(:no_tracking_present)
|
||||
|
||||
%td.actions
|
||||
- if can?(:update, shipment) && shipment.can_modify?
|
||||
- if spree_current_user.can_manage_orders? && can?(:update, shipment) && shipment.can_modify?
|
||||
= link_to '', '', :class => 'edit-tracking icon_link icon-edit no-text with-tip', :data => { :action => 'edit' }, :title => Spree.t('edit')
|
||||
- if shipment.tracking.present?
|
||||
= link_to '', '', :class => 'delete-tracking icon_link icon-trash no-text with-tip', :data => { 'shipment-number' => shipment.number, :action => 'remove' }, :title => Spree.t('delete')
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
- shipment.manifest.each do |item|
|
||||
- prepare_shipment_manifest(shipment).each do |item|
|
||||
- line_item = order.find_line_item_by_variant(item.variant)
|
||||
|
||||
- if line_item.present?
|
||||
|
||||
@@ -34,10 +34,11 @@
|
||||
%span.state{ class: order.shipment_state.to_s}
|
||||
= t('js.admin.orders.shipment_states.' + order.shipment_state.to_s)
|
||||
%td
|
||||
%a{ href: "mailto:#{order.email}", target: "_blank" }
|
||||
= order.email
|
||||
- email_value = display_value_for_producer(order, order.email)
|
||||
%a{ href: "mailto:#{email_value}", target: "_blank" }
|
||||
= email_value
|
||||
%td
|
||||
= order&.bill_address&.full_name_for_sorting
|
||||
= display_value_for_producer(order, order.bill_address&.full_name_for_sorting)
|
||||
%td.align-left
|
||||
%span
|
||||
= order.display_total
|
||||
@@ -46,10 +47,10 @@
|
||||
- if local_assigns[:success]
|
||||
%i.success.icon-ok-sign{"data-controller": "ephemeral"}
|
||||
= render AdminTooltipComponent.new(text: t('spree.admin.orders.index.edit'), link_text: "", link: edit_admin_order_path(order), link_class: "icon_link with-tip icon-edit no-text")
|
||||
- if order.ready_to_ship?
|
||||
- if spree_current_user.can_manage_orders? && order.ready_to_ship?
|
||||
%form
|
||||
= render ShipOrderComponent.new(order: order)
|
||||
= render partial: 'admin/shared/tooltip_button', locals: {button_class: "icon-road icon_link with-tip no-text", reflex_data_id: order.id.to_s, tooltip_text: t('spree.admin.orders.index.ship'), shipment: true}
|
||||
|
||||
- if order.payment_required? && order.pending_payments.reject(&:requires_authorization?).any?
|
||||
- if can?(:update, Spree::Payment) && order.payment_required? && order.pending_payments.reject(&:requires_authorization?).any?
|
||||
= render partial: 'admin/shared/tooltip_button', locals: {button_class: "icon-capture icon_link no-text", button_reflex: "click->Admin::OrdersReflex#capture", reflex_data_id: order.id.to_s, tooltip_text: t('spree.admin.orders.index.capture')}
|
||||
|
||||
@@ -6,14 +6,16 @@
|
||||
- content_for :page_actions do
|
||||
- if can?(:fire, @order)
|
||||
%li= event_links(@order)
|
||||
= render partial: 'spree/admin/shared/order_links'
|
||||
- if spree_current_user.can_manage_orders?
|
||||
= render partial: 'spree/admin/shared/order_links'
|
||||
- if can?(:admin, Spree::Order)
|
||||
%li
|
||||
%a.button.icon-arrow-left{icon: 'icon-arrow-left', href: admin_orders_path }
|
||||
= t(:back_to_orders_list)
|
||||
|
||||
= render partial: "spree/admin/shared/order_page_title"
|
||||
= render partial: "spree/admin/shared/order_tabs", locals: { current: 'Order Details' }
|
||||
- if spree_current_user.can_manage_orders?
|
||||
= render partial: "spree/admin/shared/order_tabs", locals: { current: 'Order Details' }
|
||||
|
||||
%div
|
||||
= render partial: "spree/shared/error_messages", locals: { target: @order }
|
||||
|
||||
@@ -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) && spree_current_user.can_manage_orders?
|
||||
- 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'
|
||||
|
||||
|
||||
@@ -1359,12 +1359,16 @@ en:
|
||||
enable_subscriptions_true: "Enabled"
|
||||
customer_names_in_reports: "Customer Names in Reports"
|
||||
customer_names_tip: "Enable your suppliers to see your customers names in reports"
|
||||
producers_to_edit_orders: "Ability for producers to edit orders"
|
||||
producers_to_edit_orders_tip: "Enable your suppliers to see orders containing their products, and edit quantity and weight for their own products only."
|
||||
customer_names_false: "Disabled"
|
||||
customer_names_true: "Enabled"
|
||||
customer_contacts_in_reports: "Customer contact details in reports"
|
||||
customer_contacts_tip: "Enable your suppliers to see your customer email and phone numbers in reports"
|
||||
customer_contacts_false: "Disabled"
|
||||
customer_contacts_true: "Enabled"
|
||||
producers_edit_orders_false: "Disabled"
|
||||
producers_edit_orders_true: "Enabled"
|
||||
shopfront_message: "Shopfront Message"
|
||||
shopfront_message_placeholder: >
|
||||
An optional message to welcome customers and explain how to shop with you. If text is entered here it will be displayed in a home tab when customers first arrive at your shopfront.
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class AddEnableProducersToEditOrdersToEnterprises < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
add_column :enterprises, :enable_producers_to_edit_orders, :boolean, default: false, null: false
|
||||
end
|
||||
end
|
||||
@@ -230,6 +230,7 @@ ActiveRecord::Schema[7.0].define(version: 2025_03_04_234657) do
|
||||
t.text "white_label_logo_link"
|
||||
t.boolean "hide_groups_tab", default: false
|
||||
t.string "external_billing_id", limit: 128
|
||||
t.boolean "enable_producers_to_edit_orders", default: false, null: false
|
||||
t.boolean "show_customer_contacts_to_suppliers", default: false, null: false
|
||||
t.index ["address_id"], name: "index_enterprises_on_address_id"
|
||||
t.index ["is_primary_producer", "sells"], name: "index_enterprises_on_is_primary_producer_and_sells"
|
||||
|
||||
@@ -9,8 +9,9 @@ require 'open_food_network/scope_variant_to_hub'
|
||||
|
||||
module OpenFoodNetwork
|
||||
class ScopeVariantsForSearch
|
||||
def initialize(params)
|
||||
def initialize(params, spree_current_user)
|
||||
@params = params
|
||||
@spree_current_user = spree_current_user
|
||||
end
|
||||
|
||||
def search
|
||||
@@ -20,13 +21,14 @@ module OpenFoodNetwork
|
||||
scope_to_schedule if params[:schedule_id]
|
||||
scope_to_order_cycle if params[:order_cycle_id]
|
||||
scope_to_distributor if params[:distributor_id]
|
||||
scope_to_supplier if spree_current_user.can_manage_line_items_in_orders_only?
|
||||
|
||||
@variants
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :params
|
||||
attr_reader :params, :spree_current_user
|
||||
|
||||
def search_params
|
||||
{ product_name_cont: params[:q], sku_cont: params[:q], product_sku_cont: params[:q] }
|
||||
@@ -96,5 +98,9 @@ module OpenFoodNetwork
|
||||
# Filtering could be a problem on scoped variants.
|
||||
variants.each { |v| scoper.scope(v) }
|
||||
end
|
||||
|
||||
def scope_to_supplier
|
||||
@variants = @variants.where(supplier_id: spree_current_user.enterprises.ids)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -120,11 +120,26 @@ RSpec.describe Admin::BulkLineItemsController, type: :controller do
|
||||
context "producer enterprise" do
|
||||
before do
|
||||
allow(controller).to receive_messages spree_current_user: supplier.owner
|
||||
get :index, as: :json
|
||||
end
|
||||
|
||||
it "does not display line items for which my enterprise is a supplier" do
|
||||
expect(response).to redirect_to unauthorized_path
|
||||
context "with no distributor allows to edit orders" do
|
||||
before { get :index, as: :json }
|
||||
|
||||
it "does not display line items for which my enterprise is a supplier" do
|
||||
expect(response).to redirect_to unauthorized_path
|
||||
end
|
||||
end
|
||||
|
||||
context "with distributor allows to edit orders" do
|
||||
before do
|
||||
distributor1.update_columns(enable_producers_to_edit_orders: true)
|
||||
get :index, as: :json
|
||||
end
|
||||
|
||||
it "retrieves a list of line_items from the supplier" do
|
||||
keys = json_response['line_items'].first.keys.map(&:to_sym)
|
||||
expect(line_item_attributes.all?{ |attr| keys.include? attr }).to eq(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -84,11 +84,25 @@ module Api
|
||||
context 'producer enterprise' do
|
||||
before do
|
||||
allow(controller).to receive(:spree_current_user) { supplier.owner }
|
||||
get :index
|
||||
end
|
||||
|
||||
it "does not display line items for which my enterprise is a supplier" do
|
||||
assert_unauthorized!
|
||||
context "with no distributor allows to edit orders" do
|
||||
before { get :index }
|
||||
|
||||
it "does not display line items for which my enterprise is a supplier" do
|
||||
assert_unauthorized!
|
||||
end
|
||||
end
|
||||
|
||||
context "with distributor allows to edit orders" do
|
||||
before do
|
||||
distributor.update_columns(enable_producers_to_edit_orders: true)
|
||||
get :index
|
||||
end
|
||||
|
||||
it "retrieves a list of orders which have my supplied products" do
|
||||
returns_orders(json_response)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -22,7 +22,8 @@ RSpec.describe Spree::Admin::MailMethodsController do
|
||||
owned_groups: nil)
|
||||
allow(user).to receive_messages(enterprises: [create(:enterprise)],
|
||||
admin?: true,
|
||||
locale: nil)
|
||||
locale: nil,
|
||||
can_manage_orders?: true)
|
||||
allow(controller).to receive_messages(spree_current_user: user)
|
||||
|
||||
expect {
|
||||
|
||||
@@ -5,151 +5,199 @@ require 'spec_helper'
|
||||
module Spree
|
||||
module Admin
|
||||
RSpec.describe VariantsController, type: :controller do
|
||||
before { controller_login_as_admin }
|
||||
context "log in as admin user" do
|
||||
before { controller_login_as_admin }
|
||||
|
||||
describe "#index" do
|
||||
describe "deleted variants" do
|
||||
let(:product) { create(:product, name: 'Product A') }
|
||||
let(:deleted_variant) do
|
||||
deleted_variant = product.variants.create(
|
||||
unit_value: "2", variant_unit: "weight", variant_unit_scale: 1, price: 1,
|
||||
primary_taxon: create(:taxon), supplier: create(:supplier_enterprise)
|
||||
)
|
||||
deleted_variant.delete
|
||||
deleted_variant
|
||||
end
|
||||
describe "#index" do
|
||||
describe "deleted variants" do
|
||||
let(:product) { create(:product, name: 'Product A') }
|
||||
let(:deleted_variant) do
|
||||
deleted_variant = product.variants.create(
|
||||
unit_value: "2", variant_unit: "weight", variant_unit_scale: 1, price: 1,
|
||||
primary_taxon: create(:taxon), supplier: create(:supplier_enterprise)
|
||||
)
|
||||
deleted_variant.delete
|
||||
deleted_variant
|
||||
end
|
||||
|
||||
it "lists only non-deleted variants with params[:deleted] == off" do
|
||||
spree_get :index, product_id: product.id, deleted: "off"
|
||||
expect(assigns(:variants)).to eq(product.variants)
|
||||
end
|
||||
it "lists only non-deleted variants with params[:deleted] == off" do
|
||||
spree_get :index, product_id: product.id, deleted: "off"
|
||||
expect(assigns(:variants)).to eq(product.variants)
|
||||
end
|
||||
|
||||
it "lists only deleted variants with params[:deleted] == on" do
|
||||
spree_get :index, product_id: product.id, deleted: "on"
|
||||
expect(assigns(:variants)).to eq([deleted_variant])
|
||||
it "lists only deleted variants with params[:deleted] == on" do
|
||||
spree_get :index, product_id: product.id, deleted: "on"
|
||||
expect(assigns(:variants)).to eq([deleted_variant])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#update" do
|
||||
let!(:variant) { create(:variant, display_name: "Tomatoes", sku: 123, supplier: producer) }
|
||||
let(:producer) { create(:enterprise) }
|
||||
|
||||
it "updates the variant" do
|
||||
expect {
|
||||
spree_put(
|
||||
:update,
|
||||
id: variant.id,
|
||||
product_id: variant.product.id,
|
||||
variant: { display_name: "Better tomatoes", sku: 456 }
|
||||
describe "#update" do
|
||||
let!(:variant) {
|
||||
create(
|
||||
:variant,
|
||||
display_name: "Tomatoes",
|
||||
sku: 123,
|
||||
supplier: producer
|
||||
)
|
||||
variant.reload
|
||||
}.to change { variant.display_name }.to("Better tomatoes")
|
||||
.and change { variant.sku }.to(456.to_s)
|
||||
end
|
||||
}
|
||||
let(:producer) { create(:enterprise) }
|
||||
|
||||
context "when updating supplier" do
|
||||
let(:new_producer) { create(:enterprise) }
|
||||
|
||||
it "updates the supplier" do
|
||||
it "updates the variant" do
|
||||
expect {
|
||||
spree_put(
|
||||
:update,
|
||||
id: variant.id,
|
||||
product_id: variant.product.id,
|
||||
variant: { display_name: "Better tomatoes", sku: 456 }
|
||||
)
|
||||
variant.reload
|
||||
}.to change { variant.display_name }.to("Better tomatoes")
|
||||
.and change { variant.sku }.to(456.to_s)
|
||||
end
|
||||
|
||||
context "when updating supplier" do
|
||||
let(:new_producer) { create(:enterprise) }
|
||||
|
||||
it "updates the supplier" do
|
||||
expect {
|
||||
spree_put(
|
||||
:update,
|
||||
id: variant.id,
|
||||
product_id: variant.product.id,
|
||||
variant: { supplier_id: new_producer.id }
|
||||
)
|
||||
variant.reload
|
||||
}.to change { variant.supplier_id }.to(new_producer.id)
|
||||
end
|
||||
|
||||
it "removes associated product from existing Order Cycles" do
|
||||
distributor = create(:distributor_enterprise)
|
||||
order_cycle = create(
|
||||
:simple_order_cycle,
|
||||
variants: [variant],
|
||||
coordinator: distributor,
|
||||
distributors: [distributor]
|
||||
)
|
||||
|
||||
spree_put(
|
||||
:update,
|
||||
id: variant.id,
|
||||
product_id: variant.product.id,
|
||||
variant: { supplier_id: new_producer.id }
|
||||
)
|
||||
variant.reload
|
||||
}.to change { variant.supplier_id }.to(new_producer.id)
|
||||
|
||||
expect(order_cycle.reload.distributed_variants).not_to include variant
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#search" do
|
||||
let(:supplier) { create(:supplier_enterprise) }
|
||||
let!(:p1) { create(:simple_product, name: 'Product 1', supplier_id: supplier.id) }
|
||||
let!(:p2) { create(:simple_product, name: 'Product 2', supplier_id: supplier.id) }
|
||||
let!(:v1) { p1.variants.first }
|
||||
let!(:v2) { p2.variants.first }
|
||||
let!(:vo) { create(:variant_override, variant: v1, hub: d, count_on_hand: 44) }
|
||||
let!(:d) { create(:distributor_enterprise) }
|
||||
let!(:oc) { create(:simple_order_cycle, distributors: [d], variants: [v1]) }
|
||||
|
||||
it "filters by distributor" do
|
||||
spree_get :search, q: 'Prod', distributor_id: d.id.to_s
|
||||
expect(assigns(:variants)).to eq([v1])
|
||||
end
|
||||
|
||||
it "removes associated product from existing Order Cycles" do
|
||||
distributor = create(:distributor_enterprise)
|
||||
order_cycle = create(
|
||||
:simple_order_cycle,
|
||||
variants: [variant],
|
||||
coordinator: distributor,
|
||||
distributors: [distributor]
|
||||
)
|
||||
it "applies variant overrides" do
|
||||
spree_get :search, q: 'Prod', distributor_id: d.id.to_s
|
||||
expect(assigns(:variants)).to eq([v1])
|
||||
expect(assigns(:variants).first.on_hand).to eq(44)
|
||||
end
|
||||
|
||||
spree_put(
|
||||
:update,
|
||||
id: variant.id,
|
||||
product_id: variant.product.id,
|
||||
variant: { supplier_id: new_producer.id }
|
||||
)
|
||||
it "filters by order cycle" do
|
||||
spree_get :search, q: 'Prod', order_cycle_id: oc.id.to_s
|
||||
expect(assigns(:variants)).to eq([v1])
|
||||
end
|
||||
|
||||
expect(order_cycle.reload.distributed_variants).not_to include variant
|
||||
it "does not filter when no distributor or order cycle is specified" do
|
||||
spree_get :search, q: 'Prod'
|
||||
expect(assigns(:variants)).to match_array [v1, v2]
|
||||
end
|
||||
end
|
||||
|
||||
describe '#destroy' do
|
||||
let(:variant) { create(:variant) }
|
||||
|
||||
context 'when requesting with html' do
|
||||
before do
|
||||
allow(Spree::Variant).to receive(:find).with(variant.id.to_s) { variant }
|
||||
allow(variant).to receive(:destroy).and_call_original
|
||||
end
|
||||
|
||||
it 'deletes the variant' do
|
||||
spree_delete :destroy, id: variant.id, product_id: variant.product.id,
|
||||
format: 'html'
|
||||
expect(variant).to have_received(:destroy)
|
||||
end
|
||||
|
||||
it 'shows a success flash message' do
|
||||
spree_delete :destroy, id: variant.id, product_id: variant.product.id,
|
||||
format: 'html'
|
||||
expect(flash[:success]).to be
|
||||
end
|
||||
|
||||
it 'redirects to admin_product_variants_url' do
|
||||
spree_delete :destroy, id: variant.id, product_id: variant.product.id,
|
||||
format: 'html'
|
||||
expect(response).to redirect_to spree.admin_product_variants_url(variant.product.id)
|
||||
end
|
||||
|
||||
it 'destroys all its exchanges' do
|
||||
exchange = create(:exchange)
|
||||
variant.exchanges << exchange
|
||||
|
||||
spree_delete :destroy, id: variant.id, product_id: variant.product.id,
|
||||
format: 'html'
|
||||
expect(variant.exchanges.reload).to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#search" do
|
||||
let(:supplier) { create(:supplier_enterprise) }
|
||||
let!(:p1) { create(:simple_product, name: 'Product 1', supplier_id: supplier.id) }
|
||||
let!(:p2) { create(:simple_product, name: 'Product 2', supplier_id: supplier.id) }
|
||||
context "log in as supplier and distributor enable_producers_to_edit_orders" do
|
||||
let(:supplier1) { create(:supplier_enterprise) }
|
||||
let(:supplier2) { create(:supplier_enterprise) }
|
||||
let!(:p1) { create(:simple_product, name: 'Product 1', supplier_id: supplier1.id) }
|
||||
let!(:p2) { create(:simple_product, name: 'Product 2', supplier_id: supplier2.id) }
|
||||
let!(:v1) { p1.variants.first }
|
||||
let!(:v2) { p2.variants.first }
|
||||
let!(:vo) { create(:variant_override, variant: v1, hub: d, count_on_hand: 44) }
|
||||
let!(:d) { create(:distributor_enterprise) }
|
||||
let!(:oc) { create(:simple_order_cycle, distributors: [d], variants: [v1]) }
|
||||
let!(:d) { create(:distributor_enterprise, enable_producers_to_edit_orders: true) }
|
||||
let!(:oc) { create(:simple_order_cycle, distributors: [d], variants: [v1, v2]) }
|
||||
|
||||
it "filters by distributor" do
|
||||
spree_get :search, q: 'Prod', distributor_id: d.id.to_s
|
||||
expect(assigns(:variants)).to eq([v1])
|
||||
before do
|
||||
order = create(:order_with_line_items, distributor: d, line_items_count: 1)
|
||||
order.line_items.take.variant.update_attribute(:supplier_id, supplier1.id)
|
||||
controller_login_as_enterprise_user([supplier1])
|
||||
end
|
||||
|
||||
it "applies variant overrides" do
|
||||
spree_get :search, q: 'Prod', distributor_id: d.id.to_s
|
||||
expect(assigns(:variants)).to eq([v1])
|
||||
expect(assigns(:variants).first.on_hand).to eq(44)
|
||||
describe "#search" do
|
||||
it "filters by distributor and supplier1 products" do
|
||||
spree_get :search, q: 'Prod', distributor_id: d.id.to_s
|
||||
expect(assigns(:variants)).to eq([v1])
|
||||
end
|
||||
end
|
||||
|
||||
it "filters by order cycle" do
|
||||
spree_get :search, q: 'Prod', order_cycle_id: oc.id.to_s
|
||||
expect(assigns(:variants)).to eq([v1])
|
||||
end
|
||||
|
||||
it "does not filter when no distributor or order cycle is specified" do
|
||||
spree_get :search, q: 'Prod'
|
||||
expect(assigns(:variants)).to match_array [v1, v2]
|
||||
end
|
||||
end
|
||||
|
||||
describe '#destroy' do
|
||||
let(:variant) { create(:variant) }
|
||||
|
||||
context 'when requesting with html' do
|
||||
before do
|
||||
allow(Spree::Variant).to receive(:find).with(variant.id.to_s) { variant }
|
||||
allow(variant).to receive(:destroy).and_call_original
|
||||
end
|
||||
|
||||
it 'deletes the variant' do
|
||||
spree_delete :destroy, id: variant.id, product_id: variant.product.id,
|
||||
format: 'html'
|
||||
expect(variant).to have_received(:destroy)
|
||||
end
|
||||
|
||||
it 'shows a success flash message' do
|
||||
spree_delete :destroy, id: variant.id, product_id: variant.product.id,
|
||||
format: 'html'
|
||||
expect(flash[:success]).to be
|
||||
end
|
||||
|
||||
it 'redirects to admin_product_variants_url' do
|
||||
spree_delete :destroy, id: variant.id, product_id: variant.product.id,
|
||||
format: 'html'
|
||||
expect(response).to redirect_to spree.admin_product_variants_url(variant.product.id)
|
||||
end
|
||||
|
||||
it 'destroys all its exchanges' do
|
||||
exchange = create(:exchange)
|
||||
variant.exchanges << exchange
|
||||
|
||||
spree_delete :destroy, id: variant.id, product_id: variant.product.id,
|
||||
format: 'html'
|
||||
expect(variant.exchanges.reload).to be_empty
|
||||
describe "#update" do
|
||||
it "updates the variant" do
|
||||
expect {
|
||||
spree_put(
|
||||
:update,
|
||||
id: v1.id,
|
||||
product_id: v1.product.id,
|
||||
variant: { display_name: "Better tomatoes", sku: 456 }
|
||||
)
|
||||
v1.reload
|
||||
}.to change { v1.display_name }.to("Better tomatoes")
|
||||
.and change { v1.sku }.to(456.to_s)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -19,8 +19,9 @@ RSpec.describe OpenFoodNetwork::ScopeVariantsForSearch do
|
||||
let!(:oc3) { create(:simple_order_cycle, distributors: [d2], variants: [v4]) }
|
||||
let!(:s1) { create(:schedule, order_cycles: [oc1]) }
|
||||
let!(:s2) { create(:schedule, order_cycles: [oc2]) }
|
||||
let!(:spree_current_user) { create(:user) }
|
||||
|
||||
let(:scoper) { OpenFoodNetwork::ScopeVariantsForSearch.new(params) }
|
||||
let(:scoper) { OpenFoodNetwork::ScopeVariantsForSearch.new(params, spree_current_user) }
|
||||
|
||||
describe "search" do
|
||||
let(:result) { scoper.search }
|
||||
@@ -68,8 +69,11 @@ RSpec.describe OpenFoodNetwork::ScopeVariantsForSearch do
|
||||
expect{ result }.to query_database [
|
||||
"Enterprise Load",
|
||||
"VariantOverride Load",
|
||||
"SQL"
|
||||
"SQL",
|
||||
"Enterprise Pluck",
|
||||
"Enterprise Load"
|
||||
]
|
||||
|
||||
expect(result).to include v4
|
||||
expect(result).not_to include v1, v2, v3
|
||||
end
|
||||
@@ -179,6 +183,25 @@ RSpec.describe OpenFoodNetwork::ScopeVariantsForSearch do
|
||||
to eq(["Product 1", "Product a", "Product b", "Product c"])
|
||||
end
|
||||
end
|
||||
|
||||
context "when search is done by the producer allowing to edit orders" do
|
||||
let(:params) { { q: "product" } }
|
||||
let(:producer) { create(:supplier_enterprise) }
|
||||
let!(:spree_current_user) {
|
||||
instance_double('Spree::User', enterprises: Enterprise.where(id: producer.id),
|
||||
can_manage_line_items_in_orders_only?: true)
|
||||
}
|
||||
|
||||
it "returns products distributed by distributors allowing producers to edit orders" do
|
||||
v1.supplier_id = producer.id
|
||||
v2.supplier_id = producer.id
|
||||
v1.save!
|
||||
v2.save!
|
||||
|
||||
expect(result).to include v1, v2
|
||||
expect(result).not_to include v3, v4
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -151,6 +151,7 @@ RSpec.describe Reporting::Reports::OrdersAndDistributors::Base do
|
||||
subject # build context first
|
||||
|
||||
expect { subject.table_rows }.to query_database [
|
||||
"Enterprise Pluck",
|
||||
"SQL",
|
||||
"Spree::LineItem Load",
|
||||
"Spree::PaymentMethod Load",
|
||||
|
||||
@@ -1012,6 +1012,29 @@ RSpec.describe Enterprise do
|
||||
expect(expected).to include(sender)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#is_producer_only" do
|
||||
context "when enterprise is_primary_producer and sells none" do
|
||||
it "returns true" do
|
||||
enterprise = build(:supplier_enterprise)
|
||||
expect(enterprise.is_producer_only).to be true
|
||||
end
|
||||
end
|
||||
|
||||
context "when enterprise is_primary_producer and sells any" do
|
||||
it "returns false" do
|
||||
enterprise = build(:enterprise, is_primary_producer: true, sells: "any")
|
||||
expect(enterprise.is_producer_only).to be false
|
||||
end
|
||||
end
|
||||
|
||||
context "when enterprise is_primary_producer and sells own" do
|
||||
it "returns false" do
|
||||
enterprise = build(:enterprise, is_primary_producer: true, sells: "own")
|
||||
expect(enterprise.is_producer_only).to be false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def enterprise_name_error(owner_email)
|
||||
|
||||
@@ -240,6 +240,24 @@ RSpec.describe Spree::Ability do
|
||||
it { expect(subject.can_manage_enterprises?(user)).to be true }
|
||||
it { expect(subject.can_manage_orders?(user)).to be false }
|
||||
it { expect(subject.can_manage_order_cycles?(user)).to be false }
|
||||
|
||||
context "with no distributor allows me to edit orders" do
|
||||
it { expect(subject.can_manage_orders?(user)).to be false }
|
||||
it { expect(subject.can_manage_line_items_in_orders?(user)).to be false }
|
||||
end
|
||||
|
||||
context "with any distributor allows me to edit orders containing my product" do
|
||||
before do
|
||||
order = create(
|
||||
:order_with_line_items,
|
||||
line_items_count: 1,
|
||||
distributor: create(:distributor_enterprise, enable_producers_to_edit_orders: true)
|
||||
)
|
||||
order.line_items.first.variant.update!(supplier_id: enterprise_none_producer.id)
|
||||
end
|
||||
|
||||
it { expect(subject.can_manage_line_items_in_orders?(user)).to be true }
|
||||
end
|
||||
end
|
||||
|
||||
context "as a profile" do
|
||||
@@ -260,6 +278,7 @@ RSpec.describe Spree::Ability do
|
||||
it { expect(subject.can_manage_products?(user)).to be false }
|
||||
it { expect(subject.can_manage_enterprises?(user)).to be false }
|
||||
it { expect(subject.can_manage_orders?(user)).to be false }
|
||||
it { expect(subject.can_manage_line_items_in_orders?(user)).to be false }
|
||||
it { expect(subject.can_manage_order_cycles?(user)).to be false }
|
||||
|
||||
it "can create enterprises straight off the bat" do
|
||||
|
||||
@@ -298,4 +298,40 @@ RSpec.describe Spree::User do
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#can_manage_line_items_in_orders_only?" do
|
||||
let(:producer) { create(:supplier_enterprise) }
|
||||
let(:order) { create(:order, distributor:) }
|
||||
|
||||
subject { user.can_manage_line_items_in_orders_only? }
|
||||
|
||||
context "when user has producer" do
|
||||
let(:user) { create(:user, enterprises: [producer]) }
|
||||
|
||||
context "order containing their product" do
|
||||
before do
|
||||
order.line_items << create(:line_item,
|
||||
product: create(:product, supplier_id: producer.id))
|
||||
end
|
||||
context "order distributor allow producer to edit orders" do
|
||||
let(:distributor) do
|
||||
create(:distributor_enterprise, enable_producers_to_edit_orders: true)
|
||||
end
|
||||
|
||||
it { is_expected.to be_truthy }
|
||||
end
|
||||
|
||||
context "order distributor doesn't allow producer to edit orders" do
|
||||
let(:distributor) { create(:distributor_enterprise) }
|
||||
it { is_expected.to be_falsey }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "no order containing their product" do
|
||||
let(:user) { create(:user, enterprises: [create(:distributor_enterprise)]) }
|
||||
|
||||
it { is_expected.to be_falsey }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,7 +4,6 @@ require 'spec_helper'
|
||||
|
||||
module Permissions
|
||||
RSpec.describe Order do
|
||||
let(:user) { double(:user) }
|
||||
let(:permissions) { Permissions::Order.new(user) }
|
||||
let!(:basic_permissions) { OpenFoodNetwork::Permissions.new(user) }
|
||||
let(:distributor) { create(:distributor_enterprise) }
|
||||
@@ -28,68 +27,24 @@ module Permissions
|
||||
|
||||
before { allow(OpenFoodNetwork::Permissions).to receive(:new) { basic_permissions } }
|
||||
|
||||
describe "finding orders that are visible in reports" do
|
||||
let(:random_enterprise) { create(:distributor_enterprise) }
|
||||
let(:order) { create(:order, order_cycle:, distributor: ) }
|
||||
let!(:line_item) { create(:line_item, order:) }
|
||||
let!(:producer) { create(:supplier_enterprise) }
|
||||
context "with user cannot only manage line_items in orders" do
|
||||
let(:user) { instance_double('Spree::User', can_manage_line_items_in_orders_only?: false) }
|
||||
|
||||
before do
|
||||
allow(basic_permissions).to receive(:coordinated_order_cycles) { Enterprise.where("1=0") }
|
||||
end
|
||||
describe "finding orders that are visible in reports" do
|
||||
let(:random_enterprise) { create(:distributor_enterprise) }
|
||||
let(:order) { create(:order, order_cycle:, distributor: ) }
|
||||
let!(:line_item) { create(:line_item, order:) }
|
||||
let!(:producer) { create(:supplier_enterprise) }
|
||||
|
||||
context "as the hub through which the order was placed" do
|
||||
before do
|
||||
allow(basic_permissions).to receive(:managed_enterprises) {
|
||||
Enterprise.where(id: distributor)
|
||||
}
|
||||
allow(basic_permissions).to receive(:coordinated_order_cycles) { Enterprise.where("1=0") }
|
||||
end
|
||||
|
||||
it "should let me see the order" do
|
||||
expect(permissions.visible_orders).to include order
|
||||
end
|
||||
end
|
||||
|
||||
context "as the coordinator of the order cycle through which the order was placed" do
|
||||
before do
|
||||
allow(basic_permissions).to receive(:managed_enterprises) {
|
||||
Enterprise.where(id: coordinator)
|
||||
}
|
||||
allow(basic_permissions).to receive(:coordinated_order_cycles) {
|
||||
OrderCycle.where(id: order_cycle)
|
||||
}
|
||||
end
|
||||
|
||||
it "should let me see the order" do
|
||||
expect(permissions.visible_orders).to include order
|
||||
end
|
||||
|
||||
context "with search params" do
|
||||
let(:search_params) { { completed_at_gt: Time.zone.now.yesterday.strftime('%Y-%m-%d') } }
|
||||
let(:permissions) { Permissions::Order.new(user, search_params) }
|
||||
|
||||
it "only returns completed, non-cancelled orders within search filter range" do
|
||||
expect(permissions.visible_orders).to include order_completed
|
||||
expect(permissions.visible_orders).not_to include order_cancelled
|
||||
expect(permissions.visible_orders).not_to include order_cart
|
||||
expect(permissions.visible_orders).not_to include order_from_last_year
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "as a producer which has granted P-OC to the distributor of an order" do
|
||||
before do
|
||||
allow(basic_permissions).to receive(:managed_enterprises) {
|
||||
Enterprise.where(id: producer)
|
||||
}
|
||||
create(:enterprise_relationship, parent: producer, child: distributor,
|
||||
permissions_list: [:add_to_order_cycle])
|
||||
end
|
||||
|
||||
context "which contains my products" do
|
||||
context "as the hub through which the order was placed" do
|
||||
before do
|
||||
line_item.variant.supplier = producer
|
||||
line_item.variant.save
|
||||
allow(basic_permissions).to receive(:managed_enterprises) {
|
||||
Enterprise.where(id: distributor)
|
||||
}
|
||||
end
|
||||
|
||||
it "should let me see the order" do
|
||||
@@ -97,118 +52,208 @@ module Permissions
|
||||
end
|
||||
end
|
||||
|
||||
context "which does not contain my products" do
|
||||
context "as the coordinator of the order cycle through which the order was placed" do
|
||||
before do
|
||||
allow(basic_permissions).to receive(:managed_enterprises) {
|
||||
Enterprise.where(id: coordinator)
|
||||
}
|
||||
allow(basic_permissions).to receive(:coordinated_order_cycles) {
|
||||
OrderCycle.where(id: order_cycle)
|
||||
}
|
||||
end
|
||||
|
||||
it "should let me see the order" do
|
||||
expect(permissions.visible_orders).to include order
|
||||
end
|
||||
|
||||
context "with search params" do
|
||||
let(:search_params) {
|
||||
{ completed_at_gt: Time.zone.now.yesterday.strftime('%Y-%m-%d') }
|
||||
}
|
||||
let(:permissions) { Permissions::Order.new(user, search_params) }
|
||||
|
||||
it "only returns completed, non-cancelled orders within search filter range" do
|
||||
expect(permissions.visible_orders).to include order_completed
|
||||
expect(permissions.visible_orders).not_to include order_cancelled
|
||||
expect(permissions.visible_orders).not_to include order_cart
|
||||
expect(permissions.visible_orders).not_to include order_from_last_year
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "as a producer which has granted P-OC to the distributor of an order" do
|
||||
before do
|
||||
allow(basic_permissions).to receive(:managed_enterprises) {
|
||||
Enterprise.where(id: producer)
|
||||
}
|
||||
create(:enterprise_relationship, parent: producer, child: distributor,
|
||||
permissions_list: [:add_to_order_cycle])
|
||||
end
|
||||
|
||||
context "which contains my products" do
|
||||
before do
|
||||
line_item.variant.supplier = producer
|
||||
line_item.variant.save
|
||||
end
|
||||
|
||||
it "should let me see the order" do
|
||||
expect(permissions.visible_orders).to include order
|
||||
end
|
||||
end
|
||||
|
||||
context "which does not contain my products" do
|
||||
it "should not let me see the order" do
|
||||
expect(permissions.visible_orders).not_to include order
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "as an enterprise that is a distributor in the order cycle, " \
|
||||
"but not the distributor of the order" do
|
||||
before do
|
||||
allow(basic_permissions).to receive(:managed_enterprises) {
|
||||
Enterprise.where(id: random_enterprise)
|
||||
}
|
||||
end
|
||||
|
||||
it "should not let me see the order" do
|
||||
expect(permissions.visible_orders).not_to include order
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "as an enterprise that is a distributor in the order cycle, " \
|
||||
"but not the distributor of the order" do
|
||||
describe "finding line items that are visible in reports" do
|
||||
let(:random_enterprise) { create(:distributor_enterprise) }
|
||||
let(:order) { create(:order, order_cycle:, distributor: ) }
|
||||
let!(:line_item1) { create(:line_item, order:) }
|
||||
let!(:line_item2) { create(:line_item, order:) }
|
||||
let!(:producer) { create(:supplier_enterprise) }
|
||||
|
||||
before do
|
||||
allow(basic_permissions).to receive(:managed_enterprises) {
|
||||
Enterprise.where(id: random_enterprise)
|
||||
}
|
||||
allow(basic_permissions).to receive(:coordinated_order_cycles) { Enterprise.where("1=0") }
|
||||
end
|
||||
|
||||
it "should not let me see the order" do
|
||||
expect(permissions.visible_orders).not_to include order
|
||||
context "as the hub through which the parent order was placed" do
|
||||
before do
|
||||
allow(basic_permissions).to receive(:managed_enterprises) {
|
||||
Enterprise.where(id: distributor)
|
||||
}
|
||||
end
|
||||
|
||||
it "should let me see the line_items" do
|
||||
expect(permissions.visible_line_items).to include line_item1, line_item2
|
||||
end
|
||||
end
|
||||
|
||||
context "as the coordinator of the order cycle through which the parent order was placed" do
|
||||
before do
|
||||
allow(basic_permissions).to receive(:managed_enterprises) {
|
||||
Enterprise.where(id: coordinator)
|
||||
}
|
||||
allow(basic_permissions).to receive(:coordinated_order_cycles) {
|
||||
OrderCycle.where(id: order_cycle)
|
||||
}
|
||||
end
|
||||
|
||||
it "should let me see the line_items" do
|
||||
expect(permissions.visible_line_items).to include line_item1, line_item2
|
||||
end
|
||||
end
|
||||
|
||||
context "as the manager producer which has granted P-OC to the distributor " \
|
||||
"of the parent order" do
|
||||
before do
|
||||
allow(basic_permissions).to receive(:managed_enterprises) {
|
||||
Enterprise.where(id: producer)
|
||||
}
|
||||
create(:enterprise_relationship, parent: producer, child: distributor,
|
||||
permissions_list: [:add_to_order_cycle])
|
||||
|
||||
line_item1.variant.supplier = producer
|
||||
line_item1.variant.save
|
||||
end
|
||||
|
||||
it "should let me see the line_items pertaining to variants I produce" do
|
||||
ps = permissions.visible_line_items
|
||||
expect(ps).to include line_item1
|
||||
expect(ps).not_to include line_item2
|
||||
end
|
||||
end
|
||||
|
||||
context "as an enterprise that is a distributor in the order cycle, " \
|
||||
"but not the distributor of the parent order" do
|
||||
before do
|
||||
allow(basic_permissions).to receive(:managed_enterprises) {
|
||||
Enterprise.where(id: random_enterprise)
|
||||
}
|
||||
end
|
||||
|
||||
it "should not let me see the line_items" do
|
||||
expect(permissions.visible_line_items).not_to include line_item1, line_item2
|
||||
end
|
||||
end
|
||||
|
||||
context "with search params" do
|
||||
let!(:line_item3) { create(:line_item, order: order_completed) }
|
||||
let!(:line_item4) { create(:line_item, order: order_cancelled) }
|
||||
let!(:line_item5) { create(:line_item, order: order_cart) }
|
||||
let!(:line_item6) { create(:line_item, order: order_from_last_year) }
|
||||
|
||||
let(:search_params) { { completed_at_gt: Time.zone.now.yesterday.strftime('%Y-%m-%d') } }
|
||||
let(:permissions) { Permissions::Order.new(user, search_params) }
|
||||
|
||||
before do
|
||||
allow(user).to receive(:admin?) { "admin" }
|
||||
end
|
||||
|
||||
it "only returns line items from completed, " \
|
||||
"non-cancelled orders within search filter range" do
|
||||
expect(permissions.visible_line_items).to include order_completed.line_items.first
|
||||
expect(permissions.visible_line_items).not_to include order_cancelled.line_items.first
|
||||
expect(permissions.visible_line_items).not_to include order_cart.line_items.first
|
||||
expect(permissions.visible_line_items)
|
||||
.not_to include order_from_last_year.line_items.first
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "finding line items that are visible in reports" do
|
||||
let(:random_enterprise) { create(:distributor_enterprise) }
|
||||
let(:order) { create(:order, order_cycle:, distributor: ) }
|
||||
let!(:line_item1) { create(:line_item, order:) }
|
||||
let!(:line_item2) { create(:line_item, order:) }
|
||||
let!(:producer) { create(:supplier_enterprise) }
|
||||
|
||||
before do
|
||||
allow(basic_permissions).to receive(:coordinated_order_cycles) { Enterprise.where("1=0") }
|
||||
context "with user can only manage line_items in orders" do
|
||||
let(:producer) { create(:supplier_enterprise) }
|
||||
let(:user) do
|
||||
create(:user, enterprises: [producer])
|
||||
end
|
||||
let!(:order_by_distributor_allow_edits) do
|
||||
order = create(
|
||||
:order_with_line_items,
|
||||
distributor: create(
|
||||
:distributor_enterprise,
|
||||
enable_producers_to_edit_orders: true
|
||||
),
|
||||
line_items_count: 1
|
||||
)
|
||||
order.line_items.first.variant.update_attribute(:supplier_id, producer.id)
|
||||
|
||||
context "as the hub through which the parent order was placed" do
|
||||
before do
|
||||
allow(basic_permissions).to receive(:managed_enterprises) {
|
||||
Enterprise.where(id: distributor)
|
||||
}
|
||||
end
|
||||
|
||||
it "should let me see the line_items" do
|
||||
expect(permissions.visible_line_items).to include line_item1, line_item2
|
||||
order
|
||||
end
|
||||
let!(:order_by_distributor_disallow_edits) do
|
||||
create(
|
||||
:order_with_line_items,
|
||||
distributor: create(:distributor_enterprise),
|
||||
line_items_count: 1
|
||||
)
|
||||
end
|
||||
describe "#editable_orders" do
|
||||
it "returns orders where the distributor allows producers to edit" do
|
||||
expect(permissions.editable_orders.count).to eq 1
|
||||
expect(permissions.editable_orders).to include order_by_distributor_allow_edits
|
||||
end
|
||||
end
|
||||
|
||||
context "as the coordinator of the order cycle through which the parent order was placed" do
|
||||
before do
|
||||
allow(basic_permissions).to receive(:managed_enterprises) {
|
||||
Enterprise.where(id: coordinator)
|
||||
}
|
||||
allow(basic_permissions).to receive(:coordinated_order_cycles) {
|
||||
OrderCycle.where(id: order_cycle)
|
||||
}
|
||||
end
|
||||
|
||||
it "should let me see the line_items" do
|
||||
expect(permissions.visible_line_items).to include line_item1, line_item2
|
||||
end
|
||||
end
|
||||
|
||||
context "as the manager producer which has granted P-OC to the distributor " \
|
||||
"of the parent order" do
|
||||
before do
|
||||
allow(basic_permissions).to receive(:managed_enterprises) {
|
||||
Enterprise.where(id: producer)
|
||||
}
|
||||
create(:enterprise_relationship, parent: producer, child: distributor,
|
||||
permissions_list: [:add_to_order_cycle])
|
||||
|
||||
line_item1.variant.supplier = producer
|
||||
line_item1.variant.save
|
||||
end
|
||||
|
||||
it "should let me see the line_items pertaining to variants I produce" do
|
||||
ps = permissions.visible_line_items
|
||||
expect(ps).to include line_item1
|
||||
expect(ps).not_to include line_item2
|
||||
end
|
||||
end
|
||||
|
||||
context "as an enterprise that is a distributor in the order cycle, " \
|
||||
"but not the distributor of the parent order" do
|
||||
before do
|
||||
allow(basic_permissions).to receive(:managed_enterprises) {
|
||||
Enterprise.where(id: random_enterprise)
|
||||
}
|
||||
end
|
||||
|
||||
it "should not let me see the line_items" do
|
||||
expect(permissions.visible_line_items).not_to include line_item1, line_item2
|
||||
end
|
||||
end
|
||||
|
||||
context "with search params" do
|
||||
let!(:line_item3) { create(:line_item, order: order_completed) }
|
||||
let!(:line_item4) { create(:line_item, order: order_cancelled) }
|
||||
let!(:line_item5) { create(:line_item, order: order_cart) }
|
||||
let!(:line_item6) { create(:line_item, order: order_from_last_year) }
|
||||
|
||||
let(:search_params) { { completed_at_gt: Time.zone.now.yesterday.strftime('%Y-%m-%d') } }
|
||||
let(:permissions) { Permissions::Order.new(user, search_params) }
|
||||
|
||||
before do
|
||||
allow(user).to receive(:admin?) { "admin" }
|
||||
end
|
||||
|
||||
it "only returns line items from completed, " \
|
||||
"non-cancelled orders within search filter range" do
|
||||
expect(permissions.visible_line_items).to include order_completed.line_items.first
|
||||
expect(permissions.visible_line_items).not_to include order_cancelled.line_items.first
|
||||
expect(permissions.visible_line_items).not_to include order_cart.line_items.first
|
||||
expect(permissions.visible_line_items)
|
||||
.not_to include order_from_last_year.line_items.first
|
||||
describe "#editable_line_items" do
|
||||
it "returns line items from orders where the distributor allows producers to edit" do
|
||||
expect(permissions.editable_line_items.count).to eq 1
|
||||
expect(permissions.editable_line_items.first.order).to eq order_by_distributor_allow_edits
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
165
spec/system/admin/orders/producer_actions_spec.rb
Normal file
165
spec/system/admin/orders/producer_actions_spec.rb
Normal file
@@ -0,0 +1,165 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'system_helper'
|
||||
|
||||
RSpec.describe 'As a producer who have the ability to update orders' do
|
||||
include AdminHelper
|
||||
include AuthenticationHelper
|
||||
include WebHelper
|
||||
|
||||
let!(:supplier1) { create(:supplier_enterprise, name: 'My supplier1') }
|
||||
let!(:supplier2) { create(:supplier_enterprise, name: 'My supplier2') }
|
||||
let!(:supplier1_v1) { create(:variant, supplier_id: supplier1.id) }
|
||||
let!(:supplier1_v2) { create(:variant, supplier_id: supplier1.id) }
|
||||
let!(:supplier2_v1) { create(:variant, supplier_id: supplier2.id) }
|
||||
let(:order_cycle) do
|
||||
create(:simple_order_cycle, distributors: [distributor], variants: [supplier1_v1, supplier1_v2])
|
||||
end
|
||||
let!(:order_containing_supplier1_products) do
|
||||
o = create(
|
||||
:completed_order_with_totals,
|
||||
distributor:, order_cycle:,
|
||||
user: supplier1_ent_user, line_items_count: 1
|
||||
)
|
||||
o.line_items.first.update_columns(variant_id: supplier1_v1.id)
|
||||
o
|
||||
end
|
||||
let!(:order_containing_supplier2_v1_products) do
|
||||
o = create(
|
||||
:completed_order_with_totals,
|
||||
distributor:, order_cycle:,
|
||||
user: supplier2_ent_user, line_items_count: 1
|
||||
)
|
||||
o.line_items.first.update_columns(variant_id: supplier2_v1.id)
|
||||
o
|
||||
end
|
||||
let(:supplier1_ent_user) { create(:user, enterprises: [supplier1]) }
|
||||
let(:supplier2_ent_user) { create(:user, enterprises: [supplier2]) }
|
||||
|
||||
context "As supplier1 enterprise user" do
|
||||
before { login_as(supplier1_ent_user) }
|
||||
let(:order) { order_containing_supplier1_products }
|
||||
let(:user) { supplier1_ent_user }
|
||||
|
||||
describe 'orders index page' do
|
||||
before { visit spree.admin_orders_path }
|
||||
|
||||
context "when no distributor allow the producer to edit orders" do
|
||||
let(:distributor) { create(:distributor_enterprise) }
|
||||
|
||||
it "should not allow producer to view orders page" do
|
||||
expect(page).to have_content 'Unauthorized'
|
||||
end
|
||||
end
|
||||
|
||||
context "when distributor allows the producer to edit orders" do
|
||||
let(:distributor) { create(:distributor_enterprise, enable_producers_to_edit_orders: true) }
|
||||
it "should not allow to add new orders" do
|
||||
expect(page).not_to have_link('New Order')
|
||||
end
|
||||
|
||||
context "when distributor doesn't allow to view customer details" do
|
||||
it "should allow producer to view orders page with HIDDEN customer details" do
|
||||
within('#listing_orders tbody') do
|
||||
expect(page).to have_selector('tr', count: 1) # Only one order
|
||||
# One for Email, one for Name
|
||||
expect(page).to have_selector('td', text: '< Hidden >', count: 2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when distributor allows to view customer details" do
|
||||
let(:distributor) do
|
||||
create(
|
||||
:distributor_enterprise,
|
||||
enable_producers_to_edit_orders: true,
|
||||
show_customer_names_to_suppliers: true
|
||||
)
|
||||
end
|
||||
it "should allow producer to view orders page with customer details" do
|
||||
within('#listing_orders tbody') do
|
||||
name = order.bill_address&.full_name_for_sorting
|
||||
email = order.email
|
||||
expect(page).to have_selector('tr', count: 1) # Only one order
|
||||
expect(page).to have_selector('td', text: name, count: 1)
|
||||
expect(page).to have_selector('td', text: email, count: 1)
|
||||
within 'td.actions' do
|
||||
# to have edit button
|
||||
expect(page).to have_selector("a.icon-edit")
|
||||
# not to have ship button
|
||||
expect(page).not_to have_selector('button.icon-road')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'orders edit page' do
|
||||
before { visit spree.edit_admin_order_path(order) }
|
||||
|
||||
context "when no distributor allow the producer to edit orders" do
|
||||
let(:distributor) { create(:distributor_enterprise) }
|
||||
|
||||
it "should not allow producer to view orders page" do
|
||||
expect(page).to have_content 'Unauthorized'
|
||||
end
|
||||
end
|
||||
|
||||
context "when distributor allows to edit orders" do
|
||||
let(:distributor) { create(:distributor_enterprise, enable_producers_to_edit_orders: true) }
|
||||
let(:product) { supplier1_v2.product }
|
||||
|
||||
it "should allow me to manage my products in the order" do
|
||||
expect(page).to have_content 'Add Product'
|
||||
|
||||
# Add my product
|
||||
add_product(product)
|
||||
expect_product_change(product, :add)
|
||||
|
||||
# Edit my product
|
||||
edit_product(product)
|
||||
expect_product_change(product, :update, 2)
|
||||
|
||||
# Delete my product
|
||||
delete_product(product)
|
||||
expect_product_change(product, :remove)
|
||||
end
|
||||
end
|
||||
|
||||
def expect_product_change(product, action, expected_qty = 0)
|
||||
# JS for this page sometimes take more than 2 seconds (default timeout for cappybara)
|
||||
timeout = 5
|
||||
|
||||
within('table.index tbody tr', wait: timeout) do
|
||||
case action
|
||||
when :add
|
||||
expect(page).to have_text(product.name, wait: timeout)
|
||||
when :update
|
||||
expect(page).to have_text(expected_qty.to_s, wait: timeout)
|
||||
when :remove
|
||||
expect(page).not_to have_text(product.name, wait: timeout)
|
||||
else
|
||||
raise 'Invalid action'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def add_product(product)
|
||||
select2_select product.name, from: 'add_variant_id', search: true
|
||||
find('button.add_variant').click
|
||||
end
|
||||
|
||||
def edit_product(product)
|
||||
find('a.edit-item.icon_link.icon-edit.no-text.with-tip').click
|
||||
fill_in 'quantity', with: 2
|
||||
find("a[data-variant-id='#{product.variants.last.id}'][data-action='save']").click
|
||||
end
|
||||
|
||||
def delete_product(product)
|
||||
find("a[data-variant-id='#{product.variants.last.id}'][data-action='remove']").click
|
||||
click_button 'OK'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
77
spec/system/admin/producer_bulk_order_management.rb
Normal file
77
spec/system/admin/producer_bulk_order_management.rb
Normal file
@@ -0,0 +1,77 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'system_helper'
|
||||
|
||||
RSpec.describe 'As a producer who have the ability to update orders' do
|
||||
include AdminHelper
|
||||
include AuthenticationHelper
|
||||
include WebHelper
|
||||
|
||||
let!(:supplier1) { create(:supplier_enterprise, name: 'My supplier1') }
|
||||
let!(:supplier2) { create(:supplier_enterprise, name: 'My supplier2') }
|
||||
let!(:supplier1_v1) { create(:variant, supplier_id: supplier1.id) }
|
||||
let!(:supplier1_v2) { create(:variant, supplier_id: supplier1.id) }
|
||||
let!(:supplier2_v1) { create(:variant, supplier_id: supplier2.id) }
|
||||
let(:order_cycle) do
|
||||
create(:simple_order_cycle, distributors: [distributor], variants: [supplier1_v1, supplier1_v2])
|
||||
end
|
||||
let!(:order_containing_supplier1_products) do
|
||||
o = create(
|
||||
:completed_order_with_totals,
|
||||
distributor:, order_cycle:,
|
||||
user: supplier1_ent_user, line_items_count: 1
|
||||
)
|
||||
o.line_items.first.update_columns(variant_id: supplier1_v1.id)
|
||||
o
|
||||
end
|
||||
|
||||
let(:supplier1_ent_user) { create(:user, enterprises: [supplier1]) }
|
||||
|
||||
context "As supplier1 enterprise user" do
|
||||
before { login_as(supplier1_ent_user) }
|
||||
let(:order) { order_containing_supplier1_products }
|
||||
let(:user) { supplier1_ent_user }
|
||||
|
||||
describe 'bulk orders index page' do
|
||||
before { visit spree.admin_bulk_order_management_path }
|
||||
|
||||
context "when no distributor allow the producer to edit orders" do
|
||||
let(:distributor) { create(:distributor_enterprise) }
|
||||
|
||||
it "should not allow producer to view orders page" do
|
||||
expect(page).to have_content 'Unauthorized'
|
||||
end
|
||||
end
|
||||
|
||||
context "when distributor allows the producer to edit orders" do
|
||||
let(:distributor) { create(:distributor_enterprise, enable_producers_to_edit_orders: true) }
|
||||
|
||||
context "when distributor doesn't allow to view customer details" do
|
||||
it "should allow producer to view bulk orders page with HIDDEN customer details" do
|
||||
within('tbody') do
|
||||
expect(page).to have_selector('tr', count: 1)
|
||||
expect(page).to have_selector('td', text: '< Hidden >', count: 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when distributor allows to view customer details" do
|
||||
let(:distributor) do
|
||||
create(
|
||||
:distributor_enterprise,
|
||||
enable_producers_to_edit_orders: true,
|
||||
show_customer_names_to_suppliers: true
|
||||
)
|
||||
end
|
||||
it "should allow producer to view bulk orders page with customer details" do
|
||||
within('tbody') do
|
||||
expect(page).to have_selector('tr', count: 1)
|
||||
expect(page).to have_selector('td', text: order.bill_address.full_name_for_sorting,
|
||||
count: 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -21,7 +21,7 @@ RSpec.describe "spree/admin/orders/edit.html.haml" do
|
||||
end
|
||||
end
|
||||
|
||||
allow(view).to receive_messages spree_current_user: create(:user)
|
||||
allow(view).to receive_messages spree_current_user: create(:admin_user)
|
||||
end
|
||||
|
||||
context "when order is complete" do
|
||||
|
||||
Reference in New Issue
Block a user