Compare commits

...

167 Commits

Author SHA1 Message Date
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
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
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
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
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
Hugo Daniel
07ccbf7f98 Import variants/edit.html.erb from spree_backend 2019-07-31 16:55:47 +02: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
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
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
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
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
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
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
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
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
986837d601 Import variants/_form.html.erb from spree_backend to ofn and de-deface it 2019-07-25 11:07:35 +02:00
Hugo Daniel
353d6fbc5f Import variants/index from spree_backend to ofn and convert to Haml 2019-07-24 16:57:11 +02:00
luisramos0
ffb8edef0b Fix rubocop css issues 2019-07-23 22:37:10 +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
luisramos0
5739a82c19 Remove unused admin variants search rabl template 2019-07-23 12:30:00 +01: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
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
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
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
114 changed files with 1653 additions and 810 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
@@ -157,7 +153,6 @@ Metrics/LineLength:
- lib/open_food_network/permalink_generator.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
@@ -344,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
@@ -443,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
@@ -565,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
@@ -572,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
@@ -600,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
@@ -656,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

@@ -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.

View File

@@ -37,7 +37,7 @@ gem 'stripe'
gem 'activemerchant', '~> 1.78'
gem 'devise', '~> 2.2.5'
gem 'devise-encryptable', '0.1.2'
gem 'devise-encryptable', '0.2.0'
gem 'jwt', '~> 2.2'
gem 'oauth2', '~> 1.4.1' # Used for Stripe Connect
@@ -119,6 +119,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

@@ -223,6 +223,8 @@ 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)
@@ -244,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)
@@ -454,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,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)
@@ -555,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)
@@ -591,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)
@@ -698,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)
@@ -736,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)
@@ -775,12 +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.1.2)
devise-encryptable (= 0.2.0)
diffy
eventmachine (>= 1.2.3)
factory_bot_rails

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

@@ -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

@@ -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

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

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

@@ -42,7 +42,7 @@ nav.top-bar {
}
.top-bar-section {
border-bottom: 1px solid $ofn-grey;
border-bottom: 1px solid $light-grey-transparency;
a.icon {
&:hover {
@@ -170,9 +170,10 @@ nav.top-bar {
.tab-bar {
background-color: white;
border-bottom: 1px solid $light-grey-transparency;
height: 2.8em;
position: fixed;
width: 100%;
height: 2.8em;
z-index: 1;
.cart-span {

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

@@ -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

@@ -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

@@ -61,7 +61,7 @@ Spree::Admin::BaseController.class_eval do
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

@@ -48,19 +48,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 "/api/products/bulk_products?page=1;per_page=500;#{bulk_index_query(params)}"
else
if product_set.errors.present?
render json: { errors: product_set.errors }, status: :bad_request
@@ -73,7 +67,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 +103,38 @@ 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] ||= {}
params[:filters].reduce("") do |string, filter|
filter_db_column = filter[:property][:db_column]
filter_predicate = filter[:predicate][:predicate]
filter_value = filter[:value]
"#{string}q[#{filter_db_column}_#{filter_predicate}]=#{filter_value};"
end
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 +142,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 +164,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

@@ -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

@@ -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

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

@@ -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

@@ -464,9 +464,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

@@ -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

@@ -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

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()"

View File

@@ -1,2 +0,0 @@
add_to_attributes '[data-hook="admin_variant_form_fields"]'
attributes 'ng-app' => 'admin.products'

View File

@@ -1,25 +0,0 @@
/ insert_top "[data-hook='admin_variant_form_fields']"
.field
= f.label :display_name, t(:display_name)
= f.text_field :display_name, class: "fullwidth"
.field
= f.label :display_as, t(:display_as)
= f.text_field :display_as, class: "fullwidth"
- if product_has_variant_unit_option_type?(@product)
- if @product.variant_unit != 'items'
.field{"data-hook" => "unit_value", 'ng-controller' => 'variantUnitsCtrl'}
= f.label :unit_value, "#{t('admin.'+@product.variant_unit)} ({{unitName(#{@product.variant_unit_scale}, '#{@product.variant_unit}')}})"
= hidden_field_tag 'product_variant_unit_scale', @product.variant_unit_scale
= text_field_tag :unit_value_human, nil, {class: "fullwidth", 'ng-model' => 'unit_value_human', 'ng-change' => 'updateValue()'}
= f.text_field :unit_value, {hidden: true, 'ng-value' => 'unit_value'}
.field{"data-hook" => "unit_description"}
= f.label :unit_description, t(:spree_admin_unit_description)
= f.text_field :unit_description, class: "fullwidth", placeholder: t('admin.products.unit_name_placeholder')
:javascript
angular.element(document.getElementById("new_variant")).ready(function() {
angular.bootstrap(document.getElementById("new_variant"), ['admin.products']);
});

View File

@@ -1,11 +0,0 @@
/ insert_bottom "[data-hook='admin_variant_form_fields']"
- if Spree::Config[:track_inventory_levels]
.field.checkbox
%label
= f.check_box :on_demand
= t(:on_demand)
.field
= f.label :on_hand, t(:on_hand)
.fullwidth
= f.text_field :on_hand

View File

@@ -1,10 +0,0 @@
/ replace "[data-hook='presentation']"
- unless variant_unit_option_type?(option_type)
.field{"data-hook" => "presentation"}
= label :new_variant, option_type.presentation
- if @variant.new_record?
= select(:new_variant, option_type.presentation, option_type.option_values.collect {|ov| [ ov.presentation, ov.id ] }, {}, {:class => 'select2 fullwidth'})
- else
- if opt = @variant.option_values.detect {|o| o.option_type == option_type }.try(:presentation)
= text_field(:new_variant, option_type.presentation, :value => opt, :disabled => 'disabled', :class => 'fullwidth')

View File

@@ -1,33 +0,0 @@
/ insert_bottom "[data-hook='admin_variant_form_fields']"
:javascript
$(document).ready(function() {
var on_demand = $('input#variant_on_demand');
var on_hand = $('input#variant_on_hand');
disableOnHandIfOnDemand = function() {
on_demand_checked = on_demand.attr('checked')
if ( on_demand_checked == undefined )
on_demand_checked = false;
on_hand.attr('disabled', on_demand_checked);
if(on_demand_checked) {
on_hand.attr('data-stock', on_hand.val());
on_hand.val(t('admin.products.variants.infinity'));
}
}
disableOnHandIfOnDemand();
on_demand.change(function(){
disableOnHandIfOnDemand();
if(!this.checked) {
if(on_hand.attr('data-stock') !== undefined) {
on_hand.val(on_hand.attr('data-stock'));
} else {
on_hand.val("0");
}
}
});
});

View File

@@ -1,3 +0,0 @@
/ insert_bottom "[data-hook='on_demand']"
%div{'ofn-with-tip' => t('admin.products.variants.to_order_tip')}
%a= t('admin.whats_this')

View File

@@ -1,14 +0,0 @@
/ replace "[data-hook='admin_variant_form_additional_fields']"
.right.six.columns.omega.label-block{"data-hook" => "admin_variant_form_additional_fields"}
- if @product.variant_unit != 'weight'
.field{"data-hook" => 'weight'}
= f.label 'weight', t('weight')+' (kg)'
- value = number_with_precision(@variant.weight, :precision => 2)
= f.text_field 'weight', :value => value, :class => 'fullwidth'
- [:height, :width, :depth].each do |field|
.field{"data-hook" => field}
= f.label field, t(field)
- value = number_with_precision(@variant.send(field), :precision => 2)
= f.text_field field, :value => value, :class => 'fullwidth'

View File

@@ -1,3 +0,0 @@
/ replace "code[erb-loud]:contains('variant.options_text')"
= variant.full_name

View File

@@ -1,15 +1,49 @@
class Api::Admin::VariantSerializer < ActiveModel::Serializer
attributes :id, :options_text, :unit_value, :unit_description, :unit_to_display, :on_demand, :display_as, :display_name, :name_to_display, :sku
attributes :on_hand, :price, :import_date
attributes :id, :name, :producer_name, :image, :sku, :import_date
attributes :options_text, :unit_value, :unit_description, :unit_to_display
attributes :display_as, :display_name, :name_to_display
attributes :price, :on_demand, :on_hand, :in_stock, :stock_location_id, :stock_location_name
has_many :variant_overrides
def name
if object.full_name.present?
"#{object.name} - #{object.full_name}"
else
object.name
end
end
def on_hand
return 0 if object.on_hand.nil?
object.on_hand
end
def price
# Decimals are passed to json as strings, we need to run parseFloat.toFixed(2) on the client side.
# Decimals are passed to json as strings, we need to run parseFloat.toFixed(2) on the client.
object.price.nil? ? 0.to_f : object.price
end
def producer_name
object.product.supplier.name
end
def image
return if object.product.images.empty?
object.product.images.first.mini_url
end
def in_stock
object.in_stock?
end
def stock_location_id
return if object.stock_items.empty?
object.stock_items.first.stock_location.id
end
def stock_location_name
return if object.stock_items.empty?
object.stock_items.first.stock_location.name
end
end

View File

@@ -1,10 +1,18 @@
class Api::ImageSerializer < ActiveModel::Serializer
attributes :id, :alt, :small_url, :large_url
attributes :id, :alt, :thumb_url, :small_url, :image_url, :large_url
def thumb_url
object.attachment.url(:mini, false)
end
def small_url
object.attachment.url(:small, false)
end
def image_url
object.attachment.url(:product, false)
end
def large_url
object.attachment.url(:large, false)
end

View File

@@ -0,0 +1,13 @@
module Api
class OrderCycleSerializer < ActiveModel::Serializer
attributes :order_cycle_id, :orders_close_at
def order_cycle_id
object.id
end
def orders_close_at
object.orders_close_at.to_s
end
end
end

View File

@@ -22,20 +22,36 @@ class LineItemSyncer
def update_item_quantities(order)
changed_subscription_line_items.each do |sli|
line_item = order.line_items.find_by_variant_id(sli.variant_id)
next if update_quantity(line_item, sli)
product_name = "#{line_item.product.name} - #{line_item.full_name}"
order_update_issues.add(order, product_name)
if line_item.blank?
order_update_issues.add(order, sli.variant.product_and_full_name)
next
end
unless update_quantity(line_item, sli)
add_order_update_issue(order, line_item)
end
end
end
def create_new_items(order)
new_subscription_line_items.each do |sli|
order.line_items.create(variant_id: sli.variant_id, quantity: sli.quantity, skip_stock_check: true)
new_line_item = order.line_items.create(variant_id: sli.variant_id,
quantity: sli.quantity,
skip_stock_check: skip_stock_check?(order))
next if skip_stock_check?(order) || new_line_item.sufficient_stock?
order.line_items.delete(new_line_item)
add_order_update_issue(order, new_line_item)
end
end
def destroy_obsolete_items(order)
order.line_items.where(variant_id: subscription_line_items.select(&:marked_for_destruction?).map(&:variant_id)).destroy_all
order.line_items.
where(variant_id: subscription_line_items.
select(&:marked_for_destruction?).
map(&:variant_id)).
destroy_all
end
def changed_subscription_line_items
@@ -48,8 +64,27 @@ class LineItemSyncer
def update_quantity(line_item, sli)
if line_item.quantity == sli.quantity_was
return line_item.update_attributes(quantity: sli.quantity, skip_stock_check: true)
return line_item.update_attributes(quantity: sli.quantity,
skip_stock_check: skip_stock_check?(line_item.order))
end
line_item.quantity == sli.quantity
end
def skip_stock_check?(order)
!order.complete?
end
def add_order_update_issue(order, line_item)
issue_description = "#{line_item.product.name} - #{line_item.variant.full_name}"
issue_description << " - #{stock_issue_description(line_item)}" if line_item.insufficient_stock?
order_update_issues.add(order, issue_description)
end
def stock_issue_description(line_item)
if line_item.variant.in_stock?
I18n.t("admin.subscriptions.stock.insufficient_stock")
else
I18n.t("admin.subscriptions.stock.out_of_stock")
end
end
end

View File

@@ -1,6 +1,5 @@
# Responsible for ensuring that any updates to a Subscription are propagated to any
# orders belonging to that Subscription which have been instantiated
class OrderSyncer
attr_reader :order_update_issues
@@ -11,8 +10,9 @@ class OrderSyncer
end
def sync!
future_and_undated_orders.all? do |order|
order.assign_attributes(customer_id: customer_id, email: customer.andand.email, distributor_id: shop_id)
orders_in_order_cycles_not_closed.all? do |order|
order.assign_attributes(customer_id: customer_id, email: customer.andand.email,
distributor_id: shop_id)
update_associations_for(order)
line_item_syncer.sync!(order)
order.save
@@ -25,7 +25,8 @@ class OrderSyncer
delegate :orders, :bill_address, :ship_address, :subscription_line_items, to: :subscription
delegate :shop_id, :customer, :customer_id, to: :subscription
delegate :shipping_method, :shipping_method_id, :payment_method, :payment_method_id, to: :subscription
delegate :shipping_method, :shipping_method_id,
:payment_method, :payment_method_id, to: :subscription
delegate :shipping_method_id_changed?, :shipping_method_id_was, to: :subscription
delegate :payment_method_id_changed?, :payment_method_id_was, to: :subscription
@@ -36,9 +37,10 @@ class OrderSyncer
update_payment_for(order) if payment_method_id_changed?
end
def future_and_undated_orders
return @future_and_undated_orders unless @future_and_undated_orders.nil?
@future_and_undated_orders = orders.joins(:order_cycle).merge(OrderCycle.not_closed).readonly(false)
def orders_in_order_cycles_not_closed
return @orders_in_order_cycles_not_closed unless @orders_in_order_cycles_not_closed.nil?
@orders_in_order_cycles_not_closed = orders.joins(:order_cycle).
merge(OrderCycle.not_closed).readonly(false)
end
def update_bill_address_for(order)
@@ -49,7 +51,8 @@ class OrderSyncer
end
def update_payment_for(order)
payment = order.payments.with_state('checkout').where(payment_method_id: payment_method_id_was).last
payment = order.payments.
with_state('checkout').where(payment_method_id: payment_method_id_was).last
if payment
payment.andand.void_transaction!
order.payments.create(payment_method_id: payment_method_id, amount: order.reload.total)

View File

@@ -5,4 +5,11 @@
= render 'upload_sidebar'
%h5
= t('.notice')
%br
%p
= t('.beta_notice')
%br
= render 'upload_form'

View File

@@ -1,4 +1,4 @@
#add-line-item
#add-line-item.add-line-item
%fieldset
%legend{ align: 'center'}= t(:products)
%table.no-borders.layout
@@ -6,15 +6,15 @@
%col{ width: '20%' }
%col{ width: '20%' }
%tr
%td{ style: "vertical-align:top" }
%td.vertical-align-top
.field
= label_tag :add_variant_id, t(:name_or_sku)
= label_tag :add_variant_id, t('.name_or_sku')
%input#add_variant_id.variant_autocomplete.fullwidth{ type: 'number', ng: { model: 'newItem.variant_id' } }
%td{ style: "vertical-align:top" }
%td.vertical-align-top
.field
= label_tag :add_quantity, t(:qty)
= label_tag :add_quantity, t('.quantity')
%input#add_quantity.fullwidth{ type: 'number', min: 1, ng: { model: 'newItem.quantity' } }
%td{ style: "vertical-align:top" }
%td
.actions
%a.icon-plus.button.fullwidth{ href: 'javascript:void(0)', method: :post, ng: { click: 'addSubscriptionLineItem()' } }
= t(:add)
= t('.add')

View File

@@ -1,5 +0,0 @@
object @image
attributes(*image_attributes)
attributes :viewable_type, :viewable_id
node( :thumb_url ) { @product.images.first.attachment.url(:mini) }
node( :image_url ) { @product.images.first.attachment.url(:product) }

View File

@@ -1,3 +0,0 @@
object current_order_cycle
attributes :orders_close_at
attribute id: :order_cycle_id

View File

@@ -1,5 +1,5 @@
%span.cart-span{"ng-controller" => "CartCtrl", "ng-class" => "{ dirty: Cart.dirty || Cart.empty(), 'pure-dirty': Cart.dirty }"}
%a#cart.icon{cart: true}
%a#cart.icon{"cart-toggle" => true}
%span
= t '.cart'
%span.count

View File

@@ -1,6 +1,5 @@
- content_for :scripts do
:javascript
angular.module('Darkswarm').value('orderCycleData', #{render "json/order_cycle"})
- content_for :injection_data do
= inject_current_order_cycle
%ordercycle{"ng-controller" => "OrderCycleCtrl"}

View File

@@ -1,37 +0,0 @@
<%= admin_inject_json "admin.payments", "currentOrderNumber", @order.number %>
<%= admin_inject_json_ams_array "admin.payments", "paymentMethods", @payment_methods, Api::PaymentMethodSerializer, current_order: @order %>
<div data-hook="admin_payment_form_fields" class="row">
<div class="alpha three columns">
<div class="field">
<%= f.label :amount, t(:amount) %>
<%= f.text_field :amount, :value => @order.outstanding_balance, :class => 'fullwidth', "watch-value-as" => 'form_data.amount' %>
</div>
</div>
<div class="omega nine columns">
<div class="field">
<label><%= t(:payment_method) %></label>
<ul>
<% @payment_methods.each do |method| %>
<li>
<label data-hook="payment_method_field">
<%= radio_button_tag 'payment[payment_method_id]', method.id, method == @payment_method, { class: "payment_methods_radios", "ng-model" => 'form_data.payment_method' } %>
<%= t(method.name, :scope => :payment_methods, :default => method.name) %>
</label>
</li>
<% end %>
</ul>
<div class="payment-method-settings">
<% @payment_methods.each do |method| %>
<div class="payment-methods" id="payment_method_<%= method.id %>">
<% if method.source_required? %>
<br />
<%= render :partial => "spree/admin/payments/source_forms/#{method.method_type}", :locals => { :payment_method => method } %>
<% end %>
</div>
<% end %>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,23 @@
= admin_inject_json "admin.payments", "currentOrderNumber", @order.number
= admin_inject_json_ams_array "admin.payments", "paymentMethods", @payment_methods, Api::PaymentMethodSerializer, current_order: @order
.row
.alpha.three.columns
.field
= f.label :amount, t(:amount)
= f.text_field :amount, value: @order.outstanding_balance, class: 'fullwidth', "watch-value-as" => 'form_data.amount'
.omega.nine.columns
.field
%label= t(:payment_method)
%ul
- @payment_methods.each do |method|
%li
%label
= radio_button_tag 'payment[payment_method_id]', method.id, method == @payment_method, { class: "payment_methods_radios", "ng-model" => 'form_data.payment_method' }
= t(method.name, scope: :payment_methods, default: method.name)
.payment-method-settings
- @payment_methods.each do |method|
.payment-methods{id: "payment_method_#{method.id}"}
- if method.source_required?
%br/
= render partial: "spree/admin/payments/source_forms/#{method.method_type}", locals: { payment_method: method }

View File

@@ -0,0 +1,19 @@
%table.index
%thead
%tr
%th= "#{Spree.t('date')}/#{Spree.t('time')}"
%th= Spree.t(:amount)
%th= Spree.t(:payment_method)
%th= Spree.t(:payment_state)
%th.actions
%tbody
- payments.each do |payment|
%tr{class: "#{cycle('odd', 'even')}"}
%td= pretty_time(payment.created_at)
%td.align-center= payment.display_amount.to_html
%td.align-center= link_to payment_method_name(payment), spree.admin_order_payment_path(@order, payment)
%td.align-center
%span{class: "state #{payment.state}"}= Spree.t(payment.state, scope: :payment_states, default: payment.state.capitalize)
%td.actions
- payment.actions.each do |action|
= link_to_with_icon "icon-#{action}", Spree.t(action), fire_admin_order_payment_path(@order, payment, e: action), method: :put, no_text: true, data: {action: action}

View File

@@ -0,0 +1,22 @@
= render partial: 'spree/admin/shared/order_tabs', locals: { current: 'Payments' }
- content_for :page_actions do
- if @order.outstanding_balance?
%li#new_payment_section
= button_link_to Spree.t(:new_payment), new_admin_order_payment_url(@order), icon: 'icon-plus'
%li= button_link_to Spree.t(:back_to_orders_list), admin_orders_path, icon: 'icon-arrow-left'
- content_for :page_title do
%i.icon-arrow-right
= Spree.t(:payments)
- if @order.outstanding_balance?
%h5.outstanding-balance
= @order.outstanding_balance < 0 ? Spree.t(:credit_owed) : Spree.t(:balance_due)
\:
%strong= @order.display_outstanding_balance
- if @payments.any?
= render partial: 'list', locals: { payments: @payments }
- else
.alpha.twelve.columns.no-objects-found= Spree.t(:order_has_no_payments)

View File

@@ -0,0 +1,22 @@
= render partial: 'spree/admin/shared/order_tabs', locals: { current: 'Payments' }
- content_for :page_title do
%i.icon-arrow-right
= Spree.t(:new_payment)
- content_for :page_actions do
%li= button_link_to Spree.t(:back_to_payments_list), spree.admin_order_payments_url(@order), icon: 'icon-arrow-left'
- if @payment_methods.any?
= render partial: 'spree/shared/error_messages', locals: { target: @payment }
= form_for @payment, url: admin_order_payments_path(@order), html: {"ng-app" => "admin.payments", "ng-controller" => "PaymentCtrl"} do |f|
%save-bar{ persist: "true" }
%fieldset.no-border-top
= render partial: 'form', locals: { f: f }
.filter-actions.actions
= button_tag t(:update), type: 'button', "ng-click" => "submitPayment()"
- else
= Spree.t(:cannot_create_payment_without_payment_methods)
= link_to Spree.t(:please_define_payment_methods), admin_payment_methods_url

View File

@@ -0,0 +1,18 @@
= render partial: 'spree/admin/shared/order_tabs', locals: { current: 'Payments' }
- content_for :page_title do
%i.icon-arrow-right
= Spree.t("activerecord.models.#{@payment.class.to_s.underscore}.one")
%i.icon-arrow-right
= payment_method_name(@payment)
- content_for :page_actions do
%li= button_link_to Spree.t(:back_to_payments_list), spree.admin_order_payments_url(@order), icon: 'icon-arrow-left'
= render partial: "spree/admin/payments/source_views/#{@payment.payment_method.method_type}", locals: { payment: @payment.source.is_a?(Spree::Payment) ? @payment.source : @payment }
.align-center
%h5
= label_tag nil, Spree.t(:amount)
\:
%span.green= @payment.amount

View File

@@ -1,58 +0,0 @@
<fieldset class="no-border-bottom">
<div class="field" data-hook="previous_cards">
<% @previous_cards.each do |card| %>
<label><%= radio_button_tag :card, card.id, card == @previous_cards.first %> <%= card.display_number %><br /></label>
<% end %>
<label><%= radio_button_tag :card, 'new', @previous_cards.none?, { class: "card_new" } %> <%= t(:use_new_cc) %></label>
</div>
<div class="card_form" data-hook>
<% param_prefix = "payment_source[#{payment_method.id}]" %>
<div class="clear"></div>
<div class="alpha four columns">
<div data-hook="card_number">
<div class="field">
<%= hidden_field_tag "#{param_prefix}[cc_type]", '', {class: 'ccType'} %>
<%= label_tag "card_number#{payment_method.id}", raw(t(:card_number) + content_tag(:span, ' *', :class => 'required')) %>
<%= text_field_tag "#{param_prefix}[number]", '', :class => 'required fullwidth cardNumber', :id => "card_number#{payment_method.id}", :maxlength => 19 %>
<span id="card_type" style="display:none;">
( <span id="looks_like" ><%= t(:card_type_is) %> <span id="type"></span></span>
<span id="unrecognized"><%= t(:unrecognized_card_type) %></span>
)
</span>
</div>
</div>
</div>
<div class="alpha four columns">
<div data-hook="card_name">
<div class="field">
<%= label_tag "card_name#{payment_method.id}", raw(t(:name) + content_tag(:span, ' *', :class => 'required')) %>
<%= text_field_tag "#{param_prefix}[name]", '', id: "card_name#{payment_method.id}", class: 'required fullwidth', maxlength: 19 %>
</div>
</div>
</div>
<div class="three columns">
<div data-hook="card_expiration" class="field">
<%= label_tag "card_expiry#{payment_method.id}", raw(t(:expiration) + content_tag(:span, ' *', :class => 'required')) %><br>
<%= text_field_tag "#{param_prefix}[expiry]", '', id: "card_expiry#{payment_method.id}", class: "required cardExpiry", placeholder: "MM / YY" %>
</div>
</div>
<div class="omega two columns">
<div data-hook="card_code" class="field">
<%= label_tag "card_code#{payment_method.id}", raw(t(:card_code) + content_tag(:span, ' *', :class => "required")) %>
<%= text_field_tag "#{param_prefix}[verification_value]", '', id: "card_code#{payment_method.id}", class: 'required fullwidth cardCode', size: 5 %>
<a href="/content/cvv" class="info cvvLink" target="_blank">
(<%= t(:what_is_this) %>)
</a>
</div>
</div>
<div class="nine columns">
<%= image_tag 'credit_cards/credit_card.gif', :class => 'credit-card-image' %>
</div>
<div class="clear"></div>
</div>
</fieldset>

View File

@@ -0,0 +1,45 @@
%fieldset.no-border-bottom
.field
- @previous_cards.each do |card|
%label
= radio_button_tag :card, card.id, card == @previous_cards.first
= card.display_number
%br/
%label
= radio_button_tag :card, 'new', @previous_cards.none?, { class: "card_new" }
= t(:use_new_cc)
.card_form
- param_prefix = "payment_source[#{payment_method.id}]"
.clear
.alpha.four.columns
%div
.field
= hidden_field_tag "#{param_prefix}[cc_type]", '', {class: 'ccType'}
= label_tag "card_number#{payment_method.id}", raw(t(:card_number) + content_tag(:span, ' *', class: 'required'))
= text_field_tag "#{param_prefix}[number]", '', class: 'required fullwidth cardNumber', id: "card_number#{payment_method.id}", maxlength: 19
%span#card_type{style: "display:none;"}
(
%span#looks_like
= t(:card_type_is)
%span#type
%span#unrecognized= t(:unrecognized_card_type)
)
.alpha.four.columns
%div
.field
= label_tag "card_name#{payment_method.id}", raw(t(:name) + content_tag(:span, ' *', class: 'required'))
= text_field_tag "#{param_prefix}[name]", '', id: "card_name#{payment_method.id}", class: 'required fullwidth', maxlength: 19
.three.columns
.field
= label_tag "card_expiry#{payment_method.id}", raw(t(:expiration) + content_tag(:span, ' *', class: 'required'))
%br/
= text_field_tag "#{param_prefix}[expiry]", '', id: "card_expiry#{payment_method.id}", class: "required cardExpiry", placeholder: "MM / YY"
.omega.two.columns
.field
= label_tag "card_code#{payment_method.id}", raw(t(:card_code) + content_tag(:span, ' *', class: "required"))
= text_field_tag "#{param_prefix}[verification_value]", '', id: "card_code#{payment_method.id}", class: 'required fullwidth cardCode', size: 5
%a.info.cvvLink{href: "/content/cvv", target: "_blank"}
(#{t(:what_is_this)})
.nine.columns
= image_tag 'credit_cards/credit_card.gif', class: 'credit-card-image'
.clear

View File

@@ -0,0 +1,33 @@
%fieldset
%legend{:align => "center"}= Spree.t(:credit_card)
.row
.alpha.six.columns
%dl
%dt
= Spree.t(:card_number)
\:
%dd= payment.source.display_number
%dt
= Spree.t(:expiration)
\:
%dd
= payment.source.month
\/
= payment.source.year
%dt
= Spree.t(:card_code)
\:
%dd= payment.source.verification_value
.omega.six.columns
%dl
%dt
= t(:maestro_or_solo_cards)
\:
%dd= payment.source.issue_number
%dt
= Spree.t(:start_date)
\:
%dd
= payment.source.start_month
\/
= payment.source.start_year

View File

@@ -12,13 +12,12 @@
%label{ for: 'category_filter' }= t 'category'
%br
%select.fullwidth{ id: 'category_filter', 'ofn-select2-min-search' => 5, ng: {model: 'categoryFilter', options: 'taxon.id as taxon.name for taxon in filterTaxons'} }
- if FeatureFlags.new(@current_user).product_import_enabled?
.filter_select.three.columns
%label{ for: 'import_filter' } Import Date
%br
%select.fullwidth{ id: 'import_date_filter', 'ofn-select2-min-search' => 5, ng: {model: 'importDateFilter', init: "importDates = #{@import_dates}; showLatestImport = #{@show_latest_import}"}}
%option{value: "{{date.id}}", ng: {repeat: "date in importDates track by date.id" }}
{{date.name}}
.filter_select.three.columns
%label{ for: 'import_filter' } Import Date
%br
%select.fullwidth{ id: 'import_date_filter', 'ofn-select2-min-search' => 5, ng: {model: 'importDateFilter', init: "importDates = #{@import_dates}; showLatestImport = #{@show_latest_import}"}}
%option{value: "{{date.id}}", ng: {repeat: "date in importDates track by date.id" }}
{{date.name}}
.filter_clear.three.columns.omega
%label{ for: 'clear_all_filters' }

View File

@@ -16,16 +16,13 @@
</ul>
<ul class='variant-data'>
<li class='variant-sku'><strong><%= t('admin.sku') %>:</strong> {{variant.sku}}</li>
<li class='variant-on_hand'><strong><%= t('on_hand') %>:</strong> {{variant.on_hand}}</li>
{{#if variant.on_demand }}
<li class='variant-on_demand'><strong><%= t('on_demand') %></strong></li>
{{ else }}
<li class='variant-on_hand'><strong><%= t('on_hand') %>:</strong> {{variant.on_hand}}</li>
{{/if}}
<li class='variant-options_text'><strong><%= t('.unit') %>:</strong> {{variant.options_text}}</li>
</ul>
{{#if variant.option_values}}
<ul class='variant-options'>
{{#each variant.option_values}}
<li><strong>{{this.option_type.presentation}}:</strong> {{this.presentation}}</li>
{{/each}}
</ul>
{{/if}}
</div>
</div>
</script>
@@ -45,7 +42,7 @@
</thead>
<tbody>
<tr>
{{#if variant.[in_stock?]}}
{{#if variant.in_stock}}
{{#if variant.on_demand}}
<td><%= Spree.t(:on_demand) %></td>
{{else}}

View File

@@ -0,0 +1,67 @@
.label-block.left.six.columns.alpha{'ng-app' => 'admin.products'}
.field
= f.label :display_name, t(:display_name)
= f.text_field :display_name, class: "fullwidth"
.field
= f.label :display_as, t(:display_as)
= f.text_field :display_as, class: "fullwidth"
- if product_has_variant_unit_option_type?(@product)
- if @product.variant_unit != 'items'
.field{'ng-controller' => 'variantUnitsCtrl'}
= f.label :unit_value, "#{t('admin.'+@product.variant_unit)} ({{unitName(#{@product.variant_unit_scale}, '#{@product.variant_unit}')}})"
= hidden_field_tag 'product_variant_unit_scale', @product.variant_unit_scale
= text_field_tag :unit_value_human, nil, {class: "fullwidth", 'ng-model' => 'unit_value_human', 'ng-change' => 'updateValue()'}
= f.text_field :unit_value, {hidden: true, 'ng-value' => 'unit_value'}
.field
= f.label :unit_description, t(:spree_admin_unit_description)
= f.text_field :unit_description, class: "fullwidth", placeholder: t('admin.products.unit_name_placeholder')
%div
- @product.option_types.each do |option_type|
- unless variant_unit_option_type?(option_type)
.field
= label :new_variant, option_type.presentation
- if @variant.new_record?
= select(:new_variant, option_type.presentation, option_type.option_values.collect {|ov| [ ov.presentation, ov.id ] }, {}, {class: 'select2 fullwidth'})
- else
- if opt = @variant.option_values.detect {|o| o.option_type == option_type }.try(:presentation)
= text_field(:new_variant, option_type.presentation, value: opt, disabled: 'disabled', class: 'fullwidth')
.field
= f.label :sku, Spree.t(:sku)
= f.text_field :sku, class: 'fullwidth'
.field
= f.label :price, Spree.t(:price)
= f.text_field :price, value: number_to_currency(@variant.price, unit: ''), class: 'fullwidth'
.field
= f.label :cost_price, Spree.t(:cost_price)
= f.text_field :cost_price, value: number_to_currency(@variant.cost_price, unit: ''), class: 'fullwidth'
- if Spree::Config[:track_inventory_levels]
%div{ 'set-on-demand' => '' }
.field.checkbox
%label
= f.check_box :on_demand
= t(:on_demand)
%div{'ofn-with-tip' => t('admin.products.variants.to_order_tip')}
%a= t('admin.whats_this')
.field
= f.label :on_hand, t(:on_hand)
.fullwidth
= f.text_field :on_hand
.right.six.columns.omega.label-block
- if @product.variant_unit != 'weight'
.field
= f.label 'weight', t('weight')+' (kg)'
- value = number_with_precision(@variant.weight, precision: 2)
= f.text_field 'weight', value: value, class: 'fullwidth'
- [:height, :width, :depth].each do |field|
.field
= f.label field, t(field)
- value = number_with_precision(@variant.send(field), precision: 2)
= f.text_field field, value: value, class: 'fullwidth'
.clear

View File

@@ -0,0 +1,11 @@
= render partial: 'spree/admin/shared/product_sub_menu'
= render partial: 'spree/admin/shared/product_tabs', locals: { current: 'Variants' }
= render partial: 'spree/shared/error_messages', locals: { target: @variant }
= form_for [:admin, @product, @variant] do |f|
%fieldset.no-border-top
%div
= render partial: 'form', locals: { f: f }
= render partial: 'spree/admin/shared/edit_resource_links'

View File

@@ -0,0 +1,54 @@
= render partial: 'spree/admin/shared/product_sub_menu'
= render partial: 'spree/admin/shared/product_tabs', locals: {current: 'Variants'}
#new_variant
- if @variants.any?
%table.index.sortable{"data-sortable-link" => update_positions_admin_product_variants_path(@product)}
%colgroup
%col{style: "width: 5%"}/
%col{style: "width: 25%"}/
%col{style: "width: 20%"}/
%col{style: "width: 20%"}/
%col{style: "width: 15%"}/
%col{style: "width: 15%"}/
%thead
%tr
%th{colspan: "2"}= Spree.t(:options)
%th= Spree.t(:price)
%th= Spree.t(:sku)
%th.actions
%tbody
- @variants.each do |variant|
%tr{id: spree_dom_id(variant), class: cycle('odd', 'even'), style: "#{"color:red;" if variant.deleted? }" }
%td.no-border
%span.handle
%td= variant.full_name
%td.align-center= variant.display_price.to_html
%td.align-center= variant.sku
%td.actions
= link_to_edit(variant, no_text: true) unless variant.deleted?
= link_to_delete(variant, no_text: true) unless variant.deleted?
- unless @product.has_variants?
%tr
%td{colspan: "5"}= Spree.t(:none)
- else
.alpha.twelve.columns.no-objects-found
= Spree.t(:no_results)
\.
- if @product.empty_option_values?
%p.first_add_option_types.no-objects-found
= Spree.t(:to_add_variants_you_must_first_define)
= link_to Spree.t(:option_types), admin_product_url(@product)
= Spree.t(:and)
= link_to Spree.t(:option_values), admin_option_types_url
- else
- content_for :page_actions do
%ul.inline-menu
%li#new_var_link
= link_to_with_icon('icon-plus', Spree.t(:new_variant), new_admin_product_variant_url(@product), remote: true, 'data-update' => 'new_variant', class: 'button')
%li= link_to_with_icon('icon-filter', @deleted.blank? ? Spree.t(:show_deleted) : Spree.t(:show_active), admin_product_variants_url(@product, deleted: @deleted.blank? ? "on" : "off"), class: 'button')

View File

@@ -0,0 +1,7 @@
= render partial: 'spree/shared/error_messages', locals: { target: @variant }
= form_for [:admin, @product, @variant] do |f|
%fieldset{'data-hook' => "admin_variant_new_form"}
%legend{align: "center"}= Spree.t(:new_variant)
= render partial: 'form', locals: { f: f }
= render partial: 'spree/admin/shared/new_resource_links'

View File

@@ -0,0 +1,3 @@
$("#new_variant").html('<%= escape_javascript(render template: 'spree/admin/variants/new', formats: [:html], handlers: [:erb]) %>');
$(".select2").select2();
$("#new_var_link").hide();

View File

@@ -1,40 +0,0 @@
#
# overriding spree/core/app/views/spree/admin/variants/search.rabl
#
collection @variants
attributes :sku, :options_text, :in_stock?, :on_demand, :on_hand, :id, :cost_price
node(:name) do |v|
# TODO: when products must have a unit, full_name will always be present
variant_specific = v.full_name
if variant_specific.present?
"#{v.name} - #{v.full_name}"
else
v.name
end
end
node(:full_name, &:full_name)
node(:producer_name) do |v|
v.product.supplier.name
end
node(:stock_location_id) do |v|
v.stock_items.first.stock_location.id
end
node(:stock_location_name) do |v|
v.stock_items.first.stock_location.name
end
child(images: :images) do
attributes :mini_url
end
child(option_values: :option_values) do
child(option_type: :option_type) do
attributes :name, :presentation
end
attributes :name, :presentation
end

View File

@@ -1,13 +1,16 @@
%table.order-summary{:width => "100%"}
%thead
%tr
%th{:align => "left"}
%th{align: "left"}
%h4
= t :email_order_summary_item
%th{:align => "right", :width => "25%"}
%th{align: "left"}
%h4
= t :email_order_summary_sku
%th{align: "right"}
%h4
= t :email_order_summary_quantity
%th{:align => "right", :width => "25%"}
%th{align: "right", width: "25%"}
%h4
= t :email_order_summary_price
%tbody
@@ -18,37 +21,42 @@
%br
%small
%em= raw(item.variant.product.supplier.name)
%td{:align => "right"}
%td
- if item.variant.sku.blank?
\-
- else
= item.variant.sku
%td{align: "right"}
- if @changes && @changes[item.id].present?
%del.quantity_was= @changes[item.id]
= item.quantity
-# Report changes made to subscriptions
%td{:align => "right"}
%td{align: "right"}
= item.display_amount_with_adjustments
%tfoot
%tr
%td{:align => "right", :colspan => "2"}
%td{align: "right", colspan: "3"}
= t :email_order_summary_subtotal
%td{:align => "right"}
%td{align: "right"}
= display_checkout_subtotal(@order)
- checkout_adjustments_for(@order, exclude: [:line_item]).reject{ |a| a.amount == 0 }.reverse_each do |adjustment|
%tr
%td{:align => "right", :colspan => "2"}
%td{align: "right", colspan: "3"}
= "#{raw(adjustment.label)}:"
%td{:align => "right"}
%td{align: "right"}
= adjustment.display_amount
%tr
%td{:align => "right", :colspan => "2"}
%td{align: "right", colspan: "3"}
%strong
= t :email_order_summary_total
%td{:align => "right"}
%td{align: "right"}
%strong= @order.display_total
- if @order.total_tax > 0
%tr
%td{:align => "right", :colspan => "2"}
%td{align: "right", colspan: "3"}
= t :email_order_summary_includes_tax
%td{:align => "right"}
%td{align: "right"}
= display_checkout_tax_total(@order)
%p &nbsp;

View File

@@ -0,0 +1,6 @@
if ENV['DATADOG_RAILS_APM']
Datadog.configure do |c|
c.use :rails, service_name: 'rails'
c.use :delayed_job, service_name: 'delayed_job'
end
end

View File

@@ -1003,6 +1003,10 @@ ca:
Els preus que es mostren són només una estimació i es calculen en el moment en què es canvia la subscripció.
Si canvieu els preus o les comissions, les comandes s'actualitzaran, però la subscripció continuarà mostrant els valors anteriors.
not_in_open_and_upcoming_order_cycles_warning: "No hi ha cicles de comandes oberts o futurs per a aquest producte."
autocomplete:
name_or_sku: "NOM O CODI"
quantity: "Quantitat"
add: "Afegeix"
details:
details: Detalls
invalid_error: Oops! Si us plau ompliu tots els camps obligatoris ...
@@ -1025,15 +1029,18 @@ ca:
saving: "DESANT"
saved: "DESAT"
product_already_in_order: Aquest producte ja s'ha afegit a la comanda. Editeu-ne la quantitat directament.
stock:
insufficient_stock: "Estoc disponible insuficient"
out_of_stock: "Fora d'existència"
orders:
number: Número
confirm_edit: Estàs segur que voleu editar aquesta comanda? Si ho fas és més difícil que es sincronitzin automàticament els canvis a la subscripció en el futur.
confirm_cancel_msg: Estàs segur que vols cancel·lar aquesta subscripció? Aquesta acció no es pot desfer.
cancel_failure_msg: 'Ho sentim, la cancel·lació ha fallat!'
confirm_pause_msg: Estàs segur que vols pausar aquesta subscripció?
pause_failure_msg: 'Ho sentim, la pausa ha fallat!'
confirm_unpause_msg: Estàs segur que vols reprendre aquesta subscripció?
unpause_failure_msg: 'Ho sentim, la represa ha fallat!'
confirm_cancel_msg: "Estàs segur que vols cancel·lar aquesta subscripció? Aquesta acció no es pot desfer."
cancel_failure_msg: "Ho sentim, la cancel·lació ha fallat!"
confirm_pause_msg: "Estàs segur que vols pausar aquesta subscripció?"
pause_failure_msg: "Ho sentim, la pausa ha fallat!"
confirm_unpause_msg: "Si teniu un cicle de comanda obert a la programació d'aquesta subscripció, es crearà una comanda per a aquesta consumidora. Esteu segur que voleu anul·lar aquesta subscripció?"
unpause_failure_msg: "Ho sentim, la represa ha fallat!"
confirm_cancel_open_orders_msg: "Actualment hi ha algunes comandes obertes per a aquesta subscripció. Ja s'ha notificat a les consumidores que les comandes serà atesa. Voleu cancel·lar aquestes comandes o conservar-les?"
resume_canceled_orders_msg: "Algunes comandes d'aquesta subscripció es poden reprendre ara mateix. Podeu reprendre-les des del menú desplegable de comandes."
yes_cancel_them: Cancel·lar-les
@@ -1395,6 +1402,7 @@ ca:
email_confirm_shop_number_html: "Confirmació de la comanda <strong> # %{number}</strong>"
email_order_summary_item: "Article"
email_order_summary_quantity: "quant."
email_order_summary_sku: "Número de referència (SKU)"
email_order_summary_price: "Preu"
email_order_summary_subtotal: "Subtotal:"
email_order_summary_total: "Total:"
@@ -2988,7 +2996,8 @@ ca:
confirmation_pending: "La confirmació de correu electrònic està pendent. Hem enviat un correu electrònic de confirmació a %{address}."
variants:
autocomplete:
producer_name: Productor
producer_name: "Productor"
unit: "Unitat"
general_settings:
edit:
legal_settings: "Paràmetres legals"

View File

@@ -1001,6 +1001,9 @@ de_DE:
Die angezeigten Preise sind nur Schätzungen und werden zum Zeitpunkt der Änderung des Abonnements berechnet.
Wenn Sie die Preise oder Gebühren ändern, werden die Bestellungen aktualisiert, aber das Abonnement zeigt weiterhin die alten Werte an.
not_in_open_and_upcoming_order_cycles_warning: "Für dieses Produkt gibt es keine offenen oder bevorstehenden Bestellzyklen."
autocomplete:
quantity: "Menge"
add: "Hinzufügen"
details:
details: Einzelheiten
invalid_error: Hoppla! Bitte füllen Sie alle erforderlichen Felder aus ...
@@ -1026,12 +1029,11 @@ de_DE:
orders:
number: Nummer
confirm_edit: Sind Sie sicher, dass Sie diese Bestellung bearbeiten möchten? Dies kann die automatische Synchronisierung von Änderungen am Abonnement in Zukunft erschweren.
confirm_cancel_msg: Sind Sie sicher, dass Sie dieses Abonnement kündigen möchten? Dieser Vorgang kann nicht rückgängig gemacht werden.
cancel_failure_msg: 'Entschuldigung, Stornierung fehlgeschlagen!'
confirm_pause_msg: Möchten Sie dieses Abonnement wirklich pausieren?
pause_failure_msg: 'Entschuldigung, Pausieren fehlgeschlagen!'
confirm_unpause_msg: Möchten Sie dieses Abonnement wirklich fortsetzen?
unpause_failure_msg: 'Entschuldigung, Fortsetzung fehlgeschlagen!'
confirm_cancel_msg: "Sind Sie sicher, dass Sie dieses Abonnement kündigen möchten? Dieser Vorgang kann nicht rückgängig gemacht werden."
cancel_failure_msg: "Entschuldigung, Stornierung fehlgeschlagen!"
confirm_pause_msg: "Möchten Sie dieses Abonnement wirklich pausieren?"
pause_failure_msg: "Entschuldigung, Pausieren fehlgeschlagen!"
unpause_failure_msg: "Entschuldigung, Fortsetzung fehlgeschlagen!"
confirm_cancel_open_orders_msg: "Einige Bestellungen für dieses Abonnement sind derzeit offen. Der Kunde wurde bereits informiert, dass die Bestellung aufgegeben wird. Möchten Sie diese Bestellung(en) stornieren oder erhalten?"
resume_canceled_orders_msg: "Manche Bestellungen für dieses Abonnement können jetzt fortgesetzt werden. Sie können sie aus dem Bestellungen-Dropdown-Menü wiederherstellen."
yes_cancel_them: Stornieren
@@ -1393,6 +1395,7 @@ de_DE:
email_confirm_shop_number_html: "Bestellbestätigung <strong> # %{number} </ strong>"
email_order_summary_item: "Artikel"
email_order_summary_quantity: "Menge"
email_order_summary_sku: "Artikelnummer"
email_order_summary_price: "Preis"
email_order_summary_subtotal: "Zwischensumme:"
email_order_summary_total: "Gesamt:"
@@ -2985,7 +2988,8 @@ de_DE:
confirmation_pending: "E-Mail-Bestätigung steht aus. Wir haben eine Bestätigungs-E-Mail an %{address} gesendet."
variants:
autocomplete:
producer_name: Produzent
producer_name: "Produzent"
unit: "Einheit"
general_settings:
edit:
legal_settings: "Rechtliche Einstellungen"

View File

@@ -275,6 +275,7 @@ en:
reset_password_token: Reset password token
expired: has expired, please request a new one
back_to_payments_list: "Back to Payments List"
maestro_or_solo_cards: "Maestro/Solo cards"
actions:
create_and_add_another: "Create and Add Another"
@@ -506,6 +507,8 @@ en:
encoding_error: "Please check the language setting of your source file and ensure it is saved with UTF-8 encoding"
unexpected_error: "Product Import encountered an unexpected error whilst opening the file: %{error_message}"
index:
notice: "Notice"
beta_notice: "This feature is still in beta: you may experience some errors while using it. Please don't hesitate to contact support."
select_file: Select a spreadsheet to upload
spreadsheet: Spreadsheet
choose_import_type: Select import type
@@ -1060,6 +1063,10 @@ en:
The displayed prices are only an estimate and calculated at the time the subscription is changed.
If you change prices or fees, orders will be updated, but the subscription will still display the old values.
not_in_open_and_upcoming_order_cycles_warning: "There are no open or upcoming order cycles for this product."
autocomplete:
name_or_sku: "NAME OR SKU"
quantity: "Quantity"
add: "Add"
details:
details: Details
invalid_error: Oops! Please fill in all of the required fields...
@@ -1082,15 +1089,18 @@ en:
saving: "SAVING"
saved: "SAVED"
product_already_in_order: This product has already been added to the order. Please edit the quantity directly.
stock:
insufficient_stock: "Insufficient stock available"
out_of_stock: "Out of Stock"
orders:
number: Number
confirm_edit: Are you sure you want to edit this order? Doing so may make it more difficult to automatically sync changes to the subscription in the future.
confirm_cancel_msg: Are you sure you want to cancel this subscription? This action cannot be undone.
cancel_failure_msg: 'Sorry, cancellation failed!'
confirm_pause_msg: Are you sure you want to pause this subscription?
pause_failure_msg: 'Sorry, pausing failed!'
confirm_unpause_msg: Are you sure you want to unpause this subscription?
unpause_failure_msg: 'Sorry, unpausing failed!'
confirm_cancel_msg: "Are you sure you want to cancel this subscription? This action cannot be undone."
cancel_failure_msg: "Sorry, cancellation failed!"
confirm_pause_msg: "Are you sure you want to pause this subscription?"
pause_failure_msg: "Sorry, pausing failed!"
confirm_unpause_msg: "If you have an open Order Cycle in this subscription's schedule, an order will be created for this customer. Are you sure you want to unpause this subscription?"
unpause_failure_msg: "Sorry, unpausing failed!"
confirm_cancel_open_orders_msg: "Some orders for this subscription are currently open. The customer has already been notified that the order will be placed. Would you like to cancel these order(s) or keep them?"
resume_canceled_orders_msg: "Some orders for this subscription can be resumed right now. You can resume them from the orders dropdown."
yes_cancel_them: Cancel them
@@ -1496,6 +1506,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using
email_confirm_shop_number_html: "Order confirmation <strong>#%{number}</strong>"
email_order_summary_item: "Item"
email_order_summary_quantity: "Qty"
email_order_summary_sku: "SKU"
email_order_summary_price: "Price"
email_order_summary_subtotal: "Subtotal:"
email_order_summary_total: "Total:"
@@ -3146,7 +3157,8 @@ See the %{link} to find out more about %{sitename}'s features and to start using
confirmation_pending: "Email confirmation is pending. We've sent a confirmation email to %{address}."
variants:
autocomplete:
producer_name: Producer
producer_name: "Producer"
unit: "Unit"
general_settings:
edit:
legal_settings: "Legal Settings"

View File

@@ -94,6 +94,7 @@ en_AU:
user_passwords:
spree_user:
updated_not_active: "Your password has been reset, but your email has not been confirmed yet."
updated: "Your password was changed successfully. You are now signed in."
send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes."
models:
order_cycle:
@@ -243,6 +244,7 @@ en_AU:
reset_password_token: Reset password token
expired: has expired, please request a new one
back_to_payments_list: "Back to Payments List"
maestro_or_solo_cards: "Maestro/Solo cards"
actions:
create_and_add_another: "Create and Add Another"
create: "Create"
@@ -451,6 +453,8 @@ en_AU:
encoding_error: "Please check the language setting of your source file and ensure it is saved with UTF-8 encoding"
unexpected_error: "Product Import encountered an unexpected error whilst opening the file: %{error_message}"
index:
notice: "Notice"
beta_notice: "This feature is still in beta: you may experience some errors while using it. Please don't hesitate to contact support."
select_file: Select a spreadsheet to upload
spreadsheet: Spreadsheet
choose_import_type: Select import type
@@ -1000,6 +1004,10 @@ en_AU:
The displayed prices are only an estimate and calculated at the time the subscription is changed.
If you change prices or fees, orders will be updated, but the subscription will still display the old values.
not_in_open_and_upcoming_order_cycles_warning: "There are no open or upcoming order cycles for this product."
autocomplete:
name_or_sku: "NAME OR SKU"
quantity: "Quantity"
add: "Add"
details:
details: Details
invalid_error: Oops! Please fill in all of the required fields...
@@ -1022,15 +1030,18 @@ en_AU:
saving: "SAVING"
saved: "SAVED"
product_already_in_order: This product has already been added to the order. Please edit the quantity directly.
stock:
insufficient_stock: "Insufficient stock available"
out_of_stock: "Out of Stock"
orders:
number: Number
confirm_edit: Are you sure you want to edit this order? Doing so may make it more difficult to automatically sync changes to the subscription in the future.
confirm_cancel_msg: Are you sure you want to cancel this subscription? This action cannot be undone.
cancel_failure_msg: 'Sorry, cancellation failed!'
confirm_pause_msg: Are you sure you want to pause this subscription?
pause_failure_msg: 'Sorry, pausing failed!'
confirm_unpause_msg: Are you sure you want to unpause this subscription?
unpause_failure_msg: 'Sorry, unpausing failed!'
confirm_cancel_msg: "Are you sure you want to cancel this subscription? This action cannot be undone."
cancel_failure_msg: "Sorry, cancellation failed!"
confirm_pause_msg: "Are you sure you want to pause this subscription?"
pause_failure_msg: "Sorry, pausing failed!"
confirm_unpause_msg: "If you have an open Order Cycle in this subscription's schedule, an order will be created for this customer. Are you sure you want to unpause this subscription?"
unpause_failure_msg: "Sorry, unpausing failed!"
confirm_cancel_open_orders_msg: "Some orders for this subscription are currently open. The customer has already been notified that the order will be placed. Would you like to cancel these order(s) or keep them?"
resume_canceled_orders_msg: "Some orders for this subscription can be resumed right now. You can resume them from the orders dropdown."
yes_cancel_them: Cancel them
@@ -1392,6 +1403,7 @@ en_AU:
email_confirm_shop_number_html: "Order confirmation <strong>#%{number}</strong>"
email_order_summary_item: "Item"
email_order_summary_quantity: "Qty"
email_order_summary_sku: "SKU"
email_order_summary_price: "Price"
email_order_summary_subtotal: "Subtotal:"
email_order_summary_total: "Total:"
@@ -2773,6 +2785,7 @@ en_AU:
inventory: Inventory
zipcode: Postcode
weight: Weight (per kg)
error_user_destroy_with_orders: "Users with completed orders may not be deleted"
actions:
update: "Update"
errors:
@@ -2981,7 +2994,8 @@ en_AU:
confirmation_pending: "Email confirmation is pending. We've sent a confirmation email to %{address}."
variants:
autocomplete:
producer_name: Producer
producer_name: "Producer"
unit: "Unit"
general_settings:
edit:
legal_settings: "Legal Settings"

View File

@@ -1000,6 +1000,10 @@ en_BE:
The displayed prices are only an estimate and calculated at the time the subscription is changed.
If you change prices or fees, orders will be updated, but the subscription will still display the old values.
not_in_open_and_upcoming_order_cycles_warning: "There are no open or upcoming order cycles for this product."
autocomplete:
name_or_sku: "NAME OR SKU"
quantity: "Quantity"
add: "Add"
details:
details: Details
invalid_error: Oops! Please fill in all of the required fields...
@@ -1022,15 +1026,16 @@ en_BE:
saving: "SAVING"
saved: "SAVED"
product_already_in_order: This product has already been added to the order. Please edit the quantity directly.
stock:
out_of_stock: "Out of Stock"
orders:
number: Number
confirm_edit: Are you sure you want to edit this order? Doing so may make it more difficult to automatically sync changes to the subscription in the future.
confirm_cancel_msg: Are you sure you want to cancel this subscription? This action cannot be undone.
cancel_failure_msg: 'Sorry, cancellation failed!'
confirm_pause_msg: Are you sure you want to pause this subscription?
pause_failure_msg: 'Sorry, pausing failed!'
confirm_unpause_msg: Are you sure you want to unpause this subscription?
unpause_failure_msg: 'Sorry, unpausing failed!'
confirm_cancel_msg: "Are you sure you want to cancel this subscription? This action cannot be undone."
cancel_failure_msg: "Sorry, cancellation failed!"
confirm_pause_msg: "Are you sure you want to pause this subscription?"
pause_failure_msg: "Sorry, pausing failed!"
unpause_failure_msg: "Sorry, unpausing failed!"
confirm_cancel_open_orders_msg: "Some orders for this subscription are currently open. The customer has already been notified that the order will be placed. Would you like to cancel these order(s) or keep them?"
resume_canceled_orders_msg: "Some orders for this subscription can be resumed right now. You can resume them from the orders dropdown."
yes_cancel_them: Cancel them
@@ -1392,6 +1397,7 @@ en_BE:
email_confirm_shop_number_html: "Order confirmation <strong>#%{number}</strong>"
email_order_summary_item: "Item"
email_order_summary_quantity: "Qty"
email_order_summary_sku: "SKU"
email_order_summary_price: "Price"
email_order_summary_subtotal: "Subtotal:"
email_order_summary_total: "Total:"
@@ -2981,7 +2987,8 @@ en_BE:
confirmation_pending: "Email confirmation is pending. We've sent a confirmation email to %{address}."
variants:
autocomplete:
producer_name: Producer
producer_name: "Producer"
unit: "Unit"
general_settings:
edit:
legal_settings: "Legal Settings"

View File

@@ -94,6 +94,7 @@ en_CA:
user_passwords:
spree_user:
updated_not_active: "Your password has been reset, but your email has not been confirmed yet."
updated: "Your password was changed successfully. You are now signed in."
send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes."
models:
order_cycle:
@@ -243,6 +244,7 @@ en_CA:
reset_password_token: Reset password token
expired: has expired, please request a new one
back_to_payments_list: "Back to Payments List"
maestro_or_solo_cards: "Maestro/Solo cards"
actions:
create_and_add_another: "Create and Add Another"
create: "Create"
@@ -451,6 +453,8 @@ en_CA:
encoding_error: "Please check the language setting of your source file and ensure it is saved with UTF-8 encoding"
unexpected_error: "Product Import encountered an unexpected error whilst opening the file: %{error_message}"
index:
notice: "Notice"
beta_notice: "This feature is still in beta: you may experience some errors while using it. Please don't hesitate to contact support."
select_file: Select a spreadsheet to upload
spreadsheet: Spreadsheet
choose_import_type: Select import type
@@ -1000,6 +1004,10 @@ en_CA:
The displayed prices are only an estimate and calculated at the time the subscription is changed.
If you change prices or fees, orders will be updated, but the subscription will still display the old values.
not_in_open_and_upcoming_order_cycles_warning: "There are no open or upcoming order cycles for this product."
autocomplete:
name_or_sku: "NAME OR SKU"
quantity: "Quantity"
add: "Add"
details:
details: Details
invalid_error: Oops! Please fill in all of the required fields...
@@ -1022,15 +1030,18 @@ en_CA:
saving: "SAVING"
saved: "SAVED"
product_already_in_order: This product has already been added to the order. Please edit the quantity directly.
stock:
insufficient_stock: "Insufficient stock available"
out_of_stock: "Out of Stock"
orders:
number: Number
confirm_edit: Are you sure you want to edit this order? Doing so may make it more difficult to automatically sync changes to the subscription in the future.
confirm_cancel_msg: Are you sure you want to cancel this subscription? This action cannot be undone.
cancel_failure_msg: 'Sorry, cancellation failed!'
confirm_pause_msg: Are you sure you want to pause this subscription?
pause_failure_msg: 'Sorry, pausing failed!'
confirm_unpause_msg: Are you sure you want to unpause this subscription?
unpause_failure_msg: 'Sorry, unpausing failed!'
confirm_cancel_msg: "Are you sure you want to cancel this subscription? This action cannot be undone."
cancel_failure_msg: "Sorry, cancellation failed!"
confirm_pause_msg: "Are you sure you want to pause this subscription?"
pause_failure_msg: "Sorry, pausing failed!"
confirm_unpause_msg: "If you have an open Order Cycle in this subscription's schedule, an order will be created for this customer. Are you sure you want to unpause this subscription?"
unpause_failure_msg: "Sorry, unpausing failed!"
confirm_cancel_open_orders_msg: "Some orders for this subscription are currently open. The customer has already been notified that the order will be placed. Would you like to cancel these order(s) or keep them?"
resume_canceled_orders_msg: "Some orders for this subscription can be resumed right now. You can resume them from the orders dropdown."
yes_cancel_them: Cancel them
@@ -1392,6 +1403,7 @@ en_CA:
email_confirm_shop_number_html: "Order confirmation <strong>#%{number}</strong>"
email_order_summary_item: "Item"
email_order_summary_quantity: "Qty"
email_order_summary_sku: "SKU"
email_order_summary_price: "Price"
email_order_summary_subtotal: "Subtotal:"
email_order_summary_total: "Total:"
@@ -2773,6 +2785,7 @@ en_CA:
inventory: Inventory
zipcode: Postal Code
weight: Weight (per kg)
error_user_destroy_with_orders: "Users with completed orders may not be deleted"
actions:
update: "Update"
errors:
@@ -2876,9 +2889,11 @@ en_CA:
new_shipping_method: "New Shipping Method"
back_to_shipping_methods_list: "Back to Shipping Methods List"
edit:
editing_shipping_method: "Editing Shipping Method"
new: "New"
back_to_shipping_methods_list: "Back to Shipping Methods List"
form:
categories: "Categories"
zones: "Zones"
both: "Both"
front_end: "Front End"
@@ -2909,6 +2924,7 @@ en_CA:
error_saving_payment: Error saving payment
submitting_payment: Submitting payment...
products:
image_upload_error: "The product image was not recognised. Please upload an image in PNG or JPG format."
new:
title: 'New Product'
unit_name_placeholder: 'eg. bunches'
@@ -2978,7 +2994,8 @@ en_CA:
confirmation_pending: "Email confirmation is pending. We've sent a confirmation email to %{address}."
variants:
autocomplete:
producer_name: Producer
producer_name: "Producer"
unit: "Unit"
general_settings:
edit:
legal_settings: "Legal Settings"
@@ -3008,6 +3025,7 @@ en_CA:
line_item:
insufficient_stock: "Insufficient stock available, only %{on_hand} remaining"
out_of_stock: "Out of Stock"
unavailable_item: "Currently unavailable"
shipment_states:
backorder: backorder
partial: partial
@@ -3027,6 +3045,8 @@ en_CA:
invalid: invalid
order_mailer:
cancel_email:
customer_greeting: "Hi %{name}!"
instructions: "Your order has been CANCELED. Please retain this cancellation information for your records."
order_summary_canceled: "Order Summary [CANCELED]"
subject: "Cancellation of Order"
confirm_email:

View File

@@ -94,6 +94,7 @@ en_GB:
user_passwords:
spree_user:
updated_not_active: "Your password has been reset, but your email has not been confirmed yet."
updated: "Your password was changed successfully. You are now signed in."
send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes."
models:
order_cycle:
@@ -243,6 +244,7 @@ en_GB:
reset_password_token: Reset password
expired: has expired, please request a new one
back_to_payments_list: "Back to Payments List"
maestro_or_solo_cards: "Maestro/Solo cards"
actions:
create_and_add_another: "Create and Add Another"
create: "Create"
@@ -451,6 +453,8 @@ en_GB:
encoding_error: "Please check the language setting of your source file and ensure it is saved with UTF-8 encoding"
unexpected_error: "Product Import encountered an unexpected error whilst opening the file: %{error_message}"
index:
notice: "Notice"
beta_notice: "This feature is still in beta: you may experience some errors while using it. Please don't hesitate to contact support."
select_file: Select a spreadsheet to upload
spreadsheet: Spreadsheet
choose_import_type: Select import type
@@ -1000,6 +1004,10 @@ en_GB:
The displayed prices are only an estimate and calculated at the time the subscription is changed.
If you change prices or fees, orders will be updated, but the subscription will still display the old values.
not_in_open_and_upcoming_order_cycles_warning: "There are no open or upcoming order cycles for this product."
autocomplete:
name_or_sku: "NAME OR SKU"
quantity: "Quantity"
add: "Add"
details:
details: Details
invalid_error: Oops! Please fill in all of the required fields...
@@ -1022,15 +1030,18 @@ en_GB:
saving: "SAVING"
saved: "SAVED"
product_already_in_order: This product has already been added to the order. Please edit the quantity directly.
stock:
insufficient_stock: "Insufficient stock available"
out_of_stock: "Out of Stock"
orders:
number: Number
confirm_edit: Are you sure you want to edit this order? Doing so may make it more difficult to automatically sync changes to the subscription in the future.
confirm_cancel_msg: Are you sure you want to cancel this subscription? This action cannot be undone.
cancel_failure_msg: 'Sorry, cancellation failed!'
confirm_pause_msg: Are you sure you want to pause this subscription?
pause_failure_msg: 'Sorry, pausing failed!'
confirm_unpause_msg: Are you sure you want to unpause this subscription?
unpause_failure_msg: 'Sorry, unpausing failed!'
confirm_cancel_msg: "Are you sure you want to cancel this subscription? This action cannot be undone."
cancel_failure_msg: "Sorry, cancellation failed!"
confirm_pause_msg: "Are you sure you want to pause this subscription?"
pause_failure_msg: "Sorry, pausing failed!"
confirm_unpause_msg: "If you have an open Order Cycle in this subscription's schedule, an order will be created for this customer. Are you sure you want to unpause this subscription?"
unpause_failure_msg: "Sorry, unpausing failed!"
confirm_cancel_open_orders_msg: "Some orders for this subscription are currently open. The customer has already been notified that the order will be placed. Would you like to cancel these order(s) or keep them?"
resume_canceled_orders_msg: "Some orders for this subscription can be resumed right now. You can resume them from the orders dropdown."
yes_cancel_them: Cancel them
@@ -1368,7 +1379,7 @@ en_GB:
email_confirmed: "Thank you for confirming your email address."
email_registered: "is now part of"
email_userguide_html: "The User Guide with detailed support for setting up your Producer or Hub is here: %{link}"
email_admin_html: "You can manage your account by logging into the %{link} or by clicking on the cog in the top right hand side of the homepage, and selecting Administration."
email_admin_html: "You can manage your account by logging into the %{link} or by clicking on 'Profile' in the top right hand side of the homepage, and selecting Administration."
email_community_html: "We also have an online forum for community discussion related to OFN software and the unique challenges of running a food enterprise. You are encouraged to join in. We are constantly evolving and your input into this forum will shape what happens next. %{link}"
join_community: "Join the community"
email_confirmation_activate_account: "Before we can activate your new account, we need to confirm your email address."
@@ -1392,6 +1403,7 @@ en_GB:
email_confirm_shop_number_html: "Order confirmation <strong>#%{number}</strong>"
email_order_summary_item: "Item"
email_order_summary_quantity: "Qty"
email_order_summary_sku: "Product Code"
email_order_summary_price: "Price"
email_order_summary_subtotal: "Subtotal:"
email_order_summary_total: "Total:"
@@ -2779,6 +2791,7 @@ en_GB:
inventory: Inventory
zipcode: Postcode
weight: Weight (per kg)
error_user_destroy_with_orders: "Users with completed orders may not be deleted"
actions:
update: "Update"
errors:
@@ -2987,7 +3000,8 @@ en_GB:
confirmation_pending: "Email confirmation is pending. We've sent a confirmation email to %{address}."
variants:
autocomplete:
producer_name: Producer
producer_name: "Producer"
unit: "Unit"
general_settings:
edit:
legal_settings: "Legal Settings"

View File

@@ -987,6 +987,10 @@ en_US:
The displayed prices are only an estimate and calculated at the time the subscription is changed.
If you change prices or fees, orders will be updated, but the subscription will still display the old values.
not_in_open_and_upcoming_order_cycles_warning: "There are no open or upcoming order cycles for this product."
autocomplete:
name_or_sku: "NAME OR SKU"
quantity: "Quantity"
add: "Add"
details:
details: Details
invalid_error: Oops! Please fill in all of the required fields...
@@ -1007,15 +1011,16 @@ en_US:
saving: "SAVING"
saved: "SAVED"
product_already_in_order: This product has already been added to the order. Please edit the quantity directly.
stock:
out_of_stock: "Out of Stock"
orders:
number: Number
confirm_edit: Are you sure you want to edit this order? Doing so may make it more difficult to automatically sync changes to the subscription in the future.
confirm_cancel_msg: Are you sure you want to cancel this subscription? This action cannot be undone.
cancel_failure_msg: 'Sorry, cancellation failed!'
confirm_pause_msg: Are you sure you want to pause this subscription?
pause_failure_msg: 'Sorry, pausing failed!'
confirm_unpause_msg: Are you sure you want to unpause this subscription?
unpause_failure_msg: 'Sorry, unpausing failed!'
confirm_cancel_msg: "Are you sure you want to cancel this subscription? This action cannot be undone."
cancel_failure_msg: "Sorry, cancellation failed!"
confirm_pause_msg: "Are you sure you want to pause this subscription?"
pause_failure_msg: "Sorry, pausing failed!"
unpause_failure_msg: "Sorry, unpausing failed!"
confirm_cancel_open_orders_msg: "Some orders for this subscription are currently open. The customer has already been notified that the order will be placed. Would you like to cancel these order(s) or keep them?"
resume_canceled_orders_msg: "Some orders for this subscription can be resumed right now. You can resume them from the orders dropdown."
yes_cancel_them: Cancel them
@@ -1369,6 +1374,7 @@ en_US:
email_confirm_shop_number_html: "Order confirmation <strong>#%{number}</strong>"
email_order_summary_item: "Item"
email_order_summary_quantity: "Qty"
email_order_summary_sku: "SKU"
email_order_summary_price: "Price"
email_order_summary_subtotal: "Subtotal:"
email_order_summary_total: "Total:"
@@ -2934,7 +2940,8 @@ en_US:
confirmation_pending: "Email confirmation is pending. We've sent a confirmation email to %{address}."
variants:
autocomplete:
producer_name: Producer
producer_name: "Producer"
unit: "Unit"
general_settings:
edit:
legal_settings: "Legal Settings"

View File

@@ -94,6 +94,7 @@ en_ZA:
user_passwords:
spree_user:
updated_not_active: "Your password has been reset, but your email has not been confirmed yet."
updated: "Your password was changed successfully. You are now signed in."
send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes."
models:
order_cycle:
@@ -1000,6 +1001,10 @@ en_ZA:
The displayed prices are only an estimate and calculated at the time the subscription is changed.
If you change prices or fees, orders will be updated, but the subscription will still display the old values.
not_in_open_and_upcoming_order_cycles_warning: "There are no open or upcoming order cycles for this product."
autocomplete:
name_or_sku: "NAME OR SKU"
quantity: "Quantity"
add: "Add"
details:
details: Details
invalid_error: Oops! Please fill in all of the required fields...
@@ -1022,15 +1027,18 @@ en_ZA:
saving: "SAVING"
saved: "SAVED"
product_already_in_order: This product has already been added to the order. Please edit the quantity directly.
stock:
insufficient_stock: "Insufficient stock available"
out_of_stock: "Out of Stock"
orders:
number: Number
confirm_edit: Are you sure you want to edit this order? Doing so may make it more difficult to automatically sync changes to the subscription in the future.
confirm_cancel_msg: Are you sure you want to cancel this subscription? This action cannot be undone.
cancel_failure_msg: 'Sorry, cancellation failed!'
confirm_pause_msg: Are you sure you want to pause this subscription?
pause_failure_msg: 'Sorry, pausing failed!'
confirm_unpause_msg: Are you sure you want to unpause this subscription?
unpause_failure_msg: 'Sorry, unpausing failed!'
confirm_cancel_msg: "Are you sure you want to cancel this subscription? This action cannot be undone."
cancel_failure_msg: "Sorry, cancellation failed!"
confirm_pause_msg: "Are you sure you want to pause this subscription?"
pause_failure_msg: "Sorry, pausing failed!"
confirm_unpause_msg: "If you have an open Order Cycle in this subscription's schedule, an order will be created for this customer. Are you sure you want to unpause this subscription?"
unpause_failure_msg: "Sorry, unpausing failed!"
confirm_cancel_open_orders_msg: "Some orders for this subscription are currently open. The customer has already been notified that the order will be placed. Would you like to cancel these order(s) or keep them?"
resume_canceled_orders_msg: "Some orders for this subscription can be resumed right now. You can resume them from the orders dropdown."
yes_cancel_them: Cancel them
@@ -1392,6 +1400,7 @@ en_ZA:
email_confirm_shop_number_html: "Order confirmation <strong>#%{number}</strong>"
email_order_summary_item: "Item"
email_order_summary_quantity: "Qty"
email_order_summary_sku: "SKU"
email_order_summary_price: "Price"
email_order_summary_subtotal: "Subtotal:"
email_order_summary_total: "Total:"
@@ -2674,9 +2683,9 @@ en_ZA:
check_for_spree_alerts: "Check for Spree alerts"
currency_decimal_mark: "Currency decimal mark"
currency_settings: "Currency Settings"
currency_symbol_position: Put "currency symbol before or after pound amount?"
currency_symbol_position: Put "currency symbol before or after Rand amount?"
currency_thousands_separator: "Currency thousands separator"
hide_cents: "Hide pence"
hide_cents: "Hide cents"
display_currency: "Display currency"
choose_currency: "Choose Currency"
mail_method_settings: "Mail Method Settings"
@@ -2722,7 +2731,7 @@ en_ZA:
default_tax: "Default Tax"
default_tax_zone: "Default Tax Zone"
country_based: "Country Based"
state_based: "County Based"
state_based: "Province Based"
countries: "Countries"
listing_countries: "Listing Countries"
iso_name: "ISO Name"
@@ -2780,6 +2789,7 @@ en_ZA:
inventory: Inventory
zipcode: Postcode
weight: Weight (per kg)
error_user_destroy_with_orders: "Users with completed orders may not be deleted"
actions:
update: "Update"
errors:
@@ -2988,7 +2998,8 @@ en_ZA:
confirmation_pending: "Email confirmation is pending. We've sent a confirmation email to %{address}."
variants:
autocomplete:
producer_name: Producer
producer_name: "Producer"
unit: "Unit"
general_settings:
edit:
legal_settings: "Legal Settings"

View File

@@ -1003,6 +1003,10 @@ es:
Los precios mostrados son solo una estimación y se calculan en el momento en que se cambia la suscripción.
Si cambias precios o comisiones, los pedidos se actualizarán pero la suscripción seguirá mostrando los valores anteriores.
not_in_open_and_upcoming_order_cycles_warning: "No hay ciclos de pedidos abiertos o próximos para este producto."
autocomplete:
name_or_sku: "NOMBRE O CÓDIGO SKU"
quantity: "Cantidad"
add: "Añadir"
details:
details: Detalles
invalid_error: Ups! Por favor complete todos los campos requeridos ...
@@ -1025,15 +1029,18 @@ es:
saving: "GUARDANDO"
saved: "GUARDADO"
product_already_in_order: Este producto ya ha sido agregado a la orden. Por favor edite la cantidad directamente.
stock:
insufficient_stock: "Stock disponible insuficiente"
out_of_stock: "Agotado"
orders:
number: Número
confirm_edit: ¿Seguro que quieres editar esta orden? Si lo hace, puede ser más difícil sincronizar automáticamente los cambios a la suscripción en el futuro.
confirm_cancel_msg: ¿Seguro que quieres cancelar esta suscripción? Esta acción no se puede deshacer.
cancel_failure_msg: 'Lo sentimos, ¡la cancelación falló!'
confirm_pause_msg: ¿Seguro que quieres pausar esta suscripción?
pause_failure_msg: 'Lo sentimos, pausar falló!'
confirm_unpause_msg: ¿Seguro que quieres reanudar esta suscripción?
unpause_failure_msg: 'Lo sentimos, ¡no se pudo reanudar!'
confirm_cancel_msg: "¿Seguro que quieres cancelar esta suscripción? Esta acción no se puede deshacer."
cancel_failure_msg: "Lo sentimos, ¡la cancelación falló!"
confirm_pause_msg: "¿Seguro que quieres pausar esta suscripción?"
pause_failure_msg: "Lo sentimos, pausar falló!"
confirm_unpause_msg: "Si tiene un ciclo de pedido abierto en la programación de esta suscripción, se creará un pedido para esta consumidora. ¿Estás seguro de que deseas anular la pausa de esta suscripción?"
unpause_failure_msg: "Lo sentimos, ¡no se pudo reanudar!"
confirm_cancel_open_orders_msg: "Algunas órdenes para esta suscripción están actualmente abiertas. El cliente ya ha sido notificado de que se realizará el pedido. ¿Desea cancelar estos pedidos o conservarlos?"
resume_canceled_orders_msg: "Algunos pedidos de esta suscripción se pueden reanudar en este momento. Puede reanudarlos desde el menú desplegable de pedidos."
yes_cancel_them: Cancelarlos
@@ -1395,6 +1402,7 @@ es:
email_confirm_shop_number_html: "Confirmación del pedido <strong>#%{number}</strong>"
email_order_summary_item: "Artículo"
email_order_summary_quantity: "Cantidad"
email_order_summary_sku: "SKU"
email_order_summary_price: "Precio"
email_order_summary_subtotal: "Subtotal:"
email_order_summary_total: "Total:"
@@ -2989,7 +2997,8 @@ es:
confirmation_pending: "La confirmación por correo electrónico está pendiente. Hemos enviado un correo electrónico de confirmación a %{address}."
variants:
autocomplete:
producer_name: Productora
producer_name: "Productora"
unit: "Unidad"
general_settings:
edit:
legal_settings: "Configuraciones legales"

View File

@@ -5,9 +5,9 @@ fr:
spree/order:
payment_state: Statut du paiement
shipment_state: Statut livraison
completed_at: 'Passée à '
completed_at: Date
number: N° commande
state: Etat
state: Statut
email: Email acheteur
spree/payment:
amount: Montant
@@ -216,7 +216,7 @@ fr:
unused: inutilisé
admin_and_handling: Frais si par commande
profile: Profil
supplier_only: Uniquement Producteur
supplier_only: ne gère pas de boutique
has_shopfront: gère une boutique
weight: Poids
volume: Volume
@@ -244,6 +244,7 @@ fr:
reset_password_token: La demande de réinitialisation du mot de passe
expired: a expiré, veuillez faire une nouvelle demande.
back_to_payments_list: "Retour à la liste des paiements"
maestro_or_solo_cards: "Cartes Maestro/Solo"
actions:
create_and_add_another: "Créer et ajouter nouveau"
create: "Créer"
@@ -277,7 +278,7 @@ fr:
shipping_method: Option d'expédition
shop: Boutique
sku: Référence produit
status_state: Etat
status_state: Statut
tags: Tags
variant: Variante
weight: Poids
@@ -452,6 +453,8 @@ fr:
encoding_error: "Veuillez vérifier le paramètre de langue de votre code source et vous assurer qu'il est encodé en UTF-8"
unexpected_error: "L'import de fichier produits à rencontré une erreur inconnue à l'ouverture du fichier : %{error_message}"
index:
notice: "Notice"
beta_notice: "Cette fonctionnalité est en mode bêta : il est possible que vous rencontriez des erreurs en l'utilisant. N'hésitez pas à contacter le support utilisateurs."
select_file: Sélectionner le fichier (tableur sous format csv) à importer
spreadsheet: Tableur csv
choose_import_type: Choisir le type d'import
@@ -555,7 +558,7 @@ fr:
tip: "Utilisez cette page pour changer les quantités d'un produit sur plusieurs commandes. Les produits peuvent aussi être supprimés de toutes les commandes, si nécessaire."
shared: "Ressource partagée?"
order_no: "N° commande"
order_date: "Passée le"
order_date: "Date"
max: "Max"
product_unit: "Produit: Unité"
weight_volume: "Poids/Volume"
@@ -725,7 +728,7 @@ fr:
no_rules_yet: Aucune règle ne concerne ce tag pour le moment
for_customers_tagged: 'Pour les acheteurs avec le tag:'
add_new_rule: '+ Ajouter une nouvelle règle'
add_new_tag: '+ Ajouter un nouveau tag'
add_new_tag: '+ Ajouter une règle pour un autre tag'
users:
email_confirmation_notice_html: "L'email de confirmation n'a pas encore été validé. Il a été envoyé à %{email}."
resend: Renvoyer
@@ -923,7 +926,7 @@ fr:
totals_by_supplier: Totaux Cycle de Vente par Hub Distributeur pour chaque Producteur
customer_totals: Totaux Cycle de Vente par Acheteur
all_products: Tous les produits
inventory: Catalogue boutique (en stock)
inventory: Produits disponibles (stock positif)
lettuce_share: LettuceShare
mailing_list: Liste de mails
addresses: Adresses
@@ -947,7 +950,7 @@ fr:
customers:
name: Acheteurs
products_and_inventory:
name: Produits et Catalogues
name: Listings produits
sales_total:
name: Total des Ventes
description: Total des Ventes pour toutes les Commandes
@@ -1002,6 +1005,10 @@ fr:
Les prix affichés ne sont qu'une estimation calculée au moment de la dernière modification de l'abonnement.
Si vous modifiez les prix ou marges et commissions appliquées, les commandes seront mises à jour, mais l'abonnement affichera toujours les anciennes valeurs.
not_in_open_and_upcoming_order_cycles_warning: "Il n'y a pas de cycle de vente ouvert ou à venir pour ce produit."
autocomplete:
name_or_sku: "NOM OU REF PRODUIT"
quantity: "Quantité"
add: "Ajouter"
details:
details: Informations
invalid_error: Oups! Veuillez remplir tous les champs obligatoires...
@@ -1024,15 +1031,18 @@ fr:
saving: "En cours d'enregistrement"
saved: "Enregistré"
product_already_in_order: Ce produit a déjà été ajouté à la commande. Veuillez directement modifier la quantité.
stock:
insufficient_stock: "Stock disponible insuffisant"
out_of_stock: "En rupture de stock"
orders:
number: Nombre
number: N° commande
confirm_edit: Voulez-vous vraiment modifier cette commande? Si vous poursuivez, la synchronisation automatique des modifications de l'abonnement pourrait être plus difficile à l'avenir.
confirm_cancel_msg: Voulez-vous vraiment annuler cet abonnement? Cette action sera irréversible.
cancel_failure_msg: 'Désolé, l''annulation a échoué!'
confirm_pause_msg: Voulez-vous vraiment mettre en pause cet abonnement?
pause_failure_msg: 'Désolé, la mise en pause a échoué!'
confirm_unpause_msg: Voulez-vous vraiment annuler la mise en pause de cet abonnement?
unpause_failure_msg: 'Désolé, l''annulation de la mise en pause a échoué!'
confirm_cancel_msg: "Voulez-vous vraiment annuler cet abonnement? Cette action sera irréversible."
cancel_failure_msg: "Désolé, l'annulation a échoué!"
confirm_pause_msg: "Voulez-vous vraiment mettre en pause cet abonnement?"
pause_failure_msg: "Désolé, la mise en pause a échoué!"
confirm_unpause_msg: "Si vous avez un cycle de vente ouvert pour ce rythme d'abonnement, une commande sera créée pour cet acheteur. Êtes-vous sûr de vouloir relancer cet abonnement ?"
unpause_failure_msg: "Désolé, l'annulation de la mise en pause a échoué!"
confirm_cancel_open_orders_msg: "Cet abonnement a des commandes ouvertes. Les acheteurs ont été notifiés que leur commande allait être passée. Voulez-vous annulez ces commandes ou les conserver?"
resume_canceled_orders_msg: "Certaines commandes pour cet abonnement peuvent être réouvertes dès maintenant. Vous pouvez les réouvrir depuis la liste des commandes."
yes_cancel_them: Les annuler
@@ -1394,6 +1404,7 @@ fr:
email_confirm_shop_number_html: "Confirmation de commande <strong>#%{number}</strong>"
email_order_summary_item: "Produit"
email_order_summary_quantity: "Qté"
email_order_summary_sku: "Référence Produit"
email_order_summary_price: "Prix"
email_order_summary_subtotal: "Sous-total:"
email_order_summary_total: "Total:"
@@ -1847,7 +1858,7 @@ fr:
transaction_date: "Date"
payment_state: "Statut du paiement"
shipping_state: "Statut de la livraison"
value: "Nb unités"
value: "Montant"
balance_due: "Montant dû"
credit: "Créditer"
Paid: "Payé"
@@ -2397,13 +2408,13 @@ fr:
description: Description
resolve: Résoudre
tag_rules:
shipping_method_tagged_top: "Les méthodes de livraison taggées"
shipping_method_tagged_top: "Les méthodes de livraison taguées"
shipping_method_tagged_bottom: "sont:"
payment_method_tagged_top: "Les méthodes de payments taguées"
payment_method_tagged_bottom: "sont:"
order_cycle_tagged_top: "Les cycles de vente taggés"
order_cycle_tagged_top: "Les cycles de vente tagués"
order_cycle_tagged_bottom: "sont:"
inventory_tagged_top: "Les variantes du catalogue boutique taggées"
inventory_tagged_top: "Les variantes du catalogue boutique taguées"
inventory_tagged_bottom: "sont:"
new_tag_rule_dialog:
select_rule_type: "Choisir le type de règle:"
@@ -2422,7 +2433,7 @@ fr:
address: "adresse"
adjustments: "ajustements"
awaiting_return: "attente du retour"
canceled: "annulé"
canceled: "annulée"
cart: "panier"
complete: "finalisée"
confirm: "confirmer"
@@ -2512,8 +2523,8 @@ fr:
stock_reset: Les niveaux de stock ont été réinitiatlisés (valeurs par défaut)
tag_rules:
show_hide_variants: 'Afficher ou Masquer les variantes dans ma boutique'
show_hide_shipping: 'Afficher ou Montrer les méthodes de livraison lors de la finalisation de commande'
show_hide_payment: 'Afficher ou Montrer les méthodes de paiement lors de la finalisation de commande'
show_hide_shipping: 'Afficher ou Masquer les méthodes de livraison lors de la finalisation de commande'
show_hide_payment: 'Afficher ou Masquer les méthodes de paiement lors de la finalisation de commande'
show_hide_order_cycles: 'Afficher ou Masquer les cycles de vente de ma boutique'
visible: VISIBLE
not_visible: INVISIBLE
@@ -2548,7 +2559,7 @@ fr:
close_date_not_set: Date de fin non renseignée
spree:
users:
order: "Commandes à venir"
order: "Commande"
registration:
welcome_to_ofn: "Bienvenue sur Open Food France !"
signup_or_login: "Commencez par vous inscrire (ou connexion)"
@@ -2596,7 +2607,7 @@ fr:
tax_category_name: "TVA applicable"
total_amount: "€ total"
invalid_filter_parameters: "Les filtres sélectionnés pour ce rapport sont invalides."
order: "Commandes à venir"
order: "Commande"
distribution: "Distribution"
order_details: "Détails de la commande"
customer_details: "Informations acheteur"
@@ -2840,8 +2851,8 @@ fr:
payment_state: "Statut du Paiement"
shipment_state: "Statut livraison"
completed_at: "Date"
number: "Nombre"
state: "Etat"
number: "N° commande"
state: "Statut"
email: "Email acheteur"
invoice:
issued_on: "Editée le"
@@ -2995,7 +3006,8 @@ fr:
confirmation_pending: "L'email de confirmation n'a pas encore été validé. Il a été envoyé à %{address}."
variants:
autocomplete:
producer_name: Producteur
producer_name: "Producteur"
unit: "Unité"
general_settings:
edit:
legal_settings: "Configuration légales"
@@ -3058,7 +3070,7 @@ fr:
address: adresse
adjustments: ajustements
awaiting_return: attente du retour
canceled: annulé
canceled: annulée
cart: panier
complete: finalisée
confirm: confirmer
@@ -3114,7 +3126,7 @@ fr:
closed: Fermée
until: Jusqu'à
past_orders:
order: Commandes à venir
order: Commande
shop: Boutique
completed_at: Date
items: Produits
@@ -3125,7 +3137,7 @@ fr:
default?: Carte utilisée par défaut?
delete?: Supprimer?
cards:
authorised_shops: Boutiques autorisées.
authorised_shops: Boutiques autorisées
authorised_shops_popover: Voilà la liste des boutiques que vous avez autorisées à débiter votre carte de paiement par défaut dans le cadre de vos abonnements en cours (commandes récurrentes). Les informations concernant votre carte de paiement sont sécurisées et ne sont pas accessibles par le gérant de la boutique. Vous recevrez systématiquement une notification avant tout débit sur votre carte.
saved_cards_popover: Voilà la liste des cartes de paiement que vous avez enregistrées. Votre carte par défaut sera automatiquement sélectionnée au moment de la finalisation d'une commande, et pourra être débitée par les boutiques auxquelles vous avez donné cette autorisation (voir à droite).
authorised_shops:

View File

@@ -1001,6 +1001,10 @@ fr_BE:
Les prix affichés ne sont qu'une estimation calculée au moment de la dernière modification de l'abonnement.
Si vous modifiez les prix ou marges et commissions appliquées, les commandes seront mises à jour, mais l'abonnement affichera toujours les anciennes valeurs.
not_in_open_and_upcoming_order_cycles_warning: "Aucun cycle de vente actif ou futur pour ce produit."
autocomplete:
name_or_sku: "NOM OU NUMÉRO D'ARTICLE "
quantity: "Nb commandé"
add: "Ajouter"
details:
details: Informations
invalid_error: Oups! Veuillez remplir tous les champs obligatoires...
@@ -1023,15 +1027,16 @@ fr_BE:
saving: "En cours d'enregistrement"
saved: "Enregistré"
product_already_in_order: Ce produit a déjà été ajouté à la commande. Veuillez directement modifier la quantité.
stock:
out_of_stock: "Pas en stock"
orders:
number: Nombre
confirm_edit: Voulez-vous vraiment modifier cette commande? Si vous poursuivez, la synchronisation automatique des modifications de l'abonnement pourrait être plus difficile à l'avenir.
confirm_cancel_msg: Voulez-vous vraiment annuler cet abonnement? Cette action sera irréversible.
cancel_failure_msg: 'Désolé, l''annulation a échoué!'
confirm_pause_msg: Voulez-vous vraiment mettre en pause cet abonnement?
pause_failure_msg: 'Désolé, la mise en pause a échoué!'
confirm_unpause_msg: Voulez-vous vraiment annuler la mise en pause de cet abonnement?
unpause_failure_msg: 'Désolé, l''annulation de la mise en pause a échoué!'
confirm_cancel_msg: "Voulez-vous vraiment annuler cet abonnement? Cette action sera irréversible."
cancel_failure_msg: "Désolé, l'annulation a échoué!"
confirm_pause_msg: "Voulez-vous vraiment mettre en pause cet abonnement?"
pause_failure_msg: "Désolé, la mise en pause a échoué!"
unpause_failure_msg: "Désolé, l'annulation de la mise en pause a échoué!"
confirm_cancel_open_orders_msg: "Cet abonnement a des commandes ouvertes. Les acheteurs ont été notifiés que leur commande allait être passée. Voulez-vous annulez ces commandes ou les conserver?"
resume_canceled_orders_msg: "Certaines commandes pour cet abonnement peuvent être réouvertes dès maintenant. Vous pouvez les réouvrir depuis la liste des commandes."
yes_cancel_them: Les annuler
@@ -1393,6 +1398,7 @@ fr_BE:
email_confirm_shop_number_html: "Confirmation de commande <strong>#%{number}</strong>"
email_order_summary_item: "Produit"
email_order_summary_quantity: "Qté"
email_order_summary_sku: "Référence produit"
email_order_summary_price: "Prix"
email_order_summary_subtotal: "Sous-total:"
email_order_summary_total: "Total:"
@@ -2995,7 +3001,8 @@ fr_BE:
confirmation_pending: "L'email de confirmation n'a pas encore été validé. Il a été envoyé à %{address}."
variants:
autocomplete:
producer_name: Producteur
producer_name: "Producteur"
unit: "Unité"
general_settings:
edit:
legal_settings: "Configuration légales"

View File

@@ -14,7 +14,9 @@ fr_CA:
spree/product:
primary_taxon: "Catégorie Produit"
supplier: "Fournisseur"
shipping_category_id: "Condition de transport"
variant_unit: "Unité"
variant_unit_name: "Unité de la variante"
order_cycle:
orders_close_at: Date de fermeture
errors:
@@ -75,6 +77,8 @@ fr_CA:
user_confirmations:
spree_user:
send_instructions: "Un email a été envoyé avec des instructions pour confirmer votre adresse email. Vérifiez votre boite mail!"
confirmation_sent: "L'email de confirmation a bien été envoyé"
confirmation_not_sent: "Une erreur est survenue lors de l'envoi de l'email de confirmation"
user_registrations:
spree_user:
signed_up_but_unconfirmed: "Un message avec un lien de confirmation a été envoyé à l'adresse email indiquée. Veuillez cliquer sur ce lien pour activer votre compte."
@@ -86,9 +90,12 @@ fr_CA:
Créez votre compte ou réinitialisez votre mot de passe.
unconfirmed: "Veuillez valider le lien envoyé par email pour pouvoir continuer."
already_registered: "Cet email existe déjà. Veuillez vous connecter ou utiliser une autre adresse email."
success:
logged_in_succesfully: "Vous êtes désormais connecté !"
user_passwords:
spree_user:
updated_not_active: "Votre mot de passe a été mis à jour, mais votre email n'a pas encore été confirmé."
updated: "Votre mot de passer a été changé avec succès. Vous êtes maintenant connecté(e)."
send_instructions: "Un email a été envoyé avec des instructions pour confirmer votre adresse email. Vérifiez votre boite mail!"
models:
order_cycle:
@@ -238,6 +245,7 @@ fr_CA:
reset_password_token: La demande de réinitialisation du mot de passe
expired: a expiré, veuillez faire une nouvelle demande.
back_to_payments_list: "Retour à la liste des paiements"
maestro_or_solo_cards: "Cartes Maestro/Solo"
actions:
create_and_add_another: "Créer et ajouter nouveau"
create: "Créer"
@@ -322,6 +330,7 @@ fr_CA:
invoice_settings:
edit:
title: "Paramètres de facturation"
enable_invoices?: "Autoriser l'émission de factures ?"
invoice_style2?: "Utiliser le modèle de facture alternatif qui détaille le montant de Taxe agrégé par taux et l'information du taux de taxe par produit (pas adapté pour les instances affichant les prix HT)"
enable_receipt_printing?: "Afficher les options d'impression de tickets de caisse dans le menu déroulant des commandes?"
stripe_connect_settings:
@@ -390,6 +399,7 @@ fr_CA:
calculator: "Calculateur"
calculator_values: "Valeurs applicables"
search: "Chercher"
name_placeholder: "ex.: marge de conditionnement"
enterprise_groups:
index:
new_button: Nouveau groupe d'entreprises
@@ -419,6 +429,7 @@ fr_CA:
property_name: Nom du label
inherited_property: Label producteur appliqué par défaut
variants:
infinity: "Infini"
to_order_tip: "Les articles fabriqués sur commande n'ont pas un niveau de stock défini, comme des pains faits à la main."
group_buy_options: "Options d'achat par lot"
back_to_products_list: "Retour à la liste produits"
@@ -443,6 +454,8 @@ fr_CA:
encoding_error: "Veuillez vérifier le paramètre de langue de votre code source et vous assurer qu'il est encodé en UTF-8"
unexpected_error: "L'import de fichier produits à rencontré une erreur inconnue à l'ouverture du fichier : %{error_message}"
index:
notice: "Notice"
beta_notice: "Cette fonctionnalité est en mode bêta : il est possible que vous rencontriez des erreurs en l'utilisant. N'hésitez pas à contacter le support utilisateurs."
select_file: Sélectionner une feuille de calcul à uploader
spreadsheet: Feuille de calcul
choose_import_type: Choisir le type d'import
@@ -648,6 +661,8 @@ fr_CA:
permalink_tip: "Ce nom permanent est utilisé pour créer l'url de votre boutique: %{link}ma-boutique/shop"
link_to_front: Lien URL de la boutique
link_to_front_tip: C'est le lien qui permet d'accéder en direct à votre boutique sur Open Food Network.
ofn_uid: ID OFN
ofn_uid_tip: L'identifiant unique pour les comptes entreprises sur Open Food Network.
shipping_methods:
name: Nom
applies: S'applique?
@@ -677,6 +692,8 @@ fr_CA:
shopfront_message_placeholder: >
Vous pouvez ici expliquer à vos acheteurs comment votre boutique fonctionne.
Ce texte s'affiche dans votre boutique, au-dessus de la liste de produits.
shopfront_message_link_tooltip: "Insérer / modifier un lien"
shopfront_message_link_prompt: "Veuillez entrer l'URL à insérer"
shopfront_closed_message: "Message d'accueil de la boutique fermée"
shopfront_closed_message_placeholder: >
Vous pouvez ici expliquer à vos acheteurs pourquoi votre boutique est
@@ -806,6 +823,9 @@ fr_CA:
user_already_exists: "Le compte existe déjà"
error: "Un problème est survenu"
order_cycles:
loading_flash:
loading_order_cycles: Cycles de vente en cours de chargement
loading: Chargement en cours...
edit:
advanced_settings: Paramétrages avancés
update_and_close: Mettre à jour et fermer
@@ -824,6 +844,7 @@ fr_CA:
add_distributor: 'Ajouter un distributeur'
advanced_settings:
title: Paramétrages avancés
choose_product_tip: Vous pouvez restreindre les produits entrants et sortants uniquement au catalogue boutique de %{inventory}
preferred_product_selection_from_coordinator_inventory_only_here: Uniquement le catalogue boutique du coordinateur
preferred_product_selection_from_coordinator_inventory_only_all: Tous les produits disponibles dans les catalogues producteurs
save_reload: Sauvegarder et rafraichir la page
@@ -959,6 +980,8 @@ fr_CA:
pause_subscription: Mettre en pause Abonnement
unpause_subscription: Reprendre Abonnement
cancel_subscription: Annuler Abonnement
filters:
query_placeholder: "Recherche par email"
setup_explanation:
just_a_few_more_steps: 'Encore quelques étapes avant de pouvoir commencer:'
enable_subscriptions: "Activez la fonction abonnements pour au moins une de vos boutiques"
@@ -982,6 +1005,10 @@ fr_CA:
this_is_an_estimate: |
Les prix affichés ne sont qu'une estimation calculée au moment de la dernière modification de l'abonnement.Si vous modifiez les prix ou marges et commissions appliquées, les commandes seront mises à jour, mais l'abonnement affichera toujours les anciennes valeurs.
not_in_open_and_upcoming_order_cycles_warning: "Il n'y a pas de cycle de vente ouvert ou à venir pour ce produit."
autocomplete:
name_or_sku: "NOM OU REF PRODUIT"
quantity: "Quantité"
add: "Ajouter"
details:
details: Informations
invalid_error: Oups! Veuillez remplir tous les champs obligatoires...
@@ -990,6 +1017,8 @@ fr_CA:
charges_not_allowed: Le débit automatique sur carte de paiement n'a pas été autorisé par l'acheteur
no_default_card: L'acheteur n'a pas de carte de paiement disponible pour le débit
card_ok: L'acheteur a une carte de paiement disponible pour le débit
begins_at_placeholder: "Sélectionnez une date"
ends_at_placeholder: "Facultatif"
loading_flash:
loading: Abonnements en cours de chargement
review:
@@ -1002,15 +1031,18 @@ fr_CA:
saving: "En cours d'enregistrement"
saved: "Enregistré"
product_already_in_order: Ce produit a déjà été ajouté à la commande. Veuillez directement modifier la quantité.
stock:
insufficient_stock: "Stock disponible insuffisant"
out_of_stock: "En rupture de stock"
orders:
number: Nombre
confirm_edit: Voulez-vous vraiment modifier cette commande? Si vous poursuivez, la synchronisation automatique des modifications de l'abonnement pourrait être plus difficile à l'avenir.
confirm_cancel_msg: Voulez-vous vraiment annuler cet abonnement? Cette action sera irréversible.
cancel_failure_msg: 'Désolé, l''annulation a échoué!'
confirm_pause_msg: Voulez-vous vraiment mettre en pause cet abonnement?
pause_failure_msg: 'Désolé, la mise en pause a échoué!'
confirm_unpause_msg: Voulez-vous vraiment annuler la mise en pause de cet abonnement?
unpause_failure_msg: 'Désolé, l''annulation de la mise en pause a échoué!'
confirm_cancel_msg: "Voulez-vous vraiment annuler cet abonnement? Cette action sera irréversible."
cancel_failure_msg: "Désolé, l'annulation a échoué!"
confirm_pause_msg: "Voulez-vous vraiment mettre en pause cet abonnement?"
pause_failure_msg: "Désolé, la mise en pause a échoué!"
confirm_unpause_msg: "Si vous avez un cycle de vente ouvert pour ce rythme d'abonnement, une commande sera créée pour cet acheteur. Êtes-vous sûr de vouloir relancer cet abonnement ?"
unpause_failure_msg: "Désolé, l'annulation de la mise en pause a échoué!"
confirm_cancel_open_orders_msg: "Cet abonnement a des commandes ouvertes. Les acheteurs ont été notifiés que leur commande allait être passée. Voulez-vous annulez ces commandes ou les conserver?"
resume_canceled_orders_msg: "Certaines commandes pour cet abonnement peuvent être réouvertes dès maintenant. Vous pouvez les réouvrir depuis la liste des commandes."
yes_cancel_them: Les annuler
@@ -1047,8 +1079,12 @@ fr_CA:
show_on_map: "Tout afficher sur la carte"
shared:
menu:
cart:
cart: "Panier"
signed_in:
profile: "Profil"
mobile_menu:
cart: "Panier"
joyride:
checkout: "Passer la commande"
already_ordered_products: "Déjà commandé dans ce cycle de vente"
@@ -1085,7 +1121,11 @@ fr_CA:
shop:
messages:
login: "se connecter"
signup: "inscrivez-vous"
contact: "contact"
require_customer_login: "Seul les acheteurs autorisés peuvent accéder à cette boutique."
require_login_html: "Si vous êtes déjà autorisé à accéder à la boutique, %{login}ou %{signup} pour continuer. Si vous voulez demander à y accéder, veuillez %{contact} %{enterprise}. "
require_customer_html: "Si vous voulez demander à y accéder, veuillez %{contact} %{enterprise}."
card_could_not_be_updated: La carte n'a pu être mise à jour
card_could_not_be_saved: la carte n'a pas pu être sauvegardée
spree_gateway_error_flash_for_checkout: "Il y a eu un problème avec vos informations de paiement : %{error}"
@@ -1122,6 +1162,7 @@ fr_CA:
menu_4_title: "Groupes"
menu_4_url: "/groups"
menu_5_title: "A propos"
menu_5_url: "https://about.openfoodnetwork.org.au/"
menu_6_title: "Se connecter"
menu_6_url: "https://openfoodnetwork.org/au/connect/"
menu_7_title: "Apprendre"
@@ -1363,6 +1404,7 @@ fr_CA:
email_confirm_shop_number_html: "Confirmation de commande <strong>#%{number}</strong>"
email_order_summary_item: "Produit"
email_order_summary_quantity: "Qté"
email_order_summary_sku: "Référence Produit"
email_order_summary_price: "Prix"
email_order_summary_subtotal: "Sous-total:"
email_order_summary_total: "Total:"
@@ -1557,6 +1599,7 @@ fr_CA:
sell_hubs_detail: "Créer un profil pour votre entreprise de distribution ou organisation sur OFN. A tout moment vous pourrez créer une boutique multi-fournisseurs."
sell_groups_detail: "Créer un répertoire sur mesure (regroupant différents producteurs et hubs de distribution) pour votre région ou votre organisation."
sell_user_guide: "En savoir plus en explorant le guide utilisateur."
sell_listing_price: "L'inscription sur OFFrance est gratuite. Opening and running a shop on OFN is free up to $500 of monthly sales. If you sell more we will invoice you for 2% of sales to a maximum of $100/month. For more detail on pricing visit the Software Platform section via the About link in the top menu."
sell_embed: "Nous pouvons aussi intégrer votre boutique OFN dans votre propre site web ou construire un site web d'alimentation locale sur mesure pour votre région."
sell_ask_services: "Nous consulter sur les services de OFN."
shops_title: Boutiques
@@ -1593,7 +1636,7 @@ fr_CA:
orders_show_order_number: "Commande #%{number}"
orders_show_cancelled: Annulée
orders_show_confirmed: Confirmée
orders_your_order_has_been_cancelled: "Votre commande a été annulée"
orders_your_order_has_been_cancelled: "VotrVotre commande a été annuléee commande a été annulée"
orders_could_not_cancel: "Désolé, la commande n'a pas pu être annulée"
orders_cannot_remove_the_final_item: "Impossible de supprimer le dernier produit d'une commande, si vous souhaitez supprimer l'ensemble des produits, veuillez annuler la commande."
orders_bought_items_notice:
@@ -1672,6 +1715,7 @@ fr_CA:
introduction:
registration_greeting: "Bonjour!"
registration_intro: "Vous pouvez maintenant créer votre profil \"Producteur\" ou \"Hub\""
registration_checklist: "De quoi ai-je besoin ?"
registration_time: "5-10 minutes"
registration_enterprise_address: "L'adresse de l'entreprise"
registration_contact_details: "Les détails du contact référent"
@@ -1926,6 +1970,7 @@ fr_CA:
spree_admin_supplier: Fournisseur
spree_admin_product_category: Catégorie Produit
spree_admin_variant_unit_name: Nom de la pièce (si vendu à la pièce)
unit_name: "Unité"
change_package: "Changer de type de compte"
spree_admin_single_enterprise_hint: "Astuce: Pour permettre aux gens de vous trouver, activez votre visibilité "
spree_admin_eg_pickup_from_school: "ex : \"Retrait des produits à l'Ecole Marimati / Au Café du coin / chez Babette / ...\""
@@ -2161,6 +2206,7 @@ fr_CA:
payment_methods: "Méthodes de paiement"
payment_method_fee: "Frais de transaction"
payment_processing_failed: "Le paiement n'a pas pu être traité, veuillez vérifier les informations saisies"
payment_method_not_supported: "Cette méthode de paiement n'est pas maintenue. Veuillez en sélectionner une autre."
payment_updated: "Paiement mis à jour"
inventory_settings: "Paramètres catalogue boutique"
tag_rules: "Règles de tag"
@@ -2361,8 +2407,20 @@ fr_CA:
severity: Gravité
description: Description
resolve: Résoudre
tag_rules:
shipping_method_tagged_top: "Les méthodes de livraison taggées"
shipping_method_tagged_bottom: "sont:"
payment_method_tagged_top: "Les méthodes de payments taguées"
payment_method_tagged_bottom: "sont:"
order_cycle_tagged_top: "Les cycles de vente taggés"
order_cycle_tagged_bottom: "sont:"
inventory_tagged_top: "Les variantes du catalogue boutique taggées"
inventory_tagged_bottom: "sont:"
new_tag_rule_dialog:
select_rule_type: "Choisir le type de règle:"
add_rule: "Ajouter une règle"
enterprise_fees:
inherit_from_product: "Hériter du produit"
orders:
index:
per_page: " %{results}par page"
@@ -2423,6 +2481,7 @@ fr_CA:
name_required_error: "Veuillez saisir un nom pour ce rythme d'abonnement"
no_order_cycles_error: "Veuillez saisir au moins un cycle de vente (glisser déposer)"
available: "Disponible"
selected: "sélectionné"
customers:
index:
add_customer: "Ajouter un acheteur"
@@ -2617,6 +2676,7 @@ fr_CA:
fill_in_customer_info: "Veuillez saisir les informations acheteur"
new_payment: "Nouveau paiement"
capture: "Payée"
void: "Annulé"
configurations: "Configurations"
general_settings: "Configurations générales"
site_name: "Nom du site"
@@ -2718,7 +2778,16 @@ fr_CA:
no_results: "Pas de résultats"
create: "Créer"
loading: "Chargement en cours"
flat_percent: "Pourcentage net"
per_kg: "Par kg"
amount: "Montant"
currency: "Devise"
first_item: "Coût du premier produit"
additional_item: "Coût du premier produit"
max_items: "Produits max."
minimal_amount: "Montant minimal"
normal_amount: "Montant classique"
discount_amount: "Réduction"
email: Email
account_updated: "Compte mis à jour!"
my_account: "Mon compte"
@@ -2728,6 +2797,7 @@ fr_CA:
inventory: Catalogue boutique
zipcode: Code postal
weight: Poids (au kg)
error_user_destroy_with_orders: "Les utilisateurs avec des commandes finalisées pourraient ne pas être supprimés"
actions:
update: "Mettre à jour"
errors:
@@ -2795,6 +2865,8 @@ fr_CA:
title: "Distribution"
distributor: "Distributeur : "
order_cycle: "Cycle de vente : "
line_item_adjustments: "Ajustements sur la ligne produit"
order_adjustments: "Ajustements sur la commande"
order_total: "Total Commande:"
overview:
enterprises_header:
@@ -2815,15 +2887,29 @@ fr_CA:
shipping_methods:
index:
shipping_methods: "Méthodes de livraison"
new_shipping_method: "Nouvelle méthode de livraison"
name: "Nom"
products_distributor: "Hub-distributeur"
zone: "Zone"
calculator: "Calculateur"
display: "Afficher"
both: "Les deux"
front_end: "Front End"
back_end: "Back End"
no_shipping_methods_found: "Aucune méthode de livraison trouvée"
new:
new_shipping_method: "Nouvelle méthode de livraison"
back_to_shipping_methods_list: "Retour à la liste des méthodes de livraison"
edit:
editing_shipping_method: "Modifier la méthode de livraison"
new: "Nouveau"
back_to_shipping_methods_list: "Retour à la liste des méthodes de livraison"
form:
categories: "Conditions de transport"
zones: "Zones"
both: "Les deux"
front_end: "Front End"
back_end: "Back End"
payment_methods:
new:
new_payment_method: "Nouvelle méthode de paiement"
@@ -2850,6 +2936,7 @@ fr_CA:
error_saving_payment: Erreur à l'enregistrement du paiement
submitting_payment: Envoi du paiement...
products:
image_upload_error: "L'image du produit n'a pas été reconnue. Veuillez importer une image au format PNG ou JPG."
new:
title: 'Nouveau Produit'
unit_name_placeholder: 'ex: botte'
@@ -2919,7 +3006,8 @@ fr_CA:
confirmation_pending: "L'email de confirmation n'a pas encore été validé. Il a été envoyé à %{address}."
variants:
autocomplete:
producer_name: Producteur
producer_name: "Producteur"
unit: "Unité"
general_settings:
edit:
legal_settings: "Configuration légales"
@@ -2949,6 +3037,7 @@ fr_CA:
line_item:
insufficient_stock: "Stock disponible insuffisant, il n'en reste que %{on_hand}"
out_of_stock: "En rupture de stock"
unavailable_item: "Non disponible"
shipment_states:
backorder: réapprovisionnement
partial: partiel
@@ -2968,6 +3057,8 @@ fr_CA:
invalid: invalide
order_mailer:
cancel_email:
customer_greeting: "Bonjour %{name}!"
instructions: "Votre commande a été ANNULÉE. Vous trouverez ci-dessous les informations concernant cette commande. "
order_summary_canceled: "Résumé de la commande [ANNULEE]"
subject: "Annulation de Commande"
confirm_email:

View File

@@ -983,6 +983,10 @@ it:
I prezzi visualizzati sono solo una stima e saranno calcolati nel momento in cui l'abbonamento verrà cambiato.
Se cambi i prezzi o le tariffe, le gentili richieste saranno aggiornate, ma l'abbonamento visualizzerà ancora i valori precedenti
not_in_open_and_upcoming_order_cycles_warning: "Non ci sono cicli di richieste aperte o in apertura per questo prodotto."
autocomplete:
name_or_sku: "NOME O SKU"
quantity: "Quantità"
add: "Aggiungi"
details:
details: Dettagli
invalid_error: Oops! Per favore compila i campi obbligatori...
@@ -1003,15 +1007,16 @@ it:
saving: "SALVATAGGIO"
saved: "SALVATO"
product_already_in_order: Questo prodotto è già stato aggiunto alla gentile richiesta. Per favore modifica direttamente la quantità.
stock:
out_of_stock: "Esaurito"
orders:
number: Numero
confirm_edit: Sei sicura/o di voler modificare questa gentile richiesta? Facendolo potrebbe essere più difficile in futuro sincronizzare le modifiche all'abbonamento
confirm_cancel_msg: Sei sicura/o di voler eliminare questo abbonamento? Quest'azione non potrà essere annullata.
cancel_failure_msg: 'Ci dispiace, eliminazione non riuscita!'
confirm_pause_msg: Sei sicura/o di voler mettere in pausa questo abbonamento?
pause_failure_msg: 'Spiacente, pausa fallita!'
confirm_unpause_msg: Sei sicura/o di voler riprendere questo abbonamento?
unpause_failure_msg: 'Ci dispiace, ripresa non riuscita!'
confirm_cancel_msg: "Sei sicura/o di voler eliminare questo abbonamento? Quest'azione non potrà essere annullata."
cancel_failure_msg: "Ci dispiace, eliminazione non riuscita!"
confirm_pause_msg: "Sei sicura/o di voler mettere in pausa questo abbonamento?"
pause_failure_msg: "Spiacente, pausa fallita!"
unpause_failure_msg: "Ci dispiace, ripresa non riuscita!"
confirm_cancel_open_orders_msg: "Alcune di queste richieste sono attualmente attive. I consumatori sono già stati avvisati che le richieste verranno soddisfatte. Vuoi eliminare questa/e richiesta/e o mantenerla?"
resume_canceled_orders_msg: "Alcuni ordini per questo abbonamento possono essere ripresi in questo momento. Puoi riprenderli dal menu a discesa degli ordini."
yes_cancel_them: Cancella l'articolo
@@ -1364,6 +1369,7 @@ it:
email_confirm_shop_number_html: "Conferma dell'Ordine <strong>#%{number}</strong>"
email_order_summary_item: "Articolo"
email_order_summary_quantity: "Qtà."
email_order_summary_sku: "SKU"
email_order_summary_price: "Prezzo"
email_order_summary_subtotal: "Subtotale:"
email_order_summary_total: "Totale:"
@@ -2914,7 +2920,8 @@ it:
confirmation_pending: "Email di conferma in sospeso. Abbiamo inviato una mail di conferma a %{address}."
variants:
autocomplete:
producer_name: Produttore
producer_name: "Produttore"
unit: "Unità"
general_settings:
edit:
legal_settings: "Impostazioni Legali"

View File

@@ -14,7 +14,9 @@ nb:
spree/product:
primary_taxon: "Produktkategori"
supplier: "Leverandør"
shipping_category_id: "Leveringskategori"
variant_unit: "Variant Enhet"
variant_unit_name: "Enhetsnavn Variant"
order_cycle:
orders_close_at: Lukkedato
errors:
@@ -75,6 +77,8 @@ nb:
user_confirmations:
spree_user:
send_instructions: "Du vil motta en epost med instruksjoner om hvordan du bekrefter kontoen din om noen få minutter."
confirmation_sent: "Epostbekreftelse sendt"
confirmation_not_sent: "Feil ved sending av bekreftelses-epost"
user_registrations:
spree_user:
signed_up_but_unconfirmed: "En melding med en bekreftelseslink er sendt til epostadressen din. Vennligst åpne lenken for å aktivere kontoen din."
@@ -85,9 +89,12 @@ nb:
Var du gjest forrige gang? Kanskje du må opprette en konto eller nullstille passordet.
unconfirmed: "Du må bekrefte kontoen din før du fortsetter."
already_registered: "Denne epostadressen er allerede registrert. Vennligst logg inn for å fortsette, eller gå tilbake og bruk en annen epostadresse."
success:
logged_in_succesfully: "Innlogging vellykket"
user_passwords:
spree_user:
updated_not_active: "Ditt passord har blitt tilbakestilt, men epostadressen din er ikke bekreftet enda."
updated: "Passordendringen var vellykket. Du er nå pålogget."
send_instructions: "Du vil motta en epost med instruksjoner om hvordan du bekrefter kontoen din om noen få minutter."
models:
order_cycle:
@@ -237,6 +244,7 @@ nb:
reset_password_token: Tilbakestill passordtoken
expired: er utløpt, vennligst be om en ny
back_to_payments_list: "Tilbake til betalingsliste"
maestro_or_solo_cards: "Maestro/Solo kort"
actions:
create_and_add_another: "Opprett og legg til en annen"
create: "Opprett"
@@ -321,6 +329,7 @@ nb:
invoice_settings:
edit:
title: "Fakturainnstillinger"
enable_invoices?: "Aktivér Fakturaer?"
invoice_style2?: "Bruk den alternative fakturamodellen som inkluderer total avgiftsoppdeling pr rate og avgiftsrateinfo pr vare (passer ikke for land som viser priser ekskludert avgift)"
enable_receipt_printing?: "Vis valg for utskrift av kvitteringer ved bruk av kvitteringsprinter i nedtrekksmeny for bestillinger? "
stripe_connect_settings:
@@ -444,6 +453,8 @@ nb:
encoding_error: "Vennligst sjekk språkinnstillingen til kildefilen din og kontroller at den er lagret med UTF-8-koding"
unexpected_error: "Produktimport støtte på en uventet feil ved åpning av filen: %{error_message}"
index:
notice: "Beskjed"
beta_notice: "Denne funksjonen er fremdeles i beta: du kan oppleve noen feil mens du bruker den. Ikke nøl med å kontakte support."
select_file: Velg et regneark for å laste opp
spreadsheet: Regneark
choose_import_type: Velg importtype
@@ -648,6 +659,8 @@ nb:
permalink_tip: "Denne permalinken brukes til å opprette url-en til din butikk: %{link}din-butikks-navn/shop"
link_to_front: Lenke til butikkvindu
link_to_front_tip: En direktelenke til ditt butikkvindu på Open Food Network.
ofn_uid: OFN UID
ofn_uid_tip: Den unike ID-en som brukes til å identifisere bedriften på Open Food Network.
shipping_methods:
name: Navn
applies: Gjelder?
@@ -829,6 +842,7 @@ nb:
add_distributor: 'Legg til distributør'
advanced_settings:
title: Avanserte Innstillinger
choose_product_tip: Du kan begrense innkommende og utgående produkter til kun %{inventory}s lagerbeholdning.
preferred_product_selection_from_coordinator_inventory_only_here: Kun Koordinators varelager
preferred_product_selection_from_coordinator_inventory_only_all: Alle tilgjengelige produkter
save_reload: Lagre og last siden på nytt
@@ -964,6 +978,8 @@ nb:
pause_subscription: Pause abonnement
unpause_subscription: Fortsett abonnement
cancel_subscription: Avbryt abonnement
filters:
query_placeholder: "Søk på epost..."
setup_explanation:
just_a_few_more_steps: 'Bare noen få skritt før du kan begynne:'
enable_subscriptions: "Aktiver abonnementer for minst en av butikkene dine"
@@ -988,6 +1004,10 @@ nb:
De viste prisene er bare et estimat og beregnet på det tidspunktet abonnementet endres.
Hvis du endrer priser eller avgifter, vil ordrer bli oppdatert, men abonnementet vil fortsatt vise de gamle verdiene.
not_in_open_and_upcoming_order_cycles_warning: "Det er ingen åpne eller kommende bestillingsrunder for dette produktet."
autocomplete:
name_or_sku: "NAME eller SKU"
quantity: "Mengde"
add: "Legg til"
details:
details: Detaljer
invalid_error: Oops! Vennligst fyll inn alle obligatoriske felter...
@@ -996,6 +1016,8 @@ nb:
charges_not_allowed: Korttrekk er ikke tillatt av denne kunden
no_default_card: Kunden har ingen kort tilgjengelig for å trekke
card_ok: Kunden har et kort tilgjengelig for å trekke
begins_at_placeholder: "Velg en dato"
ends_at_placeholder: "Valgfri"
loading_flash:
loading: LASTER ABONNEMENT
review:
@@ -1008,15 +1030,18 @@ nb:
saving: "LAGRER"
saved: "LAGRET"
product_already_in_order: Dette produktet er allerede lagt til i bestillingen. Vennligst rediger mengden direkte.
stock:
insufficient_stock: "Utilstrekkelig lager tilgjengelig"
out_of_stock: "Ikke på Lager"
orders:
number: Antall
confirm_edit: Er du sikker på at du vil redigere denne bestillingen? Å gjøre det kan gjøre det vanskeligere å automatisk synkronisere endringer i abonnementet i fremtiden.
confirm_cancel_msg: Er du sikker på at du vil avbryte dette abonnementet? Denne handlingen kan ikke angres.
cancel_failure_msg: 'Beklager, avbryting mislyktes!'
confirm_pause_msg: Er du sikker på at du vil pause dette abonnementet?
pause_failure_msg: 'Beklager, pause mislyktes!'
confirm_unpause_msg: Er du sikker på at du vil fortsette dette abonnementet?
unpause_failure_msg: 'Beklager, fortsettelse mislyktes!'
confirm_cancel_msg: "Er du sikker på at du vil avbryte dette abonnementet? Denne handlingen kan ikke angres."
cancel_failure_msg: "Beklager, avbryting mislyktes!"
confirm_pause_msg: "Er du sikker på at du vil pause dette abonnementet?"
pause_failure_msg: "Beklager, pause mislyktes!"
confirm_unpause_msg: "Hvis du har en åpen bestillingsrundei for dette abonnementets tidsplan opprettes en bestilling for denne kunden. Er du sikker på at du vil sette i gang abonnementet?"
unpause_failure_msg: "Beklager, fortsettelse mislyktes!"
confirm_cancel_open_orders_msg: "Noen bestillinger for dette abonnementet er for øyeblikket åpne. Kunden har allerede blitt varslet om at bestillingen vil bli lagt inn. Vil du avbryte disse bestillingene eller beholde dem?"
resume_canceled_orders_msg: "Noen bestillinger for dette abonnementet kan gjenopptas akkurat nå. Du kan gjenoppta dem fra nedtrekksmenyen for bestillinger."
yes_cancel_them: Avbryt dem
@@ -1095,7 +1120,11 @@ nb:
shop:
messages:
login: "innlogging"
signup: "melde deg på"
contact: "kontakt"
require_customer_login: "Kun godkjente kunder kan få tilgang til denne butikken."
require_login_html: "Hvis du allerede er en godkjent kunde, kan du fortsette %{login} eller %{signup}. Vil du begynne å handle her? Vennligst %{contact} %{enterprise} og spør om å bli med."
require_customer_html: "Hvis du vil begynne å handle her, vennligst %{contact} %{enterprise} for å spørre om å bli med."
card_could_not_be_updated: Kortet kunne ikke oppdateres
card_could_not_be_saved: kort kunne ikke lagres
spree_gateway_error_flash_for_checkout: "Det oppstod et problem med betalingsinformasjonen din: %{error}"
@@ -1374,6 +1403,7 @@ nb:
email_confirm_shop_number_html: "Ordrebekreftelse <strong>#%{number}</strong>"
email_order_summary_item: "Vare"
email_order_summary_quantity: "Stk"
email_order_summary_sku: "SKU"
email_order_summary_price: "Pris"
email_order_summary_subtotal: "Delsum:"
email_order_summary_total: "Sum:"
@@ -1684,6 +1714,7 @@ nb:
introduction:
registration_greeting: "Hei der!"
registration_intro: "Du kan nå opprette en profil for din Produsent eller Hub"
registration_checklist: "Hva trenger jeg?"
registration_time: "5-10 minutter"
registration_enterprise_address: "Bedriftsadresse"
registration_contact_details: "Kontaktdetaljer"
@@ -1938,6 +1969,7 @@ nb:
spree_admin_supplier: Leverandør
spree_admin_product_category: Produktkategori
spree_admin_variant_unit_name: Variant enhetsnavn
unit_name: "Enhetsnavn"
change_package: "Endre Pakke"
spree_admin_single_enterprise_hint: "Hint: For å hjelpe folk til å finne deg, skru på din synlighet under"
spree_admin_eg_pickup_from_school: "f.eks. 'Henting ved Sammfunnshuset'"
@@ -2173,6 +2205,7 @@ nb:
payment_methods: "Betalingsmetoder"
payment_method_fee: "Transaksjongebyr"
payment_processing_failed: "Betalingen kunne ikke behandles, vennligst sjekk detaljene du skrev inn"
payment_method_not_supported: "Den betalingsmåten støttes ikke. Velg en annen."
payment_updated: "Betaling Oppdatert"
inventory_settings: "Beholdningsinnstillinger"
tag_rules: "Regler merkelapper"
@@ -2751,6 +2784,7 @@ nb:
inventory: Varelager
zipcode: Postnummer
weight: Vekt (per kg)
error_user_destroy_with_orders: "Brukere med fullførte ordrer kan ikke slettes"
actions:
update: "Oppdater"
errors:
@@ -2889,6 +2923,7 @@ nb:
error_saving_payment: Feil ved lagring av betaling
submitting_payment: Sender inn betaling...
products:
image_upload_error: "Produktbildet ble ikke gjenkjent. Last opp et bilde i PNG- eller JPG-format."
new:
title: 'Nytt produkt'
unit_name_placeholder: 'f.eks. bunter'
@@ -2958,7 +2993,8 @@ nb:
confirmation_pending: "Epostbekreftelse venter. Vi har sendt en bekreftelses-epost til %{address}."
variants:
autocomplete:
producer_name: Produsent
producer_name: "Produsent"
unit: "Enhet"
general_settings:
edit:
legal_settings: "Juridiske innstillinger"

View File

@@ -1003,6 +1003,10 @@ nl_BE:
De afgebeelde prijzen zijn slechts een schatting en worden berekend op het moment dat het abonnement is veranderd.
Als je de prijzen of kosten verandert, zullen de bestellingen worden geüpdatet, maar het abonnement zal nog steeds de oude waarden weergeven.
not_in_open_and_upcoming_order_cycles_warning: "Er zijn geen openstaande of naderende bestellingscycli voor dit product."
autocomplete:
name_or_sku: "BESCHRIJVING OF ARTKELNUMMER"
quantity: "Kwantiteit"
add: "Voeg toe"
details:
details: Details
invalid_error: Oops! Gelieve al de gevraagde velden in te vullen...
@@ -1025,15 +1029,16 @@ nl_BE:
saving: "Aan het opslaan"
saved: "Opgeslaan"
product_already_in_order: Dit product is al eens toegevoegd aan de bestelling. Gelieve rechtstreeks de hoeveelheid aan te passen.
stock:
out_of_stock: "Geen voorraad"
orders:
number: Nummer
confirm_edit: Ben je zeker dat je deze bestelling wil aanpassen? Indien je hiermee wenst verder te gaan is het mogelijk dat in de toekomst het moeilijker wordt om automatisch de veranderingen in het abonnement te synchroniseren.
confirm_cancel_msg: Ben je zeker dat je dit abonnement wil annuleren? Deze actie kan niet ongedaan worden gemaakt.
cancel_failure_msg: 'Sorry, de annulatie is mislukt!'
confirm_pause_msg: Ben je zeker dat je dit abonnement wil pauseren?
pause_failure_msg: 'Sorry, pauseren mislukt!'
confirm_unpause_msg: Ben je zeker dat je dit abonnement wil hervatten?
unpause_failure_msg: 'Sorry, hervatten mislukt!'
confirm_cancel_msg: "Ben je zeker dat je dit abonnement wil annuleren? Deze actie kan niet ongedaan worden gemaakt."
cancel_failure_msg: "Sorry, de annulatie is mislukt!"
confirm_pause_msg: "Ben je zeker dat je dit abonnement wil pauseren?"
pause_failure_msg: "Sorry, pauseren mislukt!"
unpause_failure_msg: "Sorry, hervatten mislukt!"
confirm_cancel_open_orders_msg: "Sommige bestellingen voor deze abonnementen zijn nog niet afgerond. De klant werd al op de hoogte gebracht dat deze bestelling geplaatst zullen worden. Wil je graag dat deze bestelling(en) geannuleerd worden of wil je ze behouden?"
resume_canceled_orders_msg: "Sommige bestellingen voor de abonnementen kunnen nu hervat worden. Je kan verdergaan vanuit het dropdownmenu bij bestellingen."
yes_cancel_them: 'Annuleer ze '
@@ -1395,6 +1400,7 @@ nl_BE:
email_confirm_shop_number_html: "Bestellingsbevestiging <strong>#%{number}</strong>"
email_order_summary_item: "Artikel"
email_order_summary_quantity: "Aantal"
email_order_summary_sku: "SKU"
email_order_summary_price: "Prijs"
email_order_summary_subtotal: "Tussentotaal:"
email_order_summary_total: "Totaal:"
@@ -2990,7 +2996,8 @@ nl_BE:
confirmation_pending: "De validatie van de bevestigins e-mail naar %{address} toegestuurd is nog niet toegekomen."
variants:
autocomplete:
producer_name: Producent
producer_name: "Producent"
unit: "Unit"
general_settings:
edit:
legal_settings: "De legale instelling"

View File

@@ -988,6 +988,10 @@ pt:
Os preços mostrados são apenas estimativas e são calculados no momento em que a subscrição é mudada.
Se mudar preços ou taxas, as encomendas serão atualizadas, mas a subscrição ainda mostrará os preços anteriores.
not_in_open_and_upcoming_order_cycles_warning: "Não há ciclos de encomenda abertos ou que estejam para abrir para este produto."
autocomplete:
name_or_sku: "NOME OU CÓDIGO"
quantity: "Quantidade"
add: "Adicionar"
details:
details: Detalhes
invalid_error: Ooops! Por favor preencha todos os campos obrigatórios...
@@ -1008,15 +1012,16 @@ pt:
saving: "A GUARDAR"
saved: "GUARDADO"
product_already_in_order: Este produto já foi adicionado à encomenda. Por favor edite a quantidade directamente.
stock:
out_of_stock: "Sem Stock"
orders:
number: Número
confirm_edit: Tem a certeza que quer editar esta encomenda? Ao fazê-lo pode tornar-se mais difícil sincronizar alterações automaticamente com a subscrição no futuro.
confirm_cancel_msg: Tem a certeza que pretende cancelar esta subscrição? Esta acção não pode ser desfeita.
cancel_failure_msg: 'Desculpe, o cancelamento falhou!'
confirm_pause_msg: Tem a certeza que deseja pausar esta subscrição?
pause_failure_msg: 'Desculpe, a pausa falhou!'
confirm_unpause_msg: Tem a certeza que pretende parar a pausa desta subscrição?
unpause_failure_msg: 'Desculpe, não foi possível parar a pausa!'
confirm_cancel_msg: "Tem a certeza que pretende cancelar esta subscrição? Esta acção não pode ser desfeita."
cancel_failure_msg: "Desculpe, o cancelamento falhou!"
confirm_pause_msg: "Tem a certeza que deseja pausar esta subscrição?"
pause_failure_msg: "Desculpe, a pausa falhou!"
unpause_failure_msg: "Desculpe, não foi possível parar a pausa!"
confirm_cancel_open_orders_msg: "Algumas encomendas para esta subscrição estão actualmente abertas. O/a consumidor/a foi notificado que a encomenda será processada. Quer cancelar esta(s) encomenda(s) ou mantê-las?"
resume_canceled_orders_msg: "Algumas encomendas desta subscrição podem ser retomadas neste momento. Para retomá-las, selecione no menu dropdown de encomendas."
yes_cancel_them: Cancelá-las
@@ -1370,6 +1375,7 @@ pt:
email_confirm_shop_number_html: "Confirmação de encomenda <strong>#%{number}</strong>"
email_order_summary_item: "Item"
email_order_summary_quantity: "Qtd"
email_order_summary_sku: "SKU"
email_order_summary_price: "Preço"
email_order_summary_subtotal: "Subtotal:"
email_order_summary_total: "Total:"
@@ -2923,7 +2929,8 @@ pt:
confirmation_pending: "A confirmação de email está pendente. Enviamos um email de confirmação para %{address}"
variants:
autocomplete:
producer_name: Produtor
producer_name: "Produtor"
unit: "Unidade"
general_settings:
edit:
legal_settings: "Configurações Legais"

View File

@@ -593,6 +593,9 @@ sv:
packing:
name: Förpackningsrapporter
subscriptions:
autocomplete:
quantity: "Antal"
add: "Tillägga"
review:
address: Adress
products: Produkter
@@ -848,6 +851,7 @@ sv:
email_confirm_shop_number_html: "Orderbekräftelse <strong>#%{number}</strong>"
email_order_summary_item: "Artikel"
email_order_summary_quantity: "Antal"
email_order_summary_sku: "SKU"
email_order_summary_price: "Pris"
email_order_summary_subtotal: "Delsumma:"
email_order_summary_total: "Total:"
@@ -2021,7 +2025,8 @@ sv:
password: "Lösenord"
variants:
autocomplete:
producer_name: Producent
producer_name: "Producent"
unit: "Enhet"
general_settings:
edit:
enterprises_require_tos: "Företag måste acceptera servicevillkoren"

View File

@@ -34,9 +34,9 @@ def prompt_for_admin_email
end
def create_admin_user
if ENV['AUTO_ACCEPT']
password = 'spree123'
email = 'spree@example.com'
if ENV.fetch("AUTO_ACCEPT", true)
password = ENV.fetch("ADMIN_PASSWORD", "spree123").dup
email = ENV.fetch("ADMIN_EMAIL", "spree@example.com").dup
else
puts 'Create the admin user (press enter for defaults).'
#name = prompt_for_admin_name unless name
@@ -56,6 +56,8 @@ def create_admin_user
say "\nWARNING: There is already a user with the email: #{email}, so no account changes were made. If you wish to create an additional admin user, please run rake spree_auth:admin:create again with a different email.\n\n"
else
admin = Spree::User.new(attributes)
admin.skip_confirmation!
admin.skip_confirmation_notification!
if admin.save
role = Spree::Role.find_or_create_by_name 'admin'
admin.spree_roles << role
@@ -70,13 +72,4 @@ def create_admin_user
end
end
if Spree::User.admin.empty?
create_admin_user
else
puts 'Admin user has already been previously created.'
if agree('Would you like to create a new admin user? (yes/no)')
create_admin_user
else
puts 'No admin user created.'
end
end
create_admin_user if Spree::User.admin.empty?

View File

@@ -48,7 +48,7 @@ states.each do |state|
end
end
spree_user = Spree::User.first
spree_user && spree_user.confirm!
# Create users:
require File.join(File.dirname(__FILE__), 'default', 'users')
DefaultStockLocation.find_or_create

View File

@@ -11,7 +11,8 @@ module OpenFoodNetwork
when ActiveRecord::Relation
@subscriptions = subscriptions.not_ended.not_canceled
else
raise "ProxyOrderSyncer must be initialized with an instance of Subscription or ActiveRecord::Relation"
raise "ProxyOrderSyncer must be initialized with " \
"an instance of Subscription or ActiveRecord::Relation"
end
end
@@ -74,7 +75,9 @@ module OpenFoodNetwork
end
def in_range_order_cycles
order_cycles.where('orders_close_at >= ? AND orders_close_at <= ?', begins_at, ends_at || 100.years.from_now)
order_cycles.where("orders_close_at >= ? AND orders_close_at <= ?",
begins_at,
ends_at || 100.years.from_now)
end
end
end

View File

@@ -41,7 +41,11 @@ module OpenFoodNetwork
# - updates variant_override.count_on_hand
# - does not create stock_movement
# - does not update stock_item.count_on_hand
# If it is a variant override with on_demand:
# - don't change stock or call super (super would change the variant's stock)
def move(quantity, originator = nil)
return if @variant_override.andand.on_demand
if @variant_override.andand.stock_overridden?
@variant_override.move_stock! quantity
else

View File

@@ -583,7 +583,7 @@ describe Admin::SubscriptionsController, type: :controller do
end
context 'json' do
let(:params) { { format: :json, id: subscription.id } }
let(:params) { { format: :json, id: subscription.id, subscription: {} } }
context 'as a regular user' do
it 'redirects to unauthorized' do
@@ -664,6 +664,15 @@ describe Admin::SubscriptionsController, type: :controller do
expect(json_response['id']).to eq subscription.id
expect(subscription.reload.paused_at).to be nil
end
context "when there is an open OC and no associated orders exist yet for it (OC was opened when the subscription was paused)" do
it "creates an associated order" do
spree_put :unpause, params
expect(subscription.reload.paused_at).to be nil
expect(subscription.proxy_orders.size).to be 1
end
end
end
end
end

View File

@@ -168,7 +168,7 @@ describe Spree::Admin::ProductsController, type: :controller do
end
end
describe "updating" do
describe "updating a product" do
let(:producer) { create(:enterprise) }
let!(:product) { create(:simple_product, supplier: producer) }
@@ -176,6 +176,23 @@ describe Spree::Admin::ProductsController, type: :controller do
login_as_enterprise_user [producer]
end
describe "product stock setting with errors" do
it "notifies bugsnag and still raise error" do
# forces an error in the variant
product.variants.first.stock_items = []
expect(Bugsnag).to receive(:notify)
expect do
spree_put :update,
id: product,
product: {
on_hand: 1
}
end.to raise_error(StandardError)
end
end
describe "product variant unit is items" do
it "clears unit description of all variants of the product" do
product.variants.first.update_attribute :unit_description, "grams"

View File

@@ -742,7 +742,7 @@ feature '
end
end
describe "Updating product image with new upload interface" do
describe "Updating product image" do
let!(:product) { create(:simple_product, name: "Carrots") }
it "displays product images and image upload modal" do
@@ -755,6 +755,7 @@ feature '
# Shows default image when no image set
expect(page).to have_css "img[src='/assets/noimage/mini.png']"
@old_thumb_src = page.find("a.image-modal img")['src']
# Click image
page.find("a.image-modal").click
@@ -780,7 +781,7 @@ feature '
within "table#listing_products tr#p_#{product.id}" do
# New thumbnail is shown in image column
@new_thumb_src = page.find("a.image-modal img")['src']
expect(@old_thumb_src) != @new_thumb_src
expect(@old_thumb_src).not_to eq @new_thumb_src
page.find("a.image-modal").click
end

View File

@@ -223,25 +223,25 @@ feature '
let!(:different_shipping_method_for_distributor1) { create(:shipping_method, name: "Different", distributors: [distributor1]) }
let!(:shipping_method_for_distributor2) { create(:shipping_method, name: "Other", distributors: [distributor2]) }
let!(:order) do
create(:order_with_taxes, distributor: distributor1, ship_address: create(:address),
product_price: 110, tax_rate_amount: 0.1,
tax_rate_name: "Tax 1").tap do |record|
Spree::TaxRate.adjust(record)
record.update_shipping_fees!
end
end
background do
Spree::Config[:enable_receipt_printing?] = true
distributor1.update_attribute(:abn, '12345678')
@order = create(:order_with_taxes,
distributor: distributor1,
ship_address: create(:address),
product_price: 110,
tax_rate_amount: 0.1,
tax_rate_name: "Tax 1")
Spree::TaxRate.adjust(@order)
@order.update_shipping_fees!
visit spree.edit_admin_order_path(@order)
visit spree.edit_admin_order_path(order)
end
scenario "shows a list of line_items" do
within('table.index tbody', match: :first) do
@order.line_items.each do |item|
order.line_items.each do |item|
expect(page).to have_selector "td", match: :first, text: item.full_name
expect(page).to have_selector "td.item-price", text: item.single_display_amount
expect(page).to have_selector "input#quantity[value='#{item.quantity}']", visible: false
@@ -252,13 +252,13 @@ feature '
scenario "shows the order items total" do
within('fieldset#order-total') do
expect(page).to have_selector "span.order-total", text: @order.display_item_total
expect(page).to have_selector "span.order-total", text: order.display_item_total
end
end
scenario "shows the order non-tax adjustments" do
within('table.index tbody') do
@order.adjustments.eligible.each do |adjustment|
order.adjustments.eligible.each do |adjustment|
expect(page).to have_selector "td", match: :first, text: adjustment.label
expect(page).to have_selector "td.total", text: adjustment.display_amount
end
@@ -266,7 +266,7 @@ feature '
end
scenario "shows the order total" do
expect(page).to have_selector "fieldset#order-total", text: @order.display_total
expect(page).to have_selector "fieldset#order-total", text: order.display_total
end
scenario "shows the order tax adjustments" do
@@ -279,10 +279,10 @@ feature '
scenario "shows the dropdown menu" do
find("#links-dropdown .ofn-drop-down").click
within "#links-dropdown" do
expect(page).to have_link "Resend Confirmation", href: spree.resend_admin_order_path(@order)
expect(page).to have_link "Send Invoice", href: spree.invoice_admin_order_path(@order)
expect(page).to have_link "Print Invoice", href: spree.print_admin_order_path(@order)
expect(page).to have_link "Cancel Order", href: spree.fire_admin_order_path(@order, e: 'cancel')
expect(page).to have_link "Resend Confirmation", href: spree.resend_admin_order_path(order)
expect(page).to have_link "Send Invoice", href: spree.invoice_admin_order_path(order)
expect(page).to have_link "Print Invoice", href: spree.print_admin_order_path(order)
expect(page).to have_link "Cancel Order", href: spree.fire_admin_order_path(order, e: 'cancel')
end
end
@@ -327,27 +327,27 @@ feature '
print_data = page.evaluate_script('printData');
elements_in_print_data =
[
@order.distributor.name,
@order.distributor.address.address_part1,
@order.distributor.address.address_part2,
@order.distributor.contact.email,
@order.number,
@order.line_items.map { |line_item|
order.distributor.name,
order.distributor.address.address_part1,
order.distributor.address.address_part2,
order.distributor.contact.email,
order.number,
order.line_items.map { |line_item|
[line_item.quantity.to_s,
line_item.product.name,
line_item.single_display_amount_with_adjustments.format(symbol: false, with_currency: false),
line_item.display_amount_with_adjustments.format(symbol: false, with_currency: false)]
},
checkout_adjustments_for(@order, exclude: [:line_item]).reject { |a| a.amount == 0 }.map { |adjustment|
checkout_adjustments_for(order, exclude: [:line_item]).reject { |a| a.amount == 0 }.map { |adjustment|
[raw(adjustment.label),
display_adjustment_amount(adjustment).format(symbol: false, with_currency: false)]
},
@order.display_total.format(with_currency: false),
display_checkout_taxes_hash(@order).map { |tax_rate, tax_value|
order.display_total.format(with_currency: false),
display_checkout_taxes_hash(order).map { |tax_rate, tax_value|
[tax_rate,
tax_value.format(with_currency: false)]
},
display_checkout_total_less_tax(@order).format(with_currency: false)
display_checkout_total_less_tax(order).format(with_currency: false)
]
expect(print_data.join).to include(*elements_in_print_data.flatten)
end
@@ -363,6 +363,20 @@ feature '
expect(page.find("td.amount")).to have_content "$5.00"
end
context "when an included variant has been deleted" do
let!(:deleted_variant) do
order.line_items.first.variant.tap do |record|
record.delete
end
end
it "still lists the variant in the order page" do
within ".stock-contents" do
expect(page).to have_content deleted_variant.product_and_full_name
end
end
end
end
scenario "creating an order with distributor and order cycle" do

View File

@@ -1,57 +0,0 @@
require 'spec_helper'
feature 'External services' do
include AuthenticationWorkflow
include WebHelper
describe "bugherd" do
describe "limiting inclusion by environment" do
before { Spree::Config.bugherd_api_key = 'abc123' }
it "is not included in test" do
visit root_path
expect(script_content(with: 'bugherd')).to be_nil
end
it "is not included in dev" do
allow(Rails.env).to receive(:development?) { true }
visit root_path
expect(script_content(with: 'bugherd')).to be_nil
end
it "is included in staging" do
allow(Rails.env).to receive(:staging?) { true }
visit root_path
expect(script_content(with: 'bugherd')).not_to be_nil
end
it "is included in production" do
allow(Rails.env).to receive(:production?) { true }
visit root_path
expect(script_content(with: 'bugherd')).not_to be_nil
end
end
context "in an environment where BugHerd is displayed" do
before { allow(Rails.env).to receive(:staging?) { true } }
context "when there is no API key set" do
before { Spree::Config.bugherd_api_key = nil }
it "does not include the BugHerd script" do
visit root_path
expect(script_content(with: 'bugherd')).to be_nil
end
end
context "when an API key is set" do
before { Spree::Config.bugherd_api_key = 'abc123' }
it "includes the BugHerd script, with the correct API key" do
visit root_path
expect(script_content(with: 'bugherd')).to include 'abc123'
end
end
end
end
end

View File

@@ -64,31 +64,6 @@ feature "As a consumer I want to check out my cart", js: true do
context 'login in as user' do
let(:user) { create(:user) }
def fill_out_form
choose sm1.name
choose pm1.name
within "#details" do
fill_in "First Name", with: "Will"
fill_in "Last Name", with: "Marshall"
fill_in "Email", with: "test@test.com"
fill_in "Phone", with: "0468363090"
end
check "Save as default billing address"
within "#billing" do
fill_in "City", with: "Melbourne"
fill_in "Postcode", with: "3066"
fill_in "Address", with: "123 Your Head"
select "Australia", from: "Country"
select "Victoria", from: "State"
end
check "Shipping address same as billing address?"
check "Save as default shipping address"
end
before do
quick_login_as(user)
end
@@ -205,6 +180,46 @@ feature "As a consumer I want to check out my cart", js: true do
end
end
context "in the shopfront with cache enabled" do
around do |example|
original_config = Spree::Config[:enable_products_cache?]
example.run
Spree::Config[:enable_products_cache?] = original_config
end
let(:control_product) { create(:taxed_product, supplier: supplier, price: 110, zone: zone, tax_rate_amount: 0.1) }
let(:control_variant) { control_product.variants.first }
let!(:order_cycle) { create(:simple_order_cycle, suppliers: [supplier], distributors: [distributor], coordinator: create(:distributor_enterprise), variants: [variant, control_variant]) }
it "does not show item after all stock of an item is checked out (tesging cache update on checkout)" do
Spree::Config[:enable_products_cache?] = true
variant.update_attributes on_hand: 5
flush_jobs
visit shop_path
fill_in "variants[#{variant.id}]", with: '5'
wait_until { !cart_dirty }
visit checkout_path
checkout_as_guest
fill_out_details
fill_out_billing_address
choose sm1.name
choose pm1.name
place_order
expect(page).to have_content "Your order has been processed successfully"
flush_jobs
visit shop_path
# The presence of the control product ensures the list of products is fully loaded
# before we verify the sold product is not present
page.should have_content control_product.name
page.should_not have_content product.name
end
end
context "on the checkout page" do
before do
visit checkout_path
@@ -216,7 +231,7 @@ feature "As a consumer I want to check out my cart", js: true do
page.should have_content distributor.name
end
it 'does not show the save as defalut address checkbox' do
it 'does not show the save as default address checkbox' do
page.should_not have_content "Save as default billing address"
page.should_not have_content "Save as default shipping address"
end
@@ -315,20 +330,8 @@ feature "As a consumer I want to check out my cart", js: true do
describe "purchasing" do
it "takes us to the order confirmation page when we submit a complete form" do
within "#details" do
fill_in "First Name", with: "Will"
fill_in "Last Name", with: "Marshall"
fill_in "Email", with: "test@test.com"
fill_in "Phone", with: "0468363090"
end
within "#billing" do
fill_in "Address", with: "123 Your Face"
select "Australia", from: "Country"
select "Victoria", from: "State"
fill_in "City", with: "Melbourne"
fill_in "Postcode", with: "3066"
end
fill_out_details
fill_out_billing_address
within "#shipping" do
choose sm2.name
@@ -365,22 +368,8 @@ feature "As a consumer I want to check out my cart", js: true do
before do
choose sm1.name
choose pm1.name
within "#details" do
fill_in "First Name", with: "Will"
fill_in "Last Name", with: "Marshall"
fill_in "Email", with: "test@test.com"
fill_in "Phone", with: "0468363090"
end
within "#billing" do
fill_in "City", with: "Melbourne"
fill_in "Postcode", with: "3066"
fill_in "Address", with: "123 Your Face"
select "Australia", from: "Country"
select "Victoria", from: "State"
end
fill_out_details
fill_out_billing_address
check "Shipping address same as billing address?"
end
@@ -475,4 +464,36 @@ feature "As a consumer I want to check out my cart", js: true do
end
end
end
def fill_out_details
within "#details" do
fill_in "First Name", with: "Will"
fill_in "Last Name", with: "Marshall"
fill_in "Email", with: "test@test.com"
fill_in "Phone", with: "0468363090"
end
end
def fill_out_billing_address
within "#billing" do
fill_in "City", with: "Melbourne"
fill_in "Postcode", with: "3066"
fill_in "Address", with: "123 Your Head"
select "Australia", from: "Country"
select "Victoria", from: "State"
end
end
def fill_out_form
choose sm1.name
choose pm1.name
fill_out_details
check "Save as default billing address"
fill_out_billing_address
check "Shipping address same as billing address?"
check "Save as default shipping address"
end
end

View File

@@ -112,6 +112,7 @@ feature "As a consumer I want to shop with a distributor", js: true do
# that we are not filling in the quantity on the outgoing row
page.should_not have_selector "tr.product-cart"
within('product:not(.ng-leave)') { fill_in "variants[#{variant.id}]", with: 1 }
show_cart
within("li.cart") { page.should have_content with_currency(19.99) }
end

View File

@@ -16,12 +16,14 @@ feature "shopping with variant overrides defined", js: true do
let(:product1) { create(:simple_product, supplier: producer) }
let(:product2) { create(:simple_product, supplier: producer) }
let(:product3) { create(:simple_product, supplier: producer, on_demand: true) }
let(:product4) { create(:simple_product, supplier: producer) }
let(:product1_variant1) { create(:variant, product: product1, price: 11.11, unit_value: 1) }
let(:product1_variant2) { create(:variant, product: product1, price: 22.22, unit_value: 2) }
let(:product2_variant1) { create(:variant, product: product2, price: 33.33, unit_value: 3) }
let(:product1_variant3) { create(:variant, product: product1, price: 44.44, unit_value: 4) }
let(:product3_variant1) { create(:variant, product: product3, price: 55.55, unit_value: 5, on_demand: true) }
let(:product3_variant2) { create(:variant, product: product3, price: 66.66, unit_value: 6, on_demand: true) }
let(:product4_variant1) { create(:variant, product: product4, price: 77.77, unit_value: 7) }
let!(:product1_variant1_override) { create(:variant_override, :use_producer_stock_settings, hub: hub, variant: product1_variant1, price: 55.55, count_on_hand: nil, default_stock: nil, resettable: false) }
let!(:product1_variant2_override) { create(:variant_override, hub: hub, variant: product1_variant2, count_on_hand: 0, default_stock: nil, resettable: false) }
let!(:product2_variant1_override) { create(:variant_override, hub: hub, variant: product2_variant1, count_on_hand: 0, default_stock: nil, resettable: false) }
@@ -29,9 +31,10 @@ feature "shopping with variant overrides defined", js: true do
let!(:product3_variant1_override) { create(:variant_override, hub: hub, variant: product3_variant1, count_on_hand: 0, default_stock: nil, resettable: false) }
let!(:product3_variant2_override) { create(:variant_override, hub: hub, variant: product3_variant2, count_on_hand: 6, default_stock: nil, resettable: false) }
let(:enterprise_fee) { create(:enterprise_fee, enterprise: hub, fee_type: 'packing', calculator: Calculator::FlatPercentPerItem.new(preferred_flat_percent: 10)) }
let!(:product4_variant1_override) { create(:variant_override, hub: hub, variant: product4_variant1, count_on_hand: nil, on_demand: true, default_stock: nil, resettable: false) }
before do
outgoing_exchange.variants = [product1_variant1, product1_variant2, product2_variant1, product1_variant3, product3_variant1, product3_variant2]
outgoing_exchange.variants = [product1_variant1, product1_variant2, product2_variant1, product1_variant3, product3_variant1, product3_variant2, product4_variant1]
outgoing_exchange.enterprise_fees << enterprise_fee
sm.calculator.preferred_amount = 0
visit shops_path
@@ -146,6 +149,15 @@ feature "shopping with variant overrides defined", js: true do
product1_variant1_override.reload.count_on_hand.should be_nil
end
it "does not subtract stock from variants where the override has on_demand: true" do
fill_in "variants[#{product4_variant1.id}]", with: "2"
click_checkout
expect do
complete_checkout
end.to change { product4_variant1.reload.on_hand }.by(0)
expect(product4_variant1_override.reload.count_on_hand).to be_nil
end
it "does not show out of stock flags on order confirmation page" do
product1_variant3.on_hand = 0
fill_in "variants[#{product1_variant3.id}]", with: "2"

View File

@@ -49,6 +49,18 @@ describe InjectionHelper, type: :helper do
expect(helper.inject_current_order).to match order.id.to_s
end
describe "injects current order cycle" do
it "injects empty json object (not nil) when current OC is null" do
allow(helper).to receive(:current_order_cycle).and_return nil
expect(helper.inject_current_order_cycle).to match "{}"
end
it "injects current OC when OC not null" do
allow(helper).to receive(:current_order_cycle).and_return order_cycle = create(:simple_order_cycle)
expect(helper.inject_current_order_cycle).to match order_cycle.id.to_s
end
end
it "injects taxons" do
taxon = create(:taxon)
expect(helper.inject_taxons).to match taxon.name

View File

@@ -118,8 +118,12 @@ describe SubscriptionPlacementJob do
end
describe "processing a subscription order" do
let(:subscription) { create(:subscription, with_items: true) }
let(:shop) { subscription.shop }
let!(:shipping_method_created_earlier) { create(:shipping_method, distributors: [shop]) }
let!(:shipping_method) { create(:shipping_method, distributors: [shop]) }
let!(:shipping_method_created_later) { create(:shipping_method, distributors: [shop]) }
let(:shop) { create(:enterprise) }
let(:subscription) { create(:subscription, shop: shop, with_items: true) }
let(:proxy_order) { create(:proxy_order, subscription: subscription) }
let(:oc) { proxy_order.order_cycle }
let(:ex) { oc.exchanges.outgoing.find_by_sender_id_and_receiver_id(shop.id, shop.id) }
@@ -146,6 +150,19 @@ describe SubscriptionPlacementJob do
end
context "when the order is not already complete" do
describe "selection of shipping method" do
let!(:subscription) do
create(:subscription, shop: shop, shipping_method: shipping_method, with_items: true)
end
it "uses the same shipping method after advancing the order" do
job.send(:process, order)
expect(order.state).to eq "complete"
order.reload
expect(order.shipping_method).to eq(shipping_method)
end
end
context "when no stock items are available after capping stock" do
before do
allow(job).to receive(:unavailable_stock_lines_for) { order.line_items }

View File

@@ -5,7 +5,11 @@ module OpenFoodNetwork
describe ScopeVariantToHub do
let(:hub) { create(:distributor_enterprise) }
let(:v) { create(:variant, price: 11.11, on_hand: 1, on_demand: true, sku: "VARIANTSKU") }
let(:v2) { create(:variant, price: 22.22, on_hand: 5) }
let(:v3) { create(:variant, price: 33.33, on_hand: 6) }
let(:vo) { create(:variant_override, hub: hub, variant: v, price: 22.22, count_on_hand: 2, on_demand: false, sku: "VOSKU") }
let(:vo2) { create(:variant_override, hub: hub, variant: v2, price: 33.33, count_on_hand: nil, on_demand: true) }
let(:vo3) { create(:variant_override, hub: hub, variant: v3, price: 44.44, count_on_hand: 16) }
let(:vo_price_only) { create(:variant_override, :use_producer_stock_settings, hub: hub, variant: v, price: 22.22) }
let(:scoper) { ScopeVariantToHub.new(hub) }
@@ -160,6 +164,37 @@ module OpenFoodNetwork
end
end
describe "overriding #move" do
context "when override is on_demand" do
before do
vo2
scoper.scope v2
end
it "doesn't reduce variant's stock" do
v2.move(-2)
expect(Spree::Variant.find(v2.id).on_hand).to eq 5
end
end
context "when stock is overridden" do
before do
vo3
scoper.scope v3
end
it "reduces the override's stock" do
v3.move(-2)
expect(vo3.reload.count_on_hand).to eq 14
end
it "doesn't reduce the variant's stock" do
v3.move(-2)
expect(Spree::Variant.find(v3.id).on_hand).to eq 6
end
end
end
describe "overriding sku" do
context "when an override exists" do
before { vo }

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