Compare commits

...

264 Commits

Author SHA1 Message Date
Jean-Baptiste Bellet
dab595f17f Update all locales with the latest Transifex translations 2023-07-07 17:11:40 +02:00
Filipe
f0bcb79c09 Merge pull request #11169 from openfoodfoundation/11164-admin-orders-actions-dropdown-is-not-well-placed
Fix container issues introduced by #11123
2023-07-07 11:15:14 +01:00
jibees
967c5a99c3 Merge pull request #11167 from openfoodfoundation/dependabot/bundler/faraday-2.7.10
chore(deps): bump faraday from 2.7.9 to 2.7.10
2023-07-07 11:50:01 +02:00
jibees
72fa132c17 Merge pull request #11172 from openfoodfoundation/dependabot/bundler/sanitize-6.0.2
chore(deps): bump sanitize from 6.0.1 to 6.0.2
2023-07-07 11:44:16 +02:00
dependabot[bot]
9f539df5e0 chore(deps): bump sanitize from 6.0.1 to 6.0.2
Bumps [sanitize](https://github.com/rgrove/sanitize) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/rgrove/sanitize/releases)
- [Changelog](https://github.com/rgrove/sanitize/blob/main/HISTORY.md)
- [Commits](https://github.com/rgrove/sanitize/compare/v6.0.1...v6.0.2)

---
updated-dependencies:
- dependency-name: sanitize
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-07 09:06:31 +00:00
dependabot[bot]
74ef681607 chore(deps): bump faraday from 2.7.9 to 2.7.10
Bumps [faraday](https://github.com/lostisland/faraday) from 2.7.9 to 2.7.10.
- [Release notes](https://github.com/lostisland/faraday/releases)
- [Changelog](https://github.com/lostisland/faraday/blob/main/CHANGELOG.md)
- [Commits](https://github.com/lostisland/faraday/compare/v2.7.9...v2.7.10)

---
updated-dependencies:
- dependency-name: faraday
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-07 09:06:22 +00:00
Gaetan Craig-Riou
fb3c99e52c Merge pull request #11121 from filipefurtad0/cart_state_orders_not_appearing_orders_page
Cart state orders not appearing orders page
2023-07-07 09:27:36 +10:00
Matt-Yorkley
eb71c65fc0 Merge pull request #11138 from Matt-Yorkley/variant-timestamps
Add timestamps to variants table
2023-07-06 18:22:19 +01:00
Matt-Yorkley
bbf53133cb Add timestamps to variants table 2023-07-06 16:16:03 +01:00
jibees
2e9442a7ab Merge pull request #11127 from openfoodfoundation/dependabot/bundler/vcr-6.2.0
chore(deps-dev): bump vcr from 6.1.0 to 6.2.0
2023-07-06 16:43:49 +02:00
dependabot[bot]
de384ac261 chore(deps-dev): bump vcr from 6.1.0 to 6.2.0
Bumps [vcr](https://github.com/vcr/vcr) from 6.1.0 to 6.2.0.
- [Release notes](https://github.com/vcr/vcr/releases)
- [Changelog](https://github.com/vcr/vcr/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vcr/vcr/compare/v6.1.0...v6.2.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-06 14:22:55 +00:00
Filipe
ba1ba6dbec Merge pull request #11092 from mkllnk/bye-datadog
Remove datadog gem, too expensive
2023-07-06 15:20:20 +01:00
Filipe
99ed019413 Merge pull request #11136 from Matt-Yorkley/remove-available-on
Remove :available_on attribute from Product
2023-07-06 15:20:08 +01:00
jibees
3f070d7152 Merge pull request #11166 from openfoodfoundation/dependabot/npm_and_yarn/floating-ui/dom-1.4.4
chore(deps): bump @floating-ui/dom from 1.4.3 to 1.4.4
2023-07-06 16:13:35 +02:00
jibees
5f54c7fe56 Merge pull request #11146 from openfoodfoundation/dependabot/bundler/rails-7.0.6
chore(deps): bump rails from 7.0.5 to 7.0.6
2023-07-06 16:04:16 +02:00
jibees
9c035c6114 Merge pull request #11128 from openfoodfoundation/dependabot/bundler/view_component-3.3.0
chore(deps): bump view_component from 3.2.0 to 3.3.0
2023-07-06 16:00:51 +02:00
Matt-Yorkley
42a3087cdb Remove :available_on attribute from Product class 2023-07-06 14:36:35 +01:00
Jean-Baptiste Bellet
6ee388fe51 Fix container issues 2023-07-06 11:41:54 +02:00
dependabot[bot]
5c56c9b60b chore(deps): bump @floating-ui/dom from 1.4.3 to 1.4.4
Bumps [@floating-ui/dom](https://github.com/floating-ui/floating-ui/tree/HEAD/packages/dom) from 1.4.3 to 1.4.4.
- [Release notes](https://github.com/floating-ui/floating-ui/releases)
- [Commits](https://github.com/floating-ui/floating-ui/commits/@floating-ui/dom@1.4.4/packages/dom)

---
updated-dependencies:
- dependency-name: "@floating-ui/dom"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-06 09:10:25 +00:00
David Cook
05a22b80bc Merge pull request #11123 from dacook/buu-products-table
[admin_style_v3] Products table with variants
2023-07-06 09:37:31 +10:00
Filipe
39b597096c Merge pull request #11137 from Matt-Yorkley/remove-product-permalink
Remove :permalink attribute from Product
2023-07-05 18:35:48 +01:00
jibees
de34b9b109 Merge pull request #11142 from openfoodfoundation/dependabot/npm_and_yarn/floating-ui/dom-1.4.3
chore(deps): bump @floating-ui/dom from 1.4.2 to 1.4.3
2023-07-05 14:53:53 +02:00
dependabot[bot]
2a059fd879 chore(deps): bump rails from 7.0.5 to 7.0.6
Bumps [rails](https://github.com/rails/rails) from 7.0.5 to 7.0.6.
- [Release notes](https://github.com/rails/rails/releases)
- [Commits](https://github.com/rails/rails/compare/v7.0.5...v7.0.6)

---
updated-dependencies:
- dependency-name: rails
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-05 12:52:51 +00:00
jibees
9205aafbd9 Merge pull request #11147 from openfoodfoundation/dependabot/bundler/faraday-2.7.9
chore(deps): bump faraday from 2.7.6 to 2.7.9
2023-07-05 14:52:00 +02:00
jibees
409cf54a45 Merge pull request #11152 from openfoodfoundation/dependabot/bundler/state_machines-activerecord-0.9.0
chore(deps): bump state_machines-activerecord from 0.8.0 to 0.9.0
2023-07-05 14:49:08 +02:00
jibees
24f9770acc Merge pull request #11154 from openfoodfoundation/dependabot/bundler/rubocop-1.54.1
chore(deps-dev): bump rubocop from 1.52.1 to 1.54.1
2023-07-05 14:48:15 +02:00
jibees
722f7b981b Merge pull request #11158 from openfoodfoundation/dependabot/bundler/geocoder-1.8.2
chore(deps): bump geocoder from 1.8.1 to 1.8.2
2023-07-05 14:47:12 +02:00
dependabot[bot]
20bc6c8028 chore(deps): bump geocoder from 1.8.1 to 1.8.2
Bumps [geocoder](https://github.com/alexreisner/geocoder) from 1.8.1 to 1.8.2.
- [Changelog](https://github.com/alexreisner/geocoder/blob/master/CHANGELOG.md)
- [Commits](https://github.com/alexreisner/geocoder/compare/v1.8.1...v1.8.2)

---
updated-dependencies:
- dependency-name: geocoder
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-05 09:23:48 +00:00
dependabot[bot]
eba8d8db83 chore(deps-dev): bump rubocop from 1.52.1 to 1.54.1
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.52.1 to 1.54.1.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.52.1...v1.54.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-04 09:26:38 +00:00
filipefurtad0
e547e735c0 Adds test on API call for orders page
Removes unecessary assertion on http status
2023-07-03 11:51:46 +01:00
filipefurtad0
3f7958afe3 Adds regression test to issue #11120 2023-07-03 11:51:46 +01:00
dependabot[bot]
a9cb35dcc0 chore(deps): bump state_machines-activerecord from 0.8.0 to 0.9.0
Bumps [state_machines-activerecord](https://github.com/state-machines/state_machines-activerecord) from 0.8.0 to 0.9.0.
- [Commits](https://github.com/state-machines/state_machines-activerecord/compare/v0.8.0...v0.9.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-03 09:58:39 +00:00
Maikel
400d087789 Merge pull request #11133 from mkllnk/dfc-api-specs
OFN DFC API documenation in OpenAPI format generated with Rswag
2023-07-03 10:53:40 +10:00
Maikel
ffda344838 Merge pull request #11144 from mkllnk/remove-test-unit
Remove unused gem test-unit
2023-07-03 10:34:24 +10:00
Matt-Yorkley
fefa9288a4 Remove :permalink attribute from Product 2023-06-30 11:37:57 +01:00
Filipe
b175793b91 Merge pull request #10704 from abdellani/hide-customers-with-no-completed-orders
Hide users with no completed orders from a hub's customers list
2023-06-30 10:56:56 +01:00
dependabot[bot]
7c9cabbab7 chore(deps): bump faraday from 2.7.6 to 2.7.9
Bumps [faraday](https://github.com/lostisland/faraday) from 2.7.6 to 2.7.9.
- [Release notes](https://github.com/lostisland/faraday/releases)
- [Changelog](https://github.com/lostisland/faraday/blob/main/CHANGELOG.md)
- [Commits](https://github.com/lostisland/faraday/compare/v2.7.6...v2.7.9)

---
updated-dependencies:
- dependency-name: faraday
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-30 09:34:58 +00:00
Maikel Linke
9c2d092f4d Remove unused gem test-unit 2023-06-30 11:37:57 +10:00
filipefurtad0
efb5132ac2 Update all locales with the latest Transifex translations 2023-06-29 23:28:28 +01:00
Filipe
54a85a504d Merge pull request #11101 from mkllnk/dfc-api-key
Allow access to DFC API with OFN API token
2023-06-29 17:20:21 +01:00
Filipe
d27a632a38 Merge pull request #11079 from abdellani/fix-distributors-listing-on-checkout-options
filter distributors before listing on checkout options
2023-06-29 17:02:34 +01:00
Filipe
36f4b2e7f9 Merge pull request #11107 from jibees/11085-edit-variant-cant-update-values-on-the-variant-edit-page
Admin, Edit variant: remove unwanted extra space on price (added in certain specific conditions)
2023-06-29 16:46:42 +01:00
Filipe
97f131e556 Merge pull request #11089 from jibees/11049-invoices-actions-dropdown-menu-disappears-after-creating-the-first-invoice
[Invoices] Actions dropdown menu disappears after creating the first invoice
2023-06-29 16:23:35 +01:00
Filipe
da226ea021 Merge pull request #11109 from mkllnk/image-urls
Gracefully deal with missing S3 config
2023-06-29 12:50:36 +01:00
Filipe
d92c7f89bd Merge pull request #11022 from Matt-Yorkley/matomo
Call matomo manually on asynchronous page visits
2023-06-29 12:02:48 +01:00
dependabot[bot]
af4ae4aaae chore(deps): bump @floating-ui/dom from 1.4.2 to 1.4.3
Bumps [@floating-ui/dom](https://github.com/floating-ui/floating-ui/tree/HEAD/packages/dom) from 1.4.2 to 1.4.3.
- [Release notes](https://github.com/floating-ui/floating-ui/releases)
- [Commits](https://github.com/floating-ui/floating-ui/commits/@floating-ui/dom@1.4.3/packages/dom)

---
updated-dependencies:
- dependency-name: "@floating-ui/dom"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-29 09:59:20 +00:00
Jean-Baptiste Bellet
045435e9cc use the variant price itself 2023-06-29 11:02:56 +02:00
Jean-Baptiste Bellet
3286094804 number_to_currency can be nil: use a safe operator 2023-06-29 10:47:00 +02:00
Maikel Linke
8b3f45263c Remove unnecessary spec clean-up
And clarify locale setup.
2023-06-29 10:40:01 +02:00
Jean-Baptiste Bellet
2fcf706aa3 Remove unwanted space at the end of the price
This `number_to_currency` method seems to display an extra space, not necessary when unit is `''`
Strip it.

Update specs as well. Thanks @filipefurtad0 for specs!!!
2023-06-29 10:40:01 +02:00
filipefurtad0
6b84fbf2b8 Adds after block, to remove configurations
Sets pending shared examples
2023-06-29 10:40:01 +02:00
filipefurtad0
504ee50dd4 Sets up a spec for #11085 2023-06-29 10:40:00 +02:00
David Cook
0ba342bf11 Merge pull request #10965 from macanudo527/fix_linelength_bundle2
Fix Layout/LineLength - Bundle 2
2023-06-29 15:27:08 +10:00
Maikel
dd1e1328cc Merge pull request #11080 from rioug/fix-bulk-order-cancelation-spec
Fix bulk order cancellation test
2023-06-29 14:44:04 +10:00
Maikel
46ddab3781 Merge pull request #11088 from Matt-Yorkley/deployments-check
Update workflow permissions check to latest version
2023-06-29 14:34:46 +10:00
Maikel
6392c2c115 Merge pull request #11075 from mkllnk/test-cache
Use Redis for caching in test environment
2023-06-29 14:33:09 +10:00
Maikel Linke
029364d4a3 Express spec intent with DSL instead of comment 2023-06-29 14:25:50 +10:00
David Cook
714642f331 Use different Redis database for test environment 2023-06-29 14:15:18 +10:00
Filipe
ba99f85f5c Merge pull request #10914 from abdellani/fix-stripe-sca-failure
redirect user to payment when the card doesn't have enough credit
2023-06-28 19:58:18 +01:00
Matt-Yorkley
ace2c5778f Call matomo manually on Turbo page visits 2023-06-28 12:52:54 +01:00
Matt-Yorkley
a0a1f8f910 Merge pull request #11002 from openfoodfoundation/voucher-prep
Vouchers part 1
2023-06-28 11:30:12 +01:00
Maikel Linke
78d6d129e8 Simplify with extracted helper method 2023-06-28 14:11:50 +10:00
Maikel Linke
d21e6f99bb Swaggerise CatalogItems spec 2023-06-28 14:11:50 +10:00
Maikel Linke
883e637545 Create deterministic test data for stable API docs
Otherwise the auto-generated Swagger file changes all the time without
code changes.
2023-06-28 13:50:54 +10:00
Maikel Linke
df29eaab98 Document DFC example body to create a product 2023-06-28 13:50:54 +10:00
Maikel Linke
db77d1591c Add test examples to DFC API documentation
In other API specs, you provide example values in the schema. So the
specs contain examples which can be used for the documentation. But
instead of defining example data separately, we can use the generated
data by the specs. This way we document real output and don't have to
double up on documentation.

Note that we don't have schema definitions for the DFC API yet. And it
wouldn't make sense to replicate the DFC Ontology manually in JSON
Schema for this purpose. The DFC Connector ensures already that we
comply with the ontology. But I hope that we can use a tool at some
point to generate JSON Schema from the DFC Ontology which would add more
detail to the Swagger docs, I think.
2023-06-28 13:50:54 +10:00
Maikel Linke
b14c9bdf4c Swaggerize SuppliedProduct spec 2023-06-28 13:50:54 +10:00
Maikel Linke
f0a5475563 Swaggerize Enterprise spec 2023-06-28 13:50:54 +10:00
Maikel Linke
7c0a4108d8 Show api-docs in production as well
We were hiding that before because the API is not officially released
yet but that's actually quite annoying. It's very conenient to have the
UI on production and be able to try out endpoints.
2023-06-28 13:50:54 +10:00
Maikel Linke
494c5e78de Swaggerize Person spec
I chose the simplest spec first to demonstrate how it works. The UI at
/api-docs now shows this endpoint with two possible responses.

The docs are missing an example response which I hope to add later.
2023-06-28 13:50:54 +10:00
Maikel Linke
8368a6ccc9 Announce the new DFC endpoint
We need to declare in each spec file for which endpoint the spec is
because it was just choosing the first declared one by default. The
first one was v1 and now it's dfc-v1.7.
2023-06-28 13:50:54 +10:00
Maikel Linke
de51a7833d Add script to swaggerize DFC API in its engine
Rswag doesn't look for specs in engines by default. We haven't added any
Rswag specs in the dfc_provider engine yet but that will come.

The generated API schema has some superfluous whitespace removed due to
a fix in the rswag gems.
2023-06-28 13:50:54 +10:00
David Cook
f280881126 Style tables with relaxed and condensed rows
* attempt with shadows, but they are between every row: http://jsfiddle.net/d872e3nb/
 * another attempt at applying styles to tbody groups http://jsfiddle.net/sb38cLdu/
2023-06-28 09:59:57 +10:00
David Cook
2c14fe0434 Add variant rows and price column 2023-06-28 09:59:57 +10:00
David Cook
9c573f823a Move .content under main content div
The .content div provides overall page margins and a max width, and is already nested inside the nav menus (this allows the nav background to fill the full width of the page.
The main content area should be structured the same way, so we can have flexibility needed to allow some screens to use the full page.

This doesn't seem to change the layout of any screens in the admin interface.

Now the table content can stretch full width
2023-06-28 09:59:57 +10:00
David Cook
6a2025b271 Add products table
With ellipsis clipping for long lines.
2023-06-28 09:59:57 +10:00
David Cook
809c15b197 Load products page with reflex
We will add the products in the next commit.
2023-06-28 09:59:57 +10:00
David Cook
841192fb96 Add new products page
Hidden behind admin_style_v3 feature toggle.
2023-06-28 09:59:57 +10:00
David Cook
efcaab5deb Rename colour variables 2023-06-28 09:59:57 +10:00
dependabot[bot]
d65239fe47 chore(deps): bump view_component from 3.2.0 to 3.3.0
Bumps [view_component](https://github.com/viewcomponent/view_component) from 3.2.0 to 3.3.0.
- [Release notes](https://github.com/viewcomponent/view_component/releases)
- [Changelog](https://github.com/ViewComponent/view_component/blob/main/docs/CHANGELOG.md)
- [Commits](https://github.com/viewcomponent/view_component/compare/v3.2.0...v3.3.0)

---
updated-dependencies:
- dependency-name: view_component
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-27 10:03:13 +00:00
Filipe
748cdaaa52 Merge pull request #10963 from jibees/10956-orders-page-uncaught-error-missing-target-element-tooltip-for-tooltip-controller
Admin, Orders list: add tooltip on Edit action icon + capitalize tooltip (instead of uppercasing)
2023-06-27 09:58:34 +01:00
Mohamed ABDELLANI
e678c6149f extract payment_faild from processing_failed 2023-06-27 09:26:26 +01:00
Mohamed ABDELLANI
4cca823a66 redirect user to payment when the card doesn't have enough credit 2023-06-27 09:14:48 +01:00
Neal Chambers
a4220891c5 Update .rubocop_todo.yml 2023-06-26 13:06:57 +09:00
Neal Chambers
5b6f45931c Fix Layout/LineLength 2023-06-26 13:06:56 +09:00
Maikel Linke
c3d49bf31a Speed up, simplify helper with ActiveRecord scopes 2023-06-26 12:56:00 +10:00
Maikel Linke
61c4fb936a Test OrderCycleHelper with real data, not mocks
It's more realistic and doesn't break with the next change.
2023-06-26 12:55:57 +10:00
Maikel Linke
7f94fbc085 Add common whitespace to spec 2023-06-26 12:48:54 +10:00
Maikel
014fb69d4b Merge pull request #10964 from macanudo527/fix_linelength_bundle1
Fix Layout/LineLength - Bundle 1
2023-06-26 12:10:39 +10:00
Maikel
bb5c5ffc7b Merge pull request #11078 from openfoodfoundation/dependabot/bundler/aws-sdk-s3-1.126.0
chore(deps): bump aws-sdk-s3 from 1.124.0 to 1.126.0
2023-06-26 11:11:39 +10:00
Maikel
a7915b8089 Merge pull request #10849 from mkllnk/report-cable
Show "loading" screen for background reports and display when ready
2023-06-26 10:25:48 +10:00
Konrad
49db2f30bc Merge pull request #11014 from mkllnk/specs
Restore line item ordering
2023-06-25 21:45:26 +02:00
Konrad
8a8d78c081 Merge pull request #11041 from cillian/export-ofn-uid-column
Add an OFN UID column to the Users & Enterprises report
2023-06-25 20:46:18 +02:00
Maikel Linke
ff588cec40 Restore line item ordering
The line item sorting by id has been replaced by sorting by completed_at
time: ccb183d60b

While that's a good idea, the query param to order was only defined in
the client Javascript and there was no default ordering. Line items also
get their completed_at date from the order. So it's the same for all
items of the same order and the ordering with that group of line items
was random.

Now we are adding an order in addition. Items are first sorted by date
and then by id if there's any ambiguity.
2023-06-25 19:24:58 +02:00
Cillian O'Ruanaidh
8ab077bed8 Create enterprise inside :it block because it's only needed there so far 2023-06-25 19:01:42 +02:00
Cillian O'Ruanaidh
1984a1feeb Use more readable click_button helper instead of find and click in users_and_enterprises_spec.rb 2023-06-25 19:01:42 +02:00
Cillian O'Ruanaidh
40b0bfb433 Add an OFN UID column to the Users & Enterprises report 2023-06-25 19:01:42 +02:00
dependabot[bot]
5010d3bbf3 chore(deps): bump aws-sdk-s3 from 1.124.0 to 1.126.0
Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.124.0 to 1.126.0.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-25 18:26:42 +02:00
David Cook
6240baec0d Update app/controllers/admin/enterprises_controller.rb
Co-authored-by: Gaetan Craig-Riou <40413322+rioug@users.noreply.github.com>
2023-06-23 16:18:45 +09:00
Maikel
e065910d2d Merge pull request #10939 from Matt-Yorkley/master-variants
Remove master variants
2023-06-23 13:42:58 +10:00
Maikel Linke
33d212d274 Gracefully deal with missing S3 config
I could have split this into several commits:

* DRY direct linking to images.
* Check S3 config before direct linking.
* Just check if service is public instead of relying on name.

Developers may copy a staging or production database or experiment with
S3 storage. But when the S3 config is missing then calling `service`
raises an ArgumentError due to a missing name.

Now we only try to call `service` if the S3 config is present.
2023-06-23 12:41:36 +10:00
David Cook
4bf65e330b Enable master variants with associated order cycles
There's only 5 in UK prod. keeping them is easier than figuring out if it's safe to delete.
2023-06-23 11:50:26 +10:00
David Cook
2025a98f58 Delete stock_items for master variants
All variants have stock_items records, but master variants never use them, so these were always redundant.
2023-06-23 11:49:29 +10:00
David Cook
3bff7a9f13 Fix query
With deep nesting syntax.

I chose the longer alias 'left_outer_joins' because it's more explicit, and matches the use up on line 121.
2023-06-23 09:11:03 +09:00
Neal Chambers
172b1eea94 Update .rubocop_todo.yml 2023-06-23 09:11:02 +09:00
Neal Chambers
1e4034534c Fix Layout/LineLength 2023-06-23 09:08:04 +09:00
Filipe
bca7813320 Merge pull request #10323 from abdellani/enterprise-fee-w-tax-by-order
Enterprise fee w tax by order
2023-06-22 23:25:11 +01:00
Filipe
9293dd379b Merge pull request #11087 from Matt-Yorkley/image-error-notifications
Add image error Bugsnag notifications
2023-06-22 16:30:57 +01:00
Filipe
b4c4381473 Merge pull request #10987 from jibees/10979-white-label-trix-link-unlink-buttons-are-white-text-on-white-background
[White Label] Fix colors of custom content editor to have beautiful toolbar
2023-06-22 16:12:25 +01:00
Jean-Baptiste Bellet
7ce3c3f447 Overide a text-transform: uppercase to capitalize
Inherit comes from `app/webpacker/css/admin/components/buttons.scss`
2023-06-22 14:15:43 +02:00
Jean-Baptiste Bellet
91d24ba8ab Add Edit tooptip for action icon in orders table 2023-06-22 14:15:43 +02:00
Matt-Yorkley
c88799618f Set master variants which are associated to line items to non-master
Line items which reference a master variant is a scenario that in theory shouldn't have been valid or even possible for at least 5-6 years, and these old bits of data in theory should have been cleaned up at the time those changes were made. But a couple of servers have some really old data that's not in a nice state.

Here we can just flip the is_master flag to false for those specific (legacy data) cases before deleting any other master variants, to keep the legacy line item data intact.
2023-06-22 13:10:47 +01:00
jibees
22a3b31172 Merge pull request #11100 from mkllnk/remove-json-patch
Revert "Fix json v1.8.6 common.rb warning"
2023-06-22 11:11:21 +02:00
jibees
8eee90118e Merge pull request #11093 from openfoodfoundation/dependabot/npm_and_yarn/floating-ui/dom-1.4.2
chore(deps): bump @floating-ui/dom from 1.3.0 to 1.4.2
2023-06-22 10:25:13 +02:00
jibees
5ba9c815cf Merge pull request #11082 from openfoodfoundation/dependabot/bundler/rubocop-rails-2.20.2
chore(deps-dev): bump rubocop-rails from 2.19.1 to 2.20.2
2023-06-22 10:18:26 +02:00
jibees
300c4ceed2 Merge pull request #11083 from openfoodfoundation/dependabot/bundler/knapsack_pro-5.1.2
chore(deps-dev): bump knapsack_pro from 5.1.0 to 5.1.2
2023-06-22 10:17:44 +02:00
Mohamed ABDELLANI
b072da142e filter distributors before listing on checkout options 2023-06-22 09:00:39 +01:00
Maikel Linke
08a06d21fa Allow access to DFC API with OFN API token 2023-06-22 16:58:12 +10:00
Maikel Linke
82fc6a2a9d Prepare spec to authenticate with other means
I want to add OFN API key support.
2023-06-22 16:27:04 +10:00
Maikel Linke
e7fe04f526 Revert "Fix json v1.8.6 common.rb warning"
This reverts commit 21b80db0ee.

This fix was needed for an old version of the JSON module with a newer
version of Ruby. But we updated the json gem since and don't need this
any more.
2023-06-22 12:47:28 +10:00
Matt-Yorkley
f9185ea56e Remove line items related to master variants
These shouldn't technically exist, but apparently they can be present if the dataset is old enough. They can trigger a foreign key violation if they are present when a master variant is deleted, so they need to be dropped if present.
2023-06-21 18:08:21 +01:00
Matt-Yorkley
6f5d3ceacc Remove inventory units related to master variants
These shouldn't technically exist, but apparently they can be present if the dataset is old enough. They can trigger a foreign key violation if they are present when a master variant is deleted, so they need to be dropped if present.
2023-06-21 17:20:28 +01:00
Jean-Baptiste Bellet
d2534d6645 Be more specific via !important than the default button rule
This one should override the default one
2023-06-21 15:01:14 +02:00
Jean-Baptiste Bellet
7d9018c590 Instead of overriding css rules, prefer to not select rules for trix buttons 2023-06-21 15:01:14 +02:00
dependabot[bot]
c532e822e5 chore(deps): bump @floating-ui/dom from 1.3.0 to 1.4.2
Bumps [@floating-ui/dom](https://github.com/floating-ui/floating-ui/tree/HEAD/packages/dom) from 1.3.0 to 1.4.2.
- [Release notes](https://github.com/floating-ui/floating-ui/releases)
- [Commits](https://github.com/floating-ui/floating-ui/commits/@floating-ui/dom@1.4.2/packages/dom)

---
updated-dependencies:
- dependency-name: "@floating-ui/dom"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-21 09:57:46 +00:00
Jean-Baptiste Bellet
5d1c32e8cd Remove linksDropdown which is now unused 2023-06-21 10:29:48 +02:00
Jean-Baptiste Bellet
4ec41572b1 Add spec on Canceling an order
Strange that it doesn't exist, but anyway, let's create it!
2023-06-21 10:29:48 +02:00
Jean-Baptiste Bellet
ce28c14544 Replace AngularJS directive to a StimulusJS one
Delete _order_links.html.haml_spec.rb
2023-06-21 10:29:48 +02:00
Jean-Baptiste Bellet
7421691506 Creates a dropdown controller with its specs 2023-06-21 10:29:47 +02:00
David Cook
5ec872c6fd Merge pull request #11008 from mkllnk/dfc-connector-import
Prototype: Import products via DFC Connector
2023-06-21 12:23:58 +10:00
Maikel Linke
14b2e0f962 Remove datadog gem, too expensive 2023-06-21 11:44:21 +10:00
Matt-Yorkley
98a56bfcf8 Update workflow permissions check to latest version 2023-06-20 14:41:17 +01:00
Matt-Yorkley
776eac9f52 Add image error Bugsnag notifications 2023-06-20 14:14:19 +01:00
Matt-Yorkley
24aa55e053 Remove array syntax on new product form for product image 2023-06-20 13:14:52 +01:00
dependabot[bot]
e8e3aa5f5d chore(deps-dev): bump knapsack_pro from 5.1.0 to 5.1.2
Bumps [knapsack_pro](https://github.com/KnapsackPro/knapsack_pro-ruby) from 5.1.0 to 5.1.2.
- [Changelog](https://github.com/KnapsackPro/knapsack_pro-ruby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v5.1.0...v5.1.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-20 09:31:26 +00:00
dependabot[bot]
584a25052f chore(deps-dev): bump rubocop-rails from 2.19.1 to 2.20.2
Bumps [rubocop-rails](https://github.com/rubocop/rubocop-rails) from 2.19.1 to 2.20.2.
- [Release notes](https://github.com/rubocop/rubocop-rails/releases)
- [Changelog](https://github.com/rubocop/rubocop-rails/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop-rails/compare/v2.19.1...v2.20.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-20 09:14:06 +00:00
Gaetan Craig-Riou
ea73781668 Fix bulk order cancellation
Add unticking of "send cancellation email to customer" to match
the current test expectation
2023-06-20 10:03:55 +10:00
Maikel Linke
a9f8c7c4ab Update DFC API docs, describe all endpoints 2023-06-19 16:20:35 +10:00
Maikel Linke
ec8c710e3a Import simple DFC SuppliedProduct
OFN products and variants need more data like a price but the DFC
stores that in a different object. We may get a larger graph containing
that information but we don't have any test data yet.
2023-06-19 16:19:48 +10:00
Maikel Linke
df9e1ac2b4 Encapsulate SuppliedProductBuilder
And improve EnterpriseBuilder. It was builder products twice.
2023-06-19 16:19:48 +10:00
Maikel Linke
1adfb5463a Import DFC measures 2023-06-19 16:19:40 +10:00
Maikel Linke
949019a277 Map has* predicates to Connector attributes 2023-06-19 16:19:40 +10:00
Maikel Linke
bfd084d9b6 Import graphs including anonymous objects 2023-06-19 16:18:58 +10:00
Maikel Linke
3c6f90dbb3 Import from IO objects for convenience, efficiency
The Connector exports to a String but Rails' `request.body` is an IO
object. Since the used JSON-LD parser needs an IO object anyway and it
can lower the memory usage we take IO objects as well and handle
in-memory Strings only when given.
2023-06-19 16:18:58 +10:00
Maikel Linke
f5f8c349e1 Resolve DFC Connector objects when importing graph 2023-06-19 16:18:51 +10:00
Maikel Linke
12d56d725b Import properties which contains lists
Not just single values.
2023-06-19 16:18:51 +10:00
Maikel Linke
2abad60511 Import DFC graphs with multiple objects 2023-06-19 16:18:42 +10:00
Maikel Linke
15dd38d6c6 Import simple data from DFC 2023-06-19 16:16:18 +10:00
Maikel Linke
cceca5f936 Use Redis for caching in test environment
All other environments use it.
2023-06-19 15:35:17 +10:00
Maikel Linke
f6db69104f Update Gemfile.lock with new Ruby version 2023-06-19 15:03:44 +10:00
Maikel
7e20415490 Merge pull request #10888 from mkllnk/ruby3.1
Bump Ruby from 3.0.3 to 3.1.4
2023-06-19 10:08:20 +10:00
Maikel
101e72726c Merge pull request #11032 from dacook/show-current-version2
Show current version2
2023-06-19 10:07:49 +10:00
Konrad
dab5436444 Merge pull request #10532 from abdellani/invoices
Invoices
2023-06-18 21:44:29 +02:00
Mohamed ABDELLANI
d059680f4b remove white label from feature toggle 2023-06-18 21:03:13 +02:00
Mohamed ABDELLANI
27c1fd0d30 test invoice model 2023-06-18 21:03:13 +02:00
Mohamed ABDELLANI
639567e903 replace attr with attr_reader 2023-06-18 21:03:13 +02:00
Mohamed ABDELLANI
fff0b1e577 Update lib/open_food_network/feature_toggle.rb
Co-authored-by: Maikel <maikel@email.org.au>
2023-06-18 21:03:13 +02:00
Mohamed ABDELLANI
7a0686786d Update db/migrate/20230308075421_create_invoices.rb
Co-authored-by: Maikel <maikel@email.org.au>
2023-06-18 21:03:13 +02:00
Mohamed ABDELLANI
73cdcca022 fix linter issues 2023-06-18 21:03:13 +02:00
Matt-Yorkley
4eb05a1d73 Reduce public interface of OrderInvoiceComparator 2023-06-18 21:03:13 +02:00
Matt-Yorkley
3946e7a6f5 Memoize presenters in OrderInvoiceComparator
This is now twice as fast and triggers half the number of database queries if both comparison methods get called
2023-06-18 21:03:13 +02:00
Matt-Yorkley
c6ec13443e Drop next_invoice_number method from Spree::Order 2023-06-18 21:03:13 +02:00
Matt-Yorkley
d3a31bd0bd Rename @invoice_presenter instance variable to @order in invoice templates 2023-06-18 21:03:13 +02:00
Matt-Yorkley
352ad20681 Fix display_checkout_taxes_hash in invoice_table4 template 2023-06-18 21:03:13 +02:00
Matt-Yorkley
68ab539ed3 Include completed_at attribute 2023-06-18 21:03:13 +02:00
Matt-Yorkley
113e1344f2 Include tax adjustments in serializer and presenter 2023-06-18 21:03:13 +02:00
Matt-Yorkley
5bbc63f716 Fix options_text displaying when there is no options_text 2023-06-18 21:03:13 +02:00
Matt-Yorkley
72e537b598 Update *_amount_with_adjustments methods on LineItem presenter
These methods are slightly different and they're both needed in the template for invoice4
2023-06-18 21:03:13 +02:00
Matt-Yorkley
208840b99d Use @invoice_presenter.checkout_adjustments 2023-06-18 21:03:13 +02:00
Matt-Yorkley
a44f24ad43 Remove prefixes from invoice data representation so it conforms to the same interface as order 2023-06-18 21:03:13 +02:00
Matt-Yorkley
8dba1618b1 Don't call information from @order in new invoice templates
Previously this template was calling various bits of data from the @order object and not the @invoice_presenter object
2023-06-18 21:03:13 +02:00
Matt-Yorkley
c3d6b2280f Update reference to removed method 2023-06-18 21:03:13 +02:00
Mohamed ABDELLANI
0ed7599267 extract methods related to invoices from the order model to the OrderInvoiceComparator 2023-06-18 21:03:13 +02:00
Mohamed ABDELLANI
61d58df56f fix linter issues 2023-06-18 21:03:13 +02:00
Mohamed ABDELLANI
d86173c509 add feature toggle
seperate the invoice templates that rely on presenters from the old ones.
2023-06-18 21:03:13 +02:00
Mohamed ABDELLANI
fa14dc370b implement the invoice data generator 2023-06-18 21:03:13 +02:00
Mohamed ABDELLANI
d9efd10ac0 update attributes relevant for the comparaison 2023-06-18 21:03:13 +02:00
Mohamed ABDELLANI
0fbf88190e Generate invoice model
There are three main components:
1. The invoice model
2. order serializers: serialize the order for the invoice
3. data presenters: the object that will be use to access the order's serialize data
2023-06-18 21:03:13 +02:00
Matt-Yorkley
ae24b2d688 Update ScopeVariantsForSearch logic to match both product and variant SKUs 2023-06-16 21:26:28 +01:00
Matt-Yorkley
0f253bb2a0 Blank out product SKU when cloning a product
This was effectively being done before for the product's sku (stored on the master variant) via the #duplicate_variant method, but now it needs to be done explicitly on the product in #duplicate_product
2023-06-16 21:26:28 +01:00
Matt-Yorkley
15000c7ed1 Remove unnecessary iterator 2023-06-16 21:26:28 +01:00
Matt-Yorkley
733dd3c428 Disable variant is_master column 2023-06-16 21:23:44 +01:00
Matt-Yorkley
be72bbebb9 Remove master images data migration tests 2023-06-16 21:23:44 +01:00
Matt-Yorkley
fbd09869bb Remove is_master from variant serializer 2023-06-16 21:23:44 +01:00
Matt-Yorkley
ced60d4382 Remove superfluous method from products controller 2023-06-16 21:23:44 +01:00
Matt-Yorkley
b59bdc75e9 Delete master variants 2023-06-16 21:23:44 +01:00
Matt-Yorkley
1daab8994d Remove is_master and not_master scopes 2023-06-16 21:23:44 +01:00
Matt-Yorkley
0703bb4583 Remove unused is_master references in tests 2023-06-16 21:23:44 +01:00
Matt-Yorkley
85059bfb26 Remove master variant validation conditionals 2023-06-16 21:23:44 +01:00
Matt-Yorkley
8247dce2dc Improve validation feedback on new variant page and add test coverage 2023-06-16 21:23:44 +01:00
Matt-Yorkley
618900767f Fix flaky spec: use milliseconds in cache service and remove sleep 2023-06-16 21:23:44 +01:00
Matt-Yorkley
1e36043a2e Set unit_value to true when cloning a product
This value doesn't get persisted, but it's presence is validated. The product's duplicated variants store the actual :unit_value attribute
2023-06-16 21:23:44 +01:00
Matt-Yorkley
1922598d2d Reorganise associations, validations, scopes and callbacks for clarity 2023-06-16 21:23:44 +01:00
Matt-Yorkley
3ef7d2c9ff Remove master variant from product 2023-06-16 21:23:44 +01:00
Matt-Yorkley
21cba0aa13 Migrate first master variant image to product image 2023-06-16 21:23:44 +01:00
Matt-Yorkley
7dc1091bc2 Migrate product image from master variant to product 2023-06-16 21:23:44 +01:00
Matt-Yorkley
d8649fc9fb Migrate master variant :sku to product 2023-06-16 21:21:40 +01:00
Matt-Yorkley
6b9b5ea347 Stop storing unit_value and unit_description on master variant 2023-06-16 21:21:40 +01:00
Matt-Yorkley
8c0b8dad85 Stop using master variant for storing :display_as value 2023-06-16 21:21:40 +01:00
Matt-Yorkley
1b06c20197 Stop using master variant as a potential store for prices 2023-06-16 21:21:40 +01:00
Matt-Yorkley
80a0138b48 Update old specs that rely on master variant instead of real variants 2023-06-16 21:21:40 +01:00
Matt-Yorkley
d4188da7c1 Simplify product images delegation mess 2023-06-16 21:21:40 +01:00
Matt-Yorkley
42a5a48816 Remove dead code 2023-06-16 21:21:40 +01:00
Matt-Yorkley
dd224b953d Update stage.yml 2023-06-16 14:24:23 +01:00
Matt-Yorkley
cfe5d9a740 Update stage.yml 2023-06-16 14:00:30 +01:00
Matt-Yorkley
09bfe14ae9 Update stage.yml 2023-06-16 13:39:12 +01:00
Mohamed ABDELLANI
68503e4e8b remove useless variable 2023-06-16 06:54:11 +01:00
Mohamed ABDELLANI
65bc8e23c1 move update instructions to let blocks 2023-06-16 06:50:45 +01:00
Mohamed ABDELLANI
2b79258fdc renamed: spec/system/admin/reports/enterprise_summary_fees/enterprise_summary_fee_with_tax_report_by_order.rb -> spec/system/admin/reports/enterprise_summary_fees/enterprise_summary_fee_with_tax_report_by_order_spec.rb 2023-06-16 06:39:38 +01:00
Mohamed ABDELLANI
c21a35a9fc fix typo on lib/reporting/reports/enterprise_fee_summary/enterprise_fees_with_tax_report_by_order.rb 2023-06-16 06:38:15 +01:00
Mohamed ABDELLANI
c8c3e65498 Update lib/reporting/reports/list.rb
Co-authored-by: Maikel <maikel@email.org.au>
2023-06-16 06:35:01 +01:00
Mohamed ABDELLANI
2cfa435b54 Update spec/system/admin/reports/enterprise_summary_fees/enterprise_summary_fee_with_tax_report_by_order.rb
Co-authored-by: Maikel <maikel@email.org.au>
2023-06-16 06:35:01 +01:00
Mohamed ABDELLANI
3e61830b40 optimize total_excl_tax & enterprise_fee_adjustemnt_ids 2023-06-16 06:35:01 +01:00
Mohamed ABDELLANI
10fc816bba update rubocop_todo list 2023-06-16 06:35:01 +01:00
Mohamed ABDELLANI
542811b9ad implement filtering by entreprise fee owner 2023-06-16 06:35:01 +01:00
Mohamed ABDELLANI
9d53d775a6 add filtering by fee name 2023-06-16 06:35:01 +01:00
Mohamed ABDELLANI
f66d9b9626 remove producers filter 2023-06-16 06:35:01 +01:00
Mohamed ABDELLANI
83b951662a add filters 2023-06-16 06:35:01 +01:00
Mohamed ABDELLANI
e9671e4e1f test enterprise fees with tax report by order 2023-06-16 06:35:01 +01:00
Mohamed ABDELLANI
e9367b1f86 add enterprise fees with tax report by order 2023-06-16 06:35:01 +01:00
Mohamed ABDELLANI
535f651c7e implement enterprise fee report filters 2023-06-16 06:35:01 +01:00
Mohamed ABDELLANI
a120329aa6 rename EnterpriseFeeSummary::Base to EnterpriseFeeSummary::FeeSummary 2023-06-16 06:35:01 +01:00
Maikel
4e1f735630 Include feature toggle heading in release notes 2023-06-16 14:13:41 +10:00
David Cook
56e4b3b843 Load git version once at initialisation
Co-authored-by: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com>
2023-06-16 09:36:16 +10:00
David Cook
d195882645 Use builtin Rails method 2023-06-15 15:26:22 +10:00
Maikel Linke
a46917a7b7 Remove NULL possibility from customer flag
It should only be true or false. This was flagged by Rubocop. I also
added another Rubocop suggestion and combined two migrations because
they are related.
2023-06-15 12:02:45 +10:00
Maikel Linke
75cce8bc19 Simplify customer code
The API endpoint merges the created_manually flag in the params already.
No need to write it separately.
2023-06-15 12:02:45 +10:00
Maikel Linke
a655d3d787 Remove unnecessary writes on customer creation
The form only submits enterprise id and email address. We don't need to
assign any other attributes.
2023-06-15 12:02:45 +10:00
Maikel Linke
9bd6615dad Change spec to "unhide" customers on create 2023-06-15 12:02:45 +10:00
Maikel Linke
ebebcf7a13 Remove useless code 2023-06-15 12:02:45 +10:00
Maikel Linke
22a6861f6f Place class methods above instance methods 2023-06-15 12:02:45 +10:00
Mohamed ABDELLANI
298ae8ffc3 set create_manualll flag if the customer already exists 2023-06-15 12:02:45 +10:00
Maikel Linke
107b17addb Add index of much used created_manually column 2023-06-15 12:02:45 +10:00
Maikel Linke
9910d10eb8 Simplify and speed-up customers migration
This reduces the migration run time from 9.6 seconds to 0.16 seconds on
a production database.

* Simplify model naming.
* Remove unnecessary model code.
* Use Rails `missing` scope for efficient simplicity.
* Add `down` method for rollback instead of running `change` again.
2023-06-15 12:02:45 +10:00
Mohamed ABDELLANI
608ff054b0 set the created_manually flag to true for all customers that don't have any orders 2023-06-15 12:02:45 +10:00
Mohamed ABDELLANI
ebc3073604 use Customer#visible on the customers listing endpoints
Update app/models/customer.rb

Co-authored-by: Maikel <maikel@email.org.au>

Update spec/models/customer_spec.rb

Co-authored-by: Maikel <maikel@email.org.au>

Update spec/models/customer_spec.rb

Co-authored-by: Maikel <maikel@email.org.au>

authorize created_manually field to be set on APIv1
2023-06-15 12:02:45 +10:00
Matt-Yorkley
202b0041d1 Remove voucher processing from checkout edit action 2023-06-14 10:19:30 +01:00
Matt-Yorkley
1a744de37a Improve voucher #calculate tests 2023-06-14 10:19:30 +01:00
Matt-Yorkley
93df70c0a7 Use order total excluding discounts in voucher calculations 2023-06-14 10:19:30 +01:00
Matt-Yorkley
52806a35ee Fix Rubocop complaint 2023-06-14 10:19:30 +01:00
Matt-Yorkley
11382a518e Fix test setup in BOM spec 2023-06-14 10:19:30 +01:00
Matt-Yorkley
ef09492883 Update adjustment spec to use orders past delivery state 2023-06-14 10:19:30 +01:00
Matt-Yorkley
6fa381197a Don't tax fees before payment state 2023-06-14 10:19:30 +01:00
Matt-Yorkley
837e581c29 Reload order after cancelling it in tests that check shipment states 2023-06-14 10:19:30 +01:00
Matt-Yorkley
06c9697d0d Don't try to cancel shipments that might already be cancelled 2023-06-14 10:19:30 +01:00
Matt-Yorkley
c5dfecbb69 Reapply taxes at model level if order address changes
This should be done at the model level
2023-06-14 10:19:30 +01:00
Matt-Yorkley
a0f23fc510 Extract before_payment_state? method 2023-06-14 10:19:30 +01:00
Matt-Yorkley
13a22c56f4 Move taxing of admin adjustments out of customer details controller 2023-06-14 10:19:30 +01:00
Matt-Yorkley
65b6a75c9b Reorder callback definitions 2023-06-14 10:19:30 +01:00
Matt-Yorkley
a0d0f8fd2f Tidy up checkout tax spec 2023-06-14 10:19:30 +01:00
Maikel Linke
c2605b2606 Display loading spinner before quick reports
We had a race condition that could first display the report and then
replace it again with the "loading" spinner. That doesn't seem to happen
now that we changed the order of cable events.
2023-06-14 15:40:52 +10:00
Matt-Yorkley
074eb4b592 Move tax charge logic out of checkout controller and update payment transition 2023-06-13 17:53:46 +01:00
Matt-Yorkley
bf912ae4d3 Remove angular loading element in darkwarm layout 2023-06-13 17:35:13 +01:00
Maikel Linke
ec865627d2 Wait for page setup to avoid flaky spec
I'm hiding a real bug here. There's a race condition when the cable event of
the finished report is sent before the loading spinner rendered. The
spinner then overwrites the report again. I added a spec for that but
don't have a solution yet.

I also noticed that the loading spinner is not displayed in testing but
we can assert on the CSS class of the container.
2023-06-09 16:22:01 +10:00
Maikel Linke
d312a5912a Style Layout/MultilineMethodCallIndentation 2023-06-09 14:45:06 +10:00
Maikel Linke
828b2f6f44 Replace too long list of arguments with keywords
Rubocop was complaining about too many arguments. But
`ApplicationJob#perform` needs all arguments handled in one call. While
we could allow the `perform` method generally to have more arguments,
there could be other methods called `perform` which should still be
scrutinised. Instead, it seems acceptable to me to have more arguments
as long as they are clearly named as keyword arguments. Rails uses this
a lot to document all options including their default values, for
example in Active Storage. It's better then bundling several arguments
in an undocumented hash just to reduce the number of given arguments.

And once we upgraded to Ruby 3.1, we can clean the method calls up as
well. `call(user: user)` becomes `call(user:)` without repetition.
2023-06-09 14:44:54 +10:00
Maikel Linke
e56c06571c Remove outdated report timeout handling
Since we don't wait for the report any more, a timeout is very unlikely
and we don't need special handling for it.
2023-06-09 14:44:54 +10:00
Matt-Yorkley
7caf4b03d4 Improve flakyness on report specs 2023-06-09 14:44:53 +10:00
Matt-Yorkley
b230b37284 Update report email spec 2023-06-09 14:44:53 +10:00
Matt-Yorkley
524d1f0264 Switch to tighter Channel scoping...
This is not a normal pattern for setting up ActionCable channels, so it might need some notes. It ensures the broadcasts from the ReportJob are unique not just to the user session but also to the specific tab in the user's browser. Otherwise if the user has two different report pages open in separate tabs with the same session, the broadcast would overwrite the #report-table element in both of them.
2023-06-09 14:44:53 +10:00
Matt-Yorkley
a3ef604797 Run reports in background 2023-06-09 14:44:53 +10:00
Matt-Yorkley
ced959ad6a Load reports show page without all the legacy javascript 2023-06-09 14:44:53 +10:00
Matt-Yorkley
242c74ceaf DRY admin javascript imports 2023-06-09 14:44:53 +10:00
Maikel Linke
b4deb21872 Bump Ruby from 3.0.3 to 3.1.4
Major 3.1 highlights:

* https://www.ruby-lang.org/en/news/2021/12/25/ruby-3-1-0-released/
2023-05-24 16:52:34 +10:00
446 changed files with 7475 additions and 2723 deletions

View File

@@ -40,7 +40,7 @@ The full process is described at https://github.com/openfoodfoundation/openfoodn
[Ready To Go]: #zenhub
[Transifex pull request]: https://github.com/openfoodfoundation/openfoodnetwork/pulls?utf8=%E2%9C%93&q=is%3Apr+is%3Aopen+head%3Atransifex
[Draft new release]: https://github.com/openfoodfoundation/openfoodnetwork/releases/new?tag=v&title=v+Code+Name&body=Congrats%0A%0ADescription%0A%0A%23%23+User+facing+changes+:eyes:%0A%0A%0A%0A%23%23+Technical+changes+:wrench:%0A%0A
[Draft new release]: https://github.com/openfoodfoundation/openfoodnetwork/releases/new?tag=v&title=v+Code+Name&body=Congrats%0A%0ADescription%0A%0A%23%23+User+facing+changes+:eyes:%0A%0A%0A%23%23%23+Experimental+features+for+testing+:sunglasses:%0A%0A%0A%23%23+Technical+changes+:wrench:%0A%0A
[releases]: https://github.com/openfoodfoundation/openfoodnetwork/releases
[#instance-managers]: https://app.slack.com/client/T02G54U79/CG7NJ966B
[#testing]: https://openfoodnetwork.slack.com/app_redirect?channel=C02TZ6X00

View File

@@ -1,7 +1,7 @@
name: "Deploy to Staging"
on:
pull_request:
pull_request_target:
types: [labeled]
workflow_dispatch:
inputs:
@@ -14,23 +14,27 @@ on:
- staging.openfoodnetwork.org.au
- staging.coopcircuits.fr
permissions:
contents: read
jobs:
deploy_pr:
if: contains(fromJSON('["pr-staged-uk", "pr-staged-au", "pr-staged-fr"]'), github.event.label.name)
runs-on: ubuntu-latest
steps:
- name: "Check user has write access"
uses: "lannonbr/repo-permission-check-action@2.0.2"
with:
permission: "write"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Configure deployment key
if: success()
run: |
install -m 600 -D /dev/null ~/.ssh/id_rsa
echo "${{ secrets.DEPLOYMENT_KEY }}" > ~/.ssh/id_rsa
echo "${{ secrets.DEPLOYMENT_HOSTS }}" > ~/.ssh/known_hosts
- name: Deploy to Staging
env:
LABEL: ${{ github.event.label.name }}
if: success()
run: |
ssh ofn-deploy@${{ github.event.label.description }} -o LogLevel=ERROR "pull-request-${{ github.event.pull_request.number }} ."
@@ -38,12 +42,21 @@ jobs:
if: ${{ inputs.server }}
runs-on: ubuntu-latest
steps:
- name: "Check user has write access"
uses: "lannonbr/repo-permission-check-action@2.0.2"
with:
permission: "write"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Configure deployment key
if: success()
run: |
install -m 600 -D /dev/null ~/.ssh/id_rsa
echo "${{ secrets.DEPLOYMENT_KEY }}" > ~/.ssh/id_rsa
echo "${{ secrets.DEPLOYMENT_HOSTS }}" > ~/.ssh/known_hosts
- name: Deploy to Staging
if: success()
run: |
ssh ofn-deploy@${{ inputs.server }} -o LogLevel=ERROR "$GITHUB_REF_NAME $GITHUB_SHA"

View File

@@ -44,6 +44,9 @@ Metrics/BlockLength:
"xdescribe",
]
Metrics/ParameterLists:
CountKeywordArgs: false
Rails/ApplicationRecord:
Exclude:
# Migrations should not contain application code:

View File

@@ -1,6 +1,6 @@
# This configuration was generated by
# `rubocop --auto-gen-config --auto-gen-only-exclude --exclude-limit 1400 --no-auto-gen-timestamp`
# using RuboCop version 1.52.0.
# using RuboCop version 1.52.1.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
@@ -33,7 +33,6 @@ Layout/ArgumentAlignment:
- 'spec/system/admin/order_cycles/list_spec.rb'
- 'spec/system/admin/order_cycles/simple_spec.rb'
- 'spec/system/consumer/shopping/cart_spec.rb'
- 'spec/system/consumer/shopping/checkout_auth_spec.rb'
- 'spec/system/consumer/shopping/products_spec.rb'
# Offense count: 4
@@ -74,13 +73,12 @@ Layout/EmptyLines:
Exclude:
- 'app/models/spree/payment.rb'
# Offense count: 2
# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle.
# SupportedStyles: empty_lines, no_empty_lines
Layout/EmptyLinesAroundBlockBody:
Exclude:
- 'spec/requests/checkout/concurrency_spec.rb'
- 'spec/system/admin/order_cycles/list_spec.rb'
# Offense count: 2
@@ -140,16 +138,12 @@ Layout/LeadingCommentSpace:
Exclude:
- 'spec/system/admin/enterprises_spec.rb'
# Offense count: 114
# Offense count: 105
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle.
# SupportedStyles: space, no_space
Layout/LineContinuationSpacing:
Exclude:
- 'app/helpers/checkout_helper.rb'
- 'engines/order_management/spec/services/order_management/order/updater_spec.rb'
- 'engines/order_management/spec/services/order_management/subscriptions/stripe_payment_setup_spec.rb'
- 'engines/web/app/helpers/web/cookies_policy_helper.rb'
- 'spec/system/admin/bulk_order_management_spec.rb'
- 'spec/system/admin/configuration/content_spec.rb'
- 'spec/system/admin/customers_spec.rb'
@@ -171,22 +165,18 @@ Layout/LineContinuationSpacing:
- 'spec/system/consumer/caching/shops_caching_spec.rb'
- 'spec/system/consumer/cookies_spec.rb'
- 'spec/system/consumer/shopping/cart_spec.rb'
- 'spec/system/consumer/shopping/checkout_auth_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/system/consumer/split_checkout_spec.rb'
# Offense count: 18
# Offense count: 13
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: aligned, indented
Layout/LineEndStringConcatenationIndentation:
Exclude:
- 'app/mailers/spree/user_mailer.rb'
- 'engines/order_management/app/services/order_management/subscriptions/proxy_order_syncer.rb'
- 'engines/order_management/spec/services/order_management/subscriptions/stripe_payment_setup_spec.rb'
- 'spec/system/admin/configuration/content_spec.rb'
- 'spec/system/admin/customers_spec.rb'
- 'spec/system/admin/overview_spec.rb'
@@ -197,128 +187,27 @@ Layout/LineEndStringConcatenationIndentation:
- 'spec/system/consumer/cookies_spec.rb'
- 'spec/system/consumer/shopping/cart_spec.rb'
# Offense count: 606
# Offense count: 213
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: Max, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns.
# URISchemes: http, https
Layout/LineLength:
Exclude:
- 'app/components/confirm_modal_component.rb'
- 'app/controllers/admin/bulk_line_items_controller.rb'
- 'app/controllers/admin/enterprise_relationships_controller.rb'
- 'app/controllers/admin/enterprises_controller.rb'
- 'app/controllers/admin/product_import_controller.rb'
- 'app/controllers/admin/subscriptions_controller.rb'
- 'app/controllers/payment_gateways/paypal_controller.rb'
- 'app/helpers/angular_form_helper.rb'
- 'app/helpers/enterprises_helper.rb'
- 'app/jobs/subscription_confirm_job.rb'
- 'app/mailers/subscription_mailer.rb'
- 'app/models/concerns/order_shipment.rb'
- 'app/models/concerns/product_stock.rb'
- 'app/models/concerns/variant_stock.rb'
- 'app/models/customer.rb'
- 'app/models/enterprise.rb'
- 'app/models/product_import/spreadsheet_entry.rb'
- 'app/models/product_import/unit_converter.rb'
- 'app/models/proxy_order.rb'
- 'app/models/schedule.rb'
- 'app/models/spree/app_configuration.rb'
- 'app/models/spree/gateway/stripe_sca.rb'
- 'app/models/spree/line_item.rb'
- 'app/models/spree/order.rb'
- 'app/models/spree/preferences/store.rb'
- 'app/models/subscription.rb'
- 'app/models/variant_override.rb'
- 'app/services/cart_service.rb'
- 'app/services/embedded_page_service.rb'
- 'app/services/order_cycle_form.rb'
- 'app/services/order_syncer.rb'
- 'app/services/variant_units/variant_and_line_item_naming.rb'
- 'engines/order_management/app/services/order_management/subscriptions/validator.rb'
- 'engines/order_management/spec/services/order_management/order/updater_spec.rb'
- 'engines/web/app/helpers/web/cookies_policy_helper.rb'
- 'lib/discourse/single_sign_on.rb'
- 'lib/open_food_network/enterprise_fee_applicator.rb'
- 'lib/open_food_network/enterprise_fee_calculator.rb'
- 'lib/open_food_network/enterprise_issue_validator.rb'
- 'lib/open_food_network/order_cycle_form_applicator.rb'
- 'lib/open_food_network/order_cycle_permissions.rb'
- 'lib/open_food_network/scope_variants_for_search.rb'
- 'lib/reporting/line_items.rb'
- 'lib/reporting/reports/enterprise_fee_summary/report_data/enterprise_fee_type_total.rb'
- 'lib/spree/localized_number.rb'
- 'lib/tasks/data.rake'
- 'lib/tasks/enterprises.rake'
- 'lib/tasks/import_product_images.rake'
- 'spec/controllers/admin/bulk_line_items_controller_spec.rb'
- 'spec/controllers/admin/column_preferences_controller_spec.rb'
- 'spec/controllers/admin/enterprises_controller_spec.rb'
- 'spec/controllers/admin/order_cycles_controller_spec.rb'
- 'spec/controllers/admin/schedules_controller_spec.rb'
- 'spec/controllers/admin/stripe_accounts_controller_spec.rb'
- 'spec/controllers/admin/stripe_connect_settings_controller_spec.rb'
- 'spec/controllers/admin/subscription_line_items_controller_spec.rb'
- 'spec/controllers/admin/subscriptions_controller_spec.rb'
- 'spec/controllers/admin/variant_overrides_controller_spec.rb'
- 'spec/controllers/api/v0/base_controller_spec.rb'
- 'spec/controllers/api/v0/exchange_products_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/cart_controller_spec.rb'
- 'spec/controllers/checkout_controller_spec.rb'
- 'spec/controllers/enterprises_controller_spec.rb'
- 'spec/controllers/line_items_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'
- 'spec/controllers/spree/admin/orders_controller_spec.rb'
- 'spec/controllers/spree/admin/payment_methods_controller_spec.rb'
- 'spec/controllers/spree/admin/variants_controller_spec.rb'
- 'spec/controllers/spree/credit_cards_controller_spec.rb'
- 'spec/controllers/spree/orders_controller_spec.rb'
- 'spec/controllers/stripe/webhooks_controller_spec.rb'
- 'spec/factories/stock_location_factory.rb'
- 'spec/helpers/injection_helper_spec.rb'
- 'spec/helpers/order_cycles_helper_spec.rb'
- 'spec/helpers/spree/admin/base_helper_spec.rb'
- 'spec/jobs/subscription_confirm_job_spec.rb'
- 'spec/jobs/subscription_placement_job_spec.rb'
- 'spec/lib/open_food_network/enterprise_fee_calculator_spec.rb'
- 'spec/lib/open_food_network/order_cycle_form_applicator_spec.rb'
- 'spec/lib/open_food_network/order_cycle_permissions_spec.rb'
- 'spec/lib/open_food_network/permissions_spec.rb'
- 'spec/lib/open_food_network/scope_variant_to_hub_spec.rb'
- 'spec/lib/open_food_network/tag_rule_applicator_spec.rb'
- 'spec/lib/reports/customers_report_spec.rb'
- 'spec/lib/reports/order_cycle_management_report_spec.rb'
- 'spec/lib/reports/products_and_inventory_report_spec.rb'
- 'spec/lib/reports/users_and_enterprises_report_spec.rb'
- 'spec/mailers/order_mailer_spec.rb'
- 'spec/mailers/producer_mailer_spec.rb'
- 'spec/mailers/subscription_mailer_spec.rb'
- 'spec/models/concerns/calculated_adjustments_spec.rb'
- 'spec/models/concerns/order_shipment_spec.rb'
- 'spec/models/concerns/product_stock_spec.rb'
- 'spec/models/enterprise_relationship_spec.rb'
- 'spec/models/enterprise_spec.rb'
- 'spec/models/exchange_spec.rb'
- 'spec/models/order_cycle_spec.rb'
- 'spec/models/product_importer_spec.rb'
- 'spec/models/spree/ability_spec.rb'
- 'spec/models/spree/address_spec.rb'
- 'spec/models/spree/adjustment_spec.rb'
- 'spec/models/spree/classification_spec.rb'
- 'spec/models/spree/inventory_unit_spec.rb'
- 'spec/models/spree/line_item_spec.rb'
- 'spec/models/spree/order/checkout_spec.rb'
- 'spec/models/spree/order_inventory_spec.rb'
- 'spec/models/spree/order_spec.rb'
- 'spec/models/spree/payment_method_spec.rb'
- 'spec/models/spree/payment_spec.rb'
- 'spec/models/spree/product_spec.rb'
- 'spec/models/spree/shipping_method_spec.rb'
- 'spec/models/spree/tax_rate_spec.rb'
- 'spec/models/spree/user_spec.rb'
- 'spec/models/spree/variant_spec.rb'
@@ -333,7 +222,6 @@ Layout/LineLength:
- 'spec/serializers/api/admin/order_cycle_serializer_spec.rb'
- 'spec/services/address_geocoder_spec.rb'
- 'spec/services/cart_service_spec.rb'
- 'spec/services/checkout/form_data_adapter_spec.rb'
- 'spec/services/checkout/post_checkout_actions_spec.rb'
- 'spec/services/content_sanitizer_spec.rb'
- 'spec/services/embedded_page_service_spec.rb'
@@ -382,14 +270,6 @@ Layout/MultilineMethodCallIndentation:
- 'spec/system/admin/payment_method_spec.rb'
- 'spec/system/admin/variant_overrides_spec.rb'
# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: aligned, indented
Layout/MultilineOperationIndentation:
Exclude:
- 'app/models/spree/order.rb'
# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle.
@@ -473,7 +353,7 @@ Lint/DuplicateRequire:
Exclude:
- 'spec/lib/open_food_network/scope_variants_to_search_spec.rb'
# Offense count: 20
# Offense count: 19
# Configuration parameters: AllowComments, AllowEmptyLambdas.
Lint/EmptyBlock:
Exclude:
@@ -488,7 +368,6 @@ Lint/EmptyBlock:
- 'spec/jobs/order_cycle_opened_job_spec.rb'
- 'spec/jobs/subscription_placement_job_spec.rb'
- 'spec/models/product_import/entry_validator_spec.rb'
- 'spec/requests/checkout/concurrency_spec.rb'
# Offense count: 6
# Configuration parameters: AllowComments.
@@ -534,17 +413,13 @@ Lint/RedundantDirGlobSort:
- 'spec/base_spec_helper.rb'
- 'spec/system_helper.rb'
# Offense count: 6
# Offense count: 1
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: AllowedMethods.
# AllowedMethods: instance_of?, kind_of?, is_a?, eql?, respond_to?, equal?
# AllowedMethods: instance_of?, kind_of?, is_a?, eql?, respond_to?, equal?, presence, present?
Lint/RedundantSafeNavigation:
Exclude:
- 'app/models/report_blob.rb'
- 'app/models/spree/payment.rb'
- 'app/serializers/api/admin/subscription_line_item_serializer.rb'
- 'lib/open_food_network/address_finder.rb'
- 'lib/tasks/missing_payments.rake'
# Offense count: 2
# This cop supports safe autocorrection (--autocorrect).
@@ -576,13 +451,12 @@ Lint/Void:
- 'spec/system/admin/order_cycles/complex_updating_specific_time_spec.rb'
- 'spec/system/admin/order_cycles/simple_spec.rb'
# Offense count: 27
# Offense count: 26
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
Metrics/AbcSize:
Exclude:
- 'app/controllers/admin/enterprises_controller.rb'
- 'app/controllers/payment_gateways/paypal_controller.rb'
- 'app/controllers/spree/admin/orders_controller.rb'
- 'app/controllers/spree/admin/payments_controller.rb'
- 'app/controllers/spree/admin/taxons_controller.rb'
- 'app/controllers/spree/admin/variants_controller.rb'
@@ -603,7 +477,7 @@ Metrics/AbcSize:
- 'lib/tasks/enterprises.rake'
- 'spec/services/order_checkout_restart_spec.rb'
# Offense count: 41
# Offense count: 48
# Configuration parameters: CountComments, Max, CountAsOne, AllowedMethods, AllowedPatterns.
# AllowedMethods: refine
Metrics/BlockLength:
@@ -645,7 +519,7 @@ Metrics/BlockNesting:
Exclude:
- 'app/models/spree/payment/processing.rb'
# Offense count: 47
# Offense count: 49
# Configuration parameters: CountComments, Max, CountAsOne.
Metrics/ClassLength:
Exclude:
@@ -653,12 +527,12 @@ Metrics/ClassLength:
- 'app/controllers/admin/enterprise_fees_controller.rb'
- 'app/controllers/admin/enterprises_controller.rb'
- 'app/controllers/admin/order_cycles_controller.rb'
- 'app/controllers/admin/product_import_controller.rb'
- 'app/controllers/admin/resource_controller.rb'
- 'app/controllers/admin/schedules_controller.rb'
- 'app/controllers/admin/subscriptions_controller.rb'
- '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/split_checkout_controller.rb'
- 'app/controllers/spree/admin/orders_controller.rb'
@@ -695,15 +569,15 @@ Metrics/ClassLength:
- 'lib/open_food_network/order_cycle_form_applicator.rb'
- 'lib/open_food_network/order_cycle_permissions.rb'
- 'lib/open_food_network/permissions.rb'
- 'lib/reporting/reports/enterprise_fee_summary/enterprise_fees_with_tax_report_by_order.rb'
- 'lib/reporting/reports/enterprise_fee_summary/scope.rb'
- 'lib/reporting/reports/xero_invoices/base.rb'
# Offense count: 36
# Offense count: 34
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
Metrics/CyclomaticComplexity:
Exclude:
- 'app/controllers/admin/enterprises_controller.rb'
- 'app/controllers/spree/admin/orders_controller.rb'
- 'app/controllers/spree/admin/taxons_controller.rb'
- 'app/controllers/spree/orders_controller.rb'
- 'app/helpers/checkout_helper.rb'
@@ -719,7 +593,6 @@ Metrics/CyclomaticComplexity:
- 'app/models/spree/preference.rb'
- 'app/models/spree/preferences/preferable.rb'
- 'app/models/spree/preferences/preferable_class_methods.rb'
- 'app/models/spree/product.rb'
- 'app/models/spree/return_authorization.rb'
- 'app/models/spree/tax_rate.rb'
- 'app/models/spree/variant.rb'
@@ -732,7 +605,7 @@ Metrics/CyclomaticComplexity:
- 'lib/spree/localized_number.rb'
- 'spec/models/product_importer_spec.rb'
# Offense count: 24
# Offense count: 25
# Configuration parameters: CountComments, Max, CountAsOne, AllowedMethods, AllowedPatterns.
Metrics/MethodLength:
Exclude:
@@ -751,6 +624,7 @@ Metrics/MethodLength:
- 'lib/open_food_network/order_cycle_permissions.rb'
- 'lib/reporting/reports/enterprise_fee_summary/scope.rb'
- 'lib/reporting/reports/xero_invoices/base.rb'
- 'lib/spree/localized_number.rb'
- 'lib/tasks/sample_data/product_factory.rb'
# Offense count: 49
@@ -807,11 +681,10 @@ Metrics/ModuleLength:
- 'spec/support/request/shop_workflow.rb'
- 'spec/support/request/stripe_stubs.rb'
# Offense count: 8
# Offense count: 7
# Configuration parameters: Max, CountKeywordArgs, MaxOptionalParameters.
Metrics/ParameterLists:
Exclude:
- 'app/components/confirm_modal_component.rb'
- 'app/helpers/angular_form_builder.rb'
- 'app/models/product_import/entry_processor.rb'
- 'lib/reporting/reports/xero_invoices/base.rb'
@@ -838,6 +711,31 @@ Naming/AccessorMethodName:
- 'spec/support/request/shop_workflow.rb'
- 'spec/support/request/web_helper.rb'
# Offense count: 42
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle, BlockForwardingName.
# SupportedStyles: anonymous, explicit
Naming/BlockForwarding:
Exclude:
- 'app/helpers/application_helper.rb'
- 'app/helpers/link_helper.rb'
- 'app/helpers/spree/admin/base_helper.rb'
- 'app/reflexes/application_reflex.rb'
- 'app/services/cache_service.rb'
- 'app/services/current_order_locker.rb'
- 'lib/reporting/reports/enterprise_fee_summary/scope.rb'
- 'lib/spree/core/controller_helpers/respond_with.rb'
- 'lib/spree/core/delegate_belongs_to.rb'
- 'lib/spree/core/environment_extension.rb'
- 'spec/models/enterprise_caching_spec.rb'
- 'spec/support/embedded_pages_helper.rb'
- 'spec/support/preferences_helper.rb'
- 'spec/support/request/shop_workflow.rb'
- 'spec/support/request/ui_component_helper.rb'
- 'spec/support/request/web_helper.rb'
- 'spec/swagger_helper.rb'
- 'spec/system/support/capybara_setup.rb'
# Offense count: 1
# Configuration parameters: ForbiddenDelimiters.
# ForbiddenDelimiters: (?i-mx:(^|\s)(EO[A-Z]{1}|END)(\s|$))
@@ -894,7 +792,7 @@ Rails/ActionOrder:
- 'app/controllers/spree/admin/variants_controller.rb'
- 'app/controllers/user_confirmations_controller.rb'
# Offense count: 13
# Offense count: 12
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: Include.
# Include: app/models/**/*.rb
@@ -974,6 +872,7 @@ Rails/ExpandedDateRange:
- 'app/models/spree/product.rb'
# Offense count: 5
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle.
# SupportedStyles: slashes, arguments
Rails/FilePath:
@@ -1012,7 +911,6 @@ Rails/HasManyOrHasOneDependent:
- 'app/models/spree/order.rb'
- 'app/models/spree/payment.rb'
- 'app/models/spree/payment_method.rb'
- 'app/models/spree/product.rb'
- 'app/models/spree/property.rb'
- 'app/models/spree/return_authorization.rb'
- 'app/models/spree/shipment.rb'
@@ -1061,7 +959,13 @@ Rails/I18nLocaleTexts:
Exclude:
- 'app/controllers/admin/stripe_accounts_controller.rb'
# Offense count: 26
# Offense count: 1
# This cop supports unsafe autocorrection (--autocorrect-all).
Rails/IgnoredColumnsAssignment:
Exclude:
- 'app/models/spree/variant.rb'
# Offense count: 22
# Configuration parameters: IgnoreScopes, Include.
# Include: app/models/**/*.rb
Rails/InverseOf:
@@ -1105,14 +1009,13 @@ Rails/LexicallyScopedActionFilter:
- 'app/controllers/spree/admin/zones_controller.rb'
- 'app/controllers/spree/users_controller.rb'
# Offense count: 8
# Offense count: 6
# This cop supports unsafe autocorrection (--autocorrect-all).
Rails/NegateInclude:
Exclude:
- 'app/controllers/admin/resource_controller.rb'
- 'app/models/calculator/weight.rb'
- 'app/models/product_import/spreadsheet_entry.rb'
- 'app/models/spree/order/checkout.rb'
- 'app/services/order_cart_reset.rb'
- 'lib/spree/localized_number.rb'
- 'spec/support/matchers/table_matchers.rb'
@@ -1264,7 +1167,7 @@ Rails/StripHeredoc:
- 'lib/reporting/reports/enterprise_fee_summary/scope.rb'
- 'lib/tasks/data/truncate_data.rake'
# Offense count: 4
# Offense count: 3
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: EnforcedStyle.
# SupportedStyles: strict, flexible
@@ -1272,7 +1175,6 @@ Rails/TimeZone:
Exclude:
- 'app/models/spree/gateway/pay_pal_express.rb'
- 'spec/controllers/spree/credit_cards_controller_spec.rb'
- 'spec/models/spree/tax_rate_spec.rb'
- 'spec/services/customer_order_cancellation_spec.rb'
# Offense count: 1
@@ -1374,6 +1276,19 @@ Security/Open:
Exclude:
- 'app/services/image_importer.rb'
# Offense count: 11
# This cop supports unsafe autocorrection (--autocorrect-all).
Style/ArrayIntersect:
Exclude:
- 'app/models/spree/ability.rb'
- 'app/models/tag_rule/filter_order_cycles.rb'
- 'app/models/tag_rule/filter_payment_methods.rb'
- 'app/models/tag_rule/filter_products.rb'
- 'app/models/tag_rule/filter_shipping_methods.rb'
- 'app/services/order_syncer.rb'
- 'lib/open_food_network/tag_rule_applicator.rb'
- 'spec/support/matchers/select2_matchers.rb'
# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
Style/BlockComments:
@@ -1496,6 +1411,14 @@ Style/GuardClause:
- 'spec/support/request/shop_workflow.rb'
- 'spec/system/support/precompile_assets.rb'
# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle.
# SupportedStyles: braces, no_braces
Style/HashAsLastArrayItem:
Exclude:
- 'app/components/products_table_component.rb'
# Offense count: 12
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: AllowSplatArgument.
@@ -1518,13 +1441,414 @@ Style/HashLikeCase:
Exclude:
- 'app/models/enterprise.rb'
# Offense count: 1778
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle, EnforcedShorthandSyntax, UseHashRocketsWithSymbolValues, PreferHashRocketsForNonAlnumEndingSymbols.
# SupportedStyles: ruby19, hash_rockets, no_mixed_keys, ruby19_no_mixed_keys
# SupportedShorthandSyntax: always, never, either, consistent
Style/HashSyntax:
Exclude:
- 'app/components/confirm_modal_component.rb'
- 'app/components/help_modal_component.rb'
- 'app/components/products_table_component.rb'
- 'app/components/selector_with_filter_component.rb'
- 'app/controllers/admin/customers_controller.rb'
- 'app/controllers/admin/enterprise_fees_controller.rb'
- 'app/controllers/admin/enterprise_groups_controller.rb'
- 'app/controllers/admin/enterprises_controller.rb'
- 'app/controllers/admin/order_cycles_controller.rb'
- 'app/controllers/admin/reports_controller.rb'
- 'app/controllers/admin/resource_controller.rb'
- 'app/controllers/admin/stripe_connect_settings_controller.rb'
- 'app/controllers/api/v0/enterprise_attachment_controller.rb'
- 'app/controllers/api/v0/shipments_controller.rb'
- 'app/controllers/concerns/extra_fields.rb'
- 'app/controllers/concerns/manager_invitations.rb'
- 'app/controllers/concerns/reports_actions.rb'
- 'app/controllers/line_items_controller.rb'
- 'app/controllers/payment_gateways/paypal_controller.rb'
- 'app/controllers/spree/admin/mail_methods_controller.rb'
- 'app/controllers/spree/admin/orders/customer_details_controller.rb'
- 'app/helpers/admin/injection_helper.rb'
- 'app/helpers/checkout_helper.rb'
- 'app/helpers/injection_helper.rb'
- 'app/helpers/serializer_helper.rb'
- 'app/helpers/spree/admin/base_helper.rb'
- 'app/helpers/tax_helper.rb'
- 'app/jobs/report_job.rb'
- 'app/jobs/webhook_delivery_job.rb'
- 'app/json_schemas/json_api_schema/structure.rb'
- 'app/mailers/enterprise_mailer.rb'
- 'app/mailers/payment_mailer.rb'
- 'app/mailers/producer_mailer.rb'
- 'app/mailers/spree/order_mailer.rb'
- 'app/mailers/spree/shipment_mailer.rb'
- 'app/mailers/spree/test_mailer.rb'
- 'app/mailers/spree/user_mailer.rb'
- 'app/mailers/subscription_mailer.rb'
- 'app/models/column_preference.rb'
- 'app/models/concerns/calculated_adjustments.rb'
- 'app/models/concerns/order_shipment.rb'
- 'app/models/concerns/variant_stock.rb'
- 'app/models/customer.rb'
- 'app/models/enterprise.rb'
- 'app/models/enterprise_relationship.rb'
- 'app/models/exchange.rb'
- 'app/models/exchange_variant.rb'
- 'app/models/invoice/data_presenter.rb'
- 'app/models/invoice/data_presenter/adjustment.rb'
- 'app/models/invoice/data_presenter/line_item.rb'
- 'app/models/invoice/data_presenter/payment.rb'
- 'app/models/producer_property.rb'
- 'app/models/product_import/entry_validator.rb'
- 'app/models/product_import/product_importer.rb'
- 'app/models/report_blob.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/gateway/stripe_sca.rb'
- 'app/models/spree/inventory_unit.rb'
- 'app/models/spree/item_adjustments.rb'
- 'app/models/spree/line_item.rb'
- 'app/models/spree/order.rb'
- 'app/models/spree/order/checkout.rb'
- 'app/models/spree/order_contents.rb'
- 'app/models/spree/payment.rb'
- 'app/models/spree/payment/processing.rb'
- 'app/models/spree/preferences/store.rb'
- 'app/models/spree/price.rb'
- 'app/models/spree/product.rb'
- 'app/models/spree/product_property.rb'
- 'app/models/spree/return_authorization.rb'
- 'app/models/spree/shipment.rb'
- 'app/models/spree/shipping_rate.rb'
- 'app/models/spree/stock_location.rb'
- 'app/models/spree/tax_rate.rb'
- 'app/models/spree/taxonomy.rb'
- 'app/models/spree/user.rb'
- 'app/models/spree/variant.rb'
- 'app/models/stripe_account.rb'
- 'app/models/voucher.rb'
- 'app/reflexes/admin/orders_reflex.rb'
- 'app/reflexes/invite_manager_reflex.rb'
- 'app/reflexes/white_label_reflex.rb'
- 'app/serializers/api/admin/enterprise_serializer.rb'
- 'app/services/address_geocoder.rb'
- 'app/services/customer_syncer.rb'
- 'app/services/exchange_variant_bulk_updater.rb'
- 'app/services/image_importer.rb'
- 'app/services/order_cycle_warning.rb'
- 'app/services/order_invoice_comparator.rb'
- 'app/services/order_syncer.rb'
- 'app/services/products_renderer.rb'
- 'app/services/recurring_payments.rb'
- 'app/services/shop/order_cycles_list.rb'
- 'app/services/voucher_adjustments_service.rb'
- 'engines/dfc_provider/app/services/dfc_builder.rb'
- 'engines/dfc_provider/spec/services/quantitative_value_builder_spec.rb'
- 'engines/dfc_provider/spec/support/authorization_helper.rb'
- 'engines/order_management/app/services/order_management/stock/estimator.rb'
- 'engines/order_management/app/services/order_management/subscriptions/proxy_order_syncer.rb'
- 'engines/order_management/app/services/order_management/subscriptions/validator.rb'
- 'engines/order_management/spec/services/order_management/order/updater_spec.rb'
- 'engines/order_management/spec/services/order_management/stock/package_spec.rb'
- 'engines/order_management/spec/services/order_management/stock/packer_spec.rb'
- 'engines/order_management/spec/services/order_management/subscriptions/estimator_spec.rb'
- 'engines/order_management/spec/services/order_management/subscriptions/payment_setup_spec.rb'
- 'engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb'
- 'engines/order_management/spec/services/order_management/subscriptions/stripe_payment_setup_spec.rb'
- 'engines/order_management/spec/services/order_management/subscriptions/validator_spec.rb'
- 'engines/order_management/spec/services/order_management/subscriptions/variants_list_spec.rb'
- 'engines/web/app/helpers/web/cookies_policy_helper.rb'
- 'engines/web/lib/web/cookies_consent.rb'
- 'lib/open_food_network/address_finder.rb'
- 'lib/open_food_network/enterprise_fee_applicator.rb'
- 'lib/open_food_network/enterprise_fee_calculator.rb'
- 'lib/open_food_network/i18n_inflections.rb'
- 'lib/open_food_network/order_cycle_form_applicator.rb'
- 'lib/open_food_network/scope_variant_to_hub.rb'
- 'lib/reporting/report_headers_builder.rb'
- 'lib/reporting/report_renderer.rb'
- 'lib/reporting/report_rows_builder.rb'
- 'lib/reporting/reports/enterprise_fee_summary/enterprise_fees_with_tax_report_by_order.rb'
- 'lib/reporting/reports/enterprise_fee_summary/fee_summary.rb'
- 'lib/reporting/reports/list.rb'
- 'lib/reporting/reports/order_cycle_management/base.rb'
- 'lib/reporting/reports/orders_and_fulfillment/order_cycle_supplier_totals.rb'
- 'lib/reporting/reports/packing/customer.rb'
- 'lib/reporting/reports/packing/product.rb'
- 'lib/reporting/reports/packing/supplier.rb'
- 'lib/reporting/reports/sales_tax/sales_tax_totals_by_order.rb'
- 'lib/reporting/reports/sales_tax/sales_tax_totals_by_producer.rb'
- 'lib/spree/core/controller_helpers/respond_with.rb'
- 'lib/stripe/account_connector.rb'
- 'lib/stripe/credit_card_clone_destroyer.rb'
- 'lib/stripe/credit_card_clone_finder.rb'
- 'lib/stripe/payment_intent_validator.rb'
- 'lib/tasks/sample_data/addressing.rb'
- 'lib/tasks/sample_data/enterprise_factory.rb'
- 'lib/tasks/sample_data/order_cycle_factory.rb'
- 'lib/tasks/sample_data/payment_method_factory.rb'
- 'lib/tasks/sample_data/user_factory.rb'
- 'lib/tasks/subscriptions/debug.rake'
- 'lib/tasks/subscriptions/test.rake'
- 'spec/components/product_component_spec.rb'
- 'spec/constraints/feature_toggle_constraint_spec.rb'
- 'spec/controllers/admin/bulk_line_items_controller_spec.rb'
- 'spec/controllers/admin/customers_controller_spec.rb'
- 'spec/controllers/admin/enterprises_controller_spec.rb'
- 'spec/controllers/admin/inventory_items_controller_spec.rb'
- 'spec/controllers/admin/invoice_settings_controller_spec.rb'
- 'spec/controllers/admin/matomo_settings_controller_spec.rb'
- 'spec/controllers/admin/order_cycles_controller_spec.rb'
- 'spec/controllers/admin/proxy_orders_controller_spec.rb'
- 'spec/controllers/admin/reports_controller_spec.rb'
- 'spec/controllers/admin/schedules_controller_spec.rb'
- 'spec/controllers/admin/stripe_accounts_controller_spec.rb'
- 'spec/controllers/admin/stripe_connect_settings_controller_spec.rb'
- 'spec/controllers/admin/subscription_line_items_controller_spec.rb'
- 'spec/controllers/admin/subscriptions_controller_spec.rb'
- 'spec/controllers/admin/tag_rules_controller_spec.rb'
- 'spec/controllers/admin/variant_overrides_controller_spec.rb'
- 'spec/controllers/api/v0/customers_controller_spec.rb'
- 'spec/controllers/api/v0/enterprises_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/reports/packing_report_spec.rb'
- 'spec/controllers/api/v0/shipments_controller_spec.rb'
- 'spec/controllers/api/v0/taxonomies_controller_spec.rb'
- 'spec/controllers/api/v0/taxons_controller_spec.rb'
- 'spec/controllers/api/v0/variants_controller_spec.rb'
- 'spec/controllers/base_controller_spec.rb'
- 'spec/controllers/cart_controller_spec.rb'
- 'spec/controllers/enterprises_controller_spec.rb'
- 'spec/controllers/line_items_controller_spec.rb'
- 'spec/controllers/payment_gateways/stripe_controller_spec.rb'
- 'spec/controllers/split_checkout_controller_spec.rb'
- 'spec/controllers/spree/admin/adjustments_controller_spec.rb'
- 'spec/controllers/spree/admin/invoices_controller_spec.rb'
- 'spec/controllers/spree/admin/orders/customer_details_controller_spec.rb'
- 'spec/controllers/spree/admin/orders/payments/payments_controller_refunds_spec.rb'
- 'spec/controllers/spree/admin/orders/payments/payments_controller_spec.rb'
- 'spec/controllers/spree/admin/orders_controller_spec.rb'
- 'spec/controllers/spree/admin/payment_methods_controller_spec.rb'
- 'spec/controllers/spree/admin/search_controller_spec.rb'
- 'spec/controllers/spree/admin/taxons_controller_spec.rb'
- 'spec/controllers/spree/credit_cards_controller_spec.rb'
- 'spec/controllers/spree/orders_controller_spec.rb'
- 'spec/controllers/stripe/webhooks_controller_spec.rb'
- 'spec/factories/line_item_factory.rb'
- 'spec/factories/order_cycle_factory.rb'
- 'spec/factories/order_factory.rb'
- 'spec/factories/shipment_factory.rb'
- 'spec/factories/subscription_factory.rb'
- 'spec/helpers/admin/orders_helper_spec.rb'
- 'spec/helpers/checkout_helper_spec.rb'
- 'spec/helpers/spree/base_helper_spec.rb'
- 'spec/jobs/report_job_spec.rb'
- 'spec/jobs/subscription_confirm_job_spec.rb'
- 'spec/jobs/subscription_placement_job_spec.rb'
- 'spec/jobs/webhook_delivery_job_spec.rb'
- 'spec/lib/open_food_network/address_finder_spec.rb'
- 'spec/lib/open_food_network/enterprise_fee_applicator_spec.rb'
- 'spec/lib/open_food_network/enterprise_fee_calculator_spec.rb'
- 'spec/lib/open_food_network/order_cycle_form_applicator_spec.rb'
- 'spec/lib/open_food_network/order_cycle_permissions_spec.rb'
- 'spec/lib/open_food_network/property_merge_spec.rb'
- 'spec/lib/open_food_network/scope_variant_to_hub_spec.rb'
- 'spec/lib/open_food_network/scope_variants_to_search_spec.rb'
- 'spec/lib/open_food_network/tag_rule_applicator_spec.rb'
- 'spec/lib/reports/bulk_coop_report_spec.rb'
- 'spec/lib/reports/customers_report_spec.rb'
- 'spec/lib/reports/enterprise_fee_summary/enterprise_fee_summary_report_spec.rb'
- 'spec/lib/reports/enterprise_fee_summary/permissions_spec.rb'
- 'spec/lib/reports/lettuce_share_report_spec.rb'
- 'spec/lib/reports/line_items_spec.rb'
- 'spec/lib/reports/order_cycle_management_report_spec.rb'
- 'spec/lib/reports/orders_and_distributors_report_spec.rb'
- 'spec/lib/reports/orders_and_fulfillment/order_cycle_customer_totals_report_spec.rb'
- 'spec/lib/reports/orders_and_fulfillment/order_cycle_distributor_totals_by_supplier_report_spec.rb'
- 'spec/lib/reports/orders_and_fulfillment/order_cycle_supplier_totals_by_distributor_report_spec.rb'
- 'spec/lib/reports/orders_and_fulfillment/orders_cycle_supplier_totals_report_spec.rb'
- 'spec/lib/reports/packing/packing_report_spec.rb'
- 'spec/lib/reports/products_and_inventory_report_spec.rb'
- 'spec/lib/spree/core/product_duplicator_spec.rb'
- 'spec/lib/stripe/account_connector_spec.rb'
- 'spec/lib/tasks/data/remove_transient_data_spec.rb'
- 'spec/lib/tasks/data/truncate_data_spec.rb'
- 'spec/mailers/order_mailer_spec.rb'
- 'spec/mailers/producer_mailer_spec.rb'
- 'spec/mailers/report_mailer_spec.rb'
- 'spec/mailers/shipment_mailer_spec.rb'
- 'spec/mailers/subscription_mailer_spec.rb'
- 'spec/migrations/migrate_admin_tax_amounts_spec.rb'
- 'spec/models/calculator/flat_percent_item_total_spec.rb'
- 'spec/models/calculator/flexi_rate_spec.rb'
- 'spec/models/calculator/price_sack_spec.rb'
- 'spec/models/calculator/weight_spec.rb'
- 'spec/models/column_preference_spec.rb'
- 'spec/models/concerns/calculated_adjustments_spec.rb'
- 'spec/models/concerns/order_shipment_spec.rb'
- 'spec/models/concerns/product_stock_spec.rb'
- 'spec/models/customer_spec.rb'
- 'spec/models/enterprise_caching_spec.rb'
- 'spec/models/enterprise_fee_spec.rb'
- 'spec/models/enterprise_relationship_spec.rb'
- 'spec/models/enterprise_spec.rb'
- 'spec/models/exchange_spec.rb'
- 'spec/models/invoice_spec.rb'
- 'spec/models/order_cycle_spec.rb'
- 'spec/models/product_import/entry_validator_spec.rb'
- 'spec/models/product_import/inventory_reset_strategy_spec.rb'
- 'spec/models/product_importer_spec.rb'
- 'spec/models/proxy_order_spec.rb'
- 'spec/models/spree/ability_spec.rb'
- 'spec/models/spree/address_spec.rb'
- 'spec/models/spree/adjustment_spec.rb'
- 'spec/models/spree/calculator_spec.rb'
- 'spec/models/spree/classification_spec.rb'
- 'spec/models/spree/credit_card_spec.rb'
- 'spec/models/spree/gateway/stripe_sca_spec.rb'
- 'spec/models/spree/inventory_unit_spec.rb'
- 'spec/models/spree/line_item_spec.rb'
- 'spec/models/spree/order/checkout_spec.rb'
- 'spec/models/spree/order/state_machine_spec.rb'
- 'spec/models/spree/order/tax_spec.rb'
- 'spec/models/spree/order_spec.rb'
- 'spec/models/spree/payment_method_spec.rb'
- 'spec/models/spree/payment_spec.rb'
- 'spec/models/spree/preference_spec.rb'
- 'spec/models/spree/product_spec.rb'
- 'spec/models/spree/return_authorization_spec.rb'
- 'spec/models/spree/shipment_spec.rb'
- 'spec/models/spree/shipping_method_spec.rb'
- 'spec/models/spree/shipping_rate_spec.rb'
- 'spec/models/spree/stock/availability_validator_spec.rb'
- 'spec/models/spree/stock_movement_spec.rb'
- 'spec/models/spree/tax_rate_spec.rb'
- 'spec/models/spree/user_spec.rb'
- 'spec/models/spree/variant_spec.rb'
- 'spec/models/spree/zone_spec.rb'
- 'spec/models/stripe_account_spec.rb'
- 'spec/models/variant_override_spec.rb'
- 'spec/models/voucher_spec.rb'
- 'spec/queries/complete_orders_with_balance_spec.rb'
- 'spec/queries/customers_with_balance_spec.rb'
- 'spec/queries/outstanding_balance_spec.rb'
- 'spec/queries/payments_requiring_action_spec.rb'
- 'spec/requests/admin/vouchers_controller_spec.rb'
- 'spec/requests/api/v1/customers_spec.rb'
- 'spec/requests/checkout/failed_checkout_spec.rb'
- 'spec/requests/checkout/paypal_spec.rb'
- 'spec/requests/checkout/routes_spec.rb'
- 'spec/requests/checkout/stripe_sca_spec.rb'
- 'spec/requests/voucher_adjustments_spec.rb'
- 'spec/serializers/api/admin/customer_serializer_spec.rb'
- 'spec/serializers/api/admin/for_order_cycle/supplied_product_serializer_spec.rb'
- 'spec/serializers/api/admin/index_enterprise_serializer_spec.rb'
- 'spec/serializers/api/admin/order_serializer_spec.rb'
- 'spec/serializers/api/admin/variant_override_serializer_spec.rb'
- 'spec/serializers/api/enterprise_serializer_spec.rb'
- 'spec/serializers/api/order_serializer_spec.rb'
- 'spec/serializers/api/product_serializer_spec.rb'
- 'spec/services/cap_quantity_spec.rb'
- 'spec/services/cart_service_spec.rb'
- 'spec/services/checkout/payment_method_fetcher_spec.rb'
- 'spec/services/default_stock_location_spec.rb'
- 'spec/services/invoice_data_generator_spec.rb'
- 'spec/services/order_available_payment_methods_spec.rb'
- 'spec/services/order_available_shipping_methods_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_cycle_form_spec.rb'
- 'spec/services/order_cycle_webhook_service_spec.rb'
- 'spec/services/order_data_masker_spec.rb'
- 'spec/services/order_factory_spec.rb'
- 'spec/services/order_fees_handler_spec.rb'
- 'spec/services/order_invoice_comparator_spec.rb'
- 'spec/services/order_payment_finder_spec.rb'
- 'spec/services/order_syncer_spec.rb'
- 'spec/services/order_tax_adjustments_fetcher_spec.rb'
- 'spec/services/order_workflow_spec.rb'
- 'spec/services/paypal_items_builder_spec.rb'
- 'spec/services/permissions/order_spec.rb'
- 'spec/services/place_proxy_order_spec.rb'
- 'spec/services/process_payment_intent_spec.rb'
- 'spec/services/product_tag_rules_filterer_spec.rb'
- 'spec/services/products_renderer_spec.rb'
- 'spec/services/search_orders_spec.rb'
- 'spec/services/sets/product_set_spec.rb'
- 'spec/services/tax_rate_finder_spec.rb'
- 'spec/services/user_default_address_setter_spec.rb'
- 'spec/services/variants_stock_levels_spec.rb'
- 'spec/services/voucher_adjustments_service_spec.rb'
- 'spec/support/controller_helper.rb'
- 'spec/support/controller_requests_helper.rb'
- 'spec/support/request/stripe_stubs.rb'
- 'spec/support/request/ui_component_helper.rb'
- 'spec/support/request/web_helper.rb'
- 'spec/system/admin/adjustments_spec.rb'
- 'spec/system/admin/bulk_product_update_spec.rb'
- 'spec/system/admin/configuration/states_spec.rb'
- 'spec/system/admin/configuration/tax_rates_spec.rb'
- 'spec/system/admin/customers_spec.rb'
- 'spec/system/admin/enterprises_spec.rb'
- 'spec/system/admin/invoice_print_spec.rb'
- 'spec/system/admin/order_cycles/complex_creating_specific_time_spec.rb'
- 'spec/system/admin/order_cycles/complex_updating_specific_time_spec.rb'
- 'spec/system/admin/order_cycles/simple_spec.rb'
- 'spec/system/admin/order_spec.rb'
- 'spec/system/admin/orders_spec.rb'
- 'spec/system/admin/payments_stripe_spec.rb'
- 'spec/system/admin/reports/enterprise_fee_summaries_spec.rb'
- 'spec/system/admin/reports/enterprise_summary_fees/enterprise_summary_fee_with_tax_report_by_order_spec.rb'
- 'spec/system/admin/reports/orders_and_fulfillment_spec.rb'
- 'spec/system/admin/reports/packing_report_spec.rb'
- 'spec/system/admin/reports/payments_report_spec.rb'
- 'spec/system/admin/reports/revenues_by_hub_spec.rb'
- 'spec/system/admin/reports/sales_tax/sales_tax_totals_by_order_spec.rb'
- 'spec/system/admin/reports/sales_tax/sales_tax_totals_by_producer_spec.rb'
- 'spec/system/admin/reports_spec.rb'
- 'spec/system/admin/subscriptions_spec.rb'
- 'spec/system/admin/tag_rules_spec.rb'
- 'spec/system/admin/variant_overrides_spec.rb'
- 'spec/system/admin/variants_spec.rb'
- 'spec/system/admin/vouchers_spec.rb'
- 'spec/system/consumer/account/cards_spec.rb'
- 'spec/system/consumer/account/developer_settings_spec.rb'
- 'spec/system/consumer/account/payments_spec.rb'
- 'spec/system/consumer/account_spec.rb'
- 'spec/system/consumer/authentication_spec.rb'
- 'spec/system/consumer/multilingual_spec.rb'
- 'spec/system/consumer/shopping/cart_spec.rb'
- 'spec/system/consumer/shopping/checkout_auth_spec.rb'
- 'spec/system/consumer/shopping/checkout_paypal_spec.rb'
- 'spec/system/consumer/shopping/checkout_spec.rb'
- 'spec/system/consumer/shopping/checkout_stripe_spec.rb'
- 'spec/system/consumer/shopping/orders_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/system/consumer/shopping/variant_overrides_spec.rb'
- 'spec/system/consumer/split_checkout_spec.rb'
- 'spec/system/consumer/split_checkout_tax_incl_spec.rb'
- 'spec/system/consumer/split_checkout_tax_not_incl_spec.rb'
- 'spec/system/consumer/user_password_spec.rb'
- 'spec/system/consumer/white_label_spec.rb'
- 'spec/system/support/cuprite_setup.rb'
- 'spec/views/spree/orders/edit.html.haml_spec.rb'
- 'spec/views/spree/shared/_order_details.html.haml_spec.rb'
# Offense count: 4
# This cop supports unsafe autocorrection (--autocorrect-all).
Style/MapToHash:
Exclude:
- 'lib/reporting/report_query_template.rb'
- 'lib/reporting/report_row_builder.rb'
- 'lib/reporting/reports/enterprise_fee_summary/base.rb'
- 'lib/reporting/reports/enterprise_fee_summary/fee_summary.rb'
- 'lib/tasks/sample_data/user_factory.rb'
# Offense count: 3
@@ -1628,11 +1952,10 @@ Style/RedundantArgument:
- 'engines/dfc_provider/app/services/authorization_control.rb'
- 'spec/support/query_counter.rb'
# Offense count: 15
# Offense count: 14
# This cop supports safe autocorrection (--autocorrect).
Style/RedundantConstantBase:
Exclude:
- 'app/controllers/checkout_controller.rb'
- 'app/controllers/split_checkout_controller.rb'
- 'app/controllers/webhook_endpoints_controller.rb'
- 'config.ru'
@@ -1671,12 +1994,11 @@ Style/RedundantStringEscape:
- 'spec/controllers/spree/admin/shipping_methods_controller_spec.rb'
- 'spec/system/admin/enterprise_fees_spec.rb'
# Offense count: 208
# Offense count: 205
Style/Send:
Exclude:
- 'app/controllers/split_checkout_controller.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'
@@ -1706,12 +2028,6 @@ Style/Send:
- 'spec/services/variant_units/option_value_namer_spec.rb'
- 'spec/support/localized_number_helper.rb'
# Offense count: 1
# This cop supports unsafe autocorrection (--autocorrect-all).
Style/SingleArgumentDig:
Exclude:
- 'app/services/checkout/form_data_adapter.rb'
# Offense count: 4
# This cop supports unsafe autocorrection (--autocorrect-all).
Style/SlicingWithRange:

View File

@@ -1 +1 @@
3.0.3
3.1.4

View File

@@ -1,9 +1,10 @@
# frozen_string_literal: true
source 'https://rubygems.org'
ruby "3.0.3"
git_source(:github) { |repo_name| "https://github.com/#{repo_name}.git" }
ruby File.read('.ruby-version').chomp
gem 'dotenv-rails', require: 'dotenv/rails-now' # Load ENV vars before other gems
gem 'rails'
@@ -115,8 +116,6 @@ gem 'spreadsheet_architect' # write spreadsheets
gem 'whenever', require: false
gem 'test-unit', '~> 3.5'
gem 'coffee-rails', '~> 5.0.0'
gem 'angular_rails_csrf'
@@ -140,7 +139,6 @@ gem "faraday"
gem "private_address_check"
group :production, :staging do
gem 'ddtrace'
gem 'sd_notify' # For better Systemd process management. Used by Puma.
end

View File

@@ -44,49 +44,49 @@ GEM
remote: https://rubygems.org/
specs:
Ascii85 (1.1.0)
actioncable (7.0.5)
actionpack (= 7.0.5)
activesupport (= 7.0.5)
actioncable (7.0.6)
actionpack (= 7.0.6)
activesupport (= 7.0.6)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
actionmailbox (7.0.5)
actionpack (= 7.0.5)
activejob (= 7.0.5)
activerecord (= 7.0.5)
activestorage (= 7.0.5)
activesupport (= 7.0.5)
actionmailbox (7.0.6)
actionpack (= 7.0.6)
activejob (= 7.0.6)
activerecord (= 7.0.6)
activestorage (= 7.0.6)
activesupport (= 7.0.6)
mail (>= 2.7.1)
net-imap
net-pop
net-smtp
actionmailer (7.0.5)
actionpack (= 7.0.5)
actionview (= 7.0.5)
activejob (= 7.0.5)
activesupport (= 7.0.5)
actionmailer (7.0.6)
actionpack (= 7.0.6)
actionview (= 7.0.6)
activejob (= 7.0.6)
activesupport (= 7.0.6)
mail (~> 2.5, >= 2.5.4)
net-imap
net-pop
net-smtp
rails-dom-testing (~> 2.0)
actionpack (7.0.5)
actionview (= 7.0.5)
activesupport (= 7.0.5)
actionpack (7.0.6)
actionview (= 7.0.6)
activesupport (= 7.0.6)
rack (~> 2.0, >= 2.2.4)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.2.0)
actionpack-action_caching (1.2.2)
actionpack (>= 4.0.0)
actiontext (7.0.5)
actionpack (= 7.0.5)
activerecord (= 7.0.5)
activestorage (= 7.0.5)
activesupport (= 7.0.5)
actiontext (7.0.6)
actionpack (= 7.0.6)
activerecord (= 7.0.6)
activestorage (= 7.0.6)
activesupport (= 7.0.6)
globalid (>= 0.6.0)
nokogiri (>= 1.8.5)
actionview (7.0.5)
activesupport (= 7.0.5)
actionview (7.0.6)
activesupport (= 7.0.6)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
@@ -98,19 +98,19 @@ GEM
activemodel (>= 5.2.0)
activestorage (>= 5.2.0)
activesupport (>= 5.2.0)
activejob (7.0.5)
activesupport (= 7.0.5)
activejob (7.0.6)
activesupport (= 7.0.6)
globalid (>= 0.3.6)
activemerchant (1.123.0)
activesupport (>= 4.2)
builder (>= 2.1.2, < 4.0.0)
i18n (>= 0.6.9)
nokogiri (~> 1.4)
activemodel (7.0.5)
activesupport (= 7.0.5)
activerecord (7.0.5)
activemodel (= 7.0.5)
activesupport (= 7.0.5)
activemodel (7.0.6)
activesupport (= 7.0.6)
activerecord (7.0.6)
activemodel (= 7.0.6)
activesupport (= 7.0.6)
activerecord-import (1.4.1)
activerecord (>= 4.2)
activerecord-postgresql-adapter (0.0.1)
@@ -121,14 +121,14 @@ GEM
multi_json (~> 1.11, >= 1.11.2)
rack (>= 2.0.8, < 3)
railties (>= 5.2.4.1)
activestorage (7.0.5)
actionpack (= 7.0.5)
activejob (= 7.0.5)
activerecord (= 7.0.5)
activesupport (= 7.0.5)
activestorage (7.0.6)
actionpack (= 7.0.6)
activejob (= 7.0.6)
activerecord (= 7.0.6)
activesupport (= 7.0.6)
marcel (~> 1.0)
mini_mime (>= 1.1.0)
activesupport (7.0.5)
activesupport (7.0.6)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
@@ -157,16 +157,16 @@ GEM
awesome_nested_set (3.5.0)
activerecord (>= 4.0.0, < 7.1)
aws-eventstream (1.2.0)
aws-partitions (1.779.0)
aws-sdk-core (3.174.0)
aws-partitions (1.780.0)
aws-sdk-core (3.175.0)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.5)
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.66.0)
aws-sdk-kms (1.67.0)
aws-sdk-core (~> 3, >= 3.174.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.124.0)
aws-sdk-s3 (1.126.0)
aws-sdk-core (~> 3, >= 3.174.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.4)
@@ -237,12 +237,6 @@ GEM
datafoodconsortium-connector (1.0.0.pre.alpha.6)
virtual_assembly-semantizer (~> 1.0, >= 1.0.4)
date (3.3.3)
ddtrace (1.12.1)
debase-ruby_core_source (= 3.2.1)
libdatadog (~> 2.0.0.1.0)
libddwaf (~> 1.9.0.0.0)
msgpack
debase-ruby_core_source (3.2.1)
debug (1.8.0)
irb (>= 1.5.0)
reline (>= 0.3.1)
@@ -276,7 +270,7 @@ GEM
factory_bot_rails (6.2.0)
factory_bot (~> 6.2.0)
railties (>= 5.0.0)
faraday (2.7.6)
faraday (2.7.10)
faraday-net_http (>= 2.0, < 3.1)
ruby2_keywords (>= 0.0.4)
faraday-follow_redirects (0.3.0)
@@ -323,7 +317,7 @@ GEM
fuubar (2.5.1)
rspec-core (~> 3.0)
ruby-progressbar (~> 1.4)
geocoder (1.8.1)
geocoder (1.8.2)
globalid (1.1.0)
activesupport (>= 5.0)
gmaps4rails (2.1.2)
@@ -383,15 +377,13 @@ GEM
jsonapi-serializer (2.2.0)
activesupport (>= 4.2)
jwt (2.7.1)
knapsack_pro (5.1.0)
knapsack_pro (5.1.2)
rake
language_server-protocol (3.17.0.3)
launchy (2.5.0)
addressable (~> 2.7)
letter_opener (1.8.1)
launchy (>= 2.2, < 3)
libdatadog (2.0.0.1.0)
libddwaf (1.9.0.0.1)
ffi (~> 1.0)
link_header (0.0.8)
listen (3.8.0)
rb-fsevent (~> 0.10, >= 0.10.3)
@@ -416,7 +408,7 @@ GEM
mini_magick (4.11.0)
mini_mime (1.1.2)
mini_portile2 (2.8.2)
minitest (5.18.0)
minitest (5.18.1)
monetize (1.12.0)
money (~> 6.12)
money (6.16.0)
@@ -424,7 +416,7 @@ GEM
msgpack (1.7.1)
multi_json (1.15.0)
multi_xml (0.6.0)
net-imap (0.3.4)
net-imap (0.3.6)
date
net-protocol
net-pop (0.1.2)
@@ -434,7 +426,7 @@ GEM
net-smtp (0.3.3)
net-protocol
nio4r (2.5.9)
nokogiri (1.15.2)
nokogiri (1.15.3)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
oauth2 (1.4.11)
@@ -488,7 +480,6 @@ GEM
ruby-rc4
ttfunk
pg (1.2.3)
power_assert (2.0.3)
private_address_check (0.5.0)
pry (0.13.1)
coderay (~> 1.1)
@@ -500,7 +491,7 @@ GEM
activerecord (>= 4.2)
railties (>= 4.2)
raabro (1.4.0)
racc (1.7.0)
racc (1.7.1)
rack (2.2.7)
rack-mini-profiler (2.3.4)
rack (>= 1.2.0)
@@ -518,26 +509,27 @@ GEM
rack-test (2.1.0)
rack (>= 1.3)
rack-timeout (0.6.3)
rails (7.0.5)
actioncable (= 7.0.5)
actionmailbox (= 7.0.5)
actionmailer (= 7.0.5)
actionpack (= 7.0.5)
actiontext (= 7.0.5)
actionview (= 7.0.5)
activejob (= 7.0.5)
activemodel (= 7.0.5)
activerecord (= 7.0.5)
activestorage (= 7.0.5)
activesupport (= 7.0.5)
rails (7.0.6)
actioncable (= 7.0.6)
actionmailbox (= 7.0.6)
actionmailer (= 7.0.6)
actionpack (= 7.0.6)
actiontext (= 7.0.6)
actionview (= 7.0.6)
activejob (= 7.0.6)
activemodel (= 7.0.6)
activerecord (= 7.0.6)
activestorage (= 7.0.6)
activesupport (= 7.0.6)
bundler (>= 1.15.0)
railties (= 7.0.5)
railties (= 7.0.6)
rails-controller-testing (1.0.5)
actionpack (>= 5.0.1.rc1)
actionview (>= 5.0.1.rc1)
activesupport (>= 5.0.1.rc1)
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
rails-dom-testing (2.1.1)
activesupport (>= 5.0.0)
minitest
nokogiri (>= 1.6)
rails-erd (1.7.2)
activerecord (>= 4.2)
@@ -551,9 +543,9 @@ GEM
i18n (>= 0.7, < 2)
railties (>= 6.0.0, < 8)
rails_safe_tasks (1.0.0)
railties (7.0.5)
actionpack (= 7.0.5)
activesupport (= 7.0.5)
railties (7.0.6)
actionpack (= 7.0.6)
activesupport (= 7.0.6)
method_source
rake (>= 12.2)
thor (~> 1.0)
@@ -627,8 +619,9 @@ GEM
rswag-ui (2.9.0)
actionpack (>= 3.1, < 7.1)
railties (>= 3.1, < 7.1)
rubocop (1.52.1)
rubocop (1.54.1)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
parser (>= 3.2.2.3)
rainbow (>= 2.2.2, < 4.0)
@@ -639,7 +632,7 @@ GEM
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.29.0)
parser (>= 3.2.1.0)
rubocop-rails (2.19.1)
rubocop-rails (2.20.2)
activesupport (>= 4.2.0)
rack (>= 1.1)
rubocop (>= 1.33.0, < 2.0)
@@ -653,7 +646,7 @@ GEM
rubyzip (2.3.2)
rufus-scheduler (3.8.2)
fugit (~> 1.1, >= 1.1.6)
sanitize (6.0.1)
sanitize (6.0.2)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
sass (3.4.25)
@@ -695,13 +688,13 @@ GEM
actionpack (>= 5.2)
activesupport (>= 5.2)
sprockets (>= 3.0.0)
state_machines (0.5.0)
state_machines-activemodel (0.8.0)
activemodel (>= 5.1)
state_machines (>= 0.5.0)
state_machines-activerecord (0.8.0)
activerecord (>= 5.1)
state_machines-activemodel (>= 0.8.0)
state_machines (0.6.0)
state_machines-activemodel (0.9.0)
activemodel (>= 6.0)
state_machines (>= 0.6.0)
state_machines-activerecord (0.9.0)
activerecord (>= 6.0)
state_machines-activemodel (>= 0.9.0)
stimulus_reflex (3.5.0.rc2)
actioncable (>= 5.2, < 8)
actionpack (>= 5.2, < 8)
@@ -719,13 +712,11 @@ GEM
attr_required (>= 0.0.5)
httpclient (>= 2.4)
temple (0.8.2)
test-unit (3.6.0)
power_assert
thor (1.2.2)
thread-local (1.1.0)
tilt (2.1.0)
timecop (0.9.6)
timeout (0.3.2)
timeout (0.4.0)
ttfunk (1.7.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
@@ -740,8 +731,8 @@ GEM
validate_url (1.0.15)
activemodel (>= 3.0.0)
public_suffix
vcr (6.1.0)
view_component (3.2.0)
vcr (6.2.0)
view_component (3.3.0)
activesupport (>= 5.2.0, < 8.0)
concurrent-ruby (~> 1.0)
method_source (~> 1.0)
@@ -818,7 +809,6 @@ DEPENDENCIES
database_cleaner
datafoodconsortium-connector
db2fog!
ddtrace
debug (>= 1.0.0)
debugger-linecache
devise
@@ -910,7 +900,6 @@ DEPENDENCIES
stimulus_reflex (= 3.5.0.rc2)
stringex (~> 2.8.5)
stripe
test-unit (~> 3.5)
timecop
valid_email2
vcr
@@ -925,7 +914,7 @@ DEPENDENCIES
wkhtmltopdf-binary
RUBY VERSION
ruby 3.0.3p157
ruby 3.1.4p223
BUNDLED WITH
2.4.3

View File

@@ -68,25 +68,6 @@
//= require textAngular.min.js
//= require i18n/translations
//= require darkswarm/i18n.translate.js
//= require moment/min/moment.min.js
//= require moment/locale/ar.js
//= require moment/locale/ca.js
//= require moment/locale/de.js
//= require moment/locale/en-gb.js
//= require moment/locale/es.js
//= require moment/locale/fil.js
//= require moment/locale/fr.js
//= require moment/locale/it.js
//= require moment/locale/nb.js
//= require moment/locale/nl-be.js
//= require moment/locale/pt-br.js
//= require moment/locale/pt.js
//= require moment/locale/ru.js
//= require moment/locale/sv.js
//= require moment/locale/tr.js
//= require moment/locale/pl.js
//= require js-big-decimal/dist/web/js-big-decimal.min.js
// foundation
//= require ../shared/mm-foundation-tpls-0.9.0-20180826174721.min.js

View File

@@ -113,7 +113,7 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout
(DirtyProducts.count() > 0 and confirm(t("unsaved_changes_confirmation"))) or (DirtyProducts.count() == 0)
editProductUrl = (product, variant) ->
"/admin/products/" + product.permalink_live + ((if variant then "/variants/" + variant.id else "")) + "/edit"
"/admin/products/" + product.id + ((if variant then "/variants/" + variant.id else "")) + "/edit"
$scope.editWarn = (product, variant) ->
if confirm_unsaved_changes()
@@ -162,7 +162,7 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout
if confirm(t("are_you_sure"))
$http(
method: "DELETE"
url: "/api/v0/products/" + product.permalink_live + "/variants/" + variant.id
url: "/api/v0/products/" + product.id + "/variants/" + variant.id
).then (response) ->
$scope.removeVariant(product, variant)
else
@@ -352,9 +352,6 @@ filterSubmitProducts = (productsToFilter) ->
if product.hasOwnProperty("inherits_properties")
filteredProduct.inherits_properties = product.inherits_properties
hasUpdatableProperty = true
if product.hasOwnProperty("available_on")
filteredProduct.available_on = product.available_on
hasUpdatableProperty = true
if filteredMaster?
filteredProduct.master_attributes = filteredMaster
hasUpdatableProperty = true

View File

@@ -1,5 +0,0 @@
angular.module("admin.dropdown").directive "linksDropdown", ($window)->
restrict: "C"
scope:
links: "="
templateUrl: "admin/links_dropdown.html"

View File

@@ -33,6 +33,4 @@ angular.module('admin.orderCycles').factory('Enterprise', ($resource) ->
variantsOf: (product) ->
if product.variants.length > 0
variant.id for variant in product.variants
else
[product.master_id]
})

View File

@@ -1,15 +0,0 @@
$ ->
($ '#new_image_link').click (event) ->
event.preventDefault()
($ '.no-objects-found').hide()
($ this).hide()
$.ajax
type: 'GET'
url: @href
data: (
authenticity_token: AUTH_TOKEN
)
success: (r) ->
($ '#images').html r

View File

@@ -1,7 +0,0 @@
($ '#cancel_link').click (event) ->
event.preventDefault()
($ '.no-objects-found').show()
($ '#new_image_link').show()
($ '#images').html('')

View File

@@ -11,24 +11,5 @@
//= require i18n/translations
//= require darkswarm/i18n.translate.js
//= require moment/min/moment.min.js
//= require moment/locale/ar.js
//= require moment/locale/ca.js
//= require moment/locale/de.js
//= require moment/locale/en-gb.js
//= require moment/locale/es.js
//= require moment/locale/fil.js
//= require moment/locale/fr.js
//= require moment/locale/it.js
//= require moment/locale/nb.js
//= require moment/locale/nl-be.js
//= require moment/locale/pt-br.js
//= require moment/locale/pt.js
//= require moment/locale/ru.js
//= require moment/locale/sv.js
//= require moment/locale/tr.js
//= require moment/locale/pl.js
//= require js-big-decimal/dist/web/js-big-decimal.min.js
window.angular = { module: function(noop){ return { value: function(){} } } }
window.angular = { module: function(noop){ return { value: function(){} } } }

View File

@@ -29,24 +29,6 @@
#
#= require angular-flash.min.js
#
#= require moment/min/moment.min.js
#= require moment/locale/ar.js
#= require moment/locale/ca.js
#= require moment/locale/de.js
#= require moment/locale/en-gb.js
#= require moment/locale/es.js
#= require moment/locale/fil.js
#= require moment/locale/fr.js
#= require moment/locale/it.js
#= require moment/locale/nb.js
#= require moment/locale/nl-be.js
#= require moment/locale/pt-br.js
#= require moment/locale/pt.js
#= require moment/locale/ru.js
#= require moment/locale/sv.js
#= require moment/locale/tr.js
#= require moment/locale/pl.js
#
#= require modernizr
#
#= require foundation-sites/js/foundation.js

View File

@@ -33,9 +33,9 @@ angular.module('Darkswarm').factory 'Products', (OrderCycleResource, OrderCycle,
prices = (v.price for v in product.variants)
product.price = Math.min.apply(null, prices)
product.hasVariants = product.variants?.length > 0
product.primaryImage = product.images[0]?.small_url if product.images
product.primaryImage = product.image?.small_url if product.image
product.primaryImageOrMissing = product.primaryImage || "/noimage/small.png"
product.largeImage = product.images[0]?.large_url if product.images
product.largeImage = product.image?.large_url if product.image
dereference: ->
for product in @fetched_products

View File

@@ -1,19 +0,0 @@
.ofn-drop-down
%span
%i.icon-check
{{ 'admin.actions' | t }}
%i{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" }
%div.menu{ 'ng-show' => "expanded" }
%div{ 'ng-repeat' => "link in links" }
%a.menu_item{ 'ng-if': "link.method", href: '{{link.url}}', target: "{{link.target || '_self'}}", data: { method: "{{ link.method }}", "ujs-navigate": "false", confirm: "{{link.confirm}}" } }
%span
%i{ ng: { class: "link.icon" } }
%span {{ link.name }}
%a.menu_item{ 'ng-if': "link.confirm && !link.method", href: '{{link.url}}', target: "{{link.target || '_self'}}", "data-confirm": "{{link.confirm}}" }
%span
%i{ ng: { class: "link.icon" } }
%span {{ link.name }}
%a.menu_item{ 'ng-if': "!link.confirm && !link.method", href: '{{link.url}}', target: "{{link.target || '_self'}}" }
%span
%i{ ng: { class: "link.icon" } }
%span {{ link.name }}

View File

@@ -0,0 +1,13 @@
# frozen_string_literal: true
class ScopedChannel < ApplicationCable::Channel
class << self
def for_id(id)
"ScopedChannel:#{id}"
end
end
def subscribed
stream_from "ScopedChannel:#{params[:id]}"
end
end

View File

@@ -6,7 +6,7 @@ class ProductComponent < ViewComponentReflex::Component
def initialize(product:, columns:)
super
@product = product
@image = @product.images[0] if product.images.any?
@image = @product.image if product.image.present?
@columns = columns.map do |c|
{
id: c[:value],
@@ -28,7 +28,7 @@ class ProductComponent < ViewComponentReflex::Component
when 'price'
@product.price
when 'unit'
"#{@product.unit_value} #{@product.variant_unit}"
"#{@product.variants.first.unit_value} #{@product.variant_unit}"
when 'producer'
@product.supplier.name
when 'category'
@@ -43,8 +43,6 @@ class ProductComponent < ViewComponentReflex::Component
@product.tax_category.name
when 'inherits_properties'
@product.inherits_properties
when 'available_on'
format_date(@product.available_on)
when 'import_date'
format_date(@product.import_date)
end

View File

@@ -17,7 +17,6 @@ class ProductsTableComponent < ViewComponentReflex::Component
label: I18n.t("admin.products_page.columns_selector.inherits_properties"),
value: "inherits_properties"
},
{ label: I18n.t("admin.products_page.columns_selector.available_on"), value: "available_on" },
{ label: I18n.t("admin.products_page.columns_selector.import_date"), value: "import_date" }
].sort do |a, b|
a[:label] <=> b[:label]
@@ -168,7 +167,7 @@ class ProductsTableComponent < ViewComponentReflex::Component
def product_query_includes
[
master: [:images],
:image,
variants: [
:default_price,
:stock_locations,

View File

@@ -12,7 +12,7 @@ module Admin
@line_items = order_permissions.
editable_line_items.where(order_id: orders).
includes(:variant).
ransack(params[:q]).result
ransack(params[:q]).result.order(:id)
@pagy, @line_items = pagy(@line_items) if pagination_required?
@@ -34,7 +34,8 @@ module Admin
# and https://www.postgresql.org/docs/current/static/sql-select.html#SQL-FOR-UPDATE-SHARE
order.with_lock do
if order.contents.update_item(@line_item, line_item_params)
render body: nil, status: :no_content # No Content, does not trigger ng resource auto-update
# No Content, does not trigger ng resource auto-update
render body: nil, status: :no_content
else
render json: { errors: @line_item.errors }, status: :precondition_failed
end

View File

@@ -36,8 +36,10 @@ module Admin
end
def create
@customer = Customer.new(customer_params)
@customer = Customer.find_or_initialize_by(customer_params.slice(:email, :enterprise_id))
if user_can_create_customer?
@customer.created_manually = true
if @customer.save
tag_rule_mapping = TagRule.mapping_for(Enterprise.where(id: @customer.enterprise))
render_as_json @customer, tag_rule_mapping: tag_rule_mapping
@@ -83,7 +85,7 @@ module Admin
def customers
return @customers if @customers.present?
@customers = Customer.managed_by(spree_current_user)
@customers = Customer.visible.managed_by(spree_current_user)
return @customers if params[:enterprise_id].blank?
@customers = @customers.where(enterprise_id: params[:enterprise_id])

View File

@@ -62,9 +62,7 @@ module Admin
when :for_order_cycle
order_cycle = OrderCycle.find_by(id: params[:order_cycle_id]) if params[:order_cycle_id]
coordinator = Enterprise.find_by(id: params[:coordinator_id]) if params[:coordinator_id]
if order_cycle.nil? && coordinator.present?
order_cycle = OrderCycle.new(coordinator: coordinator)
end
order_cycle ||= OrderCycle.new(coordinator: coordinator) if coordinator.present?
enterprises = OpenFoodNetwork::OrderCyclePermissions.new(spree_current_user,
order_cycle).visible_enterprises
EnterpriseFee.for_enterprises(enterprises).order('enterprise_id', 'fee_type', 'name')

View File

@@ -16,7 +16,8 @@ module Admin
@enterprise_relationship = EnterpriseRelationship.new enterprise_relationship_params
if @enterprise_relationship.save
render plain: Api::Admin::EnterpriseRelationshipSerializer.new(@enterprise_relationship).to_json
render plain: Api::Admin::EnterpriseRelationshipSerializer
.new(@enterprise_relationship).to_json
else
render status: :bad_request,
json: { errors: @enterprise_relationship.errors.full_messages.join(', ') }

View File

@@ -121,8 +121,12 @@ module Admin
def for_order_cycle
respond_to do |format|
format.json do
render json: @collection,
each_serializer: Api::Admin::ForOrderCycle::EnterpriseSerializer, order_cycle: @order_cycle, spree_current_user: spree_current_user
render(
json: @collection,
each_serializer: Api::Admin::ForOrderCycle::EnterpriseSerializer,
order_cycle: @order_cycle,
spree_current_user: spree_current_user
)
end
end
end
@@ -178,9 +182,7 @@ module Admin
when :for_order_cycle
@order_cycle = OrderCycle.find_by(id: params[:order_cycle_id]) if params[:order_cycle_id]
coordinator = Enterprise.find_by(id: params[:coordinator_id]) if params[:coordinator_id]
if @order_cycle.nil? && coordinator.present?
@order_cycle = OrderCycle.new(coordinator: coordinator)
end
@order_cycle ||= OrderCycle.new(coordinator: coordinator) if coordinator.present?
enterprises = OpenFoodNetwork::OrderCyclePermissions.new(spree_current_user, @order_cycle)
.visible_enterprises
@@ -188,7 +190,7 @@ module Admin
if enterprises.present?
enterprises.includes(
supplied_products:
[:supplier, :variants, { master: [:images] }]
[:supplier, :variants, :image]
)
end
when :index

View File

@@ -37,8 +37,14 @@ module Admin
end
def reset_absent_products
@importer = ProductImport::ProductImporter.new(File.new(file_path),
spree_current_user, import_into: params[:import_into], enterprises_to_reset: params[:enterprises_to_reset], updated_ids: params[:updated_ids], settings: params[:settings])
@importer = ProductImport::ProductImporter.new(
File.new(file_path),
spree_current_user,
import_into: params[:import_into],
enterprises_to_reset: params[:enterprises_to_reset],
updated_ids: params[:updated_ids],
settings: params[:settings]
)
if params.key?(:enterprises_to_reset) && params.key?(:updated_ids)
@importer.reset_absent(params[:updated_ids])
@@ -56,8 +62,13 @@ module Admin
end
def process_data(method)
@importer = ProductImport::ProductImporter.new(File.new(file_path),
spree_current_user, start: params[:start], end: params[:end], settings: params[:settings])
@importer = ProductImport::ProductImporter.new(
File.new(file_path),
spree_current_user,
start: params[:start],
end: params[:end],
settings: params[:settings]
)
begin
@importer.public_send("#{method}_entries")

View File

@@ -0,0 +1,7 @@
# frozen_string_literal: true
module Admin
class ProductsV3Controller < Spree::Admin::BaseController
def index; end
end
end

View File

@@ -22,24 +22,29 @@ module Admin
def show
@report = report_class.new(spree_current_user, params, render: render_data?)
@background_reports = OpenFoodNetwork::FeatureToggle
.enabled?(:background_reports, spree_current_user)
if @background_reports && request.post?
return background(report_format)
end
if params[:report_format].present?
export_report
else
show_report
end
rescue Timeout::Error
render_timeout_error
end
private
def export_report
send_data render_report_as(report_format), filename: report_filename
send_data @report.render_as(report_format), filename: report_filename
end
def show_report
assign_view_data
@table = render_report_as(:html) if render_data?
@table = @report.render_as(:html) if render_data?
render "show"
end
@@ -56,45 +61,24 @@ module Admin
request.post?
end
def render_report_as(format)
if OpenFoodNetwork::FeatureToggle.enabled?(:background_reports, spree_current_user)
@blob = ReportBlob.create_for_upload_later!(report_filename)
ReportJob.perform_later(
report_class, spree_current_user, params, format, @blob
)
Timeout.timeout(max_wait_time) do
sleep 1 until @blob.content_stored?
end
def background(format)
cable_ready[ScopedChannel.for_id(params[:uuid])]
.inner_html(
selector: "#report-table",
html: render_to_string(partial: "admin/reports/loading")
).scroll_into_view(
selector: "#report-table",
block: "start"
).broadcast
# This result has been rendered by Rails in safe mode already.
@blob.result.html_safe # rubocop:disable Rails/OutputSafety
else
@report.render_as(format)
end
end
blob = ReportBlob.create_for_upload_later!(report_filename)
def render_timeout_error
assign_view_data
if @blob
@error = ".report_taking_longer_html"
@error_url = @blob.expiring_service_url
else
@error = ".report_taking_longer"
@error_url = ""
end
render "show"
end
ReportJob.perform_later(
report_class: report_class, user: spree_current_user, params: params,
format: format, blob: blob, channel: ScopedChannel.for_id(params[:uuid]),
)
def max_wait_time
# This value is used by rack-timeout and nginx, usually 30 seconds in
# staging and production:
server_timeout = ENV.fetch("RACK_TIMEOUT_SERVICE_TIMEOUT", "15").to_f
# Zero disables the timeout:
return 0 if server_timeout.zero?
# We want to time out earlier than nginx:
server_timeout - 2.seconds
head :no_content
end
end
end

View File

@@ -18,7 +18,8 @@ module Admin
if view_context.subscriptions_setup_complete?(@shops)
@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_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
@@ -100,7 +101,8 @@ module Admin
end
def load_shops
@shops = Enterprise.managed_by(spree_current_user).is_distributor.where(enable_subscriptions: true)
@shops = Enterprise.managed_by(spree_current_user)
.is_distributor.where(enable_subscriptions: true)
end
def load_form_data
@@ -139,7 +141,9 @@ module Admin
@open_orders_to_keep = @subscription.proxy_orders.placed_and_open.pluck(:id)
return if @open_orders_to_keep.empty? || params[:open_orders] == 'keep'
render json: { errors: { open_orders: t('admin.subscriptions.confirm_cancel_open_orders_msg') } },
render json: {
errors: { open_orders: t('admin.subscriptions.confirm_cancel_open_orders_msg') }
},
status: :conflict
end
@@ -147,7 +151,9 @@ module Admin
return if params[:canceled_orders] == 'notified'
return if @subscription.proxy_orders.active.canceled.empty?
render json: { errors: { canceled_orders: t('admin.subscriptions.resume_canceled_orders_msg') } },
render json: {
errors: { canceled_orders: t('admin.subscriptions.resume_canceled_orders_msg') }
},
status: :conflict
end

View File

@@ -6,7 +6,7 @@ module Api
skip_authorization_check only: :index
def index
@customers = current_api_user.customers
@customers = current_api_user.customers.visible
render json: @customers, each_serializer: CustomerSerializer
end

View File

@@ -9,9 +9,9 @@ module Api
product = Spree::Product.find(params[:product_id])
authorize! :update, product
image = product.images.first || Spree::Image.new(
viewable_id: product.master.id,
viewable_type: 'Spree::Variant'
image = product.image || Spree::Image.new(
viewable_id: product.id,
viewable_type: 'Spree::Product'
)
success_status = image.persisted? ? :ok : :created

View File

@@ -10,8 +10,6 @@ module Api
respond_to :json
DEFAULT_PER_PAGE = 15
before_action :set_default_available_on, only: :create
skip_authorization_check only: [:show, :bulk_products, :overridable]
def show
@@ -23,15 +21,10 @@ module Api
authorize! :create, Spree::Product
@product = Spree::Product.new(product_params)
begin
if @product.save
render json: @product, serializer: Api::Admin::ProductSerializer, status: :created
else
invalid_resource!(@product)
end
rescue ActiveRecord::RecordNotUnique
@product.permalink = nil
retry
if @product.save
render json: @product, serializer: Api::Admin::ProductSerializer, status: :created
else
invalid_resource!(@product)
end
end
@@ -96,8 +89,6 @@ module Api
private
def find_product(id)
product_scope.find_by!(permalink: id.to_s)
rescue ActiveRecord::RecordNotFound
product_scope.find(id)
end
@@ -116,7 +107,7 @@ module Api
def product_query_includes
[
master: { images: { attachment_attachment: :blob } },
image: { attachment_attachment: :blob },
variants: [:default_price, :stock_locations, :stock_items, :variant_overrides]
]
end
@@ -152,10 +143,6 @@ module Api
@product_params ||=
params.permit(product: PermittedAttributes::Product.attributes)[:product].to_h
end
def set_default_available_on
product_params[:available_on] ||= Time.zone.now
end
end
end
end

View File

@@ -50,15 +50,15 @@ module Api
private
def product
@product ||= Spree::Product.find_by(permalink: params[:product_id]) if params[:product_id]
@product ||= Spree::Product.find(params[:product_id]) if params[:product_id]
end
def scope
if @product
variants = if current_api_user.has_spree_role?("admin") || params[:show_deleted]
@product.variants_including_master.with_deleted
@product.variants.with_deleted
else
@product.variants_including_master
@product.variants
end
else
variants = Spree::Variant.where(nil)

View File

@@ -29,7 +29,8 @@ module Api
def create
authorize! :update, Enterprise.find(customer_params[:enterprise_id])
customer = Customer.new(customer_params)
customer = Customer.find_or_initialize_by(customer_params.slice(:email, :enterprise_id))
customer.assign_attributes(customer_params)
if customer.save
render json: Api::V1::CustomerSerializer.new(customer), status: :created
@@ -80,7 +81,7 @@ module Api
end
def visible_customers
Customer.managed_by(current_api_user)
Customer.visible.managed_by(current_api_user)
end
def customer_params
@@ -96,6 +97,7 @@ module Api
]
).to_h
attributes.merge!(created_manually: true)
attributes.merge!(tag_list: params[:tags]) if params.key?(:tags)
transform_address!(attributes, :billing_address, :bill_address)

View File

@@ -41,8 +41,8 @@ module OrderCompletion
main_app.order_path(@order, order_token: @order.token)
end
def order_failed_route
main_app.checkout_path
def order_failed_route(step: 'details')
main_app.checkout_step_path(step:)
end
def order_invalid_for_checkout?
@@ -60,8 +60,8 @@ module OrderCompletion
def process_payment_completion!
unless @order.process_payments!
processing_failed
return redirect_to order_failed_route
payment_failed
return redirect_to order_failed_route(step: 'payment')
end
if OrderWorkflow.new(@order).next && @order.complete?
@@ -82,12 +82,20 @@ module OrderCompletion
order_completion_reset(@order)
end
def processing_failed(error = RuntimeError.new(order_processing_error))
def payment_failed
notify_failure
end
def processing_failed
notify_failure
Checkout::PostCheckoutActions.new(@order).failure
end
def notify_failure(error = RuntimeError.new(order_processing_error))
Bugsnag.notify(error) do |payload|
payload.add_metadata :order, @order
end
flash[:error] = order_processing_error if flash.blank?
Checkout::PostCheckoutActions.new(@order).failure
end
def order_processing_error

View File

@@ -27,8 +27,11 @@ module PaymentGateways
redirect_to provider.express_checkout_url(pp_response, useraction: 'commit')
else
flash[:error] =
Spree.t('flash.generic_error', scope: 'paypal',
reasons: pp_response.errors.map(&:long_message).join(" "))
Spree.t(
'flash.generic_error',
scope: 'paypal',
reasons: pp_response.errors.map(&:long_message).join(" "),
)
redirect_to main_app.checkout_step_path(:payment)
end
rescue SocketError

View File

@@ -24,7 +24,6 @@ class SplitCheckoutController < ::BaseController
def edit
redirect_to_step_based_on_order unless params[:step]
check_step if params[:step]
recalculate_tax if params[:step] == "summary"
flash_error_when_no_shipping_method_available if available_shipping_methods.none?
end
@@ -204,6 +203,7 @@ class SplitCheckoutController < ::BaseController
def process_voucher
if add_voucher
VoucherAdjustmentsService.calculate(@order)
render_voucher_section_or_redirect
elsif @order.errors.present?
render_error
@@ -226,7 +226,7 @@ class SplitCheckoutController < ::BaseController
adjustment = voucher.create_adjustment(voucher.code, @order)
if !adjustment.valid?
unless adjustment.valid?
@order.errors.add(:voucher, I18n.t('split_checkout.errors.add_voucher_error'))
adjustment.errors.each { |error| @order.errors.import(error) }
return false
@@ -308,18 +308,4 @@ class SplitCheckoutController < ::BaseController
redirect_to checkout_step_path(:payment) if params[:step] == "summary"
end
end
def recalculate_tax
@order.create_tax_charge!
@order.update_order!
apply_voucher if @order.voucher_adjustments.present?
end
def apply_voucher
VoucherAdjustmentsService.calculate(@order)
# update order to take into account the voucher we applied
@order.update_order!
end
end

View File

@@ -33,7 +33,7 @@ module Spree
def model_class
const_name = controller_name.classify
return "Spree::#{const_name}".constantize if Spree.const_defined?(const_name)
return "Spree::#{const_name}".constantize if Object.const_defined?("Spree::#{const_name}")
nil
end

View File

@@ -6,7 +6,7 @@ module Spree
# This will make resource controller redirect correctly after deleting product images.
# This can be removed after upgrading to Spree 2.1.
# See here https://github.com/spree/spree/commit/334a011d2b8e16355e4ae77ae07cd93f7cbc8fd1
belongs_to 'spree/product', find_by: :permalink
belongs_to 'spree/product'
before_action :load_data
@@ -25,6 +25,7 @@ module Spree
set_viewable
@object.attributes = permitted_resource_params
if @object.save
flash[:success] = flash_message_for(@object, :successfully_created)
redirect_to spree.admin_product_images_url(params[:product_id], @url_filters)
@@ -62,20 +63,28 @@ module Spree
private
def collection
parent.image
end
def find_resource
parent.image
end
def build_resource
Spree::Image.new(viewable: parent)
end
def location_after_save
spree.admin_product_images_url(@product)
end
def load_data
@product = Product.find_by(permalink: params[:product_id])
@variants = @product.variants.collect do |variant|
[variant.options_text, variant.id]
end
@variants.insert(0, [Spree.t(:all), @product.master.id])
@product = Product.find(params[:product_id])
end
def set_viewable
@image.viewable_type = 'Spree::Variant'
@image.viewable_type = 'Spree::Product'
@image.viewable_id = params[:image][:viewable_id]
end

View File

@@ -6,6 +6,10 @@ module Spree
respond_to :json
authorize_resource class: false
def index
@order = Spree::Order.find_by(number: params[:order_id])
end
def create
invoice_service = BulkInvoiceService.new
invoice_service.start_pdf_job(params[:order_ids])
@@ -13,6 +17,24 @@ module Spree
render json: invoice_service.id, status: :ok
end
def generate
@order = Order.find_by(number: params[:order_id])
@comparator = OrderInvoiceComparator.new(@order)
if @comparator.can_generate_new_invoice?
@order.invoices.create!(
date: Time.zone.today,
number: @order.invoices.count + 1,
data: invoice_data
)
elsif @comparator.can_update_latest_invoice?
@order.invoices.last.update!(
date: Time.zone.today,
data: invoice_data
)
end
redirect_back(fallback_location: spree.admin_dashboard_path)
end
def show
invoice_id = params[:id]
invoice_pdf = BulkInvoiceService.new.filepath(invoice_id)
@@ -29,6 +51,12 @@ module Spree
render json: { created: false }, status: :unprocessable_entity
end
end
protected
def invoice_data
@invoice_data ||= InvoiceDataGenerator.new(@order).generate
end
end
end
end

View File

@@ -24,7 +24,6 @@ module Spree
end
refresh_shipment_rates
recalculate_taxes
OrderWorkflow.new(@order).advance_to_payment
flash[:success] = Spree.t('customer_details_updated')
@@ -52,15 +51,6 @@ module Spree
@order.shipments.map(&:refresh_rates)
end
def recalculate_taxes
# If the order's address has been changed, the tax zone could be different,
# which means a different set of tax rates might be applicable.
@order.create_tax_charge!
Spree::TaxRate.adjust(@order, @order.adjustments.admin)
@order.update_totals_and_states
end
def order_params
params.require(:order).permit(
:email,

View File

@@ -99,6 +99,10 @@ module Spree
end
def print
if OpenFoodNetwork::FeatureToggle.enabled?(:invoices)
@order = @order.invoices.find(params[:invoice_id]).presenter
end
render_with_wicked_pdf InvoiceRenderer.new.args(@order)
end

View File

@@ -3,7 +3,7 @@
module Spree
module Admin
class ProductPropertiesController < ::Admin::ResourceController
belongs_to 'spree/product', find_by: :permalink
belongs_to 'spree/product'
before_action :find_properties
before_action :setup_property, only: [:index]

View File

@@ -103,7 +103,7 @@ module Spree
protected
def find_resource
Product.find_by!(permalink: params[:id])
Product.find(params[:id])
end
def location_after_save
@@ -121,8 +121,7 @@ module Spree
end
def product_includes
[{ variants: [:images] },
{ master: [:images, :default_price] }]
[:image, { variants: [:images] }]
end
def collection_actions
@@ -182,7 +181,6 @@ module Spree
joins(:product).
where('spree_products.supplier_id IN (?)', editable_enterprises.collect(&:id)).
where('spree_variants.import_date IS NOT NULL').
where(spree_variants: { is_master: false }).
where(spree_variants: { deleted_at: nil }).
order('spree_variants.import_date DESC')
end
@@ -208,7 +206,7 @@ module Spree
end
def set_stock_levels(product, on_hand, on_demand)
variant = product_variant(product)
variant = product.variants.first
begin
variant.on_demand = on_demand if on_demand.present?
@@ -228,14 +226,6 @@ module Spree
end
end
def product_variant(product)
if product.variants.any?
product.variants.first
else
product.master
end
end
def set_product_master_variant_price_to_zero
@product.price = 0 if @product.price.nil?
end

View File

@@ -5,9 +5,7 @@ require 'open_food_network/scope_variants_for_search'
module Spree
module Admin
class VariantsController < ::Admin::ResourceController
belongs_to 'spree/product', find_by: :permalink
before_action :assign_default_attributes, only: :new
belongs_to 'spree/product'
def index
@url_filters = ::ProductFilters.new.extract(request.query_parameters)
@@ -45,6 +43,7 @@ module Spree
flash[:success] = flash_message_for(@object, :successfully_created)
redirect_to spree.admin_product_variants_url(params[:product_id], @url_filters)
else
flash[:error] = @object.errors.full_messages.to_sentence if @object.errors.any?
redirect_to spree.new_admin_product_variant_url(params[:product_id], @url_filters)
end
@@ -83,13 +82,6 @@ module Spree
@object.save
end
def assign_default_attributes
@object.attributes = @object.product.master.
attributes.except('id', 'created_at', 'deleted_at', 'sku', 'is_master')
# Shallow Clone of the default price to populate the price field.
@object.default_price = @object.product.master.default_price.clone
end
def collection
@deleted = params.key?(:deleted) && params[:deleted] == "on" ? "checked" : ""

View File

@@ -7,7 +7,8 @@ module AngularFormHelper
container.map do |element|
html_attributes = option_html_attributes(element)
text, value = option_text_and_value(element).map(&:to_s)
%(<option value="#{ERB::Util.html_escape(value)}"#{html_attributes}>#{ERB::Util.html_escape(text)}</option>)
%(<option value="#{ERB::Util.html_escape(value)}"\
#{html_attributes}>#{ERB::Util.html_escape(text)}</option>)
end.join("\n").html_safe
end

View File

@@ -139,7 +139,7 @@ module CheckoutHelper
def stripe_card_options(cards)
cards.map do |cc|
[
"#{cc.brand} #{cc.last_digits} #{I18n.t(:card_expiry_abbreviation)}:"\
"#{cc.brand} #{cc.last_digits} #{I18n.t(:card_expiry_abbreviation)}:" \
"#{cc.month.to_s.rjust(2, '0')}/#{cc.year}", cc.id
]
end

View File

@@ -77,7 +77,8 @@ module EnterprisesHelper
end
def subscriptions_enabled?
spree_current_user.admin? || spree_current_user.enterprises.where(enable_subscriptions: true).any?
spree_current_user.admin? ||
spree_current_user.enterprises.where(enable_subscriptions: true).any?
end
def enterprise_url_selector(enterprise)

View File

@@ -36,6 +36,13 @@ module OrderCyclesHelper
shipping_and_payment_methods: true
end
def distributors_with_editable_shipping_and_payment_methods(order_cycle)
return order_cycle.distributors if Enterprise
.managed_by(spree_current_user).exists?(order_cycle.coordinator.id)
order_cycle.distributors.managed_by(spree_current_user)
end
def order_cycle_status_class(order_cycle)
if order_cycle.undated?
'undated'

View File

@@ -8,4 +8,14 @@ module OrderHelper
def outstanding_balance_label(order)
order.outstanding_balance.label
end
def show_generate_invoice_button?(order)
comparator = order_comparator(order)
comparator.can_generate_new_invoice? ||
comparator.can_update_latest_invoice?
end
def order_comparator(order)
OrderInvoiceComparator.new(order)
end
end

View File

@@ -32,7 +32,28 @@ module ReportsHelper
end
end
def fee_name_options(orders)
EnterpriseFee.where(id: enterprise_fee_ids(orders))
.pluck(:name, :id)
end
def fee_owner_options(orders)
Enterprise.where(id: enterprise_fee_owner_ids(orders))
.pluck(:name, :id)
end
def currency_symbol
Spree::Money.currency_symbol
end
def enterprise_fee_owner_ids(orders)
EnterpriseFee.where(id: enterprise_fee_ids(orders))
.pluck(:enterprise_id)
end
def enterprise_fee_ids(orders)
Spree::Adjustment.enterprise_fee
.where(order_id: orders.map(&:id))
.pluck(:originator_id)
end
end

View File

@@ -5,11 +5,7 @@ module Spree
module ImagesHelper
def options_text_for(image)
if image.viewable.is_a?(Spree::Variant)
if image.viewable.is_master?
I18n.t(:all)
else
image.viewable.options_text
end
image.viewable.options_text
else
I18n.t(:all)
end

View File

@@ -31,6 +31,7 @@ module Spree
end
def invoice_links
return [] if OpenFoodNetwork::FeatureToggle.enabled?(:invoices)
return [] unless Spree::Config[:enable_invoices?]
[send_invoice_link, print_invoice_link]

View File

@@ -18,9 +18,8 @@ module Spree
def changeable_orders
# Only returns open order for the current user + shop + oc combo
return @changeable_orders unless @changeable_orders.nil?
unless spree_current_user && current_distributor && current_order_cycle
return @changeable_orders = []
end
return @changeable_orders = [] unless spree_current_user &&
current_distributor && current_order_cycle
return @changeable_orders = [] unless current_distributor.allow_order_changes?
@changeable_orders = Spree::Order.complete.where(

View File

@@ -7,4 +7,11 @@ class ApplicationJob < ActiveJob::Base
# Most jobs are safe to ignore if the underlying records are no longer available
# discard_on ActiveJob::DeserializationError
private
def enable_active_storage_urls
ActiveStorage::Current.url_options ||=
Rails.application.config.action_controller.default_url_options
end
end

View File

@@ -2,9 +2,14 @@
# Renders a report and stores it in a given blob.
class ReportJob < ApplicationJob
include CableReady::Broadcaster
delegate :render, to: ActionController::Base
before_perform :enable_active_storage_urls
NOTIFICATION_TIME = 5.seconds
def perform(report_class, user, params, format, blob)
def perform(report_class:, user:, params:, format:, blob:, channel: nil)
start_time = Time.zone.now
report = report_class.new(user, params, render: true)
@@ -14,6 +19,8 @@ class ReportJob < ApplicationJob
execution_time = Time.zone.now - start_time
email_result(user, blob) if execution_time > NOTIFICATION_TIME
broadcast_result(channel, format, blob) if channel
end
def email_result(user, blob)
@@ -22,4 +29,17 @@ class ReportJob < ApplicationJob
blob: blob,
).report_ready.deliver_later
end
def broadcast_result(channel, format, blob)
cable_ready[channel].inner_html(
selector: "#report-table",
html: actioncable_content(format, blob)
).broadcast
end
def actioncable_content(format, blob)
return blob.result if format.to_sym == :html
render(partial: "admin/reports/download", locals: { file_url: blob.expiring_service_url })
end
end

View File

@@ -41,7 +41,9 @@ class SubscriptionConfirmJob < ApplicationJob
def recently_closed_order_cycles
OrderCycle.closed.where(
'order_cycles.orders_close_at BETWEEN (?) AND (?) OR order_cycles.updated_at BETWEEN (?) AND (?)', 1.hour.ago, Time.zone.now, 1.hour.ago, Time.zone.now
'order_cycles.orders_close_at BETWEEN (?) AND (?) ' \
'OR order_cycles.updated_at BETWEEN (?) AND (?)',
1.hour.ago, Time.zone.now, 1.hour.ago, Time.zone.now
)
end

View File

@@ -13,7 +13,7 @@ module Spree
@edit_password_reset_url = spree.
edit_spree_user_password_url(reset_password_token: token)
subject = "#{Spree::Config[:site_name]} " \
"#{I18n.t('spree.user_mailer.reset_password_instructions.subject')}"
"#{I18n.t('spree.user_mailer.reset_password_instructions.subject')}"
I18n.with_locale valid_locale(user) do
mail(to: user.email, subject: subject)

View File

@@ -38,14 +38,16 @@ class SubscriptionMailer < ApplicationMailer
@shop = Enterprise.find(summary.shop_id)
@summary = summary
mail(to: @shop.contact.email,
subject: "#{Spree::Config[:site_name]} #{t('subscription_mailer.placement_summary_email.subject')}")
subject: "#{Spree::Config[:site_name]} " \
"#{t('subscription_mailer.placement_summary_email.subject')}")
end
def confirmation_summary_email(summary)
@shop = Enterprise.find(summary.shop_id)
@summary = summary
mail(to: @shop.contact.email,
subject: "#{Spree::Config[:site_name]} #{t('subscription_mailer.confirmation_summary_email.subject')}")
subject: "#{Spree::Config[:site_name]} " \
"#{t('subscription_mailer.confirmation_summary_email.subject')}")
end
private

View File

@@ -15,6 +15,16 @@ class ApplicationRecord < ActiveRecord::Base
ENV["S3_BUCKET"].present? ? :amazon_public : :local
end
# We might have a development environment without S3 but with a database
# dump pointing to S3 images. Accessing the service fails then.
def image_variant_url_for(variant)
if ENV["S3_BUCKET"].present? && variant.service.public?
variant.processed.url
else
url_for(variant)
end
end
def url_for(*args)
Rails.application.routes.url_helpers.url_for(*args)
end

View File

@@ -4,7 +4,7 @@ require 'active_support/concern'
# This module is an adapter for OFN to work with Spree 2 code.
#
# Although Spree 2 supports multiple shipments per order, in OFN we have only one shipment per order.
# Although Spree 2 supports multiple shipments per order, in OFN we have only 1 shipment per order.
# A shipment is associated to a shipping_method through a selected shipping_rate.
# See https://github.com/openfoodfoundation/openfoodnetwork/wiki/Spree-Upgrade:-Migration-to-multiple-shipments
# for details.
@@ -30,7 +30,8 @@ module OrderShipment
shipments.first.shipping_method
end
# Finds the shipment's shipping_rate for the given shipping_method_id and selects that shipping_rate.
# Finds the shipment's shipping_rate for the given shipping_method_id
# and selects that shipping_rate.
# If the selection is successful, it persists it in the database by saving the shipment.
# If it fails, it does not clear the current shipping_method selection.
#

View File

@@ -6,7 +6,8 @@ module ProductStock
extend ActiveSupport::Concern
def on_demand
raise 'Cannot determine product on_demand value of product with multiple variants' if variants.size > 1
raise 'Cannot determine product on_demand value of product with multiple variants' if
variants.size > 1
variants.first.on_demand
end

View File

@@ -42,7 +42,8 @@ module VariantStock
# Checks whether this variant is produced on demand.
def on_demand
# A variant that has not been saved yet or has been soft-deleted doesn't have a stock item
# This provides a default value for variant.on_demand using Spree::StockLocation.backorderable_default
# This provides a default value for variant.on_demand
# using Spree::StockLocation.backorderable_default
return Spree::StockLocation.first.backorderable_default if new_record? || deleted?
# This can be removed unless we have seen this error in Bugsnag recently
@@ -76,8 +77,10 @@ module VariantStock
end
end
# Moving Spree::Stock::Quantifier.can_supply? to the variant enables us to override this behaviour for variant overrides
# We can have this responsibility here in the variant because there is only one stock item per variant
# Moving Spree::Stock::Quantifier.can_supply? to the variant enables us
# to override this behaviour for variant overrides
# We can have this responsibility here in the variant because there is
# only one stock item per variant
#
# Here we depend only on variant.total_on_hand and variant.on_demand.
# This way, variant_overrides only need to override variant.total_on_hand and variant.on_demand.
@@ -85,8 +88,10 @@ module VariantStock
on_demand || total_on_hand >= quantity
end
# Moving Spree::StockLocation.fill_status to the variant enables us to override this behaviour for variant overrides
# We can have this responsibility here in the variant because there is only one stock item per variant
# Moving Spree::StockLocation.fill_status to the variant enables us
# to override this behaviour for variant overrides
# We can have this responsibility here in the variant because there is
# only one stock item per variant
#
# Here we depend only on variant.total_on_hand and variant.on_demand.
# This way, variant_overrides only need to override variant.total_on_hand and variant.on_demand.
@@ -102,7 +107,8 @@ module VariantStock
[on_hand, backordered]
end
# We can have this responsibility here in the variant because there is only one stock item per variant
# We can have this responsibility here in the variant because there is
# only one stock item per variant
#
# This enables us to override this behaviour for variant overrides
def move(quantity, originator = nil)
@@ -138,7 +144,8 @@ module VariantStock
# Overwrites stock_item.count_on_hand
#
# Calling stock_item.adjust_count_on_hand will bypass filling backorders and creating stock movements
# Calling stock_item.adjust_count_on_hand will bypass filling backorders
# and creating stock movements
# If that was required we could call self.move
def overwrite_stock_levels(new_level)
stock_item.adjust_count_on_hand(new_level.to_i - stock_item.count_on_hand)

View File

@@ -34,10 +34,15 @@ class Customer < ApplicationRecord
validates :code, uniqueness: { scope: :enterprise_id, allow_nil: true }
validates :email, presence: true, 'valid_email_2/email': true,
uniqueness: { scope: :enterprise_id, message: I18n.t('validation_msg_is_associated_with_an_exising_customer') }
uniqueness: {
scope: :enterprise_id,
message: I18n.t('validation_msg_is_associated_with_an_exising_customer')
}
scope :of, ->(enterprise) { where(enterprise_id: enterprise) }
scope :managed_by, ->(user) { user&.persisted? ? where(user: user).or(of(Enterprise.managed_by(user))) : none }
scope :created_manually, -> { where(created_manually: true) }
scope :visible, -> { where(id: Spree::Order.complete.select(:customer_id)).or(created_manually) }
before_create :associate_user

View File

@@ -160,7 +160,7 @@ class Enterprise < ApplicationRecord
scope :is_distributor, -> { where('sells != ?', 'none') }
scope :is_hub, -> { where(sells: 'any') }
scope :supplying_variant_in, lambda { |variants|
joins(supplied_products: :variants_including_master).
joins(supplied_products: :variants).
where('spree_variants.id IN (?)', variants).
select('DISTINCT enterprises.*')
}
@@ -389,7 +389,7 @@ class Enterprise < ApplicationRecord
def current_distributed_taxons
Spree::Taxon
.select("DISTINCT spree_taxons.*")
.joins(products: :variants_including_master)
.joins(products: :variants)
.joins("INNER JOIN (#{current_exchange_variants.to_sql}) \
AS exchange_variants ON spree_variants.id = exchange_variants.variant_id")
end
@@ -459,10 +459,10 @@ class Enterprise < ApplicationRecord
def image_url_for(image, name)
return unless image.variable?
return image.variant(name).processed.url if image.attachment.service.name == :amazon_public
url_for(image.variant(name))
image_variant_url_for(image.variant(name))
rescue ActiveStorage::Error => e
Bugsnag.notify "Enterprise ##{id} #{image.try(:name)} error: #{e.message}"
Rails.logger.error(e.message)
nil
@@ -505,7 +505,10 @@ class Enterprise < ApplicationRecord
end
def set_unused_address_fields
address.firstname = address.lastname = address.phone = address.company = 'unused' if address.present?
if address.present?
address.firstname = address.lastname = address.phone =
address.company = 'unused'
end
business_address.first_name = business_address.last_name = 'unused' if business_address.present?
end

View File

@@ -55,7 +55,7 @@ class Exchange < ApplicationRecord
}
scope :with_product, lambda { |product|
joins(:exchange_variants).
where('exchange_variants.variant_id IN (?)', product.variants_including_master.select(&:id))
where('exchange_variants.variant_id IN (?)', product.variants.select(&:id))
}
scope :by_enterprise_name, -> {
joins('INNER JOIN enterprises AS sender ON (sender.id = exchanges.sender_id)').

17
app/models/invoice.rb Normal file
View File

@@ -0,0 +1,17 @@
# frozen_string_literal: true
class Invoice < ApplicationRecord
belongs_to :order, class_name: 'Spree::Order'
serialize :data, Hash
before_validation :serialize_order
def presenter
@presenter ||= Invoice::DataPresenter.new(self)
end
def serialize_order
return data unless data.empty?
self.data = Invoice::OrderSerializer.new(order).serializable_hash
end
end

View File

@@ -0,0 +1,133 @@
# frozen_string_literal: true
class Invoice
class DataPresenter
attr_reader :invoice
delegate :data, :date, to: :invoice
FINALIZED_NON_SUCCESSFUL_STATES = %w(canceled returned).freeze
extend Invoice::DataPresenterAttributes
attributes :additional_tax_total, :currency, :included_tax_total, :payment_total,
:shipping_method_id, :state, :total, :number, :note, :special_instructions,
:completed_at
attributes_with_presenter :bill_address, :customer, :distributor, :ship_address,
:shipping_method, :order_cycle
array_attribute :sorted_line_items, class_name: 'LineItem'
array_attribute :all_eligible_adjustments, class_name: 'Adjustment'
array_attribute :payments, class_name: 'Payment'
# if any of the following attributes is updated, a new invoice should be generated
invoice_generation_attributes :additional_tax_total, :all_eligible_adjustments, :bill_address,
:included_tax_total, :payments, :payment_total, :ship_address,
:shipping_method_id, :sorted_line_items, :total
# if any of the following attributes is updated, the latest invoice should be updated
invoice_update_attributes :note, :special_instructions, :state,
:all_eligible_adjustments, :payments
def initialize(invoice)
@invoice = invoice
end
def has_taxes_included
included_tax_total > 0
end
def total_tax
additional_tax_total + included_tax_total
end
def order_completed_at
return nil if data[:completed_at].blank?
Time.zone.parse(data[:completed_at])
end
def checkout_adjustments(exclude: [], reject_zero_amount: true)
adjustments = all_eligible_adjustments
adjustments.reject! { |a| a.originator_type == 'Spree::TaxRate' }
if exclude.include? :line_item
adjustments.reject! { |a|
a.adjustable_type == 'Spree::LineItem'
}
end
if reject_zero_amount
adjustments.reject! { |a| a.amount == 0 }
end
adjustments
end
def display_checkout_taxes_hash
totals = OrderTaxAdjustmentsFetcher.new(nil).totals(all_tax_adjustments)
totals.map do |tax_rate, tax_amount|
{
amount: Spree::Money.new(tax_amount, currency: order.currency),
percentage: number_to_percentage(tax_rate.amount * 100, precision: 1),
rate_amount: tax_rate.amount,
}
end.sort_by { |tax| tax[:rate_amount] }
end
def all_tax_adjustments
all_eligible_adjustments.select { |a| a.originator_type == 'Spree::TaxRate' }
end
def invoice_date
date
end
def paid?
data[:payment_state] == 'paid' || data[:payment_state] == 'credit_owed'
end
def outstanding_balance?
!new_outstanding_balance.zero?
end
def new_outstanding_balance
if state.in?(FINALIZED_NON_SUCCESSFUL_STATES)
-payment_total
else
total - payment_total
end
end
def outstanding_balance_label
new_outstanding_balance.negative? ? I18n.t(:credit_owed) : I18n.t(:balance_due)
end
def last_payment
payments.max_by(&:created_at)
end
def last_payment_method
last_payment&.payment_method
end
def display_outstanding_balance
Spree::Money.new(new_outstanding_balance, currency: currency)
end
def display_checkout_tax_total
Spree::Money.new(total_tax, currency: currency)
end
def display_checkout_total_less_tax
Spree::Money.new(total - total_tax, currency: currency)
end
def display_total
Spree::Money.new(total, currency: currency)
end
end
end

View File

@@ -0,0 +1,34 @@
# frozen_string_literal: false
class Invoice
class DataPresenter
class Address < Invoice::DataPresenter::Base
attributes :firstname, :lastname, :address1, :address2, :city, :zipcode, :company, :phone
attributes_with_presenter :state
invoice_generation_attributes :firstname, :lastname, :address1, :address2, :city, :zipcode,
:company, :phone
def full_name
"#{firstname} #{lastname}".strip
end
def address_part1
render_address([address1, address2])
end
def address_part2
render_address([city, zipcode, state&.name])
end
def full_address
render_address([address1, address2, city, zipcode, state&.name])
end
private
def render_address(address_parts)
address_parts.compact_blank.join(', ')
end
end
end
end

View File

@@ -0,0 +1,28 @@
# frozen_string_literal: false
class Invoice
class DataPresenter
class Adjustment < Invoice::DataPresenter::Base
attributes :additional_tax_total, :adjustable_type, :amount, :currency, :included_tax_total,
:label, :originator_type
invoice_generation_attributes :additional_tax_total, :adjustable_type, :amount,
:included_tax_total
invoice_update_attributes :label
def display_amount
Spree::Money.new(amount, currency: currency)
end
def display_taxes(display_zero: false)
if included_tax_total.positive?
amount = Spree::Money.new(included_tax_total, currency: currency)
I18n.t(:tax_amount_included, amount: amount)
elsif additional_tax_total.positive?
Spree::Money.new(additional_tax_total, currency: currency)
elsif display_zero
Spree::Money.new(0.00, currency: currency)
end
end
end
end
end

View File

@@ -0,0 +1,14 @@
# frozen_string_literal: false
class Invoice
class DataPresenter
class Base
attr_reader :data
def initialize(data)
@data = data
end
extend Invoice::DataPresenterAttributes
end
end
end

View File

@@ -0,0 +1,8 @@
# frozen_string_literal: false
class Invoice
class DataPresenter
class BillAddress < Invoice::DataPresenter::Address
end
end
end

View File

@@ -0,0 +1,8 @@
# frozen_string_literal: false
class Invoice
class DataPresenter
class BusinessAddress < Invoice::DataPresenter::Address
end
end
end

View File

@@ -0,0 +1,9 @@
# frozen_string_literal: false
class Invoice
class DataPresenter
class Contact < Invoice::DataPresenter::Base
attributes :name, :email
end
end
end

View File

@@ -0,0 +1,9 @@
# frozen_string_literal: false
class Invoice
class DataPresenter
class Customer < Invoice::DataPresenter::Base
attributes :code, :email
end
end
end

View File

@@ -0,0 +1,14 @@
# frozen_string_literal: false
class Invoice
class DataPresenter
class Distributor < Invoice::DataPresenter::Base
attributes :name, :abn, :acn, :logo_url, :display_invoice_logo, :invoice_text, :email_address
attributes_with_presenter :contact, :address, :business_address
def display_invoice_logo?
display_invoice_logo == true
end
end
end
end

View File

@@ -0,0 +1,33 @@
# frozen_string_literal: false
class Invoice
class DataPresenter
class LineItem < Invoice::DataPresenter::Base
attributes :added_tax, :currency, :included_tax, :price_with_adjustments, :quantity,
:variant_id
attributes_with_presenter :variant
invoice_generation_attributes :added_tax, :included_tax, :price_with_adjustments,
:quantity, :variant_id
delegate :name_to_display, :options_text, to: :variant
def display_amount_with_adjustments
Spree::Money.new((price_with_adjustments * quantity), currency: currency)
end
def single_display_amount_with_adjustments
Spree::Money.new(price_with_adjustments, currency: currency)
end
def display_line_items_taxes(display_zero: true)
if included_tax.positive?
Spree::Money.new( included_tax, currency: currency)
elsif added_tax.positive?
Spree::Money.new( added_tax, currency: currency)
elsif display_zero
Spree::Money.new(0.00, currency: currency)
end
end
end
end
end

View File

@@ -0,0 +1,9 @@
# frozen_string_literal: false
class Invoice
class DataPresenter
class OrderCycle < Invoice::DataPresenter::Base
attributes :name
end
end
end

View File

@@ -0,0 +1,25 @@
# frozen_string_literal: false
class Invoice
class DataPresenter
class Payment < Invoice::DataPresenter::Base
attributes :amount, :currency, :state, :payment_method_id
attributes_with_presenter :payment_method
invoice_generation_attributes :amount, :payment_method_id
invoice_update_attributes :state
def created_at
datetime = data&.[](:created_at)
datetime.present? ? Time.zone.parse(datetime) : nil
end
def display_amount
Spree::Money.new(amount, currency: currency)
end
def payment_method_name
payment_method&.name
end
end
end
end

View File

@@ -0,0 +1,10 @@
# frozen_string_literal: false
class Invoice
class DataPresenter
class PaymentMethod < Invoice::DataPresenter::Base
attributes :id, :name, :description
invoice_generation_attributes :id
end
end
end

View File

@@ -0,0 +1,10 @@
# frozen_string_literal: false
class Invoice
class DataPresenter
class Product < Invoice::DataPresenter::Base
attributes :name
attributes_with_presenter :supplier
end
end
end

View File

@@ -0,0 +1,8 @@
# frozen_string_literal: false
class Invoice
class DataPresenter
class ShipAddress < Invoice::DataPresenter::Address
end
end
end

View File

@@ -0,0 +1,10 @@
# frozen_string_literal: false
class Invoice
class DataPresenter
class ShippingMethod < Invoice::DataPresenter::Base
attributes :id, :name, :require_ship_address
invoice_generation_attributes :id
end
end
end

View File

@@ -0,0 +1,9 @@
# frozen_string_literal: false
class Invoice
class DataPresenter
class State < Invoice::DataPresenter::Base
attributes :name
end
end
end

View File

@@ -0,0 +1,9 @@
# frozen_string_literal: false
class Invoice
class DataPresenter
class Supplier < Invoice::DataPresenter::Base
attributes :name
end
end
end

View File

@@ -0,0 +1,16 @@
# frozen_string_literal: false
class Invoice
class DataPresenter
class Variant < Invoice::DataPresenter::Base
attributes :id, :display_name, :options_text
attributes_with_presenter :product
def name_to_display
return product.name if display_name.blank?
display_name
end
end
end
end

View File

@@ -0,0 +1,59 @@
# frozen_string_literal: true
class Invoice
module DataPresenterAttributes
extend ActiveSupport::Concern
def attributes(*attributes, prefix: nil)
attributes.each do |attribute|
define_method([prefix, attribute].compact_blank.join("_")) do
data&.[](attribute)
end
end
end
def attributes_with_presenter(*attributes)
attributes.each do |attribute|
define_method(attribute) do
instance_variable = instance_variable_get("@#{attribute}")
return instance_variable if instance_variable
instance_variable_set("@#{attribute}",
Invoice::DataPresenter.const_get(
attribute.to_s.classify
).new(data&.[](attribute)))
end
end
end
def array_attribute(attribute_name, class_name: nil)
define_method(attribute_name) do
instance_variable = instance_variable_get("@#{attribute_name}")
return instance_variable if instance_variable
instance_variable_set("@#{attribute_name}",
data&.[](attribute_name)&.map { |item|
Invoice::DataPresenter.const_get(class_name).new(item)
})
end
end
# if one of the list attributes is updated, the invoice needs to be regenerated
def invoice_generation_attributes(*attributes)
define_method(:invoice_generation_values) do
attributes.map do |attribute|
public_send(attribute)
end
end
end
# if one of the list attributes is updated, the invoice needs to be updated
def invoice_update_attributes(*attributes)
define_method(:invoice_update_values) do
attributes.map do |attribute|
public_send(attribute)
end
end
end
end
end

View File

@@ -55,7 +55,6 @@ module ProductImport
VariantOverride.for_hubs([enterprise_id]).count
else
Spree::Variant.
not_master.
joins(:product).
where('spree_products.supplier_id IN (?)', enterprise_id).
count

View File

@@ -11,7 +11,12 @@ module ProductImport
include ActiveModel::Validations
attr_accessor :line_number, :valid, :validates_as, :product_object, :product_validations,
:on_hand_nil, :has_overrides, :units, :unscaled_units, :unit_type, :tax_category, :shipping_category, :id, :product_id, :producer, :producer_id, :distributor, :distributor_id, :name, :display_name, :sku, :unit_value, :unit_description, :variant_unit, :variant_unit_scale, :variant_unit_name, :display_as, :category, :primary_taxon_id, :price, :on_hand, :on_demand, :tax_category_id, :shipping_category_id, :description, :import_date, :enterprise, :enterprise_id
:on_hand_nil, :has_overrides, :units, :unscaled_units, :unit_type, :tax_category,
:shipping_category, :id, :product_id, :producer, :producer_id, :distributor,
:distributor_id, :name, :display_name, :sku, :unit_value, :unit_description,
:variant_unit, :variant_unit_scale, :variant_unit_name, :display_as, :category,
:primary_taxon_id, :price, :on_hand, :on_demand, :tax_category_id,
:shipping_category_id, :description, :import_date, :enterprise, :enterprise_id
NON_DISPLAY_ATTRIBUTES = ['id', 'product_id', 'unscaled_units', 'variant_id', 'enterprise',
'enterprise_id', 'producer_id', 'distributor_id', 'primary_taxon',
@@ -68,7 +73,11 @@ module ProductImport
def invalid_attributes
invalid_attrs = {}
errors = @product_validations ? @product_validations.messages.merge(self.errors.messages) : self.errors.messages
errors = if @product_validations
@product_validations.messages.merge(self.errors.messages)
else
self.errors.messages
end
errors.each do |attr, message|
invalid_attrs[attr.to_s] = "#{attr.to_s.capitalize} #{message.first}"
end

View File

@@ -73,11 +73,13 @@ module ProductImport
end
def units_and_unit_type_present?
@attrs.key?('units') && @attrs.key?('unit_type') && @attrs['units'].present? && @attrs['unit_type'].present?
@attrs.key?('units') && @attrs.key?('unit_type') && @attrs['units'].present? &&
@attrs['unit_type'].present?
end
def units_and_variant_unit_name_present?
@attrs.key?('units') && @attrs.key?('variant_unit_name') && @attrs['units'].present? && @attrs['variant_unit_name'].present?
@attrs.key?('units') && @attrs.key?('variant_unit_name') && @attrs['units'].present? &&
@attrs['variant_unit_name'].present?
end
def valid_unit_type?(unit_type)

View File

@@ -17,7 +17,8 @@ class ProxyOrder < ApplicationRecord
scope :canceled, -> { where('proxy_orders.canceled_at IS NOT NULL') }
scope :not_canceled, -> { where('proxy_orders.canceled_at IS NULL') }
scope :placed_and_open, -> {
joins(:order).not_closed.where(spree_orders: { state: ['complete', 'resumed'] })
joins(:order).not_closed
.where(spree_orders: { state: ['complete', 'resumed'] })
}
def state

View File

@@ -8,7 +8,8 @@ class Schedule < ApplicationRecord
has_many :coordinators, -> { distinct }, through: :order_cycles
scope :with_coordinator, lambda { |enterprise|
joins(:order_cycles).where('coordinator_id = ?', enterprise.id).select('DISTINCT schedules.*')
joins(:order_cycles).where('coordinator_id = ?', enterprise.id)
.select('DISTINCT schedules.*')
}
def current_or_next_order_cycle

View File

@@ -67,6 +67,8 @@ module Spree
scope :charge, -> { where('amount >= 0') }
scope :credit, -> { where('amount < 0') }
scope :return_authorization, -> { where(originator_type: "Spree::ReturnAuthorization") }
scope :voucher, -> { where(originator_type: "Voucher") }
scope :non_voucher, -> { where.not(originator_type: "Voucher") }
scope :inclusive, -> { where(included: true) }
scope :additional, -> { where(included: false) }
scope :legacy_tax, -> { additional.tax.where(adjustable_type: "Spree::Order") }

View File

@@ -75,7 +75,8 @@ module Spree
preference :attachment_url, :string,
default: '/spree/products/:id/:style/:basename.:extension'
preference :attachment_styles, :string,
default: "{\"mini\":\"48x48>\",\"small\":\"100x100>\",\"product\":\"240x240>\",\"large\":\"600x600>\"}"
default: "{\"mini\":\"48x48>\",\"small\":\"100x100>\"," \
"\"product\":\"240x240>\",\"large\":\"600x600>\"}"
preference :attachment_default_style, :string, default: 'product'
preference :s3_access_key, :string
preference :s3_bucket, :string

View File

@@ -91,7 +91,7 @@ module Spree
stripe_account: stripe_account_id)
gateway_options[:stripe_account] = stripe_account_id
# If a payment has been confirmed it cannot be voided by Stripe, and must be refunded instead
# If a payment has been confirmed it can't be voided by Stripe, and must be refunded instead
if voidable?(payment_intent_response)
provider.void(response_code, gateway_options)
else

View File

@@ -31,10 +31,10 @@ module Spree
def url(size)
return self.class.default_image_url(size) unless attachment.attached?
return variant(size).processed.url if attachment.service.name == :amazon_public
url_for(variant(size))
image_variant_url_for(variant(size))
rescue ActiveStorage::Error => e
Bugsnag.notify "Product ##{viewable_id} Image ##{id} error: #{e.message}"
Rails.logger.error(e.message)
self.class.default_image_url(size)

View File

@@ -68,6 +68,7 @@ module Spree
},
class_name: 'Spree::Adjustment',
dependent: :destroy
has_many :invoices
belongs_to :order_cycle
belongs_to :distributor, class_name: 'Enterprise'
@@ -86,15 +87,6 @@ module Spree
delegate :create_line_item_fees!, :create_order_fees!, :update_order_fees!,
:update_line_item_fees!, :recreate_all_fees!, to: :fee_handler
# Needs to happen before save_permalink is called
before_validation :set_currency
before_validation :generate_order_number, if: :new_record?
before_validation :clone_billing_address, if: :use_billing?
before_validation :ensure_customer
before_create :link_by_email
after_create :create_tax_charge!
validates :customer, presence: true, if: :require_customer?
validate :products_available_from_new_distribution, if: lambda {
distributor_id_changed? || order_cycle_id_changed?
@@ -107,16 +99,25 @@ module Spree
validates :order_cycle, presence: true, on: :require_distribution
validates :distributor, presence: true, on: :require_distribution
make_permalink field: :number
before_validation :set_currency
before_validation :generate_order_number, if: :new_record?
before_validation :clone_billing_address, if: :use_billing?
before_validation :ensure_customer
before_create :link_by_email
before_save :update_shipping_fees!, if: :complete?
before_save :update_payment_fees!, if: :complete?
after_create :create_tax_charge!
after_save :reapply_tax_on_changed_address
after_save_commit DefaultAddressUpdater
make_permalink field: :number
attribute :send_cancellation_email, type: :boolean, default: true
attribute :restock_items, type: :boolean, default: true
# -- Scopes
scope :not_empty, -> {
left_outer_joins(:line_items).where.not(spree_line_items: { id: nil })
}
@@ -145,9 +146,7 @@ module Spree
}
scope :with_line_items_variants_and_products_outer, lambda {
joins('LEFT OUTER JOIN spree_line_items ON (spree_line_items.order_id = spree_orders.id)').
joins('LEFT OUTER JOIN spree_variants ON (spree_variants.id = spree_line_items.variant_id)').
joins('LEFT OUTER JOIN spree_products ON (spree_products.id = spree_variants.product_id)')
left_outer_joins(line_items: { variant: :product })
}
# All the states an order can be in after completing the checkout
@@ -171,6 +170,11 @@ module Spree
line_items.inject(0.0) { |sum, li| sum + li.amount }
end
# Order total without any applied discounts from vouchers
def pre_discount_total
item_total + all_adjustments.additional.eligible.non_voucher.sum(:amount)
end
def currency
self[:currency] || Spree::Config[:currency]
end
@@ -317,12 +321,13 @@ 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"])
return if before_payment_state?
clear_legacy_taxes!
Spree::TaxRate.adjust(self, line_items)
Spree::TaxRate.adjust(self, shipments) if shipments.any?
Spree::TaxRate.adjust(self, adjustments.admin) if adjustments.admin.any?
fee_handler.tax_enterprise_fees!
end
@@ -574,8 +579,20 @@ module Spree
end
end
def before_payment_state?
state.in?(["cart", "address", "delivery"])
end
private
def reapply_tax_on_changed_address
return if before_payment_state?
return unless tax_address&.saved_changes?
create_tax_charge!
update_totals_and_states
end
def deliver_order_confirmation_email
return if subscription.present?

View File

@@ -77,7 +77,10 @@ module Spree
before_transition to: :delivery, do: :ensure_available_shipping_rates
before_transition to: :confirmation, do: :validate_payment_method!
after_transition to: :payment, do: :create_tax_charge!
after_transition to: :payment do |order|
order.create_tax_charge!
order.update_totals_and_states
end
after_transition to: :complete, do: :finalize!
after_transition to: :resumed, do: :after_resume
after_transition to: :canceled, do: :after_cancel
@@ -144,7 +147,7 @@ module Spree
private
def after_cancel
shipments.each(&:cancel!)
shipments.reject(&:canceled?).each(&:cancel!)
payments.checkout.each(&:void!)
OrderMailer.cancel_email(id).deliver_later if send_cancellation_email

View File

@@ -36,15 +36,17 @@ module Spree
return val
end
# If it's not in the cache, maybe it's in the database, but
# has been cleared from the cache
# If it's not in the cache, maybe it's in the database, but has been cleared from the cache
# does it exist in the database?
if should_persist? && (Spree::Preference.table_exists? && preference = Spree::Preference.find_by(key: key))
# it does exist, so let's put it back into the cache
@cache.write(preference.key, preference.value)
if should_persist? && Spree::Preference.table_exists?
preference = Spree::Preference.find_by(key: key)
if preference
# it does exist, so let's put it back into the cache
@cache.write(preference.key, preference.value)
# and return the value
return preference.value
# and return the value
return preference.value
end
end
unless fallback.nil?

View File

@@ -23,47 +23,69 @@ require 'concerns/product_stock'
#
module Spree
class Product < ApplicationRecord
include PermalinkGenerator
include ProductStock
acts_as_paranoid
searchable_attributes :supplier_id, :primary_taxon_id, :meta_keywords
searchable_associations :supplier, :properties, :primary_taxon, :variants, :master
searchable_attributes :supplier_id, :primary_taxon_id, :meta_keywords, :sku
searchable_associations :supplier, :properties, :primary_taxon, :variants
searchable_scopes :active, :with_properties
has_many :product_properties, dependent: :destroy
has_many :properties, through: :product_properties
has_many :classifications, dependent: :delete_all
has_many :taxons, through: :classifications
belongs_to :tax_category, class_name: 'Spree::TaxCategory'
belongs_to :shipping_category, class_name: 'Spree::ShippingCategory'
belongs_to :supplier, class_name: 'Enterprise', touch: true
belongs_to :primary_taxon, class_name: 'Spree::Taxon', touch: true
has_one :master,
-> { where is_master: true },
class_name: 'Spree::Variant',
dependent: :destroy
has_one :image, class_name: "Spree::Image", as: :viewable, dependent: :destroy
has_many :variants, -> {
where(is_master: false).order("spree_variants.position ASC")
}, class_name: 'Spree::Variant'
has_many :variants_including_master,
-> { order("spree_variants.position ASC") },
class_name: 'Spree::Variant',
dependent: :destroy
has_many :product_properties, dependent: :destroy
has_many :properties, through: :product_properties
has_many :classifications, dependent: :delete_all
has_many :taxons, through: :classifications
has_many :variants, -> { order("spree_variants.position ASC") }, class_name: 'Spree::Variant',
dependent: :destroy
has_many :prices, -> {
order('spree_variants.position, spree_variants.id, currency')
}, through: :variants
has_many :stock_items, through: :variants
has_many :supplier_properties, through: :supplier, source: :properties
has_many :variant_images, -> { order(:position) }, source: :images,
through: :variants
validates :name, presence: true
validates :shipping_category, presence: true
validates :supplier, presence: true
validates :primary_taxon, presence: true
validates :tax_category, presence: true,
if: proc { Spree::Config[:products_require_tax_category] }
validates :variant_unit, presence: true
validates :unit_value, presence:
{ if: ->(p) { %w(weight volume).include?(p.variant_unit) && new_record? } }
validates :variant_unit_scale,
presence: { if: ->(p) { %w(weight volume).include? p.variant_unit } }
validates :variant_unit_name,
presence: { if: ->(p) { p.variant_unit == 'items' } }
validate :validate_image
accepts_nested_attributes_for :variants, allow_destroy: true
accepts_nested_attributes_for :image
accepts_nested_attributes_for :product_properties,
allow_destroy: true,
reject_if: lambda { |pp| pp[:property_name].blank? }
# Transient attributes used temporarily when creating a new product,
# these values are persisted on the product's variant
attr_accessor :price, :display_as, :unit_value, :unit_description
before_save :add_primary_taxon_to_taxons
after_save :remove_previous_primary_taxon_from_taxons
after_create :ensure_standard_variant
after_save :update_units
scope :with_properties, ->(*property_ids) {
left_outer_joins(:product_properties).
@@ -75,58 +97,6 @@ module Spree
)
}
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
delegate :images_attributes=, :display_as=, to: :master
after_create :set_master_variant_defaults
after_save :save_master
delegate :images, to: :master, prefix: true
alias_method :images, :master_images
has_many :variant_images, -> { order(:position) }, source: :images,
through: :variants_including_master
accepts_nested_attributes_for :variants, allow_destroy: true
validates :name, presence: true
validates :permalink, presence: true
validates :price, presence: true, if: proc { Spree::Config[:require_master_price] }
validates :shipping_category, presence: true
validates :supplier, presence: true
validates :primary_taxon, presence: true
validates :tax_category, presence: true,
if: proc { Spree::Config[:products_require_tax_category] }
validates :variant_unit, presence: true
validates :unit_value, presence: { if: ->(p) { %w(weight volume).include? p.variant_unit } }
validates :variant_unit_scale,
presence: { if: ->(p) { %w(weight volume).include? p.variant_unit } }
validates :variant_unit_name,
presence: { if: ->(p) { p.variant_unit == 'items' } }
validate :validate_image_for_master
accepts_nested_attributes_for :product_properties,
allow_destroy: true,
reject_if: lambda { |pp| pp[:property_name].blank? }
make_permalink order: :name
after_initialize :ensure_master
after_initialize :set_available_on_to_now, if: :new_record?
before_validation :sanitize_permalink
before_save :add_primary_taxon_to_taxons
after_save :remove_previous_primary_taxon_from_taxons
after_save :ensure_standard_variant
after_save :update_units
before_destroy :punch_permalink
# -- Joins
scope :with_order_cycles_outer, -> {
joins("
LEFT OUTER JOIN spree_variants AS o_spree_variants
@@ -150,7 +120,7 @@ module Spree
}
scope :with_order_cycles_inner, -> {
joins(variants_including_master: { exchanges: :order_cycle })
joins(variants: { exchanges: :order_cycle })
}
scope :visible_for, lambda { |enterprise|
@@ -229,18 +199,12 @@ module Spree
return where('spree_products.supplier_id IN (?)', [enterprise.id] | permitted_producer_ids)
}
scope :active, lambda {
where("spree_products.deleted_at IS NULL AND spree_products.available_on <= ?", Time.zone.now)
}
scope :active, lambda { where("spree_products.deleted_at IS NULL") }
def self.group_by_products_id
group(column_names.map { |col_name| "#{table_name}.#{col_name}" })
end
def to_param
permalink.present? ? permalink : (permalink_was || UrlGenerator.to_url(name))
end
def tax_category
if self[:tax_category_id].nil?
TaxCategory.find_by(is_default: true)
@@ -283,13 +247,6 @@ module Spree
stock_items.sum(&:count_on_hand)
end
# Master variant may be deleted (i.e. when the product is deleted)
# which would make AR's default finder return nil.
# This is a stopgap for that little problem.
def master
super || variants_including_master.with_deleted.find_by(is_master: true)
end
def properties_including_inherited
# Product properties override producer properties
ps = product_properties.all
@@ -325,7 +282,7 @@ module Spree
touch_distributors
ExchangeVariant.
where('exchange_variants.variant_id IN (?)', variants_including_master.with_deleted.
where('exchange_variants.variant_id IN (?)', variants.with_deleted.
select(:id)).destroy_all
super
@@ -334,52 +291,10 @@ module Spree
private
# ensures the master variant is flagged as such
def set_master_variant_defaults
master.is_master = true
end
# Here we rescue errors when saving master variants (without the need for a
# validates_associated on master) and we get more specific data about the errors
def save_master
if master && (
master.changed? || master.new_record? || (
master.default_price && (
master.default_price.changed? || master.default_price.new_record?
)
)
)
master.save!
end
# If the master cannot be saved, the Product object will get its errors
# and will be destroyed
rescue ActiveRecord::RecordInvalid
master.errors.each do |error|
errors.add error.attribute, error.message
end
raise
end
def ensure_master
return unless new_record?
self.master ||= Variant.new
end
def punch_permalink
# Punch permalink with date prefix
update_attribute :permalink, "#{Time.now.to_i}_#{permalink}"
end
def set_available_on_to_now
self.available_on ||= Time.zone.now
end
def update_units
return unless saved_change_to_variant_unit? || saved_change_to_variant_unit_name?
variants_including_master.each(&:update_units)
variants.each(&:update_units)
end
def touch_distributors
@@ -397,24 +312,19 @@ module Spree
end
def ensure_standard_variant
return unless master.valid? && variants.empty?
return unless variants.empty?
variant = master.dup
variant = Spree::Variant.new
variant.product = self
variant.is_master = false
variant.price = price
variant.display_as = display_as
variant.unit_value = unit_value
variant.unit_description = unit_description
variants << variant
end
# Spree creates a permalink already but our implementation fixes an edge case.
def sanitize_permalink
return unless permalink.blank? || saved_change_to_permalink? || permalink_changed?
requested = permalink.presence || permalink_was.presence || name.presence || 'product'
self.permalink = create_unique_permalink(requested.parameterize)
end
def validate_image_for_master
return if master.images.all?(&:valid?)
def validate_image
return if image.blank? || image.valid?
errors.add(:base, I18n.t('spree.admin.products.image_not_processable'))
end

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