Compare commits

...

48 Commits

Author SHA1 Message Date
Kristina Lim
ce31a059bf Merge pull request #4553 from openfoodfoundation/transifex
Transifex
2019-12-12 22:46:22 +08:00
Luis Ramos
17bac20c65 Merge pull request #4550 from luisramos0/fix_of_report
Remove eager loding of shipping_methods and shipping_rates from customer_totals so that report runs faster
2019-12-12 14:15:19 +00:00
Pau Pérez Fabregat
066243057f Merge pull request #4545 from coopdevs/fix-db-backups
Make whenever properly read the S3 bucket
2019-12-12 11:39:54 +01:00
Transifex-Openfoodnetwork
ea40547fd7 Updating translations for config/locales/fr_CA.yml 2019-12-12 10:22:26 +11:00
Transifex-Openfoodnetwork
0ebc6d4b1e Updating translations for config/locales/en_CA.yml 2019-12-12 09:28:07 +11:00
Transifex-Openfoodnetwork
62c2e4709a Updating translations for config/locales/en_CA.yml 2019-12-12 09:25:01 +11:00
Transifex-Openfoodnetwork
4c17cf0087 Updating translations for config/locales/fr.yml 2019-12-12 04:29:14 +11:00
Transifex-Openfoodnetwork
9fe143cf94 Updating translations for config/locales/en_FR.yml 2019-12-12 04:26:13 +11:00
Transifex-Openfoodnetwork
e2d783c385 Updating translations for config/locales/fr.yml 2019-12-12 04:26:05 +11:00
Transifex-Openfoodnetwork
81cb162884 Updating translations for config/locales/nb.yml 2019-12-12 03:34:25 +11:00
Transifex-Openfoodnetwork
c7b6dd2677 Updating translations for config/locales/nb.yml 2019-12-12 03:31:14 +11:00
Transifex-Openfoodnetwork
d1fd73fd2b Updating translations for config/locales/ar.yml 2019-12-12 03:16:38 +11:00
Transifex-Openfoodnetwork
b0221d264e Updating translations for config/locales/ar.yml 2019-12-12 03:13:31 +11:00
Transifex-Openfoodnetwork
0f64badc74 Updating translations for config/locales/ar.yml 2019-12-12 03:10:21 +11:00
Luis Ramos
7ccfdc8d21 Merge pull request #4546 from kshlyk/fix_cart_link_on_mobile
Cart link in header on mobile leads to cart page instead of checkout …
2019-12-11 13:45:56 +00:00
Luis Ramos
4799293996 Merge pull request #4518 from Matt-Yorkley/ruby-2.3.7
Bump Ruby to 2.3.7
2019-12-11 13:29:01 +00:00
Luis Ramos
58a93c27ae Merge pull request #4539 from luisramos0/subs_s3
Make weight calculator work for SubscriptionLineItems
2019-12-11 11:20:53 +00:00
luisramos0
0202b59634 Remove eager loding of shipping_methods and shipping_rates from customer_totals so that report runs faster
Something makes the query run much slower with these includes
2019-12-10 21:18:17 +00:00
Luis Ramos
9f351607d1 Merge pull request #4538 from mkllnk/4537-paginated-product-order
Make product order deterministic
2019-12-10 18:00:45 +00:00
Maikel
c45e3c9cca Merge pull request #4543 from openfoodfoundation/transifex
Transifex
2019-12-10 20:10:23 +11:00
Luis Ramos
71bf3f5f71 Merge pull request #4514 from luisramos0/backend_ctrl_overview
Bring spree_backend overview controller to OFN
2019-12-09 23:36:32 +00:00
Konstantin Shlyk
ef142de5f2 Cart link in header on mobile leads to cart page instead of checkout page 2019-12-09 22:58:00 +03:00
luisramos0
f64e8bf50e Make user aware of server side errors when saving subscription products and unit test products_panel_controller 2019-12-09 17:49:38 +00:00
Pau Perez
e8d68e3b89 Make whenever properly read the S3 bucket
For unknown reasons the magic
[Figaro](https://github.com/laserlemon/figaro) does to turn keys in
`config/application.yml` into ENV vars that can be read through Ruby's
`ENV[]` is not working in `config/schedule.rb`.

As a result, the `db2fog` tasks are not translated into cron entries
which led to not having automatic backups.
2019-12-09 17:16:11 +01:00
luisramos0
1b29d474d0 Add specs to cover case where updating subscriptions products quantity fails 2019-12-09 15:11:32 +00:00
Luis Ramos
baae58ecb6 Merge pull request #4288 from luisramos0/oc_serializer_spec
Add spec for api/admin/order_cycle_serializer
2019-12-09 11:16:04 +00:00
Pau Pérez Fabregat
6411871ecb Merge pull request #4540 from openfoodfoundation/dependabot/bundler/ddtrace-0.30.0
Bump ddtrace from 0.29.1 to 0.30.0
2019-12-09 09:48:27 +01:00
Transifex-Openfoodnetwork
22833ae79b Updating translations for config/locales/it.yml 2019-12-09 19:28:13 +11:00
Transifex-Openfoodnetwork
ac20b0e7fb Updating translations for config/locales/it.yml 2019-12-09 19:25:06 +11:00
luisramos0
e9e6aa77d8 Make weight calculator work for SubscriptionLineItems by making it test if line_item responds to final_weight_volume field (final_weight_volume_present?)
We also add logic to weight_per_variant so that we use variant.unit_value if final_weight_volume is not available but variant_unit is weight
Adapt some test case to test unit_value (in grams) instead of weight (in kgs)
2019-12-08 17:36:21 +00:00
dependabot-preview[bot]
7840118dea Bump ddtrace from 0.29.1 to 0.30.0
Bumps [ddtrace](https://github.com/DataDog/dd-trace-rb) from 0.29.1 to 0.30.0.
- [Release notes](https://github.com/DataDog/dd-trace-rb/releases)
- [Changelog](https://github.com/DataDog/dd-trace-rb/blob/master/CHANGELOG.md)
- [Commits](https://github.com/DataDog/dd-trace-rb/compare/v0.29.1...v0.30.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-06 19:18:08 +00:00
luisramos0
5e27bd6d6d Add for now very basic spec to api/admin/order_cycle_serializer 2019-12-06 16:41:54 +00:00
Maikel Linke
d4512904ea Make product order deterministic
When products are sorted by name and two products have the same name,
their order is undefined. With pagination, two pages can have a
different order of products with the same name which then means that two
pages can return the same product.

Sorting by product id makes sure that the result is always in the same
order, for every page.
2019-12-05 15:37:10 +11:00
Maikel
52dc288470 Merge pull request #4530 from openfoodfoundation/transifex
Transifex
2019-12-05 11:01:30 +11:00
Luis Ramos
302de04e73 Merge pull request #4526 from kristinalim/fix/3149-fix_tool_tips_in_orders_list
3149 Fix tooltips in orders list
2019-12-04 10:38:28 +00:00
Transifex-Openfoodnetwork
41767936d6 Updating translations for config/locales/ca.yml 2019-12-03 22:50:13 +11:00
Transifex-Openfoodnetwork
0ccf30202e Updating translations for config/locales/ca.yml 2019-12-03 22:47:06 +11:00
Transifex-Openfoodnetwork
00f36e4686 Updating translations for config/locales/ca.yml 2019-12-03 22:43:57 +11:00
Maikel
4d77f30bc0 Merge pull request #4506 from openfoodfoundation/dependabot/bundler/ddtrace-0.29.1
Bump ddtrace from 0.29.0 to 0.29.1
2019-12-03 20:39:58 +11:00
Maikel
f38b1b95f0 Merge pull request #4525 from kristinalim/fix/4489-flaky_spec_for_editing_oc
4489 Improve waiting in feature spec for edit Order Cycle page
2019-12-03 20:36:37 +11:00
Kristina Lim
852adfd436 Improve waiting in feature spec for order cycle page 2019-12-02 20:06:43 +08:00
Kristina Lim
2673a6efee Fix Angular tracking of row in orders list
The tooltip content for the order in index n in page x was being used
for the order in index n in page y.

This was because ng-repeat was tracking the items/rows by index.
As far as ng-repeat is aware, rows with the same index in any page
were the same items/rows, so it didn't bother relinking the ofn-with-tip
directive.
2019-11-30 03:53:20 +08:00
Kristina Lim
6ffe7f1a99 Set width and enable wrapping for tooltips 2019-11-30 03:53:16 +08:00
luisramos0
ba1ad0a6dd Rename decorator to controller so that the rubocop exception for the index action keeps being seen by code climate 2019-11-28 16:47:02 +00:00
Matt-Yorkley
feaa928674 Bump Ruby to 2.3.7 🎉 2019-11-28 10:42:13 +01:00
luisramos0
c8d359a0da Merge spree/admin/overview_controller with its decorator 2019-11-27 22:08:46 +00:00
luisramos0
210757641c Add overview_controller from spree_backend so that we can now merge it with the OFN's decorator 2019-11-27 22:08:06 +00:00
dependabot-preview[bot]
08003f2003 Bump ddtrace from 0.29.0 to 0.29.1
Bumps [ddtrace](https://github.com/DataDog/dd-trace-rb) from 0.29.0 to 0.29.1.
- [Release notes](https://github.com/DataDog/dd-trace-rb/releases)
- [Changelog](https://github.com/DataDog/dd-trace-rb/blob/master/CHANGELOG.md)
- [Commits](https://github.com/DataDog/dd-trace-rb/compare/v0.29.0...v0.29.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-27 19:17:20 +00:00
28 changed files with 587 additions and 120 deletions

View File

@@ -362,7 +362,7 @@ Metrics/AbcSize:
- app/controllers/spree/admin/image_settings_controller.rb
- app/controllers/spree/admin/orders/customer_details_controller_decorator.rb
- app/controllers/spree/admin/orders_controller_decorator.rb
- app/controllers/spree/admin/overview_controller_decorator.rb
- app/controllers/spree/admin/overview_controller.rb
- app/controllers/spree/admin/payment_methods_controller.rb
- app/controllers/spree/admin/payments_controller_decorator.rb
- app/controllers/spree/admin/products_controller_decorator.rb

View File

@@ -1 +1 @@
2.2.10
2.3.7

View File

@@ -1,5 +1,5 @@
source 'https://rubygems.org'
ruby "2.2.10"
ruby "2.3.7"
git_source(:github) { |repo_name| "https://github.com/#{repo_name}.git" }
gem 'i18n', '~> 0.6.11'

View File

@@ -225,7 +225,7 @@ GEM
activerecord (>= 3.2.0, < 5.0)
fog (~> 1.0)
rails (>= 3.2.0, < 5.0)
ddtrace (0.29.0)
ddtrace (0.30.0)
msgpack
debugger-linecache (1.2.0)
deface (1.0.2)
@@ -828,7 +828,7 @@ DEPENDENCIES
wkhtmltopdf-binary
RUBY VERSION
ruby 2.2.10p489
ruby 2.3.7p456
BUNDLED WITH
1.17.2

View File

@@ -20,4 +20,4 @@ angular.module("admin.subscriptions").controller "ProductsPanelController", ($sc
keys = Object.keys(response.data.errors)
StatusMessage.display 'failure', response.data.errors[keys[0]][0]
else
StatusMessage.display 'success', t('js.changes_saved')
StatusMessage.display 'failure', t('js.admin.subscriptions.error_saving')

View File

@@ -0,0 +1,4 @@
#powerTip {
max-width: 240px;
white-space: normal;
}

View File

@@ -0,0 +1,79 @@
# this clas was inspired (heavily) from the mephisto admin architecture
module Spree
module Admin
class OverviewController < Spree::Admin::BaseController
def index
@enterprises = Enterprise
.managed_by(spree_current_user)
.order('is_primary_producer ASC, name')
@product_count = Spree::Product.active.managed_by(spree_current_user).count
@order_cycle_count = OrderCycle.active.managed_by(spree_current_user).count
if first_access
redirect_to enterprises_path
else
render dashboard_view
end
end
private
# Checks whether the user is accessing the admin for the first time
#
# @return [Boolean]
def first_access
outside_referral && incomplete_enterprise_registration?
end
# Checks whether the request comes from another admin page or not
#
# @return [Boolean]
def outside_referral
!URI(request.referer.to_s).path.match(%r{/admin})
end
# Checks that all of the enterprises owned by the current user have a 'sells'
# property specified, which indicates that the registration process has been
# completed
#
# @return [Boolean]
def incomplete_enterprise_registration?
@incomplete_enterprise_registration ||= spree_current_user
.owned_enterprises
.where(sells: 'unspecified')
.exists?
end
# Returns the appropriate enterprise path for the current user
#
# @return [String]
def enterprises_path
if managed_enterprises.size == 1
@enterprise = @enterprises.first
main_app.welcome_admin_enterprise_path(@enterprise)
else
main_app.admin_enterprises_path
end
end
# Returns the appropriate dashboard view for the current user
#
# @return [String]
def dashboard_view
if managed_enterprises.size == 1
@enterprise = @enterprises.first
:single_enterprise_dashboard
else
:multi_enterprise_dashboard
end
end
# Returns the list of enterprises the current user is manager of
#
# @return [ActiveRecord::Relation<Enterprise>]
def managed_enterprises
spree_current_user.enterprises
end
end
end
end

View File

@@ -1,74 +0,0 @@
Spree::Admin::OverviewController.class_eval do
def index
@enterprises = Enterprise
.managed_by(spree_current_user)
.order('is_primary_producer ASC, name')
@product_count = Spree::Product.active.managed_by(spree_current_user).count
@order_cycle_count = OrderCycle.active.managed_by(spree_current_user).count
if first_access
redirect_to enterprises_path
else
render dashboard_view
end
end
private
# Checks whether the user is accessing the admin for the first time
#
# @return [Boolean]
def first_access
outside_referral && incomplete_enterprise_registration?
end
# Checks whether the request comes from another admin page or not
#
# @return [Boolean]
def outside_referral
!URI(request.referer.to_s).path.match(%r{/admin})
end
# Checks that all of the enterprises owned by the current user have a 'sells'
# property specified, which indicates that the registration process has been
# completed
#
# @return [Boolean]
def incomplete_enterprise_registration?
@incomplete_enterprise_registration ||= spree_current_user
.owned_enterprises
.where(sells: 'unspecified')
.exists?
end
# Returns the appropriate enterprise path for the current user
#
# @return [String]
def enterprises_path
if managed_enterprises.size == 1
@enterprise = @enterprises.first
main_app.welcome_admin_enterprise_path(@enterprise)
else
main_app.admin_enterprises_path
end
end
# Returns the appropriate dashboard view for the current user
#
# @return [String]
def dashboard_view
if managed_enterprises.size == 1
@enterprise = @enterprises.first
:single_enterprise_dashboard
else
:multi_enterprise_dashboard
end
end
# Returns the list of enterprises the current user is manager of
#
# @return [ActiveRecord::Relation<Enterprise>]
def managed_enterprises
spree_current_user.enterprises
end
end

View File

@@ -25,7 +25,7 @@ module Calculator
end
def line_item_weight(line_item)
if line_item.final_weight_volume.present?
if final_weight_volume_present?(line_item)
weight_per_final_weight_volume(line_item)
else
weight_per_variant(line_item) * line_item.quantity
@@ -33,13 +33,18 @@ module Calculator
end
def weight_per_variant(line_item)
line_item.variant.andand.weight || 0
if variant_unit(line_item) == 'weight'
# The calculator price is per_kg so we need to convert unit_value to kg
convert_g_to_kg(line_item.variant.andand.unit_value)
else
line_item.variant.andand.weight || 0
end
end
def weight_per_final_weight_volume(line_item)
if line_item.variant.product.andand.variant_unit == 'weight'
# Divided by 1000 because grams is the base weight unit and the calculator price is per_kg
line_item.final_weight_volume / 1000.0
if variant_unit(line_item) == 'weight'
# The calculator price is per_kg so we need to convert final_weight_volume to kg
convert_g_to_kg(line_item.final_weight_volume)
else
weight_per_variant(line_item) * quantity_implied_in_final_weight_volume(line_item)
end
@@ -51,5 +56,19 @@ module Calculator
def quantity_implied_in_final_weight_volume(line_item)
(1.0 * line_item.final_weight_volume / line_item.variant.unit_value).round(3)
end
def final_weight_volume_present?(line_item)
line_item.respond_to?(:final_weight_volume) && line_item.final_weight_volume.present?
end
def variant_unit(line_item)
line_item.variant.product.andand.variant_unit
end
def convert_g_to_kg(value)
return 0 unless value
value / 1000
end
end
end

View File

@@ -66,7 +66,7 @@ class ProductsRenderer
.split(",").map { |id| "spree_products.primary_taxon_id=#{id} DESC" }
.join(", ") + ", spree_products.name ASC, spree_products.id ASC"
else
"spree_products.name ASC"
"spree_products.name ASC, spree_products.id"
end
end

View File

@@ -10,7 +10,7 @@
%section.right{"ng-cloak" => true}
%span.cart-span{"ng-controller" => "CartCtrl", "ng-class" => "{ dirty: Cart.dirty || Cart.empty(), 'pure-dirty': Cart.dirty }"}
%a.icon{href: main_app.checkout_path}
%a.icon{href: main_app.cart_path}
%span
= t '.cart'
%span.count

View File

@@ -47,7 +47,7 @@
%th.actions
%tbody
%tr{ng: {repeat: 'order in orders track by $index', class: {even: "'even'", odd: "'odd'"}}, 'ng-class' => "'state-{{order.state}}'"}
%tr{ng: {repeat: 'order in orders track by order.id', class: {even: "'even'", odd: "'odd'"}}, 'ng-class' => "'state-{{order.state}}'"}
%td.align-center
%input{type: 'checkbox', 'ng-model' => 'checkboxes[order.id]', 'ng-change' => 'toggleSelection(order.id)'}
%td.align-center

View File

@@ -2508,6 +2508,7 @@ ar:
customer_placeholder: "customer@example.org"
valid_email_error: "من فضلك أدخل بريد أليكترونى صحيح"
subscriptions:
error_saving: "خطأ في حفظ الاشتراك"
new:
please_select_a_shop: "يرجى اختيار متجر"
insufficient_stock: "مخزون غير متوفر ، تبقى %{on_hand}"

View File

@@ -434,9 +434,12 @@ ca:
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."
back_to_products_list: "Torna a la llista de productes"
editing_product: "Editant el producte"
tabs:
product_details: "Detalls del producte"
group_buy_options: "Opcions de compra en grup"
images: "Imatges"
variants: "Variants"
product_properties: "Propietats del producte"
product_import:
title: Importació de productes
@@ -836,21 +839,33 @@ ca:
new:
create: "Crear"
cancel: "Cancel·lar"
back_to_list: "Tornar a la llista"
edit:
advanced_settings: "Configuració avançada"
save: "Desa"
save_and_next: "Desa i següent"
next: "Següent"
cancel: "Cancel·lar"
back_to_list: "Tornar a la llista"
save_and_back_to_list: "Desa i torna a la llista"
choose_products_from: "Trieu Productes des de:"
incoming:
previous: "Anterior"
save: "Desa"
save_and_next: "Desa i següent"
next: "Següent"
cancel: "Cancel·lar"
back_to_list: "Tornar a la llista"
outgoing:
previous: "Anterior"
save: "Desa"
save_and_back_to_list: "Desa i torna a la llista"
cancel: "Cancel·lar"
back_to_list: "Tornar a la llista"
wizard_progress:
edit: "1. Configuració general"
incoming: "2. Productes entrants"
outgoing: "3. Productes sortints"
exchange_form:
pickup_time_tip: Quan les comandes d'aquest cicle de comandes estiguin preparades per a les consumidores
pickup_instructions_placeholder: "Instruccions de recollida"
@@ -2798,6 +2813,12 @@ ca:
minimal_amount: "Quantitat mínima"
normal_amount: "Quantitat normal"
discount_amount: "Import de descompte"
no_images_found: "No s'han trobat imatges"
new_image: "Nova imatge"
filename: "Nom de l'arxiu"
alt_text: "Text alternatiu"
thumbnail: "Miniatura"
back_to_images_list: "Torna a la llista dimatges"
email: Correu electrònic
account_updated: "Compte actualitzat!"
email_updated: "El compte sactualitzarà un cop es confirmi el nou correu electrònic."
@@ -2809,6 +2830,7 @@ ca:
zipcode: Codi postal
weight: Pes (per kg)
error_user_destroy_with_orders: "No es poden esborrar usuaris amb comandes completades"
options: "Opcions"
actions:
update: "Actualitzar"
errors:
@@ -2840,27 +2862,53 @@ ca:
product_properties:
index:
inherits_properties_checkbox_hint: "heredar propietats de %{supplier}? (llevat que es sobreescrigui a dalt)"
add_product_properties: "Afegeix propietats del producte"
select_from_prototype: "Seleccioneu d'un prototip"
properties:
index:
properties: "Propietats"
new_property: "Nova propietat"
name: "Nom"
presentation: "Presentació"
new:
new_property: "Nova propietat"
edit:
editing_property: "Edició de propietats"
back_to_properties_list: "Torna a la llista de propietats"
form:
name: "Nom"
presentation: "Presentació"
return_authorizations:
index:
new_return_authorization: "Nova autorització de devolució"
return_authorizations: "Autoritzacions de devolució"
back_to_orders_list: "Tornar a la llista de comandes"
rma_number: "Número RMA"
status: "Estat"
amount: "Quantitat"
cannot_create_returns: "No es poden crear devolucions ja que aquesta comanda no té cap unitat enviada."
continue: "Continua"
new:
new_return_authorization: "Nova autorització de devolució"
back_to_return_authorizations_list: "Tornar a la llista d'autorització"
continue: "Continua"
edit:
receive: "rebre"
are_you_sure: "Estàs segur?"
return_authorization: "Autorització de devolució"
form:
product: "Producte"
quantity_shipped: "Quantitat enviada"
quantity_returned: "Quantitat retornada"
return_quantity: "Devolució de la quantitat"
amount: "Quantitat"
rma_value: "Valor RMA"
reason: "Raó"
stock_location: "Ubicació d'estoc"
states:
authorized: "Autoritzat"
received: "Rebut"
canceled: "Cancel·lat"
orders:
index:
listing_orders: "Llistat comandes"
@@ -3051,12 +3099,23 @@ ca:
index:
sku: "Número de referència (SKU)"
price: "Preu"
options: "Opcions"
no_results: "Sense resultats"
to_add_variants_you_must_first_define: "Per afegir variants, primer heu de definir"
option_types: "Tipus d'opcions"
option_values: "Valors dopció"
and: "i"
new_variant: "Nova variant"
show_active: "Mostra actiu"
show_deleted: "Mostra esborrats"
new:
new_variant: "Nova variant"
form:
cost_price: "Preu de cost"
sku: "Número de referència (SKU)"
price: "Preu"
display_as: "Mostra com"
display_name: "Nom de visualització"
autocomplete:
producer_name: "Productor"
unit: "Unitat"
@@ -3196,3 +3255,19 @@ ca:
allow_charges?: "Permetre càrrecs?"
localized_number:
invalid_format: té un format no vàlid. Si us plau introdueix un número.
api:
invalid_api_key: "No sha especificat una clau dAPI vàlida (%{key})."
unauthorized: "No teniu autorització per realitzar aquesta acció."
invalid_resource: "Recurs invàlid. Corregiu els errors i torneu-ho a provar."
resource_not_found: "No s'ha trobat el recurs que buscaves."
access: "Accés a l'API"
key: "Clau"
clear_key: "Esborra la clau"
regenerate_key: "Regenerar la clau"
no_key: "Sense clau"
generate_key: "Generar clau dAPI"
key_generated: "Clau generada"
key_cleared: "La clau esborrada"
shipment:
cannot_ready: "No es pot fer l'enviament."
invalid_taxonomy_id: "Identificador de taxonomia no vàlid."

View File

@@ -2642,6 +2642,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using
customer_placeholder: "customer@example.org"
valid_email_error: "Please enter a valid email address"
subscriptions:
error_saving: "Error saving subscription"
new:
please_select_a_shop: "Please select a shop"
insufficient_stock: "Insufficient stock available, only %{on_hand} remaining"

View File

@@ -2508,6 +2508,7 @@ en_CA:
customer_placeholder: "customer@example.org"
valid_email_error: "Please enter a valid email address"
subscriptions:
error_saving: "Error saving subscription"
new:
please_select_a_shop: "Please select a shop"
insufficient_stock: "Insufficient stock available, only %{on_hand} remaining"
@@ -2875,19 +2876,35 @@ en_CA:
presentation: "Presentation"
return_authorizations:
index:
new_return_authorization: "New Return Authorization"
return_authorizations: "Return Authoriations"
back_to_orders_list: "Back to Orders List"
rma_number: "RMA Number"
status: "Status"
amount: "Amount"
cannot_create_returns: "Cannot create returns as this order has no shipped units"
continue: "Continue"
new:
new_return_authorization: "New Return Authorization"
back_to_return_authorizations_list: "Back to Return Authorization List"
continue: "Continue"
edit:
receive: "receive"
are_you_sure: "Are you sure?"
return_authorization: "Return Authorization"
form:
product: "Product"
quantity_shipped: "Quantity Shipped"
quantity_returned: "Quantity Returned"
return_quantity: "Return Quantity"
amount: "Amount"
rma_value: "RMA Value"
reason: "Reason"
stock_location: "Stock Location"
states:
authorized: "Authorized"
received: "Received"
canceled: "Canceled"
orders:
index:
listing_orders: "Listing Orders"

View File

@@ -2508,6 +2508,7 @@ en_FR:
customer_placeholder: "customer@example.org"
valid_email_error: "Please enter a valid email address"
subscriptions:
error_saving: "Error saving subscription"
new:
please_select_a_shop: "Please select a shop"
insufficient_stock: "Insufficient stock available, only %{on_hand} remaining"

View File

@@ -2536,6 +2536,7 @@ fr:
customer_placeholder: "acheteur@exemple.org"
valid_email_error: "Veuillez entrer un email valide"
subscriptions:
error_saving: "Une erreur est survenue à la sauvegarde"
new:
please_select_a_shop: "Veuillez choisir une boutique"
insufficient_stock: "Stock disponible insuffisant, il n'en reste que %{on_hand}"

View File

@@ -115,7 +115,9 @@ fr_CA:
email_welcome: "Bienvenue"
email_registered: "fait maintenant partie de"
email_userguide_html: "Le Guide Utilisateur expliquant comment mettre en place son profil producteur ou son hub est accessible ici: %{link}"
userguide: "Guide utilisateur"
email_admin_html: "Vous pouvez gérer votre compte en vous connectant ici %{link} ou en cliquant sur la roue en haut à droite de la page d'accueil et en sélectionnant Administration."
admin_panel: "interface d'administration"
email_community_html: "Nous avons aussi un forum de discussion en ligne (en anglais) pour échanger avec la communauté sur des questions liées au logiciel OFN et aux défis de la gestion d'un food hub. Nous vous invitons à y participer. Nous sommes en constante évolution et vos contributions à ce forum vont façonner les prochaines étapes. %{link}"
join_community: "Rejoindre la communauté"
invite_manager:
@@ -433,9 +435,12 @@ fr_CA:
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."
back_to_products_list: "Retour à la liste produits"
editing_product: "Modifier le produit"
tabs:
product_details: " Détails"
group_buy_options: "Options d'achat par lot"
images: "Images"
variants: "Variantes"
product_properties: "Propriétés / labels Produits"
product_import:
title: import produit
@@ -538,6 +543,7 @@ fr_CA:
title: Catalogue Boutique
description: Utilisez cette page pour gérer le catalogue de votre entreprise. Les détails produits saisis ici remplaceront ceux de la page "Produit" pour votre entreprise uniquement.
enable_reset?: Autoriser réinitialisation du stock (retour configurations par défaut)?
default_stock: "Stock par défaut"
inherit?: Hériter?
add: Ajouter
hide: Masquer
@@ -833,21 +839,33 @@ fr_CA:
new:
create: "Créer"
cancel: "Annuler"
back_to_list: "Retour à la liste"
edit:
advanced_settings: "Paramétrages avancés"
save: "Enregistrer"
save_and_next: "Sauvegarder et suivant"
next: "Suivant"
cancel: "Annuler"
back_to_list: "Retour à la liste"
save_and_back_to_list: "Sauvegarder et suivant"
choose_products_from: "Choisir produits depuis :"
incoming:
previous: "Précédent"
save: "Enregistrer"
save_and_next: "Sauvegarder et suivant"
next: "Suivant"
cancel: "Annuler"
back_to_list: "Retour à la liste"
outgoing:
previous: "Précédent"
save: "Enregistrer"
save_and_back_to_list: "Sauvegarder et suivant"
cancel: "Annuler"
back_to_list: "Retour à la liste"
wizard_progress:
edit: "1. Informations générales"
incoming: "2. Produits entrants"
outgoing: "3. Produits vendus (sortants)"
exchange_form:
pickup_time_tip: Quand des commandes liées à ce cycle de vente seront prêtes à être soumises à l'acheteur
pickup_instructions_placeholder: "Modalités de retrait/livraison"
@@ -2501,6 +2519,7 @@ fr_CA:
customer_placeholder: "acheteur@exemple.org"
valid_email_error: "Veuillez entrer un email valide"
subscriptions:
error_saving: "Une erreur est survenue à la sauvegarde"
new:
please_select_a_shop: "Veuillez choisir une boutique"
insufficient_stock: "Stock disponible insuffisant, il n'en reste que %{on_hand}"
@@ -2802,8 +2821,15 @@ fr_CA:
minimal_amount: "Montant minimal"
normal_amount: "Montant classique"
discount_amount: "Réduction"
no_images_found: "Aucune image pour l'instant"
new_image: "Nouvelle image"
filename: "Nom du fichier"
alt_text: "Texte alternatif"
thumbnail: "Miniature"
back_to_images_list: "Retour à la liste des images"
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"
@@ -2812,6 +2838,7 @@ fr_CA:
zipcode: Code postal
weight: Poids (au kg)
error_user_destroy_with_orders: "Les utilisateurs avec des commandes finalisées pourraient ne pas être supprimés"
options: "Options"
actions:
update: "Mettre à jour"
errors:
@@ -2843,27 +2870,53 @@ fr_CA:
product_properties:
index:
inherits_properties_checkbox_hint: "Hériter des propriétés de %{supplier}? (non applicable si information de remplacement déjà saisie)"
add_product_properties: "Ajouter des propriétés/labels"
select_from_prototype: "Sélectionnez depuis le prototype"
properties:
index:
properties: "Labels / propriétés"
new_property: "Nouvelle propriété"
name: "Nom"
presentation: "Présentation"
new:
new_property: "Nouvelle propriété"
edit:
editing_property: "Modifier la propriété"
back_to_properties_list: "Retour à la liste de propriétés"
form:
name: "Nom"
presentation: "Présentation"
return_authorizations:
index:
new_return_authorization: "Nouvelle autorisation de retour"
return_authorizations: "Autorisations de retours"
back_to_orders_list: "Retour à la liste des commandes"
rma_number: "Numéro RMA"
status: "Statut"
amount: "Montant"
cannot_create_returns: "Impossible de créer une autorisation de retour car aucun produit n'a été livré pour cette commande."
continue: "Suivant"
new:
new_return_authorization: "Nouvelle autorisation de retour"
back_to_return_authorizations_list: "Revenir à la liste des autorisations"
continue: "Suivant"
edit:
receive: " reçoit"
are_you_sure: "Confirmer?"
return_authorization: "Autorisations de retours"
form:
product: "Produit"
quantity_shipped: "Quantité envoyée"
quantity_returned: "Quantité retournée"
return_quantity: "Quantité à retourner"
amount: "Montant"
rma_value: "Valeur RMA"
reason: "Raison"
stock_location: "Localisation"
states:
authorized: "Autorisé"
received: "Reçu"
canceled: "Annulée"
orders:
index:
listing_orders: "Liste des commandes"
@@ -3054,12 +3107,23 @@ fr_CA:
index:
sku: "Référence Produit"
price: "Prix"
options: "Options"
no_results: "Pas de résultats"
to_add_variants_you_must_first_define: "Pour ajouter une variante, vous devez d'abord définir"
option_types: "Types d'options"
option_values: "Valeurs"
and: "et"
new_variant: "Nouvelle variante"
show_active: "Montrer les actifs"
show_deleted: "Montrer les supprimés"
new:
new_variant: "Nouvelle variante"
form:
cost_price: "Prix coutant"
sku: "Référence Produit"
price: "Prix"
display_as: "Afficher comme"
display_name: "Nom affiché"
autocomplete:
producer_name: "Producteur"
unit: "Unité"
@@ -3200,3 +3264,19 @@ fr_CA:
allow_charges?: "Autoriser les prélèvements ?"
localized_number:
invalid_format: n'est pas un format valide. Veuillez entrer un nombre.
api:
invalid_api_key: " La clé API (%{key}) n'est pas valide."
unauthorized: "Vous n'êtes pas autorisé à réaliser cette action."
invalid_resource: "La resource est invalide. Veuillez corriger les erreurs et recommencer."
resource_not_found: "La ressource recherchée n'a pas été trouvée."
access: "Accès API"
key: "Clé"
clear_key: "Supprimer la clé"
regenerate_key: "Regénérer la clé"
no_key: "Aucune clé"
generate_key: "Générer la clé API"
key_generated: "Clé générée"
key_cleared: "Clé supprimée"
shipment:
cannot_ready: "La livraison ne peut pas être préparée."
invalid_taxonomy_id: "L'identifiant de la catégorie n'est pas valide."

View File

@@ -14,7 +14,9 @@ it:
spree/product:
primary_taxon: "Categoria prodotto"
supplier: "Fornitore"
shipping_category_id: "Categoria di spedizione"
variant_unit: "Unità Variante"
variant_unit_name: "Nome Unità Variante"
order_cycle:
orders_close_at: Data chiusura
errors:
@@ -41,7 +43,7 @@ it:
end_at: "Fine"
distributor_ids: "Distributori"
producer_ids: "Produttori"
order_cycle_ids: "Cicli di richiesteCicli di richieste"
order_cycle_ids: "Cicli di richieste"
enterprise_fee_ids: "Nome commissione"
shipping_method_ids: "Metodi di spedizione"
payment_method_ids: "Metodi di pagamento"
@@ -75,6 +77,8 @@ it:
user_confirmations:
spree_user:
send_instructions: "A breve riceverai un'email con le istruzioni utili a confermare il tuo account."
confirmation_sent: "Email di conferma inviata"
confirmation_not_sent: "Errore invio emai di conferma"
user_registrations:
spree_user:
signed_up_but_unconfirmed: "Abbiamo inviato un link di conferma al tuo indirizzo email. Per favore apri il link per attivare il tuo account."
@@ -85,9 +89,12 @@ it:
La volta scorsa eri ospite? Forse devi creare un account o resettare la tua password.
unconfirmed: "Devi confermare il tuo account prima di continuare."
already_registered: "Questo indirizzo email è già registrato. Per favore effettua il log in per continuare, o torna indietro e utilizza un altro indirizzo email."
success:
logged_in_succesfully: "Collegato con successo"
user_passwords:
spree_user:
updated_not_active: "La tua password è stata resettata, ma la tua email non è ancora stata confermata."
updated: "La tua password è stata modificata con successo.\nOra sei collegato."
send_instructions: "A breve riceverai un'email con le istruzioni utili a confermare il tuo account."
models:
order_cycle:
@@ -107,7 +114,9 @@ it:
email_welcome: "Benvenuto"
email_registered: "è ora parte di"
email_userguide_html: "La Guida Utente con supporto dettagliato per l'impostazione del tuo Produttore o Hub è qui: %{link}"
userguide: "Guida di Open Food Network"
email_admin_html: "Puoi gestire il tuo profilo facendo il log in al link %{link} o cliccando sull'ingranaggio in alto a destra della homepage, e selezionando Amministrazione"
admin_panel: "Pannello di controllo"
email_community_html: "Abbiamo anche un forum on-line per le discussioni della comunità sul software OFN e le sfide uniche legate all'avere un'impresa del cibo. Sei invitato ad unirti. Ci evolviamo in continuo e il tuo contributo in questo forum plasmerà ciò che sarà. %{link}"
join_community: "Unisciti alla community"
invite_manager:
@@ -243,6 +252,8 @@ 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"
maestro_or_solo_cards: "carte Maestro/Solo"
backordered: "ordini arretrati"
on hand: "Disponibile"
ship: "Spedizione"
actions:
@@ -320,6 +331,7 @@ it:
invoice_settings:
edit:
title: "Impostazioni fatturazione"
enable_invoices?: "Abilita fatture?"
invoice_style2?: "Utilizzare il modello di fattura alternativa che include la ripartizione totale delle imposte per tariffa e le informazioni sulla tariffa fiscale per articolo (non ancora adatto per i paesi che visualizzano i prezzi al netto delle imposte)"
enable_receipt_printing?: "Visualizzo le opzioni per stampare la ricevuta usando la stampante termica nel menù a cascata?"
stripe_connect_settings:
@@ -388,6 +400,7 @@ it:
calculator: "Calcolatrice"
calculator_values: "Valori della Calcolatrice"
search: "Cerca"
name_placeholder: "Tariffa imballaggio"
enterprise_groups:
index:
new_button: Nuovo gruppo di aziende
@@ -418,11 +431,15 @@ it:
property_name: "Nome della Proprietà"
inherited_property: "Proprietà Ereditata"
variants:
infinity: "Infinito..."
to_order_tip: "Gli articoli messi in ordine non hanno un livello di stock impostato, come ad esempio il Pane fresco su ordinazione."
back_to_products_list: "Indietro alla lista dei prodotti"
editing_product: "Modifica prodotto"
tabs:
product_details: "Dettagli Prodotto"
group_buy_options: "Opzioni Acquisti di gruppo"
images: "Immagini"
variants: "Varianti"
product_properties: "Proprietà prodotto"
product_import:
title: Importa prodotto
@@ -445,6 +462,8 @@ it:
encoding_error: "Controlla l'impostazione della lingua del file sorgente e assicurati che sia salvato con la codifica UTF-8."
unexpected_error: "L'importazione del prodotto ha incontrato un errore imprevisto durante l'apertura del file:%{error_message}"
index:
notice: "Avviso"
beta_notice: "Questa opzione è ancora in fase beta: potresti incontrare errori mentre la usi. Per favore non esitare a contattare il servizio di supporto."
select_file: Seleziona un foglio di calcolo da caricare
spreadsheet: Foglio di calcolo
choose_import_type: Seleziona modalità di importazione
@@ -523,6 +542,7 @@ it:
title: Inventario
description: Usa questa paginaper gestire gli inventari delle tue aziende. I dettagli dei prodotti impostati qui sovrascriveranno quelli impostati sulla pagina 'Prodotti'
enable_reset?: Abilitare il reset del magazzino?
default_stock: "Magazzino predefinito"
inherit?: Eredita?
add: Aggiungi
hide: Nascondi
@@ -650,6 +670,8 @@ it:
permalink_tip: "Questo permalink serve a creare l'url al tuo negozio: %{link}nome-del-tuo-negozio/negozio"
link_to_front: Link alla tua vetrina
link_to_front_tip: Un link diretto alla tua vetrina su Open Food Network
ofn_uid: OFN UID
ofn_uid_tip: Il codice univoco utilizzato per identificare l'azienda su OFN
shipping_methods:
name: Nome
applies: Applica?
@@ -680,6 +702,8 @@ it:
Una spiegazione opzionale che dettaglia il funzionamento del tuo negozio,
che sarà visualizzata sopra al listino dei prodotti nella pagina del
tuo negozio.
shopfront_message_link_tooltip: "Inserisci / modifica link"
shopfront_message_link_prompt: "Per favore inserisci un URL"
shopfront_closed_message: "Messaggio Chiusura Vetrina"
shopfront_closed_message_placeholder: >
Un messaggio che fornisce una spiegazione più dettagliata sul perché
@@ -809,24 +833,39 @@ it:
user_already_exists: "L'Utente esiste già"
error: "Qualcosa è andato storto"
order_cycles:
loading_flash:
loading_order_cycles: CARICAMENTO CICLI DI RICHIESTE
loading: CARICAMENTO...
new:
create: "Crea"
cancel: "Annulla"
back_to_list: "Indietro alla lista"
edit:
advanced_settings: "Impostazioni avanzate"
save: "Salva"
save_and_next: "Salva e continua"
next: "Prossimo"
cancel: "Annulla"
back_to_list: "Indietro alla lista"
save_and_back_to_list: "Salva e torna alla lista"
choose_products_from: "Scegli i prodotti da:"
incoming:
previous: "Precedente"
save: "Salva"
save_and_next: "Salva e continua"
next: "Prossimo"
cancel: "Annulla"
back_to_list: "Indietro alla lista"
outgoing:
previous: "Precedente"
save: "Salva"
save_and_back_to_list: "Salva e torna alla lista"
cancel: "Annulla"
back_to_list: "Indietro alla lista"
wizard_progress:
edit: "1. Impostazioni generali"
incoming: "2. Prodotti in entrata"
outgoing: "3. Prodotti in uscita"
exchange_form:
pickup_time_tip: Quando gli ordini di questa Lista d'ordine saranno pronti per il cliente
pickup_instructions_placeholder: "Istruzioni per la consegna"
@@ -841,6 +880,7 @@ it:
add_distributor: 'Aggiungi distributore'
advanced_settings:
title: Impostazioni avanzate
choose_product_tip: Puoi limitare i prodotti in entrata e in uscita al%{inventory}dell'Inventario
preferred_product_selection_from_coordinator_inventory_only_here: Solo inventario del coordinatore
preferred_product_selection_from_coordinator_inventory_only_all: Tutti i prodotti disponibili
save_reload: Salva e ricarica la pagina
@@ -977,6 +1017,8 @@ it:
pause_subscription: Metti in pausa l'abbonamento
unpause_subscription: Riprendi abbonamento
cancel_subscription: Annulla abbonamento
filters:
query_placeholder: "Cerca per email..."
setup_explanation:
just_a_few_more_steps: 'Ancora pochi passi prima di cominciare:'
enable_subscriptions: "Ativa abbonamento ad almeno uno dei tuoi negozi"
@@ -1013,6 +1055,8 @@ it:
charges_not_allowed: Non sono consentiti Oneri per questo cliente
no_default_card: Il cliente non ha carte disponibili da caricare
card_ok: il cliente ha una carta disponibile da caricare
begins_at_placeholder: "Seleziona una data"
ends_at_placeholder: "Facoltativo"
loading_flash:
loading: CARICAMENTO ABBONAMENTI
review:
@@ -1026,6 +1070,7 @@ it:
saved: "SALVATO"
product_already_in_order: Questo prodotto è già stato aggiunto alla gentile richiesta. Per favore modifica direttamente la quantità.
stock:
insufficient_stock: "Quantità disponibile insufficiente"
out_of_stock: "Esaurito"
orders:
number: Numero
@@ -1034,6 +1079,7 @@ it:
cancel_failure_msg: "Ci dispiace, eliminazione non riuscita!"
confirm_pause_msg: "Sei sicura/o di voler mettere in pausa questo abbonamento?"
pause_failure_msg: "Spiacente, pausa fallita!"
confirm_unpause_msg: "If you have an open Order Cycle in this subscription's schedule, an order will be created for this customer. Are you sure you want to unpause this subscription?"
unpause_failure_msg: "Ci dispiace, ripresa non riuscita!"
confirm_cancel_open_orders_msg: "Alcune di queste richieste sono attualmente attive. I consumatori sono già stati avvisati che le richieste verranno soddisfatte. Vuoi eliminare questa/e richiesta/e o mantenerla?"
resume_canceled_orders_msg: "Alcuni ordini per questo abbonamento possono essere ripresi in questo momento. Puoi riprenderli dal menu a discesa degli ordini."
@@ -1071,8 +1117,12 @@ it:
show_on_map: "Mostra tutto nella mappa"
shared:
menu:
cart:
cart: "Carrello"
signed_in:
profile: "Profilo"
mobile_menu:
cart: "Carrello"
joyride:
checkout: "Checkout adesso"
already_ordered_products: "Già richiesto in questo ciclo di richieste"
@@ -1108,7 +1158,11 @@ it:
shop:
messages:
login: "fai il login"
signup: "Registrati"
contact: "contatto"
require_customer_login: "Solo utenti approvati hanno accesso a questo negozio"
require_login_html: "Se sei già un utente approvato, %{login} o %{signup}per procedere. Vuoi iniziare a frequentare questo negozio? Per favore %{contact} %{enterprise} e chiedi come raggiungerlo."
require_customer_html: "Se vuoi iniziare a comprare, per favore %{contact} %{enterprise} per chiedere di raggiungerci."
card_could_not_be_updated: La Carta non ha potuto essere rinnovata
card_could_not_be_saved: La Carta non ha potuto essere salvata
spree_gateway_error_flash_for_checkout: "C'è stato un problema con le informazioni sul pagamento: %{error}"
@@ -1145,6 +1199,7 @@ it:
menu_4_title: "Gruppi"
menu_4_url: "/groups"
menu_5_title: "About"
menu_5_url: "https://about.openfoodnetwork.org.au/"
menu_6_title: "Blog"
menu_6_url: "https://apropos.openfoodfrance.org/blog/"
menu_7_title: "Support"
@@ -1575,6 +1630,7 @@ it:
sell_hubs_detail: "Imposta un profilo per la tua azienda o organizzazione su OFN. In qualsiasi momento potrai far diventare il tuo profilo un negozio online multi-produttore."
sell_groups_detail: "Imposta un'area per le aziende (produttori o altro) della tua regione o per la tua organizzazione."
sell_user_guide: "Scopri di più nella nostra guida utente."
sell_listing_price: "Politica dei prezzi in fase di definizione..."
sell_embed: "Possiamo anche inserire un negozio OFN nel tuo proprio sito o creare un sito per la tua rete locale."
sell_ask_services: "Chiedici dei servizi OFN."
shops_title: Negozi
@@ -1690,6 +1746,7 @@ it:
introduction:
registration_greeting: "Ciao!"
registration_intro: "Adesso puoi creare un profilo come Produttore o Hub"
registration_checklist: "Di che cosa ho bisogno?"
registration_time: "5-10 minuti"
registration_enterprise_address: "Indirizzo dell'azienda"
registration_contact_details: "Dettagli del contatto principale"
@@ -1944,6 +2001,7 @@ it:
spree_admin_supplier: Fornitore
spree_admin_product_category: Categoria prodotto
spree_admin_variant_unit_name: Nome della variante
unit_name: "Nome Unità"
change_package: "Cambia pacchetto"
spree_admin_single_enterprise_hint: "Suggerimento: Per permettere alle persone di trovarti, abilita la tua visibilità sotto"
spree_admin_eg_pickup_from_school: "es. \"Ritiro presso la Cooperativa\""
@@ -2179,6 +2237,7 @@ it:
payment_methods: "Metodi di pagamento"
payment_method_fee: "Imposta di transizione"
payment_processing_failed: "Non è stato possibile elaborare il pagamento, per favore controlla i dettagli che hai inserito"
payment_method_not_supported: "Questo metodo di pagamento non è supportato. Per favore scegline un altro."
payment_updated: "Pagamento aggiornato"
inventory_settings: "Impostazioni dell'inventario"
tag_rules: "Regole dei tag"
@@ -2372,8 +2431,20 @@ it:
severity: Gravità
description: Descrizione
resolve: Risolvi
tag_rules:
shipping_method_tagged_top: "Metodi di consegna taggati"
shipping_method_tagged_bottom: "sono:"
payment_method_tagged_top: "Metodi di Pagamento taggati"
payment_method_tagged_bottom: "sono:"
order_cycle_tagged_top: "Cicli di richieste taggati"
order_cycle_tagged_bottom: "sono:"
inventory_tagged_top: "Varianti inventario taggate"
inventory_tagged_bottom: "sono:"
new_tag_rule_dialog:
select_rule_type: "Seleziona un tipo di regola:"
add_rule: "Aggiungi regola"
enterprise_fees:
inherit_from_product: "Eredita dal prodotto"
orders:
index:
per_page: "%{results} per pagina"
@@ -2434,6 +2505,7 @@ it:
name_required_error: "Inserisci un nome per questo programma"
no_order_cycles_error: "Per favore seleziona almeno un ciclo di richieste (drag and drop)"
available: "Disponibile"
selected: "Selezionato"
customers:
index:
add_customer: "Aggiungi cliente"
@@ -2591,6 +2663,8 @@ it:
name_or_sku: "Nome o SKU (inserisci almeno i primi 4 caratteri del nome del prodotto)"
resend: Invia di nuovo
back_to_orders_list: Torna alla lista delle richieste
return_authorizations: Authorizationi reso
cannot_create_returns: Impossibile creare resi poiché questo ordine non ha unità spedite.
select_stock: "Seleziona magazzino"
location: "Posizione"
count_on_hand: "Conta a mente"
@@ -2627,6 +2701,7 @@ it:
fill_in_customer_info: "Si prega di compilare le informazioni del cliente"
new_payment: "Nuovo pagamento"
capture: "Cattura"
void: "vuoto"
configurations: "Configurazioni"
general_settings: "Impostazioni generali"
site_name: "Nome del sito"
@@ -2728,9 +2803,25 @@ it:
no_results: "Nessun risultato"
create: "Crea"
loading: "Caricamento"
flat_percent: "Percentuale fissa"
per_kg: "Per Kg"
amount: "Quantità"
currency: "Moneta"
first_item: "Costo articolo"
additional_item: "Costo aggiuntivo articolo"
max_items: "Numero massimo di articoli"
minimal_amount: "Importo minimo"
normal_amount: "Importo normale"
discount_amount: "Totale sconto"
no_images_found: "Nessuna immagine trovata"
new_image: "Nuova immagine"
filename: "Nome file"
alt_text: "Testo alternativo"
thumbnail: "Thumbnail"
back_to_images_list: "Torna alla lista Immagini"
email: Email
account_updated: "Account aggiornato!"
email_updated: "L'account sarà aggiornato una volta confermata la nuova email"
my_account: "Il mio account"
date: "Data"
time: "Ora"
@@ -2738,6 +2829,8 @@ it:
inventory: Inventario
zipcode: CAP
weight: Peso (kg)
error_user_destroy_with_orders: "Gli utenti con ordini completi non dovrebbero essere cancellati"
options: "Opzioni"
actions:
update: "Aggiorna"
errors:
@@ -2761,7 +2854,7 @@ it:
configuration: "Configurazione"
users: "Utenti"
roles: "Ruoli"
order_cycles: "Cicli di richiesteCicli di richieste"
order_cycles: "Cicli di richieste"
enterprises: "Aziende"
enterprise_relationships: "permessi"
customers: "Consumatori"
@@ -2769,25 +2862,53 @@ it:
product_properties:
index:
inherits_properties_checkbox_hint: "Eredita le proprietà da %{supplier}? (se non sovrascritto)"
add_product_properties: "Aggiungi proprietà prodotto"
select_from_prototype: "Seleziona da un prototipo"
properties:
index:
properties: "Proprietà"
new_property: "Nuova proprietà"
name: "Nome"
presentation: "Presentazione"
new:
new_property: "Nuova proprietà"
edit:
editing_property: "Modifica Proprietà"
back_to_properties_list: "Torna alla lista delle proprietà"
form:
name: "Nome"
presentation: "Presentazione"
return_authorizations:
index:
new_return_authorization: "New Return Authorization"
return_authorizations: "Return Authorizations"
back_to_orders_list: "Torna alla lista delle richieste"
rma_number: "Numero RMA"
status: "Stato"
amount: "Quantità"
cannot_create_returns: "Impossibile creare resi poiché questo ordine non ha unità spedite."
continue: "Continua"
new:
new_return_authorization: "Nuova autorizzazione resi"
back_to_return_authorizations_list: "Torna alla lista di autorizzazioni resi"
continue: "Continua"
edit:
receive: "ricevi"
are_you_sure: "Sei sicuro?"
return_authorization: "Autorizzazione al reso"
form:
product: "Prodotto"
quantity_shipped: "Quantità spedita"
quantity_returned: "Quantità restituita"
return_quantity: "Quantità restituita"
amount: "Quantità"
rma_value: "Valore RMA"
reason: "Motivo"
stock_location: "Posizione stock"
states:
authorized: "autorizzato"
received: "ricevuto"
canceled: "Annullato"
orders:
index:
listing_orders: "Listino Ordini"
@@ -2835,7 +2956,7 @@ it:
one: "Hai un prodotto attivo"
other: "Hai il %{count} di prodotti disponibili"
order_cycles:
order_cycles: "Cicli di richiesteCicli di richieste"
order_cycles: "Cicli di richieste"
order_cycles_tip: "I cicli di richieste determinano dove e quando i tuoi prodotti sono disponibili per i consumatori."
you_have_active:
zero: "Non hai nessun ciclo di richieste attivo."
@@ -2845,15 +2966,29 @@ it:
shipping_methods:
index:
shipping_methods: "Metodi di spedizione"
new_shipping_method: "Nuovo metodo di spedizione"
name: "Nome"
products_distributor: "Distributore"
zone: "Zone"
calculator: "Calcolatrice"
display: "Visualizza"
both: "Entrambi"
front_end: "Front End"
back_end: "Back End"
no_shipping_methods_found: "Nessun metodo di spedizione trovato"
new:
new_shipping_method: "Nuovo metodo di spedizione"
back_to_shipping_methods_list: "Torna alla lista dei metodi di spedizione"
edit:
editing_shipping_method: "Modifica metodo di spedizione"
new: "Nuovo"
back_to_shipping_methods_list: "Torna alla lista dei metodi di spedizione"
form:
categories: "categorie"
zones: "Zone"
both: "Entrambi"
front_end: "Front End"
back_end: "Back End"
payment_methods:
new:
new_payment_method: "Nuovo metodo di pagamento"
@@ -2880,6 +3015,7 @@ it:
error_saving_payment: Errore memorizzando il pagamento
submitting_payment: Eseguendo il pagamento
products:
image_upload_error: "L'immagine del prodotto non è stata riconosciuta. Carica un'immagine in formato PNG o JPG."
new:
title: "Nuovo prodotto"
new_product: "Nuovo prodotto"
@@ -2887,6 +3023,7 @@ it:
product_name: "Nome Prodotto"
units: "Unità di misura"
value: "Valore"
unit_name: "Nome Unità"
price: "Prezzo"
on_hand: "Disponibile"
on_demand: "A richiesta"
@@ -2962,12 +3099,23 @@ it:
index:
sku: "SKU"
price: "Prezzo"
options: "Opzioni"
no_results: "Nessun risultato"
to_add_variants_you_must_first_define: "Per aggiungere varianti, devi prima definire"
option_types: "Tipi di opzioni"
option_values: "Valori opzione"
and: "e"
new_variant: "Nuova variante"
show_active: "Mostra attivi"
show_deleted: "Mostra cancellati"
new:
new_variant: "Nuova variante"
form:
cost_price: "Prezzo di costo"
sku: "SKU"
price: "Prezzo"
display_as: "Visualizza come"
display_name: "Nome da visualizzare"
autocomplete:
producer_name: "Produttore"
unit: "Unità"
@@ -3000,6 +3148,7 @@ it:
line_item:
insufficient_stock: "Scorte disponibili insufficienti, solo %{on_hand} rimanenti"
out_of_stock: "Esaurito"
unavailable_item: "attualmente non disponibile"
shipment_states:
backorder: ordine arretrato
partial: parziale
@@ -3019,6 +3168,8 @@ it:
invalid: invalido
order_mailer:
cancel_email:
customer_greeting: "Ciao %{name}!"
instructions: "Il tuo ordine è stato ANNULLATO. Per favore conserva queste informazioni di cancellazione per i tuoi record."
order_summary_canceled: "Riepilogo dell'ordine [CANCELLATO]"
subject: "Cancellazione dell'ordine"
confirm_email:
@@ -3104,3 +3255,19 @@ it:
allow_charges?: "Consentire ricarichi"
localized_number:
invalid_format: 'Formato non valido: inserire un numero.'
api:
invalid_api_key: "Chiave API (%{key}) specificata non valida."
unauthorized: "Non sei autorizzato a eseguire questa azione."
invalid_resource: "Risorsa non valida. Per favore correggi gli errori e riprova."
resource_not_found: "La risorsa che stavi cercando non è stata trovata."
access: "Accesso API"
key: "Chiave"
clear_key: "Cancella chiave"
regenerate_key: "Rigenera chiave"
no_key: "Nessuna chiave"
generate_key: "Genera chiave API"
key_generated: "Chiave generata"
key_cleared: "Chiave cancellata"
shipment:
cannot_ready: "Impossibile spedizione immediata."
invalid_taxonomy_id: "ID tassonomia non valido."

View File

@@ -2508,6 +2508,7 @@ nb:
customer_placeholder: "customer@example.org"
valid_email_error: "Vennligst oppgi en gyldig epostadresse"
subscriptions:
error_saving: "Feil ved lagring av abonnement"
new:
please_select_a_shop: "Vennligst velg en butikk"
insufficient_stock: "Utilstrekkelig lager tilgjengelig, kun %{on_hand} gjenværende"

View File

@@ -13,11 +13,11 @@ job_type :enqueue_job, "cd :path; :environment_variable=:environment bundle exe
every 1.day, at: '2:45am' do
rake 'db2fog:clean' if ENV['S3_BACKUPS_BUCKET']
rake 'db2fog:clean' if app_config['S3_BACKUPS_BUCKET']
end
every 4.hours do
rake 'db2fog:backup' if ENV['S3_BACKUPS_BUCKET']
rake 'db2fog:backup' if app_config['S3_BACKUPS_BUCKET']
end
every 5.minutes do

View File

@@ -192,7 +192,7 @@ module OpenFoodNetwork
def line_item_includes
[{ variant: [{ option_values: :option_type }, { product: :supplier }],
order: [:bill_address, :ship_address, :order_cycle, :adjustments, :payments,
:user, :distributor, shipments: { shipping_rates: :shipping_method }] }]
:user, :distributor, :shipments] }]
end
private

View File

@@ -328,10 +328,13 @@ feature '
expect(page).to have_content 'Your order cycle has been updated.'
# And I add a supplier and some products
expect(page).to have_selector("table.exchanges tr.supplier")
select 'My supplier', from: 'new_supplier_id'
click_button 'Add supplier'
expect(page).to have_selector("table.exchanges tr.supplier", text: "My supplier")
page.all("table.exchanges tr.supplier td.products").each(&:click)
expect(page).to have_selector "#order_cycle_incoming_exchange_1_variants_#{initial_variants.last.id}", visible: true
page.find("#order_cycle_incoming_exchange_1_variants_#{initial_variants.last.id}", visible: true).click # uncheck (with visible:true filter)
check "order_cycle_incoming_exchange_2_variants_#{v1.id}"
@@ -352,6 +355,7 @@ feature '
# And I add a distributor and some products
select 'My distributor', from: 'new_distributor_id'
click_button 'Add distributor'
expect(page).to have_field("order_cycle_outgoing_exchange_2_pickup_time")
fill_in 'order_cycle_outgoing_exchange_0_pickup_time', with: 'New time 0'
fill_in 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'New instructions 0'

View File

@@ -68,10 +68,7 @@ feature 'Subscriptions' do
expect(page).to have_no_content subscription.customer.email
# Viewing Products
within "tr#so_#{subscription.id}" do
expect(page).to have_selector "td.items.panel-toggle", text: 3
page.find("td.items.panel-toggle").click
end
open_subscription_products_panel
within "#subscription-line-items" do
expect(page).to have_selector "span#order_subtotal", text: "$15.00" # 3 x $5 items
@@ -138,6 +135,28 @@ feature 'Subscriptions' do
expect(subscription.reload.canceled_at).to be_within(5.seconds).of Time.zone.now
end
end
context "editing subscription products quantity" do
it "updates quantity" do
visit admin_subscriptions_path
select2_select shop.name, from: "shop_id"
open_subscription_products_panel
within "#sli_0" do
fill_in 'quantity', with: "5"
end
page.find("a.button.update").click
expect(page).to have_content 'SAVED'
end
end
def open_subscription_products_panel
within "tr#so_#{subscription.id}" do
expect(page).to have_selector "td.items.panel-toggle", text: 3
page.find("td.items.panel-toggle").click
end
end
end
context 'creating a new subscription' do

View File

@@ -0,0 +1,44 @@
describe "ProductsPanelController", ->
scope = null
StatusMessage = null
subscription = { shop_id: 1 }
beforeEach ->
module('admin.subscriptions')
inject ($controller, $rootScope, _StatusMessage_) ->
scope = $rootScope
scope.object = subscription
StatusMessage = _StatusMessage_
$controller 'ProductsPanelController', {$scope: scope, StatusMessage: _StatusMessage_}
describe "saving subscription", ->
update_promise_resolve = null
update_promise_reject = null
update_promise = null
beforeEach ->
update_promise = new Promise (resolve, reject) ->
update_promise_resolve = resolve
update_promise_reject = reject
subscription.update = jasmine.createSpy('update').and.returnValue(update_promise)
StatusMessage.display = jasmine.createSpy('display')
it "updates subscription and updates status message while in progress and on success", ->
scope.save()
expect(subscription.update).toHaveBeenCalled()
expect(StatusMessage.display).toHaveBeenCalledWith('progress', 'Saving...')
expect(scope.saving).toEqual(true)
update_promise.then ->
expect(StatusMessage.display.calls.all()[1].args).toEqual(['success', 'Changes saved.'])
expect(scope.saving).toEqual(false)
update_promise_resolve()
it "updates status message on errors", ->
scope.save()
update_promise.catch ->
expect(StatusMessage.display.calls.all()[1].args).toEqual(['failure', 'Error saving subscription'])
expect(scope.saving).toEqual(false)
update_promise_reject("error")

View File

@@ -4,9 +4,9 @@ describe Calculator::Weight do
it_behaves_like "a model using the LocalizedNumber module", [:preferred_per_kg]
it "computes shipping cost for an order by total weight" do
variant1 = build(:variant, weight: 10)
variant2 = build(:variant, weight: 20)
variant3 = build(:variant, weight: nil)
variant1 = build(:variant, unit_value: 10_000)
variant2 = build(:variant, unit_value: 20_000)
variant3 = build(:variant, unit_value: nil)
line_item1 = build(:line_item, variant: variant1, quantity: 1)
line_item2 = build(:line_item, variant: variant2, quantity: 3)
@@ -14,39 +14,40 @@ describe Calculator::Weight do
order = double(:order, line_items: [line_item1, line_item2, line_item3])
subject.set_preference(:per_kg, 10)
expect(subject.compute(order)).to eq((10 * 1 + 20 * 3) * 10)
subject.set_preference(:per_kg, 5)
expect(subject.compute(order)).to eq(350) # (10 * 1 + 20 * 3) * 5
end
describe "line item with variant weight" do
let(:variant) { build(:variant, weight: 10) }
describe "line item with variant_unit weight and variant unit_value" do
let(:variant) { build(:variant, unit_value: 10_000) }
let(:line_item) { build(:line_item, variant: variant, quantity: 2) }
before { subject.set_preference(:per_kg, 10) }
before { subject.set_preference(:per_kg, 5) }
it "computes shipping cost for a line item" do
expect(subject.compute(line_item)).to eq(10 * 2 * 10)
expect(subject.compute(line_item)).to eq(100) # 10 * 2 * 5
end
describe "and with final_weight_volume defined" do
before { line_item.update_attribute :final_weight_volume, '18000' }
it "computes fee using final_weight_volume, not the variant weight" do
expect(subject.compute(line_item)).to eq(10 * 18)
expect(subject.compute(line_item)).to eq(90) # 18 * 5
end
context "where variant unit is not weight" do
it "uses both final_weight_volume and weight to calculate fee" do
line_item.variant.update_attribute :weight, 7
line_item.variant.product.update_attribute :variant_unit, 'items'
expect(subject.compute(line_item)).to eq(180)
expect(subject.compute(line_item)).to eq(63) # 7 * (18000/10000) * 5
end
end
end
end
it "computes shipping cost for an object with an order" do
variant1 = build(:variant, weight: 10)
variant2 = build(:variant, weight: 5)
variant1 = build(:variant, unit_value: 10_000)
variant2 = build(:variant, unit_value: 20_000)
line_item1 = build(:line_item, variant: variant1, quantity: 1)
line_item2 = build(:line_item, variant: variant2, quantity: 2)
@@ -54,8 +55,8 @@ describe Calculator::Weight do
order = double(:order, line_items: [line_item1, line_item2])
object_with_order = double(:object_with_order, order: order)
subject.set_preference(:per_kg, 10)
expect(subject.compute(object_with_order)).to eq((10 * 1 + 5 * 2) * 10)
subject.set_preference(:per_kg, 5)
expect(subject.compute(object_with_order)).to eq(250) # (10 * 1 + 20 * 2) * 5
end
context "when line item final_weight_volume is set" do
@@ -77,7 +78,7 @@ describe Calculator::Weight do
it "is correct" do
expect(line_item.final_weight_volume).to eq(600) # 600g
line_item.final_weight_volume = 700 # 700g
expect(calculator.compute(line_item)).to eq(4.2)
expect(calculator.compute(line_item)).to eq(4.2) # 0.7 * 6
end
end
@@ -88,7 +89,7 @@ describe Calculator::Weight do
it "is correct" do
expect(line_item.final_weight_volume).to eq(6_000) # 6kg
line_item.final_weight_volume = 7_000 # 7kg
expect(calculator.compute(line_item)).to eq(42)
expect(calculator.compute(line_item)).to eq(42) # 7 * 6
end
end
@@ -99,7 +100,7 @@ describe Calculator::Weight do
it "is correct" do
expect(line_item.final_weight_volume).to eq(6_000_000) # 6T
line_item.final_weight_volume = 7_000_000 # 7T
expect(calculator.compute(line_item)).to eq(42_000)
expect(calculator.compute(line_item)).to eq(42_000) # 7000 * 6
end
end
end
@@ -112,7 +113,7 @@ describe Calculator::Weight do
it "is correct" do
expect(line_item.final_weight_volume).to eq(0.6) # 600mL
line_item.final_weight_volume = 0.7 # 700mL
expect(calculator.compute(line_item)).to eq(3.50)
expect(calculator.compute(line_item)).to eq(3.50) # 0.25 * (0.7/0.3) * 6
end
end
@@ -123,7 +124,7 @@ describe Calculator::Weight do
it "is correct" do
expect(line_item.final_weight_volume).to eq(6) # 6L
line_item.final_weight_volume = 7 # 7L
expect(calculator.compute(line_item)).to eq(35.00)
expect(calculator.compute(line_item)).to eq(35.00) # 2.5 * (7/3) * 6
end
end
@@ -134,7 +135,7 @@ describe Calculator::Weight do
it "is correct" do
expect(line_item.final_weight_volume).to eq(6_000) # 6kL
line_item.final_weight_volume = 7_000 # 7kL
expect(calculator.compute(line_item)).to eq(34_995)
expect(calculator.compute(line_item)).to eq(34_995) # 2_500 * round(7_000/3_000) * 6
end
end
end
@@ -146,7 +147,7 @@ describe Calculator::Weight do
it "is correct" do
expect(line_item.final_weight_volume).to eq(6) # 6 pcs
line_item.final_weight_volume = 7 # 7 pcs
expect(calculator.compute(line_item)).to eq(35.0)
expect(calculator.compute(line_item)).to eq(35.0) # 2.5 * (7/3) * 6
end
end
end

View File

@@ -0,0 +1,27 @@
require "spec_helper"
module Api
module Admin
describe OrderCycleSerializer do
let(:order_cycle) { create(:order_cycle) }
let(:serializer) { Api::Admin::OrderCycleSerializer.new order_cycle, current_user: order_cycle.coordinator.owner }
it "serializes an order cycle" do
expect(serializer.to_json).to include order_cycle.name
end
it "serializes the order cycle with exchanges" do
expect(serializer.exchanges.to_json).to include "\"#{order_cycle.variants.first.id}\":true"
end
it "serializes the order cycle with editable_variants_for_incoming_exchanges" do
expect(serializer.editable_variants_for_incoming_exchanges.to_json).to include order_cycle.variants.first.id.to_s
expect(serializer.editable_variants_for_incoming_exchanges.to_json).to_not include order_cycle.distributors.first.id.to_s
end
it "serializes the order cycle with editable_variants_for_outgoing_exchanges" do
expect(serializer.editable_variants_for_outgoing_exchanges.to_json).to include order_cycle.variants.first.id.to_s
end
end
end
end