Compare commits

...

49 Commits

Author SHA1 Message Date
Pau Perez
a6ba956355 Update all locales with the latest Transifex translations 2019-11-07 12:47:10 +01:00
Luis Ramos
76cffe4c7f Merge pull request #4301 from Matt-Yorkley/ruby-2.2.10
Use Ruby 2.2.10
2019-11-07 10:17:54 +00:00
Pau Pérez Fabregat
26477a8d4b Merge pull request #4421 from openfoodfoundation/transifex
Transifex
2019-11-06 18:04:23 +01:00
Luis Ramos
52ab6c52bf Merge pull request #4057 from luisramos0/remove_spree_api_2
Remove dependency to spree_api - step 2 - routes and views
2019-11-06 13:23:32 +00:00
Luis Ramos
413e93fe40 Merge pull request #4431 from Matt-Yorkley/fix_migration_clash
Fix migration mismatch
2019-11-06 09:49:15 +00:00
Matt-Yorkley
9e1b2eb4ca Fix migration mismatch
It looks like this was probably changed whilst resolving a merge conflict somewhere. The number doesn't match the last migration file, and it's breaking the ofn-install CI build (as well as migrations on fresh servers).
2019-11-05 22:58:14 +00:00
Luis Ramos
1ceae6cf8d Merge pull request #4225 from HugsDaniel/4106-edit-product-missing-translations
Add missing translations on product edit page
2019-11-05 19:30:08 +00:00
Transifex-Openfoodnetwork
5183d93601 Updating translations for config/locales/en_DE.yml 2019-11-05 23:45:05 +11:00
Luis Ramos
247854b7fe Merge pull request #4423 from openfoodfoundation/dependabot/bundler/i18n-js-3.4.1
Bump i18n-js from 3.4.0 to 3.4.1
2019-11-04 11:47:13 +00:00
dependabot-preview[bot]
85bd803785 Bump i18n-js from 3.4.0 to 3.4.1
Bumps [i18n-js](https://github.com/fnando/i18n-js) from 3.4.0 to 3.4.1.
- [Release notes](https://github.com/fnando/i18n-js/releases)
- [Changelog](https://github.com/fnando/i18n-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/fnando/i18n-js/compare/v3.4.0...v3.4.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-01 19:39:31 +00:00
Transifex-Openfoodnetwork
c6543edc85 Updating translations for config/locales/en_GB.yml 2019-11-02 01:42:11 +11:00
Transifex-Openfoodnetwork
a91d0973d4 Updating translations for config/locales/en_GB.yml 2019-11-02 01:39:02 +11:00
luisramos0
76e32b126f Add a few more missing translation keys for product images and variants display as and display name 2019-11-01 10:40:02 +11:00
luisramos0
c234cfb890 Add missing translation in the new variant page 2019-11-01 10:40:02 +11:00
luisramos0
38bda1697d Add missing translations in the product variants list page 2019-11-01 10:40:02 +11:00
luisramos0
5fb9ebc594 Add missing translations for variants edit page 2019-11-01 10:40:02 +11:00
luisramos0
acbd4b076d Move product page tabs to a separate translations key namespace 2019-11-01 10:40:01 +11:00
luisramos0
123f7aa68e Use root translation keys for basic actions 2019-11-01 10:39:09 +11:00
luisramos0
2c4af84a81 Move product seo translation keys to specific namespace 2019-11-01 10:39:09 +11:00
luisramos0
34ed16ff30 Add missing translation keys to product properties list 2019-11-01 10:39:09 +11:00
Hugo Daniel
0b20b80219 Add missing translations on product edit page 2019-11-01 10:38:06 +11:00
luisramos0
0fe4edfbf5 Make product_tag_rules_filterer_spec a bit more flexible and not test for the order of the elements 2019-10-30 11:06:25 +00:00
luisramos0
f45eb35eb1 Make user_registrations_controller_spec keep I18n.locale as it was before the spec, so that other specs wont fail 2019-10-30 10:43:46 +00:00
luisramos0
c60261a847 Make taxonomies edit page use api route instead of spree_api route that is now gone. 2019-10-28 16:01:23 +00:00
luisramos0
11fea650d6 Remove inexistent routes api/enterprises/managed and api/enterprises/acessible
The :managed endpoint was delete here 1d92d6cc33
2019-10-28 16:01:23 +00:00
luisramos0
92f1fa3b52 Remove dead route api/orders/managed 2019-10-28 16:01:23 +00:00
luisramos0
ad52022927 Add feature spec to cover api api generation in admin user edit form 2019-10-28 16:01:22 +00:00
luisramos0
9cffe48c70 Do not use Spree.t in spree admin users 2019-10-28 16:01:22 +00:00
luisramos0
d006ded439 Convert spree admin users api fields partial from erb to haml 2019-10-28 16:01:22 +00:00
luisramos0
b2e5ff46a8 Bring missing admin user edit form api_fields partial from spree_api and insert into the form (there was a deface override in spree_api injecting it before) 2019-10-28 16:01:22 +00:00
luisramos0
f46e0a2a31 Remove outdated comment, action managed has already been removed 2019-10-28 16:01:22 +00:00
luisramos0
dd66df6379 Remove dead routes api/order_cycles, these endpoints were removed in PR 4059 because they were unused, implemented in rabl and not correctly named for the future 2019-10-28 16:01:22 +00:00
luisramos0
d7b9dc1190 Fix some rubocop issues 2019-10-28 16:00:36 +00:00
luisramos0
5b6efaf687 Delete now unused rabl template authorise_api 2019-10-28 16:00:36 +00:00
luisramos0
8aab9bacbe Delete now irrelevant authorize_api endpoint and logic
OFN API is now authenticating all users, if no session and no key is provided an anonymous user will be created so that user can access public endpoints, authorization is then done at each individual endpoint. This makes this spree api auth call irrelevant
2019-10-28 16:00:36 +00:00
luisramos0
66fdbe4379 Remove spree_api dependency. Spree_api will keep being a dependency until we remove spree_backend as a dependency but now ofn works without spree_api 2019-10-28 16:00:36 +00:00
luisramos0
abcc22c34b Merge Spree::Api::BaseController with Api::BaseController. All api controllers inherit from Api::BaseController now. We can probably simplify this controller even more now 2019-10-28 16:00:36 +00:00
luisramos0
0d34b607c3 Move spree/api/base_controller#find_product to api/product_controller where it is used exclusively
Also, product_scope stops being an override
2019-10-28 16:00:36 +00:00
luisramos0
f840179573 Remove .json from Spree.routes.orders_api. This path is only used to compose the order shipments path and thus cannot have the .json 2019-10-28 16:00:36 +00:00
luisramos0
b5a521476b Remove unused method from api/base_controller 2019-10-28 16:00:36 +00:00
luisramos0
7c64777a50 Remove requires_authentication check from api/base_controller. OFN api does not require auth, it always generates an anonymous user for public endpoints 2019-10-28 16:00:36 +00:00
luisramos0
c98b4b276b Adapt spree/admin/shared/_routes.html.erb to new location of the api/taxons routes AND move spree/api/orders route to ofn api/orders route 2019-10-28 16:00:36 +00:00
luisramos0
f1138709aa Add spree_api translation keys, mostly from api standard errors and api fields in admin/users 2019-10-28 16:00:36 +00:00
luisramos0
b29983ac60 Add AMS versions of the error responses in api/base_controller and cover not_found case with a unit test 2019-10-28 16:00:36 +00:00
luisramos0
91188c5724 Adapt api/base_controller_spec from spree/api/base_controller_spec 2019-10-28 16:00:36 +00:00
luisramos0
bf291ec318 Move spree/api/base_controller_spec to api/base_controller_spec 2019-10-28 16:00:36 +00:00
luisramos0
5846593637 Remove dependency to spree_api rabl responders, we should only use AMS from now on 2019-10-28 16:00:36 +00:00
luisramos0
cf40bfa58e Simbolize keys in opts hash in xero report so that opts access works again 2019-10-15 18:05:40 +01:00
Matt-Yorkley
8e03f402b1 Use Ruby 2.2.10 2019-10-15 14:59:24 +01:00
57 changed files with 3845 additions and 447 deletions

View File

@@ -1 +1 @@
2.1.9
2.2.10

10
Gemfile
View File

@@ -1,9 +1,9 @@
source 'https://rubygems.org'
ruby "2.1.9"
ruby "2.2.10"
git_source(:github) { |repo_name| "https://github.com/#{repo_name}.git" }
gem 'i18n', '~> 0.6.11'
gem 'i18n-js', '~> 3.4.0'
gem 'i18n-js', '~> 3.4.1'
gem 'rails', '~> 3.2.22'
gem 'rails-i18n', '~> 3.0.0'
gem 'rails_safe_tasks', '~> 1.0'
@@ -15,12 +15,12 @@ gem 'nokogiri', '>= 1.6.7.1'
gem "order_management", path: "./engines/order_management"
gem 'web', path: './engines/web'
gem 'pg'
gem 'activerecord-postgresql-adapter'
gem 'pg', '~> 0.21.0'
# OFN-maintained and patched version of Spree v2.0.4. See
# https://github.com/openfoodfoundation/openfoodnetwork/wiki/Spree-2.0-upgrade
# for details.
gem 'spree_api', github: 'openfoodfoundation/spree', branch: '2-0-4-stable'
gem 'spree_backend', github: 'openfoodfoundation/spree', branch: '2-0-4-stable'
gem 'spree_core', github: 'openfoodfoundation/spree', branch: '2-0-4-stable'
@@ -98,6 +98,8 @@ gem 'roo-xls', '~> 1.1.0'
gem 'whenever', require: false
gem 'test-unit', '~> 3.0'
# Gems used only for assets and not required
# in production environments by default.
group :assets do

View File

@@ -131,6 +131,8 @@ GEM
tzinfo (~> 0.3.29)
activerecord-import (1.0.3)
activerecord (>= 3.2)
activerecord-postgresql-adapter (0.0.1)
pg
activeresource (3.2.22.5)
activemodel (= 3.2.22.5)
activesupport (= 3.2.22.5)
@@ -437,7 +439,7 @@ GEM
httparty (0.16.2)
multi_xml (>= 0.5.2)
i18n (0.6.11)
i18n-js (3.4.0)
i18n-js (3.4.1)
i18n (>= 0.6.6)
immigrant (0.3.6)
activerecord (>= 3.0)
@@ -522,6 +524,7 @@ GEM
polyamorous (0.5.0)
activerecord (~> 3.0)
polyglot (0.3.5)
power_assert (1.1.5)
powerpack (0.1.1)
pry (0.12.2)
coderay (~> 1.1.0)
@@ -671,6 +674,8 @@ GEM
stripe (4.24.0)
faraday (~> 0.13)
net-http-persistent (~> 3.0)
test-unit (3.3.3)
power_assert
thor (0.20.3)
tilt (1.4.1)
timecop (0.9.1)
@@ -722,6 +727,7 @@ DEPENDENCIES
active_model_serializers (= 0.8.4)
activemerchant (~> 1.78)
activerecord-import
activerecord-postgresql-adapter
acts-as-taggable-on (~> 3.4)
andand
angular-rails-templates (~> 0.3.0)
@@ -762,7 +768,7 @@ DEPENDENCIES
gmaps4rails
haml
i18n (~> 0.6.11)
i18n-js (~> 3.4.0)
i18n-js (~> 3.4.1)
immigrant
jquery-migrate-rails
jquery-rails (= 3.0.4)
@@ -783,7 +789,7 @@ DEPENDENCIES
order_management!
paper_trail (~> 5.2.3)
paperclip (~> 3.4.1)
pg
pg (~> 0.21.0)
pry-byebug (>= 3.4.3)
rabl
rack-mini-profiler (< 1.0.0)
@@ -806,7 +812,6 @@ DEPENDENCIES
simple_form!
simplecov
spinjs-rails
spree_api!
spree_backend!
spree_core!
spree_i18n!
@@ -814,6 +819,7 @@ DEPENDENCIES
spring (= 1.7.2)
spring-commands-rspec
stripe
test-unit (~> 3.0)
timecop
truncate_html
turbo-sprockets-rails3
@@ -828,7 +834,7 @@ DEPENDENCIES
wkhtmltopdf-binary
RUBY VERSION
ruby 2.1.9p490
ruby 2.2.10p489
BUNDLED WITH
1.17.2

View File

@@ -1,4 +1,4 @@
angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout, $filter, $http, $window, BulkProducts, DisplayProperties, DirtyProducts, VariantUnitManager, StatusMessage, producers, Taxons, SpreeApiAuth, Columns, tax_categories, RequestMonitor) ->
angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout, $filter, $http, $window, BulkProducts, DisplayProperties, DirtyProducts, VariantUnitManager, StatusMessage, producers, Taxons, Columns, tax_categories, RequestMonitor) ->
$scope.StatusMessage = StatusMessage
$scope.columns = Columns.columns
@@ -39,12 +39,7 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout
$scope.DisplayProperties = DisplayProperties
$scope.initialise = ->
SpreeApiAuth.authorise()
.then ->
$scope.spree_api_key_ok = true
$scope.fetchProducts()
.catch (message) ->
$scope.api_error_msg = message
$scope.fetchProducts()
$scope.$watchCollection '[query, producerFilter, categoryFilter, importDateFilter, per_page]', ->
$scope.page = 1 # Reset page when changing filters for new search

View File

@@ -1,16 +0,0 @@
angular.module("admin.indexUtils").factory "SpreeApiAuth", ($q, $http, SpreeApiKey) ->
new class SpreeApiAuth
authorise: ->
deferred = $q.defer()
$http.get("/api/users/authorise_api?token=" + SpreeApiKey)
.success (response) ->
if response?.success == "Use of API Authorised"
$http.defaults.headers.common["X-Spree-Token"] = SpreeApiKey
deferred.resolve()
.error (response) ->
error = response?.error || t('js.unauthorized')
deferred.reject(error)
deferred.promise

View File

@@ -1,4 +1,4 @@
angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl", ($scope, $http, $timeout, Indexer, Columns, Views, SpreeApiAuth, PagedFetcher, StatusMessage, RequestMonitor, hubs, producers, hubPermissions, InventoryItems, VariantOverrides, DirtyVariantOverrides) ->
angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl", ($scope, $http, $timeout, Indexer, Columns, Views, PagedFetcher, StatusMessage, RequestMonitor, hubs, producers, hubPermissions, InventoryItems, VariantOverrides, DirtyVariantOverrides) ->
$scope.hubs = Indexer.index hubs
$scope.hub_id = if hubs.length == 1 then hubs[0].id else null
$scope.products = []
@@ -39,13 +39,7 @@ angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl",
$scope.producerFilter != 0 || $scope.query != ''
$scope.initialise = ->
SpreeApiAuth.authorise()
.then ->
$scope.spree_api_key_ok = true
$scope.fetchProducts()
.catch (message) ->
$scope.api_error_msg = message
$scope.fetchProducts()
$scope.fetchProducts = ->
url = "/api/products/overridable?page=::page::;per_page=100"

View File

@@ -1,16 +1,44 @@
# Base controller for OFN's API
# Includes the minimum machinery required by ActiveModelSerializers
require_dependency 'spree/api/controller_setup'
module Api
class BaseController < Spree::Api::BaseController
# Need to include these because Spree::Api::BaseContoller inherits
# from ActionController::Metal rather than ActionController::Base
# and they are required by ActiveModelSerializers
class BaseController < ActionController::Metal
include Spree::Api::ControllerSetup
include Spree::Core::ControllerHelpers::SSL
include ::ActionController::Head
respond_to :json
attr_accessor :current_api_user
before_filter :set_content_type
before_filter :authenticate_user
after_filter :set_jsonp_format
rescue_from Exception, with: :error_during_processing
rescue_from CanCan::AccessDenied, with: :unauthorized
rescue_from ActiveRecord::RecordNotFound, with: :not_found
helper Spree::Api::ApiHelpers
ssl_allowed
# Include these because we inherit from ActionController::Metal
# rather than ActionController::Base and these are required for AMS
include ActionController::Serialization
include ActionController::UrlFor
include Rails.application.routes.url_helpers
use_renderers :json
check_authorization
def set_jsonp_format
return unless params[:callback] && request.get?
self.response_body = "#{params[:callback]}(#{response_body})"
headers["Content-Type"] = 'application/javascript'
end
def respond_with_conflict(json_hash)
render json: json_hash, status: :conflict
end
@@ -19,16 +47,62 @@ module Api
# Use logged in user (spree_current_user) for API authentication (current_api_user)
def authenticate_user
@current_api_user = try_spree_current_user
super
return if @current_api_user = try_spree_current_user
if api_key.blank?
# An anonymous user
@current_api_user = Spree.user_class.new
return
end
return if @current_api_user = Spree.user_class.find_by_spree_api_key(api_key.to_s)
invalid_api_key
end
# Allows API access without authentication, but only for OFN controllers which inherit
# from Api::BaseController. @current_api_user will now initialize an empty Spree::User
# unless one is present. We now also apply devise's `check_authorization`. See here for
# details: https://github.com/CanCanCommunity/cancancan/wiki/Ensure-Authorization
def requires_authentication?
false
def set_content_type
content_type = case params[:format]
when "json"
"application/json"
when "xml"
"text/xml"
end
headers["Content-Type"] = content_type
end
def error_during_processing(exception)
render(text: { exception: exception.message }.to_json,
status: :unprocessable_entity) && return
end
def current_ability
Spree::Ability.new(current_api_user)
end
def api_key
request.headers["X-Spree-Token"] || params[:token]
end
helper_method :api_key
def invalid_resource!(resource)
@resource = resource
render(json: { error: I18n.t(:invalid_resource, scope: "spree.api"),
errors: @resource.errors },
status: :unprocessable_entity)
end
def invalid_api_key
render(json: { error: I18n.t(:invalid_api_key, key: api_key, scope: "spree.api") },
status: :unauthorized) && return
end
def unauthorized
render(json: { error: I18n.t(:unauthorized, scope: "spree.api") },
status: :unauthorized) && return
end
def not_found
render(json: { error: I18n.t(:resource_not_found, scope: "spree.api") },
status: :not_found) && return
end
end
end

View File

@@ -47,7 +47,6 @@ module Api
render json: @product, serializer: Api::Admin::ProductSerializer, status: 204
end
# TODO: This should be named 'managed'. Is the action above used? Maybe we should remove it.
def bulk_products
product_query = OpenFoodNetwork::Permissions.new(current_api_user).
editable_products.merge(product_scope)
@@ -94,10 +93,13 @@ module Api
private
# Copied and modified from SpreeApi::BaseController to allow
# enterprise users to access inactive products
def find_product(id)
product_scope.find_by_permalink!(id.to_s)
rescue ActiveRecord::RecordNotFound
product_scope.find(id)
end
def product_scope
# This line modified
if current_api_user.has_spree_role?("admin") || current_api_user.enterprises.present?
scope = Spree::Product
if params[:show_deleted]

View File

@@ -58,14 +58,14 @@ module Spree
def generate_api_key
if @user.generate_spree_api_key!
flash[:success] = Spree.t('api.key_generated')
flash[:success] = t('spree.api.key_generated')
end
redirect_to edit_admin_user_path(@user)
end
def clear_api_key
if @user.clear_spree_api_key!
flash[:success] = Spree.t('api.key_cleared')
flash[:success] = t('spree.api.key_cleared')
end
redirect_to edit_admin_user_path(@user)
end

View File

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

View File

@@ -1,7 +0,0 @@
module Spree
module Api
class UsersController < Spree::Api::BaseController
respond_to :json
end
end
end

View File

@@ -7,7 +7,7 @@
- content_for :page_actions do
%ul.tollbar.inline-menu
%li
= link_to_add_fields Spree.t(:add_product_properties), 'tbody#product_properties', class: 'icon-plus button'
= link_to_add_fields t('.add_product_properties'), 'tbody#product_properties', class: 'icon-plus button'
= form_for @product, url: admin_product_url(@product), method: :put do |f|
%fieldset.no-border-top
@@ -27,7 +27,7 @@
= render partial: 'product_property_fields', locals: { f: pp_form }
= f.check_box :inherits_properties
= f.label :inherits_properties, t(".inherits_properties_checkbox_hint", supplier: @product.supplier.name)
= f.label :inherits_properties, t('.inherits_properties_checkbox_hint', supplier: @product.supplier.name)
%br
%br

View File

@@ -1,17 +1,17 @@
.row{"data-hook" => "admin_product_meta_form"}
.alpha.eleven.columns
= f.field_container :meta_keywords do
= f.label :meta_keywords, t(:product_search_keywords)
%span.icon-question-sign{ 'ofn-with-tip' => t('admin.products.product_search_tip') }
= f.label :meta_keywords, t('admin.products.seo.product_search_keywords')
%span.icon-question-sign{ 'ofn-with-tip' => t('admin.products.seo.product_search_tip') }
%br/
= f.text_field :meta_keywords, :class => 'fullwidth', :rows => 6
= f.field_container :meta_description do
= f.label :meta_description, t(:SEO_keywords)
%span.icon-question-sign{ 'ofn-with-tip' => t('admin.products.seo_tip') }
= f.label :meta_description, t('admin.products.seo.SEO_keywords')
%span.icon-question-sign{ 'ofn-with-tip' => t('admin.products.seo.seo_tip') }
%br/
= f.text_field :meta_description, :class => 'fullwidth', :rows => 6
.alpha.eleven.columns
= f.field_container :notes do
= f.label :notes, t(:notes)
= f.text_area :notes, { :class => 'fullwidth', rows: 5 }
= f.error_message_on :notes
= f.error_message_on :notes

View File

@@ -1,6 +1,3 @@
%div{ 'ng-show' => '!spree_api_key_ok' }
{{ api_error_msg }}
%div.sixteen.columns.alpha#loading{ 'ng-if' => 'RequestMonitor.loading' }
%br
%img.spinner{ src: "/assets/spinning-circles.svg" }

View File

@@ -1,5 +1,5 @@
= render partial: 'spree/admin/shared/product_sub_menu'
= render :partial => 'spree/admin/shared/product_tabs', :locals => { :current => t(:Search) }
= render :partial => 'spree/admin/shared/product_tabs', :locals => { :current => t(:search) }
= render :partial => 'spree/shared/error_messages', :locals => { :target => @product }
%div{ 'ng-app' => 'ofn.admin' }

View File

@@ -1,4 +1,4 @@
.form-buttons.filter-actions.actions
= button Spree.t('actions.update'), 'icon-refresh'
%span.or= Spree.t(:or)
= button_link_to Spree.t('actions.cancel'), collection_url, icon: 'icon-remove'
= button t(:update), 'icon-refresh'
%span.or= t(:or)
= button_link_to t(:cancel), collection_url, icon: 'icon-remove'

View File

@@ -1,5 +1,5 @@
- content_for :page_title do
= Spree.t(:editing_product)
= t('admin.products.editing_product')
= "\"#{@product.name}\""
- content_for :sidebar_title do
@@ -12,22 +12,22 @@
- if can?(:admin, Spree::Product)
- klass = current == 'Product Details' ? 'active' : ''
%li{:class => klass}
= link_to_with_icon 'icon-edit', Spree.t(:product_details), edit_admin_product_url(@product)
= link_to_with_icon 'icon-edit', t('admin.products.tabs.product_details'), edit_admin_product_url(@product)
- if can?(:admin, Spree::Image)
- klass = current == 'Images' ? 'active' : ''
%li{:class => klass}
= link_to_with_icon 'icon-picture', Spree.t(:images), admin_product_images_url(@product)
= link_to_with_icon 'icon-picture', t('admin.products.tabs.images'), admin_product_images_url(@product)
- if can?(:admin, Spree::Variant)
- klass = current == 'Variants' ? 'active' : ''
%li{:class => klass}
= link_to_with_icon 'icon-th-large', Spree.t(:variants), admin_product_variants_url(@product)
= link_to_with_icon 'icon-th-large', t('admin.products.tabs.variants'), admin_product_variants_url(@product)
- if can?(:admin, Spree::ProductProperty)
- klass = current == 'Product Properties' ? 'active' : ''
%li{:class => klass}
= link_to_with_icon 'icon-tasks', Spree.t(:product_properties), admin_product_product_properties_url(@product)
= link_to_with_icon 'icon-tasks', t('admin.products.tabs.product_properties'), admin_product_product_properties_url(@product)
- klass = current == 'Group Buy Options' ? 'active' : ''
%li{:class => klass}
= link_to_with_icon 'icon-tasks', t('admin.products.group_buy_options'), group_buy_options_admin_product_url(@product)
- klass = current == t(:Search) ? 'active' : ''
= link_to_with_icon 'icon-tasks', t('admin.products.tabs.group_buy_options'), group_buy_options_admin_product_url(@product)
- klass = current == t(:search) ? 'active' : ''
%li{:class => klass}
= link_to_with_icon 'icon-tasks', t(:Search), seo_admin_product_url(@product)
= link_to_with_icon 'icon-tasks', t(:search), seo_admin_product_url(@product)

View File

@@ -3,6 +3,6 @@
:variants_search => spree.admin_search_variants_path(:format => 'json'),
:taxons_search => main_app.api_taxons_path(:format => 'json'),
:user_search => spree.admin_search_users_path(:format => 'json'),
:orders_api => spree.api_orders_path(:format => 'json')
:orders_api => main_app.api_orders_path
}.to_json %>;
</script>

