Compare commits

...

390 Commits

Author SHA1 Message Date
Matt-Yorkley
c54e7adf97 Re-apply updated translations to release v3.4.2 2020-11-24 12:34:19 +00:00
Matt-Yorkley
5429bd8d7a Update all locales with the latest Transifex translations 2020-11-19 23:13:09 +00:00
Matt-Yorkley
300e87648b Merge pull request #6394 from openfoodfoundation/transifex
Transifex
2020-11-20 00:11:03 +01:00
Matt-Yorkley
4a9ac62d91 Merge branch 'master' into transifex 2020-11-20 00:10:48 +01:00
Luis Ramos
d7a1d7769c Merge pull request #6258 from luisramos0/s3_with_region
Upgrade aws-sdk and switch to S3 virtual host style URLs
2020-11-19 22:59:57 +00:00
Transifex-Openfoodnetwork
cd20d2612d Updating translations for config/locales/cy.yml 2020-11-19 22:09:04 +11:00
Transifex-Openfoodnetwork
446007e283 Updating translations for config/locales/cy.yml 2020-11-19 22:05:56 +11:00
Transifex-Openfoodnetwork
7bc59512fd Updating translations for config/locales/cy.yml 2020-11-19 22:02:49 +11:00
Pau Pérez Fabregat
8c9960854f Merge pull request #6343 from Matt-Yorkley/api-controllers
API controllers: strong paramaters
2020-11-19 09:04:16 +01:00
Transifex-Openfoodnetwork
9fc3ff0250 Updating translations for config/locales/en_GB.yml 2020-11-19 05:14:36 +11:00
Transifex-Openfoodnetwork
7ddbc10c19 Updating translations for config/locales/en_GB.yml 2020-11-19 05:11:27 +11:00
Matt-Yorkley
b0a70f0ba3 Improve TaxonController strong params handling 2020-11-17 19:48:27 +00:00
Matt-Yorkley
0b18b0dc0a Include Calculator attributes in PaymentMethod nested attributes and DRY repeated code 2020-11-17 19:04:26 +00:00
Matt-Yorkley
d225294b6b Extract to PermittedAttributes::Calculator 2020-11-17 18:51:48 +00:00
Matt-Yorkley
3547b9fe56 Add missing calculator params 2020-11-17 18:51:48 +00:00
Matt-Yorkley
1766f33d46 Use ActionController::Metal and include StrongParameters 2020-11-17 18:51:48 +00:00
Matt-Yorkley
cbdb6126a6 Fix strong_params in API enterprises_controller 2020-11-17 18:51:48 +00:00
Matt-Yorkley
6a26c9da8c Fix strong_params in API products_controller 2020-11-17 18:51:48 +00:00
Matt-Yorkley
36f4f40e84 Refactor and fix PaymentMethod strong params 2020-11-17 18:51:48 +00:00
Matt-Yorkley
787f29105c Fix ForbiddenAttribute errors for bulk update of enterprise fees and order cycles
Example error:
As an administrator
    I want to manage simple order cycles
 updating many order cycle opening/closing times at once
     Failure/Error: raise ActiveModel::ForbiddenAttributesError, params.to_s

     ActiveModel::ForbiddenAttributesError:
       {"order_cycle_set"=>{"collection_attributes"=>{"0"=>{"id"=>62, "name"=>"Updated Order Cycle 1", "orders_open_at"=>"2040-12-01 12:00:00", "orders_close_at"=>"2040-12-01 12:00:01"}, "1"=>{"id"=>63, "name"=>"Updated Order Cycle 2", "orders_open_at"=>"2040-12-01 12:00:02", "orders_close_at"=>"2040-12-01 12:00:03"}, "2"=>{"id"=>64, "name"=>"Updated Order Cycle 3", "orders_open_at"=>"2040-12-01 12:00:04", "orders_close_at"=>"2040-12-01 12:00:05"}}}, "controller"=>"admin/order_cycles", "action"=>"bulk_update", "format"=>"json", "order_cycle"=>{}}
     # ./app/controllers/application_controller.rb:20:in `print_params'
     # ./lib/open_food_network/rack_request_blocker.rb:36:in `call'
     # ------------------
     # --- Caused by: ---
     # ActiveModel::ForbiddenAttributesError:
     #   ActiveModel::ForbiddenAttributesError
     #   ./app/models/model_set.rb:29:in `block in collection_attributes='
2020-11-17 18:51:48 +00:00
Matt-Yorkley
642a294844 Fix broken order edit shipment
As an administrator
    I want to create and edit orders
 as an enterprise manager viewing the edit page with different shipping methods can edit shipping method
     Failure/Error: expect(page).to have_content "Shipping: #{different_shipping_method_for_distributor1.name}"
       expected to find text "Shipping: Different" in "Logged in as : owen@romaguera.ca Account Logout Store DASHBOARD PRODUCTS ORDER CYCLES ORDERS REPORTS ENTERPRISES CUSTOMERS Order # R813516688 CANCEL ACTIONS BACK TO ORDER LIST John Doe - ADD PRODUCT NAME OR SKU (ENTER AT LEAST FIRST 4 CHARACTERS OF PRODUCT NAME) Select a variant 100 - PENDING ITEM DESCRIPTION PRICE QUANTITY TOTAL Product #3 - 9924 - 1g, S $10.00 1 x none $10.00 Product #4 - 5548 - 1g, S $10.00 1 x none $10.00 Product #5 - 8080 - 1g, S $10.00 1 x none $10.00 Product #6 - 3591 - 1g, S $10.00 1 x none $10.00 Product #7 - 6461 - 1g, S $10.00 1 x none $10.00 Product #8 - 4071 - 1g, S $110.00 1 x none $110.00 SHIPPING METHOD Different $0.00 Normal $0.00 Different $0.00 Tracking: U10000 LINE ITEM ADJUSTMENTS NAME AMOUNT Tax 1 10.0%: $10.00 ORDER ADJUSTMENTS NAME AMOUNT Transaction fee: $0.00 ORDER TOTAL $160.00 DISTRIBUTION Distributor: Enterprise 4 Order cycle: Order Cycle 2 UPDATE AND RECALCULATE FEES or BACK ORDER INFORMATION STATUS COMPLETE TOTAL : $160.00 SHIPMENT : PENDING PAYMENT : BALANCE DUE DATE COMPLETED : November 08, 2020 1:51 AM ORDER DETAILS CUSTOMER DETAILS ADJUSTMENTS PAYMENTS RETURN AUTHORIZATIONS"
     # ./spec/features/admin/order_spec.rb:291:in `block (5 levels) in <top (required)>'
2020-11-17 18:51:48 +00:00
Matt-Yorkley
7401e34c52 Fix credit cards strong params 2020-11-17 18:51:48 +00:00
Matt-Yorkley
ca41bbcee7 Fix Api::VariantsController ForbiddenAttributesError 2020-11-17 18:51:48 +00:00
Matt-Yorkley
c374bf5e49 Fix strong_params in API taxons_controller 2020-11-17 18:51:48 +00:00
Matt-Yorkley
417c4d9aea Inherit from ActionController::Base in API Controllers 2020-11-17 18:51:48 +00:00
Maikel Linke
315a5f0fd9 Update translations 2020-11-17 10:17:08 +11:00
Transifex-Openfoodnetwork
4ca8c220e9 Updating translations for config/locales/fr_CA.yml 2020-11-17 09:06:27 +11:00
Transifex-Openfoodnetwork
442dbaa7d7 Updating translations for config/locales/en_CA.yml 2020-11-17 08:49:15 +11:00
Matt-Yorkley
c080c1f1d6 Merge pull request #6382 from Matt-Yorkley/menu-fix
Fix the user menu
2020-11-16 22:20:12 +01:00
Matt-Yorkley
3b92df42c3 Fix the menu!
🙈
2020-11-16 19:05:08 +00:00
Matt-Yorkley
e2dbb150e5 Update all locales with the latest Transifex translations 2020-11-16 16:02:40 +00:00
Luis Ramos
ca29604ff8 Merge pull request #6377 from luisramos0/repeat_calculator_migrations
Repeat calculator migrations to clean up existing data
2020-11-16 10:46:42 +00:00
Transifex-Openfoodnetwork
57bc146de9 Updating translations for config/locales/it.yml 2020-11-14 21:08:20 +11:00
Luis Ramos
e5b7c036d5 Repeat calculator migrations to clean up existing data 2020-11-13 16:35:22 +00:00
Pau Pérez Fabregat
6f1d8664ac Merge pull request #6355 from coopdevs/install-gems-on-docker-boot
Install any missing gems when booting docker
2020-11-13 13:32:27 +01:00
Pau Pérez Fabregat
8d5e90e40f Merge pull request #6365 from Matt-Yorkley/mail-settings
Allow mail_auth_type to be set
2020-11-13 13:30:17 +01:00
Pau Pérez Fabregat
6db80e837b Merge pull request #6361 from andrewpbrett/fix-gateway-error-error
move gateway_error require to lib/spree/core.rb
2020-11-13 13:15:13 +01:00
Matt-Yorkley
cec295a113 Merge pull request #6373 from andrewpbrett/fix-admin-users
specify Spree routes for pagination, fix 500 on admin/users
2020-11-13 11:30:16 +01:00
Maikel Linke
a553547403 Update translations 2020-11-13 14:15:45 +11:00
Maikel
1e4edc671a Merge pull request #6364 from openfoodfoundation/transifex
Transifex
2020-11-13 14:05:12 +11:00
Maikel
b2113c96a2 Merge pull request #6317 from openfoodfoundation/dependabot/bundler/kaminari-0.17.0
Bump kaminari from 0.14.1 to 0.17.0
2020-11-13 13:58:25 +11:00
Maikel
408103516e Merge pull request #6321 from openfoodfoundation/dependabot/bundler/awesome_nested_set-3.2.1
Bump awesome_nested_set from 3.0.3 to 3.2.1
2020-11-13 13:30:18 +11:00
Maikel
d96216b8d7 Merge pull request #6268 from yihyang/master-yy-added-product-sorting
Sort products alphabetically in OC edit/create page
2020-11-13 13:29:54 +11:00
Maikel
d4ff9055c0 Merge pull request #6351 from efgalvao/issue#6249
Fixes Issue#6249
2020-11-13 13:28:55 +11:00
Maikel
591ba34eb6 Merge pull request #6335 from cillian/reset-on-demand-on-inventory-import
When resetting stock to 0 on absent products in inventory import also reset the on demand setting
2020-11-13 13:28:17 +11:00
Andy Brett
8dfd3f624d paginate zones using spree routes as well 2020-11-12 14:24:04 -08:00
Andy Brett
9cf30b431a specify Spree routes for pagination 2020-11-12 14:09:59 -08:00
Pau Pérez Fabregat
777cedd90d Merge pull request #6305 from efgalvao/issue#6292
Fixed issue #6292.
2020-11-12 17:42:42 +01:00
Transifex-Openfoodnetwork
b80d15b672 Updating translations for config/locales/pt_BR.yml 2020-11-13 02:43:56 +11:00
Transifex-Openfoodnetwork
228c7cc13a Updating translations for config/locales/pt_BR.yml 2020-11-13 02:40:55 +11:00
Pau Pérez Fabregat
7c4691ab33 Merge pull request #6339 from andrewpbrett/fix-instance-unit-picker
Fix #6304 (Product edit: Cannot change Variant unit scale of an existing product)
2020-11-12 16:15:00 +01:00
Pau Pérez Fabregat
692adb0113 Merge pull request #6336 from coopdevs/fix-shop-layout
Fix .top-bar-section not to wrap the icons-menu
2020-11-11 17:29:53 +01:00
Matt-Yorkley
58e34b5ad6 Allow mail_auth_type to be set 2020-11-11 15:51:08 +00:00
Transifex-Openfoodnetwork
694bc6a598 Updating translations for config/locales/ar.yml 2020-11-12 02:18:05 +11:00
Transifex-Openfoodnetwork
e06b82f335 Updating translations for config/locales/ar.yml 2020-11-12 02:14:55 +11:00
Andy Brett
17202ff39c move gateway_error require to lib/spree/core.rb 2020-11-10 14:55:56 -08:00
Andy Brett
d5037abbe7 add specs for new/edit product pages 2020-11-10 10:49:14 -08:00
Pau Perez
5ddfc54b2b Install any missing gems when booting docker
This runs `bundle install` if there are any missing gems when booting
the containers. `bundle check` ensures we don't unnecessarily run
`bundle install`, which is rather slow.

