mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-13 18:46:49 +00:00
Compare commits
80 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9fd8613107 | ||
|
|
bea8c2035f | ||
|
|
e616e32bbc | ||
|
|
19b5a004dd | ||
|
|
4a5a6a2242 | ||
|
|
d1b60e3778 | ||
|
|
31fe8850b5 | ||
|
|
0309a20cb1 | ||
|
|
9d772dbcc9 | ||
|
|
0abcbc7b8f | ||
|
|
3badaa07d2 | ||
|
|
977ab26b00 | ||
|
|
d6160b5759 | ||
|
|
40d4ed2c95 | ||
|
|
72f5b1b251 | ||
|
|
eb2d8e65ed | ||
|
|
355c5f5c55 | ||
|
|
bb3f958dd2 | ||
|
|
b367d4328e | ||
|
|
ed346b3b54 | ||
|
|
290120d015 | ||
|
|
0fd163602d | ||
|
|
4c3a3d5d1a | ||
|
|
9771fd7f13 | ||
|
|
6a61bf7656 | ||
|
|
9754d8d754 | ||
|
|
ce5bcaaa20 | ||
|
|
de22ad0000 | ||
|
|
23706ec1d6 | ||
|
|
c3e0f45f1a | ||
|
|
0a1947ae34 | ||
|
|
b79c568b08 | ||
|
|
e8139d3948 | ||
|
|
5761014205 | ||
|
|
90bf4f312b | ||
|
|
63a9765fea | ||
|
|
5c6cb4840e | ||
|
|
99ca0adf64 | ||
|
|
1123e08a98 | ||
|
|
18cb0e0980 | ||
|
|
be3a10b2b1 | ||
|
|
ebf9be41bb | ||
|
|
95ffff5087 | ||
|
|
03bb1f053a | ||
|
|
2e3702550d | ||
|
|
56b83b6bb5 | ||
|
|
e367cbd1e6 | ||
|
|
bdf9c1e405 | ||
|
|
2070cfd5bb | ||
|
|
8001e63f77 | ||
|
|
aed384183b | ||
|
|
e453b130e4 | ||
|
|
7e355a3248 | ||
|
|
a8a81f8023 | ||
|
|
d4c48e2b94 | ||
|
|
872cfcfc58 | ||
|
|
5b3fbe0aed | ||
|
|
ebeeeb7ed3 | ||
|
|
a929d82580 | ||
|
|
1f39731068 | ||
|
|
d2f0d96174 | ||
|
|
7218bb0c7d | ||
|
|
58da11fde7 | ||
|
|
2c65cea911 | ||
|
|
95698fac37 | ||
|
|
7b30008e8b | ||
|
|
50e6ce92b3 | ||
|
|
a78d615936 | ||
|
|
cd8355ea66 | ||
|
|
724a88344e | ||
|
|
9a09f420c1 | ||
|
|
12a5a266fd | ||
|
|
efeda61e40 | ||
|
|
38c5a9e105 | ||
|
|
89e5221dc5 | ||
|
|
c75341838e | ||
|
|
84d7538b1b | ||
|
|
388d575cc8 | ||
|
|
fdd21d7d7d | ||
|
|
ab67a4f80c |
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -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?
|
||||
<!-- Any known conflicts with the Spree Upgrade?
|
||||
Explain them or remove this section. -->
|
||||
|
||||
|
||||
|
||||
#### Discourse thread
|
||||
|
||||
@@ -321,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
|
||||
@@ -399,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
|
||||
@@ -444,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
|
||||
@@ -482,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
|
||||
@@ -513,6 +532,9 @@ Metrics/CyclomaticComplexity:
|
||||
- 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
|
||||
@@ -539,6 +561,8 @@ Metrics/PerceivedComplexity:
|
||||
- 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
|
||||
@@ -601,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
|
||||
@@ -645,6 +670,11 @@ Metrics/MethodLength:
|
||||
- spec/features/consumer/shopping/variant_overrides_spec.rb
|
||||
- spec/models/product_importer_spec.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
|
||||
@@ -674,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
|
||||
@@ -686,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
|
||||
@@ -694,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
|
||||
@@ -728,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
|
||||
@@ -736,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'
|
||||
|
||||
@@ -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,27 +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'
|
||||
|
||||
# Offense count: 2
|
||||
# Configuration parameters: Include.
|
||||
# Include: app/models/**/*.rb
|
||||
Rails/UniqueValidationWithoutIndex:
|
||||
Exclude:
|
||||
- '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:
|
||||
@@ -383,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
|
||||
@@ -447,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:
|
||||
@@ -475,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
|
||||
@@ -569,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'
|
||||
@@ -624,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'
|
||||
@@ -684,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'
|
||||
@@ -702,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'
|
||||
@@ -711,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'
|
||||
@@ -803,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'
|
||||
@@ -811,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'
|
||||
@@ -831,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'
|
||||
@@ -893,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'
|
||||
@@ -906,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'
|
||||
@@ -928,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'
|
||||
@@ -949,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'
|
||||
@@ -980,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'
|
||||
@@ -1011,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'
|
||||
@@ -1030,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'
|
||||
@@ -1039,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'
|
||||
@@ -1147,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'
|
||||
@@ -1173,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'
|
||||
@@ -1190,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'
|
||||
@@ -1221,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'
|
||||
@@ -1240,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'
|
||||
@@ -1289,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'
|
||||
@@ -1305,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'
|
||||
@@ -1355,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:
|
||||
@@ -1376,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
|
||||
@@ -1416,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'
|
||||
@@ -1433,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:
|
||||
|
||||
3
Gemfile
3
Gemfile
@@ -86,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'
|
||||
|
||||
14
Gemfile.lock
14
Gemfile.lock
@@ -148,7 +148,7 @@ GEM
|
||||
nokogiri (>= 1.4.4)
|
||||
uuidtools (~> 2.1)
|
||||
bcrypt (3.1.13)
|
||||
bugsnag (6.15.0)
|
||||
bugsnag (6.16.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
builder (3.1.4)
|
||||
byebug (11.0.1)
|
||||
@@ -192,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)
|
||||
@@ -229,7 +229,6 @@ GEM
|
||||
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)
|
||||
@@ -483,8 +482,8 @@ GEM
|
||||
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)
|
||||
@@ -555,7 +554,7 @@ 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)
|
||||
@@ -743,7 +742,6 @@ DEPENDENCIES
|
||||
devise-encryptable
|
||||
devise-token_authenticatable (~> 0.4.10)
|
||||
dfc_provider!
|
||||
diffy
|
||||
eventmachine (>= 1.2.3)
|
||||
factory_bot_rails (= 4.10.0)
|
||||
ffaker (~> 1.16)
|
||||
@@ -777,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)
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
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
|
||||
|
||||
@@ -235,6 +235,7 @@ class CheckoutController < Spree::StoreController
|
||||
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
|
||||
@@ -248,4 +249,11 @@ class CheckoutController < Spree::StoreController
|
||||
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
|
||||
|
||||
16
app/controllers/spree/base_controller.rb
Normal file
16
app/controllers/spree/base_controller.rb
Normal file
@@ -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'
|
||||
@@ -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'
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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}"
|
||||
})
|
||||
|
||||
@@ -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"}
|
||||
|
||||
@@ -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"}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -30,8 +31,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']
|
||||
|
||||
@@ -14,6 +14,7 @@ en_GB:
|
||||
spree/payment:
|
||||
amount: Amount
|
||||
state: State
|
||||
source: Source
|
||||
spree/product:
|
||||
primary_taxon: "Product Category"
|
||||
supplier: "Supplier"
|
||||
@@ -272,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"
|
||||
@@ -1967,6 +1971,7 @@ en_GB:
|
||||
supplier: "Supplier"
|
||||
product_name: "Product Name"
|
||||
product_description: "Product Description"
|
||||
permalink: "Permalink"
|
||||
shipping_categories: "Shipping Categories"
|
||||
units: "Unit Size"
|
||||
coordinator: "Coordinator"
|
||||
@@ -2064,6 +2069,7 @@ 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 "
|
||||
@@ -3183,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:
|
||||
@@ -3381,6 +3389,11 @@ en_GB:
|
||||
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
|
||||
|
||||
@@ -32,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:
|
||||
|
||||
@@ -14,6 +14,7 @@ pt_BR:
|
||||
spree/payment:
|
||||
amount: Montante
|
||||
state: Estado
|
||||
source: Origem
|
||||
spree/product:
|
||||
primary_taxon: "Categoria de Produto"
|
||||
supplier: "Fornecedor"
|
||||
@@ -272,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"
|
||||
@@ -1013,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:
|
||||
@@ -1036,6 +1040,9 @@ pt_BR:
|
||||
subscriptions:
|
||||
index:
|
||||
title: "Assinaturas"
|
||||
new: "Nova Assinatura"
|
||||
new:
|
||||
title: "Nova Assinatura"
|
||||
edit:
|
||||
title: "Editar assinatura"
|
||||
table:
|
||||
@@ -1060,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
|
||||
@@ -1206,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"
|
||||
@@ -1526,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"
|
||||
@@ -1960,6 +1969,7 @@ 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"
|
||||
@@ -2057,6 +2067,7 @@ 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"
|
||||
@@ -3065,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"
|
||||
@@ -3373,6 +3384,11 @@ pt_BR:
|
||||
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
|
||||
|
||||
@@ -1885,7 +1885,7 @@ tr:
|
||||
twitter: "Twitter"
|
||||
twitter_placeholder: "Örn. @twitter_ciftlik"
|
||||
instagram: "Instagram"
|
||||
instagram_placeholder: "Örn. @instagram_ciftlik"
|
||||
instagram_placeholder: "Örn. instagram_ciftlik"
|
||||
limit_reached:
|
||||
headline: "Hayır!"
|
||||
message: "Sınıra ulaştınız!"
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
58
lib/spree/core.rb
Normal file
58
lib/spree/core.rb
Normal file
@@ -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
|
||||
81
lib/spree/core/calculated_adjustments.rb
Normal file
81
lib/spree/core/calculated_adjustments.rb
Normal file
@@ -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
|
||||
@@ -68,8 +68,7 @@ module Spree
|
||||
session[:guest_token] = nil
|
||||
end
|
||||
|
||||
# Do not attempt to merge incomplete and current orders.
|
||||
# Instead, destroy the incomplete orders.
|
||||
# Recover incomplete orders from other sessions after logging in.
|
||||
def set_current_order
|
||||
return unless (user = spree_current_user)
|
||||
|
||||
@@ -77,11 +76,10 @@ module Spree
|
||||
|
||||
if session[:order_id].nil? && last_incomplete_order
|
||||
session[:order_id] = last_incomplete_order.id
|
||||
elsif current_order(true) &&
|
||||
last_incomplete_order &&
|
||||
current_order != last_incomplete_order
|
||||
last_incomplete_order.destroy
|
||||
end
|
||||
|
||||
# Load current order and create a new one if necessary.
|
||||
current_order(true)
|
||||
end
|
||||
|
||||
def current_currency
|
||||
|
||||
94
lib/spree/core/delegate_belongs_to.rb
Normal file
94
lib/spree/core/delegate_belongs_to.rb
Normal file
@@ -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)
|
||||
13
lib/spree/core/environment/calculators.rb
Normal file
13
lib/spree/core/environment/calculators.rb
Normal file
@@ -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
|
||||
27
lib/spree/core/environment_extension.rb
Normal file
27
lib/spree/core/environment_extension.rb
Normal file
@@ -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
|
||||
7
lib/spree/core/gateway_error.rb
Normal file
7
lib/spree/core/gateway_error.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Spree
|
||||
module Core
|
||||
class GatewayError < RuntimeError; end
|
||||
end
|
||||
end
|
||||
24
lib/spree/core/mail_interceptor.rb
Normal file
24
lib/spree/core/mail_interceptor.rb
Normal file
@@ -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
|
||||
63
lib/spree/core/mail_settings.rb
Normal file
63
lib/spree/core/mail_settings.rb
Normal file
@@ -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
|
||||
75
lib/spree/core/permalinks.rb
Normal file
75
lib/spree/core/permalinks.rb
Normal file
@@ -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)
|
||||
35
lib/spree/core/s3_support.rb
Normal file
35
lib/spree/core/s3_support.rb
Normal file
@@ -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
|
||||
28
lib/spree/core/token_resource.rb
Normal file
28
lib/spree/core/token_resource.rb
Normal file
@@ -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 }
|
||||
38
lib/spree/i18n.rb
Normal file
38
lib/spree/i18n.rb
Normal file
@@ -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
|
||||
19
lib/spree/i18n/base.rb
Normal file
19
lib/spree/i18n/base.rb
Normal file
@@ -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
|
||||
3
lib/spree/i18n/initializer.rb
Normal file
3
lib/spree/i18n/initializer.rb
Normal file
@@ -0,0 +1,3 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
Spree::BaseController.include(Spree::ViewContext)
|
||||
42
lib/spree/money.rb
Normal file
42
lib/spree/money.rb
Normal file
@@ -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
|
||||
63
lib/spree/product_duplicator.rb
Normal file
63
lib/spree/product_duplicator.rb
Normal file
@@ -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
|
||||
57
lib/spree/responder.rb
Normal file
57
lib/spree/responder.rb
Normal file
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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) ->
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
require 'spec_helper'
|
||||
require 'open_food_network/orders_and_fulfillments_report'
|
||||
require 'open_food_network/order_grouper'
|
||||
|
||||
describe OpenFoodNetwork::OrdersAndFulfillmentsReport do
|
||||
include AuthenticationHelper
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
73
spec/lib/spree/core/calculated_adjustments_spec.rb
Normal file
73
spec/lib/spree/core/calculated_adjustments_spec.rb
Normal file
@@ -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
|
||||
19
spec/lib/spree/core/environment_spec.rb
Normal file
19
spec/lib/spree/core/environment_spec.rb
Normal file
@@ -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
|
||||
82
spec/lib/spree/core/mail_interceptor_spec.rb
Normal file
82
spec/lib/spree/core/mail_interceptor_spec.rb
Normal file
@@ -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
|
||||
90
spec/lib/spree/core/mail_settings_spec.rb
Normal file
90
spec/lib/spree/core/mail_settings_spec.rb
Normal file
@@ -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
|
||||
35
spec/lib/spree/core/token_resource_spec.rb
Normal file
35
spec/lib/spree/core/token_resource_spec.rb
Normal file
@@ -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
|
||||
127
spec/lib/spree/i18n_spec.rb
Normal file
127
spec/lib/spree/i18n_spec.rb
Normal file
@@ -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("<span")
|
||||
end
|
||||
|
||||
context "missed + unused translations" do
|
||||
def key_with_locale(key)
|
||||
"#{key} (#{I18n.locale})"
|
||||
end
|
||||
|
||||
before do
|
||||
Spree.used_translations = []
|
||||
end
|
||||
|
||||
context "missed translations" do
|
||||
def assert_missing_translation(key)
|
||||
key = key_with_locale(key)
|
||||
message = Spree.missing_translation_messages.detect { |m| m == key }
|
||||
expect(message).not_to(be_nil, "expected '#{key}' to be missing, but it wasn't.")
|
||||
end
|
||||
|
||||
it "logs missing translations" do
|
||||
Spree.t(:missing, scope: [:else, :where])
|
||||
Spree.check_missing_translations
|
||||
assert_missing_translation("else")
|
||||
assert_missing_translation("else.where")
|
||||
assert_missing_translation("else.where.missing")
|
||||
end
|
||||
|
||||
it "does not log present translations" do
|
||||
Spree.t(:foo)
|
||||
Spree.check_missing_translations
|
||||
expect(Spree.missing_translation_messages).to be_empty
|
||||
end
|
||||
|
||||
it "does not break when asked for multiple translations" do
|
||||
Spree.t [:foo, 'bar.foo']
|
||||
Spree.check_missing_translations
|
||||
expect(Spree.missing_translation_messages).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context "unused translations" do
|
||||
def assert_unused_translation(key)
|
||||
key = key_with_locale(key)
|
||||
message = Spree.unused_translation_messages.detect { |m| m == key }
|
||||
expect(message).not_to(be_nil, "expected '#{key}' to be unused, but it was used.")
|
||||
end
|
||||
|
||||
def assert_used_translation(key)
|
||||
key = key_with_locale(key)
|
||||
message = Spree.unused_translation_messages.detect { |m| m == key }
|
||||
expect(message).to(be_nil, "expected '#{key}' to be used, but it wasn't.")
|
||||
end
|
||||
|
||||
it "logs translations that aren't used" do
|
||||
Spree.check_unused_translations
|
||||
assert_unused_translation("bar.legacy_translation")
|
||||
assert_unused_translation("legacy_translation")
|
||||
end
|
||||
|
||||
it "does not log used translations" do
|
||||
Spree.t(:foo)
|
||||
Spree.check_unused_translations
|
||||
assert_used_translation("foo")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
135
spec/lib/spree/money_spec.rb
Normal file
135
spec/lib/spree/money_spec.rb
Normal file
@@ -0,0 +1,135 @@
|
||||
# frozen_string_literal: false
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe Spree::Money do
|
||||
before do
|
||||
configure_spree_preferences do |config|
|
||||
config.currency = "USD"
|
||||
config.currency_symbol_position = :before
|
||||
config.display_currency = false
|
||||
end
|
||||
end
|
||||
|
||||
it "formats correctly" do
|
||||
money = Spree::Money.new(10)
|
||||
expect(money.to_s).to eq("$10.00")
|
||||
end
|
||||
|
||||
it "can get cents" do
|
||||
money = Spree::Money.new(10)
|
||||
expect(money.cents).to eq(1000)
|
||||
end
|
||||
|
||||
context "with currency" do
|
||||
it "passed in option" do
|
||||
money = Spree::Money.new(10, with_currency: true, html: false)
|
||||
expect(money.to_s).to eq("$10.00 USD")
|
||||
end
|
||||
|
||||
it "config option" do
|
||||
Spree::Config[:display_currency] = true
|
||||
money = Spree::Money.new(10, html: false)
|
||||
expect(money.to_s).to eq("$10.00 USD")
|
||||
end
|
||||
end
|
||||
|
||||
context "hide cents" do
|
||||
it "hides cents suffix" do
|
||||
Spree::Config[:hide_cents] = true
|
||||
money = Spree::Money.new(10)
|
||||
expect(money.to_s).to eq("$10")
|
||||
end
|
||||
|
||||
it "shows cents suffix" do
|
||||
Spree::Config[:hide_cents] = false
|
||||
money = Spree::Money.new(10)
|
||||
expect(money.to_s).to eq("$10.00")
|
||||
end
|
||||
end
|
||||
|
||||
context "currency parameter" do
|
||||
context "when currency is specified in Canadian Dollars" do
|
||||
it "uses the currency param over the global configuration" do
|
||||
money = Spree::Money.new(10, currency: 'CAD', with_currency: true, html: false)
|
||||
expect(money.to_s).to eq("$10.00 CAD")
|
||||
end
|
||||
end
|
||||
|
||||
context "when currency is specified in Japanese Yen" do
|
||||
it "uses the currency param over the global configuration" do
|
||||
money = Spree::Money.new(100, currency: 'JPY', html: false)
|
||||
expect(money.to_s).to eq("¥100")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "symbol positioning" do
|
||||
it "passed in option" do
|
||||
money = Spree::Money.new(10, symbol_position: :after, html: false)
|
||||
expect(money.to_s).to eq("10.00 $")
|
||||
end
|
||||
|
||||
it "passed in option string" do
|
||||
money = Spree::Money.new(10, symbol_position: "after", html: false)
|
||||
expect(money.to_s).to eq("10.00 $")
|
||||
end
|
||||
|
||||
it "config option" do
|
||||
Spree::Config[:currency_symbol_position] = :after
|
||||
money = Spree::Money.new(10, html: false)
|
||||
expect(money.to_s).to eq("10.00 $")
|
||||
end
|
||||
end
|
||||
|
||||
context "JPY" do
|
||||
before do
|
||||
configure_spree_preferences do |config|
|
||||
config.currency = "JPY"
|
||||
config.currency_symbol_position = :before
|
||||
config.display_currency = false
|
||||
end
|
||||
end
|
||||
|
||||
it "formats correctly" do
|
||||
money = Spree::Money.new(1000, html: false)
|
||||
expect(money.to_s).to eq("¥1,000")
|
||||
end
|
||||
end
|
||||
|
||||
context "EUR" do
|
||||
before do
|
||||
configure_spree_preferences do |config|
|
||||
config.currency = "EUR"
|
||||
config.currency_symbol_position = :after
|
||||
config.display_currency = false
|
||||
end
|
||||
end
|
||||
|
||||
# Regression test for Spree #2634
|
||||
it "formats as plain by default" do
|
||||
money = Spree::Money.new(10)
|
||||
expect(money.to_s).to eq("10.00 €")
|
||||
end
|
||||
|
||||
# Regression test for Spree #2632
|
||||
it "acknowledges decimal mark option" do
|
||||
Spree::Config[:currency_decimal_mark] = ","
|
||||
money = Spree::Money.new(10)
|
||||
expect(money.to_s).to eq("10,00 €")
|
||||
end
|
||||
|
||||
# Regression test for Spree #2632
|
||||
it "acknowledges thousands separator option" do
|
||||
Spree::Config[:currency_thousands_separator] = "."
|
||||
money = Spree::Money.new(1000)
|
||||
expect(money.to_s).to eq("1.000.00 €")
|
||||
end
|
||||
|
||||
it "formats as HTML if asked (nicely) to" do
|
||||
money = Spree::Money.new(10)
|
||||
# The HTMLified version of the euro sign
|
||||
expect(money.to_html).to eq("10.00 €")
|
||||
end
|
||||
end
|
||||
end
|
||||
86
spec/lib/spree/product_duplicator_spec.rb
Normal file
86
spec/lib/spree/product_duplicator_spec.rb
Normal file
@@ -0,0 +1,86 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
module Spree
|
||||
describe Spree::ProductDuplicator do
|
||||
let(:product) do
|
||||
double 'Product',
|
||||
name: "foo",
|
||||
taxons: [],
|
||||
product_properties: [property],
|
||||
master: variant,
|
||||
has_variants?: false
|
||||
end
|
||||
|
||||
let(:new_product) do
|
||||
double 'New Product',
|
||||
save!: true
|
||||
end
|
||||
|
||||
let(:property) do
|
||||
double 'Property'
|
||||
end
|
||||
|
||||
let(:new_property) do
|
||||
double 'New Property'
|
||||
end
|
||||
|
||||
let(:variant) do
|
||||
double 'Variant',
|
||||
sku: "12345",
|
||||
price: 19.99,
|
||||
currency: "AUD",
|
||||
images: [image]
|
||||
end
|
||||
|
||||
let(:new_variant) do
|
||||
double 'New Variant',
|
||||
sku: "12345"
|
||||
end
|
||||
|
||||
let(:image) do
|
||||
double 'Image',
|
||||
attachment: double('Attachment')
|
||||
end
|
||||
|
||||
let(:new_image) do
|
||||
double 'New Image'
|
||||
end
|
||||
|
||||
before do
|
||||
expect(product).to receive(:dup).and_return(new_product)
|
||||
expect(variant).to receive(:dup).and_return(new_variant)
|
||||
expect(image).to receive(:dup).and_return(new_image)
|
||||
expect(property).to receive(:dup).and_return(new_property)
|
||||
end
|
||||
|
||||
it "can duplicate a product" do
|
||||
duplicator = Spree::ProductDuplicator.new(product)
|
||||
expect(new_product).to receive(:name=).with("COPY OF foo")
|
||||
expect(new_product).to receive(:taxons=).with([])
|
||||
expect(new_product).to receive(:product_properties=).with([new_property])
|
||||
expect(new_product).to receive(:created_at=).with(nil)
|
||||
expect(new_product).to receive(:updated_at=).with(nil)
|
||||
expect(new_product).to receive(:deleted_at=).with(nil)
|
||||
expect(new_product).to receive(:master=).with(new_variant)
|
||||
|
||||
expect(new_variant).to receive(:sku=).with("COPY OF 12345")
|
||||
expect(new_variant).to receive(:deleted_at=).with(nil)
|
||||
expect(new_variant).to receive(:images=).with([new_image])
|
||||
expect(new_variant).to receive(:price=).with(variant.price)
|
||||
expect(new_variant).to receive(:currency=).with(variant.currency)
|
||||
|
||||
expect(image.attachment).to receive(:clone).and_return(image.attachment)
|
||||
|
||||
expect(new_image).to receive(:assign_attributes).
|
||||
with(attachment: image.attachment).
|
||||
and_return(new_image)
|
||||
|
||||
expect(new_property).to receive(:created_at=).with(nil)
|
||||
expect(new_property).to receive(:updated_at=).with(nil)
|
||||
|
||||
duplicator.duplicate
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,149 +0,0 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe OrderUpdater do
|
||||
let(:order) { build(:order) }
|
||||
let(:order_updater) { described_class.new(Spree::OrderUpdater.new(order)) }
|
||||
|
||||
it "is failed if no valid payments" do
|
||||
allow(order).to receive_message_chain(:payments, :valid, :empty?).and_return(true)
|
||||
|
||||
order_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 {
|
||||
order_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 {
|
||||
order_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 {
|
||||
order_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 {
|
||||
order_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 {
|
||||
order_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 {
|
||||
order_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 { order_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 { order_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 { order_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
|
||||
order_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
|
||||
order_updater.before_save_hook
|
||||
expect(order.ship_address.firstname).to eq("will")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user