View File

@@ -17,7 +17,7 @@
= label_tag nil, t("spree.tree")
%br/
:javascript
Spree.routes.taxonomy_taxons_path = "#{spree.api_taxonomy_taxons_path(@taxonomy)}";
Spree.routes.taxonomy_taxons_path = "#{main_app.api_taxonomy_taxons_path(@taxonomy)}";
Spree.routes.admin_taxonomy_taxons_path = "#{spree.admin_taxonomy_taxons_path(@taxonomy)}";
#taxonomy_tree.tree
#progress{style: "display:none;"}

View File

@@ -0,0 +1,18 @@
%fieldset.omega.six.columns
%legend= t('spree.api.access')
- if @user.spree_api_key.present?
.field
= label_tag t('spree.api.key')
= ":"
= @user.spree_api_key
.filter-actions.actions
= form_tag spree.clear_api_key_admin_user_path(@user), method: :put do
= button t('spree.api.clear_key'), 'icon-trash'
%span.or= t(:or)
= form_tag spree.generate_api_key_admin_user_path(@user), method: :put do
= button t('spree.api.regenerate_key'), 'icon-refresh'
- else
.no-objects-found= t('spree.api.no_key')
.filter-actions.actions
= form_tag spree.generate_api_key_admin_user_path(@user), method: :put do
= button t('spree.api.generate_key'), 'icon-key'

