Compare commits

...

66 Commits

Author SHA1 Message Date
Maikel Linke
f9b76fadbd Update all locales with the latest Transifex translations 2025-10-31 16:05:11 +11:00
Maikel
64f44b8a9b Merge pull request #13571 from pacodelaluna/update_sum_calcultation
Update sum calculation in order_cycle_customer_totals spec
2025-10-31 16:03:11 +11:00
Maikel Linke
5dfb7645cb Avoid enabling rubocop rule listed in todo file 2025-10-31 15:39:58 +11:00
Maikel Linke
74927dd03d Regenerate Rubocop todo file 2025-10-31 15:30:17 +11:00
François Turbelin
71dd398131 Apply cosmetics and fix specs 2025-10-31 15:20:44 +11:00
François Turbelin
245f0caedb Adjust sum for remaining reports 2025-10-31 15:20:44 +11:00
François Turbelin
18bc95c6a3 Update sum calculation in order_cycle_customer_totals spec 2025-10-31 15:20:44 +11:00
Maikel
0ecfc23c67 Merge pull request #13644 from deivid-rodriguez/more-rspec-fixes
Fix Rspec warnings and the broken Stripe intent API specs that fixing them revealed
2025-10-29 15:04:22 +11:00
Maikel
ff16b575c4 Merge pull request #13653 from deivid-rodriguez/bump-rubocop
Bump rubocop to 1.86.6
2025-10-29 12:00:31 +11:00
Maikel
faa826a76e Merge pull request #13647 from deivid-rodriguez/remove-obsoleted-gem
Remove obsolete gem
2025-10-29 11:44:59 +11:00
Maikel
1e02084f95 Merge pull request #13646 from deivid-rodriguez/bump-ruby
Bump Ruby from 3.1.4 to 3.1.7
2025-10-29 11:43:04 +11:00
Maikel
44cca40db6 Merge pull request #13643 from deivid-rodriguez/fix-prettier-issues
Fix all existing prettier issues
2025-10-29 11:36:54 +11:00
David Cook
52174b1e06 Merge pull request #13645 from deivid-rodriguez/review-dog-write-checks
Fix reviewdog workflow failing to create checks
2025-10-29 09:17:26 +11:00
Filipe
cdf0777d8e Merge pull request #13641 from openfoodfoundation/dependabot/bundler/knapsack_pro-8.4.0
Bump knapsack_pro from 8.1.2 to 8.4.0
2025-10-28 12:31:44 +00:00
David Cook
9cb7c46b44 Merge pull request #13631 from rioug/13117-upgrade-node
Upgrade to node version 24
2025-10-28 10:52:34 +11:00
David Rodríguez
4c6d894bc0 Bump RuboCop to 1.86.6
There were a few changes needed:

* Plugins are now specified through `plugin:` config keyword.
* All plugin gems need to be specified explicitly in Gemfile since they
  are no longer dependencies of plugins already specified explicitly.
* All plugin gems need to be updated in other to use the new APIs.
* One cop was renamed.
* New offenses safe to correct were corrected directly with `bundle exec
  rubocop -a`.
* New offenses unsafe to correct were added to the TODO configuration
  with `bundle exec rubocop --auto-gen-config --auto-gen-only-exclude
  --exclude-limit 1400 --no-auto-gen-timestamp`.
2025-10-27 11:30:33 +01:00
David Rodríguez
27975252f5 Rename pm_card to payment_method_id
And also remove a couple of now unused `let`'s that were already using
this terminology.

Co-authored-by: David Cook <david@openfoodnetwork.org.au>
2025-10-27 10:52:36 +01:00
David Rodríguez
9fc82776ec Move Stripe test payment method handling to a single place
And comment a bit on them.

Co-authored-by: David Cook <david@openfoodnetwork.org.au>
2025-10-27 10:45:45 +01:00
David Rodríguez
2c8bf82426 Migrate some spec to not send raw card numbers to Stripe API
If I regenerate the VCR cassetes for
spec/lib/stripe/payment_intent_validator_spec.rb, I get a lot of errors
like this:

```
Stripe::CardError:

Sending credit card numbers directly to the Stripe API is generally
unsafe. We suggest you use test tokens that map to the test card you are
using, see https://stripe.com/docs/testing. To enable testing raw card
data APIs, see
https://support.stripe.com/questions/enabling-access-to-raw-card-data-apis.
```

It seems the sandbox environment associated to my developer API keys is
not allowed to send raw credit card data.

Instead of requesting Stripe support to enable that, or regenerate
cassettes with the API keys in Bitwarden, I figured we could migrate the
tests to not use raw credit card data.
2025-10-27 09:08:30 +01:00
David Rodríguez
121019411c Fix spec instantiating payment method with wrong source
Previous error is fixed, which allows the spec to proceed further, and
reveals that the current cassettes are missing some requests:

```
  1) Stripe::PaymentIntentValidator#call as a guest when payment intent is valid valid non-3D credit cards are correctly handled behaves like payments intents from Visa returns payment intent id and does not raise
     Failure/Error:
       payment_intent_response = Stripe::PaymentIntent.retrieve(
         payment_intent_id,
         stripe_account: stripe_account_id
       )

     VCR::Errors::UnhandledHTTPRequestError:

       ================================================================================
       An HTTP request has been made that VCR does not know how to handle:
         GET https://api.stripe.com/v1/payment_intents/pi_3P8hNGKuuB1fWySn0dvhu9lG

       VCR is currently using the following cassette:

       (...)
```
2025-10-27 09:08:29 +01:00
David Rodríguez
1a5eb5b39a Remove raise_error negative block to fix RSpec warnings
Currently RSpec warns these specs like this:

```
WARNING: Using `expect { }.not_to raise_error(SpecificErrorClass)` risks false positives, since literally any other error would cause the
expectation to pass, including those raised by Ruby (e.g. `NoMethodError`, `NameError` and `ArgumentError`), meaning the code you are intending
to test may not even get reached. Instead consider using `expect { }.not_to raise_error` or `expect { }.to raise_error(DifferentSpecificErrorClass)`.
This message can be suppressed by setting: `RSpec::Expectations.configuration.on_potential_false_positives = :nothing`.
Called from /path/to/spec/lib/stripe/payment_intent_validator_spec.rb:53:in `block (7 levels) in <main>'.
```

The warnings are super accurate in this particular case: the inner
assertion is not actually getting reached due to a previous unrelated
error.

Since there's an inner assertion already, I think it's best to
completely remove to `raise_error` negative block, since it just hides
errors and buys us nothing.

By removing it, the underlying error surfaces:

```
  1) Stripe::PaymentIntentValidator#call as a guest when payment intent is valid valid non-3D credit cards are correctly handled behaves like payments intents from Visa returns payment intent id and does not raise
     Failure/Error:
       create(:payment, amount: payment_intent.amount, payment_method:,
                        response_code: payment_intent.id, source: pm_card)

     NoMethodError:
       undefined method `has_query_constraints?' for Stripe::PaymentMethod:Class

               elsif (klass || self.klass).has_query_constraints? || options[:query_constraints]
                                          ^^^^^^^^^^^^^^^^^^^^^^^
     Shared Example Group: "payments intents" called from ./spec/lib/stripe/payment_intent_validator_spec.rb:75
     # ./spec/lib/stripe/payment_intent_validator_spec.rb:16:in `block (3 levels) in <main>'
     # ./spec/lib/stripe/payment_intent_validator_spec.rb:19:in `block (3 levels) in <main>'
     # ./spec/lib/stripe/payment_intent_validator_spec.rb:53:in `block (7 levels) in <main>'
     # ./spec/base_spec_helper.rb:208:in `block (2 levels) in <main>'
     # ./spec/base_spec_helper.rb:155:in `block (3 levels) in <main>'
     # ./spec/base_spec_helper.rb:155:in `block (2 levels) in <main>'
     # -e:1:in `<main>'
