mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-04-06 07:29:16 +00:00
Merge branch 'master' into remove_pin
This commit is contained in:
18
Gemfile.lock
18
Gemfile.lock
@@ -598,17 +598,17 @@ GEM
|
||||
rspec-retry (0.6.2)
|
||||
rspec-core (> 3.3)
|
||||
rspec-support (3.10.1)
|
||||
rswag (2.3.2)
|
||||
rswag-api (= 2.3.2)
|
||||
rswag-specs (= 2.3.2)
|
||||
rswag-ui (= 2.3.2)
|
||||
rswag-api (2.3.2)
|
||||
rswag (2.3.3)
|
||||
rswag-api (= 2.3.3)
|
||||
rswag-specs (= 2.3.3)
|
||||
rswag-ui (= 2.3.3)
|
||||
rswag-api (2.3.3)
|
||||
railties (>= 3.1, < 7.0)
|
||||
rswag-specs (2.3.2)
|
||||
rswag-specs (2.3.3)
|
||||
activesupport (>= 3.1, < 7.0)
|
||||
json-schema (~> 2.2)
|
||||
railties (>= 3.1, < 7.0)
|
||||
rswag-ui (2.3.2)
|
||||
rswag-ui (2.3.3)
|
||||
actionpack (>= 3.1, < 7.0)
|
||||
railties (>= 3.1, < 7.0)
|
||||
rubocop (1.9.1)
|
||||
@@ -672,7 +672,7 @@ GEM
|
||||
activerecord (>= 4.1)
|
||||
state_machines-activemodel (>= 0.5.0)
|
||||
stringex (2.8.5)
|
||||
stripe (5.29.0)
|
||||
stripe (5.29.1)
|
||||
temple (0.8.2)
|
||||
test-prof (0.11.3)
|
||||
test-unit (3.4.0)
|
||||
@@ -682,7 +682,7 @@ GEM
|
||||
thor (0.20.3)
|
||||
thread_safe (0.3.6)
|
||||
tilt (1.4.1)
|
||||
timecop (0.9.2)
|
||||
timecop (0.9.4)
|
||||
tzinfo (1.2.9)
|
||||
thread_safe (~> 0.1)
|
||||
uglifier (4.2.0)
|
||||
|
||||
@@ -13,7 +13,7 @@ window.Darkswarm = angular.module("Darkswarm", [
|
||||
'angularSlideables'
|
||||
]).config ($httpProvider, $tooltipProvider, $locationProvider, $anchorScrollProvider) ->
|
||||
$httpProvider.defaults.headers['common']['X-Requested-With'] = 'XMLHttpRequest'
|
||||
$httpProvider.defaults.headers.common.Accept = "application/json, text/javascript, */*"
|
||||
$httpProvider.defaults.headers.common['Accept'] = "application/json, text/javascript, */*"
|
||||
|
||||
# We manually handle our scrolling
|
||||
$anchorScrollProvider.disableAutoScrolling()
|
||||
|
||||
@@ -16,10 +16,7 @@
|
||||
%button.bulk-buy-add.variant-quantity{type: "button", ng: {click: "add(-1)", disabled: "!canAdd(-1)"}}>
|
||||
-# U+FF0D Fullwidth Hyphen-Minus
|
||||
-
|
||||
%input.bulk-buy.variant-quantity{
|
||||
type: "number",
|
||||
min: "0",
|
||||
max: "{{ available() }}",
|
||||
%input.bulk-buy.variant-quantity{type: "number", min: "0", max: "{{ available() }}",
|
||||
ng: {model: "variant.line_item.quantity", max: "Infinity"}}>
|
||||
%button.bulk-buy-add.variant-quantity{type: "button", ng: {click: "add(1)", disabled: "!canAdd(1)"}}
|
||||
-# U+FF0B Fullwidth Plus Sign
|
||||
@@ -31,10 +28,7 @@
|
||||
%button.bulk-buy-add.variant-quantity{type: "button", ng: {click: "addMax(-1)", disabled: "!canAddMax(-1)"}}>
|
||||
-# U+FF0D Fullwidth Hyphen-Minus
|
||||
-
|
||||
%input.bulk-buy.variant-quantity{
|
||||
type: "number",
|
||||
min: "0",
|
||||
max: "{{ available() }}",
|
||||
%input.bulk-buy.variant-quantity{type: "number", min: "0", max: "{{ available() }}",
|
||||
ng: {model: "variant.line_item.max_quantity", max: "Infinity"}}>
|
||||
%button.bulk-buy-add.variant-quantity{type: "button", ng: {click: "addMax(1)", disabled: "!canAddMax(1)"}}
|
||||
-# U+FF0B Fullwidth Plus Sign
|
||||
|
||||
@@ -8,12 +8,8 @@
|
||||
%button.variant-quantity{type: "button", ng: {click: "add(-1)", disabled: "!canAdd(-1)"}}>
|
||||
-# U+FF0D Fullwidth Hyphen-Minus
|
||||
-
|
||||
%input.variant-quantity{
|
||||
type: "number",
|
||||
min: "0",
|
||||
max: "{{ available() }}",
|
||||
ng: {model: "variant.line_item.quantity", max: "Infinity"}
|
||||
}>
|
||||
%input.variant-quantity{ type: "number", min: "0", max: "{{ available() }}",
|
||||
ng: {model: "variant.line_item.quantity", max: "Infinity"}}>
|
||||
%button.variant-quantity{type: "button", ng: {click: "add(1)", disabled: "!canAdd(1)"}}
|
||||
-# U+FF0B Fullwidth Plus Sign
|
||||
+
|
||||
|
||||
@@ -15,9 +15,7 @@ module Spree
|
||||
order = current_order || raise(ActiveRecord::RecordNotFound)
|
||||
items = order.line_items.map(&method(:line_item))
|
||||
|
||||
tax_adjustments = order.adjustments.tax
|
||||
# TODO: Remove in Spree 2.2
|
||||
tax_adjustments = tax_adjustments.additional if tax_adjustments.respond_to?(:additional)
|
||||
tax_adjustments = order.adjustments.tax.additional
|
||||
shipping_adjustments = order.adjustments.shipping
|
||||
|
||||
order.adjustments.eligible.each do |adjustment|
|
||||
@@ -175,12 +173,8 @@ module Spree
|
||||
|
||||
def payment_details(items)
|
||||
item_sum = items.sum { |i| i[:Quantity] * i[:Amount][:value] }
|
||||
# Would use tax_total here, but it can include "included" taxes as well.
|
||||
# For instance, tax_total would include the 10% GST in Australian stores.
|
||||
# A quick sum will get us around that little problem.
|
||||
# TODO: Remove additional check in 2.2
|
||||
tax_adjustments = current_order.adjustments.tax
|
||||
tax_adjustments = tax_adjustments.additional if tax_adjustments.respond_to?(:additional)
|
||||
|
||||
tax_adjustments = current_order.adjustments.tax.additional
|
||||
tax_adjustments_total = tax_adjustments.sum(:amount)
|
||||
|
||||
if item_sum.zero?
|
||||
|
||||
@@ -64,12 +64,14 @@ module Spree
|
||||
end
|
||||
end
|
||||
|
||||
scope :tax, -> { where(originator_type: 'Spree::TaxRate', adjustable_type: 'Spree::Order') }
|
||||
scope :tax, -> { where(originator_type: 'Spree::TaxRate') }
|
||||
scope :price, -> { where(adjustable_type: 'Spree::LineItem') }
|
||||
scope :optional, -> { where(mandatory: false) }
|
||||
scope :charge, -> { where('amount >= 0') }
|
||||
scope :credit, -> { where('amount < 0') }
|
||||
scope :return_authorization, -> { where(source_type: "Spree::ReturnAuthorization") }
|
||||
scope :inclusive, -> { where(included: true) }
|
||||
scope :additional, -> { where(included: false) }
|
||||
|
||||
scope :enterprise_fee, -> { where(originator_type: 'EnterpriseFee') }
|
||||
scope :admin, -> { where(source_type: nil, originator_type: nil) }
|
||||
|
||||
@@ -47,6 +47,7 @@ module Spree
|
||||
dependent: :destroy
|
||||
|
||||
has_many :line_item_adjustments, through: :line_items, source: :adjustments
|
||||
has_many :all_adjustments, class_name: 'Spree::Adjustment', dependent: :destroy
|
||||
|
||||
has_many :shipments, dependent: :destroy do
|
||||
def states
|
||||
|
||||
@@ -164,14 +164,6 @@ module Spree
|
||||
Spree::Money.new(item_cost, currency: currency)
|
||||
end
|
||||
|
||||
def total_cost
|
||||
cost + item_cost
|
||||
end
|
||||
|
||||
def display_total_cost
|
||||
Spree::Money.new(total_cost, currency: currency)
|
||||
end
|
||||
|
||||
def editable_by?(_user)
|
||||
!shipped?
|
||||
end
|
||||
|
||||
@@ -61,7 +61,7 @@ module Spree
|
||||
def adjust(order)
|
||||
label = create_label
|
||||
if included_in_price
|
||||
if Zone.default_tax.contains? order.tax_zone
|
||||
if default_zone_or_zone_match? order
|
||||
order.line_items.each { |line_item| create_adjustment(label, line_item, line_item) }
|
||||
else
|
||||
amount = -1 * calculator.compute(order)
|
||||
@@ -89,6 +89,10 @@ module Spree
|
||||
end
|
||||
end
|
||||
|
||||
def default_zone_or_zone_match?(order)
|
||||
Zone.default_tax.contains?(order.tax_zone) || order.tax_zone == zone
|
||||
end
|
||||
|
||||
# Manually apply a TaxRate to a particular amount. TaxRates normally compute against
|
||||
# LineItems or Orders, so we mock out a line item here to fit the interface
|
||||
# that our calculator (usually DefaultTax) expects.
|
||||
@@ -114,6 +118,8 @@ module Spree
|
||||
label = ""
|
||||
label << (name.presence || tax_category.name) + " "
|
||||
label << (show_rate_in_label? ? "#{amount * 100}%" : "")
|
||||
label << " (#{I18n.t('models.tax_rate.included_in_price')})" if included_in_price?
|
||||
label
|
||||
end
|
||||
|
||||
def with_tax_included_in_price
|
||||
|
||||
@@ -3,47 +3,47 @@
|
||||
.row
|
||||
.eight.columns.alpha
|
||||
.row
|
||||
.six.columns.alpha
|
||||
.five.columns.alpha
|
||||
%h3= t('.details')
|
||||
.two.columns.omega.text-right
|
||||
.eleven.columns.omega
|
||||
%input#edit-details{ type: "button", value: t(:edit), ng: { click: "setView('details')" } }
|
||||
.row
|
||||
.three.columns.alpha
|
||||
.five.columns.alpha
|
||||
%strong= t('admin.customer')
|
||||
.five.columns.omega {{ subscription.customer().email }}
|
||||
.eleven.columns.omega {{ subscription.customer().email }}
|
||||
.row
|
||||
.three.columns.alpha
|
||||
.five.columns.alpha
|
||||
%strong= t('admin.schedule')
|
||||
.five.columns.omega {{ subscription.schedule().name }}
|
||||
.eleven.columns.omega {{ subscription.schedule().name }}
|
||||
.row
|
||||
.three.columns.alpha
|
||||
.five.columns.alpha
|
||||
%strong= t('admin.payment_method')
|
||||
.five.columns.omega {{ subscription.paymentMethod().name }}
|
||||
.eleven.columns.omega {{ subscription.paymentMethod().name }}
|
||||
.row
|
||||
.three.columns.alpha
|
||||
.five.columns.alpha
|
||||
%strong= t('admin.shipping_method')
|
||||
.five.columns.omega {{ subscription.shippingMethod().name }}
|
||||
.eleven.columns.omega {{ subscription.shippingMethod().name }}
|
||||
.row
|
||||
.three.columns.alpha
|
||||
.five.columns.alpha
|
||||
%strong= t('admin.begins_at')
|
||||
.five.columns.omega {{ subscription.begins_at }}
|
||||
.eleven.columns.omega {{ subscription.begins_at }}
|
||||
.row.margin-bottom-30
|
||||
.three.columns.alpha
|
||||
.five.columns.alpha
|
||||
%strong= t('admin.ends_at')
|
||||
.five.columns.omega {{ subscription.ends_at || ('ongoing' | t) }}
|
||||
.eleven.columns.omega {{ subscription.ends_at || ('ongoing' | t) }}
|
||||
.row
|
||||
.six.columns.alpha
|
||||
.five.columns.alpha
|
||||
%h3= t('.address')
|
||||
.two.columns.omega.text-right
|
||||
.eleven.columns.omega
|
||||
%input#edit-address{ type: "button", value: t(:edit), ng: { click: "setView('address')" } }
|
||||
.row
|
||||
.three.columns.alpha
|
||||
.five.columns.alpha
|
||||
%strong= t('admin.bill_address')
|
||||
.five.columns.omega {{ formatAddress(subscription.bill_address) }}
|
||||
.eleven.columns.omega {{ formatAddress(subscription.bill_address) }}
|
||||
.row
|
||||
.three.columns.alpha
|
||||
.five.columns.alpha
|
||||
%strong= t('admin.ship_address')
|
||||
.five.columns.omega {{ formatAddress(subscription.ship_address) }}
|
||||
.eleven.columns.omega {{ formatAddress(subscription.ship_address) }}
|
||||
|
||||
.one.column
|
||||
|
||||
@@ -52,47 +52,46 @@
|
||||
.row
|
||||
.five.columns.alpha
|
||||
%h3= t('.products')
|
||||
.two.columns.omega.text-right
|
||||
.eleven.columns.omega
|
||||
%input#edit-products{ type: "button", value: t(:edit), ng: { click: "setView('products')" } }
|
||||
.row
|
||||
.seven.columns.alpha.omega
|
||||
%table#subscription-line-items.admin-subscription-review-subscription-line-items
|
||||
%colgroup
|
||||
%col{:style => "width: 62%;"}/
|
||||
%col{:style => "width: 14%;"}/
|
||||
%col{:style => "width: 10%;"}/
|
||||
%col{:style => "width: 14%;"}/
|
||||
%thead
|
||||
%tr
|
||||
%th= t(:item_description)
|
||||
%th.price= t(:price)
|
||||
%th.quantity= t(:qty)
|
||||
%th.total
|
||||
%span= t(:total)
|
||||
%tbody
|
||||
%tr.item{ id: "sli_{{$index}}", ng: { repeat: "item in subscription.subscription_line_items | filter:{ _destroy: '!true' }", class: { even: 'even', odd: 'odd' } } }
|
||||
%td
|
||||
.description {{ item.description }}
|
||||
.not-in-open-and-upcoming-order-cycles-warning{ ng: { if: '!item.in_open_and_upcoming_order_cycles' } }
|
||||
= t(".no_open_or_upcoming_order_cycle")
|
||||
%td.price.align-center {{ item.price_estimate | localizeCurrency }}
|
||||
%td.quantity {{ item.quantity }}
|
||||
%td.total.align-center {{ (item.price_estimate * item.quantity) | localizeCurrency }}
|
||||
%tbody#subtotal.no-border-top{"data-hook" => "admin_order_form_subtotal"}
|
||||
%tr#subtotal-row
|
||||
%td{:colspan => "3"}
|
||||
%b
|
||||
= t(:subtotal)
|
||||
\:
|
||||
%td.total.align-center
|
||||
%span {{ subscription.estimatedSubtotal() | localizeCurrency }}
|
||||
%tbody#order-total.grand-total.no-border-top{"data-hook" => "admin_order_form_total"}
|
||||
%tr
|
||||
%td{:colspan => "3"}
|
||||
%b
|
||||
= t(:order_total_price)
|
||||
\:
|
||||
%td.total.align-center
|
||||
%span#order_form_total {{ subscription.estimatedTotal() | localizeCurrency }}
|
||||
%p.notice
|
||||
= t "this_is_an_estimate", scope: 'admin.subscriptions.subscription_line_items'
|
||||
%table#subscription-line-items.admin-subscription-review-subscription-line-items
|
||||
%colgroup
|
||||
%col{:style => "width: 62%;"}/
|
||||
%col{:style => "width: 14%;"}/
|
||||
%col{:style => "width: 10%;"}/
|
||||
%col{:style => "width: 14%;"}/
|
||||
%thead
|
||||
%tr
|
||||
%th= t(:item_description)
|
||||
%th.price= t(:price)
|
||||
%th.quantity= t(:qty)
|
||||
%th.total
|
||||
%span= t(:total)
|
||||
%tbody
|
||||
%tr.item{ id: "sli_{{$index}}", ng: { repeat: "item in subscription.subscription_line_items | filter:{ _destroy: '!true' }", class: { even: 'even', odd: 'odd' } } }
|
||||
%td
|
||||
.description {{ item.description }}
|
||||
.not-in-open-and-upcoming-order-cycles-warning{ ng: { if: '!item.in_open_and_upcoming_order_cycles' } }
|
||||
= t(".no_open_or_upcoming_order_cycle")
|
||||
%td.price.align-center {{ item.price_estimate | localizeCurrency }}
|
||||
%td.quantity {{ item.quantity }}
|
||||
%td.total.align-center {{ (item.price_estimate * item.quantity) | localizeCurrency }}
|
||||
%tbody#subtotal.no-border-top{"data-hook" => "admin_order_form_subtotal"}
|
||||
%tr#subtotal-row
|
||||
%td{:colspan => "3"}
|
||||
%b
|
||||
= t(:subtotal)
|
||||
\:
|
||||
%td.total.align-center
|
||||
%span {{ subscription.estimatedSubtotal() | localizeCurrency }}
|
||||
%tbody#order-total.grand-total.no-border-top{"data-hook" => "admin_order_form_total"}
|
||||
%tr
|
||||
%td{:colspan => "3"}
|
||||
%b
|
||||
= t(:order_total_price)
|
||||
\:
|
||||
%td.total.align-center
|
||||
%span#order_form_total {{ subscription.estimatedTotal() | localizeCurrency }}
|
||||
%p.notice
|
||||
= t "this_is_an_estimate", scope: 'admin.subscriptions.subscription_line_items'
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
require 'open_food_network/feature_toggle'
|
||||
|
||||
beta_testers = ENV['BETA_TESTERS']&.split(/[\s,]+/)
|
||||
beta_testers = ENV['BETA_TESTERS']&.split(/[\s,]+/) || []
|
||||
|
||||
OpenFoodNetwork::FeatureToggle.enable(:customer_balance, beta_testers)
|
||||
OpenFoodNetwork::FeatureToggle.enable(:customer_balance) do |user|
|
||||
if beta_testers == ['all']
|
||||
true
|
||||
else
|
||||
beta_testers.include?(user.email)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -117,6 +117,8 @@ ca:
|
||||
models:
|
||||
order_cycle:
|
||||
cloned_order_cycle_name: "CÒPIA DE %{order_cycle}"
|
||||
tax_rate:
|
||||
included_in_price: "Inclòs en el preu"
|
||||
validators:
|
||||
date_time_string_validator:
|
||||
not_string_error: "ha de ser una seqüència"
|
||||
|
||||
@@ -117,6 +117,8 @@ de_DE:
|
||||
models:
|
||||
order_cycle:
|
||||
cloned_order_cycle_name: "Kopie von %{order_cycle}"
|
||||
tax_rate:
|
||||
included_in_price: "im Preis inbegriffen"
|
||||
validators:
|
||||
date_time_string_validator:
|
||||
not_string_error: "muss eine Zeichenfolge sein"
|
||||
@@ -192,7 +194,7 @@ de_DE:
|
||||
explainer: Die automatische Verarbeitung dieser Bestellungen ist aus einem unbekannten Grund fehlgeschlagen. Dies sollte nicht geschehen, bitte kontaktieren Sie uns, wenn Sie dies sehen.
|
||||
home: "OFN"
|
||||
title: "Open Food Network"
|
||||
welcome_to: "Willkommen bei"
|
||||
welcome_to: "Willkommen beim"
|
||||
site_meta_description: "Wir wagen den Neustart. Mit Bauern und Züchtern, die bereit sind, ihre Geschichten stolz und wahrhaftig zu erzählen. Mit Händlern, die bereit sind, Menschen fair und ehrlich mit Produkten zu verbinden. Mit Käufern, die glauben, dass ihr Einkaufsverhalten die Welt wirklich verändern kann."
|
||||
search_by_name: Suche nach Ort oder Name des Ladens/Produzents...
|
||||
producers_join: 'Wir laden Produzenten ein, jetzt dem Open Food Network beizutreten. '
|
||||
@@ -1263,7 +1265,7 @@ de_DE:
|
||||
ticket_column_item: "Artikel"
|
||||
ticket_column_unit_price: "Stückpreis"
|
||||
ticket_column_total_price: "Gesamtpreis"
|
||||
menu_1_title: "Läden"
|
||||
menu_1_title: "Einkaufen"
|
||||
menu_1_url: "/shops"
|
||||
menu_2_title: "Karte"
|
||||
menu_2_url: "/map"
|
||||
@@ -1271,12 +1273,12 @@ de_DE:
|
||||
menu_3_url: "/producers"
|
||||
menu_4_title: "Gruppen"
|
||||
menu_4_url: "/groups"
|
||||
menu_5_title: "Über uns"
|
||||
menu_5_url: "https://wp.openfoodnetwork.de/"
|
||||
menu_6_title: "Support"
|
||||
menu_6_url: "https://wp.openfoodnetwork.de/support/"
|
||||
menu_7_title: "Mehr erfahren"
|
||||
menu_7_url: "https://openfoodnetwork.org/au/learn/"
|
||||
menu_5_title: "Verkaufen"
|
||||
menu_5_url: "https://openfoodnetwork.de/sell"
|
||||
menu_6_title: "Über uns"
|
||||
menu_6_url: "https://wp.openfoodnetwork.de/"
|
||||
menu_7_title: "Hilfe"
|
||||
menu_7_url: "https://wp.openfoodnetwork.de/support/"
|
||||
logo: "Logo (640x130)"
|
||||
logo_mobile: "Mobile Logo (75x26)"
|
||||
logo_mobile_svg: "Mobile Logo (SVG)"
|
||||
@@ -1407,7 +1409,7 @@ de_DE:
|
||||
cookies_policy_link_desc: "Wenn Sie mehr erfahren möchten, besuchen Sie unsere"
|
||||
cookies_policy_link: "Hinweise zu Cookies"
|
||||
cookies_accept_button: "Cookies akzeptieren"
|
||||
home_shop: Jetzt einkaufen
|
||||
home_shop: Jetzt regional einkaufen
|
||||
brandstory_headline: "Lebensmittel Direktvermarktung"
|
||||
brandstory_intro: "Manchmal ist der beste Weg, das System zu reparieren, einen Neuanfang zu wagen ..."
|
||||
brandstory_part1: "Wir wagen den Neuanfang. Mit Bauern und Züchtern, die bereit sind, ihre Geschichten stolz und wahrhaftig zu erzählen. Mit Händlern, die bereit sind, Menschen fair und ehrlich mit Produkten zu verbinden. Mit Käufern, die glauben, dass ihr Einkaufsverhalten die Welt wirklich verändern kann."
|
||||
@@ -2960,6 +2962,7 @@ de_DE:
|
||||
display_currency: "Währung anzeigen"
|
||||
choose_currency: "Währung auswählen"
|
||||
mail_method_settings: "E-Mail-Methodeneinstellungen"
|
||||
mail_settings_notice_html: "Einige der folgenden Einstellungen können nicht geändert werden und werden hier nur zu Zwecken der Fehlerbehebung aufgeführt. Änderungen können vorgenommen werden, indem die Einstellungen der deutschen Instanz aktualisiert und mithilfe von <a href='https://github.com/openfoodfoundation/ofn-install'>ofn-install</a> bereitgestellt werden. Wenden Sie sich an das globale OFN-Team, um weitere Informationen zu erhalten."
|
||||
general: "Allgemeines"
|
||||
enable_mail_delivery: "E-Mail-Versand aktivieren"
|
||||
send_mails_as: "E-Mails senden als"
|
||||
|
||||
@@ -140,6 +140,8 @@ en:
|
||||
models:
|
||||
order_cycle:
|
||||
cloned_order_cycle_name: "COPY OF %{order_cycle}"
|
||||
tax_rate:
|
||||
included_in_price: "Included in price"
|
||||
|
||||
validators:
|
||||
date_time_string_validator:
|
||||
|
||||
@@ -2950,6 +2950,7 @@ en_CA:
|
||||
display_currency: "Display currency"
|
||||
choose_currency: "Choose Currency"
|
||||
mail_method_settings: "Mail Method Settings"
|
||||
mail_settings_notice_html: "Some of the following settings can't be edited and are listed here just for debugging purposes. Changes can be made by updating the instance's secrets and provisioning them using <a href='https://github.com/openfoodfoundation/ofn-install'>ofn-install</a>. Reach out to the OFN global team for further details."
|
||||
general: "General"
|
||||
enable_mail_delivery: "Enable Mail Delivery"
|
||||
send_mails_as: "Send Mails As"
|
||||
@@ -3466,6 +3467,8 @@ en_CA:
|
||||
cancel_email_for_shop:
|
||||
greeting: "Dear %{name},"
|
||||
subject: "Cancellation of Order"
|
||||
intro: "A customer has cancelled ther order #%{number}."
|
||||
view_cancelled_order: "View cancelled order"
|
||||
confirm_email:
|
||||
subject: "Order Confirmation"
|
||||
invoice_email:
|
||||
|
||||
@@ -117,6 +117,8 @@ en_FR:
|
||||
models:
|
||||
order_cycle:
|
||||
cloned_order_cycle_name: "COPY OF %{order_cycle}"
|
||||
tax_rate:
|
||||
included_in_price: "Included in price"
|
||||
validators:
|
||||
date_time_string_validator:
|
||||
not_string_error: "must be a string"
|
||||
|
||||
@@ -117,6 +117,8 @@ en_GB:
|
||||
models:
|
||||
order_cycle:
|
||||
cloned_order_cycle_name: "COPY OF %{order_cycle}"
|
||||
tax_rate:
|
||||
included_in_price: "Included in price"
|
||||
validators:
|
||||
date_time_string_validator:
|
||||
not_string_error: "must be a string"
|
||||
@@ -2957,6 +2959,7 @@ en_GB:
|
||||
display_currency: "Display currency"
|
||||
choose_currency: "Choose Currency"
|
||||
mail_method_settings: "Mail Method Settings"
|
||||
mail_settings_notice_html: "Some of the following settings can't be edited and are listed here just for debugging purposes. Changes can be made by updating the instance's secrets and provisioning them using <a href='https://github.com/openfoodfoundation/ofn-install'>ofn-install</a>. Reach out to the OFN global team for further details."
|
||||
general: "General"
|
||||
enable_mail_delivery: "Enable Mail Delivery"
|
||||
send_mails_as: "Send Mails As"
|
||||
@@ -3473,6 +3476,8 @@ en_GB:
|
||||
cancel_email_for_shop:
|
||||
greeting: "Dear %{name},"
|
||||
subject: "Cancellation of Order"
|
||||
intro: "A customer has cancelled their order #%{number}."
|
||||
view_cancelled_order: "View cancelled order"
|
||||
confirm_email:
|
||||
subject: "Order Confirmation"
|
||||
invoice_email:
|
||||
|
||||
@@ -289,11 +289,16 @@ en_IE:
|
||||
create_and_add_another: "Create and Add Another"
|
||||
create: "Create"
|
||||
cancel: "Cancel"
|
||||
resume: "Resume"
|
||||
save: "Save"
|
||||
edit: "Edit"
|
||||
update: "Update"
|
||||
delete: "Delete"
|
||||
add: "Add"
|
||||
cut: "Cut"
|
||||
paste: "Paste"
|
||||
destroy: "Destroy"
|
||||
rename: "Rename"
|
||||
admin:
|
||||
begins_at: Begins At
|
||||
begins_on: Begins On
|
||||
@@ -352,6 +357,7 @@ en_IE:
|
||||
has_n_rules: "has %{num} rules"
|
||||
unsaved_confirm_leave: "There are unsaved changed on this page. Continue without saving?"
|
||||
unsaved_changes: "You have unsaved changes"
|
||||
available_units: "Available Units"
|
||||
shopfront_settings:
|
||||
embedded_shopfront_settings: "Embedded Shopfront Settings"
|
||||
enable_embedded_shopfronts: "Enable Embedded Shopfronts"
|
||||
@@ -411,6 +417,7 @@ en_IE:
|
||||
search_by_email: "Search by email/code..."
|
||||
guest_label: "Guest checkout"
|
||||
credit_owed: "Credit Owed"
|
||||
balance_due: "Balance Due"
|
||||
destroy:
|
||||
has_associated_orders: "Delete failed: customer has associated orders with this shop"
|
||||
contents:
|
||||
@@ -599,6 +606,8 @@ en_IE:
|
||||
controls:
|
||||
back_to_my_inventory: Back to my inventory
|
||||
orders:
|
||||
edit:
|
||||
order_sure_want_to: Are you sure you want to %{event} this order?
|
||||
invoice_email_sent: 'Invoice email has been sent'
|
||||
order_email_resent: 'Order email has been resent'
|
||||
bulk_management:
|
||||
@@ -647,6 +656,7 @@ en_IE:
|
||||
invoice_text: Add customized text at the end of invoices
|
||||
terms_and_conditions: "Terms and Conditions"
|
||||
remove_terms_and_conditions: "Remove File"
|
||||
uploaded_on: "uploaded on"
|
||||
contact:
|
||||
name: Name
|
||||
name_placeholder: eg. Amanda Plum
|
||||
@@ -755,6 +765,7 @@ en_IE:
|
||||
is displayed on your shop only when you have no active order cycles
|
||||
(ie. shop is closed).
|
||||
shopfront_category_ordering: "Shopfront Category Ordering"
|
||||
shopfront_category_ordering_note: "(top to bottom)"
|
||||
open_date: "Open Date"
|
||||
close_date: "Close Date"
|
||||
social:
|
||||
@@ -1164,6 +1175,7 @@ en_IE:
|
||||
cart: "cart"
|
||||
message_html: "You have an order for this order cycle already. Check the %{cart} to see the items you ordered before. You can also cancel items as long as the order cycle is open."
|
||||
terms_and_conditions:
|
||||
message_html: "I agree to the seller's %{terms_and_conditions_link}."
|
||||
link_text: "Terms and Conditions"
|
||||
failed: "The checkout failed. Please let us know so that we can process your order."
|
||||
shops:
|
||||
@@ -1557,6 +1569,7 @@ en_IE:
|
||||
shopping_groups_part_of: "is part of:"
|
||||
shopping_producers_of_hub: "%{hub}'s producers:"
|
||||
enterprises_next_closing: "Next order closing"
|
||||
enterprises_currently_open: "Orders are currently open"
|
||||
enterprises_ready_for: "Ready for"
|
||||
enterprises_choose: "Choose when you want your order:"
|
||||
maps_open: "Open"
|
||||
@@ -1578,6 +1591,7 @@ en_IE:
|
||||
hubs_distance: Closest to
|
||||
hubs_distance_filter: "Show me shops near %{location}"
|
||||
shop_changeable_orders_alert_html:
|
||||
one: Your order with <a href='%{path}' target='_blank'>%{shop} / %{order}</a> is open for review. You can make changes until %{oc_close}.
|
||||
few: You have <a href='%{path}' target='_blank'>%{count} orders with %{shop}</a> currently open for review. You can make changes until %{oc_close}.
|
||||
many: You have <a href='%{path}' target='_blank'>%{count} orders with %{shop}</a> currently open for review. You can make changes until %{oc_close}.
|
||||
other: You have <a href='%{path}' target='_blank'>%{count} orders with %{shop}</a> currently open for review. You can make changes until %{oc_close}.
|
||||
@@ -1725,6 +1739,7 @@ en_IE:
|
||||
orders_could_not_cancel: "Sorry, the order could not be cancelled"
|
||||
orders_cannot_remove_the_final_item: "Cannot remove the final item from an order, please cancel the order instead."
|
||||
orders_bought_items_notice:
|
||||
one: An additional item is already confirmed for this order cycle
|
||||
few: "%{count} additional items already confirmed for this order cycle"
|
||||
many: "%{count} additional items already confirmed for this order cycle"
|
||||
other: "%{count} additional items already confirmed for this order cycle"
|
||||
@@ -2071,6 +2086,7 @@ en_IE:
|
||||
spree_classification_primary_taxon_error: "Taxon %{taxon} is the primary taxon of %{product} and cannot be deleted"
|
||||
spree_order_availability_error: "Distributor or order cycle cannot supply the products in your cart"
|
||||
spree_order_populator_error: "That distributor or order cycle can't supply all the products in your cart. Please choose another."
|
||||
spree_order_cycle_error: "Please choose an order cycle for this order."
|
||||
spree_order_populator_availability_error: "That product is not available from the chosen distributor or order cycle."
|
||||
spree_distributors_error: "At least one hub must be selected"
|
||||
spree_user_enterprise_limit_error: "^%{email} is not permitted to own any more enterprises (limit is %{enterprise_limit})."
|
||||
@@ -2303,6 +2319,8 @@ en_IE:
|
||||
payment_processing_failed: "Payment could not be processed, please check the details you entered"
|
||||
payment_method_not_supported: "That payment method is unsupported. Please choose another one."
|
||||
payment_updated: "Payment Updated"
|
||||
cannot_perform_operation: "Could not update the payment"
|
||||
action_required: "Action required"
|
||||
inventory_settings: "Inventory Settings"
|
||||
tag_rules: "Tag Rules"
|
||||
shop_preferences: "Shop Preferences"
|
||||
@@ -2363,6 +2381,7 @@ en_IE:
|
||||
js:
|
||||
saving: 'Saving...'
|
||||
changes_saved: 'Changes saved.'
|
||||
authorising: "Authorising..."
|
||||
save_changes_first: Save changes first.
|
||||
all_changes_saved: All changes saved
|
||||
unsaved_changes: You have unsaved changes
|
||||
@@ -2378,6 +2397,7 @@ en_IE:
|
||||
resolve_errors: Please resolve the following errors
|
||||
more_items: "+ %{count} More"
|
||||
default_card_updated: Default Card Updated
|
||||
default_card_voids_auth: Changing your default card will remove shops' existing authorizations to charge it. You can re-authorize shops after updating the default card. Do you wish to change the default card?"
|
||||
cart:
|
||||
add_to_cart_failed: >
|
||||
There was a problem adding this product to the cart. Perhaps it has become
|
||||
@@ -2407,6 +2427,14 @@ en_IE:
|
||||
By creating rules related to a specific customer tag, you can override
|
||||
the default behaviour (whether it be to show or to hide items) for customers
|
||||
with the specified tag.
|
||||
terms_and_conditions_info:
|
||||
title: "Uploading Terms and Conditions"
|
||||
message_1: "Terms and Conditions are the contract between you, the seller, and the shopper. If you upload a file here shoppers must accept your Terms and Conditions in order to complete checkout. For the shopper this will appear as a checkbox at checkout that must be checked in order to proceed with checkout. We highly recommend you upload Terms and Conditions in alignment with national legislation."
|
||||
message_2: "Shoppers will only be required to accept Terms and Conditions once. However if you change you Terms and Conditions shoppers will again be required to accept them before they can checkout."
|
||||
terms_and_conditions_warning:
|
||||
title: "Uploading Terms and Conditions"
|
||||
message_1: "All your buyers will have to agree to them once at checkout. If you update the file, all your buyers will have to agree to them again at checkout."
|
||||
message_2: "For buyers with subscriptions, you need to email them the Terms and Conditions (or the changes to them) for now, nothing will notify them about these new Terms and Conditions."
|
||||
panels:
|
||||
save: SAVE
|
||||
saved: SAVED
|
||||
@@ -2567,6 +2595,8 @@ en_IE:
|
||||
processing: "processing"
|
||||
void: "void"
|
||||
invalid: "invalid"
|
||||
quantity_adjusted: "Insufficient stock available. Line item updated to maximum available quantity."
|
||||
quantity_unchanged: "Quantity unchanged from previous amount."
|
||||
resend_user_email_confirmation:
|
||||
resend: "Resend"
|
||||
sending: "Resend..."
|
||||
@@ -2871,6 +2901,8 @@ en_IE:
|
||||
delete: "Delete"
|
||||
cannot_set_shipping_method_without_address: "Cannot set shipping method until customer details are provided."
|
||||
no_tracking_present: "No tracking details provided."
|
||||
tracking: "Tracking"
|
||||
tracking_number: "Tracking Number"
|
||||
order_total: "Order Total"
|
||||
customer_details: "Customer Details"
|
||||
customer_search: "Customer Search"
|
||||
@@ -2904,6 +2936,8 @@ en_IE:
|
||||
server: "Server"
|
||||
test_mode: "Test Mode"
|
||||
logourl: "Logourl"
|
||||
are_you_sure_delete: "Are you sure you want to delete this record?"
|
||||
confirm_delete: "Confirm Deletion"
|
||||
configurations: "Configurations"
|
||||
general_settings: "General Settings"
|
||||
site_name: "Site Name"
|
||||
@@ -2923,6 +2957,7 @@ en_IE:
|
||||
display_currency: "Display currency"
|
||||
choose_currency: "Choose Currency"
|
||||
mail_method_settings: "Mail Method Settings"
|
||||
mail_settings_notice_html: "Some of the following settings can't be edited and are listed here just for debugging purposes. Changes can be made by updating the instance's secrets and provisioning them using <a href='https://github.com/openfoodfoundation/ofn-install'>ofn-install</a>. Reach out to the OFN global team for further details."
|
||||
general: "General"
|
||||
enable_mail_delivery: "Enable Mail Delivery"
|
||||
send_mails_as: "Send Mails As"
|
||||
@@ -3025,6 +3060,7 @@ en_IE:
|
||||
shared:
|
||||
error_messages:
|
||||
errors_prohibited_this_record_from_being_saved:
|
||||
one: "1 error prohibited this record from being saved:"
|
||||
few: "%{count} errors prohibited this record from being saved:"
|
||||
many: "%{count} errors prohibited this record from being saved:"
|
||||
other: "%{count} errors prohibited this record from being saved:"
|
||||
@@ -3036,6 +3072,7 @@ en_IE:
|
||||
payment_state: "Payment County"
|
||||
errors:
|
||||
messages:
|
||||
included_price_validation: "cannot be selected unless you have set a Default Tax Zone"
|
||||
blank: "can't be blank"
|
||||
layouts:
|
||||
admin:
|
||||
@@ -3246,6 +3283,13 @@ en_IE:
|
||||
deactivation_warning: "De-activating a payment method can make the payment method disappear from your list. Alternatively, you can hide a payment method from the checkout page by setting the option 'Display' to 'back office only'."
|
||||
providers:
|
||||
provider: "Provider"
|
||||
check: "Cash/EFT/etc. (payments for which automatic validation is not required)"
|
||||
pin: "Pin Payments"
|
||||
paypalexpress: "PayPal Express"
|
||||
stripeconnect: "Stripe"
|
||||
stripesca: "Stripe SCA"
|
||||
bogus: "Bogus"
|
||||
bogussimple: "BogusSimple"
|
||||
payments:
|
||||
source_forms:
|
||||
stripe:
|
||||
@@ -3430,6 +3474,8 @@ en_IE:
|
||||
cancel_email_for_shop:
|
||||
greeting: "Dear %{name},"
|
||||
subject: "Cancellation of Order"
|
||||
intro: "A customer has cancelled their order #%{number}."
|
||||
view_cancelled_order: "View cancelled order"
|
||||
confirm_email:
|
||||
subject: "Order Confirmation"
|
||||
invoice_email:
|
||||
@@ -3448,6 +3494,10 @@ en_IE:
|
||||
subject: "Reset password instructions"
|
||||
confirmation_instructions:
|
||||
subject: "Please confirm your OFN account"
|
||||
payment_mailer:
|
||||
authorize_payment:
|
||||
subject: "Please authorize your payment to %{distributor} on OFN"
|
||||
instructions: "Your payment of %{amount} to %{distributor} requires additional authentication. Please visit the following URL to authorize your payment:"
|
||||
shipment_mailer:
|
||||
shipped_email:
|
||||
dear_customer: "Dear Customer,"
|
||||
@@ -3484,7 +3534,23 @@ en_IE:
|
||||
paused: paused
|
||||
canceled: cancelled
|
||||
paypal:
|
||||
already_refunded: "This payment has been refunded and no further action can be taken on it."
|
||||
no_payment_via_admin_backend: "You cannot charge PayPal accounts through the admin backend at this time."
|
||||
transaction: "PayPal Transaction"
|
||||
payer_id: "Payer ID"
|
||||
transaction_id: "Transaction ID"
|
||||
token: "Token"
|
||||
refund: "Refund"
|
||||
refund_amount: "Amount"
|
||||
original_amount: "Original amount: %{amount}"
|
||||
refund_successful: "PayPal refund successful"
|
||||
refund_unsuccessful: "PayPal refund unsuccessful"
|
||||
actions:
|
||||
refund: "Refund"
|
||||
flash:
|
||||
cancel: "Don't want to use PayPal? No problems."
|
||||
connection_failed: "Could not connect to PayPal."
|
||||
generic_error: "PayPal failed. %{reasons}"
|
||||
users:
|
||||
form:
|
||||
account_settings: Account Settings
|
||||
@@ -3523,9 +3589,11 @@ en_IE:
|
||||
delete?: Delete?
|
||||
cards:
|
||||
authorised_shops: Authorised Shops
|
||||
authorised_shops_agreement: This is the list of shops which are permitted to charge your default credit card for any subscriptions (ie. repeating orders) you may have. Your card details will be kept secure and will not be shared with shop owners. You will always be notified when you are charged. By checking the box for a shop, you are agreeing to authorise that shop to send instructions to the financial institution that issued your card to take payments in accordance with the terms of any subscription you create with that shop.
|
||||
saved_cards_popover: This is the list of cards you have opted to save for later use. Your 'default' will be selected automatically when you checkout an order, and can be charged by any shops you have allowed to do so (see right).
|
||||
authorised_shops:
|
||||
shop_name: "Shop Name"
|
||||
allow_charges?: "Allow Charges to Default Card?"
|
||||
localized_number:
|
||||
invalid_format: has an invalid format. Please enter a number.
|
||||
api:
|
||||
|
||||
@@ -117,6 +117,8 @@ es:
|
||||
models:
|
||||
order_cycle:
|
||||
cloned_order_cycle_name: "COPIA DE %{order_cycle}"
|
||||
tax_rate:
|
||||
included_in_price: "Incluido en el precio"
|
||||
validators:
|
||||
date_time_string_validator:
|
||||
not_string_error: "debe ser una cadena"
|
||||
|
||||
@@ -117,6 +117,8 @@ fr:
|
||||
models:
|
||||
order_cycle:
|
||||
cloned_order_cycle_name: "Copie de %{order_cycle}"
|
||||
tax_rate:
|
||||
included_in_price: "Inclus dans le prix"
|
||||
validators:
|
||||
date_time_string_validator:
|
||||
not_string_error: "doit être une série"
|
||||
|
||||
@@ -2321,6 +2321,8 @@ fr_CA:
|
||||
payment_processing_failed: "Le paiement n'a pas pu être traité, veuillez vérifier les informations saisies"
|
||||
payment_method_not_supported: "Cette méthode de paiement n'est pas maintenue. Veuillez en sélectionner une autre."
|
||||
payment_updated: "Paiement mis à jour"
|
||||
cannot_perform_operation: "Le paiement n'a pas pu être mis à jour."
|
||||
action_required: "Une action est requise"
|
||||
inventory_settings: "Paramètres catalogue boutique"
|
||||
tag_rules: "Règles de tag"
|
||||
shop_preferences: "Préférences boutique"
|
||||
@@ -2599,6 +2601,8 @@ fr_CA:
|
||||
processing: "en traitement"
|
||||
void: "faire un avoir"
|
||||
invalid: "invalide"
|
||||
quantity_adjusted: "Le stock disponible est insuffisant. La quantité a été mise à jour en fonction du stock restant."
|
||||
quantity_unchanged: "La quantité n'a pas été modifiée."
|
||||
resend_user_email_confirmation:
|
||||
resend: "Renvoyer"
|
||||
sending: "Renvoyer"
|
||||
@@ -2960,6 +2964,7 @@ fr_CA:
|
||||
display_currency: "Afficher la devise"
|
||||
choose_currency: "Choisir la devise"
|
||||
mail_method_settings: "Paramètre méthode mail"
|
||||
mail_settings_notice_html: "Certains champs ne peuvent pas être modifiés car ils sont utilisés uniquement pour déboggage. Les modifications peuvent être réalisées par un développeur via <a href='https://github.com/openfoodfoundation/ofn-install'>ofn-install</a>."
|
||||
general: "Général"
|
||||
enable_mail_delivery: "Permettre distribution des mails"
|
||||
send_mails_as: "Envoyer les mails en tant que"
|
||||
@@ -3476,6 +3481,8 @@ fr_CA:
|
||||
cancel_email_for_shop:
|
||||
greeting: "Bonjour %{name},"
|
||||
subject: "Annulation de Commande"
|
||||
intro: "Un acheteur a annulé sa commande # %{number}."
|
||||
view_cancelled_order: "Voir la commande annulée"
|
||||
confirm_email:
|
||||
subject: "Confirmation de commande"
|
||||
invoice_email:
|
||||
@@ -3495,6 +3502,10 @@ fr_CA:
|
||||
subject: "Reprendre"
|
||||
confirmation_instructions:
|
||||
subject: "Veuillez confirmer votre compte"
|
||||
payment_mailer:
|
||||
authorize_payment:
|
||||
subject: "Veuillez autoriser votre paiement à %{distributor} on OFN."
|
||||
instructions: "Votre paiement de %{amount} to %{distributor} demande une autorisation additionnelle. Veuillez suivre ce lien afin d'autoriser votre paiement:"
|
||||
shipment_mailer:
|
||||
shipped_email:
|
||||
dear_customer: "Cher Acheteur,"
|
||||
|
||||
@@ -117,6 +117,8 @@ it:
|
||||
models:
|
||||
order_cycle:
|
||||
cloned_order_cycle_name: "COPIA DI %{order_cycle}"
|
||||
tax_rate:
|
||||
included_in_price: "Incluso nel prezzo"
|
||||
validators:
|
||||
date_time_string_validator:
|
||||
not_string_error: "deve essere una stringa"
|
||||
@@ -2955,6 +2957,7 @@ it:
|
||||
display_currency: "Visualizza valuta"
|
||||
choose_currency: "Scegli Valuta"
|
||||
mail_method_settings: "Impostazioni del metodo di posta"
|
||||
mail_settings_notice_html: "Alcune delle seguenti impostazioni non possono essere modificate e sono elencate qui solo per scopi di debug. È possibile apportare modifiche aggiornando i segreti dell'istanza ed utilizzando <a href='https://github.com/openfoodfoundation/ofn-install'>ofn-install</a>. Contatta il team globale di OFN per maggiori dettagli. "
|
||||
general: "Generale"
|
||||
enable_mail_delivery: "Abilita recapito posta"
|
||||
send_mails_as: "Invia mail come"
|
||||
@@ -3471,6 +3474,8 @@ it:
|
||||
cancel_email_for_shop:
|
||||
greeting: "Caro %{name},"
|
||||
subject: "Cancellazione dell'ordine"
|
||||
intro: "Un cliente ha cancellato la sua gentile richiesta #%{number}."
|
||||
view_cancelled_order: "Visualizza richiesta eliminata"
|
||||
confirm_email:
|
||||
subject: "Conferma Ordine"
|
||||
invoice_email:
|
||||
|
||||
@@ -118,6 +118,8 @@ ru:
|
||||
models:
|
||||
order_cycle:
|
||||
cloned_order_cycle_name: "КОПИЯ %{order_cycle}"
|
||||
tax_rate:
|
||||
included_in_price: "Включено в цену"
|
||||
validators:
|
||||
date_time_string_validator:
|
||||
not_string_error: "должно быть строкой"
|
||||
@@ -3007,6 +3009,7 @@ ru:
|
||||
display_currency: "Показывать валюту"
|
||||
choose_currency: "Выбор валюты"
|
||||
mail_method_settings: "Почтовые Настройки"
|
||||
mail_settings_notice_html: "Некоторые из следующих параметров нельзя редактировать, и они перечислены здесь только для целей отладки. Изменения можно внести, обновив секреты экземпляра и предоставив их с помощью <a href='https://github.com/openfoodfoundation/ofn-install'>ofn-install</a> . За подробностями обращайтесь к глобальной команде ОСП."
|
||||
general: "Основные"
|
||||
enable_mail_delivery: "Включить отправку почты"
|
||||
send_mails_as: "Отправлять Почту Как"
|
||||
@@ -3523,6 +3526,8 @@ ru:
|
||||
cancel_email_for_shop:
|
||||
greeting: "Уважаемый %{name}!"
|
||||
subject: "Отмена заказа"
|
||||
intro: "Покупатель отменил заказ № %{number}."
|
||||
view_cancelled_order: "Посмотреть отмененный заказ"
|
||||
confirm_email:
|
||||
subject: "Подтверждение заказа"
|
||||
invoice_email:
|
||||
|
||||
22
db/migrate/20201227122327_add_included_to_adjustments.rb
Normal file
22
db/migrate/20201227122327_add_included_to_adjustments.rb
Normal file
@@ -0,0 +1,22 @@
|
||||
class AddIncludedToAdjustments < ActiveRecord::Migration
|
||||
class Spree::TaxRate < ActiveRecord::Base; end
|
||||
|
||||
class Spree::Adjustment < ActiveRecord::Base
|
||||
belongs_to :originator, polymorphic: true
|
||||
end
|
||||
|
||||
def up
|
||||
add_column :spree_adjustments, :included, :boolean, default: false
|
||||
Spree::Adjustment.reset_column_information
|
||||
|
||||
inclusive_tax_rates = Spree::TaxRate.where(included_in_price: true)
|
||||
|
||||
# Set included boolean to true on all adjustments based on price-inclusive tax rates
|
||||
Spree::Adjustment.where(originator_type: 'Spree::TaxRate', originator_id: inclusive_tax_rates).
|
||||
update_all(included: true)
|
||||
end
|
||||
|
||||
def down
|
||||
remove_column :spree_adjustments, :included
|
||||
end
|
||||
end
|
||||
@@ -1,27 +0,0 @@
|
||||
class MigrateVariantUnitValues < ActiveRecord::Migration
|
||||
def up
|
||||
Spree::Variant.where(unit_value: [nil, Float::NAN]).find_each do |variant|
|
||||
variant.unit_value = 1
|
||||
variant.save
|
||||
end
|
||||
Spree::Variant.where(weight: [nil, Float::NAN]).find_each do |variant|
|
||||
variant.weight = 0
|
||||
variant.save
|
||||
end
|
||||
change_column_null :spree_variants, :unit_value, false, 1
|
||||
change_column_null :spree_variants, :weight, false, 0.0
|
||||
change_column_default :spree_variants, :unit_value, 1
|
||||
change_column_default :spree_variants, :weight, 0.0
|
||||
execute "ALTER TABLE spree_variants ADD CONSTRAINT check_unit_value_for_nan CHECK (unit_value <> 'NaN')"
|
||||
execute "ALTER TABLE spree_variants ADD CONSTRAINT check_weight_for_nan CHECK (weight <> 'NaN')"
|
||||
end
|
||||
|
||||
def down
|
||||
change_column_null :spree_variants, :unit_value, true
|
||||
change_column_null :spree_variants, :weight, true
|
||||
change_column_default :spree_variants, :unit_value, nil
|
||||
change_column_default :spree_variants, :weight, nil
|
||||
execute "ALTER TABLE spree_variants DROP CONSTRAINT check_unit_value_for_nan"
|
||||
execute "ALTER TABLE spree_variants DROP CONSTRAINT check_weight_for_nan"
|
||||
end
|
||||
end
|
||||
@@ -385,16 +385,17 @@ ActiveRecord::Schema.define(version: 20210203215049) do
|
||||
t.string "label", limit: 255
|
||||
t.string "source_type", limit: 255
|
||||
t.integer "adjustable_id"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.boolean "mandatory"
|
||||
t.integer "originator_id"
|
||||
t.string "originator_type", limit: 255
|
||||
t.boolean "eligible", default: true
|
||||
t.string "adjustable_type", limit: 255
|
||||
t.decimal "included_tax", precision: 10, scale: 2, default: 0.0, null: false
|
||||
t.decimal "included_tax", precision: 10, scale: 2, default: 0.0, null: false
|
||||
t.string "state", limit: 255
|
||||
t.integer "order_id"
|
||||
t.boolean "included", default: false
|
||||
end
|
||||
|
||||
add_index "spree_adjustments", ["adjustable_id"], name: "index_adjustments_on_order_id", using: :btree
|
||||
|
||||
@@ -30,11 +30,9 @@ module OpenFoodNetwork
|
||||
new.enabled?(feature_name, user)
|
||||
end
|
||||
|
||||
def self.enable(feature_name, user_emails)
|
||||
return unless user_emails.present?
|
||||
|
||||
def self.enable(feature_name, &block)
|
||||
Thread.current[:features] ||= {}
|
||||
Thread.current[:features][feature_name] = Feature.new(user_emails)
|
||||
Thread.current[:features][feature_name] = Feature.new(block)
|
||||
end
|
||||
|
||||
def initialize
|
||||
@@ -68,17 +66,17 @@ module OpenFoodNetwork
|
||||
end
|
||||
|
||||
class Feature
|
||||
def initialize(users = [])
|
||||
@users = users
|
||||
def initialize(block)
|
||||
@block = block
|
||||
end
|
||||
|
||||
def enabled?(user)
|
||||
users.include?(user.email)
|
||||
block.call(user)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :users
|
||||
attr_reader :block
|
||||
end
|
||||
|
||||
class NullFeature
|
||||
|
||||
@@ -43,7 +43,8 @@ module Spree
|
||||
order: order_object_for(target),
|
||||
label: label,
|
||||
mandatory: mandatory,
|
||||
state: state
|
||||
state: state,
|
||||
included: tax_included?(self, target)
|
||||
)
|
||||
end
|
||||
|
||||
@@ -78,6 +79,15 @@ module Spree
|
||||
|
||||
private
|
||||
|
||||
# Used for setting the #included boolean on tax adjustments. This will be removed in a
|
||||
# later step, as the responsibility for creating all adjustments related to tax will be
|
||||
# moved into the Spree::TaxRate class.
|
||||
def tax_included?(originator, target)
|
||||
originator.is_a?(Spree::TaxRate) &&
|
||||
originator.included_in_price &&
|
||||
originator.default_zone_or_zone_match?(order_object_for(target))
|
||||
end
|
||||
|
||||
def order_object_for(target)
|
||||
# Temporary method for adjustments transition.
|
||||
if target.is_a? Spree::Order
|
||||
|
||||
@@ -6,7 +6,7 @@ require 'spree/i18n/base'
|
||||
|
||||
module Spree
|
||||
extend ActionView::Helpers::TranslationHelper
|
||||
extend ActionView::Helpers::TagHelper if ENV['DEPENDENCIES_NEXT']
|
||||
extend ActionView::Helpers::TagHelper
|
||||
|
||||
class << self
|
||||
# Add spree namespace and delegate to Rails TranslationHelper for some nice
|
||||
|
||||
@@ -69,7 +69,7 @@ describe Admin::EnterprisesController, type: :controller do
|
||||
admin_user.enterprises << create(:distributor_enterprise)
|
||||
|
||||
allow(controller).to receive_messages spree_current_user: admin_user
|
||||
enterprise_params[:enterprise][:owner_id] = admin_user
|
||||
enterprise_params[:enterprise][:owner_id] = admin_user.id
|
||||
enterprise_params[:enterprise][:sells] = 'none'
|
||||
|
||||
spree_put :create, enterprise_params
|
||||
@@ -91,7 +91,7 @@ describe Admin::EnterprisesController, type: :controller do
|
||||
|
||||
it "doesn't affect the hub status for super admins" do
|
||||
allow(controller).to receive_messages spree_current_user: admin_user
|
||||
enterprise_params[:enterprise][:owner_id] = admin_user
|
||||
enterprise_params[:enterprise][:owner_id] = admin_user.id
|
||||
enterprise_params[:enterprise][:sells] = 'any'
|
||||
|
||||
spree_put :create, enterprise_params
|
||||
@@ -198,7 +198,7 @@ describe Admin::EnterprisesController, type: :controller do
|
||||
enterprise: {
|
||||
tag_rules_attributes: {
|
||||
'0' => {
|
||||
id: tag_rule,
|
||||
id: tag_rule.id,
|
||||
type: "TagRule::DiscountOrder",
|
||||
preferred_customer_tags: "some,new,tags",
|
||||
calculator_type: "Calculator::FlatPercentItemTotal",
|
||||
@@ -246,7 +246,7 @@ describe Admin::EnterprisesController, type: :controller do
|
||||
|
||||
it "allows owner to be changed" do
|
||||
allow(controller).to receive_messages spree_current_user: distributor_owner
|
||||
update_params = { id: distributor, enterprise: { owner_id: distributor_manager } }
|
||||
update_params = { id: distributor, enterprise: { owner_id: distributor_manager.id } }
|
||||
spree_post :update, update_params
|
||||
|
||||
distributor.reload
|
||||
@@ -275,7 +275,7 @@ describe Admin::EnterprisesController, type: :controller do
|
||||
|
||||
it "allows owner to be changed" do
|
||||
allow(controller).to receive_messages spree_current_user: admin_user
|
||||
update_params = { id: distributor, enterprise: { owner_id: distributor_manager } }
|
||||
update_params = { id: distributor, enterprise: { owner_id: distributor_manager.id } }
|
||||
spree_post :update, update_params
|
||||
|
||||
distributor.reload
|
||||
|
||||
@@ -26,7 +26,7 @@ module Api
|
||||
let(:products_relation) { Spree::Product.where("1=0") }
|
||||
|
||||
it "handles it gracefully" do
|
||||
get :index, exchange_id: exchange.id
|
||||
api_get :index, exchange_id: exchange.id
|
||||
expect(json_response["products"].length).to eq 0
|
||||
end
|
||||
end
|
||||
@@ -36,14 +36,14 @@ module Api
|
||||
|
||||
describe "when an exchange id param is provided" do
|
||||
it "uses exchange order_cycle, incoming and enterprise to fetch products" do
|
||||
get :index, exchange_id: exchange.id, order_cycle_id: 666, enterprise_id: 666, incoming: false
|
||||
api_get :index, exchange_id: exchange.id, order_cycle_id: 666, enterprise_id: 666, incoming: false
|
||||
expect(json_response["products"].first["supplier_name"]).to eq exchange.variants.first.product.supplier.name
|
||||
end
|
||||
end
|
||||
|
||||
describe "when an exchange id param is not provided" do
|
||||
it "uses params order_cycle, incoming and enterprise to fetch products" do
|
||||
spree_get :index, order_cycle_id: order_cycle.id, enterprise_id: exchange.sender_id, incoming: true
|
||||
api_get :index, order_cycle_id: order_cycle.id, enterprise_id: exchange.sender_id, incoming: true
|
||||
expect(json_response["products"].first["supplier_name"]).to eq exchange.variants.first.product.supplier.name
|
||||
end
|
||||
end
|
||||
@@ -59,7 +59,7 @@ module Api
|
||||
|
||||
describe "when a specific page is requested" do
|
||||
it "returns the requested page with paginated data" do
|
||||
get :index, exchange_id: exchange.id, page: 1
|
||||
api_get :index, exchange_id: exchange.id, page: 1
|
||||
|
||||
expect(json_response["products"].size).to eq 1
|
||||
expect(json_response["pagination"]["results"]).to eq 2
|
||||
@@ -69,7 +69,7 @@ module Api
|
||||
|
||||
describe "when no specific page is requested" do
|
||||
it "returns all results without paginating" do
|
||||
get :index, exchange_id: exchange.id
|
||||
api_get :index, exchange_id: exchange.id
|
||||
|
||||
expect(json_response["products"].size).to eq 2
|
||||
expect(json_response["pagination"]).to be nil
|
||||
|
||||
@@ -174,7 +174,7 @@ describe Spree::Admin::PaymentsController, type: :controller do
|
||||
let(:params) { { e: 'credit', order_id: order.number, id: payment.id } }
|
||||
|
||||
before do
|
||||
allow(request).to receive(:referer) { 'http://foo.com' }
|
||||
request.env["HTTP_REFERER"] = "http://foo.com"
|
||||
allow(Spree::Payment).to receive(:find).with(payment.id.to_s) { payment }
|
||||
end
|
||||
|
||||
@@ -210,7 +210,7 @@ describe Spree::Admin::PaymentsController, type: :controller do
|
||||
let(:params) { { e: 'refund', order_id: order.number, id: payment.id } }
|
||||
|
||||
before do
|
||||
allow(request).to receive(:referer) { 'http://foo.com' }
|
||||
request.env["HTTP_REFERER"] = "http://foo.com"
|
||||
allow(Spree::Payment).to receive(:find).with(payment.id.to_s) { payment }
|
||||
end
|
||||
|
||||
@@ -248,7 +248,7 @@ describe Spree::Admin::PaymentsController, type: :controller do
|
||||
|
||||
before do
|
||||
allow(PaymentMailer).to receive(:authorize_payment) { mail_mock }
|
||||
allow(request).to receive(:referer) { 'http://foo.com' }
|
||||
request.env["HTTP_REFERER"] = "http://foo.com"
|
||||
allow(Spree::Payment).to receive(:find).with(payment.id.to_s) { payment }
|
||||
allow(payment).to receive(:cvv_response_message).and_return("https://www.stripe.com/authorize")
|
||||
end
|
||||
@@ -266,7 +266,7 @@ describe Spree::Admin::PaymentsController, type: :controller do
|
||||
let(:params) { { e: 'unrecognized_event', order_id: order.number, id: payment.id } }
|
||||
|
||||
before do
|
||||
allow(request).to receive(:referer) { 'http://foo.com' }
|
||||
request.env["HTTP_REFERER"] = "http://foo.com"
|
||||
allow(Spree::Payment).to receive(:find).with(payment.id.to_s) { payment }
|
||||
end
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ module Spree
|
||||
context "when the amount is not changed" do
|
||||
it "updates the record" do
|
||||
expect {
|
||||
spree_put :update, id: tax_rate.id, tax_rate: { name: "Updated Rate", amount: 0.1 }
|
||||
spree_put :update, id: tax_rate.id, tax_rate: { name: "Updated Rate", amount: "0.1" }
|
||||
}.to_not change{ Spree::TaxRate.with_deleted.count }
|
||||
|
||||
expect(response).to redirect_to spree.admin_tax_rates_url
|
||||
@@ -32,7 +32,7 @@ module Spree
|
||||
context "when the amount is changed" do
|
||||
it "duplicates the record and soft-deletes the duplicate" do
|
||||
expect {
|
||||
spree_put :update, id: tax_rate.id, tax_rate: { name: "Changed Rate", amount: 0.5 }
|
||||
spree_put :update, id: tax_rate.id, tax_rate: { name: "Changed Rate", amount: "0.5" }
|
||||
}.to change{ Spree::TaxRate.with_deleted.count }.by(1)
|
||||
|
||||
expect(response).to redirect_to spree.admin_tax_rates_url
|
||||
|
||||
@@ -117,7 +117,7 @@ feature '
|
||||
end
|
||||
end
|
||||
|
||||
it "allows adding new managers" do
|
||||
xit "allows adding new managers" do
|
||||
within 'table.managers' do
|
||||
select2_select user3.email, from: 'ignored', search: true
|
||||
|
||||
@@ -129,7 +129,7 @@ feature '
|
||||
end
|
||||
end
|
||||
|
||||
it "shows changes to enterprise contact or owner" do
|
||||
xit "shows changes to enterprise contact or owner" do
|
||||
select2_select user2.email, from: 'receives_notifications_dropdown'
|
||||
within('#save-bar') { click_button 'Update' }
|
||||
navigate_to_enterprise_users
|
||||
@@ -146,7 +146,7 @@ feature '
|
||||
end
|
||||
end
|
||||
|
||||
it "can invite unregistered users to be managers" do
|
||||
xit "can invite unregistered users to be managers" do
|
||||
setup_email
|
||||
find('a.button.help-modal').click
|
||||
expect(page).to have_css '#invite-manager-modal'
|
||||
|
||||
65
spec/initializers/feature_toggles_spec.rb
Normal file
65
spec/initializers/feature_toggles_spec.rb
Normal file
@@ -0,0 +1,65 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe 'config/initializers/feature_toggles.rb' do
|
||||
# Executes the initializer's code block by reading the Ruby file. Note that `Kernel#require` would
|
||||
# prevent this from happening twice.
|
||||
subject(:execute_initializer) do
|
||||
load Rails.root.join('config/initializers/feature_toggles.rb')
|
||||
end
|
||||
|
||||
let(:user) { build(:user) }
|
||||
|
||||
around do |example|
|
||||
original = ENV['BETA_TESTERS']
|
||||
example.run
|
||||
ENV['BETA_TESTERS'] = original
|
||||
end
|
||||
|
||||
context 'when beta_testers is ["all"]' do
|
||||
before { ENV['BETA_TESTERS'] = 'all' }
|
||||
|
||||
it 'returns true' do
|
||||
execute_initializer
|
||||
|
||||
enabled = OpenFoodNetwork::FeatureToggle.enabled?(:customer_balance, user)
|
||||
expect(enabled).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when beta_testers is a list of emails' do
|
||||
let(:other_user) { build(:user) }
|
||||
|
||||
context 'and the user is in the list' do
|
||||
before { ENV['BETA_TESTERS'] = "#{user.email}, #{other_user.email}" }
|
||||
|
||||
it 'enables the feature' do
|
||||
execute_initializer
|
||||
|
||||
enabled = OpenFoodNetwork::FeatureToggle.enabled?(:customer_balance, user)
|
||||
expect(enabled).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
context 'and the user is not in the list' do
|
||||
before { ENV['BETA_TESTERS'] = "#{other_user.email}" }
|
||||
|
||||
it 'disables the feature' do
|
||||
execute_initializer
|
||||
|
||||
enabled = OpenFoodNetwork::FeatureToggle.enabled?(:customer_balance, user)
|
||||
expect(enabled).to eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
context 'and the list is empty' do
|
||||
before { ENV['BETA_TESTERS'] = '' }
|
||||
|
||||
it 'disables the feature' do
|
||||
execute_initializer
|
||||
|
||||
enabled = OpenFoodNetwork::FeatureToggle.enabled?(:customer_balance, user)
|
||||
expect(enabled).to eq(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -32,19 +32,25 @@ module OpenFoodNetwork
|
||||
context 'when specifying users' do
|
||||
let(:user) { build(:user) }
|
||||
|
||||
context 'and the feature is enabled for them' do
|
||||
before { FeatureToggle.enable(:foo, [user.email]) }
|
||||
context 'and the block does not specify arguments' do
|
||||
before do
|
||||
FeatureToggle.enable(:foo) { 'return value' }
|
||||
end
|
||||
|
||||
it 'returns true' do
|
||||
expect(FeatureToggle.enabled?(:foo, user)).to eq(true)
|
||||
it "returns the block's return value" do
|
||||
expect(FeatureToggle.enabled?(:foo, user)).to eq('return value')
|
||||
end
|
||||
end
|
||||
|
||||
context 'and the feature is disabled for them' do
|
||||
before { FeatureToggle.enable(:foo, []) }
|
||||
context 'and the block specifies arguments' do
|
||||
let(:users) { [user.email] }
|
||||
|
||||
it 'returns false' do
|
||||
expect(FeatureToggle.enabled?(:foo, user)).to eq(false)
|
||||
before do
|
||||
FeatureToggle.enable(:foo) { |user| users.include?(user.email) }
|
||||
end
|
||||
|
||||
it "returns the block's return value" do
|
||||
expect(FeatureToggle.enabled?(:foo, user)).to eq(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -460,5 +460,65 @@ module Spree
|
||||
context "extends LocalizedNumber" do
|
||||
it_behaves_like "a model using the LocalizedNumber module", [:amount]
|
||||
end
|
||||
|
||||
describe "inclusive and additional taxes" do
|
||||
let!(:zone) { create(:zone_with_member) }
|
||||
let!(:tax_category) { create(:tax_category, name: "Tax Test") }
|
||||
let(:distributor) { create(:distributor_enterprise, charges_sales_tax: true) }
|
||||
let(:order) { create(:order, distributor: distributor) }
|
||||
let(:included_in_price) { true }
|
||||
let(:tax_rate) {
|
||||
create(:tax_rate, included_in_price: included_in_price, zone: zone,
|
||||
calculator: ::Calculator::FlatRate.new(preferred_amount: 0.1))
|
||||
}
|
||||
let(:product) { create(:product, tax_category: tax_category) }
|
||||
let(:variant) { product.variants.first }
|
||||
|
||||
describe "tax adjustment creation" do
|
||||
before do
|
||||
tax_category.tax_rates << tax_rate
|
||||
allow(order).to receive(:tax_zone) { zone }
|
||||
order.line_items << create(:line_item, variant: variant, quantity: 5)
|
||||
end
|
||||
|
||||
context "with included taxes" do
|
||||
it "records the tax as included" do
|
||||
expect(order.all_adjustments.tax.count).to eq 1
|
||||
expect(order.all_adjustments.tax.first.included).to be true
|
||||
end
|
||||
end
|
||||
|
||||
context "with additional taxes" do
|
||||
let(:included_in_price) { false }
|
||||
|
||||
it "records the tax as additional" do
|
||||
expect(order.all_adjustments.tax.count).to eq 1
|
||||
expect(order.all_adjustments.tax.first.included).to be false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "inclusive and additional scopes" do
|
||||
let(:included) { true }
|
||||
let(:adjustment) {
|
||||
create(:adjustment, adjustable: order, source: order,
|
||||
originator: tax_rate, included: included)
|
||||
}
|
||||
|
||||
context "when tax is included in price" do
|
||||
it "is returned by the #included scope" do
|
||||
expect(Spree::Adjustment.inclusive).to eq [adjustment]
|
||||
end
|
||||
end
|
||||
|
||||
context "when tax is additional to the price" do
|
||||
let(:included) { false }
|
||||
|
||||
it "is returned by the #additional scope" do
|
||||
expect(Spree::Adjustment.additional).to eq [adjustment]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -50,13 +50,6 @@ describe Spree::Shipment do
|
||||
end
|
||||
end
|
||||
|
||||
context "display_total_cost" do
|
||||
it "retuns a Spree::Money" do
|
||||
allow(shipment).to receive(:total_cost) { 21.22 }
|
||||
expect(shipment.display_total_cost).to eq Spree::Money.new(21.22)
|
||||
end
|
||||
end
|
||||
|
||||
it "#item_cost" do
|
||||
shipment = Spree::Shipment.new(
|
||||
order: build_stubbed(:order_with_totals, line_items: [build_stubbed(:line_item)])
|
||||
@@ -181,12 +174,6 @@ describe Spree::Shipment do
|
||||
end
|
||||
end
|
||||
|
||||
it '#total_cost' do
|
||||
allow(shipment).to receive_messages cost: 5.0
|
||||
allow(shipment).to receive_messages item_cost: 50.0
|
||||
expect(shipment.total_cost).to eql(55.0)
|
||||
end
|
||||
|
||||
context "#update!" do
|
||||
shared_examples_for "immutable once shipped" do
|
||||
it "should remain in shipped state once shipped" do
|
||||
|
||||
@@ -101,6 +101,10 @@ RSpec.configure do |config|
|
||||
|
||||
# Retry
|
||||
config.verbose_retry = true
|
||||
# Try twice (retry once)
|
||||
config.default_retry_count = 2
|
||||
# Only retry when Selenium raises Net::ReadTimeout
|
||||
config.exceptions_to_retry = [Net::ReadTimeout]
|
||||
|
||||
# Force use of expect (over should)
|
||||
config.expect_with :rspec do |expectations|
|
||||
|
||||
Reference in New Issue
Block a user