View File

@@ -13,3 +13,5 @@
= render partial: "form", locals: { f: f }
%div{"data-hook" => "admin_user_edit_form_button"}
= render partial: "spree/admin/shared/edit_resource_links"
= render partial: 'spree/admin/users/api_fields'

View File

@@ -1,9 +1,9 @@
.label-block.left.six.columns.alpha{'ng-app' => 'admin.products'}
.field
= f.label :display_name, t(:display_name)
= f.label :display_name, t('.display_name')
= f.text_field :display_name, class: "fullwidth"
.field
= f.label :display_as, t(:display_as)
= f.label :display_as, t('.display_as')
= f.text_field :display_as, class: "fullwidth"
- if product_has_variant_unit_option_type?(@product)
@@ -29,13 +29,13 @@
- if opt = @variant.option_values.detect {|o| o.option_type == option_type }.try(:presentation)
= text_field(:new_variant, option_type.presentation, value: opt, disabled: 'disabled', class: 'fullwidth')
.field
= f.label :sku, Spree.t(:sku)
= f.label :sku, t('.sku')
= f.text_field :sku, class: 'fullwidth'
.field
= f.label :price, Spree.t(:price)
= f.label :price, t('.price')
= f.text_field :price, value: number_to_currency(@variant.price, unit: ''), class: 'fullwidth'
.field
= f.label :cost_price, Spree.t(:cost_price)
= f.label :cost_price, t('.cost_price')
= f.text_field :cost_price, value: number_to_currency(@variant.cost_price, unit: ''), class: 'fullwidth'
%div{ 'set-on-demand' => '' }
@@ -53,7 +53,7 @@
.right.six.columns.omega.label-block
- if @product.variant_unit != 'weight'
.field
= f.label 'weight', t('weight')+' (kg)'
= f.label 'weight', t(:weight)+' (kg)'
- value = number_with_precision(@variant.weight, precision: 2)
= f.text_field 'weight', value: value, class: 'fullwidth'

View File

