Compare commits

...

158 Commits

Author SHA1 Message Date
Matt-Yorkley
74f27544f7 Merge pull request #7647 from andrewpbrett/default-country-codes
Use correct default country code
2021-05-25 11:21:34 +02:00
Matt-Yorkley
5868765087 Merge pull request #7673 from Matt-Yorkley/spree-config-caching
Fix clashing loggers
2021-05-25 11:09:33 +02:00
Maikel
545d64a2e5 Merge pull request #7682 from openfoodfoundation/dependabot/bundler/i18n-js-3.8.3
Bump i18n-js from 3.8.2 to 3.8.3
2021-05-25 14:48:19 +10:00
Matt-Yorkley
c69dee4c96 Merge pull request #7636 from psychoslave/tip/zeus
Remove all material related to Zeus
2021-05-25 00:10:01 +02:00
Andy Brett
b367001b95 Merge pull request #7641 from luisramos0/order_path
[Rails 6.1] Fix view specs
2021-05-24 14:41:32 -07:00
Andy Brett
120fc4ca42 Merge pull request #7605 from filipefurtad0/import_item_products
Products and Inventory import: Items units
2021-05-24 14:17:43 -07:00
Andy Brett
e4756a523a Merge pull request #7678 from mkllnk/schema
Update schema syntax with Rails 5.2
2021-05-24 13:22:18 -07:00
Andy Brett
46843a5efa Merge pull request #7662 from Matt-Yorkley/enterprise-rendering
Render enterprise rows as a collection
2021-05-24 09:37:58 -07:00
Matt-Yorkley
6377736f43 Allow :site_url to be picked up from ENV vars 2021-05-24 14:58:53 +01:00
dependabot[bot]
e90403dbbe Bump i18n-js from 3.8.2 to 3.8.3
Bumps [i18n-js](https://github.com/fnando/i18n-js) from 3.8.2 to 3.8.3.
- [Release notes](https://github.com/fnando/i18n-js/releases)
- [Changelog](https://github.com/fnando/i18n-js/blob/main/CHANGELOG.md)
- [Commits](https://github.com/fnando/i18n-js/compare/v3.8.2...v3.8.3)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-24 05:49:51 +00:00
Matt-Yorkley
3dc3581e6b Ensure Mail configs are applied when the app starts
Previously we only set these part-way through deployment, so the values could be out of sync between our ENV vars and Spree::Config (which itself is a mix of both cached values and database-persisted values).
2021-05-23 23:05:16 +01:00
Matt-Yorkley
ff82f70e9a Remove custom logger object
This is handled already in Delayed::Command and Delayed::Worker
2021-05-23 23:05:16 +01:00
Andy Brett
560f462f7b Merge pull request #7679 from mkllnk/sample-data
Fix sample_data by filtering params for products
2021-05-22 10:37:30 -07:00
Pau Pérez Fabregat
23b2b5ba56 Merge pull request #7563 from filipefurtad0/import_products_fixture_path
Adds file and fixture path to test product import
2021-05-21 10:12:20 +02:00
Maikel Linke
11cb8cbbdc Fix sample_data by filtering params for products
We were passing too many parameters to the product creation. Rails 5.2
complained that products don't have a distributor. Filtering the
parameters helps.
2021-05-21 12:41:55 +10:00
Maikel Linke
41799b2663 Update schema syntax with Rails 5.2
The style seems to be different. This avoids a modified schema after
running rake db:migrate.
2021-05-21 11:50:34 +10:00
filipefurtad0
2f842bcbdd Adds file and fixture path to test product import
Adds file and fixture path to test product import

Reverts changes on context and it descriptions
2021-05-20 20:08:47 +01:00
Matt-Yorkley
336a8b5825 Merge pull request #7671 from Matt-Yorkley/licence
Add Spree copyright notice
2021-05-20 18:56:16 +02:00
Andy Brett
d2f54f5bd2 Merge pull request #7666 from mkllnk/codecov
Stop Codecov failing good pull requests
2021-05-20 09:18:34 -07:00
Pau Pérez Fabregat
8c81c14c8d Merge pull request #7580 from apricot12/Remove-LineItems-N+1
Removed N+1 queries while counting line_items
2021-05-20 11:42:14 +02:00
Matt-Yorkley
1f6d872fa5 Add Spree copyright notice 2021-05-20 10:25:48 +01:00
Jean-Baptiste Bellet
ae1b9b8dd5 Update all locales with the latest Transifex translations 2021-05-20 10:12:46 +02:00
Maikel
1e1706d371 Merge pull request #7280 from Matt-Yorkley/atomic
Remove atomic gem
2021-05-20 17:53:36 +10:00
Maikel Linke
5ccaa521cf Stop Codecov failing good pull requests
Something doesn't quite work with our Codecov setup. It somehow thinks
that the coverage is decreasing even though it's either not changing or
even increasing.

Until those problems are resolved, let's not mark pull requests as
failed so that we can rely on the pull's overall status report.
2021-05-20 14:18:43 +10:00
Maikel Linke
90bb9870ab Bump Codecov from 1.3.1 to 1.5.0 2021-05-20 14:17:36 +10:00
Andy Brett
70ac719725 Merge pull request #7649 from andrewpbrett/payments-when-out-of-stock
Check stock before doing anything related to admin payments
2021-05-19 14:45:38 -07:00
Andy Brett
08d540a761 Merge pull request #7648 from Matt-Yorkley/redis
Switch cache store from memcached to redis
2021-05-19 10:36:20 -07:00
Andy Brett
304a3804bc Merge pull request #7594 from luisramos0/update_attributes
[Rails 6.1] Replace AR's update_attributes! with update! (and rename order.update! and adjustment.update! in the process)
2021-05-19 10:34:12 -07:00
Luis Ramos
f7726e552a Adapt code coming from master to the new order api with update_order! 2021-05-19 10:09:42 -07:00
Luis Ramos
a1ac4e85ed Replace update_attributes with update 2021-05-19 09:54:25 -07:00
Luis Ramos
f8e5370b0b Replace update_attributes with update 2021-05-19 09:54:25 -07:00
Luis Ramos
fb560089b9 Replace usages of update_attributes! with usage of update! 2021-05-19 09:54:25 -07:00
Luis Ramos
341f6c9f62 Now that adjustment.update! has been renamed to adjustment.update_adjustment! we can use AR's update! on adjustment 2021-05-19 09:54:25 -07:00
Luis Ramos
b2e97fe1d2 Rename order.update! to order.update_order! and adjustment.update! to adjustment.update_adjustment! 2021-05-19 09:54:22 -07:00
Andy Brett
e73584fef7 remove setters from DefaultCountry service 2021-05-19 09:42:52 -07:00
Andy Brett
45ad4bbcf1 remove setting of Spree::Config country code 2021-05-19 09:33:02 -07:00
Matt-Yorkley
096847ea07 Merge pull request #7618 from openfoodfoundation/dependabot/npm_and_yarn/hosted-git-info-2.8.9
Bump hosted-git-info from 2.8.8 to 2.8.9
2021-05-19 13:51:01 +02:00
Pau Pérez Fabregat
faf6a37c9f Merge pull request #7631 from openfoodfoundation/dependabot/bundler/ddtrace-0.49.0
Bump ddtrace from 0.48.0 to 0.49.0
2021-05-19 12:32:52 +02:00
Pau Pérez Fabregat
d4ec1bda54 Merge pull request #7652 from openfoodfoundation/dependabot/bundler/webmock-3.13.0
Bump webmock from 3.12.2 to 3.13.0
2021-05-19 12:32:08 +02:00
Pau Pérez Fabregat
5560a99423 Merge pull request #7663 from openfoodfoundation/transifex
Transifex
2021-05-19 11:50:02 +02:00
Matt-Yorkley
0c4e191f3b Render enterprise rows as a collection
Note: this is a bit like an N+1 query, but for rendering. If there are 30 enterprises, the partial file would be loaded and parsed 30 times; but if we render it as a collection it'll load the partial once and substantially improve the performance.
2021-05-19 08:48:25 +01:00
Andy Brett
2bb38619ea Merge pull request #7656 from openfoodfoundation/dependabot/bundler/rubocop-1.15.0
Bump rubocop from 1.14.0 to 1.15.0
2021-05-18 13:36:56 -07:00
Andy Brett
4b352da402 Merge pull request #7630 from apricot12/persistent_flash_after_reload
Persistent flash after reload
2021-05-18 12:55:37 -07:00
Transifex-Openfoodnetwork
75243b8e6a Updating translations for config/locales/en_US.yml 2021-05-19 05:54:38 +10:00
Andy Brett
7df2915fbd add DefaultCountry service 2021-05-18 12:44:53 -07:00
Matt-Yorkley
6427a3846b Merge pull request #7651 from openfoodfoundation/dependabot/bundler/activerecord-import-1.1.0
Bump activerecord-import from 1.0.8 to 1.1.0
2021-05-18 20:06:21 +02:00
Andy Brett
5169ee91ea add comment for before_action 2021-05-18 10:42:19 -07:00
Andy Brett
5917accdd2 refactor using Extract Method 2021-05-18 10:38:35 -07:00
Matt-Yorkley
5dd24623f7 Merge pull request #7479 from Matt-Yorkley/payment-callbacks
Update Payment after_save callback
2021-05-18 16:19:29 +02:00
Matt-Yorkley
befb6f632f Merge pull request #7659 from openfoodfoundation/dependabot/bundler/nokogiri-1.11.4
Bump nokogiri from 1.11.3 to 1.11.4
2021-05-18 11:14:32 +02:00
dependabot[bot]
92e0f8349c Bump nokogiri from 1.11.3 to 1.11.4
Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.11.3 to 1.11.4.
- [Release notes](https://github.com/sparklemotion/nokogiri/releases)
- [Changelog](https://github.com/sparklemotion/nokogiri/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.11.3...v1.11.4)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-18 08:37:29 +00:00
dependabot[bot]
ffbba01c41 Bump rubocop from 1.14.0 to 1.15.0
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.14.0 to 1.15.0.
- [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.14.0...v1.15.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-18 05:24:48 +00:00
Pau Pérez Fabregat
5f9679655c Merge pull request #7645 from Matt-Yorkley/stripe-payment-processing
Stripe payment processing
2021-05-17 16:17:21 +02:00
dependabot[bot]
6ded80d2c6 Bump webmock from 3.12.2 to 3.13.0
Bumps [webmock](https://github.com/bblimke/webmock) from 3.12.2 to 3.13.0.
- [Release notes](https://github.com/bblimke/webmock/releases)
- [Changelog](https://github.com/bblimke/webmock/blob/master/CHANGELOG.md)
- [Commits](https://github.com/bblimke/webmock/compare/v3.12.2...v3.13.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-17 05:51:55 +00:00
dependabot[bot]
eb3c33b091 Bump activerecord-import from 1.0.8 to 1.1.0
Bumps [activerecord-import](https://github.com/zdennis/activerecord-import) from 1.0.8 to 1.1.0.
- [Release notes](https://github.com/zdennis/activerecord-import/releases)
- [Changelog](https://github.com/zdennis/activerecord-import/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zdennis/activerecord-import/compare/v1.0.8...v1.1.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-17 05:51:01 +00:00
Matt-Yorkley
794216713a Ensure payment is processed if order is in completed state 2021-05-16 23:03:07 +01:00
Matt-Yorkley
a2862e604c Find relevant payment that matches the payment intent, not the last payment 2021-05-16 23:00:31 +01:00
Matt-Yorkley
8429da3d2a Remove unused argument from ProcessPaymentIntent 2021-05-16 22:19:01 +01:00
Matt-Yorkley
381b0e78d5 Improve ProcessPaymentIntent specs 2021-05-16 20:14:14 +01:00
Matt-Yorkley
2e63cd8116 Add explanatory comment on payment processing flow 2021-05-16 20:11:45 +01:00
Matt-Yorkley
52e0d84238 Reload in-memory payment before checking it's new state
The state should have changed in the database if the payment was processed successfully, and the memoized version here will not know that without a reload.
2021-05-16 20:11:45 +01:00
Matt-Yorkley
5725535715 Fix payment state checking 2021-05-16 20:11:45 +01:00
Matt-Yorkley
05ed98aa0c Use :order_with_totals in ProcessPaymentIntent
If we just use the :order factory here, it has no line items and no total, which means when we try to push it into complete state, the #requires_payment? check fails because the order total is zero, which means the call to #process_payments is ignored
2021-05-16 20:11:45 +01:00
Matt-Yorkley
fd021d4778 Refactor payment intent status checking and return "ok" if the payment has already been processed successfully in a previous request
If the page is reloaded after the payment has already gone through, we can skip the processing and give a non-error response; the payment is already completed and Stripe's response confirms it was successful.
2021-05-16 20:11:45 +01:00
Matt-Yorkley
2b9f9fce86 Fix flash session memory-effect when showing errors after payment processing
We're not doing a redirect after setting this flash message, so we need to ensure it's discarded after the current page load.
2021-05-16 20:11:45 +01:00
Matt-Yorkley
81aac442f2 Improve conditional in raise_if_not_in_capture_state 2021-05-16 20:11:45 +01:00
Matt-Yorkley
16e3af9b49 Update OrderController spec 2021-05-16 20:11:45 +01:00
Matt-Yorkley
227bdd7d4c Update ProcessPaymentIntent spec 2021-05-16 12:55:48 +01:00
Matt-Yorkley
471a7903f6 Update PaymentIntentValidator spec 2021-05-16 12:19:04 +01:00
Matt-Yorkley
37177e7207 Add test coverage to StripeSCA spec 2021-05-16 12:19:04 +01:00
Matt-Yorkley
5805104d13 Tidy up controller and add explanatory comment 2021-05-16 12:19:04 +01:00
Matt-Yorkley
e686a4f627 Move raising of errors when payment intent state != "requires_capture" out of PaymentIntentValidator service
When we're fetching the payment intent via PaymentIntentValidator in StripeSCA#purhcase (to capture it), we want it to fail loudly if it's not in "requires_capture" state. We're now also re-using the same PaymentIntentValidator service to check if payment processing was *successful*, in which case we need it *not* to fail loudly if the state == "succeeded", eg != "requires_capture".
2021-05-16 12:19:04 +01:00
Andy Brett
c7f80d86a8 Merge pull request #7638 from Matt-Yorkley/dead-code-order-distribution
Delete dead code in OrdersController#update_distribution
2021-05-15 12:40:25 -07:00
Andy Brett
19187583e1 Merge pull request #7643 from openfoodfoundation/dependabot/bundler/test-prof-1.0.5
Bump test-prof from 1.0.3 to 1.0.5
2021-05-15 12:28:22 -07:00
Andy Brett
f2c3b096a0 Merge pull request #7566 from luisramos0/erb
[Rails 6.0] Fix problem in erb template by explicitly setting format to js
2021-05-15 10:45:01 -07:00
Andy Brett
816d752dc8 Merge pull request #7439 from openfoodfoundation/dependabot/bundler/jwt-2.2.3
Bump jwt from 2.2.2 to 2.2.3
2021-05-15 10:36:13 -07:00
Andy Brett
0a880a2bf3 flip conditional order for performance 2021-05-15 07:08:07 -07:00
Matt-Yorkley
d6b3b0a3d3 Ensure a basic level of fault-tolerance on Redis connections
The default for reconnect_attempts is 0, which is not helpful! 1 is generally considered to be enough.
2021-05-15 11:36:19 +01:00
Andy Brett
ca38948e21 check stock before doing anything related to admin payments 2021-05-14 17:42:37 -07:00
Andy Brett
fe67c01e57 guard against no database, but not against .connected?
Similar to b22ce43efe
2021-05-14 12:56:24 -07:00
Matt-Yorkley
37053239c0 Switch cache store from memcached to redis 2021-05-14 20:46:13 +01:00
dependabot[bot]
2bb5a4b11f Bump test-prof from 1.0.3 to 1.0.5
Bumps [test-prof](https://github.com/test-prof/test-prof) from 1.0.3 to 1.0.5.
- [Release notes](https://github.com/test-prof/test-prof/releases)
- [Changelog](https://github.com/test-prof/test-prof/blob/master/CHANGELOG.md)
- [Commits](https://github.com/test-prof/test-prof/compare/v1.0.3...v1.0.5)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-14 05:17:23 +00:00
Maikel Linke
cea3ee4ef9 Transifex updates 2021-05-14 10:06:31 +10:00
Luis Ramos
90db52e5f5 Fix route 2021-05-14 00:14:02 +01:00
Luis Ramos
b1896733ca Fix routes 2021-05-14 00:08:20 +01:00
Luis Ramos
a949422ac9 Adapt view spec stubs to rails 6 2021-05-13 23:28:35 +01:00
Luis Ramos
0243e5cbb8 Fix route in order view 2021-05-13 23:08:50 +01:00
Andy Brett
ebdbfe0027 Merge pull request #7639 from drummer83/patch-1
Remove Ruby version from WIKI
2021-05-13 13:26:34 -07:00
Konrad
b680697af6 Remove Ruby version
Let's remove the Ruby version from the text. It changes regularly and have the link where to find it right behind it.
2021-05-13 21:16:02 +02:00
Matt-Yorkley
2e248744c0 Merge pull request #7520 from Matt-Yorkley/shipment-controller
Shipment controller: test coverage and improvements
2021-05-13 20:26:51 +02:00
Matt-Yorkley
82a6befce7 Delete dead code in OrdersController#update_distribution
I can't see any evidence that these params ever get sent to this action...
2021-05-13 15:29:53 +01:00
Mathieu Lovato Stumpf Guntz
ccef65039a Remove all material related to Zeus 2021-05-13 12:21:58 +02:00
dependabot[bot]
e4a670da5a Bump ddtrace from 0.48.0 to 0.49.0
Bumps [ddtrace](https://github.com/DataDog/dd-trace-rb) from 0.48.0 to 0.49.0.
- [Release notes](https://github.com/DataDog/dd-trace-rb/releases)
- [Changelog](https://github.com/DataDog/dd-trace-rb/blob/master/CHANGELOG.md)
- [Commits](https://github.com/DataDog/dd-trace-rb/compare/v0.48.0...v0.49.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-13 05:24:45 +00:00
Nihal Mohammed
c930b2ee60 Fix persistet flash after /cart page reload 2021-05-13 05:57:25 +05:30
Matt-Yorkley
4932e1dcb5 Merge pull request #7628 from viktorsmari/remove-distributer-sample-data
Remove distributer from sample_data
2021-05-12 23:53:13 +02:00
Viktor Smari
536281ec80 Remove distributer from sample_data
Closes #7625
2021-05-12 23:01:08 +02:00
Nihal Mohammed
367cee593f Move eager loading line_items to controller 2021-05-13 01:12:13 +05:30
Matt-Yorkley
99cf23df26 Merge pull request #7530 from Matt-Yorkley/email-after-commit
Email after commit
2021-05-12 21:22:55 +02:00
Matt-Yorkley
f49d4592a0 Merge pull request #7506 from guidoDutra/5546-prevent-deleting-only-item-in-confirmed-order
prevent deleting only item in confirmed order
2021-05-12 21:10:09 +02:00
Pau Pérez Fabregat
7f27544acb Merge pull request #7612 from openfoodfoundation/dependabot/bundler/actionpack-action_caching-1.2.2
Bump actionpack-action_caching from 1.2.1 to 1.2.2
2021-05-12 16:24:25 +02:00
Pau Pérez Fabregat
2aac44d95e Merge pull request #7620 from openfoodfoundation/transifex
Transifex
2021-05-12 15:50:25 +02:00
Pau Pérez Fabregat
8f921b8b08 Merge pull request #7593 from viktorsmari/add-bullet-footer
Add bullet footer
2021-05-12 15:47:54 +02:00
Transifex-Openfoodnetwork
dfe485b079 Updating translations for config/locales/ru.yml 2021-05-12 17:49:31 +10:00
dependabot[bot]
ad9096b5a8 Bump hosted-git-info from 2.8.8 to 2.8.9
Bumps [hosted-git-info](https://github.com/npm/hosted-git-info) from 2.8.8 to 2.8.9.
- [Release notes](https://github.com/npm/hosted-git-info/releases)
- [Changelog](https://github.com/npm/hosted-git-info/blob/v2.8.9/CHANGELOG.md)
- [Commits](https://github.com/npm/hosted-git-info/compare/v2.8.8...v2.8.9)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-11 23:49:14 +00:00
Matt-Yorkley
e60a513c88 Merge pull request #7571 from coopdevs/make-specs-accurate
Properly mock validator and extend tests
2021-05-11 22:24:01 +02:00
Pau Pérez Fabregat
1f8e731594 Merge pull request #7596 from openfoodfoundation/transifex
Transifex
2021-05-11 11:56:35 +02:00
dependabot[bot]
d69ef31bf9 Bump actionpack-action_caching from 1.2.1 to 1.2.2
Bumps [actionpack-action_caching](https://github.com/rails/actionpack-action_caching) from 1.2.1 to 1.2.2.
- [Release notes](https://github.com/rails/actionpack-action_caching/releases)
- [Changelog](https://github.com/rails/actionpack-action_caching/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rails/actionpack-action_caching/compare/v1.2.1...v1.2.2)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-11 05:05:32 +00:00
Andy Brett
9ae7c5efbc Merge pull request #7578 from psychoslave/master
Update things related to some package manager influencing setup process
2021-05-10 17:01:46 -07:00
Matt-Yorkley
902bbf7dc4 Merge pull request #7576 from Matt-Yorkley/bulk-line-items
Add test coverage to BulkLineItemsController actions
2021-05-11 01:47:17 +02:00
Andy Brett
d29ef0d7b1 Merge branch 'master' into make-specs-accurate 2021-05-10 16:10:33 -07:00
Andy Brett
d2a3d9049f Merge pull request #7588 from andrewpbrett/enterprise-permalink-spec
[Rails 6.0] Fix enterprise permalink spec
2021-05-10 15:30:45 -07:00
filipefurtad0
0cd6c53e0d Adds test-case on the inventory import for unit Items 2021-05-10 19:12:41 +01:00
filipefurtad0
5475b79cde Adds test-case on the product import unit Items 2021-05-10 19:07:05 +01:00
filipefurtad0
8e24c655b0 Adds verification of inventory import on inventory page 2021-05-10 19:01:41 +01:00
filipefurtad0
bb5452ad26 Adds verification of product import on products page 2021-05-10 18:57:47 +01:00
Matt-Yorkley
85b8e9b51f Merge pull request #7595 from openfoodfoundation/dependabot/bundler/factory_bot_rails-6.2.0
Bump factory_bot_rails from 6.1.0 to 6.2.0
2021-05-10 19:55:54 +02:00
Andy Brett
3239c893ba Merge pull request #7590 from viktorsmari/ransack-search-deprecation
Ransack.search is deprecated. Use .ransack instead
2021-05-10 08:43:09 -07:00
Andy Brett
17a0063b40 Merge pull request #7402 from filipefurtad0/products_spec_add_ons
Adds coverage for product deletion and cloning
2021-05-10 06:26:11 -07:00
Transifex-Openfoodnetwork
75dc7af0ed Updating translations for config/locales/en_GB.yml 2021-05-10 18:16:04 +10:00
dependabot[bot]
cb15e28cef Bump factory_bot_rails from 6.1.0 to 6.2.0
Bumps [factory_bot_rails](https://github.com/thoughtbot/factory_bot_rails) from 6.1.0 to 6.2.0.
- [Release notes](https://github.com/thoughtbot/factory_bot_rails/releases)
- [Changelog](https://github.com/thoughtbot/factory_bot_rails/blob/master/NEWS.md)
- [Commits](https://github.com/thoughtbot/factory_bot_rails/compare/v6.1.0...v6.2.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-10 05:55:18 +00:00
Andy Brett
cbefa5f882 Merge pull request #7589 from andrewpbrett/order-adjustments-spec
[Rails 6.0] Fix order adjustments spec
2021-05-09 10:38:19 -07:00
Andy Brett
231f01dad2 fix order adjustments spec 2021-05-09 10:09:22 -07:00
Viktor Smari
c14ccdc21c Add bullet footer
Left corner of the page will show the bullet warnings
2021-05-09 16:49:00 +02:00
Nihal Mohammed
fcf70c242e edit item_count method to shorthand for improved readability 2021-05-09 18:31:26 +05:30
Andy Brett
a0476be2c9 Merge pull request #7568 from andrewpbrett/stripe-mock-js
[Rails 6.0] Use raw to render stripe mock js file
2021-05-08 17:46:24 -07:00
Matt-Yorkley
24a5407c8f Merge pull request #7565 from luisramos0/rails6_success
[Rails 6.0] Replace be_success on test_response with status 200
2021-05-09 02:33:49 +02:00
Andy Brett
66da72ccc2 use raw to render stripe mock js 2021-05-08 17:29:38 -07:00
Viktor Smari
6a342ae368 Ransack.search is deprecated. Use .ransack instead
https://github.com/activerecord-hackery/ransack/pull/975
2021-05-09 01:05:37 +02:00
Andy Brett
dd851edbdc fix enterprise permalink spec 2021-05-08 14:21:45 -07:00
Nihal Mohammed
e485a4a8ef Remove untested change to payments 2021-05-08 23:51:38 +05:30
Nihal Mohammed
026942dd72 Fix item_count to properly count quantity of every item 2021-05-08 23:45:41 +05:30
Nihal Mohammed
237ebd6ec4 Removed N+1 queries while counting line_items 2021-05-08 21:09:06 +05:30
Mathieu Lovato Stumpf Guntz
a4d6e69309 Replace nmp with yarn, remove newrelic 2021-05-07 21:10:55 +02:00
Mathieu Lovato Stumpf Guntz
29e04dd8c8 Merge branch 'master' of https://github.com/openfoodfoundation/openfoodnetwork 2021-05-07 16:00:08 +02:00
Mathieu Lovato Stumpf Guntz
5a8e271037 Update .node-version to last LTS and drop setup tests 2021-05-07 15:54:15 +02:00
Matt-Yorkley
43e41f4980 Add more explicit test coverage to BulkLineItemsController acitons
This spec includes taxes on line items, fees on the order and on line items, taxes on fees (inherited and non-inherited), shipping and payment fees and taxes on shipping. It checks all of these things are correctly updated after the order is changed via BOM.
2021-05-07 11:54:04 +01:00
Pau Perez
fd5e0fd60f Properly mock validator and extend tests
Tests were passing but not due to the expected reason. While at it, we
extended the assertions to be more precise.
2021-05-07 08:35:54 +02:00
Luis Ramos
de000228cf Fix problem in erb template by explicitly setting format to js while calling it 2021-05-06 23:52:16 +01:00
Luis Ramos
a2de86c23e Replace be_success on test_reponse with status 200
In rails 6 response.success? is not supported.
2021-05-06 23:51:30 +01:00
Matt-Yorkley
00c4a28d22 Extract order-updating logic to Order::Updater 2021-05-04 16:40:10 +01:00
Matt-Yorkley
8e10f7af0e Update payments controller test setup
We need to use a completed order in the test setup here or it doesn't behave correctly. `order.completed_at` is nil, for example.
2021-05-04 16:40:10 +01:00
Matt-Yorkley
135a311c05 Update void payments
Backport from Spree 2.4 stable: 4121992398
2021-05-04 16:40:10 +01:00
Matt-Yorkley
13bb5aa8dd Update Payment after_save callback
Backport from Spree 2.4 stable: 4d652a77fd
2021-05-04 16:40:09 +01:00
filipefurtad0
a476416dc4 Removes html tr tag; Clarifies it block 2021-05-03 17:03:34 +01:00
filipefurtad0
19768e1398 adds coverage for product deletion and cloning 2021-05-02 18:33:13 +01:00
Matt-Yorkley
7c2d77a3ee Fix assertion in ModelSet test
The mismatched use of hash attributes as strings and hash attributes as symbols here (attrs['name'] and attrs[:name]) meant that the conditional was not returning the expected results in the test.
2021-05-02 13:42:38 +01:00
Matt-Yorkley
2560757ea2 Change Enterprise after_create callback to after_create_commit
As a general rule, if you're triggering an email job as part of an after create/save callback, it should use after commit instead.

Why? The transaction can't finish until after the record is persisted (the data is committed) which includes the logic in all callbacks. So for example if the transaction fails after the email job has been placed it will be rolled back, but the email job will already be in the queue, and it'll be referencing a record that doesn't actually exist (due to the rollback).
2021-05-02 13:23:31 +01:00
Matt-Yorkley
e290c128bf Fix error in Api::ShipmentController#update with :unlock parameter
This is a generic issue caused by a clash between state machines trying to define (or failing to define) the #open method on adjustments as part of their state changes interface. This method is already defined in Object. For more details, see: bb42e33bf7/lib/state_machines/machine.rb (L323-L350)
2021-04-30 14:13:22 +01:00
Matt-Yorkley
95a73704a2 Add more test coverage to Api::ShipmentController#update 2021-04-30 14:09:32 +01:00
Matt-Yorkley
b843b871f6 Ensure order totals and payment/shipment states are correct when changing shipping method on a completed order.
This used to happen via an after_save callback in Shipment, which called `order.update!`. That has recently been removed. After changing a shipment's selected shipping rate (shipping method), we need to ensure the order's totals and states are updated. We don't need to update all of the order's adjustments though (see previous commit).

FYI Spree handled this issue like this: 24388485ed, but there are lots of things about that commit that are clearly awful, like: params handling in a model, duplication of Order::Updater logic across the codebase, the Shipment class having responsiblity for knowing which things need to be updated on the order, etc. The result is ultimately the same as what we're doing here though.
2021-04-30 12:57:01 +01:00
Matt-Yorkley
925676f136 Split Order::Updater#update into two methods
There are two distinct (and very important) operations happening here. The first is to update all adjustments (which can be *incredibly* expensive) and the second is to ensure the order's totals and shipping/payment states are correct. There are lots of places where we currently do both of these things where in fact we only need to do the latter (and skip the really expensive part).
2021-04-30 12:48:53 +01:00
Matt-Yorkley
d3f41f14c7 Add test coverage for Api::ShipmentsController#update 2021-04-30 12:45:49 +01:00
Matt-Yorkley
045ce73c83 Simplify shipment controller params 2021-04-30 12:20:47 +01:00
Matt-Yorkley
932d000c9d Improve shipping method factory
You can now specify an amount for the flat_rate option.
2021-04-30 12:19:43 +01:00
Guido Oliveira
84285ff985 prevent deleting only item in confirmed order 2021-04-28 17:37:28 -03:00
dependabot[bot]
8b06a735ac Bump jwt from 2.2.2 to 2.2.3
Bumps [jwt](https://github.com/jwt/ruby-jwt) from 2.2.2 to 2.2.3.
- [Release notes](https://github.com/jwt/ruby-jwt/releases)
- [Changelog](https://github.com/jwt/ruby-jwt/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jwt/ruby-jwt/compare/v2.2.2...v2.2.3)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-20 05:21:34 +00:00
Matt-Yorkley
153ec268b7 Remove RackRequestBlocker 2021-03-30 13:24:44 +01:00
Matt-Yorkley
92eaf5fbaa Remove atomic gem
Bundler says this when installing gems:
```
Post-install message from atomic:
This gem has been deprecated and merged into Concurrent Ruby (http://concurrent-ruby.com).
```
We already have concurrent-ruby 👍
2021-03-30 12:29:48 +01:00
134 changed files with 1951 additions and 1356 deletions

5
.github/codecov.yml vendored Normal file
View File

@@ -0,0 +1,5 @@
coverage:
status:
project:
default:
informational: true

View File

@@ -322,4 +322,4 @@ jobs:
run: bundle exec rspec --profile --pattern "engines/*/spec/{,/*/**}/*_spec.rb,spec/features/admin/*/*_spec.rb,spec/lib/{,/*/**}/*_spec.rb"
- name: Codecov
uses: codecov/codecov-action@v1.3.1
uses: codecov/codecov-action@v1.5.0

View File

@@ -1 +1 @@
5.12.0
14.16.1

View File

@@ -6,7 +6,7 @@ This is a general guide to setting up an Open Food Network **development environ
The fastest way to make it work locally is to use Docker, you only need to setup git, see the [Docker setup guide](docker/README.md).
Otherwise, for a local setup you will need:
* Ruby 2.4.4 and bundler (check current Ruby version in [.ruby-version](https://github.com/openfoodfoundation/openfoodnetwork/blob/master/.ruby-version) file)
* Ruby and bundler (check current Ruby version in [.ruby-version](https://github.com/openfoodfoundation/openfoodnetwork/blob/master/.ruby-version) file)
* PostgreSQL database
* Chrome (for testing)
@@ -78,8 +78,6 @@ Note: If your OS is not explicitly supported in the setup guides then not all te
Note: The time zone on your machine should match the one defined in `config/application.yml`.
The project is configured to use [Zeus][zeus] to reduce the pre-test startup time while Rails loads. See the [Zeus GitHub page][zeus] for usage instructions.
Once [npm dependencies are installed][karma], AngularJS tests can be run with:
./script/karma run
@@ -119,7 +117,6 @@ If these commands succeed, you should be able to [continue the setup process](#g
[ubuntu]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/Development-Environment-Setup:-Ubuntu
[debian]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/Development-Environment-Setup:-Debian
[wiki]: https://github.com/openfoodfoundation/openfoodnetwork/wiki
[zeus]: https://github.com/burke/zeus
[rubocop]: https://rubocop.readthedocs.io/en/latest/
[karma]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/Karma
[slack-dev]: https://openfoodnetwork.slack.com/messages/C2GQ45KNU

View File

@@ -15,7 +15,7 @@ gem 'sass', '<= 4.7.1'
gem 'sass-rails', '< 6.0.0'
gem 'i18n'
gem 'i18n-js', '~> 3.8.2'
gem 'i18n-js', '~> 3.8.3'
gem 'rails-i18n'
gem 'rails_safe_tasks', '~> 1.0'
@@ -82,6 +82,9 @@ gem 'rack-rewrite'
gem 'rack-ssl', require: 'rack/ssl'
gem 'roadie-rails', '~> 2.2.0'
gem 'redis', '>= 4.0', require: ['redis', 'redis/connection/hiredis']
gem 'hiredis'
gem 'combine_pdf'
gem 'wicked_pdf'
gem 'wkhtmltopdf-binary'
@@ -127,12 +130,11 @@ end
group :test, :development do
# Pretty printed test output
gem 'atomic'
gem 'awesome_print'
gem 'bullet'
gem 'capybara'
gem 'database_cleaner', require: false
gem "factory_bot_rails", '6.1.0', require: false
gem "factory_bot_rails", '6.2.0', require: false
gem 'fuubar', '~> 2.5.1'
gem 'json_spec', '~> 1.1.4'
gem 'knapsack'

View File

@@ -64,7 +64,7 @@ GEM
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
actionpack-action_caching (1.2.1)
actionpack-action_caching (1.2.2)
actionpack (>= 4.0.0)
actionview (5.2.6)
activesupport (= 5.2.6)
@@ -88,7 +88,7 @@ GEM
activemodel (= 5.2.6)
activesupport (= 5.2.6)
arel (>= 9.0)
activerecord-import (1.0.8)
activerecord-import (1.1.0)
activerecord (>= 3.2)
activerecord-postgresql-adapter (0.0.1)
pg
@@ -124,7 +124,6 @@ GEM
angularjs-rails (1.5.5)
arel (9.0.0)
ast (2.4.2)
atomic (1.1.101)
awesome_nested_set (3.4.0)
activerecord (>= 4.0.0, < 7.0)
awesome_print (1.9.2)
@@ -193,7 +192,7 @@ GEM
daemons (1.4.0)
dalli (2.7.11)
database_cleaner (1.99.0)
ddtrace (0.48.0)
ddtrace (0.49.0)
ffi (~> 1.0)
msgpack
debugger-linecache (1.2.0)
@@ -223,10 +222,10 @@ GEM
eventmachine (1.2.7)
excon (0.79.0)
execjs (2.7.0)
factory_bot (6.1.0)
factory_bot (6.2.0)
activesupport (>= 5.0.0)
factory_bot_rails (6.1.0)
factory_bot (~> 6.1.0)
factory_bot_rails (6.2.0)
factory_bot (~> 6.2.0)
railties (>= 5.0.0)
faraday (1.3.0)
faraday-net_http (~> 1.0)
@@ -285,9 +284,10 @@ GEM
tilt
hashdiff (1.0.1)
highline (2.0.3)
hiredis (0.6.3)
i18n (1.8.10)
concurrent-ruby (~> 1.0)
i18n-js (3.8.2)
i18n-js (3.8.3)
i18n (>= 0.6.6)
immigrant (0.3.6)
activerecord (>= 3.0)
@@ -305,7 +305,7 @@ GEM
json_spec (1.1.5)
multi_json (~> 1.0)
rspec (>= 2.0, < 4.0)
jwt (2.2.2)
jwt (2.2.3)
kaminari (1.2.1)
activesupport (>= 4.1.0)
kaminari-actionview (= 1.2.1)
@@ -355,7 +355,7 @@ GEM
mustermann (1.1.1)
ruby2_keywords (~> 0.0.1)
nio4r (2.5.7)
nokogiri (1.11.3)
nokogiri (1.11.4)
mini_portile2 (~> 2.5.0)
racc (~> 1.4)
oauth2 (1.4.7)
@@ -447,6 +447,7 @@ GEM
rb-inotify (0.10.1)
ffi (~> 1.0)
redcarpet (3.5.1)
redis (4.2.5)
regexp_parser (2.1.1)
request_store (1.5.0)
rack (>= 1.4)
@@ -499,7 +500,7 @@ GEM
rswag-ui (2.4.0)
actionpack (>= 3.1, < 7.0)
railties (>= 3.1, < 7.0)
rubocop (1.14.0)
rubocop (1.15.0)
parallel (~> 1.10)
parser (>= 3.0.0.0)
rainbow (>= 2.2.2, < 4.0)
@@ -564,7 +565,7 @@ GEM
stringex (2.8.5)
stripe (5.30.0)
temple (0.8.2)
test-prof (1.0.3)
test-prof (1.0.5)
test-unit (3.4.1)
power_assert
thor (0.20.3)
@@ -596,7 +597,7 @@ GEM
nokogiri (~> 1.6)
rubyzip (>= 1.3.0)
selenium-webdriver (>= 3.0, < 4.0)
webmock (3.12.2)
webmock (3.13.0)
addressable (>= 2.3.6)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
@@ -629,7 +630,6 @@ DEPENDENCIES
angular_rails_csrf
angularjs-file-upload-rails (~> 2.4.1)
angularjs-rails (= 1.5.5)
atomic
awesome_nested_set
awesome_print
aws-sdk (= 1.67.0)
@@ -657,7 +657,7 @@ DEPENDENCIES
devise-token_authenticatable
dfc_provider!
eventmachine (>= 1.2.3)
factory_bot_rails (= 6.1.0)
factory_bot_rails (= 6.2.0)
ffaker
figaro
flipper
@@ -672,8 +672,9 @@ DEPENDENCIES
good_migrations
haml
highline (= 2.0.3)
hiredis
i18n
i18n-js (~> 3.8.2)
i18n-js (~> 3.8.3)
immigrant
jquery-migrate-rails
jquery-rails (= 4.4.0)
@@ -706,6 +707,7 @@ DEPENDENCIES
rails_safe_tasks (~> 1.0)
ransack (= 2.4.1)
redcarpet
redis (>= 4.0)
responders
roadie-rails (~> 2.2.0)
roo (~> 2.8.3)

View File

@@ -3,7 +3,7 @@ Darkswarm.controller "EditBoughtOrderController", ($scope, $resource, $timeout,
$scope.removeEnabled = true
$scope.deleteLineItem = (id) ->
if Cart.has_one_line_item()
if Cart.isOnlyItemInOrder(id)
Messages.error(t 'orders_cannot_remove_the_final_item')
$scope.removeEnabled = false
$timeout (->

View File

@@ -115,8 +115,9 @@ Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http, $modal, $roo
@line_items = []
localStorageService.clearAll() # One day this will have to be moar GRANULAR
has_one_line_item: =>
@line_items_finalised.length == 1
isOnlyItemInOrder: (id) =>
deletedItem = @line_items_finalised.find((item) -> item.id == id)
@line_items_finalised.filter((item) -> item.order_id == deletedItem.order_id).length == 1
removeFinalisedLineItem: (id) =>
@line_items_finalised = @line_items_finalised.filter (item) ->

View File

@@ -10,7 +10,7 @@ Darkswarm.service "GmapsGeo", ->
# console.log "Error: #{status}"
geocode: (address, callback) ->
geocoder = new google.maps.Geocoder()
geocoder.geocode {'address': address, 'region': "<%= Spree::Country.find_by(id: Spree::Config[:default_country_id]).iso %>"}, callback
geocoder.geocode {'address': address, 'region': "<%= DefaultCountry.code %>"}, callback
distanceBetween: (src, dst) ->
google.maps.geometry.spherical.computeDistanceBetween @toLatLng(src), @toLatLng(dst)
@@ -20,4 +20,4 @@ Darkswarm.service "GmapsGeo", ->
if locatable.lat?
locatable
else
new google.maps.LatLng locatable.latitude, locatable.longitude
new google.maps.LatLng locatable.latitude, locatable.longitude

View File

@@ -35,7 +35,7 @@ module Admin
if @line_item.update(line_item_params)
order.update_line_item_fees! @line_item
order.update_order_fees!
order.update!
order.update_order!
render body: nil, status: :no_content # No Content, does not trigger ng resource auto-update
else
render json: { errors: @line_item.errors }, status: :precondition_failed

View File

@@ -28,9 +28,7 @@ module Admin
def build_resource
enterprise_group = super
enterprise_group.address = Spree::Address.new
enterprise_group.address.country = Spree::Country.find_by(
id: Spree::Config[:default_country_id]
)
enterprise_group.address.country = DefaultCountry.country
enterprise_group
end

View File

@@ -119,7 +119,7 @@ module Admin
def build_resource
enterprise = super
enterprise.address ||= Spree::Address.new
enterprise.address.country ||= Spree::Country.find_by(id: Spree::Config[:default_country_id])
enterprise.address.country ||= DefaultCountry.country
enterprise
end

View File

@@ -31,10 +31,12 @@ module Api
unlock = params[:shipment].delete(:unlock)
if unlock == 'yes'
@shipment.fee_adjustment.open
@shipment.fee_adjustment.fire_events(:open)
end
@shipment.update(shipment_params[:shipment])
if @shipment.update(shipment_params)
@order.updater.update_totals_and_states
end
if unlock == 'yes'
@shipment.fee_adjustment.close
@@ -94,7 +96,7 @@ module Api
def find_and_update_shipment
@shipment = @order.shipments.find_by!(number: params[:id])
@shipment.update(shipment_params[:shipment]) if shipment_params[:shipment].present?
@shipment.update(shipment_params)
@shipment.reload
end
@@ -113,10 +115,9 @@ module Api
end
def shipment_params
params.permit(
[:id, :order_id, :variant_id, :quantity,
{ shipment: [:tracking, :selected_shipping_rate_id] }]
)
return {} unless params.has_key? :shipment
params.require(:shipment).permit(:tracking, :selected_shipping_rate_id)
end
end
end

View File

@@ -55,7 +55,7 @@ class CheckoutController < ::BaseController
flash[:error] = I18n.t("checkout.failed")
action_failed(e)
ensure
@order.update!
@order.update_order!
end
# Clears the cached order. Required for #current_order to return a new order

View File

@@ -43,7 +43,7 @@ class LineItemsController < BaseController
order.update_shipping_fees!
order.update_payment_fees!
order.update_order_fees!
order.update!
order.update_order!
order.create_tax_charge!
end
end

View File

@@ -14,7 +14,7 @@ module Spree
def update_order
@order.reload
@order.update!
@order.update_order!
end
def collection

View File

@@ -9,6 +9,10 @@ module Spree
before_action :load_payment, only: [:fire, :show]
before_action :load_data
before_action :can_transition_to_payment
# We ensure that items are in stock before all screens if the order is in the Payment state.
# This way, we don't allow someone to enter credit card details for an order only to be told
# that it can't be processed.
before_action :ensure_sufficient_stock_lines
respond_to :html
@@ -142,6 +146,20 @@ module Spree
redirect_to spree.edit_admin_order_customer_url(@order)
end
def ensure_sufficient_stock_lines
return if !@order.payment? || @order.insufficient_stock_lines.blank?
flash[:error] = I18n.t("spree.orders.line_item.insufficient_stock",
on_hand: "0 #{out_of_stock_item_names}")
redirect_to spree.edit_admin_order_url(@order)
end
def out_of_stock_item_names
@order.insufficient_stock_lines.map do |line_item|
line_item.variant.name
end.join(", ")
end
def load_order
@order = Order.find_by!(number: params[:order_id])
authorize! action, @order

View File

@@ -14,7 +14,7 @@ module Spree
respond_to :html
respond_to :json
before_action :update_distribution, only: :update
before_action :set_current_order, only: :update
before_action :filter_order_params, only: :update
before_action :enable_embedded_shopfront
@@ -27,13 +27,7 @@ module Spree
def show
@order = Spree::Order.find_by!(number: params[:id])
if params.key?("payment_intent")
result = ProcessPaymentIntent.new(params["payment_intent"], @order).call!
unless result.ok?
flash[:error] = "#{I18n.t("payment_could_not_process")}. #{result.error}"
end
@order.reload
end
handle_stripe_response
end
def empty
@@ -68,7 +62,7 @@ module Spree
associate_user
if @order.insufficient_stock_lines.present? || @unavailable_order_variants.present?
flash[:error] = t("spree.orders.error_flash_for_unavailable_items")
flash.now[:error] = t("spree.orders.error_flash_for_unavailable_items")
end
end
end
@@ -101,7 +95,7 @@ module Spree
@order.next_transition.run_callbacks if @order.cart?
redirect_to main_app.checkout_state_path(@order.checkout_steps.first)
elsif @order.complete?
redirect_to order_path(@order)
redirect_to main_app.order_path(@order)
else
redirect_to main_app.cart_path
end
@@ -115,24 +109,8 @@ module Spree
end
end
def update_distribution
def set_current_order
@order = current_order(true)
if params[:commit] == 'Choose Hub'
distributor = Enterprise.is_distributor.find params[:order][:distributor_id]
@order.set_distributor! distributor
flash[:notice] = I18n.t(:order_choosing_hub_notice)
redirect_to request.referer
elsif params[:commit] == 'Choose Order Cycle'
@order.empty! # empty cart
order_cycle = OrderCycle.active.find params[:order][:order_cycle_id]
@order.set_order_cycle! order_cycle
flash[:notice] = I18n.t(:order_choosing_hub_notice)
redirect_to request.referer
end
end
def filter_order_params
@@ -157,11 +135,24 @@ module Spree
else
flash[:error] = I18n.t(:orders_could_not_cancel)
end
redirect_to request.referer || order_path(@order)
redirect_to request.referer || main_app.order_path(@order)
end
private
# Stripe can redirect here after a payment is processed in the backoffice.
# We verify if it was successful here and persist the changes.
def handle_stripe_response
return unless params.key?("payment_intent")
result = ProcessPaymentIntent.new(params["payment_intent"], @order).call!
unless result.ok?
flash.now[:error] = "#{I18n.t("payment_could_not_process")}. #{result.error}"
end
@order.reload
end
def discard_empty_line_items
@order.line_items = @order.line_items.select { |li| li.quantity > 0 }
end
@@ -197,7 +188,7 @@ module Spree
if items.empty?
flash[:error] = I18n.t(:orders_cannot_remove_the_final_item)
redirect_to order_path(order_to_update)
redirect_to main_app.order_path(order_to_update)
end
end

View File

@@ -14,7 +14,7 @@ module Spree
def show
@payments_requiring_action = PaymentsRequiringAction.new(spree_current_user).query
@orders = orders_collection
@orders = orders_collection.includes(:line_items)
customers = spree_current_user.customers
@shops = Enterprise

View File

@@ -90,13 +90,13 @@ class SubscriptionConfirmJob < ActiveJob::Base
end
def send_confirmation_email(order)
order.update!
order.update_order!
record_success(order)
SubscriptionMailer.confirmation_email(order).deliver_now
end
def send_failed_payment_email(order, error_message = nil)
order.update!
order.update_order!
record_and_log_error(:failed_payment, order, error_message)
SubscriptionMailer.failed_payment_email(order).deliver_now
rescue StandardError => e

View File

@@ -77,7 +77,7 @@ class SubscriptionPlacementJob < ActiveJob::Base
def handle_empty_order(order, changes)
order.reload.all_adjustments.destroy_all
order.update!
order.update_order!
send_empty_email(order, changes)
end

View File

@@ -105,7 +105,7 @@ class Enterprise < ApplicationRecord
after_touch :touch_distributors
after_create :set_default_contact
after_create :relate_to_owners_enterprises
after_create :send_welcome_email
after_create_commit :send_welcome_email
after_rollback :restore_permalink

View File

@@ -24,7 +24,7 @@ module Spree
def self.default
country = begin
Spree::Country.find(Spree::Config[:default_country_id])
DefaultCountry.country
rescue StandardError
Spree::Country.first
end

View File

@@ -96,7 +96,7 @@ module Spree
# more than on line items at once via accepted_nested_attributes the order
# object on the association would be in a old state and therefore the
# adjustment calculations would not performed on proper values
def update!(calculable = nil, force: false)
def update_adjustment!(calculable = nil, force: false)
return amount if immutable? && !force
if originator.present?
@@ -127,11 +127,7 @@ module Spree
end
def set_absolute_included_tax!(tax)
# This rubocop issue can now fixed by renaming Adjustment#update! to something else,
# then AR's update! can be used instead of update_attributes!
# rubocop:disable Rails/ActiveRecordAliases
update_attributes! included_tax: tax.round(2)
# rubocop:enable Rails/ActiveRecordAliases
update! included_tax: tax.round(2)
end
def display_included_tax

View File

@@ -87,7 +87,7 @@ module Spree
)
refund_transaction_response = provider.refund_transaction(refund_transaction)
if refund_transaction_response.success?
payment.source.update_attributes(
payment.source.update(
refunded_at: Time.now,
refund_transaction_id: refund_transaction_response.RefundTransactionID,
state: "refunded",

View File

@@ -129,7 +129,19 @@ module Spree
payment = fetch_payment(creditcard, gateway_options)
raise Stripe::StripeError, I18n.t(:no_pending_payments) unless payment&.response_code
Stripe::PaymentIntentValidator.new.call(payment.response_code, stripe_account_id)
payment_intent_response = Stripe::PaymentIntentValidator.new.
call(payment.response_code, stripe_account_id)
raise_if_not_in_capture_state(payment_intent_response)
payment.response_code
end
def raise_if_not_in_capture_state(payment_intent_response)
state = payment_intent_response.status
return if state == 'requires_capture'
raise Stripe::StripeError, I18n.t(:invalid_payment_state, state: state)
end
def fetch_payment(creditcard, gateway_options)

View File

@@ -66,7 +66,7 @@ module Spree
end
def update_order
order.update!
order.update_order!
end
end
end

View File

@@ -17,9 +17,9 @@ module Spree
end
def update_adjustments
adjustment_total = adjustments.additional.map(&:update!).compact.sum
included_tax_total = tax_adjustments.inclusive.reload.map(&:update!).compact.sum
additional_tax_total = tax_adjustments.additional.reload.map(&:update!).compact.sum
adjustment_total = adjustments.additional.map(&:update_adjustment!).compact.sum
included_tax_total = tax_adjustments.inclusive.reload.map(&:update_adjustment!).compact.sum
additional_tax_total = tax_adjustments.additional.reload.map(&:update_adjustment!).compact.sum
item.update_columns(
included_tax_total: included_tax_total,

View File

@@ -230,7 +230,7 @@ module Spree
# update the order totals, etc.
order.create_tax_charge!
order.update!
order.update_order!
end
def update_inventory_before_destroy

View File

@@ -212,7 +212,7 @@ module Spree
@updater ||= OrderManagement::Order::Updater.new(self)
end
def update!
def update_order!
updater.update
end
@@ -748,8 +748,8 @@ module Spree
def update_adjustment!(adjustment)
return if adjustment.finalized?
adjustment.update!(force: true)
update!
adjustment.update_adjustment!(force: true)
update_order!
end
# object_params sets the payment amount to the order total, but it does this

View File

@@ -50,6 +50,7 @@ module Spree
scope :failed, -> { with_state('failed') }
scope :valid, -> { where('state NOT IN (?)', %w(failed invalid)) }
scope :authorization_action_required, -> { where.not(cvv_response_message: nil) }
scope :with_payment_intent, ->(code) { where(response_code: code) }
# order state machine (see http://github.com/pluginaweek/state_machine/tree/master for details)
state_machine initial: :checkout do
@@ -205,7 +206,7 @@ module Spree
end
def update_order
order.update!
OrderManagement::Order::Updater.new(order).after_payment_update(self)
end
# Necessary because some payment gateways will refuse payments with

View File

@@ -66,7 +66,7 @@ module Spree
order.shipped_shipments.collect{ |s| s.inventory_units.to_a }.flatten
end
# Used when Adjustment#update! wants to update the related adjustment
# Used when Adjustment#update_adjustment! wants to update the related adjustment
def compute_amount(*_args)
-amount.abs
end
@@ -105,7 +105,7 @@ module Spree
)
order.return if inventory_units.all?(&:returned?)
order.update!
order.update_order!
end
def allow_receive?

View File

@@ -50,7 +50,7 @@ module Spree
category = TaxCategory.includes(:tax_rates).find_by(is_default: true)
return 0 unless category
address ||= Address.new(country_id: Spree::Config[:default_country_id])
address ||= Address.new(country_id: DefaultCountry.id)
rate = category.tax_rates.detect { |tax_rate| tax_rate.zone.include? address }.try(:amount)
rate || 0

View File

@@ -1,5 +1,5 @@
class Api::LineItemSerializer < ActiveModel::Serializer
attributes :id, :quantity, :max_quantity, :price
attributes :id, :quantity, :max_quantity, :price, :order_id
has_one :variant, serializer: Api::VariantSerializer
end

View File

@@ -22,7 +22,7 @@ module Api
end
def item_count
object.line_items.sum(:quantity)
object.line_items.sum(&:quantity)
end
def completed_at

View File

@@ -0,0 +1,13 @@
class DefaultCountry
def self.id
country.id
end
def self.code
country.iso
end
def self.country
Spree::Country.find_by(iso: ENV["DEFAULT_COUNTRY_CODE"]) || Spree::Country.first
end
end

View File

@@ -2,9 +2,8 @@
# by setting entries on the Spree Config
# and initializing Spree:MailSettings that uses the Spree::Config.
class MailConfiguration
# @param entries [Hash] Spree Config entries
def self.entries=(entries)
entries.each do |name, value|
def self.apply!
configuration.each do |name, value|
Spree::Config[name] = value
end
apply_mail_settings
@@ -12,6 +11,21 @@ class MailConfiguration
private
def self.configuration
{
mail_host: ENV.fetch('MAIL_HOST'),
mail_domain: ENV.fetch('MAIL_DOMAIN'),
mail_port: ENV.fetch('MAIL_PORT'),
mail_auth_type: ENV.fetch('MAIL_AUTH_TYPE', 'login'),
smtp_username: ENV.fetch('SMTP_USERNAME'),
smtp_password: ENV.fetch('SMTP_PASSWORD'),
secure_connection_type: ENV.fetch('MAIL_SECURE_CONNECTION', 'None'),
mails_from: ENV.fetch('MAILS_FROM', "no-reply@#{ENV.fetch('MAIL_DOMAIN')}"),
mail_bcc: ENV.fetch('MAIL_BCC', ''),
intercept_email: ''
}
end
def self.apply_mail_settings
Spree::Core::MailSettings.init
end

View File

@@ -13,7 +13,7 @@ class OrderCheckoutRestart
clear_shipments
clear_payments
order.reload.update!
order.reload.update_order!
end
private

View File

@@ -24,7 +24,7 @@ class OrderFeesHandler
order.updater.persist_totals
end
order.update!
order.update_order!
end
def create_line_item_fees!
@@ -43,13 +43,13 @@ class OrderFeesHandler
def update_line_item_fees!(line_item)
line_item.adjustments.enterprise_fee.each do |fee|
fee.update!(line_item, force: true)
fee.update_adjustment!(line_item, force: true)
end
end
def update_order_fees!
order.adjustments.enterprise_fee.where(adjustable_type: 'Spree::Order').each do |fee|
fee.update!(order, force: true)
fee.update_adjustment!(order, force: true)
end
end

View File

@@ -44,7 +44,7 @@ module Permissions
def filtered_orders(orders)
return orders unless filter_orders?
orders.complete.not_state(:canceled).search(search_params).result
orders.complete.not_state(:canceled).ransack(search_params).result
end
def filter_orders?

View File

@@ -23,21 +23,20 @@ class ProcessPaymentIntent
end
end
def initialize(payment_intent, order, last_payment = nil)
def initialize(payment_intent, order)
@payment_intent = payment_intent
@order = order
@last_payment = last_payment.presence || OrderPaymentFinder.new(order).last_payment
@payment = order.payments.pending.with_payment_intent(payment_intent).first
end
def call!
validate_intent!
return Result.new(ok: false) unless valid?
return Result.new(ok: false) unless payment.present? && ready_for_capture?
return Result.new(ok: true) if already_processed?
OrderWorkflow.new(order).next
process_payment
if last_payment.can_complete?
last_payment.complete!
last_payment.mark_as_processed
if payment.reload.completed?
payment.mark_as_processed
Result.new(ok: true)
else
@@ -50,18 +49,29 @@ class ProcessPaymentIntent
private
attr_reader :order, :payment_intent, :last_payment
attr_reader :order, :payment_intent, :payment
def valid?
order.present? && matches_last_payment?
def process_payment
if order.state == "payment"
# Moves the order to completed, which calls #process_payments!
OrderWorkflow.new(order).next
else
order.process_payments!
end
end
def validate_intent!
Stripe::PaymentIntentValidator.new.call(payment_intent, stripe_account_id)
def ready_for_capture?
payment_intent_status == 'requires_capture'
end
def matches_last_payment?
last_payment&.state == "pending" && last_payment&.response_code == payment_intent
def already_processed?
payment_intent_status == 'succeeded'
end
def payment_intent_status
@payment_intent_status ||= Stripe::PaymentIntentValidator.new.
call(payment_intent, stripe_account_id).
status
end
def stripe_account_id
@@ -69,6 +79,6 @@ class ProcessPaymentIntent
end
def preferred_enterprise_id
last_payment.payment_method.preferred_enterprise_id
payment.payment_method.preferred_enterprise_id
end
end

View File

@@ -10,7 +10,7 @@
= "admin.enterprises"
= admin_inject_available_countries(module: 'admin.enterprises')
= admin_inject_json "admin.enterprises", "defaultCountryID", Spree::Config[:default_country_id]
= admin_inject_json "admin.enterprises", "defaultCountryID", DefaultCountry.id
-# Form

View File

@@ -38,7 +38,7 @@
= validated_input t(:postcode), "order.bill_address.zipcode"
.small-6.columns.right
= validated_select t(:country), "order.bill_address.country_id", {}, {"ng-init" => "order.bill_address.country_id = order.bill_address.country_id || #{Spree::Config[:default_country_id]}", "ng-options" => "c.id as c.name for c in countries"}
= validated_select t(:country), "order.bill_address.country_id", {}, {"ng-init" => "order.bill_address.country_id = order.bill_address.country_id || #{DefaultCountry.id}", "ng-options" => "c.id as c.name for c in countries"}
.row
.small-12.columns.text-right

View File

@@ -22,7 +22,7 @@
.small-6.columns
= validated_input t(:postcode), "order.ship_address.zipcode"
.small-6.columns.right
= validated_select t(:country), "order.ship_address.country_id", {}, {"ng-init" => "order.ship_address.country_id = order.ship_address.country_id || #{Spree::Config[:default_country_id]}", "ng-options" => "c.id as c.name for c in countries"}
= validated_select t(:country), "order.ship_address.country_id", {}, {"ng-init" => "order.ship_address.country_id = order.ship_address.country_id || #{DefaultCountry.id}", "ng-options" => "c.id as c.name for c in countries"}
.row
.small-6.columns
= validated_input t(:phone), "order.ship_address.phone"

View File

@@ -53,7 +53,7 @@
.small-12.medium-8.large-8.columns
.field
%label{ for: 'enterprise_country' }= t(".country_field")
%select.chunky{ id: 'enterprise_country', name: 'country', required: true, ng: { init: "setDefaultCountry(#{Spree::Config[:default_country_id]})", model: 'enterprise.country', options: 'c as c.name for c in countries' } }
%select.chunky{ id: 'enterprise_country', name: 'country', required: true, ng: { init: "setDefaultCountry(#{DefaultCountry.id})", model: 'enterprise.country', options: 'c as c.name for c in countries' } }
%span.error{ ng: { show: "details.country.$error.required && submitted" } }
= t(".country_field_error")

View File

@@ -1,5 +1,5 @@
- if Rails.env.test?
%script{type: "text/javascript"}
= render file: "spec/support/fixtures/stripejs-mock.js"
= raw render file: "spec/support/fixtures/stripejs-mock.js"
- else
%script{src: "https://js.stripe.com/v3/", type: "text/javascript"}

View File

@@ -26,4 +26,4 @@
var shipments = [];
- @order.shipments.each do |shipment|
shipments.push(#{shipment.to_json(:root => false, :include => [:inventory_units, :stock_location]).html_safe});
= render :partial => 'spree/admin/shared/update_order_state', :handlers => [:erb]
= render :partial => 'spree/admin/shared/update_order_state', :handlers => [:erb], :formats => [:js]

View File

@@ -25,8 +25,7 @@
%span.centered.three.columns
= t "spree_admin_enterprises_fees"
%div.sixteen.columns.alpha.list
- @enterprises.each do |enterprise|
= render 'enterprise_row', { enterprise: enterprise }
= render partial: 'enterprise_row', collection: @enterprises, as: :enterprise
%a.sixteen.columns.alpha.button.bottom.blue{ href: "#{main_app.admin_enterprises_path}" }
= t "spree_admin_overview_enterprises_footer"

View File

@@ -11,8 +11,8 @@
= configurations_sidebar_menu_item Spree.t(:tax_settings), edit_admin_tax_settings_path
= configurations_sidebar_menu_item Spree.t(:zones), admin_zones_path
= configurations_sidebar_menu_item Spree.t(:countries), admin_countries_path
- if Spree::Config[:default_country_id]
= configurations_sidebar_menu_item Spree.t(:states), admin_country_states_path(Spree::Config[:default_country_id])
- if DefaultCountry.id
= configurations_sidebar_menu_item Spree.t(:states), admin_country_states_path(DefaultCountry.id)
= configurations_sidebar_menu_item Spree.t(:payment_methods), admin_payment_methods_path
= configurations_sidebar_menu_item Spree.t(:taxonomies), admin_taxonomies_path
= configurations_sidebar_menu_item Spree.t(:shipping_methods), admin_shipping_methods_path

View File

@@ -12,7 +12,7 @@
- if order.changes_allowed?
.columns.show-for-medium-up.medium-3 &nbsp;
.columns.small-12.medium-3
= link_to cancel_order_path(@order), method: :put, :class => "button secondary expand", "confirm-link-click" => t('orders_confirm_cancel') do
= link_to main_app.cancel_order_path(@order), method: :put, :class => "button secondary expand", "confirm-link-click" => t('orders_confirm_cancel') do
%i.ofn-i_009-close
= t(:cancel_order)
.columns.small-12.medium-3

View File

@@ -41,7 +41,7 @@
= t(:orders_changeable_orders_alert_html, oc_close: l(order.order_cycle.orders_close_at, format: "%b %d, %Y %H:%M"))
%a.close{ "ng-click" => "close()" } &times;
= form_for order, url: order_path(order), html: {id: 'update-order', name: 'update_order_form' } do |order_form|
= form_for order, url: main_app.order_path(order), html: {id: 'update-order', name: 'update_order_form' } do |order_form|
- if order.changes_allowed?
= render 'spree/orders/form', order_form: order_form
-else

View File

@@ -75,13 +75,6 @@ module Openfoodnetwork
initializer 'ofn.spree_locale_settings', before: 'spree.promo.environment' do |app|
Spree::Config['checkout_zone'] = ENV['CHECKOUT_ZONE']
Spree::Config['currency'] = ENV['CURRENCY']
if ActiveRecord::Base.connected? && Spree::Country.table_exists?
country = Spree::Country.find_by(iso: ENV['DEFAULT_COUNTRY_CODE'])
Spree::Config['default_country_id'] = country.id if country.present?
else
Spree::Config['default_country_id'] = 12 # Australia
end
end
# Register Spree calculators

View File

@@ -66,5 +66,3 @@ SMTP_PASSWORD: 'f00d'
# config/initializers/feature_toggles.rb for details.
#
# BETA_TESTERS: ofn@example.com,superadmin@example.com
MEMCACHED_VALUE_MAX_MEGABYTES: '4'

View File

@@ -11,7 +11,14 @@ Openfoodnetwork::Application.configure do
config.cache_classes = !!ENV["PROFILE"]
# :file_store is used by default when no cache store is specifically configured.
config.cache_store = :memory_store if !!ENV["PROFILE"]
if !!ENV["PROFILE"]
config.cache_store = :redis_cache_store, {
driver: :hiredis,
url: ENV.fetch("OFN_REDIS_URL", "redis://localhost:6379/0"),
namespace: "cache",
expires_in: 90.minutes
}
end
config.eager_load = false

View File

@@ -42,9 +42,12 @@ Openfoodnetwork::Application.configure do
config.log_formatter = Logger::Formatter.new.tap { |f| f.datetime_format = "%Y-%m-%d %H:%M:%S" }
# Use a different cache store in production
memcached_value_max_megabytes = ENV.fetch("MEMCACHED_VALUE_MAX_MEGABYTES", 1).to_i
memcached_value_max_bytes = memcached_value_max_megabytes * 1024 * 1024
config.cache_store = :mem_cache_store, { value_max_bytes: memcached_value_max_bytes }
config.cache_store = :redis_cache_store, {
driver: :hiredis,
url: ENV.fetch("OFN_REDIS_URL", "redis://localhost:6379/0"),
namespace: "cache",
reconnect_attempts: 1
}
# Enable serving of images, stylesheets, and JavaScripts from an asset server
# config.action_controller.asset_host = "http://assets.example.com"

View File

@@ -42,9 +42,12 @@ Openfoodnetwork::Application.configure do
config.log_formatter = Logger::Formatter.new.tap { |f| f.datetime_format = "%Y-%m-%d %H:%M:%S" }
# Use a different cache store in production
memcached_value_max_megabytes = ENV.fetch("MEMCACHED_VALUE_MAX_MEGABYTES", 1).to_i
memcached_value_max_bytes = memcached_value_max_megabytes * 1024 * 1024
config.cache_store = :mem_cache_store, { value_max_bytes: memcached_value_max_bytes }
config.cache_store = :redis_cache_store, {
driver: :hiredis,
url: ENV.fetch("OFN_REDIS_URL", "redis://localhost:6379/0"),
namespace: "cache",
reconnect_attempts: 1
}
# Enable serving of images, stylesheets, and JavaScripts from an asset server
# config.action_controller.asset_host = "http://assets.example.com"

View File

@@ -50,11 +50,6 @@ Openfoodnetwork::Application.configure do
# Print deprecation notices to the stderr
config.active_support.deprecation = :stderr
# To block requests before running the database cleaner
require 'open_food_network/rack_request_blocker'
# Make sure the middleware is inserted first in middleware chain
config.middleware.insert_before(ActionDispatch::Static, RackRequestBlocker)
config.active_job.queue_adapter = :test
end

View File

@@ -3,6 +3,7 @@
if defined?(Bullet) && ENV.fetch("ENABLE_BULLET", false)
Rails.application.config.after_initialize do
Bullet.enable = true
Bullet.add_footer = true
Bullet.bullet_logger = true
Bullet.rails_logger = true
end

View File

@@ -1,4 +1,3 @@
Delayed::Worker.logger = Logger.new(Rails.root.join('log', 'delayed_job.log'))
Delayed::Worker.destroy_failed_jobs = false
Delayed::Worker.max_run_time = 15.minutes

View File

@@ -18,6 +18,7 @@ Spree::Gateway.class_eval do
end
Spree.config do |config|
config.site_url = ENV['SITE_URL'] if ENV['SITE_URL']
config.shipping_instructions = true
config.address_requires_state = true
config.admin_interface_logo = '/default_images/ofn-logo.png'
@@ -31,6 +32,10 @@ Spree.config do |config|
config.s3_protocol = ENV.fetch('S3_PROTOCOL', 'https')
end
# Read mail configuration from ENV vars at boot time and ensure the values are
# applied correctly in Spree::Config.
MailConfiguration.apply!
# Attachments settings
Spree::Image.set_attachment_attribute(:path, ENV['ATTACHMENT_PATH']) if ENV['ATTACHMENT_PATH']
Spree::Image.set_attachment_attribute(:url, ENV['ATTACHMENT_URL']) if ENV['ATTACHMENT_URL']

View File

@@ -163,7 +163,7 @@ de_DE:
confirmation_instructions:
subject: "Bitte bestätigen Sie die E-Mail-Adresse von %{enterprise} im Open Food Network"
welcome:
subject: "%{enterprise} ist jetzt im Open Food Network"
subject: "%{enterprise} ist jetzt Teil des Open Food Network"
email_welcome: "Willkommen"
email_registered: "ist jetzt Teil des"
email_userguide_html: "Das Benutzerhandbuch mit detaillierter Unterstützung für die Einrichtung Ihres Profils, Produzentenladens oder Hubs finden Sie hier: %{link}"
@@ -710,7 +710,7 @@ de_DE:
name: Name der Gebühr
fee_type: Art der Gebühr
manage_fees: Unternehmensgebühren verwalten
no_fees_yet: Sie haben noch keine Unternehmensgebühren.
no_fees_yet: Sie erheben noch keine Unternehmensgebühren.
create_button: Jetzt erstellen
images:
logo: Logo
@@ -735,7 +735,7 @@ de_DE:
name: Name der Zahlungsart
applies: Aktiv?
manage: Zahlungsarten verwalten
no_method_yet: Sie haben noch keine Zahlungsarten. Bitte erstellen Sie eine.
no_method_yet: Sie haben noch keine Zahlungsart angelegt. Bitte erstellen Sie eine.
create_button: Neue Zahlungsart
create_one_button: Jetzt erstellen
primary_details:
@@ -768,7 +768,7 @@ de_DE:
manage: "Lieferoptionen verwalten"
create_button: "Neue Lieferoption"
create_one_button: "Jetzt erstellen"
no_method_yet: "Sie haben noch keine Lieferoptionen angelegt."
no_method_yet: "Sie haben noch keine Lieferoption angelegt. Bitte erstellen Sie eine."
shop_preferences:
shopfront_requires_login: "Öffentlich sichtbarer Laden?"
shopfront_requires_login_tip: "Wählen Sie aus, ob sich Kunden einloggen müssen, um den Laden zu sehen oder ob er für alle sichtbar ist."
@@ -794,7 +794,7 @@ de_DE:
shopfront_message: "'Willkommen'-Nachricht im Laden"
shopfront_message_placeholder: >
Eine optionale Nachricht, um Kunden willkommen zu heißen und zu erklären,
wie Sie bei Ihnen einkaufen können. Wenn hier Text eingegeben wird,
wie sie bei Ihnen einkaufen können. Wenn hier Text eingegeben wird,
wird dieser auf einer Startseite in Ihrem Laden angezeigt, wenn Kunden
ihn zum ersten Mal besuchen.
shopfront_message_link_tooltip: "Link einfügen/bearbeiten"
@@ -862,7 +862,7 @@ de_DE:
shipping_methods: Lieferoptionen
shipping_methods_tip: Dieses Unternehmen hat Lieferoptionen.
enterprise_fees: Unternehmensgebühren
enterprise_fees_tip: Dieses Unternehmen hat keine Gebühren.
enterprise_fees_tip: Dieses Unternehmen erhebt keine Gebühren.
admin_index:
name: Name
role: Rolle
@@ -1044,7 +1044,7 @@ de_DE:
enterprises_hubs_tabs:
has_no_payment_methods: "%{enterprise} hat keine Zahlungsarten."
has_no_shipping_methods: "%{enterprise} hat keine Lieferoptionen."
has_no_enterprise_fees: "%{enterprise} hat keine Gebühren."
has_no_enterprise_fees: "%{enterprise} erhebt keine Gebühren."
enterprise_issues:
create_new: Erstellen
resend_email: E-Mail erneut senden
@@ -1208,7 +1208,7 @@ de_DE:
enterprise_logo:
destroy_attachment_does_not_exist: "Logo existiert nicht"
enterprise_promo_image:
destroy_attachment_does_not_exist: "Werbebild existiert nicht."
destroy_attachment_does_not_exist: "Hintergrundbild existiert nicht."
enterprise_terms_and_conditions:
destroy_attachment_does_not_exist: "AGB-Datei existiert nicht."
orders:
@@ -1237,10 +1237,10 @@ de_DE:
mailers:
powered_by:
open_food_network: "Open Food Network"
powered_html: "Dieser Einkauf wurde ermöglicht durch das %{open_food_network}."
powered_html: "Ermöglicht durch das %{open_food_network}."
menu:
cart:
cart: "Warenkorb"
cart: "Warenkorb/Kasse"
cart_sidebar:
checkout: "Zur Kasse"
edit_cart: "Warenkorb bearbeiten"
@@ -1252,7 +1252,7 @@ de_DE:
signed_in:
profile: "Profil"
mobile_menu:
cart: "Warenkorb"
cart: "Warenkorb/Kasse"
register_call:
selling_on_ofn: "Sie möchten selbst im Open Food Network verkaufen?"
register: "Hier registrieren!"
@@ -1472,7 +1472,7 @@ de_DE:
brandstory_part2: "Kaufen Sie ein in Hofläden, auf Bauernmärkten, in Food-Hubs oder schließen Sie sich zu Einkaufsgemeinschaften, Kooperativen, Genossenschaften oder einer solidarischen Landwirtschaft zusammen."
brandstory_part3: "Die Anbieter bilden gemeinsam ein regionales Netzwerk, in dem sich Käufer und Verkäufer wieder kennen und mit Vertrauen wertschätzend umgegangen wird."
brandstory_part4: "Der Programmcode dieser Internet-Plattform ist öffentlich frei verfügbar (Open Source), sie gehört also auch Ihnen und ist unverkäuflich. Alle Einnahmen werden wieder in die Weiterentwicklung des Netzwerks investiert!"
brandstory_part5_strong: "Wir nennen es Open Food Network."
brandstory_part5_strong: "Das ist das Open Food Network."
brandstory_part6: "Sie lieben Ihr Essen! Jetzt können Sie auch Ihr regionales Lebensmittelsystem lieben!"
learn_body: "Erkunden Sie Modelle, Geschichten und Ressourcen, um Sie bei der Entwicklung Ihres Fair-Food-Geschäfts oder Ihrer Organisation zu unterstützen. Finden Sie Schulungen, Veranstaltungen und andere Möglichkeiten, um von Gleichgesinnten zu lernen."
learn_cta: "Lassen Sie sich inspirieren"
@@ -1484,7 +1484,7 @@ de_DE:
system_step2: "2. Welche regionalen Lebensmittel kann ich online kaufen?"
system_step2_text: "Im Online-Shop des Ladens finden Sie ein großes Sortiment regionaler und saisonaler Produkte. Von Obst und Gemüse über Eier, Milch, Käse, Wurst und Fleisch bis hin zu Backwaren, Süßigkeiten und Fertiggerichten werden Sie fündig. Nutzen Sie die Suche oder die Filter nach Kategorien und Eigenschaften, wie bio, unverpackt oder fair gehandelt."
system_step3: "3. Wie kommen regionale Lebensmittel zu mir nach Hause?"
system_step3_text: "Jeder Laden kann seine Lieferoptionen selbst festlegen. Viele bieten einen Lieferservice an, oft ist auch die Abholung vor Ort oder an einer Abholstation möglich. Wählen Sie die gewünschte Option einfach beim Abschluss der Bestellung aus. Im Open Food Network kennt man sich - auch das Abstellen der Lieferung auf der Terrasse oder im Gartenhaus lässt sich sicher organisieren. "
system_step3_text: "Jeder Laden kann seine Lieferoptionen selbst festlegen. Viele bieten einen Lieferservice an, oft ist auch die Abholung vor Ort oder an einer Abholstation möglich. Wählen Sie die gewünschte Option einfach beim Abschluss der Bestellung aus. Im Open Food Network kennt man sich - auch das Vereinbaren eines Ablageortes lässt sich sicher organisieren. "
cta_headline: "Machen Sie die Welt mit Ihrem Einkauf ein kleines bisschen besser."
cta_label: "Jetzt regional einkaufen"
stats_headline: "Wir erschaffen ein neues Ernährungssystem."
@@ -1552,7 +1552,7 @@ de_DE:
email_social: "Verbinden Sie sich mit uns:"
email_contact: "Schreiben Sie uns eine E-Mail:"
email_signoff: "Viele Grüße,"
email_signature: "das Team vom Open Food Network"
email_signature: "das Team des Open Food Network"
email_confirm_customer_greeting: "Hallo %{name},"
email_confirm_customer_intro_html: "vielen Dank für Ihren Einkauf bei <strong>%{distributor}</strong>!"
email_confirm_customer_number_html: "<strong>Bestellbestätigung #%{number}</strong>"
@@ -1763,7 +1763,7 @@ de_DE:
sell_user_guide: "Erfahren Sie mehr in unserem Benutzerhandbuch."
sell_listing_price: "Die Aufnahme ins Open Food Network ist kostenlos. Das Eröffnen und Betreiben eines Online-Shops ist für Unternehmen mit einem monatlichen Umsatz unter 500 € kostenlos. Bei höherem Umsatz erlauben wir uns nach einer 3-monatigen kostenlosen Testphase die Berechnung von 3 % Gebühr, um unsere Kosten zu decken."
sell_embed: "Wir bieten noch weitere Dienste rund um Ihr Unternehmen an."
sell_ask_services: "Fragen Sie uns nach OFN-Dienstleistungen."
sell_ask_services: "Fragen Sie uns nach Dienstleistungen rund um das Open Food Network."
shops_title: Regional Einkaufen
shops_headline: Wählen Sie einen Laden aus der Liste.
shops_text: Pflanzen wachsen in Zyklen, Landwirte ernten in Zyklen und bei uns bestellen Sie Lebensmittel in Zyklen. Ist ein Bestellzyklus gerade geschlossen, wählen Sie einen anderen Laden oder schauen Sie später wieder vorbei.
@@ -1879,23 +1879,23 @@ de_DE:
steps:
introduction:
registration_greeting: "Herzlich willkommen!"
registration_intro: "Sie können jetzt ein Profil als Produzent oder Hub erstellen!"
registration_intro: "Erstellen Sie zunächst ein Profil um sich oder Ihre Produkte zu präsentieren!"
registration_checklist: "Was brauche ich?"
registration_time: "5-10 Minuten Zeit"
registration_enterprise_address: "Unternehmensadresse"
registration_contact_details: "Kontaktdaten (Ansprechpartner, E-Mail-Adresse, Telefonnummer)"
registration_logo: "Ihr Logo"
registration_promo_image: "Hintergrundbild für Ihr Profil"
registration_about_us: "\"Über uns\" Text"
registration_enterprise_address: "Unternehmensname und -adresse"
registration_contact_details: "Kontaktdaten (Ansprechpartner, E-Mail-Adresse)"
registration_logo: "Ihr Logo (empfohlen)"
registration_promo_image: "Hintergrundbild für Ihr Profil (empfohlen)"
registration_about_us: "\"Über uns\" Text (empfohlen)"
registration_outcome_headline: "Was bekomme ich?"
registration_outcome1_html: "Ihr Profil hilft dabei, Sie im Open Food Network zu <strong>finden</strong> und zu <strong>kontaktieren</strong>."
registration_outcome2: "Nutzen Sie Ihr Profil, um die Geschichte Ihres Unternehmens zu erzählen und verknüpfen Sie Ihren Social-Media- und Web-Auftritt."
registration_outcome3: "Ihr Profil ist auch der erste Schritt, um im Open Food Network Produkte zu handeln oder einen Laden zu eröffnen."
registration_outcome3: "Ihr Profil ist auch der erste Schritt, um im Open Food Network Produkte zu handeln oder einen Online-Shop zu eröffnen."
registration_action: "Los geht's!"
details:
title: "Ihr Unternehmen"
headline: "Ihr Unternehmen"
enterprise: "Woot! Zuerst müssen wir ein wenig über Ihr Unternehmen wissen:"
enterprise: "Nennen Sie uns zunächst bitte den Namen und die Adresse Ihres Unternehmens."
producer: "Nennen Sie uns zunächst bitte den Namen und die Adresse Ihres Betriebs."
enterprise_name_field: "Name des Unternehmens:"
producer_name_field: "Name des Betriebs:"
@@ -1926,80 +1926,80 @@ de_DE:
contact_field: "Hauptansprechpartner"
contact_field_placeholder: "Vorname Nachname"
contact_field_required: "Bitte geben Sie einen Hauptansprechpartner ein."
phone_field: "Telefonnummer"
phone_field: "Telefonnummer (optional)"
phone_field_placeholder: "z. B. 030 1234 5678"
type:
title: "Art"
headline: "Wählen Sie bitte die Profilart von %{enterprise} aus!"
question: "Sind Sie ein Produzent?"
yes_producer: "Ja, ich bin ein Produzent."
no_producer: "Nein, ich bin kein Produzent."
producer_field_error: "Bitte wählen Sie: Sind Sie ein Produzent?"
title: "Art des Profils"
headline: "Wählen Sie bitte die Profilart für %{enterprise} aus!"
question: "Ist das Unternehmen ein Produzent?"
yes_producer: "Ja, es ist ein Produzent."
no_producer: "Nein, es ist kein Produzent."
producer_field_error: "Bitte wählen Sie: Ist das Unternehmen ein Produzent?"
yes_producer_help: "Produzenten stellen leckere Lebensmittel oder Getränke her. Sie sind ein Produzent, wenn Sie anbauen, brauen, backen, fermentieren, melken oder sonst wie Lebenmittel produzieren."
no_producer_help: "Wenn Sie kein Produzent sind, sind Sie wahrscheinlich jemand, der Lebensmittel verkauft und verteilt. Sie könnten ein Foodhub, eine Lebensmittelkooperative, eine Einkaufsgemeinschaft, ein Einzelhändler, Hofladen, Großhändler oder Vergleichbares sein."
no_producer_help: "Wenn Sie kein Produzent sind, sind Sie wahrscheinlich jemand, der Lebensmittel verkauft und verteilt. Sie könnten ein Food Hub, eine Lebensmittelkooperative, eine Einkaufsgemeinschaft, ein Einzelhändler, Hofladen, Großhändler oder Vergleichbares sein."
create_profile: "Profil erstellen"
about:
title: "Über uns"
headline: "Sehr gut!"
message: "Lassen Sie uns nun die Details Ihres Profils bearbeiten:"
headline: "Über uns"
message: "Beschreiben Sie nun "
success: "Sehr gut! %{enterprise} wurde dem Open Food Network hinzugefügt."
registration_exit_message: "Wenn Sie diesen Assistenten zu einem beliebigen Zeitpunkt beenden, können Sie mit der Erstellung Ihres Profils fortfahren, indem Sie in das Menü \"Verwaltung\" gehen."
enterprise_description: "Kurzbeschreibung"
registration_exit_message: "Wenn Sie diesen Assistenten zu einem beliebigen Zeitpunkt beenden, können Sie mit der Erstellung Ihres Profils fortfahren, indem Sie sich einloggen und zum Menü \"Verwaltung\" wechseln."
enterprise_description: "Kurzbeschreibung (empfohlen)"
enterprise_description_placeholder: "Ein kurzer Satz, der Ihr Unternehmen beschreibt."
enterprise_long_desc: "Ausführliche Beschreibung"
enterprise_long_desc: "Ausführliche Beschreibung (empfohlen)"
enterprise_long_desc_placeholder: "Erzählen Sie hier die Geschichte Ihres Unternehmens - was macht Sie anders und wunderbar? Wir empfehlen, die Beschreibung unter 600 Zeichen oder 150 Wörtern zu halten."
enterprise_long_desc_length: "%{num} Zeichen/bis zu 600 empfohlen"
enterprise_abn: "USt-IdNr."
enterprise_abn: "USt-IdNr. (optional für Rechnungserstellung)"
enterprise_abn_placeholder: "z. B. DE999999999"
enterprise_acn: "St.-Nr."
enterprise_acn: "St.-Nr. (optional für Rechnungserstellung)"
enterprise_acn_placeholder: "z. B. 93815/08152"
enterprise_tax_required: "Bitte treffen Sie eine Auswahl."
images:
title: "Bilder"
headline: "Vielen Dank!"
headline: "Bilder"
description: "Laden Sie einige schöne Bilder hoch, um ein ansprechendes Profil zu gestalten!"
uploading: "Wird hochgeladen ..."
continue: "Weiter"
back: "Zurück"
logo:
select_logo: "Schritt 1. Wählen Sie ein Bild als Ihr Logo aus"
select_logo: "Schritt 1: Laden Sie Ihr Logo hoch (empfohlen)"
logo_tip: "Tipp: Am besten funktionieren quadratische Bilder, vorzugsweise mindestens 300 × 300 Pixel."
logo_label: "Wählen Sie ein Logo aus"
logo_label: "Bilddatei auswählen"
logo_drag: "Ziehen Sie Ihr Logo hierher."
review_logo: "Schritt 2. Überprüfen Sie Ihr Logo"
review_logo: "Schritt 2: Überprüfen Sie Ihr Logo"
review_logo_tip: "Tipp: Um das schönste Ergebnis zu erzielen, sollte Ihr Logo den gesamten verfügbaren Platz ausfüllen."
logo_placeholder: "Ihr Logo wird hier zur Überprüfung angezeigt, sobald es hochgeladen wurde."
promo:
select_promo_image: "Schritt 3. Wählen Sie ein Werbebild"
select_promo_image: "Schritt 3: Laden Sie ein Hintergrundbild hoch (empfohlen)"
promo_image_tip: "Tipp: Die als Banner dargestellte bevorzugte Größe beträgt 1200 × 260 Pixel."
promo_image_label: "Wählen Sie ein Werbebild"
promo_image_label: "Bilddatei auswählen"
promo_image_drag: "Ziehen Sie Ihr Bild hierher."
review_promo_image: "Schritt 4. Überprüfen Sie Ihr Werbebild"
review_promo_image_tip: "Tipp: Für ein optimales Ergebnis sollte Ihr Werbebild den verfügbaren Platz ausfüllen."
review_promo_image: "Schritt 4: Überprüfen Sie Ihr Hintergrundbild"
review_promo_image_tip: "Tipp: Für ein optimales Ergebnis sollte Ihr Hintergrundbild den verfügbaren Platz ausfüllen."
promo_image_placeholder: "Ihr Logo wird hier zur Überprüfung angezeigt, sobald es hochgeladen wurde."
social:
title: "Soziale Medien"
enterprise_final_step: "Letzter Schritt!"
enterprise_social_text: "Wie ist %{enterprise} im Internet erreichbar?"
website: "Homepage"
website: "Homepage (empfohlen)"
website_placeholder: "z. B. openfoodnetwork.de"
facebook: "Facebook"
facebook: "Facebook (optional)"
facebook_placeholder: "z. B. www.facebook.com/IhrNameHier"
linkedin: "LinkedIn"
linkedin: "LinkedIn (optional)"
linkedin_placeholder: "z. B. www.linkedin.com/IhrNameHier"
twitter: "Twitter"
twitter: "Twitter (optional)"
twitter_placeholder: "z. B. @twitter_name"
instagram: "Instagram"
instagram: "Instagram (optional)"
instagram_placeholder: "z. B. @instagram_name"
limit_reached:
headline: "Oh nein!"
message: "Sie haben das Limit erreicht!"
text: "Sie haben die maximale Anzahl der Unternehmen erreicht, die Sie besitzen dürfen im"
text: "Sie haben die maximale Anzahl der Unternehmen erreicht, die Sie verwalten dürfen im"
action: "Zurück zur Startseite"
finished:
headline: "Fertig!"
thanks: "Vielen Dank, dass Sie die Details für %{enterprise} ausgefüllt haben."
login: "Sie können die Angaben Ihres Unternehmens jederzeit ändern oder aktualisieren, indem Sie sich bei Open Food Network einloggen und zum Menü \"Verwaltung\" wechseln."
login: "Sie können die Angaben Ihres Unternehmens jederzeit ändern oder aktualisieren, indem Sie sich einloggen und zum Menü \"Verwaltung\" wechseln."
action: "Zur Übersicht der Unternehmen"
back: "Zurück"
continue: "Weiter"
@@ -2972,7 +2972,7 @@ de_DE:
back_to_zones_list: "Zurück zur Zonenliste"
card_code: "Kartenprüfnummer (3-stellig)"
card_number: "Kreditkartennummer"
category: "Produktkategorie"
category: "Steuerkategorie"
created_successfully: "Erfolgreich erstellt"
credit: "Guthaben"
editing_tax_category: "Steuerkategorie bearbeiten"
@@ -3089,7 +3089,7 @@ de_DE:
display_currency: "Währung anzeigen"
choose_currency: "Währung auswählen"
mail_method_settings: "E-Mail-Methodeneinstellungen"
mail_settings_notice_html: "Einige der folgenden Einstellungen können nicht geändert werden und werden hier nur zu Zwecken der Fehlerbehebung aufgeführt. Änderungen können vorgenommen werden, indem die Einstellungen der deutschen Instanz aktualisiert und mithilfe von <a href='https://github.com/openfoodfoundation/ofn-install'>ofn-install</a> bereitgestellt werden. Wenden Sie sich an das globale OFN-Team, um weitere Informationen zu erhalten."
mail_settings_notice_html: "Einige der folgenden Einstellungen können nicht geändert werden und werden hier nur zu Zwecken der Fehlerbehebung aufgeführt. Änderungen können vorgenommen werden, indem die Einstellungen der deutschen Instanz aktualisiert und mithilfe von <a href='https://github.com/openfoodfoundation/ofn-install'>ofn-install</a> bereitgestellt werden. Wenden Sie sich an das globale Team des Open Food Network, um weitere Informationen zu erhalten."
general: "Allgemeines"
enable_mail_delivery: "E-Mail-Versand aktivieren"
send_mails_as: "E-Mails senden als"
@@ -3340,7 +3340,7 @@ de_DE:
enterprises_header:
ofn_with_tip: Unternehmen sind Produzenten und/oder Hubs und sind die grundlegende Organisationseinheit innerhalb des Open Food Network.
enterprise_row:
has_no_enterprise_fees: "hat keine Unternehmensgebühren"
has_no_enterprise_fees: "erhebt keine Unternehmensgebühren"
has_no_payment_methods: "hat keine Zahlungsarten"
has_no_shipping_methods: "hat keine Lieferoptionen"
products:

View File

@@ -317,6 +317,8 @@ en_GB:
height: "Height"
width: "Width"
depth: "Depth"
payment_could_not_process: "The payment could not be processed"
payment_could_not_complete: "The payment could not be completed"
actions:
create_and_add_another: "Create and Add Another"
create: "Create"

View File

@@ -317,6 +317,8 @@ en_US:
height: "Height"
width: "Width"
depth: "Depth"
payment_could_not_process: "The payment could not be processed"
payment_could_not_complete: "The payment could not be completed"
actions:
create_and_add_another: "Create and Add Another"
create: "Create"

View File

@@ -85,6 +85,10 @@ es_US:
no_default_card: "^ Ninguna tarjeta predeterminada disponible para esta consumidora"
shipping_method:
not_available_to_shop: "no está disponible para %{shop}"
card_details: "Detalles de la tarjeta"
card_type: "Tipo de tarjeta"
cardholder_name: "Nombre del titular de la tarjeta"
community_forum_url: "Liga URL para el foro de la comunidad"
customer_instructions: "Instrucciones del Consumidor"
devise:
confirmations:
@@ -120,7 +124,11 @@ es_US:
cloned_order_cycle_name: "COPIA DE %{order_cycle}"
tax_rate:
included_in_price: "Incluido en el precio"
open_street_map_enabled: "Open Street Map activado"
open_street_map_default_latitude: "latitud por defecto en Open Street Map"
open_street_map_default_longitude: "longitud por defecto en Open Street Map"
sku: "SKU"
subtotal: "Subtotal"
tax_rate: "% Impuestos"
validators:
date_time_string_validator:
@@ -285,6 +293,8 @@ es_US:
height: "Altura"
width: "Anchura"
depth: "Profundidad"
payment_could_not_process: "El pago no pudo procesarse"
payment_could_not_complete: "El pago no pudo completarse"
actions:
create_and_add_another: "Crear y agregar otro"
create: "Crear"
@@ -300,8 +310,12 @@ es_US:
destroy: "Eliminar"
rename: "Renombrar"
admin:
adjustments:
skipped_changing_canceled_order: "No puede modificar un pedido cancelado."
begins_at: Empieza en
begins_on: Comienza en
bill_address: "Dirección de facturación"
ship_address: "Dirección de envío"
customer: Consumidora
date: Fecha
email: Email
@@ -1311,6 +1325,9 @@ es_US:
address2: Dirección (cont.)
city: Ciudad
city_placeholder: ej. Barcelona
latitude: Latitud
longitude: Longitud
use_geocoder: ¿Calcular la latitud y longitud automáticamente a partir de la dirección?
postcode: Código postal
postcode_placeholder: ej. 08025
suburb: Barrio
@@ -1863,6 +1880,9 @@ es_US:
state_field_error: "Región requerida"
country_field: "País:"
country_field_error: "Por favor selecciona un país"
locate_address: "Localizar una dirección en el mapa"
confirm_address: "Confirmo que la posición indicada de la empresa en el mapa es correcta."
drag_map_marker: "Debido a que muchos productores operan en áreas rurales, la precisión de los mapas siempre se puede ir mejorando. Ayúdanos a comprender mejor dónde está ubicada/o interactuando con el mapa de arriba para mover el marcador haciendo clic o seleccionando el marcador y luego arrastrando a la ubicación que sea más precisa de acuerdo a su conocimiento."
contact:
title: "Contacto"
who_is_managing_enterprise: "¿Quién es responsable de administrar %{enterprise}?"
@@ -2813,6 +2833,7 @@ es_US:
reports:
bulk_coop:
filters:
date_range: "Rango de fecha"
generate_report: "Generar informe"
enterprise_fee_summaries:
filters:

View File

@@ -318,6 +318,8 @@ ru:
height: "Высота"
width: "Ширина"
depth: "Глубина"
payment_could_not_process: "Платеж не может быть обработан"
payment_could_not_complete: "Платеж не может быть завершен"
actions:
create_and_add_another: "Создать и Добавить Другой"
create: "Создать"

View File

@@ -227,4 +227,3 @@ Spree::Country.create!([
{ name: "Saint Kitts and Nevis", iso3: "KNA", iso: "KN", iso_name: "SAINT KITTS AND NEVIS", numcode: "659" },
{ name: "Serbia", iso3: "SRB", iso: "RS", "iso_name" => "SERBIA", numcode: "999" }
])
Spree::Config[:default_country_id] = Spree::Country.find_by(iso: ENV.fetch("DEFAULT_COUNTRY_CODE", "US")).id

File diff suppressed because it is too large Load Diff

View File

@@ -2,22 +2,8 @@
# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
require 'yaml'
def set_mail_configuration
MailConfiguration.entries= {
mail_host: ENV.fetch('MAIL_HOST'),
mail_domain: ENV.fetch('MAIL_DOMAIN'),
mail_port: ENV.fetch('MAIL_PORT'),
mail_auth_type: ENV.fetch('MAIL_AUTH_TYPE', 'login'),
smtp_username: ENV.fetch('SMTP_USERNAME'),
smtp_password: ENV.fetch('SMTP_PASSWORD'),
secure_connection_type: ENV.fetch('MAIL_SECURE_CONNECTION', 'None'),
mails_from: ENV.fetch('MAILS_FROM', "no-reply@#{ENV.fetch('MAIL_DOMAIN')}"),
mail_bcc: ENV.fetch('MAIL_BCC', ''),
intercept_email: ''
}
end
# We need mail_configuration to create a user account, because it sends a confirmation email.
set_mail_configuration
MailConfiguration.apply!
puts "[db:seed] Seeding Roles"
Spree::Role.where(:name => "admin").first_or_create

View File

@@ -20,6 +20,10 @@ module OrderManagement
# associations try to save and then in turn try to call +update!+ again.)
def update
update_all_adjustments
update_totals_and_states
end
def update_totals_and_states
update_totals
if order.completed?
@@ -38,7 +42,7 @@ module OrderManagement
# - adjustment_total - total value of all adjustments
# - total - order total, it's the equivalent to item_total plus adjustment_total
def update_totals
order.payment_total = payments.completed.sum(:amount)
update_payment_total
update_item_total
update_adjustment_total
update_order_total
@@ -49,6 +53,10 @@ module OrderManagement
shipments.each { |shipment| shipment.update!(order) }
end
def update_payment_total
order.payment_total = payments.completed.sum(:amount)
end
def update_item_total
order.item_total = line_items.sum('price * quantity')
update_order_total
@@ -121,7 +129,7 @@ module OrderManagement
end
def update_all_adjustments
order.all_adjustments.reload.each(&:update!)
order.all_adjustments.reload.each(&:update_adjustment!)
end
def before_save_hook
@@ -137,6 +145,22 @@ module OrderManagement
order.ship_address = order.address_from_distributor
end
def after_payment_update(payment)
if payment.completed? || payment.void?
update_payment_total
end
if order.completed?
update_payment_state
update_shipments
update_shipment_state
end
if payment.completed? || order.completed?
persist_totals
end
end
private
def round_money(value)

View File

@@ -17,7 +17,7 @@ describe OrderManagement::Reports::BulkCoopController, type: :controller do
it "renders the report form" do
get :new
expect(response).to be_success
expect(response.status).to eq 200
expect(response).to render_template(new_template_path)
end
end
@@ -32,7 +32,7 @@ describe OrderManagement::Reports::BulkCoopController, type: :controller do
}, report_format: "csv"
}
expect(response).to be_success
expect(response.status).to eq 200
expect(response.body).not_to be_blank
expect(response.header["Content-Type"]).to eq("text/csv")
end

View File

@@ -17,7 +17,7 @@ describe OrderManagement::Reports::EnterpriseFeeSummariesController, type: :cont
it "renders the report form" do
get :new
expect(response).to be_success
expect(response.status).to eq 200
expect(response).to render_template(new_template_path)
end
end
@@ -29,7 +29,7 @@ describe OrderManagement::Reports::EnterpriseFeeSummariesController, type: :cont
report: { start_at: "2018-10-09 07:30:00" }, report_format: "csv"
}
expect(response).to be_success
expect(response.status).to eq 200
expect(response.body).not_to be_blank
expect(response.header["Content-Type"]).to eq("text/csv")
end

View File

@@ -28,7 +28,7 @@ module OrderManagement
let(:payment_method) { create(:payment_method) }
it "returns the pending payment with no change" do
expect(payment).to_not receive(:update_attributes)
expect(payment).to_not receive(:update)
expect(payment_setup.call!).to eq payment
end
end
@@ -38,7 +38,7 @@ module OrderManagement
context "and the card is already set (the payment source is a credit card)" do
it "returns the pending payment with no change" do
expect(payment).to_not receive(:update_attributes)
expect(payment).to_not receive(:update)
expect(payment_setup.call!).to eq payment
end
end
@@ -54,7 +54,7 @@ module OrderManagement
it "adds an error to the order and does not update the payment" do
payment_setup.call!
expect(payment).to_not receive(:update_attributes)
expect(payment).to_not receive(:update)
expect(payment_setup.call!).to eq payment
expect(order.errors[:base].first).to eq "There are no authorised "\
"credit cards available to charge"
@@ -80,7 +80,7 @@ module OrderManagement
it "adds an error to the order and does not update the payment" do
payment_setup.call!
expect(payment).to_not receive(:update_attributes)
expect(payment).to_not receive(:update)
expect(payment_setup.call!).to eq payment
expect(order.errors[:base].first).to eq "There are no authorised "\
"credit cards available to charge"

View File

@@ -36,7 +36,7 @@ module OpenFoodNetwork
def search
@permissions.visible_orders.select("DISTINCT spree_orders.*").
complete.not_state(:canceled).
search(@params[:q])
ransack(@params[:q])
end
def table

View File

@@ -51,7 +51,7 @@ module OpenFoodNetwork
not_state(:canceled).
distributed_by_user(@user).
managed_by(@user).
search(params[:q])
ransack(params[:q])
end
def orders

View File

@@ -36,7 +36,7 @@ module OpenFoodNetwork
end
def search
Spree::Order.complete.not_state(:canceled).managed_by(@user).search(params[:q])
Spree::Order.complete.not_state(:canceled).managed_by(@user).ransack(params[:q])
end
def table_items

View File

@@ -1,76 +0,0 @@
# Copied from http://blog.salsify.com/engineering/tearing-capybara-ajax-tests
# https://gist.github.com/jturkel/9317269/raw/ff7838684370fd8a468ffe1e5ce1f3e46ba39951/rack_request_blocker.rb
require 'atomic'
# Rack middleware that keeps track of the number of active requests and can block new requests.
class RackRequestBlocker
@@num_active_requests = Atomic.new(0)
@@block_requests = Atomic.new(false)
# Returns the number of requests the server is currently processing.
def self.num_active_requests
@@num_active_requests.value
end
# Prevents the server from accepting new requests. Any new requests will return an HTTP
# 503 status.
def self.block_requests!
@@block_requests.value = true
end
# Allows the server to accept requests again.
def self.allow_requests!
@@block_requests.value = false
end
def initialize(app)
@app = app
end
def call(env)
increment_active_requests
if block_requests?
block_request(env)
else
@app.call(env)
end
ensure
decrement_active_requests
end
def self.wait_for_requests_complete
block_requests!
max_wait_time = 30
polling_interval = 0.01
wait_until = Time.now.in_time_zone + max_wait_time.seconds
loop do
return if num_active_requests == 0
if Time.now.in_time_zone > wait_until
raise "Failed waiting for completing requests, #{num_active_requests} running."
else
sleep(polling_interval)
end
end
ensure
allow_requests!
end
private
def block_requests?
@@block_requests.value
end
def block_request(_env)
[503, {}, []]
end
def increment_active_requests
@@num_active_requests.update { |v| v + 1 }
end
def decrement_active_requests
@@num_active_requests.update { |v| v - 1 }
end
end

View File

@@ -38,7 +38,7 @@ module OpenFoodNetwork
attr_reader :orders_relation, :order_permissions
def search_orders
orders_relation.search(@params[:q])
orders_relation.ransack(@params[:q])
end
# From the line_items given, returns the ones that are editable by the user

View File

@@ -20,7 +20,7 @@ module OpenFoodNetwork
def search
permissions = ::Permissions::Order.new(@user)
permissions.editable_orders.complete.not_state(:canceled).search(@opts[:q])
permissions.editable_orders.complete.not_state(:canceled).ransack(@opts[:q])
end
def orders

View File

@@ -12,7 +12,7 @@ module Spree
end
def override!
ActionMailer::Base.default_url_options[:host] ||= Config.site_url
ActionMailer::Base.default_url_options[:host] ||= ENV.fetch("SITE_URL", Config.site_url)
ActionMailer::Base.smtp_settings = mail_server_settings
ActionMailer::Base.perform_deliveries = true
end

13
lib/spree/licence.md Normal file
View File

@@ -0,0 +1,13 @@
Spree License
=============
Copyright © 2007-2014, Spree Commerce Inc. and other contributors.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of Spree Commerce Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
_This software is provided by the copyright holders and contributors "as is" and any express or implied warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are disclaimed. In no event shall the copyright owner of contributors be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage._

View File

@@ -8,9 +8,8 @@ module Stripe
stripe_account: stripe_account_id)
raise_if_last_payment_error_present(payment_intent_response)
raise_if_not_in_capture_state(payment_intent_response)
payment_intent_id
payment_intent_response
end
private
@@ -21,12 +20,5 @@ module Stripe
raise Stripe::StripeError, payment_intent_response.last_payment_error.message
end
def raise_if_not_in_capture_state(payment_intent_response)
state = payment_intent_response.status
return unless state != 'requires_capture'
raise Stripe::StripeError, I18n.t(:invalid_payment_state, state: state)
end
end
end

View File

@@ -18,56 +18,49 @@ module SampleData
fruit = Spree::Taxon.find_by(name: 'Fruit')
fungi = Spree::Taxon.find_by(name: 'Fungi')
producers = enterprises.select(&:is_primary_producer)
distributors = enterprises.select(&:is_distributor)
[
{
name: 'Garlic',
price: 20.00,
supplier: producers[0],
taxons: [vegetables],
distributor: distributors[0]
},
{
name: 'Fuji Apple',
price: 5.00,
supplier: producers[1],
taxons: [fruit],
distributor: distributors[0]
},
{
name: 'Mushrooms',
price: 50.00,
supplier: producers[1],
taxons: [fungi],
distributor: distributors[0]
},
{
name: 'Carrots',
price: 3.00,
supplier: producers[2],
taxons: [vegetables],
distributor: distributors[0]
},
{
name: 'Potatoes',
price: 2.00,
supplier: producers[2],
taxons: [vegetables],
distributor: distributors[0]
},
{
name: 'Tomatoes',
price: 2.00,
supplier: producers[2],
taxons: [vegetables],
distributor: distributors[0]
}
]
end
def create_product(hash)
log "- #{hash[:name]}"
params = hash.merge(
params = hash.slice(:name, :price).merge(
supplier_id: hash[:supplier].id,
primary_taxon_id: hash[:taxons].first.id,
variant_unit: "weight",

View File

@@ -25,11 +25,7 @@ Usage: $0 openfoodnetwork@openfoodnetwork.org.au" >&2
exit 1
fi
if hash zeus 2>/dev/null && [ -e .zeus.sock ]; then
RAILS_RUN='zeus r'
else
RAILS_RUN='bundle exec rails runner'
fi
RAILS_RUN='bundle exec rails runner'
# -- Mirror database
echo "Mirroring database..."

View File

@@ -18,7 +18,6 @@ RED='\033[0;31m'
NO_COLOR='\033[0m'
RUBY_VERSION=$(cat .ruby-version)
NODE_VERSION=$(cat .node-version)
# Check ruby version
if ! ruby --version | grep $RUBY_VERSION > /dev/null; then
@@ -26,12 +25,6 @@ if ! ruby --version | grep $RUBY_VERSION > /dev/null; then
exit 1
fi
# Check node version
if ! node --version | grep $NODE_VERSION > /dev/null; then
printf "${RED}Open Food Network requires node ${NODE_VERSION}${NO_COLOR}. Have a look at: https://github.com/nodenv/nodenv\n"
exit 1
fi
# Set up Ruby dependencies via Bundler
if ! command -v bundle > /dev/null; then
./script/install-bundler
@@ -39,7 +32,7 @@ fi
# Install all dependencies
bundle check || bundle install
npm install
yarn install
# Set up configurable environment variables
if [ ! -f config/application.yml ]; then
@@ -47,12 +40,6 @@ if [ ! -f config/application.yml ]; then
printf "${YELLOW}Copied config/application.yml Make sure to fill it with the appropriate configuration values.\n\n${NO_COLOR}"
fi
# Set up newrelic.yml for development environment, used by the newrelic_rpm gem
if [ ! -f config/newrelic.yml ]; then
cp config/newrelic.yml.example config/newrelic.yml
printf "${YELLOW}Copied config/newrelic.yml which configures the development environment for the newrelic_rpm gem.\n\n${NO_COLOR}"
fi
# Set up the database for both development and test
# Confirming the default user and password
printf '\n\n' | bundle exec rake db:setup db:test:prepare

View File

@@ -212,7 +212,7 @@ describe Admin::BulkLineItemsController, type: :controller do
expect(line_item1.order).to receive(:reload).with(lock: true)
expect(line_item1.order).to receive(:update_line_item_fees!)
expect(line_item1.order).to receive(:update_order_fees!)
expect(line_item1.order).to receive(:update!).twice
expect(line_item1.order).to receive(:update_order!).twice
spree_put :update, params
end
@@ -287,6 +287,112 @@ describe Admin::BulkLineItemsController, type: :controller do
end
end
context "updating the order's taxes, fees, and states" do
let(:distributor) { create(:distributor_enterprise_with_tax) }
let!(:order_cycle) {
create(:order_cycle, distributors: [distributor],
coordinator_fees: [line_item_fee1, line_item_fee2, order_fee])
}
let(:outgoing_exchange) { order_cycle.exchanges.outgoing.first }
let!(:order) {
create(:order_with_line_items, line_items_count: 2, distributor: distributor, order_cycle: order_cycle)
}
let(:line_item1) { order.line_items.first }
let(:line_item2) { order.line_items.last }
let!(:zone) { create(:zone_with_member) }
let(:tax_included) { true }
let(:tax_rate5) { create(:tax_rate, amount: 0.05, zone: zone, included_in_price: tax_included) }
let(:tax_rate10) { create(:tax_rate, amount: 0.10, zone: zone, included_in_price: tax_included) }
let(:tax_rate15) { create(:tax_rate, amount: 0.15, zone: zone, included_in_price: tax_included) }
let(:tax_cat5) { create(:tax_category, tax_rates: [tax_rate5]) }
let(:tax_cat10) { create(:tax_category, tax_rates: [tax_rate10]) }
let(:tax_cat15) { create(:tax_category, tax_rates: [tax_rate15]) }
let!(:shipping_method) {
create(:shipping_method_with, :shipping_fee, tax_category: tax_cat5, name: "Shiperoo",
distributors: [distributor])
}
let!(:payment_method) { create(:payment_method, :per_item, distributors: [distributor]) }
let(:line_item_fee1) {
create(:enterprise_fee, :per_item, amount: 1, inherits_tax_category: false, tax_category: tax_cat15)
}
let(:line_item_fee2) {
create(:enterprise_fee, :per_item, amount: 2, inherits_tax_category: true)
}
let(:order_fee) { create(:enterprise_fee, :flat_rate, amount: 3, tax_category: tax_cat15 ) }
before do
outgoing_exchange.variants << [line_item1.variant, line_item2.variant]
allow(order).to receive(:tax_zone) { zone }
line_item1.product.update_columns(tax_category_id: tax_cat5.id)
line_item2.product.update_columns(tax_category_id: tax_cat10.id)
order.refresh_shipment_rates
order.select_shipping_method(shipping_method.id)
order.finalize!
order.recreate_all_fees!
order.create_tax_charge!
order.update_order!
order.payments << create(:payment, payment_method: payment_method, amount: order.total, state: "completed")
allow(controller).to receive(:spree_current_user) { distributor.owner }
allow(Spree::LineItem).to receive(:find) { line_item1 }
allow(line_item1).to receive(:order) { order }
end
describe "updating a line item" do
let(:line_item_params) { { quantity: 3 } }
let(:params) { { id: line_item1.id, order_id: order.number, line_item: line_item_params } }
it "correctly updates order totals and states" do
expect(order.total).to eq 35.0
expect(order.item_total).to eq 20.0
expect(order.adjustment_total).to eq 15.0
expect(order.included_tax_total).to eq 1.22
expect(order.payment_state).to eq "paid"
expect(order).to receive(:update_order!).at_least(:once).and_call_original
expect(order).to receive(:create_tax_charge!).at_least(:once).and_call_original
spree_put :update, params
order.reload
expect(order.total).to eq 61.0
expect(order.item_total).to eq 40.0
expect(order.adjustment_total).to eq 21.0
expect(order.included_tax_total).to eq 2.65 # Pending: this should be 3.10!
expect(order.payment_state).to eq "balance_due"
end
end
describe "deleting a line item" do
let(:params) { { id: line_item1.id, order_id: order.number } }
it "correctly updates order totals and states" do
expect(order.total).to eq 35.0
expect(order.item_total).to eq 20.0
expect(order.adjustment_total).to eq 15.0
expect(order.included_tax_total).to eq 1.22
expect(order.payment_state).to eq "paid"
expect(order).to receive(:update_order!).at_least(:once).and_call_original
expect(order).to receive(:create_tax_charge!).at_least(:once).and_call_original
spree_delete :destroy, params
order.reload
expect(order.total).to eq 22.0
expect(order.item_total).to eq 10.0
expect(order.adjustment_total).to eq 12.0
expect(order.included_tax_total).to eq 0.99
expect(order.payment_state).to eq "credit_owed"
end
end
end
private
def line_item_ids

View File

@@ -31,7 +31,7 @@ describe Api::V0::EnterprisesController, type: :controller do
it "creates as sells=any when it is not a producer" do
api_post :create, { enterprise: new_enterprise_params }
expect(response).to be_success
expect(response.status).to eq 201
enterprise = Enterprise.last
expect(enterprise.sells).to eq('any')
@@ -44,7 +44,7 @@ describe Api::V0::EnterprisesController, type: :controller do
enterprise: new_enterprise_params.
merge({ user_ids: [enterprise_owner.id, manager1.id, manager2.id] })
}
expect(response).to be_success
expect(response.status).to eq 201
enterprise = Enterprise.last
expect(enterprise.user_ids).to match_array([enterprise_owner.id, manager1.id, manager2.id])
@@ -83,7 +83,7 @@ describe Api::V0::EnterprisesController, type: :controller do
it "I can update enterprise image" do
api_post :update_image, logo: 'a logo', id: enterprise.id
expect(response).to be_success
expect(response.status).to eq 200
end
end
end

View File

@@ -30,7 +30,7 @@ module Api
it "removes logo" do
spree_delete :destroy, enterprise_id: enterprise
expect(response).to be_success
expect(response.status).to eq 200
expect(json_response["id"]).to eq enterprise.id
enterprise.reload
expect(enterprise.logo?).to be false
@@ -53,7 +53,7 @@ module Api
it "allows removal of logo" do
spree_delete :destroy, enterprise_id: enterprise
expect(response).to be_success
expect(response.status).to eq 200
end
end
@@ -62,7 +62,7 @@ module Api
it "allows removal of logo" do
spree_delete :destroy, enterprise_id: enterprise
expect(response).to be_success
expect(response.status).to eq 200
end
end

View File

@@ -164,6 +164,7 @@ describe Api::V0::ProductsController, type: :controller do
context 'as an enterprise user' do
let(:current_api_user) { supplier_enterprise_user(supplier) }
let!(:variant) { create(:variant, product_id: product.id) }
it 'responds with a successful response' do
spree_post :clone, product_id: product.id, format: :json
@@ -183,6 +184,27 @@ describe Api::V0::ProductsController, type: :controller do
expect(response.status).to eq(201)
expect(json_response['name']).to eq("COPY OF #{product_with_image.name}")
end
# test cases related to bug #660: product duplication clones master variant
# stock info - clone is set to zero
it '(does not) clone the stock info of the product' do
spree_post :clone, product_id: product.id, format: :json
expect(json_response['on_hand']).to eq(0)
end
# variants: only the master variant of the product is cloned
it '(does not) clone variants from a product with several variants' do
spree_post :clone, product_id: product.id, format: :json
expect(Spree::Product.second.variants.count).not_to eq Spree::Product.first.variants.count
end
#price info: it does not consider price changes; it considers the price set upon product creation
it '(does not) clone price which was updated' do
product.update_attribute(:price, 2.22)
spree_post :clone, product_id: product.id, format: :json
expect(json_response['price']).not_to eq(2.22)
end
end
context 'as an administrator' do

View File

@@ -30,7 +30,7 @@ module Api
it "removes promo image" do
spree_delete :destroy, enterprise_id: enterprise
expect(response).to be_success
expect(response.status).to eq 200
expect(json_response["id"]).to eq enterprise.id
enterprise.reload
expect(enterprise.promo_image?).to be false
@@ -53,7 +53,7 @@ module Api
it "allows removal of promo image" do
spree_delete :destroy, enterprise_id: enterprise
expect(response).to be_success
expect(response.status).to eq 200
end
end
@@ -62,7 +62,7 @@ module Api
it "allows removal of promo image" do
spree_delete :destroy, enterprise_id: enterprise
expect(response).to be_success
expect(response.status).to eq 200
end
end

View File

@@ -176,7 +176,88 @@ describe Api::V0::ShipmentsController, type: :controller do
end
end
context "can transition a shipment from ready to ship" do
describe "#update" do
let!(:distributor) { create(:distributor_enterprise) }
let!(:shipping_method1) {
create(:shipping_method_with, :flat_rate, distributors: [distributor], amount: 10)
}
let!(:shipping_method2) {
create(:shipping_method_with, :flat_rate, distributors: [distributor], amount: 20)
}
let!(:order_cycle) { create(:order_cycle, distributors: [distributor]) }
let!(:order) {
create(:completed_order_with_totals, order_cycle: order_cycle, distributor: distributor)
}
let(:new_shipping_rate) {
order.shipment.shipping_rates.select{ |sr| sr.shipping_method == shipping_method2 }.first
}
let(:params) {
{
id: order.shipment.number,
order_id: order.number,
shipment: {
selected_shipping_rate_id: new_shipping_rate.id
}
}
}
before do
order.shipments.first.shipping_methods = [shipping_method1, shipping_method2]
order.select_shipping_method(shipping_method1.id)
order.update_order!
order.update_columns(
payment_total: 60,
payment_state: "paid"
)
end
context "when an order has multiple shipping methods available which could be chosen" do
context "changing the selected shipping method" do
it "updates the order's totals and states" do
expect(order.shipment.shipping_method).to eq shipping_method1
expect(order.shipment.cost).to eq 10
expect(order.total).to eq 60 # item total is 50, shipping cost is 10
expect(order.payment_state).to eq "paid" # order is fully paid for
api_put :update, params
expect(response.status).to eq 200
order.reload
expect(order.shipment.shipping_method).to eq shipping_method2
expect(order.shipment.cost).to eq 20
expect(order.total).to eq 70 # item total is 50, shipping cost is 20
expect(order.payment_state).to eq "balance_due" # total changed, payment is due
end
context "using the 'unlock' parameter with closed adjustments" do
before do
order.shipment_adjustments.each(&:close)
end
it "does not update closed adjustments without unlock option" do
params[:shipment][:unlock] = "no"
expect {
api_put :update, params
expect(response.status).to eq 200
}.to_not change { order.reload.shipment.fee_adjustment.amount }
end
it "updates closed adjustments with unlock option selected" do
params[:shipment][:unlock] = "yes"
expect {
api_put :update, params
expect(response.status).to eq 200
}.to change { order.reload.shipment.fee_adjustment.amount }
end
end
end
end
end
context "#ship" do
before do
allow_any_instance_of(Spree::Order).to receive_messages(paid?: true, complete?: true)
# For the shipment notification email

View File

@@ -10,21 +10,21 @@ module Api
it "returns alive when up to date" do
Spree::Config.last_job_queue_heartbeat_at = Time.now.in_time_zone
get :job_queue
expect(response).to be_success
expect(response.status).to eq 200
expect(response.body).to eq({ alive: true }.to_json)
end
it "returns dead otherwise" do
Spree::Config.last_job_queue_heartbeat_at = 10.minutes.ago
get :job_queue
expect(response).to be_success
expect(response.status).to eq 200
expect(response.body).to eq({ alive: false }.to_json)
end
it "returns dead when no heartbeat recorded" do
Spree::Config.last_job_queue_heartbeat_at = nil
get :job_queue
expect(response).to be_success
expect(response.status).to eq 200
expect(response.body).to eq({ alive: false }.to_json)
end
end

View File

@@ -26,7 +26,7 @@ module Api
it "removes terms and conditions file" do
spree_delete :destroy, enterprise_id: enterprise
expect(response).to be_success
expect(response.status).to eq 200
expect(json_response["id"]).to eq enterprise.id
enterprise.reload
expect(enterprise.terms_and_conditions?).to be false

View File

@@ -118,7 +118,7 @@ describe CheckoutController, type: :controller do
it "does not redirect" do
get :edit
expect(response).to be_success
expect(response.status).to eq 200
end
it "returns a specific flash message when Spree::Core::GatewayError occurs" do
@@ -291,7 +291,7 @@ describe CheckoutController, type: :controller do
allow(controller).to receive(:current_order).and_return(order)
end
it "returns errors and flash if order.update_attributes fails" do
it "returns errors and flash if order.update fails" do
spree_post :update, format: :json, order: {}
expect(response.status).to eq(400)
expect(response.body).to eq({ errors: assigns[:order].errors, flash: { error: order.errors.full_messages.to_sentence } }.to_json)

View File

@@ -55,7 +55,7 @@ describe LineItemsController, type: :controller do
context "where the item's order is associated with the current user" do
before do
order.update_attributes!(user_id: user.id)
order.update!(user_id: user.id)
allow(controller).to receive_messages spree_current_user: item.order.user
end
@@ -67,7 +67,7 @@ describe LineItemsController, type: :controller do
end
context "with an order cycle and distributor" do
before { order.update_attributes!(order_cycle_id: order_cycle.id, distributor_id: distributor.id) }
before { order.update!(order_cycle_id: order_cycle.id, distributor_id: distributor.id) }
context "where changes are not allowed" do
it "denies deletion" do
@@ -77,7 +77,7 @@ describe LineItemsController, type: :controller do
end
context "where changes are allowed" do
before { distributor.update_attributes!(allow_order_changes: true) }
before { distributor.update!(allow_order_changes: true) }
it "deletes the line item" do
delete :destroy, params: params

View File

@@ -36,7 +36,7 @@ describe ShopController, type: :controller do
oc2 = create(:simple_order_cycle, distributors: [distributor])
spree_post :order_cycle, order_cycle_id: oc2.id
expect(response).to be_success
expect(response.status).to eq 200
expect(controller.current_order_cycle).to eq(oc2)
end
@@ -48,7 +48,7 @@ describe ShopController, type: :controller do
oc2 = create(:simple_order_cycle, distributors: [distributor])
spree_post :order_cycle, order_cycle_id: oc2.id
expect(response).to be_success
expect(response.status).to eq 200
expect(response.body).to have_content oc2.id
end
@@ -68,7 +68,7 @@ describe ShopController, type: :controller do
it "returns the new order cycle details" do
spree_post :order_cycle, order_cycle_id: oc2.id
expect(response).to be_success
expect(response.status).to eq 200
expect(response.body).to have_content oc2.id
end
end

View File

@@ -8,7 +8,7 @@ describe Spree::Admin::PaymentsController, type: :controller do
let!(:shop) { create(:enterprise) }
let!(:user) { shop.owner }
let!(:order) { create(:order, distributor: shop, state: 'complete') }
let!(:order) { create(:completed_order_with_totals, distributor: shop) }
let!(:line_item) { create(:line_item, order: order, price: 5.0) }
before do

View File

@@ -309,5 +309,19 @@ describe Spree::Admin::PaymentsController, type: :controller do
end
end
end
context "the order contains an item that is out of stock" do
let!(:order) { create(:order, distributor: shop, state: 'payment') }
before do
order.line_items.first.variant.update_attribute(:on_hand, 0)
end
it "redirects to the order details page" do
spree_get :index, order_id: order.number
expect(response.status).to eq 302
expect(response.location).to eq spree.edit_admin_order_url(order)
end
end
end
end

View File

@@ -17,7 +17,7 @@ module Spree
# Pay the order
order.payments.first.complete
order.update!
order.update_order!
# Ship the order
order.shipment.ship!

View File

@@ -24,7 +24,7 @@ describe Spree::OrdersController, type: :controller do
it "loads page" do
get :show, params: { id: order.number, token: order.token }
expect(response).to be_success
expect(response.status).to eq 200
end
it "stores order token in session as 'access_token'" do
@@ -43,7 +43,7 @@ describe Spree::OrdersController, type: :controller do
it "loads page" do
get :show, params: { id: order.number }
expect(response).to be_success
expect(response.status).to eq 200
end
end
@@ -52,7 +52,7 @@ describe Spree::OrdersController, type: :controller do
it "loads page" do
get :show, params: { id: order.number }
expect(response).to be_success
expect(response.status).to eq 200
end
end
@@ -82,7 +82,10 @@ describe Spree::OrdersController, type: :controller do
describe "confirming a payment intent" do
let(:customer) { create(:customer) }
let(:order) { create(:order, customer: customer, distributor: customer.enterprise) }
let(:order) {
create(:order_with_totals, customer: customer, distributor: customer.enterprise,
state: "payment")
}
let(:payment_method) { create(:stripe_sca_payment_method) }
let!(:payment) { create(
:payment,
@@ -102,39 +105,66 @@ describe Spree::OrdersController, type: :controller do
context "with a valid payment intent" do
let(:payment_intent) { "pi_123" }
let(:payment_intent_response) { double(id: "pi_123", status: "requires_capture") }
before do
allow_any_instance_of(Stripe::PaymentIntentValidator)
.to receive(:call)
.with(payment_intent, anything)
.and_return(payment_intent)
.with(payment_intent, kind_of(String))
.and_return(payment_intent_response)
allow(Spree::Order).to receive(:find_by!) { order }
end
it "completes the payment" do
get :show, params: { id: order.number, payment_intent: payment_intent }
context "when the order is in payment state" do
it "completes the payment" do
expect(order).to receive(:process_payments!) do
payment.complete!
end
expect(response).to be_success
payment.reload
expect(payment.cvv_response_message).to be nil
expect(payment.state).to eq("completed")
get :show, params: { id: order.number, payment_intent: payment_intent }
expect(response.status).to eq 200
payment.reload
expect(payment.state).to eq("completed")
expect(payment.cvv_response_message).to be nil
end
end
context "when the order is already completed" do
before do
order.update_columns(state: "complete")
end
it "should still process the payment" do
expect(order).to receive(:process_payments!) do
payment.complete!
end
get :show, params: { id: order.number, payment_intent: payment_intent }
expect(response.status).to eq 200
payment.reload
expect(payment.state).to eq("completed")
expect(payment.cvv_response_message).to be nil
end
end
end
context "with an invalid payment intent" do
let(:payment_intent) { "invalid" }
let(:result) { instance_double(ProcessPaymentIntent::Result) }
context "when the payment intent response has errors" do
let(:payment_intent) { "pi_123" }
before do
allow_any_instance_of(Stripe::PaymentIntentValidator)
.to receive(:call)
.with(payment_intent, anything)
.and_return(result)
.with(payment_intent, kind_of(String))
.and_raise(Stripe::StripeError, "error message")
end
it "does not complete the payment" do
get :show, params: { id: order.number, payment_intent: payment_intent }
expect(response).to be_success
expect(flash[:error]).to eq("#{I18n.t("payment_could_not_process")}. error message")
payment.reload
expect(payment.cvv_response_message).to eq("https://stripe.com/redirect")
expect(payment.state).to eq("pending")
@@ -148,12 +178,18 @@ describe Spree::OrdersController, type: :controller do
before do
allow(payment).to receive(:response_code).and_return("invalid")
allow(OrderPaymentFinder).to receive(:new).with(order).and_return(finder)
allow_any_instance_of(Stripe::PaymentIntentValidator)
.to receive(:call)
.with(payment_intent, kind_of(String))
.and_return(payment_intent)
end
it "does not complete the payment" do
get :show, params: { id: order.number, payment_intent: payment_intent }
expect(response).to be_success
expect(response.status).to eq 200
expect(flash[:error]).to eq("#{I18n.t("payment_could_not_process")}. ")
payment.reload
expect(payment.cvv_response_message).to eq("https://stripe.com/redirect")
expect(payment.state).to eq("pending")
@@ -219,10 +255,6 @@ describe Spree::OrdersController, type: :controller do
describe "the page" do
render_views
it "provides the right registration path" do
expect(subject.registration_path).to eq registration_path
end
it "shows the right registration link" do
# We fixed our view by hardcoding the link.
spree_registration_path = '/signup'
@@ -497,7 +529,7 @@ describe Spree::OrdersController, type: :controller do
end
before do
order.update_attributes!(order_cycle_id: order_cycle.id, distributor_id: distributor.id)
order.update!(order_cycle_id: order_cycle.id, distributor_id: distributor.id)
end
it "returns the order" do

View File

@@ -15,7 +15,7 @@ describe UserPasswordsController, type: :controller do
describe "create" do
it "returns errors" do
spree_post :create, spree_user: {}
expect(response).to be_success
expect(response.status).to eq 200
expect(response).to render_template "spree/user_passwords/new"
end

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