This avoids having to build the entire image (painfully slow) or having
to bring up a container just to install the gems. I used to do this
with `docker-compose run --rm web bundle install`.
2020-11-10 18:08:34 +01:00
Pau Pérez Fabregat
bea8982085 Merge pull request #6329 from openfoodfoundation/transifex
Transifex
2020-11-10 17:37:00 +01:00
Pau Pérez Fabregat
fc06cc242b Merge pull request #6210 from ipalo/feature/update-docker-image-to-ubuntu-20-04
Update the base Ubuntu Docker image from 18.04 to 20.04
2020-11-10 17:30:03 +01:00
Pau Pérez Fabregat
b70c349b05 Merge pull request #6352 from openfoodfoundation/dependabot/bundler/webmock-3.9.5
Bump webmock from 3.9.4 to 3.9.5
2020-11-10 16:47:44 +01:00
Pau Perez
634ab5ca6a Don't scale logo image
The trick using `width: 100%` and a set `max-width` doesn't work if we
can't know the image width as it can be uploaded by superadmins. There's
no need though because the media query breakpoint triggers just before that.
2020-11-10 09:51:41 +01:00
Matt-Yorkley
a802fe29be Fix typo in initializer 2020-11-10 00:07:06 +00:00
Luis Ramos
88ac5dc955 Fix rubocop issues by refactoring code 2020-11-10 00:03:34 +00:00
Luis Ramos
e879aa1bed Switch to s3_alias_url that enabble virtual host type of path 2020-11-10 00:03:33 +00:00
Luis Ramos
94a815a9ef Upgrade aws-sdk and set s3 host name using the provided url config.
This will enable us to set hostnames with the s3 region defined and that
will make our image upload work for all s3 regions.
2020-11-10 00:03:33 +00:00
Luis Ramos
c7c5a95407 Merge pull request #6345 from Matt-Yorkley/flaky-oc-spec
Improve flaky order cycle spec
2020-11-09 21:59:41 +00:00
dependabot-preview[bot]
1825c90a5f Bump webmock from 3.9.4 to 3.9.5
Bumps [webmock](https://github.com/bblimke/webmock) from 3.9.4 to 3.9.5.
- [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.9.4...v3.9.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-09 19:14:30 +00:00
efgalvao
307b1ca9f9 Fixes Issue#6249 2020-11-09 14:06:37 -03:00
Pau Perez
17abb3e345 Fix feature specs
The underlying markup and CSS changed but the tests did not.
2020-11-09 15:43:54 +01:00
Pau Perez
1903c575ff Reorder properties alphabetically
As Hound demands.
2020-11-09 15:40:25 +01:00
Pau Perez
9a885173b9 Remove element from class selector
Fixes Hound error `Avoid qualifying class selectors with an element.`.
2020-11-09 15:39:09 +01:00
Transifex-Openfoodnetwork
3167e5ae2b Updating translations for config/locales/ru.yml 2020-11-10 01:29:44 +11:00
Transifex-Openfoodnetwork
7f968b2b10 Updating translations for config/locales/ru.yml 2020-11-10 01:26:34 +11:00
Transifex-Openfoodnetwork
b08299e83a Updating translations for config/locales/ru.yml 2020-11-10 01:23:23 +11:00
Matt-Yorkley
d9e2a80a4f Improve flaky order cycle spec
There are various points in this spec where content is dynamically added to the DOM, but Capybara is jumping ahead to start interacting with it before it as actually finished loading.
2020-11-09 11:26:12 +00:00
dependabot-preview[bot]
863702ed4b Bump awesome_nested_set from 3.0.3 to 3.2.1
Bumps [awesome_nested_set](https://github.com/collectiveidea/awesome_nested_set) from 3.0.3 to 3.2.1.
- [Release notes](https://github.com/collectiveidea/awesome_nested_set/releases)
- [Changelog](https://github.com/collectiveidea/awesome_nested_set/blob/master/CHANGELOG)
- [Commits](https://github.com/collectiveidea/awesome_nested_set/commits/v3.2.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-07 08:58:44 +00:00
Luis Ramos
6114dfb4ef Merge pull request #6337 from openfoodfoundation/dependabot/bundler/webmock-3.9.4
Bump webmock from 3.9.3 to 3.9.4
2020-11-07 08:57:13 +00:00
Luis Ramos
f39008f3d3 Merge pull request #6338 from openfoodfoundation/dependabot/bundler/highline-2.0.3
Bump highline from 1.6.18 to 2.0.3
2020-11-07 08:57:02 +00:00
Andy Brett
99301e1fb2 fix #6304 2020-11-06 12:49:07 -08:00
dependabot-preview[bot]
cb0b7ed030 Bump highline from 1.6.18 to 2.0.3
Bumps [highline](https://github.com/JEG2/highline) from 1.6.18 to 2.0.3.
- [Release notes](https://github.com/JEG2/highline/releases)
- [Changelog](https://github.com/JEG2/highline/blob/master/Changelog.md)
- [Commits](https://github.com/JEG2/highline/commits/v2.0.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-06 19:17:11 +00:00
dependabot-preview[bot]
7d9948f5b6 Bump webmock from 3.9.3 to 3.9.4
Bumps [webmock](https://github.com/bblimke/webmock) from 3.9.3 to 3.9.4.
- [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.9.3...v3.9.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-06 19:14:43 +00:00
Transifex-Openfoodnetwork
18a7bdc631 Updating translations for config/locales/de_DE.yml 2020-11-07 05:32:48 +11:00
Transifex-Openfoodnetwork
6083d61ba7 Updating translations for config/locales/de_DE.yml 2020-11-07 05:29:38 +11:00
Transifex-Openfoodnetwork
9e2054dcd4 Updating translations for config/locales/de_DE.yml 2020-11-07 05:26:28 +11:00
Pau Perez
b5f27d48df Fix .top-bar-section not to wrap the icons-menu
This line-wrap makes the icons-menu overlap the OC selector. The menu's
background is transparent, what makes it look even more broken.

The fix involves refactoring the `.top-bar-section` into using flexbox
instead of this highly coupled CSS and floats. With flexbox it becomes
as easy as telling the browser to space the three sections evenly
filling-up the window, while scaling down the logo if there's not enough
room.

The root cause is that every instance uses a custom logo, which wasn't
the one we used while designing and implementing. This is why using
fixed-sizes in pixels won't work.
2020-11-06 17:35:24 +01:00
Cillian O'Ruanaidh
89d63dfbb9 When resetting stock to 0 on absent products in inventory import also reset the on demand setting
Before when you imported inventory and clicked the 'Set stock to zero for all existing products not present in the file' option it would set the on hand stock to 0 but if the variant override was also set to be on demand the inventory would still be available for sale. This change makes sure the on demand setting is turned off too.

Fixes #6289.
2020-11-06 14:57:31 +00:00
Matt-Yorkley
73995d1aff Merge pull request #6334 from Matt-Yorkley/hound2
Switch to rubocop_styleguide.yml as style source
2020-11-06 12:55:23 +01:00
Matt-Yorkley
f5a9c6f3f4 Switch to rubocop_styleguide.yml as style source 2020-11-06 11:53:56 +00:00
Matt-Yorkley
f6aeb04b14 Merge pull request #6322 from Matt-Yorkley/hound
Add HoundCI config
2020-11-06 12:20:03 +01:00
Matt-Yorkley
00320e4387 Use .scss-lint.yml with HoundCI 2020-11-06 10:18:35 +00:00
Matt-Yorkley
ebd7409f70 Add scss-lint configs to .scss-lint.yml 2020-11-06 10:18:34 +00:00
Transifex-Openfoodnetwork
e86d84e10f Updating translations for config/locales/en_FR.yml 2020-11-06 19:26:16 +11:00
Transifex-Openfoodnetwork
b7a503a848 Updating translations for config/locales/fr.yml 2020-11-06 19:26:04 +11:00
Luis Ramos
28570cded2 Update all locales with the latest Transifex translations 2020-11-06 04:20:08 +00:00
Luis Ramos
c0bb9aad5e Merge pull request #6286 from openfoodfoundation/transifex
Transifex
2020-11-06 04:18:56 +00:00
Luis Ramos
b281e7e9e5 Merge pull request #6312 from mkllnk/variant-override-loading
Avoid loading variant overrides for no reason
2020-11-06 03:59:33 +00:00
Matt-Yorkley
3011bdb87d Add HoundCI config 2020-11-06 00:27:32 +00:00
Matt-Yorkley
66b531ddf6 Merge pull request #6310 from luisramos0/acts_as_list
Bump acts_as_list to 0.3.0
2020-11-05 23:03:02 +01:00
Transifex-Openfoodnetwork
213f3cf072 Updating translations for config/locales/ar.yml 2020-11-06 07:43:38 +11:00
Transifex-Openfoodnetwork
e1962419c2 Updating translations for config/locales/ar.yml 2020-11-06 07:40:32 +11:00
Transifex-Openfoodnetwork
bb6f5cb3a7 Updating translations for config/locales/en_US.yml 2020-11-06 07:06:15 +11:00
dependabot-preview[bot]
2d90fa4723 Bump kaminari from 0.14.1 to 0.17.0
Bumps [kaminari](https://github.com/kaminari/kaminari) from 0.14.1 to 0.17.0.
- [Release notes](https://github.com/kaminari/kaminari/releases)
- [Changelog](https://github.com/kaminari/kaminari/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kaminari/kaminari/compare/v0.14.1...v0.17.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-05 19:15:53 +00:00
Matt-Yorkley
db3576f469 Merge pull request #6308 from luisramos0/translations
Fix some missing translations in orders edit page
2020-11-05 18:33:51 +01:00
Matt-Yorkley
c2362921fa Merge pull request #6272 from tsara27/fix-alignment-order
Align center order adjustment and order total title
2020-11-05 18:33:08 +01:00
Matt-Yorkley
0668dd2591 Merge pull request #6307 from efgalvao/issue#6262
Fixes issue #6262.
2020-11-05 18:31:49 +01:00
Matt-Yorkley
d8f9dead8b Merge pull request #6270 from Matt-Yorkley/paperclip-handlers
Remove Paperclip URL handlers
2020-11-05 18:29:20 +01:00
Matt-Yorkley
bc96ad9515 Merge pull request #6299 from Matt-Yorkley/admin-image-edit
Fix display issue in product image edit page
2020-11-05 18:28:10 +01:00
Luis Ramos
bd4da3b5ce Merge pull request #6247 from cillian/deep-munge-issue
Patch Rails :deep_munge issue so empty array parameters don't get converted to nil
2020-11-05 13:25:39 +00:00
Pau Pérez Fabregat
8e3f0d2152 Merge pull request #6134 from Matt-Yorkley/webmock-helper
Improve Webmock debugging
2020-11-05 13:11:02 +01:00
Pau Pérez Fabregat
1ea503ed5d Merge pull request #6306 from SerenaWhite/update-handbook-reference
Update reference to OFN Handbook in README.md
2020-11-05 13:05:39 +01:00
Transifex-Openfoodnetwork
719007ecb4 Updating translations for config/locales/es.yml 2020-11-05 22:57:29 +11:00
Transifex-Openfoodnetwork
bd06f898a3 Updating translations for config/locales/ca.yml 2020-11-05 22:55:21 +11:00
Transifex-Openfoodnetwork
246a1f368b Updating translations for config/locales/de_DE.yml 2020-11-05 21:59:09 +11:00
Transifex-Openfoodnetwork
f6443f00e5 Updating translations for config/locales/en_FR.yml 2020-11-05 19:23:26 +11:00
Transifex-Openfoodnetwork
fd52800d2c Updating translations for config/locales/fr.yml 2020-11-05 19:21:40 +11:00
Maikel Linke
4b1f5ae060 Avoid loading variant overrides for no reason 2020-11-05 14:31:19 +11:00
Transifex-Openfoodnetwork
31a34fc9d2 Updating translations for config/locales/en_NZ.yml 2020-11-05 10:00:28 +11:00
Transifex-Openfoodnetwork
3fc0d1bcb9 Updating translations for config/locales/en_NZ.yml 2020-11-05 09:57:27 +11:00
Luis Ramos
bb89557beb Bump acts_as_list to 0.3.0 2020-11-04 22:13:24 +00:00
Luis Ramos
0ae3bf985a Fix some missing translations in orders edit page 2020-11-04 21:54:27 +00:00
Luis Ramos
387326b9b4 Merge pull request #5978 from luisramos0/bye_bye_spree
Bye bye spree - final PR 🎉
2020-11-04 21:27:28 +00:00
Luis Ramos
cb80f67dc6 Merge pull request #5885 from luisramos0/variants
[Bye bye Spree] Bring models product, variant, price from spree_core
2020-11-04 21:26:07 +00:00
efgalvao
5260c01f16 Update registration.html.haml
Removed spaces.
2020-11-04 17:37:11 -03:00
Matt-Yorkley
3170db9532 Remove Paperclip URL handlers
See ofn-security issue #33 for details.
2020-11-04 16:49:01 +00:00
efgalvao
42d5f377e0 Fixes issue #6262. 2020-11-04 13:11:37 -03:00
Ren White
f513d888a3 Update reference to OFN handbook in README.md 2020-11-04 06:57:06 -07:00
Luis Ramos
5cde085241 Fix a number of spree translations 2020-11-04 13:55:36 +00:00
Luis Ramos
23956726e9 Add missing translation 2020-11-04 12:37:55 +00:00
efgalvao
1f1da3eb6d Fixed issue #6292. 2020-11-04 09:37:51 -03:00
Luis Ramos
f6d0905517 Add s3_support require to image.rb 2020-11-04 12:15:45 +00:00
Luis Ramos
c2591104ee Fix typo in application setup
This was forcing env test in all environments breaking payment methods that are activated by environment
2020-11-04 12:15:45 +00:00
Luis Ramos
3beea43143 Switch to a version of better_paypal_express that does not define
routes and define those routes on the OFN side
2020-11-04 12:15:45 +00:00
Luis Ramos
8f2d52b9e3 Revert "Do not reload routes and make spree routes append instead of draw in"
This reverts commit cdf4c795c7c7ae18006eb24af9336941361b6b81.
2020-11-04 12:15:45 +00:00
Luis Ramos
eada388534 Add handle_extensions to get Spree.translations (archaic spree js translations) in handlebars templates
This is all legacy from spree that can be cleaned up at some point, we only have two handlebars templates in OFN
2020-11-04 12:15:45 +00:00
Luis Ramos
f6f4faf146 Move test setup to application.rb
Without spree_core, the test environment file loads before the Spree engine is loaded
2020-11-04 12:15:45 +00:00
Luis Ramos
5c4ea1a6be Fix tax rates spec 2020-11-04 12:15:45 +00:00
Luis Ramos
72c454a211 Fix reference to Spree bug 2020-11-04 12:15:45 +00:00
Luis Ramos
543a9592c7 Adapt spec to routes without spree 2020-11-04 12:15:45 +00:00
Luis Ramos
2ce96f4bbe Registration path is working correctly again without spree 2020-11-04 12:15:45 +00:00
Luis Ramos
00d121ebfc Add misssing translation 2020-11-04 12:15:45 +00:00
Luis Ramos
c785d0d1d7 Make engine's routes append to main app instead of prepend 2020-11-04 12:15:45 +00:00
Luis Ramos
80cbe6b30f Add route helper to call to sort_link so that it can find the necessary routes 2020-11-04 12:15:45 +00:00
Luis Ramos
09aef524f3 Make route helpers use spree helper 2020-11-04 12:15:45 +00:00
Luis Ramos
805b4d243e Fix missing translations 2020-11-04 12:15:45 +00:00
Luis Ramos
a07029f660 Add require so that model is available when needed 2020-11-04 12:15:45 +00:00
Luis Ramos
ccab133d63 Make sample data use OFN's calculators 2020-11-04 12:15:45 +00:00
Luis Ramos
a51645f316 Remove deleted file 2020-11-04 12:15:45 +00:00
Luis Ramos
4125fe1690 Fix problem with string matchers 2020-11-04 12:15:45 +00:00
Luis Ramos
6950d7717f Add missing translation 2020-11-04 12:15:45 +00:00
Luis Ramos
ab53db0c61 Merge ability and ability decorator 2020-11-04 12:15:45 +00:00
Luis Ramos
1b4a4a8113 Bring code from spree_paypal_express to make it use spree url_helper 2020-11-04 12:15:45 +00:00
Luis Ramos
66fb3a9cf3 Remove code related to spree promotions 2020-11-04 12:15:45 +00:00
Luis Ramos
79a7cf9b39 Add default spree logo 2020-11-04 12:15:45 +00:00
Luis Ramos
a18a198812 Fix locations of requires in admin js all.js 2020-11-04 12:15:45 +00:00
Luis Ramos
0ca71ce0a9 Do not reload routes and make spree routes append instead of draw in
case thee routes are already defined elsewhere, for example, by the
paypal express gem
2020-11-04 12:15:45 +00:00
Luis Ramos
b7aa04353c Fix requires of product duplicator 2020-11-04 12:15:45 +00:00
Luis Ramos
bfeebccbc5 Load Spree engine before configuring it 2020-11-04 12:15:45 +00:00
Luis Ramos
4b21667974 Move initializers from Spree engine to the OFN application 2020-11-04 12:15:45 +00:00
Luis Ramos
9bbeec5031 Require code from spree/core explicitly 2020-11-04 12:15:45 +00:00
Luis Ramos
af3057f55f Remove spree requires that are not needed in OFN 2020-11-04 12:15:45 +00:00
Luis Ramos
e8381304f9 Remove spree_core dependency 2020-11-04 12:15:45 +00:00
Luis Ramos
58a476751b Remove code from the spree engine that is not needed in OFN 2020-11-04 12:15:45 +00:00
Luis Ramos
3320a3f0bc Fix some more rubocop issues 2020-11-04 12:15:45 +00:00
Luis Ramos
4c6708267a Run rubocop -a 2020-11-04 12:15:45 +00:00
Luis Ramos
2f0d61d54f Bring Spree engine.rb from spree_core 2020-11-04 12:15:45 +00:00
Luis Ramos
451d8488d9 Run rubocop -a 2020-11-04 12:15:45 +00:00
Luis Ramos
bcca2eee9d Bring user and ability related files from spree_core 2020-11-04 12:15:45 +00:00
Luis Ramos
1bce516a45 Make specs load product duplicator
This makes the ofn version of the product duplicator be used instead of the spree one
2020-11-04 12:15:45 +00:00
Luis Ramos
f6195f1159 Remove duplicate_extra logic from ProductDuplicator 2020-11-04 12:15:23 +00:00
Luis Ramos
503c17f896 Move Spree::ProductDuplicator to Spree::Core namespace 2020-11-04 12:15:23 +00:00
Luis Ramos
795b7101ab Remove spree requires that are not needed in OFN 2020-11-04 12:15:23 +00:00
Luis Ramos
9d4a15b0e0 Add required product scopes from spree_core product_scopes 2020-11-04 12:15:23 +00:00
Luis Ramos
459959c068 Remove code related to spree promotions 2020-11-04 12:15:23 +00:00
Luis Ramos
ba16de6627 Move product duplicator to lib/spree/core, it's where spree_core is currently loading it from 2020-11-04 12:15:23 +00:00
Luis Ramos
72a39fdf54 Add required factory from spree_core 2020-11-04 12:15:23 +00:00
Luis Ramos
4b8515358c Remove reference to FactoryGirl, it's FactoryBot that is used in OFN 2020-11-04 12:15:23 +00:00
Luis Ramos
cf7d8067df Fix easy rubocop issues 2020-11-04 12:15:23 +00:00
Luis Ramos
d4e4669e49 Run transpec 2020-11-04 12:15:23 +00:00
Luis Ramos
e9f76cb339 Remove some dead code (Config.track_inventory_levels), remove variant.cost_price= so that localized number is seen, and fix specs 2020-11-04 12:15:23 +00:00
Luis Ramos
b68c5ee0f9 Remove dead code (prototypes) and fix specs 2020-11-04 12:15:23 +00:00
Luis Ramos
072cd2bd54 Run rubocop autocorrect in specs 2020-11-04 12:15:23 +00:00
Luis Ramos
2f8198eecc Fix some easy rubocop issues 2020-11-04 12:15:23 +00:00
Luis Ramos
f85044e035 Run rubocop autocorrect 2020-11-04 12:15:23 +00:00
Luis Ramos
751beceb34 Merge decorators with original spree files 2020-11-04 12:15:23 +00:00
Luis Ramos
8cb75fc6d8 Bring models from spree_core: Spree::Product and Spree::Variant!
EPIC COMMIT ALERT :-)
2020-11-04 12:15:23 +00:00
Matt-Yorkley
d147996af6 Fix display issue in product image edit page 2020-11-03 18:41:09 +00:00
Transifex-Openfoodnetwork
daff0a250c Updating translations for config/locales/pt_BR.yml 2020-11-04 03:32:20 +11:00
Transifex-Openfoodnetwork
65bccb9236 Updating translations for config/locales/ru.yml 2020-11-03 20:36:52 +11:00
Transifex-Openfoodnetwork
efe5a4700a Updating translations for config/locales/en_FR.yml 2020-11-03 19:13:11 +11:00
Transifex-Openfoodnetwork
0103cc3a2f Updating translations for config/locales/fr.yml 2020-11-03 19:13:06 +11:00
Transifex-Openfoodnetwork
2a2c7bdc4e Updating translations for config/locales/es.yml 2020-11-03 08:49:53 +11:00
Transifex-Openfoodnetwork
ad76f3e91e Updating translations for config/locales/ca.yml 2020-11-03 08:48:11 +11:00
Pau Pérez Fabregat
201c9c109d Merge pull request #6281 from Matt-Yorkley/missing-translation-ordering
Add missing translation key for enterprise taxon ordering
2020-11-02 22:15:43 +01:00
Pau Pérez Fabregat
4911bb6613 Merge pull request #6274 from luisramos0/rubocop
Use rubocop auto correct to fix a number of issues
2020-11-02 22:13:36 +01:00
Pau Pérez Fabregat
9de74500cd Merge pull request #6288 from andrewpbrett/fix-cookies-banner
update template path for cookies banner, fix #6284
2020-11-02 20:52:46 +01:00
Andy Brett
04f5249176 update template path for cookies banner, fix #6284 2020-11-02 07:45:30 -08:00
Transifex-Openfoodnetwork
5c81f645c9 Updating translations for config/locales/fr.yml 2020-11-02 20:38:38 +11:00
Transifex-Openfoodnetwork
6ff8cadb26 Updating translations for config/locales/en_FR.yml 2020-11-02 20:27:13 +11:00
Transifex-Openfoodnetwork
04358dfa39 Updating translations for config/locales/en_FR.yml 2020-11-02 20:24:09 +11:00
Transifex-Openfoodnetwork
b23d6674b5 Updating translations for config/locales/ru.yml 2020-11-02 18:59:12 +11:00
Transifex-Openfoodnetwork
8904273bea Updating translations for config/locales/ru.yml 2020-11-02 18:56:03 +11:00
Luis Ramos
1bb7fd9ec8 Merge pull request #6280 from Matt-Yorkley/eastern-slavic-plurals
Add missing translation keys for Eastern Slavic plurals
2020-10-31 23:13:54 +00:00
Matt-Yorkley
0af20e48b0 Add missing translation key for enterprise taxon ordering 2020-10-31 19:17:19 +00:00
Matt-Yorkley
bc40088eaf Add missing translation keys for Eastern Slavic plurals
There are multiple forms of pluralisation here, with different translations for each.

перевод сложен !
2020-10-31 16:58:15 +00:00
Pau Perez
1abdd0112e Update all locales with the latest Transifex translations 2020-10-31 10:46:12 +01:00
Pau Pérez Fabregat
bc6ffe3b0c Merge pull request #6242 from openfoodfoundation/transifex
Transifex
2020-10-31 10:36:12 +01:00
Luis Ramos
eea73aa989 Merge pull request #5919 from luisramos0/injector_refactor_for_rails41
[Rails 4.1, works in master] Convert relations with to_a so that they work in rails 4.1
2020-10-31 09:33:27 +00:00
Pau Pérez Fabregat
03b0ce430d Merge branch 'master' into transifex 2020-10-31 10:05:27 +01:00
Luis Ramos
bfce012a4b Update manual rubocop todo 2020-10-30 17:56:13 +00:00
Luis Ramos
fb3dd0aa18 Update rubocop manual list for MethodLength and AbcSize cops 2020-10-30 17:46:49 +00:00
Luis Ramos
01320105ea Update rubocop_todo 2020-10-30 17:32:47 +00:00
Luis Ramos
c2c12b34f9 Fix more rubocop issues with auto correct 2020-10-30 17:10:23 +00:00
Luis Ramos
c71ebc38bb Fix Layout/ArgumentAlignment 2020-10-30 17:06:08 +00:00
Luis Ramos
4b03dec119 Update manual todo for Line Length 2020-10-30 17:01:38 +00:00
Luis Ramos
ca1373a366 Fix Style/RescueStandardError and Style/RegexpLiteral 2020-10-30 16:50:37 +00:00
Luis Ramos
b0e889be2a Fix Style/RandomWithOffset 2020-10-30 16:50:37 +00:00
Luis Ramos
b3196295e6 Fix Style/RaiseArgs 2020-10-30 16:50:37 +00:00
Luis Ramos
75cec3b606 Fix issue Style/HashSyntax 2020-10-30 16:50:37 +00:00
Luis Ramos
92417d849c Fix rubocop issue Rails/DynamicFindBy 2020-10-30 16:50:37 +00:00
Luis Ramos
bf5fcde885 Fix Lint/UnusedMethodArgument 2020-10-30 16:50:37 +00:00
Luis Ramos
40f8c785a2 Fix Lint/UnusedBlockArgument 2020-10-30 16:50:37 +00:00
Luis Ramos
403384dbb1 Fix rubocop isssues, trailing whitespaces and empty lines 2020-10-30 16:50:37 +00:00
Luis Ramos
c30cba8bfe Fix issue Layout/SpaceInsideHashLiteralBraces 2020-10-30 16:50:37 +00:00
Luis Ramos
e8138e8c23 Fix rubocop issues in models/payment_spec 2020-10-30 16:50:37 +00:00
Luis Ramos
4845cde20f Fix rubocop issue Layout/HashAlignment 2020-10-30 16:50:37 +00:00
Luis Ramos
a8265aff89 Fix rubocop issue Layout/FirstHashElementIndentation 2020-10-30 16:50:37 +00:00
Luis Ramos
9cb3b0b14a Fix rubocop issue Layout/FirstArrayElementIndentation 2020-10-30 16:50:37 +00:00
Luis Ramos
06433b1be3 Fix rubocop issue Layout/ExtraSpacing 2020-10-30 16:50:37 +00:00
Luis Ramos
d4c52ce122 Fix rubocop issue Layout/EmptyLinesAroundBlockBody 2020-10-30 16:50:37 +00:00
Luis Ramos
eb4e732c1a Fix rubocop issue Layout/EmptyLines 2020-10-30 16:50:37 +00:00
Luis Ramos
3fe2684270 Fix rubocop issue Layout/BlockAlignment 2020-10-30 16:50:37 +00:00
Luis Ramos
3e6e338e3d Fix rubocop issue Layout/ArgumentAlignment 2020-10-30 16:50:37 +00:00
Luis Ramos
ad14f7f9b0 Merge pull request #6203 from luisramos0/rubocop_fix
Fix ~80 rubocop issues in serializers/api/admin
2020-10-30 16:48:22 +00:00
Luis Ramos
7cc7c62232 Fix long lines 2020-10-30 16:14:39 +00:00
Luis Ramos
b6dc46a911 Fix rubocop issue by nesting module and class declarations
No file contents changed
2020-10-30 16:14:34 +00:00
Luis Ramos
0b70c67908 Merge pull request #5994 from openfoodfoundation/tcs_checkbox
Terms and Conditions checkbox on checkout
2020-10-30 15:10:06 +00:00
Luis Ramos
71a181341b Fix bug in terms_and_conditions_helper related to guest checkout where current_user is nil and T&Cs must be shown all the time 2020-10-30 15:09:13 +00:00
Luis Ramos
cf3f511f4d Add directive spec to validate the dialog template is loaded on element click 2020-10-30 15:09:13 +00:00
Luis Ramos
1d1067ebc1 Add coverage to T&Cs file opening on a new tab and also for the upload timestamp now displayed in the page 2020-10-30 15:09:13 +00:00
Luis Ramos
bd4d0ba5d3 Make the warning message work for first upload and for changes 2020-10-30 15:09:13 +00:00
Luis Ramos
3b682bc47f Add warning when uploading a file 2020-10-30 15:09:13 +00:00
Luis Ramos
be35f97622 Add tooltip icon to terms and conditions 2020-10-30 15:09:13 +00:00
Luis Ramos
ca79270ba3 Show T&Cs warning when uploading a new file 2020-10-30 15:09:13 +00:00
Luis Ramos
2cf7b1b36c Make label translatable 2020-10-30 15:09:13 +00:00
Luis Ramos
f7c07f492c Make TCs file input onoy accept pdf files 2020-10-30 15:09:13 +00:00
Luis Ramos
9f17e4fd8f Add upload timestamp to TCs upload form in enterprise business details 2020-10-30 15:09:13 +00:00
Luis Ramos
c980d22826 Make TCs link open in a new tab in the backoffice 2020-10-30 15:09:13 +00:00
Luis Ramos
ceee89fad0 Make Checkout form submit read terms_and_conditions_accepted from the checkout form checkbox 2020-10-30 15:09:13 +00:00
Luis Ramos
a942218708 Fix post checkout actions spec 2020-10-30 15:09:13 +00:00
Luis Ramos
26946ec102 Fix edge case and some specs in post checkout actions 2020-10-30 15:09:13 +00:00
Luis Ramos
dd31cbe014 Cover case where enterprise uploads new T&Cs file and customer has already accepted before 2020-10-30 15:09:13 +00:00
Luis Ramos
46733d0c0d Add feature spec to cover T&Cs ticked by default if customer has already accepted them 2020-10-30 15:09:13 +00:00
Luis Ramos
57a9d6e1e2 Make customer terms_and_conditions_accepted_at be set to current time
after a successful checkout
2020-10-30 15:09:13 +00:00
Luis Ramos
ad592785cf Rename methods to follwo ruby convention and improve readability 2020-10-30 15:09:13 +00:00
Luis Ramos
f3ba0ebdbb Move code to a new helper 2020-10-30 15:09:13 +00:00
Luis Ramos
4d64bf6ece Add column to customers table to register last time enterprise terms and
conditions were accepted so customer doesnt have to accept terms on all
checkouts but only when the enterprise updates the terms file
2020-10-30 15:09:13 +00:00
Luis Ramos
3c9c5862d1 Verify terms and conditions updated_at timestamp is touched every time the file name changes.
We will need this to check if user already accepted the terms and
conditions of this enterprise.
2020-10-30 15:08:26 +00:00
Luis Ramos
78a8f53d8d Change default translations to what's been requested on the issue 2020-10-30 15:08:26 +00:00
Luis Ramos
806c8b943d Move small class to label so that rule is actually applied 2020-10-30 15:08:26 +00:00
Luis Ramos
85096a997f Add a checkbox to checkout to tick for Terms and Conditions
Checkout button should be disabled if checkbox is not ticked
2020-10-30 15:08:26 +00:00
Transifex-Openfoodnetwork
19b6cb13f1 Updating translations for config/locales/pt_BR.yml 2020-10-31 01:36:45 +11:00
Transifex-Openfoodnetwork
dd228cc750 Updating translations for config/locales/ar.yml 2020-10-30 22:39:44 +11:00
Cillian O'Ruanaidh
5aa8c783b1 Use Rspec syntax instead of Test::Unit in ActionDispatch::Request spec. 2020-10-30 11:12:36 +00:00
Cillian O'Ruanaidh
5a66c855bc Add :frozen_string_literal magic comment and underscore prefix to unused block argument for Rubocop 2020-10-30 11:12:36 +00:00
Cillian O'Ruanaidh
ea3c456d3b Patch Rails :deep_munge issue so empty array parameters don't get converted to nil
Before people were unable to remove coordinator fees from an order cycle because Rails was converting the empty :coordinator_fee_ids array paramter into nil. This issue was introduced to Rails in v4.0.0.beta1 and isn't fixed until v5.0.0.beta1

Another way to fix this could be to do something like 'params[:coordinator_fee_ids] ||= []' but it seems like this issue could problems in other parts of the app so a more general fix might be better.

Fixes #6224
2020-10-30 11:12:36 +00:00
Luis Ramos
586e8a9abe Fix some more rubocop issues 2020-10-30 10:13:16 +00:00
Luis Ramos
1847b62cf4 Fix some rubocop issues 2020-10-30 10:12:56 +00:00
Luis Ramos
0618c9e4dd Fix line_items_decorator spec 2020-10-30 10:12:56 +00:00
Luis Ramos
d15301021a Rename inject_json_list to inject_json_array 2020-10-30 10:12:56 +00:00
Luis Ramos
55e8dace44 Fix sort_by issue on relation by calling to_a 2020-10-30 10:12:56 +00:00
Luis Ramos
9a9b455e66 Fix problem in default_tax related to sum in active record 2020-10-30 10:12:56 +00:00
Luis Ramos
399fe2c01b Make code work for relations and arrays 2020-10-30 10:12:56 +00:00
Luis Ramos
3aeb87debc Make it work with both relations and arrays 2020-10-30 10:12:56 +00:00
Luis Ramos
7b06fdd943 Convert to array before using sort_by! 2020-10-30 10:12:56 +00:00
Luis Ramos
6755354196 Convert relation to_a to be able to use sum 2020-10-30 10:12:56 +00:00
Luis Ramos
440e69e156 Convert relation to array to be able to use sum 2020-10-30 10:12:47 +00:00
Luis Ramos
a53223aefc Convert relation to array before using array only method sort_by! 2020-10-30 10:10:54 +00:00
Luis Ramos
cc1b4123b7 Make model_set handle collections that are relations and not arrays 2020-10-30 10:10:54 +00:00
Luis Ramos
65ce183830 Make checkout_adjustments_for handle adjustments if a relation is given 2020-10-30 10:10:54 +00:00
Luis Ramos
7e606471e4 Make tag_rulee_applicator and available_payment_methods_filter handle case where a relation is given instead of an array 2020-10-30 10:10:54 +00:00
Luis Ramos
1dace1f0e3 Make quantifier use stock_items relation and not an array because sum will behave differently with an array in rails 4.1 2020-10-30 10:10:54 +00:00
Luis Ramos
08d26102d2 Separate injection methods so that we can have a separate behaviour for lists without having to check their types
This change is required for rails 4.1 where the relations api changed
2020-10-30 10:10:54 +00:00
Transifex-Openfoodnetwork
35790b3cca Updating translations for config/locales/en_FR.yml 2020-10-30 19:29:20 +11:00
Transifex-Openfoodnetwork
2ce05d48bf Updating translations for config/locales/fr.yml 2020-10-30 19:29:05 +11:00
Tsara Sudrajat
f4c7a0b2a2 Align center order adjustment and order total title 2020-10-30 11:29:38 +07:00
Luis Ramos
6b826423c1 Merge pull request #6145 from andrewpbrett/instance-unit-picker
Allow instances to choose available units for products/variants
2020-10-29 22:22:33 +00:00
Luis Ramos
412457bb19 Merge pull request #6122 from luisramos0/customer_total
Add Customer balance to customer list
2020-10-29 22:06:05 +00:00
Andy Brett
2605b9cdf0 refactor unitScales function 2020-10-29 09:18:24 -07:00
Andy Brett
867947f6b2 refactor availableUnitScales into unitScales 2020-10-29 09:18:24 -07:00
Andy Brett
8d9b33abe8 update spec with new param structure 2020-10-29 09:18:24 -07:00
Andy Brett
57fe1db10e guard against nil params[:available_units] 2020-10-29 09:18:24 -07:00
Andy Brett
18d2599075 indicate block argument is unused 2020-10-29 09:18:24 -07:00
Andy Brett
292b33b4ea simplify available units params (and remove regex!) 2020-10-29 09:18:24 -07:00
Andy Brett
8591934c19 extract availableUnits to separate method 2020-10-29 09:18:24 -07:00
Andy Brett
9bf84bd5a8 provide default availableUnits to specs 2020-10-29 09:18:24 -07:00
Andy Brett
67a603f77f inject available_units for new variant creation 2020-10-29 09:18:24 -07:00
Andy Brett
331ac28b71 inject available units to edit variants page 2020-10-29 09:18:24 -07:00
Andy Brett
3ead050a56 provide availableUnits to VariantUnitManager spec 2020-10-29 09:18:24 -07:00
Andy Brett
23dd09eaad remove extra debugger statement 🤦 2020-10-29 09:18:23 -07:00
Andy Brett
8585e6c7f0 add available units injection to BOM page 2020-10-29 09:18:19 -07:00
Andy Brett
866452383d rubocop fix 2020-10-29 09:17:49 -07:00
Andy Brett
402fc902ff remove non-default units from expected options array 2020-10-29 09:17:49 -07:00
Andy Brett
8f21b66b96 add controller spec for updating available units 2020-10-29 09:17:49 -07:00
Andy Brett
c9b540677c refactor general settings controller to handle available_units params 2020-10-29 09:17:49 -07:00
Andy Brett
4f579facfe move all_units to admin helper 2020-10-29 09:17:49 -07:00
Andy Brett
fa62ec0bff only show available units for products 2020-10-29 09:17:49 -07:00
Andy Brett
cb3ea133e9 add available units to instance prefs page 2020-10-29 09:17:31 -07:00
Luis Ramos
10490536e2 Merge pull request #6244 from cillian/configurable-geocoder-service
Allow Geocoder to be configured to use different APIs
2020-10-29 16:12:52 +00:00
Yih Yang
b477ed4a0a added products variable 2020-10-29 23:37:56 +08:00
Yih Yang
f7ee08855a updated implementation 2020-10-29 22:07:11 +08:00
Yih Yang
e3d1f5256b added product sorting 2020-10-29 22:06:35 +08:00
Luis Ramos
a43737af8b Merge pull request #6266 from jhsu802701/rubocop_web_helper
Exempted spec/support/request/web_helper.rb from Metrics/AbcSize
2020-10-29 13:52:15 +00:00
Luis Ramos
0138f04506 Add spec to cover new customer balances on customers list 2020-10-29 13:38:36 +00:00
Luis Ramos
4a2684e3d9 Fix rubocop issues 2020-10-29 13:38:36 +00:00
Luis Ramos
e860e2ca57 Add label to customer balance so it's clear to the manager what's the balance status: credit owed or balance due 2020-10-29 13:38:36 +00:00
Luis Ramos
da69dca471 Make customer balance serialize with the currency 2020-10-29 13:38:36 +00:00
Luis Ramos
e4f3aae7c0 Add customer balance to customer list 2020-10-29 13:38:36 +00:00
Luis Ramos
72ae7ea8a2 Merge pull request #6267 from jhsu802701/rubocop_shopworkflow_2
Removed variant argument from click_add_bulk_max_to_cart
2020-10-29 13:36:58 +00:00
Jason Hsu
8f95de10bc Removed variant argument from click_add_bulk_max_to_cart; updated spec/features/consumer/shopping/shopping_spec.rb to reflect this 2020-10-29 00:35:49 -05:00
Jason Hsu
cbe1b53189 Exempted spec/support/request/web_helper.rb from Metrics/AbcSize; reduces the number of offenses from 122 to 121 2020-10-29 00:23:30 -05:00
Transifex-Openfoodnetwork
9c30c3c0ed Updating translations for config/locales/ar.yml 2020-10-29 11:15:12 +11:00
Luis Ramos
9a03428412 Merge pull request #6197 from cillian/reset-on-demand-on-absent-products
When resetting stock to 0 on absent products in product import also reset the on demand setting
2020-10-29 00:09:49 +00:00
Luis Ramos
76afc0b407 Merge pull request #6202 from cillian/sort-admin-products-by-name-fix
Fix sorting of admin products by name
2020-10-29 00:09:31 +00:00
Luis Ramos
200e9c5078 Merge pull request #6246 from tsara27/fix-shipping-method-translation
Add new translation for shipping method
2020-10-29 00:09:14 +00:00
Luis Ramos
caea5b2aa8 Merge pull request #6264 from openfoodfoundation/dependabot/bundler/bugsnag-6.18.0
Bump bugsnag from 6.17.0 to 6.18.0
2020-10-28 21:11:15 +00:00
Luis Ramos
3730d76b44 Merge pull request #6155 from arku/perf/model-specs
Improve model specs' performance
2020-10-28 21:06:10 +00:00
Transifex-Openfoodnetwork
28c25cff2c Updating translations for config/locales/en_IE.yml 2020-10-29 07:08:18 +11:00
Pau Pérez Fabregat
20edcfab26 Merge pull request #6217 from santakadev/docker-open-db-port
Open PostgreSQL port in docker-compose
2020-10-28 17:56:49 +01:00
Pau Pérez Fabregat
642787b95a Merge branch 'master' into reset-on-demand-on-absent-products 2020-10-28 17:28:53 +01:00
Transifex-Openfoodnetwork
a1438d3b2e Updating translations for config/locales/ru.yml 2020-10-29 02:23:55 +11:00
dependabot-preview[bot]
fc8e3d1ece Bump bugsnag from 6.17.0 to 6.18.0
Bumps [bugsnag](https://github.com/bugsnag/bugsnag-ruby) from 6.17.0 to 6.18.0.
- [Release notes](https://github.com/bugsnag/bugsnag-ruby/releases)
- [Changelog](https://github.com/bugsnag/bugsnag-ruby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/bugsnag/bugsnag-ruby/compare/v6.17.0...v6.18.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-27 17:41:49 +00:00
Transifex-Openfoodnetwork
21991515df Updating translations for config/locales/ar.yml 2020-10-27 22:56:03 +11:00
Luis Ramos
3534559fbf Merge pull request #6235 from Matt-Yorkley/flaky-tag-rules
[Flaky Specs] Fix tag_rules and select2 issues
2020-10-27 11:40:04 +00:00
Matt-Yorkley
f1373b902c Merge pull request #6256 from luisramos0/rubocop_specs
Relax ModuleLength rubocop rule for specs
2020-10-26 22:41:30 +01:00
Luis Ramos
e5e67fbdf0 Merge pull request #6255 from jhsu802701/fix_docker_up
Added yarn install to docker-compose up
2020-10-26 21:16:09 +00:00
Transifex-Openfoodnetwork
f1e80e92de Updating translations for config/locales/it.yml 2020-10-27 07:18:57 +11:00
Luis Ramos
c5186c2412 Fix rubocop_specs file path 2020-10-26 17:27:38 +00:00
Luis Ramos
52f56baa8c Remove specs with more than 100 lines but less than 300 from rubocop exceptions list 2020-10-26 17:03:54 +00:00
Luis Ramos
0b51d8b297 Add rubocop config to allow specs to be 300 lines long 2020-10-26 17:03:50 +00:00
Luis Ramos
0f5aa11f05 Nest spec in module declaration 2020-10-26 16:50:29 +00:00
Jason Hsu
00624d1b96 Added yarn install to docker-compose up; allows the app to work properly in the Docker environment 2020-10-26 11:07:01 -05:00
Transifex-Openfoodnetwork
7e8aaaa5f9 Updating translations for config/locales/fr.yml 2020-10-27 01:27:40 +11:00
Transifex-Openfoodnetwork
49b8dcb880 Updating translations for config/locales/en_FR.yml 2020-10-27 01:24:49 +11:00
Transifex-Openfoodnetwork
479520bf97 Updating translations for config/locales/fr.yml 2020-10-27 01:24:35 +11:00
Luis Ramos
b66b50cd56 Merge pull request #6125 from tsara27/fix-translation
Fix translation for password reset instruction mailer subject
2020-10-26 12:01:47 +00:00
Transifex-Openfoodnetwork
50cbc971a1 Updating translations for config/locales/pt_BR.yml 2020-10-26 10:13:53 +11:00
Transifex-Openfoodnetwork
7178a69a54 Updating translations for config/locales/pt_BR.yml 2020-10-26 10:10:47 +11:00
Matt-Yorkley
e06e8fc460 Improve flaky form interaction process in #fill_in_tag 2020-10-25 10:17:16 +00:00
Matt-Yorkley
ee402db734 Refactor and DRY tag-rule-filling-in to #fill_in_tag method 2020-10-25 09:01:04 +00:00
Matt-Yorkley
3f1e496731 Fix select2 capybara issues 2020-10-24 23:53:02 +01:00
Transifex-Openfoodnetwork
494f0d8ff6 Updating translations for config/locales/ru.yml 2020-10-24 23:18:00 +11:00
Transifex-Openfoodnetwork
15715f9bb4 Updating translations for config/locales/it.yml 2020-10-24 22:28:59 +11:00
Tsara Sudrajat
4baf53a0a9 Add new translation for shipping method 2020-10-24 17:06:19 +07:00
Transifex-Openfoodnetwork
8041111886 Updating translations for config/locales/ar.yml 2020-10-24 07:34:19 +11:00
Transifex-Openfoodnetwork
adc2bcb442 Updating translations for config/locales/es.yml 2020-10-24 01:40:48 +11:00
Transifex-Openfoodnetwork
8a51c5cb5d Updating translations for config/locales/es.yml 2020-10-24 01:37:39 +11:00
Transifex-Openfoodnetwork
e114d58ff2 Updating translations for config/locales/ca.yml 2020-10-24 01:36:14 +11:00
Transifex-Openfoodnetwork
b7fc3df86a Updating translations for config/locales/fr_CA.yml 2020-10-23 23:18:11 +11:00
Transifex-Openfoodnetwork
01fe12e72b Updating translations for config/locales/fr_CA.yml 2020-10-23 23:15:02 +11:00
Cillian O'Ruanaidh
c5e125747f Allow Geocoder to be configured to use different APIs.
This gives instances the option to use other geocoding services, for example MapBox because instances may not have a Google Maps API key if they are using Open Street Map for their map instead of Google.
2020-10-23 13:09:59 +01:00
Transifex-Openfoodnetwork
3baaa5cc40 Updating translations for config/locales/en_CA.yml 2020-10-23 23:06:57 +11:00
Cillian O'Ruanaidh
e29d6048c2 Add a test for sorting admin products by name 2020-10-23 10:53:30 +01:00
Transifex-Openfoodnetwork
c4ba8db7ed Updating translations for config/locales/en_FR.yml 2020-10-23 19:12:20 +11:00
Transifex-Openfoodnetwork
764169c9ca Updating translations for config/locales/fr.yml 2020-10-23 19:12:17 +11:00
Transifex-Openfoodnetwork
30a1832302 Updating translations for config/locales/en_FR.yml 2020-10-23 19:09:10 +11:00
Transifex-Openfoodnetwork
a07f64f8a8 Updating translations for config/locales/fr.yml 2020-10-23 19:09:07 +11:00
Daniel Santamaría
ca2d66eacf Open PostgreSQL port in docker-compose 2020-10-18 08:45:08 +02:00
Arun Kumar Mohan
c65108731c Define supplier_ids in inventory_reset_strategy specs for clarity 2020-10-17 20:12:14 -05:00
Arun Kumar Mohan
5928eba767 Use build to validate objects from the shipping method factory 2020-10-17 19:59:21 -05:00
Arun Kumar Mohan
874d33caaa Convert multiline blocks to single-line ones 2020-10-17 19:44:57 -05:00
Tsara Sudrajat
66be86cca9 Fix translation on reset password mailer 2020-10-17 17:59:54 +07:00
Paolo Rossi
4a60d7ef0e Update the base Ubuntu Docker image from 18.04 to 20.04 2020-10-16 17:26:08 +02:00
Cillian O'Ruanaidh
35110eaf4a Make sure :sorting parameter is nested inside the :q parameter to fix sorting of admin products
Fixes #6105.
2020-10-16 15:21:15 +01:00
Cillian O'Ruanaidh
c62f1bd550 Exclude products_reset_strategy_spec.rb from Rubocop's Metrics/ModuleLength check 2020-10-16 12:13:55 +01:00
Cillian O'Ruanaidh
2cc751cb30 When resetting stock to 0 on absent products in product import also reset the on demand setting
Before when you imported products and clicked the 'Set stock to zero for all existing products not present in the file' option it would set the on hand stock to 0 but if the variant was also set to be on demand the product would still be available for sale. This change makes sure the on demand setting is turned off too.

Fixes #6064.
2020-10-16 11:38:49 +01:00
Arun Kumar Mohan
2ec35b6306 Remove unnecessary let declaration 2020-10-13 01:22:11 -05:00
Arun Kumar Mohan
e963ab4bd4 Replace FactoryBot.create with create 2020-10-13 01:21:47 -05:00
Arun Kumar Mohan
14eee1c9e4 Improve product specs' performance 2020-10-11 01:10:11 -05:00
Arun Kumar Mohan
ff049d33e7 Improve variant stock specs' performance 2020-10-10 00:43:27 -05:00
Arun Kumar Mohan
b02e25af0e Improve shipment specs' performance 2020-10-09 23:28:32 -05:00
Arun Kumar Mohan
76293c335b Improve payment specs' performance 2020-10-09 23:05:14 -05:00
Arun Kumar Mohan
01d2c3cb9e Improve variant specs' performance 2020-10-09 22:11:34 -05:00
Arun Kumar Mohan
80c76606df Improve line items specs' performance 2020-10-09 22:11:34 -05:00
Arun Kumar Mohan
b07fbec8c6 Improve credit card specs' performance 2020-10-09 22:11:34 -05:00
Arun Kumar Mohan
c4205fce34 Improve enterprise specs' performance 2020-10-09 22:11:34 -05:00
Arun Kumar Mohan
a959f8e745 Improve inventory reset strategy specs' performance 2020-10-09 22:11:34 -05:00
Arun Kumar Mohan
437c39f795 Improve taxon specs' performance 2020-10-09 22:11:34 -05:00
Arun Kumar Mohan
27f1aeb803 Improve shipping method specs' performance 2020-10-09 22:11:31 -05:00
Matt-Yorkley
6d169c1b08 Improve Webmock debugging 2020-10-05 17:11:34 +01:00
298 changed files with 10026 additions and 3075 deletions

4
.hound.yml Normal file
View File

@@ -0,0 +1,4 @@
rubocop:
config_file: .rubocop_styleguide.yml
scss:
config_file: .scss-lint.yml

View File

@@ -42,7 +42,6 @@ Layout/LineLength:
- app/helpers/angular_form_helper.rb
- app/helpers/checkout_helper.rb
- app/helpers/enterprises_helper.rb
- app/helpers/injection_helper.rb
- app/helpers/markdown_helper.rb
- app/helpers/order_cycles_helper.rb
- app/helpers/spree/orders_helper.rb
@@ -62,11 +61,10 @@ Layout/LineLength:
- app/models/product_import/unit_converter.rb
- app/models/proxy_order.rb
- app/models/schedule.rb
- app/models/spree/app_configuration_decorator.rb
- app/models/spree/app_configuration.rb
- app/models/spree/gateway/stripe_connect.rb
- app/models/spree/image.rb
- app/models/spree/line_item_decorator.rb
- app/models/spree/order_decorator.rb
- app/models/spree/order.rb
- app/models/spree/payment_method.rb
- app/models/spree/product_decorator.rb
- app/models/spree/user.rb
@@ -75,6 +73,7 @@ Layout/LineLength:
- app/models/variant_override_set.rb
- app/serializers/api/admin/subscription_line_item_serializer.rb
- app/services/cart_service.rb
- app/services/checkout/post_checkout_actions.rb
- app/services/default_stock_location.rb
- app/services/embedded_page_service.rb
- app/services/order_cycle_form.rb
@@ -88,6 +87,7 @@ Layout/LineLength:
- Gemfile
- lib/discourse/single_sign_on.rb
- lib/open_food_network/available_payment_method_filter.rb
- lib/open_food_network/bulk_coop_report.rb
- lib/open_food_network/customers_report.rb
- lib/open_food_network/enterprise_fee_applicator.rb
- lib/open_food_network/enterprise_fee_calculator.rb
@@ -101,7 +101,6 @@ Layout/LineLength:
- lib/open_food_network/scope_variants_for_search.rb
- lib/open_food_network/xero_invoices_report.rb
- lib/spree/localized_number.rb
- lib/spree/product_filters.rb
- lib/tasks/data.rake
- lib/tasks/enterprises.rake
- spec/controllers/admin/bulk_line_items_controller_spec.rb
@@ -263,12 +262,17 @@ Layout/LineLength:
- spec/models/spree/adjustment_spec.rb
- spec/models/spree/classification_spec.rb
- spec/models/spree/gateway/stripe_connect_spec.rb
- spec/models/spree/inventory_unit_spec.rb
- spec/models/spree/line_item_spec.rb
- spec/models/spree/order/checkout_spec.rb
- spec/models/spree/order_inventory_spec.rb
- spec/models/spree/order_spec.rb
- spec/models/spree/order/state_machine_spec.rb
- spec/models/spree/payment_method_spec.rb
- spec/models/spree/payment_spec.rb
- spec/models/spree/product_set_spec.rb
- spec/models/spree/product_spec.rb
- spec/models/spree/return_authorization_spec.rb
- spec/models/spree/shipping_method_spec.rb
- spec/models/spree/stock_item_spec.rb
- spec/models/spree/taxon_spec.rb
@@ -298,6 +302,7 @@ Layout/LineLength:
- spec/serializers/api/order_serializer_spec.rb
- spec/services/cart_service_spec.rb
- spec/services/checkout/form_data_adapter_spec.rb
- spec/services/checkout/post_checkout_actions_spec.rb
- spec/services/embedded_page_service_spec.rb
- spec/services/exchange_products_renderer_spec.rb
- spec/services/order_cycle_distributed_products_spec.rb
@@ -384,17 +389,22 @@ Metrics/AbcSize:
- app/models/proxy_order.rb
- app/models/spree/ability.rb
- app/models/spree/address.rb
- app/models/spree/line_item_decorator.rb
- app/models/spree/line_item.rb
- app/models/spree/order/checkout.rb
- app/models/spree/order_decorator.rb
- app/models/spree/order_contents.rb
- app/models/spree/order_inventory.rb
- app/models/spree/order.rb
- app/models/spree/payment/processing.rb
- app/models/spree/payment.rb
- app/models/spree/preference.rb
- app/models/spree/preferences/preferable_class_methods.rb
- app/models/spree/preferences/preferable.rb
- app/models/spree/product_decorator.rb
- app/models/spree/return_authorization.rb
- app/models/spree/shipment.rb
- app/models/spree/taxon.rb
- app/models/spree/tax_rate.rb
- app/models/spree/zone.rb
- app/serializers/api/admin/enterprise_serializer.rb
- app/serializers/api/product_serializer.rb
- app/serializers/api/variant_serializer.rb
- app/services/cart_service.rb
@@ -452,6 +462,7 @@ Metrics/AbcSize:
- spec/services/order_checkout_restart_spec.rb
- spec/support/i18n_translations_checker.rb
- spec/support/performance_helper.rb
- spec/support/request/web_helper.rb
Metrics/BlockLength:
Max: 25
@@ -516,7 +527,11 @@ Metrics/CyclomaticComplexity:
- app/models/spree/order/checkout.rb
- app/models/spree/payment_method.rb
- app/models/spree/payment.rb
- app/models/spree/preference.rb
- app/models/spree/preferences/preferable.rb
- app/models/spree/preferences/preferable_class_methods.rb
- app/models/spree/product_decorator.rb
- app/models/spree/return_authorization.rb
- app/models/spree/zone.rb
- app/models/variant_override_set.rb
- app/services/cart_service.rb
@@ -550,7 +565,10 @@ Metrics/PerceivedComplexity:
- app/models/spree/order/checkout.rb
- app/models/spree/payment_method.rb
- app/models/spree/payment.rb
- app/models/spree/preferences/preferable.rb
- app/models/spree/preferences/preferable_class_methods.rb
- app/models/spree/product_decorator.rb
- app/models/spree/return_authorization.rb
- app/models/spree/zone.rb
- app/models/variant_override_set.rb
- app/services/cart_service.rb
@@ -576,7 +594,7 @@ Metrics/PerceivedComplexity:
- app/models/spree/ability.rb
- app/models/spree/address.rb
- app/models/spree/order/checkout.rb
- app/models/spree/order_decorator.rb
- app/models/spree/order.rb
- app/models/spree/product_decorator.rb
- app/models/spree/zone.rb
- engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb
@@ -594,61 +612,6 @@ Metrics/PerceivedComplexity:
Metrics/MethodLength:
Max: 10
Exclude:
- app/controllers/admin/enterprise_fees_controller.rb
- app/controllers/admin/enterprises_controller.rb
- app/controllers/spree/admin/taxons_controller.rb
- app/controllers/spree/orders_controller.rb
- app/helpers/checkout_helper.rb
- app/helpers/order_cycles_helper.rb
- app/helpers/spree/admin/base_helper.rb
- app/helpers/spree/admin/navigation_helper.rb
- app/models/enterprise.rb
- app/models/enterprise_relationship.rb
- app/models/spree/ability.rb
- app/models/spree/address.rb
- app/models/spree/order/checkout.rb
- app/models/spree/payment_method.rb
- app/models/spree/payment.rb
- app/models/spree/product_decorator.rb
- app/models/spree/zone.rb
- app/models/variant_override_set.rb
- app/services/cart_service.rb
- engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb
- engines/order_management/app/services/order_management/stock/estimator.rb
- lib/active_merchant/billing/gateways/stripe_payment_intents.rb
- lib/discourse/single_sign_on.rb
- lib/open_food_network/enterprise_issue_validator.rb
- lib/spree/core/calculated_adjustments.rb
- lib/spree/core/controller_helpers/order.rb
- lib/spree/core/controller_helpers/respond_with.rb
- lib/spree/core/controller_helpers/ssl.rb
- lib/spree/localized_number.rb
- spec/models/product_importer_spec.rb
- app/controllers/admin/enterprises_controller.rb
- app/controllers/api/variants_controller.rb
- app/controllers/spree/admin/taxons_controller.rb
- app/controllers/spree/orders_controller.rb
- app/helpers/checkout_helper.rb
- app/helpers/order_cycles_helper.rb
- app/helpers/spree/admin/navigation_helper.rb
- app/models/enterprise_relationship.rb
- app/models/spree/ability.rb
- app/models/spree/address.rb
- app/models/spree/order/checkout.rb
- app/models/spree/order_decorator.rb
- app/models/spree/product_decorator.rb
- app/models/spree/zone.rb
- engines/order_management/app/services/order_management/reports/bulk_coop/bulk_coop_report.rb
- engines/order_management/app/services/order_management/stock/estimator.rb
- lib/active_merchant/billing/gateways/stripe_payment_intents.rb
- lib/discourse/single_sign_on.rb
- lib/open_food_network/enterprise_issue_validator.rb
- lib/spree/core/calculated_adjustments.rb
- lib/spree/core/controller_helpers/order.rb
- lib/spree/core/controller_helpers/respond_with.rb
- lib/spree/core/controller_helpers/ssl.rb
- lib/spree/localized_number.rb
- spec/models/product_importer_spec.rb
- app/controllers/admin/contents_controller.rb
- app/controllers/admin/customers_controller.rb
- app/controllers/admin/enterprise_fees_controller.rb
@@ -698,10 +661,17 @@ Metrics/MethodLength:
- app/models/spree/address.rb
- app/models/spree/credit_card.rb
- app/models/spree/order/checkout.rb
- app/models/spree/order_decorator.rb
- app/models/spree/order_contents.rb
- app/models/spree/order_inventory.rb
- app/models/spree/order.rb
- app/models/spree/payment_method.rb
- app/models/spree/payment/processing.rb
- app/models/spree/preference.rb
- app/models/spree/preferences/preferable_class_methods.rb
- app/models/spree/preferences/preferable.rb
- app/models/spree/preferences/store.rb
- app/models/spree/product_decorator.rb
- app/models/spree/return_authorization.rb
- app/models/spree/shipment.rb
- app/models/spree/taxon.rb
- app/models/spree/tax_rate.rb
@@ -782,6 +752,8 @@ Metrics/ClassLength:
- app/models/spree/ability.rb
- app/models/spree/address.rb
- app/models/spree/credit_card.rb
- app/models/spree/line_item.rb
- app/models/spree/order.rb
- app/models/spree/payment.rb
- app/models/spree/shipment.rb
- app/models/spree/user.rb
@@ -811,40 +783,18 @@ Metrics/ModuleLength:
- app/helpers/spree/admin/navigation_helper.rb
- app/models/spree/order/checkout.rb
- app/models/spree/payment/processing.rb
- engines/order_management/spec/services/order_management/order/updater_spec.rb
- engines/order_management/spec/services/order_management/stock/package_spec.rb
- engines/order_management/spec/services/order_management/subscriptions/estimator_spec.rb
- engines/order_management/spec/services/order_management/subscriptions/form_spec.rb
- engines/order_management/spec/services/order_management/subscriptions/proxy_order_syncer_spec.rb
- engines/order_management/spec/services/order_management/subscriptions/summarizer_spec.rb
- engines/order_management/spec/services/order_management/subscriptions/validator_spec.rb
- engines/order_management/spec/services/order_management/subscriptions/variants_list_spec.rb
- lib/open_food_network/column_preference_defaults.rb
- spec/controllers/admin/order_cycles_controller_spec.rb
- spec/controllers/api/order_cycles_controller_spec.rb
- spec/controllers/api/orders_controller_spec.rb
- spec/controllers/spree/admin/payment_methods_controller_spec.rb
- spec/lib/open_food_network/address_finder_spec.rb
- spec/lib/open_food_network/customers_report_spec.rb
- spec/lib/open_food_network/enterprise_fee_calculator_spec.rb
- spec/lib/open_food_network/order_cycle_form_applicator_spec.rb
- spec/lib/open_food_network/order_cycle_permissions_spec.rb
- spec/lib/open_food_network/order_grouper_spec.rb
- spec/lib/open_food_network/packing_report_spec.rb
- spec/lib/open_food_network/permissions_spec.rb
- spec/lib/open_food_network/products_and_inventory_report_spec.rb
- spec/lib/open_food_network/scope_variant_to_hub_spec.rb
- spec/lib/open_food_network/tag_rule_applicator_spec.rb
- spec/lib/open_food_network/user_balance_calculator_spec.rb
- spec/lib/open_food_network/users_and_enterprises_report_spec.rb
- spec/models/spree/adjustment_spec.rb
- spec/models/spree/credit_card_spec.rb
- spec/models/spree/line_item_spec.rb
- spec/models/spree/product_spec.rb
- spec/models/spree/shipping_method_spec.rb
- spec/models/spree/variant_spec.rb
- spec/services/permissions/order_spec.rb
- spec/services/variant_units/option_value_namer_spec.rb
Metrics/ParameterLists:
Max: 5
@@ -853,3 +803,9 @@ Metrics/ParameterLists:
- app/models/product_import/entry_processor.rb
- lib/open_food_network/xero_invoices_report.rb
- spec/features/admin/reports_spec.rb
Lint/UselessAssignment:
Exclude:
- 'spec/**/*'
- 'app/models/spree/taxon.rb'
- 'lib/spree/core/controller_helpers/common.rb'

7
.rubocop_specs.yml Normal file
View File

@@ -0,0 +1,7 @@
inherit_from:
- .rubocop.yml
# This rubocop config file is only used for specs
# Here we allow specs to be 300 lines long
Metrics/ModuleLength:
Max: 300

View File

@@ -1,144 +1,11 @@
# This configuration was generated by
# `rubocop --auto-gen-config --exclude-limit 1400`
# on 2020-10-14 09:49:36 +0100 using RuboCop version 0.81.0.
# on 2020-10-30 17:18:53 +0000 using RuboCop version 0.81.0.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.
# Offense count: 3
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: with_first_argument, with_fixed_indentation
Layout/ArgumentAlignment:
Exclude:
- 'spec/models/spree/address_spec.rb'
- 'spec/models/spree/order/checkout_spec.rb'
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyleAlignWith.
# SupportedStylesAlignWith: either, start_of_block, start_of_line
Layout/BlockAlignment:
Exclude:
- 'spec/models/spree/order/checkout_spec.rb'
# Offense count: 3
# Cop supports --auto-correct.
Layout/EmptyLines:
Exclude:
- 'spec/features/admin/variants_spec.rb'
- 'spec/models/spree/payment_spec.rb'
# Offense count: 4
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: empty_lines, no_empty_lines
Layout/EmptyLinesAroundBlockBody:
Exclude:
- 'spec/models/spree/payment_spec.rb'
- 'spec/models/spree/zone_spec.rb'
# Offense count: 3
# Cop supports --auto-correct.
# Configuration parameters: AllowForAlignment, AllowBeforeTrailingComments, ForceEqualSignAlignment.
Layout/ExtraSpacing:
Exclude:
- 'spec/models/spree/payment_spec.rb'
- 'spec/requests/api/orders_spec.rb'
# Offense count: 2
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: special_inside_parentheses, consistent, align_brackets
Layout/FirstArrayElementIndentation:
Exclude:
- 'spec/views/spree/admin/payment_methods/index.html.haml_spec.rb'
# Offense count: 3
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: special_inside_parentheses, consistent, align_braces
Layout/FirstHashElementIndentation:
Exclude:
- 'spec/models/spree/payment_spec.rb'
- 'spec/swagger_helper.rb'
# Offense count: 8
# Cop supports --auto-correct.
# Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
# SupportedHashRocketStyles: key, separator, table
# SupportedColonStyles: key, separator, table
# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
Layout/HashAlignment:
Exclude:
- 'spec/lib/open_food_network/packing_report_spec.rb'
- 'spec/models/spree/payment_spec.rb'
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: normal, indented_internal_methods
Layout/IndentationConsistency:
Exclude:
- 'spec/models/spree/order/checkout_spec.rb'
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: symmetrical, new_line, same_line
Layout/MultilineHashBraceLayout:
Exclude:
- 'spec/models/spree/payment_spec.rb'
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: AllowForAlignment, EnforcedStyleForExponentOperator.
# SupportedStylesForExponentOperator: space, no_space
Layout/SpaceAroundOperators:
Exclude:
- 'spec/models/spree/payment_spec.rb'
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters.
# SupportedStyles: space, no_space
# SupportedStylesForEmptyBraces: space, no_space
Layout/SpaceInsideBlockBraces:
Exclude:
- 'spec/models/spree/payment_spec.rb'
# Offense count: 11
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces.
# SupportedStyles: space, no_space, compact
# SupportedStylesForEmptyBraces: space, no_space
Layout/SpaceInsideHashLiteralBraces:
Exclude:
- 'spec/models/spree/payment_spec.rb'
- 'spec/requests/api/orders_spec.rb'
- 'spec/services/checkout/form_data_adapter_spec.rb'
- 'spec/services/user_locale_setter_spec.rb'
# Offense count: 3
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: final_newline, final_blank_line
Layout/TrailingEmptyLines:
Exclude:
- 'spec/factories.rb'
- 'spec/factories/address_factory.rb'
- 'spec/support/request/stripe_helper.rb'
# Offense count: 6
# Cop supports --auto-correct.
# Configuration parameters: AllowInHeredoc.
Layout/TrailingWhitespace:
Exclude:
- 'spec/features/consumer/shopping/shopping_spec.rb'
- 'spec/lib/open_food_network/orders_and_fulfillments_report/customer_totals_report_spec.rb'
- 'spec/requests/api/orders_spec.rb'
# Offense count: 2
Lint/DuplicateMethods:
Exclude:
@@ -152,20 +19,6 @@ Lint/IneffectiveAccessModifier:
- 'app/services/mail_configuration.rb'
- 'lib/open_food_network/feature_toggle.rb'
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments.
Lint/UnusedBlockArgument:
Exclude:
- 'spec/factories/stock_location_factory.rb'
# Offense count: 4
# Cop supports --auto-correct.
# Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods.
Lint/UnusedMethodArgument:
Exclude:
- 'spec/views/spree/admin/payment_methods/index.html.haml_spec.rb'
# Offense count: 3
# Configuration parameters: ContextCreatingMethods, MethodCreatingMethods.
Lint/UselessAccessModifier:
@@ -174,19 +27,20 @@ Lint/UselessAccessModifier:
- 'app/services/mail_configuration.rb'
- 'lib/open_food_network/feature_toggle.rb'
# Offense count: 1
# Offense count: 2
Lint/UselessAssignment:
Exclude:
- 'spec/**/*'
- 'lib/spree/core/controller_helpers/common.rb'
- 'app/models/spree/taxon.rb'
- 'lib/spree/core/controller_helpers/common.rb'
# Offense count: 9
# Offense count: 10
Naming/AccessorMethodName:
Exclude:
- 'app/controllers/spree/admin/taxonomies_controller.rb'
- 'app/models/spree/adjustment.rb'
- 'app/models/spree/order_decorator.rb'
- 'app/models/spree/order.rb'
- 'app/services/checkout/post_checkout_actions.rb'
- 'lib/spree/core/controller_helpers/common.rb'
- 'spec/support/request/shop_workflow.rb'
- 'spec/support/request/web_helper.rb'
@@ -206,7 +60,7 @@ Naming/MemoizedInstanceVariableName:
- 'app/mailers/producer_mailer.rb'
- 'lib/open_food_network/address_finder.rb'
# Offense count: 20
# Offense count: 24
# Configuration parameters: NamePrefix, ForbiddenPrefixes, AllowedMethods, MethodDefinitionMacros.
# NamePrefix: is_, has_, have_
# ForbiddenPrefixes: is_, has_, have_
@@ -220,10 +74,11 @@ Naming/PredicateName:
- 'app/models/order_cycle.rb'
- 'app/models/spree/adjustment.rb'
- 'app/models/spree/credit_card.rb'
- 'app/models/spree/line_item_decorator.rb'
- 'app/models/spree/order_decorator.rb'
- 'app/models/spree/line_item.rb'
- 'app/models/spree/order.rb'
- 'app/models/spree/payment_method.rb'
- 'app/models/spree/preferences/file_configuration.rb'
- 'app/models/spree/preferences/preferable.rb'
- 'app/models/spree/shipping_method.rb'
- 'app/models/spree/user.rb'
- 'lib/open_food_network/customers_report.rb'
@@ -262,21 +117,14 @@ Rails/Date:
- 'app/models/order_cycle.rb'
- 'app/models/spree/credit_card.rb'
# Offense count: 1
# Offense count: 2
# Cop supports --auto-correct.
# Configuration parameters: EnforceForPrefixed.
Rails/Delegate:
Exclude:
- 'app/models/spree/line_item.rb'
- 'engines/order_management/app/services/order_management/reports/bulk_coop/renderers/html_renderer.rb'
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: Whitelist.
# Whitelist: find_by_sql
Rails/DynamicFindBy:
Exclude:
- 'spec/factories/state_factory.rb'
# Offense count: 16
# Configuration parameters: EnforcedStyle.
# SupportedStyles: slashes, arguments
@@ -307,13 +155,12 @@ Rails/FindBy:
- 'app/models/product_import/spreadsheet_data.rb'
- 'app/models/spree/user.rb'
# Offense count: 2
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: Include.
# Include: app/models/**/*.rb
Rails/FindEach:
Exclude:
- 'app/models/spree/order_decorator.rb'
- 'app/models/spree/shipment.rb'
# Offense count: 9
@@ -324,13 +171,13 @@ Rails/HasAndBelongsToMany:
- 'app/models/concerns/payment_method_distributors.rb'
- 'app/models/enterprise.rb'
- 'app/models/enterprise_group.rb'
- 'app/models/spree/line_item_decorator.rb'
- 'app/models/spree/line_item.rb'
- 'app/models/spree/role.rb'
- 'app/models/spree/shipping_method.rb'
- 'app/models/spree/user.rb'
- 'app/models/spree/zone.rb'
# Offense count: 35
# Offense count: 38
# Configuration parameters: Include.
# Include: app/models/**/*.rb
Rails/HasManyOrHasOneDependent:
@@ -341,9 +188,10 @@ Rails/HasManyOrHasOneDependent:
- 'app/models/spree/address.rb'
- 'app/models/spree/adjustment.rb'
- 'app/models/spree/credit_card.rb'
- 'app/models/spree/order_decorator.rb'
- 'app/models/spree/order.rb'
- 'app/models/spree/payment_method.rb'
- 'app/models/spree/property.rb'
- 'app/models/spree/return_authorization.rb'
- 'app/models/spree/shipment.rb'
- 'app/models/spree/shipping_category.rb'
- 'app/models/spree/shipping_method.rb'
@@ -392,7 +240,7 @@ Rails/LexicallyScopedActionFilter:
- 'app/controllers/spree/users_controller.rb'
- 'app/controllers/user_passwords_controller.rb'
# Offense count: 13
# Offense count: 14
Rails/OutputSafety:
Exclude:
- 'app/controllers/spree/admin/reports_controller.rb'
@@ -415,15 +263,16 @@ Rails/RakeEnvironment:
- 'lib/capistrano/tasks/**/*.rake'
- 'lib/tasks/specs.rake'
# Offense count: 9
# Offense count: 11
Rails/ReflectionClassName:
Exclude:
- 'app/models/customer.rb'
- 'app/models/distributor_shipping_method.rb'
- 'app/models/enterprise_role.rb'
- 'app/models/spree/order.rb'
- 'app/models/subscription.rb'
# Offense count: 243
# Offense count: 247
# Configuration parameters: Blacklist, Whitelist.
# Blacklist: decrement!, decrement_counter, increment!, increment_counter, toggle!, touch, update_all, update_attribute, update_column, update_columns, update_counters
Rails/SkipsModelValidations:
@@ -442,7 +291,8 @@ Rails/SkipsModelValidations:
- 'app/models/spree/address.rb'
- 'app/models/spree/adjustment.rb'
- 'app/models/spree/credit_card.rb'
- 'app/models/spree/order_decorator.rb'
- 'app/models/spree/inventory_unit.rb'
- 'app/models/spree/order.rb'
- 'app/models/spree/payment.rb'
- 'app/models/spree/shipment.rb'
- 'app/models/spree/shipping_method.rb'
@@ -480,7 +330,6 @@ Rails/SkipsModelValidations:
- 'spec/features/admin/order_cycles/complex_editing_spec.rb'
- 'spec/features/admin/order_cycles/simple_spec.rb'
- 'spec/features/admin/order_spec.rb'
- 'spec/features/admin/payments_spec.rb'
- 'spec/features/admin/reports_spec.rb'
- 'spec/features/consumer/caching/shops_caching_spec.rb'
- 'spec/features/consumer/shopping/checkout_spec.rb'
@@ -501,6 +350,7 @@ Rails/SkipsModelValidations:
- 'spec/models/spree/adjustment_spec.rb'
- 'spec/models/spree/asset_spec.rb'
- 'spec/models/spree/line_item_spec.rb'
- 'spec/models/spree/order_inventory_spec.rb'
- 'spec/models/spree/order_spec.rb'
- 'spec/models/spree/tax_category_spec.rb'
- 'spec/models/spree/variant_spec.rb'
@@ -533,7 +383,7 @@ Rails/UniqueValidationWithoutIndex:
# Environments: development, test, production
Rails/UnknownEnv:
Exclude:
- 'app/models/spree/app_configuration_decorator.rb'
- 'app/models/spree/app_configuration.rb'
- 'lib/spree/core/controller_helpers/ssl.rb'
# Offense count: 2
@@ -542,7 +392,7 @@ Style/CaseEquality:
- 'app/helpers/angular_form_helper.rb'
- 'spec/models/spree/payment_spec.rb'
# Offense count: 64
# Offense count: 29
# Cop supports --auto-correct.
# Configuration parameters: AutoCorrect, EnforcedStyle.
# SupportedStyles: nested, compact
@@ -557,40 +407,6 @@ Style/ClassAndModuleChildren:
- 'app/models/tag_rule/filter_payment_methods.rb'
- 'app/models/tag_rule/filter_shipping_methods.rb'
- 'app/serializers/api/address_serializer.rb'
- 'app/serializers/api/admin/basic_enterprise_fee_serializer.rb'
- 'app/serializers/api/admin/basic_enterprise_serializer.rb'
- 'app/serializers/api/admin/basic_order_cycle_serializer.rb'
- 'app/serializers/api/admin/calculator/flat_percent_item_total_serializer.rb'
- 'app/serializers/api/admin/calculator_serializer.rb'
- 'app/serializers/api/admin/column_preference_serializer.rb'
- 'app/serializers/api/admin/customer_serializer.rb'
- 'app/serializers/api/admin/enterprise_fee_serializer.rb'
- 'app/serializers/api/admin/enterprise_relationship_permission_serializer.rb'
- 'app/serializers/api/admin/enterprise_relationship_serializer.rb'
- 'app/serializers/api/admin/enterprise_role_serializer.rb'
- 'app/serializers/api/admin/enterprise_serializer.rb'
- 'app/serializers/api/admin/exchange_serializer.rb'
- 'app/serializers/api/admin/for_order_cycle/enterprise_serializer.rb'
- 'app/serializers/api/admin/for_order_cycle/supplied_product_serializer.rb'
- 'app/serializers/api/admin/id_name_serializer.rb'
- 'app/serializers/api/admin/id_serializer.rb'
- 'app/serializers/api/admin/index_enterprise_serializer.rb'
- 'app/serializers/api/admin/inventory_item_serializer.rb'
- 'app/serializers/api/admin/line_item_serializer.rb'
- 'app/serializers/api/admin/order_cycle_serializer.rb'
- 'app/serializers/api/admin/order_serializer.rb'
- 'app/serializers/api/admin/payment_method/base_serializer.rb'
- 'app/serializers/api/admin/payment_method/stripe_serializer.rb'
- 'app/serializers/api/admin/product_serializer.rb'
- 'app/serializers/api/admin/shipping_method_serializer.rb'
- 'app/serializers/api/admin/tag_rule_serializer.rb'
- 'app/serializers/api/admin/tax_category_serializer.rb'
- 'app/serializers/api/admin/taxon_serializer.rb'
- 'app/serializers/api/admin/units_product_serializer.rb'
- 'app/serializers/api/admin/units_variant_serializer.rb'
- 'app/serializers/api/admin/user_serializer.rb'
- 'app/serializers/api/admin/variant_override_serializer.rb'
- 'app/serializers/api/admin/variant_serializer.rb'
- 'app/serializers/api/country_serializer.rb'
- 'app/serializers/api/currency_config_serializer.rb'
- 'app/serializers/api/current_order_serializer.rb'
@@ -624,7 +440,7 @@ Style/FormatStringToken:
- 'lib/open_food_network/sales_tax_report.rb'
- 'spec/features/admin/bulk_order_management_spec.rb'
# Offense count: 818
# Offense count: 765
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: always, always_true, never
@@ -816,13 +632,10 @@ Style/FrozenStringLiteralComment:
- 'app/models/product_import/unit_converter.rb'
- 'app/models/proxy_order.rb'
- 'app/models/schedule.rb'
- 'app/models/spree/app_configuration_decorator.rb'
- 'app/models/spree/gateway/migs.rb'
- 'app/models/spree/gateway/pin.rb'
- 'app/models/spree/gateway/stripe_connect.rb'
- 'app/models/spree/line_item_decorator.rb'
- 'app/models/spree/option_type_decorator.rb'
- 'app/models/spree/order_decorator.rb'
- 'app/models/spree/preferences/file_configuration.rb'
- 'app/models/spree/price_decorator.rb'
- 'app/models/spree/product_decorator.rb'
@@ -845,48 +658,6 @@ Style/FrozenStringLiteralComment:
- 'app/models/variant_override_set.rb'
- 'app/serializers/api/address_serializer.rb'
- 'app/serializers/api/adjustment_serializer.rb'
- 'app/serializers/api/admin/basic_enterprise_fee_serializer.rb'
- 'app/serializers/api/admin/basic_enterprise_serializer.rb'
- 'app/serializers/api/admin/basic_order_cycle_serializer.rb'
- 'app/serializers/api/admin/calculator/flat_percent_item_total_serializer.rb'
- 'app/serializers/api/admin/calculator_serializer.rb'
- 'app/serializers/api/admin/column_preference_serializer.rb'
- 'app/serializers/api/admin/customer_serializer.rb'
- 'app/serializers/api/admin/enterprise_fee_serializer.rb'
- 'app/serializers/api/admin/enterprise_relationship_permission_serializer.rb'
- 'app/serializers/api/admin/enterprise_relationship_serializer.rb'
- 'app/serializers/api/admin/enterprise_role_serializer.rb'
- 'app/serializers/api/admin/enterprise_serializer.rb'
- 'app/serializers/api/admin/exchange_serializer.rb'
- 'app/serializers/api/admin/for_order_cycle/enterprise_serializer.rb'
- 'app/serializers/api/admin/for_order_cycle/supplied_product_serializer.rb'
- 'app/serializers/api/admin/id_email_serializer.rb'
- 'app/serializers/api/admin/id_name_serializer.rb'
- 'app/serializers/api/admin/id_serializer.rb'
- 'app/serializers/api/admin/index_enterprise_serializer.rb'
- 'app/serializers/api/admin/index_order_cycle_serializer.rb'
- 'app/serializers/api/admin/inventory_item_serializer.rb'
- 'app/serializers/api/admin/line_item_serializer.rb'
- 'app/serializers/api/admin/order_cycle_serializer.rb'
- 'app/serializers/api/admin/order_serializer.rb'
- 'app/serializers/api/admin/payment_method/base_serializer.rb'
- 'app/serializers/api/admin/payment_method/stripe_serializer.rb'
- 'app/serializers/api/admin/payment_method_serializer.rb'
- 'app/serializers/api/admin/product_serializer.rb'
- 'app/serializers/api/admin/proxy_order_serializer.rb'
- 'app/serializers/api/admin/schedule_serializer.rb'
- 'app/serializers/api/admin/shipping_method_serializer.rb'
- 'app/serializers/api/admin/subscription_customer_serializer.rb'
- 'app/serializers/api/admin/subscription_line_item_serializer.rb'
- 'app/serializers/api/admin/subscription_serializer.rb'
- 'app/serializers/api/admin/tag_rule_serializer.rb'
- 'app/serializers/api/admin/tax_category_serializer.rb'
- 'app/serializers/api/admin/taxon_serializer.rb'
- 'app/serializers/api/admin/units_product_serializer.rb'
- 'app/serializers/api/admin/units_variant_serializer.rb'
- 'app/serializers/api/admin/user_serializer.rb'
- 'app/serializers/api/admin/variant_override_serializer.rb'
- 'app/serializers/api/admin/variant_serializer.rb'
- 'app/serializers/api/cached_enterprise_serializer.rb'
- 'app/serializers/api/country_serializer.rb'
- 'app/serializers/api/credit_card_serializer.rb'
@@ -1053,7 +824,6 @@ Style/FrozenStringLiteralComment:
- 'lib/spree/authentication_helpers.rb'
- 'lib/spree/localized_number.rb'
- 'lib/spree/money_decorator.rb'
- 'lib/spree/product_filters.rb'
- 'lib/stripe/account_connector.rb'
- 'lib/stripe/profile_storer.rb'
- 'lib/stripe/webhook_handler.rb'
@@ -1121,6 +891,7 @@ Style/FrozenStringLiteralComment:
- 'spec/controllers/shops_controller_spec.rb'
- 'spec/controllers/spree/admin/adjustments_controller_spec.rb'
- 'spec/controllers/spree/admin/base_controller_spec.rb'
- 'spec/controllers/spree/admin/general_settings_controller_spec.rb'
- 'spec/controllers/spree/admin/invoices_controller_spec.rb'
- 'spec/controllers/spree/admin/mail_methods_controller_spec.rb'
- 'spec/controllers/spree/admin/orders/customer_details_controller_spec.rb'
@@ -1274,7 +1045,6 @@ Style/FrozenStringLiteralComment:
- 'spec/lib/open_food_network/users_and_enterprises_report_spec.rb'
- 'spec/lib/open_food_network/xero_invoices_report_spec.rb'
- 'spec/lib/spree/localized_number_spec.rb'
- 'spec/lib/spree/product_filters_spec.rb'
- 'spec/lib/stripe/account_connector_spec.rb'
- 'spec/lib/stripe/webhook_handler_spec.rb'
- 'spec/lib/tasks/enterprises_rake_spec.rb'
@@ -1318,7 +1088,6 @@ Style/FrozenStringLiteralComment:
- 'spec/models/spree/classification_spec.rb'
- 'spec/models/spree/credit_card_spec.rb'
- 'spec/models/spree/gateway/stripe_connect_spec.rb'
- 'spec/models/spree/image_spec.rb'
- 'spec/models/spree/line_item_spec.rb'
- 'spec/models/spree/order/checkout_spec.rb'
- 'spec/models/spree/order_spec.rb'
@@ -1425,7 +1194,6 @@ Style/FrozenStringLiteralComment:
- 'spec/support/products_helper.rb'
- 'spec/support/request/admin_helper.rb'
- 'spec/support/request/authentication_helper.rb'
- 'spec/support/request/checkout_helper.rb'
- 'spec/support/request/cookie_helper.rb'
- 'spec/support/request/distribution_helper.rb'
- 'spec/support/request/menu_helper.rb'
@@ -1444,7 +1212,7 @@ Style/FrozenStringLiteralComment:
- 'spec/views/spree/admin/payment_methods/index.html.haml_spec.rb'
- 'spec/views/spree/admin/shared/_order_links.html.haml_spec.rb'
# Offense count: 48
# Offense count: 44
# Configuration parameters: MinBodyLength.
Style/GuardClause:
Exclude:
@@ -1460,7 +1228,7 @@ Style/GuardClause:
- 'app/models/enterprise.rb'
- 'app/models/enterprise_group.rb'
- 'app/models/producer_property.rb'
- 'app/models/spree/order_decorator.rb'
- 'app/models/spree/preferences/preferable_class_methods.rb'
- 'app/models/spree/price_decorator.rb'
- 'app/models/spree/product_decorator.rb'
- 'app/services/order_syncer.rb'
@@ -1469,25 +1237,15 @@ Style/GuardClause:
- 'lib/open_food_network/order_cycle_form_applicator.rb'
- 'lib/open_food_network/rack_request_blocker.rb'
- 'spec/support/delayed_job_helper.rb'
- 'spec/support/request/checkout_helper.rb'
- 'spec/support/request/distribution_helper.rb'
- 'spec/support/request/shop_workflow.rb'
# Offense count: 66
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, UseHashRocketsWithSymbolValues, PreferHashRocketsForNonAlnumEndingSymbols.
# SupportedStyles: ruby19, hash_rockets, no_mixed_keys, ruby19_no_mixed_keys
Style/HashSyntax:
Exclude:
- 'spec/factories/stock_location_factory.rb'
- 'spec/models/spree/credit_card_spec.rb'
- 'spec/models/spree/payment_spec.rb'
# Offense count: 2
# Offense count: 3
Style/MissingRespondToMissing:
Exclude:
- 'app/helpers/application_helper.rb'
- 'app/models/spree/gateway.rb'
- 'app/models/spree/preferences/configuration.rb'
# Offense count: 2
Style/MixinUsage:
@@ -1495,7 +1253,7 @@ Style/MixinUsage:
- 'lib/open_food_network/orders_and_fulfillments_report.rb'
- 'spec/lib/open_food_network/packing_report_spec.rb'
# Offense count: 36
# Offense count: 43
# Cop supports --auto-correct.
# Configuration parameters: AutoCorrect, EnforcedStyle, IgnoredMethods.
# SupportedStyles: predicate, comparison
@@ -1509,8 +1267,11 @@ Style/NumericPredicate:
- 'app/models/product_import/product_importer.rb'
- 'app/models/product_import/spreadsheet_entry.rb'
- 'app/models/spree/gateway/stripe_connect.rb'
- 'app/models/spree/line_item_decorator.rb'
- 'app/models/spree/order_decorator.rb'
- 'app/models/spree/line_item.rb'
- 'app/models/spree/order.rb'
- 'app/models/spree/order_contents.rb'
- 'app/models/spree/order_inventory.rb'
- 'app/models/spree/preferences/preferable.rb'
- 'app/models/spree/user.rb'
- 'app/models/variant_override.rb'
- 'app/services/cart_service.rb'
@@ -1523,37 +1284,7 @@ Style/NumericPredicate:
- 'lib/spree/money_decorator.rb'
- 'lib/tasks/sample_data.rake'
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: compact, exploded
Style/RaiseArgs:
Exclude:
- 'spec/controllers/checkout_controller_spec.rb'
# Offense count: 1
# Cop supports --auto-correct.
Style/RandomWithOffset:
Exclude:
- 'spec/factories.rb'
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, AllowInnerSlashes.
# SupportedStyles: slashes, percent_r, mixed
Style/RegexpLiteral:
Exclude:
- 'lib/spree/core/controller_helpers/auth.rb'
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: implicit, explicit
Style/RescueStandardError:
Exclude:
- 'lib/spree/core/delegate_belongs_to.rb'
# Offense count: 231
# Offense count: 241
Style/Send:
Exclude:
- 'spec/controllers/admin/subscriptions_controller_spec.rb'
@@ -1578,8 +1309,10 @@ Style/Send:
- 'spec/models/enterprise_spec.rb'
- 'spec/models/exchange_spec.rb'
- 'spec/models/spree/gateway/stripe_connect_spec.rb'
- 'spec/models/spree/order_inventory_spec.rb'
- 'spec/models/spree/order_spec.rb'
- 'spec/models/spree/payment_spec.rb'
- 'spec/models/spree/return_authorization_spec.rb'
- 'spec/models/spree/tax_rate_spec.rb'
- 'spec/models/tag_rule/discount_order_spec.rb'
- 'spec/models/tag_rule/filter_order_cycles_spec.rb'
@@ -1597,3 +1330,11 @@ Style/Send:
Style/StructInheritance:
Exclude:
- 'lib/open_food_network/enterprise_fee_applicator.rb'
# Offense count: 2
# Cop supports --auto-correct.
# Configuration parameters: IgnoredMethods.
# IgnoredMethods: respond_to, define_method
Style/SymbolProc:
Exclude:
- 'app/models/spree/preferences/preferable.rb'

View File

@@ -1,3 +1,19 @@
scss_files: 'app/assets/stylesheets/**/*.css.scss'
exclude: 'app/assets/stylesheets/shared/**'
linters:
ImportantRule:
enabled: false
VendorPrefix:
enabled: false
LeadingZero:
enabled: false
PropertySortOrder:
enabled: false
StringQuotes:
enabled: false
DeclarationOrder:
enabled: false
NestingDepth:
enabled: false

View File

@@ -1,4 +1,10 @@
FROM ubuntu:18.04
FROM ubuntu:20.04
ENV TZ Europe/London
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN echo "deb http://security.ubuntu.com/ubuntu bionic-security main" >> /etc/apt/sources.list
# Install all the requirements
RUN apt-get update && apt-get install -y curl git build-essential software-properties-common wget zlib1g-dev libssl1.0-dev libreadline-dev libyaml-dev libffi-dev libxml2-dev libxslt1-dev wait-for-it imagemagick unzip

21
Gemfile
View File

@@ -18,18 +18,11 @@ gem 'web', path: './engines/web'
gem 'activerecord-postgresql-adapter'
gem 'pg', '~> 0.21.0'
# OFN-maintained and patched version of Spree v2.0.4. See
# https://github.com/openfoodfoundation/openfoodnetwork/wiki/Tech-Doc:-OFN's-Spree-fork%F0%9F%8D%B4
# for details.
gem 'spree_core', github: 'openfoodfoundation/spree', branch: '2-1-0-stable'
### Dependencies brought from spree core
gem 'acts_as_list', '= 0.2.0'
gem 'awesome_nested_set', '~> 3.0.0.rc.1'
gem 'acts_as_list', '= 0.3.0'
gem 'awesome_nested_set', '~> 3.2.1'
gem 'cancan', '~> 1.6.10'
gem 'ffaker', '~> 1.16'
gem 'highline', '= 1.6.18' # Necessary for the install generator
gem 'httparty', '~> 0.18' # Used to check alerts in spree_core, this is not used in OFN.
gem 'highline', '2.0.3' # Necessary for the install generator
gem 'json', '>= 1.7.7'
gem 'money', '5.1.1'
gem 'paranoia', '~> 2.0'
@@ -37,7 +30,7 @@ gem 'ransack', '~> 1.8.10'
gem 'state_machine', '1.2.0'
gem 'stringex', '~> 1.5.1'
gem 'spree_i18n', github: 'spree/spree_i18n', branch: '1-3-stable'
gem 'spree_i18n', github: 'openfoodfoundation/spree_i18n', branch: '1-3-stable'
# Our branch contains the following changes:
# - Pass customer email and phone number to PayPal (merged to upstream master)
@@ -61,13 +54,11 @@ gem 'daemons'
gem 'delayed_job_active_record'
gem 'delayed_job_web'
# Spree's default pagination gem (locked to the current version used by Spree)
# We use it's methods in OFN code as well, so this is a direct dependency
gem 'kaminari', '~> 0.14.1'
gem 'kaminari', '~> 0.17.0'
gem 'andand'
gem 'angularjs-rails', '1.5.5'
gem 'aws-sdk', '1.11.1' # temporarily locked down due to https://github.com/aws/aws-sdk-ruby/issues/273
gem 'aws-sdk', '1.67.0'
gem 'bugsnag'
gem 'db2fog'
gem 'haml'

View File

@@ -6,12 +6,11 @@ GIT
GIT
remote: https://github.com/openfoodfoundation/better_spree_paypal_express.git
revision: 1736e3268239a841576d2719a1f276cf9b74c5c5
revision: 1a477e9f7763297944cc99b6f4dd3d962aa963e9
branch: 2-1-0-stable
specs:
spree_paypal_express (2.0.3)
paypal-sdk-merchant (= 1.106.1)
spree_core (~> 2.1.0)
GIT
remote: https://github.com/openfoodfoundation/ofn-qz.git
@@ -21,39 +20,13 @@ GIT
ofn-qz (0.1.0)
GIT
remote: https://github.com/openfoodfoundation/spree.git
revision: cbb24a6ed701166ffaf2ab60a402154100d74766
branch: 2-1-0-stable
specs:
spree_core (2.1.0)
activemerchant (= 1.78.0)
acts_as_list (= 0.2.0)
awesome_nested_set (~> 3.0.0.rc.1)
aws-sdk (= 1.11.1)
cancan (~> 1.6.10)
ffaker (~> 1.16)
highline (= 1.6.18)
httparty (~> 0.11)
json (>= 1.7.7)
kaminari (~> 0.14.1)
money (= 5.1.1)
paperclip (~> 3.4.1)
paranoia (~> 2.0)
rails (~> 4.0)
ransack (~> 1.0)
state_machine (= 1.2.0)
stringex (~> 1.5.1)
truncate_html (= 0.9.2)
GIT
remote: https://github.com/spree/spree_i18n.git
revision: 752eb67204e9c5a4e22b62591a8fd55fe2285e43
remote: https://github.com/openfoodfoundation/spree_i18n.git
revision: 12f18312232f0ce70270d47859d2951d12f7791c
branch: 1-3-stable
specs:
spree_i18n (1.0.0)
i18n (~> 0.5)
rails-i18n
spree_core (>= 1.1)
PATH
remote: engines/catalog
@@ -127,7 +100,7 @@ GEM
tzinfo (~> 0.3.37)
acts-as-taggable-on (4.0.0)
activerecord (>= 4.0)
acts_as_list (0.2.0)
acts_as_list (0.3.0)
activerecord (>= 3.0)
addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0)
@@ -141,15 +114,16 @@ GEM
arel (4.0.2)
ast (2.4.0)
atomic (1.1.101)
awesome_nested_set (3.0.3)
activerecord (>= 4.0.0, < 5)
awesome_nested_set (3.2.1)
activerecord (>= 4.0.0, < 7.0)
awesome_print (1.8.0)
aws-sdk (1.11.1)
aws-sdk (1.67.0)
aws-sdk-v1 (= 1.67.0)
aws-sdk-v1 (1.67.0)
json (~> 1.4)
nokogiri (>= 1.4.4)
uuidtools (~> 2.1)
nokogiri (~> 1)
bcrypt (3.1.13)
bugsnag (6.17.0)
bugsnag (6.18.0)
concurrent-ruby (~> 1.0)
builder (3.1.4)
byebug (11.0.1)
@@ -415,11 +389,8 @@ GEM
temple (>= 0.8.0)
tilt
hashdiff (1.0.1)
highline (1.6.18)
highline (2.0.3)
hike (1.2.3)
httparty (0.18.1)
mime-types (~> 3.0)
multi_xml (>= 0.5.2)
i18n (0.6.11)
i18n-js (3.8.0)
i18n (>= 0.6.6)
@@ -440,7 +411,7 @@ GEM
multi_json (~> 1.0)
rspec (>= 2.0, < 4.0)
jwt (2.2.2)
kaminari (0.14.1)
kaminari (0.17.0)
actionpack (>= 3.0.0)
activesupport (>= 3.0.0)
kgio (2.11.3)
@@ -678,14 +649,13 @@ GEM
unicorn-worker-killer (0.4.4)
get_process_mem (~> 0)
unicorn (>= 4, < 6)
uuidtools (2.1.5)
warden (1.2.7)
rack (>= 1.0)
webdrivers (4.2.0)
nokogiri (~> 1.6)
rubyzip (>= 1.3.0)
selenium-webdriver (>= 3.0, < 4.0)
webmock (3.9.3)
webmock (3.9.5)
addressable (>= 2.3.6)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
@@ -710,15 +680,15 @@ DEPENDENCIES
activerecord-postgresql-adapter
activerecord-session_store
acts-as-taggable-on (~> 4.0)
acts_as_list (= 0.2.0)
acts_as_list (= 0.3.0)
andand
angular-rails-templates (~> 0.3.0)
angularjs-file-upload-rails (~> 2.4.1)
angularjs-rails (= 1.5.5)
atomic
awesome_nested_set (~> 3.0.0.rc.1)
awesome_nested_set (~> 3.2.1)
awesome_print
aws-sdk (= 1.11.1)
aws-sdk (= 1.67.0)
bugsnag
byebug (~> 11.0.0)
cancan (~> 1.6.10)
@@ -751,8 +721,7 @@ DEPENDENCIES
geocoder
gmaps4rails
haml
highline (= 1.6.18)
httparty (~> 0.18)
highline (= 2.0.3)
i18n (~> 0.6.11)
i18n-js (~> 3.8.0)
immigrant
@@ -762,7 +731,7 @@ DEPENDENCIES
json (>= 1.7.7)
json_spec (~> 1.1.4)
jwt (~> 2.2)
kaminari (~> 0.14.1)
kaminari (~> 0.17.0)
knapsack
letter_opener (>= 1.4.1)
mini_racer (= 0.2.15)
@@ -799,7 +768,6 @@ DEPENDENCIES
selenium-webdriver
shoulda-matchers
simplecov
spree_core!
spree_i18n!
spree_paypal_express!
spring

View File

@@ -16,7 +16,7 @@ We're part of global movement - get involved!
## Contributing
If you are interested in contributing to the OFN in any capacity, please introduce yourself [on Slack][slack-invite], and have a look through our [Contributor Guide][contributor-guide].
If you are interested in contributing to the OFN in any capacity, please introduce yourself [on Slack][slack-invite], and have a look through the [OFN Handbook][ofn-handbook].
Our [GETTING_STARTED](GETTING_STARTED.md) and [CONTRIBUTING](CONTRIBUTING.md) guides are the best place to start for developers looking to set up a development environment and make contributions to the codebase.
@@ -41,7 +41,7 @@ Copyright (c) 2012 - 2020 Open Food Foundation, released under the AGPL licence.
[survey]: https://docs.google.com/a/eaterprises.com.au/forms/d/1zxR5vSiU9CigJ9cEaC8-eJLgYid8CR8er7PPH9Mc-30/edit#
[slack-invite]: https://join.slack.com/t/openfoodnetwork/shared_invite/zt-9sjkjdlu-r02kUMP1zbrTgUhZhYPF~A
[contributor-guide]: https://ofn-user-guide.gitbook.io/ofn-contributor-guide/who-are-we
[ofn-handbook]: https://ofn-user-guide.gitbook.io/ofn-handbook/
[ofn-install]: https://github.com/openfoodfoundation/ofn-install
[super-admin-guide]: https://ofn-user-guide.gitbook.io/ofn-super-admin-guide
[welcome-dev]: https://github.com/openfoodfoundation/openfoodnetwork/projects/27

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -34,7 +34,7 @@
//= require css_browser_selector_dev
//= require responsive-tables
//= require admin/spree_paypal_express
//= require handlebars
//= require admin/spree/handlebar_extensions
// OFN specific
//= require_tree ../templates/admin

View File

@@ -104,7 +104,7 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout
$scope.$watch 'sortOptions', (sort) ->
return unless sort && sort.predicate != ""
$scope.sorting = sort.getSortingExpr()
$scope.q.sorting = sort.getSortingExpr()
$scope.fetchProducts()
, true

View File

@@ -47,3 +47,8 @@ angular.module("admin.customers").controller "customersCtrl", ($scope, $q, $filt
tag.text.toLowerCase().indexOf(query.toLowerCase()) != -1
defer.resolve filtered
defer.promise
$scope.displayBalanceStatus = (customer) ->
return unless customer.balance_status
t('admin.customers.index.' + customer.balance_status)

View File

@@ -0,0 +1,30 @@
angular.module("admin.enterprises").directive 'termsAndConditionsWarning', ($compile, $templateCache, DialogDefaults, $timeout) ->
restrict: 'A'
scope: true
link: (scope, element, attr) ->
# This file input click handler will hold the browser file input dialog and show a warning modal
scope.hold_file_input_and_show_warning_modal = (event) ->
event.preventDefault()
scope.template = $compile($templateCache.get('admin/modals/terms_and_conditions_warning.html'))(scope)
if scope.template.dialog
scope.template.dialog(DialogDefaults)
scope.template.dialog('open')
scope.$apply()
element.bind 'click', scope.hold_file_input_and_show_warning_modal
# When the user presses continue in the warning modal, we open the browser file input dialog
scope.continue = ->
scope.template.dialog('close')
# unbind warning modal handler and click file input again to open the browser file input dialog
element.unbind('click').trigger('click')
# afterwards, bind warning modal handler again so that the warning is shown the next time
$timeout ->
element.bind 'click', scope.hold_file_input_and_show_warning_modal
return
scope.close = ->
scope.template.dialog('close')
return

View File

@@ -1,4 +1,4 @@
angular.module("admin.products").factory "VariantUnitManager", ->
angular.module("admin.products").factory "VariantUnitManager", (availableUnits) ->
class VariantUnitManager
@units:
'weight':
@@ -29,12 +29,13 @@ angular.module("admin.products").factory "VariantUnitManager", ->
system: 'metric'
@variantUnitOptions: ->
available = availableUnits.split(",")
options = for unit_type, _ of @units
for scale in @unitScales(unit_type)
for scale in @unitScales(unit_type, available)
name = @getUnitName(scale, unit_type)
["#{I18n.t(unit_type)} (#{name})", "#{unit_type}_#{scale}"]
options.push [[I18n.t('items'), 'items']]
[].concat options...
options = [].concat options...
@getScale: (value, unitType) ->
scaledValue = null
@@ -53,8 +54,13 @@ angular.module("admin.products").factory "VariantUnitManager", ->
else
''
@unitScales: (unitType) ->
(parseFloat(scale) for scale in Object.keys(@units[unitType])).sort (a, b) ->
@unitScales: (unitType, availableUnits = null) ->
scales = Object.keys(@units[unitType])
if availableUnits
scales = scales.filter (scale) ->
availableUnits.includes(VariantUnitManager.getUnitName(scale, unitType))
(parseFloat(scale) for scale in scales).sort (a, b) ->
a - b
@compatibleUnitScales: (scale, unitType) ->

View File

@@ -1,5 +1,4 @@
//= require_self
//= require admin/handlebar_extensions
//= require admin/spree/orders/variant_autocomplete
/**

View File

@@ -0,0 +1,9 @@
//= require handlebars
Handlebars.registerHelper("t", function(key) {
if (Spree.translations[key]) {
return Spree.translations[key]
} else {
console.error("No translation found for " + key + ". Does it exist within spree/admin/shared/_translations.html.erb?")
}
});

View File

@@ -95,6 +95,10 @@ Darkswarm.factory 'Checkout', ($injector, CurrentOrder, ShippingMethods, StripeE
last_name: @order.bill_address.lastname
save_requested_by_customer: @secrets.save_requested_by_customer
}
if @terms_and_conditions_accepted()
munged_order["terms_and_conditions_accepted"] = true
munged_order
shippingMethod: ->
@@ -114,3 +118,7 @@ Darkswarm.factory 'Checkout', ($injector, CurrentOrder, ShippingMethods, StripeE
cartTotal: ->
@order.display_total + @shippingPrice() + @paymentPrice()
terms_and_conditions_accepted: ->
terms_and_conditions_checkbox = angular.element("#accept_terms")[0]
terms_and_conditions_checkbox? && terms_and_conditions_checkbox.checked

View File

@@ -0,0 +1,13 @@
%div
.margin-bottom-30.text-center
.text-big
{{ 'js.admin.modals.terms_and_conditions_info.title' | t }}
.margin-bottom-30
%p
{{ 'js.admin.modals.terms_and_conditions_info.message_1' | t }}
.margin-bottom-30
%p
{{ 'js.admin.modals.terms_and_conditions_info.message_2' | t }}
.text-center
%input.button.red.icon-plus{ type: 'button', value: t('js.admin.modals.got_it'), ng: { click: 'close()' } }

View File

@@ -0,0 +1,14 @@
%div
.margin-bottom-30.text-center
.text-big
{{ 'js.admin.modals.terms_and_conditions_warning.title' | t }}
.margin-bottom-30
%p
{{ 'js.admin.modals.terms_and_conditions_warning.message_1' | t }}
.margin-bottom-30
%p
{{ 'js.admin.modals.terms_and_conditions_warning.message_2' | t }}
.text-center
%input.button.red{ type: 'button', value: t('js.admin.modals.close'), ng: { click: 'close()' } }
%input.button.red{ type: 'button', value: t('js.admin.modals.continue'), ng: { click: 'continue()' } }

View File

@@ -121,3 +121,10 @@ form#image_upload {
}
}
form.edit_image {
.field {
img {
max-width: 150px;
}
}
}

View File

@@ -154,3 +154,7 @@ input.text-big {
.pad-top {
padding-top: 1em;
}
.white-space-nowrap {
white-space: nowrap;
}

View File

@@ -5,7 +5,7 @@ $large-menu-height: 4.6875rem;
$medium-menu-height: 3rem;
$gutter-width: 0.9375rem;
nav.top-bar ul.left li.powered-by {
.top-bar .powered-by {
display: none;
}

View File

@@ -44,6 +44,13 @@ nav.top-bar {
.top-bar-section {
border-bottom: 1px solid $light-grey-transparency;
display: flex;
justify-content: space-between;
.nav-main-menu,
.nav-icons-menu {
flex-shrink: 0;
}
a.icon {
&:hover {
@@ -99,21 +106,14 @@ nav.top-bar {
}
}
ul.center {
display: inline-block;
// By default, we center between the left and right uls, but we want to be centered
// relative to the whole page. The difference in width between the other uls is 74px,
// so we offset by that amount here.
margin-left: -74px;
}
ul.dropdown {
border: 1px solid $smoke;
border-top: none;
left: auto;
right: 0;
}
ul.right {
.nav-icons-menu {
> li {
border-left: 1px solid #ddd;
padding: 0 14px;
@@ -244,9 +244,7 @@ nav.top-bar {
.top-bar .ofn-logo img {
height: auto;
width: auto;
max-height: 44px;
max-width: 250px;
}
.left-off-canvas-menu {
@@ -289,10 +287,6 @@ nav.top-bar {
.has-dropdown > a {
padding: 0 ($topbar-height / 8) !important;
}
ul.center {
margin-left: -24px;
}
}
}

View File

@@ -27,7 +27,7 @@ module Admin
end
def bulk_update
@enterprise_fee_set = EnterpriseFeeSet.new(params[:enterprise_fee_set])
@enterprise_fee_set = EnterpriseFeeSet.new(enterprise_fee_bulk_params)
if @enterprise_fee_set.save
redirect_to redirect_path, notice: I18n.t(:enterprise_fees_update_notice)
@@ -78,5 +78,15 @@ module Admin
main_app.admin_enterprise_fees_path
end
def enterprise_fee_bulk_params
params.require(:enterprise_fee_set).permit(
collection_attributes: [
:id, :enterprise_id, :fee_type, :name, :tax_category_id,
:inherits_tax_category, :calculator_type,
{ calculator_attributes: PermittedAttributes::Calculator.attributes }
]
)
end
end
end

View File

@@ -181,10 +181,10 @@ module Admin
enterprise_payment_methods = @enterprise.payment_methods.to_a
enterprise_shipping_methods = @enterprise.shipping_methods.to_a
# rubocop:disable Style/TernaryParentheses
@payment_methods = Spree::PaymentMethod.managed_by(spree_current_user).sort_by! do |pm|
@payment_methods = Spree::PaymentMethod.managed_by(spree_current_user).to_a.sort_by! do |pm|
[(enterprise_payment_methods.include? pm) ? 0 : 1, pm.name]
end
@shipping_methods = Spree::ShippingMethod.managed_by(spree_current_user).sort_by! do |sm|
@shipping_methods = Spree::ShippingMethod.managed_by(spree_current_user).to_a.sort_by! do |sm|
[(enterprise_shipping_methods.include? sm) ? 0 : 1, sm.name]
end
# rubocop:enable Style/TernaryParentheses

View File

@@ -223,7 +223,7 @@ module Admin
end
def order_cycle_set
@order_cycle_set ||= OrderCycleSet.new(@order_cycles, params[:order_cycle_set])
@order_cycle_set ||= OrderCycleSet.new(@order_cycles, order_cycle_bulk_params)
end
def require_order_cycle_set_params
@@ -240,5 +240,11 @@ module Admin
def order_cycle_params
PermittedAttributes::OrderCycle.new(params).call
end
def order_cycle_bulk_params
params.require(:order_cycle_set).permit(
collection_attributes: [:id] + PermittedAttributes::OrderCycle.basic_attributes
)
end
end
end

View File

@@ -4,6 +4,7 @@ require "spree/core/controller_helpers/ssl"
module Api
class BaseController < ActionController::Metal
include ActionController::StrongParameters
include Spree::Api::ControllerSetup
include Spree::Core::ControllerHelpers::SSL
include ::ActionController::Head

View File

@@ -11,11 +11,15 @@ module Api
@customer = Customer.find(params[:id])
authorize! :update, @customer
if @customer.update(params[:customer])
if @customer.update(customer_params)
render json: @customer, serializer: CustomerSerializer, status: :ok
else
invalid_resource!(@customer)
end
end
def customer_params
params.require(:customer).permit(:code, :email, :enterprise_id, :allow_charges)
end
end
end

View File

@@ -12,7 +12,7 @@ module Api
# params[:user_ids] breaks the enterprise creation
# We remove them from params and save them after creating the enterprise
user_ids = params[:enterprise].delete(:user_ids)
@enterprise = Enterprise.new(params[:enterprise])
@enterprise = Enterprise.new(enterprise_params)
if @enterprise.save
@enterprise.user_ids = user_ids
render text: @enterprise.id, status: :created
@@ -25,7 +25,7 @@ module Api
@enterprise = Enterprise.find_by(permalink: params[:id]) || Enterprise.find(params[:id])
authorize! :update, @enterprise
if @enterprise.update(params[:enterprise])
if @enterprise.update(enterprise_params)
render text: @enterprise.id, status: :ok
else
invalid_resource!(@enterprise)
@@ -69,5 +69,9 @@ module Api
def override_visible
params[:enterprise][:visible] = false
end
def enterprise_params
PermittedAttributes::Enterprise.new(params).call
end
end
end

View File

@@ -1,4 +1,5 @@
require 'open_food_network/permissions'
require 'spree/core/product_duplicator'
module Api
class ProductsController < Api::BaseController
@@ -16,7 +17,7 @@ module Api
def create
authorize! :create, Spree::Product
params[:product][:available_on] ||= Time.zone.now
@product = Spree::Product.new(params[:product])
@product = Spree::Product.new(product_params)
begin
if @product.save
render json: @product, serializer: Api::Admin::ProductSerializer, status: :created
@@ -32,7 +33,7 @@ module Api
def update
authorize! :update, Spree::Product
@product = find_product(params[:id])
if @product.update(params[:product])
if @product.update(product_params)
render json: @product, serializer: Api::Admin::ProductSerializer, status: :ok
else
invalid_resource!(@product)
@@ -155,5 +156,9 @@ module Api
per_page: (params[:per_page] || DEFAULT_PER_PAGE).to_i
}
end
def product_params
params.require(:product).permit PermittedAttributes::Product.attributes
end
end
end

View File

@@ -30,7 +30,7 @@ module Api
@shipment.adjustment.open
end
@shipment.update(params[:shipment])
@shipment.update(shipment_params[:shipment])
if unlock == 'yes'
@shipment.adjustment.close
@@ -88,7 +88,7 @@ module Api
def find_and_update_shipment
@shipment = @order.shipments.find_by!(number: params[:id])
@shipment.update(params[:shipment])
@shipment.update(shipment_params[:shipment]) if shipment_params[:shipment].present?
@shipment.reload
end
@@ -101,5 +101,12 @@ module Api
def get_or_create_shipment(stock_location_id)
@order.shipment || @order.shipments.create(stock_location_id: stock_location_id)
end
def shipment_params
params.permit(
[:id, :order_id, :variant_id, :quantity,
{ shipment: [:tracking, :selected_shipping_rate_id] }]
)
end
end
end

View File

@@ -22,7 +22,7 @@ module Api
def create
authorize! :create, Spree::Taxon
@taxon = Spree::Taxon.new(params[:taxon])
@taxon = Spree::Taxon.new(taxon_params)
@taxon.taxonomy_id = params[:taxonomy_id]
taxonomy = Spree::Taxonomy.find_by(id: params[:taxonomy_id])
@@ -42,7 +42,7 @@ module Api
def update
authorize! :update, Spree::Taxon
if taxon.update(params[:taxon])
if taxon.update(taxon_params)
render json: taxon, serializer: Api::TaxonSerializer, status: :ok
else
invalid_resource!(taxon)
@@ -66,5 +66,11 @@ module Api
def taxon
@taxon ||= taxonomy.taxons.find(params[:id])
end
def taxon_params
return if params[:taxon].blank?
params.require(:taxon).permit([:name, :parent_id])
end
end
end

View File

@@ -17,7 +17,7 @@ module Api
def create
authorize! :create, Spree::Variant
@variant = scope.new(params[:variant])
@variant = scope.new(variant_params)
if @variant.save
render json: @variant, serializer: Api::VariantSerializer, status: :created
else
@@ -28,7 +28,7 @@ module Api
def update
authorize! :update, Spree::Variant
@variant = scope.find(params[:id])
if @variant.update(params[:variant])
if @variant.update(variant_params)
render json: @variant, serializer: Api::VariantSerializer, status: :ok
else
invalid_resource!(@product)
@@ -69,5 +69,9 @@ module Api
end
variants
end
def variant_params
params.require(:variant).permit(PermittedAttributes::Variant.attributes)
end
end
end

View File

@@ -1,7 +1,6 @@
# frozen_string_literal: true
require 'open_food_network/address_finder'
require 'spree/core/gateway_error'
class CheckoutController < Spree::StoreController
layout 'darkswarm'

View File

@@ -10,6 +10,7 @@ module Spree
end
def update
merge_available_units_params unless params[:available_units].nil?
params.each do |name, value|
next unless Spree::Config.has_preference? name
@@ -19,6 +20,13 @@ module Spree
redirect_to spree.edit_admin_general_settings_path
end
private
def merge_available_units_params
params[:available_units] =
params[:available_units].select { |_unit, checked| checked == "1" }.keys.join(",")
end
end
end
end

View File

@@ -25,7 +25,7 @@ module Spree
@object.attributes = permitted_resource_params
if @object.save
flash[:success] = flash_message_for(@object, :successfully_created)
redirect_to admin_product_images_url(params[:product_id], @url_filters)
redirect_to spree.admin_product_images_url(params[:product_id], @url_filters)
else
respond_with(@object)
end
@@ -41,7 +41,7 @@ module Spree
if @object.update(permitted_resource_params)
flash[:success] = flash_message_for(@object, :successfully_updated)
redirect_to admin_product_images_url(params[:product_id], @url_filters)
redirect_to spree.admin_product_images_url(params[:product_id], @url_filters)
else
respond_with(@object)
end
@@ -55,7 +55,7 @@ module Spree
flash[:success] = flash_message_for(@object, :successfully_removed)
end
redirect_to admin_product_images_url(params[:product_id], @url_filters)
redirect_to spree.admin_product_images_url(params[:product_id], @url_filters)
end
private

View File

@@ -3,7 +3,6 @@ require 'open_food_network/spree_api_key_loader'
module Spree
module Admin
class OrdersController < Spree::Admin::BaseController
require 'spree/core/gateway_error'
include OpenFoodNetwork::SpreeApiKeyLoader
helper CheckoutHelper

View File

@@ -15,7 +15,7 @@ module Spree
@payment_method = params[:payment_method].
delete(:type).
constantize.
new(payment_method_params)
new(PermittedAttributes::PaymentMethod.new(params[:payment_method]).call)
@object = @payment_method
invoke_callbacks(:create, :before)
@@ -92,17 +92,6 @@ module Spree
private
def payment_method_params
params.require(:payment_method).permit(
:name, :description, :type, :active,
:environment, :display_on, :tag_list,
:preferred_enterprise_id, :preferred_server, :preferred_login, :preferred_password,
:calculator_type, :preferred_api_key,
:preferred_signature, :preferred_solution, :preferred_landing_page, :preferred_logourl,
:preferred_test_mode, distributor_ids: []
)
end
def force_environment
params[:payment_method][:environment] = Rails.env unless spree_current_user.admin?
end
@@ -127,7 +116,7 @@ module Spree
def load_hubs
# rubocop:disable Style/TernaryParentheses
@hubs = Enterprise.managed_by(spree_current_user).is_distributor.sort_by! do |d|
@hubs = Enterprise.managed_by(spree_current_user).is_distributor.to_a.sort_by! do |d|
[(@payment_method.has_distributor? d) ? 0 : 1, d.name]
end
# rubocop:enable Style/TernaryParentheses
@@ -164,7 +153,7 @@ module Spree
# Also, remove password if present and blank
def params_for_update
gateway_params = params[ActiveModel::Naming.param_key(@payment_method)] || {}
params_for_update = payment_method_params.merge(gateway_params)
params_for_update = params[:payment_method].merge(gateway_params)
params_for_update.each do |key, _value|
if key.include?("password") && params_for_update[key].blank?
@@ -172,7 +161,7 @@ module Spree
end
end
params_for_update
PermittedAttributes::PaymentMethod.new(params_for_update).call
end
end
end

View File

@@ -16,7 +16,7 @@ module Spree
flash[:success] = flash_message_for(@object, :successfully_removed)
end
# if destroy fails it won't show any errors to the user
redirect_to admin_product_product_properties_url(params[:product_id], @url_filters)
redirect_to spree.admin_product_product_properties_url(params[:product_id], @url_filters)
end
private

View File

@@ -294,7 +294,7 @@ module Spree
if report_in_order_management_engine?(report)
main_app.public_send("new_order_management_reports_#{report}_url".to_sym)
else
public_send("#{report}_admin_reports_url".to_sym)
spree.public_send("#{report}_admin_reports_url".to_sym)
end
rescue NoMethodError
url_for([:new, :admin, :reports, report.to_s.singularize])

View File

@@ -50,7 +50,7 @@ module Spree
def load_hubs
# rubocop:disable Style/TernaryParentheses
@hubs = Enterprise.managed_by(spree_current_user).is_distributor.sort_by! do |d|
@hubs = Enterprise.managed_by(spree_current_user).is_distributor.to_a.sort_by! do |d|
[(@shipping_method.has_distributor? d) ? 0 : 1, d.name]
end
# rubocop:enable Style/TernaryParentheses
@@ -86,12 +86,7 @@ module Spree
params.require(:shipping_method).permit(
:name, :description, :display_on, :require_ship_address, :tag_list, :calculator_type,
distributor_ids: [],
calculator_attributes: [
:id, :preferred_currency, :preferred_amount, :preferred_unit_from_list,
:preferred_per_unit, :preferred_flat_percent, :preferred_first_item,
:preferred_additional_item, :preferred_max_items, :preferred_minimal_amount,
:preferred_normal_amount, :preferred_discount_amount
]
calculator_attributes: PermittedAttributes::Calculator.attributes
)
end
end

View File

@@ -21,9 +21,9 @@ module Spree
if @object.update(permitted_resource_params)
flash[:success] = flash_message_for(@object, :successfully_updated)
redirect_to admin_product_variants_url(params[:product_id], @url_filters)
redirect_to spree.admin_product_variants_url(params[:product_id], @url_filters)
else
redirect_to edit_admin_product_variant_url(params[:product_id], @object, @url_filters)
redirect_to spree.edit_admin_product_variant_url(params[:product_id], @object, @url_filters)
end
end
@@ -40,9 +40,9 @@ module Spree
@object.attributes = permitted_resource_params
if @object.save
flash[:success] = flash_message_for(@object, :successfully_created)
redirect_to admin_product_variants_url(params[:product_id], @url_filters)
redirect_to spree.admin_product_variants_url(params[:product_id], @url_filters)
else
redirect_to new_admin_product_variant_url(params[:product_id], @url_filters)
redirect_to spree.new_admin_product_variant_url(params[:product_id], @url_filters)
end
return unless @object.present? && @object.valid?

View File

@@ -6,6 +6,51 @@ Spree::PaypalController.class_eval do
after_action :reset_order_when_complete, only: :confirm
before_action :permit_parameters!
def express
order = current_order || raise(ActiveRecord::RecordNotFound)
items = order.line_items.map(&method(:line_item))
tax_adjustments = order.adjustments.tax
# TODO: Remove in Spree 2.2
tax_adjustments = tax_adjustments.additional if tax_adjustments.respond_to?(:additional)
shipping_adjustments = order.adjustments.shipping
order.adjustments.eligible.each do |adjustment|
next if (tax_adjustments + shipping_adjustments).include?(adjustment)
items << {
Name: adjustment.label,
Quantity: 1,
Amount: {
currencyID: order.currency,
value: adjustment.amount
}
}
end
# Because PayPal doesn't accept $0 items at all.
# See #10
# https://cms.paypal.com/uk/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_ECCustomizing
# "It can be a positive or negative value but not zero."
items.reject! do |item|
item[:Amount][:value].zero?
end
pp_request = provider.build_set_express_checkout(express_checkout_request_details(order, items))
begin
pp_response = provider.set_express_checkout(pp_request)
if pp_response.success?
redirect_to provider.express_checkout_url(pp_response, useraction: 'commit')
else
flash[:error] = Spree.t('flash.generic_error', scope: 'paypal', reasons: pp_response.errors.map(&:long_message).join(" "))
redirect_to spree.checkout_state_path(:payment)
end
rescue SocketError
flash[:error] = Spree.t('flash.connection_failed', scope: 'paypal')
redirect_to spree.checkout_state_path(:payment)
end
end
def cancel
flash[:notice] = Spree.t('flash.cancel', scope: 'paypal')
redirect_to main_app.checkout_path
@@ -49,4 +94,24 @@ Spree::PaypalController.class_eval do
orphaned_payments = current_order.payments.where(payment_method_id: payment_method.id, source_id: nil)
orphaned_payments.each(&:destroy)
end
def completion_route(order)
spree.order_path(order, token: order.token)
end
def express_checkout_request_details(order, items)
{
SetExpressCheckoutRequestDetails: {
InvoiceID: order.number,
BuyerEmail: order.email,
ReturnURL: spree.confirm_paypal_url(payment_method_id: params[:payment_method_id], utm_nooverride: 1),
CancelURL: spree.cancel_paypal_url,
SolutionType: payment_method.preferred_solution.presence || "Mark",
LandingPage: payment_method.preferred_landing_page.presence || "Billing",
cppheaderimage: payment_method.preferred_logourl.presence || "",
NoShipping: 1,
PaymentDetails: [payment_details(items)]
}
}
end
end

View File

@@ -184,6 +184,12 @@ module Admin
json: "'#{@spree_api_key}'" }
end
def admin_inject_available_units
admin_inject_json "admin.products",
"availableUnits",
Spree::Config.available_units
end
def admin_inject_json(ng_module, name, data)
json = data.to_json
render partial: "admin/json/injection_ams",

View File

@@ -7,6 +7,8 @@ module CheckoutHelper
adjustments = order.adjustments.eligible
exclude = opts[:exclude] || {}
adjustments = adjustments.to_a
# Remove empty tax adjustments and (optionally) shipping fees
adjustments.reject! { |a| a.originator_type == 'Spree::TaxRate' && a.amount == 0 }
adjustments.reject! { |a| a.originator_type == 'Spree::ShippingMethod' } if exclude.include? :shipping

View File

@@ -4,7 +4,7 @@ module InjectionHelper
include SerializerHelper
def inject_enterprises(enterprises = nil)
inject_json_ams(
inject_json_array(
"enterprises",
enterprises || default_enterprise_query,
Api::EnterpriseSerializer,
@@ -15,7 +15,7 @@ module InjectionHelper
def inject_groups
select_only = required_attributes EnterpriseGroup, Api::GroupListSerializer
inject_json_ams(
inject_json_array(
"groups",
EnterpriseGroup.on_front_page.by_position.select(select_only).
includes(enterprises: [:shipping_methods, { address: [:state, :country] }],
@@ -26,7 +26,7 @@ module InjectionHelper
end
def inject_enterprise_shopfront(enterprise)
inject_json_ams(
inject_json(
"shopfront",
enterprise,
Api::EnterpriseShopfrontSerializer
@@ -36,7 +36,7 @@ module InjectionHelper
def inject_enterprise_shopfront_list
select_only = required_attributes Enterprise, Api::EnterpriseShopfrontListSerializer
inject_json_ams(
inject_json_array(
"enterprises",
Enterprise.activated.visible.select(select_only).includes(address: [:state, :country]).all,
Api::EnterpriseShopfrontListSerializer
@@ -50,13 +50,13 @@ module InjectionHelper
includes(:properties, address: [:state, :country], supplied_products: :properties).
all
inject_json_ams "enterprises",
enterprises_and_relatives,
Api::EnterpriseSerializer, enterprise_injection_data
inject_json_array "enterprises",
enterprises_and_relatives,
Api::EnterpriseSerializer, enterprise_injection_data
end
def inject_group_enterprises
inject_json_ams(
inject_json_array(
"enterprises",
@group.enterprises.activated.all,
Api::EnterpriseSerializer,
@@ -65,11 +65,18 @@ module InjectionHelper
end
def inject_current_hub
inject_json_ams "currentHub", current_distributor, Api::EnterpriseSerializer, enterprise_injection_data
inject_json "currentHub",
current_distributor,
Api::EnterpriseSerializer,
enterprise_injection_data
end
def inject_current_order
inject_json_ams "currentOrder", current_order, Api::CurrentOrderSerializer, current_distributor: current_distributor, current_order_cycle: current_order_cycle
inject_json "currentOrder",
current_order,
Api::CurrentOrderSerializer,
current_distributor: current_distributor,
current_order_cycle: current_order_cycle
end
def inject_current_order_cycle
@@ -79,73 +86,78 @@ module InjectionHelper
end
def inject_available_shipping_methods
inject_json_ams "shippingMethods", available_shipping_methods,
Api::ShippingMethodSerializer, current_order: current_order
inject_json_array "shippingMethods", available_shipping_methods,
Api::ShippingMethodSerializer, current_order: current_order
end
def inject_available_payment_methods
inject_json_ams "paymentMethods", available_payment_methods,
Api::PaymentMethodSerializer, current_order: current_order
inject_json_array "paymentMethods", available_payment_methods,
Api::PaymentMethodSerializer, current_order: current_order
end
def inject_taxons
inject_json_ams "taxons", Spree::Taxon.all.to_a, Api::TaxonSerializer
inject_json_array "taxons", Spree::Taxon.all.to_a, Api::TaxonSerializer
end
def inject_properties
inject_json_ams "properties", Spree::Property.all.to_a, Api::PropertySerializer
inject_json_array "properties", Spree::Property.all.to_a, Api::PropertySerializer
end
def inject_currency_config
inject_json_ams "currencyConfig", {}, Api::CurrencyConfigSerializer
inject_json "currencyConfig", {}, Api::CurrencyConfigSerializer
end
def inject_open_street_map_config
inject_json_ams "openStreetMapConfig", {}, Api::OpenStreetMapConfigSerializer
inject_json "openStreetMapConfig", {}, Api::OpenStreetMapConfigSerializer
end
def inject_spree_api_key
render partial: "json/injection_ams", locals: { name: 'spreeApiKey', json: "'#{@spree_api_key}'" }
render partial: "json/injection_ams",
locals: { name: 'spreeApiKey', json: "'#{@spree_api_key}'" }
end
def inject_available_countries
inject_json_ams "availableCountries", available_countries, Api::CountrySerializer
inject_json_array "availableCountries", available_countries, Api::CountrySerializer
end
def inject_enterprise_attributes
render partial: "json/injection_ams", locals: { name: 'enterpriseAttributes', json: @enterprise_attributes.to_json.to_s }
render partial: "json/injection_ams",
locals: { name: 'enterpriseAttributes', json: @enterprise_attributes.to_json.to_s }
end
def inject_orders
inject_json_ams "orders", @orders.all, Api::OrderSerializer
inject_json_array "orders", @orders.all, Api::OrderSerializer
end
def inject_shops
customers = spree_current_user.customers
shops = Enterprise.where(id: @orders.pluck(:distributor_id).uniq | customers.pluck(:enterprise_id))
inject_json_ams "shops", shops.all, Api::ShopForOrdersSerializer
shops = Enterprise.where(id: @orders.pluck(:distributor_id).uniq |
customers.pluck(:enterprise_id))
inject_json_array "shops", shops.all, Api::ShopForOrdersSerializer
end
def inject_saved_credit_cards
data = spree_current_user ? spree_current_user.credit_cards.with_payment_profile.all : []
inject_json_ams "savedCreditCards", data, Api::CreditCardSerializer
inject_json_array "savedCreditCards", data, Api::CreditCardSerializer
end
def inject_current_user
inject_json_ams "user", spree_current_user, Api::UserSerializer
inject_json "user", spree_current_user, Api::UserSerializer
end
def inject_rails_flash
inject_json_ams "railsFlash", OpenStruct.new(flash.to_hash), Api::RailsFlashSerializer
inject_json "railsFlash", OpenStruct.new(flash.to_hash), Api::RailsFlashSerializer
end
def inject_json_ams(name, data, serializer, opts = {})
if data.is_a?(Array)
opts = { each_serializer: serializer }.merge(opts)
serializer = ActiveModel::ArraySerializer
end
def inject_json_array(name, data, serializer, opts = {})
opts = { each_serializer: serializer }.merge(opts)
serializer = ActiveModel::ArraySerializer
inject_json(name, data, serializer, opts)
end
def inject_json(name, data, serializer, opts = {})
serializer_instance = serializer.new(data, opts)
json = serializer_instance.to_json
render partial: "json/injection_ams", locals: { name: name, json: json }

View File

@@ -8,6 +8,10 @@ module Spree
end
options_from_collection_for_select(currencies, :first, :last, Spree::Config[:currency])
end
def all_units
["g", "oz", "lb", "kg", "T", "mL", "L", "kL"]
end
end
end
end

View File

@@ -86,9 +86,9 @@ module Spree
def link_to_delete(resource, options = {})
url = options[:url] || object_url(resource)
name = options[:name] || Spree.t(:delete)
name = options[:name] || I18n.t(:delete)
options[:class] = "delete-resource"
options[:data] = { confirm: Spree.t(:are_you_sure), action: 'remove' }
options[:data] = { confirm: I18n.t(:are_you_sure), action: 'remove' }
link_to_with_icon 'icon-trash', name, url, options
end

View File

@@ -113,11 +113,12 @@ module Spree
end
def event_link(event)
button_link_to(Spree.t(event),
event_label = I18n.t(event, scope: "actions")
confirm_message = I18n.t("admin.orders.edit.order_sure_want_to", event: event_label)
button_link_to(event_label,
fire_admin_order_url(@order, e: event),
method: :put,
icon: "icon-#{event}",
data: { confirm: Spree.t(:order_sure_want_to, event: Spree.t(event)) })
method: :put, icon: "icon-#{event}",
data: { confirm: confirm_message })
end
end
end

View File

@@ -0,0 +1,16 @@
# frozen_string_literal: true
module TermsAndConditionsHelper
def terms_and_conditions_activated?
current_order.distributor.terms_and_conditions.file?
end
def terms_and_conditions_already_accepted?
customer_terms_and_conditions_accepted_at = spree_current_user&.
customer_of(current_order.distributor)&.terms_and_conditions_accepted_at
customer_terms_and_conditions_accepted_at.present? &&
(customer_terms_and_conditions_accepted_at >
current_order.distributor.terms_and_conditions_updated_at)
end
end

View File

@@ -60,11 +60,11 @@ class ProducerMailer < Spree::BaseMailer
end
def total_from_line_items(line_items)
Spree::Money.new line_items.sum(&:total)
Spree::Money.new line_items.to_a.sum(&:total)
end
def tax_total_from_line_items(line_items)
Spree::Money.new line_items.sum(&:included_tax)
Spree::Money.new line_items.to_a.sum(&:included_tax)
end
# This hack makes ActiveRecord skip the default_scope (deleted_at IS NULL)

View File

@@ -8,10 +8,12 @@ module Spree
def reset_password_instructions(user, token, _opts = {})
@edit_password_reset_url = spree.
edit_spree_user_password_url(reset_password_token: token)
subject = "#{Spree::Config[:site_name]} " \
"#{I18n.t('spree.user_mailer.reset_password_instructions.subject')}"
mail(to: user.email, from: from_address,
subject: Spree::Config[:site_name] + ' ' +
I18n.t(:subject, scope: [:devise, :mailer, :reset_password_instructions]))
I18n.with_locale valid_locale(user) do
mail(to: user.email, from: from_address, subject: subject)
end
end
# This is a OFN specific email, not from Devise::Mailer

View File

@@ -49,7 +49,7 @@ module Calculator
# Finds relevant fees for each line_item,
# calculates the tax on them, and returns the total tax
def per_item_fees_total(order, calculator)
order.line_items.sum do |line_item|
order.line_items.to_a.sum do |line_item|
calculator.per_item_enterprise_fee_applicators_for(line_item.variant)
.select { |applicator| applicable_rate?(applicator, line_item) }
.sum { |applicator| applicator.enterprise_fee.compute_amount(line_item) }

View File

@@ -18,7 +18,7 @@ class Calculator::FlatPercentPerItem < Spree::Calculator
end
def compute(object)
line_items_for(object).sum do |li|
line_items_for(object).to_a.sum do |li|
unless li.price.present? && li.quantity.present?
raise ArgumentError, "object must respond to #price and #quantity"
end

View File

@@ -32,7 +32,7 @@ module Calculator
private
def total_weight(line_items)
line_items.sum do |line_item|
line_items.to_a.sum do |line_item|
line_item_weight(line_item)
end
end

View File

@@ -4,7 +4,7 @@ module ProductStock
extend ActiveSupport::Concern
def on_demand
if has_variants?
if variants?
raise 'Cannot determine product on_demand value of product with multiple variants' if variants.size > 1
variants.first.on_demand
@@ -14,7 +14,7 @@ module ProductStock
end
def on_hand
if has_variants?
if variants?
variants.map(&:on_hand).reduce(:+)
else
master.on_hand

View File

@@ -470,6 +470,8 @@ class Enterprise < ActiveRecord::Base
end
def initialize_permalink
return unless name
self.permalink = Enterprise.find_available_permalink(name)
end

View File

@@ -50,6 +50,7 @@ class ModelSet
# Remove all elements to be deleted from collection and return them
# Allows us to render @model_set.collection without deleted elements
deleted = []
@collection = collection.to_a
collection.delete_if { |e| deleted << e if @delete_if.andand.call(e.attributes) }
deleted
end

View File

@@ -8,7 +8,7 @@ module ProductImport
@enterprise_ids = enterprise_ids
if enterprise_ids.present?
relation.update_all(count_on_hand: 0)
relation.update_all(count_on_hand: 0, on_demand: false)
else
0
end

View File

@@ -47,7 +47,7 @@ module Spree
end
add_shopping_abilities user
add_base_abilities user if new_user? user
add_base_abilities user if is_new_user? user
add_enterprise_management_abilities user if can_manage_enterprises? user
add_group_management_abilities user if can_manage_groups? user
add_product_management_abilities user if can_manage_products? user
@@ -57,7 +57,7 @@ module Spree
end
# New users have no enterprises.
def new_user?(user)
def is_new_user?(user)
user.enterprises.blank?
end

View File

@@ -21,6 +21,8 @@
# a.get :color
# a.preferred_color
#
require 'spree/core/mail_settings'
module Spree
class AppConfiguration < Preferences::Configuration
# Should state/state_name be required
@@ -144,5 +146,8 @@ module Spree
# Enable cache
preference :enable_products_cache?, :boolean,
default: (Rails.env.production? || Rails.env.staging?)
# Available units
preference :available_units, :string, default: "g,kg,T,mL,L,kL"
end
end

View File

@@ -1,5 +1,7 @@
# frozen_string_literal: true
require 'spree/core/s3_support'
module Spree
class Image < Asset
validates_attachment_presence :attachment
@@ -48,26 +50,36 @@ module Spree
false
end
def self.set_attachment_attributes(attribute_name, attribute_value)
def self.set_attachment_attribute(attribute_name, attribute_value)
attachment_definitions[:attachment][attribute_name] = attribute_value
end
def self.set_s3_attachment_definitions
def self.set_storage_attachment_attributes
if Spree::Config[:use_s3]
set_attachment_attributes(:storage, :s3)
set_attachment_attributes(:s3_credentials, s3_credentials)
set_attachment_attributes(:s3_headers,
ActiveSupport::JSON.decode(Spree::Config[:s3_headers]))
set_attachment_attributes(:bucket, Spree::Config[:s3_bucket])
set_s3_attachment_attributes
else
attachment_definitions[:attachment].delete :storage
attachment_definitions[:attachment].delete(:storage)
end
end
def self.set_s3_attachment_attributes
set_attachment_attribute(:storage, :s3)
set_attachment_attribute(:s3_credentials, s3_credentials)
set_attachment_attribute(:s3_headers,
ActiveSupport::JSON.decode(Spree::Config[:s3_headers]))
set_attachment_attribute(:bucket, Spree::Config[:s3_bucket])
# We use :s3_alias_url (virtual host url style) and set the URL on property s3_host_alias
set_attachment_attribute(:s3_host_alias, attachment_definitions[:attachment][:url])
set_attachment_attribute(:url, ":s3_alias_url")
end
private_class_method :set_s3_attachment_attributes
def self.s3_credentials
{ access_key_id: Spree::Config[:s3_access_key],
secret_access_key: Spree::Config[:s3_secret],
bucket: Spree::Config[:s3_bucket] }
end
private_class_method :s3_credentials
end
end

View File

@@ -192,7 +192,7 @@ module Spree
line_item_adjustments = OrderAdjustmentsFetcher.new(order).line_item_adjustments(self)
(price + line_item_adjustments.sum(&:amount) / quantity).round(2)
(price + line_item_adjustments.to_a.sum(&:amount) / quantity).round(2)
end
def single_display_amount_with_adjustments

View File

@@ -0,0 +1,18 @@
# frozen_string_literal: true
module Spree
class OptionType < ActiveRecord::Base
has_many :products, through: :product_option_types
has_many :option_values, -> { order(:position) }, dependent: :destroy
has_many :product_option_types, dependent: :destroy
validates :name, :presentation, presence: true
default_scope -> { order("#{table_name}.position") }
accepts_nested_attributes_for :option_values,
reject_if: lambda { |ov|
ov[:name].blank? || ov[:presentation].blank?
},
allow_destroy: true
end
end

View File

@@ -1,5 +0,0 @@
module Spree
OptionType.class_eval do
has_many :products, through: :product_option_types
end
end

View File

@@ -0,0 +1,12 @@
# frozen_string_literal: true
module Spree
class OptionValue < ActiveRecord::Base
belongs_to :option_type
acts_as_list scope: :option_type
has_and_belongs_to_many :variants, join_table: 'spree_option_values_variants',
class_name: "Spree::Variant"
validates :name, :presentation, presence: true
end
end

View File

@@ -10,6 +10,9 @@
# inherited hook will assign a new hash for the subclass definitions
# and copy all the definitions allowing the subclass to add
# additional defintions without affecting the base
require 'spree/preferences/store'
module Spree
module Preferences
module Preferable

57
app/models/spree/price.rb Normal file
View File

@@ -0,0 +1,57 @@
# frozen_string_literal: true
module Spree
class Price < ActiveRecord::Base
acts_as_paranoid without_default_scope: true
belongs_to :variant, class_name: 'Spree::Variant'
validate :check_price
validates :amount, numericality: { greater_than_or_equal_to: 0 }, allow_nil: true
def display_amount
money
end
alias :display_price :display_amount
def money
Spree::Money.new(amount || 0, currency: currency)
end
def price
amount
end
def price=(price)
self[:amount] = parse_price(price)
end
# Allow prices to access associated soft-deleted variants.
def variant
Spree::Variant.unscoped { super }
end
private
def check_price
return unless currency.nil?
self.currency = Spree::Config[:currency]
end
# strips all non-price-like characters from the price, taking into account locale settings
def parse_price(price)
return price unless price.is_a?(String)
separator, _delimiter = I18n.t([:'number.currency.format.separator',
:'number.currency.format.delimiter'])
non_price_characters = /[^0-9\-#{separator}]/
# Strip everything else first
price.gsub!(non_price_characters, '')
# Then replace the locale-specific decimal separator with the standard separator if necessary
price.gsub!(separator, '.') unless separator == '.'
price.to_d
end
end
end

View File

@@ -1,18 +0,0 @@
module Spree
Price.class_eval do
acts_as_paranoid without_default_scope: true
# Allow prices to access associated soft-deleted variants.
def variant
Spree::Variant.unscoped { super }
end
private
def check_price
if currency.nil?
self.currency = Spree::Config[:currency]
end
end
end
end

485
app/models/spree/product.rb Executable file
View File

@@ -0,0 +1,485 @@
# frozen_string_literal: true
require 'open_food_network/permalink_generator'
require 'open_food_network/property_merge'
require 'concerns/product_stock'
# PRODUCTS
# Products represent an entity for sale in a store.
# Products can have variations, called variants
# Products properties include description, permalink, availability,
# shipping category, etc. that do not change by variant.
#
# MASTER VARIANT
# Every product has one master variant, which stores master price and sku, size and weight, etc.
# The master variant does not have option values associated with it.
# Price, SKU, size, weight, etc. are all delegated to the master variant.
# Contains on_hand inventory levels only when there are no variants for the product.
#
# VARIANTS
# All variants can access the product properties directly (via reverse delegation).
# Inventory units are tied to Variant.
# The master variant can have inventory units, but not option values.
# All other variants have option values and may have inventory units.
# Sum of on_hand each variant's inventory level determine "on_hand" level for the product.
#
module Spree
class Product < ActiveRecord::Base
include PermalinkGenerator
include ProductStock
acts_as_paranoid
has_many :product_option_types, dependent: :destroy
# We have an after_destroy callback on Spree::ProductOptionType. However, if we
# don't specify dependent => destroy on this association, it is not called. See:
# https://github.com/rails/rails/issues/7618
has_many :option_types, through: :product_option_types, dependent: :destroy
has_many :product_properties, dependent: :destroy
has_many :properties, through: :product_properties
has_many :classifications, dependent: :delete_all
has_many :taxons, through: :classifications
belongs_to :tax_category, class_name: 'Spree::TaxCategory'
belongs_to :shipping_category, class_name: 'Spree::ShippingCategory'
belongs_to :supplier, class_name: 'Enterprise', touch: true
belongs_to :primary_taxon, class_name: 'Spree::Taxon', touch: true
has_one :master,
-> { where is_master: true },
class_name: 'Spree::Variant',
dependent: :destroy
has_many :variants, -> {
where(is_master: false).order("#{::Spree::Variant.quoted_table_name}.position ASC")
}, class_name: 'Spree::Variant'
has_many :variants_including_master,
-> { order("#{::Spree::Variant.quoted_table_name}.position ASC") },
class_name: 'Spree::Variant',
dependent: :destroy
has_many :prices, -> {
order('spree_variants.position, spree_variants.id, currency')
}, through: :variants
has_many :stock_items, through: :variants
delegate_belongs_to :master, :sku, :price, :currency, :display_amount, :display_price, :weight,
:height, :width, :depth, :is_master, :default_price?, :cost_currency,
:price_in, :amount_in, :unit_value, :unit_description
delegate_belongs_to :master, :cost_price if Variant.table_exists? &&
Variant.column_names.include?('cost_price')
delegate :images_attributes=, :display_as=, to: :master
after_create :set_master_variant_defaults
after_create :build_variants_from_option_values_hash, if: :option_values_hash
after_save :save_master
delegate :images, to: :master, prefix: true
alias_method :images, :master_images
has_many :variant_images, -> { order(:position) }, source: :images,
through: :variants_including_master
accepts_nested_attributes_for :variants, allow_destroy: true
validates :name, presence: true
validates :permalink, presence: true
validates :price, presence: true, if: proc { Spree::Config[:require_master_price] }
validates :shipping_category_id, presence: true
validates :supplier, presence: true
validates :primary_taxon, presence: true
validates :tax_category_id, presence: true, if: "Spree::Config.products_require_tax_category"
validates :variant_unit, presence: true
validates :variant_unit_scale,
presence: { if: ->(p) { %w(weight volume).include? p.variant_unit } }
validates :variant_unit_name,
presence: { if: ->(p) { p.variant_unit == 'items' } }
attr_accessor :option_values_hash
accepts_nested_attributes_for :product_properties,
allow_destroy: true,
reject_if: lambda { |pp| pp[:property_name].blank? }
make_permalink order: :name
alias :options :product_option_types
after_initialize :ensure_master
after_initialize :set_available_on_to_now, if: :new_record?
before_validation :sanitize_permalink
before_save :add_primary_taxon_to_taxons
after_save :remove_previous_primary_taxon_from_taxons
after_save :ensure_standard_variant
after_save :update_units
before_destroy :punch_permalink
# -- Joins
scope :with_order_cycles_outer, -> {
joins("
LEFT OUTER JOIN spree_variants AS o_spree_variants
ON (o_spree_variants.product_id = spree_products.id)").
joins("
LEFT OUTER JOIN exchange_variants AS o_exchange_variants
ON (o_exchange_variants.variant_id = o_spree_variants.id)").
joins("
LEFT OUTER JOIN exchanges AS o_exchanges
ON (o_exchanges.id = o_exchange_variants.exchange_id)").
joins("
LEFT OUTER JOIN order_cycles AS o_order_cycles
ON (o_order_cycles.id = o_exchanges.order_cycle_id)")
}
scope :imported_on, lambda { |import_date|
import_date = Time.zone.parse import_date if import_date.is_a? String
import_date = import_date.to_date
joins(:variants).merge(Spree::Variant.
where(import_date: import_date.beginning_of_day..import_date.end_of_day))
}
scope :with_order_cycles_inner, -> {
joins(variants_including_master: { exchanges: :order_cycle })
}
scope :visible_for, lambda { |enterprise|
joins('
LEFT OUTER JOIN spree_variants AS o_spree_variants
ON (o_spree_variants.product_id = spree_products.id)').
joins('
LEFT OUTER JOIN inventory_items AS o_inventory_items
ON (o_spree_variants.id = o_inventory_items.variant_id)').
where('o_inventory_items.enterprise_id = (?) AND visible = (?)', enterprise, true)
}
# -- Scopes
scope :in_supplier, lambda { |supplier| where(supplier_id: supplier) }
# Products distributed via the given distributor through an OC
scope :in_distributor, lambda { |distributor|
distributor = distributor.respond_to?(:id) ? distributor.id : distributor.to_i
with_order_cycles_outer.
where('(o_exchanges.incoming = ? AND o_exchanges.receiver_id = ?)', false, distributor).
select('distinct spree_products.*')
}
scope :in_distributors, lambda { |distributors|
with_order_cycles_outer.
where('(o_exchanges.incoming = ? AND o_exchanges.receiver_id IN (?))', false, distributors).
uniq
}
# Products supplied by a given enterprise or distributed via that enterprise through an OC
scope :in_supplier_or_distributor, lambda { |enterprise|
enterprise = enterprise.respond_to?(:id) ? enterprise.id : enterprise.to_i
with_order_cycles_outer.
where("
spree_products.supplier_id = ?
OR (o_exchanges.incoming = ? AND o_exchanges.receiver_id = ?)
", enterprise, false, enterprise).
select('distinct spree_products.*')
}
# Products distributed by the given order cycle
scope :in_order_cycle, lambda { |order_cycle|
with_order_cycles_inner.
merge(Exchange.outgoing).
where('order_cycles.id = ?', order_cycle)
}
scope :in_an_active_order_cycle, lambda {
with_order_cycles_inner.
merge(OrderCycle.active).
merge(Exchange.outgoing).
where('order_cycles.id IS NOT NULL')
}
scope :by_producer, -> { joins(:supplier).order('enterprises.name') }
scope :by_name, -> { order('name') }
scope :managed_by, lambda { |user|
if user.has_spree_role?('admin')
where(nil)
else
where('supplier_id IN (?)', user.enterprises.select("enterprises.id"))
end
}
scope :stockable_by, lambda { |enterprise|
return where('1=0') if enterprise.blank?
permitted_producer_ids = EnterpriseRelationship.joins(:parent).permitting(enterprise.id)
.with_permission(:add_to_order_cycle)
.where(enterprises: { is_primary_producer: true })
.pluck(:parent_id)
return where('spree_products.supplier_id IN (?)', [enterprise.id] | permitted_producer_ids)
}
scope :active, lambda {
where("spree_products.deleted_at IS NULL AND spree_products.available_on <= ?", Time.zone.now)
}
def self.group_by_products_id
group(column_names.map { |col_name| "#{table_name}.#{col_name}" })
end
def to_param
permalink.present? ? permalink : (permalink_was || name.to_s.to_url)
end
# the master variant is not a member of the variants array
def variants?
variants.any?
end
def tax_category
if self[:tax_category_id].nil?
TaxCategory.find_by(is_default: true)
else
TaxCategory.find(self[:tax_category_id])
end
end
# Ensures option_types and product_option_types exist for keys in option_values_hash
def ensure_option_types_exist_for_values_hash
return if option_values_hash.nil?
option_values_hash.keys.map(&:to_i).each do |id|
option_type_ids << id unless option_type_ids.include?(id)
unless product_option_types.pluck(:option_type_id).include?(id)
product_option_types.create(option_type_id: id)
end
end
end
# for adding products which are closely related to existing ones
def duplicate
duplicator = Spree::Core::ProductDuplicator.new(self)
duplicator.duplicate
end
# use deleted? rather than checking the attribute directly. this
# allows extensions to override deleted? if they want to provide
# their own definition.
def deleted?
!!deleted_at
end
def available?
!(available_on.nil? || available_on.future?)
end
# split variants list into hash which shows mapping of opt value onto matching variants
# eg categorise_variants_from_option(color) => {"red" -> [...], "blue" -> [...]}
def categorise_variants_from_option(opt_type)
return {} unless option_types.include?(opt_type)
variants.active.group_by { |v| v.option_values.detect { |o| o.option_type == opt_type } }
end
def self.like_any(fields, values)
where fields.map { |field|
values.map { |value|
arel_table[field].matches("%#{value}%")
}.inject(:or)
}.inject(:or)
end
def empty_option_values?
options.empty? || options.any? do |opt|
opt.option_type.option_values.empty?
end
end
def property(property_name)
return nil unless prop = properties.find_by(name: property_name)
product_properties.find_by(property: prop).try(:value)
end
def set_property(property_name, property_value)
ActiveRecord::Base.transaction do
property = Property.where(name: property_name).first_or_create!(presentation: property_name)
product_property = ProductProperty.where(product: self,
property: property).first_or_initialize
product_property.value = property_value
product_property.save!
end
end
def total_on_hand
stock_items.sum(&:count_on_hand)
end
# Master variant may be deleted (i.e. when the product is deleted)
# which would make AR's default finder return nil.
# This is a stopgap for that little problem.
def master
super || variants_including_master.with_deleted.find_by(is_master: true)
end
def properties_including_inherited
# Product properties override producer properties
ps = product_properties.all
if inherits_properties
ps = OpenFoodNetwork::PropertyMerge.merge(ps, supplier.producer_properties)
end
ps.
sort_by(&:position).
map { |pp| { id: pp.property.id, name: pp.property.presentation, value: pp.value } }
end
def in_distributor?(distributor)
self.class.in_distributor(distributor).include? self
end
def in_order_cycle?(order_cycle)
self.class.in_order_cycle(order_cycle).include? self
end
def variants_distributed_by(order_cycle, distributor)
order_cycle.variants_distributed_by(distributor).where(product_id: self)
end
# Get the most recent import_date of a product's variants
def import_date
variants.map(&:import_date).compact.max
end
def variant_unit_option_type
return if variant_unit.blank?
option_type_name = "unit_#{variant_unit}"
option_type_presentation = variant_unit.capitalize
Spree::OptionType.find_by(name: option_type_name) ||
Spree::OptionType.create!(name: option_type_name,
presentation: option_type_presentation)
end
def self.all_variant_unit_option_types
Spree::OptionType.where('name LIKE ?', 'unit_%%')
end
def destroy_with_delete_from_order_cycles
transaction do
touch_distributors
ExchangeVariant.
where('exchange_variants.variant_id IN (?)', variants_including_master.with_deleted.
select(:id)).destroy_all
destroy_without_delete_from_order_cycles
end
end
alias_method_chain :destroy, :delete_from_order_cycles
private
# Builds variants from a hash of option types & values
def build_variants_from_option_values_hash
ensure_option_types_exist_for_values_hash
values = option_values_hash.values
values = values.inject(values.shift) { |memo, value| memo.product(value).map(&:flatten) }
values.each do |ids|
variants.create(
option_value_ids: ids,
price: master.price
)
end
save
end
# ensures the master variant is flagged as such
def set_master_variant_defaults
master.is_master = true
end
# Here we rescue errors when saving master variants (without the need for a
# validates_associated on master) and we get more specific data about the errors
def save_master
if master && (
master.changed? || master.new_record? || (
master.default_price && (
master.default_price.changed? || master.default_price.new_record?
)
)
)
master.save!
end
# If the master cannot be saved, the Product object will get its errors
# and will be destroyed
rescue ActiveRecord::RecordInvalid
master.errors.each do |att, error|
errors.add(att, error)
end
raise
end
def ensure_master
return unless new_record?
self.master ||= Variant.new
end
def punch_permalink
# Punch permalink with date prefix
update_attribute :permalink, "#{Time.now.to_i}_#{permalink}"
end
def set_available_on_to_now
self.available_on ||= Time.zone.now
end
def update_units
return unless variant_unit_changed?
option_types.delete self.class.all_variant_unit_option_types
option_types << variant_unit_option_type if variant_unit.present?
variants_including_master.each(&:update_units)
end
def touch_distributors
Enterprise.distributing_products(id).each(&:touch)
end
def add_primary_taxon_to_taxons
taxons << primary_taxon unless taxons.include? primary_taxon
end
def remove_previous_primary_taxon_from_taxons
return unless primary_taxon_id_changed? && primary_taxon_id_was
taxons.destroy(primary_taxon_id_was)
end
def ensure_standard_variant
return unless master.valid? && variants.empty?
variant = master.dup
variant.product = self
variant.is_master = false
variants << variant
end
# Spree creates a permalink already but our implementation fixes an edge case.
def sanitize_permalink
return unless permalink.blank? || permalink_changed?
requested = permalink.presence || permalink_was.presence || name.presence || 'product'
self.permalink = create_unique_permalink(requested.parameterize)
end
end
end

View File

@@ -1,265 +0,0 @@
require 'open_food_network/permalink_generator'
require 'open_food_network/property_merge'
require 'concerns/product_stock'
Spree::Product.class_eval do
include PermalinkGenerator
include ProductStock
# We have an after_destroy callback on Spree::ProductOptionType. However, if we
# don't specify dependent => destroy on this association, it is not called. See:
# https://github.com/rails/rails/issues/7618
has_many :option_types, through: :product_option_types, dependent: :destroy
belongs_to :supplier, class_name: 'Enterprise', touch: true
belongs_to :primary_taxon, class_name: 'Spree::Taxon', touch: true
delegate_belongs_to :master, :unit_value, :unit_description
delegate :images_attributes=, :display_as=, to: :master
validates :supplier, presence: true
validates :primary_taxon, presence: true
validates :tax_category_id, presence: true, if: "Spree::Config.products_require_tax_category"
validates :variant_unit, presence: true
validates :variant_unit_scale,
presence: { if: ->(p) { %w(weight volume).include? p.variant_unit } }
validates :variant_unit_name,
presence: { if: ->(p) { p.variant_unit == 'items' } }
after_initialize :set_available_on_to_now, if: :new_record?
before_validation :sanitize_permalink
before_save :add_primary_taxon_to_taxons
after_save :remove_previous_primary_taxon_from_taxons
after_save :ensure_standard_variant
after_save :update_units
# -- Joins
scope :with_order_cycles_outer, -> {
joins("
LEFT OUTER JOIN spree_variants AS o_spree_variants
ON (o_spree_variants.product_id = spree_products.id)").
joins("
LEFT OUTER JOIN exchange_variants AS o_exchange_variants
ON (o_exchange_variants.variant_id = o_spree_variants.id)").
joins("
LEFT OUTER JOIN exchanges AS o_exchanges
ON (o_exchanges.id = o_exchange_variants.exchange_id)").
joins("
LEFT OUTER JOIN order_cycles AS o_order_cycles
ON (o_order_cycles.id = o_exchanges.order_cycle_id)")
}
scope :imported_on, lambda { |import_date|
import_date = Time.zone.parse import_date if import_date.is_a? String
import_date = import_date.to_date
joins(:variants).merge(Spree::Variant.where(import_date: import_date.beginning_of_day..import_date.end_of_day))
}
scope :with_order_cycles_inner, -> {
joins(variants_including_master: { exchanges: :order_cycle })
}
scope :visible_for, lambda { |enterprise|
joins('LEFT OUTER JOIN spree_variants AS o_spree_variants ON (o_spree_variants.product_id = spree_products.id)').
joins('LEFT OUTER JOIN inventory_items AS o_inventory_items ON (o_spree_variants.id = o_inventory_items.variant_id)').
where('o_inventory_items.enterprise_id = (?) AND visible = (?)', enterprise, true)
}
# -- Scopes
scope :in_supplier, lambda { |supplier| where(supplier_id: supplier) }
# Products distributed via the given distributor through an OC
scope :in_distributor, lambda { |distributor|
distributor = distributor.respond_to?(:id) ? distributor.id : distributor.to_i
with_order_cycles_outer.
where('(o_exchanges.incoming = ? AND o_exchanges.receiver_id = ?)', false, distributor).
select('distinct spree_products.*')
}
scope :in_distributors, lambda { |distributors|
with_order_cycles_outer.
where('(o_exchanges.incoming = ? AND o_exchanges.receiver_id IN (?))', false, distributors).
uniq
}
# Products supplied by a given enterprise or distributed via that enterprise through an OC
scope :in_supplier_or_distributor, lambda { |enterprise|
enterprise = enterprise.respond_to?(:id) ? enterprise.id : enterprise.to_i
with_order_cycles_outer.
where("
spree_products.supplier_id = ?
OR (o_exchanges.incoming = ? AND o_exchanges.receiver_id = ?)
", enterprise, false, enterprise).
select('distinct spree_products.*')
}
# Products distributed by the given order cycle
scope :in_order_cycle, lambda { |order_cycle|
with_order_cycles_inner.
merge(Exchange.outgoing).
where('order_cycles.id = ?', order_cycle)
}
scope :in_an_active_order_cycle, lambda {
with_order_cycles_inner.
merge(OrderCycle.active).
merge(Exchange.outgoing).
where('order_cycles.id IS NOT NULL')
}
scope :by_producer, -> { joins(:supplier).order('enterprises.name') }
scope :by_name, -> { order('name') }
scope :managed_by, lambda { |user|
if user.has_spree_role?('admin')
where(nil)
else
where('supplier_id IN (?)', user.enterprises.select("enterprises.id"))
end
}
scope :stockable_by, lambda { |enterprise|
return where('1=0') if enterprise.blank?
permitted_producer_ids = EnterpriseRelationship.joins(:parent).permitting(enterprise.id)
.with_permission(:add_to_order_cycle).where(enterprises: { is_primary_producer: true }).pluck(:parent_id)
return where('spree_products.supplier_id IN (?)', [enterprise.id] | permitted_producer_ids)
}
# -- Methods
# Called by Spree::Product::duplicate before saving.
def duplicate_extra(_parent)
# Spree sets the SKU to "COPY OF #{parent sku}".
master.sku = ''
end
def properties_including_inherited
# Product properties override producer properties
ps = product_properties.all
if inherits_properties
ps = OpenFoodNetwork::PropertyMerge.merge(ps, supplier.producer_properties)
end
ps.
sort_by(&:position).
map { |pp| { id: pp.property.id, name: pp.property.presentation, value: pp.value } }
end
def in_distributor?(distributor)
self.class.in_distributor(distributor).include? self
end
def in_order_cycle?(order_cycle)
self.class.in_order_cycle(order_cycle).include? self
end
def variants_distributed_by(order_cycle, distributor)
order_cycle.variants_distributed_by(distributor).where(product_id: self)
end
# Get the most recent import_date of a product's variants
def import_date
variants.map(&:import_date).compact.max
end
def variant_unit_option_type
if variant_unit.present?
option_type_name = "unit_#{variant_unit}"
option_type_presentation = variant_unit.capitalize
Spree::OptionType.find_by(name: option_type_name) ||
Spree::OptionType.create!(name: option_type_name,
presentation: option_type_presentation)
end
end
def destroy_with_delete_from_order_cycles
transaction do
touch_distributors
ExchangeVariant.
where('exchange_variants.variant_id IN (?)', variants_including_master.with_deleted.
select(:id)).destroy_all
destroy_without_delete_from_order_cycles
end
end
alias_method_chain :destroy, :delete_from_order_cycles
private
def set_available_on_to_now
self.available_on ||= Time.zone.now
end
def update_units
if variant_unit_changed?
option_types.delete self.class.all_variant_unit_option_types
option_types << variant_unit_option_type if variant_unit.present?
variants_including_master.each(&:update_units)
end
end
def touch_distributors
Enterprise.distributing_products(id).each(&:touch)
end
def add_primary_taxon_to_taxons
taxons << primary_taxon unless taxons.include? primary_taxon
end
def remove_previous_primary_taxon_from_taxons
return unless primary_taxon_id_changed? && primary_taxon_id_was
taxons.destroy(primary_taxon_id_was)
end
def self.all_variant_unit_option_types
Spree::OptionType.where('name LIKE ?', 'unit_%%')
end
def ensure_standard_variant
if master.valid? && variants.empty?
variant = master.dup
variant.product = self
variant.is_master = false
variants << variant
end
end
# Override Spree's old save_master method and replace it with the most recent method from spree repository
# This fixes any problems arising from failing master saves, without the need for a validates_associated on
# master, while giving us more specific errors as to why saving failed
def save_master
if master && (
master.changed? || master.new_record? || (
master.default_price && (
master.default_price.changed? || master.default_price.new_record?
)
)
)
master.save!
end
# If the master cannot be saved, the Product object will get its errors
# and will be destroyed
rescue ActiveRecord::RecordInvalid
master.errors.each do |att, error|
errors.add(att, error)
end
raise
end
# Spree creates a permalink already but our implementation fixes an edge case.
def sanitize_permalink
if permalink.blank? || permalink_changed?
requested = permalink.presence || permalink_was.presence || name.presence || 'product'
self.permalink = create_unique_permalink(requested.parameterize)
end
end
end

View File

@@ -0,0 +1,18 @@
# frozen_string_literal: true
module Spree
class ProductOptionType < ActiveRecord::Base
after_destroy :remove_option_values
belongs_to :product, class_name: 'Spree::Product'
belongs_to :option_type, class_name: 'Spree::OptionType'
acts_as_list scope: :product
def remove_option_values
product.variants_including_master.each do |variant|
option_values = variant.option_values.where(option_type_id: option_type)
variant.option_values.destroy(*option_values)
end
end
end
end

View File

@@ -1,10 +0,0 @@
Spree::ProductOptionType.class_eval do
after_destroy :remove_option_values
def remove_option_values
product.variants_including_master.each do |variant|
option_values = variant.option_values.where(option_type_id: option_type)
variant.option_values.destroy(*option_values)
end
end
end

View File

@@ -0,0 +1,27 @@
# frozen_string_literal: true
module Spree
class ProductProperty < ActiveRecord::Base
belongs_to :product, class_name: "Spree::Product", touch: true
belongs_to :property, class_name: 'Spree::Property'
validates :property, presence: true
validates :value, length: { maximum: 255 }
default_scope -> { order("#{table_name}.position") }
# virtual attributes for use with AJAX completion stuff
def property_name
property&.name
end
def property_name=(name)
return if name.blank?
unless property = Property.find_by(name: name)
property = Property.create(name: name, presentation: name)
end
self.property = property
end
end
end

View File

@@ -1,5 +0,0 @@
module Spree
ProductProperty.class_eval do
belongs_to :product, class_name: "Spree::Product", touch: true
end
end

View File

@@ -30,7 +30,7 @@ module Spree
def fetch_stock_items
# Don't re-fetch associated stock items from the DB if we've already eager-loaded them
return @variant.stock_items.to_a if @variant.stock_items.loaded?
return @variant.stock_items if @variant.stock_items.loaded?
Spree::StockItem.joins(:stock_location).
where(:variant_id => @variant, Spree::StockLocation.table_name => { active: true })

301
app/models/spree/variant.rb Normal file
View File

@@ -0,0 +1,301 @@
# frozen_string_literal: true
require 'open_food_network/enterprise_fee_calculator'
require 'variant_units/variant_and_line_item_naming'
require 'concerns/variant_stock'
require 'spree/localized_number'
module Spree
class Variant < ActiveRecord::Base
extend Spree::LocalizedNumber
include VariantUnits::VariantAndLineItemNaming
include VariantStock
acts_as_paranoid
belongs_to :product, touch: true, class_name: 'Spree::Product'
delegate_belongs_to :product, :name, :description, :permalink, :available_on,
:tax_category_id, :shipping_category_id, :meta_description,
:meta_keywords, :tax_category, :shipping_category
has_many :inventory_units
has_many :line_items
has_many :stock_items, dependent: :destroy
has_many :stock_locations, through: :stock_items
has_many :stock_movements
has_and_belongs_to_many :option_values, join_table: :spree_option_values_variants
has_many :images, -> { order(:position) }, as: :viewable,
dependent: :destroy,
class_name: "Spree::Image"
accepts_nested_attributes_for :images
has_one :default_price,
-> { where currency: Spree::Config[:currency] },
class_name: 'Spree::Price',
dependent: :destroy
has_many :prices,
class_name: 'Spree::Price',
dependent: :destroy
delegate_belongs_to :default_price, :display_price, :display_amount,
:price, :price=, :currency
has_many :exchange_variants
has_many :exchanges, through: :exchange_variants
has_many :variant_overrides
has_many :inventory_items
localize_number :price, :cost_price, :weight
validate :check_price
validates :price, numericality: { greater_than_or_equal_to: 0 },
presence: true,
if: proc { Spree::Config[:require_master_price] }
validates :cost_price, numericality: { greater_than_or_equal_to: 0, allow_nil: true }
validates :unit_value, presence: true, if: ->(variant) {
%w(weight volume).include?(variant.product.andand.variant_unit)
}
validates :unit_description, presence: true, if: ->(variant) {
variant.product.andand.variant_unit.present? && variant.unit_value.nil?
}
before_validation :set_cost_currency
before_validation :update_weight_from_unit_value, if: ->(v) { v.product.present? }
after_save :save_default_price
after_save :update_units
after_create :create_stock_items
after_create :set_position
around_destroy :destruction
# default variant scope only lists non-deleted variants
scope :deleted, lambda { where('deleted_at IS NOT NULL') }
scope :with_order_cycles_inner, -> { joins(exchanges: :order_cycle) }
scope :not_master, -> { where(is_master: false) }
scope :in_order_cycle, lambda { |order_cycle|
with_order_cycles_inner.
merge(Exchange.outgoing).
where('order_cycles.id = ?', order_cycle).
select('DISTINCT spree_variants.*')
}
scope :in_schedule, lambda { |schedule|
joins(exchanges: { order_cycle: :schedules }).
merge(Exchange.outgoing).
where(schedules: { id: schedule }).
select('DISTINCT spree_variants.*')
}
scope :for_distribution, lambda { |order_cycle, distributor|
where('spree_variants.id IN (?)', order_cycle.variants_distributed_by(distributor).
select(&:id))
}
scope :visible_for, lambda { |enterprise|
joins(:inventory_items).
where(
'inventory_items.enterprise_id = (?) AND inventory_items.visible = (?)',
enterprise,
true
)
}
scope :not_hidden_for, lambda { |enterprise|
return where("1=0") if enterprise.blank?
joins("
LEFT OUTER JOIN (SELECT *
FROM inventory_items
WHERE enterprise_id = #{sanitize enterprise.andand.id})
AS o_inventory_items
ON o_inventory_items.variant_id = spree_variants.id")
.where("o_inventory_items.id IS NULL OR o_inventory_items.visible = (?)", true)
}
scope :stockable_by, lambda { |enterprise|
return where("1=0") if enterprise.blank?
joins(:product).
where(spree_products: { id: Spree::Product.stockable_by(enterprise).pluck(:id) })
}
# Define sope as class method to allow chaining with other scopes filtering id.
# In Rails 3, merging two scopes on the same column will consider only the last scope.
def self.in_distributor(distributor)
where(id: ExchangeVariant.select(:variant_id).
joins(:exchange).
where('exchanges.incoming = ? AND exchanges.receiver_id = ?', false, distributor))
end
def self.indexed
scoped.index_by(&:id)
end
def self.active(currency = nil)
# "where(id:" is necessary so that the returned relation has no includes
# The relation without includes will not be readonly and allow updates on it
where("spree_variants.id in (?)", joins(:prices).
where(deleted_at: nil).
where('spree_prices.currency' =>
currency || Spree::Config[:currency]).
where('spree_prices.amount IS NOT NULL').
select("spree_variants.id"))
end
# Allow variant to access associated soft-deleted prices.
def default_price
Spree::Price.unscoped { super }
end
def price_with_fees(distributor, order_cycle)
price + fees_for(distributor, order_cycle)
end
def fees_for(distributor, order_cycle)
OpenFoodNetwork::EnterpriseFeeCalculator.new(distributor, order_cycle).fees_for self
end
def fees_by_type_for(distributor, order_cycle)
OpenFoodNetwork::EnterpriseFeeCalculator.new(distributor, order_cycle).fees_by_type_for self
end
# returns number of units currently on backorder for this variant.
def on_backorder
inventory_units.with_state('backordered').size
end
def gross_profit
cost_price.nil? ? 0 : (price - cost_price)
end
# use deleted? rather than checking the attribute directly. this
# allows extensions to override deleted? if they want to provide
# their own definition.
def deleted?
deleted_at
end
def set_option_value(opt_name, opt_value)
# no option values on master
return if is_master
option_type = Spree::OptionType.where(name: opt_name).first_or_initialize do |o|
o.presentation = opt_name
o.save!
end
current_value = option_values.detect { |o| o.option_type.name == opt_name }
if current_value.nil?
# then we have to check to make sure that the product has the option type
unless product.option_types.include? option_type
product.option_types << option_type
product.save
end
else
return if current_value.name == opt_value
option_values.delete(current_value)
end
option_value = Spree::OptionValue.where(option_type_id: option_type.id,
name: opt_value).first_or_initialize do |o|
o.presentation = opt_value
o.save!
end
option_values << option_value
save
end
def option_value(opt_name)
option_values.detect { |o| o.option_type.name == opt_name }.try(:presentation)
end
def default_price?
!default_price.nil?
end
def price_in(currency)
prices.select{ |price| price.currency == currency }.first ||
Spree::Price.new(variant_id: id, currency: currency)
end
def amount_in(currency)
price_in(currency).try(:amount)
end
def name_and_sku
"#{name} - #{sku}"
end
# Product may be created with deleted_at already set,
# which would make AR's default finder return nil.
# This is a stopgap for that little problem.
def product
Spree::Product.unscoped { super }
end
# can_supply? is implemented in VariantStock
def in_stock?(quantity = 1)
can_supply?(quantity)
end
def total_on_hand
Spree::Stock::Quantifier.new(self).total_on_hand
end
private
# Ensures a new variant takes the product master price when price is not supplied
def check_price
if price.nil? && Spree::Config[:require_master_price]
raise 'No master variant found to infer price' unless product&.master
raise 'Must supply price for variant or master.price for product.' if self == product.master
self.price = product.master.price
end
return unless currency.nil?
self.currency = Spree::Config[:currency]
end
def save_default_price
default_price.save if default_price && (default_price.changed? || default_price.new_record?)
end
def set_cost_currency
self.cost_currency = Spree::Config[:currency] if cost_currency.blank?
end
def create_stock_items
StockLocation.all.find_each do |stock_location|
stock_location.propagate_variant(self)
end
end
def set_position
update_column(:position, product.variants.maximum(:position).to_i + 1)
end
def update_weight_from_unit_value
return unless product.variant_unit == 'weight' && unit_value.present?
self.weight = weight_from_unit_value
end
def destruction
exchange_variants(:reload).destroy_all
yield
end
end
end

View File

@@ -1,141 +0,0 @@
require 'open_food_network/enterprise_fee_calculator'
require 'variant_units/variant_and_line_item_naming'
require 'concerns/variant_stock'
Spree::Variant.class_eval do
extend Spree::LocalizedNumber
# Remove method From Spree, so method from the naming module is used instead
# This file may be double-loaded in delayed job environment, so we check before
# removing the Spree method to prevent error.
remove_method :options_text if instance_methods(false).include? :options_text
include VariantUnits::VariantAndLineItemNaming
include VariantStock
has_many :exchange_variants
has_many :exchanges, through: :exchange_variants
has_many :variant_overrides
has_many :inventory_items
accepts_nested_attributes_for :images
validates :unit_value, presence: true, if: ->(variant) {
%w(weight volume).include?(variant.product.andand.variant_unit)
}
validates :unit_description, presence: true, if: ->(variant) {
variant.product.andand.variant_unit.present? && variant.unit_value.nil?
}
before_validation :update_weight_from_unit_value, if: ->(v) { v.product.present? }
after_save :update_units
around_destroy :destruction
scope :with_order_cycles_inner, -> { joins(exchanges: :order_cycle) }
scope :not_master, -> { where(is_master: false) }
scope :in_order_cycle, lambda { |order_cycle|
with_order_cycles_inner.
merge(Exchange.outgoing).
where('order_cycles.id = ?', order_cycle).
select('DISTINCT spree_variants.*')
}
scope :in_schedule, lambda { |schedule|
joins(exchanges: { order_cycle: :schedules }).
merge(Exchange.outgoing).
where(schedules: { id: schedule }).
select('DISTINCT spree_variants.*')
}
scope :for_distribution, lambda { |order_cycle, distributor|
where('spree_variants.id IN (?)', order_cycle.variants_distributed_by(distributor).select(&:id))
}
scope :visible_for, lambda { |enterprise|
joins(:inventory_items).
where(
'inventory_items.enterprise_id = (?) AND inventory_items.visible = (?)',
enterprise,
true
)
}
scope :not_hidden_for, lambda { |enterprise|
return where("1=0") if enterprise.blank?
joins("
LEFT OUTER JOIN (SELECT *
FROM inventory_items
WHERE enterprise_id = #{sanitize enterprise.andand.id})
AS o_inventory_items
ON o_inventory_items.variant_id = spree_variants.id")
.where("o_inventory_items.id IS NULL OR o_inventory_items.visible = (?)", true)
}
localize_number :price, :cost_price, :weight
scope :stockable_by, lambda { |enterprise|
return where("1=0") if enterprise.blank?
joins(:product).
where(spree_products: { id: Spree::Product.stockable_by(enterprise).pluck(:id) })
}
# Define sope as class method to allow chaining with other scopes filtering id.
# In Rails 3, merging two scopes on the same column will consider only the last scope.
def self.in_distributor(distributor)
where(id: ExchangeVariant.select(:variant_id).
joins(:exchange).
where('exchanges.incoming = ? AND exchanges.receiver_id = ?', false, distributor))
end
def self.indexed
scoped.index_by(&:id)
end
def self.active(currency = nil)
# "where(id:" is necessary so that the returned relation has no includes
# The relation without includes will not be readonly and allow updates on it
where("spree_variants.id in (?)", joins(:prices).
where(deleted_at: nil).
where('spree_prices.currency' =>
currency || Spree::Config[:currency]).
where('spree_prices.amount IS NOT NULL').
select("spree_variants.id"))
end
# We override in_stock? to avoid depending
# on the non-overridable method Spree::Stock::Quantifier.can_supply?
# VariantStock implements can_supply? itself which depends on overridable methods
def in_stock?(quantity = 1)
can_supply?(quantity)
end
# Allow variant to access associated soft-deleted prices.
def default_price
Spree::Price.unscoped { super }
end
def price_with_fees(distributor, order_cycle)
price + fees_for(distributor, order_cycle)
end
def fees_for(distributor, order_cycle)
OpenFoodNetwork::EnterpriseFeeCalculator.new(distributor, order_cycle).fees_for self
end
def fees_by_type_for(distributor, order_cycle)
OpenFoodNetwork::EnterpriseFeeCalculator.new(distributor, order_cycle).fees_by_type_for self
end
private
def update_weight_from_unit_value
self.weight = weight_from_unit_value if product.variant_unit == 'weight' && unit_value.present?
end
def destruction
exchange_variants(:reload).destroy_all
yield
end
end

View File

@@ -1,3 +1,9 @@
class Api::Admin::BasicEnterpriseFeeSerializer < ActiveModel::Serializer
attributes :id, :enterprise_id
# frozen_string_literal: true
module Api
module Admin
class BasicEnterpriseFeeSerializer < ActiveModel::Serializer
attributes :id, :enterprise_id
end
end
end

View File

@@ -1,12 +1,18 @@
class Api::Admin::BasicEnterpriseSerializer < ActiveModel::Serializer
attributes :name, :id, :is_primary_producer, :is_distributor, :sells, :category,
:payment_method_ids, :shipping_method_ids, :producer_profile_only, :permalink
# frozen_string_literal: true
def payment_method_ids
object.payment_methods.map(&:id)
end
module Api
module Admin
class BasicEnterpriseSerializer < ActiveModel::Serializer
attributes :name, :id, :is_primary_producer, :is_distributor, :sells, :category,
:payment_method_ids, :shipping_method_ids, :producer_profile_only, :permalink
def shipping_method_ids
object.shipping_methods.map(&:id)
def payment_method_ids
object.payment_methods.map(&:id)
end
def shipping_method_ids
object.shipping_methods.map(&:id)
end
end
end
end

View File

@@ -1,20 +1,26 @@
class Api::Admin::BasicOrderCycleSerializer < ActiveModel::Serializer
include OrderCyclesHelper
# frozen_string_literal: true
attributes :id, :name, :status, :orders_open_at, :orders_close_at
module Api
module Admin
class BasicOrderCycleSerializer < ActiveModel::Serializer
include OrderCyclesHelper
has_many :suppliers, serializer: Api::Admin::IdNameSerializer
has_many :distributors, serializer: Api::Admin::IdNameSerializer
attributes :id, :name, :status, :orders_open_at, :orders_close_at
def status
order_cycle_status_class object
end
has_many :suppliers, serializer: Api::Admin::IdNameSerializer
has_many :distributors, serializer: Api::Admin::IdNameSerializer
def orders_open_at
object.orders_open_at.andand.strftime("%F %T %z")
end
def status
order_cycle_status_class object
end
def orders_close_at
object.orders_close_at.andand.strftime("%F %T %z")
def orders_open_at
object.orders_open_at.andand.strftime("%F %T %z")
end
def orders_close_at
object.orders_close_at.andand.strftime("%F %T %z")
end
end
end
end

View File

@@ -1,7 +1,15 @@
class Api::Admin::Calculator::FlatPercentItemTotalSerializer < ActiveModel::Serializer
attributes :id, :preferred_flat_percent
# frozen_string_literal: true
def preferred_flat_percent
object.preferred_flat_percent.to_i
module Api
module Admin
module Calculator
class FlatPercentItemTotalSerializer < ActiveModel::Serializer
attributes :id, :preferred_flat_percent
def preferred_flat_percent
object.preferred_flat_percent.to_i
end
end
end
end
end

View File

@@ -1,7 +1,13 @@
class Api::Admin::CalculatorSerializer < ActiveModel::Serializer
attributes :name, :description
# frozen_string_literal: true
delegate :name, to: :object
module Api
module Admin
class CalculatorSerializer < ActiveModel::Serializer
attributes :name, :description
delegate :description, to: :object
delegate :name, to: :object
delegate :description, to: :object
end
end
end

View File

@@ -1,3 +1,9 @@
class Api::Admin::ColumnPreferenceSerializer < ActiveModel::Serializer
attributes :id, :user_id, :action_name, :column_name, :name, :visible
# frozen_string_literal: true
module Api
module Admin
class ColumnPreferenceSerializer < ActiveModel::Serializer
attributes :id, :user_id, :action_name, :column_name, :name, :visible
end
end
end

View File

@@ -1,36 +1,61 @@
class Api::Admin::CustomerSerializer < ActiveModel::Serializer
attributes :id, :email, :enterprise_id, :user_id, :code, :tags, :tag_list, :name,
:allow_charges, :default_card_present?
# frozen_string_literal: true
has_one :ship_address, serializer: Api::AddressSerializer
has_one :bill_address, serializer: Api::AddressSerializer
module Api
module Admin
class CustomerSerializer < ActiveModel::Serializer
attributes :id, :email, :enterprise_id, :user_id, :code, :tags, :tag_list, :name,
:allow_charges, :default_card_present?, :balance, :balance_status
def tag_list
customer_tag_list.join(",")
end
has_one :ship_address, serializer: Api::AddressSerializer
has_one :bill_address, serializer: Api::AddressSerializer
def name
object.name.presence || object.bill_address.andand.full_name
end
def name
object.name.presence || object.bill_address.andand.full_name
end
def tags
customer_tag_list.map do |tag|
tag_rule_map = options[:tag_rule_mapping].andand[tag]
tag_rule_map || { text: tag, rules: nil }
def tag_list
customer_tag_list.join(",")
end
def balance
Spree::Money.new(balance_value, currency: Spree::Config[:currency]).to_s
end
def balance_status
if balance_value.positive?
"credit_owed"
elsif balance_value.negative?
"balance_due"
else
""
end
end
def tags
customer_tag_list.map do |tag|
tag_rule_map = options[:tag_rule_mapping].andand[tag]
tag_rule_map || { text: tag, rules: nil }
end
end
def default_card_present?
return unless object.user
object.user.default_card.present?
end
private
def customer_tag_list
return object.tag_list unless options[:customer_tags]
options[:customer_tags].andand[object.id] || []
end
def balance_value
@balance_value ||=
OpenFoodNetwork::UserBalanceCalculator.new(object.email, object.enterprise).balance
end
end
end
def default_card_present?
return unless object.user
object.user.default_card.present?
end
private
def customer_tag_list
return object.tag_list unless options[:customer_tags]
options[:customer_tags].andand[object.id] || []
end
end

View File

@@ -1,26 +1,32 @@
class Api::Admin::EnterpriseFeeSerializer < ActiveModel::Serializer
attributes :id, :enterprise_id, :fee_type, :name, :tax_category_id, :inherits_tax_category,
:calculator_type, :enterprise_name, :calculator_description, :calculator_settings
# frozen_string_literal: true
def enterprise_name
object.enterprise.andand.name
end
module Api
module Admin
class EnterpriseFeeSerializer < ActiveModel::Serializer
attributes :id, :enterprise_id, :fee_type, :name, :tax_category_id, :inherits_tax_category,
:calculator_type, :enterprise_name, :calculator_description, :calculator_settings
def calculator_description
object.calculator.andand.description
end
def enterprise_name
object.enterprise.andand.name
end
def calculator_settings
return nil unless options[:include_calculators]
def calculator_description
object.calculator.andand.description
end
result = nil
def calculator_settings
return nil unless options[:include_calculators]
options[:controller].__send__(:with_format, :html) do
result = options[:controller].
render_to_string(partial: 'admin/enterprise_fees/calculator_settings',
locals: { enterprise_fee: object })
result = nil
options[:controller].__send__(:with_format, :html) do
result = options[:controller].
render_to_string(partial: 'admin/enterprise_fees/calculator_settings',
locals: { enterprise_fee: object })
end
result.gsub('[0]', '[{{ $index }}]').gsub('_0_', '_{{ $index }}_')
end
end
result.gsub('[0]', '[{{ $index }}]').gsub('_0_', '_{{ $index }}_')
end
end

View File

@@ -1,3 +1,9 @@
class Api::Admin::EnterpriseRelationshipPermissionSerializer < ActiveModel::Serializer
attributes :id, :name
# frozen_string_literal: true
module Api
module Admin
class EnterpriseRelationshipPermissionSerializer < ActiveModel::Serializer
attributes :id, :name
end
end
end

View File

@@ -1,13 +1,19 @@
class Api::Admin::EnterpriseRelationshipSerializer < ActiveModel::Serializer
attributes :id, :parent_id, :parent_name, :child_id, :child_name
# frozen_string_literal: true
has_many :permissions
module Api
module Admin
class EnterpriseRelationshipSerializer < ActiveModel::Serializer
attributes :id, :parent_id, :parent_name, :child_id, :child_name
def parent_name
object.parent.name
end
has_many :permissions
def child_name
object.child.name
def parent_name
object.parent.name
end
def child_name
object.child.name
end
end
end
end

View File

@@ -1,11 +1,17 @@
class Api::Admin::EnterpriseRoleSerializer < ActiveModel::Serializer
attributes :id, :user_id, :enterprise_id, :user_email, :enterprise_name
# frozen_string_literal: true
def user_email
object.user.email
end
module Api
module Admin
class EnterpriseRoleSerializer < ActiveModel::Serializer
attributes :id, :user_id, :enterprise_id, :user_email, :enterprise_name
def enterprise_name
object.enterprise.name
def user_email
object.user.email
end
def enterprise_name
object.enterprise.name
end
end
end
end

View File

@@ -1,77 +1,92 @@
class Api::Admin::EnterpriseSerializer < ActiveModel::Serializer
attributes :name, :id, :is_primary_producer, :is_distributor, :sells, :category, :permalink,
:payment_method_ids, :shipping_method_ids, :producer_profile_only, :long_description,
:preferred_shopfront_message, :preferred_shopfront_closed_message,
:preferred_shopfront_taxon_order, :preferred_shopfront_order_cycle_order,
:preferred_product_selection_from_inventory_only,
:preferred_show_customer_names_to_suppliers, :owner, :contact, :users, :tag_groups,
:default_tag_group, :require_login, :allow_guest_orders, :allow_order_changes,
:logo, :promo_image, :terms_and_conditions, :terms_and_conditions_file_name
# frozen_string_literal: true
has_one :owner, serializer: Api::Admin::UserSerializer
has_many :users, serializer: Api::Admin::UserSerializer
has_one :address, serializer: Api::AddressSerializer
module Api
module Admin
class EnterpriseSerializer < ActiveModel::Serializer
attributes :name, :id, :is_primary_producer, :is_distributor, :sells, :category, :permalink,
:payment_method_ids, :shipping_method_ids, :producer_profile_only,
:long_description, :preferred_product_selection_from_inventory_only,
:preferred_shopfront_message, :preferred_shopfront_closed_message,
:preferred_shopfront_taxon_order, :preferred_shopfront_order_cycle_order,
:preferred_show_customer_names_to_suppliers, :owner, :contact, :users, :tag_groups,
:default_tag_group, :require_login, :allow_guest_orders, :allow_order_changes,
:logo, :promo_image, :terms_and_conditions,
:terms_and_conditions_file_name, :terms_and_conditions_updated_at
def logo
attachment_urls(object.logo, [:thumb, :small, :medium])
end
has_one :owner, serializer: Api::Admin::UserSerializer
has_many :users, serializer: Api::Admin::UserSerializer
has_one :address, serializer: Api::AddressSerializer
def promo_image
attachment_urls(object.promo_image, [:thumb, :medium, :large])
end
def terms_and_conditions
return unless @object.terms_and_conditions.file?
@object.terms_and_conditions.url
end
def tag_groups
object.tag_rules.prioritised.reject(&:is_default).each_with_object([]) do |tag_rule, tag_groups|
tag_group = find_match(tag_groups, tag_rule.preferred_customer_tags.
split(",").
map{ |t| { text: t } })
if tag_group[:rules].blank?
tag_groups << tag_group
tag_group[:position] = tag_groups.count
def logo
attachment_urls(object.logo, [:thumb, :small, :medium])
end
tag_group[:rules] << Api::Admin::TagRuleSerializer.new(tag_rule).serializable_hash
end
end
def default_tag_group
default_rules = object.tag_rules.select(&:is_default)
serialized_rules =
ActiveModel::ArraySerializer.new(default_rules,
each_serializer: Api::Admin::TagRuleSerializer)
{ tags: [], rules: serialized_rules }
end
def promo_image
attachment_urls(object.promo_image, [:thumb, :medium, :large])
end
def find_match(tag_groups, tags)
tag_groups.each do |tag_group|
return tag_group if tag_group[:tags].length == tags.length &&
(tag_group[:tags] & tags) == tag_group[:tags]
end
{ tags: tags, rules: [] }
end
def terms_and_conditions
return unless object.terms_and_conditions.file?
private
object.terms_and_conditions.url
end
# Returns a hash of URLs for specified versions of an attachment.
#
# Example:
#
# attachment_urls(object.logo, [:thumb, :small, :medium])
# # {
# # thumb: LOGO_THUMB_URL,
# # small: LOGO_SMALL_URL,
# # medium: LOGO_MEDIUM_URL
# # }
def attachment_urls(attachment, versions)
return unless attachment.file?
def terms_and_conditions_updated_at
object.terms_and_conditions_updated_at&.to_s
end
versions.each_with_object({}) do |version, urls|
urls[version] = attachment.url(version)
def tag_groups
prioritized_tag_rules.each_with_object([]) do |tag_rule, tag_groups|
tag_group = find_match(tag_groups, tag_rule.preferred_customer_tags.
split(",").
map{ |t| { text: t } })
if tag_group[:rules].blank?
tag_groups << tag_group
tag_group[:position] = tag_groups.count
end
tag_group[:rules] << Api::Admin::TagRuleSerializer.new(tag_rule).serializable_hash
end
end
def default_tag_group
default_rules = object.tag_rules.select(&:is_default)
serialized_rules =
ActiveModel::ArraySerializer.new(default_rules,
each_serializer: Api::Admin::TagRuleSerializer)
{ tags: [], rules: serialized_rules }
end
def find_match(tag_groups, tags)
tag_groups.each do |tag_group|
return tag_group if tag_group[:tags].length == tags.length &&
(tag_group[:tags] & tags) == tag_group[:tags]
end
{ tags: tags, rules: [] }
end
private
def prioritized_tag_rules
object.tag_rules.prioritised.reject(&:is_default)
end
# Returns a hash of URLs for specified versions of an attachment.
#
# Example:
#
# attachment_urls(object.logo, [:thumb, :small, :medium])
# # {
# # thumb: LOGO_THUMB_URL,
# # small: LOGO_SMALL_URL,
# # medium: LOGO_MEDIUM_URL
# # }
def attachment_urls(attachment, versions)
return unless attachment.file?
versions.each_with_object({}) do |version, urls|
urls[version] = attachment.url(version)
end
end
end
end
end

View File

@@ -1,48 +1,54 @@
class Api::Admin::ExchangeSerializer < ActiveModel::Serializer
attributes :id, :sender_id, :receiver_id, :incoming, :variants,
:receival_instructions, :pickup_time, :pickup_instructions,
:tags, :tag_list
# frozen_string_literal: true
has_many :enterprise_fees, serializer: Api::Admin::BasicEnterpriseFeeSerializer
module Api
module Admin
class ExchangeSerializer < ActiveModel::Serializer
attributes :id, :sender_id, :receiver_id, :incoming, :variants,
:receival_instructions, :pickup_time, :pickup_instructions,
:tags, :tag_list
def variants
variants = object.incoming? ? visible_incoming_variants : visible_outgoing_variants
Hash[object.variants.merge(variants).map { |v| [v.id, true] }]
end
has_many :enterprise_fees, serializer: Api::Admin::BasicEnterpriseFeeSerializer
private
def variants
variants = object.incoming? ? visible_incoming_variants : visible_outgoing_variants
Hash[object.variants.merge(variants).map { |v| [v.id, true] }]
end
def visible_incoming_variants
if object.order_cycle.prefers_product_selection_from_coordinator_inventory_only?
permitted_incoming_variants.visible_for(object.order_cycle.coordinator)
else
permitted_incoming_variants
private
def visible_incoming_variants
if object.order_cycle.prefers_product_selection_from_coordinator_inventory_only?
permitted_incoming_variants.visible_for(object.order_cycle.coordinator)
else
permitted_incoming_variants
end
end
def visible_outgoing_variants
if object.receiver.prefers_product_selection_from_inventory_only?
permitted_outgoing_variants.visible_for(object.receiver)
else
permitted_outgoing_variants.not_hidden_for(object.receiver)
end
end
def permitted_incoming_variants
OpenFoodNetwork::OrderCyclePermissions.new(options[:current_user], object.order_cycle).
visible_variants_for_incoming_exchanges_from(object.sender)
end
def permitted_outgoing_variants
OpenFoodNetwork::OrderCyclePermissions.new(options[:current_user], object.order_cycle)
.visible_variants_for_outgoing_exchanges_to(object.receiver)
end
def tag_list
object.tag_list.join(",")
end
def tags
object.tag_list.map{ |t| { text: t } }
end
end
end
def visible_outgoing_variants
if object.receiver.prefers_product_selection_from_inventory_only?
permitted_outgoing_variants.visible_for(object.receiver)
else
permitted_outgoing_variants.not_hidden_for(object.receiver)
end
end
def permitted_incoming_variants
OpenFoodNetwork::OrderCyclePermissions.new(options[:current_user], object.order_cycle).
visible_variants_for_incoming_exchanges_from(object.sender)
end
def permitted_outgoing_variants
OpenFoodNetwork::OrderCyclePermissions.new(options[:current_user], object.order_cycle)
.visible_variants_for_outgoing_exchanges_to(object.receiver)
end
def tag_list
object.tag_list.join(",")
end
def tags
object.tag_list.map{ |t| { text: t } }
end
end

View File

@@ -1,46 +1,54 @@
# frozen_string_literal: true
require 'open_food_network/enterprise_issue_validator'
class Api::Admin::ForOrderCycle::EnterpriseSerializer < ActiveModel::Serializer
attributes :id, :name, :managed,
:issues_summary_supplier, :issues_summary_distributor,
:is_primary_producer, :is_distributor, :sells
module Api
module Admin
module ForOrderCycle
class EnterpriseSerializer < ActiveModel::Serializer
attributes :id, :name, :managed,
:issues_summary_supplier, :issues_summary_distributor,
:is_primary_producer, :is_distributor, :sells
def issues_summary_supplier
issues =
OpenFoodNetwork::EnterpriseIssueValidator.
new(object).
issues_summary(confirmation_only: true)
def issues_summary_supplier
issues =
OpenFoodNetwork::EnterpriseIssueValidator.
new(object).
issues_summary(confirmation_only: true)
if issues.nil? && products.empty?
issues = "no products in inventory"
if issues.nil? && products.empty?
issues = I18n.t(:no_products)
end
issues
end
def issues_summary_distributor
OpenFoodNetwork::EnterpriseIssueValidator.new(object).issues_summary
end
def managed
Enterprise.managed_by(options[:spree_current_user]).include? object
end
private
def products_scope
products_relation = object.supplied_products
if order_cycle.prefers_product_selection_from_coordinator_inventory_only?
products_relation = products_relation.
visible_for(order_cycle.coordinator)
end
products_relation
end
def products
@products ||= products_scope
end
def order_cycle
options[:order_cycle]
end
end
end
issues
end
def issues_summary_distributor
OpenFoodNetwork::EnterpriseIssueValidator.new(object).issues_summary
end
def managed
Enterprise.managed_by(options[:spree_current_user]).include? object
end
private
def products_scope
products_relation = object.supplied_products
if order_cycle.prefers_product_selection_from_coordinator_inventory_only?
products_relation = products_relation.
visible_for(order_cycle.coordinator)
end
products_relation
end
def products
@products ||= products_scope
end
def order_cycle
options[:order_cycle]
end
end

View File

@@ -1,31 +1,39 @@
class Api::Admin::ForOrderCycle::SuppliedProductSerializer < ActiveModel::Serializer
attributes :name, :supplier_name, :image_url, :master_id, :variants
# frozen_string_literal: true
def supplier_name
object.supplier.andand.name
end
module Api
module Admin
module ForOrderCycle
class SuppliedProductSerializer < ActiveModel::Serializer
attributes :name, :supplier_name, :image_url, :master_id, :variants
def image_url
object.images.present? ? object.images.first.attachment.url(:mini) : nil
end
def supplier_name
object.supplier.andand.name
end
def master_id
object.master.id
end
def image_url
object.images.present? ? object.images.first.attachment.url(:mini) : nil
end
def variants
variants = if order_cycle.present? &&
order_cycle.prefers_product_selection_from_coordinator_inventory_only?
object.variants.visible_for(order_cycle.coordinator)
else
object.variants
end
variants.map { |variant| { id: variant.id, label: variant.full_name } }
end
def master_id
object.master.id
end
private
def variants
variants = if order_cycle.present? &&
order_cycle.prefers_product_selection_from_coordinator_inventory_only?
object.variants.visible_for(order_cycle.coordinator)
else
object.variants
end
variants.map { |variant| { id: variant.id, label: variant.full_name } }
end
def order_cycle
options[:order_cycle]
private
def order_cycle
options[:order_cycle]
end
end
end
end
end

View File

@@ -1,3 +1,5 @@
# frozen_string_literal: true
module Api
module Admin
class IdEmailSerializer < ActiveModel::Serializer

View File

@@ -1,3 +1,9 @@
class Api::Admin::IdNameSerializer < ActiveModel::Serializer
attributes :id, :name
# frozen_string_literal: true
module Api
module Admin
class IdNameSerializer < ActiveModel::Serializer
attributes :id, :name
end
end
end

View File

@@ -1,3 +1,9 @@
class Api::Admin::IdSerializer < ActiveModel::Serializer
attributes :id
# frozen_string_literal: true
module Api
module Admin
class IdSerializer < ActiveModel::Serializer
attributes :id
end
end
end

View File

@@ -1,24 +1,30 @@
# frozen_string_literal: true
require 'open_food_network/enterprise_issue_validator'
class Api::Admin::IndexEnterpriseSerializer < ActiveModel::Serializer
attributes :name, :id, :permalink, :is_primary_producer, :sells, :producer_profile_only, :owned,
:edit_path, :issues, :warnings
module Api
module Admin
class IndexEnterpriseSerializer < ActiveModel::Serializer
attributes :name, :id, :permalink, :is_primary_producer, :sells,
:producer_profile_only, :owned, :edit_path, :issues, :warnings
def owned
return true if options[:spree_current_user].admin?
def owned
return true if options[:spree_current_user].admin?
object.owner == options[:spree_current_user]
end
object.owner == options[:spree_current_user]
end
def edit_path
edit_admin_enterprise_path(object)
end
def edit_path
edit_admin_enterprise_path(object)
end
def issues
OpenFoodNetwork::EnterpriseIssueValidator.new(object).issues
end
def issues
OpenFoodNetwork::EnterpriseIssueValidator.new(object).issues
end
def warnings
OpenFoodNetwork::EnterpriseIssueValidator.new(object).warnings
def warnings
OpenFoodNetwork::EnterpriseIssueValidator.new(object).warnings
end
end
end
end

View File

@@ -1,3 +1,5 @@
# frozen_string_literal: true
require 'open_food_network/order_cycle_permissions'
module Api

View File

@@ -1,3 +1,9 @@
class Api::Admin::InventoryItemSerializer < ActiveModel::Serializer
attributes :id, :enterprise_id, :variant_id, :visible
# frozen_string_literal: true
module Api
module Admin
class InventoryItemSerializer < ActiveModel::Serializer
attributes :id, :enterprise_id, :variant_id, :visible
end
end
end

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