@@ -14,9 +14,9 @@
%col{style: "width: 15%"}/
%thead
%tr
%th{colspan: "2"}= Spree.t(:options)
%th= Spree.t(:price)
%th= Spree.t(:sku)
%th{colspan: "2"}= t('.options')
%th= t('.price')
%th= t('.sku')
%th.actions
%tbody
- @variants.each do |variant|
@@ -31,24 +31,24 @@
= link_to_delete(variant, no_text: true) unless variant.deleted?
- unless @product.has_variants?
%tr
%td{colspan: "5"}= Spree.t(:none)
%td{colspan: "5"}= t(:none)
- else
.alpha.twelve.columns.no-objects-found
= Spree.t(:no_results)
= t('.no_results')
\.
- if @product.empty_option_values?
%p.first_add_option_types.no-objects-found
= Spree.t(:to_add_variants_you_must_first_define)
= link_to Spree.t(:option_types), admin_product_url(@product)
= Spree.t(:and)
= link_to Spree.t(:option_values), admin_option_types_url
= t('.to_add_variants_you_must_first_define')
= link_to t('.option_types'), admin_product_url(@product)
= t('.and')
= link_to t('.option_values'), admin_option_types_url
- else
- content_for :page_actions do
%ul.inline-menu
%li#new_var_link
= link_to_with_icon('icon-plus', Spree.t(:new_variant), new_admin_product_variant_url(@product), remote: true, 'data-update' => 'new_variant', class: 'button')
= link_to_with_icon('icon-plus', t('.new_variant'), new_admin_product_variant_url(@product), remote: true, 'data-update' => 'new_variant', class: 'button')
%li= link_to_with_icon('icon-filter', @deleted.blank? ? Spree.t(:show_deleted) : Spree.t(:show_active), admin_product_variants_url(@product, deleted: @deleted.blank? ? "on" : "off"), class: 'button')
%li= link_to_with_icon('icon-filter', @deleted.blank? ? t('.show_deleted') : t('.show_active'), admin_product_variants_url(@product, deleted: @deleted.blank? ? "on" : "off"), class: 'button')

View File

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

View File

@@ -1,2 +0,0 @@
object false
node(:success) { "Use of API Authorised" }

View File

@@ -421,19 +421,23 @@ ar:
av_on: "المتوسط. على"
import_date: مستورد
upload_an_image: تحميل صورة
product_search_keywords: كلمات البحث المنتج
product_search_tip: اكتب كلمات للمساعدة في البحث عن منتجاتك في المتاجر. استخدام المسافة لفصل كل كلمة رئيسية.
SEO_keywords: SEO الكلمات الرئيسية
seo_tip: اكتب كلمات للمساعدة في البحث عن منتجاتك على الويب. استخدام المسافة لفصل كل كلمة رئيسية.
Search: بحث
seo:
product_search_keywords: "كلمات البحث المنتج"
product_search_tip: "اكتب كلمات للمساعدة في البحث عن منتجاتك في المتاجر. استخدام المسافة لفصل كل كلمة رئيسية."
SEO_keywords: "SEO الكلمات الرئيسية"
seo_tip: "اكتب كلمات للمساعدة في البحث عن منتجاتك على الويب. استخدام المسافة لفصل كل كلمة رئيسية."
search: "بحث"
properties:
property_name: اسم الخاصية
inherited_property: الخصائص الموروثة
property_name: "اسم الخاصية"
inherited_property: "الخصائص الموروثة"
variants:
infinity: "ما لا نهاية"
to_order_tip: "لا تحتوي المواد التي تريد طلبها على مستوى مخزون محدد ، مثل أرغفة الخبز المصنوعة طازجة حسب الطلب."
group_buy_options: "مجموعة خيارات الشراء"
back_to_products_list: "العودة إلى قائمة المنتجات"
tabs:
group_buy_options: "مجموعة خيارات الشراء"
images: "صور"
product_properties: "خصائص المنتج"
product_import:
title: استيراد المنتج
file_not_found: لم يتم العثور على الملف أو تعذر فتحه
@@ -3003,6 +3007,15 @@ ar:
email_confirmation:
confirmation_pending: "تأكيد البريد الإلكتروني معلق. لقد أرسلنا رسالة تأكيد بالبريد الإلكتروني إلى %{address}."
variants:
index:
sku: "SKU"
price: "السعر"
no_results: "لا يوجد نتائج"
option_types: "أنواع الخيارات"
form:
sku: "SKU"
price: "السعر"
display_as: "عرض ب"
autocomplete:
producer_name: "المنتج"
unit: "وحدة"

View File

@@ -421,19 +421,23 @@ ca:
av_on: "Disp. via"
import_date: S'ha importat
upload_an_image: Penja una imatge
product_search_keywords: Paraules clau de cerca de producte
product_search_tip: Escriviu paraules per ajudar-vos a cercar els vostres productes a les botigues. Utilitzeu espai per separar cada paraula clau.
SEO_keywords: Paraules clau de SEO
seo_tip: Escriviu paraules per ajudar-vos a cercar els vostres productes a la web. Utilitzeu espai per separar cada paraula clau.
Search: Cerca
seo:
product_search_keywords: "Paraules clau de cerca de producte"
product_search_tip: "Escriviu paraules per ajudar-vos a cercar els vostres productes a les botigues. Utilitzeu espai per separar cada paraula clau."
SEO_keywords: "Paraules clau de SEO"
seo_tip: "Escriviu paraules per ajudar-vos a cercar els vostres productes a la web. Utilitzeu espai per separar cada paraula clau."
search: "Cerca"
properties:
property_name: Nom de la propietat
inherited_property: Propietat heretada
property_name: "Nom de la propietat"
inherited_property: "Propietat heretada"
variants:
infinity: "Infinit"
to_order_tip: "Els articles preparats per encàrrec no tenen un nivell fixat d'existències, com ara pa fet sota comanda."
group_buy_options: "Opcions de compra en grup"
back_to_products_list: "Torna a la llista de productes"
tabs:
group_buy_options: "Opcions de compra en grup"
images: "Imatges"
product_properties: "Propietats del producte"
product_import:
title: Importació de productes
file_not_found: No s'ha trobat el fitxer o no s'ha pogut obrir
@@ -3008,6 +3012,15 @@ ca:
email_confirmation:
confirmation_pending: "La confirmació de correu electrònic està pendent. Hem enviat un correu electrònic de confirmació a %{address}."
variants:
index:
sku: "Número de referència (SKU)"
price: "Preu"
no_results: "Sense resultats"
option_types: "Tipus d'opcions"
form:
sku: "Número de referència (SKU)"
price: "Preu"
display_as: "Mostra com"
autocomplete:
producer_name: "Productor"
unit: "Unitat"

View File

@@ -417,19 +417,23 @@ de_DE:
av_on: "Verfüg. am"
import_date: Importiert
upload_an_image: Bild hochladen
product_search_keywords: Stichwörter für die Produktsuche
product_search_tip: Geben Sie Wörter ein, um Ihre Produkte in den Geschäften zu suchen. Verwenden Sie Leerzeichen, um jedes Keyword zu trennen.
SEO_keywords: SEO Schlüsselwörter
seo_tip: Geben Sie Wörter ein, um Ihre Produkte im Internet zu durchsuchen. Verwenden Sie Leerzeichen, um jedes Keyword zu trennen.
Search: Suche
seo:
product_search_keywords: "Stichwörter für die Produktsuche"
product_search_tip: "Geben Sie Wörter ein, um Ihre Produkte in den Geschäften zu suchen. Verwenden Sie Leerzeichen, um jedes Keyword zu trennen."
SEO_keywords: "SEO Schlüsselwörter"
seo_tip: "Geben Sie Wörter ein, um Ihre Produkte im Internet zu durchsuchen. Verwenden Sie Leerzeichen, um jedes Keyword zu trennen."
search: "Suche"
properties:
property_name: Name der Eigenschaft
inherited_property: Vererbte Eigenschaft
property_name: "Name der Eigenschaft"
inherited_property: "Vererbte Eigenschaft"
variants:
infinity: "Unendlichkeit"
to_order_tip: "Artikel, die auf Bestellung hergestellt werden, haben keinen festgelegten Lagerbestand."
group_buy_options: "Gruppenkaufoptionen"
back_to_products_list: "Zurück zur Produktliste"
tabs:
group_buy_options: "Gruppenkaufoptionen"
images: "Bilder"
product_properties: "Produkteigenschaften"
product_import:
title: Produkte importieren
file_not_found: Datei nicht gefunden oder konnte nicht geöffnet werden
@@ -3003,6 +3007,13 @@ de_DE:
email_confirmation:
confirmation_pending: "E-Mail-Bestätigung steht aus. Wir haben eine Bestätigungs-E-Mail an %{address} gesendet."
variants:
index:
sku: "Artikelnummer"
price: "Preis"
form:
sku: "Artikelnummer"
price: "Preis"
display_as: "Angezeigt als"
autocomplete:
producer_name: "Produzent"
unit: "Einheit"

View File

@@ -474,19 +474,26 @@ en:
av_on: "Av. On"
import_date: Imported
upload_an_image: Upload an image
product_search_keywords: Product Search Keywords
product_search_tip: Type words to help search your products in the shops. Use space to separate each keyword.
SEO_keywords: SEO Keywords
seo_tip: Type words to help search your products in the web. Use space to separate each keyword.
Search: Search
seo:
product_search_keywords: "Product Search Keywords"
product_search_tip: "Type words to help search your products in the shops. Use space to separate each keyword."
SEO_keywords: "SEO Keywords"
seo_tip: "Type words to help search your products in the web. Use space to separate each keyword."
search: "Search"
properties:
property_name: Property Name
inherited_property: Inherited Property
property_name: "Property Name"
inherited_property: "Inherited Property"
variants:
infinity: "Infinity"
to_order_tip: "Items made to order do not have a set stock level, such as loaves of bread made fresh to order."
group_buy_options: "Group Buy Options"
back_to_products_list: "Back to products list"
editing_product: "Editing Product"
tabs:
product_details: "Product Details"
group_buy_options: "Group Buy Options"
images: "Images"
variants: "Variants"
product_properties: "Product Properties"
product_import:
title: Product Import
@@ -2931,6 +2938,13 @@ See the %{link} to find out more about %{sitename}'s features and to start using
normal_amount: "Normal Amount"
discount_amount: "Discount Amount"
no_images_found: "No Images Found"
new_image: "New Image"
filename: "Filename"
alt_text: "Alternative Text"
thumbnail: "Thumbnail"
back_to_images_list: "Back To Images List"
# TODO: remove `email` key once we get to Spree 2.0
email: Email
# TODO: remove 'account_updated' key once we get to Spree 2.0
@@ -2944,6 +2958,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using
zipcode: Postcode
weight: Weight (per kg)
error_user_destroy_with_orders: "Users with completed orders may not be deleted"
options: "Options"
actions:
update: "Update"
@@ -2976,6 +2991,8 @@ See the %{link} to find out more about %{sitename}'s features and to start using
product_properties:
index:
inherits_properties_checkbox_hint: "Inherit properties from %{supplier}? (unless overridden above)"
add_product_properties: "Add Product Properties"
select_from_prototype: "Select From Prototype"
orders:
index:
listing_orders: "Listing Orders"
@@ -3163,6 +3180,26 @@ See the %{link} to find out more about %{sitename}'s features and to start using
email_confirmation:
confirmation_pending: "Email confirmation is pending. We've sent a confirmation email to %{address}."
variants:
index:
sku: "SKU"
price: "Price"
options: "Options"
no_results: "No results"
to_add_variants_you_must_first_define: "To add variants, you must first define"
option_types: "Option Types"
option_values: "Option Values"
and: "and"
new_variant: "New Variant"
show_active: "Show Active"
show_deleted: "Show Deleted"
new:
new_variant: "New Variant"
form:
cost_price: "Cost Price"
sku: "SKU"
price: "Price"
display_as: "Display As"
display_name: "Display Name"
autocomplete:
producer_name: "Producer"
unit: "Unit"
@@ -3302,3 +3339,19 @@ See the %{link} to find out more about %{sitename}'s features and to start using
allow_charges?: "Allow Charges?"
localized_number:
invalid_format: has an invalid format. Please enter a number.
api:
invalid_api_key: "Invalid API key (%{key}) specified."
unauthorized: "You are not authorized to perform that action."
invalid_resource: "Invalid resource. Please fix errors and try again."
resource_not_found: "The resource you were looking for could not be found."
access: "API Access"
key: "Key"
clear_key: "Clear key"
regenerate_key: "Regenerate Key"
no_key: "No key"
generate_key: "Generate API key"
key_generated: "Key generated"
key_cleared: "Key cleared"
shipment:
cannot_ready: "Cannot ready shipment."
invalid_taxonomy_id: "Invalid taxonomy id."

