mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
Merge remote-tracking branch 'origin/master' into HEAD
This commit is contained in:
@@ -143,6 +143,10 @@ Style/WordArray:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#stylewordarray
|
||||
|
||||
Style/SymbolArray:
|
||||
Enabled: false
|
||||
StyleGuide: https://rubocop.readthedocs.io/en/latest/cops_style/#stylesymbolarray
|
||||
|
||||
Lint/AmbiguousRegexpLiteral:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#lintambiguousregexpliteral
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# This configuration was generated by
|
||||
# `rubocop --auto-gen-config --exclude-limit 100`
|
||||
# on 2017-07-12 10:36:44 +0200 using RuboCop version 0.49.1.
|
||||
# on 2017-08-25 14:27:48 +1000 using RuboCop version 0.49.1.
|
||||
# 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
|
||||
@@ -14,7 +14,7 @@ Bundler/OrderedGems:
|
||||
Exclude:
|
||||
- 'Gemfile'
|
||||
|
||||
# Offense count: 77
|
||||
# Offense count: 128
|
||||
# Cop supports --auto-correct.
|
||||
Layout/AlignArray:
|
||||
Exclude:
|
||||
@@ -59,7 +59,7 @@ Layout/AlignHash:
|
||||
- 'spec/models/spree/shipping_method_spec.rb'
|
||||
- 'spec/models/spree/variant_spec.rb'
|
||||
|
||||
# Offense count: 42
|
||||
# Offense count: 43
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth.
|
||||
# SupportedStyles: with_first_parameter, with_fixed_indentation
|
||||
@@ -113,11 +113,12 @@ Layout/CaseIndentation:
|
||||
- 'app/models/enterprise.rb'
|
||||
- 'app/models/product_importer.rb'
|
||||
|
||||
# Offense count: 2
|
||||
# Offense count: 3
|
||||
# Cop supports --auto-correct.
|
||||
Layout/ClosingParenthesisIndentation:
|
||||
Exclude:
|
||||
- 'app/overrides/add_capture_order_shortcut.rb'
|
||||
- 'spec/serializers/variant_serializer_spec.rb'
|
||||
|
||||
# Offense count: 8
|
||||
# Cop supports --auto-correct.
|
||||
@@ -137,7 +138,7 @@ Layout/ElseAlignment:
|
||||
- 'app/serializers/api/admin/order_cycle_serializer.rb'
|
||||
- 'lib/open_food_network/sales_tax_report.rb'
|
||||
|
||||
# Offense count: 223
|
||||
# Offense count: 215
|
||||
# Cop supports --auto-correct.
|
||||
Layout/EmptyLines:
|
||||
Enabled: false
|
||||
@@ -152,7 +153,7 @@ Layout/EmptyLinesAroundAccessModifier:
|
||||
- 'spec/helpers/products_helper_spec.rb'
|
||||
- 'spec/support/request/web_helper.rb'
|
||||
|
||||
# Offense count: 73
|
||||
# Offense count: 70
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: empty_lines, no_empty_lines
|
||||
@@ -170,7 +171,6 @@ Layout/EmptyLinesAroundBlockBody:
|
||||
- 'app/models/spree/calculator_decorator.rb'
|
||||
- 'app/models/spree/money_decorator.rb'
|
||||
- 'app/models/spree/option_value_decorator.rb'
|
||||
- 'app/models/spree/payment_decorator.rb'
|
||||
- 'lib/open_food_network/group_buy_report.rb'
|
||||
- 'lib/spree/money_decorator.rb'
|
||||
- 'lib/tasks/dev.rake'
|
||||
@@ -188,10 +188,10 @@ Layout/EmptyLinesAroundBlockBody:
|
||||
- 'spec/features/admin/orders_spec.rb'
|
||||
- 'spec/features/admin/reports_spec.rb'
|
||||
- 'spec/features/admin/variant_overrides_spec.rb'
|
||||
- 'spec/features/consumer/shopping/embedded_shopfronts_spec.rb'
|
||||
- 'spec/features/consumer/shopping/shopping_spec.rb'
|
||||
- 'spec/features/consumer/shopping/variant_overrides_spec.rb'
|
||||
- 'spec/helpers/admin/business_model_configuration_helper_spec.rb'
|
||||
- 'spec/helpers/injection_helper_spec.rb'
|
||||
- 'spec/helpers/shared_helper_spec.rb'
|
||||
- 'spec/helpers/shop_helper_spec.rb'
|
||||
- 'spec/helpers/spree/orders_helper_spec.rb'
|
||||
@@ -212,8 +212,7 @@ Layout/EmptyLinesAroundBlockBody:
|
||||
- 'spec/models/tag_rule/filter_shipping_methods_spec.rb'
|
||||
- 'spec/serializers/admin/for_order_cycle/enterprise_serializer_spec.rb'
|
||||
- 'spec/serializers/admin/for_order_cycle/supplied_product_serializer_spec.rb'
|
||||
- 'spec/serializers/order_serializer_spec.rb'
|
||||
- 'spec/serializers/orders_by_distributor_serializer_spec.rb'
|
||||
- 'spec/serializers/variant_serializer_spec.rb'
|
||||
- 'spec/support/matchers/delegate_matchers.rb'
|
||||
- 'spec/support/matchers/select2_matchers.rb'
|
||||
- 'spec/support/matchers/table_matchers.rb'
|
||||
@@ -270,7 +269,7 @@ Layout/EmptyLinesAroundMethodBody:
|
||||
- 'app/serializers/api/product_serializer.rb'
|
||||
- 'lib/open_food_network/orders_and_fulfillments_report.rb'
|
||||
|
||||
# Offense count: 13
|
||||
# Offense count: 12
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: empty_lines, empty_lines_except_namespace, empty_lines_special, no_empty_lines
|
||||
@@ -278,7 +277,6 @@ Layout/EmptyLinesAroundModuleBody:
|
||||
Exclude:
|
||||
- 'app/helpers/add_to_cart_helper.rb'
|
||||
- 'app/helpers/groups_helper.rb'
|
||||
- 'app/helpers/injection_helper.rb'
|
||||
- 'app/helpers/spree/admin/base_helper_decorator.rb'
|
||||
- 'lib/open_food_network/column_preference_defaults.rb'
|
||||
- 'lib/open_food_network/group_buy_report.rb'
|
||||
@@ -289,7 +287,7 @@ Layout/EmptyLinesAroundModuleBody:
|
||||
- 'spec/support/request/distribution_helper.rb'
|
||||
- 'spec/support/request/ui_component_helper.rb'
|
||||
|
||||
# Offense count: 54
|
||||
# Offense count: 55
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: AllowForAlignment, ForceEqualSignAlignment.
|
||||
Layout/ExtraSpacing:
|
||||
@@ -326,29 +324,28 @@ Layout/ExtraSpacing:
|
||||
- 'spec/models/enterprise_spec.rb'
|
||||
- 'spec/models/order_cycle_spec.rb'
|
||||
- 'spec/models/spree/adjustment_spec.rb'
|
||||
- 'spec/models/spree/gateway/stripe_connect_spec.rb'
|
||||
- 'spec/models/spree/order_spec.rb'
|
||||
- 'spec/models/variant_override_spec.rb'
|
||||
- 'spec/serializers/admin/for_order_cycle/enterprise_serializer_spec.rb'
|
||||
- 'spec/serializers/admin/for_order_cycle/supplied_product_serializer_spec.rb'
|
||||
- 'spec/support/request/web_helper.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Offense count: 2
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth.
|
||||
# SupportedStyles: consistent, special_for_inner_method_call, special_for_inner_method_call_in_parentheses
|
||||
Layout/FirstParameterIndentation:
|
||||
Exclude:
|
||||
- 'lib/open_food_network/permissions.rb'
|
||||
- 'spec/serializers/variant_serializer_spec.rb'
|
||||
|
||||
# Offense count: 6
|
||||
# Offense count: 4
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth.
|
||||
# Configuration parameters: SupportedStyles, IndentationWidth.
|
||||
# SupportedStyles: special_inside_parentheses, consistent, align_brackets
|
||||
Layout/IndentArray:
|
||||
Exclude:
|
||||
- 'lib/open_food_network/users_and_enterprises_report.rb'
|
||||
- 'spec/features/admin/reports_spec.rb'
|
||||
- 'spec/lib/open_food_network/products_and_inventory_report_spec.rb'
|
||||
EnforcedStyle: consistent
|
||||
|
||||
# Offense count: 2
|
||||
# Cop supports --auto-correct.
|
||||
@@ -403,7 +400,7 @@ Layout/IndentationConsistency:
|
||||
- 'spec/models/spree/line_item_spec.rb'
|
||||
- 'spec/models/spree/product_spec.rb'
|
||||
|
||||
# Offense count: 20
|
||||
# Offense count: 18
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: Width, IgnoredPatterns.
|
||||
Layout/IndentationWidth:
|
||||
@@ -411,13 +408,11 @@ Layout/IndentationWidth:
|
||||
- 'app/controllers/admin/invoice_settings_controller.rb'
|
||||
- 'app/controllers/admin/order_cycles_controller.rb'
|
||||
- 'app/controllers/api/order_cycles_controller.rb'
|
||||
- 'app/controllers/spree/admin/reports_controller_decorator.rb'
|
||||
- 'app/models/spree/line_item_decorator.rb'
|
||||
- 'app/serializers/api/admin/for_order_cycle/enterprise_serializer.rb'
|
||||
- 'app/serializers/api/admin/for_order_cycle/supplied_product_serializer.rb'
|
||||
- 'app/serializers/api/admin/order_cycle_serializer.rb'
|
||||
- 'lib/discourse/single_sign_on.rb'
|
||||
- 'lib/open_food_network/last_used_address.rb'
|
||||
- 'spec/features/consumer/shopping/variant_overrides_spec.rb'
|
||||
- 'spec/helpers/admin/business_model_configuration_helper_spec.rb'
|
||||
- 'spec/helpers/groups_helper_spec.rb'
|
||||
@@ -455,7 +450,6 @@ Layout/LeadingCommentSpace:
|
||||
- 'spec/factories.rb'
|
||||
- 'spec/features/admin/products_spec.rb'
|
||||
- 'spec/features/admin/reports_spec.rb'
|
||||
- 'spec/features/consumer/shops_spec.rb'
|
||||
- 'spec/jobs/finalize_account_invoices_spec.rb'
|
||||
- 'spec/lib/open_food_network/order_and_distributor_report_spec.rb'
|
||||
- 'spec/lib/open_food_network/order_grouper_spec.rb'
|
||||
@@ -526,7 +520,15 @@ Layout/MultilineMethodCallBraceLayout:
|
||||
- 'lib/open_food_network/products_renderer.rb'
|
||||
- 'spec/lib/open_food_network/products_and_inventory_report_spec.rb'
|
||||
|
||||
# Offense count: 34
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth.
|
||||
# SupportedStyles: aligned, indented, indented_relative_to_receiver
|
||||
Layout/MultilineMethodCallIndentation:
|
||||
Exclude:
|
||||
- 'spec/serializers/variant_serializer_spec.rb'
|
||||
|
||||
# Offense count: 33
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth.
|
||||
# SupportedStyles: aligned, indented
|
||||
@@ -539,7 +541,6 @@ Layout/MultilineOperationIndentation:
|
||||
- 'app/models/producer_property.rb'
|
||||
- 'app/models/product_importer.rb'
|
||||
- 'app/models/spree/ability_decorator.rb'
|
||||
- 'app/models/spree/order_decorator.rb'
|
||||
- 'app/models/spree/product_set.rb'
|
||||
- 'app/models/variant_override_set.rb'
|
||||
- 'lib/open_food_network/accounts_and_billing_settings_validator.rb'
|
||||
@@ -559,20 +560,18 @@ Layout/SpaceAfterColon:
|
||||
- 'spec/models/variant_override_spec.rb'
|
||||
- 'spec/spec_helper.rb'
|
||||
|
||||
# Offense count: 58
|
||||
# Offense count: 53
|
||||
# Cop supports --auto-correct.
|
||||
Layout/SpaceAfterComma:
|
||||
Exclude:
|
||||
- 'app/controllers/admin/order_cycles_controller.rb'
|
||||
- 'app/controllers/spree/admin/products_controller_decorator.rb'
|
||||
- 'app/controllers/spree/admin/reports_controller_decorator.rb'
|
||||
- 'app/controllers/spree/orders_controller_decorator.rb'
|
||||
- 'app/models/column_preference.rb'
|
||||
- 'app/models/product_importer.rb'
|
||||
- 'lib/discourse/single_sign_on.rb'
|
||||
- 'lib/open_food_network/accounts_and_billing_settings_validator.rb'
|
||||
- 'lib/open_food_network/business_model_configuration_validator.rb'
|
||||
- 'lib/open_food_network/order_and_distributor_report.rb'
|
||||
- 'lib/open_food_network/order_cycle_form_applicator.rb'
|
||||
- 'lib/open_food_network/users_and_enterprises_report.rb'
|
||||
- 'spec/controllers/admin/enterprises_controller_spec.rb'
|
||||
@@ -649,7 +648,7 @@ Layout/SpaceAroundEqualsInParameterDefault:
|
||||
- 'spec/support/request/distribution_helper.rb'
|
||||
- 'spec/support/request/web_helper.rb'
|
||||
|
||||
# Offense count: 58
|
||||
# Offense count: 60
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: AllowForAlignment.
|
||||
Layout/SpaceAroundOperators:
|
||||
@@ -678,6 +677,7 @@ Layout/SpaceAroundOperators:
|
||||
- 'spec/helpers/order_cycles_helper_spec.rb'
|
||||
- 'spec/jobs/update_billable_periods_spec.rb'
|
||||
- 'spec/lib/open_food_network/order_grouper_spec.rb'
|
||||
- 'spec/lib/stripe/account_connector_spec.rb'
|
||||
- 'spec/models/calculator/weight_spec.rb'
|
||||
- 'spec/support/cancan_helper.rb'
|
||||
- 'spec/support/seeds.rb'
|
||||
@@ -716,7 +716,7 @@ Layout/SpaceInLambdaLiteral:
|
||||
- 'app/models/spree/product_decorator.rb'
|
||||
- 'app/models/spree/variant_decorator.rb'
|
||||
|
||||
# Offense count: 194
|
||||
# Offense count: 187
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles, EnforcedStyleForEmptyBraces, SupportedStylesForEmptyBraces, SpaceBeforeBlockParameters.
|
||||
# SupportedStyles: space, no_space
|
||||
@@ -766,11 +766,9 @@ Layout/SpaceInsideBlockBraces:
|
||||
- 'spec/models/spree/order_spec.rb'
|
||||
- 'spec/models/spree/payment_spec.rb'
|
||||
- 'spec/models/spree/product_spec.rb'
|
||||
- 'spec/models/spree/user_spec.rb'
|
||||
- 'spec/models/tag_rule/discount_order_spec.rb'
|
||||
- 'spec/serializers/admin/for_order_cycle/enterprise_serializer_spec.rb'
|
||||
- 'spec/serializers/admin/for_order_cycle/supplied_product_serializer_spec.rb'
|
||||
- 'spec/serializers/orders_by_distributor_serializer_spec.rb'
|
||||
- 'spec/spec_helper.rb'
|
||||
- 'spec/support/cancan_helper.rb'
|
||||
|
||||
@@ -797,7 +795,7 @@ Layout/SpaceInsideBrackets:
|
||||
- 'spec/lib/open_food_network/users_and_enterprises_report_spec.rb'
|
||||
- 'spec/performance/orders_controller_spec.rb'
|
||||
|
||||
# Offense count: 729
|
||||
# Offense count: 766
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles, EnforcedStyleForEmptyBraces, SupportedStylesForEmptyBraces.
|
||||
# SupportedStyles: space, no_space, compact
|
||||
@@ -824,12 +822,11 @@ Layout/Tab:
|
||||
- 'spec/lib/spree/product_filters_spec.rb'
|
||||
- 'spec/models/spree/line_item_spec.rb'
|
||||
|
||||
# Offense count: 32
|
||||
# Offense count: 42
|
||||
# Cop supports --auto-correct.
|
||||
Layout/TrailingWhitespace:
|
||||
Exclude:
|
||||
- 'app/models/distributor_shipping_method.rb'
|
||||
- 'app/models/product_importer.rb'
|
||||
- 'app/models/spree/money_decorator.rb'
|
||||
- 'app/serializers/api/image_serializer.rb'
|
||||
- 'app/serializers/api/shipping_method_serializer.rb'
|
||||
@@ -837,7 +834,6 @@ Layout/TrailingWhitespace:
|
||||
- 'app/views/json/_enterprises.rabl'
|
||||
- 'app/views/json/_producer.rabl'
|
||||
- 'app/views/json/partials/_producer.rabl'
|
||||
- 'lib/open_food_network/group_buy_report.rb'
|
||||
- 'lib/tasks/dev.rake'
|
||||
- 'spec/controllers/spree/store_controller_spec.rb'
|
||||
- 'spec/features/admin/enterprise_user_spec.rb'
|
||||
@@ -845,17 +841,16 @@ Layout/TrailingWhitespace:
|
||||
- 'spec/lib/open_food_network/option_value_namer_spec.rb'
|
||||
- 'spec/lib/open_food_network/order_grouper_spec.rb'
|
||||
- 'spec/serializers/admin/enterprise_serializer_spec.rb'
|
||||
- 'spec/serializers/variant_serializer_spec.rb'
|
||||
- 'spec/support/request/menu_helper.rb'
|
||||
- 'spec/views/json/producers.json.rabl_spec.rb'
|
||||
|
||||
# Offense count: 8
|
||||
# Offense count: 6
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyleAlignWith, SupportedStylesAlignWith.
|
||||
# SupportedStylesAlignWith: either, start_of_block, start_of_line
|
||||
Lint/BlockAlignment:
|
||||
Exclude:
|
||||
- 'app/controllers/spree/admin/reports_controller_decorator.rb'
|
||||
- 'lib/open_food_network/last_used_address.rb'
|
||||
- 'spec/lib/open_food_network/enterprise_fee_calculator_spec.rb'
|
||||
- 'spec/models/enterprise_spec.rb'
|
||||
- 'spec/models/spree/calculator/flat_percent_item_total_spec.rb'
|
||||
@@ -1012,7 +1007,7 @@ Lint/UselessAccessModifier:
|
||||
- 'lib/open_food_network/reports/bulk_coop_report.rb'
|
||||
- 'spec/lib/open_food_network/reports/report_spec.rb'
|
||||
|
||||
# Offense count: 340
|
||||
# Offense count: 341
|
||||
Lint/Void:
|
||||
Exclude:
|
||||
- 'app/serializers/api/enterprise_serializer.rb'
|
||||
@@ -1081,7 +1076,7 @@ Lint/Void:
|
||||
- 'spec/serializers/enterprise_serializer_spec.rb'
|
||||
- 'spec/support/request/web_helper.rb'
|
||||
|
||||
# Offense count: 706
|
||||
# Offense count: 747
|
||||
# Configuration parameters: CountComments, ExcludedMethods.
|
||||
Metrics/BlockLength:
|
||||
Max: 711
|
||||
@@ -1166,7 +1161,7 @@ Rails/Delegate:
|
||||
- 'app/serializers/api/admin/tag_rule_serializer.rb'
|
||||
- 'app/serializers/api/variant_serializer.rb'
|
||||
|
||||
# Offense count: 6
|
||||
# Offense count: 7
|
||||
Rails/FilePath:
|
||||
Exclude:
|
||||
- 'lib/tasks/karma.rake'
|
||||
@@ -1204,7 +1199,7 @@ Rails/HasAndBelongsToMany:
|
||||
- 'app/models/spree/line_item_decorator.rb'
|
||||
- 'app/models/spree/payment_method_decorator.rb'
|
||||
|
||||
# Offense count: 11
|
||||
# Offense count: 10
|
||||
Rails/OutputSafety:
|
||||
Exclude:
|
||||
- 'app/controllers/spree/admin/reports_controller_decorator.rb'
|
||||
@@ -1212,7 +1207,6 @@ Rails/OutputSafety:
|
||||
- 'app/helpers/spree/reports_helper.rb'
|
||||
- 'app/serializers/api/product_serializer.rb'
|
||||
- 'lib/spree/money_decorator.rb'
|
||||
- 'lib/tasks/karma.rake'
|
||||
|
||||
# Offense count: 6
|
||||
# Cop supports --auto-correct.
|
||||
@@ -1303,15 +1297,16 @@ Rails/Validation:
|
||||
- 'app/models/spree/variant_decorator.rb'
|
||||
- 'app/models/variant_override.rb'
|
||||
|
||||
# Offense count: 6
|
||||
# Offense count: 7
|
||||
Style/AccessorMethodName:
|
||||
Exclude:
|
||||
- 'app/models/product_importer.rb'
|
||||
- 'app/models/spree/adjustment_decorator.rb'
|
||||
- 'app/models/spree/order_decorator.rb'
|
||||
- 'spec/support/request/shop_workflow.rb'
|
||||
- 'spec/support/request/web_helper.rb'
|
||||
|
||||
# Offense count: 35
|
||||
# Offense count: 34
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: always, conditionals
|
||||
@@ -1327,7 +1322,6 @@ Style/AndOr:
|
||||
- 'app/models/product_importer.rb'
|
||||
- 'app/models/spreadsheet_entry.rb'
|
||||
- 'app/models/spree/adjustment_decorator.rb'
|
||||
- 'app/models/spree/order_decorator.rb'
|
||||
- 'app/models/spree/product_set.rb'
|
||||
- 'app/views/json/partials/_enterprise.rabl'
|
||||
- 'lib/spree/core/controller_helpers/respond_with_decorator.rb'
|
||||
@@ -1341,7 +1335,7 @@ Style/BarePercentLiterals:
|
||||
- 'spec/features/admin/variants_spec.rb'
|
||||
- 'spec/support/request/web_helper.rb'
|
||||
|
||||
# Offense count: 209
|
||||
# Offense count: 208
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: braces, no_braces, context_dependent
|
||||
@@ -1411,7 +1405,6 @@ Style/BracesAroundHashParameters:
|
||||
- 'spec/models/spree/product_spec.rb'
|
||||
- 'spec/models/spree/taxon_spec.rb'
|
||||
- 'spec/serializers/admin/customer_serializer_spec.rb'
|
||||
- 'spec/serializers/orders_by_distributor_serializer_spec.rb'
|
||||
- 'spec/spec_helper.rb'
|
||||
- 'spec/support/cancan_helper.rb'
|
||||
- 'spec/support/request/authentication_workflow.rb'
|
||||
@@ -1423,7 +1416,7 @@ Style/CaseEquality:
|
||||
- 'app/helpers/angular_form_helper.rb'
|
||||
- 'spec/models/spree/payment_spec.rb'
|
||||
|
||||
# Offense count: 86
|
||||
# Offense count: 88
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: nested, compact
|
||||
Style/ClassAndModuleChildren:
|
||||
@@ -1469,7 +1462,9 @@ Style/ClassAndModuleChildren:
|
||||
- 'app/serializers/api/admin/line_item_serializer.rb'
|
||||
- 'app/serializers/api/admin/order_cycle_serializer.rb'
|
||||
- 'app/serializers/api/admin/order_serializer.rb'
|
||||
- 'app/serializers/api/admin/payment_method_serializer.rb'
|
||||
- 'app/serializers/api/admin/payment_method/base_serializer.rb'
|
||||
- 'app/serializers/api/admin/payment_method/payment_method_serializer.rb'
|
||||
- 'app/serializers/api/admin/payment_method/stripe_serializer.rb'
|
||||
- 'app/serializers/api/admin/product_serializer.rb'
|
||||
- 'app/serializers/api/admin/shipping_method_serializer.rb'
|
||||
- 'app/serializers/api/admin/tag_rule_serializer.rb'
|
||||
@@ -1602,7 +1597,7 @@ Style/FileName:
|
||||
Style/FormatStringToken:
|
||||
EnforcedStyle: template
|
||||
|
||||
# Offense count: 88
|
||||
# Offense count: 89
|
||||
# Configuration parameters: MinBodyLength.
|
||||
Style/GuardClause:
|
||||
Exclude:
|
||||
@@ -1656,7 +1651,7 @@ Style/GuardClause:
|
||||
- 'spec/support/request/distribution_helper.rb'
|
||||
- 'spec/support/request/shop_workflow.rb'
|
||||
|
||||
# Offense count: 1241
|
||||
# Offense count: 1255
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles, UseHashRocketsWithSymbolValues, PreferHashRocketsForNonAlnumEndingSymbols.
|
||||
# SupportedStyles: ruby19, hash_rockets, no_mixed_keys, ruby19_no_mixed_keys
|
||||
@@ -1686,11 +1681,10 @@ Style/InverseMethods:
|
||||
- 'app/controllers/admin/column_preferences_controller.rb'
|
||||
- 'spec/support/cancan_helper.rb'
|
||||
|
||||
# Offense count: 9
|
||||
# Offense count: 5
|
||||
# Cop supports --auto-correct.
|
||||
Style/LineEndConcatenation:
|
||||
Exclude:
|
||||
- 'app/controllers/spree/admin/base_controller_decorator.rb'
|
||||
- 'lib/spree/core/controller_helpers/respond_with_decorator.rb'
|
||||
- 'spec/controllers/spree/admin/base_controller_spec.rb'
|
||||
|
||||
@@ -1737,11 +1731,10 @@ Style/MultilineIfModifier:
|
||||
- 'lib/open_food_network/enterprise_issue_validator.rb'
|
||||
- 'lib/spree/core/controller_helpers/respond_with_decorator.rb'
|
||||
|
||||
# Offense count: 8
|
||||
# Offense count: 7
|
||||
# Cop supports --auto-correct.
|
||||
Style/MutableConstant:
|
||||
Exclude:
|
||||
- 'app/controllers/spree/admin/reports_controller_decorator.rb'
|
||||
- 'app/models/enterprise.rb'
|
||||
- 'app/models/enterprise_fee.rb'
|
||||
- 'app/models/spree/payment_method_decorator.rb'
|
||||
@@ -1799,7 +1792,7 @@ Style/NumericLiteralPrefix:
|
||||
Exclude:
|
||||
- 'spec/features/admin/order_cycles_spec.rb'
|
||||
|
||||
# Offense count: 16
|
||||
# Offense count: 15
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: Strict.
|
||||
Style/NumericLiterals:
|
||||
@@ -2026,7 +2019,7 @@ Style/StructInheritance:
|
||||
Exclude:
|
||||
- 'lib/open_food_network/enterprise_fee_applicator.rb'
|
||||
|
||||
# Offense count: 182
|
||||
# Offense count: 183
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, MinSize, SupportedStyles.
|
||||
# SupportedStyles: percent, brackets
|
||||
@@ -2070,7 +2063,7 @@ Style/SymbolArray:
|
||||
- 'spec/models/exchange_spec.rb'
|
||||
- 'spec/models/spree/ability_spec.rb'
|
||||
|
||||
# Offense count: 97
|
||||
# Offense count: 96
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: IgnoredMethods.
|
||||
# IgnoredMethods: respond_to, define_method
|
||||
@@ -2102,7 +2095,6 @@ Style/SymbolProc:
|
||||
- 'spec/features/admin/order_cycles_spec.rb'
|
||||
- 'spec/lib/open_food_network/group_buy_report_spec.rb'
|
||||
- 'spec/lib/open_food_network/order_grouper_spec.rb'
|
||||
- 'spec/models/spree/user_spec.rb'
|
||||
|
||||
# Offense count: 6
|
||||
# Cop supports --auto-correct.
|
||||
|
||||
14
Gemfile
14
Gemfile
@@ -10,15 +10,20 @@ gem 'i18n-js', '~> 3.0.0'
|
||||
gem 'nokogiri', '>= 1.6.7.1'
|
||||
|
||||
gem 'pg'
|
||||
gem 'spree', github: 'openfoodfoundation/spree', branch: 'spree-upgrade-step1c'
|
||||
gem 'spree', github: 'openfoodfoundation/spree', branch: 'step-6a', ref: '5a76d45'
|
||||
gem 'spree_i18n', github: 'spree/spree_i18n', branch: '1-3-stable'
|
||||
gem 'spree_auth_devise', github: 'spree/spree_auth_devise', branch: '1-3-stable'
|
||||
gem 'spree_auth_devise', github: 'openfoodfoundation/spree_auth_devise', branch: 'spree-upgrade-intermediate'
|
||||
|
||||
# Our branch contains two changes
|
||||
# - Pass customer email and phone number to PayPal (merged to upstream master)
|
||||
# - Change type of password from string to password to hide it in the form
|
||||
gem 'spree_paypal_express', :github => "openfoodfoundation/better_spree_paypal_express", :branch => "hide-password"
|
||||
gem 'spree_paypal_express', :github => "openfoodfoundation/better_spree_paypal_express", :branch => "spree-upgrade-intermediate"
|
||||
#gem 'spree_paypal_express', :github => "spree-contrib/better_spree_paypal_express", :branch => "1-3-stable"
|
||||
gem 'stripe', '~> 3.3.1'
|
||||
gem 'activemerchant', '~> 1.71.0'
|
||||
|
||||
gem 'oauth2', '~> 1.2.0' # Used for Stripe Connect
|
||||
gem 'jwt', '~> 1.5'
|
||||
|
||||
gem 'delayed_job_active_record'
|
||||
gem 'daemons'
|
||||
@@ -121,7 +126,8 @@ group :test do
|
||||
end
|
||||
|
||||
group :development do
|
||||
gem 'pry-byebug'
|
||||
gem 'byebug', '~> 9.0.0' # 9.1 requires ruby 2.2
|
||||
gem 'pry-byebug', '>= 3.4.3'
|
||||
gem 'debugger-linecache'
|
||||
gem 'guard'
|
||||
gem 'guard-livereload'
|
||||
|
||||
179
Gemfile.lock
179
Gemfile.lock
@@ -14,12 +14,12 @@ GIT
|
||||
|
||||
GIT
|
||||
remote: git://github.com/openfoodfoundation/better_spree_paypal_express.git
|
||||
revision: 840d973cd5bd3250b17674a624dad494aeb09eb3
|
||||
branch: hide-password
|
||||
revision: 8d95f4544c682634812becaf50999fba0cd04df0
|
||||
branch: spree-upgrade-intermediate
|
||||
specs:
|
||||
spree_paypal_express (2.0.3)
|
||||
paypal-sdk-merchant (= 1.106.1)
|
||||
spree_core (~> 1.3.4)
|
||||
spree_core (~> 1.3.99)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/openfoodfoundation/ofn-qz.git
|
||||
@@ -30,49 +30,78 @@ GIT
|
||||
|
||||
GIT
|
||||
remote: git://github.com/openfoodfoundation/spree.git
|
||||
revision: a4c439570b77afa50f9e36299811f293232bd281
|
||||
branch: spree-upgrade-step1c
|
||||
revision: 5a76d456ff70aea7aae3d25156558d71eb7febf2
|
||||
ref: 5a76d45
|
||||
branch: step-6a
|
||||
specs:
|
||||
spree (1.3.99)
|
||||
spree_api (= 1.3.99)
|
||||
spree_backend (= 1.3.99)
|
||||
spree_cmd (= 1.3.99)
|
||||
spree_core (= 1.3.99)
|
||||
spree_dash (= 1.3.99)
|
||||
spree_promo (= 1.3.99)
|
||||
spree_frontend (= 1.3.99)
|
||||
spree_sample (= 1.3.99)
|
||||
spree_api (1.3.99)
|
||||
rabl (= 0.7.2)
|
||||
spree_core (= 1.3.99)
|
||||
versioncake (= 0.4.0)
|
||||
spree_backend (1.3.99)
|
||||
deface (>= 0.9.0)
|
||||
jquery-rails (~> 2.0)
|
||||
rails (~> 3.2.8)
|
||||
select2-rails (~> 3.2)
|
||||
spree_api (= 1.3.99)
|
||||
spree_core (= 1.3.99)
|
||||
stringex (~> 1.3.2)
|
||||
spree_cmd (1.3.99)
|
||||
thor (>= 0.14.6)
|
||||
spree_core (1.3.99)
|
||||
activemerchant (~> 1.50.0)
|
||||
acts_as_list (= 0.1.4)
|
||||
activemerchant (~> 1.50)
|
||||
acts_as_list (= 0.1.9)
|
||||
awesome_nested_set (= 2.1.5)
|
||||
aws-sdk (~> 1.11.1)
|
||||
cancan (= 1.6.8)
|
||||
deface (>= 0.9.0)
|
||||
ffaker (~> 1.15.0)
|
||||
highline (= 1.6.11)
|
||||
jquery-rails (~> 2.0)
|
||||
highline (= 1.6.15)
|
||||
httparty (= 0.9.0)
|
||||
json (>= 1.5.5)
|
||||
kaminari (= 0.13.0)
|
||||
money (= 5.0.0)
|
||||
money (= 5.1.0)
|
||||
paperclip (~> 3.0)
|
||||
rabl (= 0.7.2)
|
||||
rails (~> 3.2.13)
|
||||
ransack (= 0.7.2)
|
||||
select2-rails (~> 3.2)
|
||||
state_machine (= 1.2.0)
|
||||
stringex (~> 1.3.2)
|
||||
truncate_html (= 0.9.2)
|
||||
spree_dash (1.3.99)
|
||||
httparty (~> 0.8.1)
|
||||
spree_core (= 1.3.99)
|
||||
spree_promo (1.3.99)
|
||||
httparty (~> 0.9.0)
|
||||
spree_backend (= 1.3.99)
|
||||
spree_frontend (= 1.3.99)
|
||||
spree_frontend (1.3.99)
|
||||
deface (>= 0.9.0)
|
||||
jquery-rails (~> 2.2.1)
|
||||
rails (~> 3.2.8)
|
||||
select2-rails (~> 3.2)
|
||||
spree_api (= 1.3.99)
|
||||
spree_core (= 1.3.99)
|
||||
stringex (~> 1.3.2)
|
||||
spree_sample (1.3.99)
|
||||
spree_core (= 1.3.99)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/openfoodfoundation/spree_auth_devise.git
|
||||
revision: da9eecefc6fe13dedf4c6f3febec79caad839ec3
|
||||
branch: spree-upgrade-intermediate
|
||||
specs:
|
||||
spree_auth_devise (2.0.0)
|
||||
devise (~> 2.2.5)
|
||||
devise-encryptable (= 0.1.2)
|
||||
spree_backend (~> 1.3.6)
|
||||
spree_core (~> 1.3.6)
|
||||
spree_frontend (~> 1.3.6)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/spree/deface.git
|
||||
revision: 1110a1336252109bce7f98f9182042e0bc2930ae
|
||||
@@ -83,17 +112,6 @@ GIT
|
||||
nokogiri (~> 1.6.0)
|
||||
rails (>= 3.1)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/spree/spree_auth_devise.git
|
||||
revision: ba95589a85368297c844f096c2a0c121e5b08138
|
||||
branch: 1-3-stable
|
||||
specs:
|
||||
spree_auth_devise (1.3.0)
|
||||
cancan (~> 1.6.7)
|
||||
devise (~> 2.2.3)
|
||||
devise-encryptable (= 0.1.2)
|
||||
spree_core
|
||||
|
||||
GIT
|
||||
remote: git://github.com/spree/spree_i18n.git
|
||||
revision: 752eb67204e9c5a4e22b62591a8fd55fe2285e43
|
||||
@@ -133,8 +151,8 @@ GEM
|
||||
sprockets (~> 2.2.1)
|
||||
active_model_serializers (0.8.3)
|
||||
activemodel (>= 3.0)
|
||||
activemerchant (1.50.0)
|
||||
activesupport (>= 3.2.14, < 5.0.0)
|
||||
activemerchant (1.71.0)
|
||||
activesupport (>= 3.2.14, < 6.x)
|
||||
builder (>= 2.1.2, < 4.0.0)
|
||||
i18n (>= 0.6.9)
|
||||
nokogiri (~> 1.4)
|
||||
@@ -154,8 +172,8 @@ GEM
|
||||
multi_json (~> 1.0)
|
||||
acts-as-taggable-on (3.5.0)
|
||||
activerecord (>= 3.2, < 5)
|
||||
acts_as_list (0.1.4)
|
||||
addressable (2.3.3)
|
||||
acts_as_list (0.1.9)
|
||||
addressable (2.4.0)
|
||||
andand (1.3.3)
|
||||
angular-rails-templates (0.2.0)
|
||||
railties (>= 3.1)
|
||||
@@ -174,15 +192,13 @@ GEM
|
||||
json (~> 1.4)
|
||||
nokogiri (>= 1.4.4)
|
||||
uuidtools (~> 2.1)
|
||||
bcrypt (3.1.7)
|
||||
bcrypt (3.1.11)
|
||||
bcrypt-ruby (3.1.5)
|
||||
bcrypt (>= 3.1.3)
|
||||
blockenspiel (0.4.5)
|
||||
bugsnag (4.1.0)
|
||||
builder (3.0.4)
|
||||
byebug (2.7.0)
|
||||
columnize (~> 0.3)
|
||||
debugger-linecache (~> 1.2)
|
||||
byebug (9.0.6)
|
||||
cancan (1.6.8)
|
||||
capybara (2.7.1)
|
||||
addressable
|
||||
@@ -195,12 +211,11 @@ GEM
|
||||
timers (~> 1.1.0)
|
||||
chronic (0.10.2)
|
||||
chunky_png (1.3.4)
|
||||
climate_control (0.0.3)
|
||||
activesupport (>= 3.0)
|
||||
climate_control (0.1.0)
|
||||
cliver (0.3.2)
|
||||
cocaine (0.5.8)
|
||||
climate_control (>= 0.0.3, < 1.0)
|
||||
coderay (1.0.9)
|
||||
coderay (1.1.2)
|
||||
coffee-rails (3.2.2)
|
||||
coffee-script (>= 2.2.0)
|
||||
railties (~> 3.2.0)
|
||||
@@ -208,8 +223,7 @@ GEM
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.10.0)
|
||||
colorize (0.7.7)
|
||||
columnize (0.9.0)
|
||||
colorize (0.8.1)
|
||||
compass (1.0.3)
|
||||
chunky_png (~> 1.2)
|
||||
compass-core (~> 1.0.2)
|
||||
@@ -226,8 +240,8 @@ GEM
|
||||
compass (~> 1.0.0)
|
||||
sass-rails (<= 5.0.1)
|
||||
sprockets (< 2.13)
|
||||
crack (0.4.1)
|
||||
safe_yaml (~> 0.9.0)
|
||||
crack (0.4.3)
|
||||
safe_yaml (~> 1.0.0)
|
||||
css_parser (1.3.5)
|
||||
addressable
|
||||
css_splitter (0.4.5)
|
||||
@@ -266,6 +280,8 @@ GEM
|
||||
factory_girl_rails (3.3.0)
|
||||
factory_girl (~> 3.3.0)
|
||||
railties (>= 3.0.0)
|
||||
faraday (0.9.2)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
ffaker (1.15.0)
|
||||
ffi (1.9.3)
|
||||
figaro (0.7.0)
|
||||
@@ -410,10 +426,10 @@ GEM
|
||||
rspec (~> 2.14)
|
||||
haml (4.0.4)
|
||||
tilt
|
||||
highline (1.6.11)
|
||||
highline (1.6.15)
|
||||
hike (1.2.3)
|
||||
http_parser.rb (0.5.3)
|
||||
httparty (0.8.3)
|
||||
httparty (0.9.0)
|
||||
multi_json (~> 1.0)
|
||||
multi_xml
|
||||
i18n (0.6.11)
|
||||
@@ -426,13 +442,14 @@ GEM
|
||||
ipaddress (0.8.0)
|
||||
journey (1.0.4)
|
||||
jquery-migrate-rails (1.2.1)
|
||||
jquery-rails (2.3.0)
|
||||
jquery-rails (2.2.2)
|
||||
railties (>= 3.0, < 5.0)
|
||||
thor (>= 0.14, < 2.0)
|
||||
json (1.8.3)
|
||||
json (1.8.6)
|
||||
json_spec (1.1.1)
|
||||
multi_json (~> 1.0)
|
||||
rspec (~> 2.0)
|
||||
jwt (1.5.4)
|
||||
kaminari (0.13.0)
|
||||
actionpack (>= 3.0.0)
|
||||
activesupport (>= 3.0.0)
|
||||
@@ -454,19 +471,25 @@ GEM
|
||||
mail (2.5.4)
|
||||
mime-types (~> 1.16)
|
||||
treetop (~> 1.4.8)
|
||||
method_source (0.8.2)
|
||||
method_source (0.9.0)
|
||||
mime-types (1.25.1)
|
||||
mini_portile2 (2.0.0)
|
||||
mini_portile2 (2.1.0)
|
||||
momentjs-rails (2.5.1)
|
||||
railties (>= 3.1)
|
||||
money (5.0.0)
|
||||
i18n (~> 0.4)
|
||||
json
|
||||
money (5.1.0)
|
||||
i18n (~> 0.6.0)
|
||||
multi_json (1.12.1)
|
||||
multi_xml (0.5.5)
|
||||
multi_xml (0.6.0)
|
||||
multipart-post (2.0.0)
|
||||
newrelic_rpm (3.12.0.288)
|
||||
nokogiri (1.6.7.2)
|
||||
mini_portile2 (~> 2.0.0.rc2)
|
||||
nokogiri (1.6.8.1)
|
||||
mini_portile2 (~> 2.1.0)
|
||||
oauth2 (1.2.0)
|
||||
faraday (>= 0.8, < 0.10)
|
||||
jwt (~> 1.0)
|
||||
multi_json (~> 1.3)
|
||||
multi_xml (~> 0.5)
|
||||
rack (>= 1.2, < 3)
|
||||
oj (2.1.2)
|
||||
orm_adapter (0.5.0)
|
||||
paper_trail (3.0.8)
|
||||
@@ -497,18 +520,17 @@ GEM
|
||||
activerecord (~> 3.0)
|
||||
polyglot (0.3.5)
|
||||
powerpack (0.1.1)
|
||||
pry (0.9.12.2)
|
||||
coderay (~> 1.0.5)
|
||||
method_source (~> 0.8)
|
||||
slop (~> 3.4)
|
||||
pry-byebug (1.3.2)
|
||||
byebug (~> 2.7)
|
||||
pry (~> 0.9.12)
|
||||
pry (0.11.1)
|
||||
coderay (~> 1.1.0)
|
||||
method_source (~> 0.9.0)
|
||||
pry-byebug (3.4.3)
|
||||
byebug (>= 9.0, < 9.1)
|
||||
pry (~> 0.10)
|
||||
rabl (0.7.2)
|
||||
activesupport (>= 2.3.14)
|
||||
multi_json (~> 1.0)
|
||||
rack (1.4.7)
|
||||
rack-cache (1.6.1)
|
||||
rack-cache (1.7.0)
|
||||
rack (>= 0.4)
|
||||
rack-livereload (0.3.15)
|
||||
rack
|
||||
@@ -537,7 +559,7 @@ GEM
|
||||
rainbow (2.2.2)
|
||||
rake
|
||||
raindrops (0.13.0)
|
||||
rake (11.3.0)
|
||||
rake (10.5.0)
|
||||
ransack (0.7.2)
|
||||
actionpack (~> 3.0)
|
||||
activerecord (~> 3.0)
|
||||
@@ -574,8 +596,9 @@ GEM
|
||||
rspec-expectations (2.14.0)
|
||||
diff-lcs (>= 1.1.3, < 2.0)
|
||||
rspec-mocks (2.14.2)
|
||||
rspec-rails (2.14.0)
|
||||
rspec-rails (2.14.2)
|
||||
actionpack (>= 3.0)
|
||||
activemodel (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
railties (>= 3.0)
|
||||
rspec-core (~> 2.14.0)
|
||||
@@ -592,7 +615,7 @@ GEM
|
||||
unicode-display_width (~> 1.0, >= 1.0.1)
|
||||
ruby-progressbar (1.8.1)
|
||||
rubyzip (1.2.0)
|
||||
safe_yaml (0.9.5)
|
||||
safe_yaml (1.0.4)
|
||||
sass (3.3.14)
|
||||
sass-rails (3.2.6)
|
||||
railties (~> 3.2.0)
|
||||
@@ -602,7 +625,6 @@ GEM
|
||||
thor (~> 0.14)
|
||||
shoulda-matchers (1.1.0)
|
||||
activesupport (>= 3.0.0)
|
||||
slop (3.4.5)
|
||||
spinjs-rails (1.3)
|
||||
rails (>= 3.1)
|
||||
sprockets (2.2.3)
|
||||
@@ -612,23 +634,25 @@ GEM
|
||||
tilt (~> 1.1, != 1.3.0)
|
||||
state_machine (1.2.0)
|
||||
stringex (1.3.3)
|
||||
stripe (3.3.1)
|
||||
faraday (~> 0.9)
|
||||
therubyracer (0.12.0)
|
||||
libv8 (~> 3.16.14.0)
|
||||
ref
|
||||
thor (0.19.1)
|
||||
thor (0.19.4)
|
||||
tilt (1.4.1)
|
||||
timecop (0.8.1)
|
||||
timers (1.1.0)
|
||||
treetop (1.4.15)
|
||||
polyglot
|
||||
polyglot (>= 0.3.1)
|
||||
truncate_html (0.5.5)
|
||||
truncate_html (0.9.2)
|
||||
turbo-sprockets-rails3 (0.3.6)
|
||||
railties (> 3.2.8, < 4.0.0)
|
||||
sprockets (>= 2.0.0)
|
||||
turn (0.8.3)
|
||||
ansi
|
||||
tzinfo (0.3.49)
|
||||
tzinfo (0.3.53)
|
||||
uglifier (2.7.1)
|
||||
execjs (>= 0.3.0)
|
||||
json (>= 1.8.0)
|
||||
@@ -645,11 +669,11 @@ GEM
|
||||
actionpack (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
railties (>= 3.0)
|
||||
warden (1.2.3)
|
||||
warden (1.2.6)
|
||||
rack (>= 1.0)
|
||||
webmock (1.13.0)
|
||||
webmock (1.8.11)
|
||||
addressable (>= 2.2.7)
|
||||
crack (>= 0.3.2)
|
||||
crack (>= 0.1.7)
|
||||
websocket-driver (0.6.3)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.2)
|
||||
@@ -658,7 +682,7 @@ GEM
|
||||
chronic (>= 0.6.3)
|
||||
wicked_pdf (1.1.0)
|
||||
wkhtmltopdf-binary (0.12.3.1)
|
||||
xml-simple (1.1.4)
|
||||
xml-simple (1.1.5)
|
||||
xpath (2.0.0)
|
||||
nokogiri (~> 1.3)
|
||||
|
||||
@@ -667,6 +691,7 @@ PLATFORMS
|
||||
|
||||
DEPENDENCIES
|
||||
active_model_serializers
|
||||
activemerchant (~> 1.71.0)
|
||||
acts-as-taggable-on (~> 3.4)
|
||||
andand
|
||||
angular-rails-templates (~> 0.2.0)
|
||||
@@ -677,6 +702,7 @@ DEPENDENCIES
|
||||
aws-sdk
|
||||
blockenspiel
|
||||
bugsnag
|
||||
byebug (~> 9.0.0)
|
||||
capybara
|
||||
coffee-rails (~> 3.2.1)
|
||||
compass-rails
|
||||
@@ -711,11 +737,13 @@ DEPENDENCIES
|
||||
jquery-migrate-rails
|
||||
jquery-rails
|
||||
json_spec
|
||||
jwt (~> 1.5)
|
||||
knapsack
|
||||
letter_opener
|
||||
momentjs-rails
|
||||
newrelic_rpm
|
||||
nokogiri (>= 1.6.7.1)
|
||||
oauth2 (~> 1.2.0)
|
||||
ofn-qz!
|
||||
oj
|
||||
paper_trail (~> 3.0.8)
|
||||
@@ -723,7 +751,7 @@ DEPENDENCIES
|
||||
parallel_tests
|
||||
pg
|
||||
poltergeist
|
||||
pry-byebug
|
||||
pry-byebug (>= 3.4.3)
|
||||
rabl
|
||||
rack-livereload
|
||||
rack-ssl
|
||||
@@ -745,6 +773,7 @@ DEPENDENCIES
|
||||
spree_auth_devise!
|
||||
spree_i18n!
|
||||
spree_paypal_express!
|
||||
stripe (~> 3.3.1)
|
||||
therubyracer
|
||||
timecop
|
||||
truncate_html
|
||||
@@ -762,4 +791,4 @@ RUBY VERSION
|
||||
ruby 2.1.5p273
|
||||
|
||||
BUNDLED WITH
|
||||
1.15.2
|
||||
1.15.4
|
||||
|
||||
@@ -123,7 +123,7 @@ Do not forget to run `rake tmp:cache:clear` after locales are updated to reload
|
||||
* Maikel Linke (https://github.com/mkllnk)
|
||||
* Lynne Davis (https://github.com/lin-d-hop)
|
||||
* Paul Mackay (https://github.com/pmackay)
|
||||
* Steve Petitt (https://github.com/stveep)
|
||||
* Steve Pettitt (https://github.com/stveep)
|
||||
|
||||
|
||||
## Licence
|
||||
|
||||
@@ -14,9 +14,8 @@
|
||||
//= require angular-resource
|
||||
//= require angular-animate
|
||||
//= require angular-sanitize
|
||||
//= require admin/spree_core
|
||||
//= require admin/spree_backend
|
||||
//= require admin/spree_auth
|
||||
//= require admin/spree_promo
|
||||
//= require admin/spree_paypal_express
|
||||
//= require ../shared/ng-infinite-scroll.min.js
|
||||
//= require ../shared/ng-tags-input.min.js
|
||||
|
||||
@@ -22,7 +22,7 @@ angular.module("admin.enterprises")
|
||||
{ name: 'users', label: t('users'), icon_class: "icon-user" }
|
||||
]
|
||||
|
||||
$scope.select(0)
|
||||
SideMenu.init()
|
||||
|
||||
$scope.showItem = (item) ->
|
||||
if item.show?
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
angular.module("admin.paymentMethods").controller "StripeController", ($scope, $http, shops) ->
|
||||
$scope.shops = shops
|
||||
$scope.stripe_account = {}
|
||||
|
||||
$scope.$watch "paymentMethod.preferred_enterprise_id", (newID, oldID) ->
|
||||
return unless newID?
|
||||
$scope.stripe_account = {}
|
||||
$http.get("/admin/stripe_accounts/status.json?enterprise_id=#{newID}").success (data) ->
|
||||
angular.extend($scope.stripe_account, data)
|
||||
.error (response) ->
|
||||
$scope.stripe_account.status = "request_failed"
|
||||
|
||||
$scope.current_enterprise_stripe_path = ->
|
||||
return unless $scope.paymentMethod.preferred_enterprise_id?
|
||||
permalink = shops.filter((shop) ->
|
||||
shop.id == $scope.paymentMethod.preferred_enterprise_id
|
||||
)[0].permalink
|
||||
"/admin/enterprises/#{permalink}/edit#/payment_methods"
|
||||
33
app/assets/javascripts/admin/payments/new.js
Normal file
33
app/assets/javascripts/admin/payments/new.js
Normal file
@@ -0,0 +1,33 @@
|
||||
// Override of Spree's logic in the file of the same name
|
||||
// Changes made as per https://github.com/spree/spree/commit/8a3a80b08abf80fbed2fcee4b429ba1caf68baf1
|
||||
// which allows the form partial in admin/payments/new to be switched using radio buttons
|
||||
// We can remove this file when we reach 2.3.0
|
||||
|
||||
$(document).ready(function() {
|
||||
if ($("#new_payment").is("*")) {
|
||||
$('.payment_methods_radios').click(
|
||||
function() {
|
||||
$('.payment-methods').hide();
|
||||
if (this.checked) {
|
||||
$('#payment_method_' + this.value).show();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$('.payment_methods_radios').each(
|
||||
function() {
|
||||
if (this.checked) {
|
||||
$('#payment_method_' + this.value).show();
|
||||
} else {
|
||||
$('#payment_method_' + this.value).hide();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$(".card_new").radioControlsVisibilityOfElement('.card_form');
|
||||
|
||||
$('select.jump_menu').change(function(){
|
||||
window.location = this.options[this.selectedIndex].value;
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -1,5 +1,5 @@
|
||||
angular.module("admin.resources").factory 'LineItemResource', ($resource) ->
|
||||
$resource('/admin/:orders/:order_number/line_items/:id.json', {}, {
|
||||
$resource('/admin/bulk_line_items/:id.json', {}, {
|
||||
'index':
|
||||
method: 'GET'
|
||||
isArray: true
|
||||
|
||||
@@ -26,7 +26,7 @@ angular.module("admin.resources").factory 'LineItems', ($q, LineItemResource) ->
|
||||
save: (lineItem) ->
|
||||
deferred = $q.defer()
|
||||
lineItem.errors = {}
|
||||
lineItem.$update({id: lineItem.id, orders: "orders", order_number: lineItem.order.number})
|
||||
lineItem.$update({id: lineItem.id})
|
||||
.then( (data) =>
|
||||
@pristineByID[lineItem.id] = angular.copy(lineItem)
|
||||
deferred.resolve(data)
|
||||
@@ -54,7 +54,7 @@ angular.module("admin.resources").factory 'LineItems', ($q, LineItemResource) ->
|
||||
|
||||
delete: (lineItem, callback=null) ->
|
||||
deferred = $q.defer()
|
||||
lineItem.$delete({id: lineItem.id, orders: "orders", order_number: lineItem.order.number})
|
||||
lineItem.$delete({id: lineItem.id})
|
||||
.then( (data) =>
|
||||
delete @byID[lineItem.id]
|
||||
delete @pristineByID[lineItem.id]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
angular.module("ofn.admin").factory "BulkProducts", (PagedFetcher, dataFetcher) ->
|
||||
angular.module("ofn.admin").factory "BulkProducts", (PagedFetcher, dataFetcher, $http) ->
|
||||
new class BulkProducts
|
||||
products: []
|
||||
|
||||
@@ -11,14 +11,8 @@ angular.module("ofn.admin").factory "BulkProducts", (PagedFetcher, dataFetcher)
|
||||
PagedFetcher.fetch url, (data) => @addProducts data.products
|
||||
|
||||
cloneProduct: (product) ->
|
||||
dataFetcher("/admin/products/" + product.permalink_live + "/clone.json").then (data) =>
|
||||
# Ideally we would use Spree's built in respond_override helper here to redirect the
|
||||
# user after a successful clone with .json in the accept headers
|
||||
# However, at the time of writing there appears to be an issue which causes the
|
||||
# respond_with block in the destroy action of Spree::Admin::Product to break
|
||||
# when a respond_overrride for the clone action is used.
|
||||
id = data.product.id
|
||||
dataFetcher("/api/products/" + id + "?template=bulk_show").then (newProduct) =>
|
||||
$http.post("/api/products/" + product.id + "/clone").success (data) =>
|
||||
dataFetcher("/api/products/" + data.id + "?template=bulk_show").then (newProduct) =>
|
||||
@unpackProduct newProduct
|
||||
@insertProductAfter(product, newProduct)
|
||||
|
||||
|
||||
@@ -1,9 +1,21 @@
|
||||
angular.module("admin.side_menu")
|
||||
.factory "SideMenu", ->
|
||||
.factory "SideMenu", ($location) ->
|
||||
new class SideMenu
|
||||
items: []
|
||||
selected: null
|
||||
|
||||
|
||||
# Checks for path and uses it to set the view
|
||||
# If no path, loads first view
|
||||
init: =>
|
||||
path = $location.path()?.match(/^\/\w+$/)?[0]
|
||||
index = if path
|
||||
name = path[1..]
|
||||
@items.indexOf(@find_by_name(name))
|
||||
else
|
||||
0
|
||||
@select(index)
|
||||
|
||||
setItems: (items) =>
|
||||
@items = items
|
||||
item.visible = true for item in @items
|
||||
@@ -13,6 +25,7 @@ angular.module("admin.side_menu")
|
||||
@selected.selected = false if @selected
|
||||
@selected = @items[index]
|
||||
@selected.selected = true
|
||||
$location.path(@selected.name)
|
||||
|
||||
find_by_name: (name) =>
|
||||
for item in @items when item.name is name
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
angular.module("admin.indexUtils").directive "ofnSelect2", ($sanitize, $timeout, $filter) ->
|
||||
angular.module("admin.utils").directive "ofnSelect2", ($sanitize, $timeout, $filter) ->
|
||||
require: 'ngModel'
|
||||
restrict: 'C'
|
||||
scope:
|
||||
@@ -13,8 +13,9 @@ Darkswarm.controller "AccordionCtrl", ($scope, localStorageService, $timeout, $d
|
||||
# scroll location is closed by show(), scrollTo() will scroll to the old location of
|
||||
# the element. Putting this in a 50 ms timeout is enough delay for the DOM to
|
||||
# have updated.
|
||||
$timeout (->
|
||||
$document.scrollTo $("##{section}"), offset_height, 500), 50
|
||||
$timeout ->
|
||||
$document.scrollTo($("##{section}"), offset_height, 500)
|
||||
, 50
|
||||
|
||||
$scope.$on 'purchaseFormInvalid', (event, form) ->
|
||||
# Scroll to first invalid section
|
||||
|
||||
@@ -22,6 +22,6 @@ Darkswarm.controller "CheckoutCtrl", ($scope, localStorageService, Checkout, Cur
|
||||
event.preventDefault()
|
||||
$scope.submitted = true
|
||||
if form.$valid
|
||||
$scope.Checkout.submit()
|
||||
$scope.Checkout.purchase()
|
||||
else
|
||||
$scope.$broadcast 'purchaseFormInvalid', form
|
||||
|
||||
@@ -1,23 +1,11 @@
|
||||
Darkswarm.controller "PaymentCtrl", ($scope, $timeout) ->
|
||||
Darkswarm.controller "PaymentCtrl", ($scope, $timeout, savedCreditCards, Dates) ->
|
||||
angular.extend(this, new FieldsetMixin($scope))
|
||||
|
||||
$scope.savedCreditCards = savedCreditCards
|
||||
$scope.name = "payment"
|
||||
$scope.months = Dates.months
|
||||
$scope.years = Dates.years
|
||||
|
||||
$scope.months = [
|
||||
{key: t("january"), value: "1"},
|
||||
{key: t("february"), value: "2"},
|
||||
{key: t("march"), value: "3"},
|
||||
{key: t("april"), value: "4"},
|
||||
{key: t("may"), value: "5"},
|
||||
{key: t("june"), value: "6"},
|
||||
{key: t("july"), value: "7"},
|
||||
{key: t("august"), value: "8"},
|
||||
{key: t("september"), value: "9"},
|
||||
{key: t("october"), value: "10"},
|
||||
{key: t("november"), value: "11"},
|
||||
{key: t("december"), value: "12"},
|
||||
]
|
||||
|
||||
$scope.years = [moment().year()..(moment().year()+15)]
|
||||
$scope.secrets.card_month = "1"
|
||||
$scope.secrets.card_year = moment().year()
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
Darkswarm.controller "CreditCardsCtrl", ($scope, $timeout, CreditCard, CreditCards, Dates) ->
|
||||
angular.extend(this, new FieldsetMixin($scope))
|
||||
$scope.savedCreditCards = CreditCards.saved
|
||||
$scope.CreditCard = CreditCard
|
||||
$scope.secrets = CreditCard.secrets
|
||||
$scope.showForm = CreditCard.show
|
||||
$scope.storeCard = ->
|
||||
if $scope.new_card_form.$valid
|
||||
CreditCard.requestToken()
|
||||
|
||||
$scope.allow_name_change = true
|
||||
$scope.disable_fields = false
|
||||
@@ -1,9 +0,0 @@
|
||||
Darkswarm.controller "DistributorNodeCtrl", ($scope, HashNavigation, $anchorScroll) ->
|
||||
$scope.toggle = ->
|
||||
HashNavigation.toggle $scope.distributor.hash
|
||||
|
||||
$scope.open = ->
|
||||
HashNavigation.active($scope.distributor.hash)
|
||||
|
||||
if $scope.open()
|
||||
$anchorScroll()
|
||||
@@ -6,10 +6,9 @@ Darkswarm.controller "EnterprisesCtrl", ($scope, $rootScope, $timeout, $location
|
||||
$scope.openModal = EnterpriseModal.open
|
||||
$scope.activeTaxons = []
|
||||
$scope.show_profiles = false
|
||||
$scope.show_closed = false
|
||||
$scope.filtersActive = false
|
||||
$scope.distanceMatchesShown = false
|
||||
$scope.filterExpression = {active: true}
|
||||
|
||||
|
||||
$scope.$watch "query", (query)->
|
||||
Enterprises.flagMatching query
|
||||
@@ -36,7 +35,7 @@ Darkswarm.controller "EnterprisesCtrl", ($scope, $rootScope, $timeout, $location
|
||||
# When filter settings change, this could change which name match is at the top, or even
|
||||
# result in no matches. This affects the reference point that the distance matches are
|
||||
# calculated from, so we need to recalculate distances.
|
||||
$scope.$watch '[activeTaxons, activeProperties, shippingTypes, show_profiles]', ->
|
||||
$scope.$watch '[activeTaxons, activeProperties, shippingTypes, show_profiles, show_closed]', ->
|
||||
$timeout ->
|
||||
Enterprises.calculateDistance $scope.query, $scope.firstNameMatch()
|
||||
$rootScope.$broadcast 'enterprisesChanged'
|
||||
@@ -74,9 +73,9 @@ Darkswarm.controller "EnterprisesCtrl", ($scope, $rootScope, $timeout, $location
|
||||
undefined
|
||||
|
||||
$scope.showClosedShops = ->
|
||||
delete $scope.filterExpression['active']
|
||||
$scope.show_closed = true
|
||||
$location.search('show_closed', '1')
|
||||
|
||||
$scope.hideClosedShops = ->
|
||||
$scope.filterExpression['active'] = true
|
||||
$scope.show_closed = false
|
||||
$location.search('show_closed', null)
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
Darkswarm.controller "OrdersCtrl", ($scope, $rootScope, $timeout, Orders, Search, $document, HashNavigation, FilterSelectorsService, EnterpriseModal, enterpriseMatchesNameQueryFilter, distanceWithinKmFilter) ->
|
||||
Darkswarm.controller "OrdersCtrl", ($scope, Orders) ->
|
||||
$scope.Orders = Orders
|
||||
|
||||
@@ -1,15 +1,23 @@
|
||||
Darkswarm.controller "RegistrationFormCtrl", ($scope, RegistrationService, EnterpriseRegistrationService) ->
|
||||
$scope.submitted = false
|
||||
$scope.isDisabled = false
|
||||
|
||||
$scope.valid = (form) ->
|
||||
$scope.submitted = !form.$valid
|
||||
form.$valid
|
||||
|
||||
$scope.create = (form) ->
|
||||
EnterpriseRegistrationService.create() if $scope.valid(form)
|
||||
$scope.disableButton()
|
||||
EnterpriseRegistrationService.create($scope.enableButton) if $scope.valid(form)
|
||||
|
||||
$scope.update = (nextStep, form) ->
|
||||
EnterpriseRegistrationService.update(nextStep) if $scope.valid(form)
|
||||
|
||||
$scope.selectIfValid = (nextStep, form) ->
|
||||
RegistrationService.select(nextStep) if $scope.valid(form)
|
||||
|
||||
$scope.disableButton = ->
|
||||
$scope.isDisabled = true
|
||||
|
||||
$scope.enableButton = ->
|
||||
$scope.isDisabled = false
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
Darkswarm.controller "ShopNodeCtrl", ($scope, HashNavigation, $anchorScroll) ->
|
||||
$scope.toggle = ->
|
||||
HashNavigation.toggle $scope.shop.hash
|
||||
|
||||
$scope.open = ->
|
||||
HashNavigation.active($scope.shop.hash)
|
||||
|
||||
if $scope.open()
|
||||
$anchorScroll()
|
||||
@@ -0,0 +1,35 @@
|
||||
Darkswarm.directive "stripeElements", ($injector, StripeElements) ->
|
||||
restrict: 'E'
|
||||
template: "<label for='card-element'>\
|
||||
<div id='card-element'></div>\
|
||||
<div id='card-errors' class='error'></div>\
|
||||
</label>"
|
||||
|
||||
link: (scope, elem, attr)->
|
||||
if $injector.has('stripeObject')
|
||||
stripe = $injector.get('stripeObject')
|
||||
|
||||
card = stripe.elements().create 'card',
|
||||
hidePostalCode: false
|
||||
style:
|
||||
base:
|
||||
fontFamily: "Roboto, Arial, sans-serif"
|
||||
fontSize: '16px'
|
||||
color: '#5c5c5c'
|
||||
'::placeholder':
|
||||
color: '#6c6c6c'
|
||||
card.mount('#card-element')
|
||||
|
||||
# Elements validates user input as it is typed. To help your customers
|
||||
# catch mistakes, you should listen to change events on the card Element
|
||||
# and display any errors:
|
||||
card.addEventListener 'change', (event) ->
|
||||
displayError = document.getElementById('card-errors')
|
||||
if event.error
|
||||
displayError.textContent = event.error.message
|
||||
else
|
||||
displayError.textContent = ''
|
||||
return
|
||||
|
||||
StripeElements.stripe = stripe
|
||||
StripeElements.card = card
|
||||
12
app/assets/javascripts/darkswarm/directives/tab.js.coffee
Normal file
12
app/assets/javascripts/darkswarm/directives/tab.js.coffee
Normal file
@@ -0,0 +1,12 @@
|
||||
Darkswarm.directive "tab", ->
|
||||
restrict: "C"
|
||||
require: "^^tabsetCtrl"
|
||||
scope:
|
||||
name: "@"
|
||||
link: (scope, element, attrs, ctrl) ->
|
||||
element.on "click", ->
|
||||
scope.$apply ->
|
||||
ctrl.toggle(scope.name)
|
||||
|
||||
ctrl.registerSelectionListener (prefix, selection) ->
|
||||
element.toggleClass('selected', selection == scope.name)
|
||||
15
app/assets/javascripts/darkswarm/directives/tab_view.coffee
Normal file
15
app/assets/javascripts/darkswarm/directives/tab_view.coffee
Normal file
@@ -0,0 +1,15 @@
|
||||
Darkswarm.directive "tabView", ->
|
||||
restrict: "C"
|
||||
require: "^^tabsetCtrl"
|
||||
template: "<div ng-include='template'></div>"
|
||||
scope:
|
||||
templates: "="
|
||||
link: (scope, element, attrs, ctrl) ->
|
||||
scope.template = null
|
||||
|
||||
ctrl.registerSelectionListener (prefix, selection) ->
|
||||
if selection?
|
||||
selection = "#{prefix}/#{selection}" if prefix?
|
||||
scope.template = "#{selection}.html"
|
||||
else
|
||||
scope.template = null
|
||||
@@ -0,0 +1,28 @@
|
||||
Darkswarm.directive "tabsetCtrl", (Tabsets, $location) ->
|
||||
restrict: "C"
|
||||
scope:
|
||||
id: "@"
|
||||
selected: "@"
|
||||
navigate: "="
|
||||
prefix: "@?"
|
||||
controller: ($scope, $element) ->
|
||||
if $scope.navigate
|
||||
path = $location.path()?.match(/^\/\w+$/)?[0]
|
||||
$scope.selected = path[1..] if path
|
||||
|
||||
this.toggle = (name) ->
|
||||
Tabsets.toggle($scope.id, name)
|
||||
|
||||
this.select = (selection) ->
|
||||
$scope.$broadcast("selection:changed", selection)
|
||||
$element.toggleClass("expanded", selection?)
|
||||
$location.path(selection) if $scope.navigate
|
||||
|
||||
this.registerSelectionListener = (callback) ->
|
||||
$scope.$on "selection:changed", (event, selection) ->
|
||||
callback($scope.prefix, selection)
|
||||
|
||||
this
|
||||
|
||||
link: (scope, element, attrs, ctrl) ->
|
||||
Tabsets.register(ctrl, scope.id, scope.selected)
|
||||
@@ -0,0 +1,7 @@
|
||||
Darkswarm.filter 'closedShops', ->
|
||||
(enterprises, show_closed) ->
|
||||
enterprises ||= []
|
||||
show_closed ?= false
|
||||
|
||||
enterprises.filter (enterprise) =>
|
||||
show_closed or enterprise.active or !enterprise.is_distributor
|
||||
@@ -3,13 +3,12 @@ Darkswarm.filter "localizeCurrency", (currencyConfig)->
|
||||
(amount) ->
|
||||
# Set country code (eg. "US").
|
||||
currency_code = if currencyConfig.display_currency then " " + currencyConfig.currency else ""
|
||||
# Set decimal points, 2 or 0 if hide_cents.
|
||||
# Set decimal points, 2 or 0 if hide_cents.
|
||||
decimals = if currencyConfig.hide_cents == "true" then 0 else 2
|
||||
# We need to use parseFloat before toFixed as the amount should come in as a string.
|
||||
amount_fixed = parseFloat(amount).toFixed(decimals)
|
||||
# Set format if the currency symbol should come after the number, otherwise (default) use the locale setting.
|
||||
format = if currencyConfig.symbol_position == "after" then "%n %u" else undefined
|
||||
# We need to use parseFloat as the amount should come in as a string.
|
||||
amount = parseFloat(amount)
|
||||
|
||||
# Build the final price string. TODO use spree decimal point and spacer character settings.
|
||||
if currencyConfig.symbol_position == 'before'
|
||||
currencyConfig.symbol + amount_fixed + currency_code
|
||||
else
|
||||
amount_fixed + " " + currencyConfig.symbol + currency_code
|
||||
# Build the final price string.
|
||||
I18n.toCurrency(amount, {precision: decimals, unit: currencyConfig.symbol, format: format}) + currency_code
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
window.FieldsetMixin = ($scope)->
|
||||
$scope.next = (event = false)->
|
||||
event.preventDefault() if event
|
||||
return unless $scope.nextPanel
|
||||
$scope.show $scope.nextPanel
|
||||
|
||||
$scope.onTimeout = ->
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
Darkswarm.factory 'Checkout', (CurrentOrder, ShippingMethods, PaymentMethods, $http, Navigation, CurrentHub, RailsFlashLoader, Loading)->
|
||||
Darkswarm.factory 'Checkout', ($injector, CurrentOrder, ShippingMethods, StripeElements, PaymentMethods, $http, Navigation, CurrentHub, RailsFlashLoader, Loading)->
|
||||
new class Checkout
|
||||
errors: {}
|
||||
secrets: {}
|
||||
order: CurrentOrder.order
|
||||
|
||||
submit: ->
|
||||
purchase: ->
|
||||
if @paymentMethod()?.method_type == 'stripe' && !@secrets.selected_card
|
||||
StripeElements.requestToken(@secrets, @submit)
|
||||
else
|
||||
@submit()
|
||||
|
||||
submit: =>
|
||||
Loading.message = t 'submitting_order'
|
||||
$http.put('/checkout', {order: @preprocess()}).success (data, status)=>
|
||||
$http.put('/checkout.json', {order: @preprocess()}).success (data, status)=>
|
||||
Navigation.go data.path
|
||||
.error (response, status)=>
|
||||
if response.path
|
||||
@@ -53,6 +59,23 @@ Darkswarm.factory 'Checkout', (CurrentOrder, ShippingMethods, PaymentMethods, $h
|
||||
last_name: @order.bill_address.lastname
|
||||
}
|
||||
|
||||
if @paymentMethod()?.method_type == 'stripe'
|
||||
if @secrets.selected_card
|
||||
angular.extend munged_order, {
|
||||
existing_card_id: @secrets.selected_card
|
||||
}
|
||||
else
|
||||
angular.extend munged_order.payments_attributes[0], {
|
||||
source_attributes:
|
||||
gateway_payment_profile_id: @secrets.token
|
||||
cc_type: @secrets.cc_type
|
||||
last_digits: @secrets.card.last4
|
||||
month: @secrets.card.exp_month
|
||||
year: @secrets.card.exp_year
|
||||
first_name: @order.bill_address.firstname
|
||||
last_name: @order.bill_address.lastname
|
||||
save_requested_by_customer: @secrets.save_requested_by_customer
|
||||
}
|
||||
munged_order
|
||||
|
||||
shippingMethod: ->
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
Darkswarm.factory 'CreditCard', ($injector, $rootScope, CreditCards, StripeElements, Navigation, $http, RailsFlashLoader, Loading)->
|
||||
new class CreditCard
|
||||
visible: false
|
||||
errors: {}
|
||||
secrets: {}
|
||||
|
||||
requestToken: =>
|
||||
@setFullName()
|
||||
StripeElements.requestToken(@secrets, @submit, t("saving_credit_card"))
|
||||
|
||||
submit: =>
|
||||
params = @process_params()
|
||||
$http.put('/credit_cards/new_from_token', params )
|
||||
.success (data, status) =>
|
||||
Loading.clear()
|
||||
@reset()
|
||||
CreditCards.add(data)
|
||||
.error (response, status) =>
|
||||
if response.path
|
||||
Navigation.go response.path
|
||||
else
|
||||
Loading.clear()
|
||||
@errors = response.errors
|
||||
RailsFlashLoader.loadFlash(response.flash)
|
||||
|
||||
setFullName: ->
|
||||
@secrets.name = "#{@secrets.first_name} #{@secrets.last_name}"
|
||||
|
||||
process_params: ->
|
||||
{"exp_month": @secrets.card.exp_month,
|
||||
"exp_year": @secrets.card.exp_year,
|
||||
"last4": @secrets.card.last4,
|
||||
"token": @secrets.token,
|
||||
"cc_type": @secrets.cc_type}
|
||||
|
||||
show: => @visible = true
|
||||
|
||||
reset: =>
|
||||
@visible = false
|
||||
delete @secrets[k] for k, v of @secrets
|
||||
delete @errors[k] for k, v of @errors
|
||||
@@ -0,0 +1,6 @@
|
||||
Darkswarm.factory 'CreditCards', (savedCreditCards)->
|
||||
new class CreditCard
|
||||
saved: savedCreditCards
|
||||
|
||||
add: (card) ->
|
||||
@saved.push card
|
||||
18
app/assets/javascripts/darkswarm/services/dates.js.coffee
Normal file
18
app/assets/javascripts/darkswarm/services/dates.js.coffee
Normal file
@@ -0,0 +1,18 @@
|
||||
Darkswarm.factory "Dates", ->
|
||||
new class Dates
|
||||
months: [
|
||||
{key: t("january"), value: "1"},
|
||||
{key: t("february"), value: "2"},
|
||||
{key: t("march"), value: "3"},
|
||||
{key: t("april"), value: "4"},
|
||||
{key: t("may"), value: "5"},
|
||||
{key: t("june"), value: "6"},
|
||||
{key: t("july"), value: "7"},
|
||||
{key: t("august"), value: "8"},
|
||||
{key: t("september"), value: "9"},
|
||||
{key: t("october"), value: "10"},
|
||||
{key: t("november"), value: "11"},
|
||||
{key: t("december"), value: "12"},
|
||||
]
|
||||
|
||||
years: [moment().year()..(moment().year()+15)]
|
||||
@@ -11,7 +11,11 @@ Darkswarm.factory "EnterpriseRegistrationService", ($http, RegistrationService,
|
||||
for key, value of enterpriseAttributes
|
||||
@enterprise[key] = value
|
||||
|
||||
create: =>
|
||||
# Creates the enterprise and redirects to the about step on success.
|
||||
#
|
||||
# @param callback [Function] executed at the end of the operation both in
|
||||
# case of success or failure.
|
||||
create: (callback) =>
|
||||
Loading.message = t('creating') + " " + @enterprise.name
|
||||
$http(
|
||||
method: "POST"
|
||||
@@ -33,6 +37,7 @@ Darkswarm.factory "EnterpriseRegistrationService", ($http, RegistrationService,
|
||||
else
|
||||
alert(t('failed_to_create_enterprise_unknown'))
|
||||
)
|
||||
callback.call() if callback?
|
||||
|
||||
update: (step) =>
|
||||
Loading.message = t('updating') + " " + @enterprise.name
|
||||
|
||||
@@ -21,3 +21,6 @@ Darkswarm.factory 'Navigation', ($location, $window) ->
|
||||
$window.location.href = path
|
||||
else
|
||||
$window.location.pathname = path
|
||||
|
||||
reload: ->
|
||||
$window.location.reload()
|
||||
|
||||
@@ -1,22 +1,25 @@
|
||||
Darkswarm.factory 'Orders', (orders_by_distributor, currencyConfig, CurrentHub, Taxons, Dereferencer, visibleFilter, Matcher, Geo, $rootScope)->
|
||||
Darkswarm.factory 'Orders', (orders, shops, currencyConfig)->
|
||||
new class Orders
|
||||
all: orders
|
||||
changeable: []
|
||||
shops: shops
|
||||
shopsByID: {}
|
||||
currencySymbol = currencyConfig.symbol
|
||||
|
||||
constructor: ->
|
||||
# Populate Orders.orders from json in page.
|
||||
@orders_by_distributor = orders_by_distributor
|
||||
@changeable_orders = []
|
||||
@currency_symbol = currencyConfig.symbol
|
||||
for shop in @shops
|
||||
shop.orders = []
|
||||
shop.balance = 0.0
|
||||
@shopsByID[shop.id] = shop
|
||||
|
||||
for distributor in @orders_by_distributor
|
||||
@findChangeableOrders(distributor.distributed_orders)
|
||||
@updateRunningBalance(distributor.distributed_orders)
|
||||
for order in @all by -1
|
||||
shop = @shopsByID[order.shop_id]
|
||||
shop.orders.unshift order
|
||||
|
||||
@changeable.unshift(order) if order.changes_allowed
|
||||
|
||||
updateRunningBalance: (orders) ->
|
||||
for order, i in orders
|
||||
balances = orders.slice(i,orders.length).map (o) -> parseFloat(o.outstanding_balance)
|
||||
running_balance = balances.reduce (a,b) -> a+b
|
||||
order.running_balance = running_balance.toFixed(2)
|
||||
@updateRunningBalance(shop, order)
|
||||
|
||||
findChangeableOrders: (orders) ->
|
||||
for order in orders when order.changes_allowed
|
||||
@changeable_orders.push(order)
|
||||
updateRunningBalance: (shop, order) ->
|
||||
shop.balance += parseFloat(order.outstanding_balance)
|
||||
order.runningBalance = shop.balance.toFixed(2)
|
||||
|
||||
@@ -1,7 +1,18 @@
|
||||
Darkswarm.factory 'RailsFlashLoader', (flash, railsFlash)->
|
||||
new class RailsFlashLoader
|
||||
# The 'flash' service requires type key to
|
||||
# be one of: success, info, warn, error
|
||||
typePairings:
|
||||
success: 'success'
|
||||
error: 'error'
|
||||
notice: 'success'
|
||||
info: 'info'
|
||||
warn: 'warn'
|
||||
|
||||
initFlash: ->
|
||||
@loadFlash railsFlash
|
||||
|
||||
loadFlash: (rails_flash)->
|
||||
for type, message of rails_flash
|
||||
type = @typePairings[type]
|
||||
flash[type] = message
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
Darkswarm.factory 'StripeElements', ($rootScope, Loading, RailsFlashLoader) ->
|
||||
new class StripeElements
|
||||
# TODO: add locale here for translations of error messages etc. from Stripe
|
||||
|
||||
# These are both set from the StripeElements directive
|
||||
stripe: null
|
||||
card: null
|
||||
|
||||
# New Stripe Elements method
|
||||
requestToken: (secrets, submit, loading_message = t("processing_payment")) ->
|
||||
return unless @stripe? && @card?
|
||||
|
||||
Loading.message = loading_message
|
||||
cardData = @makeCardData(secrets)
|
||||
|
||||
@stripe.createToken(@card, cardData).then (response) =>
|
||||
if(response.error)
|
||||
Loading.clear()
|
||||
RailsFlashLoader.loadFlash({error: t("error") + ": #{response.error.message}"})
|
||||
else
|
||||
secrets.token = response.token.id
|
||||
secrets.cc_type = @mapCC(response.token.card.brand)
|
||||
secrets.card = response.token.card
|
||||
submit()
|
||||
|
||||
# Maps the brand returned by Stripe to that required by activemerchant
|
||||
mapCC: (ccType) ->
|
||||
if ccType == 'MasterCard'
|
||||
return 'master'
|
||||
else if ccType == 'Visa'
|
||||
return 'visa'
|
||||
else if ccType == 'American Express'
|
||||
return 'american_express'
|
||||
else if ccType == 'Discover'
|
||||
return 'discover'
|
||||
else if ccType == 'JCB'
|
||||
return 'jcb'
|
||||
else if ccType == 'Diners Club'
|
||||
return 'diners_club'
|
||||
return
|
||||
|
||||
# It doesn't matter if any of these are nil, all are optional.
|
||||
makeCardData: (secrets) ->
|
||||
{'name': secrets.name,
|
||||
'address1': secrets.address1,
|
||||
'city': secrets.city,
|
||||
'zipcode': secrets.zipcode}
|
||||
22
app/assets/javascripts/darkswarm/services/tabsets.js.coffee
Normal file
22
app/assets/javascripts/darkswarm/services/tabsets.js.coffee
Normal file
@@ -0,0 +1,22 @@
|
||||
Darkswarm.factory 'Tabsets', ->
|
||||
new class Tabsets
|
||||
tabsets: []
|
||||
|
||||
register: (ctrl, id, selected=null) ->
|
||||
if ctrl? && id?
|
||||
@tabsets.push { ctrl: ctrl, id: id, selected: selected }
|
||||
ctrl.select(selected) if selected?
|
||||
|
||||
toggle: (id, name, state=null) ->
|
||||
tabset = @findTabsetByObject(id)
|
||||
if tabset.selected == name
|
||||
@select(tabset, null) unless state == "open"
|
||||
else
|
||||
@select(tabset, name) unless state == "closed"
|
||||
|
||||
select: (tabset, name) ->
|
||||
tabset.selected = name
|
||||
tabset.ctrl.select(name)
|
||||
|
||||
findTabsetByObject: (id) ->
|
||||
(tabset for tabset in @tabsets when tabset.id == id)[0]
|
||||
@@ -6,8 +6,7 @@
|
||||
//
|
||||
|
||||
//= require 'jquery'
|
||||
//= require store/spree_core
|
||||
//= require store/spree_frontend
|
||||
//= require store/spree_auth
|
||||
//= require store/spree_promo
|
||||
|
||||
//= require_tree .
|
||||
|
||||
@@ -4,9 +4,8 @@
|
||||
* the top of the compiled file, but it's generally better to create a new file per style scope.
|
||||
*
|
||||
|
||||
*= require admin/spree_core
|
||||
*= require admin/spree_backend
|
||||
*= require admin/spree_auth
|
||||
*= require admin/spree_promo
|
||||
|
||||
*= require shared/jquery-ui-timepicker-addon
|
||||
*= require shared/textAngular
|
||||
|
||||
80
app/assets/stylesheets/admin/components/alert-box.css.scss
Normal file
80
app/assets/stylesheets/admin/components/alert-box.css.scss
Normal file
@@ -0,0 +1,80 @@
|
||||
@import "../../darkswarm/mixins";
|
||||
|
||||
.alert-box {
|
||||
position: relative;
|
||||
display: block;
|
||||
background-color: #eff5dc;
|
||||
border: 1px solid #9fc820;
|
||||
color: #666;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
|
||||
@include border-radius(3px);
|
||||
|
||||
transition: opacity 300ms ease-out;
|
||||
padding: 0.77778em 1.33333em 0.77778em 0.77778em;
|
||||
|
||||
a.close {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 5px;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
&.ok {
|
||||
border: 1px solid #9fc820;
|
||||
background-color: #fbffee;
|
||||
color: #9fc820;
|
||||
font-weight: bold;
|
||||
|
||||
a.button {
|
||||
padding: 3px 10px;
|
||||
background-color: #a7c44d;
|
||||
&:hover {
|
||||
background-color: #9fc820;
|
||||
}
|
||||
}
|
||||
|
||||
a.close {
|
||||
color: #9fc820;
|
||||
}
|
||||
}
|
||||
|
||||
&.error {
|
||||
border: 1px solid #c82020;
|
||||
background-color: #f5dcdc;
|
||||
color: #c82020;
|
||||
font-weight: bold;
|
||||
|
||||
a.button {
|
||||
padding: 3px 10px;
|
||||
background-color: #c85252;
|
||||
&:hover {
|
||||
background-color: #c82020;
|
||||
}
|
||||
}
|
||||
|
||||
a.close {
|
||||
color: #c82020;
|
||||
}
|
||||
}
|
||||
|
||||
&.warning {
|
||||
border: 1px solid #e6912e;
|
||||
background-color: #fff4e6;
|
||||
color: #e6912e;
|
||||
font-weight: bold;
|
||||
|
||||
a.button {
|
||||
padding: 3px 10px;
|
||||
background-color: #db9350;
|
||||
&:hover {
|
||||
background-color: #e6912e;
|
||||
}
|
||||
}
|
||||
|
||||
a.close {
|
||||
color: #e6912e;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,8 +24,6 @@ light: #ccc
|
||||
}
|
||||
}
|
||||
|
||||
/*.ui-dialog .ui-icon-closethick{background:url(/static/assets/dialogCloseButton.png);}*/
|
||||
|
||||
.ui-dialog .ui-widget-header{
|
||||
background-image: none;
|
||||
background-color: #ffffff;
|
||||
@@ -42,21 +40,18 @@ light: #ccc
|
||||
.ui-dialog .ui-corner-all{
|
||||
border-radius: 8px;
|
||||
}
|
||||
.ui-dialog {
|
||||
.ui-state-hover, .ui-state-focus{
|
||||
border: none;
|
||||
background: none;
|
||||
color: #545454;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-state-hover, .ui-widget-header .ui-state-hover, .ui-widget-content .ui-state-hover {
|
||||
background-color: #ffffff;
|
||||
background: none;
|
||||
}
|
||||
|
||||
.ui-dialog-titlebar-close {
|
||||
.ui-dialog .ui-dialog-titlebar .ui-dialog-titlebar-close {
|
||||
float: right;
|
||||
|
||||
border: none;
|
||||
background: none;
|
||||
|
||||
&:before {
|
||||
color: #000000;
|
||||
font-size: 2em;
|
||||
@@ -76,9 +71,18 @@ light: #ccc
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-button-text {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-widget-overlay {
|
||||
background: #000000;
|
||||
opacity: 0.5;
|
||||
position: fixed;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,27 +1,5 @@
|
||||
@import "../darkswarm/mixins";
|
||||
|
||||
.alert-box {
|
||||
position: relative;
|
||||
display: block;
|
||||
background-color: #eff5dc;
|
||||
border: 1px solid #9fc820;
|
||||
color: #666;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
|
||||
@include border-radius(3px);
|
||||
|
||||
transition: opacity 300ms ease-out;
|
||||
padding: 0.77778em 1.33333em 0.77778em 0.77778em;
|
||||
|
||||
a.close {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 0px;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
}
|
||||
|
||||
.dashboard_item.single-ent {
|
||||
.header {
|
||||
padding: 0.77778em 1.33333em 0.77778em 0.77778em;
|
||||
|
||||
@@ -43,6 +43,13 @@ input.red {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
a.button.red {
|
||||
&:not(:hover) {
|
||||
color: #fff;
|
||||
background-color: #DA5354;
|
||||
}
|
||||
}
|
||||
|
||||
input.orange {
|
||||
background-color: #FF9848;
|
||||
margin-right: 5px;
|
||||
|
||||
@@ -69,4 +69,10 @@ table#listing_products.bulk {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
td.left-actions {
|
||||
a.view-variants, a.add-variant {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,32 @@
|
||||
color: #4a4a4a;
|
||||
}
|
||||
|
||||
.credit_cards {
|
||||
.saved_cards {
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.saved_cards, .no_cards {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.new_card {
|
||||
opacity: 0;
|
||||
-webkit-transition: opacity 0.4s linear;
|
||||
transition: opacity 0.4s linear;
|
||||
&.visible {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
input.ng-invalid {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.orders {
|
||||
margin-top: 50px;
|
||||
margin-bottom: 100px;
|
||||
|
||||
a {
|
||||
@@ -24,6 +47,10 @@
|
||||
height: auto;
|
||||
}
|
||||
|
||||
&.active_table {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.active_table_row {
|
||||
h3 {
|
||||
margin-top: 0.5em;
|
||||
|
||||
@@ -81,3 +81,6 @@ checkout
|
||||
display: inline
|
||||
span.accordion-down
|
||||
display: none
|
||||
|
||||
.error
|
||||
color: #c82020
|
||||
|
||||
16
app/assets/stylesheets/darkswarm/stripe-elements.css.scss
Normal file
16
app/assets/stylesheets/darkswarm/stripe-elements.css.scss
Normal file
@@ -0,0 +1,16 @@
|
||||
stripe-elements {
|
||||
margin-bottom: 15px;
|
||||
display: block;
|
||||
|
||||
#card-element {
|
||||
background: white;
|
||||
box-sizing: border-box;
|
||||
font-weight: 400;
|
||||
padding: 0.6rem 0.5rem;
|
||||
border: 1px solid #cccccc;
|
||||
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
border-radius: 0px;
|
||||
height: 42px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
71
app/assets/stylesheets/darkswarm/tabset.css.scss
Normal file
71
app/assets/stylesheets/darkswarm/tabset.css.scss
Normal file
@@ -0,0 +1,71 @@
|
||||
@import "typography";
|
||||
@import "mixins";
|
||||
@import "branding";
|
||||
|
||||
.tabset-ctrl {
|
||||
.tab-view {
|
||||
padding-top: 30px;
|
||||
}
|
||||
|
||||
.tab {
|
||||
text-align: center;
|
||||
|
||||
@media all and (max-width: 640px) {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
a {
|
||||
@include headingFont;
|
||||
|
||||
background: transparent;
|
||||
text-transform: uppercase;
|
||||
font-size: 1.5em;
|
||||
text-shadow: 0 -1px 1px #ffffff;
|
||||
padding: 1em;
|
||||
border: none;
|
||||
|
||||
@media all and (max-width: 640px) {
|
||||
padding: 0.35em 0 0.65em 0;
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
border-bottom: 4px solid transparent;
|
||||
|
||||
&:hover, &:focus, &:active {
|
||||
transition: all 0.4s ease-in-out;
|
||||
border-bottom: 4px solid $clr-brick-bright;
|
||||
cursor: pointer;
|
||||
|
||||
@media all and (max-width: 640px) {
|
||||
transition: none;
|
||||
color: white;
|
||||
background-color: $clr-brick-bright;
|
||||
}
|
||||
|
||||
a {
|
||||
color: $clr-brick-bright;
|
||||
|
||||
@media all and (max-width: 640px) {
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.selected {
|
||||
border-bottom: 4px solid $clr-brick;
|
||||
|
||||
@media all and (max-width: 640px) {
|
||||
background-color: $clr-brick;
|
||||
}
|
||||
|
||||
a {
|
||||
color: $clr-brick;
|
||||
|
||||
@media all and (max-width: 640px) {
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -408,3 +408,12 @@ ul {
|
||||
display: inline-block;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fix overlapping table header on second page of long invoices.
|
||||
* Problem description: https://github.com/openfoodfoundation/openfoodnetwork/issues/1738
|
||||
* Solution: https://github.com/wkhtmltopdf/wkhtmltopdf/issues/1770#issuecomment-73530576
|
||||
*/
|
||||
thead { display: table-header-group }
|
||||
tfoot { display: table-row-group }
|
||||
tr { page-break-inside: avoid }
|
||||
|
||||
@@ -4,9 +4,8 @@
|
||||
* the top of the compiled file, but it's generally better to create a new file per style scope.
|
||||
*
|
||||
|
||||
*= require store/spree_core
|
||||
*= require store/spree_frontend
|
||||
*= require store/spree_auth
|
||||
*= require store/spree_promo
|
||||
|
||||
*= require_self
|
||||
*= require_tree .
|
||||
|
||||
68
app/controllers/admin/bulk_line_items_controller.rb
Normal file
68
app/controllers/admin/bulk_line_items_controller.rb
Normal file
@@ -0,0 +1,68 @@
|
||||
module Admin
|
||||
class BulkLineItemsController < Spree::Admin::BaseController
|
||||
# GET /admin/bulk_line_items.json
|
||||
#
|
||||
def index
|
||||
order_params = params[:q].andand.delete :order
|
||||
orders = OpenFoodNetwork::Permissions.new(spree_current_user).editable_orders.ransack(order_params).result
|
||||
line_items = OpenFoodNetwork::Permissions.new(spree_current_user).editable_line_items.where(order_id: orders).ransack(params[:q])
|
||||
render_as_json line_items.result.reorder('order_id ASC, id ASC')
|
||||
end
|
||||
|
||||
# PUT /admin/bulk_line_items/:id.json
|
||||
#
|
||||
def update
|
||||
load_line_item
|
||||
authorize_update!
|
||||
|
||||
# `with_lock` acquires an exclusive row lock on order so no other
|
||||
# requests can update it until the transaction is commited.
|
||||
# See https://github.com/rails/rails/blob/3-2-stable/activerecord/lib/active_record/locking/pessimistic.rb#L69
|
||||
# and https://www.postgresql.org/docs/current/static/sql-select.html#SQL-FOR-UPDATE-SHARE
|
||||
order.with_lock do
|
||||
if @line_item.update_attributes(params[:line_item])
|
||||
order.update_distribution_charge!
|
||||
render nothing: true, status: 204 # No Content, does not trigger ng resource auto-update
|
||||
else
|
||||
render json: { errors: @line_item.errors }, status: 412
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# DELETE /admin/bulk_line_items/:id.json
|
||||
#
|
||||
def destroy
|
||||
load_line_item
|
||||
authorize! :update, order
|
||||
|
||||
@line_item.destroy
|
||||
render nothing: true, status: 204 # No Content, does not trigger ng resource auto-update
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_line_item
|
||||
@line_item = Spree::LineItem.find(params[:id])
|
||||
end
|
||||
|
||||
def model_class
|
||||
Spree::LineItem
|
||||
end
|
||||
|
||||
# Returns the appropriate serializer for this controller
|
||||
#
|
||||
# @return [Api::Admin::LineItemSerializer]
|
||||
def serializer(_ams_prefix)
|
||||
Api::Admin::LineItemSerializer
|
||||
end
|
||||
|
||||
def authorize_update!
|
||||
authorize! :update, order
|
||||
authorize! :read, order
|
||||
end
|
||||
|
||||
def order
|
||||
@line_item.order
|
||||
end
|
||||
end
|
||||
end
|
||||
49
app/controllers/admin/stripe_accounts_controller.rb
Normal file
49
app/controllers/admin/stripe_accounts_controller.rb
Normal file
@@ -0,0 +1,49 @@
|
||||
require 'stripe/account_connector'
|
||||
|
||||
module Admin
|
||||
class StripeAccountsController < Spree::Admin::BaseController
|
||||
def connect
|
||||
payload = params.slice(:enterprise_id)
|
||||
key = Openfoodnetwork::Application.config.secret_token
|
||||
url_params = { state: JWT.encode(payload, key, 'HS256'), scope: "read_write" }
|
||||
redirect_to Stripe::OAuth.authorize_url(url_params)
|
||||
end
|
||||
|
||||
def destroy
|
||||
stripe_account = StripeAccount.find(params[:id])
|
||||
authorize! :destroy, stripe_account
|
||||
|
||||
if stripe_account.deauthorize_and_destroy
|
||||
flash[:success] = "Stripe account disconnected."
|
||||
else
|
||||
flash[:error] = "Failed to disconnect Stripe."
|
||||
end
|
||||
|
||||
redirect_to main_app.edit_admin_enterprise_path(stripe_account.enterprise)
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
flash[:error] = "Failed to disconnect Stripe."
|
||||
redirect_to spree.admin_path
|
||||
end
|
||||
|
||||
def status
|
||||
return render json: { status: :stripe_disabled } unless Spree::Config.stripe_connect_enabled
|
||||
stripe_account = StripeAccount.find_by_enterprise_id(params[:enterprise_id])
|
||||
return render json: { status: :account_missing } unless stripe_account
|
||||
authorize! :status, stripe_account
|
||||
|
||||
begin
|
||||
status = Stripe::Account.retrieve(stripe_account.stripe_user_id)
|
||||
attrs = %i[id business_name charges_enabled]
|
||||
render json: status.to_hash.slice(*attrs).merge( status: :connected)
|
||||
rescue Stripe::APIError
|
||||
render json: { status: :access_revoked }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def model_class
|
||||
StripeAccount
|
||||
end
|
||||
end
|
||||
end
|
||||
40
app/controllers/admin/stripe_connect_settings_controller.rb
Normal file
40
app/controllers/admin/stripe_connect_settings_controller.rb
Normal file
@@ -0,0 +1,40 @@
|
||||
# This controller is used by super admin users to update the settings the app is using
|
||||
|
||||
module Admin
|
||||
class StripeConnectSettingsController < Spree::Admin::BaseController
|
||||
StripeConnectSettings = Struct.new(:stripe_connect_enabled)
|
||||
|
||||
before_filter :load_settings, only: [:edit]
|
||||
|
||||
def edit
|
||||
return @stripe_account = { status: :empty_api_key } if Stripe.api_key.blank?
|
||||
attrs = %i[id business_name charges_enabled]
|
||||
@obfuscated_secret_key = obfuscated_secret_key
|
||||
@stripe_account = Stripe::Account.retrieve.to_hash.slice(*attrs).merge(status: :ok)
|
||||
rescue Stripe::AuthenticationError
|
||||
@stripe_account = { status: :auth_fail }
|
||||
end
|
||||
|
||||
def update
|
||||
Spree::Config.set(params[:settings])
|
||||
resource = t('admin.controllers.stripe_connect_settings.resource')
|
||||
flash[:success] = t(:successfully_updated, :resource => resource)
|
||||
redirect_to_edit
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_settings
|
||||
@settings = StripeConnectSettings.new(Spree::Config[:stripe_connect_enabled])
|
||||
end
|
||||
|
||||
def redirect_to_edit
|
||||
redirect_to main_app.edit_admin_stripe_connect_settings_path
|
||||
end
|
||||
|
||||
def obfuscated_secret_key
|
||||
key = Stripe.api_key
|
||||
key.first(8) + "****" + key.last(4)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -57,7 +57,7 @@ class ApplicationController < ActionController::Base
|
||||
def enable_embedded_shopfront
|
||||
whitelist = Spree::Config[:embedded_shopfronts_whitelist]
|
||||
return unless Spree::Config[:enable_embedded_shopfronts] && whitelist.present?
|
||||
return if request.referer && URI(request.referer).scheme != 'https' && !Rails.env.test?
|
||||
return if request.referer && URI(request.referer).scheme != 'https' && !Rails.env.test? && !Rails.env.development?
|
||||
|
||||
response.headers.delete 'X-Frame-Options'
|
||||
response.headers['Content-Security-Policy'] = "frame-ancestors #{whitelist}"
|
||||
|
||||
@@ -15,6 +15,10 @@ class CheckoutController < Spree::CheckoutController
|
||||
include EnterprisesHelper
|
||||
|
||||
def edit
|
||||
# This is only required because of spree_paypal_express. If we implement
|
||||
# a version of paypal that uses this controller, and more specifically
|
||||
# the #update_failed method, then we can remove this call
|
||||
restart_checkout
|
||||
end
|
||||
|
||||
def update
|
||||
@@ -26,28 +30,29 @@ class CheckoutController < Spree::CheckoutController
|
||||
return if redirect_to_paypal_express_form_if_needed
|
||||
end
|
||||
|
||||
if advance_order_state(@order)
|
||||
state_callback(:after)
|
||||
next if advance_order_state(@order)
|
||||
|
||||
if @order.errors.present?
|
||||
flash[:error] = @order.errors.full_messages.to_sentence
|
||||
else
|
||||
if @order.errors.present?
|
||||
flash[:error] = @order.errors.full_messages.to_sentence
|
||||
else
|
||||
flash[:error] = t(:payment_processing_failed)
|
||||
end
|
||||
update_failed
|
||||
return
|
||||
flash[:error] = t(:payment_processing_failed)
|
||||
end
|
||||
update_failed
|
||||
return
|
||||
end
|
||||
if @order.state == "complete" || @order.completed?
|
||||
set_default_bill_address
|
||||
set_default_ship_address
|
||||
|
||||
flash[:success] = t(:order_processed_successfully)
|
||||
ResetOrderService.new(self, current_order).call
|
||||
session[:access_token] = current_order.token
|
||||
|
||||
flash[:notice] = t(:order_processed_successfully)
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
respond_with(@order, :location => order_path(@order))
|
||||
end
|
||||
format.js do
|
||||
format.json do
|
||||
render json: {path: order_path(@order)}, status: 200
|
||||
end
|
||||
end
|
||||
@@ -59,6 +64,13 @@ class CheckoutController < Spree::CheckoutController
|
||||
end
|
||||
end
|
||||
|
||||
# Clears the cached order. Required for #current_order to return a new order
|
||||
# to serve as cart. See https://github.com/spree/spree/blob/1-3-stable/core/lib/spree/core/controller_helpers/order.rb#L14
|
||||
# for details.
|
||||
def expire_current_order
|
||||
session[:order_id] = nil
|
||||
@current_order = nil
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -111,6 +123,9 @@ class CheckoutController < Spree::CheckoutController
|
||||
if (params[:order][:payments_attributes])
|
||||
params[:order][:payments_attributes].first[:amount] = @order.total
|
||||
end
|
||||
if params[:order][:existing_card_id]
|
||||
construct_saved_card_attributes
|
||||
end
|
||||
params[:order]
|
||||
end
|
||||
|
||||
@@ -126,11 +141,12 @@ class CheckoutController < Spree::CheckoutController
|
||||
|
||||
def update_failed
|
||||
clear_ship_address
|
||||
restart_checkout
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
render :edit
|
||||
end
|
||||
format.js do
|
||||
format.json do
|
||||
render json: {errors: @order.errors, flash: flash.to_hash}.to_json, status: 400
|
||||
end
|
||||
end
|
||||
@@ -144,6 +160,15 @@ class CheckoutController < Spree::CheckoutController
|
||||
end
|
||||
end
|
||||
|
||||
def restart_checkout
|
||||
return if @order.state == 'cart'
|
||||
@order.restart_checkout! # resets state to 'cart'
|
||||
@order.update_attributes!(shipping_method_id: nil)
|
||||
@order.shipments.with_state(:pending).destroy_all
|
||||
@order.payments.with_state(:checkout).destroy_all
|
||||
@order.reload
|
||||
end
|
||||
|
||||
def skip_state_validation?
|
||||
true
|
||||
end
|
||||
@@ -154,7 +179,7 @@ class CheckoutController < Spree::CheckoutController
|
||||
raise_insufficient_quantity and return if @order.insufficient_stock_lines.present?
|
||||
redirect_to main_app.shop_path and return if @order.completed?
|
||||
before_address
|
||||
state_callback(:before)
|
||||
setup_for_current_state
|
||||
end
|
||||
|
||||
def before_address
|
||||
@@ -172,14 +197,6 @@ class CheckoutController < Spree::CheckoutController
|
||||
@order.ship_address ||= customer_preferred_ship_address || preferred_ship_address || last_used_ship_address || Spree::Address.default
|
||||
end
|
||||
|
||||
def after_payment
|
||||
# object_params sets the payment amount to the order total, but it does this before
|
||||
# the shipping method is set. This results in the customer not being charged for their
|
||||
# order's shipping. To fix this, we refresh the payment amount here.
|
||||
@order.update_totals
|
||||
@order.payments.first.update_attribute :amount, @order.total
|
||||
end
|
||||
|
||||
# Overriding Spree's methods
|
||||
def raise_insufficient_quantity
|
||||
respond_to do |format|
|
||||
@@ -202,4 +219,28 @@ class CheckoutController < Spree::CheckoutController
|
||||
render json: {path: spree.paypal_express_url(payment_method_id: payment_method.id)}, status: 200
|
||||
true
|
||||
end
|
||||
|
||||
def construct_saved_card_attributes
|
||||
existing_card_id = params[:order].delete(:existing_card_id)
|
||||
return if existing_card_id.blank?
|
||||
|
||||
credit_card = Spree::CreditCard.find(existing_card_id)
|
||||
if credit_card.try(:user_id).blank? || credit_card.user_id != spree_current_user.try(:id)
|
||||
raise Spree::Core::GatewayError, I18n.t(:invalid_credit_card)
|
||||
end
|
||||
|
||||
# Not currently supported but maybe we should add it...?
|
||||
credit_card.verification_value = params[:cvc_confirm] if params[:cvc_confirm].present?
|
||||
|
||||
params[:order][:payments_attributes].first[:source] = credit_card
|
||||
params[:order][:payments_attributes].first.delete :source_attributes
|
||||
end
|
||||
|
||||
def rescue_from_spree_gateway_error(error)
|
||||
flash[:error] = t(:spree_gateway_error_flash_for_checkout, error: error.message)
|
||||
respond_to do |format|
|
||||
format.html { render :edit }
|
||||
format.json { render json: { flash: flash.to_hash }, status: 400 }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -15,10 +15,11 @@ class EnterprisesController < BaseController
|
||||
respond_to :js, only: :permalink_checker
|
||||
|
||||
def relatives
|
||||
set_enterprise
|
||||
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
enterprise = Enterprise.find(params[:id])
|
||||
enterprises = enterprise.andand.relatives.andand.activated
|
||||
enterprises = @enterprise.andand.relatives.andand.activated
|
||||
render(json: enterprises,
|
||||
each_serializer: Api::EnterpriseSerializer,
|
||||
data: OpenFoodNetwork::EnterpriseInjectionData.new)
|
||||
@@ -40,6 +41,10 @@ class EnterprisesController < BaseController
|
||||
|
||||
private
|
||||
|
||||
def set_enterprise
|
||||
@enterprise = Enterprise.find_by_id(params[:id])
|
||||
end
|
||||
|
||||
def clean_permalink
|
||||
params[:permalink] = params[:permalink].parameterize
|
||||
end
|
||||
|
||||
@@ -6,6 +6,8 @@ class GroupsController < BaseController
|
||||
end
|
||||
|
||||
def show
|
||||
enable_embedded_shopfront
|
||||
@hide_menu = true if @shopfront_layout == 'embedded'
|
||||
@group = EnterpriseGroup.find_by_permalink(params[:id]) || EnterpriseGroup.find(params[:id])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,21 +2,6 @@ Spree::Admin::LineItemsController.class_eval do
|
||||
prepend_before_filter :load_order, except: :index
|
||||
around_filter :apply_enterprise_fees_with_lock, only: :update
|
||||
|
||||
respond_to :json
|
||||
|
||||
# TODO make updating line items faster by creating a bulk update method
|
||||
|
||||
def index
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
order_params = params[:q].andand.delete :order
|
||||
orders = OpenFoodNetwork::Permissions.new(spree_current_user).editable_orders.ransack(order_params).result
|
||||
line_items = OpenFoodNetwork::Permissions.new(spree_current_user).editable_line_items.where(order_id: orders).ransack(params[:q])
|
||||
render_as_json line_items.result.reorder('order_id ASC, id ASC')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
variant = Spree::Variant.find(params[:line_item][:variant_id])
|
||||
OpenFoodNetwork::ScopeVariantToHub.new(@order.distributor).scope(variant)
|
||||
@@ -34,9 +19,30 @@ Spree::Admin::LineItemsController.class_eval do
|
||||
end
|
||||
end
|
||||
|
||||
# TODO: simplify this, 3 formats per action is too much
|
||||
# we need `js` format for admin/orders/edit (jquery-rails gem)
|
||||
# we don't know if `html` format is needed
|
||||
def update
|
||||
respond_to do |format|
|
||||
format.html { render_order_form }
|
||||
format.js {
|
||||
if @line_item.update_attributes(params[:line_item])
|
||||
render nothing: true, status: 204 # No Content, does not trigger ng resource auto-update
|
||||
else
|
||||
render json: { errors: @line_item.errors }, status: 412
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def render_order_form
|
||||
respond_to do |format|
|
||||
format.html { render partial: 'spree/admin/orders/form', locals: {order: @order.reload} }
|
||||
end
|
||||
end
|
||||
|
||||
def load_order
|
||||
@order = Spree::Order.find_by_number!(params[:order_id])
|
||||
authorize! :update, @order
|
||||
|
||||
@@ -4,11 +4,7 @@ Spree::Admin::OrdersController.class_eval do
|
||||
include OpenFoodNetwork::SpreeApiKeyLoader
|
||||
helper CheckoutHelper
|
||||
before_filter :load_spree_api_key, :only => :bulk_management
|
||||
|
||||
# We need to add expections for collection actions other than :index here
|
||||
# because spree_auth_devise causes load_order to be called, which results
|
||||
# in an auth failure as the @order object is nil for collection actions
|
||||
before_filter :check_authorization, except: [:bulk_management, :managed]
|
||||
before_filter :load_order, only: %i[show edit update fire resend invoice print]
|
||||
|
||||
before_filter :load_distribution_choices, only: [:new, :edit, :update]
|
||||
|
||||
@@ -83,7 +79,7 @@ Spree::Admin::OrdersController.class_eval do
|
||||
template = if Spree::Config.invoice_style2? then "spree/admin/orders/invoice2" else "spree/admin/orders/invoice" end
|
||||
pdf = render_to_string pdf: "invoice-#{@order.number}.pdf", template: template, formats: [:html], encoding: "UTF-8"
|
||||
Spree::OrderMailer.invoice_email(@order.id, pdf).deliver
|
||||
flash[:success] = t(:invoice_email_sent)
|
||||
flash[:success] = t('admin.orders.invoice_email_sent')
|
||||
|
||||
respond_with(@order) { |format| format.html { redirect_to edit_admin_order_path(@order) } }
|
||||
end
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
module Spree
|
||||
module Admin
|
||||
PaymentMethodsController.class_eval do
|
||||
before_filter :restrict_stripe_account_change, only: [:update]
|
||||
before_filter :force_environment, only: [:create, :update]
|
||||
skip_before_filter :load_resource, only: [:show_provider_preferences]
|
||||
before_filter :load_hubs, only: [:new, :edit, :update]
|
||||
@@ -57,12 +58,30 @@ module Spree
|
||||
else
|
||||
@providers = Gateway.providers.reject{ |p| p.name.include? "Bogus" }.sort{|p1, p2| p1.name <=> p2.name }
|
||||
end
|
||||
@providers.reject!{ |p| p.name.ends_with? "StripeConnect" } unless show_stripe?
|
||||
@calculators = PaymentMethod.calculators.sort_by(&:name)
|
||||
end
|
||||
|
||||
def load_hubs
|
||||
@hubs = Enterprise.managed_by(spree_current_user).is_distributor.sort_by!{ |d| [(@payment_method.has_distributor? d) ? 0 : 1, d.name] }
|
||||
end
|
||||
|
||||
# Show Stripe as an option if enabled, or if the
|
||||
# current payment_method is already a Stripe method
|
||||
def show_stripe?
|
||||
Spree::Config.stripe_connect_enabled || @payment_method.try(:type) == "Spree::Gateway::StripeConnect"
|
||||
end
|
||||
|
||||
def restrict_stripe_account_change
|
||||
return unless @payment_method
|
||||
return unless @payment_method.type == "Spree::Gateway::StripeConnect"
|
||||
return unless @payment_method.preferred_enterprise_id.andand > 0
|
||||
|
||||
@stripe_account_holder = Enterprise.find(@payment_method.preferred_enterprise_id)
|
||||
return if spree_current_user.enterprises.include? @stripe_account_holder
|
||||
|
||||
params[:payment_method][:preferred_enterprise_id] = @stripe_account_holder.id
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,21 +1,32 @@
|
||||
Spree::Admin::PaymentsController.class_eval do
|
||||
# When a user fires an event, take them back to where they came from
|
||||
# Responder: http://guides.spreecommerce.com/developer/logic.html#overriding-controller-action-responses
|
||||
|
||||
# For some strange reason, adding PaymentsController.class_eval will cause gems/spree/app/controllers/spree/admin/payments_controller.rb:37 to error:
|
||||
# payments_url not defined.
|
||||
# This could be fixed by replacing line 37 with:
|
||||
# respond_with(@payment, location: admin_order_payments_url) { |format| format.html { redirect_to admin_order_payments_path(@order) } }
|
||||
respond_override :fire => { :html => { :success => lambda {
|
||||
redirect_to request.referer # Keeps any filter and sort prefs
|
||||
} } }
|
||||
|
||||
append_before_filter :filter_payment_methods
|
||||
|
||||
|
||||
# When a user fires an event, take them back to where they came from
|
||||
# (we can't use respond_override because Spree no longer uses respond_with)
|
||||
def fire
|
||||
event = params[:e]
|
||||
return unless event && @payment.payment_source
|
||||
|
||||
# Because we have a transition method also called void, we do this to avoid conflicts.
|
||||
event = "void_transaction" if event == "void"
|
||||
if @payment.send("#{event}!")
|
||||
flash[:success] = t(:payment_updated)
|
||||
else
|
||||
flash[:error] = t(:cannot_perform_operation)
|
||||
end
|
||||
rescue Spree::Core::GatewayError => ge
|
||||
flash[:error] = ge.message
|
||||
ensure
|
||||
redirect_to request.referer
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
# Only show payments for the order's distributor
|
||||
def filter_payment_methods
|
||||
@payment_methods = @payment_methods.select{ |pm| pm.has_distributor? @order.distributor}
|
||||
@payment_method ||= @payment_methods.first
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -8,9 +8,6 @@ Spree::Admin::ProductsController.class_eval do
|
||||
before_filter :load_spree_api_key, :only => [:bulk_edit, :variant_overrides]
|
||||
before_filter :strip_new_properties, only: [:create, :update]
|
||||
|
||||
|
||||
respond_to :json, :only => :clone
|
||||
|
||||
respond_override create: { html: {
|
||||
success: lambda {
|
||||
if params[:button] == "add_another"
|
||||
@@ -22,7 +19,6 @@ Spree::Admin::ProductsController.class_eval do
|
||||
failure: lambda {
|
||||
render :new
|
||||
} } }
|
||||
#respond_override :clone => { :json => {:success => lambda { redirect_to bulk_index_admin_products_url+"?q[id_eq]=#{@new.id}" } } }
|
||||
|
||||
def product_distributions
|
||||
end
|
||||
|
||||
@@ -37,6 +37,17 @@ Spree::Api::ProductsController.class_eval do
|
||||
respond_with(@product, :status => 204)
|
||||
end
|
||||
|
||||
# POST /api/products/:product_id/clone
|
||||
#
|
||||
def clone
|
||||
authorize! :create, Spree::Product
|
||||
original_product = find_product(params[:product_id])
|
||||
authorize! :update, original_product
|
||||
|
||||
@product = original_product.duplicate
|
||||
|
||||
respond_with(@product, status: 201, default_template: :show)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
|
||||
@@ -32,8 +32,4 @@ Spree::CheckoutController.class_eval do
|
||||
@order.bill_address ||= preferred_bill_address || last_used_bill_address || Spree::Address.default
|
||||
@order.ship_address ||= preferred_ship_address || last_used_ship_address || nil
|
||||
end
|
||||
|
||||
def after_complete
|
||||
reset_order
|
||||
end
|
||||
end
|
||||
|
||||
69
app/controllers/spree/credit_cards_controller.rb
Normal file
69
app/controllers/spree/credit_cards_controller.rb
Normal file
@@ -0,0 +1,69 @@
|
||||
module Spree
|
||||
class CreditCardsController < BaseController
|
||||
def new_from_token
|
||||
# A new Customer is created for every credit card (same as via ActiveMerchant)
|
||||
# Note that default_source is the card represented by the token
|
||||
|
||||
@customer = create_customer(params[:token])
|
||||
@credit_card = build_card_from(stored_card_attributes)
|
||||
if @credit_card.save
|
||||
render json: @credit_card, serializer: ::Api::CreditCardSerializer, status: :ok
|
||||
else
|
||||
message = t(:card_could_not_be_saved)
|
||||
render json: { flash: { error: I18n.t(:spree_gateway_error_flash_for_checkout, error: message) } }, status: 400
|
||||
end
|
||||
rescue Stripe::CardError => e
|
||||
return render json: { flash: { error: I18n.t(:spree_gateway_error_flash_for_checkout, error: e.message) } }, status: 400
|
||||
end
|
||||
|
||||
def destroy
|
||||
@credit_card = Spree::CreditCard.find_by_id(params[:id])
|
||||
if @credit_card
|
||||
authorize! :destroy, @credit_card
|
||||
destroy_at_stripe
|
||||
end
|
||||
|
||||
# Using try because we may not have a card here
|
||||
if @credit_card.try(:destroy)
|
||||
flash[:success] = I18n.t(:card_has_been_removed, number: "x-#{@credit_card.last_digits}")
|
||||
else
|
||||
flash[:error] = I18n.t(:card_could_not_be_removed)
|
||||
end
|
||||
redirect_to account_path(anchor: 'cards')
|
||||
rescue Stripe::CardError
|
||||
flash[:error] = I18n.t(:card_could_not_be_removed)
|
||||
redirect_to account_path(anchor: 'cards')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Currently can only destroy the whole customer object
|
||||
def destroy_at_stripe
|
||||
stripe_customer = Stripe::Customer.retrieve(@credit_card.gateway_customer_profile_id)
|
||||
stripe_customer.delete if stripe_customer
|
||||
end
|
||||
|
||||
def create_customer(token)
|
||||
Stripe::Customer.create(email: spree_current_user.email, source: token)
|
||||
end
|
||||
|
||||
def stored_card_attributes
|
||||
return {} unless @customer.try(:default_source)
|
||||
{
|
||||
month: params[:exp_month],
|
||||
year: params[:exp_year],
|
||||
last_digits: params[:last4],
|
||||
gateway_payment_profile_id: @customer.default_source,
|
||||
gateway_customer_profile_id: @customer.id,
|
||||
cc_type: params[:cc_type]
|
||||
}
|
||||
end
|
||||
|
||||
def build_card_from(attrs)
|
||||
card = Spree::CreditCard.new(attrs)
|
||||
# Can't mass assign user:
|
||||
card.user_id = spree_current_user.id
|
||||
card
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,21 +1,44 @@
|
||||
Spree::PaypalController.class_eval do
|
||||
include CheckoutHelper
|
||||
|
||||
after_filter :reset_order_when_complete, only: :confirm
|
||||
before_filter :enable_embedded_shopfront
|
||||
before_filter :destroy_orphaned_paypal_payments, only: :confirm
|
||||
after_filter :reset_order_when_complete, only: :confirm
|
||||
|
||||
def cancel
|
||||
flash[:notice] = t('flash.cancel', :scope => 'paypal')
|
||||
flash[:notice] = Spree.t('flash.cancel', :scope => 'paypal')
|
||||
redirect_to main_app.checkout_path
|
||||
end
|
||||
|
||||
# Clears the cached order. Required for #current_order to return a new order
|
||||
# to serve as cart. See https://github.com/spree/spree/blob/1-3-stable/core/lib/spree/core/controller_helpers/order.rb#L14
|
||||
# for details.
|
||||
def expire_current_order
|
||||
session[:order_id] = nil
|
||||
@current_order = nil
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def reset_order_when_complete
|
||||
if current_order.complete?
|
||||
flash[:success] = t(:order_processed_successfully)
|
||||
reset_order
|
||||
flash[:notice] = t(:order_processed_successfully)
|
||||
|
||||
ResetOrderService.new(self, current_order).call
|
||||
session[:access_token] = current_order.token
|
||||
end
|
||||
end
|
||||
|
||||
# See #1074 and #1837 for more detail on why we need this
|
||||
# An 'orphaned' Spree::Payment is created for every call to CheckoutController#update
|
||||
# for orders that are processed using a Spree::Gateway::PayPalExpress payment method
|
||||
# These payments are 'orphaned' because they are never used by the spree_paypal_express gem
|
||||
# which creates a brand new Spree::Payment from scratch in PayPalController#confirm
|
||||
# However, the 'orphaned' payments are useful when applying a transaction fee, because the fees
|
||||
# need to be calculated before the order details are sent to PayPal for confirmation
|
||||
# This is our best hook for removing the orphaned payments at an appropriate time. ie. after
|
||||
# the payment details have been confirmed, but before any payments have been processed
|
||||
def destroy_orphaned_paypal_payments
|
||||
return unless payment_method.is_a?(Spree::Gateway::PayPalExpress)
|
||||
orphaned_payments = current_order.payments.where(payment_method_id: payment_method.id, source_id: nil)
|
||||
orphaned_payments.each(&:destroy)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,4 +2,14 @@ Spree::UsersController.class_eval do
|
||||
layout 'darkswarm'
|
||||
|
||||
before_filter :enable_embedded_shopfront
|
||||
|
||||
# Override of spree_auth_devise default
|
||||
# Ignores invoice orders, only order where state: 'complete'
|
||||
def show
|
||||
@orders = @user.orders.where(state: 'complete').order('completed_at desc')
|
||||
|
||||
return unless Spree::Config.accounts_distributor_id
|
||||
|
||||
@orders = @orders.where('distributor_id != ?', Spree::Config.accounts_distributor_id)
|
||||
end
|
||||
end
|
||||
|
||||
20
app/controllers/stripe/callbacks_controller.rb
Normal file
20
app/controllers/stripe/callbacks_controller.rb
Normal file
@@ -0,0 +1,20 @@
|
||||
require 'stripe/account_connector'
|
||||
|
||||
module Stripe
|
||||
class CallbacksController < BaseController
|
||||
def index
|
||||
connector = Stripe::AccountConnector.new(spree_current_user, params)
|
||||
|
||||
if connector.create_account
|
||||
flash[:success] = t('admin.controllers.enterprises.stripe_connect_success')
|
||||
elsif connector.connection_cancelled_by_user?
|
||||
flash[:notice] = t('admin.controllers.enterprises.stripe_connect_cancelled')
|
||||
else
|
||||
flash[:error] = t('admin.controllers.enterprises.stripe_connect_fail')
|
||||
end
|
||||
redirect_to main_app.edit_admin_enterprise_path(connector.enterprise, anchor: 'payment_methods')
|
||||
rescue Stripe::StripeError => e
|
||||
render text: e.message, status: 500
|
||||
end
|
||||
end
|
||||
end
|
||||
38
app/controllers/stripe/webhooks_controller.rb
Normal file
38
app/controllers/stripe/webhooks_controller.rb
Normal file
@@ -0,0 +1,38 @@
|
||||
require 'stripe/webhook_handler'
|
||||
|
||||
module Stripe
|
||||
class WebhooksController < BaseController
|
||||
protect_from_forgery except: :create
|
||||
before_filter :verify_webhook
|
||||
|
||||
# POST /stripe/webhook
|
||||
def create
|
||||
handler = WebhookHandler.new(@event)
|
||||
result = handler.handle
|
||||
|
||||
render nothing: true, status: status_mappings[result] || 200
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def verify_webhook
|
||||
payload = request.raw_post
|
||||
signature = request.headers["HTTP_STRIPE_SIGNATURE"]
|
||||
@event = Webhook.construct_event(payload, signature, Stripe.endpoint_secret)
|
||||
rescue JSON::ParserError
|
||||
render nothing: true, status: 400
|
||||
rescue Stripe::SignatureVerificationError
|
||||
render nothing: true, status: 401
|
||||
end
|
||||
|
||||
# Stripe interprets a 4xx or 3xx response as a failure to receive the webhook,
|
||||
# and will stop sending events if too many of either of these are returned.
|
||||
def status_mappings
|
||||
{
|
||||
success: 200, # The event was handled successfully
|
||||
unknown: 202, # The event was of an unknown type
|
||||
ignored: 204 # No action was taken in response to the event
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -20,4 +20,10 @@ module ApplicationHelper
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def body_classes
|
||||
classes = []
|
||||
classes << "off-canvas" unless @hide_menu
|
||||
classes << @shopfront_layout
|
||||
end
|
||||
end
|
||||
|
||||
@@ -104,20 +104,6 @@ module CheckoutHelper
|
||||
render "shared/validated_select", name: name, path: path, options: options, attributes: attributes
|
||||
end
|
||||
|
||||
def reset_order
|
||||
distributor = current_order.distributor
|
||||
token = current_order.token
|
||||
|
||||
session[:order_id] = nil
|
||||
@current_order = nil
|
||||
current_order(true)
|
||||
|
||||
current_order.set_distributor!(distributor)
|
||||
current_order.tokenized_permission.token = token
|
||||
current_order.tokenized_permission.save!
|
||||
session[:access_token] = token
|
||||
end
|
||||
|
||||
def payment_method_price(method, order)
|
||||
price = method.compute_amount(order)
|
||||
if price == 0
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
require 'open_food_network/available_payment_method_filter'
|
||||
|
||||
module EnterprisesHelper
|
||||
def current_distributor
|
||||
@current_distributor ||= current_order(false).andand.distributor
|
||||
@@ -22,6 +24,9 @@ module EnterprisesHelper
|
||||
return [] unless current_distributor.present?
|
||||
payment_methods = current_distributor.payment_methods.available(:front_end).all
|
||||
|
||||
filter = OpenFoodNetwork::AvailablePaymentMethodFilter.new
|
||||
filter.filter!(payment_methods)
|
||||
|
||||
applicator = OpenFoodNetwork::TagRuleApplicator.new(current_distributor, "FilterPaymentMethods", current_customer.andand.tag_list)
|
||||
applicator.filter!(payment_methods)
|
||||
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
module I18nHelper
|
||||
private
|
||||
|
||||
def set_locale
|
||||
I18n.locale = params[:locale] || I18n.default_locale
|
||||
# Save a given locale
|
||||
if params[:locale] && Rails.application.config.i18n.available_locales.include?(params[:locale])
|
||||
spree_current_user.update_attributes!(locale: params[:locale]) if spree_current_user
|
||||
cookies[:locale] = params[:locale]
|
||||
end
|
||||
|
||||
# After logging in, check if the user chose a locale before
|
||||
if spree_current_user && spree_current_user.locale.nil? && cookies[:locale]
|
||||
spree_current_user.update_attributes!(locale: params[:locale])
|
||||
end
|
||||
|
||||
I18n.locale = spree_current_user.andand.locale || cookies[:locale] || I18n.default_locale
|
||||
end
|
||||
end
|
||||
|
||||
@@ -64,9 +64,21 @@ module InjectionHelper
|
||||
render partial: "json/injection_ams", locals: {name: 'enterpriseAttributes', json: "#{@enterprise_attributes.to_json}"}
|
||||
end
|
||||
|
||||
def inject_orders_by_distributor
|
||||
data_array = spree_current_user.orders_by_distributor
|
||||
inject_json_ams "orders_by_distributor", data_array, Api::OrdersByDistributorSerializer
|
||||
def inject_orders
|
||||
inject_json_ams "orders", @orders.all, Api::OrderSerializer
|
||||
end
|
||||
|
||||
def inject_shops
|
||||
shops = Enterprise.where(id: @orders.pluck(:distributor_id).uniq)
|
||||
inject_json_ams "shops", shops.all, Api::ShopForOrdersSerializer
|
||||
end
|
||||
|
||||
def inject_saved_credit_cards
|
||||
if spree_current_user
|
||||
data = spree_current_user.credit_cards.with_payment_profile.all
|
||||
end
|
||||
|
||||
inject_json_ams "savedCreditCards", data, Api::CreditCardSerializer
|
||||
end
|
||||
|
||||
def inject_json(name, partial, opts = {})
|
||||
@@ -89,5 +101,4 @@ module InjectionHelper
|
||||
@enterprise_injection_data ||= OpenFoodNetwork::EnterpriseInjectionData.new
|
||||
{data: @enterprise_injection_data}
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -22,7 +22,6 @@ module Spree
|
||||
|
||||
link_to_with_icon('icon-trash', name, '#', html_options) + f.hidden_field(:_destroy)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -71,7 +71,7 @@ class BillablePeriod < ActiveRecord::Base
|
||||
source: self,
|
||||
originator: nil, # enterprise.package
|
||||
mandatory: true,
|
||||
locked: false
|
||||
state: 'closed'
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -42,6 +42,7 @@ class Enterprise < ActiveRecord::Base
|
||||
has_many :billable_periods
|
||||
has_many :inventory_items
|
||||
has_many :tag_rules
|
||||
has_one :stripe_account, dependent: :destroy
|
||||
|
||||
delegate :latitude, :longitude, :city, :state_name, :to => :address
|
||||
|
||||
@@ -66,7 +67,6 @@ class Enterprise < ActiveRecord::Base
|
||||
supports_s3 :logo
|
||||
supports_s3 :promo_image
|
||||
|
||||
|
||||
validates :name, presence: true
|
||||
validate :name_is_unique
|
||||
validates :sells, presence: true, inclusion: {in: SELLS}
|
||||
@@ -78,7 +78,6 @@ class Enterprise < ActiveRecord::Base
|
||||
validate :enforce_ownership_limit, if: lambda { owner_id_changed? && !owner_id.nil? }
|
||||
validates_length_of :description, :maximum => 255
|
||||
|
||||
|
||||
before_save :confirmation_check, if: lambda { email_changed? }
|
||||
|
||||
before_validation :initialize_permalink, if: lambda { permalink.nil? }
|
||||
@@ -95,7 +94,6 @@ class Enterprise < ActiveRecord::Base
|
||||
|
||||
after_rollback :restore_permalink
|
||||
|
||||
|
||||
scope :by_name, order('name')
|
||||
scope :visible, where(visible: true)
|
||||
scope :confirmed, where('confirmed_at IS NOT NULL')
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
class EnterpriseFee < ActiveRecord::Base
|
||||
include Spree::Core::CalculatedAdjustments
|
||||
|
||||
belongs_to :enterprise
|
||||
belongs_to :tax_category, class_name: 'Spree::TaxCategory', foreign_key: 'tax_category_id'
|
||||
|
||||
@@ -14,9 +16,6 @@ class EnterpriseFee < ActiveRecord::Base
|
||||
# coordinator_fees and exchange_fees
|
||||
|
||||
|
||||
calculated_adjustments
|
||||
|
||||
|
||||
attr_accessible :enterprise_id, :fee_type, :name, :tax_category_id, :calculator_type, :inherits_tax_category
|
||||
|
||||
FEE_TYPES = %w(packing transport admin sales fundraising)
|
||||
@@ -54,19 +53,6 @@ class EnterpriseFee < ActiveRecord::Base
|
||||
order.adjustments.where(originator_type: 'EnterpriseFee').destroy_all
|
||||
end
|
||||
|
||||
# Create an adjustment that starts as locked. Preferable to making an adjustment and locking it since
|
||||
# the unlocked adjustment tends to get hit by callbacks before we have a chance to lock it.
|
||||
def create_locked_adjustment(label, target, calculable, mandatory=false)
|
||||
amount = compute_amount(calculable)
|
||||
return if amount == 0 && !mandatory
|
||||
target.adjustments.create({ :amount => amount,
|
||||
:source => calculable,
|
||||
:originator => self,
|
||||
:label => label,
|
||||
:mandatory => mandatory,
|
||||
:locked => true}, :without_protection => true)
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ class ProductDistribution < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def create_adjustment_for(line_item)
|
||||
a = enterprise_fee.create_locked_adjustment(adjustment_label_for(line_item), line_item.order, line_item, true)
|
||||
a = enterprise_fee.create_adjustment(adjustment_label_for(line_item), line_item.order, line_item, true)
|
||||
AdjustmentMetadata.create! adjustment: a, enterprise: enterprise_fee.enterprise, fee_name: enterprise_fee.name, fee_type: enterprise_fee.fee_type, enterprise_role: 'distributor'
|
||||
end
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
class AbilityDecorator
|
||||
include CanCan::Ability
|
||||
|
||||
# All abilites are allocated from this initialiser, currently in 5 chunks.
|
||||
# All abilites are allocated from this initialiser.
|
||||
# Spree also defines other abilities.
|
||||
def initialize(user)
|
||||
add_shopping_abilities user
|
||||
@@ -56,9 +56,14 @@ class AbilityDecorator
|
||||
user == item.order.user &&
|
||||
item.order.changes_allowed?
|
||||
end
|
||||
|
||||
can [:cancel], Spree::Order do |order|
|
||||
order.user == user
|
||||
end
|
||||
|
||||
can [:destroy], Spree::CreditCard do |credit_card|
|
||||
credit_card.user == user
|
||||
end
|
||||
end
|
||||
|
||||
# New users can create an enterprise, and gain other permissions from doing this.
|
||||
@@ -118,12 +123,16 @@ class AbilityDecorator
|
||||
can [:admin, :bulk_update], ColumnPreference do |column_preference|
|
||||
column_preference.user == user
|
||||
end
|
||||
|
||||
can [:admin, :connect, :status, :destroy], StripeAccount do |stripe_account|
|
||||
user.enterprises.include? stripe_account.enterprise
|
||||
end
|
||||
end
|
||||
|
||||
def add_product_management_abilities(user)
|
||||
# Enterprise User can only access products that they are a supplier for
|
||||
can [:create], Spree::Product
|
||||
can [:admin, :read, :update, :product_distributions, :bulk_edit, :bulk_update, :clone, :delete, :destroy], Spree::Product do |product|
|
||||
can [:admin, :read, :update, :product_distributions, :seo, :group_buy_options, :bulk_edit, :bulk_update, :clone, :delete, :destroy], Spree::Product do |product|
|
||||
OpenFoodNetwork::Permissions.new(user).managed_product_enterprises.include? product.supplier
|
||||
end
|
||||
|
||||
@@ -193,6 +202,7 @@ class AbilityDecorator
|
||||
end
|
||||
can [:admin, :bulk_management, :managed], Spree::Order if user.admin? || user.enterprises.any?(&:is_distributor)
|
||||
can [:admin , :for_line_items], Enterprise
|
||||
can [:admin, :index, :create, :update, :destroy], :line_item
|
||||
can [:admin, :index, :create], Spree::LineItem
|
||||
can [:destroy, :update], Spree::LineItem do |item|
|
||||
order = item.order
|
||||
|
||||
@@ -39,4 +39,7 @@ Spree::AppConfiguration.class_eval do
|
||||
# Invoices & Receipts
|
||||
preference :invoice_style2?, :boolean, default: false
|
||||
preference :enable_receipt_printing?, :boolean, default: false
|
||||
|
||||
# Stripe Connect
|
||||
preference :stripe_connect_enabled, :boolean, default: false
|
||||
end
|
||||
|
||||
28
app/models/spree/credit_card_decorator.rb
Normal file
28
app/models/spree/credit_card_decorator.rb
Normal file
@@ -0,0 +1,28 @@
|
||||
Spree::CreditCard.class_eval do
|
||||
# Allows user to submit these attributes with checkout request
|
||||
# Required to be able to correctly store details for token-based charges
|
||||
# Obviously can be removed once we are using strong params
|
||||
attr_accessible :cc_type, :last_digits
|
||||
|
||||
# For holding customer preference in memory
|
||||
attr_accessible :save_requested_by_customer
|
||||
attr_writer :save_requested_by_customer
|
||||
|
||||
# Should be able to remove once we reach Spree v2.2.0
|
||||
# https://github.com/spree/spree/commit/411010f3975c919ab298cb63962ee492455b415c
|
||||
belongs_to :payment_method
|
||||
|
||||
belongs_to :user
|
||||
|
||||
# Allows us to use a gateway_payment_profile_id to store Stripe Tokens
|
||||
# Should be able to remove once we reach Spree v2.2.0
|
||||
# Commit: https://github.com/spree/spree/commit/5a4d690ebc64b264bf12904a70187e7a8735ef3f
|
||||
# See also: https://github.com/spree/spree_gateway/issues/111
|
||||
def has_payment_profile? # rubocop:disable Style/PredicateName
|
||||
gateway_customer_profile_id.present? || gateway_payment_profile_id.present?
|
||||
end
|
||||
|
||||
def save_requested_by_customer?
|
||||
!!@save_requested_by_customer
|
||||
end
|
||||
end
|
||||
106
app/models/spree/gateway/stripe_connect.rb
Normal file
106
app/models/spree/gateway/stripe_connect.rb
Normal file
@@ -0,0 +1,106 @@
|
||||
require 'stripe/profile_storer'
|
||||
|
||||
module Spree
|
||||
class Gateway
|
||||
class StripeConnect < Gateway
|
||||
preference :enterprise_id, :integer
|
||||
|
||||
validate :ensure_enterprise_selected
|
||||
|
||||
attr_accessible :preferred_enterprise_id
|
||||
|
||||
CARD_TYPE_MAPPING = {
|
||||
'American Express' => 'american_express',
|
||||
'Diners Club' => 'diners_club',
|
||||
'Visa' => 'visa'
|
||||
}.freeze
|
||||
|
||||
def method_type
|
||||
'stripe'
|
||||
end
|
||||
|
||||
def provider_class
|
||||
ActiveMerchant::Billing::StripeGateway
|
||||
end
|
||||
|
||||
def payment_profiles_supported?
|
||||
true
|
||||
end
|
||||
|
||||
def stripe_account_id
|
||||
StripeAccount.find_by_enterprise_id(preferred_enterprise_id).andand.stripe_user_id
|
||||
end
|
||||
|
||||
def purchase(money, creditcard, gateway_options)
|
||||
provider.purchase(*options_for_purchase_or_auth(money, creditcard, gateway_options))
|
||||
rescue Stripe::StripeError => e
|
||||
# This will be an error caused by generating a stripe token
|
||||
failed_activemerchant_billing_response(e.message)
|
||||
end
|
||||
|
||||
def void(response_code, _creditcard, gateway_options)
|
||||
gateway_options[:stripe_account] = stripe_account_id
|
||||
provider.void(response_code, gateway_options)
|
||||
end
|
||||
|
||||
def create_profile(payment)
|
||||
return unless payment.source.gateway_customer_profile_id.nil?
|
||||
|
||||
profile_storer = Stripe::ProfileStorer.new(payment, provider)
|
||||
profile_storer.create_customer_from_token
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# In this gateway, what we call 'secret_key' is the 'login'
|
||||
def options
|
||||
options = super
|
||||
options.merge(:login => Stripe.api_key)
|
||||
end
|
||||
|
||||
def options_for_purchase_or_auth(money, creditcard, gateway_options)
|
||||
options = {}
|
||||
options[:description] = "Spree Order ID: #{gateway_options[:order_id]}"
|
||||
options[:currency] = gateway_options[:currency]
|
||||
options[:stripe_account] = stripe_account_id
|
||||
|
||||
creditcard = token_from_card_profile_ids(creditcard)
|
||||
|
||||
[money, creditcard, options]
|
||||
end
|
||||
|
||||
def update_source!(source)
|
||||
source.cc_type = CARD_TYPE_MAPPING[source.cc_type] if CARD_TYPE_MAPPING.include?(source.cc_type)
|
||||
source
|
||||
end
|
||||
|
||||
def token_from_card_profile_ids(creditcard)
|
||||
token_or_card_id = creditcard.gateway_payment_profile_id
|
||||
customer = creditcard.gateway_customer_profile_id
|
||||
|
||||
return nil if token_or_card_id.blank?
|
||||
|
||||
# Assume the gateway_payment_profile_id is a token generated by StripeJS
|
||||
return token_or_card_id if customer.blank?
|
||||
|
||||
# Assume the gateway_payment_profile_id is a Stripe card_id
|
||||
# So generate a new token, using the customer_id and card_id
|
||||
tokenize_instance_customer_card(customer, token_or_card_id)
|
||||
end
|
||||
|
||||
def tokenize_instance_customer_card(customer, card)
|
||||
token = Stripe::Token.create({card: card, customer: customer}, stripe_account: stripe_account_id)
|
||||
token.id
|
||||
end
|
||||
|
||||
def failed_activemerchant_billing_response(error_message)
|
||||
ActiveMerchant::Billing::Response.new(false, error_message)
|
||||
end
|
||||
|
||||
def ensure_enterprise_selected
|
||||
return if preferred_enterprise_id.andand > 0
|
||||
errors.add(:stripe_account_owner, I18n.t(:error_required))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -60,7 +60,7 @@ Spree::LineItem.class_eval do
|
||||
end
|
||||
|
||||
def price_with_adjustments
|
||||
# EnterpriseFee#create_locked_adjustment applies adjustments on line items to their parent order,
|
||||
# EnterpriseFee#create_adjustment applies adjustments on line items to their parent order,
|
||||
# so line_item.adjustments returns an empty array
|
||||
return 0 if quantity == 0
|
||||
(price + order.adjustments.where(source_id: id).sum(&:amount) / quantity).round(2)
|
||||
|
||||
@@ -37,7 +37,8 @@ Spree::Order.class_eval do
|
||||
end
|
||||
order.payment_required?
|
||||
}
|
||||
go_to_state :confirm, :if => lambda { |order| order.confirmation_required? }
|
||||
# NOTE: :confirm step was removed because we were not actually using it
|
||||
# go_to_state :confirm, :if => lambda { |order| order.confirmation_required? }
|
||||
go_to_state :complete
|
||||
remove_transition :from => :delivery, :to => :confirm
|
||||
end
|
||||
@@ -181,6 +182,10 @@ Spree::Order.class_eval do
|
||||
end
|
||||
|
||||
def update_distribution_charge!
|
||||
# `with_lock` acquires an exclusive row lock on order so no other
|
||||
# requests can update it until the transaction is commited.
|
||||
# See https://github.com/rails/rails/blob/3-2-stable/activerecord/lib/active_record/locking/pessimistic.rb#L69
|
||||
# and https://www.postgresql.org/docs/current/static/sql-select.html#SQL-FOR-UPDATE-SHARE
|
||||
with_lock do
|
||||
EnterpriseFee.clear_all_adjustments_on_order self
|
||||
|
||||
@@ -289,6 +294,24 @@ Spree::Order.class_eval do
|
||||
complete? && distributor.andand.allow_order_changes? && order_cycle.andand.open?
|
||||
end
|
||||
|
||||
# Override of existing Spree method. Can remove when we reach 2-0-stable
|
||||
# See commit: https://github.com/spree/spree/commit/5fca58f658273451193d5711081d018c317814ed
|
||||
# Allows GatewayError to show useful error messages in checkout
|
||||
def process_payments!
|
||||
pending_payments.each do |payment|
|
||||
break if payment_total >= total
|
||||
|
||||
payment.process!
|
||||
|
||||
if payment.completed?
|
||||
self.payment_total += payment.amount
|
||||
end
|
||||
end
|
||||
rescue Spree::Core::GatewayError => e # This section changed
|
||||
result = !!Spree::Config[:allow_checkout_on_gateway_error]
|
||||
errors.add(:base, e.message) and return result
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def shipping_address_from_distributor
|
||||
@@ -344,9 +367,23 @@ Spree::Order.class_eval do
|
||||
end
|
||||
|
||||
def update_adjustment!(adjustment)
|
||||
locked = adjustment.locked
|
||||
adjustment.locked = false
|
||||
state = adjustment.state
|
||||
adjustment.state = 'open'
|
||||
adjustment.update!(self)
|
||||
adjustment.locked = locked
|
||||
adjustment.state = state
|
||||
end
|
||||
|
||||
# object_params sets the payment amount to the order total, but it does this before
|
||||
# the shipping method is set. This results in the customer not being charged for their
|
||||
# order's shipping. To fix this, we refresh the payment amount here.
|
||||
def charge_shipping_and_payment_fees!
|
||||
update_totals
|
||||
return unless payments.any?
|
||||
payments.first.update_attribute :amount, total
|
||||
end
|
||||
end
|
||||
|
||||
Spree::Order.state_machine.after_transition to: :payment, do: :charge_shipping_and_payment_fees!
|
||||
Spree::Order.state_machine.event :restart_checkout do
|
||||
transition :to => :cart, unless: :completed?
|
||||
end
|
||||
|
||||
@@ -4,13 +4,13 @@ module Spree
|
||||
|
||||
after_save :ensure_correct_adjustment, :update_order
|
||||
|
||||
attr_accessible :source
|
||||
|
||||
def ensure_correct_adjustment
|
||||
# Don't charge for invalid payments.
|
||||
# PayPalExpress always creates a payment that is invalidated later.
|
||||
# Unknown: What about failed payments?
|
||||
if state == "invalid"
|
||||
adjustment.andand.destroy
|
||||
elsif adjustment
|
||||
revoke_adjustment_eligibility if ['failed', 'invalid'].include?(state)
|
||||
return if adjustment.try(:finalized?)
|
||||
|
||||
if adjustment
|
||||
adjustment.originator = payment_method
|
||||
adjustment.label = adjustment_label
|
||||
adjustment.save
|
||||
@@ -73,6 +73,15 @@ module Spree
|
||||
end
|
||||
end
|
||||
|
||||
# Import from future Spree v.2.3.0 d470b31798f37
|
||||
def build_source
|
||||
return if source_attributes.nil?
|
||||
return unless payment_method.andand.payment_source_class
|
||||
|
||||
self.source = payment_method.payment_source_class.new(source_attributes)
|
||||
source.payment_method_id = payment_method.id
|
||||
source.user_id = order.user_id if order
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -81,5 +90,25 @@ module Spree
|
||||
refund_amount.to_f
|
||||
end
|
||||
|
||||
def create_payment_profile
|
||||
return unless source.is_a?(CreditCard)
|
||||
return unless source.try(:save_requested_by_customer?)
|
||||
return unless source.number || source.gateway_payment_profile_id
|
||||
return unless source.gateway_customer_profile_id.nil?
|
||||
payment_method.create_profile(self)
|
||||
rescue ActiveMerchant::ConnectionError => e
|
||||
gateway_error e
|
||||
end
|
||||
|
||||
# Don't charge fees for invalid or failed payments.
|
||||
# This is called twice for failed payments, because the persistence of the 'failed'
|
||||
# state is acheived through some trickery using an after_rollback callback on the
|
||||
# payment model. See Spree::Payment#persist_invalid
|
||||
def revoke_adjustment_eligibility
|
||||
return unless adjustment.try(:reload)
|
||||
return if adjustment.finalized?
|
||||
adjustment.update_attribute(:eligible, false)
|
||||
adjustment.finalize!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
Spree::PaymentMethod.class_eval do
|
||||
include Spree::Core::CalculatedAdjustments
|
||||
|
||||
Spree::PaymentMethod::DISPLAY = [:both, :front_end, :back_end]
|
||||
|
||||
acts_as_taggable
|
||||
|
||||
has_and_belongs_to_many :distributors, join_table: 'distributors_payment_methods', :class_name => 'Enterprise', association_foreign_key: 'distributor_id'
|
||||
has_many :credit_cards, class_name: "Spree::CreditCard" # from Spree v.2.3.0 d470b31798f37
|
||||
|
||||
attr_accessible :distributor_ids, :tag_list
|
||||
|
||||
calculated_adjustments
|
||||
|
||||
after_initialize :init
|
||||
|
||||
validates_with DistributorsValidator
|
||||
@@ -39,7 +40,10 @@ Spree::PaymentMethod.class_eval do
|
||||
}
|
||||
|
||||
def init
|
||||
self.class.calculated_adjustments unless reflections.keys.include? :calculator
|
||||
unless reflections.keys.include? :calculator
|
||||
self.class.include Spree::Core::CalculatedAdjustments
|
||||
end
|
||||
|
||||
self.calculator ||= Spree::Calculator::FlatRate.new(preferred_amount: 0)
|
||||
end
|
||||
|
||||
@@ -55,6 +59,8 @@ Spree::PaymentMethod.class_eval do
|
||||
"MasterCard Internet Gateway Service (MIGS)"
|
||||
when "Spree::Gateway::Pin"
|
||||
"Pin Payments"
|
||||
when "Spree::Gateway::StripeConnect"
|
||||
"Stripe"
|
||||
when "Spree::Gateway::PayPalExpress"
|
||||
"PayPal Express"
|
||||
else
|
||||
|
||||
@@ -42,8 +42,8 @@ Spree::ShippingMethod.class_eval do
|
||||
]
|
||||
end
|
||||
|
||||
def available_to_order_with_distributor_check?(order, display_on=nil)
|
||||
available_to_order_without_distributor_check?(order, display_on) &&
|
||||
def available_to_order_with_distributor_check?(order)
|
||||
available_to_order_without_distributor_check?(order) &&
|
||||
self.distributors.include?(order.distributor)
|
||||
end
|
||||
alias_method_chain :available_to_order?, :distributor_check
|
||||
|
||||
@@ -11,13 +11,14 @@ Spree.user_class.class_eval do
|
||||
has_many :billable_periods, foreign_key: :owner_id, inverse_of: :owner
|
||||
has_one :cart
|
||||
has_many :customers
|
||||
has_many :credit_cards
|
||||
|
||||
accepts_nested_attributes_for :enterprise_roles, :allow_destroy => true
|
||||
|
||||
accepts_nested_attributes_for :bill_address
|
||||
accepts_nested_attributes_for :ship_address
|
||||
|
||||
attr_accessible :enterprise_ids, :enterprise_roles_attributes, :enterprise_limit, :bill_address_attributes, :ship_address_attributes
|
||||
attr_accessible :enterprise_ids, :enterprise_roles_attributes, :enterprise_limit, :locale, :bill_address_attributes, :ship_address_attributes
|
||||
after_create :send_signup_confirmation
|
||||
|
||||
validate :limit_owned_enterprises
|
||||
@@ -53,32 +54,6 @@ Spree.user_class.class_eval do
|
||||
owned_enterprises(:reload).size < enterprise_limit
|
||||
end
|
||||
|
||||
# Returns Enterprise IDs for distributors that the user has shopped at
|
||||
def enterprises_ordered_from
|
||||
enterprise_ids = orders.where(state: :complete).map(&:distributor_id).uniq
|
||||
# Exclude the accounts distributor
|
||||
if Spree::Config.accounts_distributor_id
|
||||
enterprise_ids = enterprise_ids.keep_if { |a| a != Spree::Config.accounts_distributor_id }
|
||||
end
|
||||
enterprise_ids
|
||||
end
|
||||
|
||||
# Returns orders and their associated payments for all distributors that have been ordered from
|
||||
def complete_orders_by_distributor
|
||||
Enterprise
|
||||
.includes(distributed_orders: { payments: :payment_method })
|
||||
.where(enterprises: { id: enterprises_ordered_from },
|
||||
spree_orders: { state: 'complete', user_id: id })
|
||||
.order('spree_orders.completed_at DESC')
|
||||
end
|
||||
|
||||
def orders_by_distributor
|
||||
# Remove uncompleted payments as these will not be reflected in order balance
|
||||
data_array = complete_orders_by_distributor.to_a
|
||||
remove_payments_in_checkout(data_array)
|
||||
data_array.sort! { |a, b| b.distributed_orders.length <=> a.distributed_orders.length }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def limit_owned_enterprises
|
||||
|
||||
21
app/models/stripe_account.rb
Normal file
21
app/models/stripe_account.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
class StripeAccount < ActiveRecord::Base
|
||||
belongs_to :enterprise
|
||||
validates :stripe_user_id, :stripe_publishable_key, presence: true
|
||||
validates :enterprise_id, uniqueness: true
|
||||
|
||||
def deauthorize_and_destroy
|
||||
accounts = StripeAccount.where(stripe_user_id: stripe_user_id)
|
||||
|
||||
# Only deauthorize the user if it is not linked to multiple accounts
|
||||
return destroy if accounts.count > 1
|
||||
|
||||
destroy && Stripe::OAuth.deauthorize(stripe_user_id: stripe_user_id)
|
||||
rescue Stripe::OAuth::OAuthError
|
||||
Bugsnag.notify(
|
||||
RuntimeError.new("StripeDeauthorizeFailure"),
|
||||
stripe_account: stripe_user_id,
|
||||
enterprise_id: enterprise_id
|
||||
)
|
||||
true
|
||||
end
|
||||
end
|
||||
@@ -1,5 +1,5 @@
|
||||
class TagRule::DiscountOrder < TagRule
|
||||
calculated_adjustments
|
||||
include Spree::Core::CalculatedAdjustments
|
||||
|
||||
private
|
||||
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
Deface::Override.new(:virtual_path => "spree/admin/products/_form",
|
||||
:insert_top => "[data-hook='admin_product_form_right']",
|
||||
:partial => "spree/admin/products/group_buy_form",
|
||||
:name => "add_group_buy_to_admin_product_edit",
|
||||
:original => '0c0e8d714989e48ee246a8253fb2b362f108621a')
|
||||
@@ -1,6 +1,7 @@
|
||||
/ replace "div[data-hook='admin_payment_method_form_fields']"
|
||||
|
||||
= admin_inject_payment_method
|
||||
= admin_inject_json_ams_array "admin.paymentMethods", "shops", @hubs, Api::Admin::BasicEnterpriseSerializer
|
||||
%div.alpha.eleven.columns{ "ng-app" => "admin.paymentMethods", "ng-controller" => "paymentMethodCtrl" }
|
||||
.row
|
||||
.alpha.three.columns
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
/ insert_bottom "[data-hook='admin_product_form_additional_fields']"
|
||||
|
||||
= f.field_container :notes do
|
||||
= f.label :notes, t(:notes)
|
||||
= f.text_area :notes, { :class => 'fullwidth', rows: 5 }
|
||||
= f.error_message_on :notes
|
||||
@@ -1,3 +1,3 @@
|
||||
/ insert_top "[data-hook='admin_product_form_right']"
|
||||
/ insert_after "div[class='variant_units_form']"
|
||||
|
||||
= render 'spree/admin/products/primary_taxon_form', f: f
|
||||
@@ -1,7 +1,6 @@
|
||||
/ insert_top "[data-hook='admin_product_form_right']"
|
||||
|
||||
/ insert_before "code[erb-loud]:contains('f.field_container :price')"
|
||||
= f.field_container :supplier do
|
||||
= f.label :supplier
|
||||
= f.label :supplier, t(:spree_admin_supplier)
|
||||
%br
|
||||
= f.collection_select(:supplier_id, @producers, :id, :name, {:include_blank => true}, {:class => "select2"})
|
||||
= f.error_message_on :supplier
|
||||
= f.error_message_on :supplier
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user