```
2025-10-27 09:08:29 +01:00
David Rodríguez
2bd536298b Showcase the problem with some specs
They're always passing because an error (different from `StripeError`),
is actually making them pass.
2025-10-27 09:08:29 +01:00
Ahmed Ejaz
7415503b63 Update all locales with the latest Transifex translations 2025-10-27 05:55:44 +05:00
Filipe
cc35d118eb Merge pull request #13627 from guidoDutra/10261/bad-table-format-in-edit-order-page
fix table format in edit order page
2025-10-24 13:16:49 +01:00
David Rodríguez
e09d78dfb2 Remove obsolete gem
Even without it, Rails seems to do this by default:

```console
$ RAILS_ENV=production SITE_URL=foo.bar SECRET_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx bin/rails db:drop
I, [2025-10-23T12:38:12.383244 #32647]  INFO -- : [dotenv] Loaded .env
I, [2025-10-23T12:38:12.383292 #32647]  INFO -- : [dotenv] Loaded .env
W, [2025-10-23T12:38:12.411675 #32647]  WARN -- [Bugsnag]: No valid API key has been set, notifications will not be sent
bin/rails aborted!
ActiveRecord::ProtectedEnvironmentError: You are attempting to run a destructive action against your 'production' database.
If you are sure you want to continue, run the same command with the environment variable:
DISABLE_DATABASE_ENVIRONMENT_CHECK=1

Tasks: TOP => db:drop => db:check_protected_environments
(See full trace by running task with --trace)
```

And the gem hasn't been updated in 10 years, so probably best to get rid
of it.
2025-10-23 12:41:37 +02:00
David Rodríguez
dad7cfc180 Bump Ruby from 3.1.4 to 3.1.7
Release announcmenets:

* https://www.ruby-lang.org/en/news/2024/04/23/ruby-3-1-5-released/
* https://www.ruby-lang.org/en/news/2024/05/29/ruby-3-1-6-released/
* https://www.ruby-lang.org/en/news/2025/03/26/ruby-3-1-7-released/
2025-10-23 10:34:21 +02:00
David Rodríguez
678497914f Fix reviewdog workflow failing to create checks 2025-10-22 19:59:10 +02:00
David Rodríguez
852e7fa81e Fix all existing prettier issues 2025-10-22 15:30:36 +02:00
dependabot[bot]
fb437fb34d Bump knapsack_pro from 8.1.2 to 8.4.0
Bumps [knapsack_pro](https://github.com/KnapsackPro/knapsack_pro-ruby) from 8.1.2 to 8.4.0.
- [Changelog](https://github.com/KnapsackPro/knapsack_pro-ruby/blob/main/CHANGELOG.md)
- [Commits](https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v8.1.2...v8.4.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-22 09:02:10 +00:00
Maikel
025f8b25b1 Merge pull request #13637 from deivid-rodriguez/fix-missing-stripe-js-error-in-edge-case
Fix JS error when Stripe connect is disabled but Stripe API keys are setup
2025-10-22 13:09:58 +11:00
Maikel
3017f61047 Merge pull request #13638 from deivid-rodriguez/refactor-specs
Remove only usage of `STRIPE_PUBLIC_TEST_API_KEY` env and refactor specs that were using it
2025-10-22 13:08:31 +11:00
Maikel
8cb3d06f7c Merge pull request #13635 from deivid-rodriguez/testing-stripe-wiki
Link to Stripe testing wiki page from the cassette regeneration script
2025-10-22 13:02:21 +11:00
Maikel
8f442e82ed Merge pull request #13634 from openfoodfoundation/dependabot/bundler/activerecord-import-2.2.0
Bump activerecord-import from 1.6.0 to 2.2.0
2025-10-22 13:00:43 +11:00
David Rodríguez
b28886dd38 Normalize casing 2025-10-21 17:34:40 +02:00
David Rodríguez
bd4f115185 Create account directly with the proper stripe_user_id 2025-10-21 17:34:40 +02:00
David Rodríguez
c43650034f Remove unnecessary test specific environment variable 2025-10-21 17:34:40 +02:00
David Rodríguez
94bc787283 Remove unused let 2025-10-21 17:34:40 +02:00
David Rodríguez
58851a8e67 Move client_id let to the only spec using it 2025-10-21 17:34:39 +02:00
David Rodríguez
c3e2382600 Move let! to the only spec using it 2025-10-21 17:34:39 +02:00
David Rodríguez
802878b4eb Fix JS error when Stripe connect is disabled but Stripe API keys are setup 2025-10-21 17:24:34 +02:00
Filipe
69d8fc3cad Merge pull request #13624 from chahmedejaz/bugfix/13556-fix-500-error-on-stripe-checkout
Error 500 checking out with Stripe, after navigating back to the Summary page
2025-10-21 14:34:53 +01:00
David Rodríguez
6a226e476d Link to Stripe testing wiki page from the cassette regeneration script
I think this is the more relevant wiki page for someone looking into
regenerating cassettes.

Also, no need to mention bitwarden explicitly, the wiki page already
explains everything.
2025-10-21 14:38:10 +02:00
dependabot[bot]
479d52a2bb Bump activerecord-import from 1.6.0 to 2.2.0
Bumps [activerecord-import](https://github.com/zdennis/activerecord-import) from 1.6.0 to 2.2.0.
- [Changelog](https://github.com/zdennis/activerecord-import/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zdennis/activerecord-import/compare/v1.6.0...v2.2.0)

---
updated-dependencies:
- dependency-name: activerecord-import
  dependency-version: 2.2.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-21 09:02:00 +00:00
Gaetan Craig-Riou
8afd6eb0ab Upgrade node to 24.10.0
This is the latest node 24 version which set to be the next lts.
2025-10-21 15:56:50 +11:00
Gaetan Craig-Riou
73688b9544 Merge pull request #13630 from openfoodfoundation/dependabot/bundler/webmock-3.25.1
Bump webmock from 3.23.1 to 3.25.1
2025-10-21 10:02:14 +11:00
dependabot[bot]
02ea3cb61c Bump webmock from 3.23.1 to 3.25.1
Bumps [webmock](https://github.com/bblimke/webmock) from 3.23.1 to 3.25.1.
- [Changelog](https://github.com/bblimke/webmock/blob/master/CHANGELOG.md)
- [Commits](https://github.com/bblimke/webmock/compare/v3.23.1...v3.25.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-20 09:26:20 +00:00
Maikel
c7d0594257 Merge pull request #13622 from deivid-rodriguez/no-reviewdog-master
Don't run reviewdog on pushes
2025-10-20 16:34:06 +11:00
Maikel
4eee7ad603 Merge pull request #13604 from deivid-rodriguez/silent-puma
Silence capybara starting puma during system specs
2025-10-20 16:26:18 +11:00
David Cook
23f7f2974a Merge pull request #13618 from deivid-rodriguez/remove-unnecessary-sleeps
Remove unnecessary explicit sleeps
2025-10-20 16:06:44 +11:00
Maikel
8105b919e0 Merge pull request #13600 from deivid-rodriguez/profile-enables-dev-caching
The PROFILE env variable should actually enable, not disable, caching
2025-10-20 16:03:20 +11:00
David Cook
53ef5148e9 Merge pull request #13617 from deivid-rodriguez/upgrade-cache-format-version
Upgrade cache format version
2025-10-20 15:41:52 +11:00
David Cook
93e6f9034c Merge pull request #13602 from deivid-rodriguez/bump-mini_magick
Update mini_magick to a version that plays nice with imagemagick v7
2025-10-20 15:26:20 +11:00
David Cook
125a92346c Merge pull request #13599 from deivid-rodriguez/fix-duplicate-key-warning
Fix duplicate keys warnings in some views
2025-10-20 15:21:40 +11:00
Gaetan Craig-Riou
31b8fe16cb Merge pull request #13623 from deivid-rodriguez/follow-up-to-old-rename
Follow up to old ofnEmptiesCart to ofnChangeHub rename
2025-10-20 10:53:47 +11:00
Gaetan Craig-Riou
cbffea8d30 Merge pull request #13616 from openfoodfoundation/dependabot/bundler/state_machines-activerecord-0.31.0
Bump state_machines-activerecord from 0.9.0 to 0.31.0
2025-10-20 09:50:30 +11:00
Guido Oliveira
be9da62d98 fix table format in edit order page 2025-10-19 07:58:40 -03:00
Ahmed Ejaz
9f6c149735 Add check for payment authorization state in StripeScaPaymentAuthorize and corresponding spec 2025-10-17 05:25:45 +05:00
David Rodríguez
50578647ee Follow up to old ofnEmptiesCart to ofnChangeHub rename
This happened back in 2015 through
9c9051498b, but two places were missed.

One was a code comment so did not affect anything (other than confused
code readers I guess?). The other one did create a regression but was
later fixed by 18d966f0de in 2021.
2025-10-16 12:56:17 +02:00
David Rodríguez
a28f05fddc Don't run reviewdog on pushes
As configured, it's meant to annotate PRs with linter errors (so you
don't have to skim through logs). So it does not make sense for pushes.

In fact, on pushes rubocop action is doing nothing, and prettier action
is failing with:

> reviewdog: this is not PullRequest build.
> sed: couldn't write 80 items to stdout: Broken pipe
2025-10-16 12:34:37 +02:00
David Rodríguez
d6c044fd5b Remove unnecessary explicit sleeps
Capybara helpers already wait for the content to show up (and we already
have a default of 10 seconds configured), so I don't think waiting more is
actually the problem in these specs.

But if we wanted to wait more, I think it's better to pass the `:wait`
option to capybara matchers, because that's a "maximum waiting value"
but we'll still proceed earlier if the content shows up.

Using the same idea, I changed the positive assertions to happen first,
because negative assertions do spend "max wait time" waiting, while
positive assertions only wait until the content shows up.
2025-10-15 13:09:52 +02:00
David Rodríguez
a75ea5b506 Upgrade cache format version
It's supposed to be faster and more compact, and the previous format
will become unsupported in Rails 7.2 as per Rails boot warnings:

> DEPRECATION WARNING: Support for `config.active_support.cache_format_version = 6.1` has been deprecated and will be removed in Rails 7.2.
>
> Check the Rails upgrade guide at https://guides.rubyonrails.org/upgrading_ruby_on_rails.html#new-activesupport-cache-serialization-format
> for more information on how to upgrade.
>    (called from <main> at /path/to/config/environment.rb:5)
2025-10-15 12:17:03 +02:00
dependabot[bot]
7f937fd4b1 Bump state_machines-activerecord from 0.9.0 to 0.31.0
Bumps [state_machines-activerecord](https://github.com/state-machines/state_machines-activerecord) from 0.9.0 to 0.31.0.
- [Release notes](https://github.com/state-machines/state_machines-activerecord/releases)
- [Changelog](https://github.com/state-machines/state_machines-activerecord/blob/master/CHANGELOG.md)
- [Commits](https://github.com/state-machines/state_machines-activerecord/compare/v0.9.0...state_machines-activerecord/v0.31.0)

---
updated-dependencies:
- dependency-name: state_machines-activerecord
  dependency-version: 0.31.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-15 09:02:41 +00:00
David Rodríguez
667ce5eda2 Silence capybara starting puma during system specs
##### Before

```
$ bin/rspec spec/system/admin/order_cycles/simple_spec.rb:460
Running via Spring preloader in process 79308
Run options: include {:locations=>{"./spec/system/admin/order_cycles/simple_spec.rb"=>[460]}}

As an administrator
    I want to manage simple order cycles
  as an enterprise user
    that is a manager of the coordinator
      when variants are hidden via inventory settings
Capybara starting Puma...
* Version 6.5.0, codename: Sky's Version
* Min threads: 0, max threads: 4
* Listening on http://127.0.0.1:51103
        shows a warning when going to 'outgoing products' tab

Finished in 3.95 seconds (files took 0.45949 seconds to load)
1 example, 0 failures
```

##### After

```
$ bin/rspec spec/system/admin/order_cycles/simple_spec.rb:460
Running via Spring preloader in process 79234
Run options: include {:locations=>{"./spec/system/admin/order_cycles/simple_spec.rb"=>[460]}}

As an administrator
    I want to manage simple order cycles
  as an enterprise user
    that is a manager of the coordinator
      when variants are hidden via inventory settings
        shows a warning when going to 'outgoing products' tab

Finished in 4.03 seconds (files took 0.49981 seconds to load)
1 example, 0 failures
```
2025-10-14 20:34:05 +02:00
David Rodríguez
c72f9477cd bundle update mini_magick
This is mainly to shush a lot of warnings when running the test suite,
like the following:

```
WARNING: The convert command is deprecated in IMv7, use "magick" instead of "convert" or "magick convert"
```
2025-10-14 08:17:12 +02:00
David Rodríguez
8787eed863 The PROFILE env variable should actually enable, not disable, caching
I think this may be a typo from 6d8ddd1edac17a431222c86482bceb83e8a7d32f?
2025-10-14 08:03:15 +02:00
David Rodríguez
e2b6199f26 Fix duplicate keys warnings in some views
We're passing the `id` key twice, and with different value, resulting in
warnings like:

> /path/to/app/views/producers/index.html.haml:27: warning: key :id is duplicated and overwritten on line 31

Use only the latest value passed to remove the warning.

##### Before

```
$ bundle exec rspec -e "displays in an iframe" -e "logging in with a redirect set"

(...)

Run options: include {:full_description=>/(?-mix:displays\ in\ an\ iframe)|(?-mix:logging\ in\ with\ a\ redirect\ set)/}
Capybara starting Puma...
* Version 6.5.0, codename: Sky's Version
* Min threads: 0, max threads: 4
* Listening on http://127.0.0.1:50292
/path/to/app/views/producers/index.html.haml:27: warning: key :id is duplicated and overwritten on line 31
./path/to/app/views/groups/show.html.haml:68: warning: key :id is duplicated and overwritten on line 72
Modal window with text `Unable to load map. Please check your browser settings and allow 3rd party cookies for this website.` has been opened, but you didn't wrap your code into (`accept_prompt` | `dismiss_prompt` | `accept_confirm` | `dismiss_confirm` | `accept_alert`), accepting by default
.

Finished in 4.54 seconds (files took 4.04 seconds to load)
2 examples, 0 failures
```

##### After

```
$ bundle exec rspec -e "displays in an iframe" -e "logging in with a redirect set"

(...)

Run options: include {:full_description=>/(?-mix:displays\ in\ an\ iframe)|(?-mix:logging\ in\ with\ a\ redirect\ set)/}
Capybara starting Puma...
* Version 6.5.0, codename: Sky's Version
* Min threads: 0, max threads: 4
* Listening on http://127.0.0.1:50256
.Modal window with text `Unable to load map. Please check your browser settings and allow 3rd party cookies for this website.` has been opened, but you didn't wrap your code into (`accept_prompt` | `dismiss_prompt` | `accept_confirm` | `dismiss_confirm` | `accept_alert`), accepting by default
.

Finished in 4.17 seconds (files took 4.1 seconds to load)
2 examples, 0 failures
```
2025-10-14 07:58:32 +02:00
275 changed files with 20553 additions and 38477 deletions

View File

@@ -20,7 +20,6 @@ STRIPE_INSTANCE_SECRET_KEY="bogus_key"
STRIPE_CUSTOMER="bogus_customer"
STRIPE_ACCOUNT="bogus_account"
STRIPE_CLIENT_ID="bogus_client_id"
STRIPE_PUBLIC_TEST_API_KEY="bogus_stripe_publishable_key"
SITE_URL="test.host"

View File

@@ -1,7 +1,8 @@
name: Linters
on: [push, pull_request]
on: [pull_request]
permissions:
contents: read # to fetch code (actions/checkout)
checks: write # to post check annotations
jobs:
lint:
name: prettier and rubocop

View File

@@ -1 +1 @@
17.9.1
24.10.0

View File

@@ -4,7 +4,7 @@
#
# The configuration is split into three files. Look into those files for more details.
#
require:
plugins:
- rubocop-capybara
- rubocop-factory_bot
- rubocop-rails

View File

@@ -94,7 +94,7 @@ Metrics/PerceivedComplexity:
Enabled: true
Max: 14 # default 8
Naming/PredicateName:
Naming/PredicatePrefix:
Enabled: false
Naming/VariableNumber:

View File

@@ -1,11 +1,44 @@
# This configuration was generated by
# `rubocop --auto-gen-config --auto-gen-only-exclude --exclude-limit 1400 --no-auto-gen-timestamp`
# using RuboCop version 1.64.1.
# using RuboCop version 1.81.6.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.
# Offense count: 1
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: RequireParenthesesForMethodChains.
Lint/AmbiguousRange:
Exclude:
- 'app/models/concerns/permalink_generator.rb'
# Offense count: 6
Lint/CopDirectiveSyntax:
Exclude:
- 'app/services/orders/bulk_cancel_service.rb'
- 'lib/tasks/simplecov.rake'
- 'spec/models/database_spec.rb'
- 'spec/system/admin/bulk_order_management_spec.rb'
- 'spec/system/admin/enterprise_relationships_spec.rb'
# Offense count: 2
Lint/DuplicateMethods:
Exclude:
- 'app/models/spree/order.rb'
- 'engines/order_management/app/services/order_management/subscriptions/form.rb'
# Offense count: 3
Lint/UselessConstantScoping:
Exclude:
- 'app/services/weights_and_measures.rb'
- 'lib/reporting/report_metadata_builder.rb'
# Offense count: 1
Lint/UselessOr:
Exclude:
- 'app/models/product_import/entry_validator.rb'
# Offense count: 24
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
Metrics/AbcSize:
@@ -42,7 +75,7 @@ Metrics/BlockLength:
- 'lib/tasks/data.rake'
# Offense count: 1
# Configuration parameters: CountBlocks, Max.
# Configuration parameters: CountBlocks, CountModifierForms, Max.
Metrics/BlockNesting:
Exclude:
- 'app/models/spree/payment/processing.rb'
@@ -100,7 +133,7 @@ Metrics/ClassLength:
- 'lib/reporting/reports/enterprise_fee_summary/scope.rb'
- 'lib/reporting/reports/xero_invoices/base.rb'
# Offense count: 30
# Offense count: 35
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
Metrics/CyclomaticComplexity:
Exclude:
@@ -123,6 +156,11 @@ Metrics/CyclomaticComplexity:
- 'app/models/spree/tax_rate.rb'
- 'app/models/spree/zone.rb'
- 'lib/open_food_network/enterprise_issue_validator.rb'
- 'lib/reporting/reports/orders_and_fulfillment/order_cycle_customer_totals.rb'
- 'lib/reporting/reports/orders_and_fulfillment/order_cycle_supplier_totals.rb'
- 'lib/reporting/reports/payments/itemised_payment_totals.rb'
- 'lib/reporting/reports/payments/payment_totals.rb'
- 'lib/reporting/reports/sales_tax/sales_tax_totals_by_producer.rb'
- 'lib/reporting/reports/xero_invoices/base.rb'
- 'lib/spree/core/controller_helpers/order.rb'
- 'lib/spree/core/controller_helpers/respond_with.rb'
@@ -182,8 +220,9 @@ Metrics/PerceivedComplexity:
- 'app/models/spree/order/checkout.rb'
# Offense count: 1
# Configuration parameters: EnforcedStyle, AllowedPatterns.
# Configuration parameters: EnforcedStyle, AllowedPatterns, ForbiddenIdentifiers, ForbiddenPatterns.
# SupportedStyles: snake_case, camelCase
# ForbiddenIdentifiers: __id__, __send__
Naming/MethodName:
Exclude:
- 'engines/dfc_provider/lib/dfc_provider/catalog_item.rb'
@@ -195,23 +234,132 @@ Naming/MethodParameterName:
Exclude:
- 'engines/dfc_provider/lib/dfc_provider/catalog_item.rb'
# Offense count: 59
# Configuration parameters: Mode, AllowedMethods, AllowedPatterns, AllowBangMethods, WaywardPredicates.
# AllowedMethods: call
# WaywardPredicates: nonzero?
Naming/PredicateMethod:
Exclude:
- 'app/controllers/admin/product_import_controller.rb'
- 'app/controllers/api/v0/order_cycles_controller.rb'
- 'app/controllers/spree/admin/overview_controller.rb'
- 'app/controllers/spree/admin/payments_controller.rb'
- 'app/controllers/voucher_adjustments_controller.rb'
- 'app/forms/enterprise_fees_bulk_update.rb'
- 'app/forms/schedule_form.rb'
- 'app/helpers/spree/orders_helper.rb'
- 'app/models/concerns/variant_stock.rb'
- 'app/models/enterprise.rb'
- 'app/models/enterprise_fee.rb'
- 'app/models/invoice/data_presenter.rb'
- 'app/models/order_cycle.rb'
- 'app/models/product_import/entry_processor.rb'
- 'app/models/product_import/entry_validator.rb'
- 'app/models/spree/order.rb'
- 'app/models/spree/order_contents.rb'
- 'app/models/spree/payment.rb'
- 'app/models/spree/payment/processing.rb'
- 'app/models/spree/state_change.rb'
- 'app/models/spree/user.rb'
- 'app/reflexes/admin/orders_reflex.rb'
- 'app/serializers/api/admin/for_order_cycle/enterprise_serializer.rb'
- 'app/serializers/api/admin/index_enterprise_serializer.rb'
- 'app/serializers/api/admin/index_order_cycle_serializer.rb'
- 'app/serializers/api/admin/order_cycle_serializer.rb'
- 'app/serializers/api/admin/order_serializer.rb'
- 'app/serializers/api/admin/schedule_serializer.rb'
- 'app/serializers/api/admin/subscription_line_item_serializer.rb'
- 'app/serializers/api/admin/user_serializer.rb'
- 'app/serializers/api/admin/variant_serializer.rb'
- 'app/serializers/api/enterprise_shopfront_serializer.rb'
- 'app/serializers/api/enterprise_thin_serializer.rb'
- 'app/serializers/api/order_serializer.rb'
- 'app/serializers/api/uncached_enterprise_serializer.rb'
- 'app/services/cart_service.rb'
- 'app/services/orders/fetch_adjustments_service.rb'
- 'app/services/orders/workflow_service.rb'
- 'app/services/sets/model_set.rb'
- 'app/services/sets/order_cycle_set.rb'
- 'app/services/sets/product_set.rb'
- 'engines/dfc_provider/app/controllers/dfc_provider/addresses_controller.rb'
- 'lib/open_food_network/order_cycle_form_applicator.rb'
- 'lib/open_food_network/order_cycle_permissions.rb'
- 'lib/reporting/reports/enterprise_fee_summary/enterprise_fees_with_tax_report_by_order.rb'
- 'lib/reporting/reports/enterprise_fee_summary/enterprise_fees_with_tax_report_by_producer.rb'
- 'lib/tasks/data/check_invalid_address_used.rake'
# Offense count: 3
# Configuration parameters: EnforcedStyle, AllowedIdentifiers, AllowedPatterns.
# Configuration parameters: EnforcedStyle, AllowedIdentifiers, AllowedPatterns, ForbiddenIdentifiers, ForbiddenPatterns.
# SupportedStyles: snake_case, camelCase
Naming/VariableName:
Exclude:
- 'engines/dfc_provider/lib/dfc_provider/catalog_item.rb'
# Offense count: 6
# This cop supports unsafe autocorrection (--autocorrect-all).
Rails/FindByOrAssignmentMemoization:
Exclude:
- 'app/controllers/admin/customers_controller.rb'
- 'app/controllers/admin/resource_controller.rb'
- 'app/controllers/api/v0/enterprise_fees_controller.rb'
- 'app/controllers/api/v0/order_cycles_controller.rb'
- 'lib/stripe/account_connector.rb'
# Offense count: 32
# This cop supports unsafe autocorrection (--autocorrect-all).
Rails/OrderArguments:
Exclude:
- 'app/controllers/admin/enterprise_fees_controller.rb'
- 'app/controllers/admin/enterprises_controller.rb'
- 'app/controllers/admin/order_cycles_controller.rb'
- 'app/controllers/admin/product_import_controller.rb'
- 'app/controllers/api/v0/states_controller.rb'
- 'app/controllers/spree/admin/overview_controller.rb'
- 'app/controllers/spree/admin/products_controller.rb'
- 'app/helpers/enterprises_helper.rb'
- 'app/models/enterprise.rb'
- 'app/models/enterprise_group.rb'
- 'app/models/enterprise_relationship_permission.rb'
- 'app/models/order_cycle.rb'
- 'app/models/product_import/product_importer.rb'
- 'app/models/schedule.rb'
- 'app/models/spree/country.rb'
- 'app/models/spree/order.rb'
- 'app/models/spree/shipping_rate.rb'
- 'app/models/spree/user.rb'
- 'app/models/spree/zone.rb'
- 'app/models/subscription_line_item.rb'
- 'app/models/tag_rule.rb'
- 'app/models/variant_override.rb'
- 'lib/open_food_network/address_finder.rb'
- 'spec/services/orders/generate_invoice_service_spec.rb'
- 'spec/system/admin/order_cycles/simple_spec.rb'
# Offense count: 1
# Configuration parameters: TransactionMethods.
Rails/TransactionExitStatement:
Exclude:
- 'app/services/place_proxy_order.rb'
# Offense count: 3
# This cop supports unsafe autocorrection (--autocorrect-all).
Style/ArrayIntersect:
Exclude:
- 'app/models/spree/ability.rb'
- 'app/models/spree/variant.rb'
# Offense count: 1
# This cop supports unsafe autocorrection (--autocorrect-all).
Style/BitwisePredicate:
Exclude:
- 'app/helpers/admin/enterprises_helper.rb'
# Offense count: 23
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: EnforcedStyle.
# Configuration parameters: EnforcedStyle, EnforcedStyleForClasses, EnforcedStyleForModules.
# SupportedStyles: nested, compact
# SupportedStylesForClasses: ~, nested, compact
# SupportedStylesForModules: ~, nested, compact
Style/ClassAndModuleChildren:
Exclude:
- 'app/models/calculator/flat_percent_per_item.rb'
@@ -237,13 +385,33 @@ Style/ClassAndModuleChildren:
- 'lib/open_food_network/locking.rb'
- 'spec/models/spree/payment_method_spec.rb'
# Offense count: 4
# Offense count: 14
# This cop supports unsafe autocorrection (--autocorrect-all).
Style/CollectionQuerying:
Exclude:
- 'app/controllers/spree/credit_cards_controller.rb'
- 'app/models/product_import/product_importer.rb'
- 'app/models/product_import/spreadsheet_entry.rb'
- 'app/models/spree/order.rb'
- 'app/models/spree/order_inventory.rb'
- 'app/models/spree/payment_method.rb'
- 'app/models/spree/user.rb'
- 'app/models/stripe_account.rb'
- 'app/services/order_cycles/warning_service.rb'
- 'lib/reporting/report_renderer.rb'
- 'lib/tasks/sample_data.rake'
# Offense count: 2
# This cop supports unsafe autocorrection (--autocorrect-all).
Style/HashSlice:
Exclude:
- 'app/services/product_filters.rb'
- 'lib/reporting/report_row_builder.rb'
# Offense count: 1
# This cop supports unsafe autocorrection (--autocorrect-all).
Style/MapToHash:
Exclude:
- 'lib/reporting/report_query_template.rb'
- 'lib/reporting/report_row_builder.rb'
- 'lib/reporting/reports/enterprise_fee_summary/fee_summary.rb'
- 'lib/tasks/sample_data/user_factory.rb'
# Offense count: 38
@@ -274,3 +442,22 @@ Style/OptionalBooleanParameter:
- 'engines/order_management/app/services/order_management/stock/estimator.rb'
- 'lib/spree/core/controller_helpers/order.rb'
- 'spec/support/request/web_helper.rb'
# Offense count: 3
# This cop supports unsafe autocorrection (--autocorrect-all).
Style/RedundantFormat:
Exclude:
- 'spec/models/product_importer_spec.rb'
- 'spec/requests/checkout/stripe_sca_spec.rb'
- 'spec/system/consumer/account/cards_spec.rb'
# Offense count: 8
# Configuration parameters: Max.
Style/SafeNavigationChainLength:
Exclude:
- 'app/controllers/concerns/extra_fields.rb'
- 'app/services/customer_syncer.rb'
- 'app/services/fdc_offer_broker.rb'
- 'engines/dfc_provider/app/services/dfc_catalog.rb'
- 'engines/dfc_provider/app/services/image_builder.rb'
- 'engines/dfc_provider/app/services/quantitative_value_builder.rb'

View File

@@ -1 +1 @@
3.1.4
3.1.7

View File

@@ -1,4 +1,4 @@
FROM ruby:3.1.4-alpine3.19 AS base
FROM ruby:3.1.7-alpine3.19 AS base
ENV LANG=C.UTF-8 \
LC_ALL=C.UTF-8 \
TZ=Europe/London \

View File

@@ -27,7 +27,6 @@ gem 'sprockets', '~> 3.7'
gem 'i18n'
gem 'i18n-js', '~> 3.9.0'
gem 'rails-i18n'
gem 'rails_safe_tasks', '~> 1.0'
gem "activerecord-import"
gem "db2fog", github: "openfoodfoundation/db2fog", branch: "rails-7"
@@ -194,8 +193,11 @@ group :development do
gem 'query_count'
gem 'rails-erd'
gem 'rubocop'
gem 'rubocop-capybara'
gem 'rubocop-factory_bot'
gem 'rubocop-rails'
gem 'rubocop-rspec'
gem 'rubocop-rspec_rails'
gem 'spring'
gem 'spring-commands-rspec'
gem 'spring-commands-rubocop'

View File

@@ -122,7 +122,7 @@ GEM
activemodel (= 7.1.5.2)
activesupport (= 7.1.5.2)
timeout (>= 0.4.0)
activerecord-import (1.6.0)
activerecord-import (2.2.0)
activerecord (>= 4.2)
activerecord-postgresql-adapter (0.0.1)
pg
@@ -156,8 +156,8 @@ GEM
activerecord (>= 6.1, < 7.2)
acts_as_list (1.0.4)
activerecord (>= 4.2)
addressable (2.8.6)
public_suffix (>= 2.0.2, < 6.0)
addressable (2.8.7)
public_suffix (>= 2.0.2, < 7.0)
aes_key_wrap (1.1.0)
afm (0.2.2)
angular-rails-templates (1.2.1)
@@ -192,8 +192,8 @@ GEM
base64 (0.3.0)
bcp47_spec (0.2.1)
bcrypt (3.1.20)
benchmark (0.4.1)
bigdecimal (3.2.2)
benchmark (0.5.0)
bigdecimal (3.3.1)
bindata (2.5.0)
bindex (0.8.1)
bootsnap (1.18.3)
@@ -374,13 +374,13 @@ GEM
temple (>= 0.8.2)
thor
tilt
hashdiff (1.1.0)
hashdiff (1.2.1)
hashery (2.1.2)
hashie (5.0.0)
highline (2.0.3)
htmlentities (4.3.4)
http_parser.rb (0.8.0)
i18n (1.14.5)
i18n (1.14.7)
concurrent-ruby (~> 1.0)
i18n-js (3.9.2)
i18n (>= 0.6.6)
@@ -416,7 +416,7 @@ GEM
thor (>= 0.14, < 2.0)
jquery-ui-rails (4.2.1)
railties (>= 3.2.16)
json (2.7.2)
json (2.15.2)
json-canonicalization (1.0.0)
json-jwt (1.16.6)
activesupport (>= 4.2)
@@ -442,15 +442,16 @@ GEM
activesupport (>= 4.2)
jwt (2.8.1)
base64
knapsack_pro (8.1.2)
knapsack_pro (8.4.0)
rake
language_server-protocol (3.17.0.3)
language_server-protocol (3.17.0.5)
launchy (3.0.0)
addressable (~> 2.8)
childprocess (~> 5.0)
letter_opener (1.10.0)
launchy (>= 2.2, < 4)
link_header (0.0.8)
lint_roller (1.1.0)
listen (3.9.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
@@ -473,10 +474,10 @@ GEM
mimemagic (0.4.3)
nokogiri (~> 1)
rake
mini_magick (4.11.0)
mini_magick (4.13.2)
mini_mime (1.1.5)
mini_portile2 (2.8.6)
minitest (5.25.5)
minitest (5.26.0)
monetize (1.13.0)
money (~> 6.12)
money (6.16.0)
@@ -539,10 +540,10 @@ GEM
paper_trail (15.1.0)
activerecord (>= 6.1)
request_store (~> 1.4)
parallel (1.24.0)
parallel (1.27.0)
paranoia (2.6.3)
activerecord (>= 5.1, < 7.2)
parser (3.3.9.0)
parser (3.3.10.0)
ast (~> 2.4.1)
racc
paypal-sdk-core (0.3.4)
@@ -560,6 +561,7 @@ GEM
pp (0.6.2)
prettyprint
prettyprint (0.2.0)
prism (1.6.0)
private_address_check (0.5.0)
pry (0.13.1)
coderay (~> 1.1)
@@ -567,7 +569,7 @@ GEM
psych (5.2.6)
date
stringio
public_suffix (5.0.5)
public_suffix (6.0.2)
puffing-billy (4.0.2)
addressable (~> 2.5)
em-http-request (~> 1.1, >= 1.1.0)
@@ -640,7 +642,6 @@ GEM
rails-i18n (7.0.10)
i18n (>= 0.7, < 2)
railties (>= 6.0.0, < 8)
rails_safe_tasks (1.0.0)
railties (7.1.5.2)
actionpack (= 7.1.5.2)
activesupport (= 7.1.5.2)
@@ -671,7 +672,7 @@ GEM
redis-client (>= 0.22.0)
redis-client (0.26.1)
connection_pool
regexp_parser (2.9.2)
regexp_parser (2.11.3)
reline (0.6.2)
io-console (~> 0.5)
request_store (1.5.1)
@@ -734,35 +735,39 @@ GEM
rswag-ui (2.16.0)
actionpack (>= 5.2, < 8.1)
railties (>= 5.2, < 8.1)
rubocop (1.64.1)
rubocop (1.81.6)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
language_server-protocol (~> 3.17.0.2)
lint_roller (~> 1.1.0)
parallel (~> 1.10)
parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.31.1, < 2.0)
regexp_parser (>= 2.9.3, < 3.0)
rubocop-ast (>= 1.47.1, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.31.3)
parser (>= 3.3.1.0)
rubocop-capybara (2.20.0)
rubocop (~> 1.41)
rubocop-factory_bot (2.25.1)
rubocop (~> 1.41)
rubocop-rails (2.28.0)
unicode-display_width (>= 2.4.0, < 4.0)
rubocop-ast (1.47.1)
parser (>= 3.3.7.2)
prism (~> 1.4)
rubocop-capybara (2.22.1)
lint_roller (~> 1.1)
rubocop (~> 1.72, >= 1.72.1)
rubocop-factory_bot (2.27.1)
lint_roller (~> 1.1)
rubocop (~> 1.72, >= 1.72.1)
rubocop-rails (2.33.4)
activesupport (>= 4.2.0)
lint_roller (~> 1.1)
rack (>= 1.1)
rubocop (>= 1.52.0, < 2.0)
rubocop-ast (>= 1.31.1, < 2.0)
rubocop-rspec (2.29.2)
rubocop (~> 1.40)
rubocop-capybara (~> 2.17)
rubocop-factory_bot (~> 2.22)
rubocop-rspec_rails (~> 2.28)
rubocop-rspec_rails (2.28.3)
rubocop (~> 1.40)
rubocop (>= 1.75.0, < 2.0)
rubocop-ast (>= 1.44.0, < 2.0)
rubocop-rspec (3.7.0)
lint_roller (~> 1.1)
rubocop (~> 1.72, >= 1.72.1)
rubocop-rspec_rails (2.31.0)
lint_roller (~> 1.1)
rubocop (~> 1.72, >= 1.72.1)
rubocop-rspec (~> 3.5)
ruby-graphviz (1.2.5)
rexml
ruby-progressbar (1.13.0)
@@ -819,13 +824,13 @@ GEM
actionpack (>= 5.2)
activesupport (>= 5.2)
sprockets (>= 3.0.0)
state_machines (0.6.0)
state_machines-activemodel (0.9.0)
activemodel (>= 6.0)
state_machines (>= 0.6.0)
state_machines-activerecord (0.9.0)
activerecord (>= 6.0)
state_machines-activemodel (>= 0.9.0)
state_machines (0.20.0)
state_machines-activemodel (0.10.0)
activemodel (>= 7.1)
state_machines (>= 0.10.0)
state_machines-activerecord (0.31.0)
activerecord (>= 7.1)
state_machines-activemodel (>= 0.10.0)
stimulus_reflex (3.5.5)
actioncable (>= 5.2)
actionpack (>= 5.2)
@@ -841,7 +846,7 @@ GEM
stringex (2.8.6)
stringio (3.1.7)
stripe (11.1.0)
strscan (3.1.2)
strscan (3.1.5)
swd (2.0.3)
activesupport (>= 3)
attr_required (>= 0.0.5)
@@ -873,7 +878,9 @@ GEM
rugged (>= 0.27, < 1.10)
simplecov
simplecov_json_formatter
unicode-display_width (2.5.0)
unicode-display_width (3.2.0)
unicode-emoji (~> 4.1)
unicode-emoji (4.1.0)
uniform_notifier (1.17.0)
uri (0.13.2)
valid_email2 (5.2.3)
@@ -906,7 +913,7 @@ GEM
activesupport
faraday (~> 2.0)
faraday-follow_redirects
webmock (3.23.1)
webmock (3.25.1)
addressable (>= 2.8.0)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
@@ -1029,7 +1036,6 @@ DEPENDENCIES
rails-controller-testing
rails-erd
rails-i18n
rails_safe_tasks (~> 1.0)
ransack (~> 4.1.0)
redcarpet
redis
@@ -1043,8 +1049,11 @@ DEPENDENCIES
rswag-api
rswag-ui
rubocop
rubocop-capybara
rubocop-factory_bot
rubocop-rails
rubocop-rspec
rubocop-rspec_rails
sd_notify
select2-rails!
shoulda-matchers
@@ -1078,7 +1087,7 @@ DEPENDENCIES
wkhtmltopdf-binary
RUBY VERSION
ruby 3.1.4p223
ruby 3.1.7p261
BUNDLED WITH
2.4.3

View File

@@ -1,6 +1,6 @@
angular.module('Darkswarm').directive "activeTableHubLink", (CurrentHub, CurrentOrder) ->
# Change the text of the hub link based on CurrentHub
# To be used with ofnEmptiesCart
# To be used with ofnChangeHub
# Takes "change" and "shop" as text string attributes
restrict: "A"
scope:

View File

@@ -12,7 +12,7 @@
.row
.columns.small-12
%a.cta-hub{"ng-repeat" => "hub in enterprise.hubs | filter:{id: '!'+enterprise.id} | orderBy:'-active'",
"ng-href" => "{{::hub.path}}#/shop_panel", "ofn-empties-cart" => "hub",
"ng-href" => "{{::hub.path}}#/shop_panel",
"ng-class" => "::{primary: hub.active, secondary: !hub.active}",
"ng-click" => "$close()",
"ofn-change-hub" => "hub"}

View File

@@ -30,7 +30,7 @@ class SearchableDropdownComponent < ViewComponent::Base
:aria_label, :other_attrs
def classes
"fullwidth #{remove_search_plugin? ? 'no-input' : ''}"
"fullwidth #{'no-input' if remove_search_plugin?}"
end
def data

View File

@@ -3,6 +3,7 @@
module Admin
class BulkLineItemsController < Spree::Admin::BaseController
include PaginationData
# GET /admin/bulk_line_items.json
#
def index

View File

@@ -4,6 +4,7 @@ module Admin
class ReportsController < Spree::Admin::BaseController
include ActiveStorage::SetCurrent
include ReportsActions
helper ReportsHelper
before_action :authorize_report, only: [:show, :create]

View File

@@ -7,6 +7,7 @@ module Api
module V0
class ExchangeProductsController < Api::V0::BaseController
include PaginationData
DEFAULT_PER_PAGE = 100
skip_authorization_check only: [:index]

View File

@@ -7,6 +7,7 @@ module Api
module V0
class ProductsController < Api::V0::BaseController
include PaginationData
respond_to :json
DEFAULT_PER_PAGE = 15

View File

@@ -6,6 +6,7 @@ module Spree
module Admin
class OrdersController < Spree::Admin::BaseController
include OpenFoodNetwork::SpreeApiKeyLoader
helper CheckoutHelper
before_action :load_order, only: [:edit, :update, :fire, :resend, :invoice, :print]

View File

@@ -10,6 +10,7 @@ module Spree
include OpenFoodNetwork::SpreeApiKeyLoader
include OrderCyclesHelper
include EnterprisesHelper
helper ::Admin::ProductsHelper
helper Spree::Admin::TaxCategoriesHelper

View File

@@ -14,6 +14,7 @@ module Spree
include Spree::Core::ControllerHelpers::Order
include I18nHelper
before_action :set_locale
# Devise::PasswordsController allows for blank passwords.

View File

@@ -36,9 +36,7 @@ class ScheduleForm
false unless @schedule.update(permitted_resource_params)
end
def order_cycle_ids
@schedule.order_cycle_ids
end
delegate :order_cycle_ids, to: :@schedule
private

View File

@@ -120,7 +120,7 @@ module InjectionHelper
def inject_enterprise_attributes(enterprise_attributes)
render partial: "json/injection_ams",
locals: { name: 'enterpriseAttributes', json: enterprise_attributes.to_json.to_s }
locals: { name: 'enterpriseAttributes', json: enterprise_attributes.to_json }
end
def inject_saved_credit_cards

View File

@@ -44,9 +44,7 @@ module ReportsHelper
.pluck(:name, :id)
end
def currency_symbol
Spree::Money.currency_symbol
end
delegate :currency_symbol, to: :'Spree::Money'
def enterprise_fee_owner_ids(orders)
EnterpriseFee.where(id: enterprise_fee_ids(orders))

View File

@@ -10,9 +10,7 @@ module TermsAndConditionsHelper
TermsOfService.required?(distributor)
end
def platform_terms_required?
TermsOfService.platform_terms_required?
end
delegate :platform_terms_required?, to: :TermsOfService
def distributor_terms_required?
TermsOfService.distributor_terms_required?(current_order.distributor)

View File

@@ -2,6 +2,7 @@
class BulkInvoiceJob < ApplicationJob
include CableReady::Broadcaster
delegate :render, to: ActionController::Base
attr_reader :options

View File

@@ -3,6 +3,7 @@
# Renders a report and stores it in a given blob.
class ReportJob < ApplicationJob
include CableReady::Broadcaster
delegate :render, to: ActionController::Base
before_perform :enable_active_storage_urls

View File

@@ -4,6 +4,7 @@ require 'active_support/concern'
module LogDestroyPerformer
extend ActiveSupport::Concern
included do
attr_accessor :destroyed_by

View File

@@ -408,7 +408,7 @@ class Enterprise < ApplicationRecord
def category
# Make this crazy logic human readable so we can argue about it sanely.
cat = is_primary_producer ? "producer_" : "non_producer_"
cat << ("sells_#{sells}")
cat << "sells_#{sells}"
# Map backend cases to front end cases.
case cat

View File

@@ -3,6 +3,7 @@
class Invoice
class DataPresenter
include ::ActionView::Helpers::NumberHelper
attr_reader :invoice
delegate :display_number, :data, :previous_invoice, to: :invoice
@@ -142,7 +143,7 @@ class Invoice
end
def paid?
data[:payment_state] == 'paid' || data[:payment_state] == 'credit_owed'
['paid', 'credit_owed'].include?(data[:payment_state])
end
def outstanding_balance?

View File

@@ -4,6 +4,7 @@ class Invoice
class DataPresenter
class Base
include ::ActionView::Helpers::NumberHelper
attr_reader :data
def initialize(data)

View File

@@ -81,17 +81,13 @@ module ProductImport
@reset_counts
end
def enterprises_index
@spreadsheet_data.enterprises_index
end
delegate :enterprises_index, to: :@spreadsheet_data
def enterprise_products
@processor&.enterprise_products
end
def total_enterprise_products
@processor.total_enterprise_products
end
delegate :total_enterprise_products, to: :@processor
def entries_json
entries = {}
@@ -130,13 +126,9 @@ module ProductImport
@processor.inventory_updated
end
def products_reset_count
@processor.products_reset_count
end
delegate :products_reset_count, to: :@processor
def total_saved_count
@processor.total_saved_count
end
delegate :total_saved_count, to: :@processor
def import_results
{ entries: entries_json, reset_counts: }
@@ -183,7 +175,7 @@ module ProductImport
end
def staged_import?
@import_settings&.key?(:start) && @import_settings&.key?(:end)
@import_settings&.key?(:start) && @import_settings.key?(:end)
end
def init_permissions

View File

@@ -31,9 +31,7 @@ module Spree
self.class.name.titleize.gsub("Calculator/", "")
end
def description
self.class.description
end
delegate :description, to: :class
def available?(_object)
true

View File

@@ -97,7 +97,7 @@ module Spree
}
validate :disallow_guest_order
validates :email, presence: true,
format: /\A([\w.%+\-']+)@([\w\-]+\.)+(\w{2,})\z/i,
format: /\A([\w.%+\-']+)@([\w-]+\.)+(\w{2,})\z/i,
if: :require_email
validates :order_cycle, presence: true, on: :require_distribution
@@ -417,7 +417,7 @@ module Spree
# Helper methods for checkout steps
def paid?
payment_state == 'paid' || payment_state == 'credit_owed'
['paid', 'credit_owed'].include?(payment_state)
end
# "Checkout" is the initial state and, for card payments, "pending" is the state after auth

View File

@@ -3,6 +3,7 @@
module Spree
class ShippingMethod < ApplicationRecord
include CalculatedAdjustments
DISPLAY_ON_OPTIONS = {
both: "",
back_end: "back_end"

View File

@@ -8,24 +8,14 @@ module Api
:open_street_map_default_latitude,
:open_street_map_default_longitude
def open_street_map_enabled
ContentConfig.open_street_map_enabled
end
delegate :open_street_map_enabled, to: :ContentConfig
def open_street_map_provider_name
ContentConfig.open_street_map_provider_name
end
delegate :open_street_map_provider_name, to: :ContentConfig
def open_street_map_provider_options
ContentConfig.open_street_map_provider_options
end
delegate :open_street_map_provider_options, to: :ContentConfig
def open_street_map_default_latitude
ContentConfig.open_street_map_default_latitude
end
delegate :open_street_map_default_latitude, to: :ContentConfig
def open_street_map_default_longitude
ContentConfig.open_street_map_default_longitude
end
delegate :open_street_map_default_longitude, to: :ContentConfig
end
end

View File

@@ -36,7 +36,7 @@ class EmbeddedPageService
def embedding_without_https?
@request.referer && URI(@request.referer).scheme != 'https' &&
!Rails.env.test? && !Rails.env.development?
!Rails.env.local?
end
def process_embedded_request

View File

@@ -65,7 +65,7 @@
.row
.small-12.columns
.active_table
%producer.active_table_node.row.animate-repeat{id: "{{producer.path}}",
%producer.active_table_node.row.animate-repeat{
"ng-repeat" => "producer in filteredEnterprises = (Enterprises.producers | searchEnterprises:query | taxons:activeTaxons | properties:activeProperties:'supplied_properties')",
"ng-controller" => "ProducerNodeCtrl",
"ng-class" => "{'closed' : !open(), 'open' : open(), 'inactive' : !producer.active}",

View File

@@ -24,7 +24,7 @@
.row
.small-12.columns
.active_table
%producer.active_table_node.row.animate-repeat{id: "{{producer.path}}",
%producer.active_table_node.row.animate-repeat{
"ng-repeat" => "producer in filteredEnterprises = (Enterprises.producers | searchEnterprises:query | taxons:activeTaxons | properties:activeProperties:'supplied_properties')",
"ng-controller" => "ProducerNodeCtrl",
"ng-class" => "{'closed' : !open(), 'open' : open(), 'inactive' : !producer.active}",

View File

@@ -3,7 +3,7 @@
= inject_json_array("shops", @shops.all, Api::ShopForOrdersSerializer)
= inject_saved_credit_cards
- if Stripe.publishable_key
- if Spree::Config.stripe_connect_enabled && Stripe.publishable_key
:javascript
angular.module('Darkswarm').value("stripeObject", Stripe("#{Stripe.publishable_key}"))
angular.module('Darkswarm').value("stripePublishableKey", "#{Stripe.publishable_key}")

View File

@@ -1,8 +1,8 @@
import consumer from './consumer'
import CableReady from 'cable_ready'
import consumer from "./consumer";
import CableReady from "cable_ready";
consumer.subscriptions.create("SessionChannel", {
received(data) {
if (data.cableReady) CableReady.perform(data.operations)
}
if (data.cableReady) CableReady.perform(data.operations);
},
});

View File

@@ -1,8 +1,8 @@
import ApplicationController from "./application_controller";
export default class extends ApplicationController {
static targets = ["extraParams"]
static values = { reflex: String }
static targets = ["extraParams"];
static values = { reflex: String };
connect() {
super.connect();
@@ -12,7 +12,7 @@ export default class extends ApplicationController {
let params = { bulk_ids: this.getSelectedIds() };
if (this.hasExtraParamsTarget) {
Object.assign(params, this.extraFormData())
Object.assign(params, this.extraFormData());
}
this.stimulate(this.reflexValue, params);
@@ -21,15 +21,15 @@ export default class extends ApplicationController {
// private
getSelectedIds() {
const checkboxes = document.querySelectorAll(
"table input[name='bulk_ids[]']:checked"
);
const checkboxes = document.querySelectorAll("table input[name='bulk_ids[]']:checked");
return Array.from(checkboxes).map((checkbox) => checkbox.value);
}
extraFormData() {
if (this.extraParamsTarget.constructor.name !== "HTMLFormElement") { return {} }
if (this.extraParamsTarget.constructor.name !== "HTMLFormElement") {
return {};
}
return Object.fromEntries(new FormData(this.extraParamsTarget).entries())
return Object.fromEntries(new FormData(this.extraParamsTarget).entries());
}
}

View File

@@ -35,7 +35,7 @@ export default class extends Controller {
countValueChanged() {
window.dispatchEvent(
new CustomEvent("checked:updated", { detail: { count: this.countValue } })
new CustomEvent("checked:updated", { detail: { count: this.countValue } }),
);
}
@@ -50,11 +50,10 @@ export default class extends Controller {
}
#closeDetails(elmnt) {
if (elmnt.getElementsByTagName('details').length == 0)
return;
if (elmnt.getElementsByTagName("details").length == 0) return;
Array.from(elmnt.getElementsByTagName('details')).forEach((element) => element.open = false);
}
Array.from(elmnt.getElementsByTagName("details")).forEach((element) => (element.open = false));
}
#toggleDisabled() {
if (!this.hasDisableTarget) {

View File

@@ -5,10 +5,10 @@ import { Controller } from "stimulus";
export default class ColumnPreferencesController extends Controller {
connect() {
this.table = document.querySelector('table[data-column-preferences-target="table"]');
this.cols = Array.from(this.table.querySelectorAll('col'));
this.colSpanCells = Array.from(this.table.querySelectorAll('th[colspan],td[colspan]'));
this.cols = Array.from(this.table.querySelectorAll("col"));
this.colSpanCells = Array.from(this.table.querySelectorAll("th[colspan],td[colspan]"));
// Initialise data-default-col-span
this.colSpanCells.forEach((cell)=> {
this.colSpanCells.forEach((cell) => {
cell.dataset.defaultColSpan ||= cell.colSpan;
});
@@ -33,24 +33,24 @@ export default class ColumnPreferencesController extends Controller {
this.table.classList.toggle(`hide-${name}`, !element.checked);
// Reset cell colspans
for(const cell of this.colSpanCells) {
for (const cell of this.colSpanCells) {
this.#updateColSpanCell(cell);
};
}
}
#showHideElement(element, show) {
element.style.display = show ? "" : "none";
}
#observeProductsTableRows(){
#observeProductsTableRows() {
this.productsTableObserver = new MutationObserver((mutations, _observer) => {
const mutationRecord = mutations[0];
if(mutationRecord){
if (mutationRecord) {
const productRowElement = mutationRecord.addedNodes[0];
if(productRowElement){
const newColSpanCell = productRowElement.querySelector('td[colspan]');
if (productRowElement) {
const newColSpanCell = productRowElement.querySelector("td[colspan]");
newColSpanCell.dataset.defaultColSpan ||= newColSpanCell.colSpan;
this.#updateColSpanCell(newColSpanCell);
this.colSpanCells.push(newColSpanCell);
@@ -61,11 +61,11 @@ export default class ColumnPreferencesController extends Controller {
this.productsTableObserver.observe(this.table, { childList: true });
}
#hiddenColCount(){
return this.checkboxes.filter((checkbox)=> !checkbox.checked).length;
#hiddenColCount() {
return this.checkboxes.filter((checkbox) => !checkbox.checked).length;
}
#updateColSpanCell(cell){
#updateColSpanCell(cell) {
cell.colSpan = parseInt(cell.dataset.defaultColSpan, 10) - this.#hiddenColCount();
}
}

View File

@@ -4,9 +4,7 @@ export default class extends Controller {
static targets = ["reportType", "checkbox", "label"];
handleSelectChange() {
this.reportTypeTarget.value == "csv" ?
this.disableField():
this.enableField();
this.reportTypeTarget.value == "csv" ? this.disableField() : this.enableField();
}
disableField() {

View File

@@ -2,7 +2,6 @@ import { Controller } from "stimulus";
// Close a <details> element when click outside
export default class extends Controller {
connect() {
document.body.addEventListener("click", this.#close.bind(this));
this.element.addEventListener("click", this.#stopPropagation.bind(this));

View File

@@ -1,7 +1,7 @@
import { Controller } from "stimulus";
document.addEventListener("turbolinks:before-cache", () =>
document.getElementById("flash").remove()
document.getElementById("flash").remove(),
);
export default class extends Controller {

View File

@@ -9,7 +9,7 @@ export default class extends Controller {
connect() {
if (this.hasSummaryTarget) {
window.addEventListener('beforeunload', this.handlePageUnload);
window.addEventListener("beforeunload", this.handlePageUnload);
}
if (!this.hasGuestTarget) {
@@ -50,7 +50,7 @@ export default class extends Controller {
removeUnloadEvent() {
if (this.hasSummaryTarget) {
window.removeEventListener('beforeunload', this.handlePageUnload);
window.removeEventListener("beforeunload", this.handlePageUnload);
}
}
}

View File

@@ -9,10 +9,7 @@ export default class extends Controller {
}
countCharacters() {
this.displayCount(
this.inputTarget.value.length,
this.inputTarget.maxLength
);
this.displayCount(this.inputTarget.value.length, this.inputTarget.maxLength);
}
displayCount(count, max) {

View File

@@ -40,20 +40,11 @@ export default class extends Controller {
document.querySelector("body").classList.add("modal-open");
});
window._paq?.push([
"trackEvent",
"Signin/Signup",
"Login Modal View",
window.location.href,
]);
window._paq?.push(["trackEvent", "Signin/Signup", "Login Modal View", window.location.href]);
};
close() {
history.pushState(
{},
"",
window.location.pathname + window.location.search
);
history.pushState({}, "", window.location.pathname + window.location.search);
this.modalTarget.classList.remove("in");
this.backgroundTarget.classList.remove("in");

View File

@@ -4,9 +4,7 @@ export default class extends Controller {
static targets = ["reportType", "checkbox", "label"];
handleSelectChange() {
this.reportTypeTarget.value == "csv" ?
this.enableField():
this.disableField();
this.reportTypeTarget.value == "csv" ? this.enableField() : this.disableField();
}
disableField() {
@@ -27,4 +25,4 @@ export default class extends Controller {
this.labelTarget.classList.remove("disabled");
}
}
}
}

View File

@@ -10,12 +10,8 @@ export const useRenderCustomer = (controller) => {
${
item.bill_address.firstname
? `<strong>${I18n.t("bill_address")}</strong>
${item.bill_address.firstname} ${
item.bill_address.lastname
}<br>
${item.bill_address.address1}, ${
item.bill_address.address2
}<br>
${item.bill_address.firstname} ${item.bill_address.lastname}<br>
${item.bill_address.address1}, ${item.bill_address.address2}<br>
${item.bill_address.city}
<br>
${
@@ -27,8 +23,7 @@ export const useRenderCustomer = (controller) => {
}
${
item.bill_address.country &&
item.bill_address.country.name
item.bill_address.country && item.bill_address.country.name
? item.bill_address.country.name
: item.bill_address.country_name
}
@@ -41,9 +36,7 @@ export const useRenderCustomer = (controller) => {
renderWithNoBillAddress(item, escape) {
return `<div class='customer-autocomplete-item'>
<div class='customer-details'><h5>${escape(
item.email
)}</h5></div>
<div class='customer-details'><h5>${escape(item.email)}</h5></div>
</div>`;
},
});

View File

@@ -3,13 +3,15 @@ import { useOpenAndCloseAsAModal } from "./mixins/useOpenAndCloseAsAModal";
export default class extends Controller {
static targets = ["background", "modal"];
static values = { instant: { type: Boolean, default: false } }
static values = { instant: { type: Boolean, default: false } };
connect() {
useOpenAndCloseAsAModal(this);
window.addEventListener("modal:close", this.close.bind(this));
if (this.instantValue) { this.open() }
if (this.instantValue) {
this.open();
}
}
disconnect() {
@@ -17,6 +19,6 @@ export default class extends Controller {
}
remove(event) {
this.close(event, true)
this.close(event, true);
}
}

View File

@@ -7,7 +7,7 @@ export default class extends Controller {
let modal = document.getElementById(this.targetValue);
let modalController = this.application.getControllerForElementAndIdentifier(
modal,
this.getIdentifier()
this.getIdentifier(),
);
modalController.open();
}

View File

@@ -1,7 +1,7 @@
import { Controller } from "stimulus";
import L from "leaflet";
import LeafetProviders from "leaflet-providers";
import { OpenStreetMapProvider } from 'leaflet-geosearch';
import { OpenStreetMapProvider } from "leaflet-geosearch";
export default class extends Controller {
static targets = ["confirmAddressField", "dragPinNote"];
@@ -9,7 +9,7 @@ export default class extends Controller {
defaultLatitude: Number,
defaultLongitude: Number,
providerName: String,
providerOptions: Object
providerOptions: Object,
};
connect() {
@@ -23,7 +23,7 @@ export default class extends Controller {
async locateAddress() {
const results = await this.provider.search({ query: this.#addressQuery() });
if(results.length > 0) {
if (results.length > 0) {
const result = results[0];
this.#setLatitudeLongitude(result.y, result.x);
this.#addMarker(result.y, result.x);
@@ -46,13 +46,15 @@ export default class extends Controller {
// If someone clicks the locate address on map button without filling in their address the
// geocoded address will not be very accurate so don't zoom in too close so it's easier for
// people to see where the marker is.
if(!addressLine1 && !city && !zipcode) {
if (!addressLine1 && !city && !zipcode) {
this.zoomLevel = 6;
} else {
this.zoomLevel = 14;
}
return [addressLine1, addressLine2, city, state, zipcode, country].filter((value) => !!value).join(", ")
return [addressLine1, addressLine2, city, state, zipcode, country]
.filter((value) => !!value)
.join(", ");
}
#addMarker(latitude, longitude) {
@@ -72,13 +74,13 @@ export default class extends Controller {
#displayMap() {
// Don't initialise map in test environment because that could possibly abuse OSM tile servers
if(process.env.RAILS_ENV == "test") {
if (process.env.RAILS_ENV == "test") {
return false;
}
this.map = L.map('open-street-map')
L.tileLayer.provider(this.providerNameValue, this.providerOptionsValue).addTo(this.map)
this.map.setView([this.defaultLatitudeValue, this.defaultLongitudeValue], this.zoomLevel)
this.map = L.map("open-street-map");
L.tileLayer.provider(this.providerNameValue, this.providerOptionsValue).addTo(this.map);
this.map.setView([this.defaultLatitudeValue, this.defaultLongitudeValue], this.zoomLevel);
this.provider = new OpenStreetMapProvider();
}
@@ -88,12 +90,12 @@ export default class extends Controller {
#displayMapWhenAtRegistrationDetailsStep() {
const observer = new IntersectionObserver(
([intersectionObserverEntry]) => {
if(intersectionObserverEntry.target.offsetParent !== null) {
if (intersectionObserverEntry.target.offsetParent !== null) {
this.#displayMap();
observer.disconnect()
observer.disconnect();
}
},
{ threshold: [0] }
{ threshold: [0] },
);
observer.observe(document.getElementById("registration-details"));
}

View File

@@ -1,55 +1,58 @@
import { Controller } from "stimulus";
export default class extends Controller {
static targets = ['statusMessage', 'cancel']
static targets = ["statusMessage", "cancel"];
connect() {
this.observer = new MutationObserver(this.updateCallback);
this.observer.observe(
this.statusMessageTarget,
{ attributes: true, attributeOldValue: true, attributeFilter: ['data-type'] }
);
this.observer.observe(this.statusMessageTarget, {
attributes: true,
attributeOldValue: true,
attributeFilter: ["data-type"],
});
if (this.hasCancelTarget) {
this.cancelTarget.addEventListener('click', this.removeUnloadEvent)
this.cancelTarget.addEventListener("click", this.removeUnloadEvent);
}
}
// Callback to trigger warning modal
updateCallback(mutationsList) {
const newDataType = document.getElementById('status-message').getAttribute('data-type');
const actionName = document.getElementById('status-message').getAttribute('data-action-name');
if(!actionName) return;
const newDataType = document.getElementById("status-message").getAttribute("data-type");
const actionName = document.getElementById("status-message").getAttribute("data-action-name");
if (!actionName) return;
for(let mutation of mutationsList) {
if (mutation.type === 'attributes' && mutation.attributeName === 'data-type') {
for (let mutation of mutationsList) {
if (mutation.type === "attributes" && mutation.attributeName === "data-type") {
// Only trigger warning modal when notice display (notice) is preceeded by progress display (progress)
if(mutation.oldValue === 'progress' && newDataType === 'notice') {
if (mutation.oldValue === "progress" && newDataType === "notice") {
// Hide all confirmation buttons in warning modal
document.querySelectorAll(
'#linked-order-warning-modal .modal-actions button.secondary'
).forEach((node) => {
node.style.display = 'none';
});
document
.querySelectorAll("#linked-order-warning-modal .modal-actions button.secondary")
.forEach((node) => {
node.style.display = "none";
});
// Show the appropriate confirmation button, open warning modal, and return
document.querySelectorAll(
`#linked-order-warning-modal button[data-trigger-action=${actionName}]`
).forEach((node) => {
node.style.display = 'block';
})
document.querySelector('.warning-modal button.modal-target-trigger').click();
document
.querySelectorAll(
`#linked-order-warning-modal button[data-trigger-action=${actionName}]`,
)
.forEach((node) => {
node.style.display = "block";
});
document.querySelector(".warning-modal button.modal-target-trigger").click();
}
}
}
}
removeUnloadEvent() {
window.removeEventListener('beforeunload', window.onBeforeUnloadHandler)
window.removeEventListener("beforeunload", window.onBeforeUnloadHandler);
}
disconnect() {
this.observer.disconnect();
if (this.hasCancelTarget) {
this.cancelTarget.removeEventListener('click', this.removeUnloadEvent)
this.cancelTarget.removeEventListener("click", this.removeUnloadEvent);
}
}
}

View File

@@ -1,12 +1,14 @@
import { Controller } from "stimulus";
export default class extends Controller {
moveSelectors = [".off-canvas-wrap .inner-wrap",
".off-canvas-wrap .inner-wrap .fixed",
".off-canvas-fixed .top-bar",
".off-canvas-fixed ofn-flash",
".off-canvas-fixed nav.tab-bar",
".off-canvas-fixed .page-alert"];
moveSelectors = [
".off-canvas-wrap .inner-wrap",
".off-canvas-wrap .inner-wrap .fixed",
".off-canvas-fixed .top-bar",
".off-canvas-fixed ofn-flash",
".off-canvas-fixed nav.tab-bar",
".off-canvas-fixed .page-alert",
];
connect() {
// Wait a moment after page load before showing the alert. Otherwise we often miss the

View File

@@ -21,11 +21,8 @@ export default class extends Controller {
}
setPaymentMethod(paymentMethodContainerId) {
Array.from(
document.getElementsByClassName("paymentmethod-container")
).forEach((container) => {
const enabled =
container.dataset.paymentmethodId === paymentMethodContainerId;
Array.from(document.getElementsByClassName("paymentmethod-container")).forEach((container) => {
const enabled = container.dataset.paymentmethodId === paymentMethodContainerId;
if (enabled) {
container.style.display = "block";

View File

@@ -12,9 +12,7 @@ export default class extends Controller {
this.hideAvailability();
this.showSpinner();
const response = await fetch(
this.urlValue + `?permalink="${this.permalinkFieldTarget.value}"`
);
const response = await fetch(this.urlValue + `?permalink="${this.permalinkFieldTarget.value}"`);
const result = await response.text();
if (this.initialPermalinkValue == result) {

View File

@@ -4,8 +4,8 @@ import { Controller } from "stimulus";
export default class PopoutController extends Controller {
static targets = ["button", "dialog"];
static values = {
updateDisplay: { Boolean, default: true }
}
updateDisplay: { Boolean, default: true },
};
connect() {
this.displayElements = Array.from(this.element.querySelectorAll('input:not([type="hidden"]'));

View File

@@ -23,7 +23,7 @@ export default class extends Controller {
{
method: "GET",
headers: { "Content-type": "application/json; charset=UTF-8" },
}
},
)
.then((data) => data.json())
.then((operation) => {

View File

@@ -18,11 +18,11 @@ export default class extends ApplicationController {
}
delete_product() {
this.#deleteByRecordType('product');
this.#deleteByRecordType("product");
}
delete_variant() {
this.#deleteByRecordType('variant');
this.#deleteByRecordType("variant");
}
showLoading = () => {
@@ -44,51 +44,52 @@ export default class extends ApplicationController {
getLoadingController = () => {
return (this.loadingController ||= this.application.getControllerForElementAndIdentifier(
this.loadingTarget,
"loading"
"loading",
));
};
// +recordType+ can either be 'product' or 'variant'
#deleteByRecordType(recordType) {
const deletePath = document.querySelector(`#${recordType}-delete-modal #modal-confirm-button`).getAttribute('data-delete-path');
const deletePath = document
.querySelector(`#${recordType}-delete-modal #modal-confirm-button`)
.getAttribute("data-delete-path");
const elementToBeRemoved = this.#getElementToBeRemoved(deletePath, recordType);
const handleSlideOutAnimationEnd = async () => {
// in case of test env, we won't be having csrf token
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute("content");
try {
const response = await fetch(deletePath, {
method: 'DELETE',
method: "DELETE",
headers: {
Accept: 'text/vnd.turbo-stream.html',
'X-CSRF-Token': csrfToken,
}
Accept: "text/vnd.turbo-stream.html",
"X-CSRF-Token": csrfToken,
},
});
// need to render the turboStream message, that's why not throwing error here
if(response.status === 500) elementToBeRemoved.classList.remove('slide-out');
// need to render the turboStream message, that's why not throwing error here
if (response.status === 500) elementToBeRemoved.classList.remove("slide-out");
const responseTurboStream = await response.text();
Turbo.renderStreamMessage(responseTurboStream);
} catch(error) {
} catch (error) {
console.error(error.message);
elementToBeRemoved.classList.remove('slide-out');
}
finally {
elementToBeRemoved.removeEventListener('animationend', handleSlideOutAnimationEnd);
elementToBeRemoved.classList.remove("slide-out");
} finally {
elementToBeRemoved.removeEventListener("animationend", handleSlideOutAnimationEnd);
}
};
// remove the clone animation before deleting
elementToBeRemoved.classList.remove('slide-in');
elementToBeRemoved.classList.add('slide-out');
elementToBeRemoved.addEventListener('animationend', handleSlideOutAnimationEnd);
};
elementToBeRemoved.classList.remove("slide-in");
elementToBeRemoved.classList.add("slide-out");
elementToBeRemoved.addEventListener("animationend", handleSlideOutAnimationEnd);
}
#getElementToBeRemoved(path, recordType) {
const recordId = path.substring(path.lastIndexOf('/') + 1);
const recordId = path.substring(path.lastIndexOf("/") + 1);
const elementDomId = `${recordType}_${recordId}`;
return document.getElementById(elementDomId);
};
}
}

View File

@@ -12,7 +12,7 @@ export default class extends Controller {
received(data) {
if (data.cableReady) CableReady.perform(data.operations);
},
}
},
);
}

View File

@@ -3,16 +3,12 @@ import ApplicationController from "./application_controller";
export default class extends ApplicationController {
connect() {
super.connect();
this.element
.querySelector("input")
.addEventListener("keydown", this.searchOnEnter);
this.element.querySelector("input").addEventListener("keydown", this.searchOnEnter);
}
disconnect() {
super.disconnect();
this.element
.querySelector("input")
.removeEventListener("keydown", this.searchOnEnter);
this.element.querySelector("input").removeEventListener("keydown", this.searchOnEnter);
}
searchOnEnter = (e) => {
@@ -22,7 +18,6 @@ export default class extends ApplicationController {
};
search(e) {
this.element.querySelector(".search-button").dataset["value"] =
e.target.value;
this.element.querySelector(".search-button").dataset["value"] = e.target.value;
}
}

View File

@@ -42,11 +42,11 @@ export default class extends TomSelectController {
});
this.setValueOnTomSelectController(
document.querySelector(attribute_wrapper + "state_id"),
data ? data.state_id : ""
data ? data.state_id : "",
);
this.setValueOnTomSelectController(
document.querySelector(attribute_wrapper + "country_id"),
data ? data.country_id : ""
data ? data.country_id : "",
);
});
document.querySelector("#order_email").value = customer.email;

View File

@@ -7,9 +7,7 @@ export default class extends SelectorController {
const query = event.target.value;
this.itemsTargets.forEach((el, i) => {
el.style.display = el.textContent.toLowerCase().includes(query)
? ""
: "none";
el.style.display = el.textContent.toLowerCase().includes(query) ? "" : "none";
});
};
}

View File

@@ -17,13 +17,10 @@ export default class extends Controller {
});
// but not the one we want ie. the one that matches the shipping method id
this.shippingMethodDescriptionTargets.find(
(e) => e.dataset["shippingmethodid"] == input.value
(e) => e.dataset["shippingmethodid"] == input.value,
).style.display = "block";
// -- Require a ship address
if (
input.dataset.requireaddress === "true" &&
!this.shippingAddressCheckboxTarget.checked
) {
if (input.dataset.requireaddress === "true" && !this.shippingAddressCheckboxTarget.checked) {
this.shippingMethodAddressTarget.style.display = "block";
} else {
this.shippingMethodAddressTarget.style.display = "none";

View File

@@ -17,7 +17,7 @@ export default class extends Controller {
([e]) => {
e.target.classList.toggle("sticked", e.intersectionRatio < 1);
},
{ threshold: [1] }
{ threshold: [1] },
);
observer.observe(this.containerTarget);
}

View File

@@ -1,15 +1,7 @@
import { Controller } from "stimulus";
export default class extends Controller {
static targets = [
"cardElement",
"cardErrors",
"expMonth",
"expYear",
"brand",
"last4",
"pmId",
];
static targets = ["cardElement", "cardErrors", "expMonth", "expYear", "brand", "last4", "pmId"];
static styles = {
base: {
fontFamily: "Roboto, Arial, sans-serif",
@@ -27,12 +19,10 @@ export default class extends Controller {
// Initialize Stripe JS
this.stripe = Stripe(this.data.get("key"));
this.stripeElement = this.stripe
.elements({ locale: I18n.base_locale })
.create("card", {
style: this.constructor.styles,
hidePostalCode: true,
});
this.stripeElement = this.stripe.elements({ locale: I18n.base_locale }).create("card", {
style: this.constructor.styles,
hidePostalCode: true,
});
// Mount Stripe Elements JS to the form field
this.stripeElement.mount(this.cardElementTarget);
@@ -58,34 +48,20 @@ export default class extends Controller {
event.preventDefault();
event.stopPropagation();
this.stripe
.createPaymentMethod({ type: "card", card: this.stripeElement })
.then((response) => {
if (response.error) {
this.updateErrors(response);
} else {
this.pmIdTarget.setAttribute("value", response.paymentMethod.id);
this.expMonthTarget.setAttribute(
"value",
response.paymentMethod.card.exp_month
);
this.expYearTarget.setAttribute(
"value",
response.paymentMethod.card.exp_year
);
this.brandTarget.setAttribute(
"value",
response.paymentMethod.card.brand
);
this.last4Target.setAttribute(
"value",
response.paymentMethod.card.last4
);
this.catchFormSubmit = false;
this.stripe.createPaymentMethod({ type: "card", card: this.stripeElement }).then((response) => {
if (response.error) {
this.updateErrors(response);
} else {
this.pmIdTarget.setAttribute("value", response.paymentMethod.id);
this.expMonthTarget.setAttribute("value", response.paymentMethod.card.exp_month);
this.expYearTarget.setAttribute("value", response.paymentMethod.card.exp_year);
this.brandTarget.setAttribute("value", response.paymentMethod.card.brand);
this.last4Target.setAttribute("value", response.paymentMethod.card.last4);
this.catchFormSubmit = false;
event.submitter.click();
}
});
event.submitter.click();
}
});
};
// Update validation messages from Stripe shown in the form

View File

@@ -17,10 +17,7 @@ export default class extends ApplicationController {
let confirmation = confirm(this.messageValue);
if (confirmation) {
location.hash = "";
this.stimulate(
"EnterpriseEdit#remove_terms_and_conditions",
event.target
);
this.stimulate("EnterpriseEdit#remove_terms_and_conditions", event.target);
}
}

View File

@@ -1,6 +1,6 @@
import { Controller } from "stimulus";
const BUTTON_TYPES = ['submit', 'button'];
const BUTTON_TYPES = ["submit", "button"];
// Toggle state of a control based on a condition.
//
@@ -65,7 +65,7 @@ export default class extends Controller {
#toggleDisplay(show) {
this.controlTargets.forEach((target) => {
target.style.display = (show ? "block" : "none");
target.style.display = show ? "block" : "none";
});
// Focus first when displayed
@@ -83,6 +83,6 @@ export default class extends Controller {
#focusFieldControl() {
const control = this.controlTargets[0];
const isButton = BUTTON_TYPES.includes(control.type);
if(!isButton) control.focus();
if (!isButton) control.focus();
}
}

View File

@@ -20,7 +20,7 @@ export default class extends Controller {
#trixActionInvoke = (event) => {
if (event.actionName === "hr") {
this.element.editor.insertAttachment(
new Trix.Attachment({ content: "<hr />", contentType: "text/html" })
new Trix.Attachment({ content: "<hr />", contentType: "text/html" }),
);
}
};
@@ -39,7 +39,7 @@ export default class extends Controller {
const button_html = `
<button type="button" class="trix-button trix-button--icon trix-button--icon-hr" data-trix-action="hr" title="Horizontal Rule" tabindex="-1">HR</button>`;
const buttonGroup = this.element.toolbarElement.querySelector(
".trix-button-group--block-tools"
".trix-button-group--block-tools",
);
buttonGroup.insertAdjacentHTML("beforeend", button_html);
buttonGroup.querySelector(".trix-button--icon-hr").addEventListener("click", (event) => {

View File

@@ -34,11 +34,9 @@ import { Controller } from "stimulus";
export default class extends Controller {
connect() {
// add onChange event to all form element
this.element
.querySelectorAll("input, select, textarea")
.forEach((input) => {
input.addEventListener("change", this.formIsChanged.bind(this));
});
this.element.querySelectorAll("input, select, textarea").forEach((input) => {
input.addEventListener("change", this.formIsChanged.bind(this));
});
this.element.addEventListener("submit", this.handleSubmit.bind(this));

View File

@@ -21,7 +21,11 @@ a.stripe-connect {
line-height: 30px;
color: white;
font-weight: bold;
font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
font-family:
Helvetica Neue,
Helvetica,
Arial,
sans-serif;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
border-radius: 3px;

View File

@@ -63,6 +63,6 @@ form.order_cycle {
}
}
#linked-order-warning-modal .reveal-modal{
#linked-order-warning-modal .reveal-modal {
width: 28rem;
}
}

View File

@@ -28,7 +28,8 @@
@font-face {
font-family: "FontAwesome";
src: url("../fonts/fontawesome-webfont.eot?v=3.2.1");
src: url("../fonts/fontawesome-webfont.eot?#iefix&v=3.2.1") format("embedded-opentype"),
src:
url("../fonts/fontawesome-webfont.eot?#iefix&v=3.2.1") format("embedded-opentype"),
url("../fonts/fontawesome-webfont.woff?v=3.2.1") format("woff"),
url("../fonts/fontawesome-webfont.ttf?v=3.2.1") format("truetype"),
url("../fonts/fontawesome-webfont.svg#fontawesomeregular?v=3.2.1") format("svg");

View File

@@ -184,8 +184,9 @@
}
// Hide columns
$columns: "image", "name", "sku", "unit_scale", "unit", "price", "on_hand", "producer",
"category", "tax_category", "tags", "inherits_properties";
$columns:
"image", "name", "sku", "unit_scale", "unit", "price", "on_hand", "producer", "category",
"tax_category", "tags", "inherits_properties";
@each $col in $columns {
&.hide-#{$col} {
.col-#{$col} {

View File

@@ -67,7 +67,8 @@ table.report__table {
#report-table {
margin-bottom: 4em;
.loading, .download {
.loading,
.download {
text-align: center;
height: 2em;
padding: 4em;

View File

@@ -187,7 +187,6 @@
font-size: 13px;
}
&[open] >,
details[open] > {
summary:after {

View File

@@ -1,7 +1,7 @@
.select2-container {
border: $border-input;
border-radius: $border-radius;
padding-bottom: 7px; // hack to make the height match other inputs
padding-bottom: 7px; // hack to make the height match other inputs
}
.select2-container {

View File

@@ -184,7 +184,7 @@
height: auto;
min-height: 0;
.ts-control {
.ts-control {
padding: ($vpadding-txt - 1px) ($hpadding-txt - 1px); // Minus 1px for border
height: auto;
@@ -227,7 +227,8 @@
// Display as "changed" if sibling select is marked as changed.
select.changed + .ts-wrapper {
&.single, &.multi {
&.single,
&.multi {
.ts-control {
border-color: $color-txt-changed-brd;
}

View File

@@ -195,7 +195,6 @@ div.dashboard_item {
&:focus {
border-color: $color-btn-hover-bg;
}
}
&:hover {

View File

@@ -1,4 +1,4 @@
// Popout widget
// Popout widget
@mixin unit_popout {
position: relative;
@@ -84,4 +84,3 @@
}
}
}

View File

@@ -1,4 +1,3 @@
#dfc_product_imports {
// Ensure label reaches to edge of table cell
td:has(> label) {
@@ -9,4 +8,4 @@
padding: 7px 5px;
font-size: inherit;
}
}
}

View File

@@ -1,7 +1,6 @@
@import "unit_popout";
#edit_variant {
.popout {
@include unit_popout;

View File

@@ -21,7 +21,6 @@ textarea {
font-size: 14px;
line-height: 22px;
// Appears just like other text on the page.
// See table.products tr:hover for example of revealing them
.naked_inputs & {

View File

@@ -134,6 +134,6 @@
// Text Colors
.black-text {
color: $near-black
color: $near-black;
}
//------------

View File

@@ -11,8 +11,6 @@
#cart-detail {
width: 100%;
display: block;
overflow-x: auto;
.cart-item-delete,
.bought-item-delete {

View File

@@ -1,10 +1,13 @@
// Call Matomo on asynchronous page loads
["turbo:load", "ujs:afterMorph"].forEach((listener) =>
document.addEventListener(listener, (event) => {
if (typeof event?.detail?.timing === "object" && Object.keys(event?.detail?.timing).length === 0) {
if (
typeof event?.detail?.timing === "object" &&
Object.keys(event?.detail?.timing).length === 0
) {
return;
}
window._mtm?.push({ "event": "mtm.PageView" });
})
window._mtm?.push({ event: "mtm.PageView" });
}),
);

View File

@@ -19,4 +19,3 @@ document.addEventListener("trix-before-initialize", (event) => {
document.addEventListener("trix-file-accept", (event) => {
event.preventDefault();
});

View File

@@ -35,6 +35,7 @@ module Openfoodnetwork
config.active_record.yaml_column_permitted_classes = [BigDecimal, Symbol, Time,
ActiveSupport::TimeWithZone,
ActiveSupport::TimeZone]
config.active_support.cache_format_version = 7.0
# Please, add to the `ignore` list any other `lib` subdirectories that do
# not contain `.rb` files, or that should not be reloaded or eager loaded.

View File

@@ -33,7 +33,7 @@ Rails.application.configure do
# Enable/disable caching. By default caching is disabled.
# Run rails dev:cache to toggle caching.
if Rails.root.join("tmp/caching-dev.txt").exist? || !ENV["PROFILE"] || !!ENV["DEV_CACHING"]
if Rails.root.join("tmp/caching-dev.txt").exist? || !!ENV["PROFILE"] || !!ENV["DEV_CACHING"]
config.action_controller.perform_caching = true
config.action_controller.enable_fragment_cache_logging = true

View File

@@ -74,9 +74,6 @@ Rails.application.configure do
allowed_warnings = [
# List strings here to allow matching deprecations.
#
# https://guides.rubyonrails.org/upgrading_ruby_on_rails.html#new-activesupport-cache-serialization-format
"config.active_support.cache_format_version",
# `Rails.application.secrets` is deprecated in favor of `Rails.application.credentials` and will be removed in Rails 7.2
"Rails.application.secrets",

View File

@@ -93,16 +93,6 @@
# }
# ** Please read carefully, this must be configured in config/application.rb **
# Change the format of the cache entry.
# Changing this default means that all new cache entries added to the cache
# will have a different format that is not supported by Rails 6.1 applications.
# Only change this value after your application is fully deployed to Rails 7.0
# and you have no plans to rollback.
# When you're ready to change format, add this to `config/application.rb` (NOT this file):
# config.active_support.cache_format_version = 7.0
# Cookie serializer: 2 options
#
# If you're upgrading and haven't set `cookies_serializer` previously, your cookie serializer

View File

@@ -273,7 +273,12 @@ de_CH:
Wir werden uns darum kümmern, aber lassen Sie uns bitte wissen, wenn das Problem weiterhin besteht.
backorder_mailer:
backorder_failed:
subject: "Eine automatische Nachbestellung ist fehlgeschlagen"
headline: "Nachbestellung fehlgeschlagen"
order: "Betroffene Bestellung: %{number}"
product: "Produkt"
backorder_incomplete:
affected: "%{enterprise} : %{order_cycle}"
enterprise_mailer:
confirmation_instructions:
subject: "Bitte bestätigen Sie die E-Mail-Adresse von %{enterprise} im Open Food Network"
@@ -1291,7 +1296,8 @@ de_CH:
re_notify_producers: Produzenten erneut benachrichtigen
notify_producers_tip: Benachrichtigen Sie die Produzenten per E-Mail über in diesem Bestellzyklus erhaltene Bestellungen.
date_time_warning_modal_content:
cancel: 'Stornieren'
content: 'Wenn Sie einen neuen Bestellzyklus erstellen möchten, empfiehlt es sich, den Bestellzyklus zunächst zu duplizieren und dann die Daten zu ändern.'
cancel: 'Abbrechen'
incoming:
incoming: "Eingehend"
supplier: "Lieferant"
@@ -1318,9 +1324,10 @@ de_CH:
back_to_list: "Zurück zur Liste"
checkout_options:
back_end: "Nur im Backoffice"
cancel: "Stornieren"
cancel: "Abbrechen"
checkout_options: "Checkout Optionen"
distributor: "Verteilstelle"
no_payment_methods: Jeder Händler in diesem Bestellzyklus benötigt mindestens eine Zahlungsmethode.
payment_methods: "Zahlungsarten"
save: "Speichern"
save_and_back_to_list: "Speichern und zurück zur Liste"
@@ -1635,7 +1642,7 @@ de_CH:
unpause_failure_msg: "Die Fortsetzung des Abonnements ist fehlgeschlagen."
confirm_cancel_open_orders_msg: "Einige Bestellungen für dieses Abonnement sind derzeit offen. Der Kunde wurde bereits informiert, dass die Bestellung aufgegeben wird. Möchten Sie diese Bestellung(en) stornieren oder erhalten?"
resume_canceled_orders_msg: "Einige Bestellungen dieses Abonnements können jetzt fortgesetzt werden. Sie können sie im Bestellungen-Dropdown-Menü wiederaufnehmen."
yes_cancel_them: Stornieren
yes_cancel_them: Abbrechen
no_keep_them: Erhalten
yes_i_am_sure: Ja, ich bin mir sicher.
number: "Bestellnummer"
@@ -1665,6 +1672,12 @@ de_CH:
remove_white_label_logo_success: "Das Logo wurde erfolgreich gelöscht."
stripe_connect_settings:
resource: Konfiguration für Stripe Connect
resend_confirmation_emails_feedback:
one: "Bestätigungs-E-Mail für 1 Bestellung gesendet."
other: "Bestätigungs-E-Mails für %{count} Bestellungen gesendet."
send_invoice_feedback:
one: "Rechnungs-E-Mail für 1 Bestellung gesendet."
other: "Rechnungs-E-Mails für %{count} Bestellungen gesendet."
api:
unknown_error: "Etwas ist schief gelaufen. Unser Team wurde benachrichtigt."
invalid_api_key: "Ungültiger API-Schlüssel (%{key}) angegeben."
@@ -1757,6 +1770,7 @@ de_CH:
title: Zahlungsart
edit: Bearbeiten
order:
title: Bestelldetails
edit: Bearbeiten
terms_and_conditions:
message_html: "Ich stimme den %{terms_and_conditions_link} des Verkäufers zu."
@@ -2350,6 +2364,7 @@ de_CH:
orders_bought_already_confirmed: "* schon bestätigt"
orders_confirm_cancel: "Sind Sie sicher, dass Sie diese Bestellung stornieren möchten?"
order_processed_successfully: "Ihre Bestellung wurde erfolgreich verarbeitet."
thank_you_for_your_order: "Vielen Dank für Ihre Bestellung"
products_cart_distributor_choice: "Verteilstelle Ihrer Bestellung:"
products_cart_distributor_change: "Die Verteilstelle für diese Bestellung wird in %{name} geändert, wenn Sie dieses Produkt zu Ihrem Warenkorb hinzufügen."
products_cart_distributor_is: "Die Verteilstelle dieser Bestellung ist %{name}."
@@ -2906,6 +2921,7 @@ de_CH:
report_header_total_taxable_admin: Summe steuerpflichtiger Admin-Anpassungen (inkl. MwSt.)
report_header_voucher_label: Gutscheinetikett
report_header_voucher_amount: "Gutscheinbetrag ( %{currency_symbol} )"
report_header_last_completed_order_date: Datum der letzten abgeschlossenen Bestellung
report_xero_configuration: Xero-Konfiguration
initial_invoice_number: "Ursprüngliche Rechnungsnummer"
invoice_date: "Rechnungsdatum"
@@ -3024,9 +3040,10 @@ de_CH:
deleting_item_will_cancel_order: "Das Löschen dieses Produkts führt zu einer oder mehreren leeren Bestellungen, die daher automatisch storniert werden. Möchten Sie fortfahren?"
modals:
got_it: "Verstanden"
confirm: "Bestätigen"
close: "Schliessen"
continue: "Weiter"
cancel: "Stornieren"
cancel: "Abbrechen"
invite: "Einladen"
invite_title: "Geben Sie die E-Mail-Adresse eines nicht registrierten Benutzers ein, um dieses Unternehmen zu verwalten."
tag_rule_help:
@@ -3496,6 +3513,7 @@ de_CH:
previous: "Vorherige"
last: "Letzte"
spree:
order_updated: "Bestellung aktualisiert"
add_country: "Neues Land"
add_state: "Neuer Kanton"
adjustment: "Anpassung"
@@ -3841,9 +3859,14 @@ de_CH:
results_found: "%{number} Ergebnisse gefunden."
viewing: "Angezeigt wird %{start} bis %{end}."
print_invoices: "Rechnungen drucken"
cancel_orders: "Bestellungen stornieren"
resend_confirmation: "Bestätigung erneut senden"
resend_confirmation_confirm_html: "Dadurch wird die Bestätigungs-E-Mail erneut an den Kunden gesendet.<br /> Möchten Sie wirklich fortfahren?"
send_invoice: "Rechnungen senden"
selected:
zero: "Keine Bestellung ausgewählt"
one: "1 Bestellung ausgewählt"
other: "%{count} Bestellungen ausgewählt"
sortable_header:
payment_state: "Zahlungsstatus"
shipment_state: "Lieferstatus"
@@ -4279,7 +4302,7 @@ de_CH:
items: Artikel
total: Gesamt
edit: Bearbeiten
cancel: Stornieren
cancel: Abbrechen
closed: Abgeschlossen
until: Bis
past_orders:

View File

@@ -1503,6 +1503,10 @@ en_CA:
invite_manager:
user_already_exists: "User already exists"
error: "Something went wrong"
tag_rules:
not_supported_type: Tag rule type not supported
confirm_delete: Are you sure you want to delete this rule ?
destroy_error: There was an issue when removing the Tag rule
order_cycles:
loading_flash:
loading_order_cycles: LOADING ORDER CYCLES

View File

@@ -31,6 +31,11 @@ module DfcProvider
)
end
def show
product = SuppliedProductBuilder.supplied_product(variant)
render json: DfcIo.export(product)
end
def create
supplied_product = import&.first
@@ -45,11 +50,6 @@ module DfcProvider
render json: DfcIo.export(supplied_product)
end
def show
product = SuppliedProductBuilder.supplied_product(variant)
render json: DfcIo.export(product)
end
def update
supplied_product = import&.first

View File

@@ -18,6 +18,8 @@ module OrderManagement
end
def call!(return_url = off_session_return_url)
# if the payment requires_authorization (3D Secure), can't be authorized again
return payment if payment&.requires_authorization?
return unless payment&.checkout?
payment.authorize!(return_url)

View File

@@ -19,6 +19,15 @@ module OrderManagement
end
end
context "when the payment already requires 3D Secure authorization" do
let(:payment) { create(:payment, amount: 10, state: 'requires_authorization') }
before { allow(order).to receive(:pending_payments).once { [payment] } }
it "returns the payment without authorizing because it has already been authorized" do
expect(payment_authorize.call!).to eq payment
end
end
context "when a payment is present" do
let(:payment) { create(:payment, amount: 10) }

View File

@@ -7,6 +7,7 @@ module Web
module V0
class CookiesConsentController < BaseController
include ActionController::Cookies
respond_to :json
def show

View File

@@ -15,7 +15,7 @@ module Reporting
# Here the query_result is already the expected result, so we just create
# a fake columns method to copy the sql result into the row result
def columns
report_data.columns.map { |field| [field.to_sym, proc { |data| data[field] }] }.to_h
report_data.columns.to_h{ |field| [field.to_sym, proc { |data| data[field] }] }
end
def search

Some files were not shown because too many files have changed in this diff Show More