View File

@@ -418,19 +418,23 @@ en_AU:
av_on: "Av. On"
import_date: Imported
upload_an_image: Upload an image
product_search_keywords: Product Search Keywords
product_search_tip: Type words to help search your products in the shops. Use space to separate each keyword.
SEO_keywords: SEO Keywords
seo_tip: Type words to help search your products in the web. Use space to separate each keyword.
Search: Search
seo:
product_search_keywords: "Product Search Keywords"
product_search_tip: "Type words to help search your products in the shops. Use space to separate each keyword."
SEO_keywords: "SEO Keywords"
seo_tip: "Type words to help search your products in the web. Use space to separate each keyword."
search: "Search"
properties:
property_name: Property Name
inherited_property: Inherited Property
property_name: "Property Name"
inherited_property: "Inherited Property"
variants:
infinity: "Infinity"
to_order_tip: "Items made to order do not have a set stock level, such as loaves of bread made fresh to order."
group_buy_options: "Group Buy Options"
back_to_products_list: "Back to products list"
tabs:
group_buy_options: "Group Buy Options"
images: "Images"
product_properties: "Product Properties"
product_import:
title: Product Import
file_not_found: File not found or could not be opened
@@ -2996,6 +3000,15 @@ en_AU:
email_confirmation:
confirmation_pending: "Email confirmation is pending. We've sent a confirmation email to %{address}."
variants:
index:
sku: "SKU"
price: "Price"
no_results: "No results"
option_types: "Option Types"
form:
sku: "SKU"
price: "Price"
display_as: "Display As"
autocomplete:
producer_name: "Producer"
unit: "Unit"

View File

@@ -416,19 +416,23 @@ en_BE:
av_on: "Av. On"
import_date: Imported
upload_an_image: Upload an image
product_search_keywords: Product Search Keywords
product_search_tip: Type words to help search your products in the shops. Use space to separate each keyword.
SEO_keywords: SEO Keywords
seo_tip: Type words to help search your products in the web. Use space to separate each keyword.
Search: Search
seo:
product_search_keywords: "Product Search Keywords"
product_search_tip: "Type words to help search your products in the shops. Use space to separate each keyword."
SEO_keywords: "SEO Keywords"
seo_tip: "Type words to help search your products in the web. Use space to separate each keyword."
search: "Search"
properties:
property_name: Property Name
inherited_property: Inherited Property
property_name: "Property Name"
inherited_property: "Inherited Property"
variants:
infinity: "Infinity"
to_order_tip: "Items made to order do not have a set stock level, such as loaves of bread made fresh to order."
group_buy_options: "Group Buy Options"
back_to_products_list: "Back to products list"
tabs:
group_buy_options: "Group Buy Options"
images: "Images"
product_properties: "Product Properties"
product_import:
title: Product Import
file_not_found: File not found or could not be opened
@@ -2989,6 +2993,15 @@ en_BE:
email_confirmation:
confirmation_pending: "Email confirmation is pending. We've sent a confirmation email to %{address}."
variants:
index:
sku: "SKU"
price: "Price"
no_results: "No results"
option_types: "Option Types"
form:
sku: "SKU"
price: "Price"
display_as: "Display As"
autocomplete:
producer_name: "Producer"
unit: "Unit"

View File

@@ -419,19 +419,23 @@ en_CA:
av_on: "Av. On"
import_date: Imported
upload_an_image: Upload an image
product_search_keywords: Product Search Keywords
product_search_tip: Type words to help search your products in the shops. Use space to separate each keyword.
SEO_keywords: SEO Keywords
seo_tip: Type words to help search your products in the web. Use space to separate each keyword.
Search: Search
seo:
product_search_keywords: "Product Search Keywords"
product_search_tip: "Type words to help search your products in the shops. Use space to separate each keyword."
SEO_keywords: "SEO Keywords"
seo_tip: "Type words to help search your products in the web. Use space to separate each keyword."
search: "Search"
properties:
property_name: Property Name
inherited_property: Inherited Property
property_name: "Property Name"
inherited_property: "Inherited Property"
variants:
infinity: "Infinity"
to_order_tip: "Items made to order do not have a set stock level, such as loaves of bread made fresh to order."
group_buy_options: "Group Buy Options"
back_to_products_list: "Back to products list"
tabs:
group_buy_options: "Group Buy Options"
images: "Images"
product_properties: "Product Properties"
product_import:
title: Product Import
file_not_found: File not found or could not be opened
@@ -3000,6 +3004,15 @@ en_CA:
email_confirmation:
confirmation_pending: "Email confirmation is pending. We've sent a confirmation email to %{address}."
variants:
index:
sku: "SKU"
price: "Price"
no_results: "No results"
option_types: "Option Types"
form:
sku: "SKU"
price: "Price"
display_as: "Display As"
autocomplete:
producer_name: "Producer"
unit: "Unit"

3157
config/locales/en_DE.yml Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -421,19 +421,23 @@ en_GB:
av_on: "Av. On"
import_date: Imported
upload_an_image: Upload an image
product_search_keywords: Product Search Keywords
product_search_tip: Type words to help search your products in the shops. Use space to separate each keyword.
SEO_keywords: SEO Keywords
seo_tip: Type words to help search your products in the web. Use space to separate each keyword.
Search: Search
seo:
product_search_keywords: "Product Search Keywords"
product_search_tip: "Type words to help search your products in the shops. Use space to separate each keyword."
SEO_keywords: "SEO Keywords"
seo_tip: "Type words to help search your products in the web. Use space to separate each keyword."
search: "Search"
properties:
property_name: Property Name
inherited_property: Inherited Property
property_name: "Property Name"
inherited_property: "Inherited Property"
variants:
infinity: "Infinity"
to_order_tip: "Items made to order do not have a set stock level, such as loaves of bread made fresh to order."
group_buy_options: "Group Buy Options"
back_to_products_list: "Back to products list"
tabs:
group_buy_options: "Group Buy Options"
images: "Images"
product_properties: "Product Properties"
product_import:
title: Product Import
file_not_found: File not found or could not be opened
@@ -535,6 +539,7 @@ en_GB:
title: Inventory
description: Use this page to manage inventories for your enterprises. Any product details set here will override those set on the 'Products' page
enable_reset?: Enable Stock Reset?
default_stock: "Default stock"
inherit?: Inherit?
add: Add
hide: Hide
@@ -3008,6 +3013,15 @@ en_GB:
email_confirmation:
confirmation_pending: "Email confirmation is pending. We've sent a confirmation email to %{address}."
variants:
index:
sku: "Product Code"
price: "Price"
no_results: "No results"
option_types: "Option Types"
form:
sku: "Product Code"
price: "Price"
display_as: "Display As"
autocomplete:
producer_name: "Producer"
unit: "Unit"

View File

@@ -421,19 +421,23 @@ en_NZ:
av_on: "Av. On"
import_date: Imported
upload_an_image: Upload an image
product_search_keywords: Product Search Keywords
product_search_tip: Type words to help search your products in the shops. Use space to separate each keyword.
SEO_keywords: SEO Keywords
seo_tip: Type words to help search your products in the web. Use space to separate each keyword.
Search: Search
seo:
product_search_keywords: "Product Search Keywords"
product_search_tip: "Type words to help search your products in the shops. Use space to separate each keyword."
SEO_keywords: "SEO Keywords"
seo_tip: "Type words to help search your products in the web. Use space to separate each keyword."
search: "Search"
properties:
property_name: Property Name
inherited_property: Inherited Property
property_name: "Property Name"
inherited_property: "Inherited Property"
variants:
infinity: "Infinity"
to_order_tip: "Items made to order do not have a set stock level, such as loaves of bread made fresh to order."
group_buy_options: "Group Buy Options"
back_to_products_list: "Back to products list"
tabs:
group_buy_options: "Group Buy Options"
images: "Images"
product_properties: "Product Properties"
product_import:
title: Product Import
file_not_found: File not found or could not be opened
@@ -3003,6 +3007,15 @@ en_NZ:
email_confirmation:
confirmation_pending: "Email confirmation is pending. We've sent a confirmation email to %{address}."
variants:
index:
sku: "SKU"
price: "Price"
no_results: "No results"
option_types: "Option Types"
form:
sku: "SKU"
price: "Price"
display_as: "Display As"
autocomplete:
producer_name: "Producer"
unit: "Unit"

