Compare commits

...

37 Commits

Author SHA1 Message Date
David Cook
a6cd393c57 Update all locales with the latest Transifex translations 2023-04-13 16:45:38 +10:00
Filipe
b1060bf1c9 Merge pull request #10640 from openfoodfoundation/dependabot/bundler/stripe-8.5.0
Bump stripe from 8.3.0 to 8.5.0
2023-04-12 19:27:18 +01:00
Filipe
1bf5fbaf3a Merge pull request #10449 from macanudo527/fix_ER
Update OCs after ER Permissions are Revoked
2023-04-12 18:59:20 +01:00
Konrad
2ace3afd67 Merge pull request #10606 from thejwuscript/10116-improve-bom-sorting
Sort orders by last name
2023-04-12 16:36:45 +02:00
Konrad
0bfceb877d Merge pull request #10666 from jibees/9723-admin-missing-translation-in-payment-report
Admin, Payment reports: add missing translation for payment state
2023-04-12 15:47:23 +02:00
Filipe
c1d28b2e8f Merge pull request #10119 from binarygit/donot-hide-producers-name-in-products
Display producer's name in products inspite of hide all refs option
2023-04-12 13:07:52 +01:00
jibees
98e44e7a40 Merge pull request #10687 from openfoodfoundation/dependabot/bundler/nokogiri-1.14.3
Bump nokogiri from 1.14.2 to 1.14.3
2023-04-12 10:25:56 +02:00
jibees
51c6c19f80 Merge pull request #10669 from openfoodfoundation/dependabot/bundler/sidekiq-7.0.8
Bump sidekiq from 7.0.7 to 7.0.8
2023-04-12 10:24:59 +02:00
dependabot[bot]
75b7a1864b Bump nokogiri from 1.14.2 to 1.14.3
Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.14.2 to 1.14.3.
- [Release notes](https://github.com/sparklemotion/nokogiri/releases)
- [Changelog](https://github.com/sparklemotion/nokogiri/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.14.2...v1.14.3)

---
updated-dependencies:
- dependency-name: nokogiri
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-12 06:24:59 +00:00
jibees
193ae7936e Merge pull request #10681 from openfoodfoundation/dependabot/bundler/rubocop-1.50.0
Bump rubocop from 1.49.0 to 1.50.0
2023-04-11 20:40:55 +02:00
Filipe
0971e8d9b5 Merge pull request #10644 from mkllnk/report-timeout-message
[Hidden] Display a friendly message when a background report times out
2023-04-11 19:40:42 +01:00
Jean-Baptiste Bellet
e78b44b9ca Do not shows <a /> if producers is hidden
Different style as it does not open any modal
2023-04-11 14:27:57 +02:00
binarygit
c5779eff81 Do not open modal for producer's who are 'hidden' 2023-04-11 14:27:57 +02:00
Jean-Baptiste Bellet
b616c14f63 Don't hide producer's name in products despite hide all refs opt selected 2023-04-11 14:26:47 +02:00
dependabot[bot]
f4c351febf Bump rubocop from 1.49.0 to 1.50.0
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.49.0 to 1.50.0.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.49.0...v1.50.0)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-11 10:05:30 +00:00
Maikel Linke
30184ac6aa Background reports time out earlier than nginx
This allows us to display a friendly message before nginx displays its
default error.
2023-04-11 16:44:13 +10:00
David Cook
a123d45eca Fix spec
It's worth noting that this page hasn't been updated by this PR.
I honestly don't know why it broke, but don't care anymore. It seems the extra `login_as_admin_and_visit` was causing a race condition on one spec. It's not necessary so I've removed this context.

Best viewed with whitespace ignored.
2023-04-11 16:38:49 +10:00
James Wu
a75f16e23c Implement full_name_for_sorting 2023-04-11 15:25:20 +10:00
James Wu
546e90b286 Sort orders by last names 2023-04-11 15:25:20 +10:00
Konrad
15058299d8 Merge pull request #10641 from openfoodfoundation/dependabot/npm_and_yarn/babel/preset-env-7.21.4
Bump @babel/preset-env from 7.18.2 to 7.21.4
2023-04-10 20:00:06 +02:00
Jean-Baptiste Bellet
c7cb982c9a Update browser list
```
npx update-browserslist-db@latest
```
2023-04-10 11:20:19 +02:00
Jean-Baptiste Bellet
34e9112c0a Fix dependencies warning: adds core and `plugin-transform-runtime 2023-04-10 11:20:19 +02:00
dependabot[bot]
28eb11bda5 Bump @babel/preset-env from 7.20.2 to 7.21.4
Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.20.2 to 7.21.4.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.21.4/packages/babel-preset-env)

---
updated-dependencies:
- dependency-name: "@babel/preset-env"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-10 11:20:19 +02:00
jibees
d8e82d9c88 Merge pull request #10668 from openfoodfoundation/dependabot/bundler/aws-sdk-s3-1.120.1
Bump aws-sdk-s3 from 1.120.0 to 1.120.1
2023-04-10 11:12:45 +02:00
jibees
5192a08082 Merge pull request #10673 from openfoodfoundation/dependabot/bundler/rubocop-rails-2.19.0
Bump rubocop-rails from 2.18.0 to 2.19.0
2023-04-07 14:33:31 +02:00
jibees
94d3f136e2 Merge pull request #10672 from openfoodfoundation/dependabot/npm_and_yarn/floating-ui/dom-1.2.6
Bump @floating-ui/dom from 1.2.5 to 1.2.6
2023-04-07 14:32:45 +02:00
dependabot[bot]
db3a923ea7 Bump rubocop-rails from 2.18.0 to 2.19.0
Bumps [rubocop-rails](https://github.com/rubocop/rubocop-rails) from 2.18.0 to 2.19.0.
- [Release notes](https://github.com/rubocop/rubocop-rails/releases)
- [Changelog](https://github.com/rubocop/rubocop-rails/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop-rails/compare/v2.18.0...v2.19.0)

---
updated-dependencies:
- dependency-name: rubocop-rails
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-07 09:59:34 +00:00
dependabot[bot]
619eb43c57 Bump @floating-ui/dom from 1.2.5 to 1.2.6
Bumps [@floating-ui/dom](https://github.com/floating-ui/floating-ui/tree/HEAD/packages/dom) from 1.2.5 to 1.2.6.
- [Release notes](https://github.com/floating-ui/floating-ui/releases)
- [Commits](https://github.com/floating-ui/floating-ui/commits/@floating-ui/dom@1.2.6/packages/dom)

---
updated-dependencies:
- dependency-name: "@floating-ui/dom"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-07 09:58:01 +00:00
dependabot[bot]
5c221621d3 Bump sidekiq from 7.0.7 to 7.0.8
Bumps [sidekiq](https://github.com/sidekiq/sidekiq) from 7.0.7 to 7.0.8.
- [Release notes](https://github.com/sidekiq/sidekiq/releases)
- [Changelog](https://github.com/sidekiq/sidekiq/blob/main/Changes.md)
- [Commits](https://github.com/sidekiq/sidekiq/compare/v7.0.7...v7.0.8)

---
updated-dependencies:
- dependency-name: sidekiq
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-06 09:58:23 +00:00
dependabot[bot]
60d7ed5036 Bump aws-sdk-s3 from 1.120.0 to 1.120.1
Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.120.0 to 1.120.1.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-06 09:57:53 +00:00
Jean-Baptiste Bellet
e74328f1d7 Add i18n for payment state key
+ update spec
2023-04-06 10:28:44 +02:00
Jean-Baptiste Bellet
6abd652251 Factorize into inherited method from Base: payment_state(order) 2023-04-06 09:50:50 +02:00
dependabot[bot]
3821eede51 Bump stripe from 8.3.0 to 8.5.0
Bumps [stripe](https://github.com/stripe/stripe-ruby) from 8.3.0 to 8.5.0.
- [Release notes](https://github.com/stripe/stripe-ruby/releases)
- [Changelog](https://github.com/stripe/stripe-ruby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/stripe/stripe-ruby/compare/v8.3.0...v8.5.0)

---
updated-dependencies:
- dependency-name: stripe
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-05 16:38:33 +00:00
Maikel Linke
020af0c0e4 Explain report timeout better to user 2023-04-05 09:59:02 +10:00
Maikel Linke
00a3976905 Display a friendly message when a report times out
Once we get a download link for a report, we can display this message
sooner. But for now we just use the existing request timeout.
2023-04-04 11:08:20 +10:00
Maikel Linke
3bd8e430f9 Use Rack::Timeout for more realistic tests
The closer the test environment is to the production environment the
more realistic the tests will be, and the more code we test.

We are now able to test the app behaviour on timeouts which I want to do
for reports. We can also catch incompatibilities with the rack-timeout
gem during testing.
2023-04-04 11:08:20 +10:00
Neal Chambers
77733169fc Update OCs after ERs Permissions are Revoked 2023-04-04 09:37:13 +09:00
36 changed files with 1032 additions and 597 deletions

View File

@@ -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"

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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" }

View File

@@ -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 }}

View File

@@ -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 }}

View File

@@ -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

View File

@@ -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"

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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) },

View File

@@ -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) },

View File

@@ -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) }

View File

@@ -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",

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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,

View File

@@ -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

View File

@@ -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"

View File

@@ -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

View File

@@ -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

657
yarn.lock

File diff suppressed because it is too large Load Diff