Merge branch 'master' into remove_pin

This commit is contained in:
Pau Pérez Fabregat
2021-02-11 11:19:18 +01:00
committed by GitHub
39 changed files with 422 additions and 196 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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
&nbsp;
@@ -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'

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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

View File

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

View File

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

View File

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

View File

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