View File

@@ -419,19 +419,23 @@ en_US:
av_on: "Av. On"
import_date: Imported
upload_an_image: Upload an image
product_search_keywords: Product Search Keywords
product_search_tip: Type words to help search your products in the shops. Use space to separate each keyword.
SEO_keywords: SEO Keywords
seo_tip: Type words to help search your products in the web. Use space to separate each keyword.
Search: Search
seo:
product_search_keywords: "Product Search Keywords"
product_search_tip: "Type words to help search your products in the shops. Use space to separate each keyword."
SEO_keywords: "SEO Keywords"
seo_tip: "Type words to help search your products in the web. Use space to separate each keyword."
search: "Search"
properties:
property_name: Property Name
inherited_property: Inherited Property
property_name: "Property Name"
inherited_property: "Inherited Property"
variants:
infinity: "Infinity"
to_order_tip: "Items made to order do not have a set stock level, such as loaves of bread made fresh to order."
group_buy_options: "Group Buy Options"
back_to_products_list: "Back to products list"
tabs:
group_buy_options: "Group Buy Options"
images: "Images"
product_properties: "Product Properties"
product_import:
title: Product Import
file_not_found: File not found or could not be opened
@@ -3000,6 +3004,15 @@ en_US:
email_confirmation:
confirmation_pending: "Email confirmation is pending. We've sent a confirmation email to %{address}."
variants:
index:
sku: "SKU"
price: "Price"
no_results: "No results"
option_types: "Option Types"
form:
sku: "SKU"
price: "Price"
display_as: "Display As"
autocomplete:
producer_name: "Producer"
unit: "Unit"

View File

@@ -418,19 +418,23 @@ en_ZA:
av_on: "Av. On"
import_date: Imported
upload_an_image: Upload an image
product_search_keywords: Product Search Keywords
product_search_tip: Type words to help search your products in the shops. Use space to separate each keyword.
SEO_keywords: SEO Keywords
seo_tip: Type words to help search your products in the web. Use space to separate each keyword.
Search: Search
seo:
product_search_keywords: "Product Search Keywords"
product_search_tip: "Type words to help search your products in the shops. Use space to separate each keyword."
SEO_keywords: "SEO Keywords"
seo_tip: "Type words to help search your products in the web. Use space to separate each keyword."
search: "Search"
properties:
property_name: Property Name
inherited_property: Inherited Property
property_name: "Property Name"
inherited_property: "Inherited Property"
variants:
infinity: "Infinity"
to_order_tip: "Items made to order do not have a set stock level, such as loaves of bread made fresh to order."
group_buy_options: "Group Buy Options"
back_to_products_list: "Back to products list"
tabs:
group_buy_options: "Group Buy Options"
images: "Images"
product_properties: "Product Properties"
product_import:
title: Product Import
file_not_found: File not found or could not be opened
@@ -3003,6 +3007,15 @@ en_ZA:
email_confirmation:
confirmation_pending: "Email confirmation is pending. We've sent a confirmation email to %{address}."
variants:
index:
sku: "SKU"
price: "Price"
no_results: "No results"
option_types: "Option Types"
form:
sku: "SKU"
price: "Price"
display_as: "Display As"
autocomplete:
producer_name: "Producer"
unit: "Unit"

View File

@@ -421,19 +421,23 @@ es:
av_on: "Av. En"
import_date: Importado
upload_an_image: Subir una imagen
product_search_keywords: Palabras clave de búsqueda de productos
product_search_tip: Escriba palabras para ayudar a buscar sus productos en las tiendas. Use espacio para separar cada palabra clave.
SEO_keywords: Palabras clave de SEO
seo_tip: Escriba palabras para ayudar a buscar sus productos en la web. Use espacio para separar cada palabra clave.
Search: Buscar
seo:
product_search_keywords: "Palabras clave de búsqueda de productos"
product_search_tip: "Escriba palabras para ayudar a buscar sus productos en las tiendas. Use espacio para separar cada palabra clave."
SEO_keywords: "Palabras clave de SEO"
seo_tip: "Escriba palabras para ayudar a buscar sus productos en la web. Use espacio para separar cada palabra clave."
search: "Buscar"
properties:
property_name: Nombre de la Propiedad
inherited_property: Propiedad Heredada
property_name: "Nombre de la Propiedad"
inherited_property: "Propiedad Heredada"
variants:
infinity: "infinito"
to_order_tip: "Los artículos hechos según demanda no tienen un nivel de stock, como por ejemplo panes hechos según demanda."
group_buy_options: "Opciones de compra grupales"
back_to_products_list: "Volver a la lista de productos"
tabs:
group_buy_options: "Opciones de compra grupales"
images: "Imágenes"
product_properties: "Propiedades del producto"
product_import:
title: Importación de productos
file_not_found: Archivo no encontrado o no se pudo abrir
@@ -3009,6 +3013,15 @@ es:
email_confirmation:
confirmation_pending: "La confirmación por correo electrónico está pendiente. Hemos enviado un correo electrónico de confirmación a %{address}."
variants:
index:
sku: "SKU"
price: "Precio"
no_results: "No hay resultados"
option_types: "Tipos de opciones"
form:
sku: "SKU"
price: "Precio"
display_as: "Mostrar como"
autocomplete:
producer_name: "Productora"
unit: "Unidad"

View File

@@ -421,19 +421,23 @@ fr:
av_on: "Disp. via"
import_date: Importé
upload_an_image: Importer une image
product_search_keywords: Mots-clés de recherche produits
product_search_tip: Saisissez des mots qui peuvent simplifier la recherche de vo produits dans les boutiques. Laissez un espace entre chaque mot-clé.
SEO_keywords: Mot-clés de référencement web
seo_tip: Saisissez des mots qui peuvent simplifier la recherche de vos produits sur le web. Laissez un espace entre chaque mot-clé.
Search: Rechercher
seo:
product_search_keywords: "Mots-clés de recherche produits"
product_search_tip: "Saisissez des mots qui peuvent simplifier la recherche de vo produits dans les boutiques. Laissez un espace entre chaque mot-clé."
SEO_keywords: "Mot-clés de référencement web"
seo_tip: "Saisissez des mots qui peuvent simplifier la recherche de vos produits sur le web. Laissez un espace entre chaque mot-clé."
search: "Rechercher"
properties:
property_name: Nom du label
inherited_property: Label producteur appliqué par défaut
property_name: "Nom du label"
inherited_property: "Label producteur appliqué par défaut"
variants:
infinity: "Infini"
to_order_tip: "Les articles fabriqués sur commande n'ont pas un niveau de stock défini, comme des pains faits à la main."
group_buy_options: "Options d'achat par lot"
back_to_products_list: "Retour à la liste produits"
tabs:
group_buy_options: "Options d'achat par lot"
images: "Images"
product_properties: "Propriétés / labels Produits"
product_import:
title: Import liste produits
file_not_found: Fichier non trouvé ou impossible à ouvrir
@@ -3032,6 +3036,15 @@ fr:
email_confirmation:
confirmation_pending: "L'email de confirmation n'a pas encore été validé. Il a été envoyé à %{address}."
variants:
index:
sku: "Référence Produit"
price: "Prix"
no_results: "Pas de résultats"
option_types: "Types d'options"
form:
sku: "Référence Produit"
price: "Prix"
display_as: "Unité affichéé"
autocomplete:
producer_name: "Producteur"
unit: "Unité"

View File

@@ -416,19 +416,23 @@ fr_BE:
av_on: "Disp. via"
import_date: Importé
upload_an_image: Importer une image
product_search_keywords: Mots-clés de recherche produits
product_search_tip: Saisissez des mots qui peuvent simplifier la recherche de vos produits dans les comptoirs. Laissez un espace entre chaque mot-clé.
SEO_keywords: Mot-clés de référencement web
seo_tip: Saisissez des mots qui peuvent simplifier la recherche de vos produits sur le web. Laissez un espace entre chaque mot-clé.
Search: Rechercher
seo:
product_search_keywords: "Mots-clés de recherche produits"
product_search_tip: "Saisissez des mots qui peuvent simplifier la recherche de vos produits dans les comptoirs. Laissez un espace entre chaque mot-clé."
SEO_keywords: "Mot-clés de référencement web"
seo_tip: "Saisissez des mots qui peuvent simplifier la recherche de vos produits sur le web. Laissez un espace entre chaque mot-clé."
search: "Rechercher"
properties:
property_name: Nom du label
inherited_property: Label producteur appliqué par défaut
property_name: "Nom du label"
inherited_property: "Label producteur appliqué par défaut"
variants:
infinity: "Infinité"
to_order_tip: "Les articles fabriqués sur commande n'ont pas un niveau de stock défini, comme des pains faits à la main."
group_buy_options: "Options d'achat par lot"
back_to_products_list: "Retour à la liste produits"
tabs:
group_buy_options: "Options d'achat par lot"
images: "Images"
product_properties: "Propriétés / labels Produits"
product_import:
title: Import liste produits
file_not_found: Fichier non trouvé ou impossible à ouvrir
@@ -3003,6 +3007,15 @@ fr_BE:
email_confirmation:
confirmation_pending: "L'email de confirmation n'a pas encore été validé. Il a été envoyé à %{address}."
variants:
index:
sku: "Référence produit"
price: "Prix"
no_results: "Aucun résultat"
option_types: "Option Types "
form:
sku: "Référence produit"
price: "Prix"
display_as: "Unité affichéé"
autocomplete:
producer_name: "Producteur"
unit: "Unité"

View File

