Compare commits

...

460 Commits

Author SHA1 Message Date
Matt-Yorkley
fc9f61ecf8 Revert PR #4204
Temporarily reverting these changes for a quick release
2019-09-05 13:23:59 +01:00
Luis Ramos
07d4528276 Merge pull request #4174 from openfoodfoundation/dependabot/bundler/delayed_job_active_record-4.1.4
Bump delayed_job_active_record from 4.1.3 to 4.1.4
2019-09-02 22:24:04 +01:00
Luis Ramos
4ace780431 Merge pull request #4187 from openfoodfoundation/dependabot/bundler/knapsack-1.18.0
Bump knapsack from 1.17.2 to 1.18.0
2019-09-02 22:23:15 +01:00
dependabot-preview[bot]
51df8de64f Bump knapsack from 1.17.2 to 1.18.0
Bumps [knapsack](https://github.com/ArturT/knapsack) from 1.17.2 to 1.18.0.
- [Release notes](https://github.com/ArturT/knapsack/releases)
- [Changelog](https://github.com/ArturT/knapsack/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ArturT/knapsack/compare/v1.17.2...v1.18.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-02 16:16:32 +00:00
Matt-Yorkley
d4a5829858 Merge pull request #4081 from Matt-Yorkley/products_pagination
Bulk Edit Products pagination
2019-09-02 17:14:14 +01:00
Matt-Yorkley
ff5fe66994 Fix route after big API refactor merge resolution 2019-09-02 16:29:03 +01:00
Matt-Yorkley
37e50a68e4 Fix timezone date parsing from Angular form fields 2019-09-02 16:29:00 +01:00
Matt-Yorkley
a72c662b97 Update per_page dropdown UX 2019-09-02 14:35:00 +01:00
Matt-Yorkley
ff2db0c5f8 Update spec routes, namespacing, and test content
Resolving new issues after a big merge
2019-09-02 14:35:00 +01:00
Matt-Yorkley
e9c60a33b9 Hide search in dropdown for per_page options 2019-09-02 14:35:00 +01:00
Matt-Yorkley
8e059d3c69 Define a limit on paginated queries with no supplied value for per_page 2019-09-02 14:35:00 +01:00
Matt-Yorkley
806ba94a2e Clarify dependency on kaminari gem 2019-09-02 14:35:00 +01:00
Matt-Yorkley
4bec583bff Refactor import_date_scope 2019-09-02 14:35:00 +01:00
Matt-Yorkley
90256f9c28 Add defaults and pages tests 2019-09-02 14:35:00 +01:00
Matt-Yorkley
eb284c1742 Use constants for defaults 2019-09-02 14:35:00 +01:00
Matt-Yorkley
b614e17f48 Add test coverage for #bulk_products endpoint and test all filtering functions 2019-09-02 14:34:54 +01:00
Matt-Yorkley
5259eaae5f Merge pull request #4204 from Matt-Yorkley/cartastrophe
Cartastrophe averted :)
2019-09-02 12:26:08 +01:00
Matt-Yorkley
b0ad0fccfa Add some defaults to avoid returning zero values when not supplied in query 2019-09-02 12:00:32 +01:00
Matt-Yorkley
2a83ad8689 Improve UX and consistency in orders pagination and page changing 2019-09-02 11:59:13 +01:00
Matt-Yorkley
c127110192 Make import_date query modification conditional 2019-09-02 11:59:13 +01:00
Matt-Yorkley
0470725112 Refactor pagination data hash 2019-09-02 11:57:32 +01:00
Matt-Yorkley
0623bab084 Don't respond to a successful update by querying 500 arbitrary products 2019-09-02 11:56:00 +01:00
Matt-Yorkley
4a0df684c7 Adjust specs 2019-09-02 11:56:00 +01:00
Matt-Yorkley
7dccb5ba90 Changing per_page should also reset the query 2019-09-02 11:56:00 +01:00
Matt-Yorkley
5a4be24df0 Add "filter results" button 2019-09-02 11:56:00 +01:00
Matt-Yorkley
5cb5967977 Fix cleared filters submitting "0" as value in queries 2019-09-02 11:56:00 +01:00
Matt-Yorkley
aeb8d30dae Fix server-side import_date filtering 2019-09-02 11:56:00 +01:00
Matt-Yorkley
1822fd97a6 Tidy up filters 2019-09-02 11:54:28 +01:00
Matt-Yorkley
4ff3e9fe10 Update Angular loading conditionals 2019-09-02 11:54:28 +01:00
Matt-Yorkley
a63994440d Add pagination to UI 2019-09-02 11:54:28 +01:00
Matt-Yorkley
f6d0de1454 Improve pagination data in bulk products 2019-09-02 11:54:28 +01:00
Matt-Yorkley
9b0e27a9d1 Add new ProductResource 2019-09-02 11:46:42 +01:00
Matt-Yorkley
415d88f302 Fix indentation in bulk product controller 2019-09-02 11:46:42 +01:00
Pau Pérez Fabregat
f9c98ea9a1 Merge pull request #4199 from openfoodfoundation/transifex
Transifex
2019-09-02 12:33:12 +02:00
Pau Pérez Fabregat
369a5a8a2f Merge pull request #4101 from luisramos0/remove_variants_rabl
Convert spree/api/products and spree/api/variants views from rabl to AMS
2019-09-02 12:14:26 +02:00
Matt-Yorkley
62341c6381 Unit test access to associated objects after soft-delete 2019-08-31 10:06:47 +01:00
Luis Ramos
fa1becb791 Merge pull request #4063 from luisramos0/dead_code
Remove dead code under views/spree/shared
2019-08-30 22:39:01 +01:00
Matt-Yorkley
50a1704994 Make prices soft-deletable 2019-08-30 20:11:32 +01:00
Matt-Yorkley
302538c370 Add failing spec for cart issue 2019-08-30 15:32:45 +01:00
Maikel
0f80b6ce12 Merge pull request #4197 from kristinalim/fix/4195-fix_invalid_date_in_firefox
4195 Specify API date format when converting date to string in JS
2019-08-30 08:36:17 +10:00
Transifex-Openfoodnetwork
1df8fc903e Updating translations for config/locales/en_ZA.yml 2019-08-30 04:22:54 +10:00
Transifex-Openfoodnetwork
9a2dcb89af Updating translations for config/locales/en_ZA.yml 2019-08-30 04:22:46 +10:00
Transifex-Openfoodnetwork
1661591f6c Updating translations for config/locales/ca.yml 2019-08-29 23:12:46 +10:00
Transifex-Openfoodnetwork
6dde720039 Updating translations for config/locales/es.yml 2019-08-29 23:10:30 +10:00
Transifex-Openfoodnetwork
a54b725d6d Updating translations for config/locales/ca.yml 2019-08-29 23:09:39 +10:00
Luis Ramos
265e76e8ca Merge pull request #4074 from HugsDaniel/defacepocalypse
[Defacepocalypse] De-deface product properties index
2019-08-28 22:18:18 +01:00
Kristina Lim
1516069888 Specify API date format when converting date to string in JS 2019-08-29 02:44:14 +08:00
Luis Ramos
cd263b761c Merge pull request #4055 from luisramos0/remove_spree_api
Remove dependency to spree_api - step 1 - controllers and routes
2019-08-28 15:34:08 +01:00
Maikel
c952ad16ad Merge pull request #4163 from luisramos0/swagger
Add swagger.yaml to codebase
2019-08-28 14:46:51 +10:00
Maikel
ca09c58f26 Merge pull request #3985 from jonleighton/string-to-text
Convert several fields from string to text
2019-08-28 11:53:49 +10:00
Maikel Linke
e876a25d59 Fix flaky proxy order spec 2019-08-28 10:48:57 +10:00
Maikel Linke
2a780151be Update all locales with the latest Transifex translations 2019-08-28 09:54:31 +10:00
Maikel
9d2009d2af Merge pull request #4188 from openfoodfoundation/transifex
Transifex
2019-08-28 09:43:02 +10:00
Maikel
f887533dda Merge pull request #4157 from mkllnk/4138-update-products
4138 Avoid infinite loop when updating products
2019-08-28 09:42:28 +10:00
Transifex-Openfoodnetwork
bef3f154d6 Updating translations for config/locales/fr_CA.yml 2019-08-28 09:12:59 +10:00
Transifex-Openfoodnetwork
6fb775d5ed Updating translations for config/locales/en_CA.yml 2019-08-28 09:05:39 +10:00
Transifex-Openfoodnetwork
b5a8563725 Updating translations for config/locales/en_GB.yml 2019-08-27 23:28:34 +10:00
Transifex-Openfoodnetwork
1a9ade6de9 Updating translations for config/locales/en_GB.yml 2019-08-27 23:25:26 +10:00
Maikel Linke
48df853ff5 Skip cascading callbacks when touching distributors 2019-08-27 10:44:19 +10:00
Maikel Linke
2137a2addb Add spec for current bug
https://github.com/openfoodfoundation/openfoodnetwork/issues/4138
2019-08-27 10:44:19 +10:00
Transifex-Openfoodnetwork
e6a7239716 Updating translations for config/locales/en_AU.yml 2019-08-27 10:09:05 +10:00
Transifex-Openfoodnetwork
25bed92f2e Updating translations for config/locales/en_AU.yml 2019-08-27 10:08:32 +10:00
Maikel
909cd407dd Merge pull request #4149 from openfoodfoundation/transifex
Transifex
2019-08-27 09:58:31 +10:00
Luis Ramos
f2d25748b1 Merge pull request #4078 from HugsDaniel/defacepocalypse-variants
[Defacepocalypse] De-deface variants
2019-08-25 22:51:15 +01:00
Luis Ramos
6396e6e970 Merge pull request #4152 from openfoodfoundation/dependabot/bundler/stripe-4.24.0
Bump stripe from 4.19.0 to 4.24.0
2019-08-25 22:49:47 +01:00
Luis Ramos
e52f813dae Merge pull request #4159 from luisramos0/fix_prod_set
Add bugsnag notifications to both product_set and products_controller when stock update fails
2019-08-25 22:49:06 +01:00
Luis Ramos
9ab2eec30c Merge pull request #4185 from kristinalim/fix/4176-fix_saving_of_shipping_method
4176 Fix saving of shipping method when automatically advancing subscription order state
2019-08-25 22:48:39 +01:00
Luis Ramos
f96b37dae3 Merge pull request #4162 from luisramos0/checkout_cache
Checkout is not refreshing products cache
2019-08-25 21:52:55 +01:00
Kristina Lim
5b68b2f707 Fix ship method when advancing subscription order 2019-08-22 21:32:41 +08:00
Kristina Lim
ff634bd870 Test ship method when advancing subscription order 2019-08-22 21:30:21 +08:00
Hugo Daniel
7d21d88dc9 Force hide the select2 close cross 2019-08-22 10:32:07 +02:00
dependabot-preview[bot]
31b62d6296 Bump delayed_job_active_record from 4.1.3 to 4.1.4
Bumps [delayed_job_active_record](https://github.com/collectiveidea/delayed_job_active_record) from 4.1.3 to 4.1.4.
- [Release notes](https://github.com/collectiveidea/delayed_job_active_record/releases)
- [Commits](https://github.com/collectiveidea/delayed_job_active_record/compare/v4.1.3...v4.1.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-20 19:14:59 +00:00
Transifex-Openfoodnetwork
5e68604f11 Updating translations for config/locales/nb.yml 2019-08-20 17:42:09 +10:00
Transifex-Openfoodnetwork
c4edd3a683 Updating translations for config/locales/fr.yml 2019-08-20 17:41:25 +10:00
Transifex-Openfoodnetwork
574781e901 Updating translations for config/locales/nb.yml 2019-08-20 17:39:01 +10:00
Transifex-Openfoodnetwork
8ea4f933da Updating translations for config/locales/fr.yml 2019-08-20 17:38:12 +10:00
Transifex-Openfoodnetwork
1e9820f291 Updating translations for config/locales/fr.yml 2019-08-20 17:35:05 +10:00
Luis Ramos
34ed86cf2d Merge pull request #4132 from Matt-Yorkley/import_launch
Product Import beta
2019-08-19 17:17:16 +01:00
Kevin Christianson
2dfcedad56 Add swagger.yaml 2019-08-18 18:26:44 +01:00
Kristina Lim
706168f2f0 Refresh variant cache when changing stock movements 2019-08-18 16:22:12 +08:00
Kristina Lim
3ecb5c0c75 Flush background jobs in failing spec 2019-08-18 18:16:28 +10:00
luisramos0
249a3c4e18 Make product set raise error and inform the user something went wrong and keep bugsnag notification so we can get more information about what's going on 2019-08-17 19:19:46 +01:00
luisramos0
2b8ebba233 Fix some rubocop issues in product_set and admin/products_controller 2019-08-17 19:15:32 +01:00
luisramos0
758394464b Add bugsnag notification to products_controller create and update when on_hand or on_demand update fails with exception 2019-08-17 19:15:32 +01:00
luisramos0
d3c624ae10 Add bugsnag notification to product_set create_variant when on_hand or on_demand update fails with exception 2019-08-17 19:15:31 +01:00
luisramos0
163c65849e Make product set a bit more robust by not failing to update on_hand when variant is not valid. This will make the overall set update work 2019-08-17 19:14:25 +01:00
luisramos0
99ff714913 Enable cache on checkout spec to test cache after checkout 2019-08-16 20:17:14 +01:00
luisramos0
c2f302450f Add spec to checkout to validate product is removed from shopfront just after all available quantity is checked out 2019-08-16 19:35:57 +01:00
luisramos0
9186bcd455 Dry out some code in checkout_spec 2019-08-16 19:35:08 +01:00
Transifex-Openfoodnetwork
3d074b530f Updating translations for config/locales/nb.yml 2019-08-15 19:16:43 +10:00
Transifex-Openfoodnetwork
20783db373 Updating translations for config/locales/en_GB.yml 2019-08-15 19:14:53 +10:00
Luis Ramos
d5b37a5171 Merge pull request #4079 from HugsDaniel/defacepocalypse-payments
[Defacepocalypse] De-deface payments
2019-08-14 19:30:33 +01:00
luisramos0
b9ddb39edc Re-add taxons jstree action to make taxonomies config page work again 2019-08-14 16:31:34 +01:00
Luis Ramos
3efe2f878d Merge pull request #4156 from coopdevs/fix-styling-in-paypal-tests
Fix Rubocop violations in PayPal tests
2019-08-14 15:59:14 +01:00
Luis Ramos
064fee79b3 Merge pull request #4151 from Matt-Yorkley/datadog_apm
Enable (optional) APM with Datadog
2019-08-14 15:58:48 +01:00
Luis Ramos
d13f182801 Merge pull request #4154 from Matt-Yorkley/fix_deployments2
Adjust user creation syntax
2019-08-14 15:56:32 +01:00
Luis Ramos
ee34935223 Fix a typo in docker.md 2019-08-14 13:55:58 +01:00
Pau Perez
0b7ce0d6db Fix Rubocop violations in PayPal tests 2019-08-14 13:33:53 +02:00
Matt-Yorkley
9dd02044a5 Fix "can't modify frozen string" error in validation callbacks 2019-08-14 10:24:30 +01:00
Matt-Yorkley
d8a7190f43 Adjust user creation syntax
#skip_confirmation! can't be chained...
2019-08-14 09:22:11 +01:00
Matt-Yorkley
e5e0fcc887 Enable DelayedJob APM 2019-08-14 08:20:47 +01:00
Pau Pérez Fabregat
53496ff9eb Merge branch 'master' into transifex 2019-08-14 09:08:40 +02:00
Pau Pérez Fabregat
6635a89af7 Merge pull request #4153 from Matt-Yorkley/fix_deployments
Fix deployments
2019-08-14 08:59:23 +02:00
Transifex-Openfoodnetwork
c1248857b8 Updating translations for config/locales/en_CA.yml 2019-08-14 09:15:20 +10:00
Matt-Yorkley
8c95399292 Don't prompt if admin user already exists 2019-08-13 21:02:12 +01:00
Matt-Yorkley
14c1abb861 Skip confirmation email on initial admin user creation 2019-08-13 21:00:30 +01:00
dependabot-preview[bot]
e2d61f5e89 Bump stripe from 4.19.0 to 4.24.0
Bumps [stripe](https://github.com/stripe/stripe-ruby) from 4.19.0 to 4.24.0.
- [Release notes](https://github.com/stripe/stripe-ruby/releases)
- [Changelog](https://github.com/stripe/stripe-ruby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/stripe/stripe-ruby/compare/v4.19.0...v4.24.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-13 19:18:17 +00:00
Transifex-Openfoodnetwork
5a1ef04c67 Updating translations for config/locales/en_ZA.yml 2019-08-14 04:57:27 +10:00
Transifex-Openfoodnetwork
e9e73ef0e4 Updating translations for config/locales/en_ZA.yml 2019-08-14 04:43:50 +10:00
Matt-Yorkley
be844253eb Enable (optional) Rails APM with Datadog 2019-08-13 18:57:49 +01:00
Transifex-Openfoodnetwork
001e3688da Updating translations for config/locales/en_GB.yml 2019-08-14 03:28:13 +10:00
luisramos0
b4ffd4dcc2 Update all locales with the latest Transifex translations 2019-08-13 18:25:23 +01:00
Transifex-Openfoodnetwork
e5a9606449 Updating translations for config/locales/en_GB.yml 2019-08-14 03:25:02 +10:00
Pau Pérez Fabregat
9eabbb8dab Merge pull request #4140 from openfoodfoundation/transifex
Transifex
2019-08-13 12:00:48 +02:00
Hugo Daniel
1217811402 Refactor and remove empty lines 2019-08-13 11:03:04 +02:00
Pau Pérez Fabregat
d4f2fcb98a Merge pull request #4126 from Matt-Yorkley/cart_dropdown
Cart dropdown now closes when clicking outside it.
2019-08-13 10:57:56 +02:00
Matt-Yorkley
0b2417849c Merge pull request #4142 from mkllnk/seed-user
Seed user
2019-08-13 08:42:07 +01:00
Matt-Yorkley
3e8369c8f5 Merge pull request #4123 from Matt-Yorkley/navigation-css
Navigation css
2019-08-13 08:41:47 +01:00
Maikel Linke
cbaedcec92 Fix seeding of default user without asking 2019-08-13 09:47:54 +10:00
Hugo Daniel
bf2c1a0c1d Add ng directive for setting on demand 2019-08-09 14:42:39 +02:00
Matt-Yorkley
0284eebf35 Fix cart dropdown positioning 2019-08-09 11:50:33 +01:00
Maikel Linke
e4ba515109 Seed admin user without asking by default 2019-08-09 14:16:01 +10:00
Maikel Linke
af1f6f6c6d Skip confirmation when creating first admin user 2019-08-09 14:16:01 +10:00
Maikel Linke
b0e8ee42c1 Restore spree_auth_devise user seeding 2019-08-09 13:48:50 +10:00
Maikel
86aeb6a3c7 Merge pull request #4135 from coopdevs/remove-bugherd-tests
Remove bugherd specs
2019-08-09 12:53:23 +10:00
Matt-Yorkley
5d83414e9b Disable rubocop for spree tabs helper 2019-08-08 20:09:35 +01:00
Transifex-Openfoodnetwork
9820d7de38 Updating translations for config/locales/ca.yml 2019-08-09 02:36:02 +10:00
Pau Pérez Fabregat
910eca810a Merge pull request #4124 from Matt-Yorkley/order_email
Add SKU to order confirmation email
2019-08-08 18:35:20 +02:00
Transifex-Openfoodnetwork
6feaddf747 Updating translations for config/locales/es.yml 2019-08-09 02:33:35 +10:00
Transifex-Openfoodnetwork
10f6fb91f6 Updating translations for config/locales/ca.yml 2019-08-09 02:32:54 +10:00
Pau Pérez Fabregat
c7bd4b94b8 Merge pull request #4137 from openfoodfoundation/transifex
Transifex
2019-08-08 18:31:47 +02:00
Transifex-Openfoodnetwork
dd223a21f2 Updating translations for config/locales/nb.yml 2019-08-08 20:58:24 +10:00
Transifex-Openfoodnetwork
549366ff15 Updating translations for config/locales/fr.yml 2019-08-08 20:52:28 +10:00
Transifex-Openfoodnetwork
e92f60fb1c Updating translations for config/locales/fr.yml 2019-08-08 20:49:20 +10:00
Pau Pérez Fabregat
92b05c76a3 Merge pull request #4068 from luisramos0/replace_oc_rabl
Convert order_cycle.rabl to Api::OrderCycleSerializer
2019-08-08 12:23:09 +02:00
Hugo Daniel
fa6fa0be64 Add missing translation 2019-08-08 11:11:32 +02:00
Kristina Lim
752efac7cf Merge pull request #4051 from luisramos0/subs_unpause
Sync subscription (create/update orders) when subscription is unpaused
2019-08-08 01:09:09 +08:00
Pau Perez
2b1f1f748b Remove bugherd specs
I don't think these are worth the time it takes to execute them every
time but most importantly I believe we are not using Bugherd anymore.
2019-08-07 16:49:32 +02:00
Pau Pérez Fabregat
798cd9e778 Merge pull request #4114 from kristinalim/fix/4103-add_specs
4103 Add specs for referencing of shipments to deleted variants
2019-08-07 12:52:11 +02:00
Matt-Yorkley
2f5b0a5afb Remove product import FeatureFlag 2019-08-07 09:59:55 +01:00
Maikel
de2d4a5870 Merge pull request #4125 from Matt-Yorkley/variant_overrides
Variant overrides with on_demand
2019-08-07 10:25:32 +10:00
Matt-Yorkley
b3728568a8 Enable product import for non-superadmin users
This class_eval hack for premissions on the #tab method was really hard to find, and is obviously quite ugly, but refactoring it is maybe outside of the scope here...
2019-08-06 18:59:12 +01:00
Matt-Yorkley
6ba98b4b2c Add beta notice to Product Import 2019-08-06 17:02:38 +01:00
Matt-Yorkley
d3d6921a0f Use light grey colour with transparency. 2019-08-06 08:23:38 +01:00
Maikel
68393f1444 Merge pull request #4037 from luisramos0/subs_stock
Subscriptions - When editing subscriptions, check stock levels when changing orders in current OC
2019-08-06 15:16:00 +10:00
Maikel
229e6fa0a3 Merge pull request #4073 from luisramos0/kill_more_rabl
Replace update_prod_image.rabl with ImageSerializer in api/product_image_controller
2019-08-06 15:00:33 +10:00
Matt-Yorkley
8a069787d1 Cart dropdown now closes when clicking outside it. 2019-08-05 21:48:37 +01:00
Matt-Yorkley
29ed38a6cc Add unit tests for overriding #move 2019-08-05 17:01:56 +01:00
Matt-Yorkley
4c7d3a491a Don't decrement variant stock if override is on_demand 2019-08-05 17:01:56 +01:00
Matt-Yorkley
b0f90cf43c Add test for variant override with :on_demand 2019-08-05 17:01:54 +01:00
Pau Pérez Fabregat
02ec0634b3 Merge pull request #4120 from openfoodfoundation/dependabot/bundler/webmock-3.6.2
Bump webmock from 3.6.0 to 3.6.2
2019-08-05 15:13:31 +02:00
Pau Pérez Fabregat
64d21969f0 Merge pull request #4064 from luisramos0/convert_search_Rabl
Replace views/admin/variants/search.rabl with Api::Admin::VariantSerializer
2019-08-05 15:07:10 +02:00
Pau Pérez Fabregat
0995adeb59 Merge pull request #4085 from openfoodfoundation/dependabot/bundler/devise-encryptable-0.2.0
Bump devise-encryptable from 0.1.2 to 0.2.0
2019-08-05 15:01:46 +02:00
Pau Pérez Fabregat
073a3fe2b4 Merge pull request #4119 from openfoodfoundation/transifex
Transifex
2019-08-05 13:18:12 +02:00
Matt-Yorkley
c07df6a5a6 Fix table column alignments 2019-08-04 20:45:00 +01:00
Matt-Yorkley
a7d109833d Add SKU to order confirmation email 2019-08-04 20:43:55 +01:00
Matt-Yorkley
0364a14073 Add navigation bottom border on mobile view 2019-08-04 16:56:43 +01:00
Matt-Yorkley
ddc8d33356 Update border colour on navigation bar 2019-08-04 16:56:03 +01:00
Kristina Lim
cd81dfaead Move deleted variant to let block in feature spec 2019-08-02 21:52:36 +08:00
Kristina Lim
25073ada84 Move order to a let block in feature spec 2019-08-02 21:52:33 +08:00
Kristina Lim
15b6f9dd5e Add specs testing edit order page still okay when variant deleted
Note that the wrapping example group also loads the edit order page
before this "before" block. This will be fixed in the next commit.
2019-08-02 21:45:39 +08:00
Kristina Lim
0377e02dc1 Add specs testing that shipments see deleted variants 2019-08-02 21:45:38 +08:00
dependabot-preview[bot]
f679708a4e Bump webmock from 3.6.0 to 3.6.2
Bumps [webmock](https://github.com/bblimke/webmock) from 3.6.0 to 3.6.2.
- [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.6.0...v3.6.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-01 19:15:26 +00:00
Transifex-Openfoodnetwork
0f748a3333 Updating translations for config/locales/en_GB.yml 2019-08-02 04:32:50 +10:00
Transifex-Openfoodnetwork
bdedaa06d8 Updating translations for config/locales/en_GB.yml 2019-08-02 04:29:40 +10:00
Pau Pérez Fabregat
6a41d9be87 Merge pull request #4092 from coopdevs/remove-admin-products-N+1
Remove N+1 while fetching distributors of OCs
2019-08-01 19:50:49 +02:00
luisramos0
4aa6c673ff Adapt api products and variants controllers to new namespace outside of Spree 2019-08-01 18:34:19 +01:00
luisramos0
aa3c1aa0fe Remove Spree module declaration from these files as they were moved out of the spree namespace 2019-08-01 14:30:11 +01:00
luisramos0
31bac9641f Move api products and variants routes and ctrl out of spree namespace 2019-08-01 14:28:55 +01:00
Pau Perez
3616a27566 Update all locales with the latest Transifex translations 2019-08-01 15:07:09 +02:00
Hugo Daniel
60bdde6349 Convert variants/new from erb to haml and import new.js.erb 2019-08-01 11:23:44 +02:00
Hugo Daniel
5faf33fabe Import variants/new.html.erb from spree_backend 2019-08-01 10:50:13 +02:00
Hugo Daniel
f3b1a5dd35 Convert variants/edit from erb to haml 2019-08-01 10:45:04 +02:00
Matt-Yorkley
5ae61017f5 Merge pull request #4091 from Matt-Yorkley/missing_css
Move CSS rule to SCSS and remove broken css file reference
2019-07-31 23:48:52 +01:00
Luis Ramos
61dffb8821 Merge pull request #4093 from openfoodfoundation/dependabot/bundler/redcarpet-3.5.0
Bump redcarpet from 3.4.0 to 3.5.0
2019-07-31 20:53:43 +01:00
Hugo Daniel
07ccbf7f98 Import variants/edit.html.erb from spree_backend 2019-07-31 16:55:47 +02:00
Luis Ramos
f9fabd088c Merge pull request #4075 from HugsDaniel/defacepocalypse-payment-methods
[Defacepocalypse] De-deface payment methods index
2019-07-31 15:49:48 +01:00
Hugo Daniel
a3af6617a9 Convert payments/show from erb to haml 2019-07-31 16:20:32 +02:00
Hugo Daniel
9f7fb654c8 Import payments/show.html.erb from spree_backend 2019-07-31 16:16:26 +02:00
Hugo Daniel
b4a6686eac Convert payments/_list from erb to haml 2019-07-31 16:15:38 +02:00
Hugo Daniel
ac13ff114c Import payments/_list.html.erb from spree_backend 2019-07-31 16:09:48 +02:00
Hugo Daniel
af9187947f Convert erb to haml 2019-07-31 16:02:48 +02:00
luisramos0
b7f7038934 Remove api/enterprises rabl template, it was only used as a member in the now removed rabl variants/products templates 2019-07-31 14:36:36 +01:00
Hugo Daniel
f0fdbf7cf4 Import payments/index from spree_backend 2019-07-31 14:33:38 +02:00
Hugo Daniel
74ab31c0e6 Import gateway.html.erb and convert to haml 2019-07-31 14:28:15 +02:00
luisramos0
6c054e6078 Add bulk_products and overridable to skip_authorization_check so these endpoints work with AMS 2019-07-31 12:18:27 +01:00
luisramos0
18974c68e1 Remove orphan price check from price model
This is a quick fix. This check is breaking product deletion in some situations and orphan Prices are not really a problem in the DB
2019-07-31 11:24:55 +01:00
luisramos0
78ab852141 Make spree/api/products_controller work with AMS 2019-07-31 11:23:43 +01:00
luisramos0
4497173213 Adapt spree/api/products_controller_spec to AMS serializer 2019-07-31 11:23:18 +01:00
luisramos0
4d74d246e8 Remove spree/api/products_controller index and new actions, not used 2019-07-31 10:32:45 +01:00
luisramos0
cc51537e93 Convert spree/api/products_controller from rabl to ams 2019-07-31 09:50:34 +01:00
luisramos0
07aececdcf Remove unused route api/products managed 2019-07-31 09:50:31 +01:00
luisramos0
c3fbf9cdf9 Remove unused pagination from index and respective specs, fix spec for search by sku by adding sku to the serializer and adapt a few specs to pass with AMS attrivbutes, 2019-07-31 09:40:19 +01:00
luisramos0
180598c603 Convert spree/api/variants_controller to AMS by changing base_controller, using render json instad of respond with, deleting rabl templates and adapting specs
Delete unused pagination spec
2019-07-31 09:40:19 +01:00
luisramos0
69a5527e24 Update/regenarate .rubocop_todo.yml 2019-07-31 09:36:48 +01:00
luisramos0
e4a6b3880f Fix some more simple rubocop issues 2019-07-31 09:36:48 +01:00
luisramos0
96ce4deb45 Transpec spec/support/api_helper.rb 2019-07-31 09:36:48 +01:00
luisramos0
a3c179bd3f Fix some more simple rubocop issues 2019-07-31 09:36:48 +01:00
luisramos0
a57504ba1f Bring api_helper.image from spree_api to support spree/api/products_controller_spec 2019-07-31 09:36:48 +01:00
luisramos0
25451eed6b Bring api spec helpers from spree_api into ofn/api_helper 2019-07-31 09:36:48 +01:00
luisramos0
50765563f8 Bring spree/api_helpers from spree_api 2019-07-31 09:35:46 +01:00
luisramos0
2ae75ce13e Add ControllerSetup from spree_api as it is used in spree/api/base_controller 2019-07-31 09:35:46 +01:00
luisramos0
18aa16650d Remove dependency to Spree::ApiConfiguration, overall requires_authentication? is true, exceptions will be endpoint specific 2019-07-31 09:35:46 +01:00
luisramos0
314ed50e0f Fix a rubocop issue in spree/api/products_controller 2019-07-31 09:34:20 +01:00
luisramos0
7346a49982 Move routes in ofn api namespace to separate routes file 2019-07-31 09:34:20 +01:00
luisramos0
5182286218 Add necessary spree api routes related to api keys for users and bring respective implementations from spree_api 2019-07-31 09:34:20 +01:00
luisramos0
a267848394 Remove unused api routes from views/spree/admin/shared/routes view 2019-07-31 09:32:33 +01:00
luisramos0
104bd31f9b Add necessary spree api routes: taxons, variants and shipments 2019-07-31 09:32:33 +01:00
luisramos0
8bc9985edb Transpec and fix rubocop issues in spree/api/variants_controller_spec 2019-07-31 09:32:33 +01:00
luisramos0
6dfc927730 Make spree/api/variant_controllers_spec pass 2019-07-31 09:32:33 +01:00
luisramos0
3771e26eba Bring tests from spree/api/variants_controller_spec from spree_api 2019-07-31 09:32:33 +01:00
luisramos0
fd21d35aee Transpec and fix rubocop issues in spree/api/shipments_controller_spec 2019-07-31 09:32:33 +01:00
luisramos0
1417b924d2 Bring and adapt tests from spree/api/shipments_controller_spec and mix them with exiting tests in OFN 2019-07-31 09:32:33 +01:00
luisramos0
2912c1b87d Transpec and fix rubocop issues in spree/api/product_controller_spec 2019-07-31 09:32:33 +01:00
luisramos0
e746a0db7d Bring tests from spree/api/products_controller_spec and add them to existing ones on the ofn side
Adapt these tests to have a green build
2019-07-31 09:32:33 +01:00
luisramos0
84a2886003 Improve auth code in spree/api/taxons_controller_spec 2019-07-31 09:32:33 +01:00
luisramos0
c668677b8a Bring spree/api/taxons_controller_spec from spree_api, adapt it, transpec it and fix rubocop issues 2019-07-31 09:32:33 +01:00
luisramos0
2490cbfccb Transpec and fix rubocop issues in spree/api/base_controller_spec 2019-07-31 09:32:33 +01:00
luisramos0
20a46a791c Bring and adapt spree/api/base_controller_spec from spree_api 2019-07-31 09:32:33 +01:00
luisramos0
0e4fe08ac4 Fix logical problem in spree/api/base_controller and in spree/checkout_controller
See this stack overflow post for more info: https://stackoverflow.com/questions/39629976/ruby-return-vs-and-return
2019-07-31 09:32:33 +01:00
luisramos0
cf0f716534 Fix easy rubocop issues in spree/api/taxons_controller 2019-07-31 09:32:33 +01:00
luisramos0
b70cfa5968 Bring spree/api/taxons controller from spree_api as it is needed in OFN admin 2019-07-31 09:32:33 +01:00
luisramos0
f77beb50ff Fix class scope in spree/api/products_controller, should not use Spree namespace here
Also, add missing dependency to spree/admin/products_controller_decorator
2019-07-31 09:32:33 +01:00
luisramos0
a941280982 Fix easy rubocop issues in spree/api/base_controller 2019-07-31 09:32:33 +01:00
luisramos0
9d40ee49e6 Bring spree/api/base_controller from spree_api 2019-07-31 09:32:33 +01:00
luisramos0
6abbdecb97 Fix the easy rubocop issues in the new spree api controllers 2019-07-31 09:32:33 +01:00
luisramos0
660ce92c27 Merge spree api controllers and its decorators 2019-07-31 09:32:33 +01:00
luisramos0
c5bcef6ae4 Delete unused spree/api/line_items_controller_decorator.rb 2019-07-31 09:32:33 +01:00
luisramos0
d26a0b6b73 Bring from spree_api the api controllers that are overriden in OFN so that we can merge the original and the override afterwards 2019-07-31 09:32:33 +01:00
luisramos0
9400516b56 Fix broken (was always green) bulk_product_update_spec updating image spec where the old src url was not stored and the expect command was wrong with != 2019-07-30 20:37:26 +01:00
luisramos0
6ebfb02d0e Update ImageSerializer with missing image size urls: mini/thumb_url, product/image_url that is used in the product image modal 2019-07-30 20:15:21 +01:00
Luis Ramos
75c7e0b939 Merge pull request #4089 from luisramos0/undeface-fix
Add doctype declaration in layouts/admin view
2019-07-30 19:29:17 +01:00
Luis Ramos
62eb2bba13 Merge pull request #4059 from luisramos0/kill_rabl
Convert 2 rabl templates to AMS and remove a few unused ones
2019-07-30 19:28:21 +01:00
Luis Ramos
3fa9e857a8 Merge pull request #4067 from luisramos0/oc_icon
Add icon to OC menu entry
2019-07-30 14:08:08 +01:00
luisramos0
11a77043eb Switch from Spree::Api::BaseController to Api::BaseController so that AMS is activated 2019-07-30 12:20:14 +01:00
luisramos0
58b43c7bc9 Remove update_product_image.v1.rabl and switch controller from respond_with to render json to switch from rabl to AMS 2019-07-30 12:19:42 +01:00
dependabot-preview[bot]
7da10db055 Bump redcarpet from 3.4.0 to 3.5.0
Bumps [redcarpet](https://github.com/vmg/redcarpet) from 3.4.0 to 3.5.0.
- [Release notes](https://github.com/vmg/redcarpet/releases)
- [Changelog](https://github.com/vmg/redcarpet/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vmg/redcarpet/compare/v3.4.0...v3.5.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-29 19:16:07 +00:00
luisramos0
be41271038 Make spelling coherent, as we have serializers with Z we get rid of the few serialisers with S we have 2019-07-29 19:57:12 +01:00
luisramos0
04e13e1136 Change css styling from id to class to make rubocop happy. Keeping id name as it may be needed in spree autocomplete css or js code 2019-07-29 19:46:12 +01:00
luisramos0
8868b7eb12 Fix rubocop issue: use nested class/module definition 2019-07-29 19:05:39 +01:00
Pau Perez
c85d00fcb8 Remove N+1 while fetching distributors of OCs
What used to be done as

```sql
SELECT "order_cycles".* FROM "order_cycles"
WHERE (order_cycles.orders_open_at <= '2019-07-29 17:45:20.137294'
  AND order_cycles.orders_close_at >= '2019-07-29 17:45:20.137333')

SELECT DISTINCT "enterprises".* FROM "enterprises"
INNER JOIN "exchanges" ON "enterprises"."id" = "exchanges"."receiver_id"
WHERE "exchanges"."order_cycle_id" = 1
  AND "exchanges"."incoming" = 'f'
(...)
SELECT DISTINCT "enterprises".* FROM "enterprises"
INNER JOIN "exchanges" ON "enterprises"."id" = "exchanges"."receiver_id"
WHERE "exchanges"."order_cycle_id" = 4
  AND "exchanges"."incoming" = 'f'
```

it became

```sql
SELECT "order_cycles".* FROM "order_cycles"
WHERE (order_cycles.orders_open_at <= '2019-07-29 17:45:20.137294'
  AND order_cycles.orders_close_at >= '2019-07-29 17:45:20.137333')

SELECT "exchanges".* FROM "exchanges"
WHERE "exchanges"."incoming" = 'f'
  AND "exchanges"."order_cycle_id" IN (1, 2, 3, 4)

SELECT "enterprises".* FROM "enterprises"
WHERE "enterprises"."id" IN (3, 4, 5, 6)
```

I haven't got any perf numbers yet but each of the N+1 queries took as
long as the single `enterprises` query on my dev machine.

This should have a noticeable perf impact since the changed method
belongs to the `BaseController` seems to be executed in all HTML
requests as it gets called by

```ruby
before_filter :warn_invalid_order_cycles, if: :html_request?
```
2019-07-29 20:02:47 +02:00
luisramos0
2c6dab9c85 Add spec for Api::OrderCycleSerializer 2019-07-29 18:56:49 +01:00
Matt-Yorkley
7b2a146404 Move CSS rule to SCSS and remove broken css file reference 2019-07-29 18:16:36 +01:00
luisramos0
c45194473b Add spec to cover inject_current_order_cycle 2019-07-29 18:14:00 +01:00
luisramos0
3c0e6eeee2 Make inject_current_order_cycle render {} instad of null if current_order_cycle is null 2019-07-29 18:13:29 +01:00
luisramos0
ca5a5bf301 Convert oc.rabl to oc serializer and use it in both haml file and controller 2019-07-29 18:13:29 +01:00
luisramos0
ddf68444fb Move head scripts from admin layout to haed partial 2019-07-29 17:04:57 +01:00
luisramos0
4867649fc9 Remove dead code related to unused variable in spree: expand_variants 2019-07-29 17:04:57 +01:00
Pau Pérez Fabregat
35841066d1 Merge pull request #4086 from openfoodfoundation/transifex
Transifex
2019-07-29 17:33:19 +02:00
luisramos0
9bc81f236c Add doctype declaration as it is defined in spree layouts/admin so that html5 mode is enabled, otherwise html 4 mode is used by browsers and the observed layout problems happen 2019-07-29 13:46:35 +01:00
luisramos0
e26a54d897 Fix indentation problem in layouts/admin view
We move most entries inside wrapper as it should be and the last ones "admin_footer_scripts" and Spree.api_key inside the body tag as it should be
2019-07-29 13:33:11 +01:00
Transifex-Openfoodnetwork
ed1d637eb5 Updating translations for config/locales/es.yml 2019-07-29 19:06:20 +10:00
Transifex-Openfoodnetwork
831284c5c8 Updating translations for config/locales/es.yml 2019-07-29 19:03:13 +10:00
Transifex-Openfoodnetwork
e45b8f6981 Updating translations for config/locales/ca.yml 2019-07-29 19:02:24 +10:00
Transifex-Openfoodnetwork
d0f8f985fb Updating translations for config/locales/es.yml 2019-07-29 19:00:02 +10:00
Transifex-Openfoodnetwork
33eec61af8 Updating translations for config/locales/ca.yml 2019-07-29 18:59:14 +10:00
Transifex-Openfoodnetwork
00c324ae45 Updating translations for config/locales/fr.yml 2019-07-29 18:01:09 +10:00
Transifex-Openfoodnetwork
12a016d31d Updating translations for config/locales/fr.yml 2019-07-29 17:57:59 +10:00
dependabot-preview[bot]
8c7a7348f4 Bump devise-encryptable from 0.1.2 to 0.2.0
Bumps [devise-encryptable](https://github.com/plataformatec/devise-encryptable) from 0.1.2 to 0.2.0.
- [Release notes](https://github.com/plataformatec/devise-encryptable/releases)
- [Changelog](https://github.com/plataformatec/devise-encryptable/blob/master/Changelog.md)
- [Commits](https://github.com/plataformatec/devise-encryptable/compare/v0.1.2...v0.2.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-26 23:12:41 +00:00
Luis Ramos
af50bde088 Merge pull request #3786 from ja9-look/feature/sticky_header_on_scroll_mobile
sticky header for mobile
2019-07-26 11:22:33 +01:00
Luis Ramos
340b92e580 Merge pull request #3700 from luisramos0/2-0-without-auth-devise
Remove dependency to spree_auth_devise
2019-07-26 10:57:38 +01:00
luisramos0
f64653db14 Add icon to OC menu entry 2019-07-26 10:52:31 +01:00
Maikel
e6ef661f0d Merge pull request #4066 from luisramos0/reorg_spec_serializers
Organizing spec/serializers - put each file in the correct place
2019-07-26 16:23:23 +10:00
Hugo Daniel
3c2b6f4ed1 Remove data-hooks 2019-07-25 14:38:09 +02:00
Hugo Daniel
ec6f6056a8 Remove data-hooks 2019-07-25 14:34:06 +02:00
Hugo Daniel
6a621f47aa Remove data-hooks 2019-07-25 14:31:07 +02:00
Hugo Daniel
c464b21d76 Remove data-hooks 2019-07-25 14:27:53 +02:00
Hugo Daniel
c83d249147 Impor missing partials from spree to ofn and convert to haml 2019-07-25 14:23:24 +02:00
Kristina Lim
dae23d3c3b Remove unused inclusion of $window in OffcanvasCtrl 2019-07-25 20:22:51 +08:00
Hugo Daniel
aae5ae9f1e De-deface payments/new 2019-07-25 13:27:41 +02:00
Hugo Daniel
888e0e0bb4 Convert erb partials to haml 2019-07-25 13:22:55 +02:00
Hugo Daniel
a0b0fb05a6 Import payments/new from spree_backend to ofn 2019-07-25 13:22:32 +02:00
Hugo Daniel
a11562e4dd Fix incorrect indentation in variants table 2019-07-25 12:05:50 +02:00
Hugo Daniel
2d872c25bf Use Haml javascript tag to make autocomplete work 2019-07-25 11:20:51 +02:00
Hugo Daniel
986837d601 Import variants/_form.html.erb from spree_backend to ofn and de-deface it 2019-07-25 11:07:35 +02:00
Kristina Lim
def2693afc Move offcanvas JS to Angular controller 2019-07-25 17:01:46 +08:00
Luis Ramos
55f26f0a3d Merge pull request #4043 from luisramos0/bring_shipment
Bring spree/admin/orders/shipment and shipment_manifest partials from spree_backend and fix an authorization bug
2019-07-24 21:59:47 +01:00
Luis Ramos
7245d1eff4 Merge pull request #4049 from luisramos0/deface_admin_orders
De-deface admin orders adjustments page and customer details page
2019-07-24 21:59:08 +01:00
Hugo Daniel
353d6fbc5f Import variants/index from spree_backend to ofn and convert to Haml 2019-07-24 16:57:11 +02:00
Hugo Daniel
87ef0215b8 De-deface payment_methods/index 2019-07-24 14:49:29 +02:00
Hugo Daniel
4b6a02cb92 Convert payment_methods/index from ERB to Haml 2019-07-24 14:39:59 +02:00
Hugo Daniel
196a301133 Import payment_methods/index.html.erb from spree_backend to ofn 2019-07-24 14:38:20 +02:00
Hugo Daniel
0a88738faa Replace old ruby syntax with new 2019-07-24 14:37:00 +02:00
Hugo Daniel
4d6af57f79 De-deface product_properties/index 2019-07-24 13:17:45 +02:00
Hugo Daniel
110fd3ecdf Convert erb to haml 2019-07-24 13:12:58 +02:00
Hugo Daniel
1cb065f829 Import product_properties/index.html.erb from spree_backend to ofn 2019-07-24 13:09:04 +02:00
Hugo Daniel
1cfa499b0e De-deface _product_propery_fields 2019-07-24 13:01:50 +02:00
luisramos0
b9b8bc70dd Remove stock location name from shipment header in the order edit page 2019-07-24 11:50:17 +01:00
Hugo Daniel
3fc0d4a666 Convert _product_properties_fields from ERB to Haml 2019-07-24 12:40:24 +02:00
Hugo Daniel
de6c96d138 Import product_properties/_product_properties_fields.html.erb from Spree to OFN 2019-07-24 12:38:29 +02:00
Kristina Lim
d42da8737e Improve readability of selectors in page alert JS directive 2019-07-24 12:44:42 +08:00
Kristina Lim
6419edcb1f Integrate styles/animations for page alert, top bar, tab bar, off canvas 2019-07-24 12:44:42 +08:00
Kristina Lim
fca82375e8 Render home page alert as :page_alert outside main content 2019-07-24 12:44:42 +08:00
Kristina Lim
ca0f746cf1 Fix animation and layout for offcanvas menu
Uses strategy from this forum comment:
http://foundation.zurb.com/forum/posts/547#comment_8840
2019-07-24 12:43:44 +08:00
Kristina Lim
a93cf46f50 Fix syntax of existing animations for offcanvas 2019-07-24 12:37:42 +08:00
luisramos0
ffb8edef0b Fix rubocop css issues 2019-07-23 22:37:10 +01:00
luisramos0
74a030f6db Organizing spec/serializers - put each file in the correct place acccording to its namespace 2019-07-23 22:17:28 +01:00
luisramos0
7a8b5e89be Add specs to cover the most important new fields in api/admin/variant_serializer 2019-07-23 22:11:00 +01:00
luisramos0
90690cd238 Move api/admin/variant_serializer_spec to the correct folder under /spec 2019-07-23 22:03:40 +01:00
luisramos0
90c621ac07 Improve translations, css and add button aligment in subscriptions_line_items variant autocomplete 2019-07-23 21:38:29 +01:00
luisramos0
2d5eccbf97 Add :in_stock, :stock_location_id, :stock_location_name to admin variant serializer, these are needed for the variant_autocomplete js code from spree 2019-07-23 21:38:29 +01:00
luisramos0
7e6259da31 Replace admin/variants/search rabl template with existing admin variant serializer with a few added attributes
This commit fixes a bug as the image of the variatn was not being rendered, we need to fetch the image of the product, not the image of the variant.
2019-07-23 21:37:45 +01:00
Luis Ramos
1f75c7e5e4 Merge pull request #4047 from luisramos0/undeface
De-deface some admin configuration pages and the general admin layout and menu
2019-07-23 18:36:09 +01:00
luisramos0
11974689ef Remove dead code under views/spree/shared 2019-07-23 16:42:00 +01:00
luisramos0
a1e6e4c38f Fix rubocop issues 2019-07-23 14:35:24 +01:00
Luis Ramos
77fb73f802 Merge pull request #4065 from coopdevs/get-latest-spree-revision
Brings in the latest Spree fork's Git commit
2019-07-23 14:28:49 +01:00
Pau Perez
9f7376a5ae Brings in the latest Spree fork's Git commit
This successfully closes #3903 by bringing in the changes done in
https://github.com/openfoodfoundation/spree/pull/41.
2019-07-23 14:56:33 +02:00
luisramos0
5739a82c19 Remove unused admin variants search rabl template 2019-07-23 12:30:00 +01:00
Luis Ramos
eae373ef4b Merge pull request #4061 from openfoodfoundation/revert-3938-get-last-spree-fork-patch
Revert "Handle soft deleted variants in order edit"
2019-07-22 21:06:10 +01:00
Luis Ramos
465332d5f9 Revert "Handle soft deleted variants in order edit" 2019-07-22 21:05:41 +01:00
Luis Ramos
e98b89625f Merge pull request #3938 from openfoodfoundation/get-last-spree-fork-patch
Handle soft deleted variants in order edit
2019-07-22 21:05:12 +01:00
luisramos0
cf61254c9e Remove unnecesary rabl template 2019-07-22 18:42:20 +01:00
luisramos0
1d92d6cc33 Remove unused api endpoint order_cycles and also action enterprises/managed and respective views 2019-07-22 17:35:41 +01:00
luisramos0
6b32764c99 Remove unused taxon.rabl from views/json 2019-07-22 16:29:54 +01:00
Pau Perez
be4fbc4d23 Update Gemfile to get spree from a feature branch
This allows us to test
https://github.com/openfoodfoundation/spree/pull/41. If it passes
testing I will then revert it back to the `2-0-4-stable` branch but
updating the target commit in the Gemfile.lock.
2019-07-22 15:40:31 +02:00
luisramos0
ea72a10b9a Remove unused rabl files from views/json 2019-07-22 12:14:10 +01:00
luisramos0
9b567a6710 Remove injection_json that renders json partials, we only use ams serializers now, not rabl partials 2019-07-21 23:55:59 +01:00
luisramos0
a8ce31fa90 Replace views/json/_flash.rabl with an ams injector with serializer 2019-07-21 22:56:15 +01:00
luisramos0
4c964fea0d Replace views/json/_current_user.rabl with an ams injector with serializer 2019-07-21 22:48:36 +01:00
luisramos0
6d7c41c04b Bring db/default/users from spree_auth_devise, this is necessary to create the first user in the DB 2019-07-20 20:48:49 +01:00
Luis Ramos
a6a695660f Merge pull request #4002 from luisramos0/more_rails4
Adapting queries in permissions to Rails 4
2019-07-19 15:17:01 +01:00
Luis Ramos
0058ef5e04 Merge pull request #4048 from idanceinbetween/4034
Add grey line below nav bar, change logo img max height 44px
2019-07-19 12:13:14 +01:00
Luis Ramos
4831bae9cb Merge pull request #3953 from mkllnk/3727-first-credit-card-default
First stored credit card becomes default again
2019-07-19 12:12:09 +01:00
Luis Ramos
f7679780de Merge pull request #4032 from luisramos0/subs_oc_date_issue
3544 Add date format to moment date conversion
2019-07-18 19:52:49 +01:00
luisramos0
f2ac354e00 Make features/admin/orders_spec test a bit more reliable by expecting element to be there before using it 2019-07-18 14:29:38 +01:00
Maikel
88ffa46ce7 Merge pull request #4045 from openfoodfoundation/transifex
Transifex
2019-07-18 16:35:41 +10:00
Maikel
869431c68d Merge pull request #3926 from mkllnk/report-missing-payments
Add rake task to report lost payments
2019-07-18 15:01:14 +10:00
luisramos0
3d6fd10e59 Add warning about creation of orders when unpausing a subscription 2019-07-17 12:14:36 +01:00
luisramos0
81482683cf Extract method in subs controller 2019-07-17 12:08:51 +01:00
luisramos0
57f1742f24 Save subscription form on subs unpause so that proxy orders and orders are synced 2019-07-17 12:08:48 +01:00
Maikel
a1f8530489 Merge pull request #3962 from luisramos0/first_view_spec
First 2 view specs in OFN
2019-07-17 10:57:58 +10:00
luisramos0
a75a0da981 Remove unused deface in spree/admin/orders/show, this action doesnt exist in ofn v2 2019-07-16 21:12:48 +01:00
luisramos0
5744240f91 Move customer_details/_form defaces to the view 2019-07-16 21:12:09 +01:00
luisramos0
873c56a642 Move customer_details/edit/replace_customer_search deface to view 2019-07-16 21:09:48 +01:00
luisramos0
f53a75660f Convert spree/admin/orders/customer_details view from erb to haml 2019-07-16 21:05:19 +01:00
luisramos0
50dcbe0b57 Bring spree/admin/order/customer_details from spree_backend 2019-07-16 21:03:35 +01:00
luisramos0
f9861fee79 De-deface spree/admin/adjustments/_adjustments_table by moving deface content to the view 2019-07-16 21:01:08 +01:00
luisramos0
d8ae97f923 Move spree/admin/adjustments/_form/add_tax_rate deface to view 2019-07-16 20:53:24 +01:00
luisramos0
9f5db217fe Convert spree/admin/adjustments views from erb to haml 2019-07-16 20:51:55 +01:00
luisramos0
c1c5dcac09 Bring spree/admin/adjustments pages from spree_backend 2019-07-16 20:51:55 +01:00
luisramos0
6064f096a7 Fix a pre-existing problem in orders_tab by moving the links in to the li elements 2019-07-16 20:16:32 +01:00
luisramos0
a62fa755f5 Remove page_title_classes as it is breaking the rendering of the classes attribute and it is no longer used 2019-07-16 20:16:32 +01:00
luisramos0
fa25991f0f Fix problem in previous de-deface, move sections around in general settings page to keep order. No changes in code, just moving 2019-07-16 20:16:32 +01:00
luisramos0
6f2be1dfa6 Fix issue in layouts/admin view, make classes compute correctly 2019-07-16 20:16:32 +01:00
luisramos0
c81a9fd032 Fix error in js tag in head 2019-07-16 20:16:32 +01:00
luisramos0
665d0cc86b Fix error related to missing _hamlout method by replacing code with standard haml 2019-07-16 20:16:32 +01:00
luisramos0
a34d8a3f20 Revert "Move app_wrapper deface to spree/layouts/admin view"
This reverts commit bb18f6ecf3c1d0ecf7c010623215d161a6102f2b.
2019-07-16 20:16:32 +01:00
luisramos0
6e35701dd6 Remove unused add_enterprise_fees_to_admin_configurations_menu deface, this menu entry is already in the view 2019-07-16 20:16:32 +01:00
luisramos0
9991458d2a Remove spree/admin/shared/_order_details defaces, these are only used in admin/order/show which is a view that is not used in ofn anymore, only admin/order/edit is used 2019-07-16 20:16:32 +01:00
luisramos0
a843fd73b7 Remove admin/shared/_order_tabs/add_customer_name, this is already in the order tabs view 2019-07-16 20:16:32 +01:00
luisramos0
9765b1e908 Move admin/shared/_head/replace_spree_title deface to head view 2019-07-16 20:16:32 +01:00
luisramos0
5ccadc1f7d Convert spree/admin/shared/_head view from erb to haml 2019-07-16 20:16:32 +01:00
luisramos0
539805e2c2 Bring spree/admin/shared/head partial from spree_backend 2019-07-16 20:16:32 +01:00
luisramos0
fac64ef5bf Remove layouts/spree_application/inside_head deface, this view is in spree_frontend which is not used in ofn anymore 2019-07-16 20:16:32 +01:00
luisramos0
a17a0a62bc Move spree/layouts/bare_admin/add_login_nav deface to layout/bare_admin view 2019-07-16 20:16:32 +01:00
luisramos0
1e91de106f Move admin html head deface to layout admin view and remove repeated (in shared/head partial) content type tag 2019-07-16 20:16:32 +01:00
luisramos0
73252132a6 Move add_i18n_script deface to layout/admin view 2019-07-16 20:16:32 +01:00
luisramos0
e3c383c61c Convert spree/admin/shared/_tabs.html from erb to haml and move menu entries from layouts/admin to the tabs view 2019-07-16 20:16:32 +01:00
luisramos0
aafb134be7 Move spree/layouts/admin/ tabs deface to spree/layout/admin view 2019-07-16 20:16:32 +01:00
luisramos0
70a1996435 Move add_currency_config deface to spree/layout/admin view 2019-07-16 20:16:31 +01:00
luisramos0
1712cb2617 Move app_wrapper deface to spree/layouts/admin view
In admin layout, only adds a div after the body tag.
2019-07-16 20:16:31 +01:00
luisramos0
25df057d05 Move spree/layouts/admin/add_analytics deface to spree/layouts/admin view 2019-07-16 20:16:31 +01:00
luisramos0
24a9991162 Convert views/spree/layouts/admin.html from erb to haml 2019-07-16 20:16:31 +01:00
luisramos0
156ff2da89 Bring spree/layouts/admin from spree_backend to de-deface it 2019-07-16 20:16:31 +01:00
luisramos0
e36b4ed01a Move temp_controller_list deface to shipping_categories index view 2019-07-16 20:16:23 +01:00
idanceinbetween
41b775b173 Remove multiline 2019-07-16 20:10:18 +01:00
idanceinbetween
35570feba0 Comment out new changes 2019-07-16 20:04:50 +01:00
idanceinbetween
1d8cfe59a2 Change hex value to variable 2019-07-16 19:37:08 +01:00
idanceinbetween
abd3efe82a Replace lightgray to hex 2019-07-16 19:32:19 +01:00
idanceinbetween
389b53cb71 Add grey line below nav bar, change logo img max height 44px 2019-07-16 19:14:10 +01:00
luisramos0
4f60273198 Move temperature_controlled_form_element deface to shipping_categories form view 2019-07-16 14:50:16 +01:00
luisramos0
856fa8685a Convert spree/admin/shipping_categories views from erb to haml 2019-07-16 14:48:47 +01:00
luisramos0
9ac4c0ba30 Bring spree/admin/shipping categories from spree_backend so we can de-deface it 2019-07-16 14:46:26 +01:00
luisramos0
2709f237f5 Move image_format deface to image settings view 2019-07-16 14:44:38 +01:00
luisramos0
9db4edcd0d Convert spree/admin/image_settings/edit.html from erb to haml 2019-07-16 14:43:20 +01:00
luisramos0
22c9f33f4c Bring image_settings view from spree_backend 2019-07-16 14:39:14 +01:00
luisramos0
24ea2a4398 Move number_localization deface to general settings view 2019-07-16 14:28:47 +01:00
luisramos0
8178f5388c Move legal settings deface to general settings view 2019-07-16 14:27:32 +01:00
luisramos0
c0c5e9d7dd Move embedded_shopfronts deface to general settings view 2019-07-16 14:26:33 +01:00
luisramos0
19f8f5c6fa Convert general_settings/edit.html from erb to haml 2019-07-16 14:15:51 +01:00
luisramos0
83a306c31b Convert class attributes to . notation in haml 2019-07-16 14:09:48 +01:00
luisramos0
d6020cdb6f Bring general_settings/edit.html.erb from spree_backend to de-deface it 2019-07-16 13:57:35 +01:00
luisramos0
3b467dbae8 Adapt line_item_syncer to the case where item is not added to the completed order because of insufficient stock and the subscription quantity is updated for that item afterwards 2019-07-16 12:08:08 +01:00
luisramos0
306390440a Revert "Swith line_item_syncer.create_new_items from deleting line item in the case of stock issue, to simply set the quantity to zero. This makes things easier later as the line item is already present if the user tries to change quantity of the subscription_line_item"
This reverts commit d153e58933.
2019-07-16 11:00:21 +01:00
luisramos0
267131626e Fix typo and add test case to cover out of stock case 2019-07-16 10:58:25 +01:00
Transifex-Openfoodnetwork
f843a0b4d9 Updating translations for config/locales/en_AU.yml 2019-07-16 17:08:24 +10:00
Transifex-Openfoodnetwork
965a274332 Updating translations for config/locales/en_AU.yml 2019-07-16 17:05:40 +10:00
Transifex-Openfoodnetwork
cb2a842746 Updating translations for config/locales/en_AU.yml 2019-07-16 17:05:17 +10:00
luisramos0
a6655623d0 New admin orders edit view spec and workaround (current_ability) to make view specs work 2019-07-15 21:59:36 +01:00
luisramos0
2a2d05ad39 First view spec in OFN testing the print invoice button display in the orders list page 2019-07-15 21:59:36 +01:00
luisramos0
e8127d81dc Change how we display variant name in order edit page, use VariantAndLineItemNaming helper method 2019-07-15 18:37:19 +01:00
luisramos0
cd7906a57b Move translations from Spree.t to root and add them to en.yml 2019-07-15 17:48:10 +01:00
luisramos0
02c573f146 Remove logic that hides item split, because the partial is now in the ofn codebase, we can now simply remove the split-item button 2019-07-15 17:11:41 +01:00
luisramos0
112017a158 Remove variants/split partial from orders/shipments partial
In OFN we have one shipment per order so it doesnt make sense to split items between shipments
2019-07-15 17:07:33 +01:00
luisramos0
4a07d67037 Convert spree/admin/orders/_shipment partial from erb to haml 2019-07-15 16:42:45 +01:00
luisramos0
54156dfd32 Convert spree/admin/orders/_shipment_manifest partial from erb to haml 2019-07-15 16:42:19 +01:00
luisramos0
ee20d35487 Fix authorization issue in shipment actions, authorization was being done on a struct (shipment manifest), now it's done on the shipment itself
This is similar to https://github.com/spree/spree/pull/5624
2019-07-15 15:38:46 +01:00
luisramos0
be18244abc Bring views/spree/admin/orders/_shipment and views/spree/admin/orders/_shipment_manifest from spree backend 2019-07-15 15:37:24 +01:00
luisramos0
02099ebdae Remove details about stock in line_item_syncer so that we avoid confusing the user with stock numbers, this way the user will know what is the problem and can check stock levels and the order for more details 2019-07-14 21:40:57 +01:00
luisramos0
d153e58933 Swith line_item_syncer.create_new_items from deleting line item in the case of stock issue, to simply set the quantity to zero. This makes things easier later as the line item is already present if the user tries to change quantity of the subscription_line_item 2019-07-14 20:59:42 +01:00
luisramos0
c2a59a374c Fix rubocop issues by simplifying method 2019-07-14 17:21:15 +01:00
luisramos0
2a1011921b Reuse line_item_syncer.add_order_update_issue in line_item_syncer.update_item_quantities to add stock info to the update_quantity order issues 2019-07-14 16:43:46 +01:00
luisramos0
df27ee0d3e Refactor line_item_syncer.add_order_update_issue out of line_item_syncer.create_new_items 2019-07-14 16:06:09 +01:00
luisramos0
c2851015ce Fix deleting created item (destroy doesnt work before save) and add order_update_issue with message so that user can understand what happened 2019-07-14 15:58:00 +01:00
luisramos0
d0c246c345 Fix some rubocop issues 2019-07-14 12:28:32 +01:00
Kristina Lim
e58546a412 Move offcanvas menu content to separate partial 2019-07-14 13:52:47 +08:00
luisramos0
6aed9ba549 Make line_item_syncer delete new line items if stock is insufficient 2019-07-13 22:57:13 +01:00
luisramos0
4f2bc33ec3 Change line_item_syncer to verify stock if order is already complete, this will happen for orders in the current OC when a subscription is changed 2019-07-13 20:56:34 +01:00
luisramos0
0f3404ca27 Rename order_syncer.future_and_undated_orders to explicitly include completed orders from current OC: orders_in_order_cycles_not_closed 2019-07-12 22:20:09 +01:00
luisramos0
9e2e460ac5 Add date format to moment date conversion. This conversion was not working on firefox 2019-07-12 12:01:18 +01:00
luisramos0
18006ea9c8 Change devise config to speed up password encryption in tests 2019-07-12 10:12:53 +01:00
luisramos0
71b648e9fa Add some tests to features/admin/users_spec from spree_auth_devise 2019-07-12 10:02:40 +01:00
luisramos0
eacd76bfa4 Add spec to features/admin/products_spec from spre_auth_devise 2019-07-11 19:47:17 +01:00
luisramos0
791ff842aa Add some tests to models/spree/user_spec from spre_auth_devise 2019-07-11 19:39:31 +01:00
luisramos0
ac0123734a Add some tests from spree/users_controller_spec from spree_auth_devise 2019-07-11 18:33:18 +01:00
luisramos0
7cab99efdf Run transpec on users_controller 2019-07-11 18:07:23 +01:00
luisramos0
5378bb7b34 Add adapted version of spree/admin/users_controller_spec from spree_auth_devise 2019-07-11 17:45:56 +01:00
luisramos0
942824cd74 Improve comments in UserMailer 2019-07-11 16:37:30 +01:00
Jon Leighton
4398ea12b8 Convert several fields from string to text
See discussion here:
https://github.com/openfoodfoundation/openfoodnetwork/pull/3751#issuecomment-503416955

Fixes #3192.

I have also done a pass over the schema to identify other fields which
would benefit from being a text rather than a string. However, I ignored
all `spree_*` tables because I didn’t want to mess up the ‘default’
Spree schema.
2019-07-09 13:11:30 +10:00
luisramos0
86accc227e Convert erb files brought from spree_auth_devise to haml 2019-07-08 18:09:03 +01:00
luisramos0
1681e8a572 Remove unused auth config 2019-07-08 14:06:01 +01:00
luisramos0
e897eb0439 Remove Spree::BaseController.class_eval, these methods are already in the application helper through spree::application_helpers
We can ignore the difference in spree_logout_path as spree.logout_path is the user_sessions#destroy route
2019-07-08 13:59:26 +01:00
luisramos0
36e3362fc1 Adding missing translation that is now being used after being brought from spree_auth_devise 2019-07-08 13:23:18 +01:00
luisramos0
10e123a9c4 Move spree/authentication_helpers injection from spree initializers directly to the application_controller
Also, switch from using send to public_send making rubocop happier
2019-07-08 13:11:57 +01:00
luisramos0
0101dcdd93 Remove unused Spree::Dash from controllers brought from spree_auth_devise 2019-07-08 13:10:52 +01:00
luisramos0
9416f61fb3 Remove spree/checkout_controller.completion_route only used in spree/checkout_controller.update which is never used in OFN. Checkout update happpens in the checkout_controller.update 2019-07-08 13:04:38 +01:00
luisramos0
8efd69c3d1 Remove unnecessary checkout registration code, it's not used in OFN 2019-07-08 12:57:17 +01:00
luisramos0
dcbdfbb081 Fix rubocop issues in multiple files copied from spree_auth_devise, mostly hash rockets 2019-07-08 11:22:56 +01:00
luisramos0
92968c5efe Merge spree/users_sessions_controller into spree/users_sessions from spree_auth_devise 2019-07-07 22:06:18 +01:00
luisramos0
c8ac64566f Merge spree/users_controller_decorator into spree/user_controller 2019-07-07 22:04:04 +01:00
luisramos0
05a72be273 Move handle_asynchronously :send_reset_password_instructions to after send_reset_password_instructions declaration
This was as it was before the merge of user_decorator and user, the declaration was in the original class and the handle_asynchronously part was in the decorator which was loaded after the main user class from spree_auth_devise, this commit restores the order and fixes a spec in authentication_spec
2019-07-07 17:53:12 +01:00
luisramos0
b1cd950051 Add missing translation keys from spree_auth_devise 2019-07-07 17:12:54 +01:00
luisramos0
f557996817 Add deface overrides from spree_auth_devise for the users menu tab, the admin top bar and the shared login bar (maybe dead code this last one) 2019-07-06 22:53:20 +01:00
luisramos0
1a64a737d4 Add ActionController::Metal frorm spree_auth_devise for api authentication 2019-07-06 10:50:48 +01:00
luisramos0
7c0087cb30 Remove reference to empty spree_auth css and js files from spree_auth_devise 2019-07-06 00:02:40 +01:00
luisramos0
17448699f9 Bring devise initializer from spree_auth_devise and fix spree initializer details 2019-07-05 22:45:59 +01:00
luisramos0
a413f22e12 Remove unnecessary dependency to spree/users helper 2019-07-05 22:37:07 +01:00
luisramos0
893952f46b Merge user_mailer_decorator into user_mailer 2019-07-05 22:31:06 +01:00
luisramos0
061e3cd722 Add user mailer from spree_auth_devise 2019-07-05 22:29:51 +01:00
luisramos0
a83790951d Add model auth_config from spree_auth_devise 2019-07-05 21:58:29 +01:00
luisramos0
4e33529845 Merge user_decorator.rb into user.rb 2019-07-05 21:58:28 +01:00
luisramos0
a2a8b330b7 Add User class from spree_auth_devise as is 2019-07-05 21:58:28 +01:00
luisramos0
9669016573 Add required views from spree_auth_devise 2019-07-05 21:58:28 +01:00
luisramos0
2755cb9ec7 Add users_tab partial from spree_auth_devise 2019-07-05 21:58:28 +01:00
luisramos0
fdcc4c2447 Remove dependency to spree auth devise 2019-07-05 21:58:07 +01:00
luisramos0
fc0ffda8ec Bring routes and controllers from spree_auth_devise 2019-07-05 15:08:42 +01:00
luisramos0
a5b5e5de32 Remove trailing backslash 2019-07-05 10:58:53 +01:00
luisramos0
ef61310bad Fix long lines in order_cycle_permissions and permissions 2019-07-04 17:17:58 +01:00
luisramos0
dee1c3d139 Fix typo in order_cycle_permissions.rb 2019-07-03 22:58:33 +01:00
luisramos0
bb9c54a445 Use enterprises.id instead of :id to remove ambiguous column errors 2019-07-03 22:03:40 +01:00
luisramos0
e5f396f975 Fix Permissions.related_enterprises_granted by adding explicit reference to table 2019-07-03 20:18:01 +01:00
luisramos0
a57a93d414 Adapt permissions.rb and order_cycle_permissions to rails 4 2019-07-03 20:18:01 +01:00
luisramos0
a82b1d8129 Adapt exchange.involving scope to rails 4 2019-07-03 20:18:00 +01:00
luisramos0
5184fa540c Adapt enterprise_relationship permitting and permitted_by scopes to rails 4 2019-07-03 20:18:00 +01:00
Kristina Lim
356e00bfbb Add space for tab bar in medium and below screens 2019-07-03 04:02:28 +08:00
Kristina Lim
5534109122 Undo setting of margin for home tagline 2019-07-03 04:02:22 +08:00
Janine Luk
ac8790ecb3 sticky header for mobile 2019-07-03 03:57:11 +08:00
Maikel Linke
d8ece7cd8b First stored credit card becomes default again
A user can store their credit card when checking out. Due to a bug in
https://github.com/openfoodfoundation/openfoodnetwork/pull/3840 it
didn't become the default card any more. This behaviour is now restored.
If there is not default card yet, a new card added during checkout
becomes the default card.
2019-06-19 15:43:38 +10:00
Maikel Linke
ee65d70eec Deal with empty payments sequence
The task was crashing when there were no payments in the query range.
2019-06-19 09:58:47 +10:00
Maikel Linke
bf8a31abda Add rake task to report lost payments
In rare cases, payment records can get lost through database rollbacks.
This new rake task tries to find log entries for lost transactions and
reports them as CSV.
2019-06-14 11:10:31 +10:00
351 changed files with 7512 additions and 2852 deletions

View File

@@ -49,7 +49,6 @@ Metrics/LineLength:
- app/controllers/spree/admin/orders_controller_decorator.rb
- app/controllers/spree/admin/payments_controller_decorator.rb
- app/controllers/spree/admin/payment_methods_controller_decorator.rb
- app/controllers/spree/admin/products_controller_decorator.rb
- app/controllers/spree/admin/reports_controller_decorator.rb
- app/controllers/spree/api/products_controller_decorator.rb
- app/controllers/spree/credit_cards_controller.rb
@@ -123,14 +122,11 @@ Metrics/LineLength:
- app/serializers/api/admin/subscription_serializer.rb
- app/serializers/api/admin/tag_rule_serializer.rb
- app/serializers/api/admin/variant_override_serializer.rb
- app/serializers/api/admin/variant_serializer.rb
- app/services/cart_service.rb
- app/services/default_stock_location.rb
- app/services/embedded_page_service.rb
- app/services/line_item_syncer.rb
- app/services/order_cycle_form.rb
- app/services/order_factory.rb
- app/services/order_syncer.rb
- app/services/subscriptions_count.rb
- app/services/variants_stock_levels.rb
- app/views/json/_groups.rabl
@@ -151,15 +147,12 @@ Metrics/LineLength:
- lib/open_food_network/order_and_distributor_report.rb
- lib/open_food_network/order_cycle_form_applicator.rb
- lib/open_food_network/order_cycle_management_report.rb
- lib/open_food_network/order_cycle_permissions.rb
- lib/open_food_network/order_grouper.rb
- lib/open_food_network/orders_and_fulfillments_report.rb
- lib/open_food_network/payments_report.rb
- lib/open_food_network/permalink_generator.rb
- lib/open_food_network/permissions.rb
- lib/open_food_network/products_cache.rb
- lib/open_food_network/products_renderer.rb
- lib/open_food_network/proxy_order_syncer.rb
- lib/open_food_network/reports/bulk_coop_allocation_report.rb
- lib/open_food_network/reports/line_items.rb
- lib/open_food_network/sales_tax_report.rb
@@ -346,10 +339,8 @@ Metrics/LineLength:
- spec/models/tag_rule/filter_shipping_methods_spec.rb
- spec/models/variant_override_spec.rb
- spec/performance/orders_controller_spec.rb
- spec/performance/proxy_order_syncer_spec.rb
- spec/performance/shop_controller_spec.rb
- spec/requests/checkout/failed_checkout_spec.rb
- spec/requests/checkout/paypal_spec.rb
- spec/requests/checkout/stripe_connect_spec.rb
- spec/requests/embedded_shopfronts_headers_spec.rb
- spec/requests/shop_spec.rb
@@ -445,7 +436,6 @@ Metrics/AbcSize:
- app/models/spree/order_decorator.rb
- app/models/spree/payment_decorator.rb
- app/models/spree/product_decorator.rb
- app/models/spree/product_set.rb
- app/models/spree/taxon_decorator.rb
- app/serializers/api/admin/enterprise_serializer.rb
- app/serializers/api/product_serializer.rb
@@ -468,6 +458,7 @@ Metrics/AbcSize:
- lib/open_food_network/orders_and_fulfillments_report.rb
- lib/open_food_network/packing_report.rb
- lib/open_food_network/payments_report.rb
- lib/open_food_network/permissions.rb
- lib/open_food_network/products_and_inventory_report.rb
- lib/open_food_network/reports/line_items.rb
- lib/open_food_network/sales_tax_report.rb
@@ -566,6 +557,7 @@ Metrics/CyclomaticComplexity:
- app/helpers/checkout_helper.rb
- app/helpers/i18n_helper.rb
- app/helpers/order_cycles_helper.rb
- app/helpers/spree/admin/navigation_helper_decorator.rb
- app/models/enterprise.rb
- app/models/enterprise_relationship.rb
- app/models/product_import/entry_processor.rb
@@ -573,7 +565,6 @@ Metrics/CyclomaticComplexity:
- app/models/spree/ability_decorator.rb
- app/models/spree/payment_decorator.rb
- app/models/spree/product_decorator.rb
- app/models/spree/product_set.rb
- app/models/variant_override_set.rb
- app/services/cart_service.rb
- lib/discourse/single_sign_on.rb
@@ -601,7 +592,6 @@ Metrics/PerceivedComplexity:
- app/models/spree/ability_decorator.rb
- app/models/spree/order_decorator.rb
- app/models/spree/product_decorator.rb
- app/models/spree/product_set.rb
- lib/discourse/single_sign_on.rb
- lib/open_food_network/bulk_coop_report.rb
- lib/open_food_network/enterprise_issue_validator.rb
@@ -657,7 +647,6 @@ Metrics/MethodLength:
- app/models/spree/payment_decorator.rb
- app/models/spree/payment_method_decorator.rb
- app/models/spree/product_decorator.rb
- app/models/spree/product_set.rb
- app/serializers/api/admin/order_cycle_serializer.rb
- app/serializers/api/cached_enterprise_serializer.rb
- app/services/order_cycle_form.rb

View File

@@ -1,6 +1,6 @@
# This configuration was generated by
# `rubocop --auto-gen-config --exclude-limit 1400`
# on 2019-05-28 16:29:07 +0100 using RuboCop version 0.57.2.
# on 2019-07-23 14:09:18 +0100 using RuboCop version 0.57.2.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
@@ -32,15 +32,6 @@ Layout/EndAlignment:
Layout/IndentHash:
EnforcedStyle: consistent
# Offense count: 7
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: aligned, indented, indented_relative_to_receiver
Layout/MultilineMethodCallIndentation:
Exclude:
- 'app/models/spree/line_item_decorator.rb'
- 'app/models/spree/product_decorator.rb'
# Offense count: 4
Lint/AmbiguousOperator:
Exclude:
@@ -55,7 +46,7 @@ Lint/DuplicateMethods:
- 'lib/discourse/single_sign_on.rb'
- 'lib/open_food_network/subscription_summary.rb'
# Offense count: 15
# Offense count: 8
Lint/IneffectiveAccessModifier:
Exclude:
- 'app/models/column_preference.rb'
@@ -79,7 +70,13 @@ Lint/UnderscorePrefixedVariableName:
Exclude:
- 'spec/support/cancan_helper.rb'
# Offense count: 6
# Offense count: 1
# Cop supports --auto-correct.
Lint/UnneededCopDisableDirective:
Exclude:
- 'app/models/product_import/entry_validator.rb'
# Offense count: 5
# Configuration parameters: ContextCreatingMethods, MethodCreatingMethods.
Lint/UselessAccessModifier:
Exclude:
@@ -89,28 +86,47 @@ Lint/UselessAccessModifier:
- 'lib/open_food_network/reports/bulk_coop_report.rb'
- 'spec/lib/open_food_network/reports/report_spec.rb'
# Offense count: 91
# Offense count: 8
# Configuration parameters: CheckForMethodsWithNoSideEffects.
Lint/Void:
Exclude:
- 'app/serializers/api/enterprise_serializer.rb'
- 'spec/features/admin/bulk_product_update_spec.rb'
- 'spec/features/admin/enterprise_groups_spec.rb'
- 'spec/features/admin/enterprises/index_spec.rb'
- 'spec/features/admin/enterprises_spec.rb'
- 'spec/features/admin/order_cycles_spec.rb'
- 'spec/features/admin/payment_method_spec.rb'
- 'spec/features/admin/products_spec.rb'
- 'spec/features/admin/variant_overrides_spec.rb'
- 'spec/features/admin/variants_spec.rb'
- 'spec/features/consumer/shopping/checkout_spec.rb'
- 'spec/features/consumer/shopping/shopping_spec.rb'
- 'spec/features/consumer/shopping/variant_overrides_spec.rb'
# Offense count: 109
# Offense count: 15
Metrics/AbcSize:
Max: 36
# Offense count: 13
# Configuration parameters: CountComments, ExcludedMethods.
Metrics/BlockLength:
Max: 774
Max: 115
# Offense count: 2
# Configuration parameters: CountComments.
Metrics/ClassLength:
Max: 169
# Offense count: 1
Metrics/CyclomaticComplexity:
Max: 8
# Offense count: 8
# Configuration parameters: CountComments.
Metrics/MethodLength:
Max: 31
# Offense count: 2
# Configuration parameters: CountComments.
Metrics/ModuleLength:
Max: 208
# Offense count: 2
Metrics/PerceivedComplexity:
Max: 11
# Offense count: 7
Naming/AccessorMethodName:
@@ -160,7 +176,7 @@ Naming/PredicateName:
- 'lib/open_food_network/packing_report.rb'
- 'lib/tasks/data.rake'
# Offense count: 12
# Offense count: 11
# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
# AllowedNames: io, id, to, by, on, in, at
Naming/UncommunicativeMethodParamName:
@@ -288,13 +304,12 @@ Style/CaseEquality:
- 'app/helpers/angular_form_helper.rb'
- 'spec/models/spree/payment_spec.rb'
# Offense count: 79
# Offense count: 78
# Cop supports --auto-correct.
# Configuration parameters: AutoCorrect, EnforcedStyle.
# SupportedStyles: nested, compact
Style/ClassAndModuleChildren:
Exclude:
- 'app/controllers/spree/store_controller_decorator.rb'
- 'app/helpers/angular_form_helper.rb'
- 'app/models/calculator/flat_percent_per_item.rb'
- 'app/models/spree/concerns/payment_method_distributors.rb'
@@ -379,11 +394,27 @@ Style/CommentedKeyword:
Exclude:
- 'app/controllers/application_controller.rb'
# Offense count: 4
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SingleLineConditionsOnly, IncludeTernaryExpressions.
# SupportedStyles: assign_to_condition, assign_inside_condition
Style/ConditionalAssignment:
Exclude:
- 'app/controllers/spree/api/products_controller.rb'
- 'app/controllers/spree/api/taxons_controller.rb'
- 'app/controllers/spree/api/variants_controller.rb'
# Offense count: 2
Style/DateTime:
Exclude:
- 'lib/open_food_network/users_and_enterprises_report.rb'
# Offense count: 1
# Cop supports --auto-correct.
Style/EachWithObject:
Exclude:
- 'app/controllers/spree/api/base_controller.rb'
# Offense count: 5
# Configuration parameters: EnforcedStyle.
# SupportedStyles: annotated, template, unannotated
@@ -393,7 +424,7 @@ Style/FormatStringToken:
- 'lib/open_food_network/sales_tax_report.rb'
- 'spec/models/enterprise_spec.rb'
# Offense count: 69
# Offense count: 68
# Configuration parameters: MinBodyLength.
Style/GuardClause:
Exclude:
@@ -410,7 +441,9 @@ Style/GuardClause:
- 'app/controllers/spree/admin/products_controller_decorator.rb'
- 'app/controllers/spree/admin/resource_controller_decorator.rb'
- 'app/controllers/spree/admin/variants_controller_decorator.rb'
- 'app/controllers/spree/orders_controller_decorator.rb'
- 'app/controllers/spree/api/base_controller.rb'
- 'app/controllers/spree/checkout_controller.rb'
- 'app/controllers/spree/orders_controller.rb'
- 'app/controllers/spree/paypal_controller_decorator.rb'
- 'app/jobs/products_cache_integrity_checker_job.rb'
- 'app/models/enterprise.rb'
@@ -434,12 +467,23 @@ Style/GuardClause:
- 'spec/support/request/distribution_helper.rb'
- 'spec/support/request/shop_workflow.rb'
# Offense count: 3
# Offense count: 6
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, UseHashRocketsWithSymbolValues, PreferHashRocketsForNonAlnumEndingSymbols.
# SupportedStyles: ruby19, hash_rockets, no_mixed_keys, ruby19_no_mixed_keys
Style/HashSyntax:
Exclude:
- 'app/controllers/spree/api/base_controller.rb'
- 'app/controllers/spree/checkout_controller.rb'
- 'app/controllers/spree/orders_controller.rb'
# Offense count: 4
Style/IfInsideElse:
Exclude:
- 'app/controllers/admin/column_preferences_controller.rb'
- 'app/controllers/admin/variant_overrides_controller.rb'
- 'app/controllers/spree/admin/products_controller_decorator.rb'
- 'app/controllers/spree/api/taxons_controller.rb'
# Offense count: 1
Style/MissingRespondToMissing:
@@ -492,9 +536,10 @@ Style/RegexpLiteral:
- 'spec/mailers/subscription_mailer_spec.rb'
- 'spec/models/content_configuration_spec.rb'
# Offense count: 243
# Offense count: 244
Style/Send:
Exclude:
- 'app/controllers/spree/checkout_controller.rb'
- 'app/models/spree/shipping_method_decorator.rb'
- 'spec/controllers/admin/subscriptions_controller_spec.rb'
- 'spec/controllers/checkout_controller_spec.rb'
@@ -541,3 +586,9 @@ Style/Send:
Style/StructInheritance:
Exclude:
- 'lib/open_food_network/enterprise_fee_applicator.rb'
# Offense count: 1
# Cop supports --auto-correct.
Style/UnlessElse:
Exclude:
- 'app/controllers/spree/api/variants_controller.rb'

View File

@@ -42,6 +42,6 @@ $ docker-compose up
```
This command will setup the database and seed it with sample data. The default admin user is 'ofn@example.com' with 'ofn123' password.
Check the app in the browser at `http:://localhost:3000`.
Check the app in the browser at `http://localhost:3000`.
You will then get the trace of the containers in the terminal. You can stop the containers using Ctrl-C in the terminal.

11
Gemfile
View File

@@ -24,7 +24,6 @@ gem 'spree_api', github: 'openfoodfoundation/spree', branch: '2-0-4-stable'
gem 'spree_backend', github: 'openfoodfoundation/spree', branch: '2-0-4-stable'
gem 'spree_core', github: 'openfoodfoundation/spree', branch: '2-0-4-stable'
gem 'spree_auth_devise', github: 'spree/spree_auth_devise', branch: '2-0-stable'
gem 'spree_i18n', github: 'spree/spree_i18n', branch: '1-3-stable'
# Our branch contains two changes
@@ -37,6 +36,8 @@ gem 'stripe'
# which is needed for Pin Payments (and possibly others).
gem 'activemerchant', '~> 1.78'
gem 'devise', '~> 2.2.5'
gem 'devise-encryptable', '0.2.0'
gem 'jwt', '~> 2.2'
gem 'oauth2', '~> 1.4.1' # Used for Stripe Connect
@@ -48,6 +49,10 @@ gem 'delayed_job_web'
# When merged, revert to upstream gem
gem 'simple_form', github: 'RohanM/simple_form'
# 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 'andand'
gem 'angularjs-rails', '1.5.5'
gem 'aws-sdk'
@@ -118,6 +123,10 @@ gem 'jquery-rails', '3.0.4'
gem 'ofn-qz', github: 'openfoodfoundation/ofn-qz', ref: '60da2ae4c44cbb4c8d602f59fb5fff8d0f21db3c'
group :production, :staging do
gem 'ddtrace'
end
group :test, :development do
# Pretty printed test output
gem 'atomic'

View File

@@ -31,7 +31,7 @@ GIT
GIT
remote: https://github.com/openfoodfoundation/spree.git
revision: 46d6f8f5fd434105b0c69958276d1727a3066a97
revision: 8a8585a43cd04d1a50dc65227f337a91b18d66d5
branch: 2-0-4-stable
specs:
spree_api (2.0.4)
@@ -66,26 +66,6 @@ GIT
state_machine (= 1.2.0)
stringex (~> 1.5.1)
truncate_html (= 0.9.2)
spree_frontend (2.0.4)
canonical-rails
deface (>= 0.9.0)
jquery-rails (~> 3.0.0)
rails (~> 3.2.13)
spree_api (= 2.0.4)
spree_core (= 2.0.4)
stringex (~> 1.5.1)
GIT
remote: https://github.com/spree/spree_auth_devise.git
revision: 0181835fb6ac77a05191d26f6f32a0f4a548d851
branch: 2-0-stable
specs:
spree_auth_devise (2.0.0)
devise (~> 2.2.5)
devise-encryptable (= 0.1.2)
spree_backend (~> 2.0.0)
spree_core (~> 2.0.0)
spree_frontend (~> 2.0.0)
GIT
remote: https://github.com/spree/spree_i18n.git
@@ -180,7 +160,7 @@ GEM
json (~> 1.4)
nokogiri (>= 1.4.4)
uuidtools (~> 2.1)
bcrypt (3.1.11)
bcrypt (3.1.13)
bcrypt-ruby (3.1.5)
bcrypt (>= 3.1.3)
blockenspiel (0.5.0)
@@ -189,8 +169,6 @@ GEM
builder (3.0.4)
byebug (9.0.6)
cancan (1.6.10)
canonical-rails (0.1.0)
rails (>= 3.1, < 5.1)
capybara (2.18.0)
addressable
mini_mime (>= 0.1.3)
@@ -245,16 +223,18 @@ GEM
activerecord (>= 3.2.0, < 5.0)
fog (~> 1.0)
rails (>= 3.2.0, < 5.0)
ddtrace (0.26.0)
msgpack
debugger-linecache (1.2.0)
deface (1.0.2)
colorize (>= 0.5.8)
nokogiri (~> 1.6.0)
polyglot
rails (>= 3.1)
delayed_job (4.1.5)
activesupport (>= 3.0, < 5.3)
delayed_job_active_record (4.1.3)
activerecord (>= 3.0, < 5.3)
delayed_job (4.1.8)
activesupport (>= 3.0, < 6.1)
delayed_job_active_record (4.1.4)
activerecord (>= 3.0, < 6.1)
delayed_job (>= 3.0, < 5)
delayed_job_web (1.4.3)
activerecord (> 3.0.0)
@@ -266,7 +246,7 @@ GEM
orm_adapter (~> 0.1)
railties (~> 3.1)
warden (~> 1.2.1)
devise-encryptable (0.1.2)
devise-encryptable (0.2.0)
devise (>= 2.1.0)
diff-lcs (1.3)
diffy (3.3.0)
@@ -476,7 +456,7 @@ GEM
rspec (>= 2.99.0, < 4.0)
haml (4.0.7)
tilt
hashdiff (0.4.0)
hashdiff (1.0.0)
highline (1.6.18)
hike (1.2.3)
http_parser.rb (0.6.0)
@@ -505,7 +485,7 @@ GEM
actionpack (>= 3.0.0)
activesupport (>= 3.0.0)
kgio (2.11.2)
knapsack (1.17.2)
knapsack (1.18.0)
rake
launchy (2.4.3)
addressable (~> 2.3)
@@ -527,11 +507,12 @@ GEM
railties (>= 3.1)
money (5.1.1)
i18n (~> 0.6.0)
msgpack (1.3.1)
multi_json (1.13.1)
multi_xml (0.6.0)
multipart-post (2.1.1)
nenv (0.3.0)
net-http-persistent (3.0.1)
net-http-persistent (3.1.0)
connection_pool (~> 2.2)
newrelic_rpm (3.18.1.330)
nokogiri (1.6.8.1)
@@ -577,7 +558,7 @@ GEM
pry-byebug (3.4.3)
byebug (>= 9.0, < 9.1)
pry (~> 0.10)
public_suffix (3.0.3)
public_suffix (3.1.1)
rabl (0.8.4)
activesupport (>= 2.3.14)
rack (1.4.7)
@@ -613,7 +594,7 @@ GEM
thor (>= 0.14.6, < 2.0)
rainbow (3.0.0)
raindrops (0.19.0)
rake (12.3.2)
rake (12.3.3)
ransack (0.7.2)
actionpack (~> 3.0)
activerecord (~> 3.0)
@@ -628,7 +609,7 @@ GEM
trollop (~> 2.1)
rdoc (3.12.2)
json (~> 1.4)
redcarpet (3.4.0)
redcarpet (3.5.0)
ref (2.0.0)
request_store (1.4.1)
rack (>= 1.4)
@@ -720,7 +701,7 @@ GEM
tilt (~> 1.1, != 1.3.0)
state_machine (1.2.0)
stringex (1.5.1)
stripe (4.19.0)
stripe (4.24.0)
faraday (~> 0.13)
net-http-persistent (~> 3.0)
therubyracer (0.12.0)
@@ -758,7 +739,7 @@ GEM
nokogiri (~> 1.6)
rubyzip (~> 1.0)
selenium-webdriver (~> 3.0)
webmock (3.6.0)
webmock (3.6.2)
addressable (>= 2.3.6)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
@@ -797,10 +778,13 @@ DEPENDENCIES
dalli
database_cleaner (= 0.7.1)
db2fog
ddtrace
debugger-linecache
deface (= 1.0.2)
delayed_job_active_record
delayed_job_web
devise (~> 2.2.5)
devise-encryptable (= 0.2.0)
diffy
eventmachine (>= 1.2.3)
factory_bot_rails
@@ -824,6 +808,7 @@ DEPENDENCIES
jquery-rails (= 3.0.4)
json_spec (~> 1.1.4)
jwt (~> 2.2)
kaminari (~> 0.14.1)
knapsack
letter_opener (>= 1.4.1)
listen (= 3.0.8)
@@ -861,7 +846,6 @@ DEPENDENCIES
skylight (< 2.0)
spinjs-rails
spree_api!
spree_auth_devise!
spree_backend!
spree_core!
spree_i18n!

View File

@@ -15,7 +15,6 @@
//= require angular-animate
//= require angular-sanitize
//= require admin/spree_backend
//= require admin/spree_auth
//= require admin/spree_paypal_express
//= require ../shared/ng-infinite-scroll.min.js
//= require ../shared/ng-tags-input.min.js

View File

@@ -1,267 +1,287 @@
angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout, $http, $window, BulkProducts, DisplayProperties, dataFetcher, DirtyProducts, VariantUnitManager, StatusMessage, producers, Taxons, SpreeApiAuth, Columns, tax_categories) ->
$scope.loading = true
$scope.loadingAllPages = true
angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout, $filter, $http, $window, BulkProducts, DisplayProperties, DirtyProducts, VariantUnitManager, StatusMessage, producers, Taxons, SpreeApiAuth, Columns, tax_categories, RequestMonitor) ->
$scope.StatusMessage = StatusMessage
$scope.StatusMessage = StatusMessage
$scope.columns = Columns.columns
$scope.columns = Columns.columns
$scope.variant_unit_options = VariantUnitManager.variantUnitOptions()
$scope.variant_unit_options = VariantUnitManager.variantUnitOptions()
$scope.RequestMonitor = RequestMonitor
$scope.pagination = BulkProducts.pagination
$scope.per_page_options = [
{id: 15, name: t('js.admin.orders.index.per_page', results: 15)},
{id: 50, name: t('js.admin.orders.index.per_page', results: 50)},
{id: 100, name: t('js.admin.orders.index.per_page', results: 100)}
]
$scope.filterableColumns = [
{ name: t("label_producers"), db_column: "producer_name" },
{ name: t("name"), db_column: "name" }
]
$scope.filterableColumns = [
{ name: t("label_producers"), db_column: "producer_name" },
{ name: t("name"), db_column: "name" }
]
$scope.filterTypes = [
{ name: t("equals"), predicate: "eq" },
{ name: t("contains"), predicate: "cont" }
]
$scope.filterTypes = [
{ name: t("equals"), predicate: "eq" },
{ name: t("contains"), predicate: "cont" }
]
$scope.optionTabs =
filters: { title: t("filter_products"), visible: false }
$scope.optionTabs =
filters: { title: t("filter_products"), visible: false }
$scope.producers = producers
$scope.taxons = Taxons.all
$scope.tax_categories = tax_categories
$scope.producerFilter = ""
$scope.categoryFilter = ""
$scope.importDateFilter = ""
$scope.page = 1
$scope.per_page = 15
$scope.products = BulkProducts.products
$scope.query = ""
$scope.DisplayProperties = DisplayProperties
$scope.initialise = ->
SpreeApiAuth.authorise()
.then ->
$scope.spree_api_key_ok = true
$scope.fetchProducts()
.catch (message) ->
$scope.api_error_msg = message
$scope.$watchCollection '[query, producerFilter, categoryFilter, importDateFilter, per_page]', ->
$scope.page = 1 # Reset page when changing filters for new search
$scope.changePage = (newPage) ->
$scope.page = newPage
$scope.fetchProducts()
$scope.fetchProducts = ->
removeClearedValues()
params = {
'q[name_cont]': $scope.query,
'q[supplier_id_eq]': $scope.producerFilter,
'q[primary_taxon_id_eq]': $scope.categoryFilter,
import_date: $scope.importDateFilter,
page: $scope.page,
per_page: $scope.per_page
}
RequestMonitor.load(BulkProducts.fetch(params).$promise).then ->
$scope.resetProducts()
removeClearedValues = ->
delete $scope.producerFilter if $scope.producerFilter == "0"
delete $scope.categoryFilter if $scope.categoryFilter == "0"
delete $scope.importDateFilter if $scope.importDateFilter == "0"
$timeout ->
if $scope.showLatestImport
$scope.importDateFilter = $scope.importDates[1].id
$scope.resetProducts = ->
DirtyProducts.clear()
StatusMessage.clear()
$scope.updateOnHand = (product) ->
on_demand_variants = []
if product.variants
on_demand_variants = (variant for id, variant of product.variants when variant.on_demand)
unless product.on_demand || on_demand_variants.length > 0
product.on_hand = $scope.onHand(product)
$scope.producers = producers
$scope.taxons = Taxons.all
$scope.tax_categories = tax_categories
$scope.filterProducers = [{id: "0", name: ""}].concat $scope.producers
$scope.filterTaxons = [{id: "0", name: ""}].concat $scope.taxons
$scope.onHand = (product) ->
onHand = 0
if product.hasOwnProperty("variants") and product.variants instanceof Object
for id, variant of product.variants
onHand = onHand + parseInt(if variant.on_hand > 0 then variant.on_hand else 0)
else
onHand = "error"
onHand
$scope.shiftTab = (tab) ->
$scope.visibleTab.visible = false unless $scope.visibleTab == tab || $scope.visibleTab == undefined
tab.visible = !tab.visible
$scope.visibleTab = tab
$scope.resetSelectFilters = ->
$scope.query = ""
$scope.producerFilter = "0"
$scope.categoryFilter = "0"
$scope.importDateFilter = "0"
$scope.products = BulkProducts.products
$scope.filteredProducts = []
$scope.currentFilters = []
$scope.limit = 15
$scope.query = ""
$scope.DisplayProperties = DisplayProperties
$scope.initialise = ->
SpreeApiAuth.authorise()
.then ->
$scope.spree_api_key_ok = true
$scope.fetchProducts()
.catch (message) ->
$scope.api_error_msg = message
$scope.$watchCollection '[query, producerFilter, categoryFilter, importDateFilter]', ->
$scope.limit = 15 # Reset limit whenever searching
$scope.fetchProducts = ->
$scope.loading = true
$scope.loadingAllPages = true
BulkProducts.fetch($scope.currentFilters, ->
$scope.loadingAllPages = false
).then ->
$scope.resetProducts()
$scope.loading = false
$timeout ->
if $scope.showLatestImport
$scope.importDateFilter = $scope.importDates[1].id
$scope.resetProducts = ->
DirtyProducts.clear()
StatusMessage.clear()
$scope.updateOnHand = (product) ->
on_demand_variants = []
if product.variants
on_demand_variants = (variant for id, variant of product.variants when variant.on_demand)
unless product.on_demand || on_demand_variants.length > 0
product.on_hand = $scope.onHand(product)
$scope.editWarn = (product, variant) ->
if (DirtyProducts.count() > 0 and confirm(t("unsaved_changes_confirmation"))) or (DirtyProducts.count() == 0)
window.location = "/admin/products/" + product.permalink_live + ((if variant then "/variants/" + variant.id else "")) + "/edit"
$scope.onHand = (product) ->
onHand = 0
if product.hasOwnProperty("variants") and product.variants instanceof Object
for id, variant of product.variants
onHand = onHand + parseInt(if variant.on_hand > 0 then variant.on_hand else 0)
else
onHand = "error"
onHand
$scope.toggleShowAllVariants = ->
showVariants = !DisplayProperties.showVariants 0
$scope.products.forEach (product) ->
DisplayProperties.setShowVariants product.id, showVariants
DisplayProperties.setShowVariants 0, showVariants
$scope.shiftTab = (tab) ->
$scope.visibleTab.visible = false unless $scope.visibleTab == tab || $scope.visibleTab == undefined
tab.visible = !tab.visible
$scope.visibleTab = tab
$scope.resetSelectFilters = ->
$scope.query = ""
$scope.producerFilter = "0"
$scope.categoryFilter = "0"
$scope.importDateFilter = "0"
$scope.editWarn = (product, variant) ->
if (DirtyProducts.count() > 0 and confirm(t("unsaved_changes_confirmation"))) or (DirtyProducts.count() == 0)
window.location = "/admin/products/" + product.permalink_live + ((if variant then "/variants/" + variant.id else "")) + "/edit"
$scope.addVariant = (product) ->
product.variants.push
id: $scope.nextVariantId()
unit_value: null
unit_description: null
on_demand: false
display_as: null
display_name: null
on_hand: null
price: null
DisplayProperties.setShowVariants product.id, true
$scope.toggleShowAllVariants = ->
showVariants = !DisplayProperties.showVariants 0
$scope.filteredProducts.forEach (product) ->
DisplayProperties.setShowVariants product.id, showVariants
DisplayProperties.setShowVariants 0, showVariants
$scope.nextVariantId = ->
$scope.variantIdCounter = 0 unless $scope.variantIdCounter?
$scope.variantIdCounter -= 1
$scope.variantIdCounter
$scope.addVariant = (product) ->
product.variants.push
id: $scope.nextVariantId()
unit_value: null
unit_description: null
on_demand: false
display_as: null
display_name: null
on_hand: null
price: null
DisplayProperties.setShowVariants product.id, true
$scope.nextVariantId = ->
$scope.variantIdCounter = 0 unless $scope.variantIdCounter?
$scope.variantIdCounter -= 1
$scope.variantIdCounter
$scope.deleteProduct = (product) ->
if confirm("Are you sure?")
$http(
method: "DELETE"
url: "/api/products/" + product.id + "/soft_delete"
).success (data) ->
$scope.products.splice $scope.products.indexOf(product), 1
DirtyProducts.deleteProduct product.id
$scope.displayDirtyProducts()
$scope.deleteVariant = (product, variant) ->
if product.variants.length > 1
if !$scope.variantSaved(variant)
$scope.removeVariant(product, variant)
else
if confirm(t("are_you_sure"))
$http(
method: "DELETE"
url: "/api/products/" + product.permalink_live + "/variants/" + variant.id + "/soft_delete"
).success (data) ->
$scope.removeVariant(product, variant)
else
alert(t("delete_product_variant"))
$scope.removeVariant = (product, variant) ->
product.variants.splice product.variants.indexOf(variant), 1
DirtyProducts.deleteVariant product.id, variant.id
$scope.displayDirtyProducts()
$scope.cloneProduct = (product) ->
BulkProducts.cloneProduct product
$scope.hasVariants = (product) ->
product.variants.length > 0
$scope.hasUnit = (product) ->
product.variant_unit_with_scale?
$scope.variantSaved = (variant) ->
variant.hasOwnProperty('id') && variant.id > 0
$scope.hasOnDemandVariants = (product) ->
(variant for id, variant of product.variants when variant.on_demand).length > 0
$scope.submitProducts = ->
# Pack pack $scope.products, so they will match the list returned from the server,
# then pack $scope.dirtyProducts, ensuring that the correct product info is sent to the server.
$scope.packProduct product for id, product of $scope.products
$scope.packProduct product for id, product of DirtyProducts.all()
productsToSubmit = filterSubmitProducts(DirtyProducts.all())
if productsToSubmit.length > 0
$scope.updateProducts productsToSubmit # Don't submit an empty list
else
StatusMessage.display 'alert', t("products_change")
$scope.updateProducts = (productsToSubmit) ->
$scope.displayUpdating()
$scope.deleteProduct = (product) ->
if confirm("Are you sure?")
$http(
method: "POST"
url: "/admin/products/bulk_update"
data:
products: productsToSubmit
filters: $scope.currentFilters
).success((data) ->
DirtyProducts.clear()
BulkProducts.updateVariantLists(data.products || [])
$timeout -> $scope.displaySuccess()
).error (data, status) ->
if status == 400 && data.errors? && data.errors.length > 0
errors = error + "\n" for error in data.errors
alert t("products_update_error") + "\n" + errors
$scope.displayFailure t("products_update_error")
else
$scope.displayFailure t("products_update_error_data") + status
method: "DELETE"
url: "/api/products/" + product.id + "/soft_delete"
).success (data) ->
$scope.products.splice $scope.products.indexOf(product), 1
DirtyProducts.deleteProduct product.id
$scope.displayDirtyProducts()
$scope.cancel = (destination) ->
$window.location = destination
$scope.packProduct = (product) ->
if product.variant_unit_with_scale
match = product.variant_unit_with_scale.match(/^([^_]+)_([\d\.]+)$/)
if match
product.variant_unit = match[1]
product.variant_unit_scale = parseFloat(match[2])
else
product.variant_unit = product.variant_unit_with_scale
product.variant_unit_scale = null
$scope.deleteVariant = (product, variant) ->
if product.variants.length > 1
if !$scope.variantSaved(variant)
$scope.removeVariant(product, variant)
else
product.variant_unit = product.variant_unit_scale = null
if confirm(t("are_you_sure"))
$http(
method: "DELETE"
url: "/api/products/" + product.permalink_live + "/variants/" + variant.id + "/soft_delete"
).success (data) ->
$scope.removeVariant(product, variant)
else
alert(t("delete_product_variant"))
$scope.packVariant product, product.master if product.master
if product.variants
for id, variant of product.variants
$scope.packVariant product, variant
$scope.removeVariant = (product, variant) ->
product.variants.splice product.variants.indexOf(variant), 1
DirtyProducts.deleteVariant product.id, variant.id
$scope.displayDirtyProducts()
$scope.packVariant = (product, variant) ->
if variant.hasOwnProperty("unit_value_with_description")
match = variant.unit_value_with_description.match(/^([\d\.]+(?= |$)|)( |)(.*)$/)
if match
product = BulkProducts.find product.id
variant.unit_value = parseFloat(match[1])
variant.unit_value = null if isNaN(variant.unit_value)
variant.unit_value *= product.variant_unit_scale if variant.unit_value && product.variant_unit_scale
variant.unit_description = match[3]
$scope.cloneProduct = (product) ->
BulkProducts.cloneProduct product
$scope.incrementLimit = ->
if $scope.limit < $scope.products.length
$scope.limit = $scope.limit + 5
$scope.hasVariants = (product) ->
product.variants.length > 0
$scope.displayUpdating = ->
StatusMessage.display 'progress', t("saving")
$scope.hasUnit = (product) ->
product.variant_unit_with_scale?
$scope.displaySuccess = ->
StatusMessage.display 'success',t("products_changes_saved")
$scope.bulk_product_form.$setPristine()
$scope.variantSaved = (variant) ->
variant.hasOwnProperty('id') && variant.id > 0
$scope.displayFailure = (failMessage) ->
StatusMessage.display 'failure', t("products_update_error_msg") + "#{failMessage}"
$scope.hasOnDemandVariants = (product) ->
(variant for id, variant of product.variants when variant.on_demand).length > 0
$scope.displayDirtyProducts = ->
count = DirtyProducts.count()
switch count
when 0 then StatusMessage.clear()
when 1 then StatusMessage.display 'notice', t("one_product_unsaved")
else StatusMessage.display 'notice', t("products_unsaved", n: count)
$scope.submitProducts = ->
# Pack pack $scope.products, so they will match the list returned from the server,
# then pack $scope.dirtyProducts, ensuring that the correct product info is sent to the server.
$scope.packProduct product for id, product of $scope.products
$scope.packProduct product for id, product of DirtyProducts.all()
productsToSubmit = filterSubmitProducts(DirtyProducts.all())
if productsToSubmit.length > 0
$scope.updateProducts productsToSubmit # Don't submit an empty list
else
StatusMessage.display 'alert', t("products_change")
$scope.updateProducts = (productsToSubmit) ->
$scope.displayUpdating()
$http(
method: "POST"
url: "/admin/products/bulk_update"
data:
products: productsToSubmit
filters:
'q[name_cont]': $scope.query
'q[supplier_id_eq]': $scope.producerFilter
'q[primary_taxon_id_eq]': $scope.categoryFilter
import_date: $scope.importDateFilter
page: $scope.page
per_page: $scope.per_page
).success((data) ->
DirtyProducts.clear()
BulkProducts.updateVariantLists(data.products || [])
$timeout -> $scope.displaySuccess()
).error (data, status) ->
if status == 400 && data.errors? && data.errors.length > 0
errors = error + "\n" for error in data.errors
alert t("products_update_error") + "\n" + errors
$scope.displayFailure t("products_update_error")
else
$scope.displayFailure t("products_update_error_data") + status
$scope.cancel = (destination) ->
$window.location = destination
$scope.packProduct = (product) ->
if product.variant_unit_with_scale
match = product.variant_unit_with_scale.match(/^([^_]+)_([\d\.]+)$/)
if match
product.variant_unit = match[1]
product.variant_unit_scale = parseFloat(match[2])
else
product.variant_unit = product.variant_unit_with_scale
product.variant_unit_scale = null
else
product.variant_unit = product.variant_unit_scale = null
$scope.packVariant product, product.master if product.master
if product.variants
for id, variant of product.variants
$scope.packVariant product, variant
$scope.packVariant = (product, variant) ->
if variant.hasOwnProperty("unit_value_with_description")
match = variant.unit_value_with_description.match(/^([\d\.]+(?= |$)|)( |)(.*)$/)
if match
product = BulkProducts.find product.id
variant.unit_value = parseFloat(match[1])
variant.unit_value = null if isNaN(variant.unit_value)
variant.unit_value *= product.variant_unit_scale if variant.unit_value && product.variant_unit_scale
variant.unit_description = match[3]
$scope.incrementLimit = ->
if $scope.limit < $scope.products.length
$scope.limit = $scope.limit + 5
$scope.displayUpdating = ->
StatusMessage.display 'progress', t("saving")
$scope.displaySuccess = ->
StatusMessage.display 'success',t("products_changes_saved")
$scope.bulk_product_form.$setPristine()
$scope.displayFailure = (failMessage) ->
StatusMessage.display 'failure', t("products_update_error_msg") + "#{failMessage}"
$scope.displayDirtyProducts = ->
count = DirtyProducts.count()
switch count
when 0 then StatusMessage.clear()
when 1 then StatusMessage.display 'notice', t("one_product_unsaved")
else StatusMessage.display 'notice', t("products_unsaved", n: count)
filterSubmitProducts = (productsToFilter) ->

View File

@@ -24,8 +24,3 @@ angular.module("admin.orders").controller "orderCtrl", ($scope, shops, orderCycl
for shop in $scope.shops
shop.disabled = !$scope.distributorHasOrderCycles(shop)
# Removes the split button introduced by spree in the order form
# We only have one stock location in OFN so it's meaningless to split the order between stock locations
# We delete it instead of hiding or changing CSS so that, when spree code toggles the element, nothing hapens
$('.split-item').remove()

View File

@@ -23,7 +23,7 @@ angular.module("admin.orders").controller "ordersCtrl", ($scope, RequestMonitor,
$scope.fetchResults = (page=1) ->
$scope.resetSelected()
Orders.index({
params = {
'q[completed_at_lt]': $scope['q']['completed_at_lt'],
'q[completed_at_gt]': $scope['q']['completed_at_gt'],
'q[state_eq]': $scope['q']['state_eq'],
@@ -39,7 +39,8 @@ angular.module("admin.orders").controller "ordersCtrl", ($scope, RequestMonitor,
'q[s]': $scope.sorting || 'completed_at desc',
per_page: $scope.per_page,
page: page
})
}
RequestMonitor.load(Orders.index(params).$promise)
$scope.resetSelected = ->
$scope.selected_orders.length = 0

View File

@@ -0,0 +1,19 @@
angular.module("admin.products").directive "setOnDemand", ->
link: (scope, element, attr) ->
onHand = element.context.querySelector("#variant_on_hand")
onDemand = element.context.querySelector("#variant_on_demand")
disableOnHandIfOnDemand = ->
if onDemand.checked
onHand.disabled = 'disabled'
onHand.dataStock = onHand.value
onHand.value = t('admin.products.variants.infinity')
disableOnHandIfOnDemand()
onDemand.addEventListener 'change', (event) ->
disableOnHandIfOnDemand()
if !onDemand.checked
onHand.removeAttribute('disabled')
onHand.value = onHand.dataStock

View File

@@ -0,0 +1,6 @@
angular.module("admin.resources").factory 'ProductResource', ($resource) ->
$resource('/admin/product/:id/:action.json', {}, {
'index':
url: '/api/products/bulk_products.json'
method: 'GET'
})

View File

@@ -1,15 +1,13 @@
angular.module("ofn.admin").factory "BulkProducts", (PagedFetcher, dataFetcher, $http) ->
angular.module("ofn.admin").factory "BulkProducts", (ProductResource, dataFetcher, $http) ->
new class BulkProducts
products: []
pagination: {}
fetch: (filters, onComplete) ->
queryString = filters.reduce (qs,f) ->
return qs + "q[#{f.property.db_column}_#{f.predicate.predicate}]=#{f.value};"
, ""
url = "/api/products/bulk_products?page=::page::;per_page=20;#{queryString}"
processData = (data) => @addProducts data.products
PagedFetcher.fetch url, processData, onComplete
fetch: (params) ->
ProductResource.index params, (data) =>
@products.length = 0
@addProducts data.products
angular.extend(@pagination, data.pagination)
cloneProduct: (product) ->
$http.post("/api/products/" + product.id + "/clone").success (data) =>

View File

@@ -5,7 +5,7 @@ angular.module("admin.subscriptions").controller "OrderUpdateIssuesController",
OrderCycles.byID[id].name
$scope.orderCycleCloses = (id) ->
closes_at = moment(OrderCycles.byID[id].orders_close_at)
closes_at = moment(OrderCycles.byID[id].orders_close_at, "YYYY-MM-DD HH:mm:SS Z")
key = if closes_at > moment() then "closes" else "closed"
text = t("js.subscriptions." + key)
"#{text} #{closes_at.fromNow()}"

View File

@@ -15,7 +15,7 @@ angular.module("admin.subscriptions").controller "OrdersPanelController", ($scop
$scope.orderCycleCloses = (id) ->
oc = OrderCycles.byID[id]
return t('js.subscriptions.close_date_not_set') unless oc?.orders_close_at?
closes_at = moment(oc.orders_close_at)
closes_at = moment(oc.orders_close_at, "YYYY-MM-DD HH:mm:SS Z")
text = if closes_at > moment() then t('js.subscriptions.closes') else t('js.subscriptions.closed')
"#{text} #{closes_at.fromNow()}"

View File

@@ -27,8 +27,6 @@ angular.module("admin.utils").directive "variantAutocomplete", ($timeout) ->
window.variants = data # this is how spree auto complete JS code picks up variants
results: data
formatResult: (variant) ->
if variant["images"][0] != undefined && variant["images"][0].image != undefined
variant.image = variant.images[0].image.mini_url
variantTemplate variant: variant
formatSelection: (variant) ->
element.parent().children(".options_placeholder").html variant.options_text

View File

@@ -0,0 +1,11 @@
Darkswarm.controller "OffcanvasCtrl", ($scope) ->
$scope.menu = $(".left-off-canvas-menu")
$scope.setOffcanvasMenuHeight = ->
$scope.menu.height($(window).height())
$scope.bind = ->
$(window).on("resize", $scope.setOffcanvasMenuHeight)
$scope.setOffcanvasMenuHeight()
$scope.bind()

View File

@@ -1,8 +0,0 @@
Darkswarm.directive "cart", ->
# Toggles visibility of the "cart" popover
restrict: 'A'
link: (scope, elem, attr)->
scope.open = false
elem.bind 'click', ->
scope.$apply ->
scope.open = !scope.open

View File

@@ -0,0 +1,19 @@
Darkswarm.directive "cartToggle", ($document) ->
# Toggles visibility of the "cart" popover
restrict: 'A'
link: (scope, elem, attr)->
scope.open = false
$document.bind 'click', (event) ->
cart_button = elem[0]
element_and_parents = [event.target, event.target.parentElement, event.target.parentElement.parentElement]
cart_button_clicked = (element_and_parents.indexOf(cart_button) != -1)
if cart_button_clicked
scope.$apply ->
scope.open = !scope.open
else
scope.$apply ->
scope.open = false
return

View File

@@ -2,7 +2,14 @@ Darkswarm.directive "ofnPageAlert", ($timeout) ->
restrict: 'A'
scope: true
link: (scope, elem, attrs) ->
container_elems = $(".off-canvas-wrap .inner-wrap, .off-canvas-wrap .inner-wrap .fixed, .page-alert")
moveSelectors = [".off-canvas-wrap .inner-wrap",
".off-canvas-wrap .inner-wrap .fixed",
".off-canvas-fixed .top-bar",
".off-canvas-fixed ofn-flash",
".off-canvas-fixed nav.tab-bar",
".off-canvas-fixed .page-alert"]
container_elems = $(moveSelectors.join(", "))
# Wait a moment after page load before showing the alert. Otherwise we often miss the
# start of the animation.

View File

@@ -1,10 +1,15 @@
@API_DATETIME_FORMAT = "YYYY-MM-DD HH:mm:SS Z"
Darkswarm.filter "date_in_words", ->
(date) ->
moment(date).fromNow()
(date, dateFormat) ->
dateFormat ?= @API_DATETIME_FORMAT
moment(date, dateFormat).fromNow()
Darkswarm.filter "sensible_timeframe", (date_in_wordsFilter)->
(date) ->
if moment().add(2, 'days') < moment(date)
(date, dateFormat) ->
dateFormat ?= @API_DATETIME_FORMAT
if moment().add(2, 'days') < moment(date, dateFormat)
t 'orders_open'
else
t('closing') + date_in_wordsFilter(date)

View File

@@ -5,12 +5,10 @@
*
*= require admin/spree_backend
*= require admin/spree_auth
*= require jquery-ui-timepicker-addon
*= require shared/textAngular
*= require shared/ng-tags-input.min
*= require admin/custom
*= require_self
*/

View File

@@ -1,2 +1 @@
/* Custom fix */
.ui-timepicker-div.ui-timepicker-oneLine dl dd { width: 25%; }

View File

@@ -0,0 +1,11 @@
.add-line-item {
fieldset {
.vertical-align-top {
vertical-align: top;
}
.actions {
padding-top: 18px;
}
}
}

View File

@@ -3,7 +3,7 @@
.select2-container {
.select2-choice {
.select2-search-choice-close {
display: none;
display: none !important;
}
.select2-arrow {
width: 22px;

View File

@@ -10,6 +10,7 @@
@import 'foundation-icons';
@import 'base/*';
@import 'layout/*';
@import '*';
@import 'pages/*';
@import '../web/all';

View File

@@ -35,5 +35,6 @@ $med-grey: #666;
$med-drk-grey: #444;
$dark-grey: #333;
$light-grey: #ddd;
$light-grey-transparency: rgba(0, 0, 0, .1);
$black: #000;
$white: #fff;

View File

@@ -0,0 +1,17 @@
@import "compass/css3/transition";
.off-canvas-fixed {
@include transition(transform 1000ms ease-in-out);
}
.move-right > .off-canvas-fixed {
height: 100%;
-webkit-transform: translate3d(15.625rem, 0, 0);
transform: translate3d(15.625rem, 0, 0);
}
.left-off-canvas-menu {
-webkit-transform: none;
transform: none;
margin-left: -15.625rem;
}

View File

@@ -1,8 +1,8 @@
@import "compass";
@import "branding";
@import "mixins";
@import "typography";
@import "variables";
@import 'compass';
@import 'branding';
@import 'mixins';
@import 'typography';
@import 'variables';
nav.top-bar {
@include textpress;
@@ -42,6 +42,8 @@ nav.top-bar {
}
.top-bar-section {
border-bottom: 1px solid $light-grey-transparency;
a.icon {
&:hover {
text-decoration: none;
@@ -168,12 +170,18 @@ nav.top-bar {
.tab-bar {
background-color: white;
border-bottom: 1px solid $light-grey-transparency;
height: 2.8em;
position: fixed;
width: 100%;
z-index: 1;
.cart-span {
background-color: #f4704c;
padding: 13px;
a, span {
a,
span {
color: white;
display: inline-block;
}
@@ -202,7 +210,6 @@ nav.top-bar {
}
}
.off-canvas-list li.language-switcher ul li {
list-style-type: none;
padding-left: 0.5em;
@@ -228,10 +235,19 @@ nav.top-bar {
padding: 9px 0 0 9px;
}
// Leave space for tab bar, in screens smaller than large.
[role="main"] {
margin-top: 2.8em;
@media #{$large-up} {
margin-top: 0;
}
}
.top-bar .ofn-logo img {
height: auto;
width: auto;
max-height: 51px;
max-height: 44px;
max-width: 250px;
}
@@ -239,7 +255,7 @@ nav.top-bar {
background-color: white;
}
.off-canvas-wrap.move-right ul.off-canvas-list {
.off-canvas-wrap ul.off-canvas-list {
font-size: 0.875rem;
.li-menu {
@@ -259,12 +275,10 @@ nav.top-bar {
background-color: transparent;
color: $brand-colour;
}
@include transition(all 0.3s ease-in-out);
}
}
.off-canvas-wrap.move-right ul.off-canvas-list i {
.off-canvas-wrap ul.off-canvas-list i {
font-size: 1.5rem;
margin-right: 0.25rem;
}
@@ -273,7 +287,8 @@ nav.top-bar {
@media screen and (max-width: 1450px) {
nav .top-bar-section {
ul li a, .has-dropdown > a {
ul li a,
.has-dropdown > a {
padding: 0 ($topbar-height / 8) !important;
}

View File

@@ -2,10 +2,12 @@
@import "animations";
@import "compass/css3/transition";
$page-alert-height: 55px;
// Basic style \\
.page-alert {
.alert-box {
height: 55px;
height: $page-alert-height;
overflow: hidden;
border: 1px solid rgba($dark-grey, 0.35);
border-left: none;
@@ -45,33 +47,26 @@
}
// Show-hide animation \\
.off-canvas-wrap .inner-wrap, .off-canvas-wrap .inner-wrap .fixed, nav.tab-bar {
@include transition(all, 1000ms, ease-in-out);
.off-canvas-wrap .inner-wrap,
.off-canvas-fixed .top-bar,
.off-canvas-fixed ofn-flash,
.off-canvas-fixed nav.tab-bar,
.off-canvas-fixed .page-alert {
@include transition(all 1000ms ease-in-out);
&.move-down {
margin-top: 55px;
@include transition(all, 1000ms, ease-in-out);
margin-top: $page-alert-height;
}
}
.off-canvas-wrap .inner-wrap .page-alert.fixed {
top: -55px;
z-index: 1;
// TODO: Compass to disable transition
-moz-transition: none;
-webkit-transition: none;
-o-transition: color 0 ease-in;
transition: none;
.off-canvas-wrap .page-alert {
top: -1 * $page-alert-height;
z-index: 100;
}
.off-canvas-wrap.move-right .inner-wrap.move-down {
.page-alert {
top: -55px * 2;
}
.left-off-canvas-menu {
top: -55px;
top: -1 * $page-alert-height;
}
}

View File

@@ -1,6 +1,7 @@
@import "mixins";
@import "branding";
@import "compass/css3/user-interface";
@import 'variables';
.cart {
@include user-select(none);
@@ -15,8 +16,8 @@
.joyride-tip-guide {
display: block;
right: 10px;
top: 55px;
right: 0;
top: $topbar-height;
width: 480px;
@media screen and (min-width: 641px) {

View File

@@ -1,4 +1,5 @@
require 'open_food_network/permissions'
require 'open_food_network/proxy_order_syncer'
module Admin
class SubscriptionsController < ResourceController
@@ -32,21 +33,11 @@ module Admin
end
def create
form = SubscriptionForm.new(@subscription, params[:subscription])
if form.save
render_as_json @subscription
else
render json: { errors: form.json_errors }, status: :unprocessable_entity
end
save_form_and_render(false)
end
def update
form = SubscriptionForm.new(@subscription, params[:subscription])
if form.save
render_as_json @subscription, order_update_issues: form.order_update_issues
else
render json: { errors: form.json_errors }, status: :unprocessable_entity
end
save_form_and_render
end
def cancel
@@ -67,12 +58,26 @@ module Admin
end
def unpause
@subscription.update_attributes(paused_at: nil)
render_as_json @subscription
params[:subscription][:paused_at] = nil
save_form_and_render
end
private
def save_form_and_render(render_issues = true)
form = SubscriptionForm.new(@subscription, params[:subscription])
unless form.save
render json: { errors: form.json_errors }, status: :unprocessable_entity
return
end
if render_issues
render_as_json @subscription, order_update_issues: form.order_update_issues
else
render_as_json @subscription
end
end
def permissions
return @permissions unless @permissions.nil?
@permissions = OpenFoodNetwork::Permissions.new(spree_current_user)

View File

@@ -9,8 +9,8 @@ module Admin
def map_by_tag
respond_to do |format|
format.json do
serialiser = ActiveModel::ArraySerializer.new(collection)
render json: serialiser.to_json
serializer = ActiveModel::ArraySerializer.new(collection)
render json: serializer.to_json
end
end
end

View File

@@ -5,12 +5,7 @@ module Api
before_filter :override_sells, only: [:create, :update]
before_filter :override_visible, only: [:create, :update]
respond_to :json
skip_authorization_check only: [:shopfront, :managed]
def managed
@enterprises = Enterprise.ransack(params[:q]).result.managed_by(current_api_user)
render params[:template] || :bulk_index
end
skip_authorization_check only: [:shopfront]
def create
authorize! :create, Enterprise

View File

@@ -1,25 +0,0 @@
module Api
class OrderCyclesController < Spree::Api::BaseController
respond_to :json
def managed
authorize! :admin, OrderCycle
authorize! :read, OrderCycle
@order_cycles = OrderCycle.ransack(params[:q]).result.managed_by(current_api_user)
render params[:template] || :bulk_index
end
def accessible
@order_cycles = if params[:as] == "distributor"
OrderCycle.ransack(params[:q]).result.
involving_managed_distributors_of(current_api_user).order('updated_at DESC')
elsif params[:as] == "producer"
OrderCycle.ransack(params[:q]).result.
involving_managed_producers_of(current_api_user).order('updated_at DESC')
else
OrderCycle.ransack(params[:q]).result.accessible_by(current_api_user)
end
render params[:template] || :bulk_index
end
end
end

View File

@@ -1,5 +1,5 @@
module Api
class ProductImagesController < Spree::Api::BaseController
class ProductImagesController < BaseController
respond_to :json
def update_product_image
@@ -8,11 +8,11 @@ module Api
if @product.images.first.nil?
@image = Spree::Image.create(attachment: params[:file], viewable_id: @product.master.id, viewable_type: 'Spree::Variant')
respond_with(@image, status: 201)
render json: @image, serializer: ImageSerializer, status: :created
else
@image = @product.images.first
@image.update_attributes(attachment: params[:file])
respond_with(@image, status: 200)
render json: @image, serializer: ImageSerializer, status: :ok
end
end
end

View File

@@ -0,0 +1,143 @@
require 'open_food_network/permissions'
module Api
class ProductsController < Api::BaseController
respond_to :json
DEFAULT_PAGE = 1
DEFAULT_PER_PAGE = 15
skip_authorization_check only: [:show, :bulk_products, :overridable]
def show
@product = find_product(params[:id])
render json: @product, serializer: Api::Admin::ProductSerializer
end
def create
authorize! :create, Spree::Product
params[:product][:available_on] ||= Time.zone.now
@product = Spree::Product.new(params[:product])
begin
if @product.save
render json: @product, serializer: Api::Admin::ProductSerializer, status: 201
else
invalid_resource!(@product)
end
rescue ActiveRecord::RecordNotUnique
@product.permalink = nil
retry
end
end
def update
authorize! :update, Spree::Product
@product = find_product(params[:id])
if @product.update_attributes(params[:product])
render json: @product, serializer: Api::Admin::ProductSerializer, status: 200
else
invalid_resource!(@product)
end
end
def destroy
authorize! :delete, Spree::Product
@product = find_product(params[:id])
@product.update_attribute(:deleted_at, Time.zone.now)
@product.variants_including_master.update_all(deleted_at: Time.zone.now)
render json: @product, serializer: Api::Admin::ProductSerializer, status: 204
end
# TODO: This should be named 'managed'. Is the action above used? Maybe we should remove it.
def bulk_products
product_query = OpenFoodNetwork::Permissions.new(current_api_user).
editable_products.merge(product_scope)
if params[:import_date].present?
product_query = product_query.imported_on(params[:import_date]).group_by_products_id
end
@products = product_query.order('created_at DESC').
ransack(params[:q]).result.
page(params[:page] || DEFAULT_PAGE).per(params[:per_page] || DEFAULT_PER_PAGE)
render_paged_products @products
end
def overridable
producers = OpenFoodNetwork::Permissions.new(current_api_user).
variant_override_producers.by_name
@products = paged_products_for_producers producers
render_paged_products @products
end
def soft_delete
authorize! :delete, Spree::Product
@product = find_product(params[:product_id])
authorize! :delete, @product
@product.destroy
render json: @product, serializer: Api::Admin::ProductSerializer, status: 204
end
# POST /api/products/:product_id/clone
#
def clone
authorize! :create, Spree::Product
original_product = find_product(params[:product_id])
authorize! :update, original_product
@product = original_product.duplicate
render json: @product, serializer: Api::Admin::ProductSerializer, status: 201
end
private
# Copied and modified from SpreeApi::BaseController to allow
# enterprise users to access inactive products
def product_scope
# This line modified
if current_api_user.has_spree_role?("admin") || current_api_user.enterprises.present?
scope = Spree::Product
if params[:show_deleted]
scope = scope.with_deleted
end
else
scope = Spree::Product.active
end
scope.includes(:master)
end
def paged_products_for_producers(producers)
Spree::Product.scoped.
merge(product_scope).
where(supplier_id: producers).
by_producer.by_name.
ransack(params[:q]).result.
page(params[:page]).per(params[:per_page])
end
def render_paged_products(products)
serializer = ActiveModel::ArraySerializer.new(
products,
each_serializer: ::Api::Admin::ProductSerializer
)
render text: {
products: serializer,
pagination: pagination_data(products)
}.to_json
end
def pagination_data(results)
{
results: results.total_count,
pages: results.num_pages,
page: (params[:page] || DEFAULT_PAGE).to_i,
per_page: (params[:per_page] || DEFAULT_PER_PAGE).to_i
}
end
end
end

View File

@@ -0,0 +1,79 @@
module Api
class VariantsController < Api::BaseController
respond_to :json
skip_authorization_check only: [:index, :show]
before_filter :product
def index
@variants = scope.includes(:option_values).ransack(params[:q]).result
render json: @variants, each_serializer: Api::VariantSerializer
end
def show
@variant = scope.includes(:option_values).find(params[:id])
render json: @variant, serializer: Api::VariantSerializer
end
def create
authorize! :create, Spree::Variant
@variant = scope.new(params[:variant])
if @variant.save
render json: @variant, serializer: Api::VariantSerializer, status: 201
else
invalid_resource!(@variant)
end
end
def update
authorize! :update, Spree::Variant
@variant = scope.find(params[:id])
if @variant.update_attributes(params[:variant])
render json: @variant, serializer: Api::VariantSerializer, status: 200
else
invalid_resource!(@product)
end
end
def soft_delete
@variant = scope.find(params[:variant_id])
authorize! :delete, @variant
VariantDeleter.new.delete(@variant)
render json: @variant, serializer: Api::VariantSerializer, status: 204
end
def destroy
authorize! :delete, Spree::Variant
@variant = scope.find(params[:id])
@variant.destroy
render json: @variant, serializer: Api::VariantSerializer, status: 204
end
private
def product
@product ||= Spree::Product.find_by_permalink(params[:product_id]) if params[:product_id]
end
def scope
if @product
unless current_api_user.has_spree_role?("admin") || params[:show_deleted]
variants = @product.variants_including_master
else
variants = @product.variants_including_master.with_deleted
end
else
variants = Spree::Variant.scoped
if current_api_user.has_spree_role?("admin")
unless params[:show_deleted]
variants = Spree::Variant.active
end
else
variants = variants.active
end
end
variants
end
end
end

View File

@@ -1,4 +1,5 @@
require 'open_food_network/referer_parser'
require 'spree/authentication_helpers'
class ApplicationController < ActionController::Base
protect_from_forgery
@@ -7,6 +8,7 @@ class ApplicationController < ActionController::Base
before_filter :set_cache_headers # prevent cart emptying via cache when using back button #1213
include EnterprisesHelper
include Spree::AuthenticationHelpers
def redirect_to(options = {}, response_status = {})
::Rails.logger.error("Redirected by #{begin

View File

@@ -8,7 +8,6 @@ class CheckoutController < Spree::CheckoutController
prepend_before_filter :require_order_cycle
prepend_before_filter :require_distributor_chosen
skip_before_filter :check_registration
before_filter :enable_embedded_shopfront
include OrderCyclesHelper

View File

@@ -0,0 +1,6 @@
# For the API
ActionController::Metal.class_eval do
def spree_current_user
@spree_current_user ||= env['warden'].user
end
end

View File

@@ -27,12 +27,12 @@ class ShopController < BaseController
if oc = OrderCycle.with_distributor(@distributor).active.find_by_id(params[:order_cycle_id])
current_order(true).set_order_cycle! oc
@current_order_cycle = oc
render partial: "json/order_cycle"
render json: @current_order_cycle, serializer: Api::OrderCycleSerializer
else
render status: :not_found, json: ""
end
else
render partial: "json/order_cycle"
render json: current_order_cycle, serializer: Api::OrderCycleSerializer
end
end

View File

@@ -47,11 +47,21 @@ Spree::Admin::BaseController.class_eval do
end
end
protected
def model_class
const_name = controller_name.classify
if Spree.const_defined?(const_name)
return "Spree::#{const_name}".constantize
end
nil
end
private
def active_distributors_not_ready_for_checkout
ocs = OrderCycle.managed_by(spree_current_user).active
distributors = ocs.map(&:distributors).flatten.uniq
distributors = ocs.includes(:distributors).map(&:distributors).flatten.uniq
Enterprise.where('enterprises.id IN (?)', distributors).not_ready_for_checkout
end

View File

@@ -1,4 +1,5 @@
Spree::Admin::Orders::CustomerDetailsController.class_eval do
before_filter :check_authorization
before_filter :set_guest_checkout_status, only: :update
def update
@@ -25,6 +26,17 @@ Spree::Admin::Orders::CustomerDetailsController.class_eval do
private
def check_authorization
load_order
session[:access_token] ||= params[:token]
resource = @order
action = params[:action].to_sym
action = :edit if action == :show # show route renders :edit for this controller
authorize! action, resource, session[:access_token]
end
def set_guest_checkout_status
registered_user = Spree::User.find_by_email(params[:order][:email])

View File

@@ -1,5 +1,6 @@
require 'open_food_network/spree_api_key_loader'
require 'open_food_network/referer_parser'
require 'open_food_network/permissions'
Spree::Admin::ProductsController.class_eval do
include OpenFoodNetwork::SpreeApiKeyLoader
@@ -48,19 +49,13 @@ Spree::Admin::ProductsController.class_eval do
end
def bulk_update
collection_hash = Hash[params[:products].each_with_index.map { |p, i| [i, p] }]
product_set = Spree::ProductSet.new(collection_attributes: collection_hash)
params[:filters] ||= {}
bulk_index_query = params[:filters].reduce("") do |string, filter|
"#{string}q[#{filter[:property][:db_column]}_#{filter[:predicate][:predicate]}]=#{filter[:value]};"
end
product_set = product_set_from_params(params)
# Ensure we're authorised to update all products
product_set.collection.each { |p| authorize! :update, p }
if product_set.save
redirect_to "/api/products/bulk_products?page=1;per_page=500;#{bulk_index_query}"
redirect_to main_app.bulk_products_api_products_path( bulk_index_query(params) )
else
if product_set.errors.present?
render json: { errors: product_set.errors }, status: :bad_request
@@ -73,7 +68,8 @@ Spree::Admin::ProductsController.class_eval do
protected
def collection
# This method is copied directly from the spree product controller, except where we narrow the search below with the managed_by search to support
# This method is copied directly from the spree product controller
# except where we narrow the search below with the managed_by search to support
# enterprise users.
# TODO: There has to be a better way!!!
return @collection if @collection.present?
@@ -108,14 +104,32 @@ Spree::Admin::ProductsController.class_eval do
private
def product_set_from_params(params)
collection_hash = Hash[params[:products].each_with_index.map { |p, i| [i, p] }]
Spree::ProductSet.new(collection_attributes: collection_hash)
end
def bulk_index_query(params)
params[:filters].to_h.merge(page: params[:page], per_page: params[:per_page])
end
def load_form_data
@producers = OpenFoodNetwork::Permissions.new(spree_current_user).managed_product_enterprises.is_primary_producer.by_name
@producers = OpenFoodNetwork::Permissions.new(spree_current_user).
managed_product_enterprises.is_primary_producer.by_name
@taxons = Spree::Taxon.order(:name)
@import_dates = product_import_dates.uniq.to_json
end
def product_import_dates
import_dates = Spree::Variant.
options = [{ id: '0', name: '' }]
product_import_dates_query.collect(&:import_date).
map { |i| options.push(id: i.to_date, name: i.to_date.to_formatted_s(:long)) }
options
end
def product_import_dates_query
Spree::Variant.
select('DISTINCT spree_variants.import_date').
joins(:product).
where('spree_products.supplier_id IN (?)', editable_enterprises.collect(&:id)).
@@ -123,18 +137,14 @@ Spree::Admin::ProductsController.class_eval do
where(spree_variants: { is_master: false }).
where(spree_variants: { deleted_at: nil }).
order('spree_variants.import_date DESC')
options = [{ id: '0', name: '' }]
import_dates.collect(&:import_date).map { |i| options.push(id: i.to_date, name: i.to_date.to_formatted_s(:long)) }
options
end
def strip_new_properties
unless spree_current_user.admin? || params[:product][:product_properties_attributes].nil?
names = Spree::Property.pluck(:name)
params[:product][:product_properties_attributes].each do |key, property|
params[:product][:product_properties_attributes].delete key unless names.include? property[:property_name]
return if spree_current_user.admin? || params[:product][:product_properties_attributes].nil?
names = Spree::Property.pluck(:name)
params[:product][:product_properties_attributes].each do |key, property|
unless names.include? property[:property_name]
params[:product][:product_properties_attributes].delete key
end
end
end
@@ -149,12 +159,32 @@ Spree::Admin::ProductsController.class_eval do
end
def set_stock_levels(product, on_hand, on_demand)
variant = product.master
if product.variants.any?
variant = product.variants.first
variant = product_variant(product)
begin
variant.on_demand = on_demand if on_demand.present?
variant.on_hand = on_hand.to_i if on_hand.present?
rescue StandardError => error
notify_bugsnag(error, product, variant)
raise error
end
end
def notify_bugsnag(error, product, variant)
Bugsnag.notify(error) do |report|
report.add_tab(:product, product.attributes)
report.add_tab(:product_error, product.errors.first) unless product.valid?
report.add_tab(:variant, variant.attributes)
report.add_tab(:variant_error, variant.errors.first) unless variant.valid?
end
end
def product_variant(product)
if product.variants.any?
product.variants.first
else
product.master
end
variant.on_demand = on_demand if on_demand.present?
variant.on_hand = on_hand.to_i if on_hand.present?
end
def set_product_master_variant_price_to_zero

View File

@@ -14,3 +14,7 @@ module AuthorizeOnLoadResource
end
Spree::Admin::ResourceController.prepend(AuthorizeOnLoadResource)
Spree::Admin::ResourceController.class_eval do
rescue_from CanCan::AccessDenied, :with => :unauthorized
end

View File

@@ -0,0 +1,131 @@
module Spree
module Admin
class UsersController < ResourceController
rescue_from Spree::User::DestroyWithOrdersError, with: :user_destroy_with_orders_error
after_filter :sign_in_if_change_own_password, only: :update
# http://spreecommerce.com/blog/2010/11/02/json-hijacking-vulnerability/
before_filter :check_json_authenticity, only: :index
before_filter :load_roles, only: [:edit, :new, :update, :create,
:generate_api_key, :clear_api_key]
def index
respond_with(@collection) do |format|
format.html
format.json { render json: json_data }
end
end
def create
if params[:user]
roles = params[:user].delete("spree_role_ids")
end
@user = Spree::User.new(params[:user])
if @user.save
if roles
@user.spree_roles = roles.reject(&:blank?).collect{ |r| Spree::Role.find(r) }
end
flash.now[:success] = Spree.t(:created_successfully)
render :edit
else
render :new
end
end
def update
if params[:user]
roles = params[:user].delete("spree_role_ids")
end
if @user.update_attributes(params[:user])
if roles
@user.spree_roles = roles.reject(&:blank?).collect{ |r| Spree::Role.find(r) }
end
flash.now[:success] = Spree.t(:account_updated)
end
render :edit
end
def generate_api_key
if @user.generate_spree_api_key!
flash[:success] = Spree.t('api.key_generated')
end
redirect_to edit_admin_user_path(@user)
end
def clear_api_key
if @user.clear_spree_api_key!
flash[:success] = Spree.t('api.key_cleared')
end
redirect_to edit_admin_user_path(@user)
end
protected
def collection
return @collection if @collection.present?
if request.xhr? && params[:q].present?
# Disabling proper nested include here due to rails 3.1 bug
@collection = Spree::User.
includes(:bill_address, :ship_address).
where("spree_users.email #{LIKE} :search
OR (spree_addresses.firstname #{LIKE} :search
AND spree_addresses.id = spree_users.bill_address_id)
OR (spree_addresses.lastname #{LIKE} :search
AND spree_addresses.id = spree_users.bill_address_id)
OR (spree_addresses.firstname #{LIKE} :search
AND spree_addresses.id = spree_users.ship_address_id)
OR (spree_addresses.lastname #{LIKE} :search
AND spree_addresses.id = spree_users.ship_address_id)",
search: "#{params[:q].strip}%").
limit(params[:limit] || 100)
else
@search = Spree::User.registered.ransack(params[:q])
@collection = @search.
result.
page(params[:page]).
per(Spree::Config[:admin_products_per_page])
end
end
private
# handling raise from Spree::Admin::ResourceController#destroy
def user_destroy_with_orders_error
invoke_callbacks(:destroy, :fails)
render status: :forbidden, text: Spree.t(:error_user_destroy_with_orders)
end
# Allow different formats of json data to suit different ajax calls
def json_data
json_format = params[:json_format] || 'default'
case json_format
when 'basic'
collection.map { |u| { 'id' => u.id, 'name' => u.email } }.to_json
else
address_fields = [:firstname, :lastname, :address1, :address2, :city,
:zipcode, :phone, :state_name, :state_id, :country_id]
includes = { only: address_fields, include: { state: { only: :name },
country: { only: :name } } }
collection.to_json(only: [:id, :email], include:
{ bill_address: includes, ship_address: includes })
end
end
def sign_in_if_change_own_password
return unless spree_current_user == @user && @user.password.present?
sign_in(@user, event: :authentication, bypass: true)
end
def load_roles
@roles = Spree::Role.scoped
end
end
end
end

View File

@@ -18,6 +18,7 @@ Spree::Admin::VariantsController.class_eval do
def search
scoper = OpenFoodNetwork::ScopeVariantsForSearch.new(params)
@variants = scoper.search
render json: @variants, each_serializer: Api::Admin::VariantSerializer
end
def destroy

View File

@@ -0,0 +1,130 @@
require_dependency 'spree/api/controller_setup'
module Spree
module Api
class BaseController < ActionController::Metal
include Spree::Api::ControllerSetup
include Spree::Core::ControllerHelpers::SSL
include ::ActionController::Head
self.responder = Spree::Api::Responders::AppResponder
respond_to :json
attr_accessor :current_api_user
before_filter :set_content_type
before_filter :check_for_user_or_api_key, :if => :requires_authentication?
before_filter :authenticate_user
after_filter :set_jsonp_format
rescue_from Exception, :with => :error_during_processing
rescue_from CanCan::AccessDenied, :with => :unauthorized
rescue_from ActiveRecord::RecordNotFound, :with => :not_found
helper Spree::Api::ApiHelpers
ssl_allowed
def set_jsonp_format
if params[:callback] && request.get?
self.response_body = "#{params[:callback]}(#{response_body})"
headers["Content-Type"] = 'application/javascript'
end
end
def map_nested_attributes_keys(klass, attributes)
nested_keys = klass.nested_attributes_options.keys
attributes.inject({}) do |h, (k, v)|
key = nested_keys.include?(k.to_sym) ? "#{k}_attributes" : k
h[key] = v
h
end.with_indifferent_access
end
private
def set_content_type
content_type = case params[:format]
when "json"
"application/json"
when "xml"
"text/xml"
end
headers["Content-Type"] = content_type
end
def check_for_user_or_api_key
# User is already authenticated with Spree, make request this way instead.
return true if @current_api_user = try_spree_current_user ||
!requires_authentication?
return if api_key.present?
render("spree/api/errors/must_specify_api_key", status: :unauthorized) && return
end
def authenticate_user
return if @current_api_user
if requires_authentication? || api_key.present?
unless @current_api_user = Spree.user_class.find_by_spree_api_key(api_key.to_s)
render("spree/api/errors/invalid_api_key", status: :unauthorized) && return
end
else
# An anonymous user
@current_api_user = Spree.user_class.new
end
end
def unauthorized
render("spree/api/errors/unauthorized", status: :unauthorized) && return
end
def error_during_processing(exception)
render(text: { exception: exception.message }.to_json,
status: :unprocessable_entity) && return
end
def requires_authentication?
true
end
def not_found
render("spree/api/errors/not_found", status: :not_found) && return
end
def current_ability
Spree::Ability.new(current_api_user)
end
def invalid_resource!(resource)
@resource = resource
render "spree/api/errors/invalid_resource", status: :unprocessable_entity
end
def api_key
request.headers["X-Spree-Token"] || params[:token]
end
helper_method :api_key
def find_product(id)
product_scope.find_by_permalink!(id.to_s)
rescue ActiveRecord::RecordNotFound
product_scope.find(id)
end
def product_scope
if current_api_user.has_spree_role?("admin")
scope = Product
if params[:show_deleted]
scope = scope.with_deleted
end
else
scope = Product.active
end
scope.includes(:master)
end
end
end
end

View File

@@ -1,13 +0,0 @@
Spree::Api::LineItemsController.class_eval do
around_filter :apply_enterprise_fees_with_lock, only: :update
private
def apply_enterprise_fees_with_lock
authorize! :read, order
order.with_lock do
yield
order.update_distribution_charge!
end
end
end

View File

@@ -1,86 +0,0 @@
require 'open_food_network/permissions'
Spree::Api::ProductsController.class_eval do
def managed
authorize! :admin, Spree::Product
authorize! :read, Spree::Product
@products = product_scope.ransack(params[:q]).result.managed_by(current_api_user).page(params[:page]).per(params[:per_page])
respond_with(@products, default_template: :index)
end
# TODO: This should be named 'managed'. Is the action above used? Maybe we should remove it.
def bulk_products
@products = OpenFoodNetwork::Permissions.new(current_api_user).editable_products.
merge(product_scope).
order('created_at DESC').
ransack(params[:q]).result.
page(params[:page]).per(params[:per_page])
render_paged_products @products
end
def overridable
producers = OpenFoodNetwork::Permissions.new(current_api_user).
variant_override_producers.by_name
@products = paged_products_for_producers producers
render_paged_products @products
end
def soft_delete
authorize! :delete, Spree::Product
@product = find_product(params[:product_id])
authorize! :delete, @product
@product.destroy
respond_with(@product, status: 204)
end
# POST /api/products/:product_id/clone
#
def clone
authorize! :create, Spree::Product
original_product = find_product(params[:product_id])
authorize! :update, original_product
@product = original_product.duplicate
respond_with(@product, status: 201, default_template: :show)
end
private
# Copied and modified from Spree::Api::BaseController to allow
# enterprise users to access inactive products
def product_scope
if current_api_user.has_spree_role?("admin") || current_api_user.enterprises.present? # This line modified
scope = Spree::Product
if params[:show_deleted]
scope = scope.with_deleted
end
else
scope = Spree::Product.active
end
scope.includes(:master)
end
def paged_products_for_producers(producers)
Spree::Product.scoped.
merge(product_scope).
where(supplier_id: producers).
by_producer.by_name.
ransack(params[:q]).result.
page(params[:page]).per(params[:per_page])
end
def render_paged_products(products)
serializer = ActiveModel::ArraySerializer.new(
products,
each_serializer: Api::Admin::ProductSerializer
)
render text: { products: serializer, pages: products.num_pages }.to_json
end
end

View File

@@ -0,0 +1,108 @@
require 'open_food_network/scope_variant_to_hub'
module Spree
module Api
class ShipmentsController < Spree::Api::BaseController
respond_to :json
before_filter :find_order
before_filter :find_and_update_shipment, only: [:ship, :ready, :add, :remove]
def create
variant = scoped_variant(params[:variant_id])
quantity = params[:quantity].to_i
@shipment = get_or_create_shipment(params[:stock_location_id])
@order.contents.add(variant, quantity, nil, @shipment)
@shipment.refresh_rates
@shipment.save!
respond_with(@shipment.reload, default_template: :show)
end
def update
authorize! :read, Shipment
@shipment = @order.shipments.find_by_number!(params[:id])
params[:shipment] ||= []
unlock = params[:shipment].delete(:unlock)
if unlock == 'yes'
@shipment.adjustment.open
end
@shipment.update_attributes(params[:shipment])
if unlock == 'yes'
@shipment.adjustment.close
end
@shipment.reload
respond_with(@shipment, default_template: :show)
end
def ready
authorize! :read, Shipment
unless @shipment.ready?
if @shipment.can_ready?
@shipment.ready!
else
render "spree/api/shipments/cannot_ready_shipment", status: :unprocessable_entity
return
end
end
respond_with(@shipment, default_template: :show)
end
def ship
authorize! :read, Shipment
unless @shipment.shipped?
@shipment.ship!
end
respond_with(@shipment, default_template: :show)
end
def add
variant = scoped_variant(params[:variant_id])
quantity = params[:quantity].to_i
@order.contents.add(variant, quantity, nil, @shipment)
respond_with(@shipment, default_template: :show)
end
def remove
variant = scoped_variant(params[:variant_id])
quantity = params[:quantity].to_i
@order.contents.remove(variant, quantity, @shipment)
@shipment.reload if @shipment.persisted?
respond_with(@shipment, default_template: :show)
end
private
def find_order
@order = Spree::Order.find_by_number!(params[:order_id])
authorize! :read, @order
end
def find_and_update_shipment
@shipment = @order.shipments.find_by_number!(params[:id])
@shipment.update_attributes(params[:shipment])
@shipment.reload
end
def scoped_variant(variant_id)
variant = Spree::Variant.find(variant_id)
OpenFoodNetwork::ScopeVariantToHub.new(@order.distributor).scope(variant)
variant
end
def get_or_create_shipment(stock_location_id)
@order.shipment || @order.shipments.create(stock_location_id: stock_location_id)
end
end
end
end

View File

@@ -1,47 +0,0 @@
require 'open_food_network/scope_variant_to_hub'
Spree::Api::ShipmentsController.class_eval do
def create
variant = scoped_variant(params[:variant_id])
quantity = params[:quantity].to_i
@shipment = get_or_create_shipment(params[:stock_location_id])
@order.contents.add(variant, quantity, nil, @shipment)
@shipment.refresh_rates
@shipment.save!
respond_with(@shipment.reload, default_template: :show)
end
def add
variant = scoped_variant(params[:variant_id])
quantity = params[:quantity].to_i
@order.contents.add(variant, quantity, nil, @shipment)
respond_with(@shipment, default_template: :show)
end
def remove
variant = scoped_variant(params[:variant_id])
quantity = params[:quantity].to_i
@order.contents.remove(variant, quantity, @shipment)
@shipment.reload if @shipment.persisted?
respond_with(@shipment, default_template: :show)
end
private
def scoped_variant(variant_id)
variant = Spree::Variant.find(variant_id)
OpenFoodNetwork::ScopeVariantToHub.new(@order.distributor).scope(variant)
variant
end
def get_or_create_shipment(stock_location_id)
@order.shipment || @order.shipments.create(stock_location_id: stock_location_id)
end
end

View File

@@ -0,0 +1,75 @@
module Spree
module Api
class TaxonsController < Spree::Api::BaseController
respond_to :json
def index
if taxonomy
@taxons = taxonomy.root.children
else
if params[:ids]
@taxons = Taxon.where(id: params[:ids].split(","))
else
@taxons = Taxon.ransack(params[:q]).result
end
end
respond_with(@taxons)
end
def show
@taxon = taxon
respond_with(@taxon)
end
def jstree
show
end
def create
authorize! :create, Taxon
@taxon = Taxon.new(params[:taxon])
@taxon.taxonomy_id = params[:taxonomy_id]
taxonomy = Taxonomy.find_by_id(params[:taxonomy_id])
if taxonomy.nil?
@taxon.errors[:taxonomy_id] = I18n.t(:invalid_taxonomy_id, scope: 'spree.api')
invalid_resource!(@taxon) && return
end
@taxon.parent_id = taxonomy.root.id unless params[:taxon][:parent_id]
if @taxon.save
respond_with(@taxon, status: 201, default_template: :show)
else
invalid_resource!(@taxon)
end
end
def update
authorize! :update, Taxon
if taxon.update_attributes(params[:taxon])
respond_with(taxon, status: 200, default_template: :show)
else
invalid_resource!(taxon)
end
end
def destroy
authorize! :delete, Taxon
taxon.destroy
respond_with(taxon, status: 204)
end
private
def taxonomy
return if params[:taxonomy_id].blank?
@taxonomy ||= Taxonomy.find(params[:taxonomy_id])
end
def taxon
@taxon ||= taxonomy.taxons.find(params[:id])
end
end
end
end

View File

@@ -1,9 +0,0 @@
Spree::Api::VariantsController.class_eval do
def soft_delete
@variant = scope.find(params[:variant_id])
authorize! :delete, @variant
VariantDeleter.new.delete(@variant)
respond_with @variant, status: 204
end
end

View File

@@ -29,7 +29,7 @@ module Spree
def load_order
@order = current_order
redirect_to main_app.cart_path && return unless @order
redirect_to(main_app.cart_path) && return unless @order
if params[:state]
redirect_to checkout_state_path(@order.state) if @order.can_go_to_state?(params[:state])

View File

@@ -0,0 +1,44 @@
module Spree
class UserPasswordsController < Devise::PasswordsController
helper 'spree/base', 'spree/store'
include Spree::Core::ControllerHelpers::Auth
include Spree::Core::ControllerHelpers::Common
include Spree::Core::ControllerHelpers::Order
include Spree::Core::ControllerHelpers::SSL
ssl_required
# Overridden due to bug in Devise.
# respond_with resource, :location => new_session_path(resource_name)
# is generating bad url /session/new.user
#
# overridden to:
# respond_with resource, :location => spree.login_path
#
def create
self.resource = resource_class.send_reset_password_instructions(params[resource_name])
if resource.errors.empty?
set_flash_message(:notice, :send_instructions) if is_navigational_format?
respond_with resource, location: spree.login_path
else
respond_with_navigational(resource) { render :new }
end
end
# Devise::PasswordsController allows for blank passwords.
# Silly Devise::PasswordsController!
# Fixes spree/spree#2190.
def update
if params[:spree_user][:password].blank?
self.resource = resource_class.new
resource.reset_password_token = params[:spree_user][:reset_password_token]
set_flash_message(:error, :cannot_be_blank)
render :edit
else
super
end
end
end
end

View File

@@ -0,0 +1,65 @@
module Spree
class UserRegistrationsController < Devise::RegistrationsController
helper 'spree/base', 'spree/store'
include Spree::Core::ControllerHelpers::Auth
include Spree::Core::ControllerHelpers::Common
include Spree::Core::ControllerHelpers::Order
include Spree::Core::ControllerHelpers::SSL
ssl_required
before_filter :check_permissions, only: [:edit, :update]
skip_before_filter :require_no_authentication
# GET /resource/sign_up
def new
super
@user = resource
end
# POST /resource/sign_up
def create
@user = build_resource(params[:spree_user])
if resource.save
set_flash_message(:notice, :signed_up)
sign_in(:spree_user, @user)
session[:spree_user_signup] = true
associate_user
respond_with resource, location: after_sign_up_path_for(resource)
else
clean_up_passwords(resource)
render :new
end
end
# GET /resource/edit
def edit
super
end
# PUT /resource
def update
super
end
# DELETE /resource
def destroy
super
end
# GET /resource/cancel
# Forces the session data which is usually expired after sign
# in to be expired now. This is useful if the user wants to
# cancel oauth signing in/up in the middle of the process,
# removing all OAuth session data.
def cancel
super
end
protected
def check_permissions
authorize!(:create, resource)
end
end
end

View File

@@ -0,0 +1,56 @@
module Spree
class UserSessionsController < Devise::SessionsController
helper 'spree/base', 'spree/store'
include Spree::Core::ControllerHelpers::Auth
include Spree::Core::ControllerHelpers::Common
include Spree::Core::ControllerHelpers::Order
include Spree::Core::ControllerHelpers::SSL
ssl_required :new, :create, :destroy, :update
ssl_allowed :login_bar
before_filter :set_checkout_redirect, only: :create
def create
authenticate_spree_user!
if spree_user_signed_in?
respond_to do |format|
format.html {
flash[:success] = t('devise.success.logged_in_succesfully')
redirect_back_or_default(after_sign_in_path_for(spree_current_user))
}
format.js {
render json: { email: spree_current_user.login }, status: :ok
}
end
else
respond_to do |format|
format.html {
flash.now[:error] = t('devise.failure.invalid')
render :new
}
format.js {
render json: { message: t('devise.failure.invalid') }, status: :unauthorized
}
end
end
end
def nav_bar
render partial: 'spree/shared/nav_bar'
end
private
def accurate_title
Spree.t(:login)
end
def redirect_back_or_default(default)
redirect_to(session["spree_user_return_to"] || default)
session["spree_user_return_to"] = nil
end
end
end

View File

@@ -1,29 +0,0 @@
Spree::UserSessionsController.class_eval do
before_filter :set_checkout_redirect, only: :create
def create
authenticate_spree_user!
if spree_user_signed_in?
respond_to do |format|
format.html {
flash[:success] = t('devise.success.logged_in_succesfully')
redirect_back_or_default(after_sign_in_path_for(spree_current_user))
}
format.js {
render json: { email: spree_current_user.login }, status: :ok
}
end
else
respond_to do |format|
format.html {
flash.now[:error] = t('devise.failure.invalid')
render :new
}
format.js {
render json: { message: t('devise.failure.invalid') }, status: :unauthorized
}
end
end
end
end

View File

@@ -0,0 +1,74 @@
module Spree
class UsersController < Spree::StoreController
layout 'darkswarm'
ssl_required
skip_before_filter :set_current_order, only: :show
prepend_before_filter :load_object, only: [:show, :edit, :update]
prepend_before_filter :authorize_actions, only: :new
include Spree::Core::ControllerHelpers
include I18nHelper
before_filter :set_locale
before_filter :enable_embedded_shopfront
# Ignores invoice orders, only order where state: 'complete'
def show
@orders = @user.orders.where(state: 'complete').order('completed_at desc')
@unconfirmed_email = spree_current_user.unconfirmed_email
end
# Endpoint for queries to check if a user is already registered
def registered_email
user = Spree.user_class.find_by_email params[:email]
render json: { registered: user.present? }
end
def create
@user = Spree::User.new(params[:user])
if @user.save
if current_order
session[:guest_token] = nil
end
redirect_back_or_default(root_url)
else
render :new
end
end
def update
if @user.update_attributes(params[:user])
if params[:user][:password].present?
# this logic needed b/c devise wants to log us out after password changes
Spree::User.reset_password_by_token(params[:user])
sign_in(@user, event: :authentication,
bypass: true)
end
redirect_to spree.account_url, notice: Spree.t(:account_updated)
else
render :edit
end
end
private
def load_object
@user ||= spree_current_user
if @user
authorize! params[:action].to_sym, @user
else
redirect_to spree.login_path
end
end
def authorize_actions
authorize! params[:action].to_sym, Spree::User.new
end
def accurate_title
Spree.t(:my_account)
end
end
end

View File

@@ -1,20 +0,0 @@
Spree::UsersController.class_eval do
layout 'darkswarm'
include I18nHelper
before_filter :set_locale
before_filter :enable_embedded_shopfront
# Override of spree_auth_devise default
# Ignores invoice orders, only order where state: 'complete'
def show
@orders = @user.orders.where(state: 'complete').order('completed_at desc')
@unconfirmed_email = spree_current_user.unconfirmed_email
end
# Endpoint for queries to check if a user is already registered
def registered_email
user = Spree.user_class.find_by_email params[:email]
render json: { registered: user.present? }
end
end

View File

@@ -61,6 +61,12 @@ module InjectionHelper
inject_json_ams "currentOrder", current_order, Api::CurrentOrderSerializer, current_distributor: current_distributor, current_order_cycle: current_order_cycle
end
def inject_current_order_cycle
serializer = Api::OrderCycleSerializer.new(current_order_cycle)
json = serializer.object.present? ? serializer.to_json : "{}"
render partial: "json/injection_ams", locals: { name: "orderCycleData", json: json }
end
def inject_available_shipping_methods
inject_json_ams "shippingMethods", available_shipping_methods,
Api::ShippingMethodSerializer, current_order: current_order
@@ -111,8 +117,12 @@ module InjectionHelper
inject_json_ams "savedCreditCards", data, Api::CreditCardSerializer
end
def inject_json(name, partial, opts = {})
render partial: "json/injection", locals: { name: name, partial: partial }.merge(opts)
def inject_current_user
inject_json_ams "user", spree_current_user, Api::UserSerializer
end
def inject_rails_flash
inject_json_ams "railsFlash", OpenStruct.new(flash.to_hash), Api::RailsFlashSerializer
end
def inject_json_ams(name, data, serializer, opts = {})

View File

@@ -18,6 +18,7 @@ module Spree
klass = Spree::Order if klass == :bulk_order_management
klass = EnterpriseGroup if klass == :group
klass = VariantOverride if klass == :Inventory
klass = ProductImport::ProductImporter if klass == :import
klass = Spree::Admin::ReportsController if klass == :report
klass
end

View File

@@ -0,0 +1,120 @@
module Spree
module Api
module ApiHelpers
def required_fields_for(model)
required_fields = model._validators.select do |_field, validations|
validations.any? { |v| v.is_a?(ActiveModel::Validations::PresenceValidator) }
end.map(&:first) # get fields that are invalid
# Permalinks presence is validated, but are really automatically generated
# Therefore we shouldn't tell API clients that they MUST send one through
required_fields.map!(&:to_s).delete("permalink")
required_fields
end
def product_attributes
[:id, :name, :description, :price, :available_on, :permalink, :meta_description,
:meta_keywords, :shipping_category_id, :taxon_ids]
end
def product_property_attributes
[:id, :product_id, :property_id, :value, :property_name]
end
def variant_attributes
[:id, :name, :sku, :price, :weight, :height, :width, :depth,
:is_master, :cost_price, :permalink]
end
def image_attributes
[:id, :position, :attachment_content_type, :attachment_file_name,
:type, :attachment_updated_at, :attachment_width, :attachment_height, :alt]
end
def option_value_attributes
[:id, :name, :presentation, :option_type_name, :option_type_id]
end
def order_attributes
[:id, :number, :item_total, :total, :state, :adjustment_total, :user_id,
:created_at, :updated_at, :completed_at, :payment_total,
:shipment_state, :payment_state, :email, :special_instructions, :token]
end
def line_item_attributes
[:id, :quantity, :price, :variant_id]
end
def option_type_attributes
[:id, :name, :presentation, :position]
end
def payment_attributes
[:id, :source_type, :source_id, :amount, :payment_method_id,
:response_code, :state, :avs_response, :created_at, :updated_at]
end
def payment_method_attributes
[:id, :name, :description]
end
def shipment_attributes
[:id, :tracking, :number, :cost, :shipped_at, :state]
end
def taxonomy_attributes
[:id, :name]
end
def taxon_attributes
[:id, :name, :pretty_name, :permalink, :position, :parent_id, :taxonomy_id]
end
def inventory_unit_attributes
[:id, :lock_version, :state, :variant_id, :shipment_id, :return_authorization_id]
end
def return_authorization_attributes
[:id, :number, :state, :amount, :order_id, :reason, :created_at, :updated_at]
end
def country_attributes
[:id, :iso_name, :iso, :iso3, :name, :numcode]
end
def state_attributes
[:id, :name, :abbr, :country_id]
end
def adjustment_attributes
[:id, :source_type, :source_id, :adjustable_type, :adjustable_id, :originator_type,
:originator_id, :amount, :label, :mandatory, :locked, :eligible, :created_at, :updated_at]
end
def creditcard_attributes
[:id, :month, :year, :cc_type, :last_digits, :first_name, :last_name,
:gateway_customer_profile_id, :gateway_payment_profile_id]
end
def user_attributes
[:id, :email, :created_at, :updated_at]
end
def property_attributes
[:id, :name, :presentation]
end
def stock_location_attributes
[:id, :name, :address1, :address2, :city,
:state_id, :state_name, :country_id, :zipcode, :phone, :active]
end
def stock_movement_attributes
[:id, :quantity, :stock_item_id]
end
def stock_item_attributes
[:id, :count_on_hand, :backorderable, :lock_version, :stock_location_id, :variant_id]
end
end
end
end

View File

@@ -59,7 +59,7 @@ class SubscriptionPlacementJob
end
def move_to_completion(order)
until order.completed? do order.next! end
AdvanceOrderService.new(order).call!
end
def unavailable_stock_lines_for(order)

View File

@@ -0,0 +1,47 @@
# This mailer is configured to be the Devise mailer
# Some methods here override Devise::Mailer methods
module Spree
class UserMailer < BaseMailer
include I18nHelper
# Overrides `Devise::Mailer.reset_password_instructions`
def reset_password_instructions(user)
recipient = user.respond_to?(:id) ? user : Spree.user_class.find(user)
@edit_password_reset_url = spree.
edit_spree_user_password_url(reset_password_token: recipient.reset_password_token)
mail(to: recipient.email, from: from_address,
subject: Spree::Config[:site_name] + ' ' +
I18n.t(:subject, scope: [:devise, :mailer, :reset_password_instructions]))
end
# This is a OFN specific email, not from Devise::Mailer
def signup_confirmation(user)
@user = user
I18n.with_locale valid_locale(@user) do
mail(to: user.email, from: from_address,
subject: t(:welcome_to) + Spree::Config[:site_name])
end
end
# Overrides `Devise::Mailer.confirmation_instructions`
def confirmation_instructions(user, _opts)
@user = user
@instance = Spree::Config[:site_name]
@contact = ContentConfig.footer_email
I18n.with_locale valid_locale(@user) do
subject = t('spree.user_mailer.confirmation_instructions.subject')
mail(to: confirmation_email_address,
from: from_address,
subject: subject)
end
end
private
def confirmation_email_address
@user.pending_reconfirmation? ? @user.unconfirmed_email : @user.email
end
end
end

View File

@@ -1,32 +0,0 @@
Spree::UserMailer.class_eval do
include I18nHelper
def signup_confirmation(user)
@user = user
I18n.with_locale valid_locale(@user) do
mail(to: user.email, from: from_address,
subject: t(:welcome_to) + Spree::Config[:site_name])
end
end
# Overriding `Spree::UserMailer.confirmation_instructions` which is
# overriding `Devise::Mailer.confirmation_instructions`.
def confirmation_instructions(user, _opts)
@user = user
@instance = Spree::Config[:site_name]
@contact = ContentConfig.footer_email
I18n.with_locale valid_locale(@user) do
subject = t('spree.user_mailer.confirmation_instructions.subject')
mail(to: confirmation_email_address,
from: from_address,
subject: subject)
end
end
private
def confirmation_email_address
@user.pending_reconfirmation? ? @user.unconfirmed_email : @user.email
end
end

View File

@@ -90,7 +90,6 @@ class Enterprise < ActiveRecord::Base
validates :permalink, uniqueness: true, presence: true
validate :shopfront_taxons
validate :enforce_ownership_limit, if: lambda { owner_id_changed? && !owner_id.nil? }
validates :description, length: { maximum: 255 }
before_validation :initialize_permalink, if: lambda { permalink.nil? }
before_validation :ensure_owner_is_manager, if: lambda { owner_id_changed? && !owner_id.nil? }
@@ -464,9 +463,11 @@ class Enterprise < ActiveRecord::Base
self.permalink = Enterprise.find_available_permalink(name)
end
# Touch distributors without them touching their distributors.
# We avoid an infinite loop and don't need to touch the whole distributor tree.
def touch_distributors
Enterprise.distributing_products(supplied_products.select(:id)).
where('enterprises.id != ?', id).
find_each(&:touch)
update_all(updated_at: Time.zone.now)
end
end

View File

@@ -25,8 +25,8 @@ class EnterpriseRelationship < ActiveRecord::Base
where('parent_id IN (?) OR child_id IN (?)', enterprises, enterprises)
}
scope :permitting, ->(enterprises) { where('child_id IN (?)', enterprises) }
scope :permitted_by, ->(enterprises) { where('parent_id IN (?)', enterprises) }
scope :permitting, ->(enterprise_ids) { where('child_id IN (?)', enterprise_ids) }
scope :permitted_by, ->(enterprise_ids) { where('parent_id IN (?)', enterprise_ids) }
scope :with_permission, ->(permission) {
joins(:permissions).

View File

@@ -1,20 +0,0 @@
# Tells whether a particular feature is enabled or not
class FeatureFlags
# Constructor
#
# @param user [User]
def initialize(user)
@user = user
end
# Checks whether product import is enabled for the specified user
#
# @return [Boolean]
def product_import_enabled?
user.superadmin?
end
private
attr_reader :user
end

View File

@@ -15,7 +15,7 @@ Spree::CreditCard.class_eval do
belongs_to :user
after_create :ensure_single_default_card
after_save :ensure_single_default_card, if: :is_default_changed?
after_save :ensure_single_default_card, if: :default_card_needs_updating?
# Allows us to use a gateway_payment_profile_id to store Stripe Tokens
# Should be able to remove once we reach Spree v2.2.0
@@ -39,6 +39,10 @@ Spree::CreditCard.class_eval do
!user.credit_cards.exists?(is_default: true)
end
def default_card_needs_updating?
is_default_changed? || gateway_customer_profile_id_changed?
end
def ensure_single_default_card
return unless user
return unless is_default? || (reusable? && default_missing?)

View File

@@ -4,6 +4,12 @@ module Spree
private
def check_price
if currency.nil?
self.currency = Spree::Config[:currency]
end
end
def refresh_products_cache
variant.andand.refresh_products_cache
end

View File

@@ -56,6 +56,12 @@ Spree::Product.class_eval do
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 })
}
@@ -118,7 +124,7 @@ Spree::Product.class_eval do
scope :stockable_by, lambda { |enterprise|
return where('1=0') if enterprise.blank?
permitted_producer_ids = EnterpriseRelationship.joins(:parent).permitting(enterprise)
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)
}

View File

@@ -17,9 +17,7 @@ class Spree::ProductSet < ModelSet
# variant.update_attributes( { price: xx.x } )
#
def update_attributes(attributes)
if attributes[:taxon_ids].present?
attributes[:taxon_ids] = attributes[:taxon_ids].split(',')
end
split_taxon_ids!(attributes)
found_model = @collection.find do |model|
model.id.to_s == attributes[:id].to_s && model.persisted?
@@ -28,12 +26,20 @@ class Spree::ProductSet < ModelSet
if found_model.nil?
@klass.new(attributes).save unless @reject_if.andand.call(attributes)
else
update_product_only_attributes(found_model, attributes) &&
update_product_variants(found_model, attributes) &&
update_product_master(found_model, attributes)
update_product(found_model, attributes)
end
end
def split_taxon_ids!(attributes)
attributes[:taxon_ids] = attributes[:taxon_ids].split(',') if attributes[:taxon_ids].present?
end
def update_product(found_model, attributes)
update_product_only_attributes(found_model, attributes) &&
update_product_variants(found_model, attributes) &&
update_product_master(found_model, attributes)
end
def update_product_only_attributes(product, attributes)
variant_related_attrs = [:id, :variants_attributes, :master_attributes]
product_related_attrs = attributes.except(*variant_related_attrs)
@@ -90,8 +96,23 @@ class Spree::ProductSet < ModelSet
variant = product.variants.create(variant_attributes)
variant.on_demand = on_demand if on_demand.present?
variant.on_hand = on_hand.to_i if on_hand.present?
begin
variant.on_demand = on_demand if on_demand.present?
variant.on_hand = on_hand.to_i if on_hand.present?
rescue StandardError => error
notify_bugsnag(error, product, variant, variant_attributes)
raise error
end
end
def notify_bugsnag(error, product, variant, variant_attributes)
Bugsnag.notify(error) do |report|
report.add_tab(:product, product.attributes)
report.add_tab(:product_error, product.errors.first) unless product.valid?
report.add_tab(:variant_attributes, variant_attributes)
report.add_tab(:variant, variant.attributes)
report.add_tab(:variant_error, variant.errors.first) unless variant.valid?
end
end
def collection_attributes=(attributes)

View File

@@ -0,0 +1,10 @@
Spree::StockMovement.class_eval do
after_save :refresh_products_cache
private
def refresh_products_cache
return if stock_item.variant.blank?
OpenFoodNetwork::ProductsCache.variant_changed stock_item.variant
end
end

194
app/models/spree/user.rb Normal file
View File

@@ -0,0 +1,194 @@
module Spree
class User < ActiveRecord::Base
include Core::UserBanners
devise :database_authenticatable, :token_authenticatable, :registerable, :recoverable,
:rememberable, :trackable, :validatable, :encryptable, encryptor: 'authlogic_sha512'
has_many :orders
belongs_to :ship_address, foreign_key: 'ship_address_id', class_name: 'Spree::Address'
belongs_to :bill_address, foreign_key: 'bill_address_id', class_name: 'Spree::Address'
before_validation :set_login
before_destroy :check_completed_orders
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation,
:remember_me, :persistence_token, :login
users_table_name = User.table_name
roles_table_name = Role.table_name
scope :admin, lambda { includes(:spree_roles).where("#{roles_table_name}.name" => "admin") }
scope :registered, -> { where("#{users_table_name}.email NOT LIKE ?", "%@example.net") }
has_many :enterprise_roles, dependent: :destroy
has_many :enterprises, through: :enterprise_roles
has_many :owned_enterprises, class_name: 'Enterprise',
foreign_key: :owner_id, inverse_of: :owner
has_many :owned_groups, class_name: 'EnterpriseGroup',
foreign_key: :owner_id, inverse_of: :owner
has_many :customers
has_many :credit_cards
accepts_nested_attributes_for :enterprise_roles, allow_destroy: true
accepts_nested_attributes_for :bill_address
accepts_nested_attributes_for :ship_address
attr_accessible :enterprise_ids, :enterprise_roles_attributes, :enterprise_limit,
:locale, :bill_address_attributes, :ship_address_attributes
after_create :associate_customers
validate :limit_owned_enterprises
# We use the same options as Spree and add :confirmable
devise :confirmable, reconfirmable: true
# TODO: Later versions of devise have a dedicated after_confirmation callback, so use that
after_update :welcome_after_confirm, if: lambda {
confirmation_token_changed? && confirmation_token.nil?
}
class DestroyWithOrdersError < StandardError; end
# Creates an anonymous user. An anonymous user is basically an auto-generated +User+ account
# that is created for the customer behind the scenes and it's transparent to the customer.
# All +Orders+ must have a +User+ so this is necessary when adding to the "cart" (an order)
# and before the customer has a chance to provide an email or to register.
def self.anonymous!
token = User.generate_token(:persistence_token)
User.create(email: "#{token}@example.net",
password: token, password_confirmation: token, persistence_token: token)
end
def self.admin_created?
User.admin.count > 0
end
def admin?
has_spree_role?('admin')
end
def anonymous?
email =~ /@example.net$/ ? true : false
end
def send_reset_password_instructions
generate_reset_password_token!
UserMailer.reset_password_instructions(id).deliver
end
# handle_asynchronously will define send_reset_password_instructions_with_delay.
# If handle_asynchronously is called twice, we get an infinite job loop.
handle_asynchronously :send_reset_password_instructions unless method_defined? :send_reset_password_instructions_with_delay
def known_users
if admin?
Spree::User.scoped
else
Spree::User
.includes(:enterprises)
.where("enterprises.id IN (SELECT enterprise_id FROM enterprise_roles WHERE user_id = ?)",
id)
end
end
def build_enterprise_roles
Enterprise.all.find_each do |enterprise|
unless enterprise_roles.find_by_enterprise_id enterprise.id
enterprise_roles.build(enterprise: enterprise)
end
end
end
def customer_of(enterprise)
return nil unless enterprise
customers.find_by_enterprise_id(enterprise)
end
def welcome_after_confirm
# Send welcome email if we are confirming an user's email
# Note: this callback only runs on email confirmation
return unless confirmed? && unconfirmed_email.nil? && !unconfirmed_email_changed?
send_signup_confirmation
end
def send_signup_confirmation
Delayed::Job.enqueue ConfirmSignupJob.new(id)
end
def associate_customers
self.customers = Customer.where(email: email)
end
def can_own_more_enterprises?
owned_enterprises(:reload).size < enterprise_limit
end
def default_card
credit_cards.where(is_default: true).first
end
# Checks whether the specified user is a superadmin, with full control of the
# instance
#
# @return [Boolean]
def superadmin?
has_spree_role?('admin')
end
def generate_spree_api_key!
self.spree_api_key = SecureRandom.hex(24)
save!
end
def clear_spree_api_key!
self.spree_api_key = nil
save!
end
protected
def password_required?
!persisted? || password.present? || password_confirmation.present?
end
private
def check_completed_orders
raise DestroyWithOrdersError if orders.complete.present?
end
def set_login
# for now force login to be same as email, eventually we will make this configurable, etc.
self.login ||= email if email
end
# Generate a friendly string randomically to be used as token.
def self.friendly_token
SecureRandom.base64(15).tr('+/=', '-_ ').strip.delete("\n")
end
# Generate a token by looping and ensuring does not already exist.
def self.generate_token(column)
loop do
token = friendly_token
break token unless find(:first, conditions: { column => token })
end
end
def limit_owned_enterprises
return unless owned_enterprises.size > enterprise_limit
errors.add(:owned_enterprises, I18n.t(:spree_user_enterprise_limit_error,
email: email,
enterprise_limit: enterprise_limit))
end
def remove_payments_in_checkout(enterprises)
enterprises.each do |enterprise|
enterprise.distributed_orders.each do |order|
order.payments.keep_if { |payment| payment.state != "checkout" }
end
end
end
end
end

View File

@@ -1,98 +0,0 @@
Spree.user_class.class_eval do
# handle_asynchronously will define send_reset_password_instructions_with_delay.
# If handle_asynchronously is called twice, we get an infinite job loop.
handle_asynchronously :send_reset_password_instructions unless method_defined? :send_reset_password_instructions_with_delay
has_many :enterprise_roles, dependent: :destroy
has_many :enterprises, through: :enterprise_roles
has_many :owned_enterprises, class_name: 'Enterprise', foreign_key: :owner_id, inverse_of: :owner
has_many :owned_groups, class_name: 'EnterpriseGroup', foreign_key: :owner_id, inverse_of: :owner
has_many :customers
has_many :credit_cards
accepts_nested_attributes_for :enterprise_roles, allow_destroy: true
accepts_nested_attributes_for :bill_address
accepts_nested_attributes_for :ship_address
attr_accessible :enterprise_ids, :enterprise_roles_attributes, :enterprise_limit, :locale, :bill_address_attributes, :ship_address_attributes
after_create :associate_customers
validate :limit_owned_enterprises
# We use the same options as Spree and add :confirmable
devise :confirmable, reconfirmable: true
# TODO: Later versions of devise have a dedicated after_confirmation callback, so use that
after_update :welcome_after_confirm, if: lambda { confirmation_token_changed? && confirmation_token.nil? }
def known_users
if admin?
Spree::User.scoped
else
Spree::User
.includes(:enterprises)
.where("enterprises.id IN (SELECT enterprise_id FROM enterprise_roles WHERE user_id = ?)", id)
end
end
def build_enterprise_roles
Enterprise.all.find_each do |enterprise|
unless enterprise_roles.find_by_enterprise_id enterprise.id
enterprise_roles.build(enterprise: enterprise)
end
end
end
def customer_of(enterprise)
return nil unless enterprise
customers.find_by_enterprise_id(enterprise)
end
def welcome_after_confirm
# Send welcome email if we are confirming an user's email
# Note: this callback only runs on email confirmation
if confirmed? && unconfirmed_email.nil? && !unconfirmed_email_changed?
send_signup_confirmation
end
end
def send_signup_confirmation
Delayed::Job.enqueue ConfirmSignupJob.new(id)
end
def associate_customers
self.customers = Customer.where(email: email)
end
def can_own_more_enterprises?
owned_enterprises(:reload).size < enterprise_limit
end
def default_card
credit_cards.where(is_default: true).first
end
# Checks whether the specified user is a superadmin, with full control of the
# instance
#
# @return [Boolean]
def superadmin?
has_spree_role?('admin')
end
private
def limit_owned_enterprises
if owned_enterprises.size > enterprise_limit
errors.add(:owned_enterprises, I18n.t(:spree_user_enterprise_limit_error, email: email, enterprise_limit: enterprise_limit))
end
end
def remove_payments_in_checkout(enterprises)
enterprises.each do |enterprise|
enterprise.distributed_orders.each do |order|
order.payments.keep_if { |payment| payment.state != "checkout" }
end
end
end
end

View File

@@ -1,6 +0,0 @@
Deface::Override.new(virtual_path: "spree/admin/shared/_configuration_menu",
name: "add_enterprise_fees_to_admin_configurations_menu",
insert_bottom: "[data-hook='admin_configurations_sidebar_menu']",
text: "<li><%= link_to I18n.t(:enterprise_fees), main_app.admin_enterprise_fees_path %></li>",
partial: 'enterprise_fees/admin_configurations_menu',
original: '8445a03cc903cacc832f395757ffcfaa7e99ca92')

View File

@@ -0,0 +1,6 @@
Deface::Override.new(virtual_path: "spree/layouts/admin",
name: "user_admin_tabs",
insert_bottom: "[data-hook='admin_tabs'], #admin_tabs[data-hook]",
partial: "spree/admin/users_tab",
disabled: false,
original: '031652cf5a054796022506622082ab6d2693699f')

View File

@@ -0,0 +1,5 @@
Deface::Override.new(virtual_path: "spree/layouts/admin",
name: "auth_admin_login_navigation_bar",
insert_top: "[data-hook='admin_login_navigation_bar'], #admin_login_navigation_bar[data-hook]",
partial: "spree/layouts/admin/login_nav",
original: '841227d0aedf7909d62237d8778df99100087715')

View File

@@ -0,0 +1,6 @@
Deface::Override.new(virtual_path: "spree/shared/_nav_bar",
name: "auth_shared_login_bar",
insert_before: "li#search-bar",
partial: "spree/shared/login_bar",
disabled: false,
original: 'eb3fa668cd98b6a1c75c36420ef1b238a1fc55ac')

View File

@@ -1,9 +0,0 @@
/ replace_contents "[data-hook='adjustment_row']"
%td.align-center.created_at= pretty_time(adjustment.created_at)
%td.align-center.label= adjustment.label
%td.align-center.amount= adjustment.display_amount.to_html
%td.align-center.included-tax= adjustment.display_included_tax.to_html
%td.actions
= link_to_edit adjustment, no_text: true
= link_to_delete adjustment, no_text: true

View File

@@ -1,8 +0,0 @@
/ replace_contents "[data-hook='adjustmment_head']"
%tr
%th= "#{t('spree.date')}/#{t('spree.time')}"
%th= t(:description)
%th= t(:amount)
%th= t(:included_tax)
%th.actions

View File

@@ -1,6 +0,0 @@
/ replace_contents "[data-hook='admin_adjustment_form_fields']"
- if @adjustment.new_record?
= render 'new_form', f: f
- else
= render 'edit_form', f: f

View File

@@ -1,11 +0,0 @@
/ insert_after "fieldset.security"
%fieldset.embedded_shopfronts.no-border-bottom
%legend{:align => "center"}= t('admin.shopfront_settings.embedded_shopfront_settings')
.field
= preference_field_tag(:enable_embedded_shopfronts, Spree::Config[:enable_embedded_shopfronts], type: Spree::Config.preference_type(:enable_embedded_shopfronts))
= label_tag(:enable_embedded_shopfronts, t('admin.shopfront_settings.enable_embedded_shopfronts')) + tag(:br)
.field
= label_tag(:embedded_shopfronts_whitelist, t('admin.shopfront_settings.embedded_shopfronts_whitelist')) + tag(:br)
= preference_field_tag(:embedded_shopfronts_whitelist, Spree::Config[:embedded_shopfronts_whitelist], type: Spree::Config.preference_type(:embedded_shopfronts_whitelist))

View File

@@ -1,22 +0,0 @@
/ insert_after "fieldset.security"
%fieldset.legal.no-border-bottom
%legend{:align => "center"}= t('.legal_settings')
.field
= label_tag(:footer_tos_url, t('.footer_tos_url')) + tag(:br)
= preference_field_tag(:footer_tos_url, Spree::Config[:footer_tos_url], type: Spree::Config.preference_type(:footer_tos_url))
.field
= preference_field_tag(:enterprises_require_tos, Spree::Config[:enterprises_require_tos], :type => Spree::Config.preference_type(:enterprises_require_tos))
= label_tag(:enterprises_require_tos, t('.enterprises_require_tos')) + tag(:br)
.field
= preference_field_tag(:cookies_consent_banner_toggle, Spree::Config[:cookies_consent_banner_toggle], :type => Spree::Config.preference_type(:cookies_consent_banner_toggle))
= label_tag(:cookies_consent_banner_toggle, t('.cookies_consent_banner_toggle')) + tag(:br)
.field
= preference_field_tag(:cookies_policy_matomo_section, Spree::Config[:cookies_policy_matomo_section], :type => Spree::Config.preference_type(:cookies_policy_matomo_section))
= label_tag(:cookies_policy_matomo_section, t('.cookies_policy_matomo_section')) + tag(:br)
.field
= preference_field_tag(:cookies_policy_ga_section, Spree::Config[:cookies_policy_ga_section], :type => Spree::Config.preference_type(:cookies_policy_ga_section))
= label_tag(:cookies_policy_ga_section, t('.cookies_policy_ga_section')) + tag(:br)
.field
= label_tag(:privacy_policy_url, t('.privacy_policy_url')) + tag(:br)
= preference_field_tag(:privacy_policy_url, Spree::Config[:privacy_policy_url], type: Spree::Config.preference_type(:privacy_policy_url))

View File

@@ -1,7 +0,0 @@
/ insert_after "fieldset.currency"
%fieldset.number_localization.no-border-bottom
%legend{:align => "center"}= t('admin.number_localization.number_localization_settings')
.field
= preference_field_tag(:enable_localized_number?, Spree::Config[:enable_localized_number?], type: Spree::Config.preference_type(:enable_localized_number?))
= label_tag(:enable_localized_number?, t('admin.number_localization.enable_localized_number')) + tag(:br)

View File

@@ -1,11 +0,0 @@
/ replace_contents '#styles_list'
- @styles.each_with_index do |(style_name, style_value), index|
.field.three.columns
= label_tag "attachment_styles[#{style_name}]", style_name
%a.destroy_style{:alt => t(:destroy), :href => "#", :title => t(:destroy)}
%i.icon-trash
= text_field_tag "attachment_styles[#{style_name}][]", admin_image_settings_geometry_from_style(style_value), :class => 'fullwidth'
%br/
- current_format = admin_image_settings_format_from_style(style_value) || ''
= select_tag "attachment_styles[#{style_name}][]", options_for_select(admin_image_settings_format_options, current_format), :class => 'fullwidth', :id => "attachment_styles_format_#{style_name}"

View File

@@ -1,2 +0,0 @@
/ set_attributes "div[data-hook='customer_fields'] div.alpha"
/ attributes({class: "fullwidth"})

View File

@@ -1 +0,0 @@
remove "div[data-hook='customer_fields'] div.omega"

View File

@@ -1,6 +0,0 @@
/ replace "erb[loud]:contains('hidden_field_tag :customer_search')"
- content_for :app_wrapper_attrs do
= 'ng-app=admin.orders'
= hidden_field_tag :customer_search_override, nil, distributor_id: @order.distributor_id, :class => 'fullwidth title customer-search-override'

View File

@@ -1,6 +0,0 @@
/ insert_after "code[erb-loud]:contains('button_link_to t(:edit)')"
%li.links-dropdown#links-dropdown{ links: order_links(@order).to_json }
:coffee
angular.bootstrap(document.getElementById("links-dropdown"),['admin.dropdown'])

View File

@@ -1,6 +0,0 @@
/ insert_after "[data-hook='admin_payment_methods_index_rows'] td:first-child"
%td.align-center
- method.distributors.each do |distributor|
= distributor.name
%br/

View File

@@ -1,4 +0,0 @@
/ insert_after "[data-hook='admin_payment_methods_index_headers'] th:first-child"
%th
= t(:products_distributor)

View File

@@ -1,9 +0,0 @@
/ replace_contents "table#listing_payment_methods colgroup"
%col{style: "width: 13%"}
%col{style: "width: 14%"}
%col{style: "width: 32%"}
%col{style: "width: 14%"}
%col{style: "width: 8%"}
%col{style: "width: 8%"}
%col{style: "width: 11%"}

View File

@@ -1 +0,0 @@
remove "erb[loud]:contains(\"render :partial => 'spree/admin/shared/configuration_menu'\")"

View File

@@ -1,2 +0,0 @@
/replace 'code[erb-loud]:contains("form_for @payment")'
= form_for @payment, :url => admin_order_payments_path(@order), :html => {"ng-app" => "admin.payments", "ng-controller" => "PaymentCtrl"} do |f|

View File

@@ -1,3 +0,0 @@
/ insert_before "fieldset.no-border-top"
%save-bar{ persist: "true" }

View File

@@ -1,2 +0,0 @@
/replace 'code[erb-loud]:contains("button @order.cart?")'
= button_tag t(:update), type: 'button', "ng-click" => "submitPayment()"

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