mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-12 18:36:49 +00:00
Compare commits
37 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a6cd393c57 | ||
|
|
b1060bf1c9 | ||
|
|
1bf5fbaf3a | ||
|
|
2ace3afd67 | ||
|
|
0bfceb877d | ||
|
|
c1d28b2e8f | ||
|
|
98e44e7a40 | ||
|
|
51c6c19f80 | ||
|
|
75b7a1864b | ||
|
|
193ae7936e | ||
|
|
0971e8d9b5 | ||
|
|
e78b44b9ca | ||
|
|
c5779eff81 | ||
|
|
b616c14f63 | ||
|
|
f4c351febf | ||
|
|
30184ac6aa | ||
|
|
a123d45eca | ||
|
|
a75f16e23c | ||
|
|
546e90b286 | ||
|
|
15058299d8 | ||
|
|
c7cb982c9a | ||
|
|
34e9112c0a | ||
|
|
28eb11bda5 | ||
|
|
d8e82d9c88 | ||
|
|
5192a08082 | ||
|
|
94d3f136e2 | ||
|
|
db3a923ea7 | ||
|
|
619eb43c57 | ||
|
|
5c221621d3 | ||
|
|
60d7ed5036 | ||
|
|
e74328f1d7 | ||
|
|
6abd652251 | ||
|
|
3821eede51 | ||
|
|
020af0c0e4 | ||
|
|
00a3976905 | ||
|
|
3bd8e430f9 | ||
|
|
77733169fc |
@@ -11,3 +11,9 @@ OFN_REDIS_URL="redis://localhost:6379/1"
|
||||
OFN_REDIS_JOBS_URL="redis://localhost:6379/2"
|
||||
|
||||
SITE_URL="0.0.0.0:3000"
|
||||
|
||||
# Deactivate rack-timeout in development.
|
||||
# https://github.com/zombocom/rack-timeout#configuring
|
||||
RACK_TIMEOUT_SERVICE_TIMEOUT="0"
|
||||
RACK_TIMEOUT_WAIT_TIMEOUT="0"
|
||||
RACK_TIMEOUT_WAIT_OVERTIME="0"
|
||||
|
||||
2
Gemfile
2
Gemfile
@@ -92,6 +92,7 @@ gem 'gmaps4rails'
|
||||
gem 'mimemagic', '> 0.3.5'
|
||||
gem 'paper_trail', '~> 12.1'
|
||||
gem 'rack-rewrite'
|
||||
gem 'rack-timeout'
|
||||
gem 'roadie-rails'
|
||||
|
||||
gem 'hiredis'
|
||||
@@ -141,7 +142,6 @@ gem "private_address_check"
|
||||
|
||||
group :production, :staging do
|
||||
gem 'ddtrace'
|
||||
gem 'rack-timeout'
|
||||
gem 'sd_notify' # For better Systemd process management. Used by Puma.
|
||||
end
|
||||
|
||||
|
||||
18
Gemfile.lock
18
Gemfile.lock
@@ -157,7 +157,7 @@ GEM
|
||||
awesome_nested_set (3.5.0)
|
||||
activerecord (>= 4.0.0, < 7.1)
|
||||
aws-eventstream (1.2.0)
|
||||
aws-partitions (1.739.0)
|
||||
aws-partitions (1.742.0)
|
||||
aws-sdk-core (3.171.0)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
aws-partitions (~> 1, >= 1.651.0)
|
||||
@@ -166,7 +166,7 @@ GEM
|
||||
aws-sdk-kms (1.63.0)
|
||||
aws-sdk-core (~> 3, >= 3.165.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
aws-sdk-s3 (1.120.0)
|
||||
aws-sdk-s3 (1.120.1)
|
||||
aws-sdk-core (~> 3, >= 3.165.0)
|
||||
aws-sdk-kms (~> 1)
|
||||
aws-sigv4 (~> 1.4)
|
||||
@@ -219,7 +219,7 @@ GEM
|
||||
matrix
|
||||
ruby-rc4 (>= 0.1.5)
|
||||
concurrent-ruby (1.2.2)
|
||||
connection_pool (2.3.0)
|
||||
connection_pool (2.4.0)
|
||||
crack (0.4.5)
|
||||
rexml
|
||||
crass (1.0.6)
|
||||
@@ -426,7 +426,7 @@ GEM
|
||||
net-smtp (0.3.3)
|
||||
net-protocol
|
||||
nio4r (2.5.8)
|
||||
nokogiri (1.14.2)
|
||||
nokogiri (1.14.3)
|
||||
mini_portile2 (~> 2.8.0)
|
||||
racc (~> 1.4)
|
||||
oauth2 (1.4.11)
|
||||
@@ -556,7 +556,7 @@ GEM
|
||||
ffi (~> 1.0)
|
||||
redcarpet (3.6.0)
|
||||
redis (4.8.1)
|
||||
redis-client (0.14.0)
|
||||
redis-client (0.14.1)
|
||||
connection_pool
|
||||
regexp_parser (2.7.0)
|
||||
reline (0.3.3)
|
||||
@@ -612,7 +612,7 @@ GEM
|
||||
rswag-ui (2.8.0)
|
||||
actionpack (>= 3.1, < 7.1)
|
||||
railties (>= 3.1, < 7.1)
|
||||
rubocop (1.49.0)
|
||||
rubocop (1.50.0)
|
||||
json (~> 2.3)
|
||||
parallel (~> 1.10)
|
||||
parser (>= 3.2.0.0)
|
||||
@@ -624,7 +624,7 @@ GEM
|
||||
unicode-display_width (>= 2.4.0, < 3.0)
|
||||
rubocop-ast (1.28.0)
|
||||
parser (>= 3.2.1.0)
|
||||
rubocop-rails (2.18.0)
|
||||
rubocop-rails (2.19.0)
|
||||
activesupport (>= 4.2.0)
|
||||
rack (>= 1.1)
|
||||
rubocop (>= 1.33.0, < 2.0)
|
||||
@@ -652,7 +652,7 @@ GEM
|
||||
semantic_range (3.0.0)
|
||||
shoulda-matchers (5.3.0)
|
||||
activesupport (>= 5.2.0)
|
||||
sidekiq (7.0.7)
|
||||
sidekiq (7.0.8)
|
||||
concurrent-ruby (< 2)
|
||||
connection_pool (>= 2.3.0)
|
||||
rack (>= 2.2.4)
|
||||
@@ -698,7 +698,7 @@ GEM
|
||||
railties (>= 5.2, < 8)
|
||||
redis (>= 4.0, < 6.0)
|
||||
stringex (2.8.5)
|
||||
stripe (8.3.0)
|
||||
stripe (8.5.0)
|
||||
swd (1.3.0)
|
||||
activesupport (>= 3)
|
||||
attr_required (>= 0.0.5)
|
||||
|
||||
@@ -11,5 +11,6 @@ angular.module("admin.indexUtils").factory 'SortOptions', ->
|
||||
sortingExpr
|
||||
|
||||
toggle: (predicate) ->
|
||||
@reverse = (@predicate == predicate) && !@reverse
|
||||
# predicate is a string or an array of strings
|
||||
@reverse = (JSON.stringify(@predicate) == JSON.stringify(predicate)) && !@reverse
|
||||
@predicate = predicate
|
||||
|
||||
@@ -2,6 +2,7 @@ angular.module('Darkswarm').factory "EnterpriseModal", ($modal, $rootScope, $htt
|
||||
# Build a modal popup for an enterprise.
|
||||
new class EnterpriseModal
|
||||
open: (enterprise)->
|
||||
return if enterprise.visible == 'hidden'
|
||||
scope = $rootScope.$new(true) # Spawn an isolate to contain the enterprise
|
||||
scope.embedded_layout = window.location.search.indexOf("embedded_shopfront=true") != -1
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@ module Admin
|
||||
else
|
||||
show_report
|
||||
end
|
||||
rescue Timeout::Error
|
||||
render_timeout_error
|
||||
end
|
||||
|
||||
private
|
||||
@@ -36,6 +38,7 @@ module Admin
|
||||
|
||||
def show_report
|
||||
assign_view_data
|
||||
@table = render_report_as(:html) if render_data?
|
||||
render "show"
|
||||
end
|
||||
|
||||
@@ -45,7 +48,6 @@ module Admin
|
||||
@report_subtype = report_subtype
|
||||
@report_title = report_title
|
||||
@rendering_options = rendering_options
|
||||
@table = render_report_as(:html) if render_data?
|
||||
@data = Reporting::FrontendData.new(spree_current_user)
|
||||
end
|
||||
|
||||
@@ -58,7 +60,9 @@ module Admin
|
||||
job = ReportJob.perform_later(
|
||||
report_class, spree_current_user, params, format
|
||||
)
|
||||
sleep 1 until job.done?
|
||||
Timeout.timeout(max_wait_time) do
|
||||
sleep 1 until job.done?
|
||||
end
|
||||
|
||||
# This result has been rendered by Rails in safe mode already.
|
||||
job.result.html_safe # rubocop:disable Rails/OutputSafety
|
||||
@@ -66,5 +70,23 @@ module Admin
|
||||
@report.render_as(format)
|
||||
end
|
||||
end
|
||||
|
||||
def render_timeout_error
|
||||
assign_view_data
|
||||
@error = ".report_taking_longer"
|
||||
render "show"
|
||||
end
|
||||
|
||||
def max_wait_time
|
||||
# This value is used by rack-timeout and nginx, usually 30 seconds in
|
||||
# staging and production:
|
||||
server_timeout = ENV.fetch("RACK_TIMEOUT_SERVICE_TIMEOUT", "15").to_f
|
||||
|
||||
# Zero disables the timeout:
|
||||
return 0 if server_timeout.zero?
|
||||
|
||||
# We want to time out earlier than nginx:
|
||||
server_timeout - 2.seconds
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,4 +4,8 @@ module AddressDisplay
|
||||
def full_name_reverse
|
||||
[lastname, firstname].reject(&:blank?).join(" ")
|
||||
end
|
||||
|
||||
def full_name_for_sorting
|
||||
[last_name, first_name].reject(&:blank?).join(", ")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -267,8 +267,7 @@ class Enterprise < ApplicationRecord
|
||||
|
||||
def plus_parents_and_order_cycle_producers(order_cycles)
|
||||
oc_producer_ids = Exchange.in_order_cycle(order_cycles).incoming.pluck :sender_id
|
||||
Enterprise.not_hidden.is_primary_producer
|
||||
.parents_of_one_union_others(id, oc_producer_ids | [id])
|
||||
Enterprise.is_primary_producer.parents_of_one_union_others(id, oc_producer_ids | [id])
|
||||
end
|
||||
|
||||
def relatives_including_self
|
||||
|
||||
@@ -13,6 +13,7 @@ class EnterpriseRelationship < ApplicationRecord
|
||||
|
||||
after_save :update_permissions_of_child_variant_overrides
|
||||
before_destroy :revoke_all_child_variant_overrides
|
||||
before_destroy :destroy_related_exchanges
|
||||
|
||||
scope :with_enterprises, -> {
|
||||
joins("
|
||||
@@ -102,6 +103,10 @@ class EnterpriseRelationship < ApplicationRecord
|
||||
child_variant_overrides.update_all(permission_revoked_at: Time.zone.now)
|
||||
end
|
||||
|
||||
def destroy_related_exchanges
|
||||
Exchange.where(sender: parent, receiver: child, incoming: true).destroy_all
|
||||
end
|
||||
|
||||
def child_variant_overrides
|
||||
VariantOverride.unscoped.for_hubs(child)
|
||||
.joins(variant: :product).where("spree_products.supplier_id IN (?)", parent)
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class EnterpriseRelationshipPermission < ApplicationRecord
|
||||
belongs_to :enterprise_relationship
|
||||
default_scope { order('name') }
|
||||
before_destroy :destroy_related_exchanges
|
||||
|
||||
def destroy_related_exchanges
|
||||
return if name != "add_to_order_cycle"
|
||||
|
||||
Exchange
|
||||
.where(sender: enterprise_relationship.parent,
|
||||
receiver: enterprise_relationship.child, incoming: true).destroy_all
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,4 +3,9 @@
|
||||
class ExchangeVariant < ApplicationRecord
|
||||
belongs_to :exchange
|
||||
belongs_to :variant, class_name: 'Spree::Variant'
|
||||
after_destroy :destroy_related_outgoing_variants
|
||||
|
||||
def destroy_related_outgoing_variants
|
||||
VariantDeleter.new.destroy_related_outgoing_variants(variant_id, exchange.order_cycle)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,8 +3,10 @@
|
||||
module Api
|
||||
module Admin
|
||||
class OrderSerializer < ActiveModel::Serializer
|
||||
attributes :id, :number, :user_id, :full_name, :email, :phone, :completed_at,
|
||||
:completed_at_utc_iso8601, :display_total,
|
||||
include AddressDisplay
|
||||
|
||||
attributes :id, :number, :user_id, :full_name, :full_name_for_sorting, :email, :phone,
|
||||
:completed_at, :completed_at_utc_iso8601, :display_total,
|
||||
:edit_path, :state, :payment_state, :shipment_state,
|
||||
:payments_path, :ready_to_ship, :ready_to_capture, :created_at,
|
||||
:distributor_name, :special_instructions, :display_outstanding_balance,
|
||||
@@ -17,6 +19,14 @@ module Api
|
||||
object.billing_address.nil? ? "" : ( object.billing_address.full_name || "" )
|
||||
end
|
||||
|
||||
def first_name
|
||||
object.billing_address&.first_name || ""
|
||||
end
|
||||
|
||||
def last_name
|
||||
object.billing_address&.last_name || ""
|
||||
end
|
||||
|
||||
def distributor_name
|
||||
object.distributor&.name
|
||||
end
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
module Api
|
||||
class EnterpriseThinSerializer < ActiveModel::Serializer
|
||||
attributes :name, :id, :active, :path
|
||||
attributes :name, :id, :active, :path, :visible
|
||||
|
||||
has_one :address, serializer: Api::AddressSerializer
|
||||
|
||||
|
||||
@@ -11,6 +11,15 @@ class VariantDeleter
|
||||
variant.destroy
|
||||
end
|
||||
|
||||
def destroy_related_outgoing_variants(variant_id, order_cycle)
|
||||
internal_variants = ExchangeVariant.where(variant_id: variant_id).
|
||||
joins(:exchange).
|
||||
where(
|
||||
exchanges: { order_cycle: order_cycle, incoming: false }
|
||||
)
|
||||
internal_variants.destroy_all
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def only_variant_on_product?(variant)
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
.report__header.print-hidden
|
||||
- if @report.message.present?
|
||||
%p.report__message= @report.message
|
||||
- if request.post?
|
||||
- if request.post? && !@error
|
||||
%button.btn-print.icon-print{ onclick: "window.print()"}= t(:report_print)
|
||||
|
||||
= t(@error) if @error
|
||||
= @table
|
||||
|
||||
@@ -10,11 +10,12 @@
|
||||
%a{"ng-click" => "triggerProductModal()", href: 'javascript:void(0)'}
|
||||
%span{"ng-bind" => "::product.name"}
|
||||
.product-description{ng: {"bind-html": "::product.description_html", click: "triggerProductModal()", show: "product.description_html.length"}}
|
||||
.product-producer
|
||||
= t :products_from
|
||||
%span
|
||||
%enterprise-modal
|
||||
%span{"ng-bind" => "::enterprise.name"}
|
||||
%div{ "ng-switch" => "enterprise.visible" }
|
||||
.product-producer
|
||||
= t :products_from
|
||||
%span{ "ng-switch-when": "hidden", "ng-bind" => "::enterprise.name"}
|
||||
%span{ "ng-switch-default": true }
|
||||
%enterprise-modal{"ng-bind" => "::enterprise.name"}
|
||||
|
||||
.product-properties.filter-shopfront.property-selectors
|
||||
%filter-selector{ 'selector-set' => "productPropertySelectors", objects: "[product] | propertiesWithValuesOf" }
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
= t :shopping_producers_of_hub, hub: '{{ shopfront.name }}'
|
||||
%ul.small-block-grid-1.medium-block-grid-2.large-block-grid-3
|
||||
%li{"ng-repeat" => "enterprise in shopfront.producers"}
|
||||
%enterprise-modal
|
||||
%enterprise-modal{"ng-if": "enterprise.visible != 'hidden'"}
|
||||
%i.ofn-i_036-producers
|
||||
{{ enterprise.name }}
|
||||
%span{"ng-if": "enterprise.visible == 'hidden'"}
|
||||
%i.ofn-i_036-producers
|
||||
{{ enterprise.name }}
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
%a{ :href => '', 'ng-click' => "sorting.toggle('order.number')" }
|
||||
= t("admin.orders.bulk_management.order_no")
|
||||
%th.full_name{ 'ng-show' => 'columns.full_name.visible' }
|
||||
%a{ :href => '', 'ng-click' => "sorting.toggle('order.full_name')" }
|
||||
%a{ :href => '', 'ng-click' => "sorting.toggle('order.full_name_for_sorting')" }
|
||||
= t("admin.name")
|
||||
%th.email{ 'ng-show' => 'columns.email.visible' }
|
||||
%a{ :href => '', 'ng-click' => "sorting.toggle('order.email')" }
|
||||
@@ -170,7 +170,7 @@
|
||||
%td.bulk
|
||||
%input{ :type => "checkbox", :name => 'bulk', 'ng-model' => 'line_item.checked', 'ignore-dirty' => true }
|
||||
%td.order_no{ 'ng-show' => 'columns.order_no.visible' } {{ line_item.order.number }}
|
||||
%td.full_name{ 'ng-show' => 'columns.full_name.visible' } {{ line_item.order.full_name }}
|
||||
%td.full_name{ 'ng-show' => 'columns.full_name.visible' } {{ line_item.order.full_name_for_sorting }}
|
||||
%td.email{ 'ng-show' => 'columns.email.visible' } {{ line_item.order.email }}
|
||||
%td.phone{ 'ng-show' => 'columns.phone.visible' } {{ line_item.order.phone }}
|
||||
%td.date{ 'ng-show' => 'columns.order_date.visible' } {{ line_item.order.completed_at }}
|
||||
|
||||
@@ -1440,6 +1440,11 @@ en:
|
||||
pack_by_customer: Pack By Customer
|
||||
pack_by_supplier: Pack By Supplier
|
||||
pack_by_product: Pack By Product
|
||||
show:
|
||||
report_taking_longer: >
|
||||
Sorry, this report took too long to process.
|
||||
It may contain a lot of data or we are busy with other reports.
|
||||
You can try again later.
|
||||
revenues_by_hub:
|
||||
name: Revenues By Hub
|
||||
description: Revenues by hub
|
||||
|
||||
@@ -1360,6 +1360,10 @@ en_FR:
|
||||
pack_by_customer: Pack By Customer
|
||||
pack_by_supplier: Pack By Supplier
|
||||
pack_by_product: Pack By Product
|
||||
show:
|
||||
report_taking_longer: >
|
||||
Sorry, this report took too long to process. It may contain a lot of data
|
||||
or we are busy with other reports. You can try again later.
|
||||
revenues_by_hub:
|
||||
name: Revenues By Hub
|
||||
description: Revenues by hub
|
||||
@@ -3609,6 +3613,7 @@ en_FR:
|
||||
shipping_categories: "Shipping Categories"
|
||||
new_shipping_category: "New Shipping Category"
|
||||
back_to_shipping_categories: "Back To Shipping Categories"
|
||||
editing_shipping_category: "Editing Shipping Category"
|
||||
name: "Name"
|
||||
description: "Description"
|
||||
type: "Type"
|
||||
|
||||
@@ -1361,6 +1361,11 @@ fr:
|
||||
pack_by_customer: Préparation des commandes par Acheteur
|
||||
pack_by_supplier: Préparation des commandes par Producteur
|
||||
pack_by_product: Préparation des commandes par Produit
|
||||
show:
|
||||
report_taking_longer: >
|
||||
Désolée, ce rapport met trop de temps à se charger, probablement parce
|
||||
qu'il contient une grande quantité de données ou que d'autres rapports
|
||||
sont en cours de téléchargement. Merci de réessayer plus tard.
|
||||
revenues_by_hub:
|
||||
name: CA par boutique
|
||||
description: CA par boutique
|
||||
@@ -3664,6 +3669,7 @@ fr:
|
||||
shipping_categories: "Conditions de transport"
|
||||
new_shipping_category: "Nouvelle condition de transport"
|
||||
back_to_shipping_categories: "Retour aux conditions de transport"
|
||||
editing_shipping_category: "Modifier condition de transport"
|
||||
name: "Produit/Variante"
|
||||
description: "Description"
|
||||
type: "Catégorie"
|
||||
|
||||
@@ -363,7 +363,7 @@ it:
|
||||
supplier_only: Solo Fornitore
|
||||
has_shopfront: Ha una Vetrina
|
||||
weight: Peso
|
||||
volume: Volume
|
||||
volume: Acquisto di gruppo
|
||||
items: Prodotti
|
||||
summary: Sommario
|
||||
detailed: Dettaglio
|
||||
@@ -487,7 +487,7 @@ it:
|
||||
tags: Etichetta
|
||||
variant: Variante
|
||||
weight: Peso
|
||||
volume: Volume
|
||||
volume: Acquisto di gruppo
|
||||
items: Prodotti
|
||||
select_all: Seleziona tutto
|
||||
quick_search: Ricerca veloce
|
||||
|
||||
@@ -11,6 +11,12 @@ module Reporting
|
||||
def query_result
|
||||
search.result.group_by { |order| [order.payment_state, order.distributor] }.values
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def payment_state(order)
|
||||
I18n.t "spree.payment_states.#{order.payment_state}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,7 +6,7 @@ module Reporting
|
||||
class ItemisedPaymentTotals < Base
|
||||
def columns
|
||||
{
|
||||
payment_state: proc { |orders| orders.first.payment_state },
|
||||
payment_state: proc { |orders| payment_state(orders.first) },
|
||||
distributor: proc { |orders| orders.first.distributor.name },
|
||||
product_total_price: proc { |orders| orders.to_a.sum(&:item_total) },
|
||||
shipping_total_price: proc { |orders| orders.sum(&:ship_total) },
|
||||
|
||||
@@ -6,7 +6,7 @@ module Reporting
|
||||
class PaymentTotals < Base
|
||||
def columns
|
||||
{
|
||||
payment_state: proc { |orders| orders.first.payment_state },
|
||||
payment_state: proc { |orders| payment_state(orders.first) },
|
||||
distributor: proc { |orders| orders.first.distributor.name },
|
||||
product_total_price: proc { |orders| orders.to_a.sum(&:item_total) },
|
||||
shipping_total_price: proc { |orders| orders.sum(&:ship_total) },
|
||||
|
||||
@@ -15,7 +15,7 @@ module Reporting
|
||||
|
||||
def columns
|
||||
{
|
||||
payment_state: proc { |payments| payments.first.order.payment_state },
|
||||
payment_state: proc { |payments| payment_state(payments.first.order) },
|
||||
distributor: proc { |payments| payments.first.order.distributor.name },
|
||||
payment_type: proc { |payments| payments.first.payment_method.name },
|
||||
total_price: proc { |payments| payments.sum(&:amount) }
|
||||
|
||||
@@ -19,8 +19,10 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/preset-env": "^7.18.2",
|
||||
"@floating-ui/dom": "^1.2.5",
|
||||
"@babel/core": "^7.21.4",
|
||||
"@babel/plugin-transform-runtime": "^7.21.4",
|
||||
"@babel/preset-env": "^7.21.4",
|
||||
"@floating-ui/dom": "^1.2.6",
|
||||
"@hotwired/turbo": "^7.3.0",
|
||||
"@rails/webpacker": "5.4.4",
|
||||
"babel-loader": "^8.2.3",
|
||||
|
||||
@@ -147,7 +147,7 @@ describe EnterpriseRelationship do
|
||||
end
|
||||
|
||||
describe "callbacks" do
|
||||
context "updating variant override permissions" do
|
||||
describe "updating variant override permissions" do
|
||||
let(:hub) { create(:distributor_enterprise) }
|
||||
let(:producer) { create(:supplier_enterprise) }
|
||||
let(:some_other_producer) { create(:supplier_enterprise) }
|
||||
@@ -255,5 +255,101 @@ describe EnterpriseRelationship do
|
||||
end
|
||||
end
|
||||
end
|
||||
describe "updating order cycles" do
|
||||
let(:hub) { create(:distributor_enterprise) }
|
||||
let(:producer) { create(:supplier_enterprise) }
|
||||
let(:order_cycle) { create(:simple_order_cycle) }
|
||||
let(:some_other_producer) { create(:supplier_enterprise) }
|
||||
|
||||
context "when order_cycle permission is present" do
|
||||
let!(:er) {
|
||||
create(:enterprise_relationship, child: hub, parent: producer,
|
||||
permissions_list: [
|
||||
:add_to_order_cycle,
|
||||
:create_variant_overrides
|
||||
] )
|
||||
}
|
||||
let!(:incoming_external_exchange) {
|
||||
order_cycle.exchanges.create! sender: producer, receiver: hub, incoming: true
|
||||
}
|
||||
let!(:other_external_exchange) {
|
||||
order_cycle.exchanges.create! sender: some_other_producer, receiver: hub, incoming: true
|
||||
}
|
||||
let!(:incoming_internal_exchange) {
|
||||
order_cycle.exchanges.create! sender: hub, receiver: hub, incoming: true
|
||||
}
|
||||
let!(:outgoing_internal_exchange) {
|
||||
order_cycle.exchanges.create! sender: hub, receiver: hub, incoming: false
|
||||
}
|
||||
let!(:variant) { create(:variant) }
|
||||
let!(:some_other_variant) { create(:variant) }
|
||||
let!(:incoming_external_variant) {
|
||||
incoming_external_exchange.exchange_variants.create!(
|
||||
exchange: incoming_external_exchange, variant: variant
|
||||
)
|
||||
}
|
||||
let!(:incoming_internal_only_variant) {
|
||||
incoming_internal_exchange.exchange_variants.create!(
|
||||
exchange: incoming_internal_exchange, variant: some_other_variant
|
||||
)
|
||||
}
|
||||
let!(:outgoing_internal_variant) {
|
||||
outgoing_internal_exchange.exchange_variants.create!(
|
||||
exchange: outgoing_internal_exchange, variant: variant
|
||||
)
|
||||
}
|
||||
let!(:outgoing_internal_only_variant) {
|
||||
outgoing_internal_exchange.exchange_variants.create!(
|
||||
exchange: outgoing_internal_exchange, variant: some_other_variant
|
||||
)
|
||||
}
|
||||
|
||||
# We need to destroy the exchange variants on all order cycles related to the ER if
|
||||
# 'add_to_order_cycle' permission is removed. If they are left on the order cycle, the
|
||||
# Taxons of the variants will still appear on the /shops page, despite the hub not
|
||||
# actually offering the variants anymore.
|
||||
context "removing exchanges and exchange variants" do
|
||||
context "when the enterprise relationship is destroyed" do
|
||||
before { er.destroy }
|
||||
it "should destroy all exchanges and exchange variants related to ER" do
|
||||
expect(Exchange.exists?(incoming_external_exchange.id)).to be false
|
||||
expect(Exchange.exists?(other_external_exchange.id)).to be true
|
||||
expect(ExchangeVariant.exists?(incoming_external_variant.id)).to be false
|
||||
expect(ExchangeVariant.exists?(outgoing_internal_variant.id)).to be false
|
||||
expect(ExchangeVariant.exists?(incoming_internal_only_variant.id)).to be true
|
||||
expect(ExchangeVariant.exists?(outgoing_internal_only_variant.id)).to be true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "and is then removed" do
|
||||
before { er.permissions_list = [:create_variant_overrides]; er.save! }
|
||||
it "should destroy all exchanges and exchange variants related to ER" do
|
||||
expect(Exchange.exists?(incoming_external_exchange.id)).to be false
|
||||
expect(Exchange.exists?(other_external_exchange.id)).to be true
|
||||
expect(ExchangeVariant.exists?(incoming_external_variant.id)).to be false
|
||||
expect(ExchangeVariant.exists?(outgoing_internal_variant.id)).to be false
|
||||
expect(ExchangeVariant.exists?(incoming_internal_only_variant.id)).to be true
|
||||
expect(ExchangeVariant.exists?(outgoing_internal_only_variant.id)).to be true
|
||||
end
|
||||
|
||||
it "should not affect other exchanges or order cycles" do
|
||||
expect(Exchange.exists?(outgoing_internal_exchange.id)).to be true
|
||||
end
|
||||
end
|
||||
|
||||
context "and then some other permission is removed" do
|
||||
before { er.permissions_list = [:add_to_order_cycle]; er.save! }
|
||||
it "should have no effect on existing exchanges" do
|
||||
expect(Exchange.exists?(incoming_external_exchange.id)).to be true
|
||||
expect(Exchange.exists?(other_external_exchange.id)).to be true
|
||||
expect(ExchangeVariant.exists?(incoming_external_variant.id)).to be true
|
||||
expect(ExchangeVariant.exists?(outgoing_internal_variant.id)).to be true
|
||||
expect(ExchangeVariant.exists?(incoming_internal_only_variant.id)).to be true
|
||||
expect(ExchangeVariant.exists?(outgoing_internal_only_variant.id)).to be true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -228,7 +228,7 @@ describe '
|
||||
|
||||
it "displays a column for user's full name" do
|
||||
expect(page).to have_selector "th.full_name", text: "NAME"
|
||||
expect(page).to have_selector "td.full_name", text: o1.bill_address.full_name
|
||||
expect(page).to have_selector "td.full_name", text: "#{o1.bill_address.last_name}, #{o1.bill_address.first_name}"
|
||||
expect(page).to have_selector "td.full_name", text: ""
|
||||
end
|
||||
|
||||
@@ -266,46 +266,69 @@ describe '
|
||||
end
|
||||
|
||||
describe "sorting of line items" do
|
||||
let!(:o1) {
|
||||
create(:order_with_distributor, state: 'complete', shipment_state: 'ready',
|
||||
completed_at: Time.zone.now)
|
||||
}
|
||||
let!(:o2) {
|
||||
create(:order_with_distributor, state: 'complete', shipment_state: 'ready',
|
||||
completed_at: Time.zone.now)
|
||||
}
|
||||
let!(:o1) do
|
||||
create(
|
||||
:order_with_distributor,
|
||||
bill_address: create(:address, first_name: 'Bob', last_name: 'Taylor'),
|
||||
state: 'complete',
|
||||
shipment_state: 'ready',
|
||||
completed_at: Time.zone.now
|
||||
)
|
||||
end
|
||||
|
||||
let!(:o2) do
|
||||
create(
|
||||
:order_with_distributor,
|
||||
bill_address: create(:address, first_name: 'Mary', last_name: 'Smith'),
|
||||
state: 'complete',
|
||||
shipment_state: 'ready',
|
||||
completed_at: Time.zone.now
|
||||
)
|
||||
end
|
||||
|
||||
let!(:o3) do
|
||||
create(
|
||||
:order_with_distributor,
|
||||
bill_address: create(:address, first_name: 'Bill', last_name: 'Taylor'),
|
||||
state: 'complete',
|
||||
shipment_state: 'ready',
|
||||
completed_at: Time.zone.now
|
||||
)
|
||||
end
|
||||
|
||||
let!(:li1) { create(:line_item_with_shipment, order: o1) }
|
||||
let!(:li2) { create(:line_item_with_shipment, order: o2) }
|
||||
let!(:li3) { create(:line_item_with_shipment, order: o3) }
|
||||
|
||||
before :each do
|
||||
visit_bulk_order_management
|
||||
end
|
||||
|
||||
it "sorts by customer name when the customer name header is clicked" do
|
||||
customer_names = [o1.name, o2.name].sort
|
||||
|
||||
it "sorts by customer last name when the customer name header is clicked" do
|
||||
within "#listing_orders thead" do
|
||||
click_on "Name"
|
||||
end
|
||||
|
||||
expect(page).to have_selector("#listing_orders .line_item:nth-child(1) .full_name",
|
||||
text: customer_names[0])
|
||||
text: "Smith, Mary")
|
||||
expect(page).to have_selector("#listing_orders .line_item:nth-child(2) .full_name",
|
||||
text: customer_names[1])
|
||||
text: "Taylor, Bill")
|
||||
expect(page).to have_selector("#listing_orders .line_item:nth-child(3) .full_name",
|
||||
text: "Taylor, Bob")
|
||||
end
|
||||
|
||||
it "sorts by customer name in reverse when the customer name header is clicked twice" do
|
||||
customer_names = [o1.name, o2.name].sort.reverse
|
||||
|
||||
it "sorts by customer last name in reverse when the customer name header is clicked twice" do
|
||||
within "#listing_orders thead" do
|
||||
click_on "Name"
|
||||
click_on "Name"
|
||||
end
|
||||
|
||||
expect(page).to have_selector("#listing_orders .line_item:nth-child(1) .full_name",
|
||||
text: customer_names[1])
|
||||
text: "Taylor, Bob")
|
||||
expect(page).to have_selector("#listing_orders .line_item:nth-child(2) .full_name",
|
||||
text: customer_names[0])
|
||||
text: "Taylor, Bill")
|
||||
expect(page).to have_selector("#listing_orders .line_item:nth-child(3) .full_name",
|
||||
text: "Smith, Mary")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -92,307 +92,306 @@ distributors: [distributor4, distributor5]) }
|
||||
bill_address_id: billing_address5.id)
|
||||
}
|
||||
|
||||
context "logging as superadmin and visiting the orders page" do
|
||||
describe "filters" do
|
||||
before do
|
||||
order2.select_shipping_method(shipping_method.id)
|
||||
order4.select_shipping_method(shipping_method2.id)
|
||||
login_as_admin_and_visit spree.admin_orders_path
|
||||
end
|
||||
|
||||
context "fiters" do
|
||||
it "order cycles appear in descending order by close date on orders page" do
|
||||
open_select2('#s2id_q_order_cycle_id_in')
|
||||
it "order cycles appear in descending order by close date on orders page" do
|
||||
open_select2('#s2id_q_order_cycle_id_in')
|
||||
|
||||
expect(find('#q_order_cycle_id_in',
|
||||
visible: :all)[:innerHTML]).to have_content(/.*Four.*Three.*Two.*Five/m)
|
||||
expect(find('#q_order_cycle_id_in',
|
||||
visible: :all)[:innerHTML]).to have_content(/.*Four.*Three.*Two.*Five/m)
|
||||
end
|
||||
|
||||
it "filter by multiple order cycles" do
|
||||
select2_select 'Two', from: 'q_order_cycle_id_in'
|
||||
select2_select 'Three', from: 'q_order_cycle_id_in'
|
||||
|
||||
page.find('.filter-actions .button.icon-search').click
|
||||
|
||||
# Order 2 and 3 should show, but not 4
|
||||
expect(page).to have_content order2.number
|
||||
expect(page).to have_content order3.number
|
||||
expect(page).to_not have_content order4.number
|
||||
end
|
||||
|
||||
it "filter by distributors" do
|
||||
select2_select distributor2.name.to_s, from: 'q_distributor_id_in'
|
||||
select2_select distributor4.name.to_s, from: 'q_distributor_id_in'
|
||||
|
||||
page.find('.filter-actions .button.icon-search').click
|
||||
|
||||
# Order 2 and 4 should show, but not 3
|
||||
expect(page).to have_content order2.number
|
||||
expect(page).to_not have_content order3.number
|
||||
expect(page).to have_content order4.number
|
||||
end
|
||||
|
||||
it "filter by complete date" do
|
||||
find("input.datepicker").click
|
||||
select_dates_from_daterangepicker(order3.completed_at.yesterday,
|
||||
order4.completed_at.tomorrow)
|
||||
|
||||
page.find('.filter-actions .button.icon-search').click
|
||||
|
||||
# Order 3 and 4 should show, but not 2
|
||||
expect(page).to_not have_content order2.number
|
||||
expect(page).to have_content order3.number
|
||||
expect(page).to have_content order4.number
|
||||
end
|
||||
|
||||
it "filter by email" do
|
||||
fill_in "Email", with: customer3.email
|
||||
|
||||
page.find('.filter-actions .button.icon-search').click
|
||||
|
||||
# Order 3 should show, but not 2 and 4
|
||||
expect(page).to_not have_content order2.number
|
||||
expect(page).to have_content order3.number
|
||||
expect(page).to_not have_content order4.number
|
||||
end
|
||||
|
||||
it "filter by customer first and last names" do
|
||||
# NOTE: this field refers to the name given in billing addresses and not to customer name
|
||||
# filtering by first name
|
||||
fill_in "First name begins with", with: billing_address2.firstname
|
||||
page.find('.filter-actions .button.icon-search').click
|
||||
# Order 3 should show, but not 2 and 4
|
||||
expect(page).to have_content order2.number
|
||||
expect(page).to_not have_content order3.number
|
||||
expect(page).to_not have_content order4.number
|
||||
|
||||
find("a#clear_filters_button").click
|
||||
# filtering by last name
|
||||
|
||||
fill_in "Last name begins with", with: billing_address4.lastname
|
||||
page.find('.filter-actions .button.icon-search').click
|
||||
# Order 4 should show, but not 2 and 3
|
||||
expect(page).to_not have_content order2.number
|
||||
expect(page).to_not have_content order3.number
|
||||
expect(page).to have_content order4.number
|
||||
end
|
||||
|
||||
it "filter by shipping methods" do
|
||||
order2.select_shipping_method(shipping_method.id)
|
||||
order4.select_shipping_method(shipping_method2.id)
|
||||
|
||||
select2_select "Pick-up at the farm", from: 'q_shipping_method_id'
|
||||
page.find('.filter-actions .button.icon-search').click
|
||||
# Order 2 should show, but not 3 and 5
|
||||
expect(page).to have_content order2.number
|
||||
expect(page).to_not have_content order3.number
|
||||
expect(page).to_not have_content order4.number
|
||||
|
||||
find("a#clear_filters_button").click
|
||||
|
||||
select2_select "Signed, sealed, delivered", from: 'q_shipping_method_id'
|
||||
page.find('.filter-actions .button.icon-search').click
|
||||
# Order 4 should show, but not 2 and 3
|
||||
expect(page).to_not have_content order2.number
|
||||
expect(page).to_not have_content order3.number
|
||||
expect(page).to have_content order4.number
|
||||
end
|
||||
|
||||
it "filter by invoice number" do
|
||||
fill_in "Invoice number:", with: order2.number
|
||||
|
||||
page.find('.filter-actions .button.icon-search').click
|
||||
|
||||
# Order 2 should show, but not 3 and 4
|
||||
expect(page).to have_content order2.number
|
||||
expect(page).to_not have_content order3.number
|
||||
expect(page).to_not have_content order4.number
|
||||
end
|
||||
|
||||
it "filter by order state" do
|
||||
order.update(state: "payment")
|
||||
|
||||
uncheck 'Only show complete orders'
|
||||
page.find('.filter-actions .button.icon-search').click
|
||||
|
||||
expect(page).to have_content order.number
|
||||
expect(page).to have_content order2.number
|
||||
expect(page).to have_content order3.number
|
||||
expect(page).to have_content order4.number
|
||||
expect(page).to have_content order5.number
|
||||
|
||||
select2_select "payment", from: 'q_state_eq'
|
||||
|
||||
page.find('.filter-actions .button.icon-search').click
|
||||
|
||||
# Order 2 should show, but not 3 and 4
|
||||
expect(page).to have_content order.number
|
||||
expect(page).to_not have_content order2.number
|
||||
expect(page).to_not have_content order3.number
|
||||
expect(page).to_not have_content order4.number
|
||||
expect(page).to_not have_content order5.number
|
||||
end
|
||||
end
|
||||
|
||||
describe "ordering" do
|
||||
context "orders with different completion dates" do
|
||||
before do
|
||||
order2.update!(completed_at: Time.zone.now - 2.weeks)
|
||||
order3.update!(completed_at: Time.zone.now - 3.weeks)
|
||||
order4.update!(completed_at: Time.zone.now - 4.weeks)
|
||||
order5.update!(completed_at: Time.zone.now - 5.weeks)
|
||||
login_as_admin_and_visit spree.admin_orders_path
|
||||
end
|
||||
|
||||
it "filter by multiple order cycles" do
|
||||
select2_select 'Two', from: 'q_order_cycle_id_in'
|
||||
select2_select 'Three', from: 'q_order_cycle_id_in'
|
||||
|
||||
page.find('.filter-actions .button.icon-search').click
|
||||
|
||||
# Order 2 and 3 should show, but not 4
|
||||
expect(page).to have_content order2.number
|
||||
expect(page).to have_content order3.number
|
||||
expect(page).to_not have_content order4.number
|
||||
end
|
||||
|
||||
it "filter by distributors" do
|
||||
select2_select distributor2.name.to_s, from: 'q_distributor_id_in'
|
||||
select2_select distributor4.name.to_s, from: 'q_distributor_id_in'
|
||||
|
||||
page.find('.filter-actions .button.icon-search').click
|
||||
|
||||
# Order 2 and 4 should show, but not 3
|
||||
expect(page).to have_content order2.number
|
||||
expect(page).to_not have_content order3.number
|
||||
expect(page).to have_content order4.number
|
||||
end
|
||||
|
||||
it "filter by complete date" do
|
||||
find("input.datepicker").click
|
||||
select_dates_from_daterangepicker(order3.completed_at.yesterday,
|
||||
order4.completed_at.tomorrow)
|
||||
|
||||
page.find('.filter-actions .button.icon-search').click
|
||||
|
||||
# Order 3 and 4 should show, but not 2
|
||||
expect(page).to_not have_content order2.number
|
||||
expect(page).to have_content order3.number
|
||||
expect(page).to have_content order4.number
|
||||
end
|
||||
|
||||
it "filter by email" do
|
||||
fill_in "Email", with: customer3.email
|
||||
|
||||
page.find('.filter-actions .button.icon-search').click
|
||||
|
||||
# Order 3 should show, but not 2 and 4
|
||||
expect(page).to_not have_content order2.number
|
||||
expect(page).to have_content order3.number
|
||||
expect(page).to_not have_content order4.number
|
||||
end
|
||||
|
||||
it "filter by customer first and last names" do
|
||||
# NOTE: this field refers to the name given in billing addresses and not to customer name
|
||||
# filtering by first name
|
||||
fill_in "First name begins with", with: billing_address2.firstname
|
||||
page.find('.filter-actions .button.icon-search').click
|
||||
# Order 3 should show, but not 2 and 4
|
||||
expect(page).to have_content order2.number
|
||||
expect(page).to_not have_content order3.number
|
||||
expect(page).to_not have_content order4.number
|
||||
|
||||
find("a#clear_filters_button").click
|
||||
# filtering by last name
|
||||
|
||||
fill_in "Last name begins with", with: billing_address4.lastname
|
||||
page.find('.filter-actions .button.icon-search').click
|
||||
# Order 4 should show, but not 2 and 3
|
||||
expect(page).to_not have_content order2.number
|
||||
expect(page).to_not have_content order3.number
|
||||
expect(page).to have_content order4.number
|
||||
end
|
||||
|
||||
it "filter by shipping methods" do
|
||||
select2_select "Pick-up at the farm", from: 'q_shipping_method_id'
|
||||
page.find('.filter-actions .button.icon-search').click
|
||||
# Order 2 should show, but not 3 and 5
|
||||
expect(page).to have_content order2.number
|
||||
expect(page).to_not have_content order3.number
|
||||
expect(page).to_not have_content order4.number
|
||||
|
||||
find("a#clear_filters_button").click
|
||||
|
||||
select2_select "Signed, sealed, delivered", from: 'q_shipping_method_id'
|
||||
page.find('.filter-actions .button.icon-search').click
|
||||
# Order 4 should show, but not 2 and 3
|
||||
expect(page).to_not have_content order2.number
|
||||
expect(page).to_not have_content order3.number
|
||||
expect(page).to have_content order4.number
|
||||
end
|
||||
|
||||
it "filter by invoice number" do
|
||||
fill_in "Invoice number:", with: order2.number
|
||||
|
||||
page.find('.filter-actions .button.icon-search').click
|
||||
|
||||
# Order 2 should show, but not 3 and 4
|
||||
expect(page).to have_content order2.number
|
||||
expect(page).to_not have_content order3.number
|
||||
expect(page).to_not have_content order4.number
|
||||
end
|
||||
|
||||
it "filter by order state" do
|
||||
order.update(state: "payment")
|
||||
|
||||
uncheck 'Only show complete orders'
|
||||
page.find('.filter-actions .button.icon-search').click
|
||||
|
||||
expect(page).to have_content order.number
|
||||
expect(page).to have_content order2.number
|
||||
expect(page).to have_content order3.number
|
||||
expect(page).to have_content order4.number
|
||||
expect(page).to have_content order5.number
|
||||
|
||||
select2_select "payment", from: 'q_state_eq'
|
||||
|
||||
page.find('.filter-actions .button.icon-search').click
|
||||
|
||||
# Order 2 should show, but not 3 and 4
|
||||
expect(page).to have_content order.number
|
||||
expect(page).to_not have_content order2.number
|
||||
expect(page).to_not have_content order3.number
|
||||
expect(page).to_not have_content order4.number
|
||||
expect(page).to_not have_content order5.number
|
||||
it "orders by completion date" do
|
||||
find("a", text: 'COMPLETED AT').click # sets ascending ordering
|
||||
expect(page).to have_content(
|
||||
/#{order5.number}.*#{order4.number}.*#{order3.number}.*#{order2.number}/m
|
||||
)
|
||||
find("a", text: 'COMPLETED AT').click # sets descending ordering
|
||||
expect(page).to have_content(
|
||||
/#{order2.number}.*#{order3.number}.*#{order4.number}.*#{order5.number}/m
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context "ordering" do
|
||||
context "orders with different completion dates" do
|
||||
before do
|
||||
order2.update!(completed_at: Time.zone.now - 2.weeks)
|
||||
order3.update!(completed_at: Time.zone.now - 3.weeks)
|
||||
order4.update!(completed_at: Time.zone.now - 4.weeks)
|
||||
order5.update!(completed_at: Time.zone.now - 5.weeks)
|
||||
login_as_admin_and_visit spree.admin_orders_path
|
||||
end
|
||||
it "orders by completion date" do
|
||||
find("a", text: 'COMPLETED AT').click # sets ascending ordering
|
||||
expect(page).to have_content(
|
||||
/#{order5.number}.*#{order4.number}.*#{order3.number}.*#{order2.number}/m
|
||||
)
|
||||
find("a", text: 'COMPLETED AT').click # sets descending ordering
|
||||
expect(page).to have_content(
|
||||
/#{order2.number}.*#{order3.number}.*#{order4.number}.*#{order5.number}/m
|
||||
)
|
||||
end
|
||||
context "orders with different order numbers" do
|
||||
before do
|
||||
order2.update!(number: "R555555555")
|
||||
order3.update!(number: "R444444444")
|
||||
order4.update!(number: "R333333333")
|
||||
order5.update!(number: "R222222222")
|
||||
login_as_admin_and_visit spree.admin_orders_path
|
||||
end
|
||||
|
||||
context "orders with different order numbers" do
|
||||
before do
|
||||
order2.update!(number: "R555555555")
|
||||
order3.update!(number: "R444444444")
|
||||
order4.update!(number: "R333333333")
|
||||
order5.update!(number: "R222222222")
|
||||
login_as_admin_and_visit spree.admin_orders_path
|
||||
end
|
||||
it "orders by order number" do
|
||||
find("a", text: 'NUMBER').click # sets ascending ordering
|
||||
expect(page).to have_content(
|
||||
/#{order5.number}.*#{order4.number}.*#{order3.number}.*#{order2.number}/m
|
||||
)
|
||||
find("a", text: 'NUMBER').click # sets descending ordering
|
||||
expect(page).to have_content(
|
||||
/#{order2.number}.*#{order3.number}.*#{order4.number}.*#{order5.number}/m
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
it "orders by order number" do
|
||||
find("a", text: 'NUMBER').click # sets ascending ordering
|
||||
expect(page).to have_content(
|
||||
/#{order5.number}.*#{order4.number}.*#{order3.number}.*#{order2.number}/m
|
||||
)
|
||||
find("a", text: 'NUMBER').click # sets descending ordering
|
||||
expect(page).to have_content(
|
||||
/#{order2.number}.*#{order3.number}.*#{order4.number}.*#{order5.number}/m
|
||||
)
|
||||
end
|
||||
context "orders with different states" do
|
||||
before do
|
||||
order2.update!(state: "payment")
|
||||
order3.update!(state: "complete")
|
||||
order4.update!(state: "cart")
|
||||
order5.cancel
|
||||
login_as_admin_and_visit spree.admin_orders_path
|
||||
uncheck 'Only show complete orders'
|
||||
page.find('.filter-actions .button.icon-search').click
|
||||
end
|
||||
|
||||
context "orders with different states" do
|
||||
before do
|
||||
order2.update!(state: "payment")
|
||||
order3.update!(state: "complete")
|
||||
order4.update!(state: "cart")
|
||||
order5.cancel
|
||||
login_as_admin_and_visit spree.admin_orders_path
|
||||
uncheck 'Only show complete orders'
|
||||
page.find('.filter-actions .button.icon-search').click
|
||||
end
|
||||
it "orders by order state" do
|
||||
find("a", text: 'STATE').click # sets ascending ordering
|
||||
expect(page).to have_content(
|
||||
/#{order5.number}.*#{order4.number}.*#{order3.number}.*#{order2.number}/m
|
||||
)
|
||||
find("a", text: 'STATE').click # sets descending ordering
|
||||
expect(page).to have_content(
|
||||
/#{order2.number}.*#{order3.number}.*#{order4.number}.*#{order5.number}/m
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
it "orders by order state" do
|
||||
find("a", text: 'STATE').click # sets ascending ordering
|
||||
expect(page).to have_content(
|
||||
/#{order5.number}.*#{order4.number}.*#{order3.number}.*#{order2.number}/m
|
||||
)
|
||||
find("a", text: 'STATE').click # sets descending ordering
|
||||
expect(page).to have_content(
|
||||
/#{order2.number}.*#{order3.number}.*#{order4.number}.*#{order5.number}/m
|
||||
)
|
||||
end
|
||||
context "orders with different payment states" do
|
||||
before do
|
||||
Spree::Payment.where(order_id: order2.id).first.update!(amount: 50.0)
|
||||
Spree::Payment.where(order_id: order3.id).first.update!(amount: 100.0)
|
||||
Spree::Payment.where(order_id: order4.id).first.update!(amount: 10.0)
|
||||
login_as_admin_and_visit spree.admin_orders_path
|
||||
end
|
||||
|
||||
context "orders with different payment states" do
|
||||
before do
|
||||
Spree::Payment.where(order_id: order2.id).first.update!(amount: 50.0)
|
||||
Spree::Payment.where(order_id: order3.id).first.update!(amount: 100.0)
|
||||
Spree::Payment.where(order_id: order4.id).first.update!(amount: 10.0)
|
||||
login_as_admin_and_visit spree.admin_orders_path
|
||||
end
|
||||
it "orders by payment state" do
|
||||
find("a", text: 'PAYMENT STATE').click # sets ascending ordering
|
||||
expect(page).to have_content(/#{order4.number}.*#{order3.number}.*#{order2.number}/m)
|
||||
find("a", text: 'PAYMENT STATE').click # sets descending ordering
|
||||
expect(page).to have_content(/#{order2.number}.*#{order3.number}.*#{order4.number}/m)
|
||||
end
|
||||
end
|
||||
|
||||
it "orders by payment state" do
|
||||
find("a", text: 'PAYMENT STATE').click # sets ascending ordering
|
||||
expect(page).to have_content(/#{order4.number}.*#{order3.number}.*#{order2.number}/m)
|
||||
find("a", text: 'PAYMENT STATE').click # sets descending ordering
|
||||
expect(page).to have_content(/#{order2.number}.*#{order3.number}.*#{order4.number}/m)
|
||||
end
|
||||
context "orders with different shipment states" do
|
||||
before do
|
||||
Spree::Payment.where(order_id: order2.id).first.update!(amount: 50.0)
|
||||
Spree::Payment.where(order_id: order3.id).first.update!(amount: 100.0)
|
||||
Spree::Payment.where(order_id: order4.id).first.update!(amount: 10.0)
|
||||
order2.ship
|
||||
login_as_admin_and_visit spree.admin_orders_path
|
||||
end
|
||||
|
||||
context "orders with different shipment states" do
|
||||
before do
|
||||
Spree::Payment.where(order_id: order2.id).first.update!(amount: 50.0)
|
||||
Spree::Payment.where(order_id: order3.id).first.update!(amount: 100.0)
|
||||
Spree::Payment.where(order_id: order4.id).first.update!(amount: 10.0)
|
||||
order2.ship
|
||||
login_as_admin_and_visit spree.admin_orders_path
|
||||
end
|
||||
it "orders by shipment state" do
|
||||
find("a", text: 'SHIPMENT STATE').click # sets ascending ordering
|
||||
expect(page).to have_content(/#{order4.number}.*#{order3.number}.*#{order2.number}/m)
|
||||
find("a", text: 'SHIPMENT STATE').click # sets descending ordering
|
||||
expect(page).to have_content(/#{order2.number}.*#{order3.number}.*#{order4.number}/m)
|
||||
end
|
||||
end
|
||||
|
||||
it "orders by shipment state" do
|
||||
find("a", text: 'SHIPMENT STATE').click # sets ascending ordering
|
||||
expect(page).to have_content(/#{order4.number}.*#{order3.number}.*#{order2.number}/m)
|
||||
find("a", text: 'SHIPMENT STATE').click # sets descending ordering
|
||||
expect(page).to have_content(/#{order2.number}.*#{order3.number}.*#{order4.number}/m)
|
||||
end
|
||||
context "orders from different customers" do
|
||||
before do
|
||||
order2.update!(email: "jkl@jkl.com")
|
||||
order3.update!(email: "ghi@ghi.com")
|
||||
order4.update!(email: "def@def.com")
|
||||
order5.update!(email: "abc@abc.com")
|
||||
login_as_admin_and_visit spree.admin_orders_path
|
||||
end
|
||||
|
||||
context "orders from different customers" do
|
||||
before do
|
||||
order2.update!(email: "jkl@jkl.com")
|
||||
order3.update!(email: "ghi@ghi.com")
|
||||
order4.update!(email: "def@def.com")
|
||||
order5.update!(email: "abc@abc.com")
|
||||
login_as_admin_and_visit spree.admin_orders_path
|
||||
end
|
||||
it "orders by customer email" do
|
||||
find("a", text: 'EMAIL').click # sets ascending ordering
|
||||
expect(page).to have_content(
|
||||
/#{order5.number}.*#{order4.number}.*#{order3.number}.*#{order2.number}/m
|
||||
)
|
||||
find("a", text: 'EMAIL').click # sets descending ordering
|
||||
expect(page).to have_content(
|
||||
/#{order2.number}.*#{order3.number}.*#{order4.number}.*#{order5.number}/m
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
it "orders by customer email" do
|
||||
find("a", text: 'EMAIL').click # sets ascending ordering
|
||||
expect(page).to have_content(
|
||||
/#{order5.number}.*#{order4.number}.*#{order3.number}.*#{order2.number}/m
|
||||
)
|
||||
find("a", text: 'EMAIL').click # sets descending ordering
|
||||
expect(page).to have_content(
|
||||
/#{order2.number}.*#{order3.number}.*#{order4.number}.*#{order5.number}/m
|
||||
)
|
||||
end
|
||||
context "orders with different billing addresses" do
|
||||
before do
|
||||
billing_address2.update!(lastname: "Mad Hatter")
|
||||
billing_address3.update!(lastname: "Duchess")
|
||||
billing_address4.update!(lastname: "Cheshire Cat")
|
||||
billing_address5.update!(lastname: "Alice")
|
||||
login_as_admin_and_visit spree.admin_orders_path
|
||||
end
|
||||
|
||||
context "orders with different billing addresses" do
|
||||
before do
|
||||
billing_address2.update!(lastname: "Mad Hatter")
|
||||
billing_address3.update!(lastname: "Duchess")
|
||||
billing_address4.update!(lastname: "Cheshire Cat")
|
||||
billing_address5.update!(lastname: "Alice")
|
||||
login_as_admin_and_visit spree.admin_orders_path
|
||||
end
|
||||
it "orders by last name" do
|
||||
find("a", text: 'NAME').click # sets ascending ordering
|
||||
expect(page).to have_content(
|
||||
/#{order5.number}.*#{order4.number}.*#{order3.number}.*#{order2.number}/m
|
||||
)
|
||||
find("a", text: 'NAME').click # sets descending ordering
|
||||
expect(page).to have_content(
|
||||
/#{order2.number}.*#{order3.number}.*#{order4.number}.*#{order5.number}/m
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
it "orders by last name" do
|
||||
find("a", text: 'NAME').click # sets ascending ordering
|
||||
expect(page).to have_content(
|
||||
/#{order5.number}.*#{order4.number}.*#{order3.number}.*#{order2.number}/m
|
||||
)
|
||||
find("a", text: 'NAME').click # sets descending ordering
|
||||
expect(page).to have_content(
|
||||
/#{order2.number}.*#{order3.number}.*#{order4.number}.*#{order5.number}/m
|
||||
)
|
||||
end
|
||||
context "orders with different order totals" do
|
||||
before do
|
||||
Spree::LineItem.where(order_id: order2.id).first.update!(quantity: 5)
|
||||
Spree::LineItem.where(order_id: order3.id).first.update!(quantity: 4)
|
||||
Spree::LineItem.where(order_id: order4.id).first.update!(quantity: 3)
|
||||
Spree::LineItem.where(order_id: order5.id).first.update!(quantity: 2)
|
||||
order2.save
|
||||
order3.save
|
||||
order4.save
|
||||
order5.save
|
||||
login_as_admin_and_visit spree.admin_orders_path
|
||||
end
|
||||
|
||||
context "orders with different order totals" do
|
||||
before do
|
||||
Spree::LineItem.where(order_id: order2.id).first.update!(quantity: 5)
|
||||
Spree::LineItem.where(order_id: order3.id).first.update!(quantity: 4)
|
||||
Spree::LineItem.where(order_id: order4.id).first.update!(quantity: 3)
|
||||
Spree::LineItem.where(order_id: order5.id).first.update!(quantity: 2)
|
||||
order2.save
|
||||
order3.save
|
||||
order4.save
|
||||
order5.save
|
||||
login_as_admin_and_visit spree.admin_orders_path
|
||||
end
|
||||
|
||||
it "orders by order total" do
|
||||
find("a", text: 'TOTAL').click # sets ascending ordering
|
||||
expect(page).to have_content(
|
||||
/#{order5.number}.*#{order4.number}.*#{order3.number}.*#{order2.number}/m
|
||||
)
|
||||
find("a", text: 'TOTAL').click # sets descending ordering
|
||||
expect(page).to have_content(
|
||||
/#{order2.number}.*#{order3.number}.*#{order4.number}.*#{order5.number}/m
|
||||
)
|
||||
end
|
||||
it "orders by order total" do
|
||||
find("a", text: 'TOTAL').click # sets ascending ordering
|
||||
expect(page).to have_content(
|
||||
/#{order5.number}.*#{order4.number}.*#{order3.number}.*#{order2.number}/m
|
||||
)
|
||||
find("a", text: 'TOTAL').click # sets descending ordering
|
||||
expect(page).to have_content(
|
||||
/#{order2.number}.*#{order3.number}.*#{order4.number}.*#{order5.number}/m
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -86,7 +86,7 @@ describe "Payments Reports" do
|
||||
].join(" ").upcase)
|
||||
|
||||
expect(page.find("table.report__table tbody tr").text).to have_content([
|
||||
order.payment_state,
|
||||
"credit owed",
|
||||
order.distributor.name,
|
||||
order.item_total.to_f + other_order.item_total.to_f,
|
||||
order.ship_total.to_f + other_order.ship_total.to_f,
|
||||
|
||||
@@ -44,6 +44,19 @@ describe '
|
||||
click_button "Go"
|
||||
expect(page).to have_content "EMAIL FIRST NAME"
|
||||
end
|
||||
|
||||
it "displays a friendly timeout message" do
|
||||
ActiveJob::Base.queue_adapter.perform_enqueued_jobs = false
|
||||
login_as_admin_and_visit admin_report_path(
|
||||
report_type: :customers, report_subtype: :mailing_list
|
||||
)
|
||||
expect(ENV).to receive(:fetch).with("RACK_TIMEOUT_SERVICE_TIMEOUT", "15")
|
||||
.and_return("-1") # Negative values time out immediately.
|
||||
|
||||
click_button "Go"
|
||||
|
||||
expect(page).to have_content "this report took too long"
|
||||
end
|
||||
end
|
||||
|
||||
describe "Can access Customers reports and generate customers report" do
|
||||
|
||||
@@ -41,6 +41,30 @@ describe "As a consumer I want to view products" do
|
||||
set_order order
|
||||
end
|
||||
|
||||
describe "supplier's name is displayed" do
|
||||
before do
|
||||
exchange1.update_attribute :pickup_time, "monday"
|
||||
add_variant_to_order_cycle(exchange1, variant)
|
||||
end
|
||||
|
||||
it "shows supplier's name" do
|
||||
visit shop_path
|
||||
expect(page).to have_content supplier.name
|
||||
page.find("span", text: supplier.name).click
|
||||
assert_selector ".reveal-modal"
|
||||
end
|
||||
|
||||
it "shows supplier's name even when supplier's visibility is hidden" do
|
||||
supplier.visible = 'hidden'
|
||||
supplier.save
|
||||
visit shop_path
|
||||
expect(page).to have_content supplier.name
|
||||
# Does not open the modal though
|
||||
page.find("span", text: supplier.name).click
|
||||
assert_no_selector ".reveal-modal"
|
||||
end
|
||||
end
|
||||
|
||||
describe "viewing HTML product descriptions" do
|
||||
before do
|
||||
exchange1.update_attribute :pickup_time, "monday"
|
||||
|
||||
@@ -42,15 +42,43 @@ describe "As a consumer I want to shop with a distributor" do
|
||||
expect(first("distributor img")['src']).to include "logo-white.png"
|
||||
end
|
||||
|
||||
it "shows the producers for a distributor" do
|
||||
exchange = Exchange.find(oc1.exchanges.to_enterprises(distributor).outgoing.first.id)
|
||||
add_variant_to_order_cycle(exchange, variant)
|
||||
|
||||
visit shop_path
|
||||
within ".tab-buttons" do
|
||||
click_link "Producers"
|
||||
describe "producers tab" do
|
||||
before do
|
||||
exchange = Exchange.find(oc1.exchanges.to_enterprises(distributor).outgoing.first.id)
|
||||
add_variant_to_order_cycle(exchange, variant)
|
||||
visit shop_path
|
||||
within ".tab-buttons" do
|
||||
click_link "Producers"
|
||||
end
|
||||
end
|
||||
|
||||
it "shows the producers for a distributor" do
|
||||
expect(page).to have_content supplier.name
|
||||
find("a", text: supplier.name).click
|
||||
within ".reveal-modal" do
|
||||
expect(page).to have_content supplier.name
|
||||
end
|
||||
end
|
||||
|
||||
context "when the producer visibility is set to 'hidden'" do
|
||||
before do
|
||||
supplier.visible = "hidden"
|
||||
supplier.save
|
||||
visit shop_path
|
||||
within ".tab-buttons" do
|
||||
click_link "Producers"
|
||||
end
|
||||
end
|
||||
|
||||
it "shows the producer name" do
|
||||
expect(page).to have_content supplier.name
|
||||
end
|
||||
|
||||
it "does not show the producer modal" do
|
||||
expect(page).to_not have_link supplier.name
|
||||
expect(page).to_not have_selector ".reveal-modal"
|
||||
end
|
||||
end
|
||||
expect(page).to have_content supplier.name
|
||||
end
|
||||
|
||||
describe "selecting an order cycle" do
|
||||
|
||||
@@ -231,6 +231,24 @@ describe 'Shops' do
|
||||
expect(page).to have_content "Shop for #{producer.name} products at:".upcase
|
||||
end
|
||||
end
|
||||
|
||||
context "when visibility is `hidden`" do
|
||||
before do
|
||||
producer.visible = "hidden"
|
||||
producer.save
|
||||
visit shops_path
|
||||
expand_active_table_node distributor.name
|
||||
end
|
||||
|
||||
it "shows the producer name" do
|
||||
expect(page).to have_content producer.name
|
||||
end
|
||||
|
||||
it "does not show the producer modal" do
|
||||
open_enterprise_modal producer
|
||||
expect(page).to_not have_selector(".reveal-modal")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "viewing closed shops by URL" do
|
||||
|
||||
Reference in New Issue
Block a user