@@ -420,19 +420,23 @@ fr_CA:
av_on: "Disp. via"
import_date: importé
upload_an_image: Importer une image
product_search_keywords: Mots-clés de recherche produits
product_search_tip: Saisissez des mots qui peuvent simplifier la recherche de vos produits dans les boutiques. Laissez un espace entre chaque mot-clé.
SEO_keywords: Mot-clés de référencement web
seo_tip: Saisissez des mots qui peuvent simplifier la recherche de vos produits sur le web. Laissez un espace entre chaque mot-clé.
Search: Rechercher
seo:
product_search_keywords: "Mots-clés de recherche produits"
product_search_tip: "Saisissez des mots qui peuvent simplifier la recherche de vos produits dans les boutiques. Laissez un espace entre chaque mot-clé."
SEO_keywords: "Mot-clés de référencement web"
seo_tip: "Saisissez des mots qui peuvent simplifier la recherche de vos produits sur le web. Laissez un espace entre chaque mot-clé."
search: "Chercher"
properties:
property_name: Nom du label
inherited_property: Label producteur appliqué par défaut
property_name: "Nom du label"
inherited_property: "Label producteur appliqué par défaut"
variants:
infinity: "Infini"
to_order_tip: "Les articles fabriqués sur commande n'ont pas un niveau de stock défini, comme des pains faits à la main."
group_buy_options: "Options d'achat par lot"
back_to_products_list: "Retour à la liste produits"
tabs:
group_buy_options: "Options d'achat par lot"
images: "Images"
product_properties: "Propriétés / labels Produits"
product_import:
title: import produit
file_not_found: Fichier non trouvé ou impossible à ouvrir
@@ -3011,6 +3015,15 @@ fr_CA:
email_confirmation:
confirmation_pending: "L'email de confirmation n'a pas encore été validé. Il a été envoyé à %{address}."
variants:
index:
sku: "Référence Produit"
price: "Prix"
no_results: "Pas de résultats"
option_types: "Types d'options"
form:
sku: "Référence Produit"
price: "Prix"
display_as: "Afficher comme"
autocomplete:
producer_name: "Producteur"
unit: "Unité"

View File

@@ -408,18 +408,22 @@ it:
av_on: "Disp. il"
import_date: Importato
upload_an_image: Carica un'immagine
product_search_keywords: Cerca prodotto per parole chiave
product_search_tip: Digita le parole che possono aiutare a trovare i tuoi prodotti nei negozi. Usa lo spazio per separare ciascuna parola chiave.
SEO_keywords: SEO Keywords
seo_tip: Digita le parole che possono aiutare a trovare i tuoi prodotti nel web. Usa lo spazio per separare ciascuna parola chiave.
Search: Cerca
seo:
product_search_keywords: "Cerca prodotto per parole chiave"
product_search_tip: "Digita le parole che possono aiutare a trovare i tuoi prodotti nei negozi. Usa lo spazio per separare ciascuna parola chiave."
SEO_keywords: "SEO Keywords"
seo_tip: "Digita le parole che possono aiutare a trovare i tuoi prodotti nel web. Usa lo spazio per separare ciascuna parola chiave."
search: "Cerca"
properties:
property_name: Nome della Proprietà
inherited_property: Proprietà Ereditata
property_name: "Nome della Proprietà"
inherited_property: "Proprietà Ereditata"
variants:
to_order_tip: "Gli articoli messi in ordine non hanno un livello di stock impostato, come ad esempio il Pane fresco su ordinazione."
group_buy_options: "Opzioni Acquisti di gruppo"
back_to_products_list: "Indietro alla lista dei prodotti"
tabs:
group_buy_options: "Opzioni Acquisti di gruppo"
images: "Immagini"
product_properties: "Proprietà prodotto"
product_import:
title: Importa prodotto
file_not_found: Documento non trovato o non disponibile
@@ -2921,6 +2925,15 @@ it:
email_confirmation:
confirmation_pending: "Email di conferma in sospeso. Abbiamo inviato una mail di conferma a %{address}."
variants:
index:
sku: "SKU"
price: "Prezzo"
no_results: "Nessun risultato"
option_types: "Tipi di opzioni"
form:
sku: "SKU"
price: "Prezzo"
display_as: "Visualizza come"
autocomplete:
producer_name: "Produttore"
unit: "Unità"

View File

@@ -421,19 +421,23 @@ nb:
av_on: "Tilgj. På"
import_date: Importert
upload_an_image: Last opp et bilde
product_search_keywords: Nøkkelord for produktsøk
product_search_tip: Skriv ord for å søke etter dine produkter i butikkene. Bruk mellomrom for å skille mellom hvert nøkkelord.
SEO_keywords: SEO Nøkkelord
seo_tip: Skriv ord for å søke etter produktene dine på nettet. Bruk mellomrom for å skille mellom hvert søkeord.
Search: Søk
seo:
product_search_keywords: "Nøkkelord for produktsøk"
product_search_tip: "Skriv ord for å søke etter dine produkter i butikkene. Bruk mellomrom for å skille mellom hvert nøkkelord."
SEO_keywords: "SEO Nøkkelord"
seo_tip: "Skriv ord for å søke etter produktene dine på nettet. Bruk mellomrom for å skille mellom hvert søkeord."
search: "Søk"
properties:
property_name: Navn på egenskap
inherited_property: Arvet egenskap
property_name: "Navn på egenskap"
inherited_property: "Arvet egenskap"
variants:
infinity: "Uendelig"
to_order_tip: "Varer laget for bestilling har ikke et lagernivå, slik som ferske skiver brød laget for bestilling."
group_buy_options: "Gruppekjøpsalternativer"
back_to_products_list: "Tilbake til produktlisten"
tabs:
group_buy_options: "Gruppekjøpsalternativer"
images: "Bilder"
product_properties: "Produktegenskaper"
product_import:
title: Produktimport
file_not_found: Filen ble ikke funnet eller kunne ikke åpnes
@@ -3002,6 +3006,15 @@ nb:
email_confirmation:
confirmation_pending: "Epostbekreftelse venter. Vi har sendt en bekreftelses-epost til %{address}."
variants:
index:
sku: "SKU"
price: "Pris"
no_results: "Ingen resultater"
option_types: "Valgtyper"
form:
sku: "SKU"
price: "Pris"
display_as: "Vis som"
autocomplete:
producer_name: "Produsent"
unit: "Enhet"

View File

@@ -416,19 +416,23 @@ nl_BE:
av_on: "Av. Op"
import_date: Geïmporteerd
upload_an_image: Een afbeelding uploaden
product_search_keywords: Product Zoeken op Trefwoorden
product_search_tip: ' Typ woorden om te helpen bij het zoeken naar uw producten in de winkels. Gebruik ruimte om elk trefwoord te scheiden.'
SEO_keywords: SEO Trefwoorden
seo_tip: Typ woorden om te helpen bij het zoeken naar uw producten op het web. Gebruik ruimte om elk trefwoord te scheiden.
Search: Zoeken
seo:
product_search_keywords: "Product Zoeken op Trefwoorden"
product_search_tip: " Typ woorden om te helpen bij het zoeken naar uw producten in de winkels. Gebruik ruimte om elk trefwoord te scheiden."
SEO_keywords: "SEO Trefwoorden"
seo_tip: "Typ woorden om te helpen bij het zoeken naar uw producten op het web. Gebruik ruimte om elk trefwoord te scheiden."
search: "Zoeken"
properties:
property_name: Naam van het pand
inherited_property: Onroerend goed uit het verleden
property_name: "Naam van het pand"
inherited_property: "Onroerend goed uit het verleden"
variants:
infinity: "Oneindigheid"
to_order_tip: "Op bestelling gemaakte artikelen hebben geen vast voorraadniveau, zoals broden die vers op bestelling worden gemaakt."
group_buy_options: "Group Buy Options"
back_to_products_list: "Terug naar productenlijst"
tabs:
group_buy_options: "Group Buy Options"
images: "Afbeeldingen"
product_properties: "Producteigenschappen"
product_import:
title: Importeren van producten
file_not_found: Bestand niet gevonden of kon niet worden geopend
@@ -2998,6 +3002,15 @@ nl_BE:
email_confirmation:
confirmation_pending: "De validatie van de bevestigins e-mail naar %{address} toegestuurd is nog niet toegekomen."
variants:
index:
sku: "SKU"
price: "Prijs"
no_results: "Geen resultaten "
option_types: "Optietypen"
form:
sku: "SKU"
price: "Prijs"
display_as: "Weergeven als"
autocomplete:
producer_name: "Producent"
unit: "Unit"

View File

@@ -408,19 +408,23 @@ pt:
av_on: "Disp. em"
import_date: Importado
upload_an_image: Carregar uma imagem
product_search_keywords: Palavras-chave para Pesquisa de Produto
product_search_tip: Insira palavras que ajudem a encontrar os seus produtos nas lojas. Use um espaço para separar cada palavra-chave
SEO_keywords: Palavras-chave para fins de SEO
seo_tip: Insira palavras que ajudem a encontrar os seus produtos na web. Use um espaço para separar cada palavra-chave
Search: Procurar
seo:
product_search_keywords: "Palavras-chave para Pesquisa de Produto"
product_search_tip: "Insira palavras que ajudem a encontrar os seus produtos nas lojas. Use um espaço para separar cada palavra-chave"
SEO_keywords: "Palavras-chave para fins de SEO"
seo_tip: "Insira palavras que ajudem a encontrar os seus produtos na web. Use um espaço para separar cada palavra-chave"
search: "Procurar"
properties:
property_name: Nome da propriedade
inherited_property: Propriedade herdada
property_name: "Nome da propriedade"
inherited_property: "Propriedade herdada"
variants:
infinity: "Infinito"
to_order_tip: "Os itens feitos por encomenda não têm um nível de stock definido, como pão fresco, por exemplo."
group_buy_options: "Opções de Compra Colectiva"
back_to_products_list: "Voltar à lista de produtos"
tabs:
group_buy_options: "Opções de Compra Colectiva"
images: "Imagens"
product_properties: "Propriedades do Produto"
product_import:
title: Importação de Produtos
file_not_found: O ficheiro não foi encontrado ou não pôde ser aberto
@@ -2930,6 +2934,15 @@ pt:
email_confirmation:
confirmation_pending: "A confirmação de email está pendente. Enviamos um email de confirmação para %{address}"
variants:
index:
sku: "SKU"
price: "Preço"
no_results: "Nenhum resultado"
option_types: "Tipos de Opções"
form:
sku: "SKU"
price: "Preço"
display_as: "Mostrar como"
autocomplete:
producer_name: "Produtor"
unit: "Unidade"

View File

@@ -419,19 +419,22 @@ pt_BR:
av_on: "Disp. Em"
import_date: Importado
upload_an_image: Carregar uma imagem
product_search_keywords: Palavras-chave da pesquisa de produto
product_search_tip: Digite palavras para ajudar a pesquisar seus produtos nas lojas. Use espaço para separar cada palavra-chave.
SEO_keywords: SEO Palavras-chave
seo_tip: Digite palavras para ajudar a pesquisar seus produtos na web. Use espaço para separar cada palavra-chave.
Search: Buscar
seo:
product_search_keywords: "Palavras-chave da pesquisa de produto"
product_search_tip: "Digite palavras para ajudar a pesquisar seus produtos nas lojas. Use espaço para separar cada palavra-chave."
SEO_keywords: "SEO Palavras-chave"
seo_tip: "Digite palavras para ajudar a pesquisar seus produtos na web. Use espaço para separar cada palavra-chave."
search: "Buscar"
properties:
property_name: Nome da propriedade
inherited_property: Propriedade herdada
property_name: "Nome da propriedade"
inherited_property: "Propriedade herdada"
variants:
infinity: "Infinidade"
to_order_tip: "Os itens feitos por encomenda não têm um nível de estoque definido, como pão fresco, por exemplo."
group_buy_options: "Opções de compra em grupo"
back_to_products_list: "Voltar à lista de produtos"
tabs:
images: "Imagens"
product_properties: "Propriedades do produto"
product_import:
title: Importação de produtos
file_not_found: O arquivo não foi encontrado ou não pôde ser aberto
@@ -3002,6 +3005,13 @@ pt_BR:
email_confirmation:
confirmation_pending: "A confirmação do email está pendente. Enviámos um email de confirmação para %{address}."
variants:
index:
sku: "SKU"
price: "Preço"
form:
sku: "SKU"
price: "Preço"
display_as: "Mostrar Como"
autocomplete:
producer_name: "Produtor"
unit: "Unidade"

View File

@@ -220,12 +220,15 @@ sv:
inherits_properties?: Ärva egenskaper?
available_on: 'Tillgänglig '
av_on: "Md. På"
Search: Sök
search: "Sök"
properties:
property_name: Egendomens Namn
inherited_property: Ärvd Egendom
property_name: "Egendomens Namn"
inherited_property: "Ärvd Egendom"
variants:
to_order_tip: "Varor som framställs för en order har inget eget varunummer, ex formbröd som värms vid en order."
tabs:
images: "Bilder"
product_properties: "Produktegenskaper"
product_import:
file_not_found: Filen hittades inte eller kunde inte öppnas
no_data: Ingen data hittades i kalkylbladet
@@ -2026,6 +2029,13 @@ sv:
enterprise_limit: "Företagets gräns"
password: "Lösenord"
variants:
index:
sku: "SKU"
price: "Pris"
form:
sku: "SKU"
price: "Pris"
display_as: "Visa som"
autocomplete:
producer_name: "Producent"
unit: "Enhet"

View File

@@ -16,8 +16,6 @@ Openfoodnetwork::Application.routes.draw do
resources :variants, :only => [:index]
resources :orders, only: [:index, :show] do
get :managed, on: :collection
resources :shipments, :only => [:create, :update] do
member do
put :ready
@@ -30,8 +28,6 @@ Openfoodnetwork::Application.routes.draw do
resources :enterprises do
post :update_image, on: :member
get :managed, on: :collection
get :accessible, on: :collection
resource :logo, only: [:destroy]
resource :promo_image, only: [:destroy]
@@ -42,9 +38,6 @@ Openfoodnetwork::Application.routes.draw do
end
resources :order_cycles do
get :managed, on: :collection
get :accessible, on: :collection
get :products, on: :member
get :taxons, on: :member
get :properties, on: :member

View File

@@ -51,12 +51,6 @@ Spree::Core::Engine.routes.prepend do
resources :credit_cards
namespace :api, :defaults => { :format => 'json' } do
resources :users do
get :authorise_api, on: :collection
end
end
namespace :admin do
get '/search/known_users' => "search#known_users", :as => :search_known_users
get '/search/customers' => 'search#customers', :as => :search_customers

View File

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

View File

@@ -4,6 +4,7 @@ module OpenFoodNetwork
@user = user
@opts = opts.
symbolize_keys.
reject { |_k, v| v.blank? }.
reverse_merge( report_type: 'summary',
invoice_date: Time.zone.today,

View File

@@ -1,5 +1,3 @@
require 'spree/api/responders'
module Spree
module Api
module ControllerSetup
@@ -24,7 +22,6 @@ module Spree
prepend_view_path Rails.root + "app/views"
append_view_path File.expand_path("../../../app/views", File.dirname(__FILE__))
self.responder = Spree::Api::Responders::AppResponder
respond_to :json
end
end

View File

@@ -1,8 +1,10 @@
require 'spec_helper'
describe Spree::Api::BaseController do
describe Api::BaseController do
render_views
controller(Spree::Api::BaseController) do
controller(Api::BaseController) do
skip_authorization_check only: :index
def index
render text: { "products" => [] }.to_json
end
@@ -23,13 +25,15 @@ describe Spree::Api::BaseController do
end
end
context "cannot make a request to the API" do
context "can make an anonymous request to the API" do
it "without an API key" do
api_get :index
expect(json_response).to eq( "error" => "You must specify an API key." )
expect(response.status).to eq(401)
expect(json_response["products"]).to eq []
expect(response.status).to eq(200)
end
end
context "cannot make a request to the API" do
it "with an invalid API key" do
request.env["X-Spree-Token"] = "fake_key"
get :index, {}
@@ -46,19 +50,15 @@ describe Spree::Api::BaseController do
it 'handles exceptions' do
expect(subject).to receive(:authenticate_user).and_return(true)
expect(subject).to receive(:index).and_raise(Exception.new("no joy"))
get :index, token: "fake_key"
get :index
expect(json_response).to eq( "exception" => "no joy" )
end
it "maps symantec keys to nested_attributes keys" do
klass = double(nested_attributes_options: { line_items: {},
bill_address: {} })
attributes = { 'line_items' => { id: 1 },
'bill_address' => { id: 2 },
'name' => 'test order' }
mapped = subject.map_nested_attributes_keys(klass, attributes)
expect(mapped.key?('line_items_attributes')).to be_truthy
expect(mapped.key?('name')).to be_truthy
it 'handles record not found' do
expect(subject).to receive(:authenticate_user).and_return(true)
expect(subject).to receive(:index).and_raise(ActiveRecord::RecordNotFound.new)
get :index
expect(json_response).to eq( "error" => "The resource you were looking for could not be found." )
expect(response.status).to eq(404)
end
end

View File

@@ -49,12 +49,14 @@ describe UserRegistrationsController, type: :controller do
end
it "sets user.locale from cookie on create" do
original_i18n_locale = I18n.locale
original_locale_cookie = cookies[:locale]
cookies[:locale] = "pt"
xhr :post, :create, spree_user: user_params, use_route: :spree
expect(assigns[:user].locale).to eq("pt")
I18n.locale = original_i18n_locale
cookies[:locale] = original_locale_cookie
end
end

View File

@@ -24,7 +24,7 @@ feature "Managing users" do
click_link "users_email_title"
end
it "should be able to list users with order email asc" do
it "should list users with order email asc" do
expect(page).to have_css('table#listing_users')
within("table#listing_users") do
expect(page).to have_content("a@example.com")
@@ -32,7 +32,7 @@ feature "Managing users" do
end
end
it "should be able to list users with order email desc" do
it "should list users with order email desc" do
click_link "users_email_title"
within("table#listing_users") do
expect(page).to have_content("a@example.com")
@@ -57,7 +57,7 @@ feature "Managing users" do
click_link("a@example.com")
end
it "should let me edit the user password" do
it "should allow editing the user password" do
fill_in "user_password", :with => "welcome"
fill_in "user_password_confirmation", :with => "welcome"
click_button "Update"
@@ -71,6 +71,23 @@ feature "Managing users" do
expect(page).to have_content("The account will be updated once the new email is confirmed.")
end
it "should allow to generate, regenarate and clear the user api key", js: true do
user = Spree::User.find_by_email("a@example.com")
expect(page).to have_content "NO KEY"
click_button "Generate API key"
first_user_api_key = user.reload.spree_api_key
expect(page).to have_content first_user_api_key
click_button "Regenerate Key"
second_user_api_key = user.reload.spree_api_key
expect(page).to have_content second_user_api_key
expect(second_user_api_key).not_to eq first_user_api_key
click_button "Clear key"
expect(page).to have_content "NO KEY"
end
end
end

View File

@@ -272,13 +272,9 @@ describe "AdminProductEditCtrl", ->
describe "loading data upon initialisation", ->
it "gets a list of producers and then resets products with a list of data", ->
$httpBackend.expectGET("/api/users/authorise_api?token=API_KEY").respond success: "Use of API Authorised"
spyOn($scope, "fetchProducts").and.returnValue "nothing"
$scope.initialise()
$httpBackend.flush()
expect($scope.fetchProducts.calls.count()).toBe 1
expect($scope.spree_api_key_ok).toEqual true
describe "fetching products", ->
$q = null

View File

@@ -79,7 +79,7 @@ describe ProductTagRulesFilterer do
variant_hidden_for_another_customer.update_attribute(:tag_list, non_applicable_rule.preferred_variant_tags)
overrides_to_hide = filterer.__send__(:overrides_to_hide)
expect(overrides_to_hide).to eq [variant_hidden_by_default.id, variant_hidden_by_rule.id]
expect(overrides_to_hide).to include variant_hidden_by_default.id, variant_hidden_by_rule.id
end
end