Compare commits

..

232 Commits

Author SHA1 Message Date
Matt-Yorkley
50ab0731d7 Bump nokogiri to 1.13.2 2022-02-26 14:39:56 +00:00
Matt-Yorkley
0b616aa9ce Update all locales with the latest Transifex translations 2022-02-24 23:34:16 +00:00
Filipe
36e3f1b7a6 Merge pull request #8883 from jibees/8475-send-email-when-payment-needs-authorization
Backoffice order, using stripe payment: when card requires auth, send authorization email to guest user
2022-02-24 13:07:31 +00:00
Matt-Yorkley
d945e69404 Merge pull request #8918 from openfoodfoundation/dependabot/npm_and_yarn/url-parse-1.5.7
Bump url-parse from 1.5.3 to 1.5.7
2022-02-22 08:17:02 +00:00
Filipe
385cd49964 Merge pull request #8876 from SarvarKh/product-import-validation
Fix product import on existing, empty unit_type and variant_unit
2022-02-21 23:20:04 +00:00
Filipe
28ac9d980c Merge pull request #8849 from jibees/render-pdf-with-stylesheet
Create a new method pdf_stylesheet_pack_tag that actually include CSS in PDF files
2022-02-21 23:09:21 +00:00
Filipe
dbf5eb76f8 Merge pull request #8689 from apricot12/Transaction_fee_when_crediting
Revoke transaction fee if there is an amount to be credited in order
2022-02-21 20:30:19 +00:00
Filipe
89dc9b938b Merge pull request #8864 from jibees/7934-display-tax-rate-for-shipping-on-invoice
Display tax rate for shipping in alternative invoice model
2022-02-21 20:02:44 +00:00
Filipe
7590b3ecf8 Merge pull request #8756 from jibees/8075-take-into-account-the-inherits_properties-attribute
Product that don't inherits from "producer"/"enterprise" properties should be filtered out by user on shop page
2022-02-21 19:04:08 +00:00
Filipe
9966b5b33c Merge pull request #8565 from jibees/8171-group-by-imperial-unit
Handle imperial units in the Bulk Order Management interface
2022-02-21 14:47:38 +00:00
dependabot[bot]
07d20d2ba0 Bump url-parse from 1.5.3 to 1.5.7
Bumps [url-parse](https://github.com/unshiftio/url-parse) from 1.5.3 to 1.5.7.
- [Release notes](https://github.com/unshiftio/url-parse/releases)
- [Commits](https://github.com/unshiftio/url-parse/compare/1.5.3...1.5.7)

---
updated-dependencies:
- dependency-name: url-parse
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-19 09:25:58 +00:00
Matt-Yorkley
6c695df917 Merge pull request #8895 from Matt-Yorkley/cloned-subscription-syncing
Sync subscriptions on newly-cloned order cycles
2022-02-17 12:44:39 +00:00
Matt-Yorkley
9a27addd14 Merge pull request #8763 from openfoodfoundation/8577-split-name-column-in-customers-table
Split name column in customers table
2022-02-17 11:57:01 +00:00
Filipe
a6c5d8ca73 Merge pull request #8673 from filipefurtad0/split_checkout_auth_spec
Adds split-checkout toggling lines
2022-02-17 11:10:44 +00:00
Filipe
4dbf047647 Merge pull request #8871 from jibees/8827-preselect-shipping-method
SplitCheckout: preselect the shipping/payment method if the only one available
2022-02-17 10:54:20 +00:00
Jean-Baptiste Bellet
bcd306ebd4 Authorize payment email could be send to guest user
Always send the email to the order.email value
2022-02-17 09:40:28 +01:00
Jean-Baptiste Bellet
012e91879a preselect the only available shipping method 2022-02-17 09:33:23 +01:00
Jean-Baptiste Bellet
716286497e Add test to cover "preselect the shipping method" if only one is available
+ do not preselect if more than one are available
2022-02-17 09:33:23 +01:00
Jean-Baptiste Bellet
7be2f418d0 preselect the only available payment method 2022-02-17 09:33:23 +01:00
Jean-Baptiste Bellet
0e053a2601 Add test to cover "preselect the payment method" if only one is available
+ do not preselect if more than one
2022-02-17 09:33:23 +01:00
Matt-Yorkley
00fa84e3b5 Sync when switching from nil dates to open 2022-02-16 21:45:43 +00:00
Matt-Yorkley
5913720c85 Sync for both open and upcoming OCs when switching from closed 2022-02-16 18:33:09 +00:00
Matt-Yorkley
4592827261 Sync OC subscriptions if transitioning from closed to open 2022-02-16 13:03:27 +00:00
Matt-Yorkley
4260422ea7 Remove a couple of unnecessary memory assignments 2022-02-16 12:55:19 +00:00
Matt-Yorkley
d4488fdb3f Return early if OC is closed 2022-02-16 12:53:22 +00:00
Matt-Yorkley
8c8b9d1b23 Sync subscriptions on newly-cloned order cycles 2022-02-16 10:44:22 +00:00
SarvarKhalimov
22de758e3a Add spec for product import validation 2022-02-16 14:17:35 +05:00
Maikel Linke
33969de371 Allow shared_examples to have more than 25 lines 2022-02-16 11:41:28 +11:00
Maikel Linke
a6dee77071 Style 2022-02-16 10:33:49 +11:00
filipefurtad0
78946f908a Adds shared examples; sets conditional filters on test cases 2022-02-15 23:23:31 +00:00
Matt-Yorkley
4c50ca69ea Improve data migration logic and add test coverage 2022-02-16 10:23:24 +11:00
Matt-Yorkley
fd815a6af6 Don't change Customer factory name generating logic 2022-02-16 10:23:24 +11:00
Matt-Yorkley
feaa92406a Split migration into two parts for easier testing 2022-02-16 10:23:24 +11:00
Maikel Linke
68193efcf6 Keep old customers.name column for compatibilty
Our app code will try to access the old attribute while the migration is
running. That would lead to errors during checkout.
2022-02-16 10:23:24 +11:00
François Turbelin
9a12957e27 Handle the empty-space name on customers 2022-02-16 10:23:23 +11:00
François Turbelin
de4d074cb3 Remove bill_address fetching logic 2022-02-16 10:23:23 +11:00
Maikel Linke
d09ba16411 Associate customers again
And simplify the before_validation actions.
2022-02-16 10:23:23 +11:00
Maikel Linke
07314af3f6 Spec customer record association more realistically
The newly added specs were tested on the master branch and passed. But
the previous commit broke one test case which I marked as pending here.

The removed specs are completely replaced by the new ones. Their main
downside was to test only small bits of internal behaviour without
considering the whole callback chain of the order. The new specs are
more realistic and catch bugs like mentioned above.
2022-02-16 10:23:23 +11:00
François Turbelin
554a8625e5 Refactor ensure_customer method 2022-02-16 10:23:23 +11:00
François Turbelin
5c9dd81595 Deal with nil attirubtes on bill_address 2022-02-16 10:23:23 +11:00
François Turbelin
6d986deb2d Remove translation changes from locale file 2022-02-16 10:23:23 +11:00
François Turbelin
4cb31d04a7 Repair specs with default values on ensure_customer method 2022-02-16 10:23:23 +11:00
François Turbelin
50302163c0 Update migration with better logic and cosmetics 2022-02-16 10:23:23 +11:00
François Turbelin
9682b9256b Arrange classes loading for good migration 2022-02-16 10:23:23 +11:00
François Turbelin
d016c47789 Refactor data migration to use data sets 2022-02-16 10:23:23 +11:00
François Turbelin
b8afb7ec4d Add default values for new fields 2022-02-16 10:23:23 +11:00
François Turbelin
836a60a6c7 Add missing full_name bind to subscriptions serializer 2022-02-16 10:23:23 +11:00
François Turbelin
23776c7a3e Fix more specs 2022-02-16 10:23:23 +11:00
François Turbelin
75345a95af Update customer factory 2022-02-16 10:23:22 +11:00
François Turbelin
eefd9891d6 Add en translations 2022-02-16 10:23:22 +11:00
François Turbelin
7c25127ab6 Improve first_name and last_name setup 2022-02-16 10:23:22 +11:00
Adrien Chauve
ca46359224 More fixes 2022-02-16 10:23:22 +11:00
Adrien Chauve
9b93102a96 More fixes 2022-02-16 10:23:22 +11:00
Adrien Chauve
ba6523bb76 Add Customer.full_name 2022-02-16 10:23:22 +11:00
Adrien Chauve
5ca4d549e7 Update customer creation 2022-02-16 10:23:22 +11:00
Adrien Chauve
d0f347efaa Add migration to split Customers.name into first and last names 2022-02-16 10:23:22 +11:00
Jean-Baptiste Bellet
405b7e6e17 Handle tax rates for ShippingMethod
Co-Authored-By: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com>
2022-02-15 15:16:58 +01:00
Matt-Yorkley
711a51f2ff Remove .eligible scope
In this case we actually expect there to be no payment fee adjustments at all on the payment, regardless of their eligibility.
2022-02-15 12:24:28 +00:00
Matt-Yorkley
5fba7811c4 Remove #try
#try is useful when the object might be nil or might not respond to the given method. In this case we expect it to exist and respond to #finalized?, so this is a bit more precise.
2022-02-15 12:21:34 +00:00
Matt-Yorkley
5be1b139b9 Replace .stub with expect(x).to receive(:y)
The #stub method is slightly deprecated syntax. Using #expect has the additional benefit here of failing if the object does not receive the expected method call.
2022-02-15 12:19:15 +00:00
Matt-Yorkley
8084ad0068 Extract a comment-method so the code conveys it's purpose 2022-02-15 12:17:08 +00:00
Nihal M. Kelanthodika
b017420319 Add specs to check ensure payment method fee is not applied when crediting/refunding order 2022-02-15 11:52:26 +00:00
Nihal M. Kelanthodika
9215ccc353 Prevents creation of payment adnustment when refunding or crediting an order 2022-02-15 11:52:26 +00:00
Matt-Yorkley
7c7a09a75c Merge pull request #8880 from openfoodfoundation/dependabot/npm_and_yarn/storybook/addon-controls-6.4.19
Bump @storybook/addon-controls from 6.4.18 to 6.4.19
2022-02-15 11:33:04 +00:00
Matt-Yorkley
0d2374f07e Merge pull request #8881 from openfoodfoundation/dependabot/npm_and_yarn/storybook/server-6.4.19
Bump @storybook/server from 6.4.18 to 6.4.19
2022-02-15 11:32:47 +00:00
dependabot[bot]
1b7d72ffa7 Bump @storybook/server from 6.4.18 to 6.4.19
Bumps [@storybook/server](https://github.com/storybookjs/storybook/tree/HEAD/app/server) from 6.4.18 to 6.4.19.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/v6.4.19/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v6.4.19/app/server)

---
updated-dependencies:
- dependency-name: "@storybook/server"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-15 11:32:14 +00:00
dependabot[bot]
2952b0582a Bump @storybook/addon-controls from 6.4.18 to 6.4.19
Bumps [@storybook/addon-controls](https://github.com/storybookjs/storybook/tree/HEAD/addons/controls) from 6.4.18 to 6.4.19.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/v6.4.19/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v6.4.19/addons/controls)

---
updated-dependencies:
- dependency-name: "@storybook/addon-controls"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-15 11:31:49 +00:00
Matt-Yorkley
4726e7a8a4 Merge pull request #8879 from openfoodfoundation/dependabot/npm_and_yarn/storybook/addon-docs-6.4.19
Bump @storybook/addon-docs from 6.4.18 to 6.4.19
2022-02-15 11:31:00 +00:00
Matt-Yorkley
46c0baee4f Merge pull request #8885 from jibees/8882-handle-webpacker-error-for-email
Modify assets builder to get CSS inside emails when running in development mode
2022-02-15 11:23:42 +00:00
Maikel Linke
1d5ebe42a9 Update translations 2022-02-15 10:50:01 +11:00
Filipe
e9e5ad2221 Merge pull request #8865 from jibees/8769-use-the-user-in-the-request-to-check-flipper-constraint
Use the user in the request to check flipper constraint for split checkout urls
2022-02-14 19:38:27 +00:00
SarvarKhalimov
d69f42e940 Update app/models/product_import/entry_validator.rb
Co-authored-by: Maikel <maikel@email.org.au>
2022-02-15 00:10:32 +05:00
Filipe
2de2703e1f Merge pull request #8868 from jibees/8852-improve-total-cell-design-on-order-summary-table
SplitCheckout : Improve design of the order summary table
2022-02-14 18:48:20 +00:00
Filipe
a9d7fa473e Merge pull request #8870 from jibees/8853-handle-back-button-on-summary-page-for-the-split-checkout
Split checkout: handle the link for "Back to Payment method" button in the summary page
2022-02-14 18:29:11 +00:00
Filipe
ddfda4011d Merge pull request #8873 from Matt-Yorkley/stripe-retries
Update checkout retry logic
2022-02-14 15:28:56 +00:00
Matt-Yorkley
e4030e673d Merge pull request #8875 from openfoodfoundation/dependabot/npm_and_yarn/follow-redirects-1.14.8
Bump follow-redirects from 1.14.7 to 1.14.8
2022-02-14 14:03:59 +00:00
Jean-Baptiste Bellet
74ed878a0c Specify the asset host for the action mailer to get the assets
when running in development with webpacker running as well.
2022-02-14 14:54:09 +01:00
Filipe
6acd8a29f2 Merge pull request #8874 from Matt-Yorkley/puma-update
Update puma to latest version
2022-02-14 09:11:51 +00:00
dependabot[bot]
699e9acfa5 Bump @storybook/addon-docs from 6.4.18 to 6.4.19
Bumps [@storybook/addon-docs](https://github.com/storybookjs/storybook/tree/HEAD/addons/docs) from 6.4.18 to 6.4.19.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/v6.4.19/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v6.4.19/addons/docs)

---
updated-dependencies:
- dependency-name: "@storybook/addon-docs"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-14 09:03:42 +00:00
Matt-Yorkley
ad44bd854b Merge pull request #8878 from mkllnk/rubocop-action
Use our defined rubocop version on CI
2022-02-14 08:58:52 +00:00
Matt-Yorkley
3418e5282a Use our defined rubocop version on CI
The default is to use the latest version. That's often fine because we
keep our version up-to-date but it may not always be. It's also great if
builds are re-producible.
2022-02-14 15:56:18 +11:00
Maikel
7601bdfd45 Merge pull request #8867 from openfoodfoundation/transifex
Transifex
2022-02-14 11:20:00 +11:00
SarvarKhalimov
42a0a973ba Fix product import on existing, empty unit_type and variant_unit 2022-02-13 18:28:21 +05:00
dependabot[bot]
0338753421 Bump follow-redirects from 1.14.7 to 1.14.8
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.14.7 to 1.14.8.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.14.7...v1.14.8)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-13 12:23:25 +00:00
Matt-Yorkley
996bc05b4f Merge pull request #8866 from openfoodfoundation/dependabot/npm_and_yarn/karma-6.3.16
Bump karma from 6.3.15 to 6.3.16
2022-02-13 12:22:34 +00:00
Matt-Yorkley
15fc50441f Update puma to latest version 2022-02-13 10:54:45 +00:00
Matt-Yorkley
e5818955ff Invalidate all incomplete payments when creating a new one, not just those in "checkout" state.
Looking at prod data; when a checkout submission fails due to something like a card being out of date, the payment's state seems to be "pending" and not "checkout", which means this mechanism fro invalidating old payments is potentially not working where it should.
2022-02-11 17:25:27 +00:00
Jean-Baptiste Bellet
43cd604405 Update to the right link the "Back to Payment method" button
+ create a spec as well
2022-02-11 15:01:53 +01:00
Jean-Baptiste Bellet
f60068c0ce Use the proxy OpenFoodNetwork::FeatureToggle
that actually call Flipper.enabled?
2022-02-11 11:19:00 +01:00
Jean-Baptiste Bellet
e50247db5a Directly used the user in the request
not the memoized one @spree_current_user
2022-02-11 11:19:00 +01:00
Jean-Baptiste Bellet
d858d6f941 Improve design by aligning cell on right but with padding 2022-02-11 11:09:54 +01:00
Transifex-Openfoodnetwork
5519b8b455 Updating translations for config/locales/cy.yml 2022-02-11 21:02:57 +11:00
dependabot[bot]
dd4f45a504 Bump karma from 6.3.15 to 6.3.16
Bumps [karma](https://github.com/karma-runner/karma) from 6.3.15 to 6.3.16.
- [Release notes](https://github.com/karma-runner/karma/releases)
- [Changelog](https://github.com/karma-runner/karma/blob/master/CHANGELOG.md)
- [Commits](https://github.com/karma-runner/karma/compare/v6.3.15...v6.3.16)

---
updated-dependencies:
- dependency-name: karma
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-11 09:44:14 +00:00
Filipe
6e2c4a385a Merge pull request #8810 from Matt-Yorkley/split-checkout-tax
Reduce expensive tax recalculation calls
2022-02-10 17:42:39 +00:00
Filipe
d8936b412e Merge pull request #8819 from apricot12/8694-Improve_subsvriptions_index_perfomance
8694 improve subscriptions index perfomance by eager loading tags, suppliers and exchanges.
2022-02-10 17:37:00 +00:00
Filipe
820417e6cc Merge pull request #8828 from apricot12/8794-Keep_schedule_when_cloning_OC
Carry over linked schedule to cloned Order Cycle
2022-02-10 17:09:56 +00:00
Filipe
0802b04feb Merge pull request #8857 from jibees/8855-login-signup-on-private-shop
Open modal on login/signup links for a "Visible to Registered Customers Only" shop page
2022-02-10 13:47:02 +00:00
Jean-Baptiste Bellet
92cd918e5a Add LoginModal as controller + connect action to open login modal 2022-02-10 09:52:13 +01:00
Maikel Linke
9c786ff39e Update translations 2022-02-10 10:08:28 +11:00
Maikel
570f9f2dc0 Merge pull request #8837 from openfoodfoundation/transifex
Transifex
2022-02-10 10:04:20 +11:00
Maikel
fb920c8960 Merge pull request #8845 from mkllnk/swagger-cleanup
Add rspec tools for better integration of the coming API v1
2022-02-10 10:04:03 +11:00
Maikel
026d4dd087 Merge pull request #8848 from openfoodfoundation/dependabot/npm_and_yarn/jest-27.5.1
Bump jest from 27.5.0 to 27.5.1
2022-02-10 09:50:32 +11:00
Maikel
463473f2c3 Merge pull request #8840 from openfoodfoundation/dependabot/npm_and_yarn/karma-6.3.15
Bump karma from 6.3.13 to 6.3.15
2022-02-10 09:48:56 +11:00
Filipe
30c1d89525 Merge pull request #8822 from Matt-Yorkley/split-checkout-payment-total
[Split Checkout] Move setting of payment total during checkout into OrderUpdater
2022-02-09 16:21:47 +00:00
Transifex-Openfoodnetwork
61a4a72b97 Updating translations for config/locales/ru.yml 2022-02-09 23:30:55 +11:00
Jean-Baptiste Bellet
a951fd2c06 Create a new method pdf_stylesheet_pack_tag that actually include CSS file
If running in developpement (ie. `Webpacker.dev_server.running?`), use webpacker to actually render/serve the CSS files.

Source: https://stackoverflow.com/a/60541688
2022-02-09 11:21:50 +01:00
dependabot[bot]
4db72f7475 Bump jest from 27.5.0 to 27.5.1
Bumps [jest](https://github.com/facebook/jest) from 27.5.0 to 27.5.1.
- [Release notes](https://github.com/facebook/jest/releases)
- [Changelog](https://github.com/facebook/jest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/jest/compare/v27.5.0...v27.5.1)

---
updated-dependencies:
- dependency-name: jest
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-09 09:04:31 +00:00
dependabot[bot]
0ebe46a17f Bump karma from 6.3.13 to 6.3.15
Bumps [karma](https://github.com/karma-runner/karma) from 6.3.13 to 6.3.15.
- [Release notes](https://github.com/karma-runner/karma/releases)
- [Changelog](https://github.com/karma-runner/karma/blob/master/CHANGELOG.md)
- [Commits](https://github.com/karma-runner/karma/compare/v6.3.13...v6.3.15)

---
updated-dependencies:
- dependency-name: karma
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-09 08:38:21 +00:00
Matt-Yorkley
f065b4c787 Merge pull request #8847 from jibees/yarn-resolve-lock-file
Update js dependencies lock file
2022-02-08 12:30:36 +00:00
Matt-Yorkley
8dc743f2d4 Extract update_payment_total method 2022-02-08 12:27:42 +00:00
Matt-Yorkley
1c180299a5 Pass indexed payment method tags to PaymentMethod Serializer 2022-02-08 11:42:24 +00:00
Matt-Yorkley
37b5e1b014 Allow Payment Method Serializers to receive options 2022-02-08 11:42:24 +00:00
Nihal M. Kelanthodika
3152fef2ef Eager load distributors and cached_incoming_exchanges 2022-02-08 11:42:24 +00:00
Nihal M. Kelanthodika
f0d6cd1f59 Query payment_method_tags by id 2022-02-08 11:42:24 +00:00
Nihal M. Kelanthodika
ee77210e81 Eager load taggings in SubscriptionsController#Index 2022-02-08 11:42:24 +00:00
Matt-Yorkley
d1339fa253 Merge pull request #8833 from openfoodfoundation/dependabot/npm_and_yarn/webpack-dev-server-3.11.3
Bump webpack-dev-server from 3.11.2 to 3.11.3
2022-02-08 10:34:03 +00:00
Matt-Yorkley
eaeda23e4f Merge pull request #8838 from SarvarKh/updated-getting-started
Update GETTING_STARTED.md to include creation of a new user
2022-02-08 10:32:58 +00:00
Matt-Yorkley
65ed199ba9 Merge pull request #8842 from openfoodfoundation/dependabot/npm_and_yarn/jest-27.5.0
Bump jest from 27.4.7 to 27.5.0
2022-02-08 10:31:16 +00:00
Jean-Baptiste Bellet
e6f7c961e1 Update yarn.lock 2022-02-08 10:26:22 +01:00
Maikel Linke
8f5cb7bd91 Update swagger files, separate v0 and v1, delete old file
The new v1 doesn't contain any API endpoints yet. We will add them later
when they are ready.
2022-02-08 11:44:36 +11:00
Matt-Yorkley
9d67606490 Generate rswag routes and helper 2022-02-08 11:43:49 +11:00
Matt-Yorkley
ae2726fc6b Generate rswag initializers
Done via rswag rake tasks and tidied up a bit.
2022-02-08 11:43:49 +11:00
Matt-Yorkley
3a6fc59f80 Add rswag support gems 2022-02-08 11:43:49 +11:00
Maikel
1ba56851bb Merge pull request #8839 from mkllnk/style
Update Rubocop todo list
2022-02-08 09:13:54 +11:00
SarvarKhalimov
97bdceb78a Update GETTING_STARTED.md to include creation of a new user 2022-02-08 00:11:11 +05:00
dependabot[bot]
c0c7663452 Bump jest from 27.4.7 to 27.5.0
Bumps [jest](https://github.com/facebook/jest) from 27.4.7 to 27.5.0.
- [Release notes](https://github.com/facebook/jest/releases)
- [Changelog](https://github.com/facebook/jest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/jest/compare/v27.4.7...v27.5.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-07 09:04:54 +00:00
Jean-Baptiste Bellet
4a3e0ea9b9 Use the right scope to retrieve products based on properties 2022-02-07 08:57:18 +01:00
Jean-Baptiste Bellet
dfe8ed26d9 Update tests and use ransack to search with the new scope: with_properties 2022-02-07 08:57:18 +01:00
Maikel Linke
572a65b324 Create a scope to retrieve product based on its properties
both inherited and own product properties

Update the product spec to test the scope that concern properties
2022-02-07 08:57:18 +01:00
Jean-Baptiste Bellet
f8002ae49a Add some controller specs that handle the supplier_property filtering
with product that don't inherits properties
2022-02-07 08:57:18 +01:00
Jean-Baptiste Bellet
242459fae4 Create the test that actually failed and should not 2022-02-07 08:57:18 +01:00
Maikel Linke
d0bb52f709 Update Rubocop todo list 2022-02-07 16:55:45 +11:00
Maikel
78cbd7b5c7 Merge pull request #8834 from openfoodfoundation/dependabot/npm_and_yarn/storybook/addon-docs-6.4.18
Bump @storybook/addon-docs from 6.4.17 to 6.4.18
2022-02-07 16:29:50 +11:00
Maikel
0d729fa0a8 Merge pull request #8831 from openfoodfoundation/dependabot/npm_and_yarn/storybook/addon-controls-6.4.18
Bump @storybook/addon-controls from 6.4.17 to 6.4.18
2022-02-07 16:29:02 +11:00
dependabot[bot]
f2c3afdbfd Bump @storybook/addon-docs from 6.4.17 to 6.4.18
Bumps [@storybook/addon-docs](https://github.com/storybookjs/storybook/tree/HEAD/addons/docs) from 6.4.17 to 6.4.18.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v6.4.18/addons/docs)

---
updated-dependencies:
- dependency-name: "@storybook/addon-docs"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-07 05:16:40 +00:00
Maikel
3ae5672d1a Merge pull request #8832 from openfoodfoundation/dependabot/npm_and_yarn/storybook/server-6.4.18
Bump @storybook/server from 6.4.17 to 6.4.18
2022-02-07 16:15:49 +11:00
Transifex-Openfoodnetwork
4c0b3bf9bf Updating translations for config/locales/en_IE.yml 2022-02-05 03:19:28 +11:00
Transifex-Openfoodnetwork
f7de43e8b7 Updating translations for config/locales/en_IE.yml 2022-02-05 03:16:24 +11:00
Matt-Yorkley
8a1fcf8a62 Update all locales with the latest Transifex translations 2022-02-04 15:50:32 +00:00
Matt-Yorkley
08d7a4de92 Merge pull request #8799 from openfoodfoundation/transifex
Transifex
2022-02-04 15:46:52 +00:00
Filipe
0777212607 Merge pull request #8774 from Matt-Yorkley/drop-dead-action
Remove unused controller action
2022-02-03 19:47:18 +00:00
Filipe
e403fc171d Merge pull request #8808 from Matt-Yorkley/login-modal
Remove all Angular code from Login/Signup process
2022-02-03 19:36:44 +00:00
Filipe
c4751d7056 Merge pull request #8813 from Matt-Yorkley/split-checkout-address-state
Split checkout: fix loading of saved addresses
2022-02-03 19:06:35 +00:00
Filipe
e2695fdbfb Merge pull request #8829 from mkllnk/8824-patch-aws-sdk
Fix image uploads by patching aws-sdk
2022-02-03 12:44:13 +00:00
dependabot[bot]
cd0542af85 Bump webpack-dev-server from 3.11.2 to 3.11.3
Bumps [webpack-dev-server](https://github.com/webpack/webpack-dev-server) from 3.11.2 to 3.11.3.
- [Release notes](https://github.com/webpack/webpack-dev-server/releases)
- [Changelog](https://github.com/webpack/webpack-dev-server/blob/v3.11.3/CHANGELOG.md)
- [Commits](https://github.com/webpack/webpack-dev-server/compare/v3.11.2...v3.11.3)

---
updated-dependencies:
- dependency-name: webpack-dev-server
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-03 09:05:42 +00:00
dependabot[bot]
a8e29d7c07 Bump @storybook/server from 6.4.17 to 6.4.18
Bumps [@storybook/server](https://github.com/storybookjs/storybook/tree/HEAD/app/server) from 6.4.17 to 6.4.18.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v6.4.18/app/server)

---
updated-dependencies:
- dependency-name: "@storybook/server"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-03 09:05:34 +00:00
dependabot[bot]
67be08b40e Bump @storybook/addon-controls from 6.4.17 to 6.4.18
Bumps [@storybook/addon-controls](https://github.com/storybookjs/storybook/tree/HEAD/addons/controls) from 6.4.17 to 6.4.18.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v6.4.18/addons/controls)

---
updated-dependencies:
- dependency-name: "@storybook/addon-controls"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-03 09:05:19 +00:00
Maikel Linke
2e6d8c1216 Provide aws-sdk with working URI.encode method
The S3 class is calling URI.encode which is removed in Ruby 3. By
providing a URI module within the S3 class makes the S3 code call that
module instead.
2022-02-03 15:20:51 +11:00
Maikel Linke
6468b7d98d Spec image upload
The use of AWS S3 was untested before and it failed after upgrading to
Ruby 3.
2022-02-03 11:25:16 +11:00
Filipe
787b643832 Merge pull request #8818 from jibees/8793-specify-a-min-width-for-radio-input
Split checkout: specify a min width for radio input that improve the rendering on iOS
2022-02-02 18:31:27 +00:00
Nihal M. Kelanthodika
b45f0f3416 Update order_cycle model spec to account for cloning of schedule along with OC 2022-02-02 21:21:38 +05:30
Nihal M. Kelanthodika
6293e927bc Keep linked schedule when cloning OC 2022-02-02 19:13:48 +05:30
Maikel
433227cc09 Merge pull request #8820 from openfoodfoundation/dependabot/npm_and_yarn/karma-6.3.13
Bump karma from 6.3.12 to 6.3.13
2022-02-02 14:46:46 +11:00
Matt-Yorkley
f77ecc1968 Improve and simplify return authorizations test setup 2022-02-01 11:39:07 +00:00
Matt-Yorkley
7235d1813d Update totals and payment explicitly in current (non-split) checkout 2022-02-01 11:39:07 +00:00
Matt-Yorkley
35392cb117 Remove Order#set_payment_amount! 2022-02-01 11:39:07 +00:00
Matt-Yorkley
31e6405125 Handle setting of payment amount during checkout in OrderUpdater 2022-02-01 11:39:07 +00:00
Filipe
ca0166a420 Merge pull request #8807 from Matt-Yorkley/closed-oc-payment-auth
Fix Stripe payment authorizing for closed order cycles
2022-02-01 11:16:31 +00:00
Filipe
998f7afdc4 Merge pull request #8523 from seballot/progress-for-ajax-request
Improve loading spinner display
2022-02-01 10:03:04 +00:00
Filipe
012527522c Merge pull request #8640 from jibees/8630-make-buttons-sticky
Make split checkout buttons sticky on step 3
2022-02-01 09:41:33 +00:00
dependabot[bot]
bbf10a7198 Bump karma from 6.3.12 to 6.3.13
Bumps [karma](https://github.com/karma-runner/karma) from 6.3.12 to 6.3.13.
- [Release notes](https://github.com/karma-runner/karma/releases)
- [Changelog](https://github.com/karma-runner/karma/blob/master/CHANGELOG.md)
- [Commits](https://github.com/karma-runner/karma/compare/v6.3.12...v6.3.13)

---
updated-dependencies:
- dependency-name: karma
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-01 09:04:04 +00:00
Maikel
b995c3ed49 Merge pull request #8815 from openfoodfoundation/dependabot/npm_and_yarn/storybook/addon-controls-6.4.17
Bump @storybook/addon-controls from 6.4.14 to 6.4.17
2022-02-01 19:02:34 +11:00
dependabot[bot]
031258e1ee Bump @storybook/addon-controls from 6.4.14 to 6.4.17
Bumps [@storybook/addon-controls](https://github.com/storybookjs/storybook/tree/HEAD/addons/controls) from 6.4.14 to 6.4.17.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v6.4.17/addons/controls)

---
updated-dependencies:
- dependency-name: "@storybook/addon-controls"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-01 06:06:09 +00:00
Maikel
e060a059d8 Merge pull request #8817 from openfoodfoundation/dependabot/npm_and_yarn/storybook/addon-docs-6.4.17
Bump @storybook/addon-docs from 6.4.14 to 6.4.17
2022-02-01 17:05:42 +11:00
dependabot[bot]
f02c79751c Bump @storybook/addon-docs from 6.4.14 to 6.4.17
Bumps [@storybook/addon-docs](https://github.com/storybookjs/storybook/tree/HEAD/addons/docs) from 6.4.14 to 6.4.17.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v6.4.17/addons/docs)

---
updated-dependencies:
- dependency-name: "@storybook/addon-docs"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-01 05:40:34 +00:00
Maikel
2938de7eee Merge pull request #8816 from openfoodfoundation/dependabot/npm_and_yarn/storybook/server-6.4.17
Bump @storybook/server from 6.4.14 to 6.4.17
2022-02-01 16:39:47 +11:00
Filipe
8d18279f53 Merge pull request #8784 from apricot12/7398-Weight_field-on-non-weight-variants
Convert variant.weight into decimal if integer or 0.0 if nil
2022-01-31 18:55:31 +00:00
Matt-Yorkley
5eb88e020c Extract/clarify methods in tabs_controller 2022-01-31 16:35:41 +00:00
Matt-Yorkley
81f5755e3d Add tests for tabs_controller 2022-01-31 16:34:35 +00:00
Filipe
4e4d9bb5a5 Merge pull request #8804 from Matt-Yorkley/split-checkout-fees
[Split Checkout] Ensure fees are applied during checkout update
2022-01-31 16:26:22 +00:00
Matt-Yorkley
5b434ca7c4 Replace conditional with a guard clause 2022-01-31 15:55:35 +00:00
Matt-Yorkley
11ed1574ca Call #check_order_cycle_expiry in PaypalController and StripeController, but avoid it on #authorize action
The authorize action is used for authorizing off-session payments where the order is *already complete* and the order cycle may have closed (backoffice and subscriptions). They are essentially asynchronous and not coupled to the current open/closed state of the order cycle.
2022-01-31 15:55:35 +00:00
Matt-Yorkley
5e6dd1e6e1 Move #check_order_cycle_expiry method to OrderStockCheck and don't call it from BaseController :before_action callback 2022-01-31 15:55:35 +00:00
Jean-Baptiste Bellet
d97381548a Specify a min width for radio 2022-01-31 15:50:37 +01:00
Nihal M. Kelanthodika
ddaac654ef Add specs for conversion of variant weight input into decimal/0.0 2022-01-31 17:43:15 +05:30
Jean-Baptiste Bellet
da6be441f8 Make sticky buttons fullwidth on mobile 2022-01-31 11:47:35 +01:00
Jean-Baptiste Bellet
ae0a71b29d This row adds an extra space on the right of the page
which introduce an horizontal scroll: visual regression
2022-01-31 11:47:21 +01:00
Jean-Baptiste Bellet
fdeadd0940 Reduce margin on step3 since the container could be a little too high 2022-01-31 11:31:32 +01:00
Jean-Baptiste Bellet
d8391aa1d3 Create a div with a special class (checkout-step3)
... and attach the controller to it

Add the T&Cs inside the sicked container with submit buttons
2022-01-31 11:31:32 +01:00
Jean-Baptiste Bellet
293bc10dde Create a sticky controller that handle the sticky position of an element
.. at the bottom
And then add the sticked class to this element if the element is actually sticked
2022-01-31 11:31:32 +01:00
Jean-Baptiste Bellet
3abef1b703 Specify css for this sticky container
with a nice box-shadow.
Handle special case for mobile view (ie. max width 700px)
2022-01-31 11:31:32 +01:00
Matt-Yorkley
5f02ab79d4 Adjust animation handling for show/hide 2022-01-31 10:02:09 +00:00
Transifex-Openfoodnetwork
8e1272b1e8 Updating translations for config/locales/en_GB.yml 2022-01-31 20:47:33 +11:00
dependabot[bot]
091c04427c Bump @storybook/server from 6.4.14 to 6.4.17
Bumps [@storybook/server](https://github.com/storybookjs/storybook/tree/HEAD/app/server) from 6.4.14 to 6.4.17.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v6.4.17/app/server)

---
updated-dependencies:
- dependency-name: "@storybook/server"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-31 09:04:40 +00:00
Matt-Yorkley
7c0a631f7f Remove an unnecessary assignment
Co-authored-by: Maikel <maikel@email.org.au>
2022-01-31 08:40:58 +00:00
Matt-Yorkley
0516ec6f15 Enable test for loading address (now passing) 2022-01-30 11:33:31 +00:00
Matt-Yorkley
5e321c9f48 Fix country/state selection for shipping address; missing controller and data 2022-01-30 11:33:31 +00:00
Matt-Yorkley
611beb2e90 Rearrange controller placement, field order, and nesting 2022-01-30 11:33:31 +00:00
Matt-Yorkley
908a22bcb6 Don't repopulate states select on page load; breaks pre-filling selection from saved address 2022-01-30 11:33:31 +00:00
Matt-Yorkley
370ec17818 Improve countries and states loading 2022-01-30 11:33:31 +00:00
Matt-Yorkley
bf4428b688 Tidy up dependent-select controller 2022-01-30 11:33:31 +00:00
Matt-Yorkley
7e62bfcdfb Add failing test for loading address with state correctly in split checkout 2022-01-30 11:33:31 +00:00
Matt-Yorkley
448e4bb67b Reduce expensive tax recalculation calls
This can only really be enabled once we've merged the split checkout
2022-01-29 18:56:52 +00:00
Transifex-Openfoodnetwork
22d5a63a5b Updating translations for config/locales/ar.yml 2022-01-30 03:59:54 +11:00
Matt-Yorkley
f3792acf55 Drop workaround previously required to avoid a bug caused by the stringex gem 2022-01-29 14:49:23 +00:00
Matt-Yorkley
8b59ef20db Improve controller tests 2022-01-29 14:49:23 +00:00
Matt-Yorkley
794e0e0326 Delete old login modal code 2022-01-29 14:49:23 +00:00
Matt-Yorkley
13a7fb79cf Move more login handling out of Angular 2022-01-29 14:49:23 +00:00
Matt-Yorkley
77d8e7da90 Use non-Angular login modal in /registration pages 2022-01-29 14:49:23 +00:00
Matt-Yorkley
a522e597e1 Add Matamo event 2022-01-29 14:49:23 +00:00
Matt-Yorkley
6116fd8881 Improve inaccurate specs 2022-01-29 14:49:23 +00:00
Matt-Yorkley
50389a864a Improve dynamic Angular Bootstrapping 2022-01-29 14:49:23 +00:00
Matt-Yorkley
89e692c6c8 Switch to CableCar for login responses 2022-01-29 14:49:23 +00:00
Matt-Yorkley
0577b46f3f Create simpler non-Angular login modal 2022-01-29 14:49:23 +00:00
Matt-Yorkley
8a18a4de66 Clear up redirecting logic and path building 2022-01-29 10:08:51 +00:00
Matt-Yorkley
04da148af0 Decouple login modal opening from Angular 2022-01-29 10:08:51 +00:00
Matt-Yorkley
6561a7246b Delete unused partial 2022-01-29 10:08:51 +00:00
Matt-Yorkley
798af2dafc Drop unused #create action 2022-01-29 10:08:50 +00:00
Transifex-Openfoodnetwork
a6bf6470f7 Updating translations for config/locales/de_DE.yml 2022-01-29 12:14:24 +11:00
Matt-Yorkley
6c6e5ca316 Ensure fees are applied during checkout 2022-01-28 11:38:23 +00:00
Transifex-Openfoodnetwork
6856f21e7e Updating translations for config/locales/it.yml 2022-01-28 19:05:08 +11:00
Transifex-Openfoodnetwork
aae40c74a9 Updating translations for config/locales/en_US.yml 2022-01-28 10:15:26 +11:00
Transifex-Openfoodnetwork
0397a68072 Updating translations for config/locales/fr_CA.yml 2022-01-28 09:31:49 +11:00
Transifex-Openfoodnetwork
ccb9df708b Updating translations for config/locales/en_CA.yml 2022-01-28 09:24:03 +11:00
Nihal M. Kelanthodika
23a7ba2479 Added before_save callback to convert variant weight to decimal and 0.0 if nil 2022-01-27 16:33:14 +05:30
Matt-Yorkley
e077607767 Remove unused controller action 2022-01-21 21:31:42 +00:00
Sebastian Castro
115dfe445b loading-message: make them all look the same in admin
use font awesome spinner instead of an image
2022-01-11 21:55:07 +01:00
Sebastian Castro
4a436978a9 loading-popup: debounce display 2022-01-11 21:55:07 +01:00
Sebastian Castro
0eb97f1cdc loading-popup: improve style 2022-01-11 21:55:07 +01:00
Jean-Baptiste Bellet
a1b21d7706 Take into account the lb unit name 2022-01-10 11:50:40 +01:00
Jean-Baptiste Bellet
f6e64f3a3c Update the tests as well 2022-01-10 11:27:32 +01:00
Jean-Baptiste Bellet
c5beff249e Should be divided by scale if the smallest unit 2022-01-10 11:27:18 +01:00
Jean-Baptiste Bellet
4c508a5bf9 Group by unit size is specific: it needs to be divided by scale if not the smallest unit 2022-01-10 11:24:22 +01:00
Jean-Baptiste Bellet
da9c0f4b8c Refactor: create two internal methods: getScale and getFormattedValueWithUnitName
Then, the old formattedValueWithUnitName calls those two private methods
2022-01-10 11:23:30 +01:00
Jean-Baptiste Bellet
467183af48 Rename getScale to getLineItemScale to be more specific 2022-01-10 11:22:11 +01:00
Jean-Baptiste Bellet
515e2cfc51 Multiply by unit_value as sumOfUnitValues is now scaled 2022-01-07 10:32:47 +01:00
Jean-Baptiste Bellet
b746eacd11 Both sumUnitValues and sumMaxUnitValues should handle imperial units 2022-01-07 10:32:46 +01:00
Jean-Baptiste Bellet
5db50481dd Rounding to 3 decimals as scope method 2022-01-07 10:32:46 +01:00
Jean-Baptiste Bellet
d4435b5f10 Update variant_unit_manager_spec.js.coffee 2022-01-07 10:32:46 +01:00
Jean-Baptiste Bellet
9cf5645478 Add a spec to handle imperial units 2022-01-07 10:32:46 +01:00
Jean-Baptiste Bellet
7b2a9df326 Handle unitsVariant when calling formattedValueWithUnitName
- unitsVariant was unread but is necessary to compute the unit_name thanks to `VariantUnitManager.getUnitName()`
2022-01-07 10:32:46 +01:00
Jean-Baptiste Bellet
3922ffa6a9 Handle imperial units for VariantUnitManager 2022-01-07 10:32:45 +01:00
201 changed files with 4201 additions and 4454 deletions

View File

@@ -11,6 +11,8 @@ jobs:
- name: rubocop
uses: reviewdog/action-rubocop@v2
with:
rubocop_version: gemfile
rubocop_extensions: rubocop-rails:gemfile
reporter: github-pr-check
level: error
fail_on_error: true

View File

@@ -202,7 +202,8 @@ Metrics/BlockLength:
"namespace",
"resource",
"resources",
"scenario"
"scenario",
"shared_examples",
]
Metrics/BlockNesting:

View File

@@ -1,11 +1,19 @@
# This configuration was generated by
# `rubocop --auto-gen-config --auto-gen-only-exclude --exclude-limit 1400`
# on 2021-12-09 22:28:37 UTC using RuboCop version 1.22.2.
# on 2022-02-07 05:53:22 UTC using RuboCop version 1.22.2.
# 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
# Cop supports --auto-correct.
# Configuration parameters: TreatCommentsAsGroupSeparators, ConsiderPunctuation, Include.
# Include: **/*.gemfile, **/Gemfile, **/gems.rb
Bundler/OrderedGems:
Exclude:
- 'Gemfile'
# Offense count: 4
# Configuration parameters: Include.
# Include: **/*.gemspec
@@ -45,7 +53,7 @@ Layout/LeadingCommentSpace:
Exclude:
- 'spec/system/admin/enterprises_spec.rb'
# Offense count: 814
# Offense count: 815
# Cop supports --auto-correct.
# Configuration parameters: Max, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
# URISchemes: http, https
@@ -59,11 +67,13 @@ Layout/LineLength:
- 'app/controllers/admin/schedules_controller.rb'
- 'app/controllers/admin/subscriptions_controller.rb'
- 'app/controllers/api/v0/order_cycles_controller.rb'
- 'app/controllers/checkout_controller.rb'
- 'app/controllers/payment_gateways/paypal_controller.rb'
- 'app/controllers/spree/admin/reports_controller.rb'
- 'app/controllers/spree/paypal_controller.rb'
- 'app/controllers/spree/users_controller.rb'
- 'app/controllers/user_confirmations_controller.rb'
- 'app/helpers/angular_form_builder.rb'
- 'app/helpers/angular_form_helper.rb'
- 'app/helpers/checkout_helper.rb'
- 'app/helpers/enterprises_helper.rb'
- 'app/helpers/order_cycles_helper.rb'
- 'app/helpers/spree/orders_helper.rb'
@@ -101,7 +111,6 @@ Layout/LineLength:
- 'app/services/variant_units/variant_and_line_item_naming.rb'
- 'engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb'
- 'engines/order_management/app/services/order_management/subscriptions/validator.rb'
- 'engines/order_management/spec/services/order_management/order/stripe_sca_payment_authorize_spec.rb'
- 'engines/order_management/spec/services/order_management/order/updater_spec.rb'
- 'engines/web/app/helpers/web/cookies_policy_helper.rb'
- 'engines/web/spec/features/consumer/cookies_spec.rb'
@@ -147,6 +156,7 @@ Layout/LineLength:
- 'spec/controllers/checkout_controller_spec.rb'
- 'spec/controllers/enterprises_controller_spec.rb'
- 'spec/controllers/line_items_controller_spec.rb'
- 'spec/controllers/registration_controller_spec.rb'
- 'spec/controllers/shops_controller_spec.rb'
- 'spec/controllers/spree/admin/orders/customer_details_controller_spec.rb'
- 'spec/controllers/spree/admin/orders/invoices_spec.rb'
@@ -159,8 +169,8 @@ Layout/LineLength:
- 'spec/controllers/stripe/callbacks_controller_spec.rb'
- 'spec/controllers/stripe/webhooks_controller_spec.rb'
- 'spec/controllers/user_confirmations_controller_spec.rb'
- 'spec/factories/order_factory.rb'
- 'spec/factories/stock_location_factory.rb'
- 'spec/features/consumer/multilingual_spec.rb'
- 'spec/helpers/enterprises_helper_spec.rb'
- 'spec/helpers/injection_helper_spec.rb'
- 'spec/helpers/order_cycles_helper_spec.rb'
@@ -198,7 +208,6 @@ Layout/LineLength:
- 'spec/models/spree/address_spec.rb'
- 'spec/models/spree/adjustment_spec.rb'
- 'spec/models/spree/classification_spec.rb'
- 'spec/models/spree/gateway/stripe_connect_spec.rb'
- 'spec/models/spree/inventory_unit_spec.rb'
- 'spec/models/spree/line_item_spec.rb'
- 'spec/models/spree/order/checkout_spec.rb'
@@ -219,7 +228,7 @@ Layout/LineLength:
- 'spec/models/variant_override_spec.rb'
- 'spec/requests/api/orders_spec.rb'
- 'spec/requests/checkout/failed_checkout_spec.rb'
- 'spec/requests/embedded_shopfronts_headers_spec.rb'
- 'spec/routing/stripe_spec.rb'
- 'spec/serializers/api/admin/exchange_serializer_spec.rb'
- 'spec/serializers/api/admin/order_cycle_serializer_spec.rb'
- 'spec/services/address_geocoder_spec.rb'
@@ -280,7 +289,6 @@ Layout/LineLength:
- 'spec/system/consumer/shopping/checkout_auth_spec.rb'
- 'spec/system/consumer/shopping/checkout_spec.rb'
- 'spec/system/consumer/shopping/checkout_stripe_spec.rb'
- 'spec/system/consumer/shopping/embedded_shopfronts_spec.rb'
- 'spec/system/consumer/shopping/products_spec.rb'
- 'spec/system/consumer/shopping/shopping_spec.rb'
- 'spec/system/consumer/shopping/unit_price_spec.rb'
@@ -303,7 +311,7 @@ Layout/MultilineMethodCallBraceLayout:
Exclude:
- 'lib/reporting/queries/joins.rb'
# Offense count: 15
# Offense count: 17
# Cop supports --auto-correct.
# Configuration parameters: AllowInHeredoc.
Layout/TrailingWhitespace:
@@ -338,6 +346,11 @@ Lint/DuplicateMethods:
Exclude:
- 'lib/discourse/single_sign_on.rb'
# Offense count: 1
Lint/DuplicateRequire:
Exclude:
- 'spec/lib/open_food_network/scope_variants_to_search_spec.rb'
# Offense count: 1
# Configuration parameters: AllowComments.
Lint/EmptyFile:
@@ -392,7 +405,7 @@ Lint/UselessMethodDefinition:
- 'app/controllers/spree/user_registrations_controller.rb'
- 'app/models/spree/gateway.rb'
# Offense count: 262
# Offense count: 261
# Configuration parameters: IgnoredMethods, CountRepeatedAttributes, Max.
Metrics/AbcSize:
Exclude:
@@ -414,8 +427,11 @@ Metrics/AbcSize:
- 'app/controllers/api/v0/taxons_controller.rb'
- 'app/controllers/api/v0/variants_controller.rb'
- 'app/controllers/checkout_controller.rb'
- 'app/controllers/concerns/order_completion.rb'
- 'app/controllers/discourse_sso_controller.rb'
- 'app/controllers/enterprises_controller.rb'
- 'app/controllers/payment_gateways/paypal_controller.rb'
- 'app/controllers/payment_gateways/stripe_controller.rb'
- 'app/controllers/split_checkout_controller.rb'
- 'app/controllers/spree/admin/adjustments_controller.rb'
- 'app/controllers/spree/admin/general_settings_controller.rb'
@@ -435,8 +451,6 @@ Metrics/AbcSize:
- 'app/controllers/spree/admin/variants_controller.rb'
- 'app/controllers/spree/credit_cards_controller.rb'
- 'app/controllers/spree/orders_controller.rb'
- 'app/controllers/spree/paypal_controller.rb'
- 'app/controllers/spree/user_passwords_controller.rb'
- 'app/controllers/spree/user_sessions_controller.rb'
- 'app/controllers/spree/users_controller.rb'
- 'app/controllers/stripe/callbacks_controller.rb'
@@ -564,7 +578,7 @@ Metrics/AbcSize:
- 'spec/system/consumer/shopping/shopping_spec.rb'
- 'spec/system/consumer/shopping/variant_overrides_spec.rb'
# Offense count: 48
# Offense count: 46
# Configuration parameters: CountComments, Max, CountAsOne, ExcludedMethods, IgnoredMethods.
# IgnoredMethods: refine
Metrics/BlockLength:
@@ -582,7 +596,6 @@ Metrics/BlockLength:
- 'spec/factories/line_item_factory.rb'
- 'spec/factories/order_cycle_factory.rb'
- 'spec/factories/order_factory.rb'
- 'spec/factories/payment_method_factory.rb'
- 'spec/factories/product_factory.rb'
- 'spec/factories/shipment_factory.rb'
- 'spec/factories/shipping_method_factory.rb'
@@ -598,7 +611,6 @@ Metrics/BlockLength:
- 'spec/swagger_helper.rb'
- 'spec/system/admin/order_cycles/complex_updating_specific_time_spec.rb'
- 'spec/system/consumer/shopping/checkout_spec.rb'
- 'spec/system/consumer/shopping/embedded_shopfronts_spec.rb'
# Offense count: 1
# Configuration parameters: CountBlocks, Max.
@@ -619,6 +631,7 @@ Metrics/ClassLength:
- 'app/controllers/api/v0/products_controller.rb'
- 'app/controllers/application_controller.rb'
- 'app/controllers/checkout_controller.rb'
- 'app/controllers/payment_gateways/paypal_controller.rb'
- 'app/controllers/spree/admin/orders_controller.rb'
- 'app/controllers/spree/admin/payment_methods_controller.rb'
- 'app/controllers/spree/admin/payments_controller.rb'
@@ -626,7 +639,6 @@ Metrics/ClassLength:
- 'app/controllers/spree/admin/reports_controller.rb'
- 'app/controllers/spree/admin/users_controller.rb'
- 'app/controllers/spree/orders_controller.rb'
- 'app/controllers/spree/paypal_controller.rb'
- 'app/models/enterprise.rb'
- 'app/models/order_cycle.rb'
- 'app/models/product_import/entry_processor.rb'
@@ -660,7 +672,7 @@ Metrics/ClassLength:
- 'lib/open_food_network/users_and_enterprises_report.rb'
- 'lib/open_food_network/xero_invoices_report.rb'
# Offense count: 72
# Offense count: 71
# Configuration parameters: IgnoredMethods, Max.
Metrics/CyclomaticComplexity:
Exclude:
@@ -723,7 +735,7 @@ Metrics/CyclomaticComplexity:
- 'spec/models/product_importer_spec.rb'
- 'spec/support/i18n_translations_checker.rb'
# Offense count: 254
# Offense count: 258
# Configuration parameters: CountComments, Max, CountAsOne, ExcludedMethods, IgnoredMethods.
Metrics/MethodLength:
Exclude:
@@ -743,6 +755,9 @@ Metrics/MethodLength:
- 'app/controllers/api/v0/shipments_controller.rb'
- 'app/controllers/api/v0/taxons_controller.rb'
- 'app/controllers/api/v0/variants_controller.rb'
- 'app/controllers/checkout_controller.rb'
- 'app/controllers/concerns/order_completion.rb'
- 'app/controllers/payment_gateways/paypal_controller.rb'
- 'app/controllers/shop_controller.rb'
- 'app/controllers/split_checkout_controller.rb'
- 'app/controllers/spree/admin/orders/customer_details_controller.rb'
@@ -757,8 +772,8 @@ Metrics/MethodLength:
- 'app/controllers/spree/admin/variants_controller.rb'
- 'app/controllers/spree/credit_cards_controller.rb'
- 'app/controllers/spree/orders_controller.rb'
- 'app/controllers/spree/paypal_controller.rb'
- 'app/controllers/spree/user_sessions_controller.rb'
- 'app/controllers/spree/users_controller.rb'
- 'app/controllers/stripe/callbacks_controller.rb'
- 'app/controllers/user_confirmations_controller.rb'
- 'app/controllers/user_passwords_controller.rb'
@@ -861,7 +876,7 @@ Metrics/MethodLength:
- 'spec/system/admin/reports_spec.rb'
- 'spec/system/consumer/shopping/variant_overrides_spec.rb'
# Offense count: 19
# Offense count: 20
# Configuration parameters: CountComments, Max, CountAsOne.
Metrics/ModuleLength:
Exclude:
@@ -877,6 +892,7 @@ Metrics/ModuleLength:
- 'engines/order_management/spec/services/order_management/subscriptions/validator_spec.rb'
- 'lib/open_food_network/column_preference_defaults.rb'
- 'spec/controllers/admin/order_cycles_controller_spec.rb'
- 'spec/controllers/api/v0/orders_controller_spec.rb'
- 'spec/lib/open_food_network/order_cycle_form_applicator_spec.rb'
- 'spec/lib/open_food_network/order_cycle_permissions_spec.rb'
- 'spec/models/spree/adjustment_spec.rb'
@@ -895,14 +911,13 @@ Metrics/ParameterLists:
- 'spec/support/controller_requests_helper.rb'
- 'spec/system/admin/reports_spec.rb'
# Offense count: 46
# Offense count: 45
# Configuration parameters: IgnoredMethods, Max.
Metrics/PerceivedComplexity:
Exclude:
- 'app/controllers/admin/enterprises_controller.rb'
- 'app/controllers/api/v0/variants_controller.rb'
- 'app/controllers/spree/admin/orders_controller.rb'
- 'app/controllers/spree/admin/payment_methods_controller.rb'
- 'app/controllers/spree/admin/payments_controller.rb'
- 'app/controllers/spree/admin/taxons_controller.rb'
- 'app/controllers/spree/admin/users_controller.rb'
@@ -1004,12 +1019,13 @@ Rails/ApplicationController:
Exclude:
- 'engines/dfc_provider/app/controllers/dfc_provider/api/base_controller.rb'
# Offense count: 5
# Offense count: 6
# Cop supports --auto-correct.
Rails/ApplicationJob:
Exclude:
- 'app/jobs/bulk_invoice_job.rb'
- 'app/jobs/heartbeat_job.rb'
- 'app/jobs/order_cycle_closing_job.rb'
- 'app/jobs/order_cycle_notification_job.rb'
- 'app/jobs/subscription_confirm_job.rb'
- 'app/jobs/subscription_placement_job.rb'
@@ -1043,22 +1059,15 @@ Rails/Date:
Exclude:
- 'spec/system/flatpickr_spec.rb'
# Offense count: 15
# Offense count: 4
# Configuration parameters: EnforcedStyle.
# SupportedStyles: slashes, arguments
Rails/FilePath:
Exclude:
- 'app/models/product_import/product_importer.rb'
- 'lib/tasks/karma.rake'
- 'spec/controllers/api/v0/logos_controller_spec.rb'
- 'spec/controllers/api/v0/product_images_controller_spec.rb'
- 'spec/controllers/api/v0/promo_images_controller_spec.rb'
- 'spec/controllers/api/v0/terms_and_conditions_controller_spec.rb'
- 'spec/factories/product_factory.rb'
- 'spec/models/content_configuration_spec.rb'
- 'spec/serializers/api/admin/enterprise_serializer_spec.rb'
- 'spec/support/downloads_helper.rb'
- 'spec/system/admin/enterprises/images_spec.rb'
# Offense count: 11
# Configuration parameters: Include.
@@ -1119,7 +1128,7 @@ Rails/HelperInstanceVariable:
- 'app/helpers/spree/orders_helper.rb'
# Offense count: 36
# Configuration parameters: Include.
# Configuration parameters: IgnoreScopes, Include.
# Include: app/models/**/*.rb
Rails/InverseOf:
Exclude:
@@ -1143,7 +1152,7 @@ Rails/InverseOf:
- 'app/models/spree/variant.rb'
- 'app/models/subscription_line_item.rb'
# Offense count: 39
# Offense count: 38
# Configuration parameters: Include.
# Include: app/controllers/**/*.rb
Rails/LexicallyScopedActionFilter:
@@ -1167,7 +1176,6 @@ Rails/LexicallyScopedActionFilter:
- 'app/controllers/spree/admin/users_controller.rb'
- 'app/controllers/spree/admin/zones_controller.rb'
- 'app/controllers/spree/users_controller.rb'
- 'app/controllers/user_passwords_controller.rb'
# Offense count: 18
Rails/OutputSafety:
@@ -1188,125 +1196,17 @@ Rails/OutputSafety:
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: AutoCorrect.
Rails/RelativeDateConstant:
Exclude:
- 'lib/tasks/data/remove_transient_data.rb'
# Offense count: 297
# Offense count: 4
# Configuration parameters: ForbiddenMethods, AllowedMethods.
# ForbiddenMethods: decrement!, decrement_counter, increment!, increment_counter, insert, insert!, insert_all, insert_all!, toggle!, touch, touch_all, update_all, update_attribute, update_column, update_columns, update_counters, upsert, upsert_all
Rails/SkipsModelValidations:
Exclude:
- 'app/controllers/admin/resource_controller.rb'
- 'app/controllers/checkout_controller.rb'
- 'app/controllers/spree/admin/payment_methods_controller.rb'
- 'app/controllers/spree/admin/shipping_methods_controller.rb'
- 'app/controllers/spree/admin/taxons_controller.rb'
- 'app/controllers/spree/credit_cards_controller.rb'
- 'app/jobs/subscription_confirm_job.rb'
- 'app/models/concerns/line_item_stock_changes.rb'
- 'app/models/enterprise.rb'
- 'app/models/enterprise_relationship.rb'
- 'app/models/product_import/inventory_reset_strategy.rb'
- 'app/models/proxy_order.rb'
- 'app/models/spree/address.rb'
- 'app/models/spree/adjustment.rb'
- 'app/models/spree/credit_card.rb'
- 'app/models/spree/gateway/pay_pal_express.rb'
- 'app/models/spree/inventory_unit.rb'
- 'app/models/spree/item_adjustments.rb'
- 'app/models/spree/order.rb'
- 'app/models/spree/order/checkout.rb'
- 'app/models/spree/payment.rb'
- 'app/models/spree/product.rb'
- 'app/models/spree/shipment.rb'
- 'app/models/spree/shipping_method.rb'
- 'app/models/spree/tax_category.rb'
- 'app/models/spree/taxonomy.rb'
- 'app/models/spree/variant.rb'
- 'app/models/spree/zone.rb'
- 'app/models/subscription.rb'
- 'app/models/variant_override.rb'
- 'app/services/order_factory.rb'
- 'app/services/place_proxy_order.rb'
- 'engines/order_management/app/services/order_management/order/updater.rb'
- 'engines/order_management/spec/services/order_management/reports/enterprise_fee_summary/report_service_spec.rb'
- 'engines/order_management/spec/services/order_management/subscriptions/stripe_payment_setup_spec.rb'
- 'lib/spree/core/controller_helpers/order.rb'
- 'lib/tasks/data/anonymize_data.rake'
- 'lib/tasks/sample_data/product_factory.rb'
- 'lib/tasks/users.rake'
- 'spec/controllers/admin/bulk_line_items_controller_spec.rb'
- 'spec/controllers/admin/customers_controller_spec.rb'
- 'spec/controllers/admin/subscription_line_items_controller_spec.rb'
- 'spec/controllers/admin/variant_overrides_controller_spec.rb'
- 'spec/controllers/api/v0/order_cycles_controller_spec.rb'
- 'spec/controllers/api/v0/orders_controller_spec.rb'
- 'spec/controllers/api/v0/products_controller_spec.rb'
- 'spec/controllers/api/v0/shipments_controller_spec.rb'
- 'spec/controllers/api/v0/variants_controller_spec.rb'
- 'spec/controllers/checkout_controller_spec.rb'
- 'spec/controllers/enterprises_controller_spec.rb'
- 'spec/controllers/spree/admin/orders/invoices_spec.rb'
- 'spec/controllers/spree/admin/orders/payments/payments_controller_spec.rb'
- 'spec/controllers/spree/admin/overview_controller_spec.rb'
- 'spec/controllers/spree/admin/payment_methods_controller_spec.rb'
- 'spec/controllers/spree/credit_cards_controller_spec.rb'
- 'spec/controllers/spree/orders_controller_spec.rb'
- 'spec/factories.rb'
- 'spec/factories/order_factory.rb'
- 'spec/factories/shipment_factory.rb'
- 'spec/helpers/enterprises_helper_spec.rb'
- 'spec/helpers/order_cycles_helper_spec.rb'
- 'spec/lib/open_food_network/address_finder_spec.rb'
- 'spec/lib/open_food_network/enterprise_fee_calculator_spec.rb'
- 'spec/lib/open_food_network/orders_and_fulfillments_report_spec.rb'
- 'spec/lib/open_food_network/permissions_spec.rb'
- 'spec/lib/open_food_network/products_and_inventory_report_spec.rb'
- 'spec/lib/open_food_network/scope_variant_to_hub_spec.rb'
- 'spec/lib/reports/packing/packing_report_spec.rb'
- 'spec/lib/stripe/credit_card_cloner_spec.rb'
- 'spec/lib/tasks/data/remove_transient_data_spec.rb'
- 'spec/models/concerns/variant_stock_spec.rb'
- 'spec/models/enterprise_relationship_spec.rb'
- 'spec/models/exchange_spec.rb'
- 'spec/models/spree/adjustment_spec.rb'
- 'spec/models/spree/asset_spec.rb'
- 'spec/models/spree/line_item_spec.rb'
- 'spec/models/spree/order/tax_spec.rb'
- 'spec/models/spree/order_inventory_spec.rb'
- 'spec/models/spree/order_spec.rb'
- 'spec/models/spree/tax_category_spec.rb'
- 'spec/models/spree/tax_rate_spec.rb'
- 'spec/models/spree/variant_spec.rb'
- 'spec/queries/customers_with_balance_spec.rb'
- 'spec/queries/outstanding_balance_spec.rb'
- 'spec/serializers/api/admin/subscription_line_item_serializer_spec.rb'
- 'spec/services/cache_service_spec.rb'
- 'spec/services/cap_quantity_spec.rb'
- 'spec/services/order_cart_reset_spec.rb'
- 'spec/services/order_checkout_restart_spec.rb'
- 'spec/services/order_cycle_distributed_products_spec.rb'
- 'spec/services/order_factory_spec.rb'
- 'spec/services/order_syncer_spec.rb'
- 'spec/services/process_payment_intent_spec.rb'
- 'spec/services/product_tag_rules_filterer_spec.rb'
- 'spec/services/products_renderer_spec.rb'
- 'spec/support/request/shop_workflow.rb'
- 'spec/system/admin/bulk_order_management_spec.rb'
- 'spec/system/admin/bulk_product_update_spec.rb'
- 'spec/system/admin/configuration/tax_rates_spec.rb'
- 'spec/system/admin/order_cycles/complex_editing_spec.rb'
- 'spec/system/admin/order_cycles/simple_spec.rb'
- 'spec/system/admin/order_spec.rb'
- 'spec/system/admin/payments_spec.rb'
- 'spec/system/consumer/caching/shops_caching_spec.rb'
- 'spec/system/consumer/shopping/checkout_spec.rb'
- 'spec/system/consumer/shopping/products_spec.rb'
- 'spec/system/consumer/shopping/shopping_spec.rb'
- 'spec/system/consumer/shopping/unit_price_spec.rb'
- 'spec/views/spree/shared/_order_details.html.haml_spec.rb'
# Offense count: 5
# Cop supports --auto-correct.
@@ -1331,12 +1231,11 @@ Rails/UniqueValidationWithoutIndex:
- 'app/models/spree/tax_category.rb'
- 'app/models/spree/zone.rb'
# Offense count: 2
# Offense count: 1
# Configuration parameters: Environments.
# Environments: development, test, production
Rails/UnknownEnv:
Exclude:
- 'app/controllers/spree/admin/payment_methods_controller.rb'
- 'app/models/spree/app_configuration.rb'
# Offense count: 1
@@ -1424,7 +1323,7 @@ Style/GlobalStdStream:
- 'lib/tasks/subscriptions/debug.rake'
- 'lib/tasks/subscriptions/test.rake'
# Offense count: 41
# Offense count: 39
# Configuration parameters: MinBodyLength.
Style/GuardClause:
Exclude:
@@ -1575,6 +1474,7 @@ Style/Send:
- 'engines/order_management/spec/services/order_management/reports/bulk_coop/bulk_coop_report_spec.rb'
- 'spec/controllers/admin/subscriptions_controller_spec.rb'
- 'spec/controllers/checkout_controller_spec.rb'
- 'spec/controllers/payment_gateways/paypal_controller_spec.rb'
- 'spec/controllers/spree/admin/base_controller_spec.rb'
- 'spec/controllers/spree/orders_controller_spec.rb'
- 'spec/helpers/order_cycles_helper_spec.rb'
@@ -1594,7 +1494,6 @@ Style/Send:
- 'spec/models/calculator/weight_spec.rb'
- 'spec/models/enterprise_spec.rb'
- 'spec/models/exchange_spec.rb'
- 'spec/models/spree/gateway/stripe_connect_spec.rb'
- 'spec/models/spree/order_inventory_spec.rb'
- 'spec/models/spree/order_spec.rb'
- 'spec/models/spree/payment_spec.rb'
@@ -1625,7 +1524,7 @@ Style/SlicingWithRange:
- 'lib/discourse/single_sign_on.rb'
- 'spec/lib/open_food_network/order_grouper_spec.rb'
# Offense count: 41
# Offense count: 31
# Cop supports --auto-correct.
# Configuration parameters: Mode.
Style/StringConcatenation:
@@ -1646,12 +1545,10 @@ Style/StringConcatenation:
- 'lib/open_food_network/orders_and_fulfillments_report/customer_totals_report.rb'
- 'lib/spree/api/controller_setup.rb'
- 'lib/spree/core/environment_extension.rb'
- 'spec/controllers/user_confirmations_controller_spec.rb'
- 'spec/lib/open_food_network/order_grouper_spec.rb'
- 'spec/models/spree/line_item_spec.rb'
- 'spec/models/spree/product_spec.rb'
- 'spec/models/spree/variant_spec.rb'
- 'spec/requests/embedded_shopfronts_headers_spec.rb'
- 'spec/services/embedded_page_service_spec.rb'
- 'spec/support/api_helper.rb'
- 'spec/support/features/datepicker_helper.rb'

View File

@@ -60,7 +60,7 @@ If the script succeeds you're ready to start developing. If not, take a look at
Now, your dreams of spinning up a development server can be realised:
bundle exec rails server
foreman start
Go to [http://localhost:3000](http://localhost:3000) to play around!

View File

@@ -59,6 +59,9 @@ gem 'oauth2', '~> 1.4.7' # Used for Stripe Connect
gem 'pagy', '~> 5.1'
gem 'rswag-api'
gem 'rswag-ui'
gem 'angularjs-rails', '1.8.0'
gem 'aws-sdk', '1.67.0'
gem 'bugsnag'
@@ -145,7 +148,7 @@ group :test, :development do
gem 'letter_opener', '>= 1.4.1'
gem 'rspec-rails', ">= 3.5.2"
gem 'rspec-retry'
gem 'rswag'
gem 'rswag-specs'
gem 'selenium-webdriver'
gem 'shoulda-matchers'
gem 'timecop'

View File

@@ -372,7 +372,7 @@ GEM
nokogiri (~> 1)
rake
mini_mime (1.1.2)
mini_portile2 (2.7.1)
mini_portile2 (2.8.0)
mini_racer (0.4.0)
libv8-node (~> 15.14.0.0)
minitest (5.15.0)
@@ -385,8 +385,8 @@ GEM
multi_xml (0.6.0)
multipart-post (2.1.1)
nio4r (2.5.8)
nokogiri (1.13.1)
mini_portile2 (~> 2.7.0)
nokogiri (1.13.3)
mini_portile2 (~> 2.8.0)
racc (~> 1.4)
oauth2 (1.4.7)
faraday (>= 0.8, < 2.0)
@@ -430,7 +430,7 @@ GEM
byebug (~> 11.0)
pry (~> 0.13.0)
public_suffix (4.0.6)
puma (5.5.2)
puma (5.6.2)
nio4r (~> 2.0)
raabro (1.4.0)
racc (1.6.0)
@@ -532,10 +532,6 @@ GEM
rspec-retry (0.6.2)
rspec-core (> 3.3)
rspec-support (3.10.2)
rswag (2.4.0)
rswag-api (= 2.4.0)
rswag-specs (= 2.4.0)
rswag-ui (= 2.4.0)
rswag-api (2.4.0)
railties (>= 3.1, < 7.0)
rswag-specs (2.4.0)
@@ -780,7 +776,9 @@ DEPENDENCIES
roo!
rspec-rails (>= 3.5.2)
rspec-retry
rswag
rswag-api
rswag-specs
rswag-ui
rubocop
rubocop-rails
sd_notify

View File

@@ -128,29 +128,53 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
$scope.selectedUnitsProduct = unitsProduct
$scope.selectedUnitsVariant = unitsVariant
$scope.getLineItemScale = (lineItem) ->
if lineItem.units_product && lineItem.units_variant && (lineItem.units_product.variant_unit == "weight" || lineItem.units_product.variant_unit == "volume")
VariantUnitManager.getScale(lineItem.units_variant.unit_value, lineItem.units_product.variant_unit)
else
1
$scope.sumUnitValues = ->
sum = $scope.filteredLineItems?.reduce (sum,lineItem) ->
sum + lineItem.final_weight_volume
sum = $scope.filteredLineItems?.reduce (sum, lineItem) ->
sum + $scope.roundToThreeDecimals(lineItem.final_weight_volume / $scope.getLineItemScale(lineItem))
, 0
$scope.sumMaxUnitValues = ->
sum = $scope.filteredLineItems?.reduce (sum,lineItem) ->
sum + lineItem.max_quantity * lineItem.units_variant.unit_value
sum + lineItem.max_quantity * $scope.roundToThreeDecimals(lineItem.units_variant.unit_value / $scope.getLineItemScale(lineItem))
, 0
$scope.roundToThreeDecimals = (value) ->
Math.round(value * 1000) / 1000
$scope.allFinalWeightVolumesPresent = ->
for i,lineItem of $scope.filteredLineItems
return false if !lineItem.hasOwnProperty('final_weight_volume') || !(lineItem.final_weight_volume > 0)
true
# How is this different to OptionValueNamer#name?
# Should it be extracted to that class or VariantUnitManager?
$scope.formattedValueWithUnitName = (value, unitsProduct, unitsVariant) ->
# A Units Variant is an API object which holds unit properies of a variant
if unitsProduct.hasOwnProperty("variant_unit") && (unitsProduct.variant_unit == "weight" || unitsProduct.variant_unit == "volume") && value > 0
scale = VariantUnitManager.getScale(value, unitsProduct.variant_unit)
Math.round(value/scale * 1000)/1000 + " " + VariantUnitManager.getUnitName(scale, unitsProduct.variant_unit)
$scope.getScale = (unitsProduct, unitsVariant) ->
if unitsProduct.hasOwnProperty("variant_unit") && (unitsProduct.variant_unit == "weight" || unitsProduct.variant_unit == "volume")
VariantUnitManager.getScale(unitsVariant.unit_value, unitsProduct.variant_unit)
else
null
$scope.getFormattedValueWithUnitName = (value, unitsProduct, unitsVariant, scale) ->
unit_name = VariantUnitManager.getUnitName(scale, unitsProduct.variant_unit)
$scope.roundToThreeDecimals(value) + " " + unit_name
$scope.getGroupBySizeFormattedValueWithUnitName = (value, unitsProduct, unitsVariant) ->
scale = $scope.getScale(unitsProduct, unitsVariant)
if scale
value = value / scale if scale != 28.35 && scale != 1 && scale != 453.6 # divide by scale if not smallest unit
$scope.getFormattedValueWithUnitName(value, unitsProduct, unitsVariant, scale)
else
''
$scope.formattedValueWithUnitName = (value, unitsProduct, unitsVariant) ->
scale = $scope.getScale(unitsProduct, unitsVariant)
if scale
$scope.getFormattedValueWithUnitName(value, unitsProduct, unitsVariant, scale)
else
''
$scope.fulfilled = (sumOfUnitValues) ->
@@ -158,7 +182,9 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
if $scope.selectedUnitsProduct.hasOwnProperty("group_buy_unit_size") && $scope.selectedUnitsProduct.group_buy_unit_size > 0 &&
$scope.selectedUnitsProduct.hasOwnProperty("variant_unit") &&
( $scope.selectedUnitsProduct.variant_unit == "weight" || $scope.selectedUnitsProduct.variant_unit == "volume" )
Math.round( sumOfUnitValues / $scope.selectedUnitsProduct.group_buy_unit_size * 1000)/1000
scale = $scope.getScale($scope.selectedUnitsProduct, $scope.selectedUnitsVariant)
sumOfUnitValues = sumOfUnitValues / scale if scale == 28.35 || scale == 453.6 # divide by scale if smallest unit
$scope.roundToThreeDecimals(sumOfUnitValues / $scope.selectedUnitsProduct.group_buy_unit_size * $scope.selectedUnitsVariant.unit_value)
else
''

View File

@@ -1,7 +1,11 @@
$(document).ready ->
progressTimer = null
$(document).ajaxStart ->
$("#progress").fadeIn()
progressTimer = setTimeout ->
$("#progress").fadeIn()
, 500
$(document).ajaxStop ->
$("#progress").fadeOut()
clearTimeout(progressTimer) if progressTimer?
$("#progress").stop().hide()

View File

@@ -56,7 +56,8 @@
#= require_tree .
document.addEventListener "turbo:load", ->
window.injector = angular.bootstrap document.body, ["Darkswarm"]
try
window.injector = angular.bootstrap document.body, ["Darkswarm"]
true
document.addEventListener "turbo:before-render", ->

View File

@@ -1,19 +0,0 @@
angular.module('Darkswarm').controller "ForgotCtrl", ($scope, $http, $location, AuthenticationService) ->
$scope.path = "/forgot"
$scope.sent = false
$scope.submit = ->
if $scope.spree_user.email != null
$http.post("/user/spree_user/password", {spree_user: $scope.spree_user}).then (response)->
$scope.sent = true
.catch (response) ->
$scope.errors = response.data.error
$scope.user_unconfirmed = (response.status == 401)
else
$scope.errors = t 'email_required'
$scope.resend_confirmation = ->
$http.post("/user/spree_user/confirmation", {spree_user: $scope.spree_user, return_url: $location.absUrl()}).then (response)->
$scope.messages = t('devise.confirmations.send_instructions')
.catch (response) ->
$scope.errors = t('devise.confirmations.failed_to_send')

View File

@@ -1,36 +0,0 @@
angular.module('Darkswarm').controller "LoginCtrl", ($scope, $timeout, $location, $http, $window, AuthenticationService, Redirections, Loading) ->
$scope.path = "/login"
$scope.modalMessage = null
$scope.$watch (->
AuthenticationService.modalMessage
), (newValue) ->
$scope.errors = newValue
$scope.submit = ->
Loading.message = t 'logging_in'
$http.post("/user/spree_user/sign_in", {spree_user: $scope.spree_user}).then (response)->
if window._paq
window._paq.push(['trackEvent', 'Signin/Signup', 'Login Submit Success', $location.absUrl()]);
if Redirections.after_login
$window.location.href = $window.location.origin + Redirections.after_login
else
$window.location.href = $window.location.origin + $window.location.pathname # Strips out hash fragments
.catch (response) ->
Loading.clear()
$scope.errors = response.data.message || response.data.error
$scope.user_unconfirmed = (response.data.error == t('devise.failure.unconfirmed'))
$scope.resend_confirmation = ->
$http.post("/user/spree_user/confirmation", {spree_user: $scope.spree_user, return_url: $location.absUrl()}).then (response)->
$scope.messages = t('devise.confirmations.send_instructions')
.catch (response) ->
$scope.errors = t('devise.confirmations.failed_to_send')
$timeout ->
if angular.isDefined($location.search()['validation'])
if $location.search()['validation'] == 'confirmed'
$scope.messages = t('devise.confirmations.confirmed')
if $location.search()['validation'] == 'not_confirmed'
$scope.errors = t('devise.confirmations.not_confirmed')

View File

@@ -1,17 +0,0 @@
angular.module('Darkswarm').controller "SignupCtrl", ($scope, $http, $window, $location, Redirections, AuthenticationService) ->
$scope.path = "/signup"
$scope.spree_user.password_confirmation = ''
$scope.errors =
email: null
password: null
$scope.submit = ->
$http.post("/user/spree_user", {spree_user: $scope.spree_user, return_url: $location.absUrl()}).then (response)->
$scope.errors = {email: null, password: null}
$scope.messages = t('devise.user_registrations.spree_user.signed_up_but_unconfirmed')
if window._paq
window._paq.push(['trackEvent', 'Signin/Signup', 'Signup Submit Success', $location.absUrl()]);
.catch (response) ->
$scope.errors = response.data

View File

@@ -1,12 +0,0 @@
angular.module('Darkswarm').controller "AuthenticationCtrl", ($scope, AuthenticationService, SpreeUser)->
$scope.open = AuthenticationService.open
$scope.toggle = AuthenticationService.toggle
$scope.spree_user = SpreeUser.spree_user
$scope.isActive = AuthenticationService.isActive
$scope.select = AuthenticationService.select
$scope.tabs =
login: { active: $scope.isActive('/login') }
signup: { active: $scope.isActive('/signup') }
forgot: { active: $scope.isActive('/forgot') }

View File

@@ -1,4 +1,4 @@
angular.module('Darkswarm').controller "CheckoutCtrl", ($scope, localStorageService, Checkout, CurrentUser, CurrentHub, AuthenticationService, SpreeUser, $http) ->
angular.module('Darkswarm').controller "CheckoutCtrl", ($scope, localStorageService, Checkout, CurrentUser, CurrentHub, $http) ->
$scope.Checkout = Checkout
$scope.submitted = false
@@ -35,14 +35,9 @@ angular.module('Darkswarm').controller "CheckoutCtrl", ($scope, localStorageServ
$scope.$broadcast 'purchaseFormInvalid', $scope.formdata
$scope.ensureUserIsGuest = (callback = null) ->
$http.post("/user/registered_email", {email: $scope.order.email}).then (response)->
if response.data.registered == true
$scope.promptLogin()
else
$http.post("/user/registered_email", {email: $scope.order.email})
.then (response)->
window.CableReady.perform(response.data)
.catch ->
$scope.validateForm() if $scope.submitted
callback() if callback
$scope.promptLogin = ->
SpreeUser.spree_user.email = $scope.order.email
AuthenticationService.pushMessage t('devise.failure.already_registered')
AuthenticationService.open '/login'

View File

@@ -1,4 +1,4 @@
angular.module('Darkswarm').controller "DetailsCtrl", ($scope, $timeout, $http, CurrentUser, AuthenticationService, SpreeUser, $controller) ->
angular.module('Darkswarm').controller "DetailsCtrl", ($scope, $timeout, $http, CurrentUser, SpreeUser, $controller) ->
angular.extend this, $controller('FieldsetMixin', {$scope: $scope})
$scope.name = "details"

View File

@@ -67,7 +67,7 @@ angular.module('Darkswarm').controller "ProductsCtrl", ($scope, $sce, $filter, $
page: page || $scope.page,
per_page: $scope.per_page,
'q[name_or_meta_keywords_or_variants_display_as_or_variants_display_name_or_supplier_name_cont]': $scope.query,
'q[properties_id_or_supplier_properties_id_in_any][]': $scope.activeProperties,
'q[with_properties][]': $scope.activeProperties,
'q[primary_taxon_id_in_any][]': $scope.activeTaxons
}

View File

@@ -1,11 +0,0 @@
angular.module('Darkswarm').directive 'auth', (AuthenticationService) ->
restrict: 'A'
link: (scope, elem, attrs) ->
elem.bind "click", ->
AuthenticationService.open '/' + attrs.auth
window.addEventListener "login:modal:open", ->
AuthenticationService.open '/login'
scope.$on "$destroy", ->
window.removeEventListener "login:modal:open"

View File

@@ -1,57 +0,0 @@
# This class deals with displaying things in the login modal. It chooses
# the modal tab templates and deals with switching tabs and passing data
# between the tabs. It has direct access to the instance of the login modal,
# and provides that access to other controllers as a service.
angular.module('Darkswarm').factory "AuthenticationService", (Navigation, $modal, $location, Redirections, Loading)->
new class AuthenticationService
selectedPath: "/login"
modalMessage: null
constructor: ->
if $location.path() in ["/login", "/signup", "/forgot"] || location.pathname is '/register/auth'
@open @initialTab(), @initialTemplate()
open: (path = false, template = 'authentication.html') =>
@modalInstance = $modal.open
templateUrl: template
windowClass: "login-modal medium"
@modalInstance.result.then @close, @close
@selectedPath = path || @selectedPath
Navigation.navigate @selectedPath
if window._paq
window._paq.push(['trackEvent', 'Signin/Signup', 'Login Modal View', window.location.href])
# Opens the /login tab if returning from email confirmation,
# the /signup tab if opened from the enterprise registration page,
# otherwise opens whichever tab is selected in the URL params ('/login', '/signup', or '/forgot')
initialTab: ->
if angular.isDefined($location.search()['validation'])
'/login'
else if location.pathname is '/register/auth'
'/signup'
else
$location.path()
# Loads the registration page modal when needed, otherwise the default modal
initialTemplate: ->
if location.pathname is '/register/auth'
'registration_authentication.html'
else
'authentication.html'
pushMessage: (message) ->
@modalMessage = String(message)
select: (path)=>
@selectedPath = path
Navigation.navigate @selectedPath
isActive: Navigation.isActive
close: ->
if location.pathname in ["/register", "/register/auth"]
Loading.message = t 'going_back_to_home_page'
location.hash = ""
location.pathname = "/"

View File

@@ -1,3 +0,0 @@
angular.module('Darkswarm').factory "Redirections", ($location)->
new class Redirections
after_login: $location.search().after_login

View File

@@ -6,6 +6,6 @@
.sixteen.columns.alpha#loading{ 'ng-show' => 'productsLoading()' }
%br
%img.spinner{ src: image_path("/spinning-circles.svg")}
%i.spinner.fa.fa-spin.fa-circle-o-notch
%h1
{{ 'js.admin.panels.exchange_products.loading_variants' | t }}

View File

@@ -1,7 +0,0 @@
%div{"ng-controller" => "AuthenticationCtrl"}
%tabset
%ng-include{src: "'login.html'"}
%ng-include{src: "'signup.html'"}
%ng-include{src: "'forgot.html'"}
%a.close-reveal-modal{"ng-click" => "$close()"}
%i.ofn-i_009-close

View File

@@ -1,31 +0,0 @@
%tab#forgot{ heading: "{{'forgot_password' | t}}", active: "tabs.forgot.active", select: "select(path)"}
%form{ ng: { controller: "ForgotCtrl", submit: "submit()" } }
.row
.large-12.columns
.alert-box.success{"ng-show" => "sent"}
{{ 'password_reset_sent' | t }}
.alert-box.success{"ng-show" => "messages != null"}
{{ messages }}
.alert-box.alert{"ng-show" => "errors != null"}
{{ errors }}
%a{ng: {show: 'user_unconfirmed', click: 'resend_confirmation()'}}
= t('devise.confirmations.resend_confirmation_email')
.row
.large-12.columns
%label{for: "email"} {{'signup_email' | t}}
%input.title.input-text{name: "email",
type: "email",
id: "email",
tabindex: 1,
inputmode: "email",
"ng-model" => "spree_user.email"}
.row
.large-12.columns
%input.button.primary{name: "commit",
tabindex: "3",
type: "submit",
value: "{{'reset_password' | t}}"}

View File

@@ -1,44 +0,0 @@
%tab#login-content{ heading: "{{'label_login' | t}}", active: "tabs.login.active", select: "select(path)"}
%form{ ng: { controller: "LoginCtrl", submit: "submit()" } }
.row
.large-12.columns
.alert-box.alert{"ng-show" => "errors != null"}
{{ errors }}
%a{ng: {show: 'user_unconfirmed', click: 'resend_confirmation()'}}
= t('devise.confirmations.resend_confirmation_email')
.alert-box.success{ng: {show: 'messages != null'}}
{{ messages }}
.row
.large-12.columns
%label{for: "email"} {{'email' | t}}
%input.title.input-text{name: "email",
type: "email",
id: "email",
tabindex: "1",
inputmode: "email",
"ng-model" => "spree_user.email"}
.row
.large-12.columns
%label{for: "password"} {{'password' | t}}
%input.title.input-text{name: "password",
type: "password",
id: "password",
autocomplete: "off",
tabindex: "2",
inputmode: "password",
"ng-model" => "spree_user.password"}
.row
.large-12.columns
%input{name: "remember_me",
type: "checkbox",
id: "remember_me",
value: "1",
tabindex: "3",
"ng-model" => "spree_user.remember_me"}
%label{for: "remember_me"} {{'remember_me' | t}}
.row
.large-12.columns
%input.button.primary{name: "commit",
tabindex: "4",
type: "submit",
value: "{{'label_login' | t}}"}

View File

@@ -1,17 +0,0 @@
.container
.row.modal-centered
%h2 {{'js.registration.welcome_to_ofn' | t}}
%h5 {{'js.registration.signup_or_login' | t}}:
%div{"ng-controller" => "AuthenticationCtrl"}
%tabset
%ng-include{src: "'signup.html'"}
%ng-include{src: "'login.html'"}
%ng-include{src: "'forgot.html'"}
%div{ ng: { show: "active('/signup')"} }
%hr
{{'js.registration.have_an_account' | t}}
%a{ href: "", ng: { click: "select('/login')"}}
{{'js.registration.action_login' | t}}
%a.close-reveal-modal{"ng-click" => "$close()"}
%i.ofn-i_009-close

View File

@@ -1,51 +0,0 @@
%tab#sign-up-content{ heading: "{{'label_signup' | t}}", active: 'tabs.signup.active', select: "select(path)"}
%form{ ng: { controller: "SignupCtrl", submit: "submit()" } }
.row
.large-12.columns
.alert-box.success{ng: {show: 'messages != null'}}
{{ messages }}
.large-12.columns
.alert-box.alert{ng: {show: 'errors.message != null'}}
{{ errors.message }}
.row
.large-12.columns
%label{for: "email"} {{'signup_email' | t}}
%input.title.input-text{name: "email",
type: "email",
id: "email",
tabindex: 1,
inputmode: "email",
"ng-model" => "spree_user.email"}
%span.error{"ng-show" => "errors.email != null"}
{{ errors.email.join(' ') }}
.row
.large-12.columns
%label{for: "password"} {{'choose_password' | t}}
%input.title.input-text{name: "password",
type: "password",
id: "password",
autocomplete: "off",
tabindex: 2,
inputmode: "password",
"ng-model" => "spree_user.password"}
%span.error{"ng-show" => "errors.password != null"}
{{ errors.password.join(' ') }}
.row
.large-12.columns
%label{for: "password_confirmation"} {{'confirm_password' | t}}
%input.title.input-text{name: "password_confirmation",
type: "password",
id: "password_confirmation",
autocomplete: "off",
tabindex: 2,
inputmode: "password",
"ng-model" => "spree_user.password_confirmation"}
%span.error{"ng-show" => "errors.password_confirmation != null"}
{{ errors.password_confirmation.join(' ') }}
.row
.large-12.columns
%input.button.primary{name: "commit",
tabindex: "3",
type: "submit",
value: "{{'action_signup' | t}}"}

View File

@@ -2,10 +2,10 @@
class SplitCheckoutConstraint
def matches?(request)
Flipper.enabled? :split_checkout, current_user(request)
OpenFoodNetwork::FeatureToggle.enabled? :split_checkout, current_user(request)
end
def current_user(request)
@spree_current_user ||= request.env['warden'].user
request.env['warden'].user
end
end

View File

@@ -99,7 +99,7 @@ module Admin
def customer_params
params.require(:customer).permit(
:enterprise_id, :name, :email, :code, :tag_list,
:enterprise_id, :first_name, :last_name, :email, :code, :tag_list,
ship_address_attributes: PermittedAttributes::Address.attributes,
bill_address_attributes: PermittedAttributes::Address.attributes,
)

View File

@@ -16,15 +16,16 @@ module Admin
respond_to do |format|
format.html do
if view_context.subscriptions_setup_complete?(@shops)
@order_cycles = OrderCycle.joins(:schedules).managed_by(spree_current_user)
@payment_methods = Spree::PaymentMethod.managed_by(spree_current_user)
@order_cycles = OrderCycle.joins(:schedules).managed_by(spree_current_user).includes([:distributors, :cached_incoming_exchanges])
@payment_methods = Spree::PaymentMethod.managed_by(spree_current_user).includes(:taggings)
@payment_method_tags = payment_method_tags_by_id
@shipping_methods = Spree::ShippingMethod.managed_by(spree_current_user)
else
@shop = @shops.first
render :setup_explanation
end
end
format.json { render_as_json @collection, ams_prefix: params[:ams_prefix] }
format.json { render_as_json @collection, ams_prefix: params[:ams_prefix], payment_method_tags: payment_method_tags_by_id }
end
end
@@ -165,5 +166,21 @@ module Admin
@subscription_params ||= PermittedAttributes::Subscription.new(params).call.
to_h.with_indifferent_access
end
def payment_method_tags_by_id
payment_method_tags = ::ActsAsTaggableOn::Tag.
joins(:taggings).
includes(:taggings).
where(taggings: { taggable_type: "Spree::PaymentMethod",
taggable_id: Spree::PaymentMethod.from(Enterprise.managed_by(spree_current_user).
select('enterprises.id').find_by(id: params[:enterprise_id])),
context: 'tags' })
payment_method_tags.each_with_object({}) do |tag, hash|
payment_method_id = tag.taggings.first.taggable_id
hash[payment_method_id] ||= []
hash[payment_method_id] << tag.name
end
end
end
end

View File

@@ -81,8 +81,7 @@ module Api
def permitted_ransack_params
[:name_or_meta_keywords_or_variants_display_as_or_variants_display_name_or_supplier_name_cont,
:properties_id_or_supplier_properties_id_in_any,
:primary_taxon_id_in_any]
:with_properties, :primary_taxon_id_in_any]
end
def distributor

View File

@@ -38,6 +38,7 @@ class ApplicationController < ActionController::Base
include Spree::Core::ControllerHelpers::Common
before_action :set_cache_headers # prevent cart emptying via cache when using back button #1213
before_action :set_after_login_url
include RawParams
include EnterprisesHelper
@@ -61,15 +62,9 @@ class ApplicationController < ActionController::Base
end
def set_checkout_redirect
referer_path = OpenFoodNetwork::RefererParser.path(request.referer)
if referer_path
is_checkout_path_the_referer = [main_app.checkout_path].include?(referer_path)
session["spree_user_return_to"] = if is_checkout_path_the_referer
referer_path
else
main_app.root_path
end
end
return unless URI(request.referer.to_s).path == main_app.checkout_path
session["spree_user_return_to"] = main_app.checkout_path
end
def shopfront_session
@@ -102,6 +97,10 @@ class ApplicationController < ActionController::Base
private
def set_after_login_url
store_location_for(:spree_user, params[:after_login]) if params[:after_login]
end
def shopfront_redirect
session[:shopfront_redirect]
end
@@ -111,7 +110,7 @@ class ApplicationController < ActionController::Base
end
def require_distributor_chosen
unless @distributor = current_distributor
unless (@distributor = current_distributor)
redirect_to main_app.root_path
false
end
@@ -139,17 +138,6 @@ class ApplicationController < ActionController::Base
!current_distributor.ready_for_checkout?
end
def check_order_cycle_expiry
if current_order_cycle&.closed?
Bugsnag.notify("Notice: order cycle closed during checkout completion", order: current_order)
current_order.empty!
current_order.set_order_cycle! nil
flash[:info] = I18n.t('order_cycle_closed')
redirect_to main_app.shop_path
end
end
# All render calls within the block will be performed with the specified format
# Useful for rendering html within a JSON response, particularly if the specified
# template or partial then goes on to render further partials without specifying

View File

@@ -12,7 +12,6 @@ class BaseController < ApplicationController
include OrderCyclesHelper
before_action :set_locale
before_action :check_order_cycle_expiry
private

View File

@@ -96,6 +96,7 @@ class CheckoutController < ::BaseController
def checkout_workflow(shipping_method_id)
while @order.state != "complete"
if @order.state == "payment"
update_payment_total
return if redirect_to_payment_gateway
return action_failed if @order.errors.any?
@@ -110,6 +111,11 @@ class CheckoutController < ::BaseController
update_response
end
def update_payment_total
@order.updater.update_totals
@order.updater.update_pending_payment
end
def redirect_to_payment_gateway
return unless selected_payment_method.external_gateway?
return unless (redirect_url = selected_payment_method.external_payment_url(order: @order))

View File

@@ -14,7 +14,7 @@ module CheckoutCallbacks
prepend_before_action :require_distributor_chosen
before_action :load_order, :associate_user, :load_saved_addresses, :load_saved_credit_cards
before_action :load_shipping_methods, :load_countries, if: -> { params[:step] == "details" }
before_action :load_shipping_methods, if: -> { params[:step] == "details" }
before_action :ensure_order_not_completed
before_action :ensure_checkout_allowed
@@ -49,15 +49,6 @@ module CheckoutCallbacks
@shipping_methods = Spree::ShippingMethod.for_distributor(@order.distributor).order(:name)
end
def load_countries
@countries = available_countries.map { |c| [c.name, c.id] }
@countries_with_states = available_countries.map { |c|
[c.id, c.states.map { |s|
[s.name, s.id]
}]
}
end
def redirect_to_shop?
!@order ||
!@order.checkout_allowed? ||

View File

@@ -18,6 +18,17 @@ module OrderStockCheck
redirect_to main_app.cart_path
end
def check_order_cycle_expiry
return unless current_order_cycle&.closed?
Bugsnag.notify("Notice: order cycle closed during checkout completion", order: current_order)
current_order.empty!
current_order.set_order_cycle! nil
flash[:info] = I18n.t('order_cycle_closed')
redirect_to main_app.shop_path
end
private
def sufficient_stock?

View File

@@ -8,6 +8,7 @@ module PaymentGateways
before_action :destroy_orphaned_paypal_payments, only: :confirm
before_action :load_checkout_order, only: [:express, :confirm]
before_action :handle_insufficient_stock, only: [:express, :confirm]
before_action :check_order_cycle_expiry, only: [:express, :confirm]
before_action :permit_parameters!
after_action :reset_order_when_complete, only: :confirm

View File

@@ -7,6 +7,7 @@ module PaymentGateways
before_action :load_checkout_order, only: :confirm
before_action :validate_payment_intent, only: :confirm
before_action :check_order_cycle_expiry, only: :confirm
before_action :validate_stock, only: :confirm
def confirm
@@ -46,7 +47,7 @@ module PaymentGateways
return if session[:access_token] || params[:order_token] || spree_current_user
flash[:error] = I18n.t("spree.orders.edit.login_to_view_order")
redirect_to root_path(anchor: "login?after_login=#{request.env['PATH_INFO']}")
redirect_to root_path(anchor: "login", after_login: request.original_fullpath)
end
def validate_stock

View File

@@ -9,7 +9,7 @@ class PaymentsController < BaseController
@payment = Spree::Payment.find(params[:id])
authorize! :show, @payment.order
if url = @payment.cvv_response_message
if (url = @payment.cvv_response_message)
redirect_to url
else
redirect_to order_url(@payment.order)
@@ -21,7 +21,9 @@ class PaymentsController < BaseController
def require_logged_in
return if session[:access_token] || spree_current_user
store_location_for :spree_user, request.original_fullpath
flash[:error] = I18n.t("spree.orders.edit.login_to_view_order")
redirect_to main_app.root_path(anchor: "login?after_login=#{request.env['PATH_INFO']}")
redirect_to main_app.root_path(anchor: "/login", after_login: request.original_fullpath)
end
end

View File

@@ -19,7 +19,7 @@ class RegistrationController < BaseController
def check_user
if spree_current_user.nil?
redirect_to registration_auth_path(anchor: "signup?after_login=#{request.env['PATH_INFO']}")
redirect_to registration_auth_path(anchor: "/signup", after_login: request.original_fullpath)
elsif !spree_current_user.can_own_more_enterprises?
render :limit_reached
end

View File

@@ -58,7 +58,7 @@ class SplitCheckoutController < ::BaseController
return unless selected_payment_method&.external_gateway?
return unless (redirect_url = selected_payment_method.external_payment_url(order: @order))
render operations: cable_car.redirect_to(url: URI(redirect_url))
render operations: cable_car.redirect_to(url: redirect_url)
true
end
@@ -71,6 +71,7 @@ class SplitCheckoutController < ::BaseController
@order.select_shipping_method(params[:shipping_method_id])
@order.update(order_params)
@order.updater.update_totals_and_states
validate_current_step!

View File

@@ -21,7 +21,8 @@ module Spree
@customers = []
if spree_current_user.enterprises.pluck(:id).include? search_params[:distributor_id].to_i
@customers = Customer.
ransack(m: 'or', email_start: search_params[:q], name_start: search_params[:q]).
ransack(m: 'or', email_start: search_params[:q], first_name_start: search_params[:q],
last_name_start: search_params[:q]).
result.
where(enterprise_id: search_params[:distributor_id].to_i)
end

View File

@@ -139,8 +139,10 @@ module Spree
def require_order_authentication
return if session[:access_token] || params[:order_token] || spree_current_user
store_location_for :spree_user, request.original_fullpath
flash[:error] = I18n.t("spree.orders.edit.login_to_view_order")
redirect_to main_app.root_path(anchor: "login?after_login=#{request.env['PATH_INFO']}")
redirect_to main_app.root_path(anchor: "/login", after_login: request.original_fullpath)
end
def order_to_update

View File

@@ -16,24 +16,6 @@ module Spree
include I18nHelper
before_action :set_locale
# Overridden due to bug in Devise.
# respond_with resource, :location => new_session_path(resource_name)
# is generating bad url /session/new.user
#
# overridden to:
# respond_with resource, :location => spree.login_path
#
def create
self.resource = resource_class.send_reset_password_instructions(raw_params[resource_name])
if resource.errors.empty?
set_flash_message(:notice, :send_instructions) if is_navigational_format?
respond_with resource, location: spree.login_path
else
respond_with_navigational(resource) { render :new }
end
end
# Devise::PasswordsController allows for blank passwords.
# Silly Devise::PasswordsController!
# Fixes spree/spree#2190.

View File

@@ -6,11 +6,12 @@ require "spree/core/controller_helpers/order"
module Spree
class UserSessionsController < Devise::SessionsController
helper 'spree/base'
include Spree::Core::ControllerHelpers::Auth
include Spree::Core::ControllerHelpers::Common
include Spree::Core::ControllerHelpers::Order
include CablecarResponses
helper 'spree/base'
before_action :set_checkout_redirect, only: :create
after_action :ensure_valid_locale_persisted, only: :create
@@ -19,25 +20,16 @@ module Spree
authenticate_spree_user!
if spree_user_signed_in?
respond_to do |format|
format.html {
flash[:success] = t('devise.success.logged_in_succesfully')
redirect_back_or_default(after_sign_in_path_for(spree_current_user))
}
format.js {
render json: { email: spree_current_user.login }, status: :ok
}
end
flash[:success] = t('devise.success.logged_in_succesfully')
render operations: cable_car.redirect_to(
url: return_url_or_default(after_sign_in_path_for(spree_current_user))
)
else
respond_to do |format|
format.html {
flash.now[:error] = t('devise.failure.invalid')
render :new
}
format.js {
render json: { message: t('devise.failure.invalid') }, status: :unauthorized
}
end
render status: :unauthorized, operations: cable_car.inner_html(
"#login-feedback",
partial("layouts/alert", locals: { type: "alert", message: t('devise.failure.invalid') })
)
end
end
@@ -57,11 +49,6 @@ module Spree
Spree.t(:login)
end
def redirect_back_or_default(default)
redirect_to(session["spree_user_return_to"] || default)
session["spree_user_return_to"] = nil
end
def ensure_valid_locale_persisted
# When creating a new user session we have to wait until after a successful
# login to be able to persist a selected locale on the current user

View File

@@ -4,6 +4,7 @@ module Spree
class UsersController < ::BaseController
include Spree::Core::ControllerHelpers
include I18nHelper
include CablecarResponses
layout 'darkswarm'
@@ -26,16 +27,33 @@ module Spree
# Endpoint for queries to check if a user is already registered
def registered_email
user = Spree::User.find_by email: params[:email]
render json: { registered: user.present? }
registered = Spree::User.find_by(email: params[:email]).present?
if registered
render status: :ok, operations: cable_car.
inner_html(
"#login-feedback",
partial("layouts/alert", locals: { type: "alert", message: t('devise.failure.already_registered') })
).
dispatch_event(name: "login:modal:open")
else
head :not_found
end
end
def create
@user = Spree::User.new(user_params)
if @user.save
redirect_back_or_default(main_app.root_url)
render operations: cable_car.inner_html(
"#signup-feedback",
partial("layouts/alert", locals: { type: "success", message: t('devise.user_registrations.spree_user.signed_up_but_unconfirmed') })
)
else
render :new
render status: :unprocessable_entity, operations: cable_car.morph(
"#signup-tab",
partial("layouts/signup_tab", locals: { signup_form_user: @user })
)
end
end

View File

@@ -3,6 +3,7 @@
class UserConfirmationsController < DeviseController
# Needed for access to current_ability, so we can authorize! actions
include Spree::Core::ControllerHelpers::Auth
include CablecarResponses
# GET /resource/confirmation/new
def new
@@ -20,6 +21,12 @@ class UserConfirmationsController < DeviseController
else
set_flash_message(:error, :confirmation_not_sent)
end
else
render operations: cable_car.inner_html(
"#forgot-feedback",
partial("layouts/alert", locals: { type: "success", message: t("devise.confirmations.send_instructions") })
)
return
end
respond_with_navigational(resource){ redirect_to login_path }
@@ -39,22 +46,25 @@ class UserConfirmationsController < DeviseController
end
def after_confirmation_path_for(resource)
result =
if resource.errors.empty?
'confirmed'
else
'not_confirmed'
end
result = resource.errors.empty? ? "confirmed" : "not_confirmed"
if result == 'confirmed' && resource.reset_password_token.present?
raw_reset_password_token = resource.regenerate_reset_password_token
return spree.edit_spree_user_password_path(
reset_password_token: raw_reset_password_token
reset_password_token: resource.regenerate_reset_password_token
)
end
path = (session[:confirmation_return_url] || login_path).to_s
path += path.include?('?') ? '&' : '?'
path + "validation=#{result}"
path = session[:confirmation_return_url] || root_path(anchor: "/login")
append_query_to_url(path, "validation", result)
end
private
def append_query_to_url(url, key, value)
uri = URI.parse(url.to_s)
query = URI.decode_www_form(uri.query || "") << [key, value]
uri.query = URI.encode_www_form(query)
uri.to_s
end
end

View File

@@ -1,38 +1,36 @@
# frozen_string_literal: true
class UserPasswordsController < Spree::UserPasswordsController
include CablecarResponses
layout 'darkswarm'
before_action :set_admin_redirect, only: :edit
def create
render_unconfirmed_response && return if user_unconfirmed?
return render_unconfirmed_response if user_unconfirmed?
self.resource = resource_class.send_reset_password_instructions(raw_params[resource_name])
if resource.errors.empty?
set_flash_message(:success, :send_instructions) if is_navigational_format?
respond_with resource, location: main_app.login_path
render operations: cable_car.inner_html(
"#forgot-feedback",
partial("layouts/alert", locals: { type: "success", message: t(:password_reset_sent) })
)
else
respond_to do |format|
format.html do
respond_with_navigational(resource) { render :new }
end
format.js do
render json: { error: t('email_not_found') }, status: :not_found
end
end
render status: :not_found, operations: cable_car.inner_html(
"#forgot-feedback",
partial("layouts/alert", locals: { type: "alert", message: t(:email_not_found) })
)
end
end
private
def set_admin_redirect
session["spree_user_return_to"] = params[:return_to] if params[:return_to]
end
def render_unconfirmed_response
render json: { error: t('email_unconfirmed') }, status: :unauthorized
render status: :unprocessable_entity, operations: cable_car.inner_html(
"#forgot-feedback",
partial("layouts/alert",
locals: { type: "alert", message: t(:email_unconfirmed), unconfirmed: true })
)
end
def user_unconfirmed?

View File

@@ -48,4 +48,13 @@ module ApplicationHelper
classes << "off-canvas" unless @hide_menu
classes << @shopfront_layout
end
def pdf_stylesheet_pack_tag(source)
if running_in_development?
options = { media: "all", host: "#{Webpacker.dev_server.host}:#{Webpacker.dev_server.port}" }
stylesheet_pack_tag(source, **options)
else
wicked_pdf_stylesheet_pack_tag(source)
end
end
end

View File

@@ -17,6 +17,24 @@ module Spree
end.sort { |a, b| a.name <=> b.name }
end
def countries
available_countries.map { |c| [c.name, c.id] }
end
def states_for_country(country)
country.states.map do |state|
[state.name, state.id]
end
end
def countries_with_states
available_countries.map { |c|
[c.id, c.states.map { |s|
[s.name, s.id]
}]
}
end
def pretty_time(time)
[I18n.l(time.to_date, format: :long),
time.strftime("%l:%M %p")].join(" ")

View File

@@ -8,9 +8,7 @@ class PaymentMailer < Spree::BaseMailer
subject = I18n.t('spree.payment_mailer.authorize_payment.subject',
distributor: @payment.order.distributor.name)
I18n.with_locale valid_locale(@payment.order.user) do
mail(to: payment.order.user.email,
from: from_address,
subject: subject)
mail(to: payment.order.email, from: from_address, subject: subject)
end
end

View File

@@ -5,7 +5,7 @@ class Customer < ApplicationRecord
acts_as_taggable
searchable_attributes :name, :email, :code
searchable_attributes :first_name, :last_name, :email, :code
belongs_to :enterprise
belongs_to :user, class_name: "Spree::User"
@@ -34,6 +34,10 @@ class Customer < ApplicationRecord
attr_accessor :gateway_recurring_payment_client_secret, :gateway_shop_id
def full_name
"#{first_name} #{last_name}".strip
end
private
def downcase_email

View File

@@ -29,6 +29,7 @@ class OrderCycle < ApplicationRecord
attr_accessor :incoming_exchanges, :outgoing_exchanges
before_update :reset_processed_at, if: :will_save_change_to_orders_close_at?
after_save :sync_subscriptions, if: :opening?
validates :name, :coordinator_id, presence: true
validate :orders_close_at_after_orders_open_at?
@@ -156,8 +157,10 @@ class OrderCycle < ApplicationRecord
# rubocop:disable Layout/LineLength
oc.preferred_product_selection_from_coordinator_inventory_only = preferred_product_selection_from_coordinator_inventory_only
# rubocop:enable Layout/LineLength
oc.schedule_ids = schedule_ids
oc.save!
exchanges.each { |e| e.clone!(oc) }
sync_subscriptions
oc.reload
end
@@ -272,6 +275,22 @@ class OrderCycle < ApplicationRecord
private
def opening?
(open? || upcoming?) && saved_change_to_orders_close_at? && was_closed?
end
def was_closed?
orders_close_at_previously_was.blank? || Time.zone.now > orders_close_at_previously_was
end
def sync_subscriptions
return unless schedule_ids.any?
OrderManagement::Subscriptions::ProxyOrderSyncer.new(
Subscription.where(schedule_id: schedule_ids)
).sync!
end
def orders_close_at_after_orders_open_at?
return if orders_open_at.blank? || orders_close_at.blank?
return if orders_close_at > orders_open_at

View File

@@ -73,11 +73,13 @@ module ProductImport
'variant_unit_scale', 'primary_taxon_id')
)
new_variant.save
if entry.attributes['on_demand'].present?
new_variant.on_demand = entry.attributes['on_demand']
end
if entry.attributes['on_hand'].present?
new_variant.on_hand = entry.attributes['on_hand']
if new_variant.persisted?
if entry.attributes['on_demand'].present?
new_variant.on_demand = entry.attributes['on_demand']
end
if entry.attributes['on_hand'].present?
new_variant.on_hand = entry.attributes['on_hand']
end
end
new_variant.product_id = product_id

View File

@@ -84,8 +84,7 @@ module Spree
before_validation :set_currency
before_validation :generate_order_number, on: :create
before_validation :clone_billing_address, if: :use_billing?
before_validation :associate_customer, unless: :customer_id?
before_validation :ensure_customer, unless: :customer_is_valid?
before_validation :ensure_customer
before_create :link_by_email
after_create :create_tax_charge!
@@ -310,6 +309,8 @@ module Spree
# Creates new tax charges if there are any applicable rates. If prices already
# include taxes then price adjustments are created instead.
def create_tax_charge!
return if state.in?(["cart", "address", "delivery"]) && Flipper.enabled?(:split_checkout)
clear_legacy_taxes!
Spree::TaxRate.adjust(self, line_items)
@@ -709,23 +710,25 @@ module Spree
def associate_customer
return customer if customer.present?
self.customer = Customer.of(distributor).find_by(email: email_for_customer)
Customer.of(distributor).find_by(email: email_for_customer)
end
def ensure_customer
return if associate_customer
def create_customer
return if customer_is_valid?
self.customer = Customer.new(
Customer.create(
enterprise: distributor,
email: email_for_customer,
user: user,
name: bill_address&.full_name,
first_name: bill_address&.first_name.to_s,
last_name: bill_address&.last_name.to_s,
bill_address: bill_address&.clone,
ship_address: ship_address&.clone
)
customer.save
end
Bugsnag.notify(customer.errors.full_messages.join(", ")) unless customer.persisted?
def ensure_customer
self.customer = associate_customer || create_customer
end
def update_adjustment!(adjustment)
@@ -734,16 +737,5 @@ module Spree
adjustment.update_adjustment!(force: true)
updater.update_totals_and_states
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 set_payment_amount!
update_totals
return unless pending_payments.any?
pending_payments.first.update_attribute :amount, total
end
end
end

View File

@@ -81,7 +81,6 @@ module Spree
after_transition to: :complete, do: :finalize!
after_transition to: :resumed, do: :after_resume
after_transition to: :canceled, do: :after_cancel
after_transition to: :payment, do: :set_payment_amount!
end
end

View File

@@ -147,7 +147,7 @@ module Spree
adjustment.originator = payment_method
adjustment.label = adjustment_label
adjustment.save
elsif payment_method.present?
elsif !processing_refund? && payment_method.present?
payment_method.create_adjustment(adjustment_label, self, true)
adjustment.reload
end
@@ -163,6 +163,10 @@ module Spree
private
def processing_refund?
amount.negative?
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
@@ -206,7 +210,7 @@ module Spree
# Makes newly entered payments invalidate previously entered payments so the most recent payment
# is used by the gateway.
def invalidate_old_payments
order.payments.with_state('checkout').where.not(id: id).each do |payment|
order.payments.incomplete.where.not(id: id).each do |payment|
# Using update_column skips validations and so it skips validate_source. As we are just
# invalidating past payments here, we don't want to validate all of them at this stage.
payment.update_columns(

View File

@@ -31,7 +31,7 @@ module Spree
searchable_attributes :supplier_id, :primary_taxon_id, :meta_keywords
searchable_associations :supplier, :properties, :primary_taxon, :variants, :master
searchable_scopes :active
searchable_scopes :active, :with_properties
has_many :product_option_types, dependent: :destroy
# We have an after_destroy callback on Spree::ProductOptionType. However, if we
@@ -69,6 +69,19 @@ module Spree
has_many :stock_items, through: :variants
has_many :supplier_properties, through: :supplier, source: :properties
scope :with_properties, ->(*property_ids) {
left_outer_joins(:product_properties).
left_outer_joins(:supplier_properties).
where(inherits_properties: true).
where(producer_properties: { property_id: property_ids }).
or(
where(spree_product_properties: { property_id: property_ids })
).
distinct
}
delegate_belongs_to :master, :sku, :price, :currency, :display_amount, :display_price, :weight,
:height, :width, :depth, :is_master, :cost_currency,
:price_in, :amount_in, :unit_value, :unit_description

View File

@@ -79,6 +79,8 @@ module Spree
after_create :create_stock_items
after_create :set_position
before_save :convert_variant_weight_to_decimal
around_destroy :destruction
# default variant scope only lists non-deleted variants
@@ -243,5 +245,9 @@ module Spree
self.unit_value = 1.0
end
def convert_variant_weight_to_decimal
self.weight = weight.to_d
end
end
end

View File

@@ -3,14 +3,14 @@
module Api
module Admin
class CustomerSerializer < ActiveModel::Serializer
attributes :id, :email, :enterprise_id, :user_id, :code, :tags, :tag_list, :name,
:allow_charges, :default_card_present?
attributes :id, :email, :enterprise_id, :user_id, :code, :tags, :tag_list, :first_name,
:last_name, :allow_charges, :default_card_present?
has_one :ship_address, serializer: Api::AddressSerializer
has_one :bill_address, serializer: Api::AddressSerializer
def name
object.name.presence || object.bill_address&.full_name
def full_name
object.full_name.presence || object.bill_address&.full_name
end
def tag_list

View File

@@ -7,11 +7,19 @@ module Api
attributes :id, :name, :type, :tag_list, :tags
def tag_list
object.tag_list.join(",")
payment_method_tag_list.join(",")
end
def tags
object.tag_list.map{ |t| { text: t } }
payment_method_tag_list.map{ |t| { text: t } }
end
private
def payment_method_tag_list
return object.tag_list unless options[:payment_method_tags]
options.dig(:payment_method_tags, object.id) || []
end
end
end

View File

@@ -7,9 +7,9 @@ module Api
def method_serializer
if object.type == 'Spree::Gateway::StripeSCA'
Api::Admin::PaymentMethod::StripeSerializer.new(object)
Api::Admin::PaymentMethod::StripeSerializer.new(object, options)
else
Api::Admin::PaymentMethod::BaseSerializer.new(object)
Api::Admin::PaymentMethod::BaseSerializer.new(object, options)
end
end
end

View File

@@ -4,8 +4,8 @@ module Api
module Admin
class SubscriptionSerializer < ActiveModel::Serializer
attributes :id, :shop_id, :customer_id, :schedule_id, :payment_method_id, :shipping_method_id,
:begins_at, :ends_at,
:customer_email, :customer_name, :schedule_name, :edit_path, :canceled_at, :paused_at, :state,
:begins_at, :ends_at, :customer_email, :customer_first_name, :customer_last_name,
:customer_full_name, :schedule_name, :edit_path, :canceled_at, :paused_at, :state,
:shipping_fee_estimate, :payment_fee_estimate
has_many :subscription_line_items, serializer: Api::Admin::SubscriptionLineItemSerializer
@@ -34,8 +34,16 @@ module Api
object.customer&.email
end
def customer_name
object.customer&.name
def customer_first_name
object.customer&.first_name
end
def customer_last_name
object.customer&.last_name
end
def customer_full_name
object.customer&.full_name
end
def schedule_name

View File

@@ -2,7 +2,7 @@
module Api
class CustomerSerializer < ActiveModel::Serializer
attributes :id, :enterprise_id, :name, :code, :email, :allow_charges
attributes :id, :enterprise_id, :first_name, :last_name, :code, :email, :allow_charges
def attributes
hash = super

View File

@@ -20,11 +20,17 @@ class TaxRateFinder
case originator
when Spree::TaxRate
[originator]
when Spree::ShippingMethod
shipping_method_fee_tax_rates(originator, adjustable)
when EnterpriseFee
enterprise_fee_tax_rates(originator, adjustable)
end
end
def shipping_method_fee_tax_rates(shipping_method, _adjustable)
shipping_method.tax_category ? shipping_method.tax_category.tax_rates : []
end
def enterprise_fee_tax_rates(enterprise_fee, adjustable)
case adjustable
when Spree::LineItem

View File

@@ -35,9 +35,9 @@
.row{ 'ng-if' => 'shop_id && RequestMonitor.loading' }
.sixteen.columns.alpha#loading
= render partial: "components/spinner"
= render partial: "components/admin_spinner"
%h1
=t :loading_customers
= t :loading_customers
.row{ :class => "sixteen columns alpha", 'ng-show' => '!RequestMonitor.loading && filteredCustomers.length == 0'}
%h1#no_results
@@ -50,7 +50,8 @@
%table.index#customers
%col.email{ width: "20%", 'ng-show' => 'columns.email.visible' }
%col.name{ width: "20%", 'ng-show' => 'columns.name.visible' }
%col.first_name{ width: "20%", 'ng-show' => 'columns.first_name.visible' }
%col.last_name{ width: "20%", 'ng-show' => 'columns.last_name.visible' }
%col.code{ width: "10%", 'ng-show' => 'columns.code.visible' }
%col.tags{ width: "20%", 'ng-show' => 'columns.tags.visible' }
%col.bill_address{ width: "10%", 'ng-show' => 'columns.bill_address.visible' }
@@ -63,8 +64,10 @@
-# %input{ :type => "checkbox", :name => 'toggle_bulk', 'ng-click' => 'toggleAllCheckboxes()', 'ng-checked' => "allBoxesChecked()" }
%th.email{ 'ng-show' => 'columns.email.visible' }
%a{ :href => '', 'ng-click' => "sorting.toggle('email')" }=t('admin.email')
%th.name{ 'ng-show' => 'columns.name.visible' }
%a{ :href => '', 'ng-click' => "sorting.toggle('name')" }=t('admin.name')
%th.first_name{ 'ng-show' => 'columns.first_name.visible' }
%a{ :href => '', 'ng-click' => "sorting.toggle('first_name')" }=t('admin.first_name')
%th.last_name{ 'ng-show' => 'columns.last_name.visible' }
%a{ :href => '', 'ng-click' => "sorting.toggle('last_name')" }=t('admin.last_name')
%th.code{ 'ng-show' => 'columns.code.visible' }
%a{ :href => '', 'ng-click' => "sorting.toggle('code')" }=t('admin.customers.index.code')
%th.tags{ 'ng-show' => 'columns.tags.visible' }=t('admin.tags')
@@ -78,8 +81,10 @@
%td.email{ 'ng-show' => 'columns.email.visible'}
%span{ 'ng-bind' => '::customer.email' }
%span.guest-label{ 'ng-show' => 'customer.user_id == null' }= t('.guest_label')
%td.name{ 'ng-show' => 'columns.name.visible'}
%input{ type: 'text', name: 'name', ng: { model: 'customer.name' }, 'obj-for-update' => 'customer', 'attr-for-update' => 'name'}
%td.first_name{ 'ng-show' => 'columns.first_name.visible'}
%input{ type: 'text', name: 'first_name', ng: { model: 'customer.first_name' }, 'obj-for-update' => 'customer', 'attr-for-update' => 'first_name'}
%td.last_name{ 'ng-show' => 'columns.last_name.visible'}
%input{ type: 'text', name: 'last_name', ng: { model: 'customer.last_name' }, 'obj-for-update' => 'customer', 'attr-for-update' => 'last_name'}
%td.code{ 'ng-show' => 'columns.code.visible' }
%input{ type: 'text', name: 'code', ng: {model: 'customer.code', change: 'checkForDuplicateCodes()'}, "obj-for-update" => "customer", "attr-for-update" => "code" }
%i.icon-warning-sign{ ng: {if: 'duplicate'} }

View File

@@ -9,8 +9,9 @@
%columns-dropdown{ action: "#{controller_name}_#{action_name}" }
.row{ 'ng-if' => '!loaded' }
.sixteen.columns.alpha#loading
= render partial: "components/spinner"
%h1= t('.loading_enterprises')
= render partial: "components/admin_spinner"
%h1
= t('.loading_enterprises')
.row{ :class => "sixteen columns alpha", 'ng-show' => 'loaded && filteredEnterprises.length == 0'}
%h1#no_results= t('.no_enterprises_found')

View File

@@ -57,7 +57,7 @@
= f.text_field :permalink, { 'ng-model' => "Enterprise.permalink", placeholder: "eg. your-shop-name", 'ng-model-options' => "{ updateOn: 'default blur', debounce: {'default': 300, 'blur': 0} }" }
.two.columns.omega
%div{ng: {show: "checking", cloak: true}, style: "width: 30px; height: 30px;"}
= render partial: "components/spinner"
= render partial: "components/admin_spinner"
%span{ ng: { class: 'availability.toLowerCase()', hide: "checking" } }
{{ availability }}
%i{ ng: { class: "{'icon-ok-sign': availability == 'Available', 'icon-remove-sign': availability == 'Unavailable'}" } }

View File

@@ -1,6 +1,6 @@
%div.sixteen.columns.alpha.omega#loading{ ng: { cloak: true, if: 'RequestMonitor.loading' } }
= render partial: "components/spinner"
= render partial: "components/admin_spinner"
%h1{ ng: { hide: 'orderCycles.length > 0' } }
=t('.loading_order_cycles')
= t('.loading_order_cycles')
%h1{ ng: { show: 'orderCycles.length > 0' } }
=t('.loading')
= t('.loading')

View File

@@ -2,7 +2,7 @@
= admin_inject_json_ams_array "admin.subscriptions", "shops", @shops, Api::Admin::IdNameSerializer if @shops
= admin_inject_json_ams_array "admin.subscriptions", "customers", @customers, Api::Admin::IdEmailSerializer if @customers
= admin_inject_json_ams_array "admin.subscriptions", "schedules", @schedules, Api::Admin::IdNameSerializer if @schedules
= admin_inject_json_ams_array "admin.subscriptions", "paymentMethods", @payment_methods, Api::Admin::PaymentMethodSerializer if @payment_methods
= admin_inject_json_ams_array "admin.subscriptions", "paymentMethods", @payment_methods, Api::Admin::PaymentMethodSerializer, { payment_method_tags: @payment_method_tags } if @payment_methods
= admin_inject_json_ams_array "admin.subscriptions", "shippingMethods", @shipping_methods, Api::Admin::IdNameSerializer if @shipping_methods
= admin_inject_json_ams_array "admin.subscriptions", "orderCycles", @order_cycles, Api::Admin::BasicOrderCycleSerializer if @order_cycles
= admin_inject_available_countries(module: "admin.subscriptions")

View File

@@ -1,3 +1,4 @@
%div.sixteen.columns.alpha.omega#loading{ ng: { cloak: true, if: 'shop_id && RequestMonitor.loading' } }
= render partial: "components/spinner"
%h1= t('.loading')
= render partial: "components/admin_spinner"
%h1
= t('.loading')

View File

@@ -41,7 +41,7 @@
%td.customer.text-center{ ng: { show: 'columns.customer.visible'}}
%span{ "ng-bind": '::subscription.customer_email' }
%br
%span{ "ng-bind": '::subscription.customer_name' }
%span{ "ng-bind": '::subscription.customer_full_name' }
%td.schedule.text-center{ ng: { show: 'columns.schedule.visible', bind: '::subscription.schedule_name' } }
%td.items.panel-toggle.text-center{ name: 'products', ng: { show: 'columns.items.visible' } }
%h5{ ng: { bind: 'itemCount(subscription)' } }

View File

@@ -1,3 +1,4 @@
%div.sixteen.columns.alpha.omega#loading{ ng: { cloak: true, if: 'hub_id && products.length == 0 && RequestMonitor.loading' } }
= render partial: "components/spinner"
%h1= t('.loading_inventory')
= render partial: "components/admin_spinner"
%h1
= t('.loading_inventory')

View File

@@ -3,17 +3,17 @@
.small-12.columns.text-center
%h3.pad-top
= t :checkout_headline
.row.pad-top
-if guest_checkout_allowed?
.row.pad-top{ "data-controller": "login-modal" }
- if guest_checkout_allowed?
.small-5.columns.text-center
%button.primary.expand{"auth" => "login"}
%button.primary.expand{ "data-action": "click->login-modal#call" }
= t :label_login
.small-2.columns.text-center
%p.pad-top= "#{t :action_or}"
.small-5.columns.text-center
%button.neutral-btn.dark.expand{"ng-click" => "enabled = true"}
= t :checkout_as_guest
-else
- else
.small-6.columns.small-centered
%button.primary.expand{"auth" => "login"}
%button.primary.expand{ "data-action": "click->login-modal#call" }
= t :label_login

View File

@@ -0,0 +1 @@
%i.spinner.fa.fa-spin.fa-circle-o-notch

View File

@@ -0,0 +1,5 @@
.alert-box{ class: "#{type}" }
= message
- if local_assigns[:unconfirmed]
%a{ "data-action": "login-modal#resend_confirmation" }
= t('devise.confirmations.resend_confirmation_email')

View File

@@ -0,0 +1,12 @@
#forgot-tab
= form_with url: spree_user_password_path, scope: :spree_user, data: { remote: "true" } do |form|
.row
.large-12.columns#forgot-feedback
.row
.large-12.columns
= form.label :email, t(:signup_email)
= form.email_field :email, { tabindex: 1, inputmode: "email", "data-login-modal-target": "email", "data-action": "input->login-modal#emailOnInput" }
.row
.large-12.columns
= form.submit t(:reset_password), { class: "button primary", tabindex: 2 }

View File

@@ -0,0 +1,24 @@
%div{"data-controller": "login-modal" }
.reveal-modal-bg.fade{ "data-login-modal-target": "background", "data-action": "click->login-modal#close" }
.reveal-modal.fade.login-modal.medium{ "data-login-modal-target": "modal" }
%div{ "data-controller": "tabs" }
%dl.tabs
%dd
%a{ data: { "tabs-target": "tab", "action": "tabs#select" } }= t(:label_login)
%dd
%a{ data: { "tabs-target": "tab", "action": "tabs#select" } }= t(:label_signup)
%dd
%a{ data: { "tabs-target": "tab", "action": "tabs#select" } }= t(:forgot_password)
.tabs-content
.content.active
%div{ data: { "tabs-target": "content" } }
= render "layouts/login_tab"
%div{ data: { "tabs-target": "content" } }
= render "layouts/signup_tab"
%div{ data: { "tabs-target": "content" } }
= render "layouts/forgot_tab"
%a.close-reveal-modal{ "data-action": "click->login-modal#close" }
%i.ofn-i_009-close

View File

@@ -0,0 +1,24 @@
#login-content
= form_with url: spree.spree_user_session_path, scope: :spree_user, data: { remote: "true" } do |form|
.row
.large-12.columns#login-feedback
- confirmation_result = request.query_parameters[:validation]
- if confirmation_result.in? ["confirmed", "not_confirmed"]
.alert-box{ class: "#{confirmation_result == "confirmed" ? "success" : "alert" }" }
= t("devise.confirmations.#{confirmation_result}")
.row
.large-12.columns
= form.label :email, t(:email)
= form.email_field :email, { tabindex: 1, inputmode: "email", autocomplete: "off", "data-login-modal-target": "email", "data-action": "input->login-modal#emailOnInput" }
.row
.large-12.columns
= form.label :password, t(:password)
= form.password_field :password, { tabindex: 2, inputmode: "password" }
.row
.large-12.columns
= form.check_box :remember_me, { tabindex: 3 }
= form.label :remember_me, t(:remember_me)
.row
.large-12.columns
= form.submit t(:label_login), { class: "button primary", tabindex: 4 }

View File

@@ -0,0 +1,25 @@
- signup_form_user = Spree::User.new if local_assigns[:signup_form_user].nil?
#signup-tab
= form_with model: signup_form_user, url: spree.account_path, scope: :user, data: { remote: "true" } do |form|
.row
.large-12.columns#signup-feedback
.row
.large-12.columns
= form.label :email, t(:signup_email)
= form.email_field :email, { tabindex: 1, "data-login-modal-target": "email", "data-action": "input->login-modal#emailOnInput" }
= form.error_message_on :email
.row
.large-12.columns
= form.label :password, t(:choose_password)
= form.password_field :password, { tabindex: 2, autocomplete: "off" }
= form.error_message_on :password
.row
.large-12.columns
= form.label :password_confirmation, t(:confirm_password)
= form.password_field :password_confirmation, { tabindex: 3, autocomplete: "off" }
= form.error_message_on :password_confirmation
.row
.large-12.columns
= form.submit t(:action_signup), { class: "button primary", tabindex: 4 }

View File

@@ -57,3 +57,5 @@
= yield :injection_data
= render "layouts/matomo_tag"
= render "layouts/login_modal"

View File

@@ -1 +1,28 @@
%div{"ng-controller" => "AuthenticationCtrl"}
%div{"data-controller": "login-modal" }
.reveal-modal-bg.fade.in{ "data-login-modal-target": "background", "data-action": "click->login-modal#returnHome", style: "display: block;" }
.reveal-modal.fade.login-modal.medium.in{ "data-login-modal-target": "modal", style: "display: block;" }
.row.modal-centered
%h2= t('js.registration.welcome_to_ofn')
%h5= t('js.registration.signup_or_login')
%div{ "data-controller": "tabs" }
%dl.tabs
%dd
%a{ data: { "tabs-target": "tab", "action": "tabs#select" } }= t(:label_signup)
%dd
%a{ data: { "tabs-target": "tab", "action": "tabs#select" } }= t(:label_login)
%dd
%a{ data: { "tabs-target": "tab", "action": "tabs#select" } }= t(:forgot_password)
.tabs-content
.content.active
%div{ data: { "tabs-target": "content" } }
= render "layouts/signup_tab"
%div{ data: { "tabs-target": "content" } }
= render "layouts/login_tab"
%div{ data: { "tabs-target": "content" } }
= render "layouts/forgot_tab"
%a.close-reveal-modal{ "data-action": "click->login-modal#returnHome" }
%i.ofn-i_009-close

View File

@@ -1,12 +0,0 @@
- if spree_current_user.nil?
%li#login-link= link_to t(:label_login), "#login", id: "sidebarLoginButton", class: "sidebar-button"
%li#login-name.hide
%li.divider
%li#sign-up-link= link_to t(:label_signup), "#signup", id: "sidebarSignUpButton", class: "sidebar-button"
%li#sign-out-link.hide= link_to "Sign Out", "/logout"
- else
%li#login-link.hide= link_to t(:label_login), "#sidebar", id: "sidebarLoginButton", class: "sidebar-button"
%li#login-name= link_to "#{spree_current_user.email}", "#"
%li.divider
%li#sign-up-link.hide= link_to t(:label_signup), "#"
%li#sign-out-link= link_to t(:label_logout), "/logout"

View File

@@ -1,5 +1,5 @@
%li#login-link
%a{"auth" => "login"}
%li#login-link{ "data-controller": "login-modal" }
%a{"auth": "login", "data-action": "click->login-modal#call" }
%img{ src: image_pack_path("menu/icn-login.svg") }
%span
= t 'label_login'

View File

@@ -1,12 +1,12 @@
.content{ "darker-background" => true }
.row.footer-pad
.small-12.columns
.small-12.columns{ "data-controller": "login-modal" }
%strong
= t '.require_customer_login'
%p
- if spree_current_user.nil?
%p
= t('.require_login_html', login: ('<a auth="login">' + t('.login') + '</a>').html_safe, signup: ('<a auth="signup">' + t('.signup') + '</a>').html_safe)
= t('.require_login_html', login: ('<a auth="login" data-action="click->login-modal#call">' + t('.login') + '</a>').html_safe, signup: ('<a auth="signup" data-action="click->login-modal#call">' + t('.signup') + '</a>').html_safe)
%p
= t('.require_login_2_html', contact: link_to(t('.contact'), '#contact'), enterprise: current_distributor.name)
- else

View File

@@ -25,7 +25,7 @@
= bill_address.text_field :phone, { placeholder: t("split_checkout.step1.your_details.phone.placeholder") }
= f.error_message_on "bill_address.phone"
%div.checkout-substep{ "data-controller": "dependant-select", "data-dependant-select-options-value": @countries_with_states }
%div.checkout-substep
-# BILLING ADDRESS
%div.checkout-title
= t("split_checkout.step1.billing_address.title")
@@ -45,18 +45,21 @@
= bill_address.text_field :city, { placeholder: t("split_checkout.step1.address.city.placeholder") }
= f.error_message_on "bill_address.city"
%div.checkout-input
= bill_address.label :state_id, t("split_checkout.step1.address.state_id.label")
= bill_address.select :state_id, @countries_with_states, { }, { "data-dependant-select-target": "select" }
%div.checkout-input
= bill_address.label :zipcode, t("split_checkout.step1.address.zipcode.label")
= bill_address.text_field :zipcode, { placeholder: t("split_checkout.step1.address.zipcode.placeholder") }
= f.error_message_on "bill_address.zipcode"
%div.checkout-input
= bill_address.label :country_id, t("split_checkout.step1.address.country_id.label")
= bill_address.select :country_id, @countries, { selected: @order.bill_address.country_id || DefaultCountry.id }, {"data-dependant-select-target": "source", "data-action": "dependant-select#handleSelectChange"}
%div{ "data-controller": "dependant-select", "data-dependant-select-options-value": countries_with_states }
- bill_address_country = @order.bill_address.country || DefaultCountry.country
%div.checkout-input
= bill_address.label :country_id, t("split_checkout.step1.address.country_id.label")
= bill_address.select :country_id, countries, { selected: bill_address_country.id }, { "data-dependant-select-target": "source", "data-action": "dependant-select#handleSelectChange" }
%div.checkout-input
= bill_address.label :state_id, t("split_checkout.step1.address.state_id.label")
= bill_address.select :state_id, states_for_country(bill_address_country), { selected: @order.bill_address&.state_id }, { "data-dependant-select-target": "select" }
- if spree_current_user||true
%div.checkout-input
@@ -71,6 +74,7 @@
- display_ship_address = false
- ship_method_description = nil
- selected_shipping_method ||= @shipping_methods[0].id if @shipping_methods.length == 1
- @shipping_methods.each do |shipping_method|
%div.checkout-input.checkout-input-radio
= fields_for shipping_method do |shipping_method_form|
@@ -121,18 +125,21 @@
= ship_address.text_field :city, { placeholder: t("split_checkout.step1.address.city.placeholder") }
= f.error_message_on "ship_address.city"
%div.checkout-input
= ship_address.label :state_id, t("split_checkout.step1.address.state_id.label")
= ship_address.select :state_id, @countries_with_states, { }, { "data-dependant-select-target": "select" }
%div.checkout-input
= ship_address.label :zipcode, t("split_checkout.step1.address.zipcode.label")
= ship_address.text_field :zipcode, { placeholder: t("split_checkout.step1.address.zipcode.placeholder") }
= f.error_message_on "ship_address.zipcode"
%div.checkout-input
= ship_address.label :country_id, t("split_checkout.step1.address.country_id.label")
= ship_address.select :country_id, @countries, { selected: @order.ship_address.country_id || DefaultCountry.id }, {"data-dependant-select-target": "source", "data-action": "dependant-select#handleSelectChange"}
%div{ "data-controller": "dependant-select", "data-dependant-select-options-value": countries_with_states }
- ship_address_country = @order.ship_address.country || DefaultCountry.country
%div.checkout-input
= ship_address.label :country_id, t("split_checkout.step1.address.country_id.label")
= ship_address.select :country_id, countries, { selected: ship_address_country.id }, { "data-dependant-select-target": "source", "data-action": "dependant-select#handleSelectChange" }
%div.checkout-input
= ship_address.label :state_id, t("split_checkout.step1.address.state_id.label")
= ship_address.select :state_id, states_for_country(ship_address_country), { selected: @order.ship_address&.state_id }, { "data-dependant-select-target": "select" }
- if spree_current_user
%div.checkout-input{ "data-toggle-target": "content", style: "display: none" }

View File

@@ -4,6 +4,7 @@
= t("split_checkout.step2.payment_method.title")
- selected_payment_method = @order.payments&.with_state(:checkout)&.first&.payment_method_id
- selected_payment_method ||= available_payment_methods[0].id if available_payment_methods.length == 1
- available_payment_methods.each do |payment_method|
%div.checkout-input.checkout-input-radio
= f.radio_button :payment_method_id, payment_method.id,

View File

@@ -71,10 +71,11 @@
= render 'spree/orders/summary', order: @order
- if any_terms_required?(@order.distributor)
= render partial: "terms_and_conditions", locals: { f: f }
%div.checkout-submit.medium-6
= f.submit t("split_checkout.step3.submit"), name: "confirm_order", class: "button primary", disabled: @terms_and_conditions_accepted == false || @platform_tos_accepted == false
%a.button.cancel{href: main_app.cart_path}
= t("split_checkout.step3.cancel")
.checkout-step3{"data-controller": "sticky", "data-sticky-target": "container"}
- if any_terms_required?(@order.distributor)
= render partial: "terms_and_conditions", locals: { f: f }
.medium-6
.checkout-submit
= f.submit t("split_checkout.step3.submit"), name: "confirm_order", class: "button primary", disabled: @terms_and_conditions_accepted == false || @platform_tos_accepted == false
%a.button.cancel{href: main_app.checkout_step_path(:payment)}
= t("split_checkout.step3.cancel")

View File

@@ -19,7 +19,7 @@
.sub-header.show-for-medium-down
= render partial: "shopping_shared/order_cycles"
.row{ "data-controller": "guest-checkout", "data-guest-checkout-distributor-value": @order.distributor.id }
%div{ "data-controller": "guest-checkout", "data-guest-checkout-distributor-value": @order.distributor.id }
%div{ style: "display: #{spree_current_user ? 'block' : 'none'}", "data-guest-checkout-target": "checkout" }
= render partial: "checkout"

View File

@@ -70,7 +70,7 @@
.three.columns
.text-center
= t("admin.orders.bulk_management.group_buy_unit_size")
.text-center {{ formattedValueWithUnitName( selectedUnitsProduct.group_buy_unit_size, selectedUnitsProduct, selectedUnitsVariant ) }}
.text-center {{ getGroupBySizeFormattedValueWithUnitName(selectedUnitsProduct.group_buy_unit_size , selectedUnitsProduct, selectedUnitsVariant ) }}
.three.columns
.text-center
= t("admin.orders.bulk_management.total_qtt_ordered")
@@ -103,7 +103,7 @@
%columns-dropdown{ action: "#{controller_name}_#{action_name}" }
%div.sixteen.columns.alpha#loading{ 'ng-if' => 'RequestMonitor.loading' }
= render partial: "components/spinner"
= render partial: "components/admin_spinner"
%h1
= t("admin.orders.bulk_management.loading")

View File

@@ -92,13 +92,10 @@
%div{'ng-if' => 'order.ready_to_capture'}
%button.icon-capture.icon_link.no-text{'ng-click' => 'capturePayment(order)', rel: 'nofollow', 'ofn-with-tip' => t('.capture')}
.orders-loading{'ng-show' => 'RequestMonitor.loading'}
.row
.small-12.columns.fullwidth.text-center
= render partial: "components/spinner"
.row
.small-12.columns.fullwidth.text-center
%span= t('.loading')
.sixteen.columns.alpha#loading{ 'ng-show' => 'RequestMonitor.loading' }
= render partial: "components/admin_spinner"
%h1
= t('.loading')
%div{'ng-show' => "!RequestMonitor.loading && orders.length > 0" }
= render partial: 'admin/shared/angular_pagination'

View File

@@ -1,4 +1,4 @@
= wicked_pdf_stylesheet_pack_tag "mail"
= pdf_stylesheet_pack_tag "mail"
%table{:width => "100%"}
%tbody

View File

@@ -1,4 +1,4 @@
= wicked_pdf_stylesheet_pack_tag "mail"
= pdf_stylesheet_pack_tag "mail"
%table{:width => "100%"}
%tbody

View File

@@ -1,7 +1,7 @@
%div.sixteen.columns.alpha#loading{ 'ng-if' => 'RequestMonitor.loading' }
%br
= render partial: "components/spinner"
%h1= t('.title')
= render partial: "components/admin_spinner"
%h1
= t('.title')
%div.sixteen.columns.alpha{ 'ng-show' => '!RequestMonitor.loading && products.length == 0 && q.query.length == 0' }
%h1#no_results= t('.no_products')

View File

@@ -20,10 +20,6 @@
Spree.routes.taxonomy_taxons = "#{main_app.api_v0_taxonomy_taxons_url(@taxonomy)}";
Spree.routes.admin_taxonomy_taxons = "#{spree.admin_taxonomy_taxons_url(@taxonomy)}";
#taxonomy_tree.tree
#progress{style: "display:none;"}
= image_pack_tag 'select2-spinner.gif', title: 'Spinner', style: "vertical-align:bottom;"
= t("spree.updating")
\..
.info= t("spree.taxonomy_tree_instruction")
%br/
.filter-actions.actions

View File

@@ -1,24 +1,4 @@
#progress
/ By Sam Herbert (@sherb), for everyone. More @ http://goo.gl/7AJzbL
%svg{:class => "spinner", :viewbox => "0 0 58 58", :xmlns => "http://www.w3.org/2000/svg"}
%g{:fill => "none", "fill-rule" => "evenodd"}
%g{:stroke => "currentColor", "stroke-width" => "1.5", :transform => "translate(2 1)"}
%circle{:cx => "42.601", :cy => "11.462", :fill => "currentColor", "fill-opacity" => "1", :r => "5"}
%animate{:attributename => "fill-opacity", :begin => "0s", :calcmode => "linear", :dur => "1.3s", :repeatcount => "indefinite", :values => "1;0;0;0;0;0;0;0"}
%circle{:cx => "49.063", :cy => "27.063", :fill => "currentColor", "fill-opacity" => "0", :r => "5"}
%animate{:attributename => "fill-opacity", :begin => "0s", :calcmode => "linear", :dur => "1.3s", :repeatcount => "indefinite", :values => "0;1;0;0;0;0;0;0"}
%circle{:cx => "42.601", :cy => "42.663", :fill => "currentColor", "fill-opacity" => "0", :r => "5"}
%animate{:attributename => "fill-opacity", :begin => "0s", :calcmode => "linear", :dur => "1.3s", :repeatcount => "indefinite", :values => "0;0;1;0;0;0;0;0"}
%circle{:cx => "27", :cy => "49.125", :fill => "currentColor", "fill-opacity" => "0", :r => "5"}
%animate{:attributename => "fill-opacity", :begin => "0s", :calcmode => "linear", :dur => "1.3s", :repeatcount => "indefinite", :values => "0;0;0;1;0;0;0;0"}
%circle{:cx => "11.399", :cy => "42.663", :fill => "currentColor", "fill-opacity" => "0", :r => "5"}
%animate{:attributename => "fill-opacity", :begin => "0s", :calcmode => "linear", :dur => "1.3s", :repeatcount => "indefinite", :values => "0;0;0;0;1;0;0;0"}
%circle{:cx => "4.938", :cy => "27.063", :fill => "currentColor", "fill-opacity" => "0", :r => "5"}
%animate{:attributename => "fill-opacity", :begin => "0s", :calcmode => "linear", :dur => "1.3s", :repeatcount => "indefinite", :values => "0;0;0;0;0;1;0;0"}
%circle{:cx => "11.399", :cy => "11.462", :fill => "currentColor", "fill-opacity" => "0", :r => "5"}
%animate{:attributename => "fill-opacity", :begin => "0s", :calcmode => "linear", :dur => "1.3s", :repeatcount => "indefinite", :values => "0;0;0;0;0;0;1;0"}
%circle{:cx => "27", :cy => "5", :fill => "currentColor", "fill-opacity" => "0", :r => "5"}
%animate{:attributename => "fill-opacity", :begin => "0s", :calcmode => "linear", :dur => "1.3s", :repeatcount => "indefinite", :values => "0;0;0;0;0;0;0;1"}
= render partial: "components/admin_spinner"
= Spree.t(:loading)
\...

View File

@@ -4,24 +4,30 @@ export default class extends Controller {
static targets = ["source", "select"];
static values = { options: Array };
connect() {
this.populateSelect(parseInt(this.sourceTarget.value));
}
handleSelectChange() {
this.populateSelect(parseInt(this.sourceTarget.value));
}
populateSelect(sourceId) {
const allOptions = this.optionsValue;
const options = allOptions.find((option) => option[0] === sourceId)[1];
const selectBox = this.selectTarget;
selectBox.innerHTML = "";
options.forEach((item) => {
const opt = document.createElement("option");
opt.value = item[1];
opt.innerHTML = item[0];
selectBox.appendChild(opt);
this.removeCurrentOptions()
this.dependantOptionsFor(sourceId).forEach((item) => {
this.addOption(item[0], item[1])
});
}
removeCurrentOptions() {
this.selectTarget.innerHTML = ""
}
addOption(label, value) {
const newOption = document.createElement("option")
newOption.innerHTML = label
newOption.value = value
this.selectTarget.appendChild(newOption)
}
dependantOptionsFor(sourceId) {
return this.optionsValue.find((option) => option[0] === sourceId)[1]
}
}

View File

@@ -0,0 +1,79 @@
import { Controller } from "stimulus"
import CableReady from "cable_ready"
export default class extends Controller {
static targets = ["background", "modal", "email"]
static values = { email: String }
connect() {
if(this.hasModalTarget) {
window.addEventListener("login:modal:open", this.open)
if(location.hash.substr(1).includes("/login")) {
this.open()
}
}
}
call(event) {
event.preventDefault()
window.dispatchEvent(new Event("login:modal:open"))
}
emailOnInput(event) {
this.emailValue = event.currentTarget.value
this.emailTargets.forEach((element) => {
element.value = this.emailValue
})
}
open = () => {
if(!location.hash.substr(1).includes("/login")) {
history.pushState({}, "", "#/login")
}
this.backgroundTarget.style.display = "block"
this.modalTarget.style.display = "block"
setTimeout(() => {
this.modalTarget.classList.add("in")
this.backgroundTarget.classList.add("in")
document.querySelector("body").classList.add("modal-open")
})
window._paq?.push(['trackEvent', 'Signin/Signup', 'Login Modal View', window.location.href])
}
close() {
history.pushState({}, "", window.location.pathname + window.location.search)
this.modalTarget.classList.remove("in")
this.backgroundTarget.classList.remove("in")
document.querySelector("body").classList.remove("modal-open")
setTimeout(() => {
this.backgroundTarget.style.display = "none"
this.modalTarget.style.display = "none"
}, 200)
}
resend_confirmation() {
fetch("/user/spree_user/confirmation", {
method: "POST",
body: JSON.stringify({
spree_user: { email: this.emailValue }
})
}).then(data => data.json()).then(CableReady.perform)
}
returnHome() {
window.location = "/"
}
disconnect() {
if(this.hasModalTarget) {
window.removeEventListener("login:modal:open", this.open)
}
}
}

View File

@@ -0,0 +1,24 @@
import { Controller } from "stimulus";
// This add a `sticked` class to the element (`container`) when the user scrolls down
// or up until the element is `sticked`.
// The class is then removed once the element is no more `sticked`.
// The element should have a `data-sticky-target` attribute with `container` as value.
// This is only functionnal with a sticked element at the bottom. We could improve that point
// by adding a `data-position` attribute with `top|bottom|left|right` as value and
// modify the code below to handle the different positions.
export default class extends Controller {
static targets = ["container"];
connect() {
this.containerTarget.style.position = "sticky";
this.containerTarget.style.bottom = "-1px";
const observer = new IntersectionObserver(
([e]) => {
e.target.classList.toggle("sticked", e.intersectionRatio < 1);
},
{ threshold: [1] }
);
observer.observe(this.containerTarget);
}
}

View File

@@ -0,0 +1,36 @@
import { Controller } from "stimulus";
export default class extends Controller {
static targets = ["tab", "content"]
select(event) {
this.setCurrentTab(this.tabTargets.indexOf(event.currentTarget))
}
// private
connect() {
this.setCurrentTab()
}
setCurrentTab(tabIndex = 0) {
this.showSelectedContent(tabIndex)
this.setButtonActiveClass(tabIndex)
}
showSelectedContent(tabIndex) {
this.contentTargets.forEach((element, index) => {
element.hidden = index !== tabIndex
})
}
setButtonActiveClass(tabIndex) {
this.tabTargets.forEach((element, index) => {
if(index === tabIndex) {
element.classList.add("active")
} else {
element.classList.remove("active")
}
})
}
}

View File

@@ -1,28 +1,42 @@
// Loading throbber displayed when ajax request takes too long to complete
#progress {
@include border-radius(10px);
position: fixed;
top: -10px;
left: 50%;
z-index: 1000;
opacity: 0.8;
width: 200px;
background-color: $spree-blue;
color: $color-1;
display: none;
font-size: 120%;
@include border-radius(0 0 4px 4px);
position: fixed;
top: 0;
left: 50%;
transform: translateX(-50%);
z-index: 1000;
background-color: $spree-blue;
color: #FFFFFF;
opacity: .8;
font-size: 1rem;
padding: .5rem 1rem;
font-weight: bold;
line-height: 40px;
margin-left: -100px;
padding-top: 15px;
text-align: center;
text-transform: uppercase;
.spinner {
position: absolute;
left: 50%;
width: 30px;
height: 30px;
top: -5px;
margin-left: -15px;
margin-right: 5px;
}
}
// Loading message replacing a table when it's loading for example
#loading {
text-align: center;
padding: 2rem 0;
color: $color-4;
i {
font-size: 2rem;
}
img.spinner {
border: 0px;
width: 100px;
height: 100px;
}
h1 {
margin-top: 20px;
color: inherit;
}
}

View File

@@ -203,19 +203,6 @@ table#listing_enterprise_groups {
}
}
#loading {
text-align: center;
img.spinner {
border: 0px;
width: 100px;
height: 100px;
}
h1 {
margin-top: 20px;
color: gray;
}
}
.field_with_errors > input {
border-color: red;
}

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