diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 86e4725518..d37e637543 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -23,10 +23,6 @@ The categories are based on https://keepachangelog.com/en/1.0.0/. -->
Changelog Category: Added | Changed | Deprecated | Removed | Fixed | Security
-#### How is this related to the Spree upgrade?
-
-
#### Discourse thread
diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml
index e4eea50ed8..fc3411e87a 100644
--- a/.rubocop_manual_todo.yml
+++ b/.rubocop_manual_todo.yml
@@ -108,7 +108,6 @@ Layout/LineLength:
- lib/open_food_network/scope_variants_for_search.rb
- lib/open_food_network/variant_and_line_item_naming.rb
- lib/open_food_network/xero_invoices_report.rb
- - lib/spree/core/controller_helpers/respond_with_decorator.rb
- lib/spree/localized_number.rb
- lib/spree/product_filters.rb
- lib/tasks/data.rake
@@ -322,6 +321,15 @@ Layout/LineLength:
- spec/support/request/shop_workflow.rb
- spec/support/request/web_helper.rb
- spec/support/seeds.rb
+ - engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb
+ - spec/controllers/base_controller2_spec.rb
+ - spec/features/consumer/caching/darkswarm_caching_spec.rb
+ - spec/models/calculator/flexi_rate_spec.rb
+ - spec/models/calculator/price_sack_spec.rb
+ - spec/models/spree/stock_item_spec.rb
+ - spec/requests/api/orders_spec.rb
+ - spec/swagger_helper.rb
+ - spec/views/spree/admin/payment_methods/index.html.haml_spec.rb
Metrics/AbcSize:
Max: 15
@@ -400,6 +408,7 @@ Metrics/AbcSize:
- app/services/create_order_cycle.rb
- app/services/order_cycle_form.rb
- app/services/order_syncer.rb
+ - engines/order_management/app/services/order_management/order/updater.rb
- engines/order_management/app/services/order_management/stock/estimator.rb
- engines/order_management/app/services/order_management/stock/package.rb
- engines/order_management/app/services/order_management/stock/packer.rb
@@ -427,7 +436,9 @@ Metrics/AbcSize:
- lib/open_food_network/variant_and_line_item_naming.rb
- lib/open_food_network/xero_invoices_report.rb
- lib/spree/api/controller_setup.rb
- - lib/spree/core/controller_helpers/respond_with_decorator.rb
+ - lib/spree/core/controller_helpers/order.rb
+ - lib/spree/core/controller_helpers/respond_with.rb
+ - lib/spree/core/controller_helpers/ssl.rb
- lib/spree/localized_number.rb
- lib/stripe/account_connector.rb
- lib/tasks/enterprises.rake
@@ -443,6 +454,11 @@ Metrics/AbcSize:
- spec/models/product_importer_spec.rb
- spec/services/order_checkout_restart_spec.rb
- spec/support/performance_helper.rb
+ - app/controllers/application_controller.rb
+ - app/models/spree/order/checkout.rb
+ - app/models/spree/payment/processing.rb
+ - app/models/spree/payment.rb
+ - engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb
Metrics/BlockLength:
Max: 25
@@ -461,6 +477,8 @@ Metrics/BlockLength:
]
Exclude:
- app/models/spree/shipment.rb
+ - lib/spree/core/controller_helpers/common.rb
+ - lib/spree/core/controller_helpers/ssl.rb
- lib/tasks/data.rake
- spec/controllers/spree/admin/invoices_controller_spec.rb
- spec/factories/enterprise_factory.rb
@@ -479,6 +497,10 @@ Metrics/BlockLength:
- spec/support/delayed_job_helper.rb
- spec/support/matchers/select2_matchers.rb
- spec/support/matchers/table_matchers.rb
+ - app/models/spree/order/checkout.rb
+ - app/models/spree/payment/processing.rb
+ - spec/requests/api/orders_spec.rb
+ - spec/swagger_helper.rb
Metrics/CyclomaticComplexity:
Max: 6
@@ -505,10 +527,14 @@ Metrics/CyclomaticComplexity:
- lib/discourse/single_sign_on.rb
- lib/open_food_network/bulk_coop_report.rb
- lib/open_food_network/enterprise_issue_validator.rb
- - lib/spree/core/controller_helpers/order_decorator.rb
- - lib/spree/core/controller_helpers/respond_with_decorator.rb
+ - lib/spree/core/controller_helpers/order.rb
+ - lib/spree/core/controller_helpers/respond_with.rb
+ - lib/spree/core/controller_helpers/ssl.rb
- lib/spree/localized_number.rb
- spec/models/product_importer_spec.rb
+ - app/models/spree/order/checkout.rb
+ - app/models/spree/payment.rb
+ - engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb
Metrics/PerceivedComplexity:
Max: 7
@@ -530,10 +556,13 @@ Metrics/PerceivedComplexity:
- lib/discourse/single_sign_on.rb
- lib/open_food_network/bulk_coop_report.rb
- lib/open_food_network/enterprise_issue_validator.rb
- - lib/spree/core/controller_helpers/order_decorator.rb
- - lib/spree/core/controller_helpers/respond_with_decorator.rb
+ - lib/spree/core/controller_helpers/order.rb
+ - lib/spree/core/controller_helpers/respond_with.rb
+ - lib/spree/core/controller_helpers/ssl.rb
- lib/spree/localized_number.rb
- spec/models/product_importer_spec.rb
+ - app/models/spree/order/checkout.rb
+ - engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb
Metrics/MethodLength:
Max: 10
@@ -596,6 +625,7 @@ Metrics/MethodLength:
- app/serializers/api/cached_enterprise_serializer.rb
- app/services/order_cycle_form.rb
- app/services/permitted_attributes/checkout.rb
+ - engines/order_management/app/services/order_management/order/updater.rb
- engines/order_management/app/services/order_management/reports/enterprise_fee_summary/scope.rb
- engines/order_management/app/services/order_management/stock/estimator.rb
- engines/order_management/app/services/order_management/stock/package.rb
@@ -626,7 +656,10 @@ Metrics/MethodLength:
- lib/open_food_network/users_and_enterprises_report.rb
- lib/open_food_network/xero_invoices_report.rb
- lib/spree/api/controller_setup.rb
- - lib/spree/core/controller_helpers/respond_with_decorator.rb
+ - lib/spree/core/controller_helpers/auth.rb
+ - lib/spree/core/controller_helpers/order.rb
+ - lib/spree/core/controller_helpers/respond_with.rb
+ - lib/spree/core/controller_helpers/ssl.rb
- lib/spree/localized_number.rb
- lib/stripe/profile_storer.rb
- lib/tasks/data/truncate_data.rb
@@ -636,7 +669,12 @@ Metrics/MethodLength:
- spec/features/consumer/shopping/checkout_paypal_spec.rb
- spec/features/consumer/shopping/variant_overrides_spec.rb
- spec/models/product_importer_spec.rb
- - spec/support/request/authentication_workflow.rb
+ - spec/support/request/authentication_helper.rb
+ - app/models/spree/order/checkout.rb
+ - app/models/spree/payment/processing.rb
+ - engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_allocation_report.rb
+ - engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb
+ - engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_supplier_report.rb
Metrics/ClassLength:
Max: 100
@@ -666,6 +704,7 @@ Metrics/ClassLength:
- app/serializers/api/cached_enterprise_serializer.rb
- app/serializers/api/enterprise_shopfront_serializer.rb
- app/services/cart_service.rb
+ - engines/order_management/app/services/order_management/order/updater.rb
- engines/order_management/app/services/order_management/reports/enterprise_fee_summary/scope.rb
- lib/active_merchant/billing/gateways/stripe_payment_intents.rb
- lib/open_food_network/bulk_coop_report.rb
@@ -678,6 +717,8 @@ Metrics/ClassLength:
- lib/open_food_network/permissions.rb
- lib/open_food_network/users_and_enterprises_report.rb
- lib/open_food_network/xero_invoices_report.rb
+ - app/models/spree/payment.rb
+ - engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb
Metrics/ModuleLength:
Max: 100
@@ -686,6 +727,7 @@ Metrics/ModuleLength:
- app/helpers/injection_helper.rb
- app/helpers/spree/admin/base_helper.rb
- app/helpers/spree/admin/navigation_helper.rb
+ - engines/order_management/spec/services/order_management/order/updater_spec.rb
- engines/order_management/spec/services/order_management/stock/package_spec.rb
- engines/order_management/spec/services/order_management/subscriptions/estimator_spec.rb
- engines/order_management/spec/services/order_management/subscriptions/form_spec.rb
@@ -720,6 +762,8 @@ Metrics/ModuleLength:
- spec/models/spree/variant_spec.rb
- spec/services/permissions/order_spec.rb
- spec/support/request/web_helper.rb
+ - app/models/spree/order/checkout.rb
+ - app/models/spree/payment/processing.rb
Metrics/ParameterLists:
Max: 5
@@ -728,3 +772,8 @@ Metrics/ParameterLists:
- app/models/product_import/entry_processor.rb
- lib/open_food_network/xero_invoices_report.rb
- spec/features/admin/reports_spec.rb
+
+Lint/UselessAssignment:
+ Exclude:
+ - 'spec/**/*'
+ - 'lib/spree/core/controller_helpers/common.rb'
diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index 753aaee48e..aec1f024b9 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -1,79 +1,214 @@
# This configuration was generated by
# `rubocop --auto-gen-config --exclude-limit 1400`
-# on 2020-06-22 13:28:10 +0100 using RuboCop version 0.81.0.
+# on 2020-08-13 16:05:53 +1000 using RuboCop version 0.81.0.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.
-# Offense count: 139
+# Offense count: 2
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyle, IndentationWidth.
+# SupportedStyles: with_first_argument, with_fixed_indentation
+Layout/ArgumentAlignment:
+ Exclude:
+ - 'spec/models/spree/order/checkout_spec.rb'
+
+# Offense count: 1
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyleAlignWith.
+# SupportedStylesAlignWith: either, start_of_block, start_of_line
+Layout/BlockAlignment:
+ Exclude:
+ - 'spec/models/spree/order/checkout_spec.rb'
+
+# Offense count: 2
+# Cop supports --auto-correct.
+Layout/EmptyLines:
+ Exclude:
+ - 'spec/models/spree/payment_spec.rb'
+
+# Offense count: 3
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: empty_lines, no_empty_lines
+Layout/EmptyLinesAroundBlockBody:
+ Exclude:
+ - 'spec/models/spree/payment_spec.rb'
+
+# Offense count: 3
+# Cop supports --auto-correct.
+# Configuration parameters: AllowForAlignment, AllowBeforeTrailingComments, ForceEqualSignAlignment.
+Layout/ExtraSpacing:
+ Exclude:
+ - 'spec/models/spree/payment_spec.rb'
+ - 'spec/requests/api/orders_spec.rb'
+
+# Offense count: 2
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyle, IndentationWidth.
+# SupportedStyles: special_inside_parentheses, consistent, align_brackets
+Layout/FirstArrayElementIndentation:
+ Exclude:
+ - 'spec/views/spree/admin/payment_methods/index.html.haml_spec.rb'
+
+# Offense count: 3
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyle, IndentationWidth.
+# SupportedStyles: special_inside_parentheses, consistent, align_braces
+Layout/FirstHashElementIndentation:
+ Exclude:
+ - 'spec/models/spree/payment_spec.rb'
+ - 'spec/swagger_helper.rb'
+
+# Offense count: 5
+# Cop supports --auto-correct.
+# Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
+# SupportedHashRocketStyles: key, separator, table
+# SupportedColonStyles: key, separator, table
+# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
+Layout/HashAlignment:
+ Exclude:
+ - 'spec/models/spree/payment_spec.rb'
+
+# Offense count: 1
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: normal, indented_internal_methods
+Layout/IndentationConsistency:
+ Exclude:
+ - 'spec/models/spree/order/checkout_spec.rb'
+
+# Offense count: 26
# Cop supports --auto-correct.
# Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
# URISchemes: http, https
Layout/LineLength:
- Max: 268
+ Max: 409
+
+# Offense count: 1
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: symmetrical, new_line, same_line
+Layout/MultilineHashBraceLayout:
+ Exclude:
+ - 'spec/models/spree/payment_spec.rb'
+
+# Offense count: 1
+# Cop supports --auto-correct.
+# Configuration parameters: AllowForAlignment, EnforcedStyleForExponentOperator.
+# SupportedStylesForExponentOperator: space, no_space
+Layout/SpaceAroundOperators:
+ Exclude:
+ - 'spec/models/spree/payment_spec.rb'
+
+# Offense count: 1
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters.
+# SupportedStyles: space, no_space
+# SupportedStylesForEmptyBraces: space, no_space
+Layout/SpaceInsideBlockBraces:
+ Exclude:
+ - 'spec/models/spree/payment_spec.rb'
+
+# Offense count: 11
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces.
+# SupportedStyles: space, no_space, compact
+# SupportedStylesForEmptyBraces: space, no_space
+Layout/SpaceInsideHashLiteralBraces:
+ Exclude:
+ - 'spec/models/spree/payment_spec.rb'
+ - 'spec/requests/api/orders_spec.rb'
+ - 'spec/services/checkout/form_data_adapter_spec.rb'
+ - 'spec/services/user_locale_setter_spec.rb'
+
+# Offense count: 6
+# Cop supports --auto-correct.
+# Configuration parameters: AllowInHeredoc.
+Layout/TrailingWhitespace:
+ Exclude:
+ - 'spec/controllers/base_controller2_spec.rb'
+ - 'spec/features/consumer/shopping/shopping_spec.rb'
+ - 'spec/requests/api/orders_spec.rb'
# Offense count: 2
Lint/DuplicateMethods:
Exclude:
- 'lib/discourse/single_sign_on.rb'
-# Offense count: 9
+# Offense count: 8
Lint/IneffectiveAccessModifier:
Exclude:
- 'app/models/column_preference.rb'
- 'app/models/spree/user.rb'
- 'app/services/mail_configuration.rb'
- 'lib/open_food_network/feature_toggle.rb'
- - 'spec/lib/open_food_network/reports/report_spec.rb'
-# Offense count: 5
+# Offense count: 4
+# Cop supports --auto-correct.
+# Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods.
+Lint/UnusedMethodArgument:
+ Exclude:
+ - 'spec/views/spree/admin/payment_methods/index.html.haml_spec.rb'
+
+# Offense count: 3
# Configuration parameters: ContextCreatingMethods, MethodCreatingMethods.
Lint/UselessAccessModifier:
Exclude:
- 'app/models/column_preference.rb'
- 'app/services/mail_configuration.rb'
- 'lib/open_food_network/feature_toggle.rb'
- - 'lib/open_food_network/reports/bulk_coop_report.rb'
- - 'spec/lib/open_food_network/reports/report_spec.rb'
-
-# Offense count: 6
-# Configuration parameters: IgnoredMethods.
-Metrics/AbcSize:
- Max: 37
# Offense count: 1
+Lint/UselessAssignment:
+ Exclude:
+ - 'spec/**/*'
+ - 'lib/spree/core/controller_helpers/common.rb'
+
+# Offense count: 19
+# Configuration parameters: IgnoredMethods.
+Metrics/AbcSize:
+ Max: 126
+
+# Offense count: 7
# Configuration parameters: CountComments, ExcludedMethods.
# ExcludedMethods: refine
Metrics/BlockLength:
- Max: 27
+ Max: 102
-# Offense count: 1
+# Offense count: 2
# Configuration parameters: CountComments.
Metrics/ClassLength:
- Max: 101
+ Max: 231
-# Offense count: 1
+# Offense count: 3
# Configuration parameters: IgnoredMethods.
Metrics/CyclomaticComplexity:
- Max: 7
+ Max: 23
-# Offense count: 6
+# Offense count: 19
# Configuration parameters: CountComments, ExcludedMethods.
Metrics/MethodLength:
- Max: 20
+ Max: 140
-# Offense count: 1
+# Offense count: 2
# Configuration parameters: CountComments.
Metrics/ModuleLength:
- Max: 121
+ Max: 208
-# Offense count: 8
+# Offense count: 2
+# Configuration parameters: IgnoredMethods.
+Metrics/PerceivedComplexity:
+ Max: 24
+
+# Offense count: 9
Naming/AccessorMethodName:
Exclude:
- 'app/controllers/spree/admin/taxonomies_controller.rb'
- 'app/models/spree/adjustment_decorator.rb'
- 'app/models/spree/order_decorator.rb'
+ - 'lib/spree/core/controller_helpers/common.rb'
- 'spec/support/request/shop_workflow.rb'
- 'spec/support/request/web_helper.rb'
@@ -117,6 +252,15 @@ Naming/PredicateName:
- 'lib/open_food_network/packing_report.rb'
- 'lib/tasks/data.rake'
+# Offense count: 7
+# Cop supports --auto-correct.
+Rails/ActiveRecordAliases:
+ Exclude:
+ - 'spec/controllers/line_items_controller_spec.rb'
+ - 'spec/controllers/spree/orders_controller_spec.rb'
+ - 'spec/features/consumer/shopping/orders_spec.rb'
+ - 'spec/requests/api/orders_spec.rb'
+
# Offense count: 1
# Configuration parameters: EnforcedStyle.
# SupportedStyles: strict, flexible
@@ -124,6 +268,13 @@ Rails/Date:
Exclude:
- 'app/models/order_cycle.rb'
+# Offense count: 1
+# Cop supports --auto-correct.
+# Configuration parameters: EnforceForPrefixed.
+Rails/Delegate:
+ Exclude:
+ - 'engines/order_management/app/services/order_management/reports/bulk_coop/renderers/html_renderer.rb'
+
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: Whitelist.
@@ -150,7 +301,7 @@ Rails/FilePath:
- 'spec/serializers/api/admin/enterprise_serializer_spec.rb'
- 'spec/support/downloads_helper.rb'
-# Offense count: 7
+# Offense count: 9
# Cop supports --auto-correct.
# Configuration parameters: Include.
# Include: app/models/**/*.rb
@@ -160,15 +311,17 @@ Rails/FindBy:
- 'app/models/product_import/entry_processor.rb'
- 'app/models/product_import/entry_validator.rb'
- 'app/models/product_import/spreadsheet_data.rb'
+ - 'app/models/spree/shipment.rb'
- 'app/models/spree/user.rb'
-# Offense count: 1
+# Offense count: 2
# Cop supports --auto-correct.
# Configuration parameters: Include.
# Include: app/models/**/*.rb
Rails/FindEach:
Exclude:
- 'app/models/spree/order_decorator.rb'
+ - 'app/models/spree/shipment.rb'
# Offense count: 5
# Configuration parameters: Include.
@@ -180,7 +333,7 @@ Rails/HasAndBelongsToMany:
- 'app/models/spree/concerns/payment_method_distributors.rb'
- 'app/models/spree/line_item_decorator.rb'
-# Offense count: 25
+# Offense count: 26
# Configuration parameters: Include.
# Include: app/models/**/*.rb
Rails/HasManyOrHasOneDependent:
@@ -192,6 +345,7 @@ Rails/HasManyOrHasOneDependent:
- 'app/models/spree/order_decorator.rb'
- 'app/models/spree/payment_method_decorator.rb'
- 'app/models/spree/property.rb'
+ - 'app/models/spree/shipment.rb'
- 'app/models/spree/shipping_method_decorator.rb'
- 'app/models/spree/user.rb'
- 'app/models/spree/variant_decorator.rb'
@@ -268,7 +422,7 @@ Rails/ReflectionClassName:
- 'app/models/enterprise_role.rb'
- 'app/models/subscription.rb'
-# Offense count: 227
+# Offense count: 233
# Configuration parameters: Blacklist, Whitelist.
# Blacklist: decrement!, decrement_counter, increment!, increment_counter, toggle!, touch, update_all, update_attribute, update_column, update_columns, update_counters
Rails/SkipsModelValidations:
@@ -287,7 +441,8 @@ Rails/SkipsModelValidations:
- 'app/models/spree/address_decorator.rb'
- 'app/models/spree/credit_card_decorator.rb'
- 'app/models/spree/order_decorator.rb'
- - 'app/models/spree/payment_decorator.rb'
+ - 'app/models/spree/payment.rb'
+ - 'app/models/spree/shipment.rb'
- 'app/models/spree/shipping_method_decorator.rb'
- 'app/models/subscription.rb'
- 'app/models/variant_override.rb'
@@ -355,20 +510,22 @@ Rails/SkipsModelValidations:
- 'spec/support/request/shop_workflow.rb'
- 'spec/views/spree/shared/_order_details.html.haml_spec.rb'
-# Offense count: 2
+# Offense count: 3
# Configuration parameters: Include.
# Include: app/models/**/*.rb
Rails/UniqueValidationWithoutIndex:
Exclude:
- 'app/models/customer.rb'
- 'app/models/exchange.rb'
+ - 'app/models/spree/stock_item.rb'
-# Offense count: 1
+# Offense count: 2
# Configuration parameters: Environments.
# Environments: development, test, production
Rails/UnknownEnv:
Exclude:
- 'app/models/spree/app_configuration_decorator.rb'
+ - 'lib/spree/core/controller_helpers/ssl.rb'
# Offense count: 2
Style/CaseEquality:
@@ -376,7 +533,7 @@ Style/CaseEquality:
- 'app/helpers/angular_form_helper.rb'
- 'spec/models/spree/payment_spec.rb'
-# Offense count: 75
+# Offense count: 71
# Cop supports --auto-correct.
# Configuration parameters: AutoCorrect, EnforcedStyle.
# SupportedStyles: nested, compact
@@ -440,20 +597,10 @@ Style/ClassAndModuleChildren:
- 'app/serializers/api/property_serializer.rb'
- 'app/serializers/api/shipping_method_serializer.rb'
- 'app/serializers/api/state_serializer.rb'
- - 'app/serializers/api/taxon_image_serializer.rb'
- 'app/serializers/api/taxon_serializer.rb'
- 'app/serializers/api/variant_serializer.rb'
- 'lib/open_food_network/locking.rb'
- - 'lib/open_food_network/reports/bulk_coop_allocation_report.rb'
- - 'lib/open_food_network/reports/bulk_coop_report.rb'
- - 'lib/open_food_network/reports/bulk_coop_supplier_report.rb'
- - 'lib/open_food_network/reports/report.rb'
- - 'lib/open_food_network/reports/row.rb'
- - 'lib/open_food_network/reports/rule.rb'
- 'spec/controllers/spree/admin/base_controller_spec.rb'
- - 'spec/lib/open_food_network/reports/report_spec.rb'
- - 'spec/lib/open_food_network/reports/row_spec.rb'
- - 'spec/lib/open_food_network/reports/rule_spec.rb'
# Offense count: 2
Style/ClassVars:
@@ -468,7 +615,7 @@ Style/FormatStringToken:
- 'lib/open_food_network/sales_tax_report.rb'
- 'spec/features/admin/bulk_order_management_spec.rb'
-# Offense count: 874
+# Offense count: 847
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: always, always_true, never
@@ -562,7 +709,6 @@ Style/FrozenStringLiteralComment:
- 'app/controllers/spree/admin/variants_controller.rb'
- 'app/controllers/spree/admin/zones_controller.rb'
- 'app/controllers/spree/credit_cards_controller.rb'
- - 'app/controllers/spree/home_controller.rb'
- 'app/controllers/spree/orders_controller.rb'
- 'app/controllers/spree/store_controller.rb'
- 'app/controllers/spree/user_passwords_controller.rb'
@@ -617,8 +763,6 @@ Style/FrozenStringLiteralComment:
- 'app/jobs/subscription_placement_job.rb'
- 'app/jobs/welcome_enterprise_job.rb'
- 'app/mailers/enterprise_mailer.rb'
- - 'app/mailers/spree/base_mailer_decorator.rb'
- - 'app/mailers/spree/order_mailer_decorator.rb'
- 'app/mailers/spree/user_mailer.rb'
- 'app/mailers/subscription_mailer.rb'
- 'app/models/adjustment_metadata.rb'
@@ -677,12 +821,6 @@ Style/FrozenStringLiteralComment:
- 'app/models/spree/address_decorator.rb'
- 'app/models/spree/adjustment_decorator.rb'
- 'app/models/spree/app_configuration_decorator.rb'
- - 'app/models/spree/calculator/default_tax_decorator.rb'
- - 'app/models/spree/calculator/flat_percent_item_total_decorator.rb'
- - 'app/models/spree/calculator/flat_rate_decorator.rb'
- - 'app/models/spree/calculator/flexi_rate_decorator.rb'
- - 'app/models/spree/calculator/per_item_decorator.rb'
- - 'app/models/spree/calculator/price_sack_decorator.rb'
- 'app/models/spree/calculator_decorator.rb'
- 'app/models/spree/classification_decorator.rb'
- 'app/models/spree/concerns/payment_method_distributors.rb'
@@ -695,7 +833,6 @@ Style/FrozenStringLiteralComment:
- 'app/models/spree/line_item_decorator.rb'
- 'app/models/spree/option_type_decorator.rb'
- 'app/models/spree/order_decorator.rb'
- - 'app/models/spree/payment_decorator.rb'
- 'app/models/spree/payment_method_decorator.rb'
- 'app/models/spree/preferences/file_configuration.rb'
- 'app/models/spree/price_decorator.rb'
@@ -704,15 +841,12 @@ Style/FrozenStringLiteralComment:
- 'app/models/spree/product_property_decorator.rb'
- 'app/models/spree/product_set.rb'
- 'app/models/spree/property.rb'
- - 'app/models/spree/shipment_decorator.rb'
- 'app/models/spree/shipping_method_decorator.rb'
- - 'app/models/spree/stock/availability_validator_decorator.rb'
- 'app/models/spree/stock_location_decorator.rb'
- 'app/models/spree/tax_rate_decorator.rb'
- 'app/models/spree/taxon_decorator.rb'
- 'app/models/spree/user.rb'
- 'app/models/spree/variant_decorator.rb'
- - 'app/models/stock/package.rb'
- 'app/models/stripe_account.rb'
- 'app/models/subscription.rb'
- 'app/models/subscription_line_item.rb'
@@ -796,7 +930,6 @@ Style/FrozenStringLiteralComment:
- 'app/serializers/api/shipping_method_serializer.rb'
- 'app/serializers/api/shop_for_orders_serializer.rb'
- 'app/serializers/api/state_serializer.rb'
- - 'app/serializers/api/taxon_image_serializer.rb'
- 'app/serializers/api/taxon_jstree_attribute_serializer.rb'
- 'app/serializers/api/taxon_jstree_serializer.rb'
- 'app/serializers/api/taxon_serializer.rb'
@@ -804,7 +937,6 @@ Style/FrozenStringLiteralComment:
- 'app/serializers/api/user_serializer.rb'
- 'app/serializers/api/variant_serializer.rb'
- 'app/services/action_callbacks.rb'
- - 'app/services/advance_order_service.rb'
- 'app/services/bulk_invoice_service.rb'
- 'app/services/cart_service.rb'
- 'app/services/create_order_cycle.rb'
@@ -824,6 +956,7 @@ Style/FrozenStringLiteralComment:
- 'app/services/order_factory.rb'
- 'app/services/order_syncer.rb'
- 'app/services/order_update_issues.rb'
+ - 'app/services/order_workflow.rb'
- 'app/services/permissions/order.rb'
- 'app/services/product_tag_rules_filterer.rb'
- 'app/services/products_renderer.rb'
@@ -886,7 +1019,6 @@ Style/FrozenStringLiteralComment:
- 'lib/discourse/single_sign_on.rb'
- 'lib/open_food_network/address_finder.rb'
- 'lib/open_food_network/available_payment_method_filter.rb'
- - 'lib/open_food_network/bulk_coop_report.rb'
- 'lib/open_food_network/column_preference_defaults.rb'
- 'lib/open_food_network/customers_report.rb'
- 'lib/open_food_network/enterprise_fee_applicator.rb'
@@ -899,7 +1031,6 @@ Style/FrozenStringLiteralComment:
- 'lib/open_food_network/i18n_config.rb'
- 'lib/open_food_network/lettuce_share_report.rb'
- 'lib/open_food_network/locking.rb'
- - 'lib/open_food_network/model_class_from_controller_name.rb'
- 'lib/open_food_network/order_and_distributor_report.rb'
- 'lib/open_food_network/order_cycle_form_applicator.rb'
- 'lib/open_food_network/order_cycle_management_report.rb'
@@ -921,14 +1052,8 @@ Style/FrozenStringLiteralComment:
- 'lib/open_food_network/property_merge.rb'
- 'lib/open_food_network/rack_request_blocker.rb'
- 'lib/open_food_network/referer_parser.rb'
- - 'lib/open_food_network/reports/bulk_coop_allocation_report.rb'
- - 'lib/open_food_network/reports/bulk_coop_report.rb'
- - 'lib/open_food_network/reports/bulk_coop_supplier_report.rb'
- 'lib/open_food_network/reports/line_items.rb'
- 'lib/open_food_network/reports/list.rb'
- - 'lib/open_food_network/reports/report.rb'
- - 'lib/open_food_network/reports/row.rb'
- - 'lib/open_food_network/reports/rule.rb'
- 'lib/open_food_network/sales_tax_report.rb'
- 'lib/open_food_network/scope_product_to_hub.rb'
- 'lib/open_food_network/scope_variant_to_hub.rb'
@@ -942,9 +1067,6 @@ Style/FrozenStringLiteralComment:
- 'lib/spree/api/controller_setup.rb'
- 'lib/spree/api/testing_support/setup.rb'
- 'lib/spree/authentication_helpers.rb'
- - 'lib/spree/core/controller_helpers/auth_decorator.rb'
- - 'lib/spree/core/controller_helpers/order_decorator.rb'
- - 'lib/spree/core/controller_helpers/respond_with_decorator.rb'
- 'lib/spree/localized_number.rb'
- 'lib/spree/money_decorator.rb'
- 'lib/spree/product_filters.rb'
@@ -973,7 +1095,6 @@ Style/FrozenStringLiteralComment:
- 'lib/tasks/sample_data/user_factory.rb'
- 'lib/tasks/specs.rake'
- 'lib/tasks/users.rake'
- - 'spec/config/application_spec.rb'
- 'spec/controllers/admin/bulk_line_items_controller_spec.rb'
- 'spec/controllers/admin/column_preferences_controller_spec.rb'
- 'spec/controllers/admin/customers_controller_spec.rb'
@@ -1004,9 +1125,9 @@ Style/FrozenStringLiteralComment:
- 'spec/controllers/api/taxonomies_controller_spec.rb'
- 'spec/controllers/api/taxons_controller_spec.rb'
- 'spec/controllers/api/variants_controller_spec.rb'
+ - 'spec/controllers/base_controller2_spec.rb'
- 'spec/controllers/base_controller_spec.rb'
- 'spec/controllers/cart_controller_spec.rb'
- - 'spec/controllers/checkout_controller_concurrency_spec.rb'
- 'spec/controllers/checkout_controller_spec.rb'
- 'spec/controllers/enterprises_controller_spec.rb'
- 'spec/controllers/groups_controller_spec.rb'
@@ -1023,7 +1144,6 @@ Style/FrozenStringLiteralComment:
- 'spec/controllers/spree/admin/orders_controller_spec.rb'
- 'spec/controllers/spree/admin/overview_controller_spec.rb'
- 'spec/controllers/spree/admin/payment_methods_controller_spec.rb'
- - 'spec/controllers/spree/admin/payments_controller_spec.rb'
- 'spec/controllers/spree/admin/products_controller_spec.rb'
- 'spec/controllers/spree/admin/reports_controller_spec.rb'
- 'spec/controllers/spree/admin/search_controller_spec.rb'
@@ -1032,7 +1152,6 @@ Style/FrozenStringLiteralComment:
- 'spec/controllers/spree/admin/variants_controller_spec.rb'
- 'spec/controllers/spree/credit_cards_controller_spec.rb'
- 'spec/controllers/spree/orders_controller_spec.rb'
- - 'spec/controllers/spree/store_controller_spec.rb'
- 'spec/controllers/spree/user_sessions_controller_spec.rb'
- 'spec/controllers/spree/users_controller_spec.rb'
- 'spec/controllers/stripe/callbacks_controller_spec.rb'
@@ -1140,7 +1259,6 @@ Style/FrozenStringLiteralComment:
- 'spec/jobs/subscription_placement_job_spec.rb'
- 'spec/jobs/welcome_enterprise_job_spec.rb'
- 'spec/lib/open_food_network/address_finder_spec.rb'
- - 'spec/lib/open_food_network/bulk_coop_report_spec.rb'
- 'spec/lib/open_food_network/customers_report_spec.rb'
- 'spec/lib/open_food_network/enterprise_fee_applicator_spec.rb'
- 'spec/lib/open_food_network/enterprise_fee_calculator_spec.rb'
@@ -1166,9 +1284,6 @@ Style/FrozenStringLiteralComment:
- 'spec/lib/open_food_network/products_and_inventory_report_spec.rb'
- 'spec/lib/open_food_network/property_merge_spec.rb'
- 'spec/lib/open_food_network/referer_parser_spec.rb'
- - 'spec/lib/open_food_network/reports/report_spec.rb'
- - 'spec/lib/open_food_network/reports/row_spec.rb'
- - 'spec/lib/open_food_network/reports/rule_spec.rb'
- 'spec/lib/open_food_network/sales_tax_report_spec.rb'
- 'spec/lib/open_food_network/scope_variant_to_hub_spec.rb'
- 'spec/lib/open_food_network/scope_variants_to_search_spec.rb'
@@ -1183,12 +1298,16 @@ Style/FrozenStringLiteralComment:
- 'spec/lib/tasks/enterprises_rake_spec.rb'
- 'spec/lib/tasks/users_rake_spec.rb'
- 'spec/mailers/enterprise_mailer_spec.rb'
- - 'spec/mailers/order_mailer_spec.rb'
- 'spec/mailers/producer_mailer_spec.rb'
- 'spec/mailers/subscription_mailer_spec.rb'
- 'spec/mailers/user_mailer_spec.rb'
- 'spec/models/adjustment_metadata_spec.rb'
+ - 'spec/models/calculator/flat_percent_item_total_spec.rb'
- 'spec/models/calculator/flat_percent_per_item_spec.rb'
+ - 'spec/models/calculator/flat_rate_spec.rb'
+ - 'spec/models/calculator/flexi_rate_spec.rb'
+ - 'spec/models/calculator/per_item_spec.rb'
+ - 'spec/models/calculator/price_sack_spec.rb'
- 'spec/models/calculator/weight_spec.rb'
- 'spec/models/column_preference_spec.rb'
- 'spec/models/concerns/order_shipment_spec.rb'
@@ -1214,11 +1333,6 @@ Style/FrozenStringLiteralComment:
- 'spec/models/spree/ability_spec.rb'
- 'spec/models/spree/addresses_spec.rb'
- 'spec/models/spree/adjustment_spec.rb'
- - 'spec/models/spree/calculator/flat_percent_item_total_spec.rb'
- - 'spec/models/spree/calculator/flat_rate_spec.rb'
- - 'spec/models/spree/calculator/flexi_rate_spec.rb'
- - 'spec/models/spree/calculator/per_item_spec.rb'
- - 'spec/models/spree/calculator/price_sack_spec.rb'
- 'spec/models/spree/calculator_spec.rb'
- 'spec/models/spree/classification_spec.rb'
- 'spec/models/spree/credit_card_spec.rb'
@@ -1233,14 +1347,12 @@ Style/FrozenStringLiteralComment:
- 'spec/models/spree/price_spec.rb'
- 'spec/models/spree/product_set_spec.rb'
- 'spec/models/spree/product_spec.rb'
- - 'spec/models/spree/shipment_spec.rb'
- 'spec/models/spree/shipping_method_spec.rb'
- 'spec/models/spree/stock/availability_validator_spec.rb'
- 'spec/models/spree/tax_rate_spec.rb'
- 'spec/models/spree/taxon_spec.rb'
- 'spec/models/spree/user_spec.rb'
- 'spec/models/spree/variant_spec.rb'
- - 'spec/models/stock/package_spec.rb'
- 'spec/models/stripe_account_spec.rb'
- 'spec/models/subscription_line_item_spec.rb'
- 'spec/models/subscription_spec.rb'
@@ -1282,7 +1394,6 @@ Style/FrozenStringLiteralComment:
- 'spec/serializers/api/product_serializer_spec.rb'
- 'spec/serializers/api/shipping_method_serializer_spec.rb'
- 'spec/serializers/api/variant_serializer_spec.rb'
- - 'spec/services/advance_order_service_spec.rb'
- 'spec/services/bulk_invoice_service_spec.rb'
- 'spec/services/cart_service_spec.rb'
- 'spec/services/default_shipping_category_spec.rb'
@@ -1298,6 +1409,7 @@ Style/FrozenStringLiteralComment:
- 'spec/services/order_cycle_warning_spec.rb'
- 'spec/services/order_factory_spec.rb'
- 'spec/services/order_syncer_spec.rb'
+ - 'spec/services/order_workflow_spec.rb'
- 'spec/services/permissions/order_spec.rb'
- 'spec/services/product_tag_rules_filterer_spec.rb'
- 'spec/services/products_renderer_spec.rb'
@@ -1331,7 +1443,7 @@ Style/FrozenStringLiteralComment:
- 'spec/support/performance_helper.rb'
- 'spec/support/products_helper.rb'
- 'spec/support/request/admin_helper.rb'
- - 'spec/support/request/authentication_workflow.rb'
+ - 'spec/support/request/authentication_helper.rb'
- 'spec/support/request/checkout_workflow.rb'
- 'spec/support/request/cookie_helper.rb'
- 'spec/support/request/distribution_helper.rb'
@@ -1348,8 +1460,9 @@ Style/FrozenStringLiteralComment:
- 'spec/validators/integer_array_validator_spec.rb'
- 'spec/views/spree/admin/orders/edit.html.haml_spec.rb'
- 'spec/views/spree/admin/orders/index.html.haml_spec.rb'
+ - 'spec/views/spree/admin/payment_methods/index.html.haml_spec.rb'
-# Offense count: 51
+# Offense count: 48
# Configuration parameters: MinBodyLength.
Style/GuardClause:
Exclude:
@@ -1369,32 +1482,35 @@ Style/GuardClause:
- 'app/models/spree/order_decorator.rb'
- 'app/models/spree/price_decorator.rb'
- 'app/models/spree/product_decorator.rb'
- - 'app/services/advance_order_service.rb'
- 'app/services/order_syncer.rb'
- 'lib/discourse/single_sign_on.rb'
- 'lib/open_food_network/order_cycle_form_applicator.rb'
- 'lib/open_food_network/rack_request_blocker.rb'
- 'lib/open_food_network/variant_and_line_item_naming.rb'
- - 'lib/spree/core/controller_helpers/order_decorator.rb'
- - 'lib/spree/core/controller_helpers/respond_with_decorator.rb'
- 'spec/support/delayed_job_helper.rb'
- 'spec/support/request/distribution_helper.rb'
- 'spec/support/request/shop_workflow.rb'
+# Offense count: 54
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyle, UseHashRocketsWithSymbolValues, PreferHashRocketsForNonAlnumEndingSymbols.
+# SupportedStyles: ruby19, hash_rockets, no_mixed_keys, ruby19_no_mixed_keys
+Style/HashSyntax:
+ Exclude:
+ - 'spec/models/spree/payment_spec.rb'
+
# Offense count: 1
Style/MissingRespondToMissing:
Exclude:
- 'app/helpers/application_helper.rb'
-# Offense count: 4
+# Offense count: 2
Style/MixinUsage:
Exclude:
- 'lib/open_food_network/orders_and_fulfillments_report.rb'
- - 'spec/lib/open_food_network/bulk_coop_report_spec.rb'
- - 'spec/lib/open_food_network/order_cycle_management_report_spec.rb'
- 'spec/lib/open_food_network/packing_report_spec.rb'
-# Offense count: 41
+# Offense count: 39
# Cop supports --auto-correct.
# Configuration parameters: AutoCorrect, EnforcedStyle, IgnoredMethods.
# SupportedStyles: predicate, comparison
@@ -1409,11 +1525,9 @@ Style/NumericPredicate:
- 'app/models/product_import/product_importer.rb'
- 'app/models/product_import/spreadsheet_entry.rb'
- 'app/models/spree/adjustment_decorator.rb'
- - 'app/models/spree/calculator/flexi_rate_decorator.rb'
- 'app/models/spree/gateway/stripe_connect.rb'
- 'app/models/spree/line_item_decorator.rb'
- 'app/models/spree/order_decorator.rb'
- - 'app/models/spree/shipment_decorator.rb'
- 'app/models/spree/user.rb'
- 'app/models/variant_override.rb'
- 'app/services/cart_service.rb'
@@ -1426,6 +1540,22 @@ Style/NumericPredicate:
- 'lib/spree/money_decorator.rb'
- 'lib/tasks/sample_data.rake'
+# Offense count: 1
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: compact, exploded
+Style/RaiseArgs:
+ Exclude:
+ - 'spec/controllers/checkout_controller_spec.rb'
+
+# Offense count: 1
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyle, AllowInnerSlashes.
+# SupportedStyles: slashes, percent_r, mixed
+Style/RegexpLiteral:
+ Exclude:
+ - 'lib/spree/core/controller_helpers/auth.rb'
+
# Offense count: 231
Style/Send:
Exclude:
diff --git a/DOCKER.md b/DOCKER.md
index 65f6815425..935e62b729 100644
--- a/DOCKER.md
+++ b/DOCKER.md
@@ -17,7 +17,13 @@ Better to have at least 2GB free on your computer in order to download images an
Open a terminal with a shell.
-Clone the repository:
+Clone the repository. If you're planning on contributing code to the project (which we [LOVE](CONTRIBUTING.md)), it is a good idea to begin by forking this repo using the Fork button in the top-right corner of this screen. You should then be able to use git clone to copy your fork onto your local machine.
+
+```sh
+$ git clone https://github.com/YOUR_GITHUB_USERNAME_HERE/openfoodnetwork
+```
+
+Otherwise, if you just want to get things running, clone from the OFN main repo:
```sh
$ git clone git@github.com:openfoodfoundation/openfoodnetwork.git
diff --git a/GETTING_STARTED.md b/GETTING_STARTED.md
index b252993215..fd8dc47769 100644
--- a/GETTING_STARTED.md
+++ b/GETTING_STARTED.md
@@ -1,6 +1,6 @@
### Getting Started
-This is a general guide to setting up an Open Food Network development environment on your local machine.
+This is a general guide to setting up an Open Food Network **development environment on your local machine**. If you want to setup OFN on a server, please have a look at the [ofn-install deployment guide](https://github.com/openfoodfoundation/ofn-install/wiki).
### Requirements
diff --git a/Gemfile b/Gemfile
index eb91b2c147..682b445502 100644
--- a/Gemfile
+++ b/Gemfile
@@ -3,7 +3,7 @@ ruby "2.3.7"
git_source(:github) { |repo_name| "https://github.com/#{repo_name}.git" }
gem 'i18n', '~> 0.6.11'
-gem 'i18n-js', '~> 3.7.0'
+gem 'i18n-js', '~> 3.7.1'
gem 'rails', '~> 4.0.13'
gem 'rails-i18n', '~> 4.0'
gem 'rails_safe_tasks', '~> 1.0'
@@ -39,18 +39,21 @@ gem 'stringex', '~> 1.5.1'
gem 'spree_i18n', github: 'spree/spree_i18n', branch: '1-3-stable'
-# Our branch contains two changes
+# Our branch contains the following changes:
# - Pass customer email and phone number to PayPal (merged to upstream master)
# - Change type of password from string to password to hide it in the form
+# - Skip CA cert file and use the ones provided by the OS
gem 'spree_paypal_express', github: 'openfoodfoundation/better_spree_paypal_express', branch: '2-1-0-stable'
+
gem 'stripe'
# We need at least this version to have Digicert's root certificate
# which is needed for Pin Payments (and possibly others).
gem 'activemerchant', '~> 1.78.0'
-gem 'devise', '~> 3.0.1'
+gem 'devise', '~> 3.5.10' # v4.0.0 needs rails 4.1
gem 'devise-encryptable'
+gem 'devise-token_authenticatable', '~> 0.4.10' # v0.5.0 needs devise v4
gem 'jwt', '~> 2.2'
gem 'oauth2', '~> 1.4.4' # Used for Stripe Connect
@@ -83,12 +86,11 @@ gem 'acts-as-taggable-on', '~> 4.0'
gem 'angularjs-file-upload-rails', '~> 2.4.1'
gem 'custom_error_message', github: 'jeremydurham/custom-err-msg'
gem 'dalli'
-gem 'diffy'
gem 'figaro'
gem 'geocoder'
gem 'gmaps4rails'
gem 'oj'
-gem 'paper_trail', '~> 5.2.3'
+gem 'paper_trail', '~> 7.1.3'
gem 'paperclip', '~> 3.4.1'
gem 'rack-rewrite'
gem 'rack-ssl', require: 'rack/ssl'
diff --git a/Gemfile.lock b/Gemfile.lock
index 9b627cb940..61a7f746ac 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -6,7 +6,7 @@ GIT
GIT
remote: https://github.com/openfoodfoundation/better_spree_paypal_express.git
- revision: e28e4a8c5cedba504eea9cdad4be440d277d7e68
+ revision: 1736e3268239a841576d2719a1f276cf9b74c5c5
branch: 2-1-0-stable
specs:
spree_paypal_express (2.0.3)
@@ -108,7 +108,7 @@ GEM
activesupport (= 4.0.13)
arel (~> 4.0.0)
activerecord-deprecated_finders (1.0.4)
- activerecord-import (1.0.5)
+ activerecord-import (1.0.6)
activerecord (>= 3.2)
activerecord-postgresql-adapter (0.0.1)
pg
@@ -148,9 +148,7 @@ GEM
nokogiri (>= 1.4.4)
uuidtools (~> 2.1)
bcrypt (3.1.13)
- bcrypt-ruby (3.1.5)
- bcrypt (>= 3.1.3)
- bugsnag (6.13.1)
+ bugsnag (6.16.0)
concurrent-ruby (~> 1.0)
builder (3.1.4)
byebug (11.0.1)
@@ -194,7 +192,7 @@ GEM
compass (~> 1.0.0)
sass-rails (< 5.1)
sprockets (< 4.0)
- concurrent-ruby (1.1.6)
+ concurrent-ruby (1.1.7)
crack (0.4.3)
safe_yaml (~> 1.0.0)
css_parser (1.7.1)
@@ -206,7 +204,7 @@ GEM
activerecord (>= 3.2.0, < 5.0)
fog (~> 1.0)
rails (>= 3.2.0, < 5.0)
- ddtrace (0.37.0)
+ ddtrace (0.39.0)
msgpack
debugger-linecache (1.2.0)
delayed_job (4.1.8)
@@ -219,15 +217,18 @@ GEM
delayed_job (> 2.0.3)
rack-protection (>= 1.5.5)
sinatra (>= 1.4.4)
- devise (3.0.4)
- bcrypt-ruby (~> 3.0)
+ devise (3.5.10)
+ bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 3.2.6, < 5)
+ responders
+ thread_safe (~> 0.1)
warden (~> 1.2.3)
devise-encryptable (0.2.0)
devise (>= 2.1.0)
+ devise-token_authenticatable (0.4.10)
+ devise (>= 3.5.2, < 4.0.0)
diff-lcs (1.3)
- diffy (3.3.0)
docile (1.3.2)
dry-inflector (0.1.2)
erubis (2.7.0)
@@ -420,7 +421,7 @@ GEM
mime-types (~> 3.0)
multi_xml (>= 0.5.2)
i18n (0.6.11)
- i18n-js (3.7.0)
+ i18n-js (3.7.1)
i18n (>= 0.6.6)
immigrant (0.3.6)
activerecord (>= 3.0)
@@ -466,7 +467,7 @@ GEM
money (5.1.1)
i18n (~> 0.6.0)
msgpack (1.3.3)
- multi_json (1.14.1)
+ multi_json (1.15.0)
multi_xml (0.6.0)
multipart-post (2.1.1)
newrelic_rpm (3.18.1.330)
@@ -478,11 +479,11 @@ GEM
multi_json (~> 1.3)
multi_xml (~> 0.5)
rack (>= 1.2, < 3)
- oj (3.10.6)
+ oj (3.10.8)
optimist (3.0.0)
orm_adapter (0.5.0)
- paper_trail (5.2.3)
- activerecord (>= 3.0, < 6.0)
+ paper_trail (7.1.3)
+ activerecord (>= 4.0, < 5.2)
request_store (~> 1.1)
paperclip (3.4.2)
activemodel (>= 3.0.0)
@@ -508,7 +509,7 @@ GEM
pry-byebug (3.7.0)
byebug (~> 11.0)
pry (~> 0.10)
- public_suffix (4.0.3)
+ public_suffix (4.0.5)
rack (1.5.5)
rack-mini-profiler (2.0.2)
rack (>= 1.2.0)
@@ -553,8 +554,10 @@ GEM
nokogiri (~> 1.5)
optimist (~> 3.0)
redcarpet (3.5.0)
- request_store (1.4.1)
+ request_store (1.5.0)
rack (>= 1.4)
+ responders (1.1.2)
+ railties (>= 3.2, < 4.2)
rexml (3.2.4)
roadie (3.4.0)
css_parser (~> 1.4)
@@ -588,19 +591,19 @@ GEM
rspec-retry (0.6.2)
rspec-core (> 3.3)
rspec-support (3.9.2)
- rswag (2.2.0)
- rswag-api (= 2.2.0)
- rswag-specs (= 2.2.0)
- rswag-ui (= 2.2.0)
- rswag-api (2.2.0)
- railties (>= 3.1, < 6.1)
- rswag-specs (2.2.0)
- activesupport (>= 3.1, < 6.1)
+ rswag (2.3.1)
+ rswag-api (= 2.3.1)
+ rswag-specs (= 2.3.1)
+ rswag-ui (= 2.3.1)
+ rswag-api (2.3.1)
+ railties (>= 3.1, < 7.0)
+ rswag-specs (2.3.1)
+ activesupport (>= 3.1, < 7.0)
json-schema (~> 2.2)
- railties (>= 3.1, < 6.1)
- rswag-ui (2.2.0)
- actionpack (>= 3.1, < 6.1)
- railties (>= 3.1, < 6.1)
+ railties (>= 3.1, < 7.0)
+ rswag-ui (2.3.1)
+ actionpack (>= 3.1, < 7.0)
+ railties (>= 3.1, < 7.0)
rubocop (0.81.0)
jaro_winkler (~> 1.5.1)
parallel (~> 1.10)
@@ -668,7 +671,7 @@ GEM
uglifier (4.2.0)
execjs (>= 0.3.0, < 3)
unicode-display_width (1.7.0)
- unicorn (5.5.5)
+ unicorn (5.6.0)
kgio (~> 2.6)
raindrops (~> 0.7)
unicorn-rails (2.2.1)
@@ -735,10 +738,10 @@ DEPENDENCIES
debugger-linecache
delayed_job_active_record
delayed_job_web
- devise (~> 3.0.1)
+ devise (~> 3.5.10)
devise-encryptable
+ devise-token_authenticatable (~> 0.4.10)
dfc_provider!
- diffy
eventmachine (>= 1.2.3)
factory_bot_rails (= 4.10.0)
ffaker (~> 1.16)
@@ -753,7 +756,7 @@ DEPENDENCIES
highline (= 1.6.18)
httparty (~> 0.18)
i18n (~> 0.6.11)
- i18n-js (~> 3.7.0)
+ i18n-js (~> 3.7.1)
immigrant
jquery-migrate-rails
jquery-rails (= 3.1.5)
@@ -772,7 +775,7 @@ DEPENDENCIES
ofn-qz!
oj
order_management!
- paper_trail (~> 5.2.3)
+ paper_trail (~> 7.1.3)
paperclip (~> 3.4.1)
paranoia (~> 2.0)
pg (~> 0.21.0)
diff --git a/app/assets/javascripts/admin/all.js b/app/assets/javascripts/admin/all.js
index eee8a874c9..c43f365cb6 100644
--- a/app/assets/javascripts/admin/all.js
+++ b/app/assets/javascripts/admin/all.js
@@ -80,7 +80,11 @@
//= require moment/nb.js
//= require moment/pt-br.js
//= require moment/pt.js
+//= require moment/ru.js
//= require moment/sv.js
+//= require moment/ca.js
+//= require moment/ar.js
+//= require moment/tr.js
// foundation
//= require ../shared/mm-foundation-tpls-0.9.0-20180826174721.min.js
diff --git a/app/assets/javascripts/darkswarm/all.js.coffee b/app/assets/javascripts/darkswarm/all.js.coffee
index 605eeb3b07..51209fadd6 100644
--- a/app/assets/javascripts/darkswarm/all.js.coffee
+++ b/app/assets/javascripts/darkswarm/all.js.coffee
@@ -37,7 +37,11 @@
#= require moment/nb.js
#= require moment/pt-br.js
#= require moment/pt.js
+#= require moment/ru.js
#= require moment/sv.js
+#= require moment/ca.js
+#= require moment/ar.js
+#= require moment/tr.js
#
#= require modernizr
#
diff --git a/app/assets/javascripts/darkswarm/directives/disable_enter_with_blur.js.coffee b/app/assets/javascripts/darkswarm/directives/disable_enter_with_blur.js.coffee
new file mode 100644
index 0000000000..1704d4c0f9
--- /dev/null
+++ b/app/assets/javascripts/darkswarm/directives/disable_enter_with_blur.js.coffee
@@ -0,0 +1,9 @@
+Darkswarm.directive "disableEnterWithBlur", ()->
+ # Stops enter from doing normal enter things, and blurs the input
+ restrict: 'A'
+ link: (scope, element, attrs)->
+ element.bind "keydown keypress", (e)->
+ code = e.keyCode || e.which
+ if code == 13
+ element.blur()
+ e.preventDefault()
diff --git a/app/assets/javascripts/darkswarm/directives/map_search.js.coffee b/app/assets/javascripts/darkswarm/directives/map_search.js.coffee
index 322fa4bb28..bd46a9c80d 100644
--- a/app/assets/javascripts/darkswarm/directives/map_search.js.coffee
+++ b/app/assets/javascripts/darkswarm/directives/map_search.js.coffee
@@ -43,7 +43,7 @@ Darkswarm.directive 'mapSearch', ($timeout, Search) ->
# When the map loads, and we have a search from ?query, perform that search
scope.performUrlSearch = (map) ->
google.maps.event.addListenerOnce map, "idle", =>
- google.maps.event.trigger(scope.input, 'focus');
+ google.maps.event.trigger(scope.input, 'focus',{});
google.maps.event.trigger(scope.input, 'keydown', {keyCode: 13});
# Bias the SearchBox results towards places that are within the bounds of the
diff --git a/app/assets/javascripts/darkswarm/directives/open_street_map.js.coffee b/app/assets/javascripts/darkswarm/directives/open_street_map.js.coffee
index 7dbdc73669..32f0d921b0 100644
--- a/app/assets/javascripts/darkswarm/directives/open_street_map.js.coffee
+++ b/app/assets/javascripts/darkswarm/directives/open_street_map.js.coffee
@@ -1,4 +1,4 @@
-Darkswarm.directive 'ofnOpenStreetMap', ($window, Enterprises, EnterpriseModal, availableCountries, openStreetMapConfig) ->
+Darkswarm.directive 'ofnOpenStreetMap', ($window, MapCentreCalculator, Enterprises, EnterpriseModal, availableCountries, openStreetMapConfig) ->
restrict: 'E'
replace: true
scope: true
@@ -11,34 +11,6 @@ Darkswarm.directive 'ofnOpenStreetMap', ($window, Enterprises, EnterpriseModal,
openStreetMapProviderName = openStreetMapConfig.open_street_map_provider_name
openStreetMapProviderOptions = JSON.parse(openStreetMapConfig.open_street_map_provider_options)
- average = (values) ->
- total = values.reduce (sum, value) ->
- sum = sum + value
- , 0
- total / values.length
-
- averageAngle = (angleName) ->
- positiveAngles = []
- negativeAngles = []
- for enterprise in Enterprises.enterprises
- if enterprise.latitude? && enterprise.longitude?
- if enterprise[angleName] > 0
- positiveAngles.push(enterprise[angleName])
- else
- negativeAngles.push(enterprise[angleName])
-
- averageNegativeAngle = average(negativeAngles)
- averagePositiveAngle = average(positiveAngles)
-
- if negativeAngles.length == 0
- averagePositiveAngle
- else if positiveAngles.length == 0
- averageNegativeAngle
- else if averagePositiveAngle > averageNegativeAngle
- averagePositiveAngle - averageNegativeAngle
- else
- averageNegativeAngle - averagePositiveAngle
-
buildMarker = (enterprise, latlng, title) ->
icon = L.icon
iconUrl: enterprise.icon
@@ -61,28 +33,31 @@ Darkswarm.directive 'ofnOpenStreetMap', ($window, Enterprises, EnterpriseModal,
displayMap = ->
setMapDimensions()
- averageLatitude = averageAngle("latitude")
- averageLongitude = averageAngle("longitude")
zoomLevel = 6
map = L.map('open-street-map')
L.tileLayer.provider(openStreetMapProviderName, openStreetMapProviderOptions).addTo(map)
- map.setView([averageLatitude, averageLongitude], zoomLevel)
+ map.setView([MapCentreCalculator.initialLatitude(), MapCentreCalculator.initialLongitude()], zoomLevel)
displayEnterprises = ->
- for enterprise in Enterprises.enterprises
- if enterprise.latitude? && enterprise.longitude?
- marker = buildMarker(enterprise, { lat: enterprise.latitude, lng: enterprise.longitude }, enterprise.name).addTo(map)
- enterpriseNames.push(enterpriseName(enterprise))
- markers.push(marker)
+ for enterprise in Enterprises.geocodedEnterprises()
+ marker = buildMarker(enterprise, { lat: enterprise.latitude, lng: enterprise.longitude }, enterprise.name).addTo(map)
+ enterpriseNames.push(enterpriseName(enterprise))
+ markers.push(marker)
+
+ disableSearchField = () =>
+ $('#open-street-map--search input').prop("disabled", true)
displaySearchField = () ->
new Autocomplete('#open-street-map--search',
onSubmit: goToEnterprise
search: searchEnterprises
)
- overwriteInlinePositionRelativeToPositionSearchField = ->
- $('#open-street-map--search').css("position", "absolute")
- overwriteInlinePositionRelativeToPositionSearchField()
+ overwriteInlinePositionRelativeToAbsoluteOnSearchField()
+ if Enterprises.geocodedEnterprises().length == 0
+ disableSearchField()
+
+ overwriteInlinePositionRelativeToAbsoluteOnSearchField = ->
+ $('#open-street-map--search').css("position", "absolute")
searchEnterprises = (input) ->
if input.length < 1
diff --git a/app/assets/javascripts/darkswarm/services/checkout.js.coffee b/app/assets/javascripts/darkswarm/services/checkout.js.coffee
index 4ec3081ad3..d74f075ea3 100644
--- a/app/assets/javascripts/darkswarm/services/checkout.js.coffee
+++ b/app/assets/javascripts/darkswarm/services/checkout.js.coffee
@@ -24,7 +24,8 @@ Darkswarm.factory 'Checkout', ($injector, CurrentOrder, ShippingMethods, StripeE
try
@loadFlash(error: t("checkout.failed")) # inform the user about the unexpected error
finally
- throw error # generate a BugsnagJS alert
+ Bugsnag.notify(error)
+ throw error
handle_checkout_error_response: (response) =>
throw response unless response.data?
diff --git a/app/assets/javascripts/darkswarm/services/enterprises.js.coffee b/app/assets/javascripts/darkswarm/services/enterprises.js.coffee
index 843749c2e6..d8347c7e41 100644
--- a/app/assets/javascripts/darkswarm/services/enterprises.js.coffee
+++ b/app/assets/javascripts/darkswarm/services/enterprises.js.coffee
@@ -84,3 +84,8 @@ Darkswarm.factory 'Enterprises', (enterprises, ShopsResource, CurrentHub, Taxons
resetDistance: ->
enterprise.distance = null for enterprise in @enterprises
+
+ geocodedEnterprises: =>
+ @enterprises.filter (enterprise) ->
+ enterprise.latitude? && enterprise.longitude?
+
diff --git a/app/assets/javascripts/darkswarm/services/map.js.coffee b/app/assets/javascripts/darkswarm/services/map.js.coffee
index 2758f299f8..9aa23a7155 100644
--- a/app/assets/javascripts/darkswarm/services/map.js.coffee
+++ b/app/assets/javascripts/darkswarm/services/map.js.coffee
@@ -2,9 +2,7 @@ Darkswarm.factory "OfnMap", (Enterprises, EnterpriseListModal, MapConfiguration)
new class OfnMap
constructor: ->
@coordinates = {}
- @enterprises = Enterprises.enterprises.filter (enterprise) ->
- # Remove enterprises w/o lat or long
- enterprise.latitude != null || enterprise.longitude != null
+ @enterprises = Enterprises.geocodedEnterprises()
@enterprises = @enterprise_markers(@enterprises)
enterprise_markers: (enterprises) ->
diff --git a/app/assets/javascripts/darkswarm/services/map_centre_calculator.js.coffee b/app/assets/javascripts/darkswarm/services/map_centre_calculator.js.coffee
new file mode 100644
index 0000000000..978afb5858
--- /dev/null
+++ b/app/assets/javascripts/darkswarm/services/map_centre_calculator.js.coffee
@@ -0,0 +1,30 @@
+Darkswarm.factory 'MapCentreCalculator', (Enterprises, openStreetMapConfig) ->
+ new class MapCentreCalculator
+
+ initialLatitude: =>
+ if Enterprises.geocodedEnterprises().length > 0
+ @_calculate("latitude", Enterprises.geocodedEnterprises())
+ else
+ openStreetMapConfig.open_street_map_default_latitude
+
+ initialLongitude: =>
+ if Enterprises.geocodedEnterprises().length > 0
+ @_calculate("longitude", Enterprises.geocodedEnterprises())
+ else
+ openStreetMapConfig.open_street_map_default_longitude
+
+ _calculate: (angleName, coordinates) =>
+ angles = []
+
+ for coordinate in coordinates
+ angles.push(coordinate[angleName])
+
+ minimumAngle = Math.min.apply(null, angles)
+ maximumAngle = Math.max.apply(null, angles)
+
+ distanceBetweenMinimumAndMaximum = if maximumAngle > minimumAngle
+ maximumAngle - minimumAngle
+ else
+ minimumAngle - maximumAngle
+
+ minimumAngle + (distanceBetweenMinimumAndMaximum / 2)
diff --git a/app/assets/stylesheets/admin/shared/layout.scss b/app/assets/stylesheets/admin/shared/layout.scss
index 804e32b3a8..71d5fbabed 100644
--- a/app/assets/stylesheets/admin/shared/layout.scss
+++ b/app/assets/stylesheets/admin/shared/layout.scss
@@ -20,9 +20,11 @@
&:first-child {
padding-left: 0;
+ width: 70%;
}
&:last-child {
padding-right: 0;
+ width: 30%;
}
}
}
diff --git a/app/assets/stylesheets/darkswarm/expanding-sidebar.scss b/app/assets/stylesheets/darkswarm/expanding-sidebar.scss
index da1034cf42..8bfcfe824b 100644
--- a/app/assets/stylesheets/darkswarm/expanding-sidebar.scss
+++ b/app/assets/stylesheets/darkswarm/expanding-sidebar.scss
@@ -16,12 +16,14 @@
width: 100%;
background-color: $shop-sidebar-overlay;
opacity: 0;
- transition: opacity $transition-sidebar;
+ visibility: hidden;
+ transition: all $transition-sidebar;
}
&.shown {
.background {
opacity: 1;
+ visibility: visible;
}
.sidebar,
diff --git a/app/assets/stylesheets/darkswarm/home_tagline.scss b/app/assets/stylesheets/darkswarm/home_tagline.scss
index c6cc15c9e8..7ad1ea0241 100644
--- a/app/assets/stylesheets/darkswarm/home_tagline.scss
+++ b/app/assets/stylesheets/darkswarm/home_tagline.scss
@@ -17,10 +17,12 @@
position: fixed;
left: 0;
right: 0;
- bottom: 0;
+ top: 0;
z-index: -1;
width: 100%;
height: 100%;
+ // Use vh units for new browsers - fixed issue 1253
+ height: 100vh;
}
h1 {
diff --git a/app/controllers/api/base_controller.rb b/app/controllers/api/base_controller.rb
index 344dd89174..e9d82d19ad 100644
--- a/app/controllers/api/base_controller.rb
+++ b/app/controllers/api/base_controller.rb
@@ -1,5 +1,6 @@
# Base controller for OFN's API
require_dependency 'spree/api/controller_setup'
+require "spree/core/controller_helpers/ssl"
module Api
class BaseController < ActionController::Metal
@@ -53,7 +54,7 @@ module Api
# Use logged in user (spree_current_user) for API authentication (current_api_user)
def authenticate_user
- return if @current_api_user = try_spree_current_user
+ return if @current_api_user = spree_current_user
if api_key.blank?
# An anonymous user
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 17585a7237..e9cb17480b 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -62,11 +62,15 @@ class ApplicationController < ActionController::Base
end
def after_sign_out_path_for(_resource_or_scope)
- session[:shopfront_redirect] || main_app.root_path
+ shopfront_redirect || main_app.root_path
end
private
+ def shopfront_redirect
+ session[:shopfront_redirect]
+ end
+
def restrict_iframes
response.headers['X-Frame-Options'] = 'DENY'
response.headers['Content-Security-Policy'] = "frame-ancestors 'none'"
diff --git a/app/controllers/base_controller.rb b/app/controllers/base_controller.rb
index 6cf878a077..b039a2447d 100644
--- a/app/controllers/base_controller.rb
+++ b/app/controllers/base_controller.rb
@@ -1,8 +1,10 @@
-require 'spree/core/controller_helpers/respond_with_decorator'
+require 'spree/core/controller_helpers/auth'
+require 'spree/core/controller_helpers/common'
+require 'spree/core/controller_helpers/order'
+require 'spree/core/controller_helpers/respond_with'
require 'open_food_network/tag_rule_applicator'
class BaseController < ApplicationController
- include Spree::Core::ControllerHelpers
include Spree::Core::ControllerHelpers::Auth
include Spree::Core::ControllerHelpers::Common
include Spree::Core::ControllerHelpers::Order
diff --git a/app/controllers/cart_controller.rb b/app/controllers/cart_controller.rb
index 997573899c..1fbf1b2b94 100644
--- a/app/controllers/cart_controller.rb
+++ b/app/controllers/cart_controller.rb
@@ -1,4 +1,4 @@
-require 'spree/core/controller_helpers/order_decorator'
+require 'spree/core/controller_helpers/order'
class CartController < BaseController
before_action :check_authorization
diff --git a/app/controllers/checkout_controller.rb b/app/controllers/checkout_controller.rb
index c83b5e361d..c47b112359 100644
--- a/app/controllers/checkout_controller.rb
+++ b/app/controllers/checkout_controller.rb
@@ -32,20 +32,20 @@ class CheckoutController < Spree::StoreController
helper 'spree/orders'
- rescue_from Spree::Core::GatewayError, with: :rescue_from_spree_gateway_error
-
def edit
return handle_redirect_from_stripe if valid_payment_intent_provided?
# This is only required because of spree_paypal_express. If we implement
# a version of paypal that uses this controller, and more specifically
- # the #update_failed method, then we can remove this call
+ # the #action_failed method, then we can remove this call
OrderCheckoutRestart.new(@order).call
+ rescue Spree::Core::GatewayError => e
+ rescue_from_spree_gateway_error(e)
end
def update
params_adapter = Checkout::FormDataAdapter.new(permitted_params, @order, spree_current_user)
- return update_failed unless @order.update(params_adapter.params[:order])
+ return action_failed unless @order.update(params_adapter.params[:order])
fire_event('spree.checkout.update')
@@ -54,7 +54,7 @@ class CheckoutController < Spree::StoreController
rescue_from_spree_gateway_error(e)
rescue StandardError => e
flash[:error] = I18n.t("checkout.failed")
- update_failed(e)
+ action_failed(e)
end
# Clears the cached order. Required for #current_order to return a new order
@@ -138,14 +138,6 @@ class CheckoutController < Spree::StoreController
current_order.payments.destroy_all if request.put?
end
- def rescue_from_spree_gateway_error(error)
- flash[:error] = t(:spree_gateway_error_flash_for_checkout, error: error.message)
- respond_to do |format|
- format.html { render :edit }
- format.json { render json: { flash: flash.to_hash }, status: :bad_request }
- end
- end
-
def valid_payment_intent_provided?
return false unless params["payment_intent"]&.starts_with?("pi_")
@@ -156,11 +148,10 @@ class CheckoutController < Spree::StoreController
end
def handle_redirect_from_stripe
- if advance_order_state(@order) && order_complete?
+ if OrderWorkflow.new(@order).next && order_complete?
checkout_succeeded
redirect_to(order_path(@order)) && return
else
- flash[:error] = order_error
checkout_failed
end
end
@@ -171,11 +162,9 @@ class CheckoutController < Spree::StoreController
return if redirect_to_payment_gateway
end
- @order.select_shipping_method(shipping_method_id) if @order.state == "delivery"
+ next if OrderWorkflow.new(@order).next({ shipping_method_id: shipping_method_id })
- next if advance_order_state(@order)
-
- return update_failed
+ return action_failed
end
update_response
@@ -190,15 +179,6 @@ class CheckoutController < Spree::StoreController
true
end
- # Perform order.next, guarding against StaleObjectErrors
- def advance_order_state(order)
- tries ||= 3
- order.next
- rescue ActiveRecord::StaleObjectError
- retry unless (tries -= 1).zero?
- false
- end
-
def order_error
if @order.errors.present?
@order.errors.full_messages.to_sentence
@@ -212,7 +192,7 @@ class CheckoutController < Spree::StoreController
checkout_succeeded
update_succeeded_response
else
- update_failed(RuntimeError.new("Order not complete after the checkout workflow"))
+ action_failed(RuntimeError.new("Order not complete after the checkout workflow"))
end
end
@@ -238,30 +218,42 @@ class CheckoutController < Spree::StoreController
end
end
- def update_failed(error = RuntimeError.new(order_error))
- Bugsnag.notify(error)
-
- flash[:error] = order_error if flash.blank?
- checkout_failed
- update_failed_response
+ def action_failed(error = RuntimeError.new(order_error))
+ checkout_failed(error)
+ action_failed_response
end
- def checkout_failed
+ def checkout_failed(error = RuntimeError.new(order_error))
+ Bugsnag.notify(error)
+ flash[:error] = order_error if flash.blank?
Checkout::PostCheckoutActions.new(@order).failure
end
- def update_failed_response
+ def action_failed_response
respond_to do |format|
format.html do
render :edit
end
format.json do
+ discard_flash_errors
render json: { errors: @order.errors, flash: flash.to_hash }.to_json, status: :bad_request
end
end
end
+ def rescue_from_spree_gateway_error(error)
+ flash[:error] = t(:spree_gateway_error_flash_for_checkout, error: error.message)
+ action_failed(error)
+ end
+
def permitted_params
PermittedAttributes::Checkout.new(params).call
end
+
+ def discard_flash_errors
+ # Marks flash errors for deletion after the current action has completed.
+ # This ensures flash errors generated during XHR requests are not persisted in the
+ # session for longer than expected.
+ flash.discard(:error)
+ end
end
diff --git a/app/controllers/enterprises_controller.rb b/app/controllers/enterprises_controller.rb
index 6d640b5d7b..7488fa8c4d 100644
--- a/app/controllers/enterprises_controller.rb
+++ b/app/controllers/enterprises_controller.rb
@@ -68,7 +68,7 @@ class EnterprisesController < BaseController
# reset_distributor must be called before any call to current_customer or current_distributor
order_cart_reset = OrderCartReset.new(order, params[:id])
order_cart_reset.reset_distributor
- order_cart_reset.reset_other!(try_spree_current_user, current_customer)
+ order_cart_reset.reset_other!(spree_current_user, current_customer)
rescue ActiveRecord::RecordNotFound
flash[:error] = I18n.t(:enterprise_shop_show_error)
redirect_to shops_path
diff --git a/app/controllers/home_controller.rb b/app/controllers/home_controller.rb
index c585b63839..c7612d3997 100644
--- a/app/controllers/home_controller.rb
+++ b/app/controllers/home_controller.rb
@@ -16,6 +16,10 @@ class HomeController < BaseController
def sell; end
+ def unauthorized
+ render 'shared/unauthorized', status: :unauthorized
+ end
+
private
# Cache the value of the query count
diff --git a/app/controllers/spree/admin/base_controller.rb b/app/controllers/spree/admin/base_controller.rb
index 7ce02d4a38..4f9cdbb4d0 100644
--- a/app/controllers/spree/admin/base_controller.rb
+++ b/app/controllers/spree/admin/base_controller.rb
@@ -24,7 +24,7 @@ module Spree
# This is in Spree::Core::ControllerHelpers::Auth
# But you can't easily reopen modules in Ruby
def unauthorized
- if try_spree_current_user
+ if spree_current_user
flash[:error] = t(:authorization_failure)
redirect_to '/unauthorized'
else
diff --git a/app/controllers/spree/admin/mail_methods_controller.rb b/app/controllers/spree/admin/mail_methods_controller.rb
index aba6ad239f..70d573f319 100644
--- a/app/controllers/spree/admin/mail_methods_controller.rb
+++ b/app/controllers/spree/admin/mail_methods_controller.rb
@@ -15,7 +15,7 @@ module Spree
end
def testmail
- if TestMailer.test_email(try_spree_current_user).deliver
+ if TestMailer.test_email(spree_current_user).deliver
flash[:success] = Spree.t('admin.mail_methods.testmail.delivery_success')
else
flash[:error] = Spree.t('admin.mail_methods.testmail.delivery_error')
diff --git a/app/controllers/spree/admin/orders/customer_details_controller.rb b/app/controllers/spree/admin/orders/customer_details_controller.rb
index 82c0c2347e..3239ffff01 100644
--- a/app/controllers/spree/admin/orders/customer_details_controller.rb
+++ b/app/controllers/spree/admin/orders/customer_details_controller.rb
@@ -23,7 +23,7 @@ module Spree
@order.associate_user!(Spree.user_class.find_by(email: @order.email))
end
- AdvanceOrderService.new(@order).call
+ OrderWorkflow.new(@order).complete
@order.shipments.map(&:refresh_rates)
flash[:success] = Spree.t('customer_details_updated')
diff --git a/app/controllers/spree/admin/orders_controller.rb b/app/controllers/spree/admin/orders_controller.rb
index 22715108e9..e0b07fbbd9 100644
--- a/app/controllers/spree/admin/orders_controller.rb
+++ b/app/controllers/spree/admin/orders_controller.rb
@@ -27,7 +27,7 @@ module Spree
def new
@order = Order.create
- @order.created_by = try_spree_current_user
+ @order.created_by = spree_current_user
@order.save
redirect_to edit_admin_order_url(@order)
end
@@ -35,7 +35,7 @@ module Spree
def edit
@order.shipments.map(&:refresh_rates)
- AdvanceOrderService.new(@order).call
+ OrderWorkflow.new(@order).complete
# The payment step shows an error of 'No pending payments'
# Clearing the errors from the order object will stop this error
diff --git a/app/controllers/spree/admin/payment_methods_controller.rb b/app/controllers/spree/admin/payment_methods_controller.rb
index 8825e4ea69..950b97340b 100644
--- a/app/controllers/spree/admin/payment_methods_controller.rb
+++ b/app/controllers/spree/admin/payment_methods_controller.rb
@@ -97,7 +97,7 @@ module Spree
:name, :description, :type, :active,
:environment, :display_on, :tag_list,
:preferred_enterprise_id, :preferred_server, :preferred_login, :preferred_password,
- :calculator_type,
+ :calculator_type, :preferred_api_key,
:preferred_signature, :preferred_solution, :preferred_landing_page, :preferred_logourl,
:preferred_test_mode, distributor_ids: []
)
diff --git a/app/controllers/spree/admin/payments_controller.rb b/app/controllers/spree/admin/payments_controller.rb
index 215f69972a..bfdb4fd2ff 100644
--- a/app/controllers/spree/admin/payments_controller.rb
+++ b/app/controllers/spree/admin/payments_controller.rb
@@ -37,7 +37,7 @@ module Spree
redirect_to admin_order_payments_path(@order)
else
- AdvanceOrderService.new(@order).call!
+ OrderWorkflow.new(@order).complete!
flash[:success] = Spree.t(:new_order_completed)
redirect_to edit_admin_order_url(@order)
@@ -61,7 +61,7 @@ module Spree
else
flash[:error] = t(:cannot_perform_operation)
end
- rescue Spree::Core::GatewayError => e
+ rescue StandardError => e
flash[:error] = e.message
ensure
redirect_to request.referer
diff --git a/app/controllers/spree/base_controller.rb b/app/controllers/spree/base_controller.rb
new file mode 100644
index 0000000000..4d20570e20
--- /dev/null
+++ b/app/controllers/spree/base_controller.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+require 'cancan'
+
+module Spree
+ class BaseController < ApplicationController
+ include Spree::Core::ControllerHelpers::Auth
+ include Spree::Core::ControllerHelpers::RespondWith
+ include Spree::Core::ControllerHelpers::SSL
+ include Spree::Core::ControllerHelpers::Common
+
+ respond_to :html
+ end
+end
+
+require 'spree/i18n/initializer'
diff --git a/app/controllers/spree/home_controller.rb b/app/controllers/spree/home_controller.rb
deleted file mode 100644
index 9fbdabe940..0000000000
--- a/app/controllers/spree/home_controller.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-module Spree
- class HomeController < Spree::StoreController
- respond_to :html
-
- def index; end
- end
-end
diff --git a/app/controllers/spree/orders_controller.rb b/app/controllers/spree/orders_controller.rb
index 545ae1ce60..898ec93f99 100644
--- a/app/controllers/spree/orders_controller.rb
+++ b/app/controllers/spree/orders_controller.rb
@@ -1,5 +1,5 @@
-require 'spree/core/controller_helpers/order_decorator'
-require 'spree/core/controller_helpers/auth_decorator'
+require 'spree/core/controller_helpers/order'
+require 'spree/core/controller_helpers/auth'
module Spree
class OrdersController < Spree::StoreController
@@ -194,7 +194,7 @@ module Spree
return if session[:access_token] || params[:token] || spree_current_user
flash[:error] = I18n.t("spree.orders.edit.login_to_view_order")
- require_login_then_redirect_to request.env['PATH_INFO']
+ redirect_to main_app.root_path(anchor: "login?after_login=#{request.env['PATH_INFO']}")
end
def order_to_update
diff --git a/app/controllers/spree/store_controller.rb b/app/controllers/spree/store_controller.rb
index cc4dd9d537..5486912bd3 100644
--- a/app/controllers/spree/store_controller.rb
+++ b/app/controllers/spree/store_controller.rb
@@ -6,9 +6,5 @@ module Spree
include I18nHelper
before_action :set_locale
-
- def unauthorized
- render 'shared/unauthorized', status: :unauthorized
- end
end
end
diff --git a/app/controllers/spree/user_passwords_controller.rb b/app/controllers/spree/user_passwords_controller.rb
index bf8b13d379..4e7fc6e824 100644
--- a/app/controllers/spree/user_passwords_controller.rb
+++ b/app/controllers/spree/user_passwords_controller.rb
@@ -1,3 +1,10 @@
+# frozen_string_literal: true
+
+require "spree/core/controller_helpers/auth"
+require "spree/core/controller_helpers/common"
+require "spree/core/controller_helpers/order"
+require "spree/core/controller_helpers/ssl"
+
module Spree
class UserPasswordsController < Devise::PasswordsController
helper 'spree/base', 'spree/store'
diff --git a/app/controllers/spree/user_registrations_controller.rb b/app/controllers/spree/user_registrations_controller.rb
index a55d327ae2..1a2d740da7 100644
--- a/app/controllers/spree/user_registrations_controller.rb
+++ b/app/controllers/spree/user_registrations_controller.rb
@@ -1,3 +1,10 @@
+# frozen_string_literal: true
+
+require "spree/core/controller_helpers/auth"
+require "spree/core/controller_helpers/common"
+require "spree/core/controller_helpers/order"
+require "spree/core/controller_helpers/ssl"
+
module Spree
class UserRegistrationsController < Devise::RegistrationsController
helper 'spree/base', 'spree/store'
@@ -23,7 +30,6 @@ module Spree
if resource.save
set_flash_message(:notice, :signed_up)
sign_in(:spree_user, @user)
- session[:spree_user_signup] = true
associate_user
respond_with resource, location: after_sign_up_path_for(resource)
else
diff --git a/app/controllers/spree/user_sessions_controller.rb b/app/controllers/spree/user_sessions_controller.rb
index df42f622e1..c17eafb892 100644
--- a/app/controllers/spree/user_sessions_controller.rb
+++ b/app/controllers/spree/user_sessions_controller.rb
@@ -1,3 +1,10 @@
+# frozen_string_literal: true
+
+require "spree/core/controller_helpers/auth"
+require "spree/core/controller_helpers/common"
+require "spree/core/controller_helpers/order"
+require "spree/core/controller_helpers/ssl"
+
module Spree
class UserSessionsController < Devise::SessionsController
helper 'spree/base', 'spree/store'
@@ -39,8 +46,18 @@ module Spree
end
end
+ def destroy
+ # Logout will clear session data including shopfront_redirect
+ # Here we store it before actually logging out so that the redirect works correctly
+ @shopfront_redirect = session[:shopfront_redirect]
+
+ super
+ end
+
private
+ attr_reader :shopfront_redirect
+
def accurate_title
Spree.t(:login)
end
diff --git a/app/controllers/spree/users_controller.rb b/app/controllers/spree/users_controller.rb
index f524f8d465..c6ce064b57 100644
--- a/app/controllers/spree/users_controller.rb
+++ b/app/controllers/spree/users_controller.rb
@@ -59,7 +59,7 @@ module Spree
if @user
authorize! params[:action].to_sym, @user
else
- redirect_to spree.login_path
+ redirect_to main_app.login_path
end
end
diff --git a/app/controllers/user_confirmations_controller.rb b/app/controllers/user_confirmations_controller.rb
index 1e15a6a296..0915447bc5 100644
--- a/app/controllers/user_confirmations_controller.rb
+++ b/app/controllers/user_confirmations_controller.rb
@@ -44,9 +44,10 @@ class UserConfirmationsController < DeviseController
'not_confirmed'
end
- if resource.reset_password_token.present?
+ if result == 'confirmed' && resource.reset_password_token.present?
+ raw_reset_password_token = resource.regenerate_reset_password_token
return spree.edit_spree_user_password_path(
- reset_password_token: resource.reset_password_token
+ reset_password_token: raw_reset_password_token
)
end
diff --git a/app/controllers/user_passwords_controller.rb b/app/controllers/user_passwords_controller.rb
index e467e915e2..9200b9b6ef 100644
--- a/app/controllers/user_passwords_controller.rb
+++ b/app/controllers/user_passwords_controller.rb
@@ -10,7 +10,7 @@ class UserPasswordsController < Spree::UserPasswordsController
if resource.errors.empty?
set_flash_message(:success, :send_instructions) if is_navigational_format?
- respond_with resource, location: spree.login_path
+ respond_with resource, location: main_app.login_path
else
respond_to do |format|
format.html do
diff --git a/app/controllers/user_registrations_controller.rb b/app/controllers/user_registrations_controller.rb
index d6fdf5ac76..f02309bf71 100644
--- a/app/controllers/user_registrations_controller.rb
+++ b/app/controllers/user_registrations_controller.rb
@@ -16,7 +16,6 @@ class UserRegistrationsController < Spree::UserRegistrationsController
return render_error(@user.errors)
end
- session[:spree_user_signup] = true
session[:confirmation_return_url] = params[:return_url]
associate_user
diff --git a/app/jobs/subscription_confirm_job.rb b/app/jobs/subscription_confirm_job.rb
index 9ed8223d0e..acf241e4e0 100644
--- a/app/jobs/subscription_confirm_job.rb
+++ b/app/jobs/subscription_confirm_job.rb
@@ -45,27 +45,33 @@ class SubscriptionConfirmJob
def confirm_order!(order)
record_order(order)
- if process_payment!(order)
- send_confirmation_email(order)
- else
+ process_payment!(order)
+ send_confirmation_email(order)
+ rescue StandardError => e
+ if order.errors.any?
send_failed_payment_email(order)
+ else
+ Bugsnag.notify(e, order: order)
+ send_failed_payment_email(order, e.message)
end
end
+ # Process the order payment and raise if it's not successful
def process_payment!(order)
- return false if order.errors.present?
- return true unless order.payment_required?
+ raise if order.errors.present?
+ return unless order.payment_required?
+ prepare_for_payment!(order)
+ order.process_payments!
+ raise if order.errors.any?
+ end
+
+ def prepare_for_payment!(order)
setup_payment!(order)
- return false if order.errors.any?
+ raise if order.errors.any?
authorize_payment!(order)
- return false if order.errors.any?
-
- order.process_payments!
- return false if order.errors.any?
-
- true
+ raise if order.errors.any?
end
def setup_payment!(order)
@@ -87,9 +93,11 @@ class SubscriptionConfirmJob
SubscriptionMailer.confirmation_email(order).deliver
end
- def send_failed_payment_email(order)
+ def send_failed_payment_email(order, error_message = nil)
order.update!
- record_and_log_error(:failed_payment, order)
+ record_and_log_error(:failed_payment, order, error_message)
SubscriptionMailer.failed_payment_email(order).deliver
+ rescue StandardError => e
+ Bugsnag.notify(e, order: order, error_message: error_message)
end
end
diff --git a/app/jobs/subscription_placement_job.rb b/app/jobs/subscription_placement_job.rb
index 8b5df2b159..b15947895b 100644
--- a/app/jobs/subscription_placement_job.rb
+++ b/app/jobs/subscription_placement_job.rb
@@ -29,10 +29,16 @@ class SubscriptionPlacementJob
def place_order_for(proxy_order)
JobLogger.logger.info("Placing Order for Proxy Order #{proxy_order.id}")
- proxy_order.initialise_order!
+ initialise_order(proxy_order)
place_order(proxy_order.order)
end
+ def initialise_order(proxy_order)
+ proxy_order.initialise_order!
+ rescue StandardError => e
+ Bugsnag.notify(e, subscription: proxy_order.subscription, proxy_order: proxy_order)
+ end
+
def place_order(order)
record_order(order)
return record_issue(:complete, order) if order.completed?
@@ -42,8 +48,9 @@ class SubscriptionPlacementJob
move_to_completion(order)
send_placement_email(order, changes)
- rescue StateMachine::InvalidTransition
- record_and_log_error(:processing, order)
+ rescue StandardError => e
+ record_and_log_error(:processing, order, e.message)
+ Bugsnag.notify(e, order: order)
end
def cap_quantity_and_store_changes(order)
@@ -66,7 +73,7 @@ class SubscriptionPlacementJob
end
def move_to_completion(order)
- AdvanceOrderService.new(order).call!
+ OrderWorkflow.new(order).complete!
end
def unavailable_stock_lines_for(order)
diff --git a/app/mailers/spree/base_mailer.rb b/app/mailers/spree/base_mailer.rb
new file mode 100644
index 0000000000..fb46bf54bc
--- /dev/null
+++ b/app/mailers/spree/base_mailer.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+module Spree
+ class BaseMailer < ActionMailer::Base
+ # Inline stylesheets
+ include Roadie::Rails::Automatic
+
+ layout 'mailer'
+
+ def from_address
+ Spree::Config[:mails_from]
+ end
+
+ def money(amount)
+ Spree::Money.new(amount).to_s
+ end
+ helper_method :money
+
+ protected
+
+ def roadie_options
+ # This lets us specify assets using relative paths in email templates
+ super.merge(url_options: { host: URI(main_app.root_url).host })
+ end
+ end
+end
diff --git a/app/mailers/spree/base_mailer_decorator.rb b/app/mailers/spree/base_mailer_decorator.rb
deleted file mode 100644
index 4c15268676..0000000000
--- a/app/mailers/spree/base_mailer_decorator.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-Spree::BaseMailer.class_eval do
- # Inline stylesheets
- include Roadie::Rails::Automatic
-
- # Define layout
- layout 'mailer'
-
- protected
-
- def roadie_options
- # This lets us specify assets using relative paths in email templates
- super.merge(url_options: { host: URI(main_app.root_url).host })
- end
-end
diff --git a/app/mailers/spree/order_mailer.rb b/app/mailers/spree/order_mailer.rb
new file mode 100644
index 0000000000..ce9b79874e
--- /dev/null
+++ b/app/mailers/spree/order_mailer.rb
@@ -0,0 +1,68 @@
+# frozen_string_literal: true
+
+module Spree
+ class OrderMailer < BaseMailer
+ helper HtmlHelper
+ helper ::CheckoutHelper
+ helper SpreeCurrencyHelper
+ helper OrderHelper
+ include I18nHelper
+
+ def cancel_email(order_or_order_id, resend = false)
+ @order = find_order(order_or_order_id)
+ I18n.with_locale valid_locale(@order.user) do
+ mail(to: @order.email,
+ from: from_address,
+ subject: mail_subject(t('spree.order_mailer.cancel_email.subject'), resend))
+ end
+ end
+
+ def confirm_email_for_customer(order_or_order_id, resend = false)
+ @order = find_order(order_or_order_id)
+ I18n.with_locale valid_locale(@order.user) do
+ subject = mail_subject(t('spree.order_mailer.confirm_email.subject'), resend)
+ mail(to: @order.email,
+ from: from_address,
+ subject: subject,
+ reply_to: @order.distributor.contact.email)
+ end
+ end
+
+ def confirm_email_for_shop(order_or_order_id, resend = false)
+ @order = find_order(order_or_order_id)
+ I18n.with_locale valid_locale(@order.user) do
+ subject = mail_subject(t('spree.order_mailer.confirm_email.subject'), resend)
+ mail(to: @order.distributor.contact.email,
+ from: from_address,
+ subject: subject)
+ end
+ end
+
+ def invoice_email(order_or_order_id, pdf)
+ @order = find_order(order_or_order_id)
+ attach_file("invoice-#{@order.number}.pdf", pdf)
+ I18n.with_locale valid_locale(@order.user) do
+ mail(to: @order.email,
+ from: from_address,
+ subject: mail_subject(t(:invoice), false),
+ reply_to: @order.distributor.contact.email)
+ end
+ end
+
+ private
+
+ # Finds an order instance from an order or from an order id
+ def find_order(order_or_order_id)
+ order_or_order_id.respond_to?(:id) ? order_or_order_id : Spree::Order.find(order_or_order_id)
+ end
+
+ def mail_subject(base_subject, resend)
+ resend_prefix = (resend ? "[#{t(:resend).upcase}] " : '')
+ "#{resend_prefix}#{Spree::Config[:site_name]} #{base_subject} ##{@order.number}"
+ end
+
+ def attach_file(filename, file)
+ attachments[filename] = file if file.present?
+ end
+ end
+end
diff --git a/app/mailers/spree/order_mailer_decorator.rb b/app/mailers/spree/order_mailer_decorator.rb
deleted file mode 100644
index fbf17013b8..0000000000
--- a/app/mailers/spree/order_mailer_decorator.rb
+++ /dev/null
@@ -1,64 +0,0 @@
-Spree::OrderMailer.class_eval do
- helper HtmlHelper
- helper CheckoutHelper
- helper SpreeCurrencyHelper
- helper OrderHelper
- include I18nHelper
-
- def cancel_email(order_or_order_id, resend = false)
- @order = find_order(order_or_order_id)
- I18n.with_locale valid_locale(@order.user) do
- mail(to: @order.email,
- from: from_address,
- subject: mail_subject(t('spree.order_mailer.cancel_email.subject'), resend))
- end
- end
-
- def confirm_email_for_customer(order_or_order_id, resend = false)
- @order = find_order(order_or_order_id)
- I18n.with_locale valid_locale(@order.user) do
- subject = mail_subject(t('spree.order_mailer.confirm_email.subject'), resend)
- mail(to: @order.email,
- from: from_address,
- subject: subject,
- reply_to: @order.distributor.contact.email)
- end
- end
-
- def confirm_email_for_shop(order_or_order_id, resend = false)
- @order = find_order(order_or_order_id)
- I18n.with_locale valid_locale(@order.user) do
- subject = mail_subject(t('spree.order_mailer.confirm_email.subject'), resend)
- mail(to: @order.distributor.contact.email,
- from: from_address,
- subject: subject)
- end
- end
-
- def invoice_email(order_or_order_id, pdf)
- @order = find_order(order_or_order_id)
- attach_file("invoice-#{@order.number}.pdf", pdf)
- I18n.with_locale valid_locale(@order.user) do
- mail(to: @order.email,
- from: from_address,
- subject: mail_subject(t(:invoice), false),
- reply_to: @order.distributor.contact.email)
- end
- end
-
- private
-
- # Finds an order instance from an order or from an order id
- def find_order(order_or_order_id)
- order_or_order_id.respond_to?(:id) ? order_or_order_id : Spree::Order.find(order_or_order_id)
- end
-
- def mail_subject(base_subject, resend)
- resend_prefix = (resend ? "[#{t(:resend).upcase}] " : '')
- "#{resend_prefix}#{Spree::Config[:site_name]} #{base_subject} ##{@order.number}"
- end
-
- def attach_file(filename, file)
- attachments[filename] = file if file.present?
- end
-end
diff --git a/app/mailers/spree/shipment_mailer.rb b/app/mailers/spree/shipment_mailer.rb
new file mode 100644
index 0000000000..3b25885f81
--- /dev/null
+++ b/app/mailers/spree/shipment_mailer.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Spree
+ class ShipmentMailer < BaseMailer
+ def shipped_email(shipment, resend = false)
+ @shipment = shipment.respond_to?(:id) ? shipment : Spree::Shipment.find(shipment)
+ subject = (resend ? "[#{Spree.t(:resend).upcase}] " : '')
+ base_subject = t('spree.shipment_mailer.shipped_email.subject')
+ subject += "#{Spree::Config[:site_name]} #{base_subject} ##{@shipment.order.number}"
+ mail(to: @shipment.order.email, from: from_address, subject: subject)
+ end
+ end
+end
diff --git a/app/mailers/spree/test_mailer.rb b/app/mailers/spree/test_mailer.rb
new file mode 100644
index 0000000000..316de40341
--- /dev/null
+++ b/app/mailers/spree/test_mailer.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+module Spree
+ class TestMailer < BaseMailer
+ def test_email(user)
+ recipient = user.respond_to?(:id) ? user : Spree.user_class.find(user)
+ subject = "#{Spree::Config[:site_name]} #{t('spree.test_mailer.test_email.subject')}"
+ mail(to: recipient.email, from: from_address, subject: subject)
+ end
+ end
+end
diff --git a/app/mailers/spree/user_mailer.rb b/app/mailers/spree/user_mailer.rb
index ba25809b5d..a93aff05a5 100644
--- a/app/mailers/spree/user_mailer.rb
+++ b/app/mailers/spree/user_mailer.rb
@@ -5,12 +5,11 @@ module Spree
include I18nHelper
# Overrides `Devise::Mailer.reset_password_instructions`
- def reset_password_instructions(user)
- recipient = user.respond_to?(:id) ? user : Spree.user_class.find(user)
+ def reset_password_instructions(user, token, _opts = {})
@edit_password_reset_url = spree.
- edit_spree_user_password_url(reset_password_token: recipient.reset_password_token)
+ edit_spree_user_password_url(reset_password_token: token)
- mail(to: recipient.email, from: from_address,
+ mail(to: user.email, from: from_address,
subject: Spree::Config[:site_name] + ' ' +
I18n.t(:subject, scope: [:devise, :mailer, :reset_password_instructions]))
end
@@ -25,8 +24,9 @@ module Spree
end
# Overrides `Devise::Mailer.confirmation_instructions`
- def confirmation_instructions(user, _opts)
+ def confirmation_instructions(user, token, _opts = {})
@user = user
+ @token = token
@instance = Spree::Config[:site_name]
@contact = ContentConfig.footer_email
diff --git a/app/models/content_configuration.rb b/app/models/content_configuration.rb
index 39d4fd9a5c..efe91e05b6 100644
--- a/app/models/content_configuration.rb
+++ b/app/models/content_configuration.rb
@@ -21,6 +21,8 @@ class ContentConfiguration < Spree::Preferences::FileConfiguration
preference :open_street_map_enabled, :boolean, default: false
preference :open_street_map_provider_name, :string, default: "OpenStreetMap.Mapnik"
preference :open_street_map_provider_options, :text, default: "{}"
+ preference :open_street_map_default_latitude, :string, default: "-37.4713077"
+ preference :open_street_map_default_longitude, :string, default: "144.7851531"
# Producer sign-up page
# All the following defaults using I18n don't work.
diff --git a/app/models/order_updater.rb b/app/models/order_updater.rb
deleted file mode 100644
index 20fa94e5b4..0000000000
--- a/app/models/order_updater.rb
+++ /dev/null
@@ -1,92 +0,0 @@
-require 'delegate'
-
-class OrderUpdater < SimpleDelegator
- # TODO: This logic adapted from Spree 2.4, remove when we get there
- # Handles state updating in a much more logical way than < 2.4
- # Specifically, doesn't depend on payments.last to determine payment state
- # Also swapped: == 0 for .zero?, .size == 0 for empty? and .size > 0 for !empty?
- # See:
- # https://github.com/spree/spree/commit/38b8456183d11fc1e00e395e7c9154c76ef65b85
- # https://github.com/spree/spree/commit/7b264acff7824f5b3dc6651c106631d8f30b147a
- def update_payment_state
- last_payment_state = order.payment_state
-
- order.payment_state = infer_payment_state
- track_payment_state_change(last_payment_state)
-
- order.payment_state
- end
-
- def before_save_hook
- shipping_address_from_distributor
- end
-
- # Sets the distributor's address as shipping address of the order for those
- # shipments using a shipping method that doesn't require address, such us
- # a pickup.
- def shipping_address_from_distributor
- return if order.shipping_method.blank? || order.shipping_method.require_ship_address
-
- order.ship_address = order.address_from_distributor
- end
-
- private
-
- def infer_payment_state
- if failed_payments?
- 'failed'
- elsif canceled_and_not_paid_for?
- 'void'
- else
- infer_payment_state_from_balance
- end
- end
-
- def infer_payment_state_from_balance
- # This part added so that we don't need to override
- # order.outstanding_balance
- balance = order.outstanding_balance
- balance = -1 * order.payment_total if canceled_and_paid_for?
-
- infer_state(balance)
- end
-
- def infer_state(balance)
- if balance > 0
- 'balance_due'
- elsif balance < 0
- 'credit_owed'
- elsif balance.zero?
- 'paid'
- end
- end
-
- # Tracks the state transition through a state_change for this order. It
- # does so until the last state is reached. That is, when the infered next
- # state is the same as the order has now.
- #
- # @param last_payment_state [String]
- def track_payment_state_change(last_payment_state)
- return if last_payment_state == order.payment_state
-
- order.state_changed('payment')
- end
-
- # Taken from order.outstanding_balance in Spree 2.4
- # See: https://github.com/spree/spree/commit/7b264acff7824f5b3dc6651c106631d8f30b147a
- def canceled_and_paid_for?
- order.canceled? && paid?
- end
-
- def canceled_and_not_paid_for?
- order.state == 'canceled' && order.payment_total.zero?
- end
-
- def paid?
- payments.present? && !payments.completed.empty?
- end
-
- def failed_payments?
- payments.present? && payments.valid.empty?
- end
-end
diff --git a/app/models/preference_sections/map_section.rb b/app/models/preference_sections/map_section.rb
index cc16939c36..deed329b44 100644
--- a/app/models/preference_sections/map_section.rb
+++ b/app/models/preference_sections/map_section.rb
@@ -10,7 +10,9 @@ module PreferenceSections
[
:open_street_map_enabled,
:open_street_map_provider_name,
- :open_street_map_provider_options
+ :open_street_map_provider_options,
+ :open_street_map_default_latitude,
+ :open_street_map_default_longitude
]
end
end
diff --git a/app/models/spree/credit_card.rb b/app/models/spree/credit_card.rb
new file mode 100644
index 0000000000..948dcf829d
--- /dev/null
+++ b/app/models/spree/credit_card.rb
@@ -0,0 +1,155 @@
+# frozen_string_literal: true
+
+module Spree
+ class CreditCard < ActiveRecord::Base
+ belongs_to :payment_method
+ belongs_to :user
+
+ has_many :payments, as: :source
+
+ before_save :set_last_digits
+
+ attr_accessor :verification_value
+ attr_reader :number
+ attr_writer :save_requested_by_customer # For holding customer preference in memory
+
+ validates :month, :year, numericality: { only_integer: true }
+ validates :number, presence: true, unless: :has_payment_profile?, on: :create
+ validates :verification_value, presence: true, unless: :has_payment_profile?, on: :create
+ validate :expiry_not_in_the_past
+
+ after_create :ensure_single_default_card
+ after_save :ensure_single_default_card, if: :default_card_needs_updating?
+
+ scope :with_payment_profile, -> { where('gateway_customer_profile_id IS NOT NULL') }
+
+ # needed for some of the ActiveMerchant gateways (eg. SagePay)
+ alias_attribute :brand, :cc_type
+
+ def expiry=(expiry)
+ self[:month], self[:year] = expiry.split(" / ")
+ self[:year] = "20" + self[:year]
+ end
+
+ def number=(num)
+ @number = begin
+ num.gsub(/[^0-9]/, '')
+ rescue StandardError
+ nil
+ end
+ end
+
+ # cc_type is set by jquery.payment, which helpfully provides different
+ # types from Active Merchant. Converting them is necessary.
+ def cc_type=(type)
+ real_type = case type
+ when 'mastercard', 'maestro'
+ 'master'
+ when 'amex'
+ 'american_express'
+ when 'dinersclub'
+ 'diners_club'
+ else
+ type
+ end
+ self[:cc_type] = real_type
+ end
+
+ def set_last_digits
+ number.to_s.gsub!(/\s/, '')
+ verification_value.to_s.gsub!(/\s/, '')
+ self.last_digits ||= number.to_s.length <= 4 ? number : number.to_s.slice(-4..-1)
+ end
+
+ def name?
+ first_name? && last_name?
+ end
+
+ def name
+ "#{first_name} #{last_name}"
+ end
+
+ def verification_value?
+ verification_value.present?
+ end
+
+ # Show the card number, with all but last 4 numbers replace with "X". (XXXX-XXXX-XXXX-4338)
+ def display_number
+ "XXXX-XXXX-XXXX-#{last_digits}"
+ end
+
+ def actions
+ %w{capture void credit}
+ end
+
+ # Indicates whether its possible to capture the payment
+ def can_capture?(payment)
+ payment.pending? || payment.checkout?
+ end
+
+ # Indicates whether its possible to void the payment.
+ def can_void?(payment)
+ !payment.void?
+ end
+
+ # Indicates whether its possible to credit the payment. Note that most gateways require that the
+ # payment be settled first which generally happens within 12-24 hours of the transaction.
+ def can_credit?(payment)
+ return false unless payment.completed?
+ return false unless payment.order.payment_state == 'credit_owed'
+
+ payment.credit_allowed.positive?
+ end
+
+ # Allows us to use a gateway_payment_profile_id to store Stripe Tokens
+ def has_payment_profile?
+ gateway_customer_profile_id.present? || gateway_payment_profile_id.present?
+ end
+
+ def to_active_merchant
+ ActiveMerchant::Billing::CreditCard.new(
+ number: number,
+ month: month,
+ year: year,
+ verification_value: verification_value,
+ first_name: first_name,
+ last_name: last_name
+ )
+ end
+
+ def save_requested_by_customer?
+ !!@save_requested_by_customer
+ end
+
+ private
+
+ def expiry_not_in_the_past
+ return unless year.present? && month.present?
+
+ time = "#{year}-#{month}-1".to_time
+ return unless time < Time.zone.now.to_time.beginning_of_month
+
+ errors.add(:base, :card_expired)
+ end
+
+ def reusable?
+ gateway_customer_profile_id.present?
+ end
+
+ def default_missing?
+ !user.credit_cards.exists?(is_default: true)
+ end
+
+ def default_card_needs_updating?
+ is_default_changed? || gateway_customer_profile_id_changed?
+ end
+
+ def ensure_single_default_card
+ return unless user
+ return unless is_default? || (reusable? && default_missing?)
+
+ user.credit_cards.update_all(['is_default=(id=?)', id])
+ self.is_default = true
+ end
+ end
+end
diff --git a/app/models/spree/credit_card_decorator.rb b/app/models/spree/credit_card_decorator.rb
deleted file mode 100644
index b8c78f01b7..0000000000
--- a/app/models/spree/credit_card_decorator.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-Spree::CreditCard.class_eval do
- # For holding customer preference in memory
- attr_writer :save_requested_by_customer
-
- # Should be able to remove once we reach Spree v2.2.0
- # https://github.com/spree/spree/commit/411010f3975c919ab298cb63962ee492455b415c
- belongs_to :payment_method
-
- belongs_to :user
-
- after_create :ensure_single_default_card
- after_save :ensure_single_default_card, if: :default_card_needs_updating?
-
- # Allows us to use a gateway_payment_profile_id to store Stripe Tokens
- # Should be able to remove once we reach Spree v2.2.0
- # Commit: https://github.com/spree/spree/commit/5a4d690ebc64b264bf12904a70187e7a8735ef3f
- # See also: https://github.com/spree/spree_gateway/issues/111
- def has_payment_profile? # rubocop:disable Naming/PredicateName
- gateway_customer_profile_id.present? || gateway_payment_profile_id.present?
- end
-
- def save_requested_by_customer?
- !!@save_requested_by_customer
- end
-
- private
-
- def reusable?
- gateway_customer_profile_id.present?
- end
-
- def default_missing?
- !user.credit_cards.exists?(is_default: true)
- end
-
- def default_card_needs_updating?
- is_default_changed? || gateway_customer_profile_id_changed?
- end
-
- def ensure_single_default_card
- return unless user
- return unless is_default? || (reusable? && default_missing?)
-
- user.credit_cards.update_all(['is_default=(id=?)', id])
- self.is_default = true
- end
-end
diff --git a/app/models/spree/gateway.rb b/app/models/spree/gateway.rb
new file mode 100644
index 0000000000..216f0cfe6b
--- /dev/null
+++ b/app/models/spree/gateway.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+require 'spree/concerns/payment_method_distributors'
+
+module Spree
+ class Gateway < PaymentMethod
+ include Spree::PaymentMethodDistributors
+
+ delegate_belongs_to :provider, :authorize, :purchase, :capture, :void, :credit
+
+ validates :name, :type, presence: true
+
+ # Default to live
+ preference :server, :string, default: 'live'
+ preference :test_mode, :boolean, default: false
+
+ def payment_source_class
+ CreditCard
+ end
+
+ # instantiates the selected gateway and configures with the options stored in the database
+ def self.current
+ super
+ end
+
+ def provider
+ gateway_options = options
+ gateway_options.delete :login if gateway_options.key?(:login) && gateway_options[:login].nil?
+ if gateway_options[:server]
+ ActiveMerchant::Billing::Base.gateway_mode = gateway_options[:server].to_sym
+ end
+ @provider ||= provider_class.new(gateway_options)
+ end
+
+ def options
+ preferences.each_with_object({}){ |(key, value), memo| memo[key.to_sym] = value; }
+ end
+
+ def method_missing(method, *args)
+ if @provider.nil? || !@provider.respond_to?(method)
+ super
+ else
+ provider.__send__(method, *args)
+ end
+ end
+
+ def payment_profiles_supported?
+ false
+ end
+
+ def method_type
+ 'gateway'
+ end
+
+ def supports?(source)
+ return true unless provider_class.respond_to? :supports?
+ return false unless source.brand
+
+ provider_class.supports?(source.brand)
+ end
+ end
+end
diff --git a/app/models/spree/gateway/bogus.rb b/app/models/spree/gateway/bogus.rb
new file mode 100644
index 0000000000..76dde5f211
--- /dev/null
+++ b/app/models/spree/gateway/bogus.rb
@@ -0,0 +1,102 @@
+# frozen_string_literal: true
+
+module Spree
+ class Gateway
+ class Bogus < Spree::Gateway
+ TEST_VISA = ['4111111111111111', '4012888888881881', '4222222222222'].freeze
+ TEST_MC = ['5500000000000004', '5555555555554444', '5105105105105100'].freeze
+ TEST_AMEX = ['378282246310005', '371449635398431',
+ '378734493671000', '340000000000009'].freeze
+ TEST_DISC = ['6011000000000004', '6011111111111117', '6011000990139424'].freeze
+
+ VALID_CCS = ['1', TEST_VISA, TEST_MC, TEST_AMEX, TEST_DISC].flatten
+
+ attr_accessor :test
+
+ def provider_class
+ self.class
+ end
+
+ def preferences
+ {}
+ end
+
+ def create_profile(payment)
+ # simulate the storage of credit card profile using remote service
+ success = VALID_CCS.include? payment.source.number
+ payment.source.update(gateway_customer_profile_id: generate_profile_id(success))
+ end
+
+ def authorize(_money, credit_card, _options = {})
+ profile_id = credit_card.gateway_customer_profile_id
+ if VALID_CCS.include?(credit_card.number) || profile_id&.starts_with?('BGS-')
+ ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {},
+ test: true, authorization: '12345',
+ avs_result: { code: 'A' })
+ else
+ ActiveMerchant::Billing::Response.new(false, 'Bogus Gateway: Forced failure',
+ { message: 'Bogus Gateway: Forced failure' },
+ test: true)
+ end
+ end
+
+ def purchase(_money, credit_card, _options = {})
+ profile_id = credit_card.gateway_customer_profile_id
+ if VALID_CCS.include?(credit_card.number) || profile_id&.starts_with?('BGS-')
+ ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {},
+ test: true, authorization: '12345',
+ avs_result: { code: 'A' })
+ else
+ ActiveMerchant::Billing::Response.new(false, 'Bogus Gateway: Forced failure',
+ message: 'Bogus Gateway: Forced failure',
+ test: true)
+ end
+ end
+
+ def credit(_money, _credit_card, _response_code, _options = {})
+ ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {},
+ test: true, authorization: '12345')
+ end
+
+ def capture(authorization, _credit_card, _gateway_options)
+ if authorization.response_code == '12345'
+ ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {},
+ test: true, authorization: '67890')
+ else
+ ActiveMerchant::Billing::Response.new(false, 'Bogus Gateway: Forced failure',
+ error: 'Bogus Gateway: Forced failure', test: true)
+ end
+ end
+
+ def void(_response_code, _credit_card, _options = {})
+ ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {},
+ test: true, authorization: '12345')
+ end
+
+ def test?
+ # Test mode is not really relevant with bogus gateway (no such thing as live server)
+ true
+ end
+
+ def payment_profiles_supported?
+ true
+ end
+
+ def actions
+ %w(capture void credit)
+ end
+
+ private
+
+ def generate_profile_id(success)
+ record = true
+ prefix = success ? 'BGS' : 'FAIL'
+ while record
+ random = "#{prefix}-#{Array.new(6){ rand(6) }.join}"
+ record = CreditCard.find_by(gateway_customer_profile_id: random)
+ end
+ random
+ end
+ end
+ end
+end
diff --git a/app/models/spree/gateway/bogus_simple.rb b/app/models/spree/gateway/bogus_simple.rb
new file mode 100644
index 0000000000..2a7c9e7778
--- /dev/null
+++ b/app/models/spree/gateway/bogus_simple.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+# Bogus Gateway that doesn't support payment profiles
+module Spree
+ class Gateway
+ class BogusSimple < Spree::Gateway::Bogus
+ def payment_profiles_supported?
+ false
+ end
+
+ def authorize(_money, credit_card, _options = {})
+ if VALID_CCS.include? credit_card.number
+ ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {},
+ test: true, authorization: '12345',
+ avs_result: { code: 'A' })
+ else
+ ActiveMerchant::Billing::Response.new(false, 'Bogus Gateway: Forced failure',
+ { message: 'Bogus Gateway: Forced failure' },
+ test: true)
+ end
+ end
+
+ def purchase(_money, credit_card, _options = {})
+ if VALID_CCS.include? credit_card.number
+ ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {},
+ test: true, authorization: '12345',
+ avs_result: { code: 'A' })
+ else
+ ActiveMerchant::Billing::Response.new(false, 'Bogus Gateway: Forced failure',
+ message: 'Bogus Gateway: Forced failure',
+ test: true)
+ end
+ end
+ end
+ end
+end
diff --git a/app/models/spree/gateway_decorator.rb b/app/models/spree/gateway_decorator.rb
deleted file mode 100644
index c62702a321..0000000000
--- a/app/models/spree/gateway_decorator.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-require 'spree/concerns/payment_method_distributors'
-
-Spree::Gateway.class_eval do
- include Spree::PaymentMethodDistributors
-
- # Default to live
- preference :server, :string, default: 'live'
- preference :test_mode, :boolean, default: false
-end
diff --git a/app/models/spree/order/checkout.rb b/app/models/spree/order/checkout.rb
new file mode 100644
index 0000000000..ffecf63f23
--- /dev/null
+++ b/app/models/spree/order/checkout.rb
@@ -0,0 +1,191 @@
+# frozen_string_literal: true
+
+module Spree
+ class Order < ActiveRecord::Base
+ module Checkout
+ def self.included(klass)
+ klass.class_eval do
+ class_attribute :next_event_transitions
+ class_attribute :previous_states
+ class_attribute :checkout_flow
+ class_attribute :checkout_steps
+ class_attribute :removed_transitions
+
+ def self.checkout_flow(&block)
+ if block_given?
+ @checkout_flow = block
+ define_state_machine!
+ else
+ @checkout_flow
+ end
+ end
+
+ def self.define_state_machine!
+ self.checkout_steps = {}
+ self.next_event_transitions = []
+ self.previous_states = [:cart]
+ self.removed_transitions = []
+
+ # Build the checkout flow using the checkout_flow defined either
+ # within the Order class, or a decorator for that class.
+ #
+ # This method may be called multiple times depending on if the
+ # checkout_flow is re-defined in a decorator or not.
+ instance_eval(&checkout_flow)
+
+ klass = self
+
+ # To avoid a ton of warnings when the state machine is re-defined
+ StateMachine::Machine.ignore_method_conflicts = true
+ # To avoid multiple occurrences of the same transition being defined
+ # On first definition, state_machines will not be defined
+ state_machines.clear if respond_to?(:state_machines)
+ state_machine :state, initial: :cart do
+ klass.next_event_transitions.each { |t| transition(t.merge(on: :next)) }
+
+ # Persist the state on the order
+ after_transition do |order|
+ order.state = order.state
+ order.save
+ end
+
+ event :cancel do
+ transition to: :canceled, if: :allow_cancel?
+ end
+
+ event :return do
+ transition to: :returned, from: :awaiting_return, unless: :awaiting_returns?
+ end
+
+ event :resume do
+ transition to: :resumed, from: :canceled, if: :allow_resume?
+ end
+
+ event :authorize_return do
+ transition to: :awaiting_return
+ end
+
+ if states[:payment]
+ before_transition to: :complete do |order|
+ order.process_payments! if order.payment_required?
+ end
+ end
+
+ before_transition from: :cart, do: :ensure_line_items_present
+
+ before_transition to: :delivery, do: :create_proposed_shipments
+ before_transition to: :delivery, do: :ensure_available_shipping_rates
+
+ after_transition to: :complete, do: :finalize!
+ after_transition to: :delivery, do: :create_tax_charge!
+ after_transition to: :resumed, do: :after_resume
+ after_transition to: :canceled, do: :after_cancel
+ end
+ end
+
+ def self.go_to_state(name, options = {})
+ checkout_steps[name] = options
+ previous_states.each do |state|
+ add_transition({ from: state, to: name }.merge(options))
+ end
+ if options[:if]
+ previous_states << name
+ else
+ self.previous_states = [name]
+ end
+ end
+
+ def self.insert_checkout_step(name, options = {})
+ before = options.delete(:before)
+ after = options.delete(:after) unless before
+ after = checkout_steps.keys.last unless before || after
+
+ cloned_steps = checkout_steps.clone
+ cloned_removed_transitions = removed_transitions.clone
+ checkout_flow do
+ cloned_steps.each_pair do |key, value|
+ go_to_state(name, options) if key == before
+ go_to_state(key, value)
+ go_to_state(name, options) if key == after
+ end
+ cloned_removed_transitions.each do |transition|
+ remove_transition(transition)
+ end
+ end
+ end
+
+ def self.remove_checkout_step(name)
+ cloned_steps = checkout_steps.clone
+ cloned_removed_transitions = removed_transitions.clone
+ checkout_flow do
+ cloned_steps.each_pair do |key, value|
+ go_to_state(key, value) unless key == name
+ end
+ cloned_removed_transitions.each do |transition|
+ remove_transition(transition)
+ end
+ end
+ end
+
+ def self.remove_transition(options = {})
+ removed_transitions << options
+ next_event_transitions.delete(find_transition(options))
+ end
+
+ def self.find_transition(options = {})
+ return nil if options.nil? || !options.include?(:from) || !options.include?(:to)
+
+ next_event_transitions.detect do |transition|
+ transition[options[:from].to_sym] == options[:to].to_sym
+ end
+ end
+
+ def self.next_event_transitions
+ @next_event_transitions ||= []
+ end
+
+ def self.checkout_steps
+ @checkout_steps ||= {}
+ end
+
+ def self.add_transition(options)
+ next_event_transitions << { options.delete(:from) => options.delete(:to) }.
+ merge(options)
+ end
+
+ def checkout_steps
+ steps = self.class.checkout_steps.
+ each_with_object([]) { |(step, options), checkout_steps|
+ next if options.include?(:if) && !options[:if].call(self)
+
+ checkout_steps << step
+ }.map(&:to_s)
+ # Ensure there is always a complete step
+ steps << "complete" unless steps.include?("complete")
+ steps
+ end
+
+ def checkout_step?(step)
+ step.present? ? checkout_steps.include?(step) : false
+ end
+
+ def checkout_step_index(step)
+ checkout_steps.index(step)
+ end
+
+ def self.removed_transitions
+ @removed_transitions ||= []
+ end
+
+ def can_go_to_state?(state)
+ return false unless self.state.present? &&
+ checkout_step?(state) &&
+ checkout_step?(self.state)
+
+ checkout_step_index(state) > checkout_step_index(self.state)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb
index 71574359a7..bf125da21d 100644
--- a/app/models/spree/order_decorator.rb
+++ b/app/models/spree/order_decorator.rb
@@ -89,6 +89,10 @@ Spree::Order.class_eval do
where("state != ?", state)
}
+ def updater
+ @updater ||= OrderManagement::Order::Updater.new(self)
+ end
+
def create_proposed_shipments
adjustments.shipping.delete_all
shipments.destroy_all
@@ -374,6 +378,13 @@ Spree::Order.class_eval do
address
end
+ # Update attributes of a record in the database without callbacks, validations etc.
+ # This was originally an extension to ActiveRecord in Spree but only used for Spree::Order
+ def update_attributes_without_callbacks(attributes)
+ assign_attributes(attributes)
+ Spree::Order.where(id: id).update_all(attributes)
+ end
+
private
def adjustments_fetcher
@@ -432,8 +443,8 @@ Spree::Order.class_eval do
# amount here.
def charge_shipping_and_payment_fees!
update_totals
- return unless payments.any?
+ return unless pending_payments.any?
- payments.first.update_attribute :amount, total
+ pending_payments.first.update_attribute :amount, total
end
end
diff --git a/app/models/spree/order_updater_decorator.rb b/app/models/spree/order_updater_decorator.rb
deleted file mode 100644
index b227444c8b..0000000000
--- a/app/models/spree/order_updater_decorator.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-# frozen_string_literal: true
-
-Spree::OrderUpdater.class_eval do
- # Override spree method to make it update all adjustments as in Spree v2.0.4
- def update_shipping_adjustments
- order.adjustments.reload.each(&:update!)
- end
-end
diff --git a/app/models/spree/payment.rb b/app/models/spree/payment.rb
new file mode 100644
index 0000000000..754119034a
--- /dev/null
+++ b/app/models/spree/payment.rb
@@ -0,0 +1,216 @@
+# frozen_string_literal: true
+
+module Spree
+ class Payment < ActiveRecord::Base
+ include Spree::Payment::Processing
+ extend Spree::LocalizedNumber
+
+ localize_number :amount
+
+ IDENTIFIER_CHARS = (('A'..'Z').to_a + ('0'..'9').to_a - %w(0 1 I O)).freeze
+
+ delegate :line_items, to: :order
+ delegate :currency, to: :order
+
+ belongs_to :order, class_name: 'Spree::Order'
+ belongs_to :source, polymorphic: true
+ belongs_to :payment_method, class_name: 'Spree::PaymentMethod'
+
+ has_many :offsets, -> { where("source_type = 'Spree::Payment' AND amount < 0").completed },
+ class_name: "Spree::Payment", foreign_key: :source_id
+ has_many :log_entries, as: :source, dependent: :destroy
+
+ has_one :adjustment, as: :source, dependent: :destroy
+
+ validate :validate_source
+ before_save :set_unique_identifier
+
+ after_save :create_payment_profile, if: :profiles_supported?
+
+ # update the order totals, etc.
+ after_save :ensure_correct_adjustment, :update_order
+ # invalidate previously entered payments
+ after_create :invalidate_old_payments
+
+ # Skips the validation of the source (for example, credit card) of the payment.
+ #
+ # This is used in refunds as the validation of the card can fail but the refund can go through,
+ # we trust the payment gateway in these cases. For example, Stripe is accepting refunds with
+ # source cards that were valid when the payment was placed but are now expired, and we
+ # consider them invalid.
+ attr_accessor :skip_source_validation
+ attr_accessor :source_attributes
+
+ after_initialize :build_source
+
+ scope :from_credit_card, -> { where(source_type: 'Spree::CreditCard') }
+ scope :with_state, ->(s) { where(state: s.to_s) }
+ scope :completed, -> { with_state('completed') }
+ scope :pending, -> { with_state('pending') }
+ scope :failed, -> { with_state('failed') }
+ scope :valid, -> { where('state NOT IN (?)', %w(failed invalid)) }
+
+ # order state machine (see http://github.com/pluginaweek/state_machine/tree/master for details)
+ state_machine initial: :checkout do
+ # With card payments, happens before purchase or authorization happens
+ event :started_processing do
+ transition from: [:checkout, :pending, :completed, :processing], to: :processing
+ end
+ # When processing during checkout fails
+ event :failure do
+ transition from: [:pending, :processing], to: :failed
+ end
+ # With card payments this represents authorizing the payment
+ event :pend do
+ transition from: [:checkout, :processing], to: :pending
+ end
+ # With card payments this represents completing a purchase or capture transaction
+ event :complete do
+ transition from: [:processing, :pending, :checkout], to: :completed
+ end
+ event :void do
+ transition from: [:pending, :completed, :checkout], to: :void
+ end
+ # when the card brand isnt supported
+ event :invalidate do
+ transition from: [:checkout], to: :invalid
+ end
+ end
+
+ def money
+ Spree::Money.new(amount, currency: currency)
+ end
+ alias display_amount money
+
+ def offsets_total
+ offsets.pluck(:amount).sum
+ end
+
+ def credit_allowed
+ amount - offsets_total
+ end
+
+ def can_credit?
+ credit_allowed.positive?
+ end
+
+ def build_source
+ return if source_attributes.nil?
+ return unless payment_method.andand.payment_source_class
+
+ self.source = payment_method.payment_source_class.new(source_attributes)
+ source.payment_method_id = payment_method.id
+ source.user_id = order.user_id if order
+ end
+
+ # Pin payments lacks void and credit methods, but it does have refund
+ # Here we swap credit out for refund and remove void as a possible action
+ def actions
+ return [] unless payment_source&.respond_to?(:actions)
+
+ actions = payment_source.actions.select do |action|
+ !payment_source.respond_to?("can_#{action}?") ||
+ payment_source.__send__("can_#{action}?", self)
+ end
+
+ if payment_method.is_a? Gateway::Pin
+ actions << 'refund' if actions.include? 'credit'
+ actions.reject! { |a| ['credit', 'void'].include? a }
+ end
+
+ actions
+ end
+
+ def payment_source
+ res = source.is_a?(Payment) ? source.source : source
+ res || payment_method
+ end
+
+ def ensure_correct_adjustment
+ revoke_adjustment_eligibility if ['failed', 'invalid'].include?(state)
+ return if adjustment.try(:finalized?)
+
+ if adjustment
+ adjustment.originator = payment_method
+ adjustment.label = adjustment_label
+ adjustment.save
+ else
+ payment_method.create_adjustment(adjustment_label, order, self, true)
+ association(:adjustment).reload
+ end
+ end
+
+ def adjustment_label
+ I18n.t('payment_method_fee')
+ end
+
+ private
+
+ # Don't charge fees for invalid or failed payments.
+ # This is called twice for failed payments, because the persistence of the 'failed'
+ # state is acheived through some trickery using an after_rollback callback on the
+ # payment model. See Spree::Payment#persist_invalid
+ def revoke_adjustment_eligibility
+ return unless adjustment.try(:reload)
+ return if adjustment.finalized?
+
+ adjustment.update_attribute(:eligible, false)
+ adjustment.finalize!
+ end
+
+ def validate_source
+ if source && !skip_source_validation && !source.valid?
+ source.errors.each do |field, error|
+ field_name = I18n.t("activerecord.attributes.#{source.class.to_s.underscore}.#{field}")
+ errors.add(Spree.t(source.class.to_s.demodulize.underscore), "#{field_name} #{error}")
+ end
+ end
+ errors.blank?
+ end
+
+ def profiles_supported?
+ payment_method.respond_to?(:payment_profiles_supported?) &&
+ payment_method.payment_profiles_supported?
+ end
+
+ def create_payment_profile
+ return unless source.is_a?(CreditCard)
+ return unless source.try(:save_requested_by_customer?)
+ return unless source.number || source.gateway_payment_profile_id
+ return unless source.gateway_customer_profile_id.nil?
+
+ payment_method.create_profile(self)
+ rescue ActiveMerchant::ConnectionError => e
+ gateway_error e
+ end
+
+ # Makes newly entered payments invalidate previously entered payments so the most recent payment
+ # is used by the gateway.
+ def invalidate_old_payments
+ order.payments.with_state('checkout').where.not(id: id).each do |payment|
+ # Using update_column skips validations and so it skips validate_source. As we are just
+ # invalidating past payments here, we don't want to validate all of them at this stage.
+ payment.update_column(:state, 'invalid')
+ payment.ensure_correct_adjustment
+ end
+ end
+
+ def update_order
+ order.payments.reload
+ order.update!
+ end
+
+ # Necessary because some payment gateways will refuse payments with
+ # duplicate IDs. We *were* using the Order number, but that's set once and
+ # is unchanging. What we need is a unique identifier on a per-payment basis,
+ # and this is it. Related to #1998.
+ # See https://github.com/spree/spree/issues/1998#issuecomment-12869105
+ def set_unique_identifier
+ self.identifier = generate_identifier while self.class.exists?(identifier: identifier)
+ end
+
+ def generate_identifier
+ Array.new(8){ IDENTIFIER_CHARS.sample }.join
+ end
+ end
+end
diff --git a/app/models/spree/payment/processing.rb b/app/models/spree/payment/processing.rb
new file mode 100644
index 0000000000..2579f76de7
--- /dev/null
+++ b/app/models/spree/payment/processing.rb
@@ -0,0 +1,277 @@
+# frozen_string_literal: true
+
+module Spree
+ class Payment < ActiveRecord::Base
+ module Processing
+ def process!
+ return unless payment_method&.source_required?
+
+ raise Core::GatewayError, Spree.t(:payment_processing_failed) unless source
+
+ return if processing?
+
+ unless payment_method.supports?(source)
+ invalidate!
+ raise Core::GatewayError, Spree.t(:payment_method_not_supported)
+ end
+
+ if payment_method.auto_capture?
+ purchase!
+ else
+ authorize!
+ end
+ end
+
+ def authorize!
+ started_processing!
+ gateway_action(source, :authorize, :pend)
+ end
+
+ def purchase!
+ started_processing!
+ gateway_action(source, :purchase, :complete)
+ end
+
+ def capture!
+ return true if completed?
+
+ started_processing!
+ protect_from_connection_error do
+ check_environment
+
+ response = if payment_method.payment_profiles_supported?
+ # Gateways supporting payment profiles will need access to credit
+ # card object because this stores the payment profile information
+ # so supply the authorization itself as well as the credit card,
+ # rather than just the authorization code
+ payment_method.capture(self, source, gateway_options)
+ else
+ # Standard ActiveMerchant capture usage
+ payment_method.capture(money.money.cents,
+ response_code,
+ gateway_options)
+ end
+
+ handle_response(response, :complete, :failure)
+ end
+ end
+
+ def void_transaction!
+ return true if void?
+
+ protect_from_connection_error do
+ check_environment
+
+ response = if payment_method.payment_profiles_supported?
+ # Gateways supporting payment profiles will need access to credit
+ # card object because this stores the payment profile information
+ # so supply the authorization itself as well as the credit card,
+ # rather than just the authorization code
+ payment_method.void(response_code, source, gateway_options)
+ else
+ # Standard ActiveMerchant void usage
+ payment_method.void(response_code, gateway_options)
+ end
+
+ record_response(response)
+
+ if response.success?
+ self.response_code = response.authorization
+ void
+ else
+ gateway_error(response)
+ end
+ end
+ end
+
+ def credit!(credit_amount = nil)
+ protect_from_connection_error do
+ check_environment
+
+ credit_amount = calculate_refund_amount(credit_amount)
+
+ response = if payment_method.payment_profiles_supported?
+ payment_method.credit(
+ (credit_amount * 100).round,
+ source,
+ response_code,
+ gateway_options
+ )
+ else
+ payment_method.credit(
+ (credit_amount * 100).round,
+ response_code,
+ gateway_options
+ )
+ end
+
+ record_response(response)
+
+ if response.success?
+ self.class.create!(
+ order: order,
+ source: self,
+ payment_method: payment_method,
+ amount: credit_amount.abs * -1,
+ response_code: response.authorization,
+ state: 'completed',
+ skip_source_validation: true
+ )
+ else
+ gateway_error(response)
+ end
+ end
+ end
+
+ def refund!(refund_amount = nil)
+ protect_from_connection_error do
+ check_environment
+
+ refund_amount = calculate_refund_amount(refund_amount)
+
+ response = if payment_method.payment_profiles_supported?
+ payment_method.refund(
+ (refund_amount * 100).round,
+ source,
+ response_code,
+ gateway_options
+ )
+ else
+ payment_method.refund(
+ (refund_amount * 100).round,
+ response_code,
+ gateway_options
+ )
+ end
+
+ record_response(response)
+
+ if response.success?
+ self.class.create!(
+ order: order,
+ source: self,
+ payment_method: payment_method,
+ amount: refund_amount.abs * -1,
+ response_code: response.authorization,
+ state: 'completed',
+ skip_source_validation: true
+ )
+ else
+ gateway_error(response)
+ end
+ end
+ end
+
+ def partial_credit(amount)
+ return if amount > credit_allowed
+
+ started_processing!
+ credit!(amount)
+ end
+
+ def gateway_options
+ options = { email: order.email,
+ customer: order.email,
+ ip: order.last_ip_address,
+ # Need to pass in a unique identifier here to make some
+ # payment gateways happy.
+ #
+ # For more information, please see Spree::Payment#set_unique_identifier
+ order_id: gateway_order_id }
+
+ options.merge!({ shipping: order.ship_total * 100,
+ tax: order.tax_total * 100,
+ subtotal: order.item_total * 100,
+ discount: order.promo_total * 100,
+ currency: currency })
+
+ options.merge!({ billing_address: order.bill_address.try(:active_merchant_hash),
+ shipping_address: order.ship_address.try(:active_merchant_hash) })
+
+ options
+ end
+
+ private
+
+ def calculate_refund_amount(refund_amount = nil)
+ refund_amount ||= if credit_allowed >= order.outstanding_balance.abs
+ order.outstanding_balance.abs
+ else
+ credit_allowed.abs
+ end
+ refund_amount.to_f
+ end
+
+ def gateway_action(source, action, success_state)
+ protect_from_connection_error do
+ check_environment
+
+ response = payment_method.public_send(
+ action,
+ (amount * 100).round,
+ source,
+ gateway_options
+ )
+ handle_response(response, success_state, :failure)
+ end
+ end
+
+ def handle_response(response, success_state, failure_state)
+ record_response(response)
+
+ if response.success?
+ unless response.authorization.nil?
+ self.response_code = response.authorization
+ self.avs_response = response.avs_result['code']
+
+ if response.cvv_result
+ self.cvv_response_code = response.cvv_result['code']
+ self.cvv_response_message = response.cvv_result['message']
+ end
+ end
+ __send__("#{success_state}!")
+ else
+ __send__(failure_state)
+ gateway_error(response)
+ end
+ end
+
+ def record_response(response)
+ log_entries.create(details: response.to_yaml)
+ end
+
+ def protect_from_connection_error
+ yield
+ rescue ActiveMerchant::ConnectionError => e
+ gateway_error(e)
+ end
+
+ def gateway_error(error)
+ text = if error.is_a? ActiveMerchant::Billing::Response
+ error.params['message'] || error.params['response_reason_text'] || error.message
+ elsif error.is_a? ActiveMerchant::ConnectionError
+ Spree.t(:unable_to_connect_to_gateway)
+ else
+ error.to_s
+ end
+ logger.error(Spree.t(:gateway_error))
+ logger.error(" #{error.to_yaml}")
+ raise Core::GatewayError, text
+ end
+
+ # Saftey check to make sure we're not accidentally performing operations on a live gateway.
+ # Ex. When testing in staging environment with a copy of production data.
+ def check_environment
+ return if payment_method.environment == Rails.env
+
+ message = Spree.t(:gateway_config_unavailable) + " - #{Rails.env}"
+ raise Core::GatewayError, message
+ end
+
+ # The unique identifier to be passed in to the payment gateway
+ def gateway_order_id
+ "#{order.number}-#{identifier}"
+ end
+ end
+ end
+end
diff --git a/app/models/spree/payment_decorator.rb b/app/models/spree/payment_decorator.rb
deleted file mode 100644
index ec84a83a83..0000000000
--- a/app/models/spree/payment_decorator.rb
+++ /dev/null
@@ -1,117 +0,0 @@
-require 'spree/localized_number'
-
-module Spree
- Payment.class_eval do
- extend Spree::LocalizedNumber
-
- delegate :line_items, to: :order
-
- has_one :adjustment, as: :source, dependent: :destroy
-
- after_save :ensure_correct_adjustment, :update_order
-
- localize_number :amount
-
- # We bypass this after_rollback callback that is setup in Spree::Payment
- # The issues the callback fixes are not experienced in OFN:
- # if a payment fails on checkout the state "failed" is persisted correctly
- def persist_invalid; end
-
- def ensure_correct_adjustment
- revoke_adjustment_eligibility if ['failed', 'invalid'].include?(state)
- return if adjustment.try(:finalized?)
-
- if adjustment
- adjustment.originator = payment_method
- adjustment.label = adjustment_label
- adjustment.save
- else
- payment_method.create_adjustment(adjustment_label, order, self, true)
- association(:adjustment).reload
- end
- end
-
- def adjustment_label
- I18n.t('payment_method_fee')
- end
-
- # Pin payments lacks void and credit methods, but it does have refund
- # Here we swap credit out for refund and remove void as a possible action
- def actions_with_pin_payment_adaptations
- actions = actions_without_pin_payment_adaptations
- if payment_method.is_a? Gateway::Pin
- actions << 'refund' if actions.include? 'credit'
- actions.reject! { |a| ['credit', 'void'].include? a }
- end
- actions
- end
- alias_method_chain :actions, :pin_payment_adaptations
-
- def refund!(refund_amount = nil)
- protect_from_connection_error do
- check_environment
-
- refund_amount = calculate_refund_amount(refund_amount)
-
- if payment_method.payment_profiles_supported?
- response = payment_method.refund((refund_amount * 100).round, source, response_code, gateway_options)
- else
- response = payment_method.refund((refund_amount * 100).round, response_code, gateway_options)
- end
-
- record_response(response)
-
- if response.success?
- self.class.create(order: order,
- source: self,
- payment_method: payment_method,
- amount: refund_amount.abs * -1,
- response_code: response.authorization,
- state: 'completed')
- else
- gateway_error(response)
- end
- end
- end
-
- # Import from future Spree v.2.3.0 d470b31798f37
- def build_source
- return if source_attributes.nil?
- return unless payment_method.andand.payment_source_class
-
- self.source = payment_method.payment_source_class.new(source_attributes)
- source.payment_method_id = payment_method.id
- source.user_id = order.user_id if order
- end
-
- private
-
- def calculate_refund_amount(refund_amount = nil)
- refund_amount ||= credit_allowed >= order.outstanding_balance.abs ? order.outstanding_balance.abs : credit_allowed.abs
- refund_amount.to_f
- end
-
- def create_payment_profile
- return unless source.is_a?(CreditCard)
- return unless source.try(:save_requested_by_customer?)
- return unless source.number || source.gateway_payment_profile_id
- return unless source.gateway_customer_profile_id.nil?
-
- payment_method.create_profile(self)
- rescue ActiveMerchant::ConnectionError => e
- gateway_error e
- end
-
- # Don't charge fees for invalid or failed payments.
- # This is called twice for failed payments, because the persistence of the 'failed'
- # state is acheived through some trickery using an after_rollback callback on the
- # payment model. See Spree::Payment#persist_invalid
- def revoke_adjustment_eligibility
- return unless adjustment.try(:reload)
- return if adjustment.finalized?
-
- adjustment.update_attribute(:eligible, false)
- adjustment.finalize!
- end
- end
-end
diff --git a/app/models/spree/payment_method.rb b/app/models/spree/payment_method.rb
new file mode 100644
index 0000000000..39df36486d
--- /dev/null
+++ b/app/models/spree/payment_method.rb
@@ -0,0 +1,137 @@
+# frozen_string_literal: true
+
+require 'spree/concerns/payment_method_distributors'
+
+module Spree
+ class PaymentMethod < ActiveRecord::Base
+ include Spree::Core::CalculatedAdjustments
+ include Spree::PaymentMethodDistributors
+
+ acts_as_taggable
+ acts_as_paranoid
+
+ DISPLAY = [:both, :front_end, :back_end].freeze
+ default_scope -> { where(deleted_at: nil) }
+
+ has_many :credit_cards, class_name: "Spree::CreditCard"
+
+ validates :name, presence: true
+ validate :distributor_validation
+
+ after_initialize :init
+
+ scope :production, -> { where(environment: 'production') }
+
+ scope :managed_by, lambda { |user|
+ if user.has_spree_role?('admin')
+ where(nil)
+ else
+ joins(:distributors).
+ where('distributors_payment_methods.distributor_id IN (?)',
+ user.enterprises.select(&:id)).
+ select('DISTINCT spree_payment_methods.*')
+ end
+ }
+
+ scope :for_distributors, ->(distributors) {
+ non_unique_matches = unscoped.joins(:distributors).where(enterprises: { id: distributors })
+ where(id: non_unique_matches.map(&:id))
+ }
+
+ scope :for_distributor, lambda { |distributor|
+ joins(:distributors).
+ where('enterprises.id = ?', distributor)
+ }
+
+ scope :for_subscriptions, -> { where(type: Subscription::ALLOWED_PAYMENT_METHOD_TYPES) }
+
+ scope :by_name, -> { order('spree_payment_methods.name ASC') }
+
+ scope :available, lambda { |display_on = 'both'|
+ where(active: true).
+ where('spree_payment_methods.display_on=? OR spree_payment_methods.display_on=? OR spree_payment_methods.display_on IS NULL', display_on, '').
+ where('spree_payment_methods.environment=? OR spree_payment_methods.environment=? OR spree_payment_methods.environment IS NULL', Rails.env, '')
+ }
+
+ def self.providers
+ Rails.application.config.spree.payment_methods
+ end
+
+ def provider_class
+ raise 'You must implement provider_class method for this gateway.'
+ end
+
+ # The class that will process payments for this payment type, used for @payment.source
+ # e.g. CreditCard in the case of a the Gateway payment type
+ # nil means the payment method doesn't require a source e.g. check
+ def payment_source_class
+ raise 'You must implement payment_source_class method for this gateway.'
+ end
+
+ def self.active?
+ where(type: to_s, environment: Rails.env, active: true).count.positive?
+ end
+
+ def method_type
+ type.demodulize.downcase
+ end
+
+ def self.find_with_destroyed(*args)
+ unscoped { find(*args) }
+ end
+
+ def payment_profiles_supported?
+ false
+ end
+
+ def source_required?
+ true
+ end
+
+ def auto_capture?
+ Spree::Config[:auto_capture]
+ end
+
+ def supports?(_source)
+ true
+ end
+
+ def init
+ unless reflections.key?(:calculator)
+ self.class.include Spree::Core::CalculatedAdjustments
+ end
+
+ self.calculator ||= Calculator::FlatRate.new(preferred_amount: 0)
+ end
+
+ def has_distributor?(distributor)
+ distributors.include?(distributor)
+ end
+
+ def self.clean_name
+ case name
+ when "Spree::PaymentMethod::Check"
+ "Cash/EFT/etc. (payments for which automatic validation is not required)"
+ when "Spree::Gateway::Migs"
+ "MasterCard Internet Gateway Service (MIGS)"
+ when "Spree::Gateway::Pin"
+ "Pin Payments"
+ when "Spree::Gateway::StripeConnect"
+ "Stripe"
+ when "Spree::Gateway::StripeSCA"
+ "Stripe SCA"
+ when "Spree::Gateway::PayPalExpress"
+ "PayPal Express"
+ else
+ i = name.rindex('::') + 2
+ name[i..-1]
+ end
+ end
+
+ private
+
+ def distributor_validation
+ validates_with DistributorsValidator
+ end
+ end
+end
diff --git a/app/models/spree/payment_method/check.rb b/app/models/spree/payment_method/check.rb
new file mode 100644
index 0000000000..9819a52c6c
--- /dev/null
+++ b/app/models/spree/payment_method/check.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module Spree
+ class PaymentMethod
+ class Check < Spree::PaymentMethod
+ def actions
+ %w{capture void}
+ end
+
+ # Indicates whether its possible to capture the payment
+ def can_capture?(payment)
+ ['checkout', 'pending'].include?(payment.state)
+ end
+
+ # Indicates whether its possible to void the payment.
+ def can_void?(payment)
+ payment.state != 'void'
+ end
+
+ def capture(*_args)
+ ActiveMerchant::Billing::Response.new(true, "", {}, {})
+ end
+
+ def void(*_args)
+ ActiveMerchant::Billing::Response.new(true, "", {}, {})
+ end
+
+ def source_required?
+ false
+ end
+ end
+ end
+end
diff --git a/app/models/spree/payment_method_decorator.rb b/app/models/spree/payment_method_decorator.rb
deleted file mode 100644
index 4c2770daea..0000000000
--- a/app/models/spree/payment_method_decorator.rb
+++ /dev/null
@@ -1,84 +0,0 @@
-require 'spree/concerns/payment_method_distributors'
-
-Spree::PaymentMethod.class_eval do
- include Spree::Core::CalculatedAdjustments
- include Spree::PaymentMethodDistributors
-
- acts_as_taggable
-
- has_many :credit_cards, class_name: "Spree::CreditCard" # from Spree v.2.3.0 d470b31798f37
-
- after_initialize :init
-
- validate :distributor_validation
-
- # -- Scopes
- scope :managed_by, lambda { |user|
- if user.has_spree_role?('admin')
- where(nil)
- else
- joins(:distributors).
- where('distributors_payment_methods.distributor_id IN (?)', user.enterprises.select(&:id)).
- select('DISTINCT spree_payment_methods.*')
- end
- }
-
- scope :for_distributors, ->(distributors) {
- non_unique_matches = unscoped.joins(:distributors).where(enterprises: { id: distributors })
- where(id: non_unique_matches.map(&:id))
- }
-
- scope :for_distributor, lambda { |distributor|
- joins(:distributors).
- where('enterprises.id = ?', distributor)
- }
-
- scope :for_subscriptions, -> { where(type: Subscription::ALLOWED_PAYMENT_METHOD_TYPES) }
-
- scope :by_name, -> { order('spree_payment_methods.name ASC') }
-
- # Rewrite Spree's ruby-land class method as a scope
- scope :available, lambda { |display_on = 'both'|
- where(active: true).
- where('spree_payment_methods.display_on=? OR spree_payment_methods.display_on=? OR spree_payment_methods.display_on IS NULL', display_on, '').
- where('spree_payment_methods.environment=? OR spree_payment_methods.environment=? OR spree_payment_methods.environment IS NULL', Rails.env, '')
- }
-
- def init
- unless reflections.key?(:calculator)
- self.class.include Spree::Core::CalculatedAdjustments
- end
-
- self.calculator ||= Calculator::FlatRate.new(preferred_amount: 0)
- end
-
- def has_distributor?(distributor)
- distributors.include?(distributor)
- end
-
- def self.clean_name
- case name
- when "Spree::PaymentMethod::Check"
- "Cash/EFT/etc. (payments for which automatic validation is not required)"
- when "Spree::Gateway::Migs"
- "MasterCard Internet Gateway Service (MIGS)"
- when "Spree::Gateway::Pin"
- "Pin Payments"
- when "Spree::Gateway::StripeConnect"
- "Stripe"
- when "Spree::Gateway::StripeSCA"
- "Stripe SCA"
- when "Spree::Gateway::PayPalExpress"
- "PayPal Express"
- else
- i = name.rindex('::') + 2
- name[i..-1]
- end
- end
-
- private
-
- def distributor_validation
- validates_with DistributorsValidator
- end
-end
diff --git a/app/models/spree/product_decorator.rb b/app/models/spree/product_decorator.rb
index 602329b5c1..554309f687 100644
--- a/app/models/spree/product_decorator.rb
+++ b/app/models/spree/product_decorator.rb
@@ -63,8 +63,7 @@ Spree::Product.class_eval do
scope :visible_for, lambda { |enterprise|
joins('LEFT OUTER JOIN spree_variants AS o_spree_variants ON (o_spree_variants.product_id = spree_products.id)').
joins('LEFT OUTER JOIN inventory_items AS o_inventory_items ON (o_spree_variants.id = o_inventory_items.variant_id)').
- where('o_inventory_items.enterprise_id = (?) AND visible = (?)', enterprise, true).
- select('DISTINCT spree_products.*')
+ where('o_inventory_items.enterprise_id = (?) AND visible = (?)', enterprise, true)
}
# -- Scopes
diff --git a/app/models/spree/stock_item.rb b/app/models/spree/stock_item.rb
new file mode 100644
index 0000000000..e6df19b03a
--- /dev/null
+++ b/app/models/spree/stock_item.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+module Spree
+ class StockItem < ActiveRecord::Base
+ acts_as_paranoid
+
+ belongs_to :stock_location, class_name: 'Spree::StockLocation'
+ belongs_to :variant, class_name: 'Spree::Variant'
+ has_many :stock_movements, dependent: :destroy
+
+ validates :stock_location, :variant, presence: true
+ validates :variant_id, uniqueness: { scope: [:stock_location_id, :deleted_at] }
+ validates :count_on_hand, numericality: { greater_than_or_equal_to: 0, unless: :backorderable? }
+
+ delegate :weight, to: :variant
+ delegate :name, to: :variant, prefix: true
+
+ def backordered_inventory_units
+ Spree::InventoryUnit.backordered_for_stock_item(self)
+ end
+
+ def adjust_count_on_hand(value)
+ with_lock do
+ self.count_on_hand = count_on_hand + value
+ process_backorders if in_stock?
+
+ save!
+ end
+ end
+
+ def in_stock?
+ count_on_hand.positive?
+ end
+
+ # Tells whether it's available to be included in a shipment
+ def available?
+ in_stock? || backorderable?
+ end
+
+ def variant
+ Spree::Variant.unscoped { super }
+ end
+
+ private
+
+ def count_on_hand=(value)
+ self[:count_on_hand] = value
+ end
+
+ def process_backorders
+ backordered_inventory_units.each do |unit|
+ break unless in_stock?
+
+ unit.fill_backorder
+ end
+ end
+ end
+end
diff --git a/app/models/spree/taxon_decorator.rb b/app/models/spree/taxon_decorator.rb
index ad2a85cfdb..f2c6f1e20a 100644
--- a/app/models/spree/taxon_decorator.rb
+++ b/app/models/spree/taxon_decorator.rb
@@ -1,9 +1,6 @@
Spree::Taxon.class_eval do
has_many :classifications, dependent: :destroy
- attachment_definitions[:icon][:path] = 'public/images/spree/taxons/:id/:style/:basename.:extension'
- attachment_definitions[:icon][:url] = '/images/spree/taxons/:id/:style/:basename.:extension'
-
# Indicate which filters should be used for this taxon
def applicable_filters
fs = []
diff --git a/app/models/spree/user.rb b/app/models/spree/user.rb
index 3df57a9cf8..da276ec936 100644
--- a/app/models/spree/user.rb
+++ b/app/models/spree/user.rb
@@ -34,10 +34,6 @@ module Spree
# We use the same options as Spree and add :confirmable
devise :confirmable, reconfirmable: true
- # TODO: Later versions of devise have a dedicated after_confirmation callback, so use that
- after_update :welcome_after_confirm, if: lambda {
- confirmation_token_changed? && confirmation_token.nil?
- }
class DestroyWithOrdersError < StandardError; end
@@ -49,14 +45,14 @@ module Spree
has_spree_role?('admin')
end
- def send_reset_password_instructions
- generate_reset_password_token!
- UserMailer.reset_password_instructions(id).deliver
- end
# handle_asynchronously will define send_reset_password_instructions_with_delay.
# If handle_asynchronously is called twice, we get an infinite job loop.
handle_asynchronously :send_reset_password_instructions unless method_defined? :send_reset_password_instructions_with_delay
+ def regenerate_reset_password_token
+ set_reset_password_token
+ end
+
def known_users
if admin?
Spree::User.where(nil)
@@ -82,9 +78,9 @@ module Spree
customers.find_by(enterprise_id: enterprise)
end
- def welcome_after_confirm
- # Send welcome email if we are confirming an user's email
- # Note: this callback only runs on email confirmation
+ # This is a Devise Confirmable callback that runs on email confirmation
+ # It sends a welcome email after the user email is confirmed
+ def after_confirmation
return unless confirmed? && unconfirmed_email.nil? && !unconfirmed_email_changed?
send_signup_confirmation
diff --git a/app/serializers/api/admin/for_order_cycle/enterprise_serializer.rb b/app/serializers/api/admin/for_order_cycle/enterprise_serializer.rb
index 360f135680..fecf675c5f 100644
--- a/app/serializers/api/admin/for_order_cycle/enterprise_serializer.rb
+++ b/app/serializers/api/admin/for_order_cycle/enterprise_serializer.rb
@@ -30,9 +30,10 @@ class Api::Admin::ForOrderCycle::EnterpriseSerializer < ActiveModel::Serializer
def products_scope
products_relation = object.supplied_products
if order_cycle.prefers_product_selection_from_coordinator_inventory_only?
- products_relation = products_relation.visible_for(order_cycle.coordinator)
+ products_relation = products_relation.
+ visible_for(order_cycle.coordinator)
end
- products_relation.order(:name)
+ products_relation
end
def products
diff --git a/app/serializers/api/open_street_map_config_serializer.rb b/app/serializers/api/open_street_map_config_serializer.rb
index 8c5aec5dbb..29f87ad34e 100644
--- a/app/serializers/api/open_street_map_config_serializer.rb
+++ b/app/serializers/api/open_street_map_config_serializer.rb
@@ -4,7 +4,9 @@ module Api
class OpenStreetMapConfigSerializer < ActiveModel::Serializer
attributes :open_street_map_enabled,
:open_street_map_provider_name,
- :open_street_map_provider_options
+ :open_street_map_provider_options,
+ :open_street_map_default_latitude,
+ :open_street_map_default_longitude
def open_street_map_enabled
ContentConfig.open_street_map_enabled
@@ -15,7 +17,15 @@ module Api
end
def open_street_map_provider_options
- ContentConfig.open_street_map_provider_options.to_json
+ ContentConfig.open_street_map_provider_options
+ end
+
+ def open_street_map_default_latitude
+ ContentConfig.open_street_map_default_latitude
+ end
+
+ def open_street_map_default_longitude
+ ContentConfig.open_street_map_default_longitude
end
end
end
diff --git a/app/serializers/api/taxon_image_serializer.rb b/app/serializers/api/taxon_image_serializer.rb
deleted file mode 100644
index bc920637cd..0000000000
--- a/app/serializers/api/taxon_image_serializer.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-class Api::TaxonImageSerializer < ActiveModel::Serializer
- attributes :id, :alt, :small_url, :large_url
-
- def small_url
- object.attachment.url(:small, false)
- end
-
- def large_url
- object.attachment.url(:large, false)
- end
-end
diff --git a/app/serializers/api/taxon_serializer.rb b/app/serializers/api/taxon_serializer.rb
index 775c069a41..43d3ddefd9 100644
--- a/app/serializers/api/taxon_serializer.rb
+++ b/app/serializers/api/taxon_serializer.rb
@@ -2,9 +2,5 @@ class Api::TaxonSerializer < ActiveModel::Serializer
cached
delegate :cache_key, to: :object
- attributes :id, :name, :permalink, :icon, :pretty_name, :position, :parent_id, :taxonomy_id
-
- def icon
- object.icon(:original)
- end
+ attributes :id, :name, :permalink, :pretty_name, :position, :parent_id, :taxonomy_id
end
diff --git a/app/services/advance_order_service.rb b/app/services/advance_order_service.rb
deleted file mode 100644
index 1377c36147..0000000000
--- a/app/services/advance_order_service.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-class AdvanceOrderService
- attr_reader :order
-
- def initialize(order)
- @order = order
- end
-
- def call
- advance_order(advance_order_options)
- end
-
- def call!
- advance_order!(advance_order_options)
- end
-
- private
-
- def advance_order_options
- shipping_method_id = order.shipping_method.id if order.shipping_method.present?
- { shipping_method_id: shipping_method_id }
- end
-
- def advance_order(options)
- until order.state == "complete"
- break unless order.next
-
- after_transition_hook(options)
- end
- end
-
- def advance_order!(options)
- until order.completed?
- order.next!
- after_transition_hook(options)
- end
- end
-
- def after_transition_hook(options)
- if order.state == "delivery"
- order.select_shipping_method(options[:shipping_method_id]) if options[:shipping_method_id]
- end
- end
-end
diff --git a/app/services/checkout/form_data_adapter.rb b/app/services/checkout/form_data_adapter.rb
index a374444637..1333ed5dbd 100644
--- a/app/services/checkout/form_data_adapter.rb
+++ b/app/services/checkout/form_data_adapter.rb
@@ -12,6 +12,8 @@ module Checkout
move_payment_source_to_payment_attributes!
+ fill_in_card_type
+
set_amount_in_payments_attributes
construct_saved_card_attributes if @params[:order][:existing_card_id]
@@ -31,6 +33,28 @@ module Checkout
@params[:order][:payments_attributes].first[:source_attributes] = payment_source_params
end
+ # Ensures cc_type is always passed to the model by inferring the type when
+ # the frontend didn't provide it. This fixes Pin Payments specifically
+ # although it might be useful for future payment gateways.
+ #
+ # More details: app/assets/javascripts/darkswarm/services/checkout.js.coffee#L70-L98
+ def fill_in_card_type
+ return unless payment_source_attributes
+
+ return if payment_source_attributes.dig(:number).blank?
+
+ payment_source_attributes[:cc_type] ||= card_brand(payment_source_attributes[:number])
+ end
+
+ def payment_source_attributes
+ @payment_source_attributes ||=
+ params[:order][:payments_attributes]&.first&.dig(:source_attributes)
+ end
+
+ def card_brand(number)
+ ActiveMerchant::Billing::CreditCard.brand?(number)
+ end
+
def delete_payment_source_params!
@params.delete(:payment_source)[
@params[:order][:payments_attributes].first[:payment_method_id].underscore
diff --git a/app/services/order_adjustments_fetcher.rb b/app/services/order_adjustments_fetcher.rb
index 40d78cf6bc..560f04bdb1 100644
--- a/app/services/order_adjustments_fetcher.rb
+++ b/app/services/order_adjustments_fetcher.rb
@@ -57,11 +57,12 @@ class OrderAdjustmentsFetcher
if adjustments_eager_loaded?
adjustment_scope = public_send("#{scope}_scope")
+ # Adjustments are already loaded here, this block is using `Array#select`
adjustments.select do |adjustment|
- match_by_scope(adjustment, adjustment_scope)
+ match_by_scope(adjustment, adjustment_scope) && match_by_scope(adjustment, eligible_scope)
end
else
- adjustments.where(nil).public_send scope
+ adjustments.where(nil).eligible.public_send scope
end
end
diff --git a/app/services/order_workflow.rb b/app/services/order_workflow.rb
new file mode 100644
index 0000000000..b55ed43ce1
--- /dev/null
+++ b/app/services/order_workflow.rb
@@ -0,0 +1,79 @@
+class OrderWorkflow
+ attr_reader :order
+
+ def initialize(order)
+ @order = order
+ end
+
+ def complete
+ advance_order(advance_order_options)
+ end
+
+ def complete!
+ advance_order!(advance_order_options)
+ end
+
+ def next(options = {})
+ result = advance_order_one_step
+
+ after_transition_hook(options)
+
+ result
+ end
+
+ private
+
+ def advance_order_options
+ shipping_method_id = order.shipping_method.id if order.shipping_method.present?
+ { shipping_method_id: shipping_method_id }
+ end
+
+ def advance_order(options)
+ until order.state == "complete"
+ break unless order.next
+
+ after_transition_hook(options)
+ end
+ end
+
+ def advance_order!(options)
+ until order.completed?
+ order.next!
+ after_transition_hook(options)
+ end
+ end
+
+ def advance_order_one_step
+ tries ||= 3
+ order.next
+ rescue ActiveRecord::StaleObjectError
+ retry unless (tries -= 1).zero?
+ false
+ end
+
+ def after_transition_hook(options)
+ if order.state == "delivery"
+ order.select_shipping_method(options[:shipping_method_id]) if options[:shipping_method_id]
+ end
+
+ persist_all_payments if order.state == "payment"
+ end
+
+ # When a payment fails, the order state machine stays in 'payment' and rollbacks all transactions
+ # This rollback also reverts the payment state from 'failed', 'void' or 'invalid' to 'pending'
+ # Despite the rollback, the in-memory payment still has the correct state, so we persist it
+ def persist_all_payments
+ order.payments.each do |payment|
+ in_memory_payment_state = payment.state
+ if different_from_db_payment_state?(in_memory_payment_state, payment.id)
+ payment.reload.update(state: in_memory_payment_state)
+ end
+ end
+ end
+
+ # Verifies if the in-memory payment state is different from the one stored in the database
+ # This is be done without reloading the payment so that in-memory data is not changed
+ def different_from_db_payment_state?(in_memory_payment_state, payment_id)
+ in_memory_payment_state != Spree::Payment.find(payment_id).state
+ end
+end
diff --git a/app/services/permitted_attributes/order_cycle.rb b/app/services/permitted_attributes/order_cycle.rb
index 41fd82bead..b81dccef0f 100644
--- a/app/services/permitted_attributes/order_cycle.rb
+++ b/app/services/permitted_attributes/order_cycle.rb
@@ -11,6 +11,7 @@ module PermittedAttributes
@params.require(:order_cycle).permit(
:name, :orders_open_at, :orders_close_at, :coordinator_id,
+ :preferred_product_selection_from_coordinator_inventory_only,
incoming_exchanges: permitted_exchange_attributes,
outgoing_exchanges: permitted_exchange_attributes,
schedule_ids: [], coordinator_fee_ids: []
diff --git a/app/views/admin/subscriptions/_form.html.haml b/app/views/admin/subscriptions/_form.html.haml
index 2b3a06673b..cfb4feddaf 100644
--- a/app/views/admin/subscriptions/_form.html.haml
+++ b/app/views/admin/subscriptions/_form.html.haml
@@ -4,7 +4,7 @@
%a.button{ href: main_app.admin_subscriptions_path, ng: { show: "['details','review'].indexOf(view) >= 0" } }= t(:cancel)
%input{ type: "button", value: t(:back), ng: { click: 'back()', show: '!!backCallbacks[view]'} }
%input.red{ type: "button", value: t(:next), ng: { click: 'next()', show: '!!nextCallbacks[view]' } }
- %input.red{ type: "submit", value: t('admin.subscriptions.create'), ng: { show: "view == 'review'" } }
+ %input.red{ type: "submit", value: t('.create'), ng: { show: "view == 'review'" } }
%div{ ng: { show: 'subscription.id' } }
%a.button{ href: main_app.admin_subscriptions_path }= t(:close)
%input.red{ type: "button", value: t(:review), ng: { click: "setView('review')", show: "view != 'review'" } }
diff --git a/app/views/admin/subscriptions/edit.html.haml b/app/views/admin/subscriptions/edit.html.haml
index 2084e9d761..51b4c40045 100644
--- a/app/views/admin/subscriptions/edit.html.haml
+++ b/app/views/admin/subscriptions/edit.html.haml
@@ -1,5 +1,5 @@
- content_for :page_title do
- =t('admin.subscriptions.edit')
+ =t('.title')
-# - content_for :page_actions do
-# %li= button_link_to "Back to subscriptions list", main_app.admin_subscriptions_path, icon: 'icon-arrow-left'
diff --git a/app/views/admin/subscriptions/index.html.haml b/app/views/admin/subscriptions/index.html.haml
index 4dd37c4f75..f6688693f7 100644
--- a/app/views/admin/subscriptions/index.html.haml
+++ b/app/views/admin/subscriptions/index.html.haml
@@ -1,5 +1,5 @@
- content_for :page_title do
- = t('admin.subscriptions.subscriptions')
+ = t('.title')
- content_for :main_ng_app_name do
= "admin.subscriptions"
@@ -7,7 +7,7 @@
- content_for :page_actions do
%li
%a.button.icon-plus#new-subscription{ href: "javascript:void(0)", "new-subscription-dialog" => true }
- = t('admin.subscriptions.new')
+ = t('.new')
= render :partial => 'spree/admin/shared/order_sub_menu'
diff --git a/app/views/admin/subscriptions/new.html.haml b/app/views/admin/subscriptions/new.html.haml
index c82824891c..6ac3749982 100644
--- a/app/views/admin/subscriptions/new.html.haml
+++ b/app/views/admin/subscriptions/new.html.haml
@@ -1,7 +1,7 @@
-# = render :partial => 'spree/shared/error_messages', :locals => { :target => @enterprise }
- content_for :page_title do
- =t('admin.subscriptions.new')
+ =t('.title')
-# - content_for :page_actions do
-# %li= button_link_to "Back to subscriptions list", main_app.admin_subscriptions_path, icon: 'icon-arrow-left'
diff --git a/app/views/admin/subscriptions/setup_explanation.html.haml b/app/views/admin/subscriptions/setup_explanation.html.haml
index 676483a55e..a3e7a8017e 100644
--- a/app/views/admin/subscriptions/setup_explanation.html.haml
+++ b/app/views/admin/subscriptions/setup_explanation.html.haml
@@ -1,4 +1,4 @@
-%h1.text-center.margin-bottom-30= t('admin.subscription.subscriptions')
+%h1.text-center.margin-bottom-30= t('.title')
.row
.four.columns.alpha
diff --git a/app/views/layouts/_bugsnag_js.html.haml b/app/views/layouts/_bugsnag_js.html.haml
index b9f3f5a736..9c3b3b9238 100644
--- a/app/views/layouts/_bugsnag_js.html.haml
+++ b/app/views/layouts/_bugsnag_js.html.haml
@@ -1,10 +1,8 @@
- bugsnag_js_key = ENV['BUGSNAG_JS_KEY'] || ENV['BUGSNAG_API_KEY']
- if bugsnag_js_key.present?
- %script{src: "//d2wy8f7a9ursnm.cloudfront.net/v6/bugsnag.min.js"}
+ %script{src: "//d2wy8f7a9ursnm.cloudfront.net/v7/bugsnag.min.js"}
:javascript
- window.bugsnagClient = bugsnag({
+ Bugsnag.start({
apiKey: "#{bugsnag_js_key}",
- beforeSend: function (report) {
- report.app.releaseStage = "#{Rails.env}"
- }
- });
+ releaseStage: "#{Rails.env}"
+ })
diff --git a/app/views/layouts/darkswarm.html.haml b/app/views/layouts/darkswarm.html.haml
index 7fd21a35d3..17f256124a 100644
--- a/app/views/layouts/darkswarm.html.haml
+++ b/app/views/layouts/darkswarm.html.haml
@@ -9,7 +9,7 @@
%meta{name: "robots", content: "noindex"}
%title= content_for?(:title) ? "#{yield(:title)} - #{t(:title)}".html_safe : "#{t(:welcome_to)} #{t(:title)}"
- if Rails.env.production?
- = favicon_link_tag
+ = favicon_link_tag "/favicon.ico"
- else
= favicon_link_tag "/favicon-staging.ico"
%link{href: "https://fonts.googleapis.com/css?family=Roboto:400,300italic,400italic,300,700,700italic|Oswald:300,400,700", rel: "stylesheet", type: "text/css"}
diff --git a/app/views/layouts/registration.html.haml b/app/views/layouts/registration.html.haml
index ebbcd9fd17..9f7e77612c 100644
--- a/app/views/layouts/registration.html.haml
+++ b/app/views/layouts/registration.html.haml
@@ -5,7 +5,7 @@
%title= content_for?(:title) ? "#{yield(:title)} - #{Spree::Config[:site_name]}" : "#{t(:welcome_to)} #{Spree::Config[:site_name]}"
- if Rails.env.production?
- = favicon_link_tag
+ = favicon_link_tag "/favicon.ico"
- else
= favicon_link_tag "/favicon-staging.ico"
%link{href: "https://fonts.googleapis.com/css?family=Roboto:400,300italic,400italic,300,700,700italic|Oswald:300,400,700", rel: "stylesheet", type: "text/css"}
diff --git a/app/views/producers/_fat.html.haml b/app/views/producers/_fat.html.haml
index 7712d43629..35156e3c51 100644
--- a/app/views/producers/_fat.html.haml
+++ b/app/views/producers/_fat.html.haml
@@ -22,7 +22,6 @@
%p.trans-sentence
%div
%span.fat-taxons{"ng-repeat" => "taxon in producer.supplied_taxons"}
- %render-svg{path: "{{taxon.icon}}"}
%span{"ng-bind" => "::taxon.name"}
%div
%span.fat-properties{"ng-repeat" => "property in producer.supplied_properties"}
@@ -79,8 +78,8 @@
.row.cta-container
.columns.small-12
%a.cta-hub{"ng-repeat" => "hub in producer.hubs | orderBy:'-active'",
- "ng-href" => "{{::hub.path}}", "ng-attr-target" => "_blank",
- "ng-class" => "::{primary: hub.active, secondary: !hub.active}", "target" => "_blank"}
+ "ng-href" => "{{::hub.path}}", "ng-attr-target" => "{{ embedded_layout ? '_blank' : undefined }}",
+ "ng-class" => "::{primary: hub.active, secondary: !hub.active}"}
%i.ofn-i_068-shop-reversed{"ng-if" => "::hub.active"}
%i.ofn-i_068-shop-reversed{"ng-if" => "::!hub.active"}
.hub-name{"ng-bind" => "::hub.name"}
diff --git a/app/views/producers/_skinny.html.haml b/app/views/producers/_skinny.html.haml
index 8664537362..6e05619d07 100644
--- a/app/views/producers/_skinny.html.haml
+++ b/app/views/producers/_skinny.html.haml
@@ -3,7 +3,7 @@
%span{"ng-if" => "::producer.is_distributor" }
.row.vertical-align-middle
.columns.small-12
- %a.is_distributor{"ng-href" => "{{::producer.path}}", "ng-attr-target" => "_blank", "data-is-link" => "true", "target" => "_blank"}
+ %a.is_distributor{"ng-href" => "{{::producer.path}}", "ng-attr-target" => "{{ embedded_layout ? '_blank' : undefined}}", "data-is-link" => "true"}
%i{ng: {class: "::producer.producer_icon_font"}}
%span.margin-top
%strong{"ng-bind" => "::producer.name"}
diff --git a/app/views/shared/menu/_cart_sidebar.html.haml b/app/views/shared/menu/_cart_sidebar.html.haml
index 03c3f52222..10bef792ab 100644
--- a/app/views/shared/menu/_cart_sidebar.html.haml
+++ b/app/views/shared/menu/_cart_sidebar.html.haml
@@ -1,4 +1,4 @@
-.expanding-sidebar.cart-sidebar{ng: {controller: 'CartCtrl', show: 'showCartSidebar', class: "{'shown': showCartSidebar, 'hidden': !showCartSidebar}"}}
+.expanding-sidebar.cart-sidebar{ng: {controller: 'CartCtrl', class: "{'shown': showCartSidebar}"}}
.background{ng: {click: 'toggleCartSidebar()'}}
.sidebar
.cart-header
diff --git a/app/views/shop/products/_searchbar.haml b/app/views/shop/products/_searchbar.haml
index f18d9b9382..bda087f4c7 100644
--- a/app/views/shop/products/_searchbar.haml
+++ b/app/views/shop/products/_searchbar.haml
@@ -6,7 +6,7 @@
type: 'search',
placeholder: t(:products_search),
"ng-debounce" => "200",
- "ofn-disable-enter" => true}
+ "disable-enter-with-blur" => true}
%a.clear{type: 'button', ng: {show: 'query', click: 'clearQuery()'}, 'focus-search' => true}
= image_tag "icn-close.png"
diff --git a/app/views/shop/products/_summary.html.haml b/app/views/shop/products/_summary.html.haml
index 628ae5a161..3c12a68db8 100644
--- a/app/views/shop/products/_summary.html.haml
+++ b/app/views/shop/products/_summary.html.haml
@@ -18,4 +18,3 @@
%span{"ng-bind" => "::enterprise.name"}
.small-2.medium-2.large-1.columns.text-center
.taxon-flag
- %render-svg{path: "{{::product.primary_taxon.icon}}"}
diff --git a/app/views/shops/_fat.html.haml b/app/views/shops/_fat.html.haml
index 56772bde40..cd5d9c6f45 100644
--- a/app/views/shops/_fat.html.haml
+++ b/app/views/shops/_fat.html.haml
@@ -10,7 +10,6 @@
.trans-sentence
%div
%span.fat-taxons{"ng-repeat" => "taxon in hub.taxons"}
- %render-svg{path: "{{taxon.icon}}"}
%span{"ng-bind" => "::taxon.name"}
%div
%span.fat-properties{"ng-repeat" => "property in hub.distributed_properties"}
diff --git a/app/views/spree/admin/adjustments/index.html.haml b/app/views/spree/admin/adjustments/index.html.haml
index 02433a6e5c..4aa8de7967 100644
--- a/app/views/spree/admin/adjustments/index.html.haml
+++ b/app/views/spree/admin/adjustments/index.html.haml
@@ -7,6 +7,7 @@
- content_for :page_actions do
%li= button_link_to t(:new_adjustment), new_admin_order_adjustment_url(@order), :icon => 'icon-plus'
+ = render partial: 'spree/admin/shared/order_links'
%li= button_link_to t(:back_to_orders_list), admin_orders_path, :icon => 'icon-arrow-left'
= render :partial => 'adjustments_table'
diff --git a/app/views/spree/admin/orders/bulk_management.html.haml b/app/views/spree/admin/orders/bulk_management.html.haml
index 1053235c67..644a9531e4 100644
--- a/app/views/spree/admin/orders/bulk_management.html.haml
+++ b/app/views/spree/admin/orders/bulk_management.html.haml
@@ -151,7 +151,7 @@
%th.final_weight_volume{ 'ng-show' => 'columns.final_weight_volume.visible' }
= t("admin.orders.bulk_management.weight_volume")
%th.price{ 'ng-show' => 'columns.price.visible' }
- = t("admin.price (#{currency_symbol})")
+ = "#{t('admin.price')} (#{currency_symbol})"
%th.actions
%th.actions
= t("admin.orders.bulk_management.ask")
diff --git a/app/views/spree/admin/orders/customer_details/edit.html.haml b/app/views/spree/admin/orders/customer_details/edit.html.haml
index 584c3350b9..765224d247 100644
--- a/app/views/spree/admin/orders/customer_details/edit.html.haml
+++ b/app/views/spree/admin/orders/customer_details/edit.html.haml
@@ -8,6 +8,7 @@
= Spree.t(:customer_details)
- content_for :page_actions do
+ = render partial: 'spree/admin/shared/order_links'
%li= button_link_to Spree.t(:back_to_orders_list), admin_orders_path, :icon => 'icon-arrow-left'
- if @order.cart? || @order.address?
diff --git a/app/views/spree/admin/orders/edit.html.haml b/app/views/spree/admin/orders/edit.html.haml
index d2047e6bf4..ada2ff5953 100644
--- a/app/views/spree/admin/orders/edit.html.haml
+++ b/app/views/spree/admin/orders/edit.html.haml
@@ -4,7 +4,7 @@
%li= event_links
- if can?(:resend, @order)
%li= button_link_to Spree.t(:resend), resend_admin_order_url(@order), :method => :post, :icon => 'icon-email'
- %li.links-dropdown#links-dropdown{ links: order_links(@order).to_json }
+ = render partial: 'spree/admin/shared/order_links'
- if can?(:admin, Spree::Order)
%li= button_link_to t(:back_to_orders_list), admin_orders_path, :icon => 'icon-arrow-left'
@@ -29,6 +29,3 @@
%div{"data-hook" => "admin_order_edit_form"}
= render :partial => 'form', :locals => { :order => @order }
-
-:coffee
- angular.bootstrap(document.getElementById("links-dropdown"),['admin.dropdown'])
diff --git a/app/views/spree/admin/overview/single_enterprise_dashboard.html.haml b/app/views/spree/admin/overview/single_enterprise_dashboard.html.haml
index caa8e925c4..e53f9e436e 100644
--- a/app/views/spree/admin/overview/single_enterprise_dashboard.html.haml
+++ b/app/views/spree/admin/overview/single_enterprise_dashboard.html.haml
@@ -37,13 +37,10 @@
.alpha.seven.columns.dashboard_item.single-ent#map
.header
%h3
- %span.icon-map-marker
+ %span.icon-user
= t "your_profil_live"
- %p
- = t "on_ofn_map"
.list
- /-# Can we pass an anchor here to zoom to our enterprise?
- %a.button.bottom{href: main_app.map_path, target: '_blank'}
+ %a.button.bottom{href: main_app.enterprise_shop_url(@enterprise), target: '_blank'}
= t "see"
= @enterprise.name
= t "live"
diff --git a/app/views/spree/admin/payments/index.html.haml b/app/views/spree/admin/payments/index.html.haml
index 7fbe76429f..c06a473479 100644
--- a/app/views/spree/admin/payments/index.html.haml
+++ b/app/views/spree/admin/payments/index.html.haml
@@ -5,6 +5,7 @@
- if @order.outstanding_balance?
%li#new_payment_section
= button_link_to t(:new_payment), new_admin_order_payment_url(@order), icon: 'icon-plus'
+ = render partial: 'spree/admin/shared/order_links'
%li= button_link_to t(:back_to_orders_list), admin_orders_path, icon: 'icon-arrow-left'
- content_for :page_title do
diff --git a/app/views/spree/admin/payments/source_forms/_paypal.html.haml b/app/views/spree/admin/payments/source_forms/_paypal.html.haml
index e26db66846..124139dae0 100644
--- a/app/views/spree/admin/payments/source_forms/_paypal.html.haml
+++ b/app/views/spree/admin/payments/source_forms/_paypal.html.haml
@@ -5,4 +5,4 @@
-# of the views we are using, so the warning below wasn't displaying without this override.
#paypal-warning
- %strong= t('no_payment_via_admin_backend', :scope => 'paypal')
+ %strong= t('.no_payment_via_admin_backend', :scope => 'paypal')
diff --git a/app/views/spree/admin/return_authorizations/index.html.haml b/app/views/spree/admin/return_authorizations/index.html.haml
index bc8ed9dd80..390551307c 100644
--- a/app/views/spree/admin/return_authorizations/index.html.haml
+++ b/app/views/spree/admin/return_authorizations/index.html.haml
@@ -5,6 +5,7 @@
- if @order.shipments.any? &:shipped?
%li
= button_link_to t('.new_return_authorization'), new_admin_order_return_authorization_url(@order), icon: 'icon-plus'
+ = render partial: 'spree/admin/shared/order_links'
%li= button_link_to t('.back_to_orders_list'), spree.admin_orders_path, icon: 'icon-arrow-left'
- content_for :page_title do
diff --git a/app/views/spree/admin/shared/_order_links.html.haml b/app/views/spree/admin/shared/_order_links.html.haml
new file mode 100644
index 0000000000..352371c04a
--- /dev/null
+++ b/app/views/spree/admin/shared/_order_links.html.haml
@@ -0,0 +1,4 @@
+%li.links-dropdown#links-dropdown{ links: order_links(@order).to_json }
+
+:coffee
+ angular.bootstrap(document.getElementById("links-dropdown"),['admin.dropdown'])
diff --git a/app/views/spree/admin/taxons/_form.html.haml b/app/views/spree/admin/taxons/_form.html.haml
index 72ba498a4d..a23a55be0f 100644
--- a/app/views/spree/admin/taxons/_form.html.haml
+++ b/app/views/spree/admin/taxons/_form.html.haml
@@ -12,11 +12,6 @@
%br/
= @taxon.permalink.split("/")[0...-1].join("/") + "/"
= text_field_tag :permalink_part, @permalink_part
- = f.field_container :icon do
- = f.label :icon, t(:icon)
- %br/
- = f.file_field :icon
- %img{src: @taxon.icon(:original)}
= f.field_container :meta_title do
= f.label :meta_title, t(:meta_title)
%br/
diff --git a/app/views/spree/layouts/_admin_body.html.haml b/app/views/spree/layouts/_admin_body.html.haml
index d5aa05dbee..7b1d643dee 100644
--- a/app/views/spree/layouts/_admin_body.html.haml
+++ b/app/views/spree/layouts/_admin_body.html.haml
@@ -66,4 +66,4 @@
%div{"data-hook" => "admin_footer_scripts"}
%script
- = raw "Spree.api_key = \"#{try_spree_current_user.try(:spree_api_key).to_s}\";"
+ = raw "Spree.api_key = \"#{spree_current_user.try(:spree_api_key).to_s}\";"
diff --git a/app/views/spree/shipment_mailer/shipped_email.html.haml b/app/views/spree/shipment_mailer/shipped_email.html.haml
new file mode 100644
index 0000000000..c5675a6975
--- /dev/null
+++ b/app/views/spree/shipment_mailer/shipped_email.html.haml
@@ -0,0 +1,30 @@
+%p
+ = t('.dear_customer')
+%p
+ = t('.instructions')
+
+%p
+ = "============================================================"
+ %br
+ = t('.shipment_summary')
+ %br
+ = "============================================================"
+
+%p
+ - @shipment.manifest.each do |item|
+ = item.variant.sku
+ = item.variant.product.name
+ = item.variant.options_text
+ %br
+ = "============================================================"
+
+- if @shipment.tracking
+ %p
+ = t('.track_information', tracking: @shipment.tracking)
+
+- if @shipment.tracking_url
+ %p
+ = t('.track_link', url: @shipment.tracking_url)
+
+%p
+ = t('.thanks')
diff --git a/app/views/spree/test_mailer/test_email.html.haml b/app/views/spree/test_mailer/test_email.html.haml
new file mode 100644
index 0000000000..6f9e2e771c
--- /dev/null
+++ b/app/views/spree/test_mailer/test_email.html.haml
@@ -0,0 +1,4 @@
+= t('.greeting')
+= "================"
+
+= t('.message')
diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb
index e20b748148..5a101fbe4d 100644
--- a/config/initializers/devise.rb
+++ b/config/initializers/devise.rb
@@ -90,10 +90,6 @@ Devise.setup do |config|
# Time interval to unlock the account if :time is enabled as unlock_strategy.
# config.unlock_in = 1.hour
- # ==> Configuration for :token_authenticatable
- # Defines name of the authentication token params key
- config.token_authentication_key = :auth_token
-
# ==> Scopes configuration
# Turn scoped views on. Before rendering 'sessions/new', it will first check for
# 'users/sessions/new'. It's turned off by default because it's slower if you
@@ -141,3 +137,8 @@ Devise.setup do |config|
config.case_insensitive_keys = [:email]
end
+
+Devise::TokenAuthenticatable.setup do |config|
+ # Defines name of the authentication token params key
+ config.token_authentication_key = :auth_token
+end
diff --git a/config/initializers/spree.rb b/config/initializers/spree.rb
index 6ff230c5f5..9280befea3 100644
--- a/config/initializers/spree.rb
+++ b/config/initializers/spree.rb
@@ -6,6 +6,7 @@
# In order to initialize a setting do:
# config.setting_name = 'new value'
+require "spree/core/environment"
require 'spree/product_filters'
# Due to a bug in ActiveRecord we need to load the tagging code in Gateway which
@@ -17,9 +18,6 @@ Spree::Gateway.class_eval do
acts_as_taggable
end
-require "#{Rails.root}/app/models/spree/payment_method_decorator"
-require "#{Rails.root}/app/models/spree/gateway_decorator"
-
Spree.config do |config|
config.shipping_instructions = true
config.address_requires_state = true
@@ -30,8 +28,6 @@ Spree.config do |config|
config.auto_capture = true
#config.override_actionmailer_config = false
- config.order_updater_decorator = OrderUpdater
-
# S3 settings
config.s3_bucket = ENV['S3_BUCKET'] if ENV['S3_BUCKET']
config.s3_access_key = ENV['S3_ACCESS_KEY'] if ENV['S3_ACCESS_KEY']
diff --git a/config/locales/ar.yml b/config/locales/ar.yml
index a2dc262509..728504b5d3 100644
--- a/config/locales/ar.yml
+++ b/config/locales/ar.yml
@@ -13,6 +13,8 @@ ar:
email: الايميل الالكتروني للعميل
spree/payment:
amount: القيمة
+ state: ولاية
+ source: المصدر
spree/product:
primary_taxon: "نوع المنتج "
supplier: "المورد"
@@ -33,6 +35,10 @@ ar:
taken: "يوجد حساب متصل بهذا الايميل.\nالرجاء الدخول او اعادة تعيين كلمة السر."
spree/order:
no_card: لا يوجد بطاقة ائتمان معتمدة متاحة لاتمام عملية الدفع
+ spree/credit_card:
+ attributes:
+ base:
+ card_expired: "انتهت صلاحيته"
order_cycle:
attributes:
orders_close_at:
@@ -178,6 +184,7 @@ ar:
explainer: فشلت المعالجة التلقائية لهذه الطلبات لسبب غير معروف. لا ينبغي أن يحدث هذا ، يرجى الاتصال بنا إذا كنت ترى هذا.
home: "OFN"
title: "شبكة الغذاء المفتوح"
+ welcome_to: "مرحبا بك في"
site_meta_description: "نبدأ من الألف إلى الياء. مع المزارعين والمزارعين على استعداد لرواية قصصهم بفخر وحق. مع الموزعين على استعداد لتوصيل الأشخاص بالمنتجات بطريقة عادلة وبصدق. مع المشترين الذين يعتقدون أن أفضل قرارات التسوق الأسبوعية يمكن ..."
search_by_name: البحث بالاسم أو الضاحية ...
producers_join: المنتجون الأستراليون مدعوون الآن للانضمام إلى شبكة الغذاء المفتوح.
@@ -266,6 +273,9 @@ ar:
on hand: "متوفر"
ship: "الشحن"
shipping_category: "نوع الشحن"
+ height: "الارتفاع"
+ width: "العرض"
+ depth: "العمق"
actions:
create_and_add_another: "إنشاء وإضافة آخر"
create: "انشاء"
@@ -321,6 +331,7 @@ ar:
show_n_more: عرض %{num} أكثر
choose: "أختر..."
please_select: الرجاء اختيار ...
+ column_save_as_default: إحفظ كافتراض اساسي
columns: أعمدة
actions: أجراءات
viewing: "عرض: %{current_view_name}"
@@ -365,7 +376,10 @@ ar:
title: "إعدادات Matomo"
matomo_url: "العنوان الالكتروني ل Matomo "
matomo_site_id: "معرف موقع Matomo"
+ matomo_tag_manager_url: "عنوان URL لبرنامج Matomo "
+ info_html: "ماتومو هو تطبيق تحليلات الويب والجوال. يمكنك اضافة Matomo محليًا أو استخدام خدمة مستضافة على السحابة. انظر matomo.org لمزيد من المعلومات."
config_instructions_html: "هنا يمكنك تهيئة تكامل Matomo لشبكة الغذاء المفتوح. يجب أن يشير عنوان الالكتروني URL الخاص بـ Matomo أدناه إلى مثيل Matomo حيث سيتم إرسال معلومات تتبع المستخدم إلى ؛ إذا تم تركه فارغًا ، فسيتم تعطيل تتبع مستخدم Matomo. حقل معرف الموقع ليس إلزاميًا ولكنه مفيد إذا كنت تتعقب أكثر من موقع ويب على مثيل Matomo ؛ يمكن العثور عليه على وحدة تحكم مثيل Matomo."
+ config_instructions_tag_manager_html: "يؤدي تعيين عنوان URL لبرنامج Matomo إلى تمكين Matomo . تتيح لك هذه الأداة إعداد أحداث التحليلات. يتم نسخ عنوان URL لبرنامج Matomo من قسم كود التثبيت في Manager. تأكد من تحديد الحاوية والبيئة المناسبة لأن هذه الخيارات تغير عنوان URL."
customers:
index:
new_customer: "عميل جديد"
@@ -471,6 +485,7 @@ ar:
line_number: "السطر %{number}:"
encoding_error: "يرجى التحقق من إعداد اللغة للملف المصدر والتأكد من حفظه بترميز UTF-8"
unexpected_error: "واجه استيراد المنتج خطأ غير متوقع أثناء فتح الملف: %{error_message}"
+ malformed_csv: "صادف استيراد المنتج ملف CSV مشوه: %{error_message}"
index:
notice: "تنويه"
beta_notice: "لا تزال هذه الميزة تجريبية: قد تواجه بعض الأخطاء أثناء استخدامها. من فضلك لا تتردد في الاتصال بالدعم."
@@ -683,6 +698,7 @@ ar:
ofn_uid_tip: المعرف الفريد المستخدم لتحديد الشركة على شبكة الغذاء المفتوح.
shipping_methods:
name: "اسم"
+ applies: "نشيط؟"
manage: "إدارة طرق الشحن"
create_button: "إنشاء طريقة شحن جديدة"
create_one_button: "إنشاء واحدة الآن"
@@ -860,6 +876,7 @@ ar:
incoming: "الوارد"
supplier: "المورد"
products: "منتجات"
+ receival_details: "تفاصيل الاستلام"
fees: "رسوم"
save: "حفظ"
save_and_next: "حفظ والتالي"
@@ -871,6 +888,7 @@ ar:
distributor: "الموزع"
products: "منتجات"
tags: "الاوسمة"
+ delivery_details: "تفاصيل التسليم"
fees: "رسوم"
previous: "السابق"
save: "حفظ"
@@ -1020,10 +1038,13 @@ ar:
name: "ملخص رسوم الشركات"
description: "ملخص رسوم الشركات التي تم جمعها"
subscriptions:
- subscriptions: الاشتراكات
- new: اشتراك جديد
- create: إنشاء اشتراك
- edit: تحرير الاشتراك
+ index:
+ title: "الاشتراكات"
+ new: "اشتراك جديد"
+ new:
+ title: "اشتراك جديد"
+ edit:
+ title: "تحرير الاشتراك"
table:
edit_subscription: تحرير الاشتراك
pause_subscription: وقف مؤقت الاشتراك
@@ -1032,6 +1053,7 @@ ar:
filters:
query_placeholder: "البحث عن طريق البريد الإلكتروني ..."
setup_explanation:
+ title: "الاشتراكات"
just_a_few_more_steps: 'فقط بضع خطوات أخرى قبل أن تبدأ:'
enable_subscriptions: "تمكين الاشتراكات في واحد على الأقل من المتاجر الخاصة بك"
enable_subscriptions_step_1_html: 1. انتقل إلى صفحة %{enterprises_link} ، وابحث عن متجرك ، وانقر على "إدارة"
@@ -1045,6 +1067,8 @@ ar:
create_at_least_one_schedule_step_3: 3. انقر فوق "+ جدول جديد" ، واملأ النموذج
once_you_are_done_you_can_html: بمجرد الانتهاء من ذلك ، يمكنك %{reload_this_page_link}
reload_this_page: اعد تحميل هذه الصفحة
+ form:
+ create: "إنشاء اشتراك"
steps:
details: 1. التفاصيل الأساسية
address: 2. العنوان
@@ -1136,7 +1160,12 @@ ar:
cart: "سلة"
cart_sidebar:
checkout: "تابع للخروج"
+ edit_cart: "تعديل سلة التسوق"
+ items_in_cart_singular: "%{num} عنصر في سلة التسوق الخاصة بك"
+ items_in_cart_plural: "%{num} العناصر في سلة التسوق الخاصة بك"
close: "إغلاق"
+ cart_empty: "سلة التسوق فارغة"
+ take_me_shopping: "خذني للتسوق!"
signed_in:
profile: "الملف الشخصي"
mobile_menu:
@@ -1168,7 +1197,11 @@ ar:
signup: "سجل"
contact: "اتصل"
require_customer_login: "يمكن للعملاء المعتمدين فقط الوصول إلى هذا المتجر."
+ require_login_html: "إذا كنت عميلاً معتمدًا بالفعل ، %{login} أو %{signup} للمتابعة."
+ require_login_2_html: "تريد أن تبدأ التسوق هنا؟ من فضلك %{contact} %{enterprise} واسأل عن الانضمام."
require_customer_html: "إذا كنت ترغب في بدء التسوق هنا ، فيرجى %{contact} %{enterprise} أن تسأل عن الانضمام."
+ select_oc:
+ select_oc_html: "يرجى اختيار الوقت الذي تريده لطلبك ، لمعرفة المنتجات المتوفرة."
card_could_not_be_updated: لا يمكن تحديث البطاقة
card_could_not_be_saved: لا يمكن حفظ البطاقة
spree_gateway_error_flash_for_checkout: "حدثت مشكلة في معلومات الدفع الخاصة بك: %{error}"
@@ -1280,6 +1313,8 @@ ar:
cart_updating: "جارٍ تحديث العربة ..."
cart_empty: "السلة فارغة"
cart_edit: "تعديل عربة التسوق"
+ item: "بند"
+ qty: "الكمية"
card_number: رقم البطاقة
card_securitycode: "رمز الحماية"
card_expiry_date: تاريخ الانتهاء
@@ -1532,12 +1567,17 @@ ar:
orders_changeable_orders_alert_html: تم تأكيد هذا الطلب ، ولكن يمكنك إجراء تغييرات حتى %{oc_close} .
products_clear: ازالة
products_showing: "عرض:"
+ products_results_for: "نتائج"
products_or: "أو"
products_and: "و"
+ products_filters_in: "في"
products_with: مع
+ products_search: "بحث..."
products_filter_by: "مرشح بواسطة"
products_filter_selected: "تم الاختيار"
+ products_filter_heading: "المرشحات"
products_filter_clear: "ازالة"
+ products_filter_done: "تم"
products_loading: "جارٍ تحميل المنتجات ..."
products_updating_cart: "جارٍ تحديث سلة المشتريات..."
products_cart_empty: "السلة فارغة"
@@ -1548,6 +1588,8 @@ ar:
products_update_error_msg: "فشل الحفظ."
products_update_error_data: "فشل الحفظ بسبب بيانات غير صالحة:"
products_changes_saved: "تم حفظ التغييرات."
+ products_no_results_html: "عذرا ، لم يتم العثور على نتائج لـ %{query}"
+ products_clear_search: "مسح البحث"
search_no_results_html: "عذرًا ، لم يتم العثور على نتائج لـ %{query}. جرب بحث آخر؟"
components_profiles_popover: "لا تملك ملفات التعريف واجهة متجر على شبكة الغذاء المفتوح ، ولكن قد يكون لها متجر على ارض الواقع أو عبر الإنترنت في أي مكان آخر"
components_profiles_show: "إظهار الملفات الشخصية"
@@ -1692,6 +1734,7 @@ ar:
remember_me: تذكرنى
are_you_sure: "هل أنت واثق؟"
orders_open: "الطلب مفتوح"
+ closing: "إغلاق"
going_back_to_home_page: "الرجوع إلى الصفحة الرئيسية"
creating: انشاء
updating: تحديث
@@ -1906,6 +1949,7 @@ ar:
admin_enterprise_relationships_permits: "تسمح"
admin_enterprise_relationships_seach_placeholder: "بحث"
admin_enterprise_relationships_button_create: "انشاء"
+ admin_enterprise_relationships_to: "إلى"
admin_enterprise_groups: "مجموعات المؤسسة"
admin_enterprise_groups_name: "اسم"
admin_enterprise_groups_owner: "المالك"
@@ -1934,6 +1978,8 @@ ar:
supplier: "المورد"
product_name: "اسم المنتج"
product_description: "وصف المنتج"
+ permalink: "الرابط الثابت"
+ shipping_categories: "فئات الشحن"
units: "حجم الوحدة"
coordinator: "منسق"
distributor: "الموزع"
@@ -2030,6 +2076,8 @@ ar:
remove_tax: "إزالة الضريبة"
first_name_begins_with: "الاسم الأول يبدأ بـ"
last_name_begins_with: "اسم العائلة يبدأ بـ"
+ shipping_method: "طريقة الشحن"
+ new_order: "طلب جديد"
enterprise_tos_link: "شروط المؤسسة لخدمة الرابط"
enterprise_tos_message: "نريد العمل مع أشخاص يشاركوننا أهدافنا وقيمنا. على هذا النحو ، نطلب من المؤسسات الجديدة الموافقة على"
enterprise_tos_link_text: "شروط الخدمة."
@@ -2048,6 +2096,7 @@ ar:
hub_sidebar_at_least: "يجب تحديد مركز واحد على الأقل"
hub_sidebar_blue: "أزرق"
hub_sidebar_red: "أحمر"
+ order_cycles_closed_for_hub: "المحور الذي حددته مغلق مؤقتًا للطلبات. الرجاء معاودة المحاولة في وقت لاحق."
report_customers_distributor: "الموزع"
report_customers_supplier: "المورد"
report_customers_cycle: "ترتيب الدورة"
@@ -2282,6 +2331,7 @@ ar:
order_cycles_email_to_producers_notice: 'رسائل البريد الإلكتروني المراد إرسالها إلى المنتجين تم وضعها في قائمة الانتظار للإرسال.'
order_cycles_no_permission_to_coordinate_error: "لا تملك أي من مؤسساتك إذنًا لتنسيق دورة الطلب"
order_cycles_no_permission_to_create_error: "ليس لديك إذن لإنشاء دورة طلب تنسقها تلك المؤسسة"
+ order_cycle_closed: "تم إغلاق دورة الطلب التي حددتها للتو. حاول مرة اخرى!"
back_to_orders_list: "العودة إلى قائمة الطلب"
no_orders_found: "لم يتم العثور على أية طلبات"
order_information: "معلومات الطلب"
@@ -2309,6 +2359,10 @@ ar:
resolve_errors: يرجى حل الأخطاء التالية
more_items: "+ %{count} ايضا"
default_card_updated: تم تحديث البطاقة الافتراضية
+ cart:
+ add_to_cart_failed: >
+ حدثت مشكلة أثناء إضافة هذا المنتج إلى عربة التسوق. ربما أصبح غير متوفر أو
+ أن المحل يغلق.
admin:
enterprise_limit_reached: "لقد وصلت إلى الحد القياسي للمؤسسات لكل حساب. اكتب %{contact_email} إذا كنت بحاجة إلى زيادته."
modals:
@@ -2593,6 +2647,13 @@ ar:
few: "كل"
many: "كل"
other: "كل"
+ bunch:
+ zero: "عناقيد"
+ one: "حفنة"
+ two: "عناقيد"
+ few: "عناقيد"
+ many: "عناقيد"
+ other: "عناقيد"
pack:
zero: "حزم"
one: "رزمة"
@@ -2600,6 +2661,13 @@ ar:
few: "حزم"
many: "حزم"
other: "حزم"
+ box:
+ zero: "مربعات"
+ one: "صندوق"
+ two: "مربعات"
+ few: "مربعات"
+ many: "مربعات"
+ other: "بكسات"
bottle:
zero: "زجاجات"
one: "زجاجة"
@@ -2607,6 +2675,62 @@ ar:
few: "زجاجات"
many: "زجاجات"
other: "زجاجات"
+ jar:
+ zero: "الجرار"
+ one: "إناء"
+ two: "الجرار"
+ few: "الجرار"
+ many: "الجرار"
+ other: "مرتبان"
+ head:
+ zero: "رؤساء"
+ one: "رئيس"
+ two: "رؤساء"
+ few: "رؤساء"
+ many: "رؤساء"
+ other: "رؤوس"
+ bag:
+ zero: "أكياس"
+ one: "كيس"
+ two: "أكياس"
+ few: "أكياس"
+ many: "أكياس"
+ other: "أكياس"
+ loaf:
+ zero: "أرغفة"
+ one: "رغيف"
+ two: "أرغفة"
+ few: "أرغفة"
+ many: "أرغفة"
+ other: "أرغفة"
+ single:
+ zero: "الفردي"
+ one: "غير مرتبطة"
+ two: "الفردي"
+ few: "الفردي"
+ many: "الفردي"
+ other: "الفردي"
+ tub:
+ zero: "أحواض"
+ one: "حوض"
+ two: "أحواض"
+ few: "أحواض"
+ many: "أحواض"
+ other: "أحواض"
+ punnet:
+ zero: "سلات"
+ one: "إناء"
+ two: "سلات"
+ few: "سلات"
+ many: "سلات"
+ other: "سلات"
+ packet:
+ zero: "الحزم"
+ one: "رزمة"
+ two: "الحزم"
+ few: "الحزم"
+ many: "الحزم"
+ other: "الحزم"
item:
zero: "العناصر"
one: "بند"
@@ -2628,6 +2752,62 @@ ar:
few: "الوحدات"
many: "الوحدات"
other: "الوحدات"
+ serve:
+ zero: "يخدم"
+ one: "تخدم"
+ two: "يخدم"
+ few: "يخدم"
+ many: "يخدم"
+ other: "خدمة"
+ tray:
+ zero: "صواني"
+ one: "صينية"
+ two: "صواني"
+ few: "صواني"
+ many: "صواني"
+ other: "صواني"
+ piece:
+ zero: "قطع"
+ one: "قطعة"
+ two: "قطع"
+ few: "قطع"
+ many: "قطع"
+ other: "قطع"
+ pot:
+ zero: "الأواني"
+ one: "وعاء"
+ two: "الأواني"
+ few: "الأواني"
+ many: "الأواني"
+ other: "اصص"
+ bundle:
+ zero: "حزم"
+ one: "حزمة"
+ two: "حزم"
+ few: "حزم"
+ many: "حزم"
+ other: "حزم"
+ flask:
+ zero: "قوارير"
+ one: "قارورة"
+ two: "قوارير"
+ few: "قوارير"
+ many: "قوارير"
+ other: "قوارير"
+ basket:
+ zero: "سلال"
+ one: "سلة"
+ two: "سلال"
+ few: "سلال"
+ many: "سلال"
+ other: "سلال"
+ sack:
+ zero: "أكياس"
+ one: "كيس"
+ two: "أكياس"
+ few: "أكياس"
+ many: "أكياس"
+ other: "أكياس"
producers:
signup:
start_free_profile: "ابدأ بملف تعريف مجاني ، وتوسع عندما تكون جاهزًا!"
@@ -2757,6 +2937,12 @@ ar:
void: "فارغ"
login: "تسجيل الدخول"
password: "كلمه السر"
+ signature: "التوقيع"
+ solution: "المحاليل"
+ landing_page: "الصفحة المقصودة"
+ server: "الخادم"
+ test_mode: "وضع الاختبار"
+ logourl: "وحدة"
configurations: "تهيئة"
general_settings: "الاعدادات العامة"
site_name: "اسم الموقع"
@@ -2873,6 +3059,16 @@ ar:
options: "خيارات"
actions:
update: "تحديث"
+ shared:
+ error_messages:
+ errors_prohibited_this_record_from_being_saved:
+ zero: "منعت أخطاء %{count} حفظ هذا السجل:"
+ one: "حظر خطأ واحد حفظ هذا السجل:"
+ two: "منعت أخطاء %{count} حفظ هذا السجل:"
+ few: "منعت أخطاء %{count} حفظ هذا السجل:"
+ many: "منعت أخطاء %{count} حفظ هذا السجل:"
+ other: "منعت أخطاء %{count} حفظ هذا السجل:"
+ there_were_problems_with_the_following_fields: "كانت هناك مشاكل مع الحقول التالية"
errors:
messages:
blank: "لا يمكن أن تكون فارغة"
@@ -3015,6 +3211,8 @@ ar:
zone: "منطقة"
calculator: "آلة حاسبة"
display: "عرض"
+ both: "كل من تسجيل الخروج والمكتب الخلفي"
+ back_end: "المكتب الخلفي فقط"
no_shipping_methods_found: "لم يتم العثور على طرق الشحن"
new:
new_shipping_method: "طريقة الشحن الجديدة"
@@ -3026,6 +3224,9 @@ ar:
form:
categories: "التصنيفات"
zones: "مناطق"
+ both: "كل من تسجيل الخروج والمكتب الخلفي"
+ back_end: "المكتب الخلفي فقط"
+ deactivation_warning: "يمكن أن يؤدي إلغاء تنشيط طريقة الشحن إلى اختفاء طريقة الشحن من قائمتك. بدلاً من ذلك ، يمكنك إخفاء طريقة الشحن من صفحة الخروج عن طريق تعيين الخيار\"عرض\" إلى\"المكتب الخلفي فقط\"."
payment_methods:
index:
payment_methods: "طريقة الدفع"
@@ -3037,8 +3238,11 @@ ar:
display: "عرض"
active: "نشط"
both: "على حد سواء"
+ front_end: "الخروج فقط"
+ back_end: "المكتب الخلفي فقط"
active_yes: "نعم"
active_no: "لا"
+ no_payment_methods_found: "لم يتم العثور على طرق دفع"
new:
new_payment_method: "طريقة الدفع الجديدة"
back_to_payment_methods_list: "العودة إلى قائمة طرق الدفع"
@@ -3067,7 +3271,11 @@ ar:
active: "نشط"
active_yes: "نعم"
active_no: "لا"
+ both: "كل من تسجيل الخروج والمكتب الخلفي"
+ front_end: "الخروج فقط"
+ back_end: "المكتب الخلفي فقط"
tags: "الاوسمة"
+ deactivation_warning: "يمكن أن يؤدي إلغاء تنشيط طريقة الدفع إلى اختفاء طريقة الدفع من قائمتك. بدلاً من ذلك ، يمكنك إخفاء طريقة الدفع من صفحة الخروج عن طريق تعيين الخيار \"عرض\" إلى\"المكتب الخلفي فقط\"."
providers:
provider: "مزود"
payments:
@@ -3075,6 +3283,8 @@ ar:
stripe:
error_saving_payment: خطأ في حفظ الدفعة
submitting_payment: تقديم الدفعة ...
+ paypal:
+ no_payment_via_admin_backend: لا يمكن التقاط مدفوعات Paypal في Backoffice
products:
image_upload_error: "لم يتم التعرف على صورة المنتج. يرجى تحميل صورة بتنسيق PNG أو JPG."
new:
@@ -3169,6 +3379,8 @@ ar:
price: "السعر"
display_as: "عرض ب"
display_name: "اسم العرض"
+ display_as_placeholder: 'على سبيل المثال 2 كجم'
+ display_name_placeholder: 'على سبيل المثال طماطم'
autocomplete:
out_of_stock: "غير متوفر"
producer_name: "المنتج"
@@ -3208,6 +3420,7 @@ ar:
format: '٪ س-٪ م-%d'
js_format: 'يوم-شهر-سنة'
orders:
+ error_flash_for_unavailable_items: "عنصر في سلة التسوق الخاصة بك أصبح غير متوفر. يرجى تحديث الكميات المحددة."
edit:
login_to_view_order: "يرجى تسجيل الدخول لعرض طلبك."
bought:
@@ -3235,12 +3448,46 @@ ar:
invalid: غير صالحة
order_mailer:
cancel_email:
+ customer_greeting: "عزيزي %{name} ،"
+ instructions_html: "تم إلغاء طلبك مع %{distributor} . يرجى الاحتفاظ بمعلومات الإلغاء هذه في سجلاتك."
+ dont_cancel: "إذا غيرت رأيك أو لا ترغب في إلغاء هذا الطلب ، فيرجى الاتصال بـ %{email}"
+ order_summary_canceled_html: "ملخص الطلب # %{number} [ملغي]"
+ details: "إليك تفاصيل ما طلبته:"
+ unpaid_order: "لم يتم سداد طلبك ، لذا لم يتم رد الأموال"
+ paid_order: "تم دفع طلبك حتى أعاد %{distributor} المبلغ بالكامل"
+ credit_order: "تم دفع طلبك حتى تم إضافة رصيد إلى حسابك"
subject: "إلغاء الطلب"
confirm_email:
subject: "تأكيد الطلب"
invoice_email:
hi: "مرحبًا %{name}"
invoice_attached_text: يرجى الاطلاع على فاتورة مرفقة لطلبك الأخير من
+ user_mailer:
+ reset_password_instructions:
+ request_sent_text: |
+ تم تقديم طلب لإعادة تعيين كلمة المرور الخاصة بك.
+ إذا لم تقدم هذا الطلب ، ببساطة تجاهل هذا البريد الإلكتروني.
+ link_text: >
+ إذا قمت بهذا الطلب ، فما عليك سوى النقر فوق الرابط أدناه:
+ issue_text: |
+ إذا لم يعمل عنوان URL أعلاه ، فحاول نسخه ولصقه في متصفحك.
+ إذا كنت لا تزال تواجه مشاكل ، فلا تتردد في الاتصال بنا.
+ confirmation_instructions:
+ subject: "يرجى تأكيد حسابك OFN"
+ shipment_mailer:
+ shipped_email:
+ dear_customer: "عزيزي العميل،"
+ instructions: "تم شحن طلبك"
+ shipment_summary: "ملخص الشحن"
+ subject: "إشعار الشحن"
+ thanks: "شكرا لك على اعمالك."
+ track_information: "معلومات التتبع : %{tracking}"
+ track_link: "رابط التتبع: %{url}"
+ test_mailer:
+ test_email:
+ greeting: "تهانينا!"
+ message: "إذا كنت قد تلقيت هذا البريد الإلكتروني ، فإن إعدادات بريدك الإلكتروني صحيحة."
+ subject: "اختبار البريد"
order_state:
address: العنوان
adjustments: التعديلات
@@ -3262,18 +3509,6 @@ ar:
ended: انتهى
paused: التعليق
canceled: الالغاء
- user_mailer:
- reset_password_instructions:
- request_sent_text: |
- تم تقديم طلب لإعادة تعيين كلمة المرور الخاصة بك.
- إذا لم تقدم هذا الطلب ، ببساطة تجاهل هذا البريد الإلكتروني.
- link_text: >
- إذا قمت بهذا الطلب ، فما عليك سوى النقر فوق الرابط أدناه:
- issue_text: |
- إذا لم يعمل عنوان URL أعلاه ، فحاول نسخه ولصقه في متصفحك.
- إذا كنت لا تزال تواجه مشاكل ، فلا تتردد في الاتصال بنا.
- confirmation_instructions:
- subject: يرجى تأكيد حسابك OFN
users:
form:
account_settings: إعدادت الحساب
diff --git a/config/locales/ca.yml b/config/locales/ca.yml
index a71b762573..c1ac9478a7 100644
--- a/config/locales/ca.yml
+++ b/config/locales/ca.yml
@@ -13,6 +13,8 @@ ca:
email: Correu electrònic de la consumidora
spree/payment:
amount: Import
+ state: Estat
+ source: Source
spree/product:
primary_taxon: "Categoria del producte"
supplier: "Proveïdora"
@@ -43,7 +45,7 @@ ca:
after_orders_open_at: s'ha de fer amb el termini obert
variant_override:
count_on_hand:
- using_producer_stock_settings_but_count_on_hand_set: "ha d'estar en blanc perquè s'utilitza la configuració de l'inventari de la productora"
+ using_producer_stock_settings_but_count_on_hand_set: "ha d'estar en blanc perquè s'utilitza la configuració d'estoc de la productora"
on_demand_but_count_on_hand_set: "ha d'estar en blanc si és sota demanda"
limited_stock_but_no_count_on_hand: "cal especificar-se perquè força existències limitades"
activemodel:
@@ -182,6 +184,7 @@ ca:
explainer: El processament automàtic d'aquestes comandes va fallar per un motiu desconegut. Això no hauria de passar, si us plau, contacteu amb nosaltres si esteu veient això.
home: "OFN"
title: "Open Food Network"
+ welcome_to: "Benvingut a "
site_meta_description: "Comencem des de baix. Amb agricultors i productors disposats a explicar les seves històries amb orgull i sinceritat. Amb distribuïdors connectant persones i productes de manera justa i honesta. Amb compradors que creuen que millors decisions de compra setmanal poden ..."
search_by_name: Cercar per nom o barri ...
producers_join: Els productors australians son ara benvinguts a unir-se a Open Food Network.
@@ -270,6 +273,9 @@ ca:
on hand: "Disponibles"
ship: "Enviament"
shipping_category: "Categoria d'enviament"
+ height: "Alçada"
+ width: "Amplada"
+ depth: "Profunditat"
actions:
create_and_add_another: "Crea i afegeix-ne una altra"
create: "Crear"
@@ -1036,10 +1042,13 @@ ca:
name: "Resum de les comissions de l'organització"
description: "Resum de les comissions de l'organització recollides"
subscriptions:
- subscriptions: Subscripcions
- new: Nova subscripció
- create: Crea una subscripció
- edit: Edita la subscripció
+ index:
+ title: "Subscripcions"
+ new: "Nova subscripció"
+ new:
+ title: "Nova subscripció"
+ edit:
+ title: "Edita la subscripció"
table:
edit_subscription: Edita la subscripció
pause_subscription: Pausa la subscripció
@@ -1048,6 +1057,7 @@ ca:
filters:
query_placeholder: "Cerca per correu electrònic ..."
setup_explanation:
+ title: "Subscripcions"
just_a_few_more_steps: 'Només uns quants passos més abans de començar:'
enable_subscriptions: "Activa les subscripcions d'almenys una de les teves botigues"
enable_subscriptions_step_1_html: 1. Aneu a la pàgina %{enterprises_link}, cerqueu la vostra botiga i feu clic a "Gestionar"
@@ -1061,6 +1071,8 @@ ca:
create_at_least_one_schedule_step_3: 3. Fes clic a '+ Nova programació' i omple el formulari
once_you_are_done_you_can_html: Un cop hagueu acabat, podeu %{reload_this_page_link}
reload_this_page: tornar a carregar aquesta pàgina
+ form:
+ create: "Crea una subscripció"
steps:
details: 1. Detalls bàsics
address: 2. Adreça
@@ -1305,6 +1317,8 @@ ca:
cart_updating: "Actualitzant la cistella..."
cart_empty: "Cistella buida"
cart_edit: "Edita la teva cistella"
+ item: "Article"
+ qty: "quant."
card_number: Número de targeta
card_securitycode: "Codi de seguretat"
card_expiry_date: Data de caducitat
@@ -1526,7 +1540,7 @@ ca:
shopping_contact_social: "Segueix"
shopping_groups_part_of: "forma part de:"
shopping_producers_of_hub: "Productores de%{hub}:"
- enterprises_next_closing: "Tancament de la comanda següent"
+ enterprises_next_closing: "La següent comanda tanca"
enterprises_ready_for: "Llest per"
enterprises_choose: "Escull quan vols la teva comanda:"
maps_open: "Obert"
@@ -1716,6 +1730,7 @@ ca:
remember_me: Recorda'm
are_you_sure: "Estàs segur?"
orders_open: "Comandes obertes"
+ closing: "Tancant"
going_back_to_home_page: "Tornant a la pàgina d'inici"
creating: Creant
updating: Actualitzant
@@ -1934,7 +1949,7 @@ ca:
admin_enterprise_groups: "Grups d'organització"
admin_enterprise_groups_name: "Nom"
admin_enterprise_groups_owner: "Propietària"
- admin_enterprise_groups_on_front_page: "A la primera pàgina?"
+ admin_enterprise_groups_on_front_page: "Visible a la web"
admin_enterprise_groups_enterprise: "Organitzacions"
admin_enterprise_groups_data_powertip: "La usuària principal responsable d'aquest grup."
admin_enterprise_groups_data_powertip_logo: "Això és el logotip del grup"
@@ -1959,6 +1974,8 @@ ca:
supplier: "Proveïdora"
product_name: "Nom del producte"
product_description: "Descripció del producte"
+ permalink: "Enllaç permanent"
+ shipping_categories: "Tipus d'enviament"
units: "Mida d'unitat"
coordinator: "Coordinador"
distributor: "Distribuïdora"
@@ -2055,6 +2072,8 @@ ca:
remove_tax: "Suprimeix comissions"
first_name_begins_with: "El nom comença amb"
last_name_begins_with: "El cognom comença amb"
+ shipping_method: "Mètode d'enviament"
+ new_order: "Nova comanda"
enterprise_tos_link: "Enllaç a les condicions d'ús de l'organització"
enterprise_tos_message: "Volem treballar amb persones que comparteixen els nostres objectius i valors. Com a tal, demanem a les noves organitzacions que acceptin la nostra"
enterprise_tos_link_text: "Termes del servei."
@@ -2073,6 +2092,7 @@ ca:
hub_sidebar_at_least: "Cal seleccionar almenys un grup "
hub_sidebar_blue: "blau"
hub_sidebar_red: "vermell"
+ order_cycles_closed_for_hub: "La botiga que has triat està temporalment tancada per a fer comandes. Sisplau, prova una mica més tard"
report_customers_distributor: "Distribuïdora"
report_customers_supplier: "Proveïdora"
report_customers_cycle: "Cicle de Comanda"
@@ -2309,6 +2329,7 @@ ca:
order_cycles_email_to_producers_notice: 'Els correus electrònics per enviar a les productores estan en cua.'
order_cycles_no_permission_to_coordinate_error: "Cap de les vostres organitzacions té permís per coordinar un cicle de comanda"
order_cycles_no_permission_to_create_error: "No teniu permís per crear un cicle de comandes coordinat per aquesta organització"
+ order_cycle_closed: "El cicle de comandes que has triat acaba de tancar. Sisplau prova en un altre moment."
back_to_orders_list: "Torna a la llista de comandes"
no_orders_found: "No s'han trobat comandes"
order_information: "Informació de la comanda"
@@ -2564,7 +2585,7 @@ ca:
'yes': "Sota demanda"
variant_overrides:
on_demand:
- use_producer_settings: "Utilitzeu la configuració d'inventari de la productora"
+ use_producer_settings: "Utilitzeu la configuració d'estoc de la productora"
'yes': "Sí"
'no': "No"
inventory_products: "Productes de l'inventari"
@@ -3168,6 +3189,8 @@ ca:
stripe:
error_saving_payment: Error en desar el pagament
submitting_payment: S'està lliurant el pagament...
+ paypal:
+ no_payment_via_admin_backend: Els pagaments amb Paypal no es poden capturar des de l'administració
products:
image_upload_error: "No s'ha reconegut la imatge del producte. Carregueu una imatge en format PNG o JPG."
new:
@@ -3345,6 +3368,32 @@ ca:
invoice_email:
hi: "Hola %{name}"
invoice_attached_text: Trobareu adjunta un comprovant de la compra per a la vostra comanda recent
+ user_mailer:
+ reset_password_instructions:
+ request_sent_text: |
+ S'ha fet una sol·licitud per restablir la teva contrasenya.
+ Si no has fet aquesta sol·licitud, simplement ignora aquest correu electrònic.
+ link_text: >
+ Si has fet aquesta sol·licitud, fes clic a l'enllaç següent:
+ issue_text: |
+ Si l'URL anterior no funciona, prova de copiar-lo i enganxar-lo al navegador.
+ Si continues tenint problemes, no dubtis en contactar-nos.
+ confirmation_instructions:
+ subject: "Si us plau confirma el teu compte d'OFN"
+ shipment_mailer:
+ shipped_email:
+ dear_customer: "Benvolguda consumidora:"
+ instructions: "La vostra comanda s'ha enviat"
+ shipment_summary: "Resum de l'enviament"
+ subject: "Notificació d'enviament"
+ thanks: "Gràcies per la teva compra."
+ track_information: "Informació del seguiment: %{tracking}"
+ track_link: "Enllaç del seguiment: %{url}"
+ test_mailer:
+ test_email:
+ greeting: "Enhorabona!"
+ message: "Si heu rebut aquest correu electrònic, la vostra configuració de correu electrònic és correcta."
+ subject: "Correu de prova"
order_state:
address: adreça
adjustments: ajustaments
@@ -3366,18 +3415,6 @@ ca:
ended: acabat
paused: en pausa
canceled: cancel·lat
- user_mailer:
- reset_password_instructions:
- request_sent_text: |
- S'ha fet una sol·licitud per restablir la teva contrasenya.
- Si no has fet aquesta sol·licitud, simplement ignora aquest correu electrònic.
- link_text: >
- Si has fet aquesta sol·licitud, fes clic a l'enllaç següent:
- issue_text: |
- Si l'URL anterior no funciona, prova de copiar-lo i enganxar-lo al navegador.
- Si continues tenint problemes, no dubtis en contactar-nos.
- confirmation_instructions:
- subject: Si us plau confirma el teu compte d'OFN
users:
form:
account_settings: Configuració del compte
diff --git a/config/locales/de_DE.yml b/config/locales/de_DE.yml
index de1588cf38..06e334a22a 100644
--- a/config/locales/de_DE.yml
+++ b/config/locales/de_DE.yml
@@ -13,6 +13,7 @@ de_DE:
email: E-Mail des Kunden
spree/payment:
amount: Betrag
+ state: Status
spree/product:
primary_taxon: "Produktkategorie"
supplier: "Anbieter"
@@ -1028,10 +1029,13 @@ de_DE:
name: "Unternehmensgebühr Zusammenfassung"
description: "Zusammenfassung der erhobenen Zuschläge"
subscriptions:
- subscriptions: Abonnements
- new: Neues Abonnement
- create: Abonnement erstellen
- edit: Abonnement bearbeiten
+ index:
+ title: "Abonnements"
+ new: "Neues Abonnement"
+ new:
+ title: "Neues Abonnement"
+ edit:
+ title: "Abonnement bearbeiten"
table:
edit_subscription: Abonnement bearbeiten
pause_subscription: Abonement pausieren
@@ -1040,6 +1044,7 @@ de_DE:
filters:
query_placeholder: "Suche per E-Mail ..."
setup_explanation:
+ title: "Abonnements"
just_a_few_more_steps: 'Nur noch ein paar Schritte bevor Sie beginnen können:'
enable_subscriptions: "Aktivieren Sie Abonnements für mindestens einen Ihrer Läden"
enable_subscriptions_step_1_html: 1. Gehen Sie zur Seite %{enterprises_link}, suchen Sie Ihren Laden und klicken Sie auf "Verwalten"
@@ -1053,6 +1058,8 @@ de_DE:
create_at_least_one_schedule_step_3: 3. Klicken Sie auf "+ Neuer Zeitplan" und füllen Sie das Formular aus
once_you_are_done_you_can_html: Sobald Sie fertig sind, können Sie %{reload_this_page_link}
reload_this_page: diese Seite neu laden
+ form:
+ create: "Abonnement erstellen"
steps:
details: 1. Grundlegendes
address: 2. Adresse
@@ -1285,6 +1292,8 @@ de_DE:
cart_updating: "Warenkorb aktualisieren..."
cart_empty: "Warenkorb leer"
cart_edit: "Warenkorb bearbeiten"
+ item: "Artikel"
+ qty: "Menge"
card_number: Kartennummer
card_securitycode: "Sicherheitscode"
card_expiry_date: Ablaufdatum
@@ -1930,6 +1939,7 @@ de_DE:
supplier: "Anbieter"
product_name: "Produktname"
product_description: "Produktbeschreibung"
+ shipping_categories: "Versandkategorien"
units: "Einheitsgröße"
coordinator: "Koordinator"
distributor: "Verteiler"
@@ -3257,6 +3267,27 @@ de_DE:
invoice_email:
hi: "Hallo %{name}"
invoice_attached_text: Im Anhang findest Du eine Rechnung für die letzte Bestellung vom
+ user_mailer:
+ reset_password_instructions:
+ request_sent_text: |
+ Es wurde angefragt, das Passwort zurückzusetzen.
+ Sollte kein neues Passwort angefordert werden, bitte dieses E-Mail ignorieren.
+ link_text: >
+ Sollte ein neues Passwort angefordert werden, bitte den folgenden Aktivierungslink
+ bestätigen.
+ issue_text: |
+ Falls die URL nicht funktioniert, bitte den Link kopieren und in die Adresszeile Ihres Browsers einfügen
+ confirmation_instructions:
+ subject: "Bitte OFN-Konto bestätigen"
+ shipment_mailer:
+ shipped_email:
+ dear_customer: "Sehr geehrter Kunde,"
+ instructions: "Ihre Bestellung wurde versandt"
+ shipment_summary: "Übersicht"
+ subject: "Versandbenachrichtigung"
+ thanks: "Danke für Ihren Einkauf."
+ track_information: "Tracking-Informationen: %{tracking}"
+ track_link: "Tracking-Link: %{url}"
order_state:
address: Adresse
adjustments: Verbesserungen
@@ -3278,18 +3309,6 @@ de_DE:
ended: beendet
paused: pausiert
canceled: storniert
- user_mailer:
- reset_password_instructions:
- request_sent_text: |
- Es wurde angefragt, das Passwort zurückzusetzen.
- Sollte kein neues Passwort angefordert werden, bitte dieses E-Mail ignorieren.
- link_text: >
- Sollte ein neues Passwort angefordert werden, bitte den folgenden Aktivierungslink
- bestätigen.
- issue_text: |
- Falls die URL nicht funktioniert, bitte den Link kopieren und in die Adresszeile Ihres Browsers einfügen
- confirmation_instructions:
- subject: Bitte OFN-Konto bestätigen
users:
form:
account_settings: Konto Einstellungen
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 3726167337..8759f90d9b 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -34,6 +34,8 @@ en:
email: Customer E-Mail
spree/payment:
amount: Amount
+ state: State
+ source: Source
spree/product:
primary_taxon: "Product Category"
supplier: "Supplier"
@@ -82,7 +84,7 @@ en:
messages:
inclusion: "is not included in the list"
models:
- order_management/subscriptions/validator:
+ order_management/subscriptions/validator:
attributes:
subscription_line_items:
at_least_one_product: "^Please add at least one product"
@@ -254,6 +256,7 @@ en:
enterprises: Enterprises
enterprise_groups: Groups
reports: Reports
+ listing_reports: Listing Reports
variant_overrides: Inventory
import: Import
spree_products: Spree Products
@@ -303,6 +306,9 @@ en:
"on hand": "On Hand"
ship: "Ship"
shipping_category: "Shipping Category"
+ height: "Height"
+ width: "Width"
+ depth: "Depth"
actions:
create_and_add_another: "Create and Add Another"
@@ -1091,10 +1097,13 @@ en:
name: "Enterprise Fee Summary"
description: "Summary of Enterprise Fees collected"
subscriptions:
- subscriptions: Subscriptions
- new: New Subscription
- create: Create Subscription
- edit: Edit Subscription
+ index:
+ title: "Subscriptions"
+ new: "New Subscription"
+ new:
+ title: "New Subscription"
+ edit:
+ title: "Edit Subscription"
table:
edit_subscription: Edit Subscription
pause_subscription: Pause Subscription
@@ -1103,6 +1112,7 @@ en:
filters:
query_placeholder: "Search by email..."
setup_explanation:
+ title: "Subscriptions"
just_a_few_more_steps: 'Just a few more steps before you can begin:'
enable_subscriptions: "Enable subscriptions for at least one of your shops"
enable_subscriptions_step_1_html: 1. Go to the %{enterprises_link} page, find your shop, and click "Manage"
@@ -1116,6 +1126,8 @@ en:
create_at_least_one_schedule_step_3: 3. Click '+ New Schedule', and fill out the form
once_you_are_done_you_can_html: Once you are done, you can %{reload_this_page_link}
reload_this_page: reload this page
+ form:
+ create: "Create Subscription"
steps:
details: 1. Basic Details
address: 2. Address
@@ -1384,6 +1396,8 @@ en:
cart_updating: "Updating cart..."
cart_empty: "Cart empty"
cart_edit: "Edit your cart"
+ item: "Item"
+ qty: "Qty"
card_number: Card Number
card_securitycode: "Security Code"
@@ -2088,6 +2102,8 @@ See the %{link} to find out more about %{sitename}'s features and to start using
supplier: "Supplier"
product_name: "Product Name"
product_description: "Product Description"
+ permalink: "Permalink"
+ shipping_categories: "Shipping Categories"
units: "Unit Size"
coordinator: "Coordinator"
distributor: "Distributor"
@@ -2167,7 +2183,6 @@ See the %{link} to find out more about %{sitename}'s features and to start using
spree_user_enterprise_limit_error: "^%{email} is not permitted to own any more enterprises (limit is %{enterprise_limit})."
spree_variant_product_error: must have at least one variant
your_profil_live: "Your profile live"
- on_ofn_map: "on the Open Food Network map"
see: "See"
live: "live"
manage: "Manage"
@@ -2184,6 +2199,8 @@ See the %{link} to find out more about %{sitename}'s features and to start using
remove_tax: "Remove tax"
first_name_begins_with: "First name begins with"
last_name_begins_with: "Last name begins with"
+ shipping_method: "Shipping method"
+ new_order: "New Order"
enterprise_tos_link: "Enterprise Terms of Service link"
enterprise_tos_message: "We want to work with people that share our aims and values. As such we ask new enterprises to agree to our "
@@ -3331,6 +3348,8 @@ See the %{link} to find out more about %{sitename}'s features and to start using
stripe:
error_saving_payment: Error saving payment
submitting_payment: Submitting payment...
+ paypal:
+ no_payment_via_admin_backend: Paypal payments cannot be captured in the Backoffice
products:
image_upload_error: "The product image was not recognised. Please upload an image in PNG or JPG format."
new:
@@ -3508,6 +3527,32 @@ See the %{link} to find out more about %{sitename}'s features and to start using
invoice_email:
hi: "Hi %{name}"
invoice_attached_text: Please find attached an invoice for your recent order from
+ user_mailer:
+ reset_password_instructions:
+ request_sent_text: |
+ A request to reset your password has been made.
+ If you did not make this request, simply ignore this email.
+ link_text: >
+ If you did make this request just click the link below:
+ issue_text: |
+ If the above URL does not work try copying and pasting it into your browser.
+ If you continue to have problems please feel free to contact us.
+ confirmation_instructions:
+ subject: "Please confirm your OFN account"
+ shipment_mailer:
+ shipped_email:
+ dear_customer: "Dear Customer,"
+ instructions: "Your order has been shipped"
+ shipment_summary: "Shipment Summary"
+ subject: "Shipment Notification"
+ thanks: "Thank you for your business."
+ track_information: ! "Tracking Information: %{tracking}"
+ track_link: ! "Tracking Link: %{url}"
+ test_mailer:
+ test_email:
+ greeting: "Congratulations!"
+ message: "If you have received this email, then your email settings are correct."
+ subject: "Test Mail"
order_state:
address: address
adjustments: adjustments
@@ -3529,18 +3574,6 @@ See the %{link} to find out more about %{sitename}'s features and to start using
ended: ended
paused: paused
canceled: cancelled
- user_mailer:
- reset_password_instructions:
- request_sent_text: |
- A request to reset your password has been made.
- If you did not make this request, simply ignore this email.
- link_text: >
- If you did make this request just click the link below:
- issue_text: |
- If the above URL does not work try copying and pasting it into your browser.
- If you continue to have problems please feel free to contact us.
- confirmation_instructions:
- subject: Please confirm your OFN account
users:
form:
account_settings: Account Settings
diff --git a/config/locales/en_AU.yml b/config/locales/en_AU.yml
index 528ee44b6d..276534010f 100644
--- a/config/locales/en_AU.yml
+++ b/config/locales/en_AU.yml
@@ -13,6 +13,7 @@ en_AU:
email: Customer E-Mail
spree/payment:
amount: Amount
+ state: State
spree/product:
primary_taxon: "Product Category"
supplier: "Supplier"
@@ -1027,10 +1028,13 @@ en_AU:
name: "Enterprise Fee Summary"
description: "Summary of Enterprise Fees collected"
subscriptions:
- subscriptions: Subscriptions
- new: New Subscription
- create: Create Subscription
- edit: Edit Subscription
+ index:
+ title: "Subscriptions"
+ new: "New Subscription"
+ new:
+ title: "New Subscription"
+ edit:
+ title: "Edit Subscription"
table:
edit_subscription: Edit Subscription
pause_subscription: Pause Subscription
@@ -1039,6 +1043,7 @@ en_AU:
filters:
query_placeholder: "Search by email..."
setup_explanation:
+ title: "Subscriptions"
just_a_few_more_steps: 'Just a few more steps before you can begin:'
enable_subscriptions: "Enable subscriptions for at least one of your shops"
enable_subscriptions_step_1_html: 1. Go to the %{enterprises_link} page, find your shop, and click "Manage"
@@ -1052,6 +1057,8 @@ en_AU:
create_at_least_one_schedule_step_3: 3. Click '+ New Schedule', and fill out the form
once_you_are_done_you_can_html: Once you are done, you can %{reload_this_page_link}
reload_this_page: reload this page
+ form:
+ create: "Create Subscription"
steps:
details: 1. Basic Details
address: 2. Address
@@ -1284,6 +1291,8 @@ en_AU:
cart_updating: "Updating cart..."
cart_empty: "Cart empty"
cart_edit: "Edit your cart"
+ item: "Item"
+ qty: "Qty"
card_number: Card Number
card_securitycode: "Security Code"
card_expiry_date: Expiry Date
@@ -1927,6 +1936,7 @@ en_AU:
supplier: "Supplier"
product_name: "Product Name"
product_description: "Product Description"
+ shipping_categories: "Shipping Categories"
units: "Unit Size"
coordinator: "Coordinator"
distributor: "Distributor"
@@ -2022,6 +2032,7 @@ en_AU:
remove_tax: "Remove tax"
first_name_begins_with: "First name begins with"
last_name_begins_with: "Last name begins with"
+ new_order: "New Order"
enterprise_tos_link: "Enterprise Terms of Service link"
enterprise_tos_message: "We want to work with people that share our aims and values. As such we ask new enterprises to agree to our "
enterprise_tos_link_text: "Terms of Service."
@@ -3184,6 +3195,27 @@ en_AU:
invoice_email:
hi: "Hi %{name}"
invoice_attached_text: Please find attached an invoice for your recent order from
+ user_mailer:
+ reset_password_instructions:
+ request_sent_text: |
+ A request to reset your password has been made.
+ If you did not make this request, simply ignore this email.
+ link_text: >
+ If you did make this request just click the link below:
+ issue_text: |
+ If the above URL does not work try copying and pasting it into your browser.
+ If you continue to have problems please feel free to contact us.
+ confirmation_instructions:
+ subject: "Please confirm your OFN account"
+ shipment_mailer:
+ shipped_email:
+ dear_customer: "Dear Customer,"
+ instructions: "Your order has been shipped"
+ shipment_summary: "Shipment Summary"
+ subject: "Shipment Notification"
+ thanks: "Thank you for your business."
+ track_information: "Tracking Information: %{tracking}"
+ track_link: "Tracking Link: %{url}"
order_state:
address: address
adjustments: adjustments
@@ -3205,18 +3237,6 @@ en_AU:
ended: ended
paused: paused
canceled: cancelled
- user_mailer:
- reset_password_instructions:
- request_sent_text: |
- A request to reset your password has been made.
- If you did not make this request, simply ignore this email.
- link_text: >
- If you did make this request just click the link below:
- issue_text: |
- If the above URL does not work try copying and pasting it into your browser.
- If you continue to have problems please feel free to contact us.
- confirmation_instructions:
- subject: Please confirm your OFN account
users:
form:
account_settings: Account Settings
diff --git a/config/locales/en_BE.yml b/config/locales/en_BE.yml
index ff1dc8bbc1..e68a2db4ab 100644
--- a/config/locales/en_BE.yml
+++ b/config/locales/en_BE.yml
@@ -13,6 +13,7 @@ en_BE:
email: Customer E-Mail
spree/payment:
amount: Amount
+ state: State
spree/product:
primary_taxon: "Product Category"
supplier: "Supplier"
@@ -990,10 +991,13 @@ en_BE:
name: "Enterprise Fee Summary"
description: "Summary of Enterprise Fees collected"
subscriptions:
- subscriptions: Subscriptions
- new: New Subscription
- create: Create Subscription
- edit: Edit Subscription
+ index:
+ title: "Subscriptions"
+ new: "New Subscription"
+ new:
+ title: "New Subscription"
+ edit:
+ title: "Edit Subscription"
table:
edit_subscription: Edit Subscription
pause_subscription: Pause Subscription
@@ -1002,6 +1006,7 @@ en_BE:
filters:
query_placeholder: "Search by email..."
setup_explanation:
+ title: "Subscriptions"
just_a_few_more_steps: 'Just a few more steps before you can begin:'
enable_subscriptions: "Enable subscriptions for at least one of your shops"
enable_subscriptions_step_1_html: 1. Go to the %{enterprises_link} page, find your shop, and click "Manage"
@@ -1015,6 +1020,8 @@ en_BE:
create_at_least_one_schedule_step_3: 3. Click '+ New Schedule', and fill out the form
once_you_are_done_you_can_html: Once you are done, you can %{reload_this_page_link}
reload_this_page: reload this page
+ form:
+ create: "Create Subscription"
steps:
details: 1. Basic Details
address: 2. Address
@@ -1245,6 +1252,8 @@ en_BE:
cart_updating: "Updating cart..."
cart_empty: "Cart empty"
cart_edit: "Edit your cart"
+ item: "Item"
+ qty: "Qty"
card_number: Card Number
card_securitycode: "Security Code"
card_expiry_date: Expiry Date
@@ -1887,6 +1896,7 @@ en_BE:
supplier: "Supplier"
product_name: "Product Name"
product_description: "Product Description"
+ shipping_categories: "Shipping Categories"
units: "Unit Size"
coordinator: "Coordinator"
distributor: "Distributor"
@@ -1982,6 +1992,7 @@ en_BE:
remove_tax: "Remove tax"
first_name_begins_with: "First name begins with"
last_name_begins_with: "Last name begins with"
+ new_order: "New Order"
enterprise_tos_link: "Enterprise Terms of Service link"
enterprise_tos_message: "We want to work with people that share our aims and values. As such we ask new enterprises to agree to our "
enterprise_tos_link_text: "Terms of Service."
@@ -3093,6 +3104,27 @@ en_BE:
invoice_email:
hi: "Hi %{name}"
invoice_attached_text: Please find attached an invoice for your recent order from
+ user_mailer:
+ reset_password_instructions:
+ request_sent_text: |
+ A request to reset your password has been made.
+ If you did not make this request, simply ignore this email.
+ link_text: >
+ If you did make this request just click the link below:
+ issue_text: |
+ If the above URL does not work try copying and pasting it into your browser.
+ If you continue to have problems please feel free to contact us.
+ confirmation_instructions:
+ subject: "Please confirm your OFN account"
+ shipment_mailer:
+ shipped_email:
+ dear_customer: "Dear Customer,"
+ instructions: "Your order has been shipped"
+ shipment_summary: "Shipment Summary"
+ subject: "Shipment Notification"
+ thanks: "Thank you for your business."
+ track_information: "Tracking Information: %{tracking}"
+ track_link: "Tracking Link: %{url}"
order_state:
address: address
adjustments: adjustments
@@ -3114,18 +3146,6 @@ en_BE:
ended: ended
paused: paused
canceled: cancelled
- user_mailer:
- reset_password_instructions:
- request_sent_text: |
- A request to reset your password has been made.
- If you did not make this request, simply ignore this email.
- link_text: >
- If you did make this request just click the link below:
- issue_text: |
- If the above URL does not work try copying and pasting it into your browser.
- If you continue to have problems please feel free to contact us.
- confirmation_instructions:
- subject: Please confirm your OFN account
users:
form:
account_settings: Account Settings
diff --git a/config/locales/en_CA.yml b/config/locales/en_CA.yml
index a267d6397d..658cbcf1d4 100644
--- a/config/locales/en_CA.yml
+++ b/config/locales/en_CA.yml
@@ -13,6 +13,8 @@ en_CA:
email: Customer E-Mail
spree/payment:
amount: Amount
+ state: State
+ source: Source
spree/product:
primary_taxon: "Product Category"
supplier: "Supplier"
@@ -182,6 +184,7 @@ en_CA:
explainer: Automatic processing of these orders failed for an unknown reason. This should not occur, please contact us if you are seeing this.
home: "OFN"
title: "Open Food Network"
+ welcome_to: "Welcome to"
site_meta_description: "We begin from the ground up. With farmers and growers ready to tell their stories proudly and truly. With distributors ready to connect people with products fairly and honestly. With buyers who believe that better weekly shopping decisions can…"
search_by_name: Search by name or city
producers_join: Producers are welcome to join the Open Food Network.
@@ -270,6 +273,9 @@ en_CA:
on hand: "On Hand"
ship: "Ship"
shipping_category: "Shipping Category"
+ height: "Height"
+ width: "Width"
+ depth: "Depth"
actions:
create_and_add_another: "Create and Add Another"
create: "Create"
@@ -1033,10 +1039,13 @@ en_CA:
name: "Enterprise Fee Summary"
description: "Summary of Enterprise Fees collected"
subscriptions:
- subscriptions: Subscriptions
- new: New Subscription
- create: Create Subscription
- edit: Edit Subscription
+ index:
+ title: "Subscriptions"
+ new: "New Subscription"
+ new:
+ title: "New Subscription"
+ edit:
+ title: "Edit Subscription"
table:
edit_subscription: Edit Subscription
pause_subscription: Pause Subscription
@@ -1045,6 +1054,7 @@ en_CA:
filters:
query_placeholder: "Search by email..."
setup_explanation:
+ title: "Subscriptions"
just_a_few_more_steps: 'Just a few more steps before you can begin:'
enable_subscriptions: "Enable subscriptions for at least one of your shops"
enable_subscriptions_step_1_html: 1. Go to the %{enterprises_link} page, find your shop, and click "Manage"
@@ -1058,6 +1068,8 @@ en_CA:
create_at_least_one_schedule_step_3: 3. Click '+ New Schedule', and fill out the form
once_you_are_done_you_can_html: Once you are done, you can %{reload_this_page_link}
reload_this_page: reload this page
+ form:
+ create: "Create Subscription"
steps:
details: 1. Basic Details
address: 2. Address
@@ -1160,7 +1172,7 @@ en_CA:
mobile_menu:
cart: "Cart"
register_call:
- selling_on_ofn: "Interested in getting on the Open Food Network?"
+ selling_on_ofn: "Interested in selling on the Open Food Network?"
register: "Register here"
footer:
footer_secure: "Secure and trusted."
@@ -1302,6 +1314,8 @@ en_CA:
cart_updating: "Updating cart..."
cart_empty: "Cart empty"
cart_edit: "Edit your cart"
+ item: "Item"
+ qty: "Qty"
card_number: Card Number
card_securitycode: "Security Code"
card_expiry_date: Expiry Date
@@ -1713,6 +1727,7 @@ en_CA:
remember_me: Remember Me
are_you_sure: "Are you sure?"
orders_open: "Orders open"
+ closing: "Closing"
going_back_to_home_page: "Taking you back to the home page"
creating: Creating
updating: Updating
@@ -1956,6 +1971,8 @@ en_CA:
supplier: "Supplier"
product_name: "Product Name"
product_description: "Product Description"
+ permalink: "Permalink"
+ shipping_categories: "Shipping Categories"
units: "Unit Size"
coordinator: "Coordinator"
distributor: "Distributor"
@@ -2052,6 +2069,8 @@ en_CA:
remove_tax: "Remove tax"
first_name_begins_with: "First name begins with"
last_name_begins_with: "Last name begins with"
+ shipping_method: "Shipping method"
+ new_order: "New Order"
enterprise_tos_link: "Enterprise Terms of Service link"
enterprise_tos_message: "We want to work with people that share our aims and values. As such we ask new enterprises to agree to our "
enterprise_tos_link_text: "Terms of Service."
@@ -2070,6 +2089,7 @@ en_CA:
hub_sidebar_at_least: "At least one hub must be selected"
hub_sidebar_blue: "blue"
hub_sidebar_red: "red"
+ order_cycles_closed_for_hub: "The hub you have selected is temporarily closed for orders. Please try again later."
report_customers_distributor: "Distributor"
report_customers_supplier: "Supplier"
report_customers_cycle: "Order Cycle"
@@ -2306,6 +2326,7 @@ en_CA:
order_cycles_email_to_producers_notice: 'Emails to be sent to producers have been queued for sending.'
order_cycles_no_permission_to_coordinate_error: "None of your enterprises have permission to coordinate an order cycle"
order_cycles_no_permission_to_create_error: "You don't have permission to create an order cycle coordinated by that enterprise"
+ order_cycle_closed: "The order cycle you've selected has just closed. Please try again!"
back_to_orders_list: "Back to order list"
no_orders_found: "No Orders Found"
order_information: "Order Information"
@@ -2807,7 +2828,7 @@ en_CA:
city: "City"
zip: "Postal Code"
country: "Country"
- state: "Province"
+ state: "State"
phone: "Phone"
update: "Update"
use_billing_address: "Use Billing Address"
@@ -3161,6 +3182,8 @@ en_CA:
stripe:
error_saving_payment: Error saving payment
submitting_payment: Submitting payment...
+ paypal:
+ no_payment_via_admin_backend: Paypal payments cannot be captured in the backoffice.
products:
image_upload_error: "The product image was not recognised. Please upload an image in PNG or JPG format."
new:
@@ -3338,6 +3361,32 @@ en_CA:
invoice_email:
hi: "Hi %{name}"
invoice_attached_text: Please find attached an invoice for your recent order from
+ user_mailer:
+ reset_password_instructions:
+ request_sent_text: |
+ A request to reset your password has been made.
+ If you did not make this request, simply ignore this email.
+ link_text: >
+ If you did make this request just click the link below:
+ issue_text: |
+ If the above URL does not work try copying and pasting it into your browser.
+ If you continue to have problems please feel free to contact us.
+ confirmation_instructions:
+ subject: "Please confirm your OFN account"
+ shipment_mailer:
+ shipped_email:
+ dear_customer: "Dear Customer, "
+ instructions: "Your order has been shipped or picked up."
+ shipment_summary: "Shipment/Pick Up Summary"
+ subject: "Shipment/Pick Up Notification"
+ thanks: "Thank you for your business."
+ track_information: "Tracking Information: %{tracking}"
+ track_link: "Tracking Link: %{url}"
+ test_mailer:
+ test_email:
+ greeting: "Congratulations!"
+ message: "If you have received this email, then your OFN email settings are correct."
+ subject: "Test Mail"
order_state:
address: address
adjustments: adjustments
@@ -3359,18 +3408,6 @@ en_CA:
ended: ended
paused: paused
canceled: cancelled
- user_mailer:
- reset_password_instructions:
- request_sent_text: |
- A request to reset your password has been made.
- If you did not make this request, simply ignore this email.
- link_text: >
- If you did make this request just click the link below:
- issue_text: |
- If the above URL does not work try copying and pasting it into your browser.
- If you continue to have problems please feel free to contact us.
- confirmation_instructions:
- subject: Please confirm your OFN account
users:
form:
account_settings: Account Settings
diff --git a/config/locales/en_DE.yml b/config/locales/en_DE.yml
index 62e613451c..c854c60e94 100644
--- a/config/locales/en_DE.yml
+++ b/config/locales/en_DE.yml
@@ -13,6 +13,7 @@ en_DE:
email: Customer E-Mail
spree/payment:
amount: Amount
+ state: State
spree/product:
primary_taxon: "Product Category"
supplier: "Supplier"
@@ -998,10 +999,13 @@ en_DE:
name: "Enterprise Fee Summary"
description: "Summary of Enterprise Fees collected"
subscriptions:
- subscriptions: Subscriptions
- new: New Subscription
- create: Create Subscription
- edit: Edit Subscription
+ index:
+ title: "Subscriptions"
+ new: "New Subscription"
+ new:
+ title: "New Subscription"
+ edit:
+ title: "Edit Subscription"
table:
edit_subscription: Edit Subscription
pause_subscription: Pause Subscription
@@ -1010,6 +1014,7 @@ en_DE:
filters:
query_placeholder: "Search by email..."
setup_explanation:
+ title: "Subscriptions"
just_a_few_more_steps: 'Just a few more steps before you can begin:'
enable_subscriptions: "Enable subscriptions for at least one of your shops"
enable_subscriptions_step_1_html: 1. Go to the %{enterprises_link} page, find your shop, and click "Manage"
@@ -1023,6 +1028,8 @@ en_DE:
create_at_least_one_schedule_step_3: 3. Click '+ New Schedule', and fill out the form
once_you_are_done_you_can_html: Once you are done, you can %{reload_this_page_link}
reload_this_page: reload this page
+ form:
+ create: "Create Subscription"
steps:
details: 1. Basic Details
address: 2. Address
@@ -1255,6 +1262,8 @@ en_DE:
cart_updating: "Updating cart..."
cart_empty: "Cart empty"
cart_edit: "Edit your cart"
+ item: "Item"
+ qty: "Qty"
card_number: Card Number
card_securitycode: "Security Code"
card_expiry_date: Expiry Date
@@ -1897,6 +1906,7 @@ en_DE:
supplier: "Supplier"
product_name: "Product Name"
product_description: "Product Description"
+ shipping_categories: "Shipping Categories"
units: "Unit Size"
coordinator: "Coordinator"
distributor: "Distributor"
@@ -1992,6 +2002,7 @@ en_DE:
remove_tax: "Remove tax"
first_name_begins_with: "First name begins with"
last_name_begins_with: "Last name begins with"
+ new_order: "New Order"
enterprise_tos_link: "Enterprise Terms of Service link"
enterprise_tos_message: "We want to work with people that share our aims and values. As such we ask new enterprises to agree to our "
enterprise_tos_link_text: "Terms of Service."
@@ -3110,6 +3121,27 @@ en_DE:
invoice_email:
hi: "Hi %{name}"
invoice_attached_text: Please find attached an invoice for your recent order from
+ user_mailer:
+ reset_password_instructions:
+ request_sent_text: |
+ A request to reset your password has been made.
+ If you did not make this request, simply ignore this email.
+ link_text: >
+ If you did make this request just click the link below:
+ issue_text: |
+ If the above URL does not work try copying and pasting it into your browser.
+ If you continue to have problems please feel free to contact us.
+ confirmation_instructions:
+ subject: "Please confirm your OFN account"
+ shipment_mailer:
+ shipped_email:
+ dear_customer: "Dear Customer,"
+ instructions: "Your order has been shipped"
+ shipment_summary: "Shipment Summary"
+ subject: "Shipment Notification"
+ thanks: "Thank you for your business."
+ track_information: "Tracking Information: %{tracking}"
+ track_link: "Tracking Link: %{url}"
order_state:
address: address
adjustments: adjustments
@@ -3131,18 +3163,6 @@ en_DE:
ended: ended
paused: paused
canceled: cancelled
- user_mailer:
- reset_password_instructions:
- request_sent_text: |
- A request to reset your password has been made.
- If you did not make this request, simply ignore this email.
- link_text: >
- If you did make this request just click the link below:
- issue_text: |
- If the above URL does not work try copying and pasting it into your browser.
- If you continue to have problems please feel free to contact us.
- confirmation_instructions:
- subject: Please confirm your OFN account
users:
form:
account_settings: Account Settings
diff --git a/config/locales/en_FR.yml b/config/locales/en_FR.yml
index c514500eff..833ae09d47 100644
--- a/config/locales/en_FR.yml
+++ b/config/locales/en_FR.yml
@@ -13,6 +13,8 @@ en_FR:
email: Customer E-Mail
spree/payment:
amount: Amount
+ state: State
+ source: Source
spree/product:
primary_taxon: "Product Category"
supplier: "Supplier"
@@ -271,6 +273,9 @@ en_FR:
on hand: "On Hand"
ship: "Ship"
shipping_category: "Shipping Category"
+ height: "Height"
+ width: "Width"
+ depth: "Depth"
actions:
create_and_add_another: "Create and Add Another"
create: "Create"
@@ -1034,10 +1039,13 @@ en_FR:
name: "Enterprise Fee Summary"
description: "Summary of Enterprise Fees collected"
subscriptions:
- subscriptions: Subscriptions
- new: New Subscription
- create: Create Subscription
- edit: Edit Subscription
+ index:
+ title: "Subscriptions"
+ new: "New Subscription"
+ new:
+ title: "New Subscription"
+ edit:
+ title: "Edit Subscription"
table:
edit_subscription: Edit Subscription
pause_subscription: Pause Subscription
@@ -1046,6 +1054,7 @@ en_FR:
filters:
query_placeholder: "Search by email..."
setup_explanation:
+ title: "Subscriptions"
just_a_few_more_steps: 'Just a few more steps before you can begin:'
enable_subscriptions: "Enable subscriptions for at least one of your shops"
enable_subscriptions_step_1_html: 1. Go to the %{enterprises_link} page, find your shop, and click "Manage"
@@ -1059,6 +1068,8 @@ en_FR:
create_at_least_one_schedule_step_3: 3. Click '+ New Schedule', and fill out the form
once_you_are_done_you_can_html: Once you are done, you can %{reload_this_page_link}
reload_this_page: reload this page
+ form:
+ create: "Create Subscription"
steps:
details: 1. Basic Details
address: 2. Address
@@ -1303,6 +1314,8 @@ en_FR:
cart_updating: "Updating cart..."
cart_empty: "Cart empty"
cart_edit: "Edit your cart"
+ item: "Item"
+ qty: "Qty"
card_number: Card Number
card_securitycode: "Security Code"
card_expiry_date: Expiry Date
@@ -1958,6 +1971,8 @@ en_FR:
supplier: "Supplier"
product_name: "Product Name"
product_description: "Product Description"
+ permalink: "Permalink"
+ shipping_categories: "Shipping Categories"
units: "Unit Size"
coordinator: "Coordinator"
distributor: "Distributor"
@@ -2054,6 +2069,8 @@ en_FR:
remove_tax: "Remove tax"
first_name_begins_with: "First name begins with"
last_name_begins_with: "Last name begins with"
+ shipping_method: "Shipping method"
+ new_order: "New Order"
enterprise_tos_link: "Enterprise Terms of Service link"
enterprise_tos_message: "We want to work with people that share our aims and values. As such we ask new enterprises to agree to our "
enterprise_tos_link_text: "Terms of Service."
@@ -3166,6 +3183,8 @@ en_FR:
stripe:
error_saving_payment: Error saving payment
submitting_payment: Submitting payment...
+ paypal:
+ no_payment_via_admin_backend: Paypal payments cannot be captured in the Backoffice
products:
image_upload_error: "The product image was not recognised. Please upload an image in PNG or JPG format."
new:
@@ -3343,6 +3362,32 @@ en_FR:
invoice_email:
hi: "Hi %{name}"
invoice_attached_text: Please find attached an invoice for your recent order from
+ user_mailer:
+ reset_password_instructions:
+ request_sent_text: |
+ A request to reset your password has been made.
+ If you did not make this request, simply ignore this email.
+ link_text: >
+ If you did make this request just click the link below:
+ issue_text: |
+ If the above URL does not work try copying and pasting it into your browser.
+ If you continue to have problems please feel free to contact us.
+ confirmation_instructions:
+ subject: "Please confirm your OFN account"
+ shipment_mailer:
+ shipped_email:
+ dear_customer: "Dear Customer,"
+ instructions: "Your order has been shipped"
+ shipment_summary: "Shipment Summary"
+ subject: "Shipment Notification"
+ thanks: "Thank you for your business."
+ track_information: "Tracking Information: %{tracking}"
+ track_link: "Tracking Link: %{url}"
+ test_mailer:
+ test_email:
+ greeting: "Congratulations!"
+ message: "If you have received this email, then your email settings are correct."
+ subject: "Test Mail"
order_state:
address: address
adjustments: adjustments
@@ -3364,18 +3409,6 @@ en_FR:
ended: ended
paused: paused
canceled: cancelled
- user_mailer:
- reset_password_instructions:
- request_sent_text: |
- A request to reset your password has been made.
- If you did not make this request, simply ignore this email.
- link_text: >
- If you did make this request just click the link below:
- issue_text: |
- If the above URL does not work try copying and pasting it into your browser.
- If you continue to have problems please feel free to contact us.
- confirmation_instructions:
- subject: Please confirm your OFN account
users:
form:
account_settings: Account Settings
diff --git a/config/locales/en_GB.yml b/config/locales/en_GB.yml
index 2250c91bb5..8885e48054 100644
--- a/config/locales/en_GB.yml
+++ b/config/locales/en_GB.yml
@@ -13,6 +13,8 @@ en_GB:
email: Customer E-Mail
spree/payment:
amount: Amount
+ state: State
+ source: Source
spree/product:
primary_taxon: "Product Category"
supplier: "Supplier"
@@ -182,6 +184,7 @@ en_GB:
explainer: Automatic processing of these orders failed for an unknown reason. This should not occur, please contact us if you are seeing this.
home: "OFN"
title: "Open Food Network"
+ welcome_to: "Welcome to"
site_meta_description: "The Open Food Network software platform allows farmers to sell produce online, at a price that works for them. It has been built specifically for selling food so it can handle tricky measures or stock levels that only food has - a dozen eggs, a bunch of parsley, a whole chicken that varies in weight…"
search_by_name: Search by name, town, county or postcode...
producers_join: UK producers are now welcome to join Open Food Network UK.
@@ -270,6 +273,9 @@ en_GB:
on hand: "In Stock"
ship: "Ship"
shipping_category: "Shipping Category"
+ height: "Height"
+ width: "Width"
+ depth: "Depth"
actions:
create_and_add_another: "Create and Add Another"
create: "Create"
@@ -1033,10 +1039,13 @@ en_GB:
name: "Enterprise Fee Summary"
description: "Summary of Enterprise Fees collected"
subscriptions:
- subscriptions: Subscriptions
- new: New Subscription
- create: Create Subscription
- edit: Edit Subscription
+ index:
+ title: "Subscriptions"
+ new: "New Subscription"
+ new:
+ title: "New Subscription"
+ edit:
+ title: "Edit Subscription"
table:
edit_subscription: Edit Subscription
pause_subscription: Pause Subscription
@@ -1045,6 +1054,7 @@ en_GB:
filters:
query_placeholder: "Search by email..."
setup_explanation:
+ title: "Subscriptions"
just_a_few_more_steps: 'Just a few more steps before you can begin:'
enable_subscriptions: "Enable subscriptions for at least one of your shops"
enable_subscriptions_step_1_html: 1. Go to the %{enterprises_link} page, find your shop, and click "Manage"
@@ -1058,6 +1068,8 @@ en_GB:
create_at_least_one_schedule_step_3: 3. Click '+ New Schedule', and fill out the form
once_you_are_done_you_can_html: Once you are done, you can %{reload_this_page_link}
reload_this_page: reload this page
+ form:
+ create: "Create Subscription"
steps:
details: 1. Basic Details
address: 2. Address
@@ -1302,6 +1314,8 @@ en_GB:
cart_updating: "Updating cart..."
cart_empty: "Cart empty"
cart_edit: "Edit your cart"
+ item: "Item"
+ qty: "Qty"
card_number: Card Number
card_securitycode: "Security Code"
card_expiry_date: Expiry Date
@@ -1713,6 +1727,7 @@ en_GB:
remember_me: Remember Me
are_you_sure: "Are you sure?"
orders_open: "Orders open"
+ closing: "Closing"
going_back_to_home_page: "Taking you back to the home page"
creating: Creating
updating: Updating
@@ -1956,6 +1971,8 @@ en_GB:
supplier: "Supplier"
product_name: "Product Name"
product_description: "Product Description"
+ permalink: "Permalink"
+ shipping_categories: "Shipping Categories"
units: "Unit Size"
coordinator: "Coordinator"
distributor: "Distributor"
@@ -2052,6 +2069,8 @@ en_GB:
remove_tax: "Remove tax"
first_name_begins_with: "First name begins with"
last_name_begins_with: "Surname begins with"
+ shipping_method: "Shipping method"
+ new_order: "New Order"
enterprise_tos_link: "Enterprise Terms of Service link"
enterprise_tos_message: "We want to work with people that share our aims and values. As such we ask new enterprises to agree to our "
enterprise_tos_link_text: "Terms of Service."
@@ -3170,6 +3189,8 @@ en_GB:
stripe:
error_saving_payment: Error saving payment
submitting_payment: Submitting payment...
+ paypal:
+ no_payment_via_admin_backend: Paypal payments cannot be captured in the Backoffice
products:
image_upload_error: "The product image was not recognised. Please upload an image in PNG or JPG format."
new:
@@ -3347,6 +3368,32 @@ en_GB:
invoice_email:
hi: "Hi %{name}"
invoice_attached_text: Please find attached an invoice for your recent order from
+ user_mailer:
+ reset_password_instructions:
+ request_sent_text: |
+ A request to reset your password has been made.
+ If you did not make this request, simply ignore this email.
+ link_text: >
+ If you did make this request just click the link below:
+ issue_text: |
+ If the above URL does not work try copying and pasting it into your browser.
+ If you continue to have problems please feel free to contact us.
+ confirmation_instructions:
+ subject: "Please confirm your OFN account"
+ shipment_mailer:
+ shipped_email:
+ dear_customer: "Dear Customer,"
+ instructions: "Your order has been shipped"
+ shipment_summary: "Shipment Summary"
+ subject: "Shipment Notification"
+ thanks: "Thank you for your order with us."
+ track_information: "Tracking Information: %{tracking}"
+ track_link: "Tracking Link: %{url}"
+ test_mailer:
+ test_email:
+ greeting: "Congratulations!"
+ message: "If you have received this email, then your email settings are correct."
+ subject: "Test Mail"
order_state:
address: address
adjustments: adjustments
@@ -3368,18 +3415,6 @@ en_GB:
ended: ended
paused: paused
canceled: cancelled
- user_mailer:
- reset_password_instructions:
- request_sent_text: |
- A request to reset your password has been made.
- If you did not make this request, simply ignore this email.
- link_text: >
- If you did make this request just click the link below:
- issue_text: |
- If the above URL does not work try copying and pasting it into your browser.
- If you continue to have problems please feel free to contact us.
- confirmation_instructions:
- subject: Please confirm your OFN account
users:
form:
account_settings: Account Settings
diff --git a/config/locales/en_IE.yml b/config/locales/en_IE.yml
index c9112cfb88..c0743a88b4 100644
--- a/config/locales/en_IE.yml
+++ b/config/locales/en_IE.yml
@@ -13,6 +13,8 @@ en_IE:
email: Customer E-Mail
spree/payment:
amount: Amount
+ state: County
+ source: Source
spree/product:
primary_taxon: "Product Category"
supplier: "Supplier"
@@ -182,7 +184,8 @@ en_IE:
explainer: Automatic processing of these orders failed for an unknown reason. This should not occur, please contact us if you are seeing this.
home: "OFN"
title: "Open Food Network"
- site_meta_description: "The Open Food Network software platform allows farmers to sell produce online, at a price that works for them. It has been built specifically for selling food so it can handle tricky measures or stock levels that only food has - a dozen eggs, a bunch of parsley, a whole chicken that varies in weight…"
+ welcome_to: "Welcome to"
+ site_meta_description: "Open Food Network Ireland allows farmers to sell produce online, at a price that works for them. It has been built specifically for selling food so it can handle tricky measures or stock levels that only food has - a dozen eggs, a bunch of parsley, a whole chicken that varies in weight…"
search_by_name: Search by name, town, county or eircode...
producers_join: Producers are now welcome to join Open Food Network Ireland.
charges_sales_tax: Charges VAT?
@@ -270,6 +273,9 @@ en_IE:
on hand: "In Stock"
ship: "Ship"
shipping_category: "Shipping Category"
+ height: "Height"
+ width: "Width"
+ depth: "Depth"
actions:
create_and_add_another: "Create and Add Another"
create: "Create"
@@ -1033,10 +1039,13 @@ en_IE:
name: "Enterprise Fee Summary"
description: "Summary of Enterprise Fees collected"
subscriptions:
- subscriptions: Subscriptions
- new: New Subscription
- create: Create Subscription
- edit: Edit Subscription
+ index:
+ title: "Subscriptions"
+ new: "New Subscription"
+ new:
+ title: "New Subscription"
+ edit:
+ title: "Edit Subscription"
table:
edit_subscription: Edit Subscription
pause_subscription: Pause Subscription
@@ -1045,6 +1054,7 @@ en_IE:
filters:
query_placeholder: "Search by email..."
setup_explanation:
+ title: "Subscriptions"
just_a_few_more_steps: 'Just a few more steps before you can begin:'
enable_subscriptions: "Enable subscriptions for at least one of your shops"
enable_subscriptions_step_1_html: 1. Go to the %{enterprises_link} page, find your shop, and click "Manage"
@@ -1058,6 +1068,8 @@ en_IE:
create_at_least_one_schedule_step_3: 3. Click '+ New Schedule', and fill out the form
once_you_are_done_you_can_html: Once you are done, you can %{reload_this_page_link}
reload_this_page: reload this page
+ form:
+ create: "Create Subscription"
steps:
details: 1. Basic Details
address: 2. Address
@@ -1302,6 +1314,8 @@ en_IE:
cart_updating: "Updating cart..."
cart_empty: "Cart empty"
cart_edit: "Edit your cart"
+ item: "Item"
+ qty: "Qty"
card_number: Card Number
card_securitycode: "Security Code"
card_expiry_date: Expiry Date
@@ -1650,7 +1664,7 @@ en_IE:
sell_hubs_detail: "Set up a profile for your food enterprise or organisation on the OFN. At any time you can upgrade your profile to a multi-producer shop."
sell_groups_detail: "Set up a tailored directory of enterprises (producers and other food enterprises) for your region or for your organisation."
sell_user_guide: "Find out more in our user guide."
- sell_listing_price: "Listing a profile on OFN Ireland is free. Plans for shops and hubs start from as little as £1 per month. For more detail on pricing visit https://about.openfoodnetwork.org.ie/pricing-and-plans/ ."
+ sell_listing_price: "Listing a profile on OFN Ireland is free. Plans for shops and hubs start from as little as €1 per month. For more details go to our Pricing page in the top menu."
sell_embed: "We collectively budget for new feature development from the international OFN community. This way the huge cost of good software development can be shared. If you want a new feature, chances are someone in France, South Africa, Australia, India or Brazil might want it too! Use the Community Forum to suggest features you'd like to see."
sell_ask_services: "Ask us about OFN services."
shops_title: Shops
@@ -1713,6 +1727,7 @@ en_IE:
remember_me: Remember Me
are_you_sure: "Are you sure?"
orders_open: "Orders open"
+ closing: "Closing"
going_back_to_home_page: "Taking you back to the home page"
creating: Creating
updating: Updating
@@ -1862,7 +1877,7 @@ en_IE:
enterprise_final_step: "Final step!"
enterprise_social_text: "How can people find %{enterprise} online?"
website: "Website"
- website_placeholder: "eg. openfoodnetwork.org.au"
+ website_placeholder: "eg. openfoodnetwork.ie"
facebook: "Facebook"
facebook_placeholder: "eg. www.facebook.com/PageNameHere"
linkedin: "LinkedIn"
@@ -1956,6 +1971,8 @@ en_IE:
supplier: "Supplier"
product_name: "Product Name"
product_description: "Product Description"
+ permalink: "Permalink"
+ shipping_categories: "Shipping Categories"
units: "Unit Size"
coordinator: "Coordinator"
distributor: "Distributor"
@@ -2052,6 +2069,8 @@ en_IE:
remove_tax: "Remove tax"
first_name_begins_with: "First name begins with"
last_name_begins_with: "Surname begins with"
+ shipping_method: "Shipping method"
+ new_order: "New Order"
enterprise_tos_link: "Enterprise Terms of Service link"
enterprise_tos_message: "We want to work with people that share our aims and values. As such we ask new enterprises to agree to our "
enterprise_tos_link_text: "Terms of Service."
@@ -3170,6 +3189,8 @@ en_IE:
stripe:
error_saving_payment: Error saving payment
submitting_payment: Submitting payment...
+ paypal:
+ no_payment_via_admin_backend: Paypal payments cannot be captured in the Backoffice
products:
image_upload_error: "The product image was not recognised. Please upload an image in PNG or JPG format."
new:
@@ -3347,6 +3368,32 @@ en_IE:
invoice_email:
hi: "Hi %{name}"
invoice_attached_text: Please find attached an invoice for your recent order from
+ user_mailer:
+ reset_password_instructions:
+ request_sent_text: |
+ A request to reset your password has been made.
+ If you did not make this request, simply ignore this email.
+ link_text: >
+ If you did make this request just click the link below:
+ issue_text: |
+ If the above URL does not work try copying and pasting it into your browser.
+ If you continue to have problems please feel free to contact us.
+ confirmation_instructions:
+ subject: "Please confirm your OFN account"
+ shipment_mailer:
+ shipped_email:
+ dear_customer: "Dear Customer,"
+ instructions: "Your order has been shipped"
+ shipment_summary: "Shipment Summary"
+ subject: "Shipment Notification"
+ thanks: "Thank you for your order with us."
+ track_information: "Tracking Information: %{tracking}"
+ track_link: "Tracking Link: %{url}"
+ test_mailer:
+ test_email:
+ greeting: "Congratulations!"
+ message: "If you have received this email, then your email settings are correct."
+ subject: "Test Mail"
order_state:
address: address
adjustments: adjustments
@@ -3368,18 +3415,6 @@ en_IE:
ended: ended
paused: paused
canceled: cancelled
- user_mailer:
- reset_password_instructions:
- request_sent_text: |
- A request to reset your password has been made.
- If you did not make this request, simply ignore this email.
- link_text: >
- If you did make this request just click the link below:
- issue_text: |
- If the above URL does not work try copying and pasting it into your browser.
- If you continue to have problems please feel free to contact us.
- confirmation_instructions:
- subject: Please confirm your OFN account
users:
form:
account_settings: Account Settings
diff --git a/config/locales/en_IN.yml b/config/locales/en_IN.yml
index e3ea0153f7..75a7047ad3 100644
--- a/config/locales/en_IN.yml
+++ b/config/locales/en_IN.yml
@@ -13,6 +13,7 @@ en_IN:
email: Customer E-Mail
spree/payment:
amount: Amount
+ state: State
spree/product:
primary_taxon: "Product Category"
supplier: "Supplier"
@@ -1034,10 +1035,13 @@ en_IN:
name: "Enterprise Fee Summary"
description: "Summary of Enterprise Fees collected"
subscriptions:
- subscriptions: Subscriptions
- new: New Subscription
- create: Create Subscription
- edit: Edit Subscription
+ index:
+ title: "Subscriptions"
+ new: "New Subscription"
+ new:
+ title: "New Subscription"
+ edit:
+ title: "Edit Subscription"
table:
edit_subscription: Edit Subscription
pause_subscription: Pause Subscription
@@ -1046,6 +1050,7 @@ en_IN:
filters:
query_placeholder: "Search by email..."
setup_explanation:
+ title: "Subscriptions"
just_a_few_more_steps: 'Just a few more steps before you can begin:'
enable_subscriptions: "Enable subscriptions for at least one of your shops"
enable_subscriptions_step_1_html: 1. Go to the %{enterprises_link} page, find your shop, and click "Manage"
@@ -1059,6 +1064,8 @@ en_IN:
create_at_least_one_schedule_step_3: 3. Click '+ New Schedule', and fill out the form
once_you_are_done_you_can_html: Once you are done, you can %{reload_this_page_link}
reload_this_page: reload this page
+ form:
+ create: "Create Subscription"
steps:
details: 1. Basic Details
address: 2. Address
@@ -1303,6 +1310,8 @@ en_IN:
cart_updating: "Updating cart..."
cart_empty: "Cart empty"
cart_edit: "Edit your cart"
+ item: "Item"
+ qty: "Qty"
card_number: Card Number
card_securitycode: "Security Code"
card_expiry_date: Expiry Date
@@ -1958,6 +1967,7 @@ en_IN:
supplier: "Supplier"
product_name: "Product Name"
product_description: "Product Description"
+ shipping_categories: "Shipping Categories"
units: "Unit Size"
coordinator: "Coordinator"
distributor: "Distributor"
@@ -2054,6 +2064,7 @@ en_IN:
remove_tax: "Remove tax"
first_name_begins_with: "First name begins with"
last_name_begins_with: "Surname begins with"
+ new_order: "New Order"
enterprise_tos_link: "Enterprise Terms of Service link"
enterprise_tos_message: "We want to work with people that share our aims and values. As such we ask new enterprises to agree to our "
enterprise_tos_link_text: "Terms of Service."
@@ -3349,6 +3360,27 @@ en_IN:
invoice_email:
hi: "Hi %{name}"
invoice_attached_text: Please find attached an invoice for your recent order from
+ user_mailer:
+ reset_password_instructions:
+ request_sent_text: |
+ A request to reset your password has been made.
+ If you did not make this request, simply ignore this email.
+ link_text: >
+ If you did make this request just click the link below:
+ issue_text: |
+ If the above URL does not work try copying and pasting it into your browser.
+ If you continue to have problems please feel free to contact us.
+ confirmation_instructions:
+ subject: "Please confirm your OFN account"
+ shipment_mailer:
+ shipped_email:
+ dear_customer: "Dear Customer,"
+ instructions: "Your order has been shipped"
+ shipment_summary: "Shipment Summary"
+ subject: "Shipment Notification"
+ thanks: "Thank you for your order with us."
+ track_information: "Tracking Information: %{tracking}"
+ track_link: "Tracking Link: %{url}"
order_state:
address: address
adjustments: adjustments
@@ -3370,18 +3402,6 @@ en_IN:
ended: ended
paused: paused
canceled: cancelled
- user_mailer:
- reset_password_instructions:
- request_sent_text: |
- A request to reset your password has been made.
- If you did not make this request, simply ignore this email.
- link_text: >
- If you did make this request just click the link below:
- issue_text: |
- If the above URL does not work try copying and pasting it into your browser.
- If you continue to have problems please feel free to contact us.
- confirmation_instructions:
- subject: Please confirm your OFN account
users:
form:
account_settings: Account Settings
diff --git a/config/locales/en_NZ.yml b/config/locales/en_NZ.yml
index 226b98a5f6..987b08cdf0 100644
--- a/config/locales/en_NZ.yml
+++ b/config/locales/en_NZ.yml
@@ -13,6 +13,8 @@ en_NZ:
email: Customer E-Mail
spree/payment:
amount: Amount
+ state: State
+ source: Source
spree/product:
primary_taxon: "Product Category"
supplier: "Supplier"
@@ -182,6 +184,7 @@ en_NZ:
explainer: Automatic processing of these orders failed for an unknown reason. This should not occur, please contact us if you are seeing this.
home: "OFN"
title: "Open Food Network"
+ welcome_to: "Welcome to"
site_meta_description: "We begin from the ground up. With farmers, growers, and producers ready to tell their stories proudly and truly. With distributors ready to connect people with products fairly and honestly. With buyers who believe that better weekly shopping decisions can…"
search_by_name: Search by name or suburb...
producers_join: New Zealand producers are now welcome to join the Open Food Network.
@@ -270,6 +273,9 @@ en_NZ:
on hand: "On Hand"
ship: "Ship"
shipping_category: "Shipping Category"
+ height: "Height"
+ width: "Width"
+ depth: "Depth"
actions:
create_and_add_another: "Create and Add Another"
create: "Create"
@@ -1033,10 +1039,13 @@ en_NZ:
name: "Enterprise Fee Summary"
description: "Summary of Enterprise Fees collected"
subscriptions:
- subscriptions: Subscriptions
- new: New Subscription
- create: Create Subscription
- edit: Edit Subscription
+ index:
+ title: "Subscriptions"
+ new: "New Subscription"
+ new:
+ title: "New Subscription"
+ edit:
+ title: "Edit Subscription"
table:
edit_subscription: Edit Subscription
pause_subscription: Pause Subscription
@@ -1045,6 +1054,7 @@ en_NZ:
filters:
query_placeholder: "Search by email..."
setup_explanation:
+ title: "Subscriptions"
just_a_few_more_steps: 'Just a few more steps before you can begin:'
enable_subscriptions: "Enable subscriptions for at least one of your shops"
enable_subscriptions_step_1_html: 1. Go to the %{enterprises_link} page, find your shop, and click "Manage"
@@ -1058,6 +1068,8 @@ en_NZ:
create_at_least_one_schedule_step_3: 3. Click '+ New Schedule', and fill out the form
once_you_are_done_you_can_html: Once you are done, you can %{reload_this_page_link}
reload_this_page: reload this page
+ form:
+ create: "Create Subscription"
steps:
details: 1. Basic Details
address: 2. Address
@@ -1160,7 +1172,7 @@ en_NZ:
mobile_menu:
cart: "Cart"
register_call:
- selling_on_ofn: "Interested in getting on the Open Food Network?"
+ selling_on_ofn: "Want to set up a shop on the Open Food Network?"
register: "Register here"
footer:
footer_secure: "Secure and trusted."
@@ -1169,7 +1181,7 @@ en_NZ:
footer_contact_email: "Email us"
footer_nav_headline: "Navigate"
footer_join_headline: "Join us"
- footer_join_body: "Create a listing, shop or group directory on the Open Food Network."
+ footer_join_body: "Create a listing, build a shop or group directory on the Open Food Network."
footer_join_cta: "Tell me more!"
footer_legal_call: "Read our"
footer_legal_tos: "Terms and conditions"
@@ -1302,6 +1314,8 @@ en_NZ:
cart_updating: "Updating cart..."
cart_empty: "Cart empty"
cart_edit: "Edit your cart"
+ item: "Item"
+ qty: "Qty"
card_number: Card Number
card_securitycode: "Security Code"
card_expiry_date: Expiry Date
@@ -1377,7 +1391,7 @@ en_NZ:
system_step1: "1. Search"
system_step1_text: "Search our diverse, independent shops for seasonal local food. Search by neighbourhood and food category, or whether you prefer delivery or pickup."
system_step2: "2. Shop"
- system_step2_text: "Transform your transactions with affordable local food from diverse producers and hubs. Know the stories behind your food and the people who make it!"
+ system_step2_text: "Choose what you want, checkout as guest or make an account, you are good to go. Its that simple. If you'd like a box every week then ask for a subscription."
system_step3: "3. Pick-up / Delivery"
system_step3_text: "Hang on for your delivery, or visit your producer or hub for a more personal connection with your food. Food shopping as diverse as nature intended it."
cta_headline: "Shopping that makes the world a better place."
@@ -1713,6 +1727,7 @@ en_NZ:
remember_me: Remember Me
are_you_sure: "Are you sure?"
orders_open: "Orders open"
+ closing: "Closing"
going_back_to_home_page: "Taking you back to the home page"
creating: Creating
updating: Updating
@@ -1764,7 +1779,7 @@ en_NZ:
steps:
introduction:
registration_greeting: "Hi there!"
- registration_intro: "You can now create a profile for your Producer or Hub"
+ registration_intro: "Producer or Hub? You can create a profile"
registration_checklist: "What do I need?"
registration_time: "5-10 minutes"
registration_enterprise_address: "Enterprise address"
@@ -1956,6 +1971,8 @@ en_NZ:
supplier: "Supplier"
product_name: "Product Name"
product_description: "Product Description"
+ permalink: "Permalink"
+ shipping_categories: "Shipping Categories"
units: "Unit Size"
coordinator: "Coordinator"
distributor: "Distributor"
@@ -2052,6 +2069,8 @@ en_NZ:
remove_tax: "Remove tax"
first_name_begins_with: "First name begins with"
last_name_begins_with: "Last name begins with"
+ shipping_method: "Shipping method"
+ new_order: "New Order"
enterprise_tos_link: "Enterprise Terms of Service link"
enterprise_tos_message: "We want to work with people that share our aims and values. As such we ask new enterprises to agree to our "
enterprise_tos_link_text: "Terms of Service."
@@ -3164,6 +3183,8 @@ en_NZ:
stripe:
error_saving_payment: Error saving payment
submitting_payment: Submitting payment...
+ paypal:
+ no_payment_via_admin_backend: Paypal payments cannot be captured in the Backoffice
products:
image_upload_error: "The product image was not recognised. Please upload an image in PNG or JPG format."
new:
@@ -3341,6 +3362,32 @@ en_NZ:
invoice_email:
hi: "Hi %{name}"
invoice_attached_text: Please find attached an invoice for your recent order from
+ user_mailer:
+ reset_password_instructions:
+ request_sent_text: |
+ A request to reset your password has been made.
+ If you did not make this request, simply ignore this email.
+ link_text: >
+ If you did make this request just click the link below:
+ issue_text: |
+ If the above URL does not work try copying and pasting it into your browser.
+ If you continue to have problems please contact us.
+ confirmation_instructions:
+ subject: "Please confirm your OFN account"
+ shipment_mailer:
+ shipped_email:
+ dear_customer: "Dear Customer,"
+ instructions: "Your order has been shipped"
+ shipment_summary: "Shipment Summary"
+ subject: "Shipment Notification"
+ thanks: "Thank you for your business."
+ track_information: "Tracking Information: %{tracking}"
+ track_link: "Tracking Link: %{url}"
+ test_mailer:
+ test_email:
+ greeting: "Congratulations!"
+ message: "If you have received this email, then your email settings are correct."
+ subject: "Test Mail"
order_state:
address: address
adjustments: adjustments
@@ -3362,18 +3409,6 @@ en_NZ:
ended: ended
paused: paused
canceled: cancelled
- user_mailer:
- reset_password_instructions:
- request_sent_text: |
- A request to reset your password has been made.
- If you did not make this request, simply ignore this email.
- link_text: >
- If you did make this request just click the link below:
- issue_text: |
- If the above URL does not work try copying and pasting it into your browser.
- If you continue to have problems please contact us.
- confirmation_instructions:
- subject: Please confirm your OFN account
users:
form:
account_settings: Account Settings
diff --git a/config/locales/en_PH.yml b/config/locales/en_PH.yml
index 7ac90cfc1b..25c7dbbe71 100644
--- a/config/locales/en_PH.yml
+++ b/config/locales/en_PH.yml
@@ -13,6 +13,7 @@ en_PH:
email: Customer E-Mail
spree/payment:
amount: Amount
+ state: Province
spree/product:
primary_taxon: "Product Category"
supplier: "Supplier"
@@ -1026,10 +1027,13 @@ en_PH:
name: "Enterprise Fee Summary"
description: "Summary of Enterprise Fees collected"
subscriptions:
- subscriptions: Subscriptions
- new: New Subscription
- create: Create Subscription
- edit: Edit Subscription
+ index:
+ title: "Subscriptions"
+ new: "New Subscription"
+ new:
+ title: "New Subscription"
+ edit:
+ title: "Edit Subscription"
table:
edit_subscription: Edit Subscription
pause_subscription: Pause Subscription
@@ -1038,6 +1042,7 @@ en_PH:
filters:
query_placeholder: "Search by email..."
setup_explanation:
+ title: "Subscriptions"
just_a_few_more_steps: 'Just a few more steps before you can begin:'
enable_subscriptions: "Enable subscriptions for at least one of your shops"
enable_subscriptions_step_1_html: 1. Go to the %{enterprises_link} page, find your shop, and click "Manage"
@@ -1051,6 +1056,8 @@ en_PH:
create_at_least_one_schedule_step_3: 3. Click '+ New Schedule', and fill out the form
once_you_are_done_you_can_html: Once you are done, you can %{reload_this_page_link}
reload_this_page: reload this page
+ form:
+ create: "Create Subscription"
steps:
details: 1. Basic Details
address: 2. Address
@@ -1286,6 +1293,8 @@ en_PH:
cart_updating: "Updating cart..."
cart_empty: "Cart empty"
cart_edit: "Edit your cart"
+ item: "Item"
+ qty: "Qty"
card_number: Card Number
card_securitycode: "Security Code"
card_expiry_date: Expiry Date
@@ -1932,6 +1941,7 @@ en_PH:
supplier: "Supplier"
product_name: "Product Name"
product_description: "Product Description"
+ shipping_categories: "Shipping Categories"
units: "Unit Size"
coordinator: "Coordinator"
distributor: "Distributor"
@@ -2028,6 +2038,7 @@ en_PH:
remove_tax: "Remove tax"
first_name_begins_with: "First name begins with"
last_name_begins_with: "Last name begins with"
+ new_order: "New Order"
enterprise_tos_link: "Enterprise Terms of Service link"
enterprise_tos_message: "We want to work with people that share our aims and values. As such we ask new enterprises to agree to our "
enterprise_tos_link_text: "Terms of Service."
@@ -3276,6 +3287,27 @@ en_PH:
invoice_email:
hi: "Hi %{name}"
invoice_attached_text: Please find attached an invoice for your recent order from
+ user_mailer:
+ reset_password_instructions:
+ request_sent_text: |
+ A request to reset your password has been made.
+ If you did not make this request, simply ignore this email.
+ link_text: >
+ If you did make this request just click the link below:
+ issue_text: |
+ If the above URL does not work try copying and pasting it into your browser.
+ If you continue to have problems please feel free to contact us.
+ confirmation_instructions:
+ subject: "Please confirm your OFN account"
+ shipment_mailer:
+ shipped_email:
+ dear_customer: "Dear Customer,"
+ instructions: "Your order has been shipped"
+ shipment_summary: "Shipment Summary"
+ subject: "Shipment Notification"
+ thanks: "Thank you for your business."
+ track_information: "Tracking Information: %{tracking}"
+ track_link: "Tracking Link: %{url}"
order_state:
address: address
adjustments: adjustments
@@ -3297,18 +3329,6 @@ en_PH:
ended: ended
paused: paused
canceled: cancelled
- user_mailer:
- reset_password_instructions:
- request_sent_text: |
- A request to reset your password has been made.
- If you did not make this request, simply ignore this email.
- link_text: >
- If you did make this request just click the link below:
- issue_text: |
- If the above URL does not work try copying and pasting it into your browser.
- If you continue to have problems please feel free to contact us.
- confirmation_instructions:
- subject: Please confirm your OFN account
users:
form:
account_settings: Account Settings
diff --git a/config/locales/en_US.yml b/config/locales/en_US.yml
index f8c377e354..8cf511303b 100644
--- a/config/locales/en_US.yml
+++ b/config/locales/en_US.yml
@@ -13,6 +13,8 @@ en_US:
email: Customer E-mail
spree/payment:
amount: Amount
+ state: State
+ source: Source
spree/product:
primary_taxon: "Product Category"
supplier: "Supplier"
@@ -30,7 +32,7 @@ en_US:
spree/user:
attributes:
email:
- taken: "There's already an account registered for this email. Please login to reset your password."
+ taken: "There's already an account registered for this email. Please login or reset your password."
spree/order:
no_card: There are no authorized credit cards available to charge
spree/credit_card:
@@ -182,6 +184,7 @@ en_US:
explainer: Automatic processing of these orders failed for an unknown reason. This should not occur, please contact us if you are seeing this.
home: "OFN"
title: "Open Food Network"
+ welcome_to: "Welcome to"
site_meta_description: "We begin from the ground up. With farmers and growers ready to tell their stories proudly and truly. With distributors ready to connect people with products fairly and honestly. With buyers who believe that better weekly shopping decisions can seriously change the world."
search_by_name: Search by name or city...
producers_join: US producers are now welcome to join the Open Food Network.
@@ -270,6 +273,9 @@ en_US:
on hand: "On Hand"
ship: "Ship"
shipping_category: "Shipping Category"
+ height: "Height"
+ width: "Width"
+ depth: "Depth"
actions:
create_and_add_another: "Create and Add Another"
create: "Create"
@@ -1033,10 +1039,13 @@ en_US:
name: "Enterprise Fee Summary"
description: "Summary of Enterprise Fees collected"
subscriptions:
- subscriptions: Subscriptions
- new: New Subscription
- create: Create Subscription
- edit: Edit Subscription
+ index:
+ title: "Subscriptions"
+ new: "New Subscription"
+ new:
+ title: "New Subscription"
+ edit:
+ title: "Edit Subscription"
table:
edit_subscription: Edit Subscription
pause_subscription: Pause Subscription
@@ -1045,6 +1054,7 @@ en_US:
filters:
query_placeholder: "Search by email..."
setup_explanation:
+ title: "Subscriptions"
just_a_few_more_steps: 'Just a few more steps before you can begin:'
enable_subscriptions: "Enable subscriptions for at least one of your shops"
enable_subscriptions_step_1_html: 1. Go to the %{enterprises_link} page, find your shop, and click "Manage"
@@ -1058,6 +1068,8 @@ en_US:
create_at_least_one_schedule_step_3: 3. Click '+ New Schedule', and fill out the form
once_you_are_done_you_can_html: Once you are done, you can %{reload_this_page_link}
reload_this_page: reload this page
+ form:
+ create: "Create Subscription"
steps:
details: 1. Basic Details
address: 2. Address
@@ -1302,6 +1314,8 @@ en_US:
cart_updating: "Updating cart..."
cart_empty: "Cart empty"
cart_edit: "Edit your cart"
+ item: "Item"
+ qty: "Qty"
card_number: Card number
card_securitycode: "Security code"
card_expiry_date: Expiry date
@@ -1713,6 +1727,7 @@ en_US:
remember_me: Remember Me
are_you_sure: "Are you sure?"
orders_open: "Orders open"
+ closing: "Closing"
going_back_to_home_page: "Taking you back to the home page"
creating: Creating
updating: Updating
@@ -1956,6 +1971,8 @@ en_US:
supplier: "Supplier"
product_name: "Product Name"
product_description: "Product Description"
+ permalink: "Permalink"
+ shipping_categories: "Shipping Categories"
units: "Unit Size"
coordinator: "Coordinator"
distributor: "Distributor"
@@ -2052,6 +2069,8 @@ en_US:
remove_tax: "Remove tax"
first_name_begins_with: "First name begins with"
last_name_begins_with: "Last name begins with"
+ shipping_method: "Shipping method"
+ new_order: "New Order"
enterprise_tos_link: "Enterprise Terms of Service link"
enterprise_tos_message: "We want to work with people that share our aims and values. As such we ask new enterprises to agree to our "
enterprise_tos_link_text: "Terms of Service."
@@ -3164,6 +3183,8 @@ en_US:
stripe:
error_saving_payment: Error saving payment
submitting_payment: Submitting payment...
+ paypal:
+ no_payment_via_admin_backend: Paypal payments cannot be captured in the Backoffice
products:
image_upload_error: "The product image was not recognised. Please upload an image in PNG or JPG format."
new:
@@ -3341,6 +3362,32 @@ en_US:
invoice_email:
hi: "Hi %{name}"
invoice_attached_text: Please find attached an invoice for your recent order from
+ user_mailer:
+ reset_password_instructions:
+ request_sent_text: |
+ A request to reset your password has been made.
+ If you did not make this request, simply ignore this email.
+ link_text: >
+ If you did make this request just click the link below.
+ issue_text: |
+ If the above URL does nor work, try to copy and paste it into your browser.
+ If you continue to have problems please feel free to contact us.
+ confirmation_instructions:
+ subject: "Please confirm your OFN account"
+ shipment_mailer:
+ shipped_email:
+ dear_customer: "Dear Customer,"
+ instructions: "Your order has been shipped"
+ shipment_summary: "Shipment Summary"
+ subject: "Shipment Notification"
+ thanks: "Thank you for your business."
+ track_information: "Tracking Information: %{tracking}"
+ track_link: "Tracking Link: %{url}"
+ test_mailer:
+ test_email:
+ greeting: "Congratulations!"
+ message: "If you have received this email, then your email settings are correct."
+ subject: "Test Mail"
order_state:
address: address
adjustments: adjustments
@@ -3362,18 +3409,6 @@ en_US:
ended: ended
paused: paused
canceled: cancelled
- user_mailer:
- reset_password_instructions:
- request_sent_text: |
- A request to reset your password has been made.
- If you did not make this request, simply ignore this email.
- link_text: >
- If you did make this request just click the link below.
- issue_text: |
- If the above URL does nor work, try to copy and paste it into your browser.
- If you continue to have problems please feel free to contact us.
- confirmation_instructions:
- subject: Please confirm your OFN account
users:
form:
account_settings: Account Settings
diff --git a/config/locales/en_ZA.yml b/config/locales/en_ZA.yml
index aa488086cc..e35379630c 100644
--- a/config/locales/en_ZA.yml
+++ b/config/locales/en_ZA.yml
@@ -13,6 +13,7 @@ en_ZA:
email: Customer E-Mail
spree/payment:
amount: Amount
+ state: Province
spree/product:
primary_taxon: "Product Category"
supplier: "Supplier"
@@ -1028,10 +1029,13 @@ en_ZA:
name: "Enterprise Fee Summary"
description: "Summary of Enterprise Fees collected"
subscriptions:
- subscriptions: Subscriptions
- new: New Subscription
- create: Create Subscription
- edit: Edit Subscription
+ index:
+ title: "Subscriptions"
+ new: "New Subscription"
+ new:
+ title: "New Subscription"
+ edit:
+ title: "Edit Subscription"
table:
edit_subscription: Edit Subscription
pause_subscription: Pause Subscription
@@ -1040,6 +1044,7 @@ en_ZA:
filters:
query_placeholder: "Search by email..."
setup_explanation:
+ title: "Subscriptions"
just_a_few_more_steps: 'Just a few more steps before you can begin:'
enable_subscriptions: "Enable subscriptions for at least one of your shops"
enable_subscriptions_step_1_html: 1. Go to the %{enterprises_link} page, find your shop, and click "Manage"
@@ -1053,6 +1058,8 @@ en_ZA:
create_at_least_one_schedule_step_3: 3. Click '+ New Schedule', and fill out the form
once_you_are_done_you_can_html: Once you are done, you can %{reload_this_page_link}
reload_this_page: reload this page
+ form:
+ create: "Create Subscription"
steps:
details: 1. Basic Details
address: 2. Address
@@ -1292,6 +1299,8 @@ en_ZA:
cart_updating: "Updating cart..."
cart_empty: "Cart empty"
cart_edit: "Edit your cart"
+ item: "Item"
+ qty: "Qty"
card_number: Card Number
card_securitycode: "Security Code"
card_expiry_date: Expiry Date
@@ -1946,6 +1955,7 @@ en_ZA:
supplier: "Supplier"
product_name: "Product Name"
product_description: "Product Description"
+ shipping_categories: "Shipping Categories"
units: "Unit Size"
coordinator: "Coordinator"
distributor: "Distributor"
@@ -2042,6 +2052,7 @@ en_ZA:
remove_tax: "Remove tax"
first_name_begins_with: "First name begins with"
last_name_begins_with: "Surname begins with"
+ new_order: "New Order"
enterprise_tos_link: "Enterprise Terms of Service link"
enterprise_tos_message: "We want to work with people that share our aims and values. As such we ask new enterprises to agree to our "
enterprise_tos_link_text: "Terms of Service."
@@ -3169,6 +3180,27 @@ en_ZA:
invoice_email:
hi: "Hi %{name}"
invoice_attached_text: Please find attached an invoice for your recent order from
+ user_mailer:
+ reset_password_instructions:
+ request_sent_text: |
+ A request to reset your password has been made.
+ If you did not make this request, simply ignore this email.
+ link_text: >
+ If you did make this request just click the link below:
+ issue_text: |
+ If the above URL does not work try copying and pasting it into your browser.
+ If you continue to have problems please feel free to contact us.
+ confirmation_instructions:
+ subject: "Please confirm your OFN account"
+ shipment_mailer:
+ shipped_email:
+ dear_customer: "Dear Customer,"
+ instructions: "Your order has been shipped"
+ shipment_summary: "Shipment Summary"
+ subject: "Shipment Notification"
+ thanks: "Thank you for your order with us."
+ track_information: "Tracking Information: %{tracking}"
+ track_link: "Tracking Link: %{url}"
order_state:
address: address
adjustments: adjustments
@@ -3190,18 +3222,6 @@ en_ZA:
ended: ended
paused: paused
canceled: cancelled
- user_mailer:
- reset_password_instructions:
- request_sent_text: |
- A request to reset your password has been made.
- If you did not make this request, simply ignore this email.
- link_text: >
- If you did make this request just click the link below:
- issue_text: |
- If the above URL does not work try copying and pasting it into your browser.
- If you continue to have problems please feel free to contact us.
- confirmation_instructions:
- subject: Please confirm your OFN account
users:
form:
account_settings: Account Settings
diff --git a/config/locales/es.yml b/config/locales/es.yml
index 75eed08b9d..206400d614 100644
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -13,6 +13,8 @@ es:
email: E-mail del consumidor
spree/payment:
amount: Cantidad
+ state: Provincia
+ source: Source
spree/product:
primary_taxon: "categoría del producto"
supplier: "Proveedora"
@@ -182,6 +184,7 @@ es:
explainer: El procesamiento automático de estas órdenes falló por un motivo desconocido. Esto no debería ocurrir, contáctanos si estás viendo esto.
home: "OFN"
title: "Open Food Network"
+ welcome_to: "Bienvenido a"
site_meta_description: "Nosotros empezamos desde abajo. Con granjeros y productoras listas para contar sus historias con orgullo y autenticidad. Con distribuidoras listas para conectar gente con productos de forma justa y honesta. Con compradores que creen que mejores decisiones de compras semanales pueden..."
search_by_name: Buscar por nombre o municipio...
producers_join: Las productoras australianas ahora son bienvenidas a unirse a Open Food Network.
@@ -270,6 +273,9 @@ es:
on hand: "Disponibles"
ship: "Envío"
shipping_category: "Categoría de envío"
+ height: "Altura"
+ width: "Anchura"
+ depth: "Profundidad"
actions:
create_and_add_another: "Crear y agregar otro"
create: "Crear"
@@ -1035,10 +1041,13 @@ es:
name: "Resumen de las comisiones de la organización"
description: "Resumen de las comisiones de la organización recolectadas"
subscriptions:
- subscriptions: Suscripciones
- new: Nueva suscripción
- create: Crear suscripción
- edit: Editar suscripción
+ index:
+ title: "Suscripciones"
+ new: "Nueva suscripción"
+ new:
+ title: "Nueva suscripción"
+ edit:
+ title: "Editar suscripción"
table:
edit_subscription: Editar suscripción
pause_subscription: Pausa Suscripción
@@ -1047,6 +1056,7 @@ es:
filters:
query_placeholder: "Buscar por correo electrónico ..."
setup_explanation:
+ title: "Suscripciones"
just_a_few_more_steps: 'Solo unos pocos pasos más antes de que pueda comenzar:'
enable_subscriptions: "Habilita suscripciones para al menos una de tus tiendas"
enable_subscriptions_step_1_html: 1. Vaya a la página %{enterprises_link}, encuentre su tienda y haga clic en "Administrar"
@@ -1060,6 +1070,8 @@ es:
create_at_least_one_schedule_step_3: 3. Haga clic en '+ Nueva programación' y complete el formulario
once_you_are_done_you_can_html: Una vez que haya terminado, puede %{reload_this_page_link}
reload_this_page: recarga esta página
+ form:
+ create: "Crear suscripción"
steps:
details: 1. Detalles básicos
address: 2. Dirección
@@ -1151,7 +1163,12 @@ es:
cart: "Carrito"
cart_sidebar:
checkout: "Validar"
+ edit_cart: "Editar carrito"
+ items_in_cart_singular: "%{num} artículo en su carrito"
+ items_in_cart_plural: "%{num} artículos en su carrito"
close: "Cerrar"
+ cart_empty: "Tu carrito esta vacío"
+ take_me_shopping: "¡Llévame de compras!"
signed_in:
profile: "Perfil"
mobile_menu:
@@ -1299,6 +1316,8 @@ es:
cart_updating: "Actualizando el carrito..."
cart_empty: "Carrito vacío"
cart_edit: "Editar carrito"
+ item: "Artículo"
+ qty: "Cantidad"
card_number: Número de tarjeta
card_securitycode: "Código de seguridad"
card_expiry_date: Fecha de expiración
@@ -1710,6 +1729,7 @@ es:
remember_me: Recordarme
are_you_sure: "¿Está seguro?"
orders_open: "Pedidos abiertos"
+ closing: "Cerrando"
going_back_to_home_page: "Le estamos llevando de vuelta a la página de inicio"
creating: Creando
updating: Actualizando
@@ -1953,6 +1973,8 @@ es:
supplier: "Proveedora"
product_name: "nombre del producto"
product_description: "Descripción del producto"
+ permalink: "Enlace permanente"
+ shipping_categories: "Categorías de envío"
units: "Unidad de medida"
coordinator: "Coordinadora"
distributor: "Distribuidor"
@@ -2049,6 +2071,8 @@ es:
remove_tax: "Eliminar impuesto"
first_name_begins_with: "El nombre comienza con"
last_name_begins_with: "El apellido comienza con"
+ shipping_method: "Método de envío"
+ new_order: "Nuevo pedido"
enterprise_tos_link: "Enlace a los Términos del Servicio de la Organización"
enterprise_tos_message: "Queremos trabajar con personas que compartan nuestros objetivos y valores. Por ello, pedimos a las nuevas organizaciones que acepten"
enterprise_tos_link_text: "Términos del Servicio."
@@ -2067,6 +2091,7 @@ es:
hub_sidebar_at_least: "Al menos un grupo debe ser seleccionado"
hub_sidebar_blue: "azul"
hub_sidebar_red: "rojo"
+ order_cycles_closed_for_hub: "El grupo que ha seleccionado está temporalmente cerrado para pedidos. Por favor, inténtelo de nuevo más tarde."
report_customers_distributor: "Distribuidor"
report_customers_supplier: "Proveedora"
report_customers_cycle: "Ciclo de Pedido"
@@ -2303,6 +2328,7 @@ es:
order_cycles_email_to_producers_notice: 'Los correos electrónicos que se enviarán a las productoras se han puesto en cola para enviarlos.'
order_cycles_no_permission_to_coordinate_error: "Ninguna de tus organizaciones tiene permiso para coordinar un ciclo de pedido"
order_cycles_no_permission_to_create_error: "No tienes permiso para crear un ciclo de pedido coordinado por esta empresa."
+ order_cycle_closed: "El ciclo de pedido que ha seleccionado se acaba de cerrar. ¡Inténtalo de nuevo!"
back_to_orders_list: "Volver a la lista de pedidos"
no_orders_found: "No se encontraron pedidos"
order_information: "información del pedido"
@@ -3163,6 +3189,8 @@ es:
stripe:
error_saving_payment: Error al guardar el pago
submitting_payment: Enviando pago...
+ paypal:
+ no_payment_via_admin_backend: Los pagos de PayPal no se pueden capturar desde la administración
products:
image_upload_error: "La imagen del producto no fue reconocida. Por favor, cargue una imagen en formato PNG o JPG."
new:
@@ -3340,6 +3368,32 @@ es:
invoice_email:
hi: "Hola %{name}"
invoice_attached_text: Adjunta una factura para su pedido reciente de
+ user_mailer:
+ reset_password_instructions:
+ request_sent_text: |
+ Se ha solicitado el cambio de tu contraseña.
+ Si tu no lo has solicitado simplemente ignora este email.
+ link_text: >
+ Si has solicitado esta acción haz click en el siguiente enlace:
+ issue_text: |
+ Si el enlace no funciona prueba a copiarlo y pegarlo en tu navegador.
+ Si los problemas continúan no dudes en contactarnos.
+ confirmation_instructions:
+ subject: "Por favor, confirma tu cuenta de OFN"
+ shipment_mailer:
+ shipped_email:
+ dear_customer: "Estimada consumidora,"
+ instructions: "Tu pedido ha sido enviado"
+ shipment_summary: "Resumen de envío"
+ subject: "Notificación de envío"
+ thanks: "Gracias por hacer negocios."
+ track_information: "Información de seguimiento: %{tracking}"
+ track_link: "Enlace de seguimiento: %{url}"
+ test_mailer:
+ test_email:
+ greeting: "¡Felicidades!"
+ message: "Si ha recibido este correo electrónico, su configuración de correo electrónico es correcta."
+ subject: "Correo de prueba"
order_state:
address: dirección
adjustments: ajustes
@@ -3361,18 +3415,6 @@ es:
ended: terminado
paused: pausado
canceled: cancelado
- user_mailer:
- reset_password_instructions:
- request_sent_text: |
- Se ha solicitado el cambio de tu contraseña.
- Si tu no lo has solicitado simplemente ignora este email.
- link_text: >
- Si has solicitado esta acción haz click en el siguiente enlace:
- issue_text: |
- Si el enlace no funciona prueba a copiarlo y pegarlo en tu navegador.
- Si los problemas continúan no dudes en contactarnos.
- confirmation_instructions:
- subject: Por favor, confirma tu cuenta de OFN
users:
form:
account_settings: Configuración de la cuenta
diff --git a/config/locales/es_CR.yml b/config/locales/es_CR.yml
index d22b5cdff1..fd81f7dc12 100644
--- a/config/locales/es_CR.yml
+++ b/config/locales/es_CR.yml
@@ -13,6 +13,7 @@ es_CR:
email: Correo electrónico del cliente
spree/payment:
amount: Cantidad
+ state: Provincia
spree/product:
primary_taxon: "Categoría del producto"
supplier: "Proveedor"
@@ -1029,10 +1030,13 @@ es_CR:
name: "Resumen de las comisiones de la organización"
description: "Resumen de las comisiones de la organización recolectadas"
subscriptions:
- subscriptions: Suscripciones
- new: Nueva suscripción
- create: Crear suscripción
- edit: Editar suscripción
+ index:
+ title: "Suscripciones"
+ new: "Nueva suscripción"
+ new:
+ title: "Nueva suscripción"
+ edit:
+ title: "Editar suscripción"
table:
edit_subscription: Editar suscripción
pause_subscription: Pausar suscripción
@@ -1041,6 +1045,7 @@ es_CR:
filters:
query_placeholder: "Buscar por correo electrónico ..."
setup_explanation:
+ title: "Suscripciones"
just_a_few_more_steps: 'Solo unos pocos pasos más antes de que pueda comenzar:'
enable_subscriptions: "Habilita suscripciones para al menos una de sus tiendas"
enable_subscriptions_step_1_html: 1. Ir a la página %{enterprises_link}, encuentre su tienda y haga clic en "Administrar"
@@ -1054,6 +1059,8 @@ es_CR:
create_at_least_one_schedule_step_3: 3. Haga clic en '+ Nueva programación' y complete el formulario
once_you_are_done_you_can_html: Una vez que haya terminado, puede %{reload_this_page_link}
reload_this_page: recarga esta página
+ form:
+ create: "Crear suscripción"
steps:
details: 1. Detalles básicos
address: 2. Dirección
@@ -1289,6 +1296,8 @@ es_CR:
cart_updating: "Actualizando el carrito..."
cart_empty: "Carrito vacío"
cart_edit: "Editar carrito"
+ item: "Artículo"
+ qty: "Cantidad"
card_number: Número de tarjeta
card_securitycode: "Código de seguridad"
card_expiry_date: Fecha de expiración
@@ -1936,6 +1945,7 @@ es_CR:
supplier: "Proveedora"
product_name: "nombre del producto"
product_description: "Descripción del producto"
+ shipping_categories: "Categorías de envío"
units: "Unidad de medida"
coordinator: "Coordinadora"
distributor: "Distribuidor"
@@ -2032,6 +2042,7 @@ es_CR:
remove_tax: "Eliminar impuesto"
first_name_begins_with: "El nombre comienza con"
last_name_begins_with: "El apellido comienza con"
+ new_order: "Nuevo pedido"
enterprise_tos_link: "Enlace a los Términos del Servicio de la Organización"
enterprise_tos_message: "Queremos trabajar con personas que compartan nuestros objetivos y valores. Por ello, pedimos a las nuevas organizaciones que acepten"
enterprise_tos_link_text: "Términos del Servicio."
@@ -3284,6 +3295,27 @@ es_CR:
invoice_email:
hi: "Hola %{name}"
invoice_attached_text: Adjunta una factura para su pedido reciente de
+ user_mailer:
+ reset_password_instructions:
+ request_sent_text: |
+ La solicitud de restablecer su contraseña se ha realizado.
+ Si usted no lo ha solicitado, ignora este correo electrónico.
+ link_text: >
+ Si has solicitado esta acción haz click en el siguiente enlace:
+ issue_text: |
+ Si el enlace anterior no funciona pruebe con copiarlo y pegarlo en su navegador.
+ Si los problemas continúan no dude en contactarnos.
+ confirmation_instructions:
+ subject: "Por favor, confirma tu cuenta de OFN"
+ shipment_mailer:
+ shipped_email:
+ dear_customer: "Estimado cliente,"
+ instructions: "Su pedido ha sido enviado"
+ shipment_summary: "Resumen de envío"
+ subject: "Notificación de envío"
+ thanks: "Gracias por su negocio."
+ track_information: "Información de seguimiento: %{tracking}"
+ track_link: "Enlace de seguimiento: %{url}"
order_state:
address: dirección
adjustments: ajustes
@@ -3305,18 +3337,6 @@ es_CR:
ended: terminado
paused: pausado
canceled: cancelado
- user_mailer:
- reset_password_instructions:
- request_sent_text: |
- La solicitud de restablecer su contraseña se ha realizado.
- Si usted no lo ha solicitado, ignora este correo electrónico.
- link_text: >
- Si has solicitado esta acción haz click en el siguiente enlace:
- issue_text: |
- Si el enlace anterior no funciona pruebe con copiarlo y pegarlo en su navegador.
- Si los problemas continúan no dude en contactarnos.
- confirmation_instructions:
- subject: Por favor, confirma tu cuenta de OFN
users:
form:
account_settings: Configuración de la cuenta
diff --git a/config/locales/fil_PH.yml b/config/locales/fil_PH.yml
index 94f2cac702..a22b91439c 100644
--- a/config/locales/fil_PH.yml
+++ b/config/locales/fil_PH.yml
@@ -13,6 +13,7 @@ fil_PH:
email: Email ng Parokyano
spree/payment:
amount: Halaga
+ state: province
spree/product:
primary_taxon: "Kategorya ng Produkto"
supplier: "Supplier"
@@ -315,7 +316,7 @@ fil_PH:
clear_all: alisin lahat
start_date: "Petsa ng Pagsimula"
end_date: "Petsa ng Pagtatapos"
- form_invalid: "ang form ay may nawawala o hindi valid na sagot sa mga patlang"
+ form_invalid: "ang form ay may kulang o hindi valid na mga sagot"
clear_filters: alisin ang mga filter
clear: alisin
save: i-save
@@ -355,7 +356,7 @@ fil_PH:
settings: "settings"
stripe_connect_enabled: paganahin ang pagtanggap ng mga bayad gamit ang Stripe Connect sa mga Shop?
no_api_key_msg: walang Stripe account para sa enterprise na ito
- configuration_explanation_html: para sa detalyadong panuto sa pag-configure ng pagsasama ng Stripe Connect, maaari lamang nakumonsulta sa gabay.
+ configuration_explanation_html: para sa detalyadong panuto sa pag-configure upang magamit ang Stripe Connect, maaari lamang nakumonsulta sa gabay.
status: Status
ok: Ok
instance_secret_key: Instance Secret Key
@@ -387,11 +388,11 @@ fil_PH:
select_state: 'pumili ng Lalawigan'
edit: 'i-edit'
update_address: 'i-update ang address'
- confirm_delete: 'siguradong tatanggalin?'
+ confirm_delete: 'siguradong tatanggalin na?'
search_by_email: "hanapin gamit ang email/code..."
guest_label: 'Guest checkout'
destroy:
- has_associated_orders: 'hindi tagumpay ang pagtanggal: ang customer ay may mga iniugnay na order sa kaniyang shop'
+ has_associated_orders: 'hindi tagumpay ang pagtanggal: ang customer ay may iniugnay na mga order sa kaniyang shop'
contents:
edit:
title: nilalaman
@@ -423,7 +424,7 @@ fil_PH:
form:
manages: namamahala
enterprise_role:
- manages: namamahala
+ manages: pinamamahalaan
products:
unit_name_placeholder: 'hal. mga kumpol'
index:
@@ -541,7 +542,7 @@ fil_PH:
products_created: ang mga produkto ay nagawa na
products_updated: in-update ang mga produkto
inventory_created: ang mga imbentaryo ng item ay nagawa na
- inventory_updated: inupdate ang mga inimbentaryong item
+ inventory_updated: inupdate ang mga naka-imbentaryong item
products_reset: na-reset sa zero ang lebel ng stock ng mga produkto
inventory_reset: na-reset sa zero ang lebel ng stock ng mga imbentaryo ng item
all_saved: "lahat ng mga item ay matagumpay na na-save"
@@ -1029,10 +1030,13 @@ fil_PH:
name: "buod ng bayad sa enterprise"
description: "buod ng mga nakolektang fees para sa enterprise"
subscriptions:
- subscriptions: mga subscription
- new: bagong subscription
- create: gumawa ng subscription
- edit: i-edit ang subscription
+ index:
+ title: "mga nauulit na order"
+ new: "bagong subscription"
+ new:
+ title: "bagong subscription"
+ edit:
+ title: "i-edit ang subscription"
table:
edit_subscription: i-edit ang subscription
pause_subscription: panandaliang ihinto ang subscription
@@ -1041,6 +1045,7 @@ fil_PH:
filters:
query_placeholder: "hanapin gamit ang email..."
setup_explanation:
+ title: "mga nauulit na order"
just_a_few_more_steps: 'ilang hakbang na lamang bago ka makapagsimula:'
enable_subscriptions: "paganahin ang subscription sa kahit isa sa iyong mga shop"
enable_subscriptions_step_1_html: 1. pumunta sa%{enterprises_link}pahina, hanapin ang iyong shop at pindutin ang "pamahalaan"
@@ -1054,6 +1059,8 @@ fil_PH:
create_at_least_one_schedule_step_3: 3. pindutin ang '+ bagong iskedyul' at sagutan ang form
once_you_are_done_you_can_html: kapag natapos na ito, maaari mong%{reload_this_page_link}
reload_this_page: i-reload ang pahina na ito
+ form:
+ create: "gumawa ng subscription"
steps:
details: 1. pangunahing detalye
address: 2. address
@@ -1107,7 +1114,7 @@ fil_PH:
yes_cancel_them: kanselahin
no_keep_them: ituloy
yes_i_am_sure: oo, sigurado ako
- order_update_issues_msg: ang ibang mga order ay hindi awtomatikong ma-update, sapagkat ito ay manwal na inayos. Tignan ang mga isyu na nakalista sa baba at gawin ang nararapat na pag-aayos sa bawat order kung kinakailangan.
+ order_update_issues_msg: "ang ibang mga order ay hindi awtomatikong ma-update, sapagkat ito ay manwal na inayos. Tignan ang mga isyu na nakalista sa baba at gawin ang nararapat na pag-aayos sa bawat indibiduwal na \norder kung kinakailangan."
no_results:
no_subscriptions: wala pang mga subscription....
why_dont_you_add_one: nais mo bang magdagdag ng isa? :)
@@ -1165,7 +1172,7 @@ fil_PH:
footer_legal_call: "basahin ang aming"
footer_legal_tos: "mga tuntunin at kondisyon"
footer_legal_visit: "Hanapin kami sa"
- footer_legal_text_html: "ang Open Food Network ay isang libre at bukas ang pinagkukuhanang platform. ang mga nilalaman nito ay lisensiyado ng%{content_license}at ang aming mga code ng %{code_license}."
+ footer_legal_text_html: "ang Open Food Network ay isang libre at open source software platform. ang mga nilalaman nito ay lisensiyado ng%{content_license}at ang aming mga code ng %{code_license}."
footer_data_text_with_privacy_policy_html: "Pinangangalagaan namin ang inyong impormasyon. Basahin ang aming%{privacy_policy}at%{cookies_policy}"
footer_data_text_without_privacy_policy_html: "Pinangangalagaan namin ang inyong impormasyon. Basahin ang aming%{cookies_policy}"
footer_data_privacy_policy: "patakaran ng privacy"
@@ -1280,8 +1287,8 @@ fil_PH:
label_administration: "administrasyon"
label_admin: "admin"
label_account: "Account"
- label_more: "ipakita lahat"
- label_less: "ipakita ang mas kaunti"
+ label_more: "ipakita ang iba pa"
+ label_less: "huwag ipakita ang lahat"
label_notices: "mga abiso"
cart_items: "mga item"
cart_headline: "Ang iyong shopping cart"
@@ -1289,6 +1296,8 @@ fil_PH:
cart_updating: "ina-update ang cart"
cart_empty: "walang laman ang cart"
cart_edit: "i-edit ang cart"
+ item: "Item"
+ qty: "Dami"
card_number: numero ng card
card_securitycode: "Security code"
card_expiry_date: petsa ng pag-expire
@@ -1936,6 +1945,7 @@ fil_PH:
supplier: "Supplier"
product_name: "pangalan ng produkto"
product_description: "paglalarawan ng produkto"
+ shipping_categories: "mga kategorya ng pagpapadala"
units: "laki kada yunit"
coordinator: "coordinator"
distributor: "Distributor"
@@ -2032,6 +2042,7 @@ fil_PH:
remove_tax: "alisin ang tax"
first_name_begins_with: "ang pangalan ay nagsisimula sa"
last_name_begins_with: "ang apelyido ay nagsisimula sa"
+ new_order: "bagong order"
enterprise_tos_link: "Link para sa palatuntunan ng serbisyo ng Enterprise"
enterprise_tos_message: "nais naming makiisa sa mga taong kapareho ng aming layunin at adhikain. Dahil dito, hinihiling namin sa mga bagong enterprise na sumang-ayon sa aming"
enterprise_tos_link_text: "Mga Tuntunin ng Serbisyo."
@@ -3289,6 +3300,27 @@ fil_PH:
invoice_email:
hi: "Hi %{name}"
invoice_attached_text: 'tignan ang nakalakip na invoice para sa pinakabagong order mula sa '
+ user_mailer:
+ reset_password_instructions:
+ request_sent_text: |
+ may ginawang request para i-reset ang inyong password.
+ kung hindi ikaw ang gumawa nito, huwag pansinin ang email na ito.
+ link_text: >
+ kung ikaw ang gumawa ng request na ito, pindutin ang link sa ilalim:
+ issue_text: |
+ kung ang URL sa itaas ay hindi gumagana, subukang kopyahin at i-paste ito sa inyong browser.
+ kung patuloy na magkakaroon ng mga problema, huwag mag-atubiling makipag-ugnayan sa amin.
+ confirmation_instructions:
+ subject: "kumpirmahin ang inyong OFN account"
+ shipment_mailer:
+ shipped_email:
+ dear_customer: "Dear Customer,"
+ instructions: "ang iyong order ay na-ship na "
+ shipment_summary: "buod ng kargamento"
+ subject: "notification ukol sa kargamento"
+ thanks: "Salamat sa inyong pagtangkilik"
+ track_information: "Impormasyon ukol sa pag-track: %{tracking}"
+ track_link: "Link ng pag-track:%{url}"
order_state:
address: tirahan
adjustments: mga pagsasaayos
@@ -3310,18 +3342,6 @@ fil_PH:
ended: natapos na
paused: nakahinto
canceled: kanselado
- user_mailer:
- reset_password_instructions:
- request_sent_text: |
- may ginawang request para i-reset ang inyong password.
- kung hindi ikaw ang gumawa nito, huwag pansinin ang email na ito.
- link_text: >
- kung ikaw ang gumawa ng request na ito, pindutin ang link sa ilalim:
- issue_text: |
- kung ang URL sa itaas ay hindi gumagana, subukang kopyahin at i-paste ito sa inyong browser.
- kung patuloy na magkakaroon ng mga problema, huwag mag-atubiling makipag-ugnayan sa amin.
- confirmation_instructions:
- subject: kumpirmahin ang inyong OFN account
users:
form:
account_settings: Setting ng Account
diff --git a/config/locales/fr.yml b/config/locales/fr.yml
index eb8d4e055d..29757b8572 100644
--- a/config/locales/fr.yml
+++ b/config/locales/fr.yml
@@ -13,6 +13,8 @@ fr:
email: Email acheteur
spree/payment:
amount: Montant
+ state: Statut
+ source: Source
spree/product:
primary_taxon: "Catégorie Produit"
supplier: "Fournisseur"
@@ -271,6 +273,9 @@ fr:
on hand: "En stock"
ship: "Expédier"
shipping_category: "Condition de transport"
+ height: "Hauteur"
+ width: "Largeur"
+ depth: "Profondeur"
actions:
create_and_add_another: "Créer et ajouter nouveau"
create: "Créer"
@@ -1036,10 +1041,13 @@ fr:
name: "Résumé des marges et commissions"
description: "Résumé des marges et commissions collectées"
subscriptions:
- subscriptions: Abonnements
- new: Nouvel abonnement
- create: Créer abonnement
- edit: Mettre à jour Abonnement
+ index:
+ title: "Abonnements"
+ new: "Nouvel abonnement"
+ new:
+ title: "Nouvel abonnement"
+ edit:
+ title: "Mettre à jour Abonnement"
table:
edit_subscription: Mettre à jour Abonnement
pause_subscription: Mettre en pause Abonnement
@@ -1048,6 +1056,7 @@ fr:
filters:
query_placeholder: "Recherche par email"
setup_explanation:
+ title: "Abonnements"
just_a_few_more_steps: 'Encore quelques étapes avant de pouvoir commencer:'
enable_subscriptions: "Activez la fonction abonnements pour au moins une de vos boutiques"
enable_subscriptions_step_1_html: 1. Allez à %{enterprises_link}, trouvez votre boutique, et cliquez sur "Gérer"
@@ -1061,6 +1070,8 @@ fr:
create_at_least_one_schedule_step_3: 3. Cliquez sur "+ Nouveau Rythme d'abonnement", et remplissez le formulaire
once_you_are_done_you_can_html: Une fois que c'est fait, vous pouvez %{reload_this_page_link}
reload_this_page: recharger cette page
+ form:
+ create: "Créer abonnement"
steps:
details: 1. Informations de base
address: 2. Adresse
@@ -1151,7 +1162,7 @@ fr:
cart:
cart: "Panier"
cart_sidebar:
- checkout: "Etape suivante (coordonnées)"
+ checkout: "Etape suivante"
edit_cart: "Modifier le panier"
items_in_cart_singular: "%{num} élément dans le panier"
items_in_cart_plural: "%{num} éléments dans le panier"
@@ -1305,6 +1316,8 @@ fr:
cart_updating: "Mettre à jour le panier"
cart_empty: "Panier vide"
cart_edit: "Modifier votre panier"
+ item: "Produit"
+ qty: "Qté"
card_number: Numéro de carte
card_securitycode: "Cryptogramme visuel"
card_expiry_date: Date d'expiration
@@ -1400,7 +1413,7 @@ fr:
checkout_details: "Vos informations"
checkout_billing: "Informations de facturation"
checkout_default_bill_address: "Sauvegarder comme adresse de facturation par défaut"
- checkout_shipping: Informations de livraison
+ checkout_shipping: Informations de livraison ou de retrait
checkout_default_ship_address: "Sauvegarder comme adresse de livraison par défaut"
checkout_method_free: Pas de frais supplémentaires
checkout_address_same: Adresse de livraison identique à l'adresse de facturation?
@@ -1960,6 +1973,8 @@ fr:
supplier: "Fournisseur"
product_name: "Nom du Produit"
product_description: "Description du Produit"
+ permalink: "Permalien"
+ shipping_categories: "Conditions de transport"
units: "Unité de mesure"
coordinator: "Coordinateur"
distributor: "Distributeur"
@@ -2056,6 +2071,8 @@ fr:
remove_tax: "Retirer TVA"
first_name_begins_with: "Prénom commence par"
last_name_begins_with: "Nom de famille commence par"
+ shipping_method: "Méthode de livraison"
+ new_order: "Nouvelle commande"
enterprise_tos_link: "Lien vers les Conditions Générales d'Utilisation"
enterprise_tos_message: "Nous soutenons la mise en place d'un système alimentaire résilient et durable, et souhaitons œuvrer avec des entreprises qui partagent nos valeurs et notre vision. Ainsi, nous demandons aux entreprises s'enregistrant sur Open Food France de valider nos "
enterprise_tos_link_text: "Conditions d'utilisation"
@@ -3139,12 +3156,12 @@ fr:
zones: "Zones"
both: "Vu par l'acheteur sur la boutique"
back_end: "Visible pour l'administration uniquement"
- deactivation_warning: "Désactiver une méthode de livraison peut engendre sa disparition de la liste ici. Si vous souhaitez uniquement ne plus l'afficher pour l'acheteur, modifiez-là et utilisez l'option d'affichage \"visible pour l'administrateur uniquement\"."
+ deactivation_warning: "Désactiver une méthode de livraison peut engendrer sa disparition de la liste ici. Si vous souhaitez uniquement ne plus l'afficher pour l'acheteur, modifiez-là et utilisez l'option d'affichage \"visible pour l'administrateur uniquement\"."
payment_methods:
index:
payment_methods: "Méthodes de paiement"
new_payment_method: "Nouvelle méthode de paiement"
- name: "Produit/Variante"
+ name: "Nom"
products_distributor: "Distributeur"
provider: "Fournisseur"
environment: "Environnement"
@@ -3177,7 +3194,7 @@ fr:
business_name: Nom de l'entreprise
charges_enabled: Frais activés
form:
- name: "Produit/Variante"
+ name: "Nom"
description: "Description"
environment: "Environnement"
display: "Afficher"
@@ -3196,6 +3213,8 @@ fr:
stripe:
error_saving_payment: Erreur à l'enregistrement du paiement
submitting_payment: Envoi du paiement...
+ paypal:
+ no_payment_via_admin_backend: 'Il n''est pas encore possible de payer avec Paypal via l''administration. '
products:
image_upload_error: "L'image du produit n'a pas été reconnue. Veuillez importer une image au format PNG ou JPG."
new:
@@ -3373,6 +3392,33 @@ fr:
invoice_email:
hi: "Bonjour %{name}"
invoice_attached_text: 'Veuillez trouver ci-joint la facture pour votre récente commande auprès de '
+ user_mailer:
+ reset_password_instructions:
+ request_sent_text: |
+ Votre demande de nouveau mot de passe a bien été prise en compte.
+ Si vous n'avez pas demandé de nouveau mot de passe, veuillez ignorer cet e-mail.
+ link_text: >
+ Si vous êtes bien à l'origine de cette demande, veuillez cliquer sur le
+ lien ci-dessous :
+ issue_text: |
+ Si le lien ne fonctionne pas, essayez de le copier - coller dans la barre d'adresse de votre navigateur.
+ Si le problème persiste, n'hésitez pas à nous contacter.
+ confirmation_instructions:
+ subject: "Veuillez confirmer votre compte"
+ shipment_mailer:
+ shipped_email:
+ dear_customer: "Cher Acheteur,"
+ instructions: "Votre commande a été expédiée"
+ shipment_summary: "Résumé de l'envoi"
+ subject: "Notification d'expédition"
+ thanks: "Merci pour votre commande."
+ track_information: "Informations de suivi : %{tracking}"
+ track_link: "Lien de suivi : %{url}"
+ test_mailer:
+ test_email:
+ greeting: "Félicitations !"
+ message: "Si vous avez reçu cet email, cela signifie que vos emails sont bien paramétrés."
+ subject: "Mail de test"
order_state:
address: adresse
adjustments: ajustements
@@ -3394,19 +3440,6 @@ fr:
ended: terminé
paused: mis en pause
canceled: annulé
- user_mailer:
- reset_password_instructions:
- request_sent_text: |
- Votre demande de nouveau mot de passe a bien été prise en compte.
- Si vous n'avez pas demandé de nouveau mot de passe, veuillez ignorer cet e-mail.
- link_text: >
- Si vous êtes bien à l'origine de cette demande, veuillez cliquer sur le
- lien ci-dessous :
- issue_text: |
- Si le lien ne fonctionne pas, essayez de le copier - coller dans la barre d'adresse de votre navigateur.
- Si le problème persiste, n'hésitez pas à nous contacter.
- confirmation_instructions:
- subject: Veuillez confirmer votre compte
users:
form:
account_settings: Paramètres du Compte
diff --git a/config/locales/fr_BE.yml b/config/locales/fr_BE.yml
index a8822f7337..0cda69808c 100644
--- a/config/locales/fr_BE.yml
+++ b/config/locales/fr_BE.yml
@@ -13,6 +13,7 @@ fr_BE:
email: Adresse électronique acheteur
spree/payment:
amount: Montant
+ state: Statut de la commande
spree/product:
primary_taxon: "Catégorie de Produit"
supplier: "Fournisseur"
@@ -1028,10 +1029,13 @@ fr_BE:
name: "Récapitulatif de la commission d'entreprise "
description: "Récapitulatif des commissions d'entreprise perçues"
subscriptions:
- subscriptions: Abonnements
- new: Nouvel abonnement
- create: Créer abonnement
- edit: Mettre à jour Abonnement
+ index:
+ title: "commandes récurrantes"
+ new: "Nouvel abonnement"
+ new:
+ title: "Nouvel abonnement"
+ edit:
+ title: "Mettre à jour Abonnement"
table:
edit_subscription: Mettre à jour Abonnement
pause_subscription: Mettre en pause Abonnement
@@ -1040,6 +1044,7 @@ fr_BE:
filters:
query_placeholder: "Recherche par email ..."
setup_explanation:
+ title: "commandes récurrantes"
just_a_few_more_steps: 'Encore quelques étapes avant de pouvoir commencer:'
enable_subscriptions: "Activez la fonction abonnements pour au moins une de vos comptoirs"
enable_subscriptions_step_1_html: 1. Allez à %{enterprises_link}, trouvez votre comptoir, et cliquez sur "Gérer"
@@ -1053,6 +1058,8 @@ fr_BE:
create_at_least_one_schedule_step_3: 3. Cliquez sur "+ Nouveau Rythme d'abonnement", et remplissez le formulaire
once_you_are_done_you_can_html: Une fois que c'est fait, vous pouvez %{reload_this_page_link}
reload_this_page: recharger cette page
+ form:
+ create: "Créer abonnement"
steps:
details: 1. Informations de base
address: 2. Adresse
@@ -1292,6 +1299,8 @@ fr_BE:
cart_updating: "Mettre à jour le panier"
cart_empty: "Panier vide"
cart_edit: "Modifier votre panier"
+ item: "Produit"
+ qty: "Qté"
card_number: Numéro de carte
card_securitycode: "Cryptogramme visuel"
card_expiry_date: Date d'expiration
@@ -1939,6 +1948,7 @@ fr_BE:
supplier: "Fournisseurs"
product_name: "Nom du Produit"
product_description: "Description du Produit"
+ shipping_categories: "Condition de transport"
units: "Unité de mesure"
coordinator: "Coordinateur"
distributor: "Distributeur"
@@ -2035,6 +2045,7 @@ fr_BE:
remove_tax: "Retirer TVA"
first_name_begins_with: "Début du prénom"
last_name_begins_with: "Début du nom de famille"
+ new_order: "Nouvelle commande"
enterprise_tos_link: "Lien vers les Conditions Générales d'Utilisation"
enterprise_tos_message: "Nous soutenons la mise en place d'un système alimentaire résilient et durable, et souhaitons œuvrer avec des acteurs et actrices qui partagent nos valeurs et notre vision. Ainsi, nous demandons aux acteurs s'enregistrant sur Open Food Network de valider nos "
enterprise_tos_link_text: "Conditions d'utilisation"
@@ -3227,6 +3238,28 @@ fr_BE:
invoice_email:
hi: "Bonjour %{name}"
invoice_attached_text: 'Veuillez trouver ci-joint la facture pour votre récente commande auprès de '
+ user_mailer:
+ reset_password_instructions:
+ request_sent_text: |
+ Votre demande de nouveau mot de passe a bien été prise en compte.
+ Si vous n'avez pas demandé de nouveau mot de passe, veuillez ignorer cet e-mail.
+ link_text: >
+ Si vous êtes bien à l'origine de cette demande, veuillez cliquer sur le
+ lien ci-dessous :
+ issue_text: |
+ Si le lien ne fonctionne pas, essayez de le copier - coller dans la barre d'adresse de votre navigateur.
+ Si le problème persiste, n'hésitez pas à nous contacter.
+ confirmation_instructions:
+ subject: "Veuillez confirmer votre compte"
+ shipment_mailer:
+ shipped_email:
+ dear_customer: "Cher Client,"
+ instructions: "Votre commande a été expédiée"
+ shipment_summary: "Résumé de l'envoi"
+ subject: "Notification d'expédition"
+ thanks: "Merci pour votre commande."
+ track_information: "Informations de suivi : %{tracking}"
+ track_link: "Lien de suivi : %{url}"
order_state:
address: adresse
adjustments: ajustements
@@ -3248,19 +3281,6 @@ fr_BE:
ended: terminé
paused: mis en pause
canceled: annulé
- user_mailer:
- reset_password_instructions:
- request_sent_text: |
- Votre demande de nouveau mot de passe a bien été prise en compte.
- Si vous n'avez pas demandé de nouveau mot de passe, veuillez ignorer cet e-mail.
- link_text: >
- Si vous êtes bien à l'origine de cette demande, veuillez cliquer sur le
- lien ci-dessous :
- issue_text: |
- Si le lien ne fonctionne pas, essayez de le copier - coller dans la barre d'adresse de votre navigateur.
- Si le problème persiste, n'hésitez pas à nous contacter.
- confirmation_instructions:
- subject: Veuillez confirmer votre compte
users:
form:
account_settings: Paramètres du Compte
diff --git a/config/locales/fr_CA.yml b/config/locales/fr_CA.yml
index 2e57fa8dd7..9fd489c31a 100644
--- a/config/locales/fr_CA.yml
+++ b/config/locales/fr_CA.yml
@@ -13,6 +13,7 @@ fr_CA:
email: Email acheteur
spree/payment:
amount: Montant
+ state: Département
spree/product:
primary_taxon: "Catégorie Produit"
supplier: "Fournisseur"
@@ -183,6 +184,7 @@ fr_CA:
explainer: Le traitement automatique de ces commandes a échoué pour une raison inconnue. Cela n'aurait pas dû arriver, veuillez nous contacter si vous lisez ce message.
home: "OFN"
title: "Open Food Network "
+ welcome_to: "Bienvenue sur"
site_meta_description: "Tout commence dans le sol. Avec ces paysans, agriculteurs, producteurs, engagés pour une agriculture durable et régénératrice, et désireux de partager leur histoire et leur passion avec fierté. Avec ces distributeurs souhaitant reconnecter les individus à leurs aliments et aux gens qui les produisent, soutenir les prises de conscience, dans une démarche de transparence, d'honnêteté, en assurant une juste rémunération des producteurs. Avec ces acheteurs qui croient que de meilleures décisions d'achats peuvent ..."
search_by_name: Recherche par nom ou ville...
producers_join: Les producteurs et autres hubs basés au Québec sont invités à rejoindre Open Food Network Canada.
@@ -480,6 +482,7 @@ fr_CA:
line_number: "Ligne :%{number}"
encoding_error: "Veuillez vérifier le paramètre de langue de votre code source et vous assurer qu'il est encodé en UTF-8"
unexpected_error: "L'import de fichier produits à rencontré une erreur inconnue à l'ouverture du fichier : %{error_message}"
+ malformed_csv: "L'outil d'import a rencontré un fichier CSV avec le ou les problèmes suivants :%{error_message}"
index:
notice: "Notice"
beta_notice: "Cette fonctionnalité est en mode bêta : il est possible que vous rencontriez des erreurs en l'utilisant. N'hésitez pas à contacter le support utilisateurs."
@@ -1035,10 +1038,13 @@ fr_CA:
name: "Résumé des marges et commissions"
description: "Résumé des marges et commissions collectées"
subscriptions:
- subscriptions: Abonnements
- new: Nouvel abonnement
- create: Créer abonnement
- edit: Mettre à jour Abonnement
+ index:
+ title: "Abonnements"
+ new: "Nouvel abonnement"
+ new:
+ title: "Nouvel abonnement"
+ edit:
+ title: "Mettre à jour Abonnement"
table:
edit_subscription: Mettre à jour Abonnement
pause_subscription: Mettre en pause Abonnement
@@ -1047,6 +1053,7 @@ fr_CA:
filters:
query_placeholder: "Recherche par email"
setup_explanation:
+ title: "Abonnements"
just_a_few_more_steps: 'Encore quelques étapes avant de pouvoir commencer:'
enable_subscriptions: "Activez la fonction abonnements pour au moins une de vos boutiques"
enable_subscriptions_step_1_html: 1. Allez à %{enterprises_link}, trouvez votre boutique, et cliquez sur "Gérer"
@@ -1060,6 +1067,8 @@ fr_CA:
create_at_least_one_schedule_step_3: 3. Cliquez sur "+ Nouveau Rythme d'abonnement", et remplissez le formulaire
once_you_are_done_you_can_html: Une fois que c'est fait, vous pouvez %{reload_this_page_link}
reload_this_page: recharger cette page
+ form:
+ create: "Créer abonnement"
steps:
details: 1. Informations de base
address: 2. Adresse
@@ -1150,7 +1159,12 @@ fr_CA:
cart: "Panier"
cart_sidebar:
checkout: "Finalisation commande"
+ edit_cart: "Modifier le panier"
+ items_in_cart_singular: "%{num}élément dans le panier"
+ items_in_cart_plural: "%{num}éléments dans le panier"
close: "Ferme"
+ cart_empty: "Le panier est vide"
+ take_me_shopping: "Continuer mes achats"
signed_in:
profile: "Profil"
mobile_menu:
@@ -1298,6 +1312,8 @@ fr_CA:
cart_updating: "Mettre à jour le panier"
cart_empty: "Panier vide"
cart_edit: "Modifier votre panier"
+ item: "Produit"
+ qty: "Qté"
card_number: Numéro de carte
card_securitycode: "Cryptogramme visuel"
card_expiry_date: Date d'expiration
@@ -1709,6 +1725,7 @@ fr_CA:
remember_me: Se souvenir de moi
are_you_sure: "Confirmer?"
orders_open: "Boutique ouverte"
+ closing: "Fermeture"
going_back_to_home_page: "Retour à la page d'accueil"
creating: Création
updating: Mettre à jour
@@ -1952,6 +1969,7 @@ fr_CA:
supplier: "Fournisseurs"
product_name: "Nom du Produit"
product_description: "Description du Produit"
+ shipping_categories: "Condition de transport"
units: "Unité de mesure"
coordinator: "Coordinateur"
distributor: "Distributeur"
@@ -2048,6 +2066,7 @@ fr_CA:
remove_tax: "Retirer taxe"
first_name_begins_with: "Prénom commence par"
last_name_begins_with: "Nom de famille commence par"
+ new_order: "Nouvelle commande"
enterprise_tos_link: "Lien vers les Conditions Générales d'Utilisation"
enterprise_tos_message: "Nous soutenons la mise en place d'un système alimentaire résilient et durable, et souhaitons œuvrer avec des entreprises qui partagent nos valeurs et notre vision. Ainsi, nous demandons aux entreprises s'enregistrant sur Open Food Network de valider nos "
enterprise_tos_link_text: "Conditions d'utilisation"
@@ -2066,6 +2085,7 @@ fr_CA:
hub_sidebar_at_least: "Sélectionnez un/des hubs"
hub_sidebar_blue: "bleu"
hub_sidebar_red: "rouge"
+ order_cycles_closed_for_hub: "La boutique sélectionnée a fermé temporairement ses commandes. Veuillez essayez à nouveau ultérieurement."
report_customers_distributor: "Distributeur"
report_customers_supplier: "Fournisseurs"
report_customers_cycle: "Cycle de vente"
@@ -2304,6 +2324,7 @@ fr_CA:
order_cycles_email_to_producers_notice: 'Les emails à destination des producteurs ont été mis en file d''attente pour envoi.'
order_cycles_no_permission_to_coordinate_error: "Aucune de vos entreprises n'a les droits requis pour coordonner un cycle de vente"
order_cycles_no_permission_to_create_error: "Vous n'avez pas les droits requis pour créer un cycle de vente coordonné par cette entreprise"
+ order_cycle_closed: "Le cycle de vente que vous avez sélectionné a fermé. "
back_to_orders_list: "Retour à la liste des commandes"
no_orders_found: "Aucune commande trouvée"
order_information: "Info commande"
@@ -3346,6 +3367,28 @@ fr_CA:
invoice_email:
hi: "Bonjour %{name}"
invoice_attached_text: 'Veuillez trouver ci-joint la facture pour votre récente commande auprès de '
+ user_mailer:
+ reset_password_instructions:
+ request_sent_text: |
+ Votre demande de nouveau mot de passe a bien été prise en compte.
+ Si vous n'avez pas demandé de nouveau mot de passe, veuillez ignorer cet e-mail.
+ link_text: >
+ Si vous êtes bien à l'origine de cette demande, veuillez cliquer sur le
+ lien ci-dessous :
+ issue_text: |
+ Si le lien ne fonctionne pas, essayez de le copier - coller dans la barre d'adresse de votre navigateur.
+ Si le problème persiste, n'hésitez pas à nous contacter.
+ confirmation_instructions:
+ subject: "Veuillez confirmer votre compte"
+ shipment_mailer:
+ shipped_email:
+ dear_customer: "Cher Acheteur,"
+ instructions: "Votre commande a été expédiée"
+ shipment_summary: "Résumé de l'envoi"
+ subject: "Notification d'expédition"
+ thanks: "Merci pour votre commande."
+ track_information: "Informations de suivi :%{tracking}"
+ track_link: "Lien de suivi :%{url}"
order_state:
address: adresse
adjustments: ajustements
@@ -3367,19 +3410,6 @@ fr_CA:
ended: terminé
paused: mis en pause
canceled: annulé
- user_mailer:
- reset_password_instructions:
- request_sent_text: |
- Votre demande de nouveau mot de passe a bien été prise en compte.
- Si vous n'avez pas demandé de nouveau mot de passe, veuillez ignorer cet e-mail.
- link_text: >
- Si vous êtes bien à l'origine de cette demande, veuillez cliquer sur le
- lien ci-dessous :
- issue_text: |
- Si le lien ne fonctionne pas, essayez de le copier - coller dans la barre d'adresse de votre navigateur.
- Si le problème persiste, n'hésitez pas à nous contacter.
- confirmation_instructions:
- subject: Veuillez confirmer votre compte
users:
form:
account_settings: Paramètres du Compte
diff --git a/config/locales/it.yml b/config/locales/it.yml
index ebbf8932d0..6b1c036ebe 100644
--- a/config/locales/it.yml
+++ b/config/locales/it.yml
@@ -13,6 +13,8 @@ it:
email: E-Mail Cliente
spree/payment:
amount: Quantità
+ state: Stato
+ source: Fonte
spree/product:
primary_taxon: "Categoria Prodotto"
supplier: "Fornitore"
@@ -182,6 +184,7 @@ it:
explainer: L'elaborazione automatica di queste gentili richieste non è riuscita per una ragione sconosciuta. Questo non dovrebbe accadere, ti preghiamo di contattarci se visualizzi questo messaggio.
home: "OFN"
title: "Open Food Network"
+ welcome_to: "Benvenuto su"
site_meta_description: "Cominciamo da zero. Con i produttori e gli allevatori pronti a raccontare le loro storie, sinceramente e orgogliosamente. Con i distributori pronti a connettere le persone con i prodotti in modo giusto ed equo. Con i compratori che credono che migliori decisioni per l'acquisto settimanale possano..."
search_by_name: Cerca per nome o zona...
producers_join: I Produttori sono ora invitati ad unirsi ad Open Food Network
@@ -1034,10 +1037,13 @@ it:
name: "Riepilogo commissioni dell'azienda"
description: "Riepilogo delle commissioni dell'azienda"
subscriptions:
- subscriptions: Abbonamenti
- new: Nuovo Abbonamento
- create: Crea Abbonamento
- edit: Modifica Abbonamento
+ index:
+ title: "Abbonamenti"
+ new: "Nuovo Abbonamento"
+ new:
+ title: "Nuovo Abbonamento"
+ edit:
+ title: "Modifica Abbonamento"
table:
edit_subscription: Modifica Abbonamento
pause_subscription: Metti in pausa l'abbonamento
@@ -1046,6 +1052,7 @@ it:
filters:
query_placeholder: "Cerca per email..."
setup_explanation:
+ title: "Abbonamenti"
just_a_few_more_steps: 'Ancora pochi passi prima di cominciare:'
enable_subscriptions: "Ativa abbonamento ad almeno uno dei tuoi negozi"
enable_subscriptions_step_1_html: 1. Vai alla pagina %{enterprises_link}, trova il tuo negozio e clicca "Gestisci"
@@ -1059,6 +1066,8 @@ it:
create_at_least_one_schedule_step_3: '3. Clicca su"+ Nuovo programma" e compila il modulo '
once_you_are_done_you_can_html: Quando hai fatto, puoi %{reload_this_page_link}
reload_this_page: Ricarica questa pagina
+ form:
+ create: "Crea Abbonamento"
steps:
details: 1. Dettagli base
address: 2. Indirizzo
@@ -1150,7 +1159,11 @@ it:
cart: "Carrello"
cart_sidebar:
checkout: "Paga"
+ edit_cart: "Modifica il carrello"
+ items_in_cart_singular: "%{num} articolo nel tuo carrello"
+ items_in_cart_plural: "%{num} articoli nel tuo carrello"
close: "Chiuso"
+ cart_empty: "Il tuo carrello è vuoto"
signed_in:
profile: "Profilo"
mobile_menu:
@@ -1298,6 +1311,8 @@ it:
cart_updating: "Aggiornamento del carrello..."
cart_empty: "Carrello vuoto"
cart_edit: "Modifica il tuo carrello"
+ item: "Articolo"
+ qty: "Qtà"
card_number: Numero della carta
card_securitycode: "Codice di sicurezza"
card_expiry_date: Data di scadenza
@@ -1709,6 +1724,7 @@ it:
remember_me: Ricordami
are_you_sure: "Sei sicuro?"
orders_open: "Richieste aperte"
+ closing: "In chiusura"
going_back_to_home_page: "Reindirizzamento alla homepage"
creating: In creazione
updating: In aggiornamento
@@ -1952,6 +1968,7 @@ it:
supplier: "Fornitore"
product_name: "Nome Prodotto"
product_description: "Descrizione prodotto"
+ shipping_categories: "Categorie Spedizioni"
units: "Unità di misura"
coordinator: "Coordinatore"
distributor: "Distributore"
@@ -2048,6 +2065,7 @@ it:
remove_tax: "Rimuovi tassa"
first_name_begins_with: "Il nome inizia con"
last_name_begins_with: "Il cognome inizia con"
+ new_order: "Nuovo ordine"
enterprise_tos_link: "link Termini di Servizio Aziende"
enterprise_tos_message: "Abbiamo bisogno di lavorare con persone che condividono i nostri scopi e i nostri valori. Per questo chiediamo alle nuove aziende di sottoscrivere i nostri"
enterprise_tos_link_text: "Termini di Servizio"
@@ -2066,6 +2084,7 @@ it:
hub_sidebar_at_least: "Almeno un hub deve essere selezionato"
hub_sidebar_blue: "blu"
hub_sidebar_red: "rosso"
+ order_cycles_closed_for_hub: "L'hub che hai selezionato è temporaneamente chiuso. Riprova più tardi."
report_customers_distributor: "Distributore"
report_customers_supplier: "Fornitore"
report_customers_cycle: "Ciclo di richieste"
@@ -2302,6 +2321,7 @@ it:
order_cycles_email_to_producers_notice: 'Le email da inviare ai produttori sono state messe in coda per l''invio.'
order_cycles_no_permission_to_coordinate_error: "Nessuna delle tue aziende ha il permesso di coordinare un ciclo di richieste"
order_cycles_no_permission_to_create_error: "Non hai il permesso di creare un ciclo di richieste coordinato da questa azienda"
+ order_cycle_closed: "Il ciclo di richieste che hai selezionato è appena chiuso. Riprova per favore!"
back_to_orders_list: "Indietro alla lista delle gentili richieste"
no_orders_found: "Nessuna gentile richiesta trovata"
order_information: "Informazioni Gentile Richiesta"
@@ -3338,6 +3358,27 @@ it:
invoice_email:
hi: "Ciao %{name}"
invoice_attached_text: 'Aggiunge una fattura per il tuo recente ordine di '
+ user_mailer:
+ reset_password_instructions:
+ request_sent_text: |
+ E' stata fatta una richiesta per resettare la tua password
+ Se non hai fatto questa richiesta, ignora semplicemente questa email.
+ link_text: >
+ Se hai fatto questa richiesta, clicca il link seguente:
+ issue_text: |
+ Se l'URL qui sopra non funziona, prova a copiarlo e incollarlo nel tuo browser.
+ Se continui ad avere problemi, contattaci.
+ confirmation_instructions:
+ subject: "Per favore conferma il tuo account OFN"
+ shipment_mailer:
+ shipped_email:
+ dear_customer: "Caro Cliente,"
+ instructions: "Il tuo ordine è stato spedito"
+ shipment_summary: "Riepilogo della Spedizione"
+ subject: "Notifica di Spedizione"
+ thanks: "Grazie per il tuo lavoro."
+ track_information: "Informazioni Tracking: %{tracking}"
+ track_link: "Tracking Link: %{url}"
order_state:
address: indirizzo
adjustments: aggiustamenti
@@ -3359,18 +3400,6 @@ it:
ended: finito
paused: in pausa
canceled: annullato
- user_mailer:
- reset_password_instructions:
- request_sent_text: |
- E' stata fatta una richiesta per resettare la tua password
- Se non hai fatto questa richiesta, ignora semplicemente questa email.
- link_text: >
- Se hai fatto questa richiesta, clicca il link seguente:
- issue_text: |
- Se l'URL qui sopra non funziona, prova a copiarlo e incollarlo nel tuo browser.
- Se continui ad avere problemi, contattaci.
- confirmation_instructions:
- subject: Per favore conferma il tuo account OFN
users:
form:
account_settings: Impostazioni account
diff --git a/config/locales/nb.yml b/config/locales/nb.yml
index c47ad93636..6abf1fb797 100644
--- a/config/locales/nb.yml
+++ b/config/locales/nb.yml
@@ -13,6 +13,8 @@ nb:
email: Epost Kunde
spree/payment:
amount: Beløp
+ state: Tilstand
+ source: Kilde
spree/product:
primary_taxon: "Produktkategori"
supplier: "Leverandør"
@@ -182,6 +184,7 @@ nb:
explainer: Automatisk behandling av disse bestillingene mislyktes av en ukjent grunn. Dette bør ikke skje, vennligst kontakt oss hvis du ser dette.
home: "OFN"
title: "Open Food Network"
+ welcome_to: "Velkommen til"
site_meta_description: "Vi begynner fra grunnen. Med bønder og dyrkere klare til å fortelle sine historier, stolt og virkelig. Med distributører klare til å koble mennesker med produkter på en rettferdig og ærlig måte. Med kunder som tror på at ukentlige innkjøpsrutiner kan..."
search_by_name: Søk på navn eller sted...
producers_join: Norske produsenter er nå velkommen til å bli med i Open Food Network.
@@ -270,6 +273,9 @@ nb:
on hand: "Tilgjengelig"
ship: "Levere"
shipping_category: "Leveringskategori"
+ height: "Høyde"
+ width: "Bredde"
+ depth: "Dybde"
actions:
create_and_add_another: "Opprett og legg til en annen"
create: "Opprett"
@@ -1033,10 +1039,13 @@ nb:
name: "Sammendrag Bedriftsavgift"
description: "Sammendrag av bedriftsavgifter innsamlet"
subscriptions:
- subscriptions: Abonnement
- new: Nytt abonnement
- create: Opprett abonnement
- edit: Rediger abonnement
+ index:
+ title: "Abonnement"
+ new: "Nytt abonnement"
+ new:
+ title: "Nytt abonnement"
+ edit:
+ title: "Rediger abonnement"
table:
edit_subscription: Rediger abonnement
pause_subscription: Pause abonnement
@@ -1045,6 +1054,7 @@ nb:
filters:
query_placeholder: "Søk på epost..."
setup_explanation:
+ title: "Abonnement"
just_a_few_more_steps: 'Bare noen få skritt før du kan begynne:'
enable_subscriptions: "Aktiver abonnementer for minst en av butikkene dine"
enable_subscriptions_step_1_html: 1. Gå til siden %{enterprises_link}, finn butikken din, og klikk på "Endre profil"
@@ -1058,6 +1068,8 @@ nb:
create_at_least_one_schedule_step_3: 3. Klikk på '+ Ny tidsplan', og fyll ut skjemaet
once_you_are_done_you_can_html: Når du er ferdig, kan du %{reload_this_page_link}
reload_this_page: oppdater denne siden
+ form:
+ create: "Opprett abonnement"
steps:
details: 1. Grunnleggende detaljer
address: 2. Adresse
@@ -1302,6 +1314,8 @@ nb:
cart_updating: "Oppdaterer handlekurv..."
cart_empty: "Handlekurven er tom"
cart_edit: "Rediger handlekurv"
+ item: "Vare"
+ qty: "Antall"
card_number: Kortnummer
card_securitycode: "Sikkerhetskode"
card_expiry_date: Utløpsdato
@@ -1713,6 +1727,7 @@ nb:
remember_me: Husk meg
are_you_sure: "Er du sikker?"
orders_open: "Åpen for bestilling"
+ closing: "Stenger"
going_back_to_home_page: "Tar deg tilbake til hjemmesiden"
creating: Oppretter
updating: Oppdaterer
@@ -1956,6 +1971,8 @@ nb:
supplier: "Leverandør"
product_name: "Produktnavn"
product_description: "Produktbeskrivelse"
+ permalink: "Permalink"
+ shipping_categories: "Fraktkategorier"
units: "Enhetsstørrelse"
coordinator: "Koordinator"
distributor: "Distributør"
@@ -2052,6 +2069,8 @@ nb:
remove_tax: "Fjern avgift"
first_name_begins_with: "Fornavn begynner med"
last_name_begins_with: "Etternavn begynner med"
+ shipping_method: "Leveringsmetode"
+ new_order: "Ny bestilling"
enterprise_tos_link: "Lenke til Tjenestevilkår for Bedrifter"
enterprise_tos_message: "Vi ønsker å jobbe med bedrifter som deler våre mål og verdier. Derfor ber vi nye bedrifter om å godta vår"
enterprise_tos_link_text: "Tjenestevilkår."
@@ -2070,6 +2089,7 @@ nb:
hub_sidebar_at_least: "Minst én hub må være valgt"
hub_sidebar_blue: "blå"
hub_sidebar_red: "rød"
+ order_cycles_closed_for_hub: "Huben du har valgt er midlertidig lukket for bestillinger. Vennligst prøv igjen senere."
report_customers_distributor: "Distributør"
report_customers_supplier: "Leverandør"
report_customers_cycle: "Bestillingsrunde"
@@ -2306,6 +2326,7 @@ nb:
order_cycles_email_to_producers_notice: 'E-poster som skal sendes til produsentene har blitt satt i kø for sending.'
order_cycles_no_permission_to_coordinate_error: "Ingen av bedriftene dine har tillatelse til å koordinere en bestillingsrunde"
order_cycles_no_permission_to_create_error: "Du har ikke rettigheter til å opprette en bestillingsrunde som er koordinert av den bedriften"
+ order_cycle_closed: "Bestillingsrunden du har valgt har akkurat stengt. Vennligst prøv igjen!"
back_to_orders_list: "Tilbake til bestillingslisten"
no_orders_found: "Ingen bestillinger funnet"
order_information: "Bestillingsinformasjon"
@@ -3161,6 +3182,8 @@ nb:
stripe:
error_saving_payment: Feil ved lagring av betaling
submitting_payment: Sender inn betaling...
+ paypal:
+ no_payment_via_admin_backend: Paypal-betalinger kan ikke behandles i Backoffice
products:
image_upload_error: "Produktbildet ble ikke gjenkjent. Last opp et bilde i PNG- eller JPG-format."
new:
@@ -3338,6 +3361,32 @@ nb:
invoice_email:
hi: "Hei %{name}"
invoice_attached_text: Vennligst finn vedlagt en faktura for din nylige bestilling fra
+ user_mailer:
+ reset_password_instructions:
+ request_sent_text: |
+ En forespørsel om å nullstille ditt passord er utført.
+ Hvis det ikke var du som forespurte dette kan du se bort i fra denne eposten.
+ link_text: >
+ Hvis det var du som forespurte dette kan du klikke nedenfor:
+ issue_text: |
+ Hvis URL'en ovenfor ikke fungerer prøv å kopier og lim den inn i din nettleser.
+ Hvis du fortsatt har problemer vennligst ta kontakt.
+ confirmation_instructions:
+ subject: "Vennligst bekreft OFN-kontoen din"
+ shipment_mailer:
+ shipped_email:
+ dear_customer: "Kjære Kunde,"
+ instructions: "Din bestilling har blitt sendt"
+ shipment_summary: "Leveringssammendrag"
+ subject: "Leveringsvarsling"
+ thanks: "Takk for handelen."
+ track_information: "Sporingsinformasjon: %{tracking}"
+ track_link: "Sporingslink: %{url}"
+ test_mailer:
+ test_email:
+ greeting: "Gratulerer!"
+ message: "Hvis du har mottatt denne eposten, er epostinnstillingene dine riktige."
+ subject: "Test Epost"
order_state:
address: adresse
adjustments: justeringer
@@ -3359,18 +3408,6 @@ nb:
ended: avsluttet
paused: pauset
canceled: avbrutt
- user_mailer:
- reset_password_instructions:
- request_sent_text: |
- En forespørsel om å nullstille ditt passord er utført.
- Hvis det ikke var du som forespurte dette kan du se bort i fra denne eposten.
- link_text: >
- Hvis det var du som forespurte dette kan du klikke nedenfor:
- issue_text: |
- Hvis URL'en ovenfor ikke fungerer prøv å kopier og lim den inn i din nettleser.
- Hvis du fortsatt har problemer vennligst ta kontakt.
- confirmation_instructions:
- subject: Vennligst bekreft OFN-kontoen din
users:
form:
account_settings: Kontoinnstillinger
diff --git a/config/locales/nl_BE.yml b/config/locales/nl_BE.yml
index 61e9b4a7d9..52ee2cf0eb 100644
--- a/config/locales/nl_BE.yml
+++ b/config/locales/nl_BE.yml
@@ -13,6 +13,7 @@ nl_BE:
email: Klanten e-mail
spree/payment:
amount: Bedrag
+ state: Staat
spree/product:
primary_taxon: "Product categorie"
supplier: "Leverancier"
@@ -993,10 +994,13 @@ nl_BE:
name: "Samenvatting van de honoraria voor ondernemingen"
description: "Overzicht van de geïnde ondernemingsvergoedingen"
subscriptions:
- subscriptions: Abonnementen
- new: Nieuw abonnement
- create: Abonnement aanmaken
- edit: Abonnement bewerken
+ index:
+ title: "Abonnementen"
+ new: "Nieuw abonnement"
+ new:
+ title: "Nieuw abonnement"
+ edit:
+ title: "Abonnement bewerken"
table:
edit_subscription: Abonnement bewerken
pause_subscription: Pauze Abonnement
@@ -1005,6 +1009,7 @@ nl_BE:
filters:
query_placeholder: "Zoeken per e-mail ..."
setup_explanation:
+ title: "Abonnementen"
just_a_few_more_steps: 'Nog een paar stappen voordat u kunt beginnen:'
enable_subscriptions: "Inschrijven voor minstens één van uw winkels mogelijk maken"
enable_subscriptions_step_1_html: 1. Ga naar de %{enterprises_link}pagina, vind uw winkel en klik op "Beheren".
@@ -1018,6 +1023,8 @@ nl_BE:
create_at_least_one_schedule_step_3: 3. Klik '+ Nieuwe Planning', en vul een formulier in
once_you_are_done_you_can_html: Eens je klaar bent, kan je %{reload_this_page_link}
reload_this_page: herlaad deze pagina
+ form:
+ create: "Abonnement aanmaken"
steps:
details: 1. Basis Specificaties
address: 2. Adres
@@ -1248,6 +1255,8 @@ nl_BE:
cart_updating: "winkelwagentje wordt geüpdatet..."
cart_empty: "Winkelwagentje is leeg"
cart_edit: "Pas je winkelwagentje aan"
+ item: "Artikel"
+ qty: "Aantal"
card_number: Kaartnummer
card_securitycode: "Veiligheidscode"
card_expiry_date: Vervaldatum
@@ -1890,6 +1899,7 @@ nl_BE:
supplier: "Leverancier"
product_name: "Naam produkt"
product_description: "Beschrijving product"
+ shipping_categories: "Verzendingscategorieën"
units: "Stukgrootte"
coordinator: "Coördinator"
distributor: "Distributeur"
@@ -1985,6 +1995,7 @@ nl_BE:
remove_tax: "Verwijder belasting"
first_name_begins_with: "Voornaam begint met"
last_name_begins_with: "Familienaam begint met "
+ new_order: "Nieuwe bestelling"
enterprise_tos_link: "Link Voorwaarden Onderneming"
enterprise_tos_message: "We willen met mensen werken die onze normen en waarden en delen. Daarom vragen wij aan de nieuwe bedrijven akkoord te gaan met onze "
enterprise_tos_link_text: "Dienstvoorwaarden"
@@ -3102,6 +3113,28 @@ nl_BE:
invoice_email:
hi: "Hallo %{name}"
invoice_attached_text: 'Gelieve hier de factuur te vinden in veband met de laatste bestelling geplaatst bij '
+ user_mailer:
+ reset_password_instructions:
+ request_sent_text: |
+ Uw aanvraag voor een nieuww paswoord is in acht genomen
+ Indien je geen nieuw paswoord aangevraagd heeft, gelieve hiermee geen rekening te houden.
+ link_text: >
+ Indien U wel de aanvraag gedaan hebt, gelieve op de link hieronder te
+ klikken :
+ issue_text: |
+ Indien de link niet functioneert, gelieve die te copiëren-plakken in het adresstrook van uw navigator.
+ Moest het probleem blijven duren, aarzel niet ons te contacteren
+ confirmation_instructions:
+ subject: "Gelieve uw OFN rekening te bevestigen"
+ shipment_mailer:
+ shipped_email:
+ dear_customer: "Geachte klant,"
+ instructions: "Uw bestelling is verzonden"
+ shipment_summary: "Samenvatting van de zending"
+ subject: "Kennisgeving van verzending"
+ thanks: "Bedankt voor uw bedrijf."
+ track_information: "Tracking informatie: %{tracking}"
+ track_link: "Tracking Link:%{url} "
order_state:
address: adres
adjustments: aanpassingen
@@ -3123,19 +3156,6 @@ nl_BE:
ended: ten einde gebracht
paused: 'in pause '
canceled: geschrapt
- user_mailer:
- reset_password_instructions:
- request_sent_text: |
- Uw aanvraag voor een nieuww paswoord is in acht genomen
- Indien je geen nieuw paswoord aangevraagd heeft, gelieve hiermee geen rekening te houden.
- link_text: >
- Indien U wel de aanvraag gedaan hebt, gelieve op de link hieronder te
- klikken :
- issue_text: |
- Indien de link niet functioneert, gelieve die te copiëren-plakken in het adresstrook van uw navigator.
- Moest het probleem blijven duren, aarzel niet ons te contacteren
- confirmation_instructions:
- subject: Gelieve uw OFN rekening te bevestigen
users:
form:
account_settings: Rekeningsinstellingen
diff --git a/config/locales/pt.yml b/config/locales/pt.yml
index 0e9da2fb53..bd70c0746e 100644
--- a/config/locales/pt.yml
+++ b/config/locales/pt.yml
@@ -13,6 +13,7 @@ pt:
email: Email do/a Consumidor/a
spree/payment:
amount: Quantia
+ state: Estado
spree/product:
primary_taxon: "Categoria de Produto"
supplier: "Fornecedor"
@@ -978,16 +979,20 @@ pt:
name: "Sumário das Taxas de Organização"
description: "Sumário das Taxas de Organização cobradas"
subscriptions:
- subscriptions: Subscrições
- new: Nova Subscrição
- create: Criar Subscrição
- edit: Editar Subscrição
+ index:
+ title: "Subscrições"
+ new: "Nova Subscrição"
+ new:
+ title: "Nova Subscrição"
+ edit:
+ title: "Editar Subscrição"
table:
edit_subscription: Editar Subscrição
pause_subscription: Pausar Subscrição
unpause_subscription: Parar pausa da Subscrição
cancel_subscription: Cancelar Subscrição
setup_explanation:
+ title: "Subscrições"
just_a_few_more_steps: 'Só mais uns passos antes de poder começar:'
enable_subscriptions: "Activar subscrições para pelo menos uma das suas lojas"
enable_subscriptions_step_1_html: 1. Vá à página %{enterprises_link}, encontre a sua loja, e clique em "Gerir"
@@ -1001,6 +1006,8 @@ pt:
create_at_least_one_schedule_step_3: 3. Clique em '+ Novo Horário', e preencha o formulário
once_you_are_done_you_can_html: Assim que estiver feito, pode %{reload_this_page_link}
reload_this_page: carregar de novo esta página
+ form:
+ create: "Criar Subscrição"
steps:
details: 1. Detalhes Básicos
address: 2. Morada
@@ -1222,6 +1229,8 @@ pt:
cart_updating: "Atualizando carrinho"
cart_empty: "Carrinho vazio"
cart_edit: "Edite o seu carrinho"
+ item: "Item"
+ qty: "Qtd"
card_number: Número do Cartão
card_securitycode: "Código de Segurança"
card_expiry_date: Data de Vencimento
@@ -1863,6 +1872,7 @@ pt:
supplier: "Fornecedor"
product_name: "Nome do Produto"
product_description: "Descrição do Produto"
+ shipping_categories: "Categorias de Envio"
units: "Tamanho unitário"
coordinator: "Coordenador"
distributor: "Distribuidor"
@@ -1957,6 +1967,7 @@ pt:
remove_tax: "Remover imposto"
first_name_begins_with: "Primeiro nome começa com"
last_name_begins_with: "Último nome começa com"
+ new_order: "Nova Encomenda"
enterprise_tos_link: "Ligação para Termos de Serviço da Organização"
enterprise_tos_message: "Queremos trabalhar com pessoas que partilham os nossos objectivos e valores. Por isso pedimos às organizações novas que concordem com os nossos"
enterprise_tos_link_text: "Termos de Serviço."
@@ -3038,6 +3049,26 @@ pt:
invoice_email:
hi: "Olá %{name}"
invoice_attached_text: Pode encontrar em anexo um recibo da encomenda que fez recentemente a
+ user_mailer:
+ reset_password_instructions:
+ request_sent_text: |
+ Recebemos um pedido para redefinir a sua palavra-passe.
+ Se não fez este pedido, simplesmente ignore esta mensagem.
+ link_text: >
+ Se fez este pedido, clique no link abaixo:
+ issue_text: |
+ Se o endereço URL acima não funcionar, tente copiá-lo e colá-lo directamente no browser. Se continuar a ter problemas por favor entre em contacto connosco.
+ confirmation_instructions:
+ subject: "Por favor confirme a sua conta OFN"
+ shipment_mailer:
+ shipped_email:
+ dear_customer: "Caro Consumidor,"
+ instructions: "A sua encomenda foi enviada"
+ shipment_summary: "Sumário de Envio"
+ subject: "Notificação de Envio"
+ thanks: "Obrigado."
+ track_information: "Informação de envio: %{tracking}"
+ track_link: "Link de envio: %{url}"
order_state:
address: morada
adjustments: ajustes
@@ -3059,17 +3090,6 @@ pt:
ended: terminou
paused: em pausa
canceled: cancelado
- user_mailer:
- reset_password_instructions:
- request_sent_text: |
- Recebemos um pedido para redefinir a sua palavra-passe.
- Se não fez este pedido, simplesmente ignore esta mensagem.
- link_text: >
- Se fez este pedido, clique no link abaixo:
- issue_text: |
- Se o endereço URL acima não funcionar, tente copiá-lo e colá-lo directamente no browser. Se continuar a ter problemas por favor entre em contacto connosco.
- confirmation_instructions:
- subject: Por favor confirme a sua conta OFN
users:
form:
account_settings: Definições de Conta
diff --git a/config/locales/pt_BR.yml b/config/locales/pt_BR.yml
index acdf438a4d..0fe3b4ab6c 100644
--- a/config/locales/pt_BR.yml
+++ b/config/locales/pt_BR.yml
@@ -13,6 +13,8 @@ pt_BR:
email: Email do cliente
spree/payment:
amount: Montante
+ state: Estado
+ source: Origem
spree/product:
primary_taxon: "Categoria de Produto"
supplier: "Fornecedor"
@@ -271,6 +273,9 @@ pt_BR:
on hand: "Disponível"
ship: "Envio"
shipping_category: "Tipos de Frete"
+ height: "Altura"
+ width: "Largura"
+ depth: "Profundidade"
actions:
create_and_add_another: "Criar e adicionar outro"
create: "Criar"
@@ -1012,7 +1017,7 @@ pt_BR:
name: Relatórios de pagamento
description: Relatórios para pagamentos
orders_and_fulfillment:
- name: Relatórios de pedidos e de satisfação
+ name: Relatórios de pedidos e fechamento
customers:
name: Clientes
products_and_inventory:
@@ -1033,10 +1038,13 @@ pt_BR:
name: "Resumo das taxas da empresa"
description: "Resumo das taxas corporativas coletadas"
subscriptions:
- subscriptions: Assinaturas
- new: Nova assinatura
- create: Criar assinatura
- edit: Editar assinatura
+ index:
+ title: "Assinaturas"
+ new: "Nova Assinatura"
+ new:
+ title: "Nova Assinatura"
+ edit:
+ title: "Editar assinatura"
table:
edit_subscription: Editar assinatura
pause_subscription: Pausar assinatura
@@ -1045,6 +1053,7 @@ pt_BR:
filters:
query_placeholder: "Pesquisar por email ..."
setup_explanation:
+ title: "Assinaturas"
just_a_few_more_steps: 'Apenas mais algumas etapas antes de começar:'
enable_subscriptions: "Ative assinaturas para pelo menos uma de suas lojas"
enable_subscriptions_step_1_html: '1. Vá para a página %{enterprises_link}, encontre sua loja e clique em "Gerenciar" '
@@ -1058,6 +1067,8 @@ pt_BR:
create_at_least_one_schedule_step_3: 3. Clique em "Novo cronograma" e preencha o formulário
once_you_are_done_you_can_html: Quando terminar, você pode %{reload_this_page_link}
reload_this_page: recarregar esta página
+ form:
+ create: "Criar Assinatura"
steps:
details: 1. Detalhes Básicos
address: 2. Endereço
@@ -1204,14 +1215,14 @@ pt_BR:
invoice_column_price_without_taxes: "Preço total (sem taxas)"
invoice_column_tax_rate: "Taxa de imposto"
invoice_tax_total: "Total de Imposto sobre Bens e Serviços"
- tax_invoice: "NOTA FISCAL"
+ tax_invoice: "FATURA"
tax_total: "Total de imposto (%{rate}):"
total_excl_tax: "Total (sem imposto):"
total_incl_tax: "Total (com imposto):"
abn: "CNPJ"
acn: "CNPJ:"
- invoice_issued_on: "Nota fiscal emitida em:"
- order_number: "Número da nota fiscal:"
+ invoice_issued_on: "Fatura emitida em:"
+ order_number: "Número da fatura:"
date_of_transaction: "Dia da transação:"
ticket_column_qty: "Qtd"
ticket_column_item: "Ítem"
@@ -1301,6 +1312,8 @@ pt_BR:
cart_updating: "Atualizando carrinho"
cart_empty: "Carrinho vazio"
cart_edit: "Edite seu carrinho"
+ item: "Ítem"
+ qty: "Qtd"
card_number: Número do Cartão
card_securitycode: "Código de Segurança"
card_expiry_date: Data de Vencimento
@@ -1522,7 +1535,7 @@ pt_BR:
shopping_contact_social: "Seguir"
shopping_groups_part_of: "é parte de:"
shopping_producers_of_hub: "produtores de %{hub}:"
- enterprises_next_closing: "Próximo fechamento de pedido"
+ enterprises_next_closing: "Próximo fechamento"
enterprises_ready_for: "Pronto para"
enterprises_choose: "Escolha para quando você quer seu pedido:"
maps_open: "Aberto"
@@ -1956,6 +1969,8 @@ pt_BR:
supplier: "Fornecedor"
product_name: "Nome do Produto"
product_description: "Descrição do Produto"
+ permalink: "Permalink"
+ shipping_categories: "Categorias de Remessa"
units: "Unidade de medida"
coordinator: "Coordenador"
distributor: "Distribuidor"
@@ -2052,6 +2067,8 @@ pt_BR:
remove_tax: "Remover taxa"
first_name_begins_with: "O primeiro nome começa com"
last_name_begins_with: "O sobrenome começa com"
+ shipping_method: "Método de Envio"
+ new_order: "Novo Pedido"
enterprise_tos_link: "Link de Termos de Serviço da iniciativa"
enterprise_tos_message: "Queremos trabalhar com pessoas que compartilham nossos objetivos e valores. Como tal, pedimos às novas iniciativas que concordem com nossos"
enterprise_tos_link_text: "Termos de Serviço."
@@ -3059,7 +3076,7 @@ pt_BR:
email: "Email do cliente"
invoice:
issued_on: "Emitida em"
- tax_invoice: "NOTA FISCAL"
+ tax_invoice: "FATURA"
code: "Código"
from: "De"
to: "Informações de cobrança"
@@ -3346,6 +3363,32 @@ pt_BR:
invoice_email:
hi: "Oi %{name}"
invoice_attached_text: Encontre anexa uma fatura para sua recente ordem de
+ user_mailer:
+ reset_password_instructions:
+ request_sent_text: |
+ Foi feito um pedido para redefinir sua senha.
+ Se você não fez essa solicitação, simplesmente ignore este e-mail.
+ link_text: >
+ Se você fez esse pedido, basta clicar no link abaixo:
+ issue_text: |
+ Se o URL acima não funcionar, tente copiar e colá-lo em seu navegador.
+ Se continuar a ter problemas, por favor não hesite em contactar-nos.
+ confirmation_instructions:
+ subject: "Confirme sua conta na OFB"
+ shipment_mailer:
+ shipped_email:
+ dear_customer: "Estimado cliente,"
+ instructions: "Seu pedido foi enviado"
+ shipment_summary: "Resumo de Envio"
+ subject: "Notificação de envio"
+ thanks: "Agradeço pelos seus serviços."
+ track_information: "Informações de rastreamento: %{tracking}"
+ track_link: "Link de rastreamento: %{url}"
+ test_mailer:
+ test_email:
+ greeting: "Parabéns!"
+ message: "Se você recebeu este email, então as suas configurações de email estão corretas."
+ subject: "Email Teste"
order_state:
address: endereço
adjustments: ajustes
@@ -3367,18 +3410,6 @@ pt_BR:
ended: finalizado
paused: pausado
canceled: cancelado
- user_mailer:
- reset_password_instructions:
- request_sent_text: |
- Foi feito um pedido para redefinir sua senha.
- Se você não fez essa solicitação, simplesmente ignore este e-mail.
- link_text: >
- Se você fez esse pedido, basta clicar no link abaixo:
- issue_text: |
- Se o URL acima não funcionar, tente copiar e colá-lo em seu navegador.
- Se continuar a ter problemas, por favor não hesite em contactar-nos.
- confirmation_instructions:
- subject: Confirme sua conta na OFB
users:
form:
account_settings: Configurações da conta
diff --git a/config/locales/sv.yml b/config/locales/sv.yml
index 92d5d360e6..96d65d324e 100644
--- a/config/locales/sv.yml
+++ b/config/locales/sv.yml
@@ -8,6 +8,8 @@ sv:
payment_state: Betalningstatus
shipment_state: Leveransstatus
state: Region
+ spree/payment:
+ state: Region
spree/product:
supplier: "Leverantör"
variant_unit: "Enhet för variant"
@@ -751,6 +753,8 @@ sv:
cart_updating: "Uppdatera din varukorg"
cart_empty: "Tom varukorg"
cart_edit: "Redigera din varukorg "
+ item: "Vara"
+ qty: "Kvantitet"
card_number: Kortnummer
card_securitycode: "Säkerhetskod"
card_expiry_date: Förfallodatum
@@ -2106,6 +2110,16 @@ sv:
invoice_email:
hi: "Hi %{name}"
invoice_attached_text: Här är en faktura för din senaste order från
+ user_mailer:
+ reset_password_instructions:
+ request_sent_text: |
+ En begäran om att återställa ditt lösenord har gjorts.
+ Om du inte gjorde denna förfrågan ignorerar du bara det här e-postmeddelandet.
+ link_text: >
+ Om du gjorde denna förfrågan klickar du bara på länken nedan:
+ issue_text: |
+ Om den ovan nämnda webbadressen inte fungerar kan du försöka kopiera och klistra in den i webbläsaren.
+ Om du får problem, var god kontakta oss.
order_state:
address: adress
adjustments: justeringar
@@ -2118,16 +2132,6 @@ sv:
resumed: återupptagen
returned: returnerad
skrill: skrill
- user_mailer:
- reset_password_instructions:
- request_sent_text: |
- En begäran om att återställa ditt lösenord har gjorts.
- Om du inte gjorde denna förfrågan ignorerar du bara det här e-postmeddelandet.
- link_text: >
- Om du gjorde denna förfrågan klickar du bara på länken nedan:
- issue_text: |
- Om den ovan nämnda webbadressen inte fungerar kan du försöka kopiera och klistra in den i webbläsaren.
- Om du får problem, var god kontakta oss.
users:
open_orders:
order: Beställningar
diff --git a/config/locales/tr.yml b/config/locales/tr.yml
index dae3555bb1..e5aa022fee 100644
--- a/config/locales/tr.yml
+++ b/config/locales/tr.yml
@@ -13,6 +13,8 @@ tr:
email: Müşteri E-postası
spree/payment:
amount: Tutar
+ state: Durum
+ source: Kaynak
spree/product:
primary_taxon: "ÜRÜN KATEGORİSİ"
supplier: "TEDARİKÇİ"
@@ -123,9 +125,9 @@ tr:
subject: "Lütfen %{enterprise} için e-posta adresini doğrulayın"
welcome:
subject: "%{enterprise} şimdi %{sitename} 'de"
- email_welcome: "Hoşgeldiniz"
+ email_welcome: "Aramıza Hoşgeldiniz "
email_registered: "şimdi bir parçası"
- email_userguide_html: "Tezgah veya Pazar hesapları ayarları ile ilgili ayrıntılı desteğe sahip Kullanıcı Kılavuzu burada: %{link}"
+ email_userguide_html: "Dükkan veya Pazar hesapları ayarları ile ilgili ayrıntılı desteğe sahip Kullanıcı Kılavuzu burada: %{link}"
userguide: "Açık Gıda Ağı Kullanıcı Kılavuzu"
email_admin_html: "%{link}'dan oturum açarak veya ana sayfanın sağ üst kısmındaki ayarlar simgesini tıkladıktan sonra Yönetim' butonu üzerinden hesabınızı yönetebilirsiniz."
admin_panel: "YönetiİCİ Panelİ"
@@ -221,7 +223,7 @@ tr:
edit: Düzenle
clone: Kopyala
distributors: Dağıtımcılar
- bulk_order_management: Toplu Sipariş Yönetimi
+ bulk_order_management: TOPLU SİPARİŞ YÖNETİMİ
enterprises: İşletmeler
enterprise_groups: AĞLAR
reports: Raporlar
@@ -256,7 +258,7 @@ tr:
processing_payment: "Ödeme İşlemi Gerçekleştiriliyor.."
no_pending_payments: "Bekleyen ödeme yok"
invalid_payment_state: "Geçersiz ödeme durumu"
- filter_results: Sonuçları Filtrele
+ filter_results: SONUÇLARI FİLTRELE
quantity: Miktar
pick_up: Teslim Alma
copy: Kopyala
@@ -271,6 +273,9 @@ tr:
on hand: "Mevcut"
ship: "Teslimat"
shipping_category: "Teslimat KategOrİSİ"
+ height: "Boy"
+ width: "En"
+ depth: "Boy"
actions:
create_and_add_another: "Oluştur ve Yeni Ekle"
create: "Oluştur"
@@ -429,7 +434,7 @@ tr:
enterprise_role:
manages: yönetir
products:
- unit_name_placeholder: 'örn. demet'
+ unit_name_placeholder: 'Örn. demet'
index:
unit: Birim
display_as: Gösterme Şekli
@@ -593,7 +598,7 @@ tr:
product_unit: "Ürün: Birim"
weight_volume: "Ağırlık / Hacim"
ask: "Sor?"
- page_title: "Toplu Sipariş Yönetimi"
+ page_title: "TOPLU SİPARİŞ YÖNETİMİ"
actions_delete: "Seçilenleri Sil"
loading: "Siparişler yükleniyor"
no_results: "Sipariş bulunamadı."
@@ -632,12 +637,12 @@ tr:
name: Ad
name_placeholder: Örn. Toprak Güneş
email_address: E-posta Adresi
- email_address_placeholder: Örn. siparis@yesilciftlik.com
+ email_address_placeholder: Örn. siparis@ciftlik.com
email_address_tip: "Bu e-posta adresi profilinizde görüntülenecek"
phone: Telefon
phone_placeholder: Örn. 0532 123 00 01
website: İnternet sitesi
- website_placeholder: 'Örn: www.yesilciftlik.com'
+ website_placeholder: Örn. www.ciftlik.com
enterprise_fees:
name: Ad
fee_type: Ücret Türü
@@ -676,11 +681,11 @@ tr:
primary_producer: Birincil üretici misiniz?
primary_producer_tip: Siz de birincil üreticisiyseniz 'Üretici' yi seçin.
producer: ÜRETİCİ
- any: Hepsi
- none: SATMIYOR
+ any: KENDİ VE/VEYA BAŞKASININ ÜRÜNLERİ
+ none: SATIŞ YAPMIYOR
own: KENDİ ÜRÜNLERİ
sells: NE SATIYOR
- sells_tip: "Hiç - İşletme müşterilere doğrudan satış yapmaz.
Kendi - İşletme müşterilerine kendi ürünlerini satar.
Hepsi - İşletme kendi ürünlerini veya diğer işletmelerin ürünlerini satabilir.
"
+ sells_tip: "Satış Yapmıyor - İşletme müşterilere doğrudan satış yapmaz.
Kendi Ürünleri - İşletme müşterilerine kendi ürünlerini satar.
Kendi ve/veya başkasının ürünleri - İşletme kendi ürünlerini ve/veya diğer işletmelerin ürünlerini satabilir.
"
visible_in_search: ARAMADA GÖRÜNÜR MÜ?
visible_in_search_tip: Sitede arama yapılırken bu işletmenin müşteriler tarafından görünür olup olmayacağını belirler.
visible: GÖRÜNÜR
@@ -730,11 +735,11 @@ tr:
sizi ziyaret edenler tarafından görülecek. (örn. neden kapalı olduğunu
ve ne zaman açılacağını belirtebilirsiniz)
shopfront_category_ordering: "DÜKKAN KATEGORİ SIRALAMASI"
- open_date: "Açılış Tarihi"
- close_date: "Kapanış Tarih"
+ open_date: "AÇILIŞ TARİHİ"
+ close_date: "KAPANIŞ TARİHİ"
social:
- twitter_placeholder: "Örneğin. @the_usta"
- instagram_placeholder: "Örneğin. the_usta"
+ twitter_placeholder: "Örn. @the_usta"
+ instagram_placeholder: "Örn. ciftlik (başına @ işareti koymayınız)"
facebook_placeholder: "Örn: www.facebook.com/TurkiyeKoop"
linkedin_placeholder: "Örn: www.linkedin.com/in/adınızsoyadınız"
stripe_connect:
@@ -795,21 +800,21 @@ tr:
producer: ÜRETİCİ
change_type_form:
producer_profile: ÜRETİCİ PROFİLİ
- connect_ofn: AGA üzerinden bağlan
+ connect_ofn: AGA PLATFORMUNA KATIL
always_free: HER ZAMAN ÜCRETSİZ
producer_description_text: Ürünlerinizi Açık Gıda Ağı'na yükleyin. Böylece ürünleriniz pazar hesapları üzerinden satışa sunulabilir.
producer_shop: ÜRETİCİ DÜKKANI
- sell_your_produce: Kendi ürününü sat
+ sell_your_produce: KENDİ ÜRÜNÜNÜ SAT
producer_shop_description_text: Açık Gıda Ağı üzerinden açtığınız bireysel dükkanınız ile ürünlerinizi doğrudan müşterilere ulaştırabilirsiniz.
producer_shop_description_text2: Üretici Dükkanı sadece sizin ürünleriniz içindir. Üretiminiz haricindeki ürünleri satabilmek için lütfen 'Üretici Pazarı' seçeneğini seçin.
producer_hub: ÜRETİCİ PAZARI
- producer_hub_text: Kendi ürünleriniz ile beraber başkalarının ürünlerini de satın
+ producer_hub_text: KENDİ ÜRÜNLERİNİZ İLE BERABER BAŞKALARININ ÜRÜNLERİNİ DE SATIN
producer_hub_description_text: İşletmeniz, yerel gıda sisteminizin bel kemiğidir. Açık Gıda Ağı'ndaki mağazanız aracılığıyla kendi ürünlerinizi ve çevrenizdeki diğer üreticilerin ürünlerini beraber satabilirsiniz.
profile: Yalnızca Profil
get_listing: Görünür ol
profile_description_text: İnsanlar Açık Gıda Ağı üzerinden sizi bulabilir ve sizinle iletişim kurabilir. İşletmeniz haritada ve listelerde görünür olacak.
hub_shop: Türetici Pazarı
- hub_shop_text: Başkalarının ürünlerini satın
+ hub_shop_text: BAŞKALARININ ÜRÜNLERİNİ SATIN
hub_shop_description_text: İşletmeniz yerel gıda sisteminizin belkemiğidir. Diğer işletmelerin ürünlerini bir araya getirebilir, Açık Gıda Ağı'na kayıtlı dükkanınız üzerinden alıcılara ulaştırabilirsiniz.
choose_option: Lütfen yukarıdaki seçeneklerden birini seçin.
change_now: Değiştir
@@ -897,10 +902,10 @@ tr:
outgoing: "3. GİDEN ÜRÜNLER"
exchange_form:
pickup_time_tip: Bu sipariş dönemine ait siparişlerin müşteriler için hazır olma tarihi
- pickup_instructions_placeholder: "Teslimat Talimatları"
+ pickup_instructions_placeholder: "TESLİMAT DETAYLARI"
pickup_instructions_tip: Bu talimatlar, siparişi tamamladıktan sonra müşterilere iletilir
pickup_time_placeholder: "Teslimat (örn. Tarih / Saat)"
- receival_instructions_placeholder: "Teslim Alma talimatları"
+ receival_instructions_placeholder: "TESLİM ALMA TALİMATLARI"
add_fee: 'Ücret ekle'
remove: 'Kaldır'
selected: 'seçildi'
@@ -1015,7 +1020,7 @@ tr:
orders_and_fulfillment:
name: Siparişler ve Gerçekleşme Raporları
customers:
- name: MÜŞTERİLER
+ name: Müşteriler
products_and_inventory:
name: Ürünler ve Stok
users_and_enterprises:
@@ -1034,10 +1039,13 @@ tr:
name: "İşletme Ücreti Özeti"
description: "Toplanan İşletme Ücretlerinin Özeti"
subscriptions:
- subscriptions: Üyelikler
- new: Yeni Üyelik
- create: Üyelik Oluştur
- edit: Üyeliği düzenle
+ index:
+ title: "Üyelikler"
+ new: "Yeni Üyelik"
+ new:
+ title: "Yeni Üyelik"
+ edit:
+ title: "Üyeliği Düzenle"
table:
edit_subscription: Üyeliği Düzenle
pause_subscription: Üyeliği Duraklat
@@ -1046,6 +1054,7 @@ tr:
filters:
query_placeholder: "E-posta ile ara ..."
setup_explanation:
+ title: "Üyelikler"
just_a_few_more_steps: 'Başlamadan önce birkaç adım kaldı:'
enable_subscriptions: "Dükkanınızdan en az biri için üyelikleri etkinleştirin"
enable_subscriptions_step_1_html: 1. %{enterprises_link} sayfasına gidin, dükkanınızı bulun ve ‘Yönet’i tıklayın
@@ -1059,6 +1068,8 @@ tr:
create_at_least_one_schedule_step_3: 3. 'Yeni Takvim' butonuna tıklayın ve formu doldurun
once_you_are_done_you_can_html: 'İşiniz bittiğinde, %{reload_this_page_link} '
reload_this_page: Sayfayı yeniden yükle
+ form:
+ create: "Üyelik Oluştur"
steps:
details: 1. Temel Bilgiler
address: 2. Adres
@@ -1303,6 +1314,8 @@ tr:
cart_updating: "Sepet güncelleniyor ..."
cart_empty: "Sepetiniz boş"
cart_edit: "Sepetinizi düzenleyin"
+ item: "Ürün"
+ qty: "Miktar"
card_number: Kart numarası
card_securitycode: "Güvenlik Kodu"
card_expiry_date: Son kullanma tarihi
@@ -1362,8 +1375,8 @@ tr:
cookies_policy_link: "çerezler politikası"
cookies_accept_button: "Çerezleri kabul et"
home_shop: 'ALIŞVERİŞE BAŞLAYIN '
- brandstory_headline: "Bağımsız, adil ve temiz gıda ..."
- brandstory_intro: "Bazen sistemi düzeltmenin en iyi yolu yeni bir sistem yaratmaktır…"
+ brandstory_headline: "Yerel, adil ve temiz gıda."
+ brandstory_intro: "Eğer sistemi düzeltemiyorsak en iyi yol yeni bir sistem yaratmaktır."
brandstory_part1: "Açık Gıda Ağı, adil, temiz bir gıda sistemi oluşturmak için tasarlanan bir sosyal girişim projesidir. Üretici ve türeticilerin bir araya gelerek aracısız bir gıda düzeni ile her açıdan daha sağlıklı bir toplum yaratmaları için çözümler sunar. Toplum yararına çalışır, iletişim, dürüstlük ve dayanışmayı destekler."
brandstory_part2: "AGA, üreticilere ve alıcılara aracısız ticaret faydaları sağlar ve toplumsal iletişimi ve güveni cesaretlendirir. Gıda yetiştiriciliği ve satışının kendine özgü ihtiyaçlarını karşılamak için geliştirilmiştir. Temiz gıdaya ulaşım sürecini kolaylaştırır."
brandstory_part3: "Platform üzerinden yalnızca yerel ve bağımsız gıda üreticileri ve dağıtımcıları satış yapabilir. Siz de ürünlerinizi AGA üzerinden oluşturduğunuz dükan ile doğrudan alıcılara ulaştırabilir, dilerseniz bölgenizdeki diğer üreticiler ile bir araya gelerek kendi ortak 'Üretici Pazarı' veya 'Türetici Pazarı' nızı oluşturabilirsiniz. Bu şekilde çeşitliliği ve bereketi artırır, dayanışmanın getirdiği faydalardan da yararlanabilirsiniz."
@@ -1376,17 +1389,17 @@ tr:
connect_cta: "Keşfedin"
system_headline: "Nasıl çalışıyor ?"
system_step1: "1. Ara"
- system_step1_text: "Yerel, adil, temiz ve mevsimsel gıda için, bağımsız ve cesur üreticilerimizin ve dağıtımcılarımızın dükkanlarından alışveriş yapın. Konuma, ürün kategorisine, üretici özelliklerine veya teslimat tercihlerine göre arama yapabilirsiniz. "
+ system_step1_text: "Yerel ve mevsimsel gıda için, bağımsız ve cesur üreticilerimizin ve dağıtımcılarımızın dükkanlarından alışveriş yapın. "
system_step2: "2. Alışveriş Yap"
- system_step2_text: "Gıdanızı yerel üretici tezgahlarından, üretici ve türetici pazarlarından temin edin. Yaşanabilir bir dünya için alışkanlıklarınızı şimdi değiştirin. Gıdanızın ve onu size getiren insanların hikayelerini öğrenin!"
+ system_step2_text: "Gıdanızı yerel üreticilerden ve türetici pazarlarından temin edin. Yaşanabilir bir dünya için alışkanlıklarınızı şimdi değiştirin. "
system_step3: "3. Teslimat "
- system_step3_text: "Gıdanıza ulaşmak için adresinize teslim edilmesini bekleyin. Dilerseniz gıdanız ile daha kişisel bir bağ kurmak için üreticinizi veya pazarını kendiniz ziyaret edin. Doğayla ve gıdayla istediğiniz şekilde ama gerçek bir bağ kurun. "
+ system_step3_text: "Siparişinizin teslim edilmesini bekleyin veya teslim alım noktasında buluşun. Gıdayla istediğiniz şekilde ama gerçek bir bağ kurun. "
cta_headline: "Dünyayı daha iyi bir yer yapan alışveriş biçimi."
- cta_label: "Hazırım"
+ cta_label: "ALIŞVERİŞE HAZIRIM"
stats_headline: "Yeni bir gıda sistemi yaratıyoruz."
stats_producers: "ÜRETİCİ"
stats_shops: "DÜKKAN"
- stats_shoppers: "TÜRETİCİ"
+ stats_shoppers: "ALICI"
stats_orders: "ALIŞVERİŞ"
checkout_title: Ödeme Yap
checkout_now: Alışverişi Tamamla
@@ -1521,7 +1534,7 @@ tr:
shopping_tabs_contact: "İLETİŞİM"
shopping_contact_address: "Adres"
shopping_contact_web: "İLETİŞİM"
- shopping_contact_social: "Takip et"
+ shopping_contact_social: "TAKİP ET"
shopping_groups_part_of: "şunun parçası:"
shopping_producers_of_hub: "%{hub} üreticileri:"
enterprises_next_closing: "Bir sonraki sipariş kapanışı"
@@ -1542,7 +1555,7 @@ tr:
hubs_filter_delivery: "Eve Teslim"
hubs_filter_property: "Özellik"
hubs_matches: "Bunu mu arıyordunuz?"
- hubs_intro: Bulunduğunuz bölgeden alışveriş yapın
+ hubs_intro: Alışverişe başlayın
hubs_distance: En yakın
hubs_distance_filter: "Bana %{location} yakınındaki dükkanları göster"
shop_changeable_orders_alert_html:
@@ -1581,14 +1594,14 @@ tr:
components_filters_clearfilters: "TÜM FİLTRELERİ TEMİZLE"
groups_title: Gruplar
groups_headline: Gruplar
- groups_text: "Her üretici özeldir ve her işletmenin ortaya koyabileceği farklı bir değer vardır. Üyelerimiz, ürünlerini, emeklerini ve gıdanın ortak değerleri paylaşan üretici, türetici ve dağıtımcı kolektifleridir. Bu bileşenler, adil ve temiz gıdaya ulaşım yollarını kolaylaştırır ve bozulmuş gıda sistemini hep beraber düzeltmemize yardımcı olur."
+ groups_text: "Her üretici özeldir ve her işletmenin ortaya koyabileceği farklı bir değer vardır. Üyelerimiz, ürünlerini, emeklerini ve gıdanın ortak değerlerini paylaşan üretici, türetici ve dağıtımcı kolektifleridir. Bu bileşenler, adil ve temiz gıdaya ulaşım yollarını kolaylaştırır ve bozulmuş gıda sistemini düzeltmemize öncülük ederler."
groups_search: "İsim veya anahtar kelime ile ara"
groups_no_groups: "Ağ bulunamadı"
groups_about: "Hakkımızda"
groups_producers: "ÜRETİCİLERİMİZ"
groups_hubs: "Pazarlarımız"
groups_contact_web: İLETİŞİM
- groups_contact_social: Takip et
+ groups_contact_social: TAKİP ET
groups_contact_address: Adres
groups_contact_email: Bize e-posta gönderin
groups_contact_website: İnternet sitemizi ziyaret edin
@@ -1615,9 +1628,9 @@ tr:
producers_about: Hakkımızda
producers_buy: Alışveriş ürünleri
producers_contact: İLETİŞİM
- producers_contact_phone: Ara
- producers_contact_social: Takip et
- producers_buy_at_html: "%{enterprise} ürünleri için buradan alışveriş yapın:"
+ producers_contact_phone: 'Tel:'
+ producers_contact_social: TAKİP ET
+ producers_buy_at_html: "%{enterprise} ÜRÜNLERİNİ SATIN ALIN:"
producers_filter: Filtrele
producers_filter_type: tür
producers_filter_property: Özellik
@@ -1864,15 +1877,15 @@ tr:
enterprise_final_step: "Son adım!"
enterprise_social_text: "Kişiler %{enterprise}' nasıl çevrimiçi bulabilir?"
website: "İnternet sitesi"
- website_placeholder: "Örneğin. yesilciftlik.com"
+ website_placeholder: "Örn. ciftlik.com"
facebook: "Facebook"
- facebook_placeholder: "Örneğin. www.facebook.com/SayfaAdı"
+ facebook_placeholder: "Örn. www.facebook.com/Ciftlik"
linkedin: "LinkedIn"
- linkedin_placeholder: "Örneğin. www.linkedin.com/Adınız"
+ linkedin_placeholder: "Örn. www.linkedin.com/Adınız"
twitter: "Twitter"
- twitter_placeholder: "Örneğin. @twitter_ciftlik"
+ twitter_placeholder: "Örn. @twitter_ciftlik"
instagram: "Instagram"
- instagram_placeholder: "Örneğin. @instagram_ciftlik"
+ instagram_placeholder: "Örn. instagram_ciftlik"
limit_reached:
headline: "Hayır!"
message: "Sınıra ulaştınız!"
@@ -1893,10 +1906,10 @@ tr:
bulk: "toplu"
shop_variant_quantity_min: "min"
shop_variant_quantity_max: "maks"
- follow: "Takip et"
- shop_for_products_html: "%{enterprise} ürünleri için şuradan alışveriş yapın:"
+ follow: "TAKİP ET"
+ shop_for_products_html: "%{enterprise} ÜRÜNLERİNİ SATIN ALIN:"
change_shop: "Dükkanı şuna değiştir:"
- shop_at: "Şimdi alışveriş yapın:"
+ shop_at: "ŞİMDİ ALIŞVERİŞ YAPIN:"
price_breakdown: "Fiyat dökümü"
admin_fee: "Yönetim Ücreti"
sales_fee: "Satış Ücreti"
@@ -1918,7 +1931,7 @@ tr:
ok: tamam
not_visible: görünmez
you_have_no_orders_yet: "Henüz siparişiniz yok"
- show_only_complete_orders: "Yalnızca tamamlanan siparişleri göster"
+ show_only_complete_orders: "YALNIZCA TAMAMLANAN SİPARİŞLERİ GÖSTER"
successfully_created: '%{resource} BAŞARIYLA OLUŞTURULDU!'
successfully_removed: '%{resource} BAŞARIYLA KALDIRILDI!'
successfully_updated: '%{resource} BAŞARIYLA GÜNCELLENDİ!'
@@ -1939,25 +1952,27 @@ tr:
admin_enterprise_groups_data_powertip_logo: "Grubun logosu"
admin_enterprise_groups_data_powertip_promo_image: "Bu resim grup profilinin üstünde görüntülenir"
admin_enterprise_groups_contact: "İLETİŞİM"
- admin_enterprise_groups_contact_phone_placeholder: "Örneğin. 532 100 05 01"
- admin_enterprise_groups_contact_address1_placeholder: "Örneğin. 123 Cadde"
+ admin_enterprise_groups_contact_phone_placeholder: "Örn. 532 100 05 01"
+ admin_enterprise_groups_contact_address1_placeholder: "Örn. 123 Cadde"
admin_enterprise_groups_contact_city: "İlçe"
- admin_enterprise_groups_contact_city_placeholder: "Örneğin. Kadıköy"
+ admin_enterprise_groups_contact_city_placeholder: "Örn. Kadıköy"
admin_enterprise_groups_contact_zipcode: "Posta kodu"
admin_enterprise_groups_contact_zipcode_placeholder: "Örn. 34000"
admin_enterprise_groups_contact_state_id: "Şehir"
admin_enterprise_groups_contact_country_id: "Ülke"
admin_enterprise_groups_web: "Web Kaynakları"
- admin_enterprise_groups_web_twitter: "Örneğin. @the_prof"
- admin_enterprise_groups_web_website_placeholder: "Örneğin. www.ciftlik.com"
+ admin_enterprise_groups_web_twitter: "Örn. @the_ciftlik"
+ admin_enterprise_groups_web_website_placeholder: "Örn. www.ciftlik.com"
admin_order_cycles: "Yönetici Sipariş Dönemleri"
open: "AÇILIŞ"
- close: "KAPANIŞ"
+ close: "Kapat"
create: "Oluştur"
search: "Ara"
supplier: "Tedarikçi"
product_name: "Ürün Adı"
product_description: "Ürün Açıklaması"
+ permalink: "Permalink"
+ shipping_categories: "Teslimat Kategorileri"
units: "Ölçü Birimi"
coordinator: "KOORDİNATÖR"
distributor: "Dağıtımcı"
@@ -2025,8 +2040,8 @@ tr:
spree_admin_product_category: Ürün Kategorisi
spree_admin_variant_unit_name: Varyant Birimi Adı
unit_name: "Birim adı"
- change_package: "Hesap Türünü Değiştir"
- spree_admin_single_enterprise_hint: "İpucu: İnsanların sizi bulmasına izin vermek için, alttaki görünürlük kısmını açın."
+ change_package: "HESAP TÜRÜNÜ DEĞİŞTİR"
+ spree_admin_single_enterprise_hint: "İpucu: İnsanların sizi bulmasına izin vermek için 'Görünür' olmayı ayarlamayı unutmayın:"
spree_admin_eg_pickup_from_school: "Örn. 'Teslimat noktası: Moda İlkokulu Bahçesi'"
spree_admin_eg_collect_your_order: "Örn. Lütfen siparişinizi Moda Cad. No:17 Temiz Dükkan'dan teslim alınız."
spree_classification_primary_taxon_error: "%{taxon} cinsi, %{product}ürününün birincil cinsidir ve silinemez"
@@ -2054,6 +2069,8 @@ tr:
remove_tax: "Vergiyi kaldır"
first_name_begins_with: "Adının BAŞ HARFİ"
last_name_begins_with: "Soyadının BAŞ HARFİ"
+ shipping_method: "Teslimat Yöntemi"
+ new_order: "Yeni Sipariş"
enterprise_tos_link: "İşletme Üyelik Sözleşmesi bağlantısı"
enterprise_tos_message: "Amaçlarımızı ve değerlerimizi paylaşan insanlarla çalışmak istiyoruz. Yasal zorunluluk gereği de yeni işletmelerden kabul etmesini istiyoruz:"
enterprise_tos_link_text: "Üyelik Sözleşmesi"
@@ -2129,7 +2146,7 @@ tr:
report_header_incoming_transport: Gelen Nakliye
report_header_special_instructions: Özel Talimatlar
report_header_order_number: Sipariş numarası
- report_header_date: tarih
+ report_header_date: Tarih
report_header_confirmation_date: Onay tarihi
report_header_tags: ETİKETLER
report_header_items: Kalemler
@@ -2429,8 +2446,8 @@ tr:
en iyi şekilde yönetmeniz için tüm imkanları ve araçları sağlamaya hazırız.
get_listing: Görünür Olun
always_free: HER ZAMAN ÜCRETSİZ
- sell_produce_others: Başkalarının ürünlerini sat
- sell_own_produce: Kendi ürününü sat
+ sell_produce_others: BAŞKALARININ ÜRÜNLERİNİ SAT
+ sell_own_produce: KENDİ ÜRÜNÜNÜ SAT
sell_both: Kendi ürünlerini ve başkalarının ürünlerini sat
enterprise_producer:
producer: Üretici
@@ -2452,12 +2469,12 @@ tr:
adına sipariş ve teslimatları yönetebilir, adil ve temiz gıdayı nihai
tüketiciler ile buluşturmaya yardımcı olabilirler.
producer_desc: Gıda üreticileri
- producer_example: 'Örn: ÇİFTÇİLER, FIRINLAR, ÜRETİM KOOPERATİFLERİ vs.'
+ producer_example: Örn. ÇİFTÇİLER, FIRINLAR, ÜRETİM KOOPERATİFLERİ vs.
non_producer_desc: Diğer tüm gıda işletmeleri
- non_producer_example: 'Örn: Manavlar, Gıda Kooperatifleri, Gıda Toplulukları vs.'
+ non_producer_example: Örn. Dükkanlar, Gıda Kooperatifleri, Gıda Toplulukları vs.
enterprise_status:
status_title: "%{name} kuruldu ve başlamaya hazır!"
- severity: Şiddet
+ severity: ÖNEM
description: Açıklama
resolve: Çözüm
exchange_products:
@@ -2966,7 +2983,7 @@ tr:
tab:
dashboard: "KONTROL PANELİ"
orders: "SİPARİŞLER"
- bulk_order_management: "Toplu Sipariş Yönetimi"
+ bulk_order_management: "TOPLU SİPARİŞ YÖNETİMİ"
subscriptions: "Üyelikler"
products: "Ürünler"
option_types: "Seçenek Türleri"
@@ -3103,7 +3120,7 @@ tr:
new_shipping_method: "YENİ TESLİMAT YÖNTEMİ"
back_to_shipping_methods_list: "Teslİmat Yöntemlerİne Gerİ Dön"
edit:
- editing_shipping_method: "Teslİmat YöntemİNİ Düzenle"
+ editing_shipping_method: "Teslimat Yöntemini Düzenle"
new: "YENİ"
back_to_shipping_methods_list: "Teslİmat Yöntemlerİne Gerİ Dön"
form:
@@ -3168,6 +3185,8 @@ tr:
stripe:
error_saving_payment: Ödeme kaydedilirken hata oluştu
submitting_payment: Ödeme gönderiliyor ...
+ paypal:
+ no_payment_via_admin_backend: Paypal ödemeleri alınamıyor.
products:
image_upload_error: "Ürün resmi tanınamadı. Lütfen PNG veya JPG biçiminde bir resim yükleyin."
new:
@@ -3184,7 +3203,7 @@ tr:
product_description: "Ürün Açıklaması"
image: "Görsel"
or: "veya"
- unit_name_placeholder: 'Örneğin. demet'
+ unit_name_placeholder: 'Örn. Demet'
index:
header:
title: Ürünleri Toplu Düzenleme
@@ -3262,8 +3281,8 @@ tr:
price: "Fiyat"
display_as: "Gösterme Şekli"
display_name: "Ekran adı"
- display_as_placeholder: 'örn. 2 kg'
- display_name_placeholder: 'örn. Domates'
+ display_as_placeholder: 'Örn. 2 kg'
+ display_name_placeholder: 'Örn. Domates'
autocomplete:
out_of_stock: "Stokta Yok"
producer_name: "Üretici"
@@ -3345,6 +3364,32 @@ tr:
invoice_email:
hi: "Merhaba %{name}"
invoice_attached_text: 'Son siparişiniz için gelen fatura ektedir:'
+ user_mailer:
+ reset_password_instructions:
+ request_sent_text: |
+ Şifrenizin değiştirilmesi için bir talepte bulunuldu.
+ Eğer talepte bulunan siz değilseniz lütfen bu mesajı gözardı edin.
+ link_text: >
+ Bu talepte bulunduysanız lütfen aşağıdaki bağlantıya tıklayın:
+ issue_text: |
+ Üstteki URL çalışmıyor ise tarayıcınızın adres çubuğuna kopyalayıp yapıştırmayı deneyebilirsiniz.
+ Sorun yaşamaya devam ederseniz bizimle iletişime geçmekten çekinmeyin.
+ confirmation_instructions:
+ subject: "Lütfen AGA hesabınızı onaylayın"
+ shipment_mailer:
+ shipped_email:
+ dear_customer: "Değerli Müşterimiz,"
+ instructions: "Siparişiniz gönderildi"
+ shipment_summary: "Teslimat Özeti"
+ subject: "TESLİMAT BİLDİRİMİ"
+ thanks: "İş birliğiniz için teşekkür ederim."
+ track_information: "Takip Bilgileri: %{tracking}"
+ track_link: "Takip Bağlantısı: %{url}"
+ test_mailer:
+ test_email:
+ greeting: "Tebrikler!"
+ message: "Bu maili teslim aldıysanız e-posta ayarlarınız doğru yapılmıştır demektir."
+ subject: "Test Maili"
order_state:
address: adres
adjustments: düzenlemeler
@@ -3366,18 +3411,6 @@ tr:
ended: bitti
paused: durduruldu
canceled: iptal edildi
- user_mailer:
- reset_password_instructions:
- request_sent_text: |
- Şifrenizin değiştirilmesi için bir talepte bulunuldu.
- Eğer talepte bulunan siz değilseniz lütfen bu mesajı gözardı edin.
- link_text: >
- Bu talepte bulunduysanız lütfen aşağıdaki bağlantıya tıklayın:
- issue_text: |
- Üstteki URL çalışmıyor ise tarayıcınızın adres çubuğuna kopyalayıp yapıştırmayı deneyebilirsiniz.
- Sorun yaşamaya devam ederseniz bizimle iletişime geçmekten çekinmeyin.
- confirmation_instructions:
- subject: Lütfen AGA hesabınızı onaylayın
users:
form:
account_settings: Hesap Ayarları
diff --git a/config/routes.rb b/config/routes.rb
index ef3380ea79..a657f7f234 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -9,6 +9,7 @@ Openfoodnetwork::Application.routes.draw do
get "/about_us", to: redirect(ContentConfig.footer_about_url)
get "/login", to: redirect("/#/login")
+ get '/unauthorized', :to => 'home#unauthorized', :as => :unauthorized
get "/discourse/login", to: "discourse_sso#login"
get "/discourse/sso", to: "discourse_sso#sso"
diff --git a/config/routes/spree.rb b/config/routes/spree.rb
index ca5993aca5..5aecadbf49 100644
--- a/config/routes/spree.rb
+++ b/config/routes/spree.rb
@@ -1,7 +1,5 @@
# Overriding Devise routes to use our own controller
Spree::Core::Engine.routes.draw do
- root to: 'home#index'
-
devise_for :spree_user,
:class_name => 'Spree::User',
:controllers => { :sessions => 'spree/user_sessions',
@@ -15,7 +13,6 @@ Spree::Core::Engine.routes.draw do
resources :users, :only => [:edit, :update]
devise_scope :spree_user do
- get '/login' => 'user_sessions#new', :as => :login
post '/login' => 'user_sessions#create', :as => :create_new_session
get '/logout' => 'user_sessions#destroy', :as => :logout
get '/signup' => 'user_registrations#new', :as => :signup
@@ -174,8 +171,6 @@ Spree::Core::Engine.routes.draw do
# Used by spree_paypal_express
get '/checkout/:state', :to => 'checkout#edit', :as => :checkout_state
-
- get '/unauthorized', :to => 'home#unauthorized', :as => :unauthorized
get '/content/cvv', :to => 'content#cvv', :as => :cvv
get '/content/*path', :to => 'content#show', :as => :content
end
diff --git a/db/migrate/20200512070717_add_lock_version_to_stock_items.rb b/db/migrate/20200512070717_add_lock_version_to_stock_items.rb
new file mode 100644
index 0000000000..416a43f62e
--- /dev/null
+++ b/db/migrate/20200512070717_add_lock_version_to_stock_items.rb
@@ -0,0 +1,5 @@
+class AddLockVersionToStockItems < ActiveRecord::Migration
+ def change
+ add_column :spree_stock_items, :lock_version, :integer, default: 0
+ end
+end
diff --git a/db/migrate/20200514174526_reset_negative_nonbackorderable_count_on_hand_in_stock_items.rb b/db/migrate/20200514174526_reset_negative_nonbackorderable_count_on_hand_in_stock_items.rb
new file mode 100644
index 0000000000..c57730c99a
--- /dev/null
+++ b/db/migrate/20200514174526_reset_negative_nonbackorderable_count_on_hand_in_stock_items.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class ResetNegativeNonbackorderableCountOnHandInStockItems < ActiveRecord::Migration
+ module Spree
+ class StockItem < ActiveRecord::Base
+ self.table_name = "spree_stock_items"
+ end
+ end
+
+ def up
+ Spree::StockItem.where(backorderable: false)
+ .where("count_on_hand < 0")
+ .update_all(count_on_hand: 0)
+ end
+
+ def down
+ raise ActiveRecord::IrreversibleMigration
+ end
+end
diff --git a/db/migrate/20200721135726_move_calculators_preferences_outside_spree_namespace.rb b/db/migrate/20200721135726_move_calculators_preferences_outside_spree_namespace.rb
new file mode 100644
index 0000000000..2591550dd1
--- /dev/null
+++ b/db/migrate/20200721135726_move_calculators_preferences_outside_spree_namespace.rb
@@ -0,0 +1,25 @@
+# As we moved the calculators outside the Spree namespace in migration MoveAllCalculatorsOutsideTheSpreeNamespace
+# We need to move their preferences too (currency, value, etc), otherwise they are not used
+class MoveCalculatorsPreferencesOutsideSpreeNamespace < ActiveRecord::Migration
+ def up
+ replace_preferences_key("/spree/calculator", "/calculator")
+ end
+
+ def down
+ replace_preferences_key("/calculator", "/spree/calculator")
+ end
+
+ private
+
+ def replace_preferences_key(from_pattern, to_pattern)
+ updated_pref_key = "replace( pref.key, '" + from_pattern + "', '" + to_pattern + "')"
+ Spree::Preference.connection.execute(
+ "UPDATE spree_preferences pref SET key = " + updated_pref_key + "
+ WHERE pref.key like '" + from_pattern + "%'
+ AND NOT EXISTS (SELECT 1 FROM spree_preferences existing_pref
+ WHERE existing_pref.key = " + updated_pref_key + ")"
+ )
+
+ Rails.cache.clear
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 97ddcb63d2..f56c95f405 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20200702112157) do
+ActiveRecord::Schema.define(version: 20200721135726) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -901,6 +901,7 @@ ActiveRecord::Schema.define(version: 20200702112157) do
t.datetime "updated_at", null: false
t.boolean "backorderable", default: false
t.datetime "deleted_at"
+ t.integer "lock_version", default: 0
end
add_index "spree_stock_items", ["stock_location_id", "variant_id"], name: "stock_item_by_loc_and_var_id", using: :btree
diff --git a/engines/order_management/app/services/order_management/order/updater.rb b/engines/order_management/app/services/order_management/order/updater.rb
new file mode 100644
index 0000000000..e7cb051a4f
--- /dev/null
+++ b/engines/order_management/app/services/order_management/order/updater.rb
@@ -0,0 +1,184 @@
+# frozen_string_literal: true
+
+module OrderManagement
+ module Order
+ class Updater
+ attr_reader :order
+ delegate :payments, :line_items, :adjustments, :shipments, :update_hooks, to: :order
+
+ def initialize(order)
+ @order = order
+ end
+
+ # This is a multi-purpose method for processing logic related to changes in the Order.
+ # It is meant to be called from various observers so that the Order is aware of changes
+ # that affect totals and other values stored in the Order.
+ #
+ # This method should never do anything to the Order that results in a save call on the
+ # object with callbacks (otherwise you will end up in an infinite recursion as the
+ # associations try to save and then in turn try to call +update!+ again.)
+ def update
+ update_totals
+
+ if order.completed?
+ update_payment_state
+
+ # give each of the shipments a chance to update themselves
+ shipments.each { |shipment| shipment.update!(order) }
+ update_shipment_state
+ end
+
+ update_all_adjustments
+ # update totals a second time in case updated adjustments have an effect on the total
+ update_totals
+
+ order.update_attributes_without_callbacks(
+ payment_state: order.payment_state,
+ shipment_state: order.shipment_state,
+ item_total: order.item_total,
+ adjustment_total: order.adjustment_total,
+ payment_total: order.payment_total,
+ total: order.total
+ )
+
+ run_hooks
+ end
+
+ def run_hooks
+ update_hooks.each { |hook| order.__send__(hook) }
+ end
+
+ # Updates the following Order total values:
+ #
+ # - payment_total - total value of all finalized Payments (excludes non-finalized Payments)
+ # - item_total - total value of all LineItems
+ # - adjustment_total - total value of all adjustments
+ # - total - order total, it's the equivalent to item_total plus adjustment_total
+ def update_totals
+ order.payment_total = payments.completed.map(&:amount).sum
+ order.item_total = line_items.map(&:amount).sum
+ order.adjustment_total = adjustments.eligible.map(&:amount).sum
+ order.total = order.item_total + order.adjustment_total
+ end
+
+ # Updates the +shipment_state+ attribute according to the following logic:
+ #
+ # - shipped - when the order shipment is in the "shipped" state
+ # - ready - when the order shipment is in the "ready" state
+ # - backorder - when there is backordered inventory associated with an order
+ # - pending - when the shipment is in the "pending" state
+ #
+ # The +shipment_state+ value helps with reporting, etc. since it provides a quick and easy way
+ # to locate Orders needing attention.
+ def update_shipment_state
+ order.shipment_state = if order.shipment&.backordered?
+ 'backorder'
+ else
+ # It returns nil if there is no shipment
+ order.shipment&.state
+ end
+
+ order.state_changed('shipment')
+ end
+
+ # Updates the +payment_state+ attribute according to the following logic:
+ #
+ # - paid - when +payment_total+ is equal to +total+
+ # - balance_due - when +payment_total+ is less than +total+
+ # - credit_owed - when +payment_total+ is greater than +total+
+ # - failed - when most recent payment is in the failed state
+ #
+ # The +payment_state+ value helps with reporting, etc. since it provides a quick and easy way
+ # to locate Orders needing attention.
+ def update_payment_state
+ last_payment_state = order.payment_state
+
+ order.payment_state = infer_payment_state
+ track_payment_state_change(last_payment_state)
+
+ order.payment_state
+ end
+
+ def update_all_adjustments
+ order.adjustments.reload.each(&:update!)
+ end
+
+ def before_save_hook
+ shipping_address_from_distributor
+ end
+
+ # Sets the distributor's address as shipping address of the order for those
+ # shipments using a shipping method that doesn't require address, such us
+ # a pickup.
+ def shipping_address_from_distributor
+ return if order.shipping_method.blank? || order.shipping_method.require_ship_address
+
+ order.ship_address = order.address_from_distributor
+ end
+
+ private
+
+ def round_money(value)
+ (value * 100).round / 100.0
+ end
+
+ def infer_payment_state
+ if failed_payments?
+ 'failed'
+ elsif canceled_and_not_paid_for?
+ 'void'
+ else
+ infer_payment_state_from_balance
+ end
+ end
+
+ def infer_payment_state_from_balance
+ # This part added so that we don't need to override
+ # order.outstanding_balance
+ balance = order.outstanding_balance
+ balance = -1 * order.payment_total if canceled_and_paid_for?
+
+ infer_state(balance)
+ end
+
+ def infer_state(balance)
+ if balance.positive?
+ 'balance_due'
+ elsif balance.negative?
+ 'credit_owed'
+ elsif balance.zero?
+ 'paid'
+ end
+ end
+
+ # Tracks the state transition through a state_change for this order. It
+ # does so until the last state is reached. That is, when the infered next
+ # state is the same as the order has now.
+ #
+ # @param last_payment_state [String]
+ def track_payment_state_change(last_payment_state)
+ return if last_payment_state == order.payment_state
+
+ order.state_changed('payment')
+ end
+
+ # Taken from order.outstanding_balance in Spree 2.4
+ # See: https://github.com/spree/spree/commit/7b264acff7824f5b3dc6651c106631d8f30b147a
+ def canceled_and_paid_for?
+ order.canceled? && paid?
+ end
+
+ def canceled_and_not_paid_for?
+ order.state == 'canceled' && order.payment_total.zero?
+ end
+
+ def paid?
+ payments.present? && !payments.completed.empty?
+ end
+
+ def failed_payments?
+ payments.present? && payments.valid.empty?
+ end
+ end
+ end
+end
diff --git a/engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb b/engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb
index 8adaef7f33..bc44c2b857 100644
--- a/engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb
+++ b/engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb
@@ -138,8 +138,13 @@ module OrderManagement
private
def line_item_includes
- [{ order: [:bill_address],
- variant: [{ option_values: :option_type }, { product: :supplier }] }]
+ [
+ {
+ order: [:bill_address],
+ variant: [{ option_values: :option_type }, { product: :supplier }]
+ },
+ :option_values
+ ]
end
def order_permissions
diff --git a/engines/order_management/app/services/order_management/subscriptions/summarizer.rb b/engines/order_management/app/services/order_management/subscriptions/summarizer.rb
index 8029716338..f591295d1c 100644
--- a/engines/order_management/app/services/order_management/subscriptions/summarizer.rb
+++ b/engines/order_management/app/services/order_management/subscriptions/summarizer.rb
@@ -22,12 +22,15 @@ module OrderManagement
summary_for(order).record_issue(type, order, message)
end
- def record_and_log_error(type, order)
+ def record_and_log_error(type, order, error_message = nil)
return record_issue(type, order) unless order.errors.any?
error = "Subscription#{type.to_s.camelize}Error"
line1 = "#{error}: Cannot process order #{order.number} due to errors"
- line2 = "Errors: #{order.errors.full_messages.join(', ')}"
+
+ error_message ||= order.errors.full_messages.join(', ')
+ line2 = "Errors: #{error_message}"
+
JobLogger.logger.info("#{line1}\n#{line2}")
record_issue(type, order, line2)
end
diff --git a/engines/order_management/spec/features/order_management/reports/bulk_coop_spec.rb b/engines/order_management/spec/features/order_management/reports/bulk_coop_spec.rb
index 29caf17a15..2cbc464c75 100644
--- a/engines/order_management/spec/features/order_management/reports/bulk_coop_spec.rb
+++ b/engines/order_management/spec/features/order_management/reports/bulk_coop_spec.rb
@@ -3,12 +3,11 @@
require "spec_helper"
feature "bulk coop" do
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
scenario "bulk co-op report" do
- quick_login_as_admin
- visit spree.admin_reports_path
+ login_as_admin_and_visit spree.admin_reports_path
click_link 'Bulk Co-Op'
click_button 'Generate Report'
diff --git a/engines/order_management/spec/features/order_management/reports/enterprise_fee_summaries_spec.rb b/engines/order_management/spec/features/order_management/reports/enterprise_fee_summaries_spec.rb
index 553d78d093..8d66b93bfc 100644
--- a/engines/order_management/spec/features/order_management/reports/enterprise_fee_summaries_spec.rb
+++ b/engines/order_management/spec/features/order_management/reports/enterprise_fee_summaries_spec.rb
@@ -3,7 +3,7 @@
require "spec_helper"
feature "enterprise fee summaries", js: true do
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
let!(:distributor) { create(:distributor_enterprise) }
diff --git a/engines/order_management/spec/services/order_management/order/updater_spec.rb b/engines/order_management/spec/services/order_management/order/updater_spec.rb
new file mode 100644
index 0000000000..1bd901d37c
--- /dev/null
+++ b/engines/order_management/spec/services/order_management/order/updater_spec.rb
@@ -0,0 +1,275 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+module OrderManagement
+ module Order
+ describe Updater do
+ let(:order) { build(:order) }
+ let(:updater) { OrderManagement::Order::Updater.new(order) }
+
+ before { allow(order).to receive(:backordered?) { false } }
+
+ it "updates totals" do
+ payments = [double(amount: 5), double(amount: 5)]
+ allow(order).to receive_message_chain(:payments, :completed).and_return(payments)
+
+ line_items = [double(amount: 10), double(amount: 20)]
+ allow(order).to receive_messages line_items: line_items
+
+ adjustments = [double(amount: 10), double(amount: -20)]
+ allow(order).to receive_message_chain(:adjustments, :eligible).and_return(adjustments)
+
+ updater.update_totals
+ expect(order.payment_total).to eq 10
+ expect(order.item_total).to eq 30
+ expect(order.adjustment_total).to eq(-10)
+ expect(order.total).to eq 20
+ end
+
+ context "updating shipment state" do
+ let(:shipment) { build(:shipment) }
+
+ before do
+ allow(order).to receive(:shipments).and_return([shipment])
+ end
+
+ it "is backordered" do
+ allow(shipment).to receive(:backordered?) { true }
+ updater.update_shipment_state
+
+ expect(order.shipment_state).to eq 'backorder'
+ end
+
+ it "is nil" do
+ allow(shipment).to receive(:state).and_return(nil)
+
+ updater.update_shipment_state
+ expect(order.shipment_state).to be_nil
+ end
+
+ ["shipped", "ready", "pending"].each do |state|
+ it "is #{state}" do
+ allow(shipment).to receive(:state).and_return(state)
+ updater.update_shipment_state
+ expect(order.shipment_state).to eq state.to_s
+ end
+ end
+ end
+
+ it "state change" do
+ order = create(:order)
+ order.shipment_state = 'shipped'
+ state_changes = double
+ allow(order).to receive(:state_changes) { state_changes }
+ expect(state_changes).to receive(:create).with(
+ previous_state: nil,
+ next_state: 'shipped',
+ name: 'shipment',
+ user_id: order.user_id
+ )
+
+ order.state_changed('shipment')
+ end
+
+ context "completed order" do
+ before { allow(order).to receive(:completed?) { true } }
+
+ it "updates payment state" do
+ expect(updater).to receive(:update_payment_state)
+ updater.update
+ end
+
+ it "updates shipment state" do
+ expect(updater).to receive(:update_shipment_state)
+ updater.update
+ end
+
+ it "updates the order shipment" do
+ shipment = build(:shipment)
+ allow(order).to receive_messages shipments: [shipment]
+
+ expect(shipment).to receive(:update!).with(order)
+ updater.update
+ end
+ end
+
+ context "incompleted order" do
+ before { allow(order).to receive_messages completed?: false }
+
+ it "doesnt update payment state" do
+ expect(updater).not_to receive(:update_payment_state)
+ updater.update
+ end
+
+ it "doesnt update shipment state" do
+ expect(updater).not_to receive(:update_shipment_state)
+ updater.update
+ end
+
+ it "doesnt update the order shipment" do
+ shipment = build(:shipment)
+ allow(order).to receive_messages shipments: [shipment]
+
+ expect(shipment).not_to receive(:update!).with(order)
+ updater.update
+ end
+ end
+
+ it "updates totals twice" do
+ expect(updater).to receive(:update_totals).twice
+ updater.update
+ end
+
+ it "updates all adjustments" do
+ expect(updater).to receive(:update_all_adjustments)
+ updater.update
+ end
+
+ it "is failed if no valid payments" do
+ allow(order).to receive_message_chain(:payments, :valid, :empty?).and_return(true)
+
+ updater.update_payment_state
+ expect(order.payment_state).to eq('failed')
+ end
+
+ context "payment total is greater than order total" do
+ it "is credit_owed" do
+ order.payment_total = 2
+ order.total = 1
+
+ expect {
+ updater.update_payment_state
+ }.to change { order.payment_state }.to 'credit_owed'
+ end
+ end
+
+ context "order total is greater than payment total" do
+ it "is credit_owed" do
+ order.payment_total = 1
+ order.total = 2
+
+ expect {
+ updater.update_payment_state
+ }.to change { order.payment_state }.to 'balance_due'
+ end
+ end
+
+ context "order total equals payment total" do
+ it "is paid" do
+ order.payment_total = 30
+ order.total = 30
+
+ expect {
+ updater.update_payment_state
+ }.to change { order.payment_state }.to 'paid'
+ end
+ end
+
+ context "order is canceled" do
+ before do
+ order.state = 'canceled'
+ end
+
+ context "and is still unpaid" do
+ it "is void" do
+ order.payment_total = 0
+ order.total = 30
+ expect {
+ updater.update_payment_state
+ }.to change { order.payment_state }.to 'void'
+ end
+ end
+
+ context "and is paid" do
+ it "is credit_owed" do
+ order.payment_total = 30
+ order.total = 30
+ allow(order).to receive_message_chain(:payments, :valid, :empty?).and_return(false)
+ allow(order).to receive_message_chain(:payments, :completed, :empty?).and_return(false)
+ expect {
+ updater.update_payment_state
+ }.to change { order.payment_state }.to 'credit_owed'
+ end
+ end
+
+ context "and payment is refunded" do
+ it "is void" do
+ order.payment_total = 0
+ order.total = 30
+ allow(order).to receive_message_chain(:payments, :valid, :empty?).and_return(false)
+ allow(order).to receive_message_chain(:payments, :completed, :empty?).and_return(false)
+ expect {
+ updater.update_payment_state
+ }.to change { order.payment_state }.to 'void'
+ end
+ end
+ end
+
+ context 'when the set payment_state does not match the last payment_state' do
+ before { order.payment_state = 'previous_to_paid' }
+
+ context 'and the order is being updated' do
+ before { allow(order).to receive(:persisted?) { true } }
+
+ it 'creates a new state_change for the order' do
+ expect { updater.update_payment_state }
+ .to change { order.state_changes.size }.by(1)
+ end
+ end
+
+ context 'and the order is being created' do
+ before { allow(order).to receive(:persisted?) { false } }
+
+ it 'creates a new state_change for the order' do
+ expect { updater.update_payment_state }
+ .not_to change { order.state_changes.size }
+ end
+ end
+ end
+
+ context 'when the set payment_state matches the last payment_state' do
+ before { order.payment_state = 'paid' }
+
+ it 'does not create any state_change' do
+ expect { updater.update_payment_state }
+ .not_to change { order.state_changes.size }
+ end
+ end
+
+ context '#before_save_hook' do
+ let(:distributor) { build(:distributor_enterprise) }
+ let(:shipment) {
+ create(:shipment_with, :shipping_method, shipping_method: shipping_method)
+ }
+
+ before do
+ order.distributor = distributor
+ order.shipments = [shipment]
+ end
+
+ context 'when shipping method is pickup' do
+ let(:shipping_method) { create(:shipping_method_with, :pickup) }
+ let(:address) { build(:address, firstname: 'joe') }
+ before { distributor.address = address }
+
+ it "populates the shipping address from distributor" do
+ updater.before_save_hook
+ expect(order.ship_address.address1).to eq(distributor.address.address1)
+ end
+ end
+
+ context 'when shipping_method is delivery' do
+ let(:shipping_method) { create(:shipping_method_with, :delivery) }
+ let(:address) { build(:address, firstname: 'will') }
+ before { order.ship_address = address }
+
+ it "does not populate the shipping address from distributor" do
+ updater.before_save_hook
+ expect(order.ship_address.firstname).to eq("will")
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/knapsack_rspec_report.json b/knapsack_rspec_report.json
index 91499ba40e..f745a4438d 100644
--- a/knapsack_rspec_report.json
+++ b/knapsack_rspec_report.json
@@ -113,7 +113,6 @@
"spec/models/subscription_line_item_spec.rb": 0.021193265914916992,
"spec/controllers/api/statuses_controller_spec.rb": 0.02451467514038086,
"spec/lib/open_food_network/referer_parser_spec.rb": 0.015799283981323242,
- "spec/lib/open_food_network/reports/rule_spec.rb": 0.01628732681274414,
"spec/helpers/serializer_helper_spec.rb": 0.004682064056396484,
"spec/jobs/heartbeat_job_spec.rb": 0.013271570205688477,
"spec/services/mail_configuration_spec.rb": 0.01050567626953125,
@@ -246,7 +245,6 @@
"spec/validators/integer_array_validator_spec.rb": 0.04994392395019531,
"spec/validators/date_time_string_validator_spec.rb": 0.05316734313964844,
"spec/models/product_import/reset_absent_spec.rb": 0.04071307182312012,
- "spec/lib/open_food_network/reports/report_spec.rb": 0.04329681396484375,
"spec/jobs/confirm_signup_job_spec.rb": 0.03060293197631836,
"spec/services/order_cycle_distributed_variants_spec.rb": 0.02808237075805664,
"spec/lib/open_food_network/feature_toggle_spec.rb": 0.0240786075592041,
@@ -255,7 +253,6 @@
"spec/models/spree/calculator/flat_rate_spec.rb": 0.014808177947998047,
"spec/models/spree/image_spec.rb": 0.014715909957885742,
"spec/helpers/spree/admin/base_helper_spec.rb": 0.008042573928833008,
- "spec/lib/open_food_network/reports/row_spec.rb": 0.005358695983886719,
"engines/order_management/spec/controllers/order_management/reports/enterprise_fee_summaries_controller_spec.rb": 0.7100100517272949,
"engines/order_management/spec/services/order_management/reports/enterprise_fee_summary/parameters_spec.rb": 4.190261602401733,
"engines/order_management/spec/services/order_management/reports/enterprise_fee_summary/report_data/enterprise_fee_type_total_spec.rb": 0.006247282028198242,
diff --git a/lib/open_food_network/model_class_from_controller_name.rb b/lib/open_food_network/model_class_from_controller_name.rb
deleted file mode 100644
index 97b92a18d7..0000000000
--- a/lib/open_food_network/model_class_from_controller_name.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-module OpenFoodNetwork
- module ModelClassFromControllerName
- # Equivalent to CanCan's "authorize_resource :class => false" (see https://github.com/ryanb/cancan/blob/master/lib/cancan/controller_resource.rb#L146)
- def model_class
- self.class.to_s.sub("Controller", "").underscore.split('/').last.singularize.to_sym
- end
- end
-end
diff --git a/lib/open_food_network/reports/report.rb b/lib/open_food_network/reports/report.rb
deleted file mode 100644
index 2c4e5900f2..0000000000
--- a/lib/open_food_network/reports/report.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-require 'open_food_network/reports/row'
-require 'open_food_network/reports/rule'
-
-module OpenFoodNetwork::Reports
- class Report
- class_attribute :_header, :_columns, :_rules_head
-
- # -- API
- def header
- _header
- end
-
- def columns
- _columns.to_a
- end
-
- def rules
- # Flatten linked list and return as hashes
- rules = []
-
- rule = _rules_head
- while rule
- rules << rule
- rule = rule.next
- end
-
- rules.map(&:to_h)
- end
-
- # -- DSL
- def self.header(*columns)
- self._header = columns
- end
- end
-end
diff --git a/lib/open_food_network/reports/row.rb b/lib/open_food_network/reports/row.rb
deleted file mode 100644
index 35b4bffe33..0000000000
--- a/lib/open_food_network/reports/row.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-module OpenFoodNetwork::Reports
- class Row
- def initialize
- @columns = []
- end
-
- def column(&block)
- @columns << block
- end
-
- def to_a
- @columns
- end
- end
-end
diff --git a/lib/open_food_network/reports/rule.rb b/lib/open_food_network/reports/rule.rb
deleted file mode 100644
index cfb8b7e67f..0000000000
--- a/lib/open_food_network/reports/rule.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-require 'open_food_network/reports/row'
-
-module OpenFoodNetwork::Reports
- class Rule
- attr_reader :next
-
- def group(&block)
- @group = block
- end
-
- def sort(&block)
- @sort = block
- end
-
- def to_h
- h = { group_by: @group, sort_by: @sort }
- h[:summary_columns] = @summary_row.to_a if @summary_row
- h
- end
- end
-end
diff --git a/lib/spree/authentication_helpers.rb b/lib/spree/authentication_helpers.rb
index 49bd97542a..1f26c65f2c 100644
--- a/lib/spree/authentication_helpers.rb
+++ b/lib/spree/authentication_helpers.rb
@@ -11,7 +11,9 @@ module Spree
current_spree_user
end
- delegate :login_path, to: :spree, prefix: true
+ def spree_login_path
+ main_app.login_path
+ end
delegate :signup_path, to: :spree, prefix: true
diff --git a/lib/spree/core.rb b/lib/spree/core.rb
new file mode 100644
index 0000000000..5a7d98dbd2
--- /dev/null
+++ b/lib/spree/core.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+require 'rails/all'
+require 'active_merchant'
+require 'acts_as_list'
+require 'awesome_nested_set'
+require 'cancan'
+require 'kaminari'
+require 'mail'
+require 'paperclip'
+require 'paranoia'
+require 'ransack'
+require 'state_machine'
+
+module Spree
+ mattr_accessor :user_class
+
+ def self.user_class
+ if @@user_class.is_a?(Class)
+ raise "Spree.user_class MUST be a String object, not a Class object."
+ end
+
+ return unless @@user_class.is_a?(String)
+
+ @@user_class.constantize
+ end
+
+ # Used to configure Spree.
+ #
+ # Example:
+ #
+ # Spree.config do |config|
+ # config.site_name = "An awesome Spree site"
+ # end
+ #
+ # This method is defined within the core gem on purpose.
+ # Some people may only wish to use the Core part of Spree.
+ def self.config
+ yield(Spree::Config)
+ end
+end
+
+require 'spree/core/version'
+require 'spree/core/engine'
+
+require 'spree/i18n'
+require 'spree/money'
+
+require 'spree/core/delegate_belongs_to'
+require 'spree/core/ext/active_record'
+require 'spree/core/permalinks'
+require 'spree/core/token_resource'
+require 'spree/core/calculated_adjustments'
+require 'spree/core/product_duplicator'
+
+ActiveRecord::Base.class_eval do
+ include CollectiveIdea::Acts::NestedSet
+end
diff --git a/lib/spree/core/calculated_adjustments.rb b/lib/spree/core/calculated_adjustments.rb
new file mode 100644
index 0000000000..c502c00099
--- /dev/null
+++ b/lib/spree/core/calculated_adjustments.rb
@@ -0,0 +1,81 @@
+# frozen_string_literal: true
+
+module Spree
+ module Core
+ module CalculatedAdjustments
+ def self.included(klass)
+ klass.class_eval do
+ has_one :calculator, class_name: "Spree::Calculator", as: :calculable, dependent: :destroy
+ accepts_nested_attributes_for :calculator
+ validates :calculator, presence: true
+
+ def self.calculators
+ spree_calculators.__send__(model_name_without_spree_namespace)
+ end
+
+ def calculator_type
+ calculator.class.to_s if calculator
+ end
+
+ def calculator_type=(calculator_type)
+ klass = calculator_type.constantize if calculator_type
+ self.calculator = klass.new if klass && !calculator.is_a?(klass)
+ end
+
+ # Creates a new adjustment for the target object
+ # (which is any class that has_many :adjustments) and sets amount based on the
+ # calculator as applied to the given calculable (Order, LineItems[], Shipment, etc.)
+ # By default the adjustment will not be considered mandatory
+ def create_adjustment(label, target, calculable, mandatory = false, state = "closed")
+ # Adjustment calculations done on Spree::Shipment objects MUST
+ # be done on their to_package'd variants instead
+ # It's only the package that contains the correct information.
+ # See https://github.com/spree/spree_active_shipping/pull/96 et. al
+ old_calculable = calculable
+ calculable = calculable.to_package if calculable.is_a?(Spree::Shipment)
+ amount = compute_amount(calculable)
+ return if amount.zero? && !mandatory
+
+ target.adjustments.create(
+ amount: amount,
+ source: old_calculable,
+ originator: self,
+ label: label,
+ mandatory: mandatory,
+ state: state
+ )
+ end
+
+ # Updates the amount of the adjustment using our Calculator and
+ # calling the +compute+ method with the +calculable+
+ # referenced passed to the method.
+ def update_adjustment(adjustment, calculable)
+ # Adjustment calculations done on Spree::Shipment objects MUST
+ # be done on their to_package'd variants instead
+ # It's only the package that contains the correct information.
+ # See https://github.com/spree/spree_active_shipping/pull/96 et. al
+ calculable = calculable.to_package if calculable.is_a?(Spree::Shipment)
+ adjustment.update_column(:amount, compute_amount(calculable))
+ end
+
+ # Calculate the amount to be used when creating an adjustment
+ # NOTE: May be overriden by classes where this module is included into.
+ # Such as Spree::Promotion::Action::CreateAdjustment.
+ def compute_amount(calculable)
+ calculator.compute(calculable)
+ end
+
+ def self.model_name_without_spree_namespace
+ to_s.tableize.gsub('/', '_').sub('spree_', '')
+ end
+ private_class_method :model_name_without_spree_namespace
+
+ def self.spree_calculators
+ Rails.application.config.spree.calculators
+ end
+ private_class_method :spree_calculators
+ end
+ end
+ end
+ end
+end
diff --git a/lib/spree/core/controller_helpers.rb b/lib/spree/core/controller_helpers.rb
new file mode 100644
index 0000000000..3df5251c9a
--- /dev/null
+++ b/lib/spree/core/controller_helpers.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Spree
+ module Core
+ module ControllerHelpers
+ def self.included(klass)
+ klass.class_eval do
+ include Spree::Core::ControllerHelpers::Common
+ include Spree::Core::ControllerHelpers::Auth
+ include Spree::Core::ControllerHelpers::RespondWith
+ include Spree::Core::ControllerHelpers::Order
+ end
+ end
+ end
+ end
+end
diff --git a/lib/spree/core/controller_helpers/auth.rb b/lib/spree/core/controller_helpers/auth.rb
new file mode 100644
index 0000000000..c6c18b9be1
--- /dev/null
+++ b/lib/spree/core/controller_helpers/auth.rb
@@ -0,0 +1,69 @@
+# frozen_string_literal: true
+
+module Spree
+ module Core
+ module ControllerHelpers
+ module Auth
+ extend ActiveSupport::Concern
+
+ included do
+ before_filter :ensure_api_key
+
+ rescue_from CanCan::AccessDenied do
+ unauthorized
+ end
+ end
+
+ # Needs to be overriden so that we use Spree's Ability rather than anyone else's.
+ def current_ability
+ @current_ability ||= Spree::Ability.new(spree_current_user)
+ end
+
+ # Redirect as appropriate when an access request fails. The default action is to redirect
+ # to the login screen. Override this method in your controllers if you want to have
+ # special behavior in case the user is not authorized to access the requested action.
+ # For example, a popup window might simply close itself.
+ def unauthorized
+ if spree_current_user
+ flash[:error] = Spree.t(:authorization_failure)
+ redirect_to '/unauthorized'
+ else
+ store_location
+ redirect_to main_app.root_path(anchor: "login?after_login=#{request.env['PATH_INFO']}")
+ end
+ end
+
+ def store_location
+ # disallow return to login, logout, signup pages
+ authentication_routes = [:spree_signup_path, :spree_login_path, :spree_logout_path]
+ disallowed_urls = []
+ authentication_routes.each do |route|
+ if respond_to?(route)
+ disallowed_urls << __send__(route)
+ end
+ end
+
+ disallowed_urls.map!{ |url| url[/\/\w+$/] }
+ return if disallowed_urls.include?(request.fullpath)
+
+ session['spree_user_return_to'] = request.fullpath.gsub('//', '/')
+ end
+
+ def redirect_back_or_default(default)
+ redirect_to(session["spree_user_return_to"] || default)
+ session["spree_user_return_to"] = nil
+ end
+
+ # Need to generate an API key for a user due to some actions potentially
+ # requiring authentication to the Spree API
+ def ensure_api_key
+ return unless (user = spree_current_user)
+
+ return unless user.respond_to?(:spree_api_key) && user.spree_api_key.blank?
+
+ user.generate_spree_api_key!
+ end
+ end
+ end
+ end
+end
diff --git a/lib/spree/core/controller_helpers/auth_decorator.rb b/lib/spree/core/controller_helpers/auth_decorator.rb
deleted file mode 100644
index 7342450c74..0000000000
--- a/lib/spree/core/controller_helpers/auth_decorator.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-Spree::Core::ControllerHelpers::Auth.class_eval do
- def require_login_then_redirect_to(url)
- redirect_to main_app.root_path(anchor: "login?after_login=#{url}")
- end
-end
diff --git a/lib/spree/core/controller_helpers/common.rb b/lib/spree/core/controller_helpers/common.rb
new file mode 100644
index 0000000000..e88920eaf6
--- /dev/null
+++ b/lib/spree/core/controller_helpers/common.rb
@@ -0,0 +1,93 @@
+# frozen_string_literal: true
+
+module Spree
+ module Core
+ module ControllerHelpers
+ module Common
+ extend ActiveSupport::Concern
+ included do
+ helper_method :title
+ helper_method :title=
+ helper_method :accurate_title
+
+ layout :get_layout
+
+ before_filter :set_user_language
+
+ protected
+
+ # Convenience method for firing instrumentation events with the default payload hash
+ def fire_event(name, extra_payload = {})
+ ActiveSupport::Notifications.instrument(name, default_notification_payload.
+ merge(extra_payload))
+ end
+
+ # Creates the hash that is sent as the payload for all notifications.
+ # Specific notifications will add additional keys as appropriate.
+ # This method can be overriden to provide additional data when
+ # responding to a notification
+ def default_notification_payload
+ { user: spree_current_user, order: current_order }
+ end
+
+ # This can be used in views as well as controllers.
+ # e.g. <% self.title = 'This is a custom title for this view' %>
+ attr_writer :title
+
+ def title
+ title_string = @title.presence || accurate_title
+ if title_string.present?
+ if Spree::Config[:always_put_site_name_in_title]
+ [title_string, default_title].join(' - ')
+ else
+ title_string
+ end
+ else
+ default_title
+ end
+ end
+
+ def default_title
+ Spree::Config[:site_name]
+ end
+
+ # This is a hook for subclasses to provide title
+ def accurate_title
+ Spree::Config[:default_seo_title]
+ end
+
+ def render_404(_exception = nil)
+ respond_to do |type|
+ type.html {
+ render status: :not_found,
+ file: "#{::Rails.root}/public/404",
+ formats: [:html],
+ layout: nil
+ }
+ type.all { render status: :not_found, nothing: true }
+ end
+ end
+
+ private
+
+ def set_user_language
+ locale = session[:locale]
+ locale ||= config_locale if respond_to?(:config_locale, true)
+ locale ||= Rails.application.config.i18n.default_locale
+ unless I18n.available_locales.map(&:to_s).include?(locale)
+ locale ||= I18n.default_locale
+ end
+ I18n.locale = locale
+ end
+
+ # Returns which layout to render.
+ # The layout to render can be set inside Spree configuration with the +:layout+ option.
+ # Default layout is: +app/views/spree/layouts/spree_application+
+ def get_layout
+ layout ||= Spree::Config[:layout]
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/spree/core/controller_helpers/order.rb b/lib/spree/core/controller_helpers/order.rb
new file mode 100644
index 0000000000..e95499bef2
--- /dev/null
+++ b/lib/spree/core/controller_helpers/order.rb
@@ -0,0 +1,95 @@
+# frozen_string_literal: true
+
+require 'open_food_network/scope_variant_to_hub'
+
+module Spree
+ module Core
+ module ControllerHelpers
+ module Order
+ def self.included(base)
+ base.class_eval do
+ helper_method :current_order
+ helper_method :current_currency
+ before_filter :set_current_order
+ end
+ end
+
+ def current_order(create_order_if_necessary = false)
+ order = spree_current_order(create_order_if_necessary)
+
+ if order
+ scoper = OpenFoodNetwork::ScopeVariantToHub.new(order.distributor)
+ order.line_items.each do |li|
+ scoper.scope(li.variant)
+ end
+ end
+
+ order
+ end
+
+ # The current incomplete session order used in cart and checkout
+ def spree_current_order(create_order_if_necessary = false)
+ return @current_order if @current_order
+
+ if session[:order_id]
+ current_order = Spree::Order.includes(:adjustments)
+ .find_by(id: session[:order_id], currency: current_currency)
+ @current_order = current_order unless current_order.try(:completed?)
+ end
+
+ if create_order_if_necessary && (@current_order.nil? || @current_order.completed?)
+ @current_order = Spree::Order.new(currency: current_currency)
+ @current_order.user ||= spree_current_user
+ # See https://github.com/spree/spree/issues/3346 for reasons why this line is here
+ @current_order.created_by ||= spree_current_user
+ @current_order.save!
+
+ # Verify that the user has access to the order (if they are a guest)
+ if spree_current_user.nil?
+ session[:access_token] = @current_order.token
+ end
+ end
+
+ return unless @current_order
+
+ @current_order.last_ip_address = ip_address
+ session[:order_id] = @current_order.id
+ @current_order
+ end
+
+ def associate_user
+ @order ||= current_order
+ if spree_current_user && @order
+ if @order.user.blank? || @order.email.blank?
+ @order.associate_user!(spree_current_user)
+ end
+ end
+
+ session[:guest_token] = nil
+ end
+
+ # Recover incomplete orders from other sessions after logging in.
+ def set_current_order
+ return unless (user = spree_current_user)
+
+ last_incomplete_order = user.last_incomplete_spree_order
+
+ if session[:order_id].nil? && last_incomplete_order
+ session[:order_id] = last_incomplete_order.id
+ end
+
+ # Load current order and create a new one if necessary.
+ current_order(true)
+ end
+
+ def current_currency
+ Spree::Config[:currency]
+ end
+
+ def ip_address
+ request.env['HTTP_X_REAL_IP'] || request.env['REMOTE_ADDR']
+ end
+ end
+ end
+ end
+end
diff --git a/lib/spree/core/controller_helpers/order_decorator.rb b/lib/spree/core/controller_helpers/order_decorator.rb
deleted file mode 100644
index 6da1b42ee6..0000000000
--- a/lib/spree/core/controller_helpers/order_decorator.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-require 'open_food_network/scope_variant_to_hub'
-
-Spree::Core::ControllerHelpers::Order.class_eval do
- def current_order_with_scoped_variants(create_order_if_necessary = false)
- order = current_order_without_scoped_variants(create_order_if_necessary)
-
- if order
- scoper = OpenFoodNetwork::ScopeVariantToHub.new(order.distributor)
- order.line_items.each do |li|
- scoper.scope(li.variant)
- end
- end
-
- order
- end
- alias_method_chain :current_order, :scoped_variants
-
- # Override definition in Spree::Core::ControllerHelpers::Order
- # Do not attempt to merge incomplete and current orders. Instead, destroy the incomplete orders.
- def set_current_order
- if user = try_spree_current_user
- last_incomplete_order = user.last_incomplete_spree_order
-
- if session[:order_id].nil? && last_incomplete_order
- session[:order_id] = last_incomplete_order.id
-
- elsif current_order && last_incomplete_order && current_order != last_incomplete_order
- last_incomplete_order.destroy
- end
- end
- end
-end
diff --git a/lib/spree/core/controller_helpers/respond_with.rb b/lib/spree/core/controller_helpers/respond_with.rb
new file mode 100644
index 0000000000..6b3e7129ca
--- /dev/null
+++ b/lib/spree/core/controller_helpers/respond_with.rb
@@ -0,0 +1,79 @@
+# frozen_string_literal: true
+
+module ActionController
+ class Base
+ def respond_with(*resources, &block)
+ if self.class.mimes_for_respond_to.empty?
+ raise "In order to use respond_with, first you need to declare the formats your " \
+ "controller responds to in the class level"
+ end
+
+ return unless (collector = retrieve_collector_from_mimes(&block))
+
+ options = resources.size == 1 ? {} : resources.extract_options!
+
+ # Fix spree issues #3531 and #2210 (patch provided by leiyangyou)
+ if (defined_response = collector.response) &&
+ !Spree::BaseController.spree_responders[self.class.to_s.to_sym].try(:[],
+ action_name.to_sym)
+ if action = options.delete(:action)
+ render action: action
+ else
+ defined_response.call
+ end
+ else
+ # The action name is needed for processing
+ options[:action_name] = action_name.to_sym
+ # If responder is not specified then pass in Spree::Responder
+ (options.delete(:responder) || Spree::Responder).call(self, resources, options)
+ end
+ end
+ end
+end
+
+module Spree
+ module Core
+ module ControllerHelpers
+ module RespondWith
+ extend ActiveSupport::Concern
+
+ included do
+ cattr_accessor :spree_responders
+ self.spree_responders = {}
+ end
+
+ module ClassMethods
+ def clear_overrides!
+ self.spree_responders = {}
+ end
+
+ def respond_override(options = {})
+ return if options.blank?
+
+ action_name = options.keys.first
+ action_value = options.values.first
+
+ if action_name.blank? || action_value.blank?
+ raise ArgumentError, "invalid values supplied #{options.inspect}"
+ end
+
+ format_name = action_value.keys.first
+ format_value = action_value.values.first
+
+ if format_name.blank? || format_value.blank?
+ raise ArgumentError, "invalid values supplied #{options.inspect}"
+ end
+
+ if format_value.is_a?(Proc)
+ options = {
+ action_name.to_sym => { format_name.to_sym => { success: format_value } }
+ }
+ end
+
+ spree_responders.deep_merge!(name.to_sym => options)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/spree/core/controller_helpers/respond_with_decorator.rb b/lib/spree/core/controller_helpers/respond_with_decorator.rb
deleted file mode 100644
index 522247ea01..0000000000
--- a/lib/spree/core/controller_helpers/respond_with_decorator.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-module ActionController
- class Base
- def respond_with(*resources, &block)
- if self.class.mimes_for_respond_to.empty?
- raise "In order to use respond_with, first you need to declare the formats your " \
- "controller responds to in the class level"
- end
-
- if collector = retrieve_collector_from_mimes(&block)
- options = resources.size == 1 ? {} : resources.extract_options!
-
- # Fix spree issues #3531 and #2210 (patch provided by leiyangyou)
- if (defined_response = collector.response) && !Spree::BaseController.spree_responders[self.class.to_s.to_sym].try(:[], action_name.to_sym)
- if action = options.delete(:action)
- render action: action
- else
- defined_response.call
- end
- else
- # The action name is needed for processing
- options[:action_name] = action_name.to_sym
- # If responder is not specified then pass in Spree::Responder
- (options.delete(:responder) || Spree::Responder).call(self, resources, options)
- end
- end
- end
- end
-end
diff --git a/lib/spree/core/controller_helpers/ssl.rb b/lib/spree/core/controller_helpers/ssl.rb
new file mode 100644
index 0000000000..6c923e4977
--- /dev/null
+++ b/lib/spree/core/controller_helpers/ssl.rb
@@ -0,0 +1,61 @@
+# frozen_string_literal: true
+
+module Spree
+ module Core
+ module ControllerHelpers
+ module SSL
+ extend ActiveSupport::Concern
+
+ included do
+ before_filter :force_non_ssl_redirect, if: proc { Spree::Config[:redirect_https_to_http] }
+
+ def self.ssl_allowed(*actions)
+ class_attribute :ssl_allowed_actions
+ self.ssl_allowed_actions = actions
+ end
+
+ def self.ssl_required(*actions)
+ class_attribute :ssl_required_actions
+ self.ssl_required_actions = actions
+ return unless ssl_supported?
+
+ if ssl_required_actions.empty? || Rails.application.config.force_ssl
+ force_ssl
+ else
+ force_ssl only: ssl_required_actions
+ end
+ end
+
+ def self.ssl_supported?
+ return Spree::Config[:allow_ssl_in_production] if Rails.env.production?
+ return Spree::Config[:allow_ssl_in_staging] if Rails.env.staging?
+ return unless Rails.env.development? || Rails.env.test?
+
+ Spree::Config[:allow_ssl_in_development_and_test]
+ end
+
+ private
+
+ # Redirect the existing request to use the HTTP protocol.
+ #
+ # ==== Parameters
+ # * host - Redirect to a different host name
+ def force_non_ssl_redirect(host = nil)
+ return true if defined?(ssl_allowed_actions) &&
+ ssl_allowed_actions.include?(action_name.to_sym)
+
+ return unless request.ssl? &&
+ (!defined?(ssl_required_actions) ||
+ !ssl_required_actions.include?(action_name.to_sym))
+
+ redirect_options = { protocol: 'http://', status: :moved_permanently }
+ redirect_options.merge!(host: host) if host
+ redirect_options.merge!(params: request.query_parameters)
+ flash.keep if respond_to?(:flash)
+ redirect_to redirect_options
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/spree/core/delegate_belongs_to.rb b/lib/spree/core/delegate_belongs_to.rb
new file mode 100644
index 0000000000..bfbf0b1fc0
--- /dev/null
+++ b/lib/spree/core/delegate_belongs_to.rb
@@ -0,0 +1,94 @@
+# frozen_string_literal: true
+
+##
+# Creates methods on object which delegate to an association proxy.
+# see delegate_belongs_to for two uses
+#
+# Todo - integrate with ActiveRecord::Dirty to make sure changes to delegate object are noticed
+# Should do
+# class User < ActiveRecord::Base; delegate_belongs_to :contact, :firstname; end
+# class Contact < ActiveRecord::Base; end
+# u = User.first
+# u.changed? # => false
+# u.firstname = 'Bobby'
+# u.changed? # => true
+#
+# Right now the second call to changed? would return false
+#
+# Todo - add has_one support. fairly straightforward addition
+##
+module DelegateBelongsTo
+ extend ActiveSupport::Concern
+
+ module ClassMethods
+ @@default_rejected_delegate_columns = ['created_at', 'created_on', 'updated_at',
+ 'updated_on', 'lock_version', 'type', 'id',
+ 'position', 'parent_id', 'lft', 'rgt']
+ mattr_accessor :default_rejected_delegate_columns
+
+ ##
+ # Creates methods for accessing and setting attributes on an association. Uses same
+ # default list of attributes as delegates_to_association.
+ # delegate_belongs_to :contact
+ # delegate_belongs_to :contact, [:defaults] ## same as above, and useless
+ # delegate_belongs_to :contact, [:defaults, :address, :fullname], :class_name => 'VCard'
+ ##
+ def delegate_belongs_to(association, *attrs)
+ opts = attrs.extract_options!
+ initialize_association :belongs_to, association, opts
+ attrs = get_association_column_names(association) if attrs.empty?
+ attrs.concat get_association_column_names(association) if attrs.delete :defaults
+ attrs.each do |attr|
+ class_def attr do |*args|
+ if args.empty?
+ __send__(:delegator_for, association).__send__(attr)
+ else
+ __send__(:delegator_for, association).__send__(attr, *args)
+ end
+ end
+ class_def "#{attr}=" do |val|
+ __send__(:delegator_for, association).__send__("#{attr}=", val)
+ end
+ end
+ end
+
+ protected
+
+ def get_association_column_names(association, without_default_rejected_delegate_columns = true)
+ association_klass = reflect_on_association(association).klass
+ methods = association_klass.column_names
+ if without_default_rejected_delegate_columns
+ methods.reject!{ |x| default_rejected_delegate_columns.include?(x.to_s) }
+ end
+ methods
+ rescue
+ []
+ end
+
+ ##
+ # initialize_association :belongs_to, :contact
+ def initialize_association(type, association, opts = {})
+ unless [:belongs_to].include?(type.to_s.to_sym)
+ raise 'Illegal or unimplemented association type.'
+ end
+
+ __send__(type, association, opts) if reflect_on_association(association).nil?
+ end
+
+ private
+
+ def class_def(name, method = nil, &blk)
+ class_eval { method.nil? ? define_method(name, &blk) : define_method(name, method) }
+ end
+ end
+
+ def delegator_for(association)
+ if __send__(association).nil?
+ __send__("#{association}=", self.class.reflect_on_association(association).klass.new)
+ end
+ __send__(association)
+ end
+ protected :delegator_for
+end
+
+ActiveRecord::Base.include(DelegateBelongsTo)
diff --git a/lib/spree/core/environment/calculators.rb b/lib/spree/core/environment/calculators.rb
new file mode 100644
index 0000000000..a5f60555f7
--- /dev/null
+++ b/lib/spree/core/environment/calculators.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Spree
+ module Core
+ class Environment
+ class Calculators
+ include EnvironmentExtension
+
+ attr_accessor :shipping_methods, :tax_rates
+ end
+ end
+ end
+end
diff --git a/lib/spree/core/environment_extension.rb b/lib/spree/core/environment_extension.rb
new file mode 100644
index 0000000000..7b05908752
--- /dev/null
+++ b/lib/spree/core/environment_extension.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+module Spree
+ module Core
+ module EnvironmentExtension
+ extend ActiveSupport::Concern
+
+ def add_class(name)
+ instance_variable_set "@#{name}", Set.new
+
+ create_method( "#{name}=".to_sym ) { |val|
+ instance_variable_set( "@" + name, val)
+ }
+
+ create_method(name.to_sym) do
+ instance_variable_get( "@" + name )
+ end
+ end
+
+ private
+
+ def create_method(name, &block)
+ self.class.__send__(:define_method, name, &block)
+ end
+ end
+ end
+end
diff --git a/lib/spree/core/gateway_error.rb b/lib/spree/core/gateway_error.rb
new file mode 100644
index 0000000000..f90310bc54
--- /dev/null
+++ b/lib/spree/core/gateway_error.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+module Spree
+ module Core
+ class GatewayError < RuntimeError; end
+ end
+end
diff --git a/lib/spree/core/mail_interceptor.rb b/lib/spree/core/mail_interceptor.rb
new file mode 100644
index 0000000000..87ae2e33ab
--- /dev/null
+++ b/lib/spree/core/mail_interceptor.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+# Allows us to intercept any outbound mail message and make last minute changes
+# (such as specifying a "from" address or sending to a test email account)
+#
+# See http://railscasts.com/episodes/206-action-mailer-in-rails-3 for more details.
+module Spree
+ module Core
+ class MailInterceptor
+ def self.delivering_email(message)
+ return unless MailSettings.override?
+
+ if Config[:intercept_email].present?
+ message.subject = "#{message.to} #{message.subject}"
+ message.to = Config[:intercept_email]
+ end
+
+ return if Config[:mail_bcc].blank?
+
+ message.bcc ||= Config[:mail_bcc]
+ end
+ end
+ end
+end
diff --git a/lib/spree/core/mail_settings.rb b/lib/spree/core/mail_settings.rb
new file mode 100644
index 0000000000..80664d1c64
--- /dev/null
+++ b/lib/spree/core/mail_settings.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+module Spree
+ module Core
+ class MailSettings
+ MAIL_AUTH = ['None', 'plain', 'login', 'cram_md5'].freeze
+ SECURE_CONNECTION_TYPES = ['None', 'SSL', 'TLS'].freeze
+
+ # Override the Rails application mail settings based on preferences
+ # This makes it possible to configure the mail settings through an admin
+ # interface instead of requiring changes to the Rails envrionment file
+ def self.init
+ new.override! if override?
+ end
+
+ def self.override?
+ Config.override_actionmailer_config
+ end
+
+ def override!
+ if Config.enable_mail_delivery
+ ActionMailer::Base.default_url_options[:host] ||= Config.site_url
+ ActionMailer::Base.smtp_settings = mail_server_settings
+ ActionMailer::Base.perform_deliveries = true
+ else
+ ActionMailer::Base.perform_deliveries = false
+ end
+ end
+
+ private
+
+ def mail_server_settings
+ settings = if need_authentication?
+ basic_settings.merge(user_credentials)
+ else
+ basic_settings
+ end
+
+ settings.merge(enable_starttls_auto: secure_connection?)
+ end
+
+ def user_credentials
+ { user_name: Config.smtp_username,
+ password: Config.smtp_password }
+ end
+
+ def basic_settings
+ { address: Config.mail_host,
+ domain: Config.mail_domain,
+ port: Config.mail_port,
+ authentication: Config.mail_auth_type }
+ end
+
+ def need_authentication?
+ Config.mail_auth_type != 'None'
+ end
+
+ def secure_connection?
+ Config.secure_connection_type == 'TLS'
+ end
+ end
+ end
+end
diff --git a/lib/spree/core/permalinks.rb b/lib/spree/core/permalinks.rb
new file mode 100644
index 0000000000..b9d8a83274
--- /dev/null
+++ b/lib/spree/core/permalinks.rb
@@ -0,0 +1,75 @@
+# frozen_string_literal: true
+
+require 'stringex'
+
+module Spree
+ module Core
+ module Permalinks
+ extend ActiveSupport::Concern
+
+ included do
+ class_attribute :permalink_options
+ end
+
+ module ClassMethods
+ def make_permalink(options = {})
+ options[:field] ||= :permalink
+ self.permalink_options = options
+
+ return unless connected? &&
+ table_exists? &&
+ column_names.include?(permalink_options[:field].to_s)
+
+ before_validation(on: :create) { save_permalink }
+ end
+
+ def find_by_param(value, *args)
+ __send__("find_by_#{permalink_field}", value, *args)
+ end
+
+ def find_by_param!(value, *args)
+ __send__("find_by_#{permalink_field}!", value, *args)
+ end
+
+ def permalink_field
+ permalink_options[:field]
+ end
+
+ def permalink_prefix
+ permalink_options[:prefix] || ""
+ end
+
+ def permalink_order
+ order = permalink_options[:order]
+ "#{order} ASC," if order
+ end
+ end
+
+ def generate_permalink
+ "#{self.class.permalink_prefix}#{Array.new(9) { rand(9) }.join}"
+ end
+
+ def save_permalink(permalink_value = to_param)
+ with_lock do
+ permalink_value ||= generate_permalink
+
+ field = self.class.permalink_field
+
+ # Do other links exist with this permalink?
+ other = self.class.
+ where("#{self.class.table_name}.#{field} LIKE ?", "#{permalink_value}%")
+ if other.any?
+ # Find the existing permalink with the highest number, and increment that number.
+ # (If none of the existing permalinks have a number, this will evaluate to 1.)
+ number = other.map { |o| o.__send__(field)[/-(\d+)$/, 1].to_i }.max + 1
+ permalink_value += "-#{number}"
+ end
+ write_attribute(field, permalink_value)
+ end
+ end
+ end
+ end
+end
+
+ActiveRecord::Base.include(Spree::Core::Permalinks)
+ActiveRecord::Relation.include(Spree::Core::Permalinks)
diff --git a/lib/spree/core/s3_support.rb b/lib/spree/core/s3_support.rb
new file mode 100644
index 0000000000..92229c15f5
--- /dev/null
+++ b/lib/spree/core/s3_support.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+module Spree
+ module Core
+ # This module exists to reduce duplication in S3 settings between
+ # the Image and Taxon models in Spree
+ module S3Support
+ extend ActiveSupport::Concern
+
+ included do
+ def self.supports_s3(field)
+ # Load user defined paperclip settings
+ config = Spree::Config
+ return unless config[:use_s3]
+
+ s3_creds = { access_key_id: config[:s3_access_key],
+ secret_access_key: config[:s3_secret],
+ bucket: config[:s3_bucket] }
+ attachment_definitions[field][:storage] = :s3
+ attachment_definitions[field][:s3_credentials] = s3_creds
+ attachment_definitions[field][:s3_headers] = ActiveSupport::JSON.
+ decode(config[:s3_headers])
+ attachment_definitions[field][:bucket] = config[:s3_bucket]
+ if config[:s3_protocol].present?
+ attachment_definitions[field][:s3_protocol] = config[:s3_protocol].downcase
+ end
+
+ return if config[:s3_host_alias].blank?
+
+ attachment_definitions[field][:s3_host_alias] = config[:s3_host_alias]
+ end
+ end
+ end
+ end
+end
diff --git a/lib/spree/core/token_resource.rb b/lib/spree/core/token_resource.rb
new file mode 100644
index 0000000000..8d4173d11b
--- /dev/null
+++ b/lib/spree/core/token_resource.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+module Spree
+ module Core
+ module TokenResource
+ module ClassMethods
+ def token_resource
+ has_one :tokenized_permission, as: :permissable
+ delegate :token, to: :tokenized_permission, allow_nil: true
+ after_create :create_token
+ end
+ end
+
+ def create_token
+ permission = build_tokenized_permission
+ permission.token = token = ::SecureRandom.hex(8)
+ permission.save!
+ token
+ end
+
+ def self.included(receiver)
+ receiver.extend ClassMethods
+ end
+ end
+ end
+end
+
+ActiveRecord::Base.class_eval { include Spree::Core::TokenResource }
diff --git a/lib/spree/i18n.rb b/lib/spree/i18n.rb
new file mode 100644
index 0000000000..7780bc3ad7
--- /dev/null
+++ b/lib/spree/i18n.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+require 'i18n'
+require 'active_support/core_ext/array/extract_options'
+require 'spree/i18n/base'
+
+module Spree
+ extend ActionView::Helpers::TranslationHelper
+
+ class << self
+ # Add spree namespace and delegate to Rails TranslationHelper for some nice
+ # extra functionality. e.g return reasonable strings for missing translations
+ def translate(*args)
+ @virtual_path = virtual_path
+
+ options = args.extract_options!
+ options[:scope] = [*options[:scope]].unshift(:spree)
+ args << options
+ super(*args)
+ end
+
+ alias_method :t, :translate
+
+ def context
+ Spree::ViewContext.context
+ end
+
+ def virtual_path
+ return unless context
+
+ path = context.instance_variable_get("@virtual_path")
+
+ return unless path
+
+ path.gsub(/spree/, '')
+ end
+ end
+end
diff --git a/lib/spree/i18n/base.rb b/lib/spree/i18n/base.rb
new file mode 100644
index 0000000000..88c2d3106d
--- /dev/null
+++ b/lib/spree/i18n/base.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Spree
+ module ViewContext
+ def self.context=(context)
+ @context = context
+ end
+
+ def self.context
+ @context
+ end
+
+ def view_context
+ super.tap do |context|
+ Spree::ViewContext.context = context
+ end
+ end
+ end
+end
diff --git a/lib/spree/i18n/initializer.rb b/lib/spree/i18n/initializer.rb
new file mode 100644
index 0000000000..64b649f708
--- /dev/null
+++ b/lib/spree/i18n/initializer.rb
@@ -0,0 +1,3 @@
+# frozen_string_literal: true
+
+Spree::BaseController.include(Spree::ViewContext)
diff --git a/lib/spree/money.rb b/lib/spree/money.rb
new file mode 100644
index 0000000000..413c2f0e8c
--- /dev/null
+++ b/lib/spree/money.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: false
+
+require 'money'
+
+module Spree
+ class Money
+ attr_reader :money
+
+ delegate :cents, to: :money
+
+ def initialize(amount, options = {})
+ @money = ::Money.parse([amount, (options[:currency] || Spree::Config[:currency])].join)
+ @options = {}
+ @options[:with_currency] = Spree::Config[:display_currency]
+ @options[:symbol_position] = Spree::Config[:currency_symbol_position].to_sym
+ @options[:no_cents] = Spree::Config[:hide_cents]
+ @options[:decimal_mark] = Spree::Config[:currency_decimal_mark]
+ @options[:thousands_separator] = Spree::Config[:currency_thousands_separator]
+ @options.merge!(options)
+ # Must be a symbol because the Money gem doesn't do the conversion
+ @options[:symbol_position] = @options[:symbol_position].to_sym
+ end
+
+ def to_s
+ @money.format(@options)
+ end
+
+ def to_html(options = { html: true })
+ output = @money.format(@options.merge(options))
+ if options[:html]
+ # 1) prevent blank, breaking spaces
+ # 2) prevent escaping of HTML character entities
+ output = output.gsub(" ", " ").html_safe
+ end
+ output
+ end
+
+ def ==(other)
+ @money == other.money
+ end
+ end
+end
diff --git a/lib/spree/product_duplicator.rb b/lib/spree/product_duplicator.rb
new file mode 100644
index 0000000000..8866f85fa5
--- /dev/null
+++ b/lib/spree/product_duplicator.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+module Spree
+ class ProductDuplicator
+ attr_accessor :product
+
+ def initialize(product)
+ @product = product
+ end
+
+ def duplicate
+ new_product = duplicate_product
+
+ # don't dup the actual variants, just the characterising types
+ new_product.option_types = product.option_types if product.has_variants?
+
+ # allow site to do some customization
+ new_product.__send__(:duplicate_extra, product) if new_product.respond_to?(:duplicate_extra)
+ new_product.save!
+ new_product
+ end
+
+ protected
+
+ def duplicate_product
+ product.dup.tap do |new_product|
+ new_product.name = "COPY OF #{product.name}"
+ new_product.taxons = product.taxons
+ new_product.created_at = nil
+ new_product.deleted_at = nil
+ new_product.updated_at = nil
+ new_product.product_properties = reset_properties
+ new_product.master = duplicate_master
+ end
+ end
+
+ def duplicate_master
+ master = product.master
+ master.dup.tap do |new_master|
+ new_master.sku = "COPY OF #{master.sku}"
+ new_master.deleted_at = nil
+ new_master.images = master.images.map { |image| duplicate_image image }
+ new_master.price = master.price
+ new_master.currency = master.currency
+ end
+ end
+
+ def duplicate_image(image)
+ new_image = image.dup
+ new_image.assign_attributes(attachment: image.attachment.clone)
+ new_image
+ end
+
+ def reset_properties
+ product.product_properties.map do |prop|
+ prop.dup.tap do |new_prop|
+ new_prop.created_at = nil
+ new_prop.updated_at = nil
+ end
+ end
+ end
+ end
+end
diff --git a/lib/spree/responder.rb b/lib/spree/responder.rb
new file mode 100644
index 0000000000..3c0e60aa5b
--- /dev/null
+++ b/lib/spree/responder.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+module Spree
+ class Responder < ::ActionController::Responder #:nodoc:
+ attr_accessor :on_success, :on_failure
+
+ def initialize(controller, resources, options = {})
+ super
+
+ class_name = controller.class.name.to_sym
+ action_name = options.delete(:action_name)
+
+ result = Spree::BaseController.spree_responders[class_name].
+ try(:[], action_name).
+ try(:[], self.format.to_sym)
+ return unless result
+
+ self.on_success = handler(controller, result, :success)
+ self.on_failure = handler(controller, result, :failure)
+ end
+
+ def to_html
+ if !(on_success || on_failure)
+ super
+ return
+ end
+
+ has_errors? ? controller.instance_exec(&on_failure) : controller.instance_exec(&on_success)
+ end
+
+ def to_format
+ if !(on_success || on_failure)
+ super
+ return
+ end
+
+ has_errors? ? controller.instance_exec(&on_failure) : controller.instance_exec(&on_success)
+ end
+
+ private
+
+ def handler(controller, result, status)
+ return result if result.respond_to? :call
+
+ case result
+ when Hash
+ if result[status].is_a? Symbol
+ controller.method(result[status])
+ else
+ result[status]
+ end
+ when Symbol
+ controller.method(result)
+ end
+ end
+ end
+end
diff --git a/lib/tasks/sample_data/order_factory.rb b/lib/tasks/sample_data/order_factory.rb
index 29d4cf03c6..9614f685a0 100644
--- a/lib/tasks/sample_data/order_factory.rb
+++ b/lib/tasks/sample_data/order_factory.rb
@@ -45,7 +45,7 @@ class OrderFactory
def create_complete_order
order = create_cart_order
- AdvanceOrderService.new(order).call
+ OrderWorkflow.new(order).complete
order
end
diff --git a/spec/controllers/admin/bulk_line_items_controller_spec.rb b/spec/controllers/admin/bulk_line_items_controller_spec.rb
index 941b44eb0c..da05149079 100644
--- a/spec/controllers/admin/bulk_line_items_controller_spec.rb
+++ b/spec/controllers/admin/bulk_line_items_controller_spec.rb
@@ -1,8 +1,6 @@
require 'spec_helper'
describe Admin::BulkLineItemsController, type: :controller do
- include AuthenticationWorkflow
-
describe '#index' do
render_views
@@ -17,11 +15,11 @@ describe Admin::BulkLineItemsController, type: :controller do
let!(:line_item4) { FactoryBot.create(:line_item_with_shipment, order: order3) }
context "as a normal user" do
- before { allow(controller).to receive_messages spree_current_user: create_enterprise_user }
+ before { allow(controller).to receive_messages spree_current_user: create(:user) }
it "should deny me access to the index action" do
spree_get :index, format: :json
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
@@ -94,7 +92,7 @@ describe Admin::BulkLineItemsController, type: :controller do
end
it "does not display line items for which my enterprise is a supplier" do
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
@@ -172,7 +170,7 @@ describe Admin::BulkLineItemsController, type: :controller do
end
it "does not allow access" do
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
diff --git a/spec/controllers/admin/column_preferences_controller_spec.rb b/spec/controllers/admin/column_preferences_controller_spec.rb
index acc3c194a5..53f2d12fda 100644
--- a/spec/controllers/admin/column_preferences_controller_spec.rb
+++ b/spec/controllers/admin/column_preferences_controller_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Admin::ColumnPreferencesController, type: :controller do
- include AuthenticationWorkflow
+ include AuthenticationHelper
describe "bulk_update" do
let!(:user1) { create(:user) }
diff --git a/spec/controllers/admin/customers_controller_spec.rb b/spec/controllers/admin/customers_controller_spec.rb
index b1503d89f7..b439cc7c9c 100644
--- a/spec/controllers/admin/customers_controller_spec.rb
+++ b/spec/controllers/admin/customers_controller_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Admin::CustomersController, type: :controller do
- include AuthenticationWorkflow
+ include AuthenticationHelper
describe "index" do
let(:enterprise) { create(:distributor_enterprise) }
@@ -90,7 +90,7 @@ describe Admin::CustomersController, type: :controller do
it "prevents me from updating the customer" do
spree_put :update, format: :json, id: customer.id, customer: { email: 'new.email@gmail.com' }
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
expect(assigns(:customer)).to eq nil
expect(customer.email).to_not eq 'new.email@gmail.com'
end
@@ -166,7 +166,7 @@ describe Admin::CustomersController, type: :controller do
it "prevents me from updating the customer" do
spree_get :show, format: :json, id: customer.id
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
end
diff --git a/spec/controllers/admin/enterprises_controller_spec.rb b/spec/controllers/admin/enterprises_controller_spec.rb
index 78678e03e2..a51af80b36 100644
--- a/spec/controllers/admin/enterprises_controller_spec.rb
+++ b/spec/controllers/admin/enterprises_controller_spec.rb
@@ -2,8 +2,6 @@ require 'spec_helper'
require 'open_food_network/order_cycle_permissions'
describe Admin::EnterprisesController, type: :controller do
- include AuthenticationWorkflow
-
let(:user) { create(:user) }
let(:admin_user) { create(:admin_user) }
let(:distributor_manager) { create(:user, enterprise_limit: 10, enterprises: [distributor]) }
@@ -138,7 +136,7 @@ describe Admin::EnterprisesController, type: :controller do
let!(:property) { create(:property, name: "A nice name") }
before do
- login_as_enterprise_user [producer]
+ controller_login_as_enterprise_user [producer]
end
context "when a submitted property does not already exist" do
@@ -179,7 +177,7 @@ describe Admin::EnterprisesController, type: :controller do
let!(:tag_rule) { create(:tag_rule, enterprise: enterprise) }
before do
- login_as_enterprise_user [enterprise]
+ controller_login_as_enterprise_user [enterprise]
end
context "discount order rules" do
@@ -294,7 +292,7 @@ describe Admin::EnterprisesController, type: :controller do
it "does not allow access" do
spree_post :register, id: enterprise.id, sells: 'none'
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
@@ -306,7 +304,7 @@ describe Admin::EnterprisesController, type: :controller do
it "does not allow access" do
spree_post :register, id: enterprise.id, sells: 'none'
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
@@ -366,18 +364,8 @@ describe Admin::EnterprisesController, type: :controller do
end
describe "bulk updating enterprises" do
- let!(:original_owner) do
- user = create_enterprise_user
- user.enterprise_limit = 2
- user.save!
- user
- end
- let!(:new_owner) do
- user = create_enterprise_user
- user.enterprise_limit = 2
- user.save!
- user
- end
+ let!(:original_owner) { create(:user) }
+ let!(:new_owner) { create(:user) }
let!(:profile_enterprise1) { create(:enterprise, sells: 'none', owner: original_owner ) }
let!(:profile_enterprise2) { create(:enterprise, sells: 'none', owner: original_owner ) }
@@ -441,7 +429,7 @@ describe Admin::EnterprisesController, type: :controller do
end
describe "for_order_cycle" do
- let!(:user) { create_enterprise_user }
+ let!(:user) { create(:user) }
let!(:enterprise) { create(:enterprise, sells: 'any', owner: user) }
let(:permission_mock) { double(:permission) }
@@ -487,7 +475,7 @@ describe Admin::EnterprisesController, type: :controller do
end
describe "visible" do
- let!(:user) { create(:user, enterprise_limit: 10) }
+ let!(:user) { create(:user) }
let!(:visible_enterprise) { create(:enterprise, sells: 'any', owner: user) }
let!(:not_visible_enterprise) { create(:enterprise, sells: 'any') }
@@ -508,10 +496,10 @@ describe Admin::EnterprisesController, type: :controller do
describe "index" do
context "as super admin" do
let(:super_admin) { create(:admin_user) }
- let!(:user) { create_enterprise_user(enterprise_limit: 10) }
+ let!(:user) { create(:user) }
let!(:enterprise1) { create(:enterprise, sells: 'any', owner: user) }
let!(:enterprise2) { create(:enterprise, sells: 'own', owner: user) }
- let!(:enterprise3) { create(:enterprise, sells: 'any', owner: create_enterprise_user ) }
+ let!(:enterprise3) { create(:enterprise, sells: 'any', owner: create(:user) ) }
before do
allow(controller).to receive_messages spree_current_user: super_admin
@@ -533,10 +521,10 @@ describe Admin::EnterprisesController, type: :controller do
end
context "as an enterprise user" do
- let!(:user) { create_enterprise_user(enterprise_limit: 10) }
+ let!(:user) { create(:user) }
let!(:enterprise1) { create(:enterprise, sells: 'any', owner: user) }
let!(:enterprise2) { create(:enterprise, sells: 'own', owner: user) }
- let!(:enterprise3) { create(:enterprise, sells: 'any', owner: create_enterprise_user ) }
+ let!(:enterprise3) { create(:enterprise, sells: 'any', owner: create(:user) ) }
before do
allow(controller).to receive_messages spree_current_user: user
diff --git a/spec/controllers/admin/inventory_items_controller_spec.rb b/spec/controllers/admin/inventory_items_controller_spec.rb
index 741f329663..6d3f30f41f 100644
--- a/spec/controllers/admin/inventory_items_controller_spec.rb
+++ b/spec/controllers/admin/inventory_items_controller_spec.rb
@@ -1,8 +1,6 @@
require 'spec_helper'
describe Admin::InventoryItemsController, type: :controller do
- # include AuthenticationWorkflow
-
describe "create" do
context "json" do
let(:format) { :json }
@@ -21,7 +19,7 @@ describe Admin::InventoryItemsController, type: :controller do
it "redirects to unauthorized" do
spree_post :create, params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
@@ -33,7 +31,7 @@ describe Admin::InventoryItemsController, type: :controller do
context "but the producer has not granted VO permission" do
it "redirects to unauthorized" do
spree_post :create, params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
@@ -84,7 +82,7 @@ describe Admin::InventoryItemsController, type: :controller do
it "redirects to unauthorized" do
spree_put :update, params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
@@ -96,7 +94,7 @@ describe Admin::InventoryItemsController, type: :controller do
context "but the producer has not granted VO permission" do
it "redirects to unauthorized" do
spree_put :update, params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
diff --git a/spec/controllers/admin/order_cycles_controller_spec.rb b/spec/controllers/admin/order_cycles_controller_spec.rb
index 2ba98c9f8e..6988fa4787 100644
--- a/spec/controllers/admin/order_cycles_controller_spec.rb
+++ b/spec/controllers/admin/order_cycles_controller_spec.rb
@@ -2,9 +2,7 @@ require 'spec_helper'
module Admin
describe OrderCyclesController, type: :controller do
- include AuthenticationWorkflow
-
- let!(:distributor_owner) { create_enterprise_user enterprise_limit: 2 }
+ let!(:distributor_owner) { create(:user) }
before do
allow(controller).to receive_messages spree_current_user: distributor_owner
@@ -104,7 +102,7 @@ module Admin
let(:params) { { format: :json, order_cycle: {} } }
before do
- login_as_enterprise_user([shop])
+ controller_login_as_enterprise_user([shop])
allow(OrderCycleForm).to receive(:new) { form_mock }
end
@@ -150,7 +148,7 @@ module Admin
end
context "as a manager of the coordinator" do
- before { login_as_enterprise_user([coordinator]) }
+ before { controller_login_as_enterprise_user([coordinator]) }
let(:params) { { format: :json, id: order_cycle.id, order_cycle: {} } }
context "when updating succeeds" do
@@ -178,10 +176,22 @@ module Admin
it "returns an error message" do
spree_put :update, params
+
json_response = JSON.parse(response.body)
expect(json_response['errors']).to be
end
end
+
+ it "can update preference product_selection_from_coordinator_inventory_only" do
+ expect(OrderCycleForm).to receive(:new).
+ with(order_cycle,
+ { "preferred_product_selection_from_coordinator_inventory_only" => true },
+ anything) { form_mock }
+ allow(form_mock).to receive(:save) { true }
+
+ spree_put :update, params.
+ merge(order_cycle: { preferred_product_selection_from_coordinator_inventory_only: true })
+ end
end
end
@@ -288,7 +298,7 @@ module Admin
end
describe "notifying producers" do
- let(:user) { create_enterprise_user }
+ let(:user) { create(:user) }
let(:admin_user) do
user = create(:user)
user.spree_roles << Spree::Role.find_or_create_by!(name: 'admin')
diff --git a/spec/controllers/admin/proxy_orders_controller_spec.rb b/spec/controllers/admin/proxy_orders_controller_spec.rb
index 1d612e2c57..ccd4a9bb02 100644
--- a/spec/controllers/admin/proxy_orders_controller_spec.rb
+++ b/spec/controllers/admin/proxy_orders_controller_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Admin::ProxyOrdersController, type: :controller do
- include AuthenticationWorkflow
+ include AuthenticationHelper
describe 'cancel' do
let!(:user) { create(:user, enterprise_limit: 10) }
@@ -20,7 +20,7 @@ describe Admin::ProxyOrdersController, type: :controller do
context 'as a regular user' do
it 'redirects to unauthorized' do
spree_put :cancel, params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
@@ -31,7 +31,7 @@ describe Admin::ProxyOrdersController, type: :controller do
it 'redirects to unauthorized' do
spree_put :cancel, params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
@@ -77,7 +77,7 @@ describe Admin::ProxyOrdersController, type: :controller do
before do
# Processing order to completion
allow(Spree::OrderMailer).to receive(:cancel_email) { double(:email, deliver: true) }
- AdvanceOrderService.new(order).call!
+ OrderWorkflow.new(order).complete!
proxy_order.reload
proxy_order.cancel
allow(controller).to receive(:spree_current_user) { user }
@@ -89,7 +89,7 @@ describe Admin::ProxyOrdersController, type: :controller do
context 'as a regular user' do
it 'redirects to unauthorized' do
spree_put :resume, params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
@@ -100,7 +100,7 @@ describe Admin::ProxyOrdersController, type: :controller do
it 'redirects to unauthorized' do
spree_put :resume, params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
diff --git a/spec/controllers/admin/schedules_controller_spec.rb b/spec/controllers/admin/schedules_controller_spec.rb
index 99b73f4e03..0648574642 100644
--- a/spec/controllers/admin/schedules_controller_spec.rb
+++ b/spec/controllers/admin/schedules_controller_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Admin::SchedulesController, type: :controller do
- include AuthenticationWorkflow
+ include AuthenticationHelper
describe "index" do
let!(:coordinated_order_cycle) { create(:simple_order_cycle) }
@@ -106,7 +106,7 @@ describe Admin::SchedulesController, type: :controller do
it "prevents me from updating the schedule" do
spree_put :update, format: :json, id: coordinated_schedule.id, schedule: { name: "my awesome schedule" }
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
expect(assigns(:schedule)).to eq nil
expect(coordinated_schedule.name).to_not eq "my awesome schedule"
end
diff --git a/spec/controllers/admin/stripe_accounts_controller_spec.rb b/spec/controllers/admin/stripe_accounts_controller_spec.rb
index 9a6854ae85..c1b0890316 100644
--- a/spec/controllers/admin/stripe_accounts_controller_spec.rb
+++ b/spec/controllers/admin/stripe_accounts_controller_spec.rb
@@ -46,7 +46,7 @@ describe Admin::StripeAccountsController, type: :controller do
it "redirects to unauthorized" do
spree_delete :destroy, params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
@@ -93,7 +93,7 @@ describe Admin::StripeAccountsController, type: :controller do
it "redirects to unauthorized" do
spree_get :status, params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
diff --git a/spec/controllers/admin/stripe_connect_settings_controller_spec.rb b/spec/controllers/admin/stripe_connect_settings_controller_spec.rb
index 11cebea66e..73331a151a 100644
--- a/spec/controllers/admin/stripe_connect_settings_controller_spec.rb
+++ b/spec/controllers/admin/stripe_connect_settings_controller_spec.rb
@@ -14,7 +14,7 @@ describe Admin::StripeConnectSettingsController, type: :controller do
it "does not allow access" do
spree_get :edit
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
@@ -76,7 +76,7 @@ describe Admin::StripeConnectSettingsController, type: :controller do
it "does not allow access" do
spree_get :update, params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
diff --git a/spec/controllers/admin/subscription_line_items_controller_spec.rb b/spec/controllers/admin/subscription_line_items_controller_spec.rb
index d60c581ab5..6df2a71f53 100644
--- a/spec/controllers/admin/subscription_line_items_controller_spec.rb
+++ b/spec/controllers/admin/subscription_line_items_controller_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Admin::SubscriptionLineItemsController, type: :controller do
- include AuthenticationWorkflow
+ include AuthenticationHelper
describe "build" do
let(:user) { create(:user) }
diff --git a/spec/controllers/admin/subscriptions_controller_spec.rb b/spec/controllers/admin/subscriptions_controller_spec.rb
index c7f0e207a4..1aeb87ddef 100644
--- a/spec/controllers/admin/subscriptions_controller_spec.rb
+++ b/spec/controllers/admin/subscriptions_controller_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Admin::SubscriptionsController, type: :controller do
- include AuthenticationWorkflow
+ include AuthenticationHelper
include OpenFoodNetwork::EmailHelper
describe 'index' do
@@ -18,7 +18,7 @@ describe Admin::SubscriptionsController, type: :controller do
context 'as a regular user' do
it 'redirects to unauthorized' do
spree_get :index, params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
@@ -55,7 +55,7 @@ describe Admin::SubscriptionsController, type: :controller do
context 'as a regular user' do
it 'redirects to unauthorized' do
spree_get :index, params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
@@ -120,7 +120,7 @@ describe Admin::SubscriptionsController, type: :controller do
it 'redirects to unauthorized' do
spree_post :create, params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
@@ -272,7 +272,7 @@ describe Admin::SubscriptionsController, type: :controller do
it 'redirects to unauthorized' do
spree_post :update, params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
@@ -390,7 +390,7 @@ describe Admin::SubscriptionsController, type: :controller do
context 'as a regular user' do
it 'redirects to unauthorized' do
spree_put :cancel, params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
@@ -401,7 +401,7 @@ describe Admin::SubscriptionsController, type: :controller do
it 'redirects to unauthorized' do
spree_put :cancel, params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
@@ -489,7 +489,7 @@ describe Admin::SubscriptionsController, type: :controller do
context 'as a regular user' do
it 'redirects to unauthorized' do
spree_put :pause, params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
@@ -500,7 +500,7 @@ describe Admin::SubscriptionsController, type: :controller do
it 'redirects to unauthorized' do
spree_put :pause, params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
@@ -588,7 +588,7 @@ describe Admin::SubscriptionsController, type: :controller do
context 'as a regular user' do
it 'redirects to unauthorized' do
spree_put :unpause, params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
@@ -599,7 +599,7 @@ describe Admin::SubscriptionsController, type: :controller do
it 'redirects to unauthorized' do
spree_put :unpause, params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
diff --git a/spec/controllers/admin/tag_rules_controller_spec.rb b/spec/controllers/admin/tag_rules_controller_spec.rb
index b4da011923..5d654958a4 100644
--- a/spec/controllers/admin/tag_rules_controller_spec.rb
+++ b/spec/controllers/admin/tag_rules_controller_spec.rb
@@ -19,7 +19,7 @@ describe Admin::TagRulesController, type: :controller do
it "redirects to unauthorized" do
spree_delete :destroy, params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
diff --git a/spec/controllers/admin/variant_overrides_controller_spec.rb b/spec/controllers/admin/variant_overrides_controller_spec.rb
index c75a265cd1..cc8add0156 100644
--- a/spec/controllers/admin/variant_overrides_controller_spec.rb
+++ b/spec/controllers/admin/variant_overrides_controller_spec.rb
@@ -1,8 +1,6 @@
require 'spec_helper'
describe Admin::VariantOverridesController, type: :controller do
- # include AuthenticationWorkflow
-
describe "bulk_update" do
context "json" do
let(:format) { :json }
@@ -22,7 +20,7 @@ describe Admin::VariantOverridesController, type: :controller do
it "redirects to unauthorized" do
spree_put :bulk_update, format: format, variant_overrides: variant_override_params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
@@ -34,7 +32,7 @@ describe Admin::VariantOverridesController, type: :controller do
context "but the producer has not granted VO permission" do
it "redirects to unauthorized" do
spree_put :bulk_update, format: format, variant_overrides: variant_override_params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
@@ -78,7 +76,7 @@ describe Admin::VariantOverridesController, type: :controller do
it "allows to update other variant overrides" do
spree_put :bulk_update, format: format, variant_overrides: variant_override_params
- expect(response).to_not redirect_to spree.unauthorized_path
+ expect(response).to_not redirect_to unauthorized_path
variant_override.reload
expect(variant_override.price).to eq 123.45
end
@@ -111,7 +109,7 @@ describe Admin::VariantOverridesController, type: :controller do
it "redirects to unauthorized" do
spree_put :bulk_reset, params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
@@ -123,7 +121,7 @@ describe Admin::VariantOverridesController, type: :controller do
context "where the producer has not granted create_variant_overrides permission to the hub" do
it "restricts access" do
spree_put :bulk_reset, params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
diff --git a/spec/controllers/api/base_controller_spec.rb b/spec/controllers/api/base_controller_spec.rb
index d501aa98fb..1ebd3eca15 100644
--- a/spec/controllers/api/base_controller_spec.rb
+++ b/spec/controllers/api/base_controller_spec.rb
@@ -14,7 +14,7 @@ describe Api::BaseController do
context "signed in as a user using an authentication extension" do
before do
- allow(controller).to receive_messages try_spree_current_user:
+ allow(controller).to receive_messages spree_current_user:
double(email: "ofn@example.com")
end
diff --git a/spec/controllers/api/customers_controller_spec.rb b/spec/controllers/api/customers_controller_spec.rb
index cab5b2e1e1..25fc52cc09 100644
--- a/spec/controllers/api/customers_controller_spec.rb
+++ b/spec/controllers/api/customers_controller_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
module Api
describe CustomersController, type: :controller do
- include AuthenticationWorkflow
+ include AuthenticationHelper
render_views
let(:user) { create(:user) }
diff --git a/spec/controllers/api/enterprise_fees_controller_spec.rb b/spec/controllers/api/enterprise_fees_controller_spec.rb
index 8991e5fcde..b32423fea2 100644
--- a/spec/controllers/api/enterprise_fees_controller_spec.rb
+++ b/spec/controllers/api/enterprise_fees_controller_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
module Api
describe EnterpriseFeesController, type: :controller do
- include AuthenticationWorkflow
+ include AuthenticationHelper
let!(:unreferenced_fee) { create(:enterprise_fee) }
let!(:referenced_fee) { create(:enterprise_fee) }
diff --git a/spec/controllers/api/enterprises_controller_spec.rb b/spec/controllers/api/enterprises_controller_spec.rb
index b6e42967dc..0a2a185b72 100644
--- a/spec/controllers/api/enterprises_controller_spec.rb
+++ b/spec/controllers/api/enterprises_controller_spec.rb
@@ -1,13 +1,12 @@
require 'spec_helper'
describe Api::EnterprisesController, type: :controller do
- include AuthenticationWorkflow
render_views
let(:enterprise) { create(:distributor_enterprise) }
context "as an enterprise owner" do
- let(:enterprise_owner) { create_enterprise_user enterprise_limit: 10 }
+ let(:enterprise_owner) { create(:user) }
let!(:enterprise) { create(:distributor_enterprise, owner: enterprise_owner) }
before do
@@ -52,7 +51,7 @@ describe Api::EnterprisesController, type: :controller do
end
context "as an enterprise manager" do
- let(:enterprise_manager) { create_enterprise_user }
+ let(:enterprise_manager) { create(:user) }
before do
enterprise_manager.enterprise_roles.build(enterprise: enterprise).save
@@ -74,7 +73,7 @@ describe Api::EnterprisesController, type: :controller do
end
context "as an non-managing user" do
- let(:non_managing_user) { create_enterprise_user }
+ let(:non_managing_user) { create(:user) }
before do
allow(Enterprise)
diff --git a/spec/controllers/api/exchange_products_controller_spec.rb b/spec/controllers/api/exchange_products_controller_spec.rb
index f94089280c..3fa7248198 100644
--- a/spec/controllers/api/exchange_products_controller_spec.rb
+++ b/spec/controllers/api/exchange_products_controller_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
module Api
describe ExchangeProductsController, type: :controller do
- include AuthenticationWorkflow
+ include AuthenticationHelper
let(:order_cycle) { create(:order_cycle) }
let(:exchange) { order_cycle.exchanges.incoming.first }
diff --git a/spec/controllers/api/logos_controller_spec.rb b/spec/controllers/api/logos_controller_spec.rb
index 213ac8bc6e..b4cee3e896 100644
--- a/spec/controllers/api/logos_controller_spec.rb
+++ b/spec/controllers/api/logos_controller_spec.rb
@@ -2,7 +2,7 @@ require "spec_helper"
module Api
describe LogosController, type: :controller do
- include AuthenticationWorkflow
+ include AuthenticationHelper
let(:admin_user) { create(:admin_user) }
let(:enterprise_owner) { create(:user) }
diff --git a/spec/controllers/api/orders_controller_spec.rb b/spec/controllers/api/orders_controller_spec.rb
index 726756734d..b4d03951fc 100644
--- a/spec/controllers/api/orders_controller_spec.rb
+++ b/spec/controllers/api/orders_controller_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
module Api
describe OrdersController, type: :controller do
- include AuthenticationWorkflow
+ include AuthenticationHelper
render_views
let!(:regular_user) { create(:user) }
diff --git a/spec/controllers/api/product_images_controller_spec.rb b/spec/controllers/api/product_images_controller_spec.rb
index 5015d41b00..44fb239e38 100644
--- a/spec/controllers/api/product_images_controller_spec.rb
+++ b/spec/controllers/api/product_images_controller_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
module Api
describe ProductImagesController, type: :controller do
- include AuthenticationWorkflow
+ include AuthenticationHelper
render_views
describe "uploading an image" do
diff --git a/spec/controllers/api/promo_images_controller_spec.rb b/spec/controllers/api/promo_images_controller_spec.rb
index cce6d08f5f..ac73a1d94b 100644
--- a/spec/controllers/api/promo_images_controller_spec.rb
+++ b/spec/controllers/api/promo_images_controller_spec.rb
@@ -2,7 +2,7 @@ require "spec_helper"
module Api
describe PromoImagesController, type: :controller do
- include AuthenticationWorkflow
+ include AuthenticationHelper
let(:admin_user) { create(:admin_user) }
let(:enterprise_owner) { create(:user) }
diff --git a/spec/controllers/api/shops_controller_spec.rb b/spec/controllers/api/shops_controller_spec.rb
index a90f606f57..08040feea8 100644
--- a/spec/controllers/api/shops_controller_spec.rb
+++ b/spec/controllers/api/shops_controller_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe Api::ShopsController, type: :controller do
- include AuthenticationWorkflow
+ include AuthenticationHelper
render_views
context "as a non-authenticated user" do
diff --git a/spec/controllers/base_controller_spec.rb b/spec/controllers/base_controller_spec.rb
index ee7dcb4bcc..fb1d399335 100644
--- a/spec/controllers/base_controller_spec.rb
+++ b/spec/controllers/base_controller_spec.rb
@@ -9,6 +9,90 @@ describe BaseController, type: :controller do
end
end
+ describe "#current_order" do
+ let(:user) { create(:user) }
+
+ it "doesn't change anything without a user" do
+ expect {
+ get :index
+ }.to_not change { Spree::Order.count }
+ end
+
+ it "creates a new order" do
+ allow(controller).to receive(:spree_current_user).and_return(user)
+
+ expect {
+ get :index
+ }.to change { Spree::Order.count }.by(1)
+
+ expect(user.orders.count).to eq 1
+ end
+
+ it "uses the last incomplete order" do
+ last_cart = create(:order, user: user, created_by: user, state: "cart", completed_at: nil)
+ allow(controller).to receive(:spree_current_user).and_return(user)
+
+ expect {
+ get :index
+ }.to_not change { Spree::Order.count }
+
+ expect(session[:order_id]).to eq last_cart.id
+ end
+
+ it "ignores the last incomplete order" do
+ # Spree used to merge the last order with the current one.
+ # And we used to override that logic to delete old incomplete orders.
+ # Now we are checking here that none of that is happening.
+
+ last_cart = create(:order, user: user, created_by: user, state: "cart", completed_at: nil)
+ last_cart.line_items << create(:line_item)
+
+ current_cart = create(
+ :order,
+ user: user,
+ created_by: user,
+ state: "cart",
+ completed_at: nil,
+ created_at: 1.week.ago
+ )
+ session[:order_id] = current_cart.id
+
+ allow(controller).to receive(:spree_current_user).and_return(user)
+
+ expect {
+ get :index
+ }.to_not change { Spree::Order.count }
+
+ expect(current_cart.line_items.count).to eq 0
+ end
+
+ it "doesn't recover old orders after checkout, a new empty one is created" do
+ last_cart = create(:order, user: user, created_by: user, state: "cart", completed_at: nil)
+ last_cart.line_items << create(:line_item)
+
+ just_completed_order = create(
+ :order,
+ user: user,
+ created_by: user,
+ state: "complete",
+ completed_at: Time.zone.now,
+ created_at: 1.week.ago
+ )
+ expect(just_completed_order.completed_at).to be_present
+ session[:order_id] = just_completed_order.id
+
+ allow(controller).to receive(:spree_current_user).and_return(user)
+
+ expect {
+ get :index
+ }.to change { Spree::Order.count }.by(1)
+
+ expect(session[:order_id]).to_not eq just_completed_order.id
+ expect(session[:order_id]).to_not eq last_cart.id
+ expect(controller.current_order.line_items.count).to eq 0
+ end
+ end
+
it "redirects to home with message if order cycle is expired" do
expect(controller).to receive(:current_order_cycle).and_return(oc).twice
expect(controller).to receive(:current_order).and_return(order).twice
diff --git a/spec/controllers/checkout_controller_concurrency_spec.rb b/spec/controllers/checkout_controller_concurrency_spec.rb
index 51eefe98ae..266f9a4fbe 100644
--- a/spec/controllers/checkout_controller_concurrency_spec.rb
+++ b/spec/controllers/checkout_controller_concurrency_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
# This is the first example of testing concurrency in the Open Food Network.
@@ -15,6 +17,20 @@ describe CheckoutController, concurrency: true, type: :controller do
let(:payment_method) { create(:payment_method, distributors: [distributor]) }
let(:breakpoint) { Mutex.new }
+ let(:address_params) { address.attributes.except("id") }
+ let(:order_params) {
+ {
+ "payments_attributes" => [
+ {
+ "payment_method_id" => payment_method.id,
+ "amount" => order.total
+ }
+ ],
+ "bill_address_attributes" => address_params,
+ "ship_address_attributes" => address_params,
+ }
+ }
+
before do
# Create a valid order ready for checkout:
create(:shipping_method, distributors: [distributor])
@@ -26,7 +42,9 @@ describe CheckoutController, concurrency: true, type: :controller do
allow(controller).to receive(:spree_current_user).and_return(order.user)
allow(controller).to receive(:current_distributor).and_return(order.distributor)
allow(controller).to receive(:current_order_cycle).and_return(order.order_cycle)
+ end
+ it "handles two concurrent orders successfully" do
# New threads start running straight away. The breakpoint is after loading
# the order and before advancing the order's state and making payments.
breakpoint.lock
@@ -36,21 +54,6 @@ describe CheckoutController, concurrency: true, type: :controller do
# I did not find out how to call the original code otherwise.
ActiveSupport::Notifications.instrument("spree.checkout.update")
end
- end
-
- it "waits for concurrent checkouts" do
- # Basic data the user submits during checkout:
- address_params = address.attributes.except("id")
- order_params = {
- "payments_attributes" => [
- {
- "payment_method_id" => payment_method.id,
- "amount" => order.total
- }
- ],
- "bill_address_attributes" => address_params,
- "ship_address_attributes" => address_params,
- }
# Starting two checkout threads. The controller code will determine if
# these two threads are synchronised correctly or run into a race condition.
diff --git a/spec/controllers/checkout_controller_spec.rb b/spec/controllers/checkout_controller_spec.rb
index ecb18971db..0d285dab08 100644
--- a/spec/controllers/checkout_controller_spec.rb
+++ b/spec/controllers/checkout_controller_spec.rb
@@ -67,10 +67,31 @@ describe CheckoutController, type: :controller do
allow(order).to receive_message_chain(:insufficient_stock_lines, :empty?).and_return true
end
- it "does not redirect" do
- expect(order_cycle_distributed_variants).to receive(:distributes_order_variants?).with(order).and_return(true)
- get :edit
- expect(response).to be_success
+ describe "order variants are distributed in the OC" do
+ before do
+ expect(order_cycle_distributed_variants).to receive(:distributes_order_variants?).with(order).and_return(true)
+ end
+
+ it "does not redirect" do
+ get :edit
+ expect(response).to be_success
+ end
+
+ it "returns a specific flash message when Spree::Core::GatewayError occurs" do
+ order_checkout_restart = double(:order_checkout_restart)
+ allow(OrderCheckoutRestart).to receive(:new) { order_checkout_restart }
+ call_count = 0
+ allow(order_checkout_restart).to receive(:call) do
+ call_count += 1
+ raise Spree::Core::GatewayError.new("Gateway blow up") if call_count == 1
+ end
+
+ spree_post :edit
+
+ expect(response.status).to eq(200)
+ flash_message = I18n.t(:spree_gateway_error_flash_for_checkout, error: "Gateway blow up")
+ expect(flash[:error]).to eq flash_message
+ end
end
describe "when the order is in payment state and a stripe payment intent is provided" do
@@ -230,6 +251,15 @@ describe CheckoutController, type: :controller do
expect(response.body).to eq({ errors: {}, flash: { error: I18n.t("checkout.failed") } }.to_json)
end
+ it "returns a specific error on Spree::Core::GatewayError" do
+ allow(order).to receive(:update).and_raise(Spree::Core::GatewayError.new("Gateway blow up"))
+ spree_post :update, format: :json, order: {}
+
+ expect(response.status).to eq(400)
+ flash_message = I18n.t(:spree_gateway_error_flash_for_checkout, error: "Gateway blow up")
+ expect(json_response["flash"]["error"]).to eq flash_message
+ end
+
describe "stale object handling" do
it "retries when a stale object error is encountered" do
allow(OrderCompletionReset).to receive(:new).with(controller, order) { reset_order_service }
@@ -298,7 +328,7 @@ describe CheckoutController, type: :controller do
end
end
- describe "#update_failed" do
+ describe "#action_failed" do
let(:restart_checkout) { instance_double(OrderCheckoutRestart, call: true) }
before do
@@ -312,7 +342,7 @@ describe CheckoutController, type: :controller do
expect(restart_checkout).to receive(:call)
expect(controller).to receive(:respond_to)
- controller.send(:update_failed)
+ controller.send(:action_failed)
end
end
end
diff --git a/spec/controllers/registration_controller_spec.rb b/spec/controllers/registration_controller_spec.rb
index 31a1a91116..ea5f73c590 100644
--- a/spec/controllers/registration_controller_spec.rb
+++ b/spec/controllers/registration_controller_spec.rb
@@ -1,7 +1,6 @@
require 'spec_helper'
describe RegistrationController, type: :controller do
- include AuthenticationWorkflow
describe "redirecting when user not logged in" do
it "index" do
get :index
@@ -10,7 +9,7 @@ describe RegistrationController, type: :controller do
end
describe "redirecting when user has reached enterprise ownership limit" do
- let!(:user) { create_enterprise_user( enterprise_limit: 1 ) }
+ let!(:user) { create(:user, enterprise_limit: 1 ) }
let!(:enterprise) { create(:distributor_enterprise, owner: user) }
before do
@@ -24,7 +23,7 @@ describe RegistrationController, type: :controller do
end
describe "loading data when user is logged in" do
- let!(:user) { create_enterprise_user }
+ let!(:user) { create(:user) }
before do
allow(controller).to receive_messages spree_current_user: user
diff --git a/spec/controllers/spree/admin/adjustments_controller_spec.rb b/spec/controllers/spree/admin/adjustments_controller_spec.rb
index 4ad02b73c7..7691bd6e72 100644
--- a/spec/controllers/spree/admin/adjustments_controller_spec.rb
+++ b/spec/controllers/spree/admin/adjustments_controller_spec.rb
@@ -2,9 +2,9 @@ require 'spec_helper'
module Spree
describe Admin::AdjustmentsController, type: :controller do
- include AuthenticationWorkflow
+ include AuthenticationHelper
- before { login_as_admin }
+ before { controller_login_as_admin }
describe "setting included tax" do
let(:order) { create(:order) }
diff --git a/spec/controllers/spree/admin/countries_controller_spec.rb b/spec/controllers/spree/admin/countries_controller_spec.rb
index 4146a506de..87a9356f1e 100644
--- a/spec/controllers/spree/admin/countries_controller_spec.rb
+++ b/spec/controllers/spree/admin/countries_controller_spec.rb
@@ -5,10 +5,10 @@ require 'spec_helper'
module Spree
module Admin
describe CountriesController, type: :controller do
- include AuthenticationWorkflow
+ include AuthenticationHelper
describe "#update" do
- before { login_as_admin }
+ before { controller_login_as_admin }
it "updates the name of an existing country" do
country = create(:country)
diff --git a/spec/controllers/spree/admin/image_settings_controller_spec.rb b/spec/controllers/spree/admin/image_settings_controller_spec.rb
index 89ccac822c..20bdd9dae0 100644
--- a/spec/controllers/spree/admin/image_settings_controller_spec.rb
+++ b/spec/controllers/spree/admin/image_settings_controller_spec.rb
@@ -1,9 +1,9 @@
require 'spec_helper'
describe Spree::Admin::ImageSettingsController do
- include AuthenticationWorkflow
+ include AuthenticationHelper
- before { login_as_admin }
+ before { controller_login_as_admin }
context "updating image settings" do
it "should be able to update paperclip settings" do
diff --git a/spec/controllers/spree/admin/mail_methods_controller_spec.rb b/spec/controllers/spree/admin/mail_methods_controller_spec.rb
index 422491660e..f7aa10959b 100644
--- a/spec/controllers/spree/admin/mail_methods_controller_spec.rb
+++ b/spec/controllers/spree/admin/mail_methods_controller_spec.rb
@@ -1,9 +1,9 @@
require 'spec_helper'
describe Spree::Admin::MailMethodsController do
- include AuthenticationWorkflow
+ include AuthenticationHelper
- before { login_as_admin }
+ before { controller_login_as_admin }
context "#update" do
it "should reinitialize the mail settings" do
@@ -18,8 +18,10 @@ describe Spree::Admin::MailMethodsController do
spree_api_key: 'fake',
id: nil,
owned_groups: nil)
- allow(user).to receive_messages(enterprises: [create(:enterprise)], has_spree_role?: true)
- allow(controller).to receive_messages(try_spree_current_user: user)
+ allow(user).to receive_messages(enterprises: [create(:enterprise)],
+ has_spree_role?: true,
+ locale: nil)
+ allow(controller).to receive_messages(spree_current_user: user)
Spree::Config[:enable_mail_delivery] = "1"
ActionMailer::Base.perform_deliveries = true
diff --git a/spec/controllers/spree/admin/orders/customer_details_controller_spec.rb b/spec/controllers/spree/admin/orders/customer_details_controller_spec.rb
index c62d0a0f9c..bc0c135505 100644
--- a/spec/controllers/spree/admin/orders/customer_details_controller_spec.rb
+++ b/spec/controllers/spree/admin/orders/customer_details_controller_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Spree::Admin::Orders::CustomerDetailsController, type: :controller do
- include AuthenticationWorkflow
+ include AuthenticationHelper
describe "#update" do
context "adding customer details via newly created admin order" do
@@ -37,7 +37,7 @@ describe Spree::Admin::Orders::CustomerDetailsController, type: :controller do
}
before do
- login_as_enterprise_user [order.distributor]
+ controller_login_as_enterprise_user [order.distributor]
end
it "advances the order state" do
diff --git a/spec/controllers/spree/admin/orders/payments/payments_controller_spec.rb b/spec/controllers/spree/admin/orders/payments/payments_controller_spec.rb
index 6932efa236..8e78be69d8 100644
--- a/spec/controllers/spree/admin/orders/payments/payments_controller_spec.rb
+++ b/spec/controllers/spree/admin/orders/payments/payments_controller_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Spree::Admin::PaymentsController, type: :controller do
@@ -10,7 +12,7 @@ describe Spree::Admin::PaymentsController, type: :controller do
allow(controller).to receive(:spree_current_user) { user }
end
- context "#create" do
+ describe "#create" do
let!(:payment_method) { create(:payment_method, distributors: [shop]) }
let(:params) { { amount: order.total, payment_method_id: payment_method.id } }
@@ -138,4 +140,92 @@ describe Spree::Admin::PaymentsController, type: :controller do
end
end
end
+
+ describe '#fire' do
+ let(:payment_method) do
+ create(
+ :stripe_sca_payment_method,
+ distributor_ids: [create(:distributor_enterprise).id],
+ preferred_enterprise_id: create(:enterprise).id
+ )
+ end
+ let(:order) { create(:order, state: 'complete') }
+ let(:payment) do
+ create(:payment, order: order, payment_method: payment_method, amount: order.total)
+ end
+
+ let(:successful_response) { ActiveMerchant::Billing::Response.new(true, "Yay!") }
+
+ context 'on credit event' do
+ let(:params) { { e: 'credit', order_id: order.number, id: payment.id } }
+
+ before do
+ allow(request).to receive(:referer) { 'http://foo.com' }
+ allow(Spree::Payment).to receive(:find).with(payment.id.to_s) { payment }
+ end
+
+ it 'handles gateway errors' do
+ allow(payment.payment_method)
+ .to receive(:credit).and_raise(Spree::Core::GatewayError, 'error message')
+
+ spree_put :fire, params
+
+ expect(flash[:error]).to eq('error message')
+ expect(response).to redirect_to('http://foo.com')
+ end
+
+ it 'handles validation errors' do
+ allow(payment).to receive(:credit!).and_raise(StandardError, 'validation error')
+
+ spree_put :fire, params
+
+ expect(flash[:error]).to eq('validation error')
+ expect(response).to redirect_to('http://foo.com')
+ end
+
+ it 'displays a success message and redirects to the referer' do
+ allow(payment_method).to receive(:credit) { successful_response }
+
+ spree_put :fire, params
+
+ expect(flash[:success]).to eq(I18n.t(:payment_updated))
+ end
+ end
+
+ context 'on refund event' do
+ let(:params) { { e: 'refund', order_id: order.number, id: payment.id } }
+
+ before do
+ allow(request).to receive(:referer) { 'http://foo.com' }
+ allow(Spree::Payment).to receive(:find).with(payment.id.to_s) { payment }
+ end
+
+ it 'handles gateway errors' do
+ allow(payment.payment_method)
+ .to receive(:refund).and_raise(Spree::Core::GatewayError, 'error message')
+
+ spree_put :fire, params
+
+ expect(flash[:error]).to eq('error message')
+ expect(response).to redirect_to('http://foo.com')
+ end
+
+ it 'handles validation errors' do
+ allow(payment).to receive(:refund!).and_raise(StandardError, 'validation error')
+
+ spree_put :fire, params
+
+ expect(flash[:error]).to eq('validation error')
+ expect(response).to redirect_to('http://foo.com')
+ end
+
+ it 'displays a success message and redirects to the referer' do
+ allow(payment_method).to receive(:refund) { successful_response }
+
+ spree_put :fire, params
+
+ expect(flash[:success]).to eq(I18n.t(:payment_updated))
+ end
+ end
+ end
end
diff --git a/spec/controllers/spree/admin/orders_controller_spec.rb b/spec/controllers/spree/admin/orders_controller_spec.rb
index 8ab20c385a..0d10068f1e 100644
--- a/spec/controllers/spree/admin/orders_controller_spec.rb
+++ b/spec/controllers/spree/admin/orders_controller_spec.rb
@@ -1,13 +1,12 @@
require 'spec_helper'
describe Spree::Admin::OrdersController, type: :controller do
- include AuthenticationWorkflow
include OpenFoodNetwork::EmailHelper
describe "#edit" do
let!(:order) { create(:order_with_totals_and_distribution, ship_address: create(:address)) }
- before { login_as_admin }
+ before { controller_login_as_admin }
it "advances the order state" do
expect {
@@ -41,7 +40,7 @@ describe Spree::Admin::OrdersController, type: :controller do
order_cycle_id: order.order_cycle_id } }
end
- before { login_as_admin }
+ before { controller_login_as_admin }
context "complete order" do
let(:order) { create :completed_order_with_totals }
@@ -109,11 +108,11 @@ describe Spree::Admin::OrdersController, type: :controller do
describe "#index" do
context "as a regular user" do
- before { allow(controller).to receive(:spree_current_user) { create_enterprise_user } }
+ before { allow(controller).to receive(:spree_current_user) { create(:user) } }
it "should deny me access to the index action" do
spree_get :index
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
@@ -140,7 +139,7 @@ describe Spree::Admin::OrdersController, type: :controller do
it "should prevent me from sending order invoices" do
spree_get :invoice, params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
@@ -150,7 +149,7 @@ describe Spree::Admin::OrdersController, type: :controller do
it "should prevent me from sending order invoices" do
spree_get :invoice, params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
@@ -198,7 +197,7 @@ describe Spree::Admin::OrdersController, type: :controller do
it "should prevent me from sending order invoices" do
spree_get :print, params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
@@ -207,7 +206,7 @@ describe Spree::Admin::OrdersController, type: :controller do
before { allow(controller).to receive(:spree_current_user) { user } }
it "should prevent me from sending order invoices" do
spree_get :print, params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
diff --git a/spec/controllers/spree/admin/overview_controller_spec.rb b/spec/controllers/spree/admin/overview_controller_spec.rb
index e445932555..3c610b62cc 100644
--- a/spec/controllers/spree/admin/overview_controller_spec.rb
+++ b/spec/controllers/spree/admin/overview_controller_spec.rb
@@ -1,15 +1,13 @@
require 'spec_helper'
describe Spree::Admin::OverviewController, type: :controller do
- include AuthenticationWorkflow
-
describe "#index" do
before do
allow(controller).to receive(:spree_current_user).and_return(user)
end
context "when user owns only one enterprise" do
- let(:user) { create_enterprise_user }
+ let(:user) { create(:user) }
let!(:enterprise) { create(:distributor_enterprise, owner: user) }
context "when the referer is not an admin page" do
@@ -48,7 +46,7 @@ describe Spree::Admin::OverviewController, type: :controller do
end
context "when user owns multiple enterprises" do
- let(:user) { create_enterprise_user(enterprise_limit: 2) }
+ let(:user) { create(:user) }
let!(:enterprise1) { create(:distributor_enterprise, owner: user) }
before { create(:distributor_enterprise, owner: user) }
diff --git a/spec/controllers/spree/admin/payment_methods_controller_spec.rb b/spec/controllers/spree/admin/payment_methods_controller_spec.rb
index dfc7dd307e..3e752170c7 100644
--- a/spec/controllers/spree/admin/payment_methods_controller_spec.rb
+++ b/spec/controllers/spree/admin/payment_methods_controller_spec.rb
@@ -39,6 +39,20 @@ module Spree
expect(response).to redirect_to spree.edit_admin_payment_method_path(assigns(:payment_method))
end
+ it "can save Pin Payment payment method details" do
+ expect {
+ spree_post :create, payment_method: {
+ name: "Test Method", type: "Spree::Gateway::Pin", distributor_ids: [enterprise.id],
+ preferred_server: "test", preferred_api_key: "apikey123", preferred_test_mode: "1"
+ }
+ }.to change(Spree::PaymentMethod, :count).by(1)
+
+ payment_method = Spree::PaymentMethod.last
+ expect(payment_method.preferences[:server]).to eq "test"
+ expect(payment_method.preferences[:api_key]).to eq "apikey123"
+ expect(payment_method.preferences[:test_mode]).to eq true
+ end
+
it "can not create a payment method of an invalid type" do
expect {
spree_post :create, payment_method: { name: "Invalid Payment Method", type: "Spree::InvalidType", distributor_ids: [enterprise.id] }
diff --git a/spec/controllers/spree/admin/products_controller_spec.rb b/spec/controllers/spree/admin/products_controller_spec.rb
index e8ae658e9e..b33198d14c 100644
--- a/spec/controllers/spree/admin/products_controller_spec.rb
+++ b/spec/controllers/spree/admin/products_controller_spec.rb
@@ -10,13 +10,13 @@ describe Spree::Admin::ProductsController, type: :controller do
end
before do
- login_as_enterprise_user [s_managed]
+ controller_login_as_enterprise_user [s_managed]
spree_post :bulk_update,
"products" => [{ "id" => product.id, "name" => "Pine nuts" }]
end
it "denies access" do
- expect(response).to redirect_to spree.unauthorized_url
+ expect(response).to redirect_to unauthorized_path
end
it "does not update any product" do
@@ -38,7 +38,7 @@ describe Spree::Admin::ProductsController, type: :controller do
)
end
- before { login_as_enterprise_user([producer]) }
+ before { controller_login_as_enterprise_user([producer]) }
it 'fails' do
spree_post :bulk_update,
@@ -92,7 +92,7 @@ describe Spree::Admin::ProductsController, type: :controller do
)
end
- before { login_as_enterprise_user([producer]) }
+ before { controller_login_as_enterprise_user([producer]) }
it 'does not fail' do
spree_post :bulk_update,
@@ -134,7 +134,7 @@ describe Spree::Admin::ProductsController, type: :controller do
}
before do
- login_as_admin
+ controller_login_as_admin
create(:stock_location)
end
@@ -174,7 +174,7 @@ describe Spree::Admin::ProductsController, type: :controller do
let!(:product) { create(:simple_product, supplier: producer) }
before do
- login_as_enterprise_user [producer]
+ controller_login_as_enterprise_user [producer]
end
describe "change product supplier" do
diff --git a/spec/controllers/spree/admin/reports_controller_spec.rb b/spec/controllers/spree/admin/reports_controller_spec.rb
index 8cfda5fe36..9b72b5418f 100644
--- a/spec/controllers/spree/admin/reports_controller_spec.rb
+++ b/spec/controllers/spree/admin/reports_controller_spec.rb
@@ -65,7 +65,7 @@ describe Spree::Admin::ReportsController, type: :controller do
context "Coordinator Enterprise User" do
let!(:present_objects) { [orderA1, orderA2, orderB1, orderB2] }
- before { login_as_enterprise_user [coordinator1] }
+ before { controller_login_as_enterprise_user [coordinator1] }
describe 'Orders & Fulfillment' do
it "shows all orders in order cycles I coordinate" do
@@ -79,7 +79,7 @@ describe Spree::Admin::ReportsController, type: :controller do
# As a Distributor Enterprise user for distributor1
context "Distributor Enterprise User" do
- before { login_as_enterprise_user [distributor1] }
+ before { controller_login_as_enterprise_user [distributor1] }
describe 'Orders and Distributors' do
let!(:present_objects) { [orderA1, orderA2, orderB1, orderB2] }
@@ -132,7 +132,7 @@ describe Spree::Admin::ReportsController, type: :controller do
# As a Supplier Enterprise user for supplier1
context "Supplier" do
- before { login_as_enterprise_user [supplier1] }
+ before { controller_login_as_enterprise_user [supplier1] }
describe 'index' do
it "loads reports relevant to producers" do
@@ -191,7 +191,7 @@ describe Spree::Admin::ReportsController, type: :controller do
end
context "Products & Inventory" do
- before { login_as_admin }
+ before { controller_login_as_admin }
context "with distributors and suppliers" do
let(:distributors) { [coordinator1, distributor1, distributor2] }
@@ -235,7 +235,7 @@ describe Spree::Admin::ReportsController, type: :controller do
end
context "My Customers" do
- before { login_as_admin }
+ before { controller_login_as_admin }
it "should have report types for customers" do
expect(subject.report_types[:customers]).to eq([
@@ -286,7 +286,7 @@ describe Spree::Admin::ReportsController, type: :controller do
end
context "Admin" do
- before { login_as_admin }
+ before { controller_login_as_admin }
describe "users_and_enterprises" do
let!(:present_objects) { [coordinator1] }
diff --git a/spec/controllers/spree/admin/return_authorizations_controller_spec.rb b/spec/controllers/spree/admin/return_authorizations_controller_spec.rb
index 6c28642da5..4cc170872b 100644
--- a/spec/controllers/spree/admin/return_authorizations_controller_spec.rb
+++ b/spec/controllers/spree/admin/return_authorizations_controller_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
module Spree
module Admin
describe ReturnAuthorizationsController, type: :controller do
- include AuthenticationWorkflow
+ include AuthenticationHelper
let(:order) do
create(:order, :with_line_item, :completed,
@@ -13,7 +13,7 @@ module Spree
end
before do
- login_as_admin
+ controller_login_as_admin
# Pay the order
order.payments.first.complete
diff --git a/spec/controllers/spree/admin/search_controller_spec.rb b/spec/controllers/spree/admin/search_controller_spec.rb
index 48fffbabcd..a6f8623b30 100644
--- a/spec/controllers/spree/admin/search_controller_spec.rb
+++ b/spec/controllers/spree/admin/search_controller_spec.rb
@@ -1,13 +1,12 @@
require 'spec_helper'
describe Spree::Admin::SearchController, type: :controller do
- include AuthenticationWorkflow
context "Distributor Enterprise User" do
- let!(:owner) { create_enterprise_user( email: "test1@email.com" ) }
- let!(:manager) { create_enterprise_user( email: "test2@email.com" ) }
- let!(:random) { create_enterprise_user( email: "test3@email.com" ) }
+ let!(:owner) { create(:user, email: "test1@email.com" ) }
+ let!(:manager) { create(:user, email: "test2@email.com" ) }
+ let!(:random) { create(:user, email: "test3@email.com" ) }
let!(:enterprise) { create(:enterprise, owner: owner, users: [owner, manager]) }
- before { login_as_enterprise_user [enterprise] }
+ before { controller_login_as_enterprise_user [enterprise] }
describe 'searching for known users' do
describe "when search query is not an exact match" do
diff --git a/spec/controllers/spree/admin/shipping_categories_controller_spec.rb b/spec/controllers/spree/admin/shipping_categories_controller_spec.rb
index 531b175072..05aefff048 100644
--- a/spec/controllers/spree/admin/shipping_categories_controller_spec.rb
+++ b/spec/controllers/spree/admin/shipping_categories_controller_spec.rb
@@ -5,10 +5,10 @@ require 'spec_helper'
module Spree
module Admin
describe ShippingCategoriesController, type: :controller do
- include AuthenticationWorkflow
+ include AuthenticationHelper
describe "#create and #update" do
- before { login_as_admin }
+ before { controller_login_as_admin }
it "creates a shipping shipping category" do
expect {
diff --git a/spec/controllers/spree/admin/shipping_methods_controller_spec.rb b/spec/controllers/spree/admin/shipping_methods_controller_spec.rb
index 105d55563c..f209e87a81 100644
--- a/spec/controllers/spree/admin/shipping_methods_controller_spec.rb
+++ b/spec/controllers/spree/admin/shipping_methods_controller_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Spree::Admin::ShippingMethodsController, type: :controller do
- include AuthenticationWorkflow
+ include AuthenticationHelper
describe "#update" do
let(:shipping_method) { create(:shipping_method) }
@@ -16,7 +16,7 @@ describe Spree::Admin::ShippingMethodsController, type: :controller do
}
}
- before { login_as_admin }
+ before { controller_login_as_admin }
it "updates preferred_amount and preferred_currency of a FlatRate calculator" do
shipping_method.calculator = create(:calculator_flat_rate, calculable: shipping_method)
@@ -81,7 +81,7 @@ describe Spree::Admin::ShippingMethodsController, type: :controller do
let(:shipping_method) { create(:shipping_method) }
scenario "is soft deleted" do
- login_as_admin
+ controller_login_as_admin
expect(shipping_method.deleted_at).to be_nil
spree_delete :destroy, "id" => shipping_method.id
@@ -94,7 +94,7 @@ describe Spree::Admin::ShippingMethodsController, type: :controller do
let(:order) { create(:order_with_line_items) }
scenario "is not soft deleted" do
- login_as_admin
+ controller_login_as_admin
expect(order.shipping_method.deleted_at).to be_nil
spree_delete :destroy, "id" => order.shipping_method.id
diff --git a/spec/controllers/spree/admin/variants_controller_spec.rb b/spec/controllers/spree/admin/variants_controller_spec.rb
index 7163f6f423..9af2be952a 100644
--- a/spec/controllers/spree/admin/variants_controller_spec.rb
+++ b/spec/controllers/spree/admin/variants_controller_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
module Spree
module Admin
describe VariantsController, type: :controller do
- before { login_as_admin }
+ before { controller_login_as_admin }
describe "#index" do
describe "deleted variants" do
diff --git a/spec/controllers/spree/credit_cards_controller_spec.rb b/spec/controllers/spree/credit_cards_controller_spec.rb
index e8996433f3..fd15916f0f 100644
--- a/spec/controllers/spree/credit_cards_controller_spec.rb
+++ b/spec/controllers/spree/credit_cards_controller_spec.rb
@@ -1,9 +1,7 @@
require 'spec_helper'
-require 'support/request/authentication_workflow'
describe Spree::CreditCardsController, type: :controller do
- include AuthenticationWorkflow
- let(:user) { create_enterprise_user }
+ let(:user) { create(:user) }
let(:token) { "tok_234bd2c22" }
before do
@@ -88,7 +86,7 @@ describe Spree::CreditCardsController, type: :controller do
context "but the card is not owned by the user" do
it "redirects to unauthorized" do
spree_put :update, params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
@@ -135,7 +133,7 @@ describe Spree::CreditCardsController, type: :controller do
context "but the card is not owned by the user" do
it "redirects to unauthorized" do
spree_delete :destroy, params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
diff --git a/spec/controllers/spree/orders_controller_spec.rb b/spec/controllers/spree/orders_controller_spec.rb
index cee76bdc39..1f74a3915f 100644
--- a/spec/controllers/spree/orders_controller_spec.rb
+++ b/spec/controllers/spree/orders_controller_spec.rb
@@ -58,7 +58,7 @@ describe Spree::OrdersController, type: :controller do
it "redirects to unauthorized" do
spree_get :show, id: order.number
- expect(response.status).to eq(401)
+ expect(response).to redirect_to unauthorized_path
end
end
@@ -415,9 +415,11 @@ describe Spree::OrdersController, type: :controller do
let(:params) { { id: order.number } }
context "when the user does not have permission to cancel the order" do
+ before { allow(controller).to receive(:spree_current_user) { create(:user) } }
+
it "responds with unauthorized" do
spree_put :cancel, params
- expect(response).to render_template 'shared/unauthorized'
+ expect(response).to redirect_to unauthorized_path
end
end
diff --git a/spec/controllers/spree/store_controller_spec.rb b/spec/controllers/spree/store_controller_spec.rb
deleted file mode 100644
index b04ac0167e..0000000000
--- a/spec/controllers/spree/store_controller_spec.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-require 'spec_helper'
-
-describe Spree::StoreController, type: :controller do
- controller(Spree::StoreController) do
- before_filter :unauthorized
- def index
- render text: ""
- end
- end
- it "redirects to home when unauthorized" do
- get :index
- expect(response).to render_template("shared/unauthorized", layout: 'darkswarm')
- end
-end
diff --git a/spec/controllers/spree/user_sessions_controller_spec.rb b/spec/controllers/spree/user_sessions_controller_spec.rb
index 60cbbb7d03..d5bcff290c 100644
--- a/spec/controllers/spree/user_sessions_controller_spec.rb
+++ b/spec/controllers/spree/user_sessions_controller_spec.rb
@@ -1,9 +1,7 @@
require 'spec_helper'
describe Spree::UserSessionsController, type: :controller do
- include AuthenticationWorkflow
-
- let(:user) { create_enterprise_user }
+ let(:user) { create(:user) }
before do
@request.env["devise.mapping"] = Devise.mappings[:spree_user]
diff --git a/spec/controllers/spree/users_controller_spec.rb b/spec/controllers/spree/users_controller_spec.rb
index 50ac3ebf6f..5210c1717a 100644
--- a/spec/controllers/spree/users_controller_spec.rb
+++ b/spec/controllers/spree/users_controller_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Spree::UsersController, type: :controller do
- include AuthenticationWorkflow
+ include AuthenticationHelper
describe "show" do
let!(:u1) { create(:user) }
diff --git a/spec/controllers/stripe/callbacks_controller_spec.rb b/spec/controllers/stripe/callbacks_controller_spec.rb
index 33f7bd5b76..50c5433767 100644
--- a/spec/controllers/stripe/callbacks_controller_spec.rb
+++ b/spec/controllers/stripe/callbacks_controller_spec.rb
@@ -30,7 +30,7 @@ describe Stripe::CallbacksController, type: :controller do
it "redirects to unauthorized" do
spree_get :index, params
- expect(response).to redirect_to spree.unauthorized_path
+ expect(response).to redirect_to unauthorized_path
end
end
diff --git a/spec/controllers/user_confirmations_controller_spec.rb b/spec/controllers/user_confirmations_controller_spec.rb
index 9920330161..82ec5c2cc3 100644
--- a/spec/controllers/user_confirmations_controller_spec.rb
+++ b/spec/controllers/user_confirmations_controller_spec.rb
@@ -1,17 +1,16 @@
require 'spec_helper'
describe UserConfirmationsController, type: :controller do
- include AuthenticationWorkflow
include OpenFoodNetwork::EmailHelper
- let!(:user) { create_enterprise_user }
- let!(:confirmed_user) { create_enterprise_user(confirmed_at: nil) }
- let!(:unconfirmed_user) { create_enterprise_user(confirmed_at: nil) }
+ let!(:user) { create(:user) }
+ let!(:confirmed_user) { create(:user, confirmed_at: nil) }
+ let!(:unconfirmed_user) { create(:user, confirmed_at: nil) }
let!(:confirmed_token) { confirmed_user.confirmation_token }
before do
@request.env["devise.mapping"] = Devise.mappings[:spree_user]
- confirmed_user.confirm!
+ confirmed_user.confirm
end
context "confirming a user" do
@@ -52,7 +51,8 @@ describe UserConfirmationsController, type: :controller do
unconfirmed_user.reset_password_token = Devise.friendly_token
unconfirmed_user.save!
spree_get :show, confirmation_token: unconfirmed_user.confirmation_token
- expect(response).to redirect_to spree.edit_spree_user_password_path(reset_password_token: unconfirmed_user.reset_password_token)
+ expect(response).to be_redirect
+ expect(response.body).to include spree.edit_spree_user_password_path
end
end
end
diff --git a/spec/factories.rb b/spec/factories.rb
index ad3c804c92..455fc9b9a4 100644
--- a/spec/factories.rb
+++ b/spec/factories.rb
@@ -15,6 +15,7 @@ require 'spree/testing_support/factories'
# * order_with_inventory_unit_shipped
# * completed_order_with_totals
#
+
FactoryBot.define do
factory :classification, class: Spree::Classification do
end
diff --git a/spec/features/admin/adjustments_spec.rb b/spec/features/admin/adjustments_spec.rb
index fcd0a0bb39..5911e602c5 100644
--- a/spec/features/admin/adjustments_spec.rb
+++ b/spec/features/admin/adjustments_spec.rb
@@ -4,7 +4,7 @@ feature '
As an administrator
I want to manage adjustments on orders
', js: true do
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
let!(:user) { create(:user) }
@@ -21,8 +21,7 @@ feature '
scenario "adding taxed adjustments to an order" do
# When I go to the adjustments page for the order
- login_to_admin_section
- visit spree.admin_orders_path
+ login_as_admin_and_visit spree.admin_orders_path
page.find('td.actions a.icon-edit').click
click_link 'Adjustments'
@@ -44,8 +43,7 @@ feature '
adjustment = create(:adjustment, label: "Extra Adjustment", adjustable: order, amount: 110, included_tax: 10)
# When I go to the adjustments page for the order
- login_to_admin_section
- visit spree.admin_orders_path
+ login_as_admin_and_visit spree.admin_orders_path
page.find('td.actions a.icon-edit').click
click_link 'Adjustments'
page.find('tr', text: 'Extra Adjustment').find('a.icon-edit').click
@@ -68,8 +66,7 @@ feature '
adjustment = create(:adjustment, label: "Extra Adjustment", adjustable: order, amount: 110, included_tax: 0)
# When I go to the adjustments page for the order
- login_to_admin_section
- visit spree.admin_orders_path
+ login_as_admin_and_visit spree.admin_orders_path
page.find('td.actions a.icon-edit').click
click_link 'Adjustments'
page.find('tr', text: 'Extra Adjustment').find('a.icon-edit').click
diff --git a/spec/features/admin/authentication_spec.rb b/spec/features/admin/authentication_spec.rb
index 6ff46d15a4..f9401ad192 100644
--- a/spec/features/admin/authentication_spec.rb
+++ b/spec/features/admin/authentication_spec.rb
@@ -2,24 +2,21 @@ require 'spec_helper'
feature "Authentication", js: true do
include UIComponentHelper
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
let(:user) { create(:user, password: "password", password_confirmation: "password") }
let!(:enterprise) { create(:enterprise, owner: user) } # Required for access to admin
scenario "logging into admin redirects home, then back to admin" do
- # This is the first admin spec, so give a little extra load time for slow systems
- Capybara.using_wait_time(120) do
- visit spree.admin_dashboard_path
+ visit spree.admin_dashboard_path
- fill_in "Email", with: user.email
- fill_in "Password", with: user.password
- click_login_button
- expect(page).to have_content "DASHBOARD"
- expect(page).to have_current_path spree.admin_dashboard_path
- expect(page).to have_no_content "CONFIGURATION"
- end
+ fill_in "Email", with: user.email
+ fill_in "Password", with: user.password
+ click_login_button
+ expect(page).to have_content "DASHBOARD"
+ expect(page).to have_current_path spree.admin_dashboard_path
+ expect(page).to have_no_content "CONFIGURATION"
end
scenario "viewing my account" do
diff --git a/spec/features/admin/bulk_order_management_spec.rb b/spec/features/admin/bulk_order_management_spec.rb
index a92afed022..efe3a3ed7e 100644
--- a/spec/features/admin/bulk_order_management_spec.rb
+++ b/spec/features/admin/bulk_order_management_spec.rb
@@ -5,12 +5,12 @@ feature '
I want to be able to manage orders in bulk
', js: true do
include AdminHelper
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
context "listing orders" do
before :each do
- quick_login_as_admin
+ login_as_admin
end
it "displays a message when number of line items is zero" do
@@ -121,7 +121,7 @@ feature '
context "altering line item properties" do
before :each do
- quick_login_as_admin
+ login_as_admin
end
context "tracking changes" do
@@ -177,7 +177,7 @@ feature '
context "using page controls" do
before :each do
- quick_login_as_admin
+ login_as_admin
end
let!(:p1) { create(:product_with_option_types, group_buy: true, group_buy_unit_size: 5000, variant_unit: "weight", variants: [create(:variant, unit_value: 1000)] ) }
@@ -719,11 +719,11 @@ feature '
let!(:line_item_not_distributed) { create(:line_item_with_shipment, order: o2, product: create(:product, supplier: s1) ) }
before(:each) do
- @enterprise_user = create_enterprise_user
+ @enterprise_user = create(:user)
@enterprise_user.enterprise_roles.build(enterprise: s1).save
@enterprise_user.enterprise_roles.build(enterprise: d1).save
- quick_login_as @enterprise_user
+ login_as @enterprise_user
end
it "displays a Bulk Management Tab under the Orders item" do
diff --git a/spec/features/admin/bulk_product_update_spec.rb b/spec/features/admin/bulk_product_update_spec.rb
index c0b55ed224..553e2182aa 100644
--- a/spec/features/admin/bulk_product_update_spec.rb
+++ b/spec/features/admin/bulk_product_update_spec.rb
@@ -5,12 +5,12 @@ feature '
I want to be able to manage products in bulk
', js: true do
include AdminHelper
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
describe "listing products" do
before do
- quick_login_as_admin
+ login_as_admin
end
it "displays a list of products" do
@@ -101,7 +101,7 @@ feature '
describe "listing variants" do
before do
- quick_login_as_admin
+ login_as_admin
end
it "displays a list of variants for each product" do
@@ -176,8 +176,7 @@ feature '
shipping_category = create(:shipping_category)
taxon = create(:taxon)
- quick_login_as_admin
- visit spree.admin_products_path
+ login_as_admin_and_visit spree.admin_products_path
find("a", text: "NEW PRODUCT").click
expect(page).to have_content 'NEW PRODUCT'
@@ -199,7 +198,7 @@ feature '
scenario "creating new variants" do
# Given a product without variants or a unit
p = FactoryBot.create(:product, variant_unit: 'weight', variant_unit_scale: 1000)
- quick_login_as_admin
+ login_as_admin
visit spree.admin_products_path
# I should see an add variant button
@@ -250,7 +249,7 @@ feature '
t2 = FactoryBot.create(:taxon)
p = FactoryBot.create(:product, supplier: s1, available_on: Date.current, variant_unit: 'volume', variant_unit_scale: 1, primary_taxon: t2, sku: "OLD SKU")
- quick_login_as_admin
+ login_as_admin
visit spree.admin_products_path
toggle_columns "Available On", /^Category?/, "Inherits Properties?", "SKU"
@@ -290,7 +289,7 @@ feature '
scenario "updating a product with a variant unit of 'items'" do
p = FactoryBot.create(:product, variant_unit: 'weight', variant_unit_scale: 1000)
- quick_login_as_admin
+ login_as_admin
visit spree.admin_products_path
expect(page).to have_select "variant_unit_with_scale", selected: "Weight (kg)"
@@ -317,7 +316,7 @@ feature '
v.update_attribute(:on_demand, false)
v.update_attribute(:on_hand, 9)
- quick_login_as_admin
+ login_as_admin
visit spree.admin_products_path
expect(page).to have_selector "a.view-variants", count: 1
find("a.view-variants").click
@@ -353,7 +352,7 @@ feature '
p = FactoryBot.create(:product)
v = FactoryBot.create(:variant, product: p, price: 3.0)
- quick_login_as_admin
+ login_as_admin
visit spree.admin_products_path
expect(page).to have_selector "a.view-variants", count: 1
find("a.view-variants").click
@@ -376,7 +375,7 @@ feature '
scenario "updating a product mutiple times without refresh" do
p = FactoryBot.create(:product, name: 'original name')
- quick_login_as_admin
+ login_as_admin
visit spree.admin_products_path
@@ -409,7 +408,7 @@ feature '
scenario "updating a product after cloning a product" do
p = FactoryBot.create(:product, name: "product 1")
- quick_login_as_admin
+ login_as_admin
visit spree.admin_products_path
@@ -435,7 +434,7 @@ feature '
s2 = create(:supplier_enterprise)
p1 = FactoryBot.create(:simple_product, name: "product1", supplier: s1)
p2 = FactoryBot.create(:simple_product, name: "product2", supplier: s2)
- quick_login_as_admin
+ login_as_admin
visit spree.admin_products_path
@@ -463,7 +462,7 @@ feature '
let!(:v3) { FactoryBot.create(:variant, product: p2 ) }
before do
- quick_login_as_admin
+ login_as_admin
visit spree.admin_products_path
end
@@ -512,8 +511,7 @@ feature '
let!(:v2) { p2.variants.first }
before do
- quick_login_as_admin
- visit spree.admin_products_path
+ login_as_admin_and_visit spree.admin_products_path
end
it "shows an edit button for products, which takes the user to the standard edit page for that product in a new window" do
@@ -555,9 +553,8 @@ feature '
p1 = FactoryBot.create(:product, name: "P1")
p2 = FactoryBot.create(:product, name: "P2")
p3 = FactoryBot.create(:product, name: "P3")
- quick_login_as_admin
- visit spree.admin_products_path
+ login_as_admin_and_visit spree.admin_products_path
expect(page).to have_selector "a.clone-product", count: 3
@@ -581,9 +578,7 @@ feature '
describe "using column display dropdown" do
it "shows a column display dropdown, which shows a list of columns when clicked" do
FactoryBot.create(:simple_product)
- quick_login_as_admin
-
- visit spree.admin_products_path
+ login_as_admin_and_visit spree.admin_products_path
toggle_columns "Available On"
@@ -609,9 +604,8 @@ feature '
s2 = create(:supplier_enterprise)
p1 = FactoryBot.create(:simple_product, name: "product1", supplier: s1)
p2 = FactoryBot.create(:simple_product, name: "product2", supplier: s2)
- quick_login_as_admin
- visit spree.admin_products_path
+ login_as_admin_and_visit spree.admin_products_path
# Page shows the filter controls
expect(page).to have_select "producer_filter", visible: false
@@ -658,7 +652,7 @@ feature '
end
before do
- @enterprise_user = create_enterprise_user
+ @enterprise_user = create(:user)
@enterprise_user.enterprise_roles.build(enterprise: supplier_managed1).save
@enterprise_user.enterprise_roles.build(enterprise: supplier_managed2).save
@enterprise_user.enterprise_roles.build(enterprise: distributor_managed).save
@@ -762,8 +756,7 @@ feature '
let!(:product) { create(:simple_product, name: "Carrots") }
it "displays product images and image upload modal" do
- quick_login_as_admin
- visit spree.admin_products_path
+ login_as_admin_and_visit spree.admin_products_path
within "table#listing_products tr#p_#{product.id}" do
# Displays product images
diff --git a/spec/features/admin/configuration/general_settings_spec.rb b/spec/features/admin/configuration/general_settings_spec.rb
index 4dcc8ab63a..e676f32801 100644
--- a/spec/features/admin/configuration/general_settings_spec.rb
+++ b/spec/features/admin/configuration/general_settings_spec.rb
@@ -1,11 +1,10 @@
require 'spec_helper'
describe "General Settings" do
- include AuthenticationWorkflow
+ include AuthenticationHelper
before(:each) do
- quick_login_as_admin
- visit spree.admin_dashboard_path
+ login_as_admin_and_visit spree.admin_dashboard_path
click_link "Configuration"
click_link "General Settings"
end
diff --git a/spec/features/admin/configuration/image_settings_spec.rb b/spec/features/admin/configuration/image_settings_spec.rb
index 858f53c677..5c87e8e6ad 100644
--- a/spec/features/admin/configuration/image_settings_spec.rb
+++ b/spec/features/admin/configuration/image_settings_spec.rb
@@ -1,11 +1,10 @@
require 'spec_helper'
describe "image settings" do
- include AuthenticationWorkflow
+ include AuthenticationHelper
before do
- quick_login_as_admin
- visit spree.admin_dashboard_path
+ login_as_admin_and_visit spree.admin_dashboard_path
click_link "Configuration"
click_link "Image Settings"
end
diff --git a/spec/features/admin/configuration/mail_methods_spec.rb b/spec/features/admin/configuration/mail_methods_spec.rb
index d1e550db02..27d044d894 100644
--- a/spec/features/admin/configuration/mail_methods_spec.rb
+++ b/spec/features/admin/configuration/mail_methods_spec.rb
@@ -1,12 +1,10 @@
require 'spec_helper'
describe "Mail Methods" do
- include AuthenticationWorkflow
+ include AuthenticationHelper
before(:each) do
- quick_login_as_admin
- visit spree.admin_dashboard_path
- click_link "Configuration"
+ login_as_admin_and_visit spree.edit_admin_general_settings_path
end
context "edit" do
diff --git a/spec/features/admin/configuration/states_spec.rb b/spec/features/admin/configuration/states_spec.rb
index b762b33c84..e3a761088d 100755
--- a/spec/features/admin/configuration/states_spec.rb
+++ b/spec/features/admin/configuration/states_spec.rb
@@ -1,12 +1,12 @@
require 'spec_helper'
describe "States" do
- include AuthenticationWorkflow
+ include AuthenticationHelper
let!(:country) { create(:country) }
before(:each) do
- quick_login_as_admin
+ login_as_admin
@hungary = Spree::Country.create!(name: "Hungary", iso_name: "Hungary")
Spree::Config[:default_country_id] = country.id
end
diff --git a/spec/features/admin/configuration/tax_categories_spec.rb b/spec/features/admin/configuration/tax_categories_spec.rb
index 4248ff2596..9e5d2f3823 100644
--- a/spec/features/admin/configuration/tax_categories_spec.rb
+++ b/spec/features/admin/configuration/tax_categories_spec.rb
@@ -1,12 +1,10 @@
require 'spec_helper'
describe "Tax Categories" do
- include AuthenticationWorkflow
+ include AuthenticationHelper
before(:each) do
- quick_login_as_admin
- visit spree.admin_dashboard_path
- click_link "Configuration"
+ login_as_admin_and_visit spree.edit_admin_general_settings_path
end
context "admin visiting tax categories list" do
diff --git a/spec/features/admin/configuration/tax_rates_spec.rb b/spec/features/admin/configuration/tax_rates_spec.rb
index c4d11716c2..56ff8fac73 100644
--- a/spec/features/admin/configuration/tax_rates_spec.rb
+++ b/spec/features/admin/configuration/tax_rates_spec.rb
@@ -1,15 +1,13 @@
require 'spec_helper'
describe "Tax Rates" do
- include AuthenticationWorkflow
+ include AuthenticationHelper
let!(:calculator) { create(:calculator_per_item, calculable: create(:order)) }
let!(:tax_rate) { create(:tax_rate, calculator: calculator) }
before do
- quick_login_as_admin
- visit spree.admin_dashboard_path
- click_link "Configuration"
+ login_as_admin_and_visit spree.edit_admin_general_settings_path
end
# Regression test for #535
diff --git a/spec/features/admin/configuration/taxonomies_spec.rb b/spec/features/admin/configuration/taxonomies_spec.rb
index 6e871e3529..f26b320be3 100644
--- a/spec/features/admin/configuration/taxonomies_spec.rb
+++ b/spec/features/admin/configuration/taxonomies_spec.rb
@@ -1,12 +1,10 @@
require 'spec_helper'
describe "Taxonomies" do
- include AuthenticationWorkflow
+ include AuthenticationHelper
before(:each) do
- quick_login_as_admin
- visit spree.admin_dashboard_path
- click_link "Configuration"
+ login_as_admin_and_visit spree.edit_admin_general_settings_path
end
context "show" do
diff --git a/spec/features/admin/configuration/zones_spec.rb b/spec/features/admin/configuration/zones_spec.rb
index 11b3f92649..1c03ff0941 100644
--- a/spec/features/admin/configuration/zones_spec.rb
+++ b/spec/features/admin/configuration/zones_spec.rb
@@ -1,19 +1,18 @@
require 'spec_helper'
describe "Zones" do
- include AuthenticationWorkflow
+ include AuthenticationHelper
before do
- quick_login_as_admin
+ login_as_admin
Spree::Zone.delete_all
end
scenario "list existing zones" do
- visit spree.admin_dashboard_path
- click_link "Configuration"
-
+ visit spree.edit_admin_general_settings_path
create(:zone, name: "eastern", description: "zone is eastern")
create(:zone, name: "western", description: "cool san fran")
+
click_link "Zones"
within_row(1) { expect(page).to have_content("eastern") }
diff --git a/spec/features/admin/content_spec.rb b/spec/features/admin/content_spec.rb
index 75dd4ad656..cdc4971839 100644
--- a/spec/features/admin/content_spec.rb
+++ b/spec/features/admin/content_spec.rb
@@ -4,12 +4,11 @@ feature '
As a site administrator
I want to configure the site content
' do
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
before do
- login_to_admin_section
- click_link 'Configuration'
+ login_as_admin_and_visit spree.edit_admin_general_settings_path
click_link 'Content'
end
diff --git a/spec/features/admin/customers_spec.rb b/spec/features/admin/customers_spec.rb
index a78e5b70e4..4674504e2a 100644
--- a/spec/features/admin/customers_spec.rb
+++ b/spec/features/admin/customers_spec.rb
@@ -2,11 +2,11 @@ require 'spec_helper'
feature 'Customers' do
include AdminHelper
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
context "as an enterprise user" do
- let(:user) { create_enterprise_user(enterprise_limit: 10) }
+ let(:user) { create(:user, enterprise_limit: 10) }
let(:managed_distributor1) { create(:distributor_enterprise, owner: user) }
let(:managed_distributor2) { create(:distributor_enterprise, owner: user) }
let(:unmanaged_distributor) { create(:distributor_enterprise) }
@@ -18,7 +18,7 @@ feature 'Customers' do
let!(:customer4) { create(:customer, enterprise: managed_distributor2) }
before do
- quick_login_as user
+ login_as user
visit admin_customers_path
end
diff --git a/spec/features/admin/enterprise_fees_spec.rb b/spec/features/admin/enterprise_fees_spec.rb
index a231f272e5..a525ae854a 100644
--- a/spec/features/admin/enterprise_fees_spec.rb
+++ b/spec/features/admin/enterprise_fees_spec.rb
@@ -4,8 +4,8 @@ feature '
As an administrator
I want to manage enterprise fees
', js: true do
- include AuthenticationWorkflow
include WebHelper
+ include AuthenticationHelper
let!(:tax_category_gst) { create(:tax_category, name: 'GST') }
@@ -13,8 +13,7 @@ feature '
fee = create(:enterprise_fee, name: '$0.50 / kg', fee_type: 'packing', tax_category: tax_category_gst)
amount = fee.calculator.preferred_amount
- login_to_admin_section
- click_link 'Configuration'
+ login_as_admin_and_visit spree.edit_admin_general_settings_path
click_link 'Enterprise Fees'
expect(page).to have_select "enterprise_fee_set_collection_attributes_0_enterprise_id"
@@ -30,8 +29,7 @@ feature '
e = create(:supplier_enterprise, name: 'Feedme')
# When I go to the enterprise fees page
- quick_login_as_admin
- visit admin_enterprise_fees_path
+ login_as_admin_and_visit admin_enterprise_fees_path
# And I fill in the fields for a new enterprise fee and click update
select 'Feedme', from: 'enterprise_fee_set_collection_attributes_0_enterprise_id'
@@ -59,8 +57,7 @@ feature '
enterprise = create(:enterprise, name: 'Foo')
# When I go to the enterprise fees page
- quick_login_as_admin
- visit admin_enterprise_fees_path
+ login_as_admin_and_visit admin_enterprise_fees_path
# And I update the fields for the enterprise fee and click update
select 'Foo', from: 'enterprise_fee_set_collection_attributes_0_enterprise_id'
@@ -93,8 +90,7 @@ feature '
fee = create(:enterprise_fee)
# When I go to the enterprise fees page
- quick_login_as_admin
- visit admin_enterprise_fees_path
+ login_as_admin_and_visit admin_enterprise_fees_path
# And I click delete
accept_alert do
@@ -107,7 +103,7 @@ feature '
end
context "as an enterprise manager" do
- let(:enterprise_user) { create_enterprise_user }
+ let(:enterprise_user) { create(:user) }
let(:distributor1) { create(:distributor_enterprise, name: 'First Distributor') }
let(:distributor2) { create(:distributor_enterprise, name: 'Second Distributor') }
let(:distributor3) { create(:distributor_enterprise, name: 'Third Distributor') }
@@ -117,7 +113,7 @@ feature '
before(:each) do
enterprise_user.enterprise_roles.build(enterprise: distributor1).save
enterprise_user.enterprise_roles.build(enterprise: distributor2).save
- quick_login_as enterprise_user
+ login_as enterprise_user
end
it "creates enterprise fees" do
diff --git a/spec/features/admin/enterprise_groups_spec.rb b/spec/features/admin/enterprise_groups_spec.rb
index c6fa57b055..ff19b44f17 100644
--- a/spec/features/admin/enterprise_groups_spec.rb
+++ b/spec/features/admin/enterprise_groups_spec.rb
@@ -4,8 +4,8 @@ feature '
As an administrator
I want to manage enterprise groups
' do
- include AuthenticationWorkflow
include WebHelper
+ include AuthenticationHelper
before(:each) do
login_to_admin_section
@@ -107,12 +107,12 @@ feature '
end
context "as an enterprise user" do
- let(:user) { create_enterprise_user }
+ let(:user) { create(:user) }
let!(:enterprise) { create(:distributor_enterprise, owner: user) }
let!(:group) { create(:enterprise_group, name: 'My Group', owner: user) }
it "lets me access enterprise groups" do
- quick_login_as user
+ login_as user
visit spree.admin_dashboard_path
click_link 'Groups'
expect(page).to have_content 'My Group'
diff --git a/spec/features/admin/enterprise_relationships_spec.rb b/spec/features/admin/enterprise_relationships_spec.rb
index 1926503045..3dd00acbae 100644
--- a/spec/features/admin/enterprise_relationships_spec.rb
+++ b/spec/features/admin/enterprise_relationships_spec.rb
@@ -4,11 +4,11 @@ feature '
As an Administrator
I want to manage relationships between enterprises
', js: true do
- include AuthenticationWorkflow
include WebHelper
+ include AuthenticationHelper
context "as a site administrator" do
- before { quick_login_as_admin }
+ before { login_as_admin }
scenario "listing relationships" do
# Given some enterprises with relationships
@@ -92,13 +92,13 @@ feature '
let!(:d1) { create(:distributor_enterprise) }
let!(:d2) { create(:distributor_enterprise) }
let!(:d3) { create(:distributor_enterprise) }
- let(:enterprise_user) { create_enterprise_user( enterprises: [d1] ) }
+ let(:enterprise_user) { create(:user, enterprises: [d1] ) }
let!(:er1) { create(:enterprise_relationship, parent: d1, child: d2) }
let!(:er2) { create(:enterprise_relationship, parent: d2, child: d1) }
let!(:er3) { create(:enterprise_relationship, parent: d2, child: d3) }
- before { quick_login_as enterprise_user }
+ before { login_as enterprise_user }
scenario "enterprise user can only see relationships involving their enterprises" do
visit admin_enterprise_relationships_path
diff --git a/spec/features/admin/enterprise_roles_spec.rb b/spec/features/admin/enterprise_roles_spec.rb
index ff29207aeb..2e7c2775a1 100644
--- a/spec/features/admin/enterprise_roles_spec.rb
+++ b/spec/features/admin/enterprise_roles_spec.rb
@@ -4,7 +4,7 @@ feature '
As an Administrator
I want to manage relationships between users and enterprises
', js: true do
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
include OpenFoodNetwork::EmailHelper
diff --git a/spec/features/admin/enterprise_user_spec.rb b/spec/features/admin/enterprise_user_spec.rb
index 6b4f4dd778..30b3907970 100644
--- a/spec/features/admin/enterprise_user_spec.rb
+++ b/spec/features/admin/enterprise_user_spec.rb
@@ -4,10 +4,10 @@ feature '
As a Super User
I want to setup users to manage an enterprise
' do
- include AuthenticationWorkflow
include WebHelper
+ include AuthenticationHelper
- let!(:user) { create_enterprise_user }
+ let!(:user) { create(:user) }
let!(:supplier1) { create(:supplier_enterprise, name: 'Supplier 1') }
let!(:supplier2) { create(:supplier_enterprise, name: 'Supplier 2') }
let(:supplier_profile) { create(:supplier_enterprise, name: 'Supplier profile', sells: 'none') }
@@ -19,8 +19,7 @@ feature '
context "with a limitted number of owned enterprises" do
scenario "setting the enterprise ownership limit" do
expect(user.enterprise_limit).to eq 5
- login_to_admin_section
- click_link 'Users'
+ login_as_admin_and_visit spree.admin_users_path
click_link user.email
fill_in "user_enterprise_limit", with: 2
@@ -35,7 +34,7 @@ feature '
describe "system management lockdown" do
before do
user.enterprise_roles.create!(enterprise: supplier1)
- quick_login_as user
+ login_as user
end
scenario "should not be able to see system configuration" do
diff --git a/spec/features/admin/enterprises/images_spec.rb b/spec/features/admin/enterprises/images_spec.rb
index 110b8c2664..0d4644f8c7 100644
--- a/spec/features/admin/enterprises/images_spec.rb
+++ b/spec/features/admin/enterprises/images_spec.rb
@@ -1,17 +1,17 @@
require "spec_helper"
feature "Managing enterprise images" do
- include AuthenticationWorkflow
include WebHelper
+ include AuthenticationHelper
context "as an Enterprise user", js: true do
- let(:enterprise_user) { create_enterprise_user(enterprise_limit: 1) }
+ let(:enterprise_user) { create(:user, enterprise_limit: 1) }
let(:distributor) { create(:distributor_enterprise, name: "First Distributor") }
before do
enterprise_user.enterprise_roles.build(enterprise: distributor).save!
- quick_login_as enterprise_user
+ login_as enterprise_user
visit edit_admin_enterprise_path(distributor)
end
diff --git a/spec/features/admin/enterprises/index_spec.rb b/spec/features/admin/enterprises/index_spec.rb
index b4897cbb11..550879d3c1 100644
--- a/spec/features/admin/enterprises/index_spec.rb
+++ b/spec/features/admin/enterprises/index_spec.rb
@@ -1,16 +1,15 @@
require 'spec_helper'
feature 'Enterprises Index' do
- include AuthenticationWorkflow
include WebHelper
+ include AuthenticationHelper
context "as an admin user" do
scenario "listing enterprises" do
s = create(:supplier_enterprise)
d = create(:distributor_enterprise)
- login_to_admin_section
- click_link 'Enterprises'
+ login_as_admin_and_visit admin_enterprises_path
within("tr.enterprise-#{s.id}") do
expect(page).to have_content s.name
@@ -36,7 +35,7 @@ feature 'Enterprises Index' do
context "editing enterprises in bulk" do
let!(:s){ create(:supplier_enterprise) }
let!(:d){ create(:distributor_enterprise, sells: 'none') }
- let!(:d_manager) { create_enterprise_user(enterprise_limit: 1) }
+ let!(:d_manager) { create(:user, enterprise_limit: 1) }
before do
d_manager.enterprise_roles.build(enterprise: d).save
@@ -45,8 +44,7 @@ feature 'Enterprises Index' do
context "without violating rules" do
before do
- quick_login_as_admin
- visit admin_enterprises_path
+ login_as_admin_and_visit admin_enterprises_path
end
it "updates the enterprises" do
@@ -72,8 +70,7 @@ feature 'Enterprises Index' do
d_manager.enterprise_roles.build(enterprise: second_distributor).save
expect(d.owner).to_not eq d_manager
- quick_login_as_admin
- visit admin_enterprises_path
+ login_as_admin_and_visit admin_enterprises_path
end
def enterprise_row_index(enterprise_name)
@@ -107,14 +104,14 @@ feature 'Enterprises Index' do
let(:distributor1) { create(:distributor_enterprise, name: 'First Distributor') }
let(:distributor2) { create(:distributor_enterprise, name: 'Another Distributor') }
let(:distributor3) { create(:distributor_enterprise, name: 'Yet Another Distributor') }
- let(:enterprise_manager) { create_enterprise_user }
+ let(:enterprise_manager) { create(:user) }
let!(:er) { create(:enterprise_relationship, parent: distributor3, child: distributor1, permissions_list: [:edit_profile]) }
before(:each) do
enterprise_manager.enterprise_roles.build(enterprise: supplier1).save
enterprise_manager.enterprise_roles.build(enterprise: distributor1).save
- quick_login_as enterprise_manager
+ login_as enterprise_manager
end
context "listing enterprises", js: true do
@@ -165,11 +162,11 @@ feature 'Enterprises Index' do
end
describe "as the owner of an enterprise" do
- let!(:user) { create_enterprise_user }
+ let!(:user) { create(:user) }
let!(:owned_distributor) { create(:distributor_enterprise, name: 'Owned Distributor', owner: user) }
before do
- quick_login_as user
+ login_as user
end
context "listing enterprises", js: true do
diff --git a/spec/features/admin/enterprises_spec.rb b/spec/features/admin/enterprises_spec.rb
index 4244e265e7..be7e9ddfa9 100644
--- a/spec/features/admin/enterprises_spec.rb
+++ b/spec/features/admin/enterprises_spec.rb
@@ -4,8 +4,8 @@ feature '
As an administrator
I want to manage enterprises
' do
- include AuthenticationWorkflow
include WebHelper
+ include AuthenticationHelper
scenario "viewing an enterprise" do
e = create(:enterprise)
@@ -25,7 +25,7 @@ feature '
enterprise_fee = create(:enterprise_fee)
# Navigating
- admin = quick_login_as_admin
+ admin = login_as_admin
visit '/admin/enterprises'
click_link 'New Enterprise'
@@ -66,7 +66,7 @@ feature '
enterprise_fee = create(:enterprise_fee, enterprise: @enterprise )
user = create(:user)
- admin = quick_login_as_admin
+ admin = login_as_admin
visit '/admin/enterprises'
within "tr.enterprise-#{@enterprise.id}" do
@@ -219,8 +219,7 @@ feature '
s = create(:supplier_enterprise)
# When I go to its properties page
- quick_login_as_admin
- visit admin_enterprises_path
+ login_as_admin_and_visit admin_enterprises_path
within(".enterprise-#{s.id}") { click_link 'Properties' }
# And I create a property
@@ -243,8 +242,7 @@ feature '
s.producer_properties.create! property_name: 'Certified Organic', value: 'NASAA 12345'
# When I go to its properties page
- quick_login_as_admin
- visit main_app.admin_enterprise_producer_properties_path(s)
+ login_as_admin_and_visit main_app.admin_enterprise_producer_properties_path(s)
# And I update the property
fill_in 'enterprise_producer_properties_attributes_0_property_name', with: "Biodynamic"
@@ -266,8 +264,7 @@ feature '
pp = s.producer_properties.create! property_name: 'Certified Organic', value: 'NASAA 12345'
# When I go to its properties page
- quick_login_as_admin
- visit main_app.admin_enterprise_producer_properties_path(s)
+ login_as_admin_and_visit main_app.admin_enterprise_producer_properties_path(s)
# And I remove the property
expect(page).to have_field 'enterprise_producer_properties_attributes_0_property_name', with: 'Certified Organic'
@@ -287,14 +284,14 @@ feature '
let(:distributor1) { create(:distributor_enterprise, name: 'First Distributor') }
let(:distributor2) { create(:distributor_enterprise, name: 'Another Distributor') }
let(:distributor3) { create(:distributor_enterprise, name: 'Yet Another Distributor') }
- let(:enterprise_user) { create_enterprise_user(enterprise_limit: 1) }
+ let(:enterprise_user) { create(:user, enterprise_limit: 1) }
let!(:er) { create(:enterprise_relationship, parent: distributor3, child: distributor1, permissions_list: [:edit_profile]) }
before(:each) do
enterprise_user.enterprise_roles.build(enterprise: supplier1).save
enterprise_user.enterprise_roles.build(enterprise: distributor1).save
- quick_login_as enterprise_user
+ login_as enterprise_user
end
context "when I have reached my enterprise ownership limit" do
diff --git a/spec/features/admin/external_services_spec.rb b/spec/features/admin/external_services_spec.rb
index 3a9a72610e..ceeef4c556 100644
--- a/spec/features/admin/external_services_spec.rb
+++ b/spec/features/admin/external_services_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'External services' do
- include AuthenticationWorkflow
+ include AuthenticationHelper
describe "bugherd" do
before do
diff --git a/spec/features/admin/image_settings_spec.rb b/spec/features/admin/image_settings_spec.rb
index 9ef2860cd4..83e584a0ce 100644
--- a/spec/features/admin/image_settings_spec.rb
+++ b/spec/features/admin/image_settings_spec.rb
@@ -4,7 +4,7 @@ feature '
As an admin
I want to manage image formats
' do
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
before(:all) do
@@ -20,8 +20,7 @@ feature '
scenario "setting the image format for a paperclip style" do
# When I go to the image settings page
- login_to_admin_section
- visit spree.edit_admin_image_settings_path
+ login_as_admin_and_visit spree.edit_admin_image_settings_path
# All the styles should default to "Unchanged"
expect(page).to have_select 'attachment_styles_format_mini', selected: 'Unchanged'
diff --git a/spec/features/admin/multilingual_spec.rb b/spec/features/admin/multilingual_spec.rb
index 90d21d1ecd..32e4684936 100644
--- a/spec/features/admin/multilingual_spec.rb
+++ b/spec/features/admin/multilingual_spec.rb
@@ -1,14 +1,14 @@
require 'spec_helper'
feature 'Multilingual', js: true do
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
let(:admin_role) { Spree::Role.find_or_create_by!(name: 'admin') }
let(:admin_user) { create(:user) }
background do
admin_user.spree_roles << admin_role
- quick_login_as admin_user
+ login_as admin_user
visit spree.admin_dashboard_path
end
diff --git a/spec/features/admin/order_cycles/complex_creating_specific_time_spec.rb b/spec/features/admin/order_cycles/complex_creating_specific_time_spec.rb
index 39130fa434..237764eaae 100644
--- a/spec/features/admin/order_cycles/complex_creating_specific_time_spec.rb
+++ b/spec/features/admin/order_cycles/complex_creating_specific_time_spec.rb
@@ -7,7 +7,7 @@ feature '
I want to create/update complex order cycles with a specific time
', js: true do
include AdminHelper
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
let(:order_cycle_opening_time) { Time.zone.local(2040, 11, 0o6, 0o6, 0o0, 0o0).strftime("%F %T %z") }
@@ -33,8 +33,7 @@ feature '
distributor_fee = create(:enterprise_fee, enterprise: distributor, name: 'Distributor fee')
# When I go to the new order cycle page
- quick_login_as_admin
- visit admin_order_cycles_path
+ login_as_admin_and_visit admin_order_cycles_path
click_link 'New Order Cycle'
# Select a coordinator since there are two available
diff --git a/spec/features/admin/order_cycles/complex_editing_exchange_same_enterprise_spec.rb b/spec/features/admin/order_cycles/complex_editing_exchange_same_enterprise_spec.rb
index 484dd21f40..ef0d1c5f95 100644
--- a/spec/features/admin/order_cycles/complex_editing_exchange_same_enterprise_spec.rb
+++ b/spec/features/admin/order_cycles/complex_editing_exchange_same_enterprise_spec.rb
@@ -7,7 +7,7 @@ feature '
I want to manage complex order cycles
', js: true do
include AdminHelper
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
scenario "editing an order cycle with an exchange between the same enterprise" do
@@ -20,8 +20,7 @@ feature '
oc_outgoing = create(:simple_order_cycle, coordinator: c, distributors: [c])
# When I edit the first order cycle, the exchange should appear as incoming
- quick_login_as_admin
- visit admin_order_cycle_incoming_path(oc_incoming)
+ login_as_admin_and_visit admin_order_cycle_incoming_path(oc_incoming)
expect(page).to have_selector 'table.exchanges tr.supplier'
visit admin_order_cycle_outgoing_path(oc_incoming)
expect(page).not_to have_selector 'table.exchanges tr.distributor'
diff --git a/spec/features/admin/order_cycles/complex_editing_multiple_product_pages_spec.rb b/spec/features/admin/order_cycles/complex_editing_multiple_product_pages_spec.rb
index 5ff181e7f5..c13e0dd8b1 100644
--- a/spec/features/admin/order_cycles/complex_editing_multiple_product_pages_spec.rb
+++ b/spec/features/admin/order_cycles/complex_editing_multiple_product_pages_spec.rb
@@ -7,7 +7,7 @@ feature '
I want to manage complex order cycles
', js: true do
include AdminHelper
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
describe "editing an order cycle with multiple pages of products", js: true do
@@ -18,8 +18,7 @@ feature '
before do
stub_const("#{Api::ExchangeProductsController}::DEFAULT_PER_PAGE", 1)
- quick_login_as_admin
- visit admin_order_cycle_incoming_path(order_cycle)
+ login_as_admin_and_visit admin_order_cycle_incoming_path(order_cycle)
expect(page).to have_content "1 / 2 selected"
page.find("tr.supplier-#{supplier_enterprise.id} td.products").click
diff --git a/spec/features/admin/order_cycles/complex_editing_spec.rb b/spec/features/admin/order_cycles/complex_editing_spec.rb
index 72eb521554..4b9aa275fc 100644
--- a/spec/features/admin/order_cycles/complex_editing_spec.rb
+++ b/spec/features/admin/order_cycles/complex_editing_spec.rb
@@ -7,7 +7,7 @@ feature '
I want to manage complex order cycles
', js: true do
include AdminHelper
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
scenario "editing an order cycle" do
@@ -19,8 +19,7 @@ feature '
oc.distributors.last.update_attribute :name, 'ZZZZ'
# When I edit it
- quick_login_as_admin
- visit edit_admin_order_cycle_path(oc)
+ login_as_admin_and_visit edit_admin_order_cycle_path(oc)
wait_for_edit_form_to_load_order_cycle(oc)
diff --git a/spec/features/admin/order_cycles/complex_updating_specific_time_spec.rb b/spec/features/admin/order_cycles/complex_updating_specific_time_spec.rb
index 2094a83f7e..dfa2946d97 100644
--- a/spec/features/admin/order_cycles/complex_updating_specific_time_spec.rb
+++ b/spec/features/admin/order_cycles/complex_updating_specific_time_spec.rb
@@ -7,7 +7,7 @@ feature '
I want to create/update complex order cycles with a specific time
', js: true do
include AdminHelper
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
let(:order_cycle_opening_time) { Time.zone.local(2040, 11, 0o6, 0o6, 0o0, 0o0).strftime("%F %T %z") }
@@ -40,8 +40,7 @@ feature '
distributor_fee2 = create(:enterprise_fee, enterprise: distributor, name: 'Distributor fee 2')
# When I go to its edit page
- quick_login_as_admin
- visit admin_order_cycles_path
+ login_as_admin_and_visit admin_order_cycles_path
within "tr.order-cycle-#{oc.id}" do
find("a.edit-order-cycle").click
end
diff --git a/spec/features/admin/order_cycles/list_spec.rb b/spec/features/admin/order_cycles/list_spec.rb
index d675984dd8..a7a4890511 100644
--- a/spec/features/admin/order_cycles/list_spec.rb
+++ b/spec/features/admin/order_cycles/list_spec.rb
@@ -7,7 +7,7 @@ feature '
I want to list and filter order cycles
', js: true do
include AdminHelper
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
scenario "listing and filtering order cycles" do
@@ -30,8 +30,7 @@ feature '
create(:proxy_order, subscription: create(:subscription, schedule: schedule1), order_cycle: oc1)
# When I go to the admin order cycles page
- login_to_admin_section
- click_link 'Order Cycles'
+ login_as_admin_and_visit admin_order_cycles_path
# Then the order cycles should be ordered correctly
expect(page).to have_selector "#listing_order_cycles tr td:first-child", count: 7
@@ -129,8 +128,7 @@ feature '
context 'using datepickers' do
it "correctly opens the datepicker and changes the date field" do
- quick_login_as_admin
- visit admin_order_cycles_path
+ login_as_admin_and_visit admin_order_cycles_path
within("tr.order-cycle-#{oc_pt.id}") do
expect(find('input.datetimepicker', match: :first).value).to start_with '2012-01-01 00:00'
diff --git a/spec/features/admin/order_cycles/simple_spec.rb b/spec/features/admin/order_cycles/simple_spec.rb
index 0d6872c19c..1f22485f4c 100644
--- a/spec/features/admin/order_cycles/simple_spec.rb
+++ b/spec/features/admin/order_cycles/simple_spec.rb
@@ -7,7 +7,7 @@ feature '
I want to manage simple order cycles
', js: true do
include AdminHelper
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
scenario "updating many order cycle opening/closing times at once", js: true do
@@ -19,8 +19,7 @@ feature '
orders_close_at: Time.zone.local(2041, 12, 12, 12, 12, 12))
# When I go to the order cycles page
- quick_login_as_admin
- visit admin_order_cycles_path
+ login_as_admin_and_visit admin_order_cycles_path
# And I fill in some new opening/closing times and save them
within("tr.order-cycle-#{oc1.id}") do
@@ -77,8 +76,7 @@ feature '
oc = create(:simple_order_cycle)
# When I clone it
- quick_login_as_admin
- visit admin_order_cycles_path
+ login_as_admin_and_visit admin_order_cycles_path
within "tr.order-cycle-#{oc.id}" do
find('a.clone-order-cycle').click
end
@@ -100,8 +98,7 @@ feature '
end
it "displays a warning on the order cycles screen" do
- quick_login_as_admin
- visit admin_order_cycles_path
+ login_as_admin_and_visit admin_order_cycles_path
expect(page).to have_content "The hub #{hub.name} is listed in an active order cycle, but does not have valid shipping and payment methods. Until you set these up, customers will not be able to shop at this hub."
end
end
@@ -151,12 +148,12 @@ feature '
context "that is a manager of the coordinator" do
before do
- @new_user = create_enterprise_user
+ @new_user = create(:user)
@new_user.enterprise_roles.build(enterprise: supplier_managed).save
@new_user.enterprise_roles.build(enterprise: distributor_managed).save
@new_user.enterprise_roles.build(enterprise: other_distributor_managed).save
- quick_login_as @new_user
+ login_as @new_user
end
scenario "viewing a list of order cycles I am coordinating" do
@@ -288,7 +285,7 @@ feature '
end
context "that is a manager of a participating producer" do
- let(:new_user) { create_enterprise_user }
+ let(:new_user) { create(:user) }
before do
new_user.enterprise_roles.build(enterprise: supplier_managed).save
@@ -354,7 +351,7 @@ feature '
context "that is the manager of a participating hub" do
let(:my_distributor) { create(:distributor_enterprise) }
- let(:new_user) { create_enterprise_user }
+ let(:new_user) { create(:user) }
before do
create(:enterprise_relationship, parent: supplier_managed, child: my_distributor, permissions_list: [:add_to_order_cycle])
@@ -419,7 +416,7 @@ feature '
end
describe "simplified interface for enterprise users selling only their own produce" do
- let(:user) { create_enterprise_user }
+ let(:user) { create(:user) }
let(:enterprise) { create(:enterprise, is_primary_producer: true, sells: 'own') }
let!(:p1) { create(:simple_product, supplier: enterprise) }
let!(:p2) { create(:simple_product, supplier: enterprise) }
@@ -508,8 +505,7 @@ feature '
ex.update! pickup_time: 'pickup time', pickup_instructions: 'pickup instructions'
# When I edit it
- quick_login_as_admin
- visit admin_order_cycles_path
+ login_as_admin_and_visit admin_order_cycles_path
within "tr.order-cycle-#{oc.id}" do
find("a.edit-order-cycle").click
end
@@ -541,8 +537,7 @@ feature '
ex.update! pickup_time: 'pickup time', pickup_instructions: 'pickup instructions'
# When I edit it
- quick_login_as_admin
- visit edit_admin_order_cycle_path oc
+ login_as_admin_and_visit edit_admin_order_cycle_path oc
wait_for_edit_form_to_load_order_cycle(oc)
@@ -596,8 +591,7 @@ feature '
scenario "deleting an order cycle" do
order_cycle = create(:simple_order_cycle, name: "Translusent Berries")
- quick_login_as_admin
- visit admin_order_cycles_path
+ login_as_admin_and_visit admin_order_cycles_path
expect(page).to have_selector "tr.order-cycle-#{order_cycle.id}"
accept_alert do
first('a.delete-order-cycle').click
diff --git a/spec/features/admin/order_cycles_complex_nav_check_spec.rb b/spec/features/admin/order_cycles_complex_nav_check_spec.rb
index 4d89e16bb1..1814d9f5af 100644
--- a/spec/features/admin/order_cycles_complex_nav_check_spec.rb
+++ b/spec/features/admin/order_cycles_complex_nav_check_spec.rb
@@ -6,15 +6,14 @@ feature '
As an administrator
I want to be alerted when I navigate away from a dirty order cycle form
', js: true do
- include AuthenticationWorkflow
+ include AuthenticationHelper
scenario "alert when navigating away from dirty form" do
# Given a 'complex' order cycle form
oc = create(:order_cycle)
# When I edit the form
- quick_login_as_admin
- visit edit_admin_order_cycle_path(oc)
+ login_as_admin_and_visit edit_admin_order_cycle_path(oc)
wait_for_edit_form_to_load_order_cycle(oc)
diff --git a/spec/features/admin/order_print_ticket_spec.rb b/spec/features/admin/order_print_ticket_spec.rb
index add2ef9e7d..15fd46692a 100644
--- a/spec/features/admin/order_print_ticket_spec.rb
+++ b/spec/features/admin/order_print_ticket_spec.rb
@@ -6,8 +6,8 @@ feature '
As an administrator
I want to print a ticket for an order
', js: true do
- include AuthenticationWorkflow
include CheckoutHelper
+ include AuthenticationHelper
include ActionView::Helpers::NumberHelper
context "as an enterprise manager" do
@@ -24,10 +24,10 @@ feature '
end
before do
- @enterprise_user = create_enterprise_user
+ @enterprise_user = create(:user)
@enterprise_user.enterprise_roles.build(enterprise: distributor).save
- quick_login_as @enterprise_user
+ login_as @enterprise_user
Spree::Config[:enable_receipt_printing?] = true
end
diff --git a/spec/features/admin/order_spec.rb b/spec/features/admin/order_spec.rb
index 009092686b..bfef4f6931 100644
--- a/spec/features/admin/order_spec.rb
+++ b/spec/features/admin/order_spec.rb
@@ -6,8 +6,8 @@ feature '
As an administrator
I want to create and edit orders
', js: true do
- include AuthenticationWorkflow
include WebHelper
+ include AuthenticationHelper
let(:user) { create(:user) }
let(:product) { create(:simple_product) }
@@ -43,8 +43,7 @@ feature '
distributor_disabled = create(:distributor_enterprise)
create(:simple_order_cycle, name: 'Two')
- quick_login_as_admin
- visit spree.admin_orders_path
+ login_as_admin_and_visit spree.admin_orders_path
click_link 'New Order'
# Distributors without an order cycle should be shown as disabled
@@ -79,8 +78,7 @@ feature '
end
scenario "can add a product to an existing order" do
- quick_login_as_admin
- visit spree.edit_admin_order_path(order)
+ login_as_admin_and_visit spree.edit_admin_order_path(order)
targetted_select2_search product.name, from: '#add_variant_id', dropdown_css: '.select2-drop'
@@ -102,8 +100,7 @@ feature '
order.user = nil
order.save
- quick_login_as_admin
- visit spree.edit_admin_order_path(order)
+ login_as_admin_and_visit spree.edit_admin_order_path(order)
expect(page).to have_select2 "order_distributor_id", with_options: [d.name]
select2_select d.name, from: 'order_distributor_id'
@@ -117,15 +114,13 @@ feature '
scenario "can't add products to an order outside the order's hub and order cycle" do
product = create(:simple_product)
- quick_login_as_admin
- visit spree.edit_admin_order_path(order)
+ login_as_admin_and_visit spree.edit_admin_order_path(order)
expect(page).not_to have_select2 "add_variant_id", with_options: [product.name]
end
scenario "can't change distributor or order cycle once order has been finalized" do
- quick_login_as_admin
- visit spree.edit_admin_order_path(order)
+ login_as_admin_and_visit spree.edit_admin_order_path(order)
expect(page).not_to have_select2 'order_distributor_id'
expect(page).not_to have_select2 'order_order_cycle_id'
@@ -149,7 +144,7 @@ feature '
order.shipping_method.update_attribute :require_ship_address, true
# When I create a new order
- quick_login_as user
+ login_as user
new_order_with_distribution(distributor, order_cycle)
targetted_select2_search product.name, from: '#add_variant_id', dropdown_css: '.select2-drop'
find('button.add_variant').click
@@ -187,12 +182,12 @@ feature '
let(:product) { order_cycle1.products.first }
before(:each) do
- @enterprise_user = create_enterprise_user
+ @enterprise_user = create(:user)
@enterprise_user.enterprise_roles.build(enterprise: supplier1).save
@enterprise_user.enterprise_roles.build(enterprise: coordinator1).save
@enterprise_user.enterprise_roles.build(enterprise: distributor1).save
- quick_login_as @enterprise_user
+ login_as @enterprise_user
end
feature "viewing the edit page" do
diff --git a/spec/features/admin/orders_spec.rb b/spec/features/admin/orders_spec.rb
index ea50ddb082..8510ff5943 100644
--- a/spec/features/admin/orders_spec.rb
+++ b/spec/features/admin/orders_spec.rb
@@ -6,7 +6,7 @@ feature '
As an administrator
I want to manage orders
', js: true do
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
let(:user) { create(:user) }
@@ -29,8 +29,7 @@ feature '
create(:simple_order_cycle, name: 'Four', orders_close_at: 4.weeks.from_now)
create(:simple_order_cycle, name: 'Three', orders_close_at: 3.weeks.from_now)
- quick_login_as_admin
- visit 'admin/orders'
+ login_as_admin_and_visit 'admin/orders'
open_select2('#s2id_q_order_cycle_id_in')
@@ -50,8 +49,7 @@ feature '
order4 = create(:order_with_credit_payment, user: user, distributor: distributor,
order_cycle: order_cycle4)
- quick_login_as_admin
- visit 'admin/orders'
+ login_as_admin_and_visit 'admin/orders'
multi_select2_select 'Two', from: 'q_order_cycle_id_in'
multi_select2_select 'Three', from: 'q_order_cycle_id_in'
@@ -71,9 +69,7 @@ feature '
end
scenario "capture payment" do
- quick_login_as_admin
-
- visit spree.admin_orders_path
+ login_as_admin_and_visit spree.admin_orders_path
expect(page).to have_current_path spree.admin_orders_path
# click the 'capture' link for the order
@@ -91,8 +87,7 @@ feature '
scenario "ship order from the orders index page" do
order.payments.first.capture!
- quick_login_as_admin
- visit spree.admin_orders_path
+ login_as_admin_and_visit spree.admin_orders_path
page.find("[data-powertip=Ship]").click
@@ -106,9 +101,7 @@ feature '
scenario "can edit order" do
incomplete_order = create(:order, distributor: distributor, order_cycle: order_cycle)
- quick_login_as_admin
-
- visit spree.admin_orders_path
+ login_as_admin_and_visit spree.admin_orders_path
uncheck 'Only show complete orders'
page.find('a.icon-search').click
diff --git a/spec/features/admin/overview_spec.rb b/spec/features/admin/overview_spec.rb
index 3d472dac2f..3a4a3feb7d 100644
--- a/spec/features/admin/overview_spec.rb
+++ b/spec/features/admin/overview_spec.rb
@@ -4,15 +4,15 @@ feature '
As a backend user
I want to be given information about the state of my enterprises, products and order cycles
', js: true do
- include AuthenticationWorkflow
include WebHelper
+ include AuthenticationHelper
include ::Spree::TestingSupport::AuthorizationHelpers
context "as an enterprise user" do
before do
- @enterprise_user = create_enterprise_user
+ @enterprise_user = create(:user)
allow_any_instance_of(Spree::Admin::OverviewController).to receive(:spree_current_user).and_return @enterprise_user
- quick_login_as @enterprise_user
+ login_as @enterprise_user
end
context "with an enterprise" do
diff --git a/spec/features/admin/payment_method_spec.rb b/spec/features/admin/payment_method_spec.rb
index 356c450611..851c1be1a0 100644
--- a/spec/features/admin/payment_method_spec.rb
+++ b/spec/features/admin/payment_method_spec.rb
@@ -4,8 +4,8 @@ feature '
As a Super Admin
I want to be able to set a distributor on each payment method
' do
- include AuthenticationWorkflow
include WebHelper
+ include AuthenticationHelper
background do
@distributors = (1..3).map { create(:distributor_enterprise) }
@@ -13,9 +13,7 @@ feature '
describe "creating a payment method", js: true do
scenario "assigning a distributor to the payment method" do
- login_to_admin_section
-
- click_link 'Configuration'
+ login_as_admin_and_visit spree.edit_admin_general_settings_path
click_link 'Payment Methods'
click_link 'New Payment Method'
@@ -47,7 +45,7 @@ feature '
end
it "communicates the status of the stripe connection to the user" do
- quick_login_as user
+ login_as user
visit spree.new_admin_payment_method_path
select2_select "Stripe", from: "payment_method_type"
@@ -70,14 +68,12 @@ feature '
scenario "checking a single distributor is checked by default" do
2.times.each { Enterprise.last.destroy }
- quick_login_as_admin
- visit spree.new_admin_payment_method_path
+ login_as_admin_and_visit spree.new_admin_payment_method_path
expect(page).to have_field "payment_method_distributor_ids_#{@distributors[0].id}", checked: true
end
scenario "checking more than a distributor displays no default choice" do
- quick_login_as_admin
- visit spree.new_admin_payment_method_path
+ login_as_admin_and_visit spree.new_admin_payment_method_path
expect(page).to have_field "payment_method_distributor_ids_#{@distributors[0].id}", checked: false
expect(page).to have_field "payment_method_distributor_ids_#{@distributors[1].id}", checked: false
expect(page).to have_field "payment_method_distributor_ids_#{@distributors[2].id}", checked: false
@@ -85,10 +81,9 @@ feature '
end
scenario "updating a payment method", js: true do
- payment_method = create(:payment_method, distributors: [@distributors[0]])
- quick_login_as_admin
-
- visit spree.edit_admin_payment_method_path payment_method
+ payment_method = create(:payment_method, distributors: [@distributors[0]],
+ calculator: build(:calculator_flat_rate))
+ login_as_admin_and_visit spree.edit_admin_payment_method_path payment_method
fill_in 'payment_method_name', with: 'New PM Name'
find(:css, "tags-input .tags input").set "member\n"
@@ -131,7 +126,7 @@ feature '
end
context "as an enterprise user", js: true do
- let(:enterprise_user) { create_enterprise_user }
+ let(:enterprise_user) { create(:user) }
let(:distributor1) { create(:distributor_enterprise, name: 'First Distributor') }
let(:distributor2) { create(:distributor_enterprise, name: 'Second Distributor') }
let(:distributor3) { create(:distributor_enterprise, name: 'Third Distributor') }
@@ -142,7 +137,7 @@ feature '
before(:each) do
enterprise_user.enterprise_roles.build(enterprise: distributor1).save
enterprise_user.enterprise_roles.build(enterprise: distributor2).save
- quick_login_as enterprise_user
+ login_as enterprise_user
end
it "I can get to the new enterprise page" do
diff --git a/spec/features/admin/payments_spec.rb b/spec/features/admin/payments_spec.rb
index adce888db2..851843dc30 100644
--- a/spec/features/admin/payments_spec.rb
+++ b/spec/features/admin/payments_spec.rb
@@ -4,13 +4,12 @@ feature '
As an admin
I want to manage payments
' do
- include AuthenticationWorkflow
+ include AuthenticationHelper
let(:order) { create(:completed_order_with_fees) }
scenario "visiting the payment form" do
- quick_login_as_admin
- visit spree.new_admin_order_payment_path order
+ login_as_admin_and_visit spree.new_admin_order_payment_path order
expect(page).to have_content "New Payment"
end
@@ -26,8 +25,7 @@ feature '
end
scenario "visiting the payment form" do
- quick_login_as_admin
- visit spree.new_admin_order_payment_path order
+ login_as_admin_and_visit spree.new_admin_order_payment_path order
expect(page).to have_content "New Payment"
end
@@ -40,8 +38,7 @@ feature '
end
it "renders the payment details" do
- quick_login_as_admin
- visit spree.admin_order_payments_path order
+ login_as_admin_and_visit spree.admin_order_payments_path order
page.click_link("StripeSCA")
expect(page).to have_content order.payments.last.source.last_digits
@@ -53,8 +50,7 @@ feature '
end
it "renders the payment details" do
- quick_login_as_admin
- visit spree.admin_order_payments_path order
+ login_as_admin_and_visit spree.admin_order_payments_path order
page.click_link("StripeSCA")
expect(page).to have_content order.payments.last.amount
diff --git a/spec/features/admin/product_import_spec.rb b/spec/features/admin/product_import_spec.rb
index e12f2db82c..a4bae3794a 100644
--- a/spec/features/admin/product_import_spec.rb
+++ b/spec/features/admin/product_import_spec.rb
@@ -3,12 +3,12 @@ require 'open_food_network/permissions'
feature "Product Import", js: true do
include AdminHelper
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
let!(:admin) { create(:admin_user) }
- let!(:user) { create_enterprise_user }
- let!(:user2) { create_enterprise_user }
+ let!(:user) { create(:user) }
+ let!(:user2) { create(:user) }
let!(:enterprise) { create(:supplier_enterprise, owner: user, name: "User Enterprise") }
let!(:enterprise2) { create(:distributor_enterprise, owner: user2, name: "Another Enterprise") }
let!(:relationship) { create(:enterprise_relationship, parent: enterprise, child: enterprise2, permissions_list: [:create_variant_overrides]) }
@@ -31,7 +31,7 @@ feature "Product Import", js: true do
let(:shipping_category_id_str) { Spree::ShippingCategory.all.first.id.to_s }
describe "when importing products from uploaded file" do
- before { quick_login_as_admin }
+ before { login_as_admin }
after { File.delete('/tmp/test.csv') }
it "validates entries and saves them if they are all valid and allows viewing new items in Bulk Products" do
@@ -342,7 +342,7 @@ feature "Product Import", js: true do
end
describe "when dealing with uploaded files" do
- before { quick_login_as_admin }
+ before { login_as_admin }
it "checks filetype on upload" do
File.write('/tmp/test.txt', "Wrong filetype!")
@@ -408,7 +408,7 @@ feature "Product Import", js: true do
end
File.write('/tmp/test.csv', csv_data)
- quick_login_as user
+ login_as user
visit main_app.admin_product_import_path
attach_file 'file', '/tmp/test.csv'
@@ -432,7 +432,7 @@ feature "Product Import", js: true do
let(:tmp_csv_path) { "/tmp/test.csv" }
before do
- quick_login_as admin
+ login_as admin
visit main_app.admin_product_import_path
end
diff --git a/spec/features/admin/products_spec.rb b/spec/features/admin/products_spec.rb
index b2ef204312..dd9bfafd2c 100644
--- a/spec/features/admin/products_spec.rb
+++ b/spec/features/admin/products_spec.rb
@@ -4,8 +4,8 @@ feature '
As an admin
I want to set a supplier and distributor(s) for a product
' do
- include AuthenticationWorkflow
include WebHelper
+ include AuthenticationHelper
let!(:taxon) { create(:taxon) }
let!(:stock_location) { create(:stock_location, backorderable_default: false) }
@@ -67,8 +67,7 @@ feature '
end
scenario "creating an on-demand product", js: true do
- quick_login_as_admin
- visit spree.admin_products_path
+ login_as_admin_and_visit spree.admin_products_path
click_link 'New Product'
@@ -97,7 +96,7 @@ feature '
let!(:tax_category) { create(:tax_category) }
before do
- @new_user = create_enterprise_user
+ @new_user = create(:user)
@supplier2 = create(:supplier_enterprise, name: 'Another Supplier')
@supplier_permitted = create(:supplier_enterprise, name: 'Permitted Supplier')
@new_user.enterprise_roles.build(enterprise: @supplier2).save
@@ -105,7 +104,7 @@ feature '
create(:enterprise_relationship, parent: @supplier_permitted, child: @supplier2,
permissions_list: [:manage_products])
- quick_login_as @new_user
+ login_as @new_user
end
context "products do not require a tax category" do
diff --git a/spec/features/admin/properties_spec.rb b/spec/features/admin/properties_spec.rb
index 905810039e..634f3fd436 100644
--- a/spec/features/admin/properties_spec.rb
+++ b/spec/features/admin/properties_spec.rb
@@ -6,11 +6,10 @@ feature '
As an admin
I want to manage product properties
' do
- include AuthenticationWorkflow
+ include AuthenticationHelper
scenario "creating and editing a property" do
- login_to_admin_section
- visit spree.admin_properties_path
+ login_as_admin_and_visit spree.admin_properties_path
click_link 'New Property'
fill_in 'property_name', with: 'New property!'
diff --git a/spec/features/admin/reports/packing_report_spec.rb b/spec/features/admin/reports/packing_report_spec.rb
index 9ab6ff1150..41035bada1 100644
--- a/spec/features/admin/reports/packing_report_spec.rb
+++ b/spec/features/admin/reports/packing_report_spec.rb
@@ -1,7 +1,7 @@
require "spec_helper"
feature "Packing Reports", js: true do
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
let(:distributor) { create(:distributor_enterprise) }
@@ -13,7 +13,7 @@ feature "Packing Reports", js: true do
before do
order.line_items << li1
order.line_items << li2
- quick_login_as_admin
+ login_as_admin
end
describe "viewing a report" do
diff --git a/spec/features/admin/reports_spec.rb b/spec/features/admin/reports_spec.rb
index b8eb70f010..265d8cb97d 100644
--- a/spec/features/admin/reports_spec.rb
+++ b/spec/features/admin/reports_spec.rb
@@ -4,22 +4,22 @@ feature '
As an administrator
I want numbers, all the numbers!
' do
- include AuthenticationWorkflow
include WebHelper
+ include AuthenticationHelper
context "Permissions for different reports" do
context "As an enterprise user" do
let(:user) do
- create_enterprise_user(enterprises: [
- create(:distributor_enterprise)
- ])
+ create(:user, enterprises: [create(:distributor_enterprise)])
end
+
it "does not show super admin only report" do
login_to_admin_as user
click_link "Reports"
expect(page).not_to have_content "Users & Enterprises"
end
end
+
context "As an admin user" do
it "shows the super admin only report" do
login_to_admin_section
@@ -31,8 +31,7 @@ feature '
describe "Customers report" do
before do
- quick_login_as_admin
- visit spree.admin_reports_path
+ login_as_admin_and_visit spree.admin_reports_path
end
scenario "customers report" do
@@ -63,8 +62,7 @@ feature '
describe "Order cycle management report" do
before do
- quick_login_as_admin
- visit spree.admin_reports_path
+ login_as_admin_and_visit spree.admin_reports_path
end
scenario "payment method report" do
@@ -90,8 +88,7 @@ feature '
describe "Packing reports" do
before do
- quick_login_as_admin
- visit spree.admin_reports_path
+ login_as_admin_and_visit spree.admin_reports_path
end
let(:bill_address1) { create(:address, lastname: "Aman") }
@@ -147,8 +144,7 @@ feature '
end
scenario "orders and distributors report" do
- quick_login_as_admin
- visit spree.admin_reports_path
+ login_as_admin_and_visit spree.admin_reports_path
click_link 'Orders And Distributors'
click_button 'Search'
@@ -156,8 +152,7 @@ feature '
end
scenario "payments reports" do
- quick_login_as_admin
- visit spree.admin_reports_path
+ login_as_admin_and_visit spree.admin_reports_path
click_link 'Payment Reports'
click_button 'Search'
@@ -167,8 +162,8 @@ feature '
describe "sales tax report" do
let(:distributor1) { create(:distributor_enterprise, with_payment_and_shipping: true, charges_sales_tax: true) }
let(:distributor2) { create(:distributor_enterprise, with_payment_and_shipping: true, charges_sales_tax: true) }
- let(:user1) { create_enterprise_user enterprises: [distributor1] }
- let(:user2) { create_enterprise_user enterprises: [distributor2] }
+ let(:user1) { create(:user, enterprises: [distributor1]) }
+ let(:user2) { create(:user, enterprises: [distributor2]) }
let!(:shipping_method) { create(:shipping_method_with, :expensive_name, distributors: [distributor1]) }
let(:enterprise_fee) { create(:enterprise_fee, enterprise: user1.enterprises.first, tax_category: product2.tax_category, calculator: Calculator::FlatRate.new(preferred_amount: 120.0)) }
let(:order_cycle) { create(:simple_order_cycle, coordinator: distributor1, coordinator_fees: [enterprise_fee], distributors: [distributor1], variants: [product1.master]) }
@@ -191,8 +186,7 @@ feature '
order1.reload.update_distribution_charge!
order1.finalize!
- quick_login_as_admin
- visit spree.admin_reports_path
+ login_as_admin_and_visit spree.admin_reports_path
click_link "Sales Tax"
select("Tax types", from: "report_type")
@@ -227,8 +221,7 @@ feature '
describe "orders & fulfilment reports" do
it "loads the report page" do
- quick_login_as_admin
- visit spree.admin_reports_path
+ login_as_admin_and_visit spree.admin_reports_path
click_link 'Orders & Fulfillment Reports'
expect(page).to have_content 'Supplier'
@@ -253,8 +246,7 @@ feature '
it "is precise to time of day, not just date" do
# When I generate a customer report with a timeframe that includes one order but not the other
- quick_login_as_admin
- visit spree.orders_and_fulfillment_admin_reports_path
+ login_as_admin_and_visit spree.orders_and_fulfillment_admin_reports_path
fill_in 'q_completed_at_gt', with: '2013-04-25 13:00:00'
fill_in 'q_completed_at_lt', with: '2013-04-25 15:00:00'
@@ -271,8 +263,7 @@ feature '
oc = create(:simple_order_cycle, name: "My Order Cycle", distributors: [distributor], orders_open_at: Time.zone.now, orders_close_at: nil)
o = create(:order, order_cycle: oc, distributor: distributor)
- quick_login_as_admin
- visit spree.orders_and_fulfillment_admin_reports_path
+ login_as_admin_and_visit spree.orders_and_fulfillment_admin_reports_path
expect(page).to have_content "My Order Cycle"
end
@@ -303,8 +294,7 @@ feature '
end
it "shows products and inventory report" do
- quick_login_as_admin
- visit spree.admin_reports_path
+ login_as_admin_and_visit spree.admin_reports_path
expect(page).to have_content "All products"
expect(page).to have_content "Inventory (on hand)"
@@ -318,8 +308,7 @@ feature '
end
it "shows the LettuceShare report" do
- quick_login_as_admin
- visit spree.admin_reports_path
+ login_as_admin_and_visit spree.admin_reports_path
click_link 'LettuceShare'
click_button "Go"
@@ -329,15 +318,14 @@ feature '
end
describe "users and enterprises report" do
- let!(:enterprise1) { create( :enterprise, owner: create_enterprise_user ) }
- let!(:enterprise2) { create( :enterprise, owner: create_enterprise_user ) }
- let!(:enterprise3) { create( :enterprise, owner: create_enterprise_user ) }
+ let!(:enterprise1) { create( :enterprise, owner: create(:user) ) }
+ let!(:enterprise2) { create( :enterprise, owner: create(:user) ) }
+ let!(:enterprise3) { create( :enterprise, owner: create(:user) ) }
before do
enterprise3.enterprise_roles.build( user: enterprise1.owner ).save
- quick_login_as_admin
- visit spree.admin_reports_path
+ login_as_admin_and_visit spree.admin_reports_path
click_link 'Users & Enterprises'
end
@@ -379,8 +367,8 @@ feature '
describe "Xero invoices report" do
let(:distributor1) { create(:distributor_enterprise, with_payment_and_shipping: true, charges_sales_tax: true) }
let(:distributor2) { create(:distributor_enterprise, with_payment_and_shipping: true, charges_sales_tax: true) }
- let(:user1) { create_enterprise_user enterprises: [distributor1] }
- let(:user2) { create_enterprise_user enterprises: [distributor2] }
+ let(:user1) { create(:user, enterprises: [distributor1]) }
+ let(:user2) { create(:user, enterprises: [distributor2]) }
let(:shipping_method) { create(:shipping_method_with, :expensive_name) }
let(:shipment) { create(:shipment_with, :shipping_method, shipping_method: shipping_method) }
@@ -414,8 +402,7 @@ feature '
order1.update_attribute :email, 'customer@email.com'
Timecop.travel(Time.zone.local(2015, 4, 25, 14, 0, 0)) { order1.finalize! }
- quick_login_as_admin
- visit spree.admin_reports_path
+ login_as_admin_and_visit spree.admin_reports_path
click_link 'Xero Invoices'
end
diff --git a/spec/features/admin/schedules_spec.rb b/spec/features/admin/schedules_spec.rb
index f017596e53..41c963e403 100644
--- a/spec/features/admin/schedules_spec.rb
+++ b/spec/features/admin/schedules_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'Schedules', js: true do
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
context "as an enterprise user" do
@@ -16,7 +16,7 @@ feature 'Schedules', js: true do
let!(:oc5) { create(:simple_order_cycle, coordinator: managed_enterprise2, name: 'oc5') }
let!(:weekly_schedule) { create(:schedule, name: 'Weekly', order_cycles: [oc1, oc2, oc3, oc4]) }
- before { quick_login_as user }
+ before { login_as user }
describe "Adding a new Schedule" do
it "immediately shows the schedule in the order cycle list once created" do
diff --git a/spec/features/admin/shipping_methods_spec.rb b/spec/features/admin/shipping_methods_spec.rb
index 84de423581..560fe2f357 100644
--- a/spec/features/admin/shipping_methods_spec.rb
+++ b/spec/features/admin/shipping_methods_spec.rb
@@ -1,8 +1,8 @@
require 'spec_helper'
feature 'shipping methods' do
- include AuthenticationWorkflow
include WebHelper
+ include AuthenticationHelper
before :each do
@shipping_method = create(:shipping_method)
@@ -10,7 +10,7 @@ feature 'shipping methods' do
context "as a site admin" do
before(:each) do
- quick_login_as_admin
+ login_as_admin
end
scenario "creating a shipping method owned by some distributors" do
@@ -82,7 +82,7 @@ feature 'shipping methods' do
end
context "as an enterprise user", js: true do
- let(:enterprise_user) { create_enterprise_user }
+ let(:enterprise_user) { create(:user) }
let(:distributor1) { create(:distributor_enterprise, name: 'First Distributor') }
let(:distributor2) { create(:distributor_enterprise, name: 'Second Distributor') }
let(:distributor3) { create(:distributor_enterprise, name: 'Third Distributor') }
@@ -94,7 +94,7 @@ feature 'shipping methods' do
before(:each) do
enterprise_user.enterprise_roles.build(enterprise: distributor1).save
enterprise_user.enterprise_roles.build(enterprise: distributor2).save
- quick_login_as enterprise_user
+ login_as enterprise_user
end
it "creating a shipping method" do
diff --git a/spec/features/admin/subscriptions_spec.rb b/spec/features/admin/subscriptions_spec.rb
index 61d5f59bcd..4278018aa2 100644
--- a/spec/features/admin/subscriptions_spec.rb
+++ b/spec/features/admin/subscriptions_spec.rb
@@ -2,16 +2,16 @@ require 'spec_helper'
feature 'Subscriptions' do
include AdminHelper
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
context "as an enterprise user", js: true do
- let!(:user) { create_enterprise_user(enterprise_limit: 10) }
+ let!(:user) { create(:user) }
let!(:shop) { create(:distributor_enterprise, owner: user, enable_subscriptions: true) }
let!(:shop2) { create(:distributor_enterprise, owner: user, enable_subscriptions: true) }
let!(:shop_unmanaged) { create(:distributor_enterprise, enable_subscriptions: true) }
- before { quick_login_as user }
+ before { login_as user }
context 'listing subscriptions' do
let!(:subscription) { create(:subscription, shop: shop, with_items: true, with_proxy_orders: true) }
diff --git a/spec/features/admin/tag_rules_spec.rb b/spec/features/admin/tag_rules_spec.rb
index ca53fb68a9..0f3f035379 100644
--- a/spec/features/admin/tag_rules_spec.rb
+++ b/spec/features/admin/tag_rules_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'Tag Rules', js: true do
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
let!(:enterprise) { create(:distributor_enterprise) }
@@ -242,8 +242,7 @@ feature 'Tag Rules', js: true do
end
def visit_tag_rules
- login_to_admin_section
- visit main_app.edit_admin_enterprise_path(enterprise)
+ login_as_admin_and_visit main_app.edit_admin_enterprise_path(enterprise)
expect(page).to have_content "PRIMARY DETAILS"
click_link "Tag Rules"
end
diff --git a/spec/features/admin/tax_settings_spec.rb b/spec/features/admin/tax_settings_spec.rb
index 830f45f692..5da7384c55 100644
--- a/spec/features/admin/tax_settings_spec.rb
+++ b/spec/features/admin/tax_settings_spec.rb
@@ -1,12 +1,10 @@
require 'spec_helper'
feature 'Account and Billing Settings' do
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
describe "updating" do
- let!(:admin) { create(:admin_user) }
-
before do
Spree::Config.set(
products_require_tax_category: false,
@@ -15,14 +13,9 @@ feature 'Account and Billing Settings' do
)
end
- before do
- quick_login_as_admin
- end
-
context "as an admin user" do
it "loads the page" do
- visit spree.admin_dashboard_path
- click_link "Configuration"
+ login_as_admin_and_visit spree.edit_admin_general_settings_path
click_link "Tax Settings"
expect(page).to have_unchecked_field 'preferences_products_require_tax_category'
@@ -31,7 +24,7 @@ feature 'Account and Billing Settings' do
end
it "attributes can be changed" do
- visit spree.edit_admin_tax_settings_path
+ login_as_admin_and_visit spree.edit_admin_tax_settings_path
check 'preferences_products_require_tax_category'
check 'preferences_shipment_inc_vat'
diff --git a/spec/features/admin/users_spec.rb b/spec/features/admin/users_spec.rb
index b97089a0aa..94cb4b881f 100644
--- a/spec/features/admin/users_spec.rb
+++ b/spec/features/admin/users_spec.rb
@@ -1,13 +1,13 @@
require "spec_helper"
feature "Managing users" do
- include AuthenticationWorkflow
+ include AuthenticationHelper
include OpenFoodNetwork::EmailHelper
context "as super-admin" do
before do
setup_email
- quick_login_as_admin
+ login_as_admin
end
context "from the index page" do
diff --git a/spec/features/admin/variant_overrides_spec.rb b/spec/features/admin/variant_overrides_spec.rb
index 1fb6e15981..7c4c6ff543 100644
--- a/spec/features/admin/variant_overrides_spec.rb
+++ b/spec/features/admin/variant_overrides_spec.rb
@@ -6,7 +6,7 @@ feature "
Without affecting other hubs that share the same products
", js: true do
include AdminHelper
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
context "as the manager of a hub" do
@@ -24,9 +24,9 @@ feature "
create(:enterprise_relationship, parent: producer_related, child: hub,
permissions_list: [:create_variant_overrides])
}
- let(:user) { create_enterprise_user enterprises: [hub, producer_managed] }
+ let(:user) { create(:user, enterprises: [hub, producer_managed]) }
- before { quick_login_as user }
+ before { login_as user }
describe "selecting a hub" do
let!(:er1) {
@@ -401,9 +401,7 @@ feature "
let(:product) { order_cycle.products.first }
before do
- login_to_admin_section
-
- visit 'admin/orders/new'
+ login_as_admin_and_visit spree.new_admin_order_path
select2_select distributor.name, from: 'order_distributor_id'
select2_select order_cycle.name, from: 'order_order_cycle_id'
click_button 'Next'
@@ -473,7 +471,7 @@ feature "
last_variant = inventory_items.last.variant
first_variant.product.update!(name: "A First Product")
last_variant.product.update!(name: "Z Last Product")
- quick_login_as supplier.users.first
+ login_as supplier.users.first
visit admin_inventory_path
expect(page).to have_text first_variant.name
diff --git a/spec/features/admin/variants_spec.rb b/spec/features/admin/variants_spec.rb
index 700c375954..2b5df3c0aa 100644
--- a/spec/features/admin/variants_spec.rb
+++ b/spec/features/admin/variants_spec.rb
@@ -4,7 +4,7 @@ feature '
As an admin
I want to manage product variants
' do
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
scenario "creating a new variant" do
@@ -12,8 +12,7 @@ feature '
product = create(:simple_product, variant_unit: "weight", variant_unit_scale: "1")
# When I create a variant on the product
- login_to_admin_section
- visit spree.admin_product_variants_path product
+ login_as_admin_and_visit spree.admin_product_variants_path product
click_link 'New Variant'
fill_in 'unit_value_human', with: '1'
@@ -35,8 +34,7 @@ feature '
product.option_types << variant.option_values.first.option_type
# When I view the variant
- login_to_admin_section
- visit spree.admin_product_variants_path product
+ login_as_admin_and_visit spree.admin_product_variants_path product
page.find('table.index .icon-edit').click
# Then I should not see a traditional option value field for the unit-related option value
@@ -62,8 +60,7 @@ feature '
variant = product.variants.first
variant.update(unit_description: 'foo')
- login_to_admin_section
- visit spree.edit_admin_product_variant_path(product, variant)
+ login_as_admin_and_visit spree.edit_admin_product_variant_path(product, variant)
expect(page).to_not have_field "unit_value_human"
expect(page).to have_field "variant_unit_description", with: "foo"
@@ -120,8 +117,7 @@ feature '
product = create(:simple_product)
variant = create(:variant, product: product)
- login_to_admin_section
- visit spree.admin_product_variants_path product
+ login_as_admin_and_visit spree.admin_product_variants_path product
within "tr#spree_variant_#{variant.id}" do
accept_alert do
@@ -138,8 +134,7 @@ feature '
variant = product.variants.first
# When I view the variant
- login_to_admin_section
- visit spree.admin_product_variants_path product
+ login_as_admin_and_visit spree.admin_product_variants_path product
page.find('table.index .icon-edit').click
# It should allow the display name to be changed
diff --git a/spec/features/consumer/account/cards_spec.rb b/spec/features/consumer/account/cards_spec.rb
index 2b2008b049..e364d8057f 100644
--- a/spec/features/consumer/account/cards_spec.rb
+++ b/spec/features/consumer/account/cards_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature "Credit Cards", js: true do
- include AuthenticationWorkflow
+ include AuthenticationHelper
describe "as a logged in user" do
let(:user) { create(:user) }
let!(:customer) { create(:customer, user: user) }
@@ -9,7 +9,7 @@ feature "Credit Cards", js: true do
let!(:non_default_card) { create(:credit_card, user_id: user.id, gateway_customer_profile_id: 'cus_FDTG') }
before do
- quick_login_as user
+ login_as user
allow(Stripe).to receive(:api_key) { "sk_test_xxxx" }
allow(Stripe).to receive(:publishable_key) { "some_token" }
diff --git a/spec/features/consumer/account/settings_spec.rb b/spec/features/consumer/account/settings_spec.rb
index 2edc45cab1..77012ee3d8 100644
--- a/spec/features/consumer/account/settings_spec.rb
+++ b/spec/features/consumer/account/settings_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature "Account Settings", js: true do
- include AuthenticationWorkflow
+ include AuthenticationHelper
include OpenFoodNetwork::EmailHelper
describe "as a logged in user" do
@@ -14,7 +14,7 @@ feature "Account Settings", js: true do
before do
setup_email
- quick_login_as user
+ login_as user
visit "/account"
click_link I18n.t('spree.users.show.tabs.settings')
expect(page).to have_content I18n.t('spree.users.form.account_settings')
diff --git a/spec/features/consumer/account_spec.rb b/spec/features/consumer/account_spec.rb
index bdba76c971..401c8fbd33 100644
--- a/spec/features/consumer/account_spec.rb
+++ b/spec/features/consumer/account_spec.rb
@@ -6,7 +6,7 @@ feature '
and view any outstanding balance.
', js: true do
include UIComponentHelper
- include AuthenticationWorkflow
+ include AuthenticationHelper
let(:user) { create(:user) }
let!(:distributor1) { create(:distributor_enterprise) }
diff --git a/spec/features/consumer/authentication_spec.rb b/spec/features/consumer/authentication_spec.rb
index c172f40f38..790681cbd6 100644
--- a/spec/features/consumer/authentication_spec.rb
+++ b/spec/features/consumer/authentication_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature "Authentication", js: true do
- include AuthenticationWorkflow
+ include AuthenticationHelper
include UIComponentHelper
include OpenFoodNetwork::EmailHelper
@@ -28,6 +28,7 @@ feature "Authentication", js: true do
browse_as_large
open_login_modal
end
+
scenario "showing login" do
expect(page).to have_login_modal
end
@@ -106,8 +107,31 @@ feature "Authentication", js: true do
end.to enqueue_job Delayed::PerformableMethod
expect(Delayed::Job.last.payload_object.method_name).to eq(:send_reset_password_instructions_without_delay)
end
+
+ context "user with unconfirmed email" do
+ let(:email) { "test@example.org" }
+ let!(:user) { Spree::User.create(email: email, unconfirmed_email: email, password: "secret") }
+
+ scenario "cannot reset password before confirming email" do
+ fill_in "Your email", with: email
+ click_reset_password_button
+ expect(page).to have_content I18n.t('email_unconfirmed')
+ page.find("a", text: I18n.t('devise.confirmations.resend_confirmation_email')).click
+ expect(page).to have_content I18n.t('devise.confirmations.send_instructions')
+
+ visit spree.spree_user_confirmation_path(confirmation_token: user.confirmation_token)
+ expect(user.reload.confirmed?).to be true
+ expect(page).to have_text I18n.t('devise.confirmations.confirmed')
+
+ select_login_tab "Forgot Password?"
+ fill_in "Your email", with: email
+ click_reset_password_button
+ expect(page).to have_reset_password
+ end
+ end
end
end
+
describe "as medium" do
before do
browse_as_medium
diff --git a/spec/features/consumer/confirm_invitation_spec.rb b/spec/features/consumer/confirm_invitation_spec.rb
index bfdd4baddc..43645a9e31 100644
--- a/spec/features/consumer/confirm_invitation_spec.rb
+++ b/spec/features/consumer/confirm_invitation_spec.rb
@@ -1,7 +1,7 @@
require "spec_helper"
feature "Confirm invitation as manager" do
- include UIComponentHelper # for be_logged_in_as
+ include UIComponentHelper
include OpenFoodNetwork::EmailHelper
describe "confirm email and set password" do
@@ -15,8 +15,8 @@ feature "Confirm invitation as manager" do
user.save!
end
- it "allows you to set a password" do
- visit spree.spree_user_confirmation_url(confirmation_token: user.confirmation_token)
+ it "lets the user set a password" do
+ visit spree.spree_user_confirmation_path(confirmation_token: user.confirmation_token)
expect(user.reload.confirmed?).to be true
expect(page).to have_text I18n.t(:change_my_password)
diff --git a/spec/features/consumer/groups_spec.rb b/spec/features/consumer/groups_spec.rb
index dc9a3e4b75..3284b709c8 100644
--- a/spec/features/consumer/groups_spec.rb
+++ b/spec/features/consumer/groups_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'Groups', js: true do
- include AuthenticationWorkflow
+ include AuthenticationHelper
include UIComponentHelper
let(:enterprise) { create(:distributor_enterprise) }
diff --git a/spec/features/consumer/multilingual_spec.rb b/spec/features/consumer/multilingual_spec.rb
index 3e8a19f4d0..1a54a813d3 100644
--- a/spec/features/consumer/multilingual_spec.rb
+++ b/spec/features/consumer/multilingual_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'Multilingual', js: true do
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
include ShopWorkflow
include UIComponentHelper
@@ -77,14 +77,14 @@ feature 'Multilingual', js: true do
expect_menu_and_cookie_in_es
expect(user.locale).to be_nil
- quick_login_as user
+ login_as user
visit root_path
expect_menu_and_cookie_in_es
end
it 'updates user locale and stays in cookie after logout' do
- quick_login_as user
+ login_as user
visit root_path(locale: 'es')
user.reload
diff --git a/spec/features/consumer/producers_spec.rb b/spec/features/consumer/producers_spec.rb
index cf49db00df..f9e03d5f87 100644
--- a/spec/features/consumer/producers_spec.rb
+++ b/spec/features/consumer/producers_spec.rb
@@ -5,7 +5,7 @@ feature '
I want to see a list of producers
So that I can shop at hubs distributing their products
', js: true do
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
include UIComponentHelper
diff --git a/spec/features/consumer/registration_spec.rb b/spec/features/consumer/registration_spec.rb
index 0e9f1b221c..3d7cbb0a0f 100644
--- a/spec/features/consumer/registration_spec.rb
+++ b/spec/features/consumer/registration_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature "Registration", js: true do
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
describe "Registering a Profile" do
@@ -154,7 +154,7 @@ feature "Registration", js: true do
let!(:user2) { create(:user) }
before do
- quick_login_as user2
+ login_as user2
end
context "if accepting Terms of Service is not required" do
diff --git a/spec/features/consumer/shopping/cart_spec.rb b/spec/features/consumer/shopping/cart_spec.rb
index 0bc4523a24..5339aa99f7 100644
--- a/spec/features/consumer/shopping/cart_spec.rb
+++ b/spec/features/consumer/shopping/cart_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature "full-page cart", js: true do
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
include ShopWorkflow
include UIComponentHelper
@@ -262,7 +262,7 @@ feature "full-page cart", js: true do
order.distributor.allow_order_changes = true
order.distributor.save
add_product_to_cart order, product_with_tax
- quick_login_as user
+ login_as user
visit main_app.cart_path
end
diff --git a/spec/features/consumer/shopping/checkout_auth_spec.rb b/spec/features/consumer/shopping/checkout_auth_spec.rb
index a4d9d8c1c3..acbbabd970 100644
--- a/spec/features/consumer/shopping/checkout_auth_spec.rb
+++ b/spec/features/consumer/shopping/checkout_auth_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature "As a consumer I want to check out my cart", js: true do
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
include ShopWorkflow
include CheckoutWorkflow
@@ -24,7 +24,7 @@ feature "As a consumer I want to check out my cart", js: true do
end
it "does not render the login form when logged in" do
- quick_login_as user
+ login_as user
visit checkout_path
within "section[role='main']" do
expect(page).to have_no_content "Login"
diff --git a/spec/features/consumer/shopping/checkout_spec.rb b/spec/features/consumer/shopping/checkout_spec.rb
index 342c699a43..dd79d95958 100644
--- a/spec/features/consumer/shopping/checkout_spec.rb
+++ b/spec/features/consumer/shopping/checkout_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature "As a consumer I want to check out my cart", js: true do
- include AuthenticationWorkflow
+ include AuthenticationHelper
include ShopWorkflow
include CheckoutWorkflow
include WebHelper
@@ -65,7 +65,7 @@ feature "As a consumer I want to check out my cart", js: true do
let(:user) { create(:user) }
before do
- quick_login_as(user)
+ login_as(user)
end
context "with details filled out" do
@@ -292,7 +292,7 @@ feature "As a consumer I want to check out my cart", js: true do
expect(page).to have_content "Donkeys"
expect(page).not_to have_content "Local"
- quick_login_as(user)
+ login_as(user)
visit checkout_path
# Default rule in still effect, disallows access to 'Local'
diff --git a/spec/features/consumer/shopping/embedded_shopfronts_spec.rb b/spec/features/consumer/shopping/embedded_shopfronts_spec.rb
index 445a92186f..075209769e 100644
--- a/spec/features/consumer/shopping/embedded_shopfronts_spec.rb
+++ b/spec/features/consumer/shopping/embedded_shopfronts_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature "Using embedded shopfront functionality", js: true do
include OpenFoodNetwork::EmbeddedPagesHelper
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
include ShopWorkflow
include CheckoutWorkflow
diff --git a/spec/features/consumer/shopping/orders_spec.rb b/spec/features/consumer/shopping/orders_spec.rb
index 4f2a379c12..f7b0a832c5 100644
--- a/spec/features/consumer/shopping/orders_spec.rb
+++ b/spec/features/consumer/shopping/orders_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature "Order Management", js: true do
- include AuthenticationWorkflow
+ include AuthenticationHelper
include OpenFoodNetwork::EmailHelper
describe "viewing a completed order" do
@@ -109,7 +109,7 @@ feature "Order Management", js: true do
order.save
order.reload
- quick_login_as user
+ login_as user
end
it 'shows the name of the shipping method' do
diff --git a/spec/features/consumer/shopping/products_spec.rb b/spec/features/consumer/shopping/products_spec.rb
index 0846845021..91393e3213 100644
--- a/spec/features/consumer/shopping/products_spec.rb
+++ b/spec/features/consumer/shopping/products_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature "As a consumer I want to view products", js: true do
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
include ShopWorkflow
include UIComponentHelper
diff --git a/spec/features/consumer/shopping/shopping_spec.rb b/spec/features/consumer/shopping/shopping_spec.rb
index cf825ca475..f55c3aded5 100644
--- a/spec/features/consumer/shopping/shopping_spec.rb
+++ b/spec/features/consumer/shopping/shopping_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature "As a consumer I want to shop with a distributor", js: true do
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
include ShopWorkflow
include UIComponentHelper
@@ -194,14 +194,16 @@ feature "As a consumer I want to shop with a distributor", js: true do
end
it "returns search results for products where the search term matches one of the product's variant names" do
+ pending "has been broken for a while"
+
visit shop_path
fill_in "search", with: "Badg" # For variant with display_name "Badgers"
within('div.pad-top') do
- expect(page).to have_content product.name
- expect(page).to have_content variant2.display_name
expect(page).not_to have_content product2.name
expect(page).not_to have_content variant3.display_name
+ expect(page).to have_content product.name
+ expect(page).to have_content variant2.display_name
end
end
@@ -483,7 +485,7 @@ feature "As a consumer I want to shop with a distributor", js: true do
let(:user) { create(:user, bill_address: address, ship_address: address) }
before do
- quick_login_as user
+ login_as user
end
context "as non-customer" do
@@ -531,7 +533,7 @@ feature "As a consumer I want to shop with a distributor", js: true do
let!(:returning_user) { create(:user, email: unregistered_customer.email) }
before do
- quick_login_as returning_user
+ login_as returning_user
end
it "shows the products without customer only message" do
diff --git a/spec/features/consumer/shopping/variant_overrides_spec.rb b/spec/features/consumer/shopping/variant_overrides_spec.rb
index 9c7ca0a5d1..d89990dc55 100644
--- a/spec/features/consumer/shopping/variant_overrides_spec.rb
+++ b/spec/features/consumer/shopping/variant_overrides_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature "shopping with variant overrides defined", js: true do
- include AuthenticationWorkflow
+ include AuthenticationHelper
include WebHelper
include ShopWorkflow
include CheckoutWorkflow
diff --git a/spec/features/consumer/shops_spec.rb b/spec/features/consumer/shops_spec.rb
index a9c262817c..80483840fc 100644
--- a/spec/features/consumer/shops_spec.rb
+++ b/spec/features/consumer/shops_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'Shops', js: true do
- include AuthenticationWorkflow
+ include AuthenticationHelper
include UIComponentHelper
include WebHelper
diff --git a/spec/javascripts/unit/darkswarm/services/checkout_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/checkout_spec.js.coffee
index d7e23b457b..8caacdc531 100644
--- a/spec/javascripts/unit/darkswarm/services/checkout_spec.js.coffee
+++ b/spec/javascripts/unit/darkswarm/services/checkout_spec.js.coffee
@@ -1,4 +1,6 @@
describe 'Checkout service', ->
+ BugsnagMock =
+ notify: (arg) ->
Checkout = null
orderData = null
$httpBackend = null
@@ -48,6 +50,8 @@ describe 'Checkout service', ->
ship_address: {test: "bar"}
user_id: 901
+ window.Bugsnag = BugsnagMock
+
module 'Darkswarm'
module ($provide)->
$provide.value "RailsFlashLoader", FlashLoaderMock
@@ -128,6 +132,7 @@ describe 'Checkout service', ->
expect(Checkout.errors).toEqual {error: "frogs"}
it "throws exception and sends generic flash message when there are errors but no flash message", ->
+ spyOn(BugsnagMock, "notify")
$httpBackend.expectPUT("/checkout.json").respond 400, {errors: {error: "broken response"}}
try
Checkout.submit()
@@ -136,9 +141,11 @@ describe 'Checkout service', ->
expect(error.data.errors.error).toBe("broken response")
expect(Checkout.errors).toEqual {}
+ expect(BugsnagMock.notify).toHaveBeenCalled()
it "throws an exception and sends a flash message to the flash service when reponse doesnt contain errors nor a flash message", ->
spyOn(FlashLoaderMock, "loadFlash") # Stubbing out writes to window.location
+ spyOn(BugsnagMock, "notify")
$httpBackend.expectPUT("/checkout.json").respond 400, "broken response"
try
Checkout.submit()
@@ -147,9 +154,11 @@ describe 'Checkout service', ->
expect(error.data).toBe("broken response")
expect(FlashLoaderMock.loadFlash).toHaveBeenCalledWith({ error: t("checkout.failed") })
+ expect(BugsnagMock.notify).toHaveBeenCalled()
it "throws an exception and sends a flash message to the flash service when an exception is thrown while handling the error", ->
spyOn(FlashLoaderMock, "loadFlash") # Stubbing out writes to window.location
+ spyOn(BugsnagMock, "notify")
navigationSpy.and.callFake(-> throw "unexpected error")
$httpBackend.expectPUT("/checkout.json").respond 400, {path: 'path'}
try
@@ -159,6 +168,7 @@ describe 'Checkout service', ->
expect(error).toBe("unexpected error")
expect(FlashLoaderMock.loadFlash).toHaveBeenCalledWith({ error: t("checkout.failed") })
+ expect(BugsnagMock.notify).toHaveBeenCalled()
describe "when using the Stripe Connect gateway", ->
beforeEach inject ($injector, StripeElements) ->
diff --git a/spec/javascripts/unit/darkswarm/services/enterprise_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/enterprise_spec.js.coffee
index c95fbdf81b..088ea359e0 100644
--- a/spec/javascripts/unit/darkswarm/services/enterprise_spec.js.coffee
+++ b/spec/javascripts/unit/darkswarm/services/enterprise_spec.js.coffee
@@ -24,7 +24,7 @@ describe "Enterprises service", ->
{id: 5, visible: true, name: 'e', category: "producer_hub", hubs: [{id: 1}]},
{id: 6, visible: true, name: 'f', category: "producer_shop", hubs: [{id: 2}]},
{id: 7, visible: true, name: 'g', category: "producer", hubs: [{id: 2}]}
- {id: 8, visible: true, name: 'h', category: "producer", hubs: [{id: 2}]}
+ {id: 8, visible: true, name: 'h', category: "producer", hubs: [{id: 2}], latitude: 76.26, longitude: -42.66 }
]
H1: 0
beforeEach ->
@@ -142,4 +142,8 @@ describe "Enterprises service", ->
it "resets the distance", ->
Enterprises.resetDistance()
for e in Enterprises.enterprises
- expect(e.distance).toBeNull()
\ No newline at end of file
+ expect(e.distance).toBeNull()
+
+ describe "geocodedEnterprises", ->
+ it "only returns enterprises which have a latitude and longitude", ->
+ expect(Enterprises.geocodedEnterprises()).toEqual [Enterprises.enterprises[7]]
diff --git a/spec/javascripts/unit/darkswarm/services/map_centre_calculator_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/map_centre_calculator_spec.js.coffee
new file mode 100644
index 0000000000..0d18541442
--- /dev/null
+++ b/spec/javascripts/unit/darkswarm/services/map_centre_calculator_spec.js.coffee
@@ -0,0 +1,86 @@
+describe 'MapCentreCalculator service', ->
+ MapCentreCalculator = null
+ Enterprises = null
+ defaultLongitude = null
+ defaultLatitude = null
+
+ beforeEach ->
+ module 'Darkswarm'
+ defaultLongitude = -6
+ defaultLatitude = 53
+ angular.module('Darkswarm').value 'openStreetMapConfig', {
+ open_street_map_default_latitude: 76.26,
+ open_street_map_default_longitude: -42.66
+ }
+
+ inject (_MapCentreCalculator_, _Enterprises_)->
+ MapCentreCalculator = _MapCentreCalculator_
+ Enterprises = _Enterprises_
+
+ describe "initialLatitude", ->
+ it "calculates the center latitude of any present geocoded enterprises", ->
+ Enterprises.geocodedEnterprises = -> [
+ { latitude: 53, longitude: defaultLongitude },
+ { latitude: 54, longitude: defaultLongitude }
+ ]
+
+ expect(MapCentreCalculator.initialLatitude()).toEqual 53.5
+
+ it "returns the default configured latitude when there are no geocoded enterprises present", ->
+ Enterprises.geocodedEnterprises = -> []
+
+ expect(MapCentreCalculator.initialLatitude()).toEqual 76.26
+
+ describe "initialLongitude", ->
+ it "calculates the center longitude of any present geocoded enterprises", ->
+ Enterprises.geocodedEnterprises = -> [
+ { latitude: defaultLatitude, longitude: -6 },
+ { latitude: defaultLatitude, longitude: -7 }
+ ]
+
+ expect(MapCentreCalculator.initialLongitude()).toEqual -6.5
+
+ it "returns the default configured longitude when there are no geocoded enterprises present", ->
+ Enterprises.geocodedEnterprises = -> []
+
+ expect(MapCentreCalculator.initialLongitude()).toEqual -42.66
+
+ describe "_calculate", ->
+ it "calculates the average angle correctly when given a single angle", ->
+ coordinates = [
+ { latitude: defaultLatitude, longitude: -7 }
+ ]
+
+ expect(MapCentreCalculator._calculate("longitude", coordinates)).toEqual -7
+
+ it "calculates the centre correctly when given a set of positive angles", ->
+ coordinates = [
+ { latitude: 53, longitude: defaultLongitude },
+ { latitude: 54, longitude: defaultLongitude }
+ ]
+
+ expect(MapCentreCalculator._calculate("latitude", coordinates)).toEqual 53.5
+
+ it "calculates the centre correctly when given a set of negative angles", ->
+ coordinates = [
+ { latitude: defaultLatitude, longitude: -6 },
+ { latitude: defaultLatitude, longitude: -7 }
+ ]
+
+ expect(MapCentreCalculator._calculate("longitude", coordinates)).toEqual -6.5
+
+ it "calculates the centre correctly when given a mixture of positive and negative angles and the centre is positive", ->
+ coordinates = [
+ { latitude: defaultLatitude, longitude: 7 },
+ { latitude: defaultLatitude, longitude: -4 }
+ ]
+
+ expect(MapCentreCalculator._calculate("longitude", coordinates)).toEqual 1.5
+
+ it "calculates the centre correctly when given a mixture of positive and negative angles and the centre is negative", ->
+ coordinates = [
+ { latitude: defaultLatitude, longitude: 4 },
+ { latitude: defaultLatitude, longitude: -7 }
+ ]
+
+ expect(MapCentreCalculator._calculate("longitude", coordinates)).toEqual -1.5
diff --git a/spec/jobs/subscription_confirm_job_spec.rb b/spec/jobs/subscription_confirm_job_spec.rb
index 603da10a10..87b3db0fd9 100644
--- a/spec/jobs/subscription_confirm_job_spec.rb
+++ b/spec/jobs/subscription_confirm_job_spec.rb
@@ -19,7 +19,7 @@ describe SubscriptionConfirmJob do
let(:proxy_orders) { job.send(:unconfirmed_proxy_orders) }
before do
- AdvanceOrderService.new(order).call!
+ OrderWorkflow.new(order).complete!
end
it "returns proxy orders that meet all of the criteria" do
@@ -126,7 +126,7 @@ describe SubscriptionConfirmJob do
let(:order) { proxy_order.initialise_order! }
before do
- AdvanceOrderService.new(order).call!
+ OrderWorkflow.new(order).complete!
allow(job).to receive(:send_confirmation_email).and_call_original
setup_email
expect(job).to receive(:record_order)
@@ -216,7 +216,7 @@ describe SubscriptionConfirmJob do
it "records and logs an error and sends the email" do
expect(order).to receive(:update!)
- expect(job).to receive(:record_and_log_error).with(:failed_payment, order).once
+ expect(job).to receive(:record_and_log_error).with(:failed_payment, order, nil).once
job.send(:send_failed_payment_email, order)
expect(SubscriptionMailer).to have_received(:failed_payment_email).with(order)
expect(mail_mock).to have_received(:deliver)
diff --git a/spec/lib/open_food_network/order_cycle_form_applicator_spec.rb b/spec/lib/open_food_network/order_cycle_form_applicator_spec.rb
index a850e1ead9..94742455e3 100644
--- a/spec/lib/open_food_network/order_cycle_form_applicator_spec.rb
+++ b/spec/lib/open_food_network/order_cycle_form_applicator_spec.rb
@@ -4,9 +4,7 @@ require 'open_food_network/order_cycle_form_applicator'
module OpenFoodNetwork
describe OrderCycleFormApplicator do
- include AuthenticationWorkflow
-
- let!(:user) { create_enterprise_user }
+ let!(:user) { create(:user) }
context "unit specs" do
it "creates new exchanges for incoming_exchanges" do
diff --git a/spec/lib/open_food_network/order_cycle_management_report_spec.rb b/spec/lib/open_food_network/order_cycle_management_report_spec.rb
index 8f65a80889..e0214b732a 100644
--- a/spec/lib/open_food_network/order_cycle_management_report_spec.rb
+++ b/spec/lib/open_food_network/order_cycle_management_report_spec.rb
@@ -1,8 +1,6 @@
require 'spec_helper'
require 'open_food_network/order_cycle_management_report'
-include AuthenticationWorkflow
-
module OpenFoodNetwork
describe OrderCycleManagementReport do
context "as a site admin" do
@@ -37,7 +35,7 @@ module OpenFoodNetwork
end
context "as an enterprise user" do
- let!(:user) { create_enterprise_user }
+ let!(:user) { create(:user) }
subject { OrderCycleManagementReport.new user, {}, true }
diff --git a/spec/lib/open_food_network/orders_and_fulfillments_report/customer_totals_report_spec.rb b/spec/lib/open_food_network/orders_and_fulfillments_report/customer_totals_report_spec.rb
index 6bae6da8a1..4799c3e4ac 100644
--- a/spec/lib/open_food_network/orders_and_fulfillments_report/customer_totals_report_spec.rb
+++ b/spec/lib/open_food_network/orders_and_fulfillments_report/customer_totals_report_spec.rb
@@ -1,5 +1,7 @@
require "spec_helper"
+require 'open_food_network/orders_and_fulfillments_report'
require 'open_food_network/orders_and_fulfillments_report/customer_totals_report'
+require 'open_food_network/order_grouper'
RSpec.describe OpenFoodNetwork::OrdersAndFulfillmentsReport::CustomerTotalsReport do
let!(:distributor) { create(:distributor_enterprise) }
@@ -79,6 +81,27 @@ RSpec.describe OpenFoodNetwork::OrdersAndFulfillmentsReport::CustomerTotalsRepor
end
end
+ context "displaying payment fees" do
+ context "with both failed and completed payments present" do
+ let!(:order) {
+ create(:order_ready_to_ship, user: customer.user,
+ customer: customer, distributor: distributor)
+ }
+ let(:completed_payment) { order.payments.completed.first }
+ let!(:failed_payment) { create(:payment, order: order, state: "failed") }
+
+ before do
+ completed_payment.adjustment.update amount: 123.00
+ failed_payment.adjustment.update amount: 456.00, eligible: false, state: "finalized"
+ end
+
+ it "shows the correct payment fee amount for the order" do
+ payment_fee_field = report_table.last[12]
+ expect(payment_fee_field).to eq completed_payment.adjustment.amount
+ end
+ end
+ end
+
context 'when a variant override applies' do
let!(:order) do
create(:completed_order_with_totals, line_items_count: 1, user: customer.user,
diff --git a/spec/lib/open_food_network/orders_and_fulfillments_report_spec.rb b/spec/lib/open_food_network/orders_and_fulfillments_report_spec.rb
index e646884e6e..f970c4b83a 100644
--- a/spec/lib/open_food_network/orders_and_fulfillments_report_spec.rb
+++ b/spec/lib/open_food_network/orders_and_fulfillments_report_spec.rb
@@ -1,8 +1,9 @@
require 'spec_helper'
require 'open_food_network/orders_and_fulfillments_report'
+require 'open_food_network/order_grouper'
describe OpenFoodNetwork::OrdersAndFulfillmentsReport do
- include AuthenticationWorkflow
+ include AuthenticationHelper
let(:distributor) { create(:distributor_enterprise) }
let(:order_cycle) { create(:simple_order_cycle) }
diff --git a/spec/lib/open_food_network/packing_report_spec.rb b/spec/lib/open_food_network/packing_report_spec.rb
index 197224d5d8..462baf0b58 100644
--- a/spec/lib/open_food_network/packing_report_spec.rb
+++ b/spec/lib/open_food_network/packing_report_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
require 'open_food_network/packing_report'
-include AuthenticationWorkflow
+include AuthenticationHelper
module OpenFoodNetwork
describe PackingReport do
diff --git a/spec/lib/open_food_network/reports/report_spec.rb b/spec/lib/open_food_network/reports/report_spec.rb
deleted file mode 100644
index 86e76bcec5..0000000000
--- a/spec/lib/open_food_network/reports/report_spec.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-require 'open_food_network/reports/report'
-
-module OpenFoodNetwork::Reports
- class TestReport < Report
- header 'One', 'Two', 'Three', 'Four'
- end
-
- describe Report do
- let(:report) { TestReport.new }
-
- it "returns the header" do
- expect(report.header).to eq(%w(One Two Three Four))
- end
- end
-end
diff --git a/spec/lib/open_food_network/reports/row_spec.rb b/spec/lib/open_food_network/reports/row_spec.rb
deleted file mode 100644
index c541832edf..0000000000
--- a/spec/lib/open_food_network/reports/row_spec.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-require 'spec_helper'
-require 'open_food_network/reports/row'
-
-module OpenFoodNetwork::Reports
- describe Row do
- let(:row) { Row.new }
- # rubocop:disable Style/Proc
- let(:proc) { Proc.new {} }
- # rubocop:enable Style/Proc
-
- it "can define a number of columns and return them as an array" do
- row.column(&proc)
- row.column(&proc)
- row.column(&proc)
-
- expect(row.to_a).to eq([proc, proc, proc])
- end
- end
-end
diff --git a/spec/lib/open_food_network/reports/rule_spec.rb b/spec/lib/open_food_network/reports/rule_spec.rb
deleted file mode 100644
index eae5b26045..0000000000
--- a/spec/lib/open_food_network/reports/rule_spec.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-require 'spec_helper'
-require 'open_food_network/reports/rule'
-
-module OpenFoodNetwork::Reports
- describe Rule do
- let(:rule) { Rule.new }
- # rubocop:disable Style/Proc
- let(:proc) { Proc.new {} }
- # rubocop:enable Style/Proc
-
- it "can define a group proc and return it in a hash" do
- rule.group(&proc)
- expect(rule.to_h).to eq(group_by: proc, sort_by: nil)
- end
-
- it "can define a sort proc and return it in a hash" do
- rule.sort(&proc)
- expect(rule.to_h).to eq(group_by: nil, sort_by: proc)
- end
- end
-end
diff --git a/spec/lib/open_food_network/users_and_enterprises_report_spec.rb b/spec/lib/open_food_network/users_and_enterprises_report_spec.rb
index 0587e7bbaa..f7503d992c 100644
--- a/spec/lib/open_food_network/users_and_enterprises_report_spec.rb
+++ b/spec/lib/open_food_network/users_and_enterprises_report_spec.rb
@@ -3,8 +3,6 @@ require 'open_food_network/users_and_enterprises_report'
module OpenFoodNetwork
describe UsersAndEnterprisesReport do
- include AuthenticationWorkflow
-
describe "users_and_enterprises" do
let!(:owners_and_enterprises) { double(:owners_and_enterprises) }
let!(:managers_and_enterprises) { double(:managers_and_enterprises) }
@@ -63,8 +61,8 @@ module OpenFoodNetwork
end
describe "filtering results" do
- let!(:enterprise1) { create(:enterprise, owner: create_enterprise_user ) }
- let!(:enterprise2) { create(:enterprise, owner: create_enterprise_user ) }
+ let!(:enterprise1) { create(:enterprise, owner: create(:user) ) }
+ let!(:enterprise2) { create(:enterprise, owner: create(:user) ) }
describe "for owners and enterprises" do
describe "by enterprise id" do
@@ -103,8 +101,8 @@ module OpenFoodNetwork
end
describe "by user id" do
- let!(:manager1) { create_enterprise_user }
- let!(:manager2) { create_enterprise_user }
+ let!(:manager1) { create(:user) }
+ let!(:manager2) { create(:user) }
let!(:params) { { user_id_in: [manager1.id.to_s] } }
let!(:subject) { OpenFoodNetwork::UsersAndEnterprisesReport.new params, true }
diff --git a/spec/lib/spree/core/calculated_adjustments_spec.rb b/spec/lib/spree/core/calculated_adjustments_spec.rb
new file mode 100644
index 0000000000..b9210c4f29
--- /dev/null
+++ b/spec/lib/spree/core/calculated_adjustments_spec.rb
@@ -0,0 +1,73 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+# Its pretty difficult to test this module in isolation b/c it needs to work in conjunction
+# with an actual class that extends ActiveRecord::Base and has a corresponding table in the DB.
+# So we'll just test it using Order and ShippingMethod. These classes are including the module.
+describe Spree::Core::CalculatedAdjustments do
+ let(:calculator) { build(:calculator) }
+ let(:tax_rate) { Spree::TaxRate.new(calculator: calculator) }
+
+ before do
+ allow(calculator).to receive(:compute) { 10 }
+ allow(calculator).to receive(:[]) { nil }
+ end
+
+ it "should add has_one :calculator relationship" do
+ assert Spree::ShippingMethod.
+ reflect_on_all_associations(:has_one).map(&:name).include?(:calculator)
+ end
+
+ context "#create_adjustment and its resulting adjustment" do
+ let(:order) { Spree::Order.create }
+ let(:target) { order }
+
+ it "should be associated with the target" do
+ expect(target.adjustments).to receive(:create)
+ tax_rate.create_adjustment("foo", target, order)
+ end
+
+ it "should have the correct originator and an amount derived from the calculator and supplied calculable" do
+ adjustment = tax_rate.create_adjustment("foo", target, order)
+ expect(adjustment).not_to be_nil
+ expect(adjustment.amount).to eq 10
+ expect(adjustment.source).to eq order
+ expect(adjustment.originator).to eq tax_rate
+ end
+
+ it "should be mandatory if true is supplied for that parameter" do
+ adjustment = tax_rate.create_adjustment("foo", target, order, true)
+ expect(adjustment).to be_mandatory
+ end
+
+ context "when the calculator returns 0" do
+ before { allow(calculator).to receive_messages(compute: 0) }
+
+ context "when adjustment is mandatory" do
+ before { tax_rate.create_adjustment("foo", target, order, true) }
+
+ it "should create an adjustment" do
+ expect(Spree::Adjustment.count).to eq 1
+ end
+ end
+
+ context "when adjustment is not mandatory" do
+ before { tax_rate.create_adjustment("foo", target, order, false) }
+
+ it "should not create an adjustment" do
+ expect(Spree::Adjustment.count).to eq 0
+ end
+ end
+ end
+ end
+
+ context "#update_adjustment" do
+ it "should update the adjustment using its calculator (and the specified source)" do
+ adjustment = double(:adjustment).as_null_object
+ calculable = double :calculable
+ expect(adjustment).to receive(:update_column).with(:amount, 10)
+ tax_rate.update_adjustment(adjustment, calculable)
+ end
+ end
+end
diff --git a/spec/lib/spree/core/environment_spec.rb b/spec/lib/spree/core/environment_spec.rb
new file mode 100644
index 0000000000..7eec8dc329
--- /dev/null
+++ b/spec/lib/spree/core/environment_spec.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Spree::Core::Environment do
+ # Our version doesn't add any features we could test.
+ # So we just check that our file is loaded correctly.
+ let(:our_file) { Rails.root.join("lib/spree/core/environment.rb").to_s }
+
+ it "is defined in our code" do
+ file = subject.method(:initialize).source_location.first
+ expect(file).to eq our_file
+ end
+
+ it "used by Spree" do
+ file = Spree::Core::Engine.config.spree.method(:initialize).source_location.first
+ expect(file).to eq our_file
+ end
+end
diff --git a/spec/lib/spree/core/mail_interceptor_spec.rb b/spec/lib/spree/core/mail_interceptor_spec.rb
new file mode 100644
index 0000000000..48a7f948bb
--- /dev/null
+++ b/spec/lib/spree/core/mail_interceptor_spec.rb
@@ -0,0 +1,82 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+# Here we use the OrderMailer as a way to test the mail interceptor.
+describe Spree::OrderMailer do
+ let(:order) do
+ Spree::Order.new(distributor: create(:enterprise),
+ bill_address: create(:address))
+ end
+ let(:message) { Spree::OrderMailer.confirm_email_for_shop(order) }
+
+ before(:all) do
+ ActionMailer::Base.perform_deliveries = true
+ ActionMailer::Base.deliveries.clear
+ end
+
+ context "#deliver" do
+ before do
+ ActionMailer::Base.delivery_method = :test
+ end
+
+ after { ActionMailer::Base.deliveries.clear }
+
+ it "should use the from address specified in the preference" do
+ Spree::Config[:mails_from] = "no-reply@foobar.com"
+ message.deliver
+ @email = ActionMailer::Base.deliveries.first
+ expect(@email.from).to eq ["no-reply@foobar.com"]
+ end
+
+ it "should use the provided from address" do
+ Spree::Config[:mails_from] = "preference@foobar.com"
+ message.from = "override@foobar.com"
+ message.to = "test@test.com"
+ message.deliver
+ email = ActionMailer::Base.deliveries.first
+ expect(email.from).to eq ["override@foobar.com"]
+ expect(email.to).to eq ["test@test.com"]
+ end
+
+ it "should add the bcc email when provided" do
+ Spree::Config[:mail_bcc] = "bcc-foo@foobar.com"
+ message.deliver
+ @email = ActionMailer::Base.deliveries.first
+ expect(@email.bcc).to eq ["bcc-foo@foobar.com"]
+ end
+
+ context "when intercept_email is provided" do
+ it "should strip the bcc recipients" do
+ expect(message.bcc).to be_blank
+ end
+
+ it "should strip the cc recipients" do
+ expect(message.cc).to be_blank
+ end
+
+ it "should replace the receipient with the specified address" do
+ Spree::Config[:intercept_email] = "intercept@foobar.com"
+ message.deliver
+ @email = ActionMailer::Base.deliveries.first
+ expect(@email.to).to eq ["intercept@foobar.com"]
+ end
+
+ it "should modify the subject to include the original email" do
+ Spree::Config[:intercept_email] = "intercept@foobar.com"
+ message.deliver
+ @email = ActionMailer::Base.deliveries.first
+ expect(@email.subject).to include order.distributor.contact.email
+ end
+ end
+
+ context "when intercept_mode is not provided" do
+ it "should not modify the recipient" do
+ Spree::Config[:intercept_email] = ""
+ message.deliver
+ @email = ActionMailer::Base.deliveries.first
+ expect(@email.to).to eq [order.distributor.contact.email]
+ end
+ end
+ end
+end
diff --git a/spec/lib/spree/core/mail_settings_spec.rb b/spec/lib/spree/core/mail_settings_spec.rb
new file mode 100644
index 0000000000..a8db4d5eed
--- /dev/null
+++ b/spec/lib/spree/core/mail_settings_spec.rb
@@ -0,0 +1,90 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+module Spree
+ module Core
+ describe MailSettings do
+ let!(:subject) { MailSettings.new }
+
+ context "override option is true" do
+ before { Config.override_actionmailer_config = true }
+
+ context "init" do
+ it "calls override!" do
+ expect(MailSettings).to receive(:new).and_return(subject)
+ expect(subject).to receive(:override!)
+ MailSettings.init
+ end
+ end
+
+ context "enable delivery" do
+ before { Config.enable_mail_delivery = true }
+
+ context "overrides appplication defaults" do
+ context "authentication method is none" do
+ before do
+ Config.mail_host = "smtp.example.com"
+ Config.mail_domain = "example.com"
+ Config.mail_port = 123
+ Config.mail_auth_type = MailSettings::SECURE_CONNECTION_TYPES[0]
+ Config.smtp_username = "schof"
+ Config.smtp_password = "hellospree!"
+ Config.secure_connection_type = "TLS"
+ subject.override!
+ end
+
+ it { expect(ActionMailer::Base.smtp_settings[:address]).to eq "smtp.example.com" }
+ it { expect(ActionMailer::Base.smtp_settings[:domain]).to eq "example.com" }
+ it { expect(ActionMailer::Base.smtp_settings[:port]).to eq 123 }
+ it { expect(ActionMailer::Base.smtp_settings[:authentication]).to eq "None" }
+ it { expect(ActionMailer::Base.smtp_settings[:enable_starttls_auto]).to be_truthy }
+
+ it "doesnt touch user name config" do
+ expect(ActionMailer::Base.smtp_settings[:user_name]).to be_nil
+ end
+
+ it "doesnt touch password config" do
+ expect(ActionMailer::Base.smtp_settings[:password]).to be_nil
+ end
+ end
+ end
+
+ context "when mail_auth_type is other than none" do
+ before do
+ Config.mail_auth_type = "login"
+ Config.smtp_username = "schof"
+ Config.smtp_password = "hellospree!"
+ subject.override!
+ end
+
+ context "overrides user credentials" do
+ it { expect(ActionMailer::Base.smtp_settings[:user_name]).to eq "schof" }
+ it { expect(ActionMailer::Base.smtp_settings[:password]).to eq "hellospree!" }
+ end
+ end
+ end
+
+ context "do not enable delivery" do
+ before do
+ Config.enable_mail_delivery = false
+ subject.override!
+ end
+
+ it { expect(ActionMailer::Base.perform_deliveries).to be_falsy }
+ end
+ end
+
+ context "override option is false" do
+ before { Config.override_actionmailer_config = false }
+
+ context "init" do
+ it "doesnt calls override!" do
+ expect(subject).not_to receive(:override!)
+ MailSettings.init
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/spree/core/token_resource_spec.rb b/spec/lib/spree/core/token_resource_spec.rb
new file mode 100644
index 0000000000..087c5b9350
--- /dev/null
+++ b/spec/lib/spree/core/token_resource_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+# Its pretty difficult to test this module in isolation b/c it needs to work in conjunction
+# with an actual class that extends ActiveRecord::Base and has a corresponding table in the DB.
+# So we'll just test it using Order instead since it included the module.
+describe Spree::Core::TokenResource do
+ let(:order) { Spree::Order.new }
+ let(:permission) { double(Spree::TokenizedPermission) }
+
+ it 'should add has_one :tokenized_permission relationship' do
+ assert Spree::Order.
+ reflect_on_all_associations(:has_one).map(&:name).include?(:tokenized_permission)
+ end
+
+ context '#token' do
+ it 'should return the token of the associated permission' do
+ allow(order).to receive_messages tokenized_permission: permission
+ allow(permission).to receive_messages token: 'foo'
+ expect(order.token).to eq 'foo'
+ end
+
+ it 'should return nil if there is no associated permission' do
+ expect(order.token).to be_nil
+ end
+ end
+
+ context '#create_token' do
+ it 'should create a randomized 16 character token' do
+ token = order.create_token
+ expect(token.size).to eq 16
+ end
+ end
+end
diff --git a/spec/lib/spree/i18n_spec.rb b/spec/lib/spree/i18n_spec.rb
new file mode 100644
index 0000000000..386dd9d2ec
--- /dev/null
+++ b/spec/lib/spree/i18n_spec.rb
@@ -0,0 +1,127 @@
+# frozen_string_literal: true
+
+require 'rspec/expectations'
+require 'spree/i18n'
+require 'spree/testing_support/i18n'
+
+describe "i18n" do
+ before do
+ I18n.backend.store_translations(
+ :en,
+ {
+ spree: {
+ foo: "bar",
+ bar: {
+ foo: "bar within bar scope",
+ invalid: nil,
+ legacy_translation: "back in the day..."
+ },
+ invalid: nil,
+ legacy_translation: "back in the day..."
+ }
+ }
+ )
+ end
+
+ it "translates within the spree scope" do
+ expect(Spree.normal_t(:foo)).to eql("bar")
+ expect(Spree.translate(:foo)).to eql("bar")
+ end
+
+ it "translates within the spree scope using a path" do
+ allow(Spree).to receive(:virtual_path).and_return('bar')
+
+ expect(Spree.normal_t('.legacy_translation')).to eql("back in the day...")
+ expect(Spree.translate('.legacy_translation')).to eql("back in the day...")
+ end
+
+ it "raise error without any context when using a path" do
+ expect {
+ Spree.normal_t('.legacy_translation')
+ }.to raise_error
+
+ expect {
+ Spree.translate('.legacy_translation')
+ }.to raise_error
+ end
+
+ it "prepends a string scope" do
+ expect(Spree.normal_t(:foo, scope: "bar")).to eql("bar within bar scope")
+ end
+
+ it "prepends to an array scope" do
+ expect(Spree.normal_t(:foo, scope: ["bar"])).to eql("bar within bar scope")
+ end
+
+ it "returns two translations" do
+ expect(Spree.normal_t([:foo, 'bar.foo'])).to eql(["bar", "bar within bar scope"])
+ end
+
+ it "returns reasonable string for missing translations" do
+ expect(Spree.t(:missing_entry)).to include(" 'avs-code' })
+ @fail_response = double('gateway_response', success?: false)
+
+ @payment_gateway = create(:payment_method,
+ environment: 'test')
+ allow(@payment_gateway).to receive_messages :payment_profiles_supported? => true,
+ :authorize => @success_response,
+ :purchase => @success_response,
+ :capture => @success_response,
+ :void => @success_response,
+ :credit => @success_response
+ allow(@payment).to receive_messages payment_method: @payment_gateway
+ end
+
+ context "#can_capture?" do
+ it "should be true if payment is pending" do
+ payment = create(:payment, created_at: Time.zone.now)
+ allow(payment).to receive(:pending?) { true }
+ expect(credit_card.can_capture?(payment)).to be_truthy
+ end
+
+ it "should be true if payment is checkout" do
+ payment = create(:payment, created_at: Time.zone.now)
+ allow(payment).to receive_messages :pending? => false,
+ :checkout? => true
+ expect(credit_card.can_capture?(payment)).to be_truthy
+ end
+ end
+
+ context "#can_void?" do
+ it "should be true if payment is not void" do
+ payment = create(:payment)
+ allow(payment).to receive(:void?) { false }
+ expect(credit_card.can_void?(payment)).to be_truthy
+ end
+ end
+
+ context "#can_credit?" do
+ it "should be false if payment is not completed" do
+ payment = create(:payment)
+ allow(payment).to receive(:completed?) { false }
+ expect(credit_card.can_credit?(payment)).to be_falsy
+ end
+
+ it "should be false when order payment_state is not 'credit_owed'" do
+ payment = create(:payment,
+ order: create(:order, payment_state: 'paid'))
+ allow(payment).to receive(:completed?) { true }
+ expect(credit_card.can_credit?(payment)).to be_falsy
+ end
+
+ it "should be false when credit_allowed is zero" do
+ payment = create(:payment,
+ order: create(:order, payment_state: 'credit_owed'))
+ allow(payment).to receive_messages :completed? => true,
+ :credit_allowed => 0
+
+ expect(credit_card.can_credit?(payment)).to be_falsy
+ end
+ end
+
+ context "#valid?" do
+ it "should validate presence of number" do
+ credit_card.attributes = valid_credit_card_attributes.except(:number)
+ expect(credit_card).to_not be_valid
+ expect(credit_card.errors[:number]).to eq ["can't be blank"]
+ end
+
+ it "should validate presence of security code" do
+ credit_card.attributes = valid_credit_card_attributes.except(:verification_value)
+ expect(credit_card).to_not be_valid
+ expect(credit_card.errors[:verification_value]).to eq ["can't be blank"]
+ end
+
+ it "should validate expiration is not in the past" do
+ credit_card.month = 1.month.ago.month
+ credit_card.year = 1.month.ago.year
+ expect(credit_card).to_not be_valid
+ expect(credit_card.errors[:base]).to eq ["has expired"]
+ end
+
+ it "does not run expiration in the past validation if month is not set" do
+ credit_card.month = nil
+ credit_card.year = Time.zone.now.year
+ expect(credit_card).to_not be_valid
+ expect(credit_card.errors[:base]).to be_blank
+ end
+
+ it "does not run expiration in the past validation if year is not set" do
+ credit_card.month = Time.zone.now.month
+ credit_card.year = nil
+ expect(credit_card).to_not be_valid
+ expect(credit_card.errors[:base]).to be_blank
+ end
+
+ it "does not run expiration in the past validation if year and month are empty" do
+ credit_card.year = ""
+ credit_card.month = ""
+ expect(credit_card).to_not be_valid
+ expect(credit_card.errors[:card]).to be_blank
+ end
+
+ it "should only validate on create" do
+ credit_card.attributes = valid_credit_card_attributes
+ credit_card.save
+ expect(credit_card).to be_valid
+ end
+ end
+
+ context "#save" do
+ before do
+ credit_card.attributes = valid_credit_card_attributes
+ credit_card.save!
+ end
+
+ let!(:persisted_card) { Spree::CreditCard.find(credit_card.id) }
+
+ it "should not actually store the number" do
+ expect(persisted_card.number).to be_blank
+ end
+
+ it "should not actually store the security code" do
+ expect(persisted_card.verification_value).to be_blank
+ end
+ end
+
+ context "#number=" do
+ it "should strip non-numeric characters from card input" do
+ credit_card.number = "6011000990139424"
+ expect(credit_card.number).to eq "6011000990139424"
+
+ credit_card.number = " 6011-0009-9013-9424 "
+ expect(credit_card.number).to eq "6011000990139424"
+ end
+
+ it "should not raise an exception on non-string input" do
+ credit_card.number = ({})
+ expect(credit_card.number).to be_nil
+ end
+ end
+
+ context "#cc_type=" do
+ it "converts between the different types" do
+ credit_card.cc_type = 'mastercard'
+ expect(credit_card.cc_type).to eq 'master'
+
+ credit_card.cc_type = 'maestro'
+ expect(credit_card.cc_type).to eq 'master'
+
+ credit_card.cc_type = 'amex'
+ expect(credit_card.cc_type).to eq 'american_express'
+
+ credit_card.cc_type = 'dinersclub'
+ expect(credit_card.cc_type).to eq 'diners_club'
+
+ credit_card.cc_type = 'some_outlandish_cc_type'
+ expect(credit_card.cc_type).to eq 'some_outlandish_cc_type'
+ end
+ end
+
+ context "#associations" do
+ it "should be able to access its payments" do
+ expect { credit_card.payments.to_a }.not_to raise_error
+ end
+ end
+
+ context "#to_active_merchant" do
+ before do
+ credit_card.number = "4111111111111111"
+ credit_card.year = Time.zone.now.year
+ credit_card.month = Time.zone.now.month
+ credit_card.first_name = "Bob"
+ credit_card.last_name = "Boblaw"
+ credit_card.verification_value = 123
+ end
+
+ it "converts to an ActiveMerchant::Billing::CreditCard object" do
+ am_card = credit_card.to_active_merchant
+ expect(am_card.number).to eq "4111111111111111"
+ expect(am_card.year).to eq Time.zone.now.year
+ expect(am_card.month).to eq Time.zone.now.month
+ expect(am_card.first_name).to eq "Bob"
+ am_card.last_name = "Boblaw"
+ expect(am_card.verification_value).to eq 123
+ end
+ end
+ end
+
describe "setting default credit card for a user" do
let(:user) { create(:user) }
let(:onetime_card_attrs) do
diff --git a/spec/models/spree/gateway_spec.rb b/spec/models/spree/gateway_spec.rb
new file mode 100644
index 0000000000..294073a559
--- /dev/null
+++ b/spec/models/spree/gateway_spec.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Spree::Gateway do
+ class Provider
+ def initialize(options); end
+
+ def imaginary_method; end
+ end
+
+ class TestGateway < Spree::Gateway
+ def provider_class
+ Provider
+ end
+ end
+
+ it "passes through all arguments on a method_missing call" do
+ gateway = TestGateway.new
+ expect(gateway.provider).to receive(:imaginary_method).with('foo')
+ gateway.imaginary_method('foo')
+ end
+end
diff --git a/spec/models/spree/line_item_spec.rb b/spec/models/spree/line_item_spec.rb
index bef32dc8d7..2836c2c51c 100644
--- a/spec/models/spree/line_item_spec.rb
+++ b/spec/models/spree/line_item_spec.rb
@@ -97,7 +97,7 @@ module Spree
end
it "caps at zero when stock is negative" do
- v.update! on_hand: -2
+ v.__send__(:stock_item).update_column(:count_on_hand, -2)
li.cap_quantity_at_stock!
expect(li.reload.quantity).to eq 0
end
@@ -123,7 +123,7 @@ module Spree
before { vo.update(count_on_hand: -3) }
it "caps at zero" do
- v.update(on_hand: -2)
+ v.__send__(:stock_item).update_column(:count_on_hand, -2)
li.cap_quantity_at_stock!
expect(li.reload.quantity).to eq 0
end
diff --git a/spec/models/spree/order/checkout_spec.rb b/spec/models/spree/order/checkout_spec.rb
index 8eed383c6a..5f49792aa2 100644
--- a/spec/models/spree/order/checkout_spec.rb
+++ b/spec/models/spree/order/checkout_spec.rb
@@ -1,6 +1,306 @@
require 'spec_helper'
describe Spree::Order do
+ let(:order) { Spree::Order.new }
+
+ context "with default state machine" do
+ let(:transitions) do
+ [
+ { address: :delivery },
+ { delivery: :payment },
+ { payment: :complete },
+ { delivery: :complete }
+ ]
+ end
+
+ it "has the following transitions" do
+ transitions.each do |transition|
+ puts transition.keys.first
+ puts transition.values.first
+ transition = Spree::Order.find_transition(from: transition.keys.first,
+ to: transition.values.first)
+ expect(transition).to_not be_nil
+ end
+ end
+
+ it "does not have a transition from delivery to confirm" do
+ transition = Spree::Order.find_transition(from: :delivery, to: :confirm)
+ expect(transition).to be_nil
+ end
+
+ it '.find_transition when contract was broken' do
+ expect(Spree::Order.find_transition({ foo: :bar, baz: :dog })).to be_falsy
+ end
+
+ it '.remove_transition' do
+ options = { from: transitions.first.keys.first, to: transitions.first.values.first }
+ allow(Spree::Order).to receive(:next_event_transition).and_return([options])
+ expect(Spree::Order.remove_transition(options)).to be_truthy
+ end
+
+ it '.remove_transition when contract was broken' do
+ expect(Spree::Order.remove_transition(nil)).to be_falsy
+ end
+
+ context "#checkout_steps" do
+ context "when payment not required" do
+ before { allow(order).to receive_messages payment_required?: false }
+ specify do
+ expect(order.checkout_steps).to eq %w(address delivery complete)
+ end
+ end
+
+ context "when payment required" do
+ before { allow(order).to receive_messages payment_required?: true }
+ specify do
+ expect(order.checkout_steps).to eq %w(address delivery payment complete)
+ end
+ end
+ end
+
+ it "starts out at cart" do
+ expect(order.state).to eq "cart"
+ end
+
+ it "transitions to address" do
+ order.line_items << FactoryGirl.create(:line_item)
+ order.email = "user@example.com"
+ order.next!
+ expect(order.state).to eq "address"
+ end
+
+ it "cannot transition to address without any line items" do
+ expect(order.line_items).to be_blank
+ expect(lambda { order.next! }).to raise_error(StateMachine::InvalidTransition,
+ /#{Spree.t(:there_are_no_items_for_this_order)}/)
+ end
+
+ context "from address" do
+ before do
+ order.state = 'address'
+ allow(order).to receive(:has_available_payment)
+ order.shipments << create(:shipment)
+ order.email = "user@example.com"
+ order.save!
+ end
+
+ it "transitions to delivery" do
+ allow(order).to receive_messages(ensure_available_shipping_rates: true)
+ order.next!
+ expect(order.state).to eq "delivery"
+ end
+
+ context "cannot transition to delivery" do
+ context "if there are no shipping rates for any shipment" do
+ specify do
+ transition = lambda { order.next! }
+ expect(transition).to raise_error(StateMachine::InvalidTransition,
+ /#{Spree.t(:items_cannot_be_shipped)}/)
+ end
+ end
+ end
+ end
+
+ context "from delivery" do
+ before do
+ order.state = 'delivery'
+ end
+
+ context "with payment required" do
+ before do
+ allow(order).to receive_messages payment_required?: true
+ end
+
+ it "transitions to payment" do
+ order.next!
+ expect(order.state).to eq 'payment'
+ end
+ end
+
+ context "without payment required" do
+ before do
+ allow(order).to receive_messages payment_required?: false
+ end
+
+ it "transitions to complete" do
+ order.next!
+ expect(order.state).to eq "complete"
+ end
+ end
+ end
+
+ context "from payment" do
+ before do
+ order.state = 'payment'
+ end
+
+ context "when payment is required" do
+ before do
+ allow(order).to receive_messages confirmation_required?: false
+ allow(order).to receive_messages payment_required?: true
+ end
+
+ it "transitions to complete" do
+ expect(order).to receive(:process_payments!).once.and_return true
+ order.next!
+ expect(order.state).to eq "complete"
+ end
+ end
+
+ # Regression test for #2028
+ context "when payment is not required" do
+ before do
+ allow(order).to receive_messages payment_required?: false
+ end
+
+ it "does not call process payments" do
+ expect(order).to_not receive(:process_payments!)
+ order.next!
+ expect(order.state).to eq "complete"
+ end
+ end
+ end
+ end
+
+ context "subclassed order" do
+ # This causes another test above to fail, but fixing this test should make
+ # the other test pass
+ class SubclassedOrder < Spree::Order
+ checkout_flow do
+ go_to_state :payment
+ go_to_state :complete
+ end
+ end
+
+ it "should only call default transitions once when checkout_flow is redefined" do
+ order = SubclassedOrder.new
+ allow(order).to receive_messages payment_required?: true
+ expect(order).to receive(:process_payments!).once
+ order.state = "payment"
+ order.next!
+ expect(order.state).to eq "complete"
+ end
+ end
+
+ context "re-define checkout flow" do
+ before do
+ @old_checkout_flow = Spree::Order.checkout_flow
+ Spree::Order.class_eval do
+ checkout_flow do
+ go_to_state :payment
+ go_to_state :complete
+ end
+ end
+ end
+
+ after do
+ Spree::Order.checkout_flow(&@old_checkout_flow)
+ end
+
+ it "should not keep old event transitions when checkout_flow is redefined" do
+ expect(Spree::Order.next_event_transitions).to eq [{ cart: :payment }, { payment: :complete }]
+ end
+
+ it "should not keep old events when checkout_flow is redefined" do
+ state_machine = Spree::Order.state_machine
+ expect(state_machine.states.any? { |s| s.name == :address }).to be_falsy
+ known_states = state_machine.events[:next].branches.map(&:known_states).flatten
+ expect(known_states).to_not include(:address)
+ expect(known_states).to_not include(:delivery)
+ expect(known_states).to_not include(:confirm)
+ end
+ end
+
+ # Regression test for #3665
+ context "with only a complete step" do
+ before do
+ @old_checkout_flow = Spree::Order.checkout_flow
+ Spree::Order.class_eval do
+ checkout_flow do
+ go_to_state :complete
+ end
+ end
+ end
+
+ after do
+ Spree::Order.checkout_flow(&@old_checkout_flow)
+ end
+
+ it "does not attempt to process payments" do
+ allow(order).to receive_message_chain(:line_items, :present?).and_return(true)
+ expect(order).to_not receive(:payment_required?)
+ expect(order).to_not receive(:process_payments!)
+ order.next!
+ end
+ end
+
+ context "insert checkout step" do
+ before do
+ @old_checkout_flow = Spree::Order.checkout_flow
+ Spree::Order.class_eval do
+ insert_checkout_step :new_step, before: :address
+ end
+ end
+
+ after do
+ Spree::Order.checkout_flow(&@old_checkout_flow)
+ end
+
+ it "should maintain removed transitions" do
+ transition = Spree::Order.find_transition(from: :delivery, to: :confirm)
+ expect(transition).to be_nil
+ end
+
+ context "before" do
+ before do
+ Spree::Order.class_eval do
+ insert_checkout_step :before_address, before: :address
+ end
+ end
+
+ specify do
+ order = Spree::Order.new
+ expect(order.checkout_steps).to eq %w(new_step before_address address delivery complete)
+ end
+ end
+
+ context "after" do
+ before do
+ Spree::Order.class_eval do
+ insert_checkout_step :after_address, after: :address
+ end
+ end
+
+ specify do
+ order = Spree::Order.new
+ expect(order.checkout_steps).to eq %w(new_step address after_address delivery complete)
+ end
+ end
+ end
+
+ context "remove checkout step" do
+ before do
+ @old_checkout_flow = Spree::Order.checkout_flow
+ Spree::Order.class_eval do
+ remove_checkout_step :address
+ end
+ end
+
+ after do
+ Spree::Order.checkout_flow(&@old_checkout_flow)
+ end
+
+ it "should maintain removed transitions" do
+ transition = Spree::Order.find_transition(from: :delivery, to: :confirm)
+ expect(transition).to be_nil
+ end
+
+ specify do
+ order = Spree::Order.new
+ expect(order.checkout_steps).to eq %w(delivery complete)
+ end
+ end
+
describe 'event :restart_checkout' do
let(:order) { create(:order) }
diff --git a/spec/models/spree/order_spec.rb b/spec/models/spree/order_spec.rb
index 0c2c3d33e5..5c583a5252 100644
--- a/spec/models/spree/order_spec.rb
+++ b/spec/models/spree/order_spec.rb
@@ -855,12 +855,39 @@ describe Spree::Order do
order.state = 'delivery' # payment's previous state
allow(order).to receive(:payment_required?) { true }
- allow(order).to receive(:charge_shipping_and_payment_fees!)
end
- it 'calls charge_shipping_and_payment_fees!' do
+ it 'calls charge_shipping_and_payment_fees! and updates totals' do
+ expect(order).to receive(:charge_shipping_and_payment_fees!)
+ expect(order).to receive(:update_totals).at_least(:once)
+
order.next
- expect(order).to have_received(:charge_shipping_and_payment_fees!)
+ end
+
+ context "payment's amount" do
+ let(:failed_payment) { create(:payment, order: order, state: 'failed', amount: 100) }
+
+ before do
+ allow(order).to receive(:total) { 120 }
+ end
+
+ it 'is not updated for failed payments' do
+ failed_payment
+
+ order.next
+
+ expect(failed_payment.reload.amount).to eq 100
+ end
+
+ it 'is updated only for pending payments' do
+ pending_payment = create(:payment, order: order, state: 'pending', amount: 80)
+ failed_payment
+
+ order.next
+
+ expect(failed_payment.reload.amount).to eq 100
+ expect(pending_payment.reload.amount).to eq 120
+ end
end
end
end
diff --git a/spec/models/spree/payment_method_spec.rb b/spec/models/spree/payment_method_spec.rb
index 396b9f1ab0..3e0d99c5fa 100644
--- a/spec/models/spree/payment_method_spec.rb
+++ b/spec/models/spree/payment_method_spec.rb
@@ -1,7 +1,46 @@
require 'spec_helper'
+class Spree::Gateway::Test < Spree::Gateway
+end
+
module Spree
describe PaymentMethod do
+ describe "#available" do
+ let(:enterprise) { create(:enterprise) }
+
+ before do
+ Spree::PaymentMethod.delete_all
+
+ [nil, 'both', 'front_end', 'back_end'].each do |display_on|
+ Spree::Gateway::Test.create(
+ name: 'Display Both',
+ display_on: display_on,
+ active: true,
+ environment: 'test',
+ description: 'foofah',
+ distributors: [enterprise]
+ )
+ end
+ expect(Spree::PaymentMethod.all.size).to eq 4
+ end
+
+ it "should return all methods available to front-end/back-end when no parameter is passed" do
+ expect(Spree::PaymentMethod.available.size).to eq 2
+ end
+
+ it "should return all methods available to front-end/back-end when display_on = :both" do
+ expect(Spree::PaymentMethod.available(:both).size).to eq 2
+ end
+
+ it "should return all methods available to front-end when display_on = :front_end" do
+ expect(Spree::PaymentMethod.available(:front_end).size).to eq 2
+ end
+
+ it "should return all methods available to back-end when display_on = :back_end" do
+ expect(Spree::PaymentMethod.available(:back_end).size).to eq 2
+ end
+ end
+
it "orders payment methods by name" do
pm1 = create(:payment_method, name: 'ZZ')
pm2 = create(:payment_method, name: 'AA')
diff --git a/spec/models/spree/payment_spec.rb b/spec/models/spree/payment_spec.rb
index 1ca723566c..200efab868 100644
--- a/spec/models/spree/payment_spec.rb
+++ b/spec/models/spree/payment_spec.rb
@@ -1,7 +1,687 @@
require 'spec_helper'
-module Spree
- describe Payment do
+describe Spree::Payment do
+ context 'original specs from Spree' do
+ let(:order) { create(:order) }
+ let(:gateway) do
+ gateway = Spree::Gateway::Bogus.new(:environment => 'test', :active => true)
+ gateway.stub :source_required => true
+ gateway
+ end
+
+ let(:card) { create(:credit_card) }
+
+ before { allow(card).to receive(:has_payment_profile?).and_return(true) }
+
+ let(:payment) do
+ payment = create(:payment)
+ payment.source = card
+ payment.order = order
+ payment.payment_method = gateway
+ payment
+ end
+
+ let(:amount_in_cents) { payment.amount.to_f * 100 }
+
+ let!(:success_response) do
+ double('success_response', :success? => true,
+ :authorization => '123',
+ :avs_result => { 'code' => 'avs-code' },
+ :cvv_result => { 'code' => 'cvv-code', 'message' => "CVV Result"})
+ end
+
+ let(:failed_response) { double('gateway_response', :success? => false) }
+
+ before(:each) do
+ # So it doesn't create log entries every time a processing method is called
+ allow(payment).to receive(:record_response)
+ end
+
+ context "extends LocalizedNumber" do
+ it_behaves_like "a model using the LocalizedNumber module", [:amount]
+ end
+
+ context 'validations' do
+ it "returns useful error messages when source is invalid" do
+ payment.source = Spree::CreditCard.new
+ expect(payment).not_to be_valid
+ cc_errors = payment.errors['Credit Card']
+ expect(cc_errors).to include("Number can't be blank")
+ expect(cc_errors).to include("Month is not a number")
+ expect(cc_errors).to include("Year is not a number")
+ expect(cc_errors).to include("Verification Value can't be blank")
+ end
+ end
+
+ # Regression test for https://github.com/spree/spree/pull/2224
+ context 'failure' do
+ it 'should transition to failed from pending state' do
+ payment.state = 'pending'
+ payment.failure
+ expect(payment.state).to eql('failed')
+ end
+
+ it 'should transition to failed from processing state' do
+ payment.state = 'processing'
+ payment.failure
+ expect(payment.state).to eql('failed')
+ end
+
+ end
+
+ context 'invalidate' do
+ it 'should transition from checkout to invalid' do
+ payment.state = 'checkout'
+ payment.invalidate
+ expect(payment.state).to eq('invalid')
+ end
+ end
+
+ context "processing" do
+ before do
+ payment.stub(:update_order)
+ payment.stub(:create_payment_profile)
+ end
+
+ context "#process!" do
+ it "should purchase if with auto_capture" do
+ payment.payment_method.should_receive(:auto_capture?).and_return(true)
+ payment.should_receive(:purchase!)
+ payment.process!
+ end
+
+ it "should authorize without auto_capture" do
+ payment.payment_method.should_receive(:auto_capture?).and_return(false)
+ payment.should_receive(:authorize!)
+ payment.process!
+ end
+
+ it "should make the state 'processing'" do
+ payment.should_receive(:started_processing!)
+ payment.process!
+ end
+
+ it "should invalidate if payment method doesnt support source" do
+ payment.payment_method.should_receive(:supports?).with(payment.source).and_return(false)
+ expect { payment.process!}.to raise_error(Spree::Core::GatewayError)
+ expect(payment.state).to eq('invalid')
+ end
+
+ end
+
+ context "#authorize" do
+ it "should call authorize on the gateway with the payment amount" do
+ payment.payment_method.should_receive(:authorize).with(amount_in_cents,
+ card,
+ anything).and_return(success_response)
+ payment.authorize!
+ end
+
+ it "should call authorize on the gateway with the currency code" do
+ payment.stub :currency => 'GBP'
+ payment.payment_method.should_receive(:authorize).with(amount_in_cents,
+ card,
+ hash_including({:currency => "GBP"})).and_return(success_response)
+ payment.authorize!
+ end
+
+ it "should log the response" do
+ payment.authorize!
+ expect(payment).to have_received(:record_response)
+ end
+
+ context "when gateway does not match the environment" do
+ it "should raise an exception" do
+ gateway.stub :environment => "foo"
+ expect { payment.authorize! }.to raise_error(Spree::Core::GatewayError)
+ end
+ end
+
+ context "if successful" do
+ before do
+ payment.payment_method.should_receive(:authorize).with(amount_in_cents,
+ card,
+ anything).and_return(success_response)
+ end
+
+ it "should store the response_code, avs_response and cvv_response fields" do
+ payment.authorize!
+ expect(payment.response_code).to eq('123')
+ expect(payment.avs_response).to eq('avs-code')
+ expect(payment.cvv_response_code).to eq('cvv-code')
+ expect(payment.cvv_response_message).to eq('CVV Result')
+ end
+
+ it "should make payment pending" do
+ payment.should_receive(:pend!)
+ payment.authorize!
+ end
+ end
+
+ context "if unsuccessful" do
+ it "should mark payment as failed" do
+ gateway.stub(:authorize).and_return(failed_response)
+ payment.should_receive(:failure)
+ payment.should_not_receive(:pend)
+ expect {
+ payment.authorize!
+ }.to raise_error(Spree::Core::GatewayError)
+ end
+ end
+ end
+
+ context "purchase" do
+ it "should call purchase on the gateway with the payment amount" do
+ gateway.should_receive(:purchase).with(amount_in_cents, card, anything).and_return(success_response)
+ payment.purchase!
+ end
+
+ it "should log the response" do
+ payment.purchase!
+ expect(payment).to have_received(:record_response)
+ end
+
+ context "when gateway does not match the environment" do
+ it "should raise an exception" do
+ gateway.stub :environment => "foo"
+ expect { payment.purchase! }.to raise_error(Spree::Core::GatewayError)
+ end
+ end
+
+ context "if successful" do
+ before do
+ payment.payment_method.should_receive(:purchase).with(amount_in_cents,
+ card,
+ anything).and_return(success_response)
+ end
+
+ it "should store the response_code and avs_response" do
+ payment.purchase!
+ expect(payment.response_code).to eq('123')
+ expect(payment.avs_response).to eq('avs-code')
+ end
+
+ it "should make payment complete" do
+ payment.should_receive(:complete!)
+ payment.purchase!
+ end
+ end
+
+ context "if unsuccessful" do
+ it "should make payment failed" do
+ gateway.stub(:purchase).and_return(failed_response)
+ payment.should_receive(:failure)
+ payment.should_not_receive(:pend)
+ expect { payment.purchase! }.to raise_error(Spree::Core::GatewayError)
+ end
+ end
+ end
+
+ context "#capture" do
+ before do
+ payment.stub(:complete).and_return(true)
+ end
+
+ context "when payment is pending" do
+ before do
+ payment.state = 'pending'
+ end
+
+ context "if successful" do
+ before do
+ payment.payment_method.should_receive(:capture).with(payment, card, anything).and_return(success_response)
+ end
+
+ it "should make payment complete" do
+ payment.should_receive(:complete)
+ payment.capture!
+ end
+
+ it "should store the response_code" do
+ gateway.stub :capture => success_response
+ payment.capture!
+ expect(payment.response_code).to eq('123')
+ end
+ end
+
+ context "if unsuccessful" do
+ it "should not make payment complete" do
+ gateway.stub :capture => failed_response
+ payment.should_receive(:failure)
+ payment.should_not_receive(:complete)
+ expect { payment.capture! }.to raise_error(Spree::Core::GatewayError)
+ end
+ end
+ end
+
+ # Regression test for #2119
+ context "when payment is completed" do
+ before do
+ payment.state = 'completed'
+ end
+
+ it "should do nothing" do
+ payment.should_not_receive(:complete)
+ payment.payment_method.should_not_receive(:capture)
+ payment.log_entries.should_not_receive(:create)
+ payment.capture!
+ end
+ end
+ end
+
+ context "#void" do
+ before do
+ payment.response_code = '123'
+ payment.state = 'pending'
+ end
+
+ context "when profiles are supported" do
+ it "should call payment_gateway.void with the payment's response_code" do
+ gateway.stub :payment_profiles_supported? => true
+ gateway.should_receive(:void).with('123', card, anything).and_return(success_response)
+ payment.void_transaction!
+ end
+ end
+
+ context "when profiles are not supported" do
+ it "should call payment_gateway.void with the payment's response_code" do
+ gateway.stub :payment_profiles_supported? => false
+ gateway.should_receive(:void).with('123', anything).and_return(success_response)
+ payment.void_transaction!
+ end
+ end
+
+ it "should log the response" do
+ payment.void_transaction!
+ expect(payment).to have_received(:record_response)
+ end
+
+ context "when gateway does not match the environment" do
+ it "should raise an exception" do
+ gateway.stub :environment => "foo"
+ expect { payment.void_transaction! }.to raise_error(Spree::Core::GatewayError)
+ end
+ end
+
+ context "if successful" do
+ it "should update the response_code with the authorization from the gateway" do
+ # Change it to something different
+ payment.response_code = 'abc'
+ payment.void_transaction!
+ expect(payment.response_code).to eq('12345')
+ end
+ end
+
+ context "if unsuccessful" do
+ it "should not void the payment" do
+ gateway.stub :void => failed_response
+ payment.should_not_receive(:void)
+ expect { payment.void_transaction! }.to raise_error(Spree::Core::GatewayError)
+ end
+ end
+
+ # Regression test for #2119
+ context "if payment is already voided" do
+ before do
+ payment.state = 'void'
+ end
+
+ it "should not void the payment" do
+ payment.payment_method.should_not_receive(:void)
+ payment.void_transaction!
+ end
+ end
+ end
+
+ context "#credit" do
+ before do
+ payment.state = 'completed'
+ payment.response_code = '123'
+ end
+
+ context "when outstanding_balance is less than payment amount" do
+ before do
+ payment.order.stub :outstanding_balance => 10
+ payment.stub :credit_allowed => 1000
+ end
+
+ it "should call credit on the gateway with the credit amount and response_code" do
+ gateway.should_receive(:credit).with(1000, card, '123', anything).and_return(success_response)
+ payment.credit!
+ end
+ end
+
+ context "when outstanding_balance is equal to payment amount" do
+ before do
+ payment.order.stub :outstanding_balance => payment.amount
+ end
+
+ it "should call credit on the gateway with the credit amount and response_code" do
+ gateway.should_receive(:credit).with(amount_in_cents, card, '123', anything).and_return(success_response)
+ payment.credit!
+ end
+ end
+
+ context "when outstanding_balance is greater than payment amount" do
+ before do
+ payment.order.stub :outstanding_balance => 101
+ end
+
+ it "should call credit on the gateway with the original payment amount and response_code" do
+ gateway.should_receive(:credit).with(amount_in_cents.to_f, card, '123', anything).and_return(success_response)
+ payment.credit!
+ end
+ end
+
+ it "should log the response" do
+ payment.credit!
+ expect(payment).to have_received(:record_response)
+ end
+
+ context "when gateway does not match the environment" do
+ it "should raise an exception" do
+ gateway.stub :environment => "foo"
+ expect { payment.credit! }.to raise_error(Spree::Core::GatewayError)
+ end
+ end
+
+ context "when response is successful" do
+ it "should create an offsetting payment" do
+ expect(Spree::Payment).to receive(:create!)
+ payment.credit!
+ end
+
+ it "resulting payment should have correct values" do
+ allow(payment.order).to receive(:outstanding_balance) { 100 }
+ allow(payment).to receive(:credit_allowed) { 10 }
+
+ offsetting_payment = payment.credit!
+ expect(offsetting_payment.amount.to_f).to eq(-10)
+ expect(offsetting_payment).to be_completed
+ expect(offsetting_payment.response_code).to eq('12345')
+ expect(offsetting_payment.source).to eq(payment)
+ end
+
+ context 'and the source payment card is expired' do
+ let(:card) do
+ Spree::CreditCard.new(month: 12, year: 1995, number: '4111111111111111')
+ end
+
+ let(:successful_response) do
+ ActiveMerchant::Billing::Response.new(true, "Yay!")
+ end
+
+ it 'lets the new payment to be saved' do
+ allow(payment.order).to receive(:outstanding_balance) { 100 }
+ allow(payment).to receive(:credit_allowed) { 10 }
+
+ offsetting_payment = payment.credit!
+
+ expect(offsetting_payment).to be_valid
+ end
+ end
+ end
+ end
+ end
+
+ context "when response is unsuccessful" do
+ it "should not create a payment" do
+ gateway.stub :credit => failed_response
+ Spree::Payment.should_not_receive(:create)
+ expect { payment.credit! }.to raise_error(Spree::Core::GatewayError)
+ end
+ end
+
+ context "when already processing" do
+ it "should return nil without trying to process the source" do
+ payment.state = 'processing'
+
+ payment.should_not_receive(:authorize!)
+ payment.should_not_receive(:purchase!)
+ expect(payment.process!).to be_nil
+ end
+ end
+
+ context "with source required" do
+ context "raises an error if no source is specified" do
+ before do
+ payment.source = nil
+ end
+
+ specify do
+ expect { payment.process! }.to raise_error(Spree::Core::GatewayError, Spree.t(:payment_processing_failed))
+ end
+ end
+ end
+
+ context "with source optional" do
+ context "raises no error if source is not specified" do
+ before do
+ payment.source = nil
+ payment.payment_method.stub(:source_required? => false)
+ end
+
+ specify do
+ expect { payment.process! }.not_to raise_error
+ end
+ end
+ end
+
+ context "#credit_allowed" do
+ it "is the difference between offsets total and payment amount" do
+ payment.amount = 100
+ payment.stub(:offsets_total).and_return(0)
+ expect(payment.credit_allowed).to eq(100)
+ payment.stub(:offsets_total).and_return(80)
+ expect(payment.credit_allowed).to eq(20)
+ end
+ end
+
+ context "#can_credit?" do
+ it "is true if credit_allowed > 0" do
+ payment.stub(:credit_allowed).and_return(100)
+ expect(payment.can_credit?).to be true
+ end
+ it "is false if credit_allowed is 0" do
+ payment.stub(:credit_allowed).and_return(0)
+ expect(payment.can_credit?).to be false
+ end
+ end
+
+ context "#credit" do
+ context "when amount <= credit_allowed" do
+ it "makes the state processing" do
+ payment.payment_method.name = 'Gateway'
+ payment.payment_method.distributors << create(:distributor_enterprise)
+ payment.payment_method.save!
+
+ payment.order = create(:order)
+
+ payment.state = 'completed'
+ payment.stub(:credit_allowed).and_return(10)
+ payment.partial_credit(10)
+ expect(payment).to be_processing
+ end
+ it "calls credit on the source with the payment and amount" do
+ payment.state = 'completed'
+ payment.stub(:credit_allowed).and_return(10)
+ payment.should_receive(:credit!).with(10)
+ payment.partial_credit(10)
+ end
+ end
+ context "when amount > credit_allowed" do
+ it "should not call credit on the source" do
+ payment.state = 'completed'
+ payment.stub(:credit_allowed).and_return(10)
+ payment.partial_credit(20)
+ expect(payment).to be_completed
+ end
+ end
+ end
+
+ context "#save" do
+ it "should call order#update!" do
+ gateway.name = 'Gateway'
+ gateway.distributors << create(:distributor_enterprise)
+ gateway.save!
+
+ order = create(:order)
+ payment = Spree::Payment.create(:amount => 100, :order => order, :payment_method => gateway)
+ order.should_receive(:update!)
+ payment.save
+ end
+
+ context "when profiles are supported" do
+ before do
+ gateway.stub :payment_profiles_supported? => true
+ payment.source.stub :has_payment_profile? => false
+ end
+
+
+ context "when there is an error connecting to the gateway" do
+ it "should call gateway_error " do
+ pending '[Spree build] Failing spec'
+ message = double("gateway_error")
+ connection_error = ActiveMerchant::ConnectionError.new(message, nil)
+ expect(gateway).to receive(:create_profile).and_raise(connection_error)
+ expect do
+ Spree::Payment.create(
+ :amount => 100,
+ :order => order,
+ :source => card,
+ :payment_method => gateway
+ )
+ end.should raise_error(Spree::Core::GatewayError)
+ end
+ end
+
+ context "when successfully connecting to the gateway" do
+ it "should create a payment profile" do
+ gateway.name = 'Gateway'
+ gateway.distributors << create(:distributor_enterprise)
+ gateway.save!
+
+ payment.payment_method = gateway
+ payment.source.save_requested_by_customer = true
+
+ expect(gateway).to receive(:create_profile)
+
+ Spree::Payment.create(
+ :amount => 100,
+ :order => create(:order),
+ :source => card,
+ :payment_method => gateway
+ )
+ end
+ end
+
+
+ end
+
+ context "when profiles are not supported" do
+ before { gateway.stub :payment_profiles_supported? => false }
+
+ it "should not create a payment profile" do
+ gateway.name = 'Gateway'
+ gateway.distributors << create(:distributor_enterprise)
+ gateway.save!
+
+ gateway.should_not_receive :create_profile
+ payment = Spree::Payment.create(
+ :amount => 100,
+ :order => create(:order),
+ :source => card,
+ :payment_method => gateway
+ )
+ end
+ end
+ end
+
+ context "#build_source" do
+ it "should build the payment's source" do
+ params = { :amount => 100, :payment_method => gateway,
+ :source_attributes => {
+ :expiry =>"1 / 99",
+ :number => '1234567890123',
+ :verification_value => '123'
+ }
+ }
+
+ payment = Spree::Payment.new(params)
+ expect(payment).to be_valid
+ expect(payment.source).not_to be_nil
+ end
+
+ it "errors when payment source not valid" do
+ params = { :amount => 100, :payment_method => gateway,
+ :source_attributes => {:expiry => "1 / 12" }}
+
+ payment = Spree::Payment.new(params)
+ expect(payment).not_to be_valid
+ expect(payment.source).not_to be_nil
+ expect(payment.source.errors[:number]).not_to be_empty
+ expect(payment.source.errors[:verification_value]).not_to be_empty
+ end
+ end
+
+ context "#currency" do
+ before { order.stub(:currency) { "ABC" } }
+ it "returns the order currency" do
+ expect(payment.currency).to eq("ABC")
+ end
+ end
+
+ context "#display_amount" do
+ it "returns a Spree::Money for this amount" do
+ expect(payment.display_amount).to eq(Spree::Money.new(payment.amount))
+ end
+ end
+
+ # Regression test for #2216
+ context "#gateway_options" do
+ before { order.stub(:last_ip_address => "192.168.1.1") }
+
+ it "contains an IP" do
+ expect(payment.gateway_options[:ip]).to eq(order.last_ip_address)
+ end
+ end
+
+ context "#set_unique_identifier" do
+ # Regression test for #1998
+ it "sets a unique identifier on create" do
+ payment.run_callbacks(:save)
+ expect(payment.identifier).not_to be_blank
+ expect(payment.identifier.size).to eq(8)
+ expect(payment.identifier).to be_a(String)
+ end
+
+ context "other payment exists" do
+ let(:other_payment) {
+ gateway.name = 'Gateway'
+ gateway.distributors << create(:distributor_enterprise)
+ gateway.save!
+
+ payment = Spree::Payment.new
+ payment.source = card
+ payment.order = create(:order)
+ payment.payment_method = gateway
+ payment
+ }
+
+ before { other_payment.save! }
+
+ it "doesn't set duplicate identifier" do
+ payment.should_receive(:generate_identifier).and_return(other_payment.identifier)
+ payment.should_receive(:generate_identifier).and_call_original
+
+ payment.run_callbacks(:save)
+
+ expect(payment.identifier).not_to be_blank
+ expect(payment.identifier).not_to eq(other_payment.identifier)
+ end
+ end
+ end
+
describe "available actions" do
context "for most gateways" do
let(:payment) { create(:payment, source: create(:credit_card)) }
@@ -24,7 +704,7 @@ module Spree
context "for Pin Payments" do
let(:d) { create(:distributor_enterprise) }
- let(:pin) { Gateway::Pin.create! name: 'pin', distributor_ids: [d.id] }
+ let(:pin) { Spree::Gateway::Pin.create! name: 'pin', distributor_ids: [d.id] }
let(:payment) { create(:payment, source: create(:credit_card), payment_method: pin) }
it "does not void" do
@@ -45,7 +725,7 @@ module Spree
end
end
- describe "refunding" do
+ describe "refund!" do
let(:payment) { create(:payment) }
let(:success) { double(success?: true, authorization: 'abc123') }
let(:failure) { double(success?: false) }
@@ -105,9 +785,9 @@ module Spree
expect do
payment.refund!
- end.to change(Payment, :count).by(1)
+ end.to change(Spree::Payment, :count).by(1)
- p = Payment.last
+ p = Spree::Payment.last
expect(p.order).to eq(payment.order)
expect(p.source).to eq(payment)
expect(p.payment_method).to eq(payment.payment_method)
@@ -147,12 +827,23 @@ module Spree
it "creates adjustment" do
payment = create(:payment, order: order, payment_method: payment_method,
- amount: order.total)
+ amount: order.total)
expect(payment.adjustment).to be_present
expect(payment.adjustment.amount).not_to eq(0)
end
end
end
+ end
+ end
+
+ context 'OFN specs from previously decorated model' do
+ describe "applying transaction fees" do
+ let!(:order) { create(:order) }
+ let!(:line_item) { create(:line_item, order: order, quantity: 3, price: 5.00) }
+
+ before do
+ order.reload.update!
+ end
context "to Stripe payments" do
let(:shop) { create(:enterprise) }
@@ -229,9 +920,5 @@ module Spree
end
end
end
-
- context "extends LocalizedNumber" do
- it_behaves_like "a model using the LocalizedNumber module", [:amount]
- end
end
end
diff --git a/spec/models/spree/stock_item_spec.rb b/spec/models/spree/stock_item_spec.rb
new file mode 100644
index 0000000000..9c9b233986
--- /dev/null
+++ b/spec/models/spree/stock_item_spec.rb
@@ -0,0 +1,106 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Spree::StockItem do
+ let(:stock_location) { create(:stock_location_with_items) }
+
+ subject { stock_location.stock_items.order(:id).first }
+
+ describe "validation" do
+ let(:stock_item) { stock_location.stock_items.first }
+
+ it "requires count_on_hand to be positive if not backorderable" do
+ stock_item.backorderable = false
+
+ stock_item.__send__(:count_on_hand=, 1)
+ expect(stock_item.valid?).to eq(true)
+
+ stock_item.__send__(:count_on_hand=, 0)
+ expect(stock_item.valid?).to eq(true)
+
+ stock_item.__send__(:count_on_hand=, -1)
+ expect(stock_item.valid?).to eq(false)
+ end
+
+ it "allows count_on_hand to be negative if backorderable" do
+ stock_item.backorderable = true
+
+ stock_item.__send__(:count_on_hand=, 1)
+ expect(stock_item.valid?).to eq(true)
+
+ stock_item.__send__(:count_on_hand=, -1)
+ expect(stock_item.valid?).to eq(true)
+ end
+ end
+
+ it 'maintains the count on hand for a variant' do
+ expect(subject.count_on_hand).to eq 15
+ end
+
+ it "can return the stock item's variant's name" do
+ expect(subject.variant_name).to eq(subject.variant.name)
+ end
+
+ context "available to be included in shipment" do
+ context "has stock" do
+ it { expect(subject).to be_available }
+ end
+
+ context "backorderable" do
+ before { subject.backorderable = true }
+ it { expect(subject).to be_available }
+ end
+
+ context "no stock and not backorderable" do
+ before do
+ subject.backorderable = false
+ allow(subject).to receive_messages(count_on_hand: 0)
+ end
+
+ it { expect(subject).not_to be_available }
+ end
+ end
+
+ context "adjust count_on_hand" do
+ let!(:current_on_hand) { subject.count_on_hand }
+
+ it 'is updated pessimistically' do
+ copy = Spree::StockItem.find(subject.id)
+
+ subject.adjust_count_on_hand(5)
+ expect(subject.count_on_hand).to eq(current_on_hand + 5)
+
+ expect(copy.count_on_hand).to eq(current_on_hand)
+ copy.adjust_count_on_hand(5)
+ expect(copy.count_on_hand).to eq(current_on_hand + 10)
+ end
+
+ context "item out of stock (by two items)" do
+ let(:inventory_unit) { double('InventoryUnit') }
+ let(:inventory_unit_2) { double('InventoryUnit2') }
+
+ before do
+ allow(subject).to receive(:backorderable?).and_return(true)
+ subject.adjust_count_on_hand(- (current_on_hand + 2))
+ end
+
+ it "doesn't process backorders" do
+ expect(subject).not_to receive(:backordered_inventory_units)
+ subject.adjust_count_on_hand(1)
+ end
+
+ context "adds new items" do
+ before { allow(subject).to receive_messages(backordered_inventory_units: [inventory_unit, inventory_unit_2]) }
+
+ it "fills existing backorders" do
+ expect(inventory_unit).to receive(:fill_backorder)
+ expect(inventory_unit_2).to receive(:fill_backorder)
+
+ subject.adjust_count_on_hand(3)
+ expect(subject.count_on_hand).to eq(1)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/models/spree/user_spec.rb b/spec/models/spree/user_spec.rb
index ba5b4cd488..fc89796e3c 100644
--- a/spec/models/spree/user_spec.rb
+++ b/spec/models/spree/user_spec.rb
@@ -109,7 +109,7 @@ describe Spree.user_class do
setup_email
expect do
- create(:user, confirmed_at: nil).confirm!
+ create(:user, confirmed_at: nil).confirm
end.to enqueue_job ConfirmSignupJob
end
end
diff --git a/spec/requests/checkout/stripe_connect_spec.rb b/spec/requests/checkout/stripe_connect_spec.rb
index 000b2250a8..4bc09fc74f 100644
--- a/spec/requests/checkout/stripe_connect_spec.rb
+++ b/spec/requests/checkout/stripe_connect_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe "checking out an order with a Stripe Connect payment method", type: :request do
include ShopWorkflow
- include AuthenticationWorkflow
+ include AuthenticationHelper
include OpenFoodNetwork::ApiHelper
let!(:order_cycle) { create(:simple_order_cycle) }
@@ -244,7 +244,7 @@ describe "checking out an order with a Stripe Connect payment method", type: :re
before do
params[:order][:existing_card_id] = credit_card.id
- quick_login_as(order.user)
+ login_as(order.user)
# Requests a token
stub_request(:post, "https://api.stripe.com/v1/tokens")
diff --git a/spec/requests/checkout/stripe_sca_spec.rb b/spec/requests/checkout/stripe_sca_spec.rb
index d2734f66d4..ad03211b1a 100644
--- a/spec/requests/checkout/stripe_sca_spec.rb
+++ b/spec/requests/checkout/stripe_sca_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
describe "checking out an order with a Stripe SCA payment method", type: :request do
include ShopWorkflow
- include AuthenticationWorkflow
+ include AuthenticationHelper
include OpenFoodNetwork::ApiHelper
let!(:order_cycle) { create(:simple_order_cycle) }
@@ -289,7 +289,7 @@ describe "checking out an order with a Stripe SCA payment method", type: :reques
before do
params[:order][:existing_card_id] = credit_card.id
- quick_login_as(order.user)
+ login_as(order.user)
end
context "and the payment intent and payment method requests are accepted" do
diff --git a/spec/requests/embedded_shopfronts_headers_spec.rb b/spec/requests/embedded_shopfronts_headers_spec.rb
index 9e1dd4be4d..1a6f2a3a01 100644
--- a/spec/requests/embedded_shopfronts_headers_spec.rb
+++ b/spec/requests/embedded_shopfronts_headers_spec.rb
@@ -1,13 +1,13 @@
require 'spec_helper'
describe "setting response headers for embedded shopfronts", type: :request do
- include AuthenticationWorkflow
+ include AuthenticationHelper
let(:enterprise) { create(:distributor_enterprise) }
let(:user) { enterprise.owner }
before do
- quick_login_as(user)
+ login_as(user)
end
context "with embedded shopfront disabled" do
diff --git a/spec/requests/home_controller_spec.rb b/spec/requests/home_controller_spec.rb
new file mode 100644
index 0000000000..9400fedcd9
--- /dev/null
+++ b/spec/requests/home_controller_spec.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe HomeController, type: :request do
+ context "#unauthorized" do
+ it "renders the unauthorized template" do
+ get "/unauthorized"
+
+ expect(response.status).to eq 401
+ expect(response).to render_template("shared/unauthorized", layout: 'darkswarm')
+ end
+ end
+end
diff --git a/spec/serializers/api/admin/index_enterprise_serializer_spec.rb b/spec/serializers/api/admin/index_enterprise_serializer_spec.rb
index f1d084b946..f0e0233ea2 100644
--- a/spec/serializers/api/admin/index_enterprise_serializer_spec.rb
+++ b/spec/serializers/api/admin/index_enterprise_serializer_spec.rb
@@ -1,11 +1,9 @@
require 'spec_helper'
describe Api::Admin::IndexEnterpriseSerializer do
- include AuthenticationWorkflow
-
let(:enterprise) { create(:distributor_enterprise) }
context "when spree_current_user is a manager" do
- let(:user) { create_enterprise_user }
+ let(:user) { create(:user) }
before do
user.enterprise_roles.create(enterprise: enterprise)
end
diff --git a/spec/services/checkout/form_data_adapter_spec.rb b/spec/services/checkout/form_data_adapter_spec.rb
index be248a2af0..e2b3c38a94 100644
--- a/spec/services/checkout/form_data_adapter_spec.rb
+++ b/spec/services/checkout/form_data_adapter_spec.rb
@@ -36,6 +36,26 @@ describe Checkout::FormDataAdapter do
end
end
+ describe "and a credit card is provided" do
+ before do
+ params[:order][:payments_attributes].first[:source_attributes] = {number: "4444333322221111"}
+ end
+
+ it "fills in missing credit card brand" do
+ expect(adapter.params[:order][:payments_attributes].first[:source_attributes][:cc_type]).to eq "visa"
+ end
+
+ it "leaves an existing credit card brand" do
+ params[:order][:payments_attributes].first[:source_attributes][:cc_type] = "test"
+ expect(adapter.params[:order][:payments_attributes].first[:source_attributes][:cc_type]).to eq "test"
+ end
+
+ it "doesn't touch the credit card brand without a number" do
+ params[:order][:payments_attributes].first[:source_attributes][:number] = ""
+ expect(adapter.params[:order][:payments_attributes].first[:source_attributes].key?(:cc_type)).to eq false
+ end
+ end
+
describe "and existing credit card is provided" do
before { params[:order][:existing_card_id] = credit_card.id }
diff --git a/spec/services/exchange_products_renderer_spec.rb b/spec/services/exchange_products_renderer_spec.rb
index 67233906ad..b2eba1c6c3 100644
--- a/spec/services/exchange_products_renderer_spec.rb
+++ b/spec/services/exchange_products_renderer_spec.rb
@@ -7,8 +7,9 @@ describe ExchangeProductsRenderer do
describe "#exchange_products" do
describe "for an incoming exchange" do
+ let(:exchange) { order_cycle.exchanges.incoming.first }
+
it "loads products" do
- exchange = order_cycle.exchanges.incoming.first
products = renderer.exchange_products(true, exchange.sender)
expect(products.first.supplier.name).to eq exchange.variants.first.product.supplier.name
@@ -16,14 +17,34 @@ describe ExchangeProductsRenderer do
end
describe "for an outgoing exchange" do
+ let(:exchange) { order_cycle.exchanges.outgoing.first }
+
it "loads products" do
- exchange = order_cycle.exchanges.outgoing.first
products = renderer.exchange_products(false, exchange.receiver)
suppliers = [exchange.variants[0].product.supplier.name, exchange.variants[1].product.supplier.name]
expect(suppliers).to include products.first.supplier.name
expect(suppliers).to include products.second.supplier.name
end
+
+ context "showing products from coordinator inventory only" do
+ before { order_cycle.update prefers_product_selection_from_coordinator_inventory_only: true }
+
+ it "loads no products if there are no products from the coordinator inventory" do
+ products = renderer.exchange_products(false, exchange.receiver)
+
+ expect(products).to be_empty
+ end
+
+ it "loads products from the coordinator inventory" do
+ # Add variant already in the exchange to the coordinator's inventory
+ exchange.variants.first.inventory_items = [create(:inventory_item, enterprise: order_cycle.coordinator)]
+
+ products = renderer.exchange_products(false, exchange.receiver)
+
+ expect(products).to eq [exchange.variants.first.product]
+ end
+ end
end
end
diff --git a/spec/services/order_factory_spec.rb b/spec/services/order_factory_spec.rb
index c67cbaaf0e..394de7eaeb 100644
--- a/spec/services/order_factory_spec.rb
+++ b/spec/services/order_factory_spec.rb
@@ -47,7 +47,7 @@ describe OrderFactory do
end
it "retains address, delivery, and payment attributes until completion of the order" do
- AdvanceOrderService.new(order).call
+ OrderWorkflow.new(order).complete
order.reload
diff --git a/spec/services/order_syncer_spec.rb b/spec/services/order_syncer_spec.rb
index 9990425f6a..2cd6010736 100644
--- a/spec/services/order_syncer_spec.rb
+++ b/spec/services/order_syncer_spec.rb
@@ -409,7 +409,7 @@ describe OrderSyncer do
context "when order is complete" do
it "does not update the line_item quantities and adds the order to order_update_issues with insufficient stock" do
- AdvanceOrderService.new(order).call
+ OrderWorkflow.new(order).complete
expect(syncer.sync!).to be true
@@ -423,7 +423,7 @@ describe OrderSyncer do
it "does not update the line_item quantities and adds the order to order_update_issues with out of stock" do
# this single item available is used when the order is completed below, making the item out of stock
variant.update_attribute(:on_hand, 1)
- AdvanceOrderService.new(order).call
+ OrderWorkflow.new(order).complete
expect(syncer.sync!).to be true
@@ -507,7 +507,7 @@ describe OrderSyncer do
end
context "when order is complete" do
- before { AdvanceOrderService.new(order).call }
+ before { OrderWorkflow.new(order).complete }
it "does not add line_item and adds the order to order_update_issues" do
expect(syncer.sync!).to be true
diff --git a/spec/services/advance_order_service_spec.rb b/spec/services/order_workflow_spec.rb
similarity index 89%
rename from spec/services/advance_order_service_spec.rb
rename to spec/services/order_workflow_spec.rb
index 58a2fcb03a..5b2b6f0bf5 100644
--- a/spec/services/advance_order_service_spec.rb
+++ b/spec/services/order_workflow_spec.rb
@@ -1,6 +1,6 @@
require "spec_helper"
-describe AdvanceOrderService do
+describe OrderWorkflow do
let!(:distributor) { create(:distributor_enterprise) }
let!(:order) do
create(:order_with_totals_and_distribution, distributor: distributor,
@@ -13,7 +13,7 @@ describe AdvanceOrderService do
it "transitions the order multiple steps" do
expect(order.state).to eq("cart")
- service.call
+ service.complete
order.reload
expect(order.state).to eq("complete")
end
@@ -30,7 +30,7 @@ describe AdvanceOrderService do
it "retains delivery method of the order" do
order.select_shipping_method(shipping_method_b.id)
- service.call
+ service.complete
order.reload
expect(order.shipping_method).to eq(shipping_method_b)
end
@@ -38,7 +38,7 @@ describe AdvanceOrderService do
context "when raising on error" do
it "transitions the order multiple steps" do
- service.call!
+ service.complete!
order.reload
expect(order.state).to eq("complete")
end
@@ -49,7 +49,7 @@ describe AdvanceOrderService do
end
it "raises error" do
- expect { service.call! }.to raise_error(StateMachine::InvalidTransition)
+ expect { service.complete! }.to raise_error(StateMachine::InvalidTransition)
end
end
end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 9ea40e8c66..d4130a9d2d 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -181,6 +181,16 @@ RSpec.configure do |config|
config.include JsonSpec::Helpers
+ # Suppress Selenium deprecation warnings. Stops a flood of pointless warnings filling the
+ # test output. We can remove this in the future after upgrading Rails, Rack, and Capybara.
+ if Rails::VERSION::MAJOR == 4 && Rails::VERSION::MINOR == 0
+ Selenium::WebDriver.logger.level = :error
+ else
+ ActiveSupport::Deprecation.warn(
+ "Suppressing Selenium deprecation warnings is not needed any more."
+ )
+ end
+
# Profiling
#
# This code shouldn't be run in normal circumstances. But if you want to know
@@ -201,4 +211,5 @@ RSpec.configure do |config|
# config.after :suite do
# PerfTools::CpuProfiler.stop
# end
+ config.infer_spec_type_from_file_location!
end
diff --git a/spec/support/controller_helper.rb b/spec/support/controller_helper.rb
index b543555319..2d7ddf585d 100644
--- a/spec/support/controller_helper.rb
+++ b/spec/support/controller_helper.rb
@@ -1,6 +1,6 @@
module OpenFoodNetwork
module ControllerHelper
- def login_as_admin
+ def controller_login_as_admin
@admin_user ||= begin
user = create(:user)
user.spree_roles << Spree::Role.find_or_create_by!(name: 'admin')
@@ -10,7 +10,7 @@ module OpenFoodNetwork
allow(controller).to receive_messages(spree_current_user: @admin_user)
end
- def login_as_enterprise_user(enterprises)
+ def controller_login_as_enterprise_user(enterprises)
@enterprise_user ||= begin
user = create(:user)
user.spree_roles = []
diff --git a/spec/support/email_helper.rb b/spec/support/email_helper.rb
index f622785425..4291844575 100644
--- a/spec/support/email_helper.rb
+++ b/spec/support/email_helper.rb
@@ -2,8 +2,6 @@ module OpenFoodNetwork
module EmailHelper
# Some specs trigger actions that send emails, for example creating an order.
# But sending emails doesn't work out-of-the-box. This code sets it up.
- # It's here in a single place to allow an easy upgrade to Spree 2 which
- # needs a different implementation of this method.
def setup_email
Spree::Config[:mails_from] = "test@ofn.example.org"
end
diff --git a/spec/support/request/authentication_helper.rb b/spec/support/request/authentication_helper.rb
new file mode 100644
index 0000000000..8c5e9e890a
--- /dev/null
+++ b/spec/support/request/authentication_helper.rb
@@ -0,0 +1,34 @@
+module AuthenticationHelper
+ include Warden::Test::Helpers
+
+ def login_as_admin
+ admin_user = create(:admin_user)
+ login_as admin_user
+ admin_user
+ end
+
+ def login_as_admin_and_visit(path_visit)
+ login_as_admin
+ visit path_visit
+ end
+
+ def login_to_admin_section
+ login_as_admin_and_visit(spree.admin_dashboard_path)
+ end
+
+ def login_to_admin_as(user)
+ login_as user
+ visit spree.admin_dashboard_path
+ end
+
+ def fill_in_and_submit_login_form(user)
+ fill_in "email", with: user.email
+ fill_in "password", with: user.password
+ click_button "Login"
+ end
+
+ def expect_logged_in
+ # Ensure page has been reloaded after submitting login form
+ expect(page).to_not have_selector ".menu #login-link"
+ end
+end
diff --git a/spec/support/request/authentication_workflow.rb b/spec/support/request/authentication_workflow.rb
deleted file mode 100644
index 8968c84da5..0000000000
--- a/spec/support/request/authentication_workflow.rb
+++ /dev/null
@@ -1,74 +0,0 @@
-module AuthenticationWorkflow
- include Warden::Test::Helpers
-
- def quick_login_as(user)
- login_as user
- end
-
- def quick_login_as_admin
- admin_role = Spree::Role.find_or_create_by!(name: 'admin')
- admin_user = create(:user,
- password: 'passw0rd',
- password_confirmation: 'passw0rd',
- remember_me: false,
- persistence_token: 'pass',
- login: 'admin@ofn.org')
-
- admin_user.spree_roles << admin_role
- quick_login_as admin_user
- admin_user
- end
-
- def login_to_admin_section
- quick_login_as_admin
- visit spree.admin_dashboard_path
- end
-
- # TODO: Should probably just rename this to create_user
- def create_enterprise_user( attrs = {} )
- new_user = build(:user, attrs)
- new_user.spree_roles = [Spree::Role.find_or_create_by!(name: 'user')]
- new_user.save
- if attrs.key? :enterprises
- attrs[:enterprises].each do |enterprise|
- enterprise.users << new_user
- end
- end
- new_user
- end
-
- def login_to_admin_as(user)
- quick_login_as user
- visit spree.admin_dashboard_path
- # visit spree.admin_dashboard_path
- # fill_in 'spree_user_email', :with => user.email
- # fill_in 'spree_user_password', :with => user.password
- # click_button 'Login'
- end
-
- def fill_in_and_submit_login_form(user)
- fill_in "email", with: user.email
- fill_in "password", with: user.password
- click_button "Login"
- end
-
- def expect_logged_in
- # Ensure page has been reloaded after submitting login form
- expect(page).to_not have_selector ".menu #login-link"
- end
-end
-
-RSpec.configure do |config|
- config.extend AuthenticationWorkflow, type: :feature
-
- # rspec-rails 3 will no longer automatically infer an example group's spec type
- # from the file location. You can explicitly opt-in to the feature using this
- # config option.
- # To explicitly tag specs without using automatic inference, set the `:type`
- # metadata manually:
- #
- # describe ThingsController, :type => :controller do
- # # Equivalent to being in spec/controllers
- # end
- config.infer_spec_type_from_file_location!
-end
diff --git a/spec/views/spree/admin/orders/edit.html.haml_spec.rb b/spec/views/spree/admin/orders/edit.html.haml_spec.rb
index b33cd187ef..e6b779df39 100644
--- a/spec/views/spree/admin/orders/edit.html.haml_spec.rb
+++ b/spec/views/spree/admin/orders/edit.html.haml_spec.rb
@@ -1,7 +1,6 @@
require "spec_helper"
describe "spree/admin/orders/edit.html.haml" do
- include AuthenticationWorkflow
helper Spree::BaseHelper # required to make pretty_time work
around do |example|
@@ -17,7 +16,7 @@ describe "spree/admin/orders/edit.html.haml" do
end
end
- allow(view).to receive_messages spree_current_user: create_enterprise_user
+ allow(view).to receive_messages spree_current_user: create(:user)
order = create(:completed_order_with_fees)
order.distributor = create(:distributor_enterprise)
diff --git a/spec/views/spree/admin/orders/index.html.haml_spec.rb b/spec/views/spree/admin/orders/index.html.haml_spec.rb
index 8cbbfeb90a..8379a77610 100644
--- a/spec/views/spree/admin/orders/index.html.haml_spec.rb
+++ b/spec/views/spree/admin/orders/index.html.haml_spec.rb
@@ -1,8 +1,6 @@
require "spec_helper"
describe "spree/admin/orders/index.html.haml" do
- include AuthenticationWorkflow
-
around do |example|
original_config = Spree::Config[:enable_invoices?]
example.run
@@ -16,7 +14,7 @@ describe "spree/admin/orders/index.html.haml" do
end
end
- allow(view).to receive_messages spree_current_user: create_enterprise_user
+ allow(view).to receive_messages spree_current_user: create(:user)
end
describe "print invoices button" do
diff --git a/spec/views/spree/admin/shared/_order_links.html.haml_spec.rb b/spec/views/spree/admin/shared/_order_links.html.haml_spec.rb
new file mode 100644
index 0000000000..027c188cab
--- /dev/null
+++ b/spec/views/spree/admin/shared/_order_links.html.haml_spec.rb
@@ -0,0 +1,18 @@
+require "spec_helper"
+
+describe "spree/admin/shared/_order_links.html.haml" do
+ helper Spree::BaseHelper # required to make pretty_time work
+
+ before do
+ order = create(:order)
+ assign(:order, order)
+ end
+
+ describe "actions dropwdown" do
+ it "contains all the actions buttons" do
+ render
+
+ expect(rendered).to have_content("links-dropdown")
+ end
+ end
+end
diff --git a/spec/views/spree/shared/_order_details.html.haml_spec.rb b/spec/views/spree/shared/_order_details.html.haml_spec.rb
index ac6d788f24..60e95ac0f6 100644
--- a/spec/views/spree/shared/_order_details.html.haml_spec.rb
+++ b/spec/views/spree/shared/_order_details.html.haml_spec.rb
@@ -3,7 +3,7 @@
require "spec_helper"
describe "spree/shared/_order_details.html.haml" do
- include AuthenticationWorkflow
+ include AuthenticationHelper
helper Spree::BaseHelper
let(:order) { create(:completed_order_with_fees) }
diff --git a/vendor/assets/javascripts/leaflet-providers.js b/vendor/assets/javascripts/leaflet-providers.js
index 208b6257d0..6d8349839b 100644
--- a/vendor/assets/javascripts/leaflet-providers.js
+++ b/vendor/assets/javascripts/leaflet-providers.js
@@ -219,66 +219,16 @@
}
},
CyclOSM: {
- url: 'https://dev.{s}.tile.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png',
+ url: 'https://{s}.tile-cyclosm.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png',
options: {
maxZoom: 20,
attribution: 'CyclOSM | Map data: {attribution.OpenStreetMap}'
}
},
- OpenMapSurfer: {
- url: 'https://maps.heigit.org/openmapsurfer/tiles/{variant}/webmercator/{z}/{x}/{y}.png',
- options: {
- maxZoom: 19,
- variant: 'roads',
- attribution: 'Imagery from GIScience Research Group @ University of Heidelberg | Map data '
- },
- variants: {
- Roads: {
- options: {
- variant: 'roads',
- attribution: '{attribution.OpenMapSurfer}{attribution.OpenStreetMap}'
- }
- },
- Hybrid: {
- options: {
- variant: 'hybrid',
- attribution: '{attribution.OpenMapSurfer}{attribution.OpenStreetMap}'
- }
- },
- AdminBounds: {
- options: {
- variant: 'adminb',
- maxZoom: 18,
- attribution: '{attribution.OpenMapSurfer}{attribution.OpenStreetMap}'
- }
- },
- ContourLines: {
- options: {
- variant: 'asterc',
- maxZoom: 18,
- minZoom: 13,
- attribution: '{attribution.OpenMapSurfer} ASTER GDEM'
- }
- },
- Hillshade: {
- options: {
- variant: 'asterh',
- maxZoom: 18,
- attribution: '{attribution.OpenMapSurfer} ASTER GDEM, SRTM'
- }
- },
- ElementsAtRisk: {
- options: {
- variant: 'elements_at_risk',
- attribution: '{attribution.OpenMapSurfer}{attribution.OpenStreetMap}'
- }
- }
- }
- },
Hydda: {
url: 'https://{s}.tile.openstreetmap.se/hydda/{variant}/{z}/{x}/{y}.png',
options: {
- maxZoom: 18,
+ maxZoom: 20,
variant: 'full',
attribution: 'Tiles courtesy of OpenStreetMap Sweden — Map data {attribution.OpenStreetMap}'
},
@@ -288,18 +238,73 @@
RoadsAndLabels: 'roads_and_labels'
}
},
- MapBox: {
- url: 'https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}{r}.png?access_token={accessToken}',
+ Jawg: {
+ url: 'https://{s}.tile.jawg.io/{variant}/{z}/{x}/{y}{r}.png?access-token={accessToken}',
options: {
attribution:
- '© Mapbox ' +
+ '© JawgMaps ' +
+ '{attribution.OpenStreetMap}',
+ minZoom: 0,
+ maxZoom: 22,
+ subdomains: 'abcd',
+ variant: 'jawg-terrain',
+ // Get your own Jawg access token here : https://www.jawg.io/lab/
+ // NB : this is a demonstration key that comes with no guarantee
+ accessToken: '',
+ },
+ variants: {
+ Streets: 'jawg-streets',
+ Terrain: 'jawg-terrain',
+ Sunny: 'jawg-sunny',
+ Dark: 'jawg-dark',
+ Light: 'jawg-light',
+ Matrix: 'jawg-matrix'
+ }
+ },
+ MapBox: {
+ url: 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}{r}?access_token={accessToken}',
+ options: {
+ attribution:
+ '© Mapbox ' +
'{attribution.OpenStreetMap} ' +
'Improve this map',
- subdomains: 'abcd',
- id: 'mapbox.streets',
+ tileSize: 512,
+ maxZoom: 18,
+ zoomOffset: -1,
+ id: 'mapbox/streets-v11',
accessToken: '',
}
},
+ MapTiler: {
+ url: 'https://api.maptiler.com/maps/{variant}/{z}/{x}/{y}{r}.{ext}?key={key}',
+ options: {
+ attribution:
+ '© MapTiler © OpenStreetMap contributors',
+ variant: 'streets',
+ ext: 'png',
+ key: '',
+ tileSize: 512,
+ zoomOffset: -1,
+ minZoom: 0,
+ maxZoom: 21
+ },
+ variants: {
+ Streets: 'streets',
+ Basic: 'basic',
+ Bright: 'bright',
+ Pastel: 'pastel',
+ Positron: 'positron',
+ Hybrid: {
+ options: {
+ variant: 'hybrid',
+ ext: 'jpg'
+ }
+ },
+ Toner: 'toner',
+ Topo: 'topo',
+ Voyager: 'voyager'
+ }
+ },
Stamen: {
url: 'https://stamen-tiles-{s}.a.ssl.fastly.net/{variant}/{z}/{x}/{y}{r}.{ext}',
options: {
@@ -719,11 +724,11 @@
}
},
FreeMapSK: {
- url: 'http://t{s}.freemap.sk/T/{z}/{x}/{y}.jpeg',
+ url: 'https://{s}.freemap.sk/T/{z}/{x}/{y}.jpeg',
options: {
minZoom: 8,
maxZoom: 16,
- subdomains: '1234',
+ subdomains: 'abcd',
bounds: [[47.204642, 15.996093], [49.830896, 22.576904]],
attribution:
'{attribution.OpenStreetMap}, vizualization CC-By-SA 2.0 Freemap.sk'