Compare commits

...

126 Commits

Author SHA1 Message Date
luisramos0
5077b0e625 Update all locales with the latest Transifex translations 2019-10-08 10:02:54 +01:00
Luis Ramos
1299c0b5eb Merge pull request #4339 from openfoodfoundation/transifex
Transifex
2019-10-08 09:40:54 +01:00
Pau Pérez Fabregat
057572a445 Merge pull request #4321 from luisramos0/fix_pt_br
Delete old pt-BR translations file (it's now correctly called pt_BR)
2019-10-08 08:49:12 +02:00
Pau Pérez Fabregat
3403ab4162 Merge pull request #4340 from openfoodfoundation/sigmundpetersen-patch-1
Delete ISSUE_TEMPLATE.md
2019-10-08 08:48:47 +02:00
Luis Ramos
9a036d18b7 Merge pull request #4271 from luisramos0/no_obsolete_master
Remove logic related to master variants in Exchanges and migrate data
2019-10-07 15:22:53 +01:00
luisramos0
f2b57057cd Add migration to delete all master variants from exchanges and replace them with standard variants 2019-10-07 14:53:44 +01:00
luisramos0
95bc8fa984 Remove logic from OrderCycleDistributedProducts related to obsolete master variants in OCs, this is a condition that will never happen now since we ensure products always have a standard variants
A migration will be added as well to clean up any very old master variants available in order cycles
2019-10-07 14:53:44 +01:00
Luis Ramos
54c44c33eb Merge pull request #4324 from Matt-Yorkley/reports_memoize
Reports memoization
2019-10-07 13:20:03 +01:00
Luis Ramos
8a732568e7 Merge pull request #4325 from kristinalim/feature/4312-remove_find_variant_in_orders_and_fulfillment_report
4312 Use association instead of OrderAndFulfillmentsReport#find_variant
2019-10-07 11:38:37 +01:00
Pau Pérez Fabregat
f4523f0305 Merge pull request #4350 from luisramos0/docker
Update ruby version in dockerfile and in getting started
2019-10-04 16:21:22 +02:00
Transifex-Openfoodnetwork
56a7a49ea2 Updating translations for config/locales/es.yml 2019-10-04 21:23:11 +10:00
Transifex-Openfoodnetwork
7d1ae3bf67 Updating translations for config/locales/es.yml 2019-10-04 21:20:03 +10:00
Transifex-Openfoodnetwork
b9aa4e11da Updating translations for config/locales/ca.yml 2019-10-04 21:19:57 +10:00
Luis Ramos
96428c11c6 Merge pull request #4334 from Matt-Yorkley/products_renderer
Products renderer
2019-10-03 13:47:04 +01:00
Luis Ramos
c15660da0e Merge pull request #4269 from luisramos0/spree_be_config
Move shipping_methods and shipping categories from spree_backend to OFN
2019-10-03 13:45:17 +01:00
Transifex-Openfoodnetwork
9ea05b0794 Updating translations for config/locales/de_DE.yml 2019-10-03 20:48:44 +10:00
luisramos0
c5b939c8ee Update ruby version in dockerfile and in getting started 2019-10-02 23:45:23 +01:00
Luis Ramos
e6408161db Merge pull request #4291 from luisramos0/spree_be_config_taxons
Move taxons and taxonomies from spree_backend to OFN
2019-10-02 21:13:12 +01:00
Luis Ramos
4540b32d3a Merge branch 'master' into spree_be_config_taxons 2019-10-02 15:35:15 +01:00
Luis Ramos
9f8d2fddbc Merge pull request #4292 from luisramos0/spree_be_config_tax
Move tax_rates, tax categories and tax settings from spree_backend to OFN
2019-10-02 15:33:32 +01:00
Luis Ramos
14047c620a Merge branch 'master' into spree_be_config_tax 2019-10-02 15:31:25 +01:00
Luis Ramos
2be1c231f7 Merge pull request #4290 from luisramos0/spree_be_config_zones
Move zones, countries and states from spree_backend to OFN
2019-10-02 14:30:59 +01:00
Luis Ramos
c34646724c Merge pull request #4254 from luisramos0/swagger
Update API swagger docs to reflect current API state
2019-10-02 10:31:13 +01:00
Luis Ramos
b731635270 Merge pull request #4303 from luisramos0/missing_translation
Add missing translation for order.shipment.state "on hand" (with a space between on and hand)
2019-10-02 10:27:33 +01:00
Transifex-Openfoodnetwork
c9a62fad4c Updating translations for config/locales/nb.yml 2019-10-02 16:50:07 +10:00
Transifex-Openfoodnetwork
70169d477c Updating translations for config/locales/nb.yml 2019-10-02 16:47:01 +10:00
Transifex-Openfoodnetwork
d95646ea98 Updating translations for config/locales/en_NZ.yml 2019-10-02 14:29:29 +10:00
Transifex-Openfoodnetwork
d50bf928e1 Updating translations for config/locales/de_DE.yml 2019-10-02 10:58:44 +10:00
Luis Ramos
3f7aff4b8b Merge pull request #4305 from luisramos0/new_product_translations
Make translations in new product page relative and specific to the page
2019-10-01 22:38:49 +01:00
Sigmund Petersen
5fded022d4 Update README.md
Slack invite link changed
2019-10-01 23:09:47 +02:00
Pau Pérez Fabregat
1f644f4020 Merge pull request #4281 from Matt-Yorkley/memcached-apm
Add memcached APM
2019-10-01 18:46:22 +02:00
Matt-Yorkley
cc11d4e5f0 Remove unused user parameter from OrdersAndFulfillmentsReport 2019-10-01 15:59:51 +01:00
Pau Pérez Fabregat
5ecac77aa5 Merge branch 'master' into memcached-apm 2019-10-01 16:58:01 +02:00
Matt-Yorkley
a5d2579c69 Pluck line_item ids instead of all line_items 2019-10-01 15:51:45 +01:00
Matt-Yorkley
112adb11db Pass permissions object into OrdersAndFulfillMentsReport 2019-10-01 15:51:43 +01:00
Transifex-Openfoodnetwork
5fdc11bdc7 Updating translations for config/locales/fr.yml 2019-10-01 23:59:19 +10:00
Matt-Yorkley
c038b485b1 Rename service and methods to remove use of "shop" term 2019-10-01 14:43:47 +01:00
Luis Ramos
19eb93012c Merge pull request #4326 from kristinalim/feature/4310-remove_shipments_count
4310 Do not count order shipments in Order#shipping_method
2019-10-01 11:17:42 +01:00
Luis Ramos
d998ec8453 Merge pull request #4331 from openfoodfoundation/dependabot/bundler/uglifier-4.2.0
Bump uglifier from 4.1.20 to 4.2.0
2019-10-01 11:11:35 +01:00
Luis Ramos
0c93665030 Merge pull request #4335 from Matt-Yorkley/remove_deprecations
Remove deprecation warnings from VariantStock methods
2019-10-01 10:59:57 +01:00
Luis Ramos
c4d298d732 Merge branch 'master' into remove_deprecations 2019-10-01 10:57:10 +01:00
Luis Ramos
8c252fc160 Merge pull request #4341 from openfoodfoundation/dependabot/bundler/webmock-3.7.6
Bump webmock from 3.7.5 to 3.7.6
2019-10-01 10:53:54 +01:00
Pau Pérez Fabregat
c2f8803d72 Merge pull request #4297 from luisramos0/inv_levels
Remove all usages of Spree Config track_inventory_levels
2019-10-01 10:35:20 +02:00
dependabot-preview[bot]
07967275d8 Bump webmock from 3.7.5 to 3.7.6
Bumps [webmock](https://github.com/bblimke/webmock) from 3.7.5 to 3.7.6.
- [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.7.5...v3.7.6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-30 22:02:54 +00:00
Sigmund Petersen
c7db1b7fc0 Delete ISSUE_TEMPLATE.md
This ISSUE_TEMPLATE.md file is the old way of handling templates on Github. OFN is now using the new method for handling templates, so this file can be removed. 
This template still comes up as 'Default template' when opening an issue from the Zenhub board. This gives 2 almost equal template choices which is confusing.
2019-09-30 21:18:51 +02:00
Rachel Arnould
fa57d71a23 Merge pull request #4332 from openfoodfoundation/RachL-patch-2
Update story template
2019-09-30 20:06:12 +02:00
Rachel Arnould
be5e7bd18d Merge pull request #4330 from openfoodfoundation/RachL-patch-1
Update bug template
2019-09-30 20:05:51 +02:00
Transifex-Openfoodnetwork
5cfc2613ac Updating translations for config/locales/en_GB.yml 2019-10-01 04:01:28 +10:00
Transifex-Openfoodnetwork
903eb23122 Updating translations for config/locales/en_GB.yml 2019-10-01 03:58:19 +10:00
Rachel Arnould
375d4fbffd Add workaround item 2019-09-30 11:02:36 +02:00
Matt-Yorkley
6153789055 Eager-load serialized objects in variant query 2019-09-29 20:44:48 +01:00
Matt-Yorkley
032741c54f Refactor ProductsRenderer variants queries
This removes another N+1 and allows pagination applied to the inital query to also affect the returned variants
2019-09-29 17:41:58 +01:00
Matt-Yorkley
e9acf6e0de Refactor #load_products and memoize 2019-09-29 14:30:04 +01:00
Matt-Yorkley
d5e90c3c6c Extract #load_products logic into a new service 2019-09-29 00:10:47 +01:00
Matt-Yorkley
7e7429446d Remove deprecation warnings from VariantStock methods 2019-09-27 17:28:16 +01:00
Matt-Yorkley
535e389fb4 Query variant stock including overrides
This allows the results to be properly filtered and paginated whilst showing the correct stock, and removes a big N+1
2019-09-27 17:25:52 +01:00
Matt-Yorkley
cecebb82f4 Move distributed products relation out from OrderCycleDistributedProducts 2019-09-27 17:25:50 +01:00
Matt-Yorkley
fe0b3172c7 Move scoper to method 2019-09-27 01:52:45 +01:00
Matt-Yorkley
5b27ed6b9f Remove unnecessary #deleted? check
It should be included in te default product scope
2019-09-27 01:52:29 +01:00
Matt-Yorkley
bef4741e31 Enable analytics in all APM services 2019-09-26 22:38:20 +01:00
Rachel Arnould
d604328bfb Update story template 2019-09-26 21:25:01 +02:00
dependabot-preview[bot]
2af3de51c7 Bump uglifier from 4.1.20 to 4.2.0
Bumps [uglifier](https://github.com/lautis/uglifier) from 4.1.20 to 4.2.0.
- [Release notes](https://github.com/lautis/uglifier/releases)
- [Changelog](https://github.com/lautis/uglifier/blob/master/CHANGELOG.md)
- [Commits](https://github.com/lautis/uglifier/compare/v4.1.20...v4.2.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-26 19:21:05 +00:00
Rachel Arnould
d0c77a8dc4 Update bug template 2019-09-26 21:20:50 +02:00
Kristina Lim
8fc4ca6f65 Do not use OrderAndFulfillmentsReport#find_variant 2019-09-26 11:45:05 +08:00
Kristina Lim
721a0d3a98 Do not count order shipments in Order#shipping_method 2019-09-26 11:01:06 +08:00
luisramos0
bb372984e1 Deleting old pt-BR translations file, it's now called pt_BR with underscore 2019-09-25 11:26:06 +01:00
luisramos0
f3bc038c05 Make translations in new product page relative and specific to the page 2019-09-23 17:02:30 +01:00
luisramos0
7817a40a35 Add missing translation for shipment state on hand with space between on and hand 2019-09-23 16:33:59 +01:00
luisramos0
cd6d34663e Remove all usages of Spree Config track_inventory_levels, this is always true in OFN since v2.0.0 2019-09-22 15:25:24 +01:00
luisramos0
fc433ff8f0 Refactor ship methods controller destroy action: remove single action before_filter 2019-09-20 16:29:36 +01:00
luisramos0
8e33437fbb MErge ship method controller decorator with the controller that came from spree 2019-09-20 15:59:24 +01:00
luisramos0
a5103c737d Fix rubocop issues in ship methods controller from spree 2019-09-20 15:58:05 +01:00
luisramos0
37c8f42244 Bring shipping methods and categories controllers from spree_backend 2019-09-20 15:56:24 +01:00
luisramos0
0e8765636b Bring tax_settings from spree_backend to ofn 2019-09-20 15:46:33 +01:00
luisramos0
6855e5c8f4 Fix rubocop issues in feature spec 2019-09-20 15:43:55 +01:00
luisramos0
a96b56239c Transpec feature specs brought from spre_backend 2019-09-20 15:43:55 +01:00
luisramos0
4f9eee2682 Fix feature specs added from spree_backend in the configuration area 2019-09-20 15:43:55 +01:00
luisramos0
44761315c2 Bring feature specs for configuration pages from spree_backend 2019-09-20 15:43:55 +01:00
luisramos0
0d18b1a032 Bring spree/admin configuration routes to ofn 2019-09-20 15:43:55 +01:00
luisramos0
cc0dabcd1e Convert spree/admin/tax_rates from erb to haml 2019-09-20 15:36:58 +01:00
luisramos0
e79c672263 Convert spree/admin/tax_categories from erb to haml 2019-09-20 15:36:54 +01:00
luisramos0
bc6f7934e0 Add spree_backend views related to admin/configuration menu that are missing in ofn 2019-09-20 15:35:49 +01:00
luisramos0
89029f46f9 Fix basic rubocop issues in newly added controller 2019-09-20 15:32:34 +01:00
luisramos0
144369e55f Add tax related controllers from spree_backend related to config 2019-09-20 15:31:30 +01:00
luisramos0
3833cbbf73 Fix rubocop issues in feature spec 2019-09-20 15:24:26 +01:00
luisramos0
5b703a02cd Transpec feature spec brought from spree_backend 2019-09-20 15:24:26 +01:00
luisramos0
1d4aebd3f9 Fix feature spec added from spree_backend 2019-09-20 15:24:15 +01:00
luisramos0
845a764320 Bring taxonomies feature spec from spree_backend 2019-09-20 15:24:06 +01:00
luisramos0
c66579a22f Fix simple rubocop issues in helper 2019-09-20 15:24:06 +01:00
luisramos0
9291bf5c82 Bring taxons_helper from spree 2019-09-20 15:24:06 +01:00
luisramos0
4781ab93ef Bring spree/admin configuration routes to ofn 2019-09-20 15:24:06 +01:00
luisramos0
def9ab7c47 Convert spree/admin/taxons from erb to haml 2019-09-20 15:24:06 +01:00
luisramos0
2a68d34fb0 Convert spree/admin/taxonomies from erb to haml 2019-09-20 15:24:06 +01:00
luisramos0
2ce56aef2c Add spree_backend views related to admin/configuration taxonomies that are missing in ofn 2019-09-20 15:23:45 +01:00
luisramos0
20f965731d Fix basic rubocop issues in recently added controller from spree_backend 2019-09-20 15:14:34 +01:00
luisramos0
8378dce752 Bring taxons config controller that is overriden in ofn to ofn so we can merge them with their decorator in a second step 2019-09-20 15:13:45 +01:00
luisramos0
d7a4e3a896 Add taxonomies controller from spree_backend 2019-09-20 15:12:38 +01:00
luisramos0
7d9de0ca70 Fix rubocop issues in feature specs 2019-09-20 15:07:34 +01:00
luisramos0
f9c6f09cd4 Transpec feature specs brought from spre_backend 2019-09-20 15:06:02 +01:00
luisramos0
4a83eca832 Fix feature specs added from spree_backend in the configuration area 2019-09-20 15:05:21 +01:00
luisramos0
4954db64b3 Bring feature specs for configuration pages from spree_backend 2019-09-20 15:04:45 +01:00
luisramos0
b2c4b97d94 Bring spree/admin configuration routes to ofn 2019-09-20 15:02:01 +01:00
luisramos0
32c1eecece Convert spree/admin/zones from erb to haml 2019-09-20 15:01:06 +01:00
luisramos0
6d8c7a4bee Fix minor detail in states and countries views 2019-09-20 14:57:48 +01:00
luisramos0
bd2045cad7 Convert spree/admin/states from erb to haml 2019-09-20 14:55:36 +01:00
luisramos0
e1c3d2442a Convert spree/admin/countries from erb to haml 2019-09-20 14:55:10 +01:00
luisramos0
3df65d0463 Add spree_backend views related to admin/configuration menu that are missing in ofn 2019-09-20 14:54:55 +01:00
luisramos0
822a17f732 Fix basic rubocop issues in newly added controllers 2019-09-20 14:50:38 +01:00
luisramos0
ffde0307e2 Add controllers from spree_backend related to config 2019-09-20 14:50:01 +01:00
Matt-Yorkley
e6387197ec Add memcached APM 2019-09-19 19:48:16 +01:00
luisramos0
caebcdf184 Add correct schemas for EnterpriseShopfront and Variant (not Api::Admin::VariantSerializer but Api::VariantSerializer) 2019-09-13 15:33:54 +01:00
luisramos0
c66a659e8e Fix /products payloads: product, variants and variant overrides 2019-09-13 14:55:18 +01:00
luisramos0
b8b107dd2d Fix api_key header name 2019-09-13 14:27:39 +01:00
luisramos0
3d32987227 Fix taxonomies to represent the endpoints in OFN 2019-09-12 19:52:13 +01:00
luisramos0
902e51e580 Add api/customers endpoints 2019-09-12 19:11:53 +01:00
luisramos0
743cb3b33a Add update product image endpoint and delete enterprise fees endpoint 2019-09-12 18:02:06 +01:00
luisramos0
74e49787f4 Add the remaining missing enterprises endpoints 2019-09-12 15:16:35 +01:00
luisramos0
afa8f97627 Add post and put on enterprises and fix details in shipments endpoints 2019-09-12 13:42:40 +01:00
luisramos0
6e677fecce Remove now inexistent endpoints /new 2019-09-12 13:19:43 +01:00
luisramos0
889a3e6d9d Improve file layout and move Order model to correct place 2019-09-12 13:15:40 +01:00
luisramos0
664be47ac3 Add endpoints for /orders/shipments 2019-09-12 13:08:39 +01:00
luisramos0
0e4b5ad9ec Remove now gone orders/{order_number} endpoint and its models, may be readded in the near future but the models may be different as these docs refer to the now gone spree_api order rabl representation 2019-09-11 11:35:01 +01:00
luisramos0
5634f4af18 Move orders endpoints above in the file as they are the most important endpoints 2019-09-11 11:34:57 +01:00
luisramos0
0dede39617 Make list of /products/{product_id}/variants endpoints correct according to current code 2019-09-11 11:15:55 +01:00
luisramos0
a2e6b84db2 List the actual actions available in the api/products endpoint 2019-09-10 17:22:52 +01:00
luisramos0
d319f97733 Remove now unexisting endpoints zones, states and countries 2019-09-10 12:36:34 +01:00
102 changed files with 2690 additions and 2100 deletions

View File

@@ -1,66 +0,0 @@
<!-- Provide a general summary of the issue in the Title above.
If your issue is not a bug, please use the Feature template instead:
https://github.com/openfoodfoundation/openfoodnetwork/wiki/Feature-template
-->
## Description
<!-- Provide a more detailed introduction to the issue itself, and why you consider it to be a bug -->
## Expected Behavior
<!-- Tell us what should happen -->
## Actual Behavior
<!-- Tell us what happens instead -->
## Steps to Reproduce
<!-- Provide an unambiguous set of steps to reproduce this bug -->
<!-- Include code to reproduce if relevant -->
1.
2.
3.
4.
## Animated Gif/Screenshot
<!-- Provide a screenshot or brief animated gif reproducing the bug. Linux users can use
[Peek](https://github.com/phw/peek#ubuntu) while Mac users can use [Recordit](http://recordit.co/) -->
## Context
<!-- How has this bug affected you? What were you trying to accomplish? -->
## Severity
<!-- Assign a label and explain the impact.
bug-s1: a critical feature is broken: checkout, payments, signup, login
bug-s2: a non-critical feature is broken, no workaround
bug-s3: a feature is broken but there is a workaround
bug-s4: it's annoying, but you can use it
bug-s5: we can live with it, only a few users impacted
https://github.com/openfoodfoundation/openfoodnetwork/wiki/Bug-severity
-->
## Your Environment
<!-- Include relevant details about the environment you experienced the bug in -->
* Version used:
* Browser name and version:
* Operating System and version (desktop or mobile):
## Possible Fix
<!-- Not obligatory, but suggest a fix or reason for the bug -->

View File

@@ -9,6 +9,7 @@ assignees: ''
## Description
<!-- Provide a more detailed introduction to the issue itself, and why you consider it to be a bug -->
<!-- How has this bug affected you? What were you trying to accomplish? -->
## Expected Behavior
@@ -22,6 +23,8 @@ assignees: ''
## Steps to Reproduce
<!-- Provide an unambiguous set of steps to reproduce this bug -->
<!-- Include code to reproduce if relevant -->
<!-- Include links -->
<!-- Include user ID -->
1.
2.
@@ -29,13 +32,11 @@ assignees: ''
4.
## Animated Gif/Screenshot
<!-- Provide a screenshot or brief animated gif reproducing the bug. Linux users can use
[Peek](https://github.com/phw/peek#ubuntu) while Mac users can use [Recordit](http://recordit.co/) -->
## Context
<!-- How has this bug affected you? What were you trying to accomplish? -->
<!-- Provide a screenshot or brief video reproducing the bug. -->
<!-- Please try to have the dev tools opened on the network tab (press F12 to open the devtools of your browser -->
## Workaround
<!-- Include a workaround for this bug (if relevant) -->
## Severity
<!-- Assign a label and explain the impact.
@@ -55,7 +56,6 @@ https://github.com/openfoodfoundation/openfoodnetwork/wiki/Bug-severity
* Version used:
* Browser name and version:
* Operating System and version (desktop or mobile):
* OFN Platform instance where you discovered the bug, and which version of the software they are using.
## Possible Fix
<!-- Not obligatory, but suggest a fix or reason for the bug -->

View File

@@ -14,5 +14,12 @@ assignees: ''
**- I want to be able to do:** (specify the desired behavior)
(Link to others issues or resources to provide context > only if really necessary). -->
## Acceptance Criteria
<!-- Document the outcomes that need to be achieved before this component can be considered complete. -->
## Acceptance Criteria & Tests
<!-- Document the outcomes that need to be achieved before this component can be considered complete.
-->
<!-- Provide an unambiguous set of steps a tester should do to validate the PR that will solve this issue -->
1.
2.
3.
4.

View File

@@ -6,7 +6,7 @@ RUN apt-get update && apt-get install -y curl git build-essential software-prope
# Setup ENV variables
ENV PATH /usr/local/src/rbenv/shims:/usr/local/src/rbenv/bin:$PATH
ENV RBENV_ROOT /usr/local/src/rbenv
ENV RUBY_VERSION 2.1.5
ENV RUBY_VERSION 2.1.9
ENV CONFIGURE_OPTS --disable-install-doc
# Rbenv & Ruby part

View File

@@ -11,7 +11,7 @@ The following guides are located in the wiki and provide more OS-specific step-b
### Dependencies
* Rails 3.2.x
* Ruby 2.1.5
* Ruby 2.1.9
* PostgreSQL database
* PhantomJS (for testing)
* See Gemfile for a list of gems required

View File

@@ -683,7 +683,7 @@ GEM
railties (> 3.2.8, < 4.0.0)
sprockets (>= 2.2.0)
tzinfo (0.3.55)
uglifier (4.1.20)
uglifier (4.2.0)
execjs (>= 0.3.0, < 3)
unicode-display_width (1.3.2)
unicorn (5.5.1)
@@ -703,7 +703,7 @@ GEM
nokogiri (~> 1.6)
rubyzip (~> 1.0)
selenium-webdriver (~> 3.0)
webmock (3.7.5)
webmock (3.7.6)
addressable (>= 2.3.6)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)

View File

@@ -35,7 +35,7 @@ We use [BrowserStack](https://www.browserstack.com/) as a manual testing tool. B
Copyright (c) 2012 - 2019 Open Food Foundation, released under the AGPL licence.
[survey]: https://docs.google.com/a/eaterprises.com.au/forms/d/1zxR5vSiU9CigJ9cEaC8-eJLgYid8CR8er7PPH9Mc-30/edit#
[slack-invite]: https://join.slack.com/t/openfoodnetwork/shared_invite/enQtMzU2Mjk5MDc2MjA5LTM4ZTAzZjIwNzIxMmU5ODFiNWY1MTU2ZWUyNzQwNjdjNTY0N2VhY2UwOGU4ZmVjNzYyZDU2NjY3NzZkZmQwYjk
[slack-invite]: https://join.slack.com/t/openfoodnetwork/shared_invite/enQtNzY3NDEwNzM2MDM0LWFmNGRhNDUwYzNmNWNkYmFkMzgxNDg1OTg1ODNjNWY4Y2FhNDIwNmE4ZWI0OThiMGNmZjFkODczNGZiYTJmNWI
[contributor-guide]: https://ofn-user-guide.gitbook.io/ofn-contributor-guide/who-are-we
[ofn-install]: https://github.com/openfoodfoundation/ofn-install
[super-admin-guide]: https://ofn-user-guide.gitbook.io/ofn-super-admin-guide

View File

@@ -0,0 +1,9 @@
module Spree
module Admin
class CountriesController < ResourceController
def collection
super.order(:name)
end
end
end
end

View File

@@ -126,7 +126,8 @@ Spree::Admin::ReportsController.class_eval do
@include_blank = I18n.t(:all)
# -- Build Report with Order Grouper
@report = OpenFoodNetwork::OrdersAndFulfillmentsReport.new spree_current_user, params, render_content?
@report = OpenFoodNetwork::OrdersAndFulfillmentsReport.new(permissions,
params, render_content?)
@table = order_grouper_table
csv_file_name = "#{params[:report_type]}_#{timestamp}.csv"

View File

@@ -0,0 +1,6 @@
module Spree
module Admin
class ShippingCategoriesController < ResourceController
end
end
end

View File

@@ -0,0 +1,79 @@
module Spree
module Admin
class ShippingMethodsController < ResourceController
before_filter :load_data, except: [:index]
before_filter :set_shipping_category, only: [:create, :update]
before_filter :set_zones, only: [:create, :update]
before_filter :load_hubs, only: [:new, :edit, :create, :update]
# Sort shipping methods by distributor name
def collection
collection = super
collection = collection.managed_by(spree_current_user).by_name
if params.key? :enterprise_id
distributor = Enterprise.find params[:enterprise_id]
collection = collection.for_distributor(distributor)
end
collection
end
def destroy
# Our reports are not adapted to soft deleted shipping_methods so here we prevent
# the deletion (even soft) of shipping_methods that are referenced in orders
if order = order_referenced_by_shipping_method
flash[:error] = I18n.t(:shipping_method_destroy_error, number: order.number)
redirect_to(collection_url) && return
end
@object.touch :deleted_at
flash[:success] = flash_message_for(@object, :successfully_removed)
respond_with(@object) do |format|
format.html { redirect_to collection_url }
end
end
private
def order_referenced_by_shipping_method
Order.joins(shipments: :shipping_rates)
.where( spree_shipping_rates: { shipping_method_id: @object } )
.first
end
def load_hubs
# rubocop:disable Style/TernaryParentheses
@hubs = Enterprise.managed_by(spree_current_user).is_distributor.sort_by! do |d|
[(@shipping_method.has_distributor? d) ? 0 : 1, d.name]
end
# rubocop:enable Style/TernaryParentheses
end
def set_shipping_category
return true if params["shipping_method"][:shipping_categories] == ""
@shipping_method.shipping_categories =
Spree::ShippingCategory.where(id: params["shipping_method"][:shipping_categories])
@shipping_method.save
params[:shipping_method].delete(:shipping_categories)
end
def set_zones
return true if params["shipping_method"][:zones] == ""
@shipping_method.zones = Spree::Zone.where(id: params["shipping_method"][:zones])
@shipping_method.save
params[:shipping_method].delete(:zones)
end
def location_after_save
edit_admin_shipping_method_path(@shipping_method)
end
def load_data
@available_zones = Zone.order(:name)
@calculators = ShippingMethod.calculators.sort_by(&:name)
end
end
end
end

View File

@@ -1,42 +0,0 @@
module Spree
module Admin
ShippingMethodsController.class_eval do
before_filter :do_not_destroy_referenced_shipping_methods, only: :destroy
before_filter :load_hubs, only: [:new, :edit, :create, :update]
# Sort shipping methods by distributor name
def collection
collection = super
collection = collection.managed_by(spree_current_user).by_name
if params.key? :enterprise_id
distributor = Enterprise.find params[:enterprise_id]
collection = collection.for_distributor(distributor)
end
collection
end
# Spree allows soft deletes of shipping_methods but our reports are not adapted to that
# Here we prevent the deletion (even soft) of shipping_methods that are referenced in orders
def do_not_destroy_referenced_shipping_methods
order = Order.joins(shipments: :shipping_rates)
.where( spree_shipping_rates: { shipping_method_id: @object } )
.first
return unless order
flash[:error] = I18n.t(:shipping_method_destroy_error, number: order.number)
redirect_to(collection_url) && return
end
private
def load_hubs
# rubocop:disable Style/TernaryParentheses
@hubs = Enterprise.managed_by(spree_current_user).is_distributor.sort_by! do |d|
[(@shipping_method.has_distributor? d) ? 0 : 1, d.name]
end
# rubocop:enable Style/TernaryParentheses
end
end
end
end

View File

@@ -0,0 +1,29 @@
module Spree
module Admin
class StatesController < ResourceController
belongs_to 'spree/country'
before_filter :load_data
def index
respond_with(@collection) do |format|
format.html
format.js { render partial: 'state_list' }
end
end
protected
def location_after_save
admin_country_states_url(@country)
end
def collection
super.order(:name)
end
def load_data
@countries = Country.order(:name)
end
end
end
end

View File

@@ -0,0 +1,19 @@
module Spree
module Admin
class TaxCategoriesController < ResourceController
def destroy
if @object.destroy
flash[:success] = flash_message_for(@object, :successfully_removed)
respond_with(@object) do |format|
format.html { redirect_to collection_url }
format.js { render partial: "spree/admin/shared/destroy" }
end
else
respond_with(@object) do |format|
format.html { redirect_to collection_url }
end
end
end
end
end
end

View File

@@ -0,0 +1,26 @@
module Spree
module Admin
class TaxRatesController < ResourceController
before_filter :load_data
update.after :update_after
create.after :create_after
private
def load_data
@available_zones = Zone.order(:name)
@available_categories = TaxCategory.order(:name)
@calculators = TaxRate.calculators.sort_by(&:name)
end
def update_after
Rails.cache.delete('vat_rates')
end
def create_after
Rails.cache.delete('vat_rates')
end
end
end
end

View File

@@ -0,0 +1,15 @@
module Spree
module Admin
class TaxSettingsController < Spree::Admin::BaseController
def update
Spree::Config.set(params[:preferences])
respond_to do |format|
format.html {
redirect_to edit_admin_tax_settings_path
}
end
end
end
end
end

View File

@@ -0,0 +1,21 @@
module Spree
module Admin
class TaxonomiesController < ResourceController
respond_to :json, :only => [:get_children]
def get_children
@taxons = Taxon.find(params[:parent_id]).children
end
private
def location_after_save
if @taxonomy.created_at == @taxonomy.updated_at
edit_admin_taxonomy_url(@taxonomy)
else
admin_taxonomies_url
end
end
end
end
end

View File

@@ -0,0 +1,118 @@
module Spree
module Admin
class TaxonsController < Spree::Admin::BaseController
respond_to :html, :json, :js
def search
if params[:ids]
@taxons = Spree::Taxon.where(id: params[:ids].split(','))
else
@taxons = Spree::Taxon.limit(20).search(name_cont: params[:q]).result
end
end
def create
@taxonomy = Taxonomy.find(params[:taxonomy_id])
@taxon = @taxonomy.taxons.build(params[:taxon])
if @taxon.save
respond_with(@taxon) do |format|
format.json { render json: @taxon.to_json }
end
else
flash[:error] = Spree.t('errors.messages.could_not_create_taxon')
respond_with(@taxon) do |format|
format.html do
if redirect_to @taxonomy
edit_admin_taxonomy_url(@taxonomy)
else
admin_taxonomies_url
end
end
end
end
end
def edit
@taxonomy = Taxonomy.find(params[:taxonomy_id])
@taxon = @taxonomy.taxons.find(params[:id])
@permalink_part = @taxon.permalink.split("/").last
end
def update
@taxonomy = Taxonomy.find(params[:taxonomy_id])
@taxon = @taxonomy.taxons.find(params[:id])
parent_id = params[:taxon][:parent_id]
new_position = params[:taxon][:position]
if parent_id || new_position # taxon is being moved
new_parent = parent_id.nil? ? @taxon.parent : Taxon.find(parent_id.to_i)
new_position = new_position.nil? ? -1 : new_position.to_i
# Bellow is a very complicated way of finding where in nested set we
# should actually move the taxon to achieve sane results,
# JS is giving us the desired position, which was awesome for previous setup,
# but now it's quite complicated to find where we should put it as we have
# to differenciate between moving to the same branch, up down and into
# first position.
new_siblings = new_parent.children
if new_position <= 0 && new_siblings.empty?
@taxon.move_to_child_of(new_parent)
elsif new_parent.id != @taxon.parent_id
if new_position.zero?
@taxon.move_to_left_of(new_siblings.first)
else
@taxon.move_to_right_of(new_siblings[new_position - 1])
end
elsif new_position < new_siblings.index(@taxon)
@taxon.move_to_left_of(new_siblings[new_position]) # we move up
else
@taxon.move_to_right_of(new_siblings[new_position - 1]) # we move down
end
# Reset legacy position, if any extensions still rely on it
new_parent.children.reload.each{ |t| t.update_column(:position, t.position) }
if parent_id
@taxon.reload
@taxon.set_permalink
@taxon.save!
@update_children = true
end
end
if params.key? "permalink_part"
parent_permalink = @taxon.permalink.split("/")[0...-1].join("/")
parent_permalink += "/" if parent_permalink.present?
params[:taxon][:permalink] = parent_permalink + params[:permalink_part]
end
# check if we need to rename child taxons if parent name or permalink changes
if params[:taxon][:name] != @taxon.name || params[:taxon][:permalink] != @taxon.permalink
@update_children = true
end
if @taxon.update_attributes(params[:taxon])
flash[:success] = flash_message_for(@taxon, :successfully_updated)
end
# rename child taxons
if @update_children
@taxon.descendants.each do |taxon|
taxon.reload
taxon.set_permalink
taxon.save!
end
end
respond_with(@taxon) do |format|
format.html { redirect_to edit_admin_taxonomy_url(@taxonomy) }
format.json { render json: @taxon.to_json }
end
end
def destroy
@taxon = Taxon.find(params[:id])
@taxon.destroy
respond_with(@taxon) { |format| format.json { render json: '' } }
end
end
end
end

View File

@@ -0,0 +1,26 @@
module Spree
module Admin
class ZonesController < ResourceController
before_filter :load_data, except: [:index]
def new
@zone.zone_members.build
end
protected
def collection
params[:q] ||= {}
params[:q][:s] ||= "ascend_by_name"
@search = super.ransack(params[:q])
@zones = @search.result.page(params[:page]).per(Spree::Config[:orders_per_page])
end
def load_data
@countries = Country.order(:name)
@states = State.order(:name)
@zones = Zone.order(:name)
end
end
end
end

View File

@@ -0,0 +1,9 @@
module Spree
module Admin
module TaxonsHelper
def taxon_path(taxon)
taxon.ancestors.reverse.collect(&:name).join( " >> ")
end
end
end
end

View File

@@ -19,7 +19,7 @@ module OrderShipment
#
# @return [ShippingMethod]
def shipping_method
return if shipments.empty?
return if shipments.blank?
shipments.first.shipping_method
end

View File

@@ -25,36 +25,21 @@ module VariantStock
#
# @return [Float|Integer]
def on_hand
warn_deprecation(__method__, '#total_on_hand')
total_on_hand
end
# Sets the stock level of the variant.
# This will only work if `track_inventory_levels` config is set
# and if there is a stock item for the variant.
# This will only work if there is a stock item for the variant.
#
# @raise [StandardError] when the track_inventory_levels config key is not set
# and when the variant has no stock item
# @raise [StandardError] when the variant has no stock item
def on_hand=(new_level)
warn_deprecation(__method__, '#total_on_hand')
error = 'Cannot set on_hand value when Spree::Config[:track_inventory_levels] is false'
raise error unless Spree::Config.track_inventory_levels
raise_error_if_no_stock_item_available
overwrite_stock_levels(new_level)
end
# Checks whether this variant is produced on demand.
#
# In Spree 2.0 this attribute is removed in favour of
# track_inventory_levels only. It was initially introduced in
# https://github.com/openfoodfoundation/spree/commit/20b5ad9835dca7f41a40ad16c7b45f987eea6dcc
def on_demand
warn_deprecation(__method__, 'StockItem#backorderable?')
# A variant that has not been saved yet, doesn't have a stock item
# This provides a default value for variant.on_demand using Spree::StockLocation.backorderable_default
return Spree::StockLocation.first.backorderable_default if stock_items.empty?
@@ -69,8 +54,6 @@ module VariantStock
#
# @raise [StandardError] when the variant has no stock item yet
def on_demand=(new_value)
warn_deprecation(__method__, 'StockItem#backorderable=')
raise_error_if_no_stock_item_available
# There should be only one at the default stock location.
@@ -89,8 +72,6 @@ module VariantStock
# Here we depend only on variant.total_on_hand and variant.on_demand.
# This way, variant_overrides only need to override variant.total_on_hand and variant.on_demand.
def can_supply?(quantity)
return true unless Spree::Config[:track_inventory_levels]
on_demand || total_on_hand >= quantity
end
@@ -158,11 +139,4 @@ module VariantStock
def stock_item
stock_items.first
end
def warn_deprecation(method_name, new_method_name)
ActiveSupport::Deprecation.warn(
"`##{method_name}` is deprecated and will be removed. " \
"Please use `#{new_method_name}` instead."
)
end
end

View File

@@ -32,7 +32,7 @@ module Spree
# NOTE: This is an override of spree's method, needed to allow orders
# without line items (ie. user invoices) to not have inventory units
def require_inventory
return false unless Spree::Config[:track_inventory_levels] && line_items.count > 0 # This line altered
return false unless line_items.count > 0 # This line altered
order.completed? && !order.canceled?
end
end

View File

@@ -1,41 +1,75 @@
# Finds valid products distributed by a particular distributor in an order cycle
#
# If a product without variants is added to an order cycle, and then some
# variants are added to that product, but not the order cycle, then the master
# variant should not available for customers to purchase. This class filters
# out such products so that the customer cannot purchase them.
# Returns a (paginatable) AR object for the products or variants in stock for a given shop and OC.
# The stock-checking includes on_demand and stock level overrides from variant_overrides.
class OrderCycleDistributedProducts
def initialize(order_cycle, distributor)
@order_cycle = order_cycle
def initialize(distributor, order_cycle)
@distributor = distributor
@order_cycle = order_cycle
end
# Returns an ActiveRecord relation without invalid products. Check
# #valid_products_distributed_by for details
#
# @return [ActiveRecord::Relation<Spree::Product>]
def relation
variants = order_cycle.variants_distributed_by(distributor)
products = variants.map(&:product).uniq
def products_relation
Spree::Product.where(id: stocked_products)
end
valid_products = products.reject do |product|
product_has_only_obsolete_master_in_distribution?(product, variants)
end
product_ids = valid_products.map(&:id)
Spree::Product.where(id: product_ids)
def variants_relation
@order_cycle.
variants_distributed_by(@distributor).
merge(stocked_variants_and_overrides)
end
private
attr_reader :order_cycle, :distributor
def stocked_products
@order_cycle.
variants_distributed_by(@distributor).
merge(stocked_variants_and_overrides).
select("DISTINCT spree_variants.product_id")
end
# If a product without variants is added to an order cycle, and then some variants are added
# to that product, but not the order cycle, then the master variant should not available for
# customers to purchase.
def product_has_only_obsolete_master_in_distribution?(product, distributed_variants)
product.has_variants? &&
distributed_variants.include?(product.master) &&
(product.variants & distributed_variants).empty?
def stocked_variants_and_overrides
Spree::Variant.
joins("LEFT OUTER JOIN variant_overrides ON variant_overrides.variant_id = spree_variants.id
AND variant_overrides.hub_id = #{@distributor.id}").
joins(:stock_items).
where(query_stock_with_overrides)
end
def query_stock_with_overrides
"( #{variant_not_overriden} AND ( #{variant_on_demand} OR #{variant_in_stock} ) )
OR ( #{variant_overriden} AND ( #{override_on_demand} OR #{override_in_stock} ) )
OR ( #{variant_overriden} AND ( #{override_on_demand_null} AND #{variant_on_demand} ) )
OR ( #{variant_overriden} AND ( #{override_on_demand_null}
AND #{variant_not_on_demand} AND #{variant_in_stock} ) )"
end
def variant_not_overriden
"variant_overrides.id IS NULL"
end
def variant_overriden
"variant_overrides.id IS NOT NULL"
end
def variant_in_stock
"spree_stock_items.count_on_hand > 0"
end
def variant_on_demand
"spree_stock_items.backorderable IS TRUE"
end
def variant_not_on_demand
"spree_stock_items.backorderable IS FALSE"
end
def override_on_demand
"variant_overrides.on_demand IS TRUE"
end
def override_in_stock
"variant_overrides.count_on_hand > 0"
end
def override_on_demand_null
"variant_overrides.on_demand IS NULL"
end
end

View File

@@ -0,0 +1,14 @@
.row
.alpha.four.columns
.field
= f.label :name, t("spree.name")
= f.text_field :name, class: 'fullwidth'
.four.columns
.field
= f.label :iso_name, t("spree.iso_name")
= f.text_field :iso_name, class: 'fullwidth'
.omega.four.columns
.field.checkbox
%label
= f.check_box :states_required
= t("spree.states_required")

View File

@@ -0,0 +1,16 @@
= render partial: 'spree/admin/shared/configuration_menu'
- content_for :page_title do
= t("spree.editing_country")
- content_for :page_actions do
%li
= button_link_to t("spree.back_to_countries_list"), spree.admin_countries_path, icon: 'icon-arrow-left'
= render partial: 'spree/shared/error_messages', locals: { target: @country }
= form_for [:admin, @country] do |f|
%fieldset.no-border-top
= render partial: 'form', locals: { f: f }
.clear
= render partial: 'spree/admin/shared/edit_resource_links'

View File

@@ -0,0 +1,27 @@
= render partial: 'spree/admin/shared/configuration_menu'
- content_for :page_title do
= t("spree.listing_countries")
%table#listing_countries.index
%colgroup
%col{style: "width: 35%"}/
%col{style: "width: 35%"}/
%col{style: "width: 20%"}/
%col{style: "width: 10%"}/
%thead
%tr
%th= t("spree.country_name")
%th= t("spree.iso_name")
%th= t("spree.states_required")
%th.actions
%tbody
- @countries.each do |country|
- tr_class = cycle('odd', 'even')
- tr_id = spree_dom_id(country)
%tr{class: tr_class, id: tr_id}
%td= country.name
%td= country.iso_name
%td.align-center= country.states_required.to_s.titleize
%td.actions
= link_to_edit country, no_text: true

View File

@@ -53,18 +53,17 @@
= f.label :sku, t(:sku)
= f.text_field :sku, :size => 16
- if Spree::Config[:track_inventory_levels]
.alpha.two.columns
= f.field_container :on_hand do
= f.label :on_hand, t(:on_hand)
= f.number_field :on_hand, :min => 0
.omega.two.columns
= f.field_container :on_demand, :class => ['checkbox'] do
%label
= f.check_box :on_demand
= t(:on_demand)
.alpha.two.columns
= f.field_container :on_hand do
= f.label :on_hand, t(:on_hand)
= f.number_field :on_hand, :min => 0
.omega.two.columns
= f.field_container :on_demand, :class => ['checkbox'] do
%label
= f.check_box :on_demand
= t(:on_demand)
.clear
.clear
%ul#shipping_specs
%li#shipping_specs_weight_field.field.alpha.two.columns

View File

@@ -3,17 +3,17 @@
= form_for [:admin, @product], :html => { :multipart => true } do |f|
.twelve.columns.alpha
%fieldset.no-border-bottom{ id: "new_product" }
%legend{align: "center"}= t(:new_product)
%legend{align: "center"}= t(".new_product")
.twelve.columns.alpha
.six.columns.alpha
= f.field_container :supplier do
= f.label :supplier_id, t(:supplier)
= f.label :supplier_id, t(".supplier")
%span.required *
= f.collection_select(:supplier_id, @producers, :id, :name, {:include_blank => true}, {:class => "select2 fullwidth"})
= f.error_message_on :supplier
.six.columns.omega
= f.field_container :name do
= f.label :name, t(:product_name)
= f.label :name, t(".product_name")
%span.required *
%br/
= f.text_field :name, :class => 'fullwidth title'
@@ -21,7 +21,7 @@
.twelve.columns.alpha{ 'ng-controller' => 'unitsCtrl' }
.six.columns.alpha
= f.field_container :units do
= f.label :variant_unit_with_scale, t(:units)
= f.label :variant_unit_with_scale, t(".units")
%span.required *
%select.select2.fullwidth{ id: 'product_variant_unit_with_scale', 'ng-model' => 'product.variant_unit_with_scale', 'ng-options' => 'unit[1] as unit[0] for unit in variant_unit_options' }
%option{'value' => '', 'ng-hide' => "hasUnit(product)"}
@@ -29,7 +29,7 @@
%input{ type: 'hidden', 'ng-value' => 'product.variant_unit_scale', name: 'product[variant_unit_scale]' }
.three.columns
= f.field_container :unit_value do
= f.label :product_unit_value_with_description, t(:value), 'ng-disabled' => "!hasUnit(product)"
= f.label :product_unit_value_with_description, t(".value"), 'ng-disabled' => "!hasUnit(product)"
%span.required *
%input.fullwidth{ id: 'product_unit_value_with_description', 'ng-model' => 'product.master.unit_value_with_description', :type => 'text', placeholder: "eg. 2", 'ng-disabled' => "!hasUnit(product)" }
%input{ type: 'hidden', 'ng-value' => 'product.master.unit_value', name: 'product[unit_value]' }
@@ -37,28 +37,28 @@
= render 'display_as', f: f
.three.columns.omega{ 'ng-show' => "product.variant_unit_with_scale == 'items'" }
= f.field_container :unit_name do
= f.label :product_variant_unit_name, t(:unit_name)
= f.label :product_variant_unit_name, t(".unit_name")
%input.fullwidth{ id: 'product_variant_unit_name','ng-model' => 'product.variant_unit_name', :name => 'product[variant_unit_name]', :placeholder => t('admin.products.unit_name_placeholder'), :type => 'text' }
.twelve.columns.alpha
.six.columns.alpha
= render 'spree/admin/products/primary_taxon_form', f: f
.two.columns
= f.field_container :price do
= f.label :price, t(:price)
= f.label :price, t(".price")
%span.required *
%br/
= f.text_field :price, class: 'fullwidth'
= f.error_message_on :price
.two.columns
= f.field_container :on_hand do
= f.label :on_hand, t(:on_hand)
= f.label :on_hand, t(".on_hand")
%span.required *
%br/
= f.text_field :on_hand, class: 'fullwidth'
= f.error_message_on :on_hand
.two.columns.omega
= f.field_container :on_demand do
= f.label :on_demand, t(:on_demand)
= f.label :on_demand, t(".on_demand")
%br/
= f.check_box :on_demand
= f.error_message_on :on_demand
@@ -74,13 +74,13 @@
.twelve.columns.alpha
= f.field_container :description do
= f.label :product_description, t(:product_description)
= f.label :product_description, t(".product_description")
%br/
%text-angular{'id' => 'product_description', 'name' => 'product[description]', 'class' => 'text-angular', "textangular-links-target-blank" => true, 'ta-toolbar' => "[['bold','italics','underline','clear'],['insertLink']]"}
= f.error_message_on :description
.four.columns.omega{ style: "text-align: center" }
%fieldset.no-border-bottom{ id: "image" }
%legend{align: "center"}= t(:image)
%legend{align: "center"}= t(".image")
.row
= image_tag "noimage/product.png", class: "four columns alpha"
.row
@@ -90,10 +90,10 @@
.form-buttons.filter-actions.actions
= button t('actions.create'), 'icon-ok', :submit, value: "create"
%span.or
= t(:or)
= t(".or")
= button t('actions.create_and_add_another'), 'icon-repeat', :submit, value: 'add_another'
%span.or
= t(:or)
= t(".or")
= link_to_with_icon 'icon-remove', t('actions.cancel'), admin_products_path, :class => 'button'

View File

@@ -0,0 +1,9 @@
.row
.alpha.six.columns
= f.field_container :name do
= f.label :name, t("spree.name")
= f.text_field :name, class: 'fullwidth'
.omega.six.columns
= f.field_container :abbr do
= f.label :abbr, t("spree.abbreviation")
= f.text_field :abbr, class: 'fullwidth'

View File

@@ -0,0 +1,24 @@
#new_state
%table#listing_states.index
%colgroup
%col{style: "width: 70%"}/
%col{style: "width: 15%"}/
%col{style: "width: 15%"}/
%thead
%tr
%th= t("spree.name")
%th= t("spree.abbreviation")
%th.actions
%tbody
- @states.each do |state|
- tr_class = cycle('odd', 'even')
- tr_id = spree_dom_id(state)
%tr{class: tr_class, id: tr_id}
%td= state.name
%td.align-center= state.abbr
%td.actions
= link_to_with_icon 'icon-edit', t("spree.edit"), edit_admin_country_state_url(@country, state), no_text: true
= link_to_delete state, no_text: true
- if @states.empty?
%tr
%td{colspan: "3"}= t("spree.none")

View File

@@ -0,0 +1,16 @@
= render partial: 'spree/admin/shared/configuration_menu'
- content_for :page_title do
= t("spree.editing_state")
%i.icon-arrow-right
= @state.name
- content_for :page_actions do
%li
= button_link_to t("spree.back_to_states_list"), spree.admin_country_states_url(@country), icon: 'icon-arrow-left'
= render partial: 'spree/shared/error_messages', locals: { target: @state }
= form_for [:admin, @country, @state] do |f|
%fieldset.no-border-top
= render partial: 'form', locals: { f: f }
= render partial: 'spree/admin/shared/edit_resource_links'

View File

@@ -0,0 +1,16 @@
= render partial: 'spree/admin/shared/configuration_menu'
- content_for :page_title do
= t("spree.states")
- content_for :page_actions do
%li#new_state_link
= button_link_to t("spree.new_state"), new_admin_country_state_url(@country), { remote: true, icon: 'icon-plus', id: 'new_state_link' }
.field.row
= label_tag :country, t("spree.country")
- databaseurl = "#{admin_states_path(format: :js)}?country_id="
%select#country.observe_field.select2.fullwidth{"data-base-url" => databaseurl, "data-update" => "#state-list"}
= options_from_collection_for_select(@countries, :id, :name, @country.id)
= image_tag 'select2-spinner.gif', plugin: 'spree', style: 'display:none;', id: 'busy_indicator'
#state-list
= render partial: 'state_list'

View File

@@ -0,0 +1,12 @@
= render partial: 'spree/admin/shared/configuration_menu'
= render partial: 'spree/shared/error_messages', locals: { target: @state }
- content_for :page_title do
= t("spree.new_state")
= form_for [:admin, @country, @state] do |f|
%fieldset
%legend= t("spree.new_state")
= render partial: 'form', locals: { f: f }
= render partial: 'spree/admin/shared/new_resource_links'

View File

@@ -0,0 +1,2 @@
$("#new_state").html("<%= escape_javascript(render :template => 'spree/admin/states/new', :formats => [:html], :handlers => [:erb]) %>");
$("#new_state_link").parent().hide();

View File

@@ -0,0 +1,15 @@
.row
.alpha.four.columns
= f.field_container :name do
= f.label :name, t("spree.name")
= f.text_field :name, class: 'fullwidth'
.five.columns
= f.field_container :description do
= f.label :description, t("spree.description")
%br/
= f.text_field :description, class: 'fullwidth'
.three.columns.omega
= f.field_container :is_default, class: ['checkbox'] do
%label
= f.check_box :is_default
= t("spree.default")

View File

@@ -0,0 +1,14 @@
= render partial: 'spree/admin/shared/configuration_menu'
- content_for :page_title do
= t("spree.editing_tax_category")
- content_for :page_actions do
%li= link_to_with_icon 'icon-arrow-left', t("spree.back_to_tax_categories_list"), admin_tax_categories_path, class: 'button'
= render partial: 'spree/shared/error_messages', locals: { target: @tax_category }
= form_for [:admin, @tax_category] do |f|
%fieldset.no-border-top
= render partial: 'form', locals: { f: f }
= render partial: 'spree/admin/shared/edit_resource_links'

View File

@@ -0,0 +1,38 @@
= render :partial => 'spree/admin/shared/configuration_menu'
- content_for :page_title do
= t("spree.listing_tax_categories")
- content_for :page_actions do
%ul.actions.inline-menu
%li
= button_link_to t("spree.new_tax_category"), new_object_url, :icon => 'icon-plus', :id => 'admin_new_tax_categories_link'
%table#listing_tax_categories.index
%colgroup
%col{style: "width: 30%"}/
%col{style: "width: 40%"}/
%col{style: "width: 15%"}/
%col{style: "width: 15%"}/
%thead
%tr{"data-hook" => "tax_header"}
%th= t("spree.name")
%th= t("spree.description")
%th= t("spree.default")
%th.actions
%tbody
- @tax_categories.each do |tax_category|
- @edit_url = edit_admin_tax_category_path(tax_category)
- @delete_url = admin_tax_category_path(tax_category)
- tr_class = cycle('odd', 'even')
- tr_id = spree_dom_id(tax_category)
%tr{class: tr_class, id: tr_id}
%td= tax_category.name
%td= tax_category.description
%td.align-center= tax_category.is_default.to_s.titleize
%td.actions
= link_to_edit tax_category, no_text: true
= link_to_delete tax_category, no_text: true
- if @tax_categories.empty?
%tr
%td{colspan: "4"}= t("spree.none")

View File

@@ -0,0 +1,14 @@
= render partial: 'spree/admin/shared/configuration_menu'
- content_for :page_title do
= t("spree.new_tax_category")
- content_for :page_actions do
%li= link_to_with_icon 'icon-arrow-left', t("spree.back_to_tax_categories_list"), admin_tax_categories_path, class: 'button'
= render partial: 'spree/shared/error_messages', locals: { target: @tax_category }
= form_for [:admin, @tax_category] do |f|
%fieldset.no-border-top
= render partial: 'form', locals: { f: f }
= render partial: 'spree/admin/shared/new_resource_links'

View File

@@ -0,0 +1 @@
= render partial: 'spree/admin/shared/configuration_menu'

View File

@@ -0,0 +1,28 @@
%div
.alpha.twelve.columns
%fieldset.no-border-bottom
%legend{align: "center"}= t("spree.general_settings")
.alpha.six.columns
.field
= f.label :name, t("spree.name")
= f.text_field :name, class: 'fullwidth'
.field
= f.label :amount, t("spree.rate")
= f.text_field :amount, class: 'fullwidth'
%p
%em= t("spree.tax_rate_amount_explanation")
.field
= f.check_box :included_in_price
= f.label :included_in_price, t("spree.included_in_price")
.omega.six.columns
.field
= f.label :zone, t("spree.zone")
= f.collection_select(:zone_id, @available_zones, :id, :name, {}, {class: 'select2 fullwidth'})
.field
= f.label :tax_category_id, t("spree.tax_category")
= f.collection_select(:tax_category_id, @available_categories,:id, :name, {}, {class: 'select2 fullwidth'})
.field
= f.check_box :show_rate_in_label
= f.label :show_rate_in_label, t("spree.show_rate_in_label")
.clear
= render partial: 'spree/admin/shared/calculator_fields', locals: { f: f }

View File

@@ -0,0 +1,16 @@
= render partial: 'spree/admin/shared/configuration_menu'
- content_for :page_title do
= t("spree.editing_tax_rate")
- content_for :page_actions do
%li
= button_link_to t("spree.back_to_tax_rates_list"), spree.admin_tax_rates_path, icon: 'icon-arrow-left'
= render partial: 'spree/shared/error_messages', locals: { target: @tax_rate }
= form_for [:admin, @tax_rate] do |f|
%fieldset.no-border-top
= render partial: 'form', locals: { f: f }
.clear
= render partial: 'spree/admin/shared/edit_resource_links'

View File

@@ -0,0 +1,48 @@
= render partial: 'spree/admin/shared/configuration_menu'
- content_for :page_title do
= t("spree.tax_rates")
- content_for :page_actions do
%li
= button_link_to t("spree.new_tax_rate"), new_object_url, icon: 'icon-plus'
- unless @tax_rates.any?
.no-objects-found
= t("spree.no_results")
- else
%table.index
%colgroup
%col{style: "width: 15%"}/
%col{style: "width: 15%"}/
%col{style: "width: 10%"}/
%col{style: "width: 10%"}/
%col{style: "width: 10%"}/
%col{style: "width: 10%"}/
%col{style: "width: 15%"}/
%col{style: "width: 15%"}/
%thead
%tr
%th= t("spree.zone")
%th= t("spree.name")
%th= t("spree.category")
%th= t("spree.amount")
%th= t("spree.included_in_price")
%th= t("spree.show_rate_in_label")
%th= t("spree.calculator")
%th.actions
%tbody
- @tax_rates.each do |tax_rate|
- tr_class = cycle('odd', 'even')
- tr_id = spree_dom_id(tax_rate)
%tr{class: tr_class, id: tr_id}
%td= tax_rate.zone.try(:name) || t("spree.not_available")
%td= tax_rate.name
%td= tax_rate.tax_category.try(:name) || t("spree.not_available")
%td.align-center= tax_rate.amount
%td.align-center= tax_rate.included_in_price
%td.align-center= tax_rate.show_rate_in_label
%td.align-center= tax_rate.calculator.to_s
%td.actions
= link_to_edit tax_rate, no_text: true
= link_to_delete tax_rate, no_text: true

View File

@@ -0,0 +1,16 @@
= render partial: 'spree/admin/shared/configuration_menu'
- content_for :page_title do
= t("spree.new_tax_rate")
- content_for :page_actions do
%li
= button_link_to t("spree.back_to_tax_rates_list"), spree.admin_tax_rates_path, icon: 'icon-arrow-left'
= render partial: 'spree/shared/error_messages', locals: { target: @tax_rate }
= form_for [:admin, @tax_rate] do |f|
%fieldset.no-border-top
= render partial: 'form', locals: { f: f }
.clear
= render partial: 'spree/admin/shared/new_resource_links'

View File

@@ -0,0 +1,7 @@
.field.align-center
= f.field_container :name do
= f.label :name, t("spree.name")
%span.required *
%br/
= error_message_on :taxonomy, :name, class: 'fullwidth title'
= text_field :taxonomy, :name

View File

@@ -0,0 +1,13 @@
<% content_for :head do %>
<%= javascript_tag "var taxonomy_id = #{@taxonomy.id};
var loading = '#{escape_javascript t("spree.loading")}';
var new_taxon = '#{escape_javascript t("spree.new_taxon")}';
var server_error = '#{escape_javascript t("spree.server_error")}';
var taxonomy_tree_error = '#{escape_javascript t("spree.taxonomy_tree_error")}';
$(document).ready(function(){
setup_taxonomy_tree(taxonomy_id);
});
"
%>
<% end %>

View File

@@ -0,0 +1,19 @@
%table#listing_taxonomies.index.sortable{"data-sortable-link" => update_positions_admin_taxonomies_url}
%colgroup
%col{style: "width: 85%"}/
%col{style: "width: 15%"}/
%thead
%tr
%th= t("spree.name")
%th.actions
%tbody
- @taxonomies.each do |taxonomy|
- tr_class = cycle('odd', 'even')
- tr_id = spree_dom_id(taxonomy)
%tr{class: tr_class, id: tr_id}
%td
%span.handle
= taxonomy.name
%td.actions
= link_to_edit taxonomy.id, no_text: true
= link_to_delete taxonomy, no_text: true

View File

@@ -0,0 +1,7 @@
- if taxon.children.length != 0
%ul
- taxon.children.each do |child|
%li{id: "#{child.id}", rel: "taxon"}
%a{href: "#", style: "background-image: url(#{child.icon.url});"}= child.name
- if child.children.length > 0
= render partial: 'taxon', locals: { taxon: child }

View File

@@ -0,0 +1,32 @@
= render partial: 'spree/admin/shared/configuration_menu'
= render partial: 'js_head'
- content_for :page_title do
= t("spree.taxonomy_edit")
- content_for :page_actions do
%li
= button_link_to t("spree.back_to_taxonomies_list"), spree.admin_taxonomies_path, icon: 'icon-arrow-left'
#ajax_error.errorExplanation{style: "display:none;"}
= form_for [:admin, @taxonomy] do |f|
%fieldset.no-border-top
= render partial: 'form', locals: { f: f }
%div
= label_tag nil, t("spree.tree")
%br/
:javascript
Spree.routes.taxonomy_taxons_path = "#{spree.api_taxonomy_taxons_path(@taxonomy)}";
Spree.routes.admin_taxonomy_taxons_path = "#{spree.admin_taxonomy_taxons_path(@taxonomy)}";
#taxonomy_tree.tree
#progress{style: "display:none;"}
= image_tag 'select2-spinner.gif', title: 'Spinner', style: "vertical-align:bottom;"
= t("spree.updating")
\..
.info= t("spree.taxonomy_tree_instruction")
%br/
.filter-actions.actions
= button t('spree.actions.update'), 'icon-refresh'
%span.or= t("spree.or")
= button_link_to t('spree.actions.cancel'), admin_taxonomies_path, icon: 'icon-remove'

View File

@@ -0,0 +1,11 @@
= render partial: 'spree/admin/shared/configuration_menu'
- content_for :page_title do
= t("spree.taxonomies")
- content_for :page_actions do
%li
= button_link_to t("spree.new_taxonomy"), spree.new_admin_taxonomy_url, icon: 'icon-plus', id: 'admin_new_taxonomy_link'
#list-taxonomies
= render partial: 'list'

View File

@@ -0,0 +1,15 @@
= render partial: 'spree/admin/shared/configuration_menu'
- content_for :page_title do
= t("spree.new_taxonomy")
- content_for :page_actions do
%li
= button_link_to t("spree.back_to_taxonomies_list"), spree.admin_taxonomies_path, icon: 'icon-arrow-left'
= form_for [:admin, @taxonomy] do |f|
= render partial: 'form', locals: { f: f }
%fieldset.no-border-top
%br/
.filter-actions.actions
= button t("spree.create"), 'icon-ok'

View File

@@ -1,11 +1,11 @@
.row{"data-hook" => "admin_inside_taxon_form"}
.row
.alpha.five.columns
= f.field_container :name do
= f.label :name, t(:name)
%span.required *
%br/
= error_message_on :taxon, :name, :class => 'fullwidth title'
= text_field :taxon, :name, :class => 'fullwidth'
= error_message_on :taxon, :name, class: 'fullwidth title'
= text_field :taxon, :name, class: 'fullwidth'
= f.field_container :permalink_part do
= f.label :permalink_part, t(:permalink)
%span.required *
@@ -20,17 +20,17 @@
= f.field_container :meta_title do
= f.label :meta_title, t(:meta_title)
%br/
= f.text_field :meta_title, :class => 'fullwidth', :rows => 6
= f.text_field :meta_title, class: 'fullwidth', rows: 6
= f.field_container :meta_description do
= f.label :meta_description, t(:meta_description)
%br/
= f.text_field :meta_description, :class => 'fullwidth', :rows => 6
= f.text_field :meta_description, class: 'fullwidth', rows: 6
= f.field_container :meta_description do
= f.label :meta_keywords, t(:meta_keywords)
%br/
= f.text_field :meta_keywords, :class => 'fullwidth', :rows => 6
= f.text_field :meta_keywords, class: 'fullwidth', rows: 6
.omega.seven.columns
= f.field_container :description do
= f.label :description, t(:description)
%br/
= f.text_area :description, :class => 'fullwidth', :rows => 6
= f.text_area :description, class: 'fullwidth', rows: 6

View File

@@ -0,0 +1,20 @@
%table.index
%thead
%tr
%th= t("spree.name")
%th= t("spree.path")
%th
%tbody
- taxons.each do |taxon|
- tr_class = cycle('odd', 'even')
- tr_id = spree_dom_id(taxon)
%tr{class: tr_class, id: tr_id}
%td= taxon.name
%td= taxon_path taxon
%td.actions
= link_to_delete taxon, url: remove_admin_product_taxon_url(@product, taxon), name: icon('delete') + ' ' + t("spree.remove")
- if taxons.empty?
%tr
%td{colspan: "3"}
= t("spree.none")
\.

View File

@@ -0,0 +1,17 @@
= render partial: 'spree/admin/shared/configuration_menu'
- content_for :page_title do
= t("spree.taxon_edit")
- content_for :page_actions do
%li
= button_link_to t("spree.back_to_taxonomies_list"), spree.admin_taxonomies_path, icon: 'icon-arrow-left'
- # Because otherwise the form would attempt to use to_param of @taxon
- form_url = admin_taxonomy_taxon_path(@taxonomy.id, @taxon.id)
= form_for [:admin, @taxonomy, @taxon], method: :put, url: form_url, html: { multipart: true } do |f|
= render partial: 'form', locals: { f: f }
.form-buttons
= button t('spree.actions.update'), 'icon-refresh'
= t("spree.or")
= button_link_to t('spree.actions.cancel'), edit_admin_taxonomy_url(@taxonomy), icon: "icon-remove"

View File

@@ -0,0 +1,4 @@
object false
child(@taxons => :taxons) do
attributes :name, :pretty_name, :id
end

View File

@@ -38,18 +38,17 @@
= 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
%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'

View File

@@ -0,0 +1,4 @@
%li
= f.hidden_field :zoneable_type, value: 'Spree::Country'
= f.collection_select(:zoneable_id, @countries, :id, :name, {include_blank: true}, {class: 'select2 fullwidth'})
= remove_nested f

View File

@@ -0,0 +1,23 @@
.alpha.six.columns
%fieldset.no-border-bottom
%legend{align: "center"}= t("spree.general_settings")
= zone_form.field_container :name do
= zone_form.label :name, t("spree.name")
%br/
= zone_form.text_field :name, class: 'fullwidth'
= zone_form.field_container :description do
= zone_form.label :description, t("spree.description")
%br/
= zone_form.text_field :description, class: 'fullwidth'
.field
= zone_form.check_box :default_tax
= label_tag t("spree.default_tax_zone")
.field
= label_tag t("spree.type")
%ul
%li
= zone_form.radio_button('kind', 'country', { id: 'country_based' })
= label_tag :country_based, t("spree.country_based")
%li
= zone_form.radio_button('kind', 'state', { id: 'state_based' })
= label_tag :state_based, t("spree.state_based")

View File

@@ -0,0 +1,11 @@
= javascript_tag "var #{type}_member='#{generate_template(zone_form, :zone_members, {:partial => type + "_member"})}';"
.omega.six.columns{id: "#{type}_members"}
%fieldset.no-border-bottom
%legend{align: "center"}= t("spree.type")
%ul.member-list.fields{id: "ul-nested-#{type.dasherize}"}
- members_of_type = zone_form.object.zone_members.select { |member| member.zoneable_type && member.zoneable_type == "Spree::#{type.camelize}" }
= zone_form.fields_for :zone_members, members_of_type do |member_form|
= render partial: "#{type}_member", locals: { f: member_form }
.field.align-center
= button_link_to t("spree.add_#{type}"), "##{type}_member", { icon: 'icon-plus', id:"nested-#{type.dasherize}" }

View File

@@ -0,0 +1,4 @@
%li.field
= f.hidden_field :zoneable_type, value: 'Spree::State'
= f.collection_select(:zoneable_id, @states, :id, :name, {include_blank: true}, {class: 'select2 fullwidth'})
= remove_nested f

View File

@@ -0,0 +1,18 @@
= render partial: 'spree/admin/shared/configuration_menu'
- content_for :page_title do
= t("spree.editing_zone")
- content_for :page_actions do
%li
= button_link_to t("spree.back_to_zones_list"), admin_zones_path, icon: 'icon-arrow-left'
= render partial: 'spree/shared/error_messages', locals: { target: @zone }
= form_for [:admin, @zone] do |zone_form|
%fieldset.no-border-top
= render partial: 'form', locals: { zone_form: zone_form }
= render partial: 'member_type', locals: { type: 'country', zone_form: zone_form }
= render partial: 'member_type', locals: { type: 'state', zone_form: zone_form }
.clear
= render partial: 'spree/admin/shared/edit_resource_links'

View File

@@ -0,0 +1,41 @@
= render partial: 'spree/admin/shared/configuration_menu'
- content_for :page_title do
= t("spree.zones")
- content_for :page_actions do
%li
= button_link_to t("spree.new_zone"), new_object_url, icon: 'icon-plus', id: 'admin_new_zone_link'
= paginate @zones
- if @zones.empty?
.no-objects-found
= t("spree.none")
- else
%table#listing_zones.index
%colgroup
%col{style: "width: 30%"}/
%col{style: "width: 40%"}/
%col{style: "width: 15%"}/
%col{style: "width: 15%"}/
%thead
%tr
%th= sort_link @search,:name, t("spree.name"), title: 'zones_order_by_name_title'
%th
= sort_link @search,:description, t("spree.description"), {}, {title: 'zones_order_by_description_title'}
%th= t("spree.default_tax")
%th.actions
%tbody
- @zones.each do |zone|
- tr_class = cycle('odd', 'even')
- tr_id = spree_dom_id(zone)
%tr{class: tr_class, id: tr_id}
%td= zone.name
%td= zone.description
%td.align-center= zone.default_tax
%td.actions
= link_to_edit zone, no_text: true
= link_to_delete zone, no_text: true
= paginate @zones

View File

@@ -0,0 +1,15 @@
= render partial: 'spree/admin/shared/configuration_menu'
- content_for :page_title do
= t("spree.new_zone")
- content_for :page_actions do
%li
= button_link_to t("spree.back_to_zones_list"), spree.admin_zones_path, icon: 'icon-arrow-left'
= render partial: 'spree/shared/error_messages', locals: { target: @zone }
= form_for [:admin, @zone] do |zone_form|
= render partial: 'form', locals: { zone_form: zone_form }
.clear
= render partial: 'spree/admin/shared/new_resource_links'

View File

@@ -2,6 +2,7 @@ if ENV['DATADOG_RAILS_APM']
Datadog.configure do |c|
c.use :rails, service_name: 'rails'
c.use :delayed_job, service_name: 'delayed_job'
c.use :dalli, service_name: 'memcached'
c.analytics_enabled = true
end
end

View File

@@ -246,6 +246,7 @@ ca:
back_to_payments_list: "Torna a la llista de pagaments"
maestro_or_solo_cards: "Targetes Maestro/Solo"
backordered: "Reabastit"
on hand: "Disponibles"
ship: "Enviament"
actions:
create_and_add_another: "Crea i afegeix-ne una altra"
@@ -777,7 +778,7 @@ ca:
producer_shop_description_text2: Una productora amb botiga només és per als teus productes; si vols vendre productes produïts / cultivats fora del lloc, selecciona "Grup de productores".
producer_hub: Grup de productores
producer_hub_text: Ven productes propis i d'altres productores
producer_hub_description_text: La vostra organització és la columna vertebral del sistema alimentari local. Podeu vendre els vostres propis productes i o afegir els productes d'altres organitzacions a través de la vostra botiga a la Katuma.
producer_hub_description_text: La vostra organització és la columna vertebral del sistema alimentari local. Podeu vendre els vostres propis productes i o afegir els productes d'altres organitzacions a través de la vostra botiga a Katuma.
profile: Només perfil
get_listing: Apareix en els directoris
profile_description_text: La gent pot trobar-vos i contactar-vos a Katuma. La vostra organització serà visible al mapa i es podrà cercar als directoris.
@@ -815,7 +816,7 @@ ca:
removed_successfully: "Imatge promocional eliminada correctament"
immediate_removal_warning: "La imatge promocional s'eliminarà immediatament després de confirmar."
welcome:
welcome_title: Benvingut a la Katuma - Open Food Network!
welcome_title: Benvingut a Katuma - Open Food Network!
welcome_text: Heu creat correctament un
next_step: Següent pas
choose_starting_point: 'Escull el teu perfil:'
@@ -2326,7 +2327,7 @@ ca:
hub_shop_text1: >
La teva organització és la columna vertebral del vostre sistema alimentari
local. Afegeix productes d'altres organitzacions productores i ven-los
a través de la vostra botiga a la Katuma.
a través de la vostra botiga a Katuma.
hub_shop_text2: >
Els grups poden prendre moltes formes, ja siguin una cooperativa d'aliments,
un grup de compra, o una botiga de queviures local, un supermercat cooperatiu.
@@ -2555,7 +2556,7 @@ ca:
users:
order: "Comanda"
registration:
welcome_to_ofn: "Benvingut a la Katuma - Open Food Network!"
welcome_to_ofn: "Benvingut a Katuma - Open Food Network!"
signup_or_login: "Comenceu registrant-vos (o iniciant sessió)"
have_an_account: "Ja tens un compte?"
action_login: "Inicia la sessió ara."
@@ -2786,6 +2787,7 @@ ca:
discount_amount: "Import de descompte"
email: Correu electrònic
account_updated: "Compte actualitzat!"
email_updated: "El compte sactualitzarà un cop es confirmi el nou correu electrònic."
my_account: "El meu compte"
date: "Data"
time: "Hora"
@@ -2934,7 +2936,19 @@ ca:
products:
image_upload_error: "No s'ha reconegut la imatge del producte. Carregueu una imatge en format PNG o JPG."
new:
title: 'Nou producte'
title: "Nou producte"
new_product: "Nou producte"
supplier: "Proveïdora"
product_name: "Nom del producte"
units: "Mida d'unitat"
value: "Valor"
unit_name: "Nom de la unitat"
price: "Preu"
on_hand: "Disponibles"
on_demand: "Sota demanda"
product_description: "Descripció del producte"
image: "Imatge"
or: "o"
unit_name_placeholder: 'per exemple: manat'
index:
header:

View File

@@ -94,6 +94,7 @@ de_DE:
user_passwords:
spree_user:
updated_not_active: "Ihr Passwort wurde zurückgesetzt, aber ihre E-Mail muss noch bestätigt werden."
updated: "Ihr Kennwort wurde erfolgreich geändert. Sie sind jetzt angemeldet."
send_instructions: "Sie erhalten in einigen Minuten eine E-Mail mit Anweisungen zur Bestätigung Ihres Kontos."
models:
order_cycle:
@@ -243,6 +244,9 @@ de_DE:
reset_password_token: Passwort-Token zurücksetzen
expired: abgelaufen ist, fordern Sie bitte ein neues an
back_to_payments_list: "Zurück zur Zahlungsliste"
maestro_or_solo_cards: "Maestro / Solo-Karten"
backordered: "Nachbestellt"
on hand: "Verfügbar"
ship: "Liefern"
actions:
create_and_add_another: "Erstellen und weitere hinzufügen"
@@ -250,6 +254,7 @@ de_DE:
cancel: "Abbrechen"
save: "Speichern"
edit: "Bearbeiten"
delete: "Löschen"
admin:
begins_at: Beginnt um
begins_on: Beginnt am
@@ -451,6 +456,8 @@ de_DE:
encoding_error: "Bitte überprüfen Sie die Spracheinstellung Ihrer Quelldatei und stellen Sie sicher, dass sie mit der UTF-8-Kodierung gespeichert wird"
unexpected_error: "Beim Produktimport ist beim Öffnen der Datei ein unerwarteter Fehler aufgetreten: %{error_message}"
index:
notice: "Beachten"
beta_notice: "Diese Funktion befindet sich noch in der Beta-Phase: Während der Verwendung können Fehler auftreten. Bitte zögern Sie nicht, den Support zu kontaktieren."
select_file: Wählen Sie eine Tabelle zum Hochladen
spreadsheet: Kalkulationstabelle
choose_import_type: Wählen Sie die Importart
@@ -1003,6 +1010,7 @@ de_DE:
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:
name_or_sku: "NAME ODER SKU"
quantity: "Menge"
add: "Hinzufügen"
details:
@@ -1027,6 +1035,9 @@ de_DE:
saving: "SPEICHERN"
saved: "GESPEICHERT"
product_already_in_order: Dieses Produkt wurde bereits zur Bestellung hinzugefügt. Bitte änderns Sie stattdessen die Menge.
stock:
insufficient_stock: "Unzureichender Bestand verfügbar"
out_of_stock: "Nicht vorrättig"
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.
@@ -1034,6 +1045,7 @@ de_DE:
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: "Wenn Sie einen offenen Bestellzyklus in der Liste dieses Abonnements haben, wird eine Bestellung für diesen Kunden erstellt. Möchten Sie dieses Abonnement wirklich aufheben?"
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."
@@ -1153,7 +1165,7 @@ de_DE:
menu_4_title: "Gruppen"
menu_4_url: "/groups"
menu_5_title: "Über Uns"
menu_5_url: "https://about.openfoodnetwork.org.au/"
menu_5_url: "https://wp.openfoodnetwork.de/"
menu_6_title: "Verbinden"
menu_6_url: "https://openfoodnetwork.org/au/connect/"
menu_7_title: "Mehr Erfahren"
@@ -2623,6 +2635,8 @@ de_DE:
name_or_sku: "Name oder SKU (geben Sie mindestens die ersten 4 Zeichen des Produktnamens ein)"
resend: Erneut senden
back_to_orders_list: Zurück zur Bestellliste
return_authorizations: Rückgabeberechtigungen
cannot_create_returns: Retouren können nicht erstellt werden, da für diese Bestellung keine Versandeinheiten vorhanden sind.
select_stock: "Bestand auswählen"
location: "Ort"
count_on_hand: "Zählen Sie zur Hand"
@@ -2773,6 +2787,7 @@ de_DE:
discount_amount: "Rabattbetrag"
email: Email
account_updated: "Konto aktualisiert!"
email_updated: "Das Konto wird aktualisiert, sobald die neue E-Mail bestätigt wurde."
my_account: "Mein Konto"
date: "Datum"
time: "Zeit"
@@ -2780,6 +2795,7 @@ de_DE:
inventory: Katalog
zipcode: Postleitzahl
weight: Gewicht (pro kg)
error_user_destroy_with_orders: "Benutzer mit abgeschlossenen Bestellungen dürfen nicht gelöscht werden"
actions:
update: "Aktualisieren"
errors:
@@ -2920,7 +2936,19 @@ de_DE:
products:
image_upload_error: "Das Produktbild wurde nicht erkannt. Bitte laden Sie ein Bild im PNG- oder JPG-Format hoch."
new:
title: 'Neues Produkt'
title: "Neues Produkt"
new_product: "Neues Produkt"
supplier: "Anbieter"
product_name: "Produktname"
units: "Einheitsgröße"
value: "Wert"
unit_name: "Einheitenname"
price: "Preis"
on_hand: "Verfügbar"
on_demand: "Unbegrenzt"
product_description: "Produktbeschreibung"
image: "Bild"
or: "oder"
unit_name_placeholder: 'z.B. Trauben'
index:
header:

View File

@@ -278,6 +278,7 @@ en:
maestro_or_solo_cards: "Maestro/Solo cards"
backordered: "Backordered"
on_hand: "On Hand"
"on hand": "On Hand"
ship: "Ship"
actions:
@@ -3092,9 +3093,20 @@ See the %{link} to find out more about %{sitename}'s features and to start using
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'
title: "New Product"
new_product: "New Product"
supplier: "Supplier"
product_name: "Product Name"
units: "Unit Size"
value: "Value"
unit_name: "Unit name"
price: "Price"
on_hand: "On Hand"
on_demand: "On Demand"
product_description: "Product Description"
image: "Image"
or: "or"
unit_name_placeholder: 'eg. bunches'
index:
header:

View File

@@ -245,6 +245,7 @@ en_AU:
expired: has expired, please request a new one
back_to_payments_list: "Back to Payments List"
maestro_or_solo_cards: "Maestro/Solo cards"
on hand: "On Hand"
ship: "Ship"
actions:
create_and_add_another: "Create and Add Another"
@@ -2926,7 +2927,19 @@ en_AU:
products:
image_upload_error: "The product image was not recognised. Please upload an image in PNG or JPG format."
new:
title: 'New Product'
title: "New Product"
new_product: "New Product"
supplier: "Supplier"
product_name: "Product Name"
units: "Unit Size"
value: "Value"
unit_name: "Unit name"
price: "Price"
on_hand: "On Hand"
on_demand: "On Demand"
product_description: "Product Description"
image: "Image"
or: "or"
unit_name_placeholder: 'eg. bunches'
index:
header:

View File

@@ -243,6 +243,7 @@ en_BE:
reset_password_token: Reset password token
expired: has expired, please request a new one
back_to_payments_list: "Back to Payments List"
on hand: "On Hand"
ship: "Ship"
actions:
create_and_add_another: "Create and Add Another"
@@ -2919,7 +2920,19 @@ en_BE:
products:
image_upload_error: "The product image was not recognised. Please upload an image in PNG or JPG format."
new:
title: 'New Product'
title: "New Product"
new_product: "New Product"
supplier: "Supplier"
product_name: "Product Name"
units: "Unit Size"
value: "Value"
unit_name: "Unit name"
price: "Price"
on_hand: "On Hand"
on_demand: "On Demand"
product_description: "Product Description"
image: "Image"
or: "or"
unit_name_placeholder: 'eg. bunches'
index:
header:

View File

@@ -246,6 +246,7 @@ en_CA:
back_to_payments_list: "Back to Payments List"
maestro_or_solo_cards: "Maestro/Solo cards"
backordered: "Backordered"
on hand: "On Hand"
ship: "Ship"
actions:
create_and_add_another: "Create and Add Another"
@@ -2929,7 +2930,19 @@ en_CA:
products:
image_upload_error: "The product image was not recognised. Please upload an image in PNG or JPG format."
new:
title: 'New Product'
title: "New Product"
new_product: "New Product"
supplier: "Supplier"
product_name: "Product Name"
units: "Unit Size"
value: "Value"
unit_name: "Unit Name"
price: "Price"
on_hand: "On Hand"
on_demand: "On Demand"
product_description: "Product Description"
image: "Image"
or: "or"
unit_name_placeholder: 'eg. bunches'
index:
header:

View File

@@ -246,6 +246,7 @@ en_GB:
back_to_payments_list: "Back to Payments List"
maestro_or_solo_cards: "Maestro/Solo cards"
backordered: "Backordered"
on hand: "In Stock"
ship: "Ship"
actions:
create_and_add_another: "Create and Add Another"
@@ -2787,6 +2788,7 @@ en_GB:
discount_amount: "Discount Amount"
email: Email
account_updated: "Account updated!"
email_updated: "The account will be updated once the new email is confirmed."
my_account: "My account"
date: "Date"
time: "Time"
@@ -2935,7 +2937,19 @@ en_GB:
products:
image_upload_error: "The product image was not recognised. Please upload an image in PNG or JPG format."
new:
title: 'New Product'
title: "New Product"
new_product: "New Product"
supplier: "Supplier"
product_name: "Product Name"
units: "Unit Size"
value: "Value"
unit_name: "Unit name"
price: "Price"
on_hand: "In Stock"
on_demand: "Unlimited"
product_description: "Product Description"
image: "Image"
or: "or"
unit_name_placeholder: 'eg. bunches'
index:
header:

View File

@@ -246,6 +246,7 @@ en_NZ:
back_to_payments_list: "Back to Payments List"
maestro_or_solo_cards: "Maestro/Solo cards"
backordered: "Backordered"
on hand: "On Hand"
ship: "Ship"
actions:
create_and_add_another: "Create and Add Another"
@@ -1600,8 +1601,8 @@ en_NZ:
sell_groups_detail: "Set up a tailored directory of enterprises (producers and other food enterprises) for your region or for your organisation."
sell_user_guide: "Find out more in our user guide."
sell_listing_price: "Listing on OFN incurs a nominal monthly charge and if you sell products we ask for a small percentage of your sales. For details see the About tab in the menu\nYour money pays for the server and admin costs and the contribution NZ pays to the global OFN organisation.\n\nYou can always chose to support the development of OFN by increasing the amount you pay."
sell_embed: "We can also embed an OFN shop in your own customised website or build a customised local food network website for your region."
sell_ask_services: "Ask us about OFN services."
sell_embed: "The software that runs OFN is supported by a team of software specialists. Check out the community forum at https://community.openfoodnetwork.org/ to learn of new features in the pipeline."
sell_ask_services: "Please contact us if you have any questions."
shops_title: Shops
shops_headline: Shopping, transformed.
shops_text: Food grows in cycles, farmers harvest in cycles, and we order food in cycles. If you find an order cycle closed, check back soon.
@@ -2781,6 +2782,7 @@ en_NZ:
discount_amount: "Discount Amount"
email: Email
account_updated: "Account updated!"
email_updated: "The account will be updated once the new email is confirmed."
my_account: "My account"
date: "Date"
time: "Time"
@@ -2929,7 +2931,19 @@ en_NZ:
products:
image_upload_error: "The product image was not recognised. Please upload an image in PNG or JPG format."
new:
title: 'New Product'
title: "New Product"
new_product: "New Product"
supplier: "Supplier"
product_name: "Product Name"
units: "Unit Size"
value: "Value"
unit_name: "Unit name"
price: "Price"
on_hand: "On Hand"
on_demand: "On Demand"
product_description: "Product Description"
image: "Image"
or: "or"
unit_name_placeholder: 'eg. bunches'
index:
header:

View File

@@ -245,6 +245,7 @@ en_US:
expired: has expired, please request a new one
back_to_payments_list: "Back to Payments List"
maestro_or_solo_cards: "Debit cards"
on hand: "On Hand"
ship: "Ship"
actions:
create_and_add_another: "Create and Add Another"
@@ -2926,7 +2927,19 @@ en_US:
products:
image_upload_error: "The product image was not recognised. Please upload an image in PNG or JPG format."
new:
title: 'New Product'
title: "New Product"
new_product: "New Product"
supplier: "Supplier"
product_name: "Product Name"
units: "Unit Size"
value: "Value"
unit_name: "Unit name"
price: "Price"
on_hand: "On Hand"
on_demand: "On Demand"
product_description: "Product Description"
image: "Image"
or: "or"
unit_name_placeholder: 'eg. bunches'
index:
header:

View File

@@ -245,6 +245,7 @@ en_ZA:
expired: has expired, please request a new one
back_to_payments_list: "Back to Payments List"
maestro_or_solo_cards: "Maestro/Solo cards"
on hand: "In Stock"
ship: "Ship"
actions:
create_and_add_another: "Create and Add Another"
@@ -2933,7 +2934,19 @@ en_ZA:
products:
image_upload_error: "The product image was not recognised. Please upload an image in PNG or JPG format."
new:
title: 'New Product'
title: "New Product"
new_product: "New Product"
supplier: "Supplier"
product_name: "Product Name"
units: "Unit Size"
value: "Value"
unit_name: "Unit name"
price: "Price"
on_hand: "In Stock"
on_demand: "Unlimited"
product_description: "Product Description"
image: "Image"
or: "or"
unit_name_placeholder: 'eg. bunches'
index:
header:

View File

@@ -246,6 +246,7 @@ es:
back_to_payments_list: "Volver a la lista de pagos"
maestro_or_solo_cards: "Tarjetas Maestro/Solo"
backordered: "Reabastecido"
on hand: "Disponibles"
ship: "Envío"
actions:
create_and_add_another: "Crear y agregar otro"
@@ -2787,6 +2788,7 @@ es:
discount_amount: "Importe de descuento"
email: Email
account_updated: "Cuenta actualizada!"
email_updated: "La cuenta se actualizará una vez que se confirme el nuevo correo electrónico."
my_account: "Mi cuenta"
date: "Fecha"
time: "Hora"
@@ -2935,7 +2937,19 @@ es:
products:
image_upload_error: "La imagen del producto no fue reconocida. Por favor, cargue una imagen en formato PNG o JPG."
new:
title: 'Nuevo producto'
title: "Nuevo producto"
new_product: "Nuevo producto"
supplier: "Proveedora"
product_name: "nombre del producto"
units: "Unidad de medida"
value: "Valor"
unit_name: "Nombre de la unidad"
price: "Precio"
on_hand: "Disponibles"
on_demand: "Bajo demanda"
product_description: "Descripción del producto"
image: "Imagen"
or: "o"
unit_name_placeholder: 'ej. manojos'
index:
header:

View File

@@ -246,6 +246,7 @@ fr:
back_to_payments_list: "Retour à la liste des paiements"
maestro_or_solo_cards: "Cartes Maestro/Solo"
backordered: "(à volonté)"
on hand: "En stock"
ship: "Expédier"
actions:
create_and_add_another: "Créer et ajouter nouveau"
@@ -2810,6 +2811,7 @@ fr:
discount_amount: "Réduction"
email: Email
account_updated: "Compte mis à jour!"
email_updated: "Le compte sera mis à jour une fois la nouvelle adresse email confirmée."
my_account: "Mon compte"
date: "Date"
time: "Heure"
@@ -2958,7 +2960,19 @@ fr:
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'
title: "Nouveau Produit"
new_product: "Nouveau Produit"
supplier: "Fournisseur"
product_name: "Nom du Produit"
units: "Unité de mesure"
value: "Montant"
unit_name: "Unité"
price: "Prix"
on_hand: "En stock"
on_demand: "A volonté"
product_description: "Description du Produit"
image: "Image"
or: "ou"
unit_name_placeholder: 'ex: botte'
index:
header:

View File

@@ -243,6 +243,7 @@ fr_BE:
reset_password_token: réinitialisation du mot de passe
expired: a expiré, veuillez en demander un nouveau
back_to_payments_list: "Retour à la liste des paiements"
on hand: "En stock"
ship: "Expédier"
actions:
create_and_add_another: "Créer et ajouter un nouveau"
@@ -2933,7 +2934,19 @@ fr_BE:
products:
image_upload_error: "L'image du produit n'a pas été reconnue. Veuillez télécharger une image au format PNG ou JPG."
new:
title: 'Nouveau Produit'
title: "Nouveau Produit"
new_product: "Nouveau Produit"
supplier: "Fournisseur"
product_name: "Nom du Produit"
units: "Unité de mesure"
value: "Nb unités"
unit_name: "Nom de l'unité"
price: "Prix"
on_hand: "En stock"
on_demand: "A volonté"
product_description: "Description du Produit"
image: "Image"
or: "ou"
unit_name_placeholder: 'ex: botte'
index:
header:

View File

@@ -247,6 +247,7 @@ fr_CA:
back_to_payments_list: "Retour à la liste des paiements"
maestro_or_solo_cards: "Cartes Maestro/Solo"
backordered: "à volonté"
on hand: "En stock"
ship: "Expédier"
actions:
create_and_add_another: "Créer et ajouter nouveau"
@@ -2941,7 +2942,19 @@ fr_CA:
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'
title: "Nouveau Produit"
new_product: "Nouveau Produit"
supplier: "Fournisseur"
product_name: "Nom du Produit"
units: "Unité de mesure"
value: "Nb unités"
unit_name: "Unité"
price: "Prix"
on_hand: "En stock"
on_demand: "A volonté"
product_description: "Description du Produit"
image: "Image"
or: "ou"
unit_name_placeholder: 'ex: botte'
index:
header:

View File

@@ -237,6 +237,7 @@ it:
reset_password_token: Token per il reset della password
expired: è scaduto, si prega di richiederne uno nuovo
back_to_payments_list: "Torna alla lista dei pagamenti"
on hand: "Disponibile"
ship: "Spedizione"
actions:
create_and_add_another: "Crea e aggiungi un altro"
@@ -2852,7 +2853,18 @@ it:
submitting_payment: Eseguendo il pagamento
products:
new:
title: 'Nuovo prodotto'
title: "Nuovo prodotto"
new_product: "Nuovo prodotto"
supplier: "Fornitore"
product_name: "Nome Prodotto"
units: "Unità di misura"
value: "Valore"
price: "Prezzo"
on_hand: "Disponibile"
on_demand: "A richiesta"
product_description: "Descrizione prodotto"
image: "Immagine"
or: "o"
unit_name_placeholder: 'es. grappoli'
index:
header:

View File

@@ -246,6 +246,7 @@ nb:
back_to_payments_list: "Tilbake til betalingsliste"
maestro_or_solo_cards: "Maestro/Solo kort"
backordered: "Restbestilte"
on hand: "Tilgjengelig"
ship: "Levere"
actions:
create_and_add_another: "Opprett og legg til en annen"
@@ -1309,7 +1310,7 @@ nb:
brandstory_part4: "Det fungerer overalt. Det forandrer alt."
brandstory_part5_strong: "Vi kaller det Open Food Network."
brandstory_part6: "Alle er vi glad i mat. Nå kan vi elske vårt matsystem også."
learn_body: "See på modeller, historier og ressurser for å støtte deg å utvikle en god mat bedrift eller organisasjon. Finne opplæring, arrangement og andre muligheter til å lære fra andre."
learn_body: "Se på modeller, historier og ressurser for å støtte deg å utvikle en god mat bedrift eller organisasjon. Finne opplæring, arrangement og andre muligheter til å lære fra andre."
learn_cta: "Bli Inspirert"
connect_body: "Søk i vår katalog av produsenter, hubs og grupper for å finne god mat nær deg. Vise din bedrift eller organisasjon på OFN slik at kjøpere kan finne deg. Bli med i fellesskapet for å få råd og løse problemer sammen."
connect_cta: "Utforske"
@@ -2780,6 +2781,7 @@ nb:
discount_amount: "Rabattmengde"
email: Epost
account_updated: "Konto oppdatert!"
email_updated: "Kontoen vil bli oppdatert når den nye epostadressen er bekreftet."
my_account: "Min konto"
date: "Dato"
time: "Tid"
@@ -2928,7 +2930,19 @@ nb:
products:
image_upload_error: "Produktbildet ble ikke gjenkjent. Last opp et bilde i PNG- eller JPG-format."
new:
title: 'Nytt produkt'
title: "Nytt produkt"
new_product: "Nytt produkt"
supplier: "Leverandør"
product_name: "Produktnavn"
units: "Enhetsstørrelse"
value: "Verdi"
unit_name: "Enhetsnavn"
price: "Pris"
on_hand: "Tilgjengelig"
on_demand: "Ved forespørsel"
product_description: "Produktbeskrivelse"
image: "Bilde"
or: "eller"
unit_name_placeholder: 'f.eks. bunter'
index:
header:

View File

@@ -243,6 +243,7 @@ nl_BE:
reset_password_token: Reset wachtwoord token
expired: is verlopen, gelieve een nieuwe aan te vragen
back_to_payments_list: "Terug naar Betalingslijst"
on hand: "Bij de Hand"
ship: "Verzenden"
actions:
create_and_add_another: "Een ander maken en toevoegen"
@@ -2928,7 +2929,19 @@ nl_BE:
products:
image_upload_error: "Het productbeeld werd niet herkend. Upload een afbeelding in PNG- of JPG-indeling."
new:
title: 'Nieuw product'
title: "Nieuw product"
new_product: "Nieuw product"
supplier: "Leverancier"
product_name: "Naam produkt"
units: "Stukgrootte"
value: "Waarde"
unit_name: "Unit naam"
price: "Prijs"
on_hand: "Bij de Hand"
on_demand: "Op Aanvraag"
product_description: "Beschrijving product"
image: "beeltenis"
or: "of"
unit_name_placeholder: 'b.v. trossen'
index:
header:

File diff suppressed because it is too large Load Diff

View File

@@ -237,6 +237,7 @@ pt:
reset_password_token: Redefinir palavra-passe
expired: expirou, por favor peça uma nova
back_to_payments_list: "Voltar à lista de pagamentos"
on hand: "Disponível"
ship: "Enviar"
actions:
create_and_add_another: "Criar e acrescentar outro"
@@ -2861,7 +2862,18 @@ pt:
submitting_payment: A submeter pagamento...
products:
new:
title: 'Novo Produto'
title: "Novo Produto"
new_product: "Novo Produto"
supplier: "Fornecedor"
product_name: "Nome do Produto"
units: "Tamanho unitário"
value: "Valor"
price: "Preço"
on_hand: "Disponível"
on_demand: "Sob Encomenda"
product_description: "Descrição do Produto"
image: "Imagem"
or: "ou"
unit_name_placeholder: 'ex: ramos'
index:
header:

View File

@@ -246,6 +246,7 @@ pt_BR:
back_to_payments_list: "voltar para lista de pagamento"
maestro_or_solo_cards: "Cartões Maestro / Solo"
backordered: "Pedidos em atraso"
on hand: "Disponível"
ship: "Envio"
actions:
create_and_add_another: "Criar e adicionar outro"
@@ -2931,7 +2932,17 @@ pt_BR:
products:
image_upload_error: "A imagem do produto não foi reconhecida. Faça o upload de uma imagem no formato PNG ou JPG."
new:
title: 'Novo produto'
title: "Novo produto"
new_product: "Novo produto"
supplier: "Fornecedor"
product_name: "Nome do Produto"
units: "Tamanho da Unidade"
value: "Valor"
price: "Preço"
on_hand: "Disponível"
on_demand: "Sob Encomenda"
image: "Imagem"
or: "ou"
unit_name_placeholder: 'por exemplo. cachos'
index:
header:

View File

@@ -99,6 +99,7 @@ sv:
powered_by: Drivs av
blocked_cookies_alert: "Din webbläsare kan blockera cookies som behövs för att använda den här butiken. Klicka nedan för att tillåta cookies och ladda om sidan."
allow_cookies: "Tillåt cookies"
on hand: "På lager"
ship: "Frakta"
actions:
create: "Skapa"
@@ -1988,6 +1989,14 @@ sv:
products_distributor: "Distributör"
calculator: "Beräkning"
products:
new:
supplier: "Leverantör"
units: "Enhetsstorlek"
value: "Värde"
price: "Pris"
on_hand: "På lager"
on_demand: "På begäran"
or: "eller"
index:
header:
title: 'Redigera Omfång av Produkter '

View File

@@ -88,6 +88,33 @@ Spree::Core::Engine.routes.prepend do
put :clear_api_key
end
end
# Configuration section
resources :taxonomies do
collection do
post :update_positions
end
member do
get :get_children
end
resources :taxons
end
resources :taxons, :only => [] do
collection do
get :search
end
end
resources :tax_rates
resource :tax_settings
resources :tax_categories
resources :zones
resources :countries do
resources :states
end
resources :states
end
resources :orders do

View File

@@ -0,0 +1,53 @@
class RemoveAllMasterVariantsFromExchanges < ActiveRecord::Migration
def up
# 1. We add standard variants of the products of "lonely masters" into the Exchanges where the master variants are lonely
match_master_variants
# 2. We delete all master variants from Exchanges
delete_master_variants
end
def down
end
private
def match_master_variants
# Master variants that are distributed in Exchanges and their product doesnt have any other variant in those Exchanges
lonely_masters_sql = "
SELECT e.id exchange_id, v.id master_variant_id
FROM exchanges e
JOIN exchange_variants ev ON (e.id = ev.exchange_id)
JOIN spree_variants v ON (ev.variant_id = v.id)
WHERE v.is_master = true
AND not exists (SELECT 1
FROM exchanges e_std
JOIN exchange_variants ev_std ON (e_std.id = ev_std.exchange_id)
JOIN spree_variants v_std ON (ev_std.variant_id = v_std.id)
WHERE v_std.is_master = false AND e.order_cycle_id = e_std.order_cycle_id)"
# List of all Master Variant IDs with respective max (latest) Standard Variant ID
latest_standard_variants_sql = "
SELECT v_master.id master_variant_id, max(v.id) standard_variant_id
FROM spree_variants v
JOIN spree_variants v_master ON (v.product_id = v_master.product_id and v_master.is_master = true)
WHERE v.is_master = false
GROUP BY v_master.id"
# Insert latest standard variant of each lonely_master into the Exchanges where the lonely_masters are
execute(
"INSERT INTO exchange_variants (exchange_id, variant_id, created_at, updated_at)
SELECT lonely_masters.exchange_id, latest_standard_variants.standard_variant_id, now(), now()
FROM (#{lonely_masters_sql}) lonely_masters
JOIN (#{latest_standard_variants_sql}) latest_standard_variants on (lonely_masters.master_variant_id = latest_standard_variants.master_variant_id)" )
end
def delete_master_variants
execute("
DELETE
FROM exchange_variants ev
USING spree_variants v
WHERE ev.variant_id = v.id
AND v.is_master = true")
end
end

View File

@@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20190916110029) do
ActiveRecord::Schema.define(:version => 20190918105234) do
create_table "adjustment_metadata", :force => true do |t|
t.integer "adjustment_id"

View File

@@ -6,9 +6,9 @@ include Spree::ReportsHelper
module OpenFoodNetwork
class OrdersAndFulfillmentsReport
attr_reader :params
def initialize(user, params = {}, render_table = false)
def initialize(permissions, params = {}, render_table = false)
@params = params
@user = user
@permissions = permissions
@render_table = render_table
end
@@ -60,30 +60,30 @@ module OpenFoodNetwork
when "order_cycle_supplier_totals"
[
{
group_by: proc { |line_item| find_variant(line_item.variant_id).product.supplier },
group_by: proc { |line_item| line_item.variant.product.supplier },
sort_by: proc { |supplier| supplier.name }
},
{
group_by: proc { |line_item| find_variant(line_item.variant_id).product },
group_by: proc { |line_item| line_item.variant.product },
sort_by: proc { |product| product.name }
},
{
group_by: proc { |line_item| find_variant(line_item.variant_id).full_name },
group_by: proc { |line_item| line_item.variant.full_name },
sort_by: proc { |full_name| full_name }
}
]
when "order_cycle_supplier_totals_by_distributor"
[
{
group_by: proc { |line_item| find_variant(line_item.variant_id).product.supplier },
group_by: proc { |line_item| line_item.variant.product.supplier },
sort_by: proc { |supplier| supplier.name }
},
{
group_by: proc { |line_item| find_variant(line_item.variant_id).product },
group_by: proc { |line_item| line_item.variant.product },
sort_by: proc { |product| product.name }
},
{
group_by: proc { |line_item| find_variant(line_item.variant_id).full_name },
group_by: proc { |line_item| line_item.variant.full_name },
sort_by: proc { |full_name| full_name },
summary_columns: [
proc { |_line_items| "" },
@@ -119,15 +119,15 @@ module OpenFoodNetwork
]
},
{
group_by: proc { |line_item| find_variant(line_item.variant_id).product.supplier },
group_by: proc { |line_item| line_item.variant.product.supplier },
sort_by: proc { |supplier| supplier.name }
},
{
group_by: proc { |line_item| find_variant(line_item.variant_id).product },
group_by: proc { |line_item| line_item.variant.product },
sort_by: proc { |product| product.name }
},
{
group_by: proc { |line_item| find_variant(line_item.variant_id).full_name },
group_by: proc { |line_item| line_item.variant.full_name },
sort_by: proc { |full_name| full_name }
}
]
@@ -184,11 +184,11 @@ module OpenFoodNetwork
]
},
{
group_by: proc { |line_item| find_variant(line_item.variant_id).product },
group_by: proc { |line_item| line_item.variant.product },
sort_by: proc { |product| product.name }
},
{
group_by: proc { |line_item| find_variant(line_item.variant_id) },
group_by: proc { |line_item| line_item.variant },
sort_by: proc { |variant| variant.full_name }
},
{
@@ -220,8 +220,8 @@ module OpenFoodNetwork
when "order_cycle_supplier_totals_by_distributor"
[
supplier_name,
proc { |line_items| find_variant(line_items.first.variant_id).product.name },
proc { |line_items| find_variant(line_items.first.variant_id).full_name },
proc { |line_items| line_items.first.variant.product.name },
proc { |line_items| line_items.first.variant.full_name },
proc { |line_items| line_items.first.order.distributor.name },
proc { |line_items| line_items.sum(&:quantity) },
proc { |line_items| line_items.first.price },
@@ -230,9 +230,9 @@ module OpenFoodNetwork
]
when "order_cycle_distributor_totals_by_supplier"
[proc { |line_items| line_items.first.order.distributor.name },
proc { |line_items| find_variant(line_items.first.variant_id).product.supplier.name },
proc { |line_items| find_variant(line_items.first.variant_id).product.name },
proc { |line_items| find_variant(line_items.first.variant_id).full_name },
proc { |line_items| line_items.first.variant.product.supplier.name },
proc { |line_items| line_items.first.variant.product.name },
proc { |line_items| line_items.first.variant.full_name },
proc { |line_items| line_items.sum(&:quantity) },
proc { |line_items| line_items.first.price },
proc { |line_items| line_items.sum(&:amount) },
@@ -245,9 +245,9 @@ module OpenFoodNetwork
proc { |line_items| line_items.first.order.bill_address.firstname + " " + line_items.first.order.bill_address.lastname },
proc { |line_items| line_items.first.order.email },
proc { |line_items| line_items.first.order.bill_address.phone },
proc { |line_items| find_variant(line_items.first.variant_id).product.supplier.name },
proc { |line_items| find_variant(line_items.first.variant_id).product.name },
proc { |line_items| find_variant(line_items.first.variant_id).full_name },
proc { |line_items| line_items.first.variant.product.supplier.name },
proc { |line_items| line_items.first.variant.product.name },
proc { |line_items| line_items.first.variant.full_name },
proc { |line_items| line_items.sum(&:quantity) },
proc { |line_items| line_items.sum(&:amount) },
@@ -268,7 +268,7 @@ module OpenFoodNetwork
proc { |line_items| line_items.first.order.ship_address.andand.state if rsa.call(line_items) },
proc { |_line_items| "" },
proc { |line_items| find_variant(line_items.first.variant_id).sku },
proc { |line_items| line_items.first.variant.sku },
proc { |line_items| line_items.first.order.order_cycle.andand.name },
proc { |line_items| line_items.first.order.payments.first.andand.payment_method.andand.name },
@@ -288,32 +288,29 @@ module OpenFoodNetwork
private
attr_reader :permissions
def supplier_name
proc { |line_items| find_variant(line_items.first.variant_id).product.supplier.name }
proc { |line_items| line_items.first.variant.product.supplier.name }
end
def product_name
proc { |line_items| find_variant(line_items.first.variant_id).product.name }
proc { |line_items| line_items.first.variant.product.name }
end
def line_item_name
proc { |line_item| find_variant(line_item.variant_id).full_name }
proc { |line_item| line_item.variant.full_name }
end
def line_items_name
proc { |line_items| find_variant(line_items.first.variant_id).full_name }
end
def permissions
return @permissions unless @permissions.nil?
@permissions = OpenFoodNetwork::Permissions.new(@user)
proc { |line_items| line_items.first.variant.full_name }
end
def total_units(line_items)
return " " if not_all_have_unit?(line_items)
total_units = line_items.sum do |li|
product = find_variant(li.variant_id).product
product = li.variant.product
li.quantity * li.unit_value / scale_factor(product)
end
@@ -327,10 +324,5 @@ module OpenFoodNetwork
def scale_factor(product)
product.variant_unit == 'weight' ? 1000 : 1
end
# Returns the variant with the given id, including soft-deleted ones
def find_variant(id)
Spree::Variant.unscoped.find(id)
end
end
end

View File

@@ -1,8 +1,7 @@
module OpenFoodNetwork
class OrdersAndFulfillmentsReport
class DefaultReport
delegate :line_item_name, :find_variant, :supplier_name, :product_name,
:line_items_name, to: :context
delegate :line_item_name, :supplier_name, :product_name, :line_items_name, to: :context
def initialize(context)
@context = context
@@ -25,11 +24,11 @@ module OpenFoodNetwork
def rules
[
{
group_by: proc { |line_item| find_variant(line_item.variant_id).product.supplier },
group_by: proc { |line_item| line_item.variant.product.supplier },
sort_by: proc { |supplier| supplier.name }
},
{
group_by: proc { |line_item| find_variant(line_item.variant_id).product },
group_by: proc { |line_item| line_item.variant.product },
sort_by: proc { |product| product.name }
},
{

View File

@@ -10,8 +10,6 @@ module OpenFoodNetwork
end
def products_json
products = load_products
if products
enterprise_fee_calculator = EnterpriseFeeCalculator.new @distributor, @order_cycle
@@ -29,17 +27,20 @@ module OpenFoodNetwork
private
def load_products
def products
return unless @order_cycle
scoper = ScopeProductToHub.new(@distributor)
OrderCycleDistributedProducts.new(@order_cycle, @distributor).
relation.
order(taxon_order).
each { |product| scoper.scope(product) }.
select do |product|
!product.deleted? && product.has_stock_for_distribution?(@order_cycle, @distributor)
end
@products ||= begin
scoper = ScopeProductToHub.new(@distributor)
distributed_products.products_relation.
order(taxon_order).
each { |product| scoper.scope(product) }
end
end
def distributed_products
OrderCycleDistributedProducts.new(@distributor, @order_cycle)
end
def taxon_order
@@ -53,25 +54,23 @@ module OpenFoodNetwork
end
end
def all_variants_for_shop
@all_variants_for_shop ||= begin
# We use the in_stock? method here instead of the in_stock scope
# because we need to look up the stock as overridden by
# VariantOverrides, and the scope method is not affected by them.
scoper = OpenFoodNetwork::ScopeVariantToHub.new(@distributor)
Spree::Variant.
for_distribution(@order_cycle, @distributor).
each { |v| scoper.scope(v) }.
select(&:in_stock?)
end
def variants_for_shop
@variants_for_shop ||= begin
scoper = OpenFoodNetwork::ScopeVariantToHub.new(@distributor)
distributed_products.variants_relation.
includes(:default_price, :stock_locations, :product).
where(product_id: products).
each { |v| scoper.scope(v) }
end
end
def variants_for_shop_by_id
index_by_product_id all_variants_for_shop.reject(&:is_master)
index_by_product_id variants_for_shop.reject(&:is_master)
end
def master_variants_for_shop_by_id
index_by_product_id all_variants_for_shop.select(&:is_master)
index_by_product_id variants_for_shop.select(&:is_master)
end
def index_by_product_id(variants)

View File

@@ -12,11 +12,11 @@ module OpenFoodNetwork
line_items = permissions.visible_line_items.merge(Spree::LineItem.where(order_id: orders))
line_items = line_items.supplied_by_any(params[:supplier_id_in]) if params[:supplier_id_in].present?
# If empty array is passed in, the where clause will return all line_items, which is bad
line_items_with_hidden_details =
permissions.editable_line_items.empty? ? line_items : line_items.where('"spree_line_items"."id" NOT IN (?)', permissions.editable_line_items)
hidden_line_items = line_items_with_hidden_details(permissions, line_items)
line_items.select{ |li| line_items_with_hidden_details.include? li }.each do |line_item|
line_items.select{ |li|
hidden_line_items.include? li
}.each do |line_item|
# TODO We should really be hiding customer code here too, but until we
# have an actual association between order and customer, it's a bit tricky
line_item.order.bill_address.andand.assign_attributes(firstname: I18n.t('admin.reports.hidden'), lastname: "", phone: "", address1: "", address2: "", city: "", zipcode: "", state: nil)
@@ -25,6 +25,16 @@ module OpenFoodNetwork
end
line_items
end
def self.line_items_with_hidden_details(permissions, line_items)
editable_line_items = permissions.editable_line_items.pluck(:id)
if editable_line_items.empty?
line_items
else
line_items.where('"spree_line_items"."id" NOT IN (?)', editable_line_items)
end
end
end
end
end

View File

@@ -0,0 +1,77 @@
require 'spec_helper'
describe "States" do
include AuthenticationWorkflow
let!(:country) { create(:country) }
before(:each) do
quick_login_as_admin
@hungary = Spree::Country.create!(name: "Hungary", iso_name: "Hungary")
Spree::Config[:default_country_id] = country.id
end
# TODO: For whatever reason, rendering of the states page takes a non-trivial amount of time
# Therefore we navigate to it, and wait until what we see is visible
def go_to_states_page
visit spree.admin_country_states_path(country)
counter = 0
until page.has_css?("#new_state_link")
raise "Could not see new state link!" if counter >= 10
sleep(2)
counter += 1
end
end
context "admin visiting states listing" do
let!(:state) { create(:state, country: country) }
it "should correctly display the states" do
visit spree.admin_country_states_path(country)
expect(page).to have_content(state.name)
end
end
context "creating and editing states" do
it "should allow an admin to edit existing states", js: true do
go_to_states_page
set_select2_field("country", country.id)
click_link "new_state_link"
fill_in "state_name", with: "Calgary"
fill_in "Abbreviation", with: "CL"
click_button "Create"
expect(page).to have_content("successfully created!")
expect(page).to have_content("Calgary")
end
it "should allow an admin to create states for non default countries", js: true do
go_to_states_page
set_select2_field "#country", @hungary.id
# Just so the change event actually gets triggered in this spec
# It is definitely triggered in the "real world"
page.execute_script("$('#country').trigger('change');")
click_link "new_state_link"
fill_in "state_name", with: "Pest megye"
fill_in "Abbreviation", with: "PE"
click_button "Create"
expect(page).to have_content("successfully created!")
expect(page).to have_content("Pest megye")
expect(find("#s2id_country span.select2-chosen").text).to eq("Hungary")
end
it "should show validation errors", js: true do
go_to_states_page
set_select2_field("country", country.id)
click_link "new_state_link"
fill_in "state_name", with: ""
fill_in "Abbreviation", with: ""
click_button "Create"
expect(page).to have_content("Name can't be blank")
end
end
end

View File

@@ -0,0 +1,56 @@
require 'spec_helper'
describe "Tax Categories" do
include AuthenticationWorkflow
before(:each) do
quick_login_as_admin
visit spree.admin_path
click_link "Configuration"
end
context "admin visiting tax categories list" do
it "should display the existing tax categories" do
create(:tax_category, name: "Clothing", description: "For Clothing")
click_link "Tax Categories"
expect(page).to have_content("Listing Tax Categories")
within_row(1) do
expect(column_text(1)).to eq("Clothing")
expect(column_text(2)).to eq("For Clothing")
expect(column_text(3)).to eq("False")
end
end
end
context "admin creating new tax category" do
before(:each) do
click_link "Tax Categories"
click_link "admin_new_tax_categories_link"
end
it "should be able to create new tax category" do
expect(page).to have_content("New Tax Category")
fill_in "tax_category_name", with: "sports goods"
fill_in "tax_category_description", with: "sports goods desc"
click_button "Create"
expect(page).to have_content("successfully created!")
end
it "should show validation errors if there are any" do
click_button "Create"
expect(page).to have_content("Name can't be blank")
end
end
context "admin editing a tax category" do
it "should be able to update an existing tax category" do
create(:tax_category)
click_link "Tax Categories"
within_row(1) { click_icon :edit }
fill_in "tax_category_description", with: "desc 99"
click_button "Update"
expect(page).to have_content("successfully updated!")
expect(page).to have_content("desc 99")
end
end
end

View File

@@ -0,0 +1,32 @@
require 'spec_helper'
describe "Tax Rates" do
include AuthenticationWorkflow
let!(:calculator) { create(:calculator_per_item, calculable: create(:order)) }
let!(:tax_rate) { create(:tax_rate, calculator: calculator) }
before do
quick_login_as_admin
visit spree.admin_path
click_link "Configuration"
end
# Regression test for #535
it "can see a tax rate in the list if the tax category has been deleted" do
tax_rate.tax_category.update_column(:deleted_at, Time.zone.now)
expect { click_link "Tax Rates" }.not_to raise_error
within("table tbody td:nth-child(3)") do
expect(page).to have_content("N/A")
end
end
# Regression test for #1422
it "can create a new tax rate" do
click_link "Tax Rates"
click_link "New Tax Rate"
fill_in "Rate", with: "0.05"
click_button "Create"
expect(page).to have_content("Tax Rate has been successfully created!")
end
end

View File

@@ -0,0 +1,53 @@
require 'spec_helper'
describe "Taxonomies" do
include AuthenticationWorkflow
before(:each) do
quick_login_as_admin
visit spree.admin_path
click_link "Configuration"
end
context "show" do
it "should display existing taxonomies" do
create(:taxonomy, name: 'Brand')
create(:taxonomy, name: 'Categories')
click_link "Taxonomies"
within_row(1) { expect(page).to have_content("Brand") }
within_row(2) { expect(page).to have_content("Categories") }
end
end
context "create" do
before(:each) do
click_link "Taxonomies"
click_link "admin_new_taxonomy_link"
end
it "should allow an admin to create a new taxonomy" do
expect(page).to have_content("New Taxonomy")
fill_in "taxonomy_name", with: "sports"
click_button "Create"
expect(page).to have_content("successfully created!")
end
it "should display validation errors" do
fill_in "taxonomy_name", with: ""
click_button "Create"
expect(page).to have_content("can't be blank")
end
end
context "edit" do
it "should allow an admin to update an existing taxonomy" do
create(:taxonomy)
click_link "Taxonomies"
within_row(1) { click_icon :edit }
fill_in "taxonomy_name", with: "sports 99"
click_button "Update"
expect(page).to have_content("successfully updated!")
expect(page).to have_content("sports 99")
end
end
end

View File

@@ -0,0 +1,40 @@
require 'spec_helper'
describe "Zones" do
include AuthenticationWorkflow
before(:each) do
quick_login_as_admin
Spree::Zone.delete_all
visit spree.admin_path
click_link "Configuration"
end
context "show" do
it "should display existing zones" do
create(:zone, name: "eastern", description: "zone is eastern")
create(:zone, name: "western", description: "cool san fran")
click_link "Zones"
within_row(1) { expect(page).to have_content("eastern") }
within_row(2) { expect(page).to have_content("western") }
click_link "zones_order_by_description_title"
within_row(1) { expect(page).to have_content("western") }
within_row(2) { expect(page).to have_content("eastern") }
end
end
context "create" do
it "should allow an admin to create a new zone" do
click_link "Zones"
click_link "admin_new_zone_link"
expect(page).to have_content("New Zone")
fill_in "zone_name", with: "japan"
fill_in "zone_description", with: "japanese time zone"
click_button "Create"
expect(page).to have_content("successfully created!")
end
end
end

View File

@@ -23,7 +23,7 @@ describe OpenFoodNetwork::OrdersAndFulfillmentsReport do
before { order.line_items << line_item }
context "as a site admin" do
subject { described_class.new admin_user, {}, true }
subject { described_class.new OpenFoodNetwork::Permissions.new(admin_user), {}, true }
it "fetches completed orders" do
o2 = create(:order)
@@ -39,7 +39,7 @@ describe OpenFoodNetwork::OrdersAndFulfillmentsReport do
end
context "as a manager of a supplier" do
subject { described_class.new user, {}, true }
subject { described_class.new OpenFoodNetwork::Permissions.new(user), {}, true }
let(:s1) { create(:supplier_enterprise) }
@@ -98,7 +98,7 @@ describe OpenFoodNetwork::OrdersAndFulfillmentsReport do
end
context "as a manager of a distributor" do
subject { described_class.new user, {}, true }
subject { described_class.new OpenFoodNetwork::Permissions.new(user), {}, true }
before do
distributor.enterprise_roles.create!(user: user)
@@ -133,7 +133,8 @@ describe OpenFoodNetwork::OrdersAndFulfillmentsReport do
]
report_types.each do |report_type|
report = described_class.new admin_user, report_type: report_type
report = described_class.new OpenFoodNetwork::Permissions.new(admin_user),
report_type: report_type
expect(report.header.size).to eq(report.columns.size)
end
end
@@ -149,7 +150,9 @@ describe OpenFoodNetwork::OrdersAndFulfillmentsReport do
end
let(:items) {
report = described_class.new(admin_user, { report_type: "order_cycle_customer_totals" }, true)
report = described_class.new(OpenFoodNetwork::Permissions.new(admin_user),
{ report_type: "order_cycle_customer_totals" },
true)
OpenFoodNetwork::OrderGrouper.new(report.rules, report.columns).table(report.table_items)
}

View File

@@ -25,13 +25,13 @@ module OpenFoodNetwork
it "sorts products by the distributor's preferred taxon list" do
allow(distributor).to receive(:preferred_shopfront_taxon_order) { "#{t1.id},#{t2.id}" }
products = pr.send(:load_products)
products = pr.send(:products)
expect(products).to eq([p2, p4, p1, p3])
end
it "alphabetizes products by name when taxon list is not set" do
allow(distributor).to receive(:preferred_shopfront_taxon_order) { "" }
products = pr.send(:load_products)
products = pr.send(:products)
expect(products).to eq([p1, p2, p3, p4])
end
end

View File

@@ -45,33 +45,14 @@ describe VariantStock do
end
describe '#on_hand=' do
context 'when track_inventory_levels is set' do
before do
allow(Spree::Config)
.to receive(:track_inventory_levels) { true }
end
it 'sets the new level as the stock item\'s count_on_hand' do
variant.on_hand = 3
unique_stock_item = variant.stock_items.first
expect(unique_stock_item.count_on_hand).to eq(3)
end
context 'when the variant has no stock item' do
let(:variant) { build(:variant) }
it 'raises' do
expect { variant.on_hand = 3 }
.to raise_error(StandardError)
end
end
it 'sets the new level as the stock item\'s count_on_hand' do
variant.on_hand = 3
unique_stock_item = variant.stock_items.first
expect(unique_stock_item.count_on_hand).to eq(3)
end
context 'when track_inventory_levels is not set' do
before do
allow(Spree::Config)
.to receive(:track_inventory_levels) { false }
end
context 'when the variant has no stock item' do
let(:variant) { build(:variant) }
it 'raises' do
expect { variant.on_hand = 3 }

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