Merge branch 'master' into include-ready-for-in-producer-notification

This commit is contained in:
Cillian O'Ruanaidh
2021-01-29 11:30:11 +00:00
123 changed files with 1743 additions and 1530 deletions

View File

@@ -21,6 +21,7 @@ if ENV['DEPENDENCIES_NEXT']
gem 'responders'
gem 'sass', '<= 4.7.1'
gem 'sass-rails', '< 6.0.0'
gem 'libv8', '< 8'
else
gem 'rails', '~> 4.2'
@@ -34,6 +35,10 @@ else
gem 'db2fog'
gem 'unicorn'
group :test do
gem 'test_after_commit' # needed to test Devise callbacks
end
end
gem 'i18n'
@@ -160,7 +165,6 @@ end
group :test do
gem 'simplecov', require: false
gem 'test-prof'
gem 'test_after_commit' # needed to test Devise callbacks
gem 'webmock'
# See spec/spec_helper.rb for instructions
# gem 'perftools.rb'

View File

@@ -166,7 +166,7 @@ GEM
compass (~> 1.0.0)
sass-rails (< 5.1)
sprockets (< 4.0)
concurrent-ruby (1.1.7)
concurrent-ruby (1.1.8)
crack (0.4.5)
rexml
crass (1.0.6)
@@ -179,7 +179,7 @@ GEM
activerecord (>= 3.2.0, < 5.0)
fog (~> 1.0)
rails (>= 3.2.0, < 5.0)
ddtrace (0.44.0)
ddtrace (0.45.0)
msgpack
debugger-linecache (1.2.0)
delayed_job (4.1.9)
@@ -438,7 +438,7 @@ GEM
letter_opener (1.7.0)
launchy (~> 2.2)
libv8 (7.3.492.27.1)
loofah (2.8.0)
loofah (2.9.0)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mail (2.7.1)
@@ -456,7 +456,7 @@ GEM
money (~> 6.12)
money (6.14.0)
i18n (>= 0.6.4, <= 2)
msgpack (1.3.3)
msgpack (1.4.1)
multi_json (1.15.0)
multi_xml (0.6.0)
multipart-post (2.1.1)
@@ -598,17 +598,17 @@ GEM
rspec-retry (0.6.2)
rspec-core (> 3.3)
rspec-support (3.10.1)
rswag (2.3.1)
rswag-api (= 2.3.1)
rswag-specs (= 2.3.1)
rswag-ui (= 2.3.1)
rswag-api (2.3.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)
railties (>= 3.1, < 7.0)
rswag-specs (2.3.1)
rswag-specs (2.3.2)
activesupport (>= 3.1, < 7.0)
json-schema (~> 2.2)
railties (>= 3.1, < 7.0)
rswag-ui (2.3.1)
rswag-ui (2.3.2)
actionpack (>= 3.1, < 7.0)
railties (>= 3.1, < 7.0)
rubocop (1.8.1)
@@ -642,7 +642,7 @@ GEM
selenium-webdriver (3.142.7)
childprocess (>= 0.5, < 4.0)
rubyzip (>= 1.2.2)
shoulda-matchers (4.5.0)
shoulda-matchers (4.5.1)
activesupport (>= 4.2.0)
simplecov (0.18.5)
docile (~> 1.1)

View File

@@ -270,7 +270,7 @@ GEM
addressable (~> 2.3)
letter_opener (1.7.0)
launchy (~> 2.2)
libv8 (8.4.255.0)
libv8 (7.3.492.27.1)
loofah (2.7.0)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
@@ -502,8 +502,6 @@ GEM
test-prof (0.7.5)
test-unit (3.3.7)
power_assert
test_after_commit (1.1.0)
activerecord (>= 3.2)
thor (0.20.3)
thread_safe (0.3.6)
tilt (2.0.10)
@@ -608,6 +606,7 @@ DEPENDENCIES
kaminari (~> 1.2.1)
knapsack
letter_opener (>= 1.4.1)
libv8 (< 8)
mini_racer (= 0.2.15)
monetize (~> 1.1)
oauth2 (~> 1.4.4)
@@ -649,7 +648,6 @@ DEPENDENCIES
stripe
test-prof
test-unit (~> 3.3)
test_after_commit
timecop
uglifier (>= 1.0.3)
unicorn-rails

View File

@@ -15,8 +15,6 @@
//= require jquery.cookie
//= require jquery.jstree/jquery.jstree
//= require jquery.vAlign
//= require jquery.horizontalNav
//= require jquery.adaptivemenu
//= require angular
//= require angular-resource
//= require angular-animate

View File

@@ -8,27 +8,10 @@ Hopefully, this will evolve into a propper class.
**/
jQuery(function($) {
// Make main menu use full width
mainMenu = $('.fullwidth-menu')
if (typeof mainMenu.horizontalNav === 'function' )
mainMenu.horizontalNav({
tableDisplay: false,
responsiveDelay: 0
});
// Vertical align of checkbox fields
if (typeof $('.field.checkbox label').vAlign === 'function' )
$('.field.checkbox label').vAlign()
// We activate AdaptiveMenu only if not on webdriver
// Re-adjusting the admin menu during tests causes tests to fail.
if (!navigator.webdriver && typeof Spree !== 'undefined') {
$('.main-menu-wrapper ul').AdaptiveMenu({
text: "<a href='#'><i class='icon-chevron-down'></i> " + Spree.translations.more + "</a>",
klass: "dropdown"
});
}
// Add some tips
if (typeof $('.with-tip').powerTip === 'function' ) {
$('.with-tip').powerTip({

View File

@@ -45,7 +45,7 @@ $(document).ready(function() {
if (quantity > maxQuantity) {
quantity = maxQuantity;
save.parents('tr').find('input.line_item_quantity').val(maxQuantity);
alert('<%= I18n.t("js.admin.orders.quantity_adjusted") %>');
alert(t("js.admin.orders.quantity_adjusted"));
}
toggleItemEdit();
@@ -84,7 +84,7 @@ adjustItems = function(shipment_number, variant_id, quantity){
url += '.json';
if (new_quantity == 0) {
alert('<%= I18n.t("js.admin.orders.quantity_unchanged") %>');
alert(t("js.admin.orders.quantity_unchanged"));
} else {
$.ajax({
type: "PUT",

View File

@@ -6,28 +6,62 @@ Darkswarm.controller "ShopVariantCtrl", ($scope, $modal, Cart) ->
return if old_value[0] == null && new_value[0] == null
Cart.adjust($scope.variant.line_item)
$scope.add = (quantity) ->
$scope.variant.line_item.quantity ||= 0
$scope.$watch "variant.line_item.quantity", ->
item = $scope.variant.line_item
item.quantity += quantity
if $scope.variant.product.group_buy
if item.quantity > $scope.available()
item.quantity = $scope.available()
$scope.$watch "variant.line_item.max_quantity", ->
item = $scope.variant.line_item
if item.max_quantity > $scope.available()
item.max_quantity = $scope.available()
if $scope.variant.product.group_buy
$scope.$watch "variant.line_item.quantity", ->
item = $scope.variant.line_item
if item.quantity < 1 || item.max_quantity < item.quantity
item.max_quantity = item.quantity
$scope.$watch "variant.line_item.max_quantity", ->
item = $scope.variant.line_item
if item.max_quantity < item.quantity
item.quantity = item.max_quantity
$scope.quantity = ->
$scope.variant.line_item.quantity || 0
$scope.maxQuantity = ->
$scope.variant.line_item.max_quantity || $scope.sanitizedQuantity()
$scope.sanitizedQuantity = ->
Math.max(0, Math.min($scope.quantity(), $scope.available()))
$scope.sanitizedMaxQuantity = ->
Math.max($scope.sanitizedQuantity(), Math.min($scope.maxQuantity(), $scope.available()))
$scope.add = (quantity) ->
item = $scope.variant.line_item
item.quantity = $scope.sanitizedQuantity() + quantity
$scope.addMax = (quantity) ->
item = $scope.variant.line_item
item.max_quantity += quantity
if item.max_quantity < item.quantity
item.quantity = item.max_quantity
item.max_quantity = $scope.sanitizedMaxQuantity() + quantity
$scope.canAdd = (quantity) ->
wantedQuantity = $scope.variant.line_item.quantity + quantity
wantedQuantity = $scope.sanitizedQuantity() + quantity
$scope.quantityValid(wantedQuantity)
$scope.canAddMax = (quantity) ->
variant = $scope.variant
wantedQuantity = variant.line_item.max_quantity + quantity
wantedQuantity = $scope.sanitizedMaxQuantity() + quantity
$scope.quantityValid(wantedQuantity) && variant.line_item.quantity > 0
$scope.available = ->
variant = $scope.variant
variant.on_demand && Infinity || variant.on_hand
$scope.quantityValid = (quantity) ->
variant = $scope.variant
minimum = 0

View File

@@ -1,4 +1,4 @@
Darkswarm.directive "tabsetCtrl", (Tabsets, $location) ->
Darkswarm.directive "tabsetCtrl", (Tabsets, $location, $rootScope) ->
restrict: "C"
scope:
id: "@"
@@ -9,7 +9,13 @@ Darkswarm.directive "tabsetCtrl", (Tabsets, $location) ->
if $scope.navigate
path = $location.path()?.match(/^\/\w+$/)?[0]
$scope.selected = path[1..] if path
# Watch location change success event to operate back/forward buttons
$rootScope.$on "$locationChangeSuccess", ->
if $scope.navigate
path = $location.path()?.match(/^\/\w+$/)?[0]
Tabsets.toggle($scope.id, path[1..] if path)
this.toggle = (name) ->
Tabsets.toggle($scope.id, name)

View File

@@ -23,5 +23,5 @@ Darkswarm.factory 'Variants', ->
lineItemFor: (variant) ->
variant: variant
quantity: null
max_quantity: null
quantity: 0
max_quantity: 0

View File

@@ -9,27 +9,33 @@
{{ variant.line_item.total_price | localizeCurrency }}
.row
.columns.small-6
.columns.small-12.medium-6
.variant-bulk-buy-quantity-label
{{ "js.shopfront.bulk_buy_modal.min_quantity" | t }}
%div
%button.bulk-buy-add.variant-quantity{type: "button", ng: {click: "add(-1)", disabled: "!canAdd(-1)"}}>
-# U+FF0D Fullwidth Hyphen-Minus
%span.bulk-buy.variant-quantity>
{{ variant.line_item.quantity }}
%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
.columns.small-6
.columns.small-12.medium-6
.variant-bulk-buy-quantity-label
{{ "js.shopfront.bulk_buy_modal.max_quantity" | t }}
%div
%button.bulk-buy-add.variant-quantity{type: "button", ng: {click: "addMax(-1)", disabled: "!canAddMax(-1)"}}>
-# U+FF0D Fullwidth Hyphen-Minus
%span.bulk-buy.variant-quantity>
{{ variant.line_item.max_quantity }}
%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

@@ -1,14 +1,22 @@
.small-5.medium-3.large-3.columns.text-right{"ng-if" => "::!variant.product.group_buy"}
.small-5.medium-3.large-3.columns.variant-quantity-column.text-right{"ng-if" => "::!variant.product.group_buy"}
%button.add-variant{type: "button", ng: {if: "!variant.line_item.quantity", click: "add(1)", disabled: "!canAdd(1)"}}
{{ "js.shopfront.variant.add_to_cart" | t }}
%button.variant-quantity{type: "button", ng: {if: "variant.line_item.quantity", click: "add(-1)"}}>
-# U+FF0D Fullwidth Hyphen-Minus
%button.variant-quantity{type: "button", ng: {if: "variant.line_item.quantity", click: "add(1)", disabled: "!canAdd(1)"}}
-# U+FF0B Fullwidth Plus Sign
%br
.variant-quantity-inputs{ng: {if: "variant.line_item.quantity == 0"}}
%button.add-variant{type: "button", ng: {click: "add(1)", disabled: "!canAdd(1)"}}
{{ "js.shopfront.variant.add_to_cart" | t }}
.variant-quantity-inputs{ng: {if: "variant.line_item.quantity != 0"}}
%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"}
}>
%button.variant-quantity{type: "button", ng: {click: "add(1)", disabled: "!canAdd(1)"}}
-# U+FF0B Fullwidth Plus Sign
.variant-quantity-display{ng: {class: "{visible: variant.line_item.quantity}"}}
{{ "js.shopfront.variant.quantity_in_cart" | t:{quantity: variant.line_item.quantity || 0} }}
%input{type: :hidden,

View File

@@ -1,4 +1,4 @@
.small-5.medium-3.large-3.columns.text-right{"ng-if" => "::variant.product.group_buy"}
.small-5.medium-3.large-3.columns.variant-quantity-column.text-right{"ng-if" => "::variant.product.group_buy"}
%button.add-variant{type: "button", ng: {if: "!variant.line_item.quantity", click: "addBulk(1)", disabled: "!canAdd(1)"}}
{{ "js.shopfront.variant.add_to_cart" | t }}

View File

@@ -1,5 +1,5 @@
.variants.row
.small-4.medium-4.large-6.columns.variant-name
.small-4.medium-4.large-5.columns.variant-name
.inline{"ng-if" => "::variant.display_name"} {{ ::variant.display_name }}
.variant-unit {{ ::variant.unit_to_display }}
.small-3.medium-3.large-2.columns.variant-price
@@ -8,7 +8,7 @@
"price-breakdown-placement" => "bottom",
"price-breakdown-animation" => true}
{{ variant.price_with_fees | localizeCurrency }}
.medium-2.large-1.columns.total-price
.medium-2.large-2.columns.total-price
%span{"ng-class" => "{filled: variant.line_item.total_price}"}
{{ variant.line_item.total_price | localizeCurrency }}

View File

@@ -5,7 +5,6 @@
*
*= require normalize
*= require skeleton
*= require responsive-tables
*= require jquery.powertip
*= require jquery.ui.datepicker

View File

@@ -65,12 +65,17 @@ nav.menu {
#admin-menu {
background-color: $color-3;
ul {
display: flex;
}
li {
min-width: 90px;
flex-grow: 1;
a {
display: block;
padding: 25px 20px;
padding: 25px 5px;
color: $color-1 !important;
text-transform: uppercase;
position: relative;
@@ -160,3 +165,11 @@ nav.menu {
}
}
}
#header figure {
margin: 0.25em 0;
}
#login-nav {
line-height: 1.75em;
}

View File

@@ -66,7 +66,6 @@ div.dashboard_item {
a {
border-radius: 0px 4px 0px 0px;
margin-left: 8px;
height: 100%;
padding: 15px 2px 0px 2px;
}

View File

@@ -0,0 +1,134 @@
// Grid Calculations
// Adjust $col-gutter (space between columns, as percentage) to adjust everything else automatically
$col-gutter: 2;
$total-gutter: $col-gutter * 15;
$total-colspace: 100 - $total-gutter;
$gutter-width: $col-gutter / 100;
$col-width: ($total-colspace / 16) / 100;
$col-1: $col-width;
$col-2: ($col-width * 2) + $gutter-width;
$col-3: ($col-width * 3) + ($gutter-width * 2);
$col-4: ($col-width * 4) + ($gutter-width * 3);
$col-5: ($col-width * 5) + ($gutter-width * 4);
$col-6: ($col-width * 6) + ($gutter-width * 5);
$col-7: ($col-width * 7) + ($gutter-width * 6);
$col-8: ($col-width * 8) + ($gutter-width * 7);
$col-9: ($col-width * 9) + ($gutter-width * 8);
$col-10: ($col-width * 10) + ($gutter-width * 9);
$col-11: ($col-width * 11) + ($gutter-width * 10);
$col-12: ($col-width * 12) + ($gutter-width * 11);
$col-13: ($col-width * 13) + ($gutter-width * 12);
$col-14: ($col-width * 14) + ($gutter-width * 13);
$col-15: ($col-width * 15) + ($gutter-width * 14);
$col-16: 100;
// Grid Classes
.container {
position: relative;
width: 100%;
margin: 0 auto;
padding: 0 1.5%;
box-sizing: border-box;
display: flex;
max-width: 1400px;
&.no-gutter {
padding: 0;
}
.row {
width: 100%;
margin-bottom: 1.5em;
}
}
.container::after,
.row::after,
.clearfix::after,
.clear::after {
content: "";
display: table;
clear: both;
}
.column,
.columns {
margin-left: percentage($gutter-width);
float: left;
box-sizing: border-box;
}
.column.one,
.columns.one { width: percentage($col-1); }
.columns.two { width: percentage($col-2); }
.columns.three { width: percentage($col-3); }
.columns.four { width: percentage($col-4); }
.columns.five { width: percentage($col-5); }
.columns.six { width: percentage($col-6); }
.columns.seven { width: percentage($col-7); }
.columns.eight { width: percentage($col-8); }
.columns.nine { width: percentage($col-9); }
.columns.ten { width: percentage($col-10); }
.columns.eleven { width: percentage($col-11); }
.columns.twelve { width: percentage($col-12); }
.columns.thirteen { width: percentage($col-13); }
.columns.fourteen { width: percentage($col-14);}
.columns.fifteen { width: percentage($col-15); }
.columns.sixteen { width: 100%; }
.column.offset-by-one,
.columns.offset-by-one { margin-left: $col-2; }
.columns.offset-by-two { margin-left: $col-3; }
.columns.offset-by-three { margin-left: $col-4; }
.columns.offset-by-four { margin-left: $col-5; }
.columns.offset-by-five { margin-left: $col-6; }
.columns.offset-by-six { margin-left: $col-7; }
.columns.offset-by-seven { margin-left: $col-8; }
.columns.offset-by-eight { margin-left: $col-9; }
.columns.offset-by-nine { margin-left: $col-10; }
.columns.offset-by-ten { margin-left: $col-11; }
.columns.offset-by-eleven { margin-left: $col-12; }
.columns.offset-by-twelve { margin-left: $col-13; }
.columns.offset-by-thirteen { margin-left: $col-14; }
.columns.offset-by-fourteen { margin-left: $col-15; }
.columns.offset-by-fifteen { margin-left: 100%; }
.column.alpha,
.columns.alpha,
.columns.sixteen,
.column:first-child,
.columns:first-child {
margin-left: 0;
}

View File

@@ -185,6 +185,7 @@ fieldset {
text-transform: uppercase;
text-align: center;
padding: 8px 15px;
margin: 0 auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;

View File

@@ -6,15 +6,25 @@
.darkswarm {
// #search
@include placeholder(rgba(0, 0, 0, 0.4), #777);
.row .columns.variant-quantity-column {
padding-left: 0;
}
}
.reveal-modal.product-bulk-modal {
width: 26em;
width: 27em;
}
// Components to add variants to cart and change quantities
//
// They are not nested so that they can be used in modals.
.variant-quantity-inputs {
height: 2.5rem;
white-space: nowrap;
}
button.add-variant, button.variant-quantity {
height: 2.5rem;
border-radius: 0;
@@ -48,7 +58,7 @@ button.add-variant, button.variant-quantity {
}
button.add-variant {
min-width: 6rem;
min-width: 7rem;
padding: 0 1em;
&[disabled] {
@@ -59,7 +69,7 @@ button.add-variant {
}
button.variant-quantity {
width: 3rem;
width: 2.25rem;
&:nth-of-type(1):not(.bulk-buy):not(.bulk-buy-add) {
border-right: .1em solid $orange-400;
@@ -71,7 +81,7 @@ button.variant-quantity {
font-size: 0.875em;
margin-top: 0.25em;
text-align: center;
width: 6rem;
width: 7rem;
visibility: hidden;
&.visible {
@@ -83,20 +93,28 @@ button.bulk-buy.variant-quantity {
background-color: transparent;
border: .1em solid $grey-200;
color: inherit;
width: 3.5rem;
}
button.bulk-buy-add.variant-quantity {
width: 2.5rem;
}
span.bulk-buy.variant-quantity {
[type="number"].variant-quantity {
border: .1em solid $grey-200;
height: 2.5rem;
display: inline-block;
min-width: 3em;
padding: .5em;
width: 2.5rem;
padding: 0;
text-align: center;
vertical-align: top;
appearance: none;
-webkit-appearance: none;
-moz-appearance: textfield;
&.bulk-buy {
width: 5rem;
}
}
.variant-bulk-buy-price-summary {

View File

@@ -3,9 +3,9 @@
// See https://github.com/zurb/foundation/issues/3855#issuecomment-30372252
@import "variables";
@import "components/global";
@import "components/buttons";
@import "components/panels";
@import "foundation/components/global";
@import "foundation/components/buttons";
@import "foundation/components/panels";
#sidebar {
margin-top: 1.875em;

View File

@@ -135,7 +135,6 @@ class ApplicationController < ActionController::Base
def check_order_cycle_expiry
if current_order_cycle.andand.closed?
session[:expired_order_cycle_id] = current_order_cycle.id
current_order.empty!
current_order.set_order_cycle! nil
flash[:info] = I18n.t('order_cycle_closed')

View File

@@ -142,7 +142,7 @@ class CheckoutController < ::BaseController
def handle_redirect_from_stripe
if OrderWorkflow.new(@order).next && order_complete?
checkout_succeeded
redirect_to(spree.order_path(@order)) && return
redirect_to(order_path(@order)) && return
else
checkout_failed
end
@@ -202,10 +202,10 @@ class CheckoutController < ::BaseController
def update_succeeded_response
respond_to do |format|
format.html do
respond_with(@order, location: spree.order_path(@order))
respond_with(@order, location: order_path(@order))
end
format.json do
render json: { path: spree.order_path(@order) }, status: :ok
render json: { path: order_path(@order) }, status: :ok
end
end
end

View File

@@ -153,7 +153,7 @@ module Spree
def authorize_stripe_sca_payment
return unless @payment.payment_method.class == Spree::Gateway::StripeSCA
@payment.authorize!(spree.order_path(@payment.order, only_path: false))
@payment.authorize!(main_app.order_path(@payment.order, only_path: false))
raise Spree::Core::GatewayError, I18n.t('authorization_failure') unless @payment.pending?

View File

@@ -85,7 +85,7 @@ module Spree
@order.next_transition.run_callbacks if @order.cart?
redirect_to checkout_state_path(@order.checkout_steps.first)
elsif @order.complete?
redirect_to spree.order_path(@order)
redirect_to order_path(@order)
else
redirect_to main_app.cart_path
end
@@ -132,17 +132,6 @@ module Spree
end
end
def clear
@order = current_order(true)
@order.empty!
@order.set_order_cycle! nil
redirect_to main_app.enterprise_path(@order.distributor.id)
end
def order_cycle_expired
@order_cycle = OrderCycle.find session[:expired_order_cycle_id]
end
def cancel
@order = Spree::Order.find_by!(number: params[:id])
authorize! :cancel, @order
@@ -152,7 +141,7 @@ module Spree
else
flash[:error] = I18n.t(:orders_could_not_cancel)
end
redirect_to request.referer || spree.order_path(@order)
redirect_to request.referer || order_path(@order)
end
private
@@ -216,7 +205,7 @@ module Spree
if items.empty?
flash[:error] = I18n.t(:orders_cannot_remove_the_final_item)
redirect_to spree.order_path(order_to_update)
redirect_to order_path(order_to_update)
end
end

View File

@@ -234,7 +234,7 @@ module Spree
end
def completion_route(order)
spree.order_path(order, token: order.token)
main_app.order_path(order, token: order.token)
end
def address_required?

View File

@@ -12,9 +12,13 @@ module Spree
before_action :set_locale
before_action :enable_embedded_shopfront
# Ignores invoice orders, only order where state: 'complete'
def show
@orders = @user.orders.where(state: 'complete').order('completed_at desc')
@orders = orders_collection
customers = spree_current_user.customers
@shops = Enterprise
.where(id: @orders.pluck(:distributor_id).uniq | customers.pluck(:enterprise_id))
@unconfirmed_email = spree_current_user.unconfirmed_email
end
@@ -54,6 +58,14 @@ module Spree
private
def orders_collection
if OpenFoodNetwork::FeatureToggle.enabled?(:customer_balance, spree_current_user)
CompleteOrdersWithBalance.new(@user).query
else
@user.orders.where(state: 'complete').order('completed_at desc')
end
end
def load_object
@user ||= spree_current_user
if @user

View File

@@ -28,7 +28,7 @@ module Spree
end
def changeable_orders_link_path
changeable_orders.one? ? spree.order_path(changeable_orders.first) : spree.account_path
changeable_orders.one? ? order_path(changeable_orders.first) : spree.account_path
end
def shop_changeable_orders_alert_html

View File

@@ -92,7 +92,6 @@ module Spree
preference :s3_host_alias, :string
# Default mail headers settings
preference :enable_mail_delivery, :boolean, default: false
preference :mails_from, :string, default: 'ofn@example.com'
preference :mail_bcc, :string, default: 'ofn@example.com'
preference :intercept_email, :string, default: nil

View File

@@ -130,6 +130,11 @@ module Spree
where("state != ?", state)
}
# All the states an order can be in after completing the checkout
FINALIZED_STATES = %w(complete canceled resumed awaiting_return returned).freeze
scope :finalized, -> { where(state: FINALIZED_STATES) }
def self.by_number(number)
where(number: number)
end
@@ -723,15 +728,7 @@ module Spree
end
def total_tax
(adjustments.to_a + price_adjustments.to_a).sum(&:included_tax)
end
def price_adjustments
adjustments = []
line_items.each { |line_item| adjustments.concat line_item.adjustments }
adjustments
(adjustments.to_a + line_item_adjustments.to_a).sum(&:included_tax)
end
def price_adjustment_totals

View File

@@ -5,7 +5,6 @@ module Spree
module Processing
def process!
return unless validate!
return if cvv_response_message.present?
if payment_method.auto_capture?
purchase!
@@ -16,7 +15,6 @@ module Spree
def process_offline!
return unless validate!
return if cvv_response_message.present?
if payment_method.auto_capture?
charge_offline!

View File

@@ -83,8 +83,8 @@ module Spree
order.adjustments(:reload)
order.line_items(:reload)
# TaxRate adjustments (order.adjustments.tax)
# and price adjustments (tax included on line items) consist of 100% tax
(order.adjustments.tax + order.price_adjustments).each do |adjustment|
# and line item adjustments (tax included on line items) consist of 100% tax
(order.adjustments.tax + order.line_item_adjustments.reload).each do |adjustment|
adjustment.set_absolute_included_tax! adjustment.amount
end
end

View File

@@ -0,0 +1,21 @@
# frozen_string_literal: true
# Fetches complete orders of the specified user including their balance as a computed column
class CompleteOrdersWithBalance
def initialize(user)
@user = user
end
def query
OutstandingBalance.new(sorted_finalized_orders).query
end
private
def sorted_finalized_orders
@user.orders
.finalized
.select('spree_orders.*')
.order(completed_at: :desc)
end
end

View File

@@ -0,0 +1,39 @@
# frozen_string_literal: true
# Fetches the customers of the specified enterprise including the aggregated balance across the
# customer's orders. That is, we get the total balance for each customer with this enterprise.
class CustomersWithBalance
def initialize(enterprise)
@enterprise = enterprise
end
def query
Customer.of(enterprise).
joins(left_join_complete_orders).
group("customers.id").
select("customers.*").
select(outstanding_balance_sum)
end
private
attr_reader :enterprise
def outstanding_balance_sum
"SUM(#{OutstandingBalance.new.statement}) AS balance_value"
end
# The resulting orders are in states that belong after the checkout. Only these can be considered
# for a customer's balance.
def left_join_complete_orders
<<-SQL.strip_heredoc
LEFT JOIN spree_orders ON spree_orders.customer_id = customers.id
AND #{finalized_states.to_sql}
SQL
end
def finalized_states
states = Spree::Order::FINALIZED_STATES.map { |state| Arel::Nodes.build_quoted(state) }
Arel::Nodes::In.new(Spree::Order.arel_table[:state], states)
end
end

View File

@@ -0,0 +1,44 @@
# frozen_string_literal: true
# Encapsulates the SQL statement that computes the balance of an order as a new column in the result
# set. This can then be reused chaining it with the ActiveRecord::Relation objects you pass in the
# constructor.
#
# Alternatively, you can get the SQL by calling #statement, which is suitable for more complex
# cases.
#
# See CompleteOrdersWithBalance or CustomersWithBalance as examples.
class OutstandingBalance
# All the states of a finished order but that shouldn't count towards the balance (the customer
# didn't get the order for whatever reason). Note it does not include complete
FINALIZED_NON_SUCCESSFUL_STATES = %w(canceled returned).freeze
# The relation must be an ActiveRecord::Relation object with `spree_orders` in the SQL statement
# FROM for #statement to work.
def initialize(relation = nil)
@relation = relation
end
def query
relation.select("#{statement} AS balance_value")
end
# Arel doesn't support CASE statements until v7.1.0 so we'll have to wait with SQL literals
# a little longer. See https://github.com/rails/arel/pull/400 for details.
def statement
<<-SQL.strip_heredoc
CASE WHEN state IN #{non_fulfilled_states_group.to_sql} THEN payment_total
WHEN state IS NOT NULL THEN payment_total - total
ELSE 0 END
SQL
end
private
attr_reader :relation
def non_fulfilled_states_group
states = FINALIZED_NON_SUCCESSFUL_STATES.map { |state| Arel::Nodes.build_quoted(state) }
Arel::Nodes::Grouping.new(states)
end
end

View File

@@ -7,6 +7,14 @@ module Api
has_many :payments, serializer: Api::PaymentSerializer
def outstanding_balance
if OpenFoodNetwork::FeatureToggle.enabled?(:customer_balance, object.user)
-object.balance_value
else
object.outstanding_balance
end
end
def payments
object.payments.joins(:payment_method).completed
end
@@ -42,13 +50,13 @@ module Api
end
def path
Spree::Core::Engine.routes.url_helpers.order_path(object)
order_path(object)
end
def cancel_path
return nil unless object.changes_allowed?
Spree::Core::Engine.routes.url_helpers.cancel_order_path(object)
cancel_order_path(object)
end
def changes_allowed

View File

@@ -1,61 +0,0 @@
# frozen_string_literal: true
class CustomersWithBalance
def initialize(enterprise)
@enterprise = enterprise
end
def query
Customer.of(enterprise).
joins(left_join_complete_orders).
group("customers.id").
select("customers.*").
select(outstanding_balance)
end
private
attr_reader :enterprise
# Arel doesn't support CASE statements until v7.1.0 so we'll have to wait with SQL literals
# a little longer. See https://github.com/rails/arel/pull/400 for details.
def outstanding_balance
<<-SQL.strip_heredoc
SUM(
CASE WHEN state IN #{non_fulfilled_states_group.to_sql} THEN payment_total
WHEN state IS NOT NULL THEN payment_total - total
ELSE 0 END
) AS balance_value
SQL
end
# The resulting orders are in states that belong after the checkout. Only these can be considered
# for a customer's balance.
def left_join_complete_orders
<<-SQL.strip_heredoc
LEFT JOIN spree_orders ON spree_orders.customer_id = customers.id
AND #{complete_orders.to_sql}
SQL
end
def complete_orders
states_group = prior_to_completion_states.map { |state| Arel::Nodes.build_quoted(state) }
Arel::Nodes::NotIn.new(Spree::Order.arel_table[:state], states_group)
end
def non_fulfilled_states_group
states_group = non_fulfilled_states.map { |state| Arel::Nodes.build_quoted(state) }
Arel::Nodes::Grouping.new(states_group)
end
# All the states an order can be in before completing the checkout
def prior_to_completion_states
%w(cart address delivery payment)
end
# All the states of a complete order but that shouldn't count towards the balance. Those that the
# customer won't enjoy.
def non_fulfilled_states
%w(canceled returned)
end
end

View File

@@ -8,9 +8,9 @@
.calculator-settings
= f.fields_for :calculator do |calculator_form|
- preference_fields(enterprise_fee.calculator, calculator_form).each do |field|
.field.alpha.one.columns
%span.field
= field[:label]
.field.omega.two.columns
%p.field
= field[:field]
= calculator_form_string

View File

@@ -6,7 +6,7 @@
.four.columns.alpha
= render 'admin/shared/side_menu'
.one.column &nbsp;
.eleven.columns.omega.fullwidth_inputs
.eight.columns.omega.fullwidth_inputs
= render 'form_primary_details', f: f
= render 'form_users', f: f
= render 'form_about', f: f

View File

@@ -31,8 +31,7 @@
\/
= af.label :country_id, t(:country)
%span.required *
%div{ "ng-controller" => "countryCtrl" }
.four.columns
%input.ofn-select2.fullwidth#enterprise_address_attributes_state_id{ name: 'enterprise[address_attributes][state_id]', type: 'number', data: 'countriesById[Enterprise.address.country_id].states', placeholder: t('admin.choose'), ng: { model: 'Enterprise.address.state_id' } }
.four.columns.omega
%input.ofn-select2.fullwidth#enterprise_address_attributes_country_id{ name: 'enterprise[address_attributes][country_id]', type: 'number', data: 'countries', placeholder: t('admin.choose'), ng: { model: 'Enterprise.address.country_id' } }
.four.columns{ "ng-controller" => "countryCtrl" }
%input.ofn-select2.fullwidth#enterprise_address_attributes_state_id{ name: 'enterprise[address_attributes][state_id]', type: 'number', data: 'countriesById[Enterprise.address.country_id].states', placeholder: t('admin.choose'), ng: { model: 'Enterprise.address.state_id' } }
.four.columns.omega{ "ng-controller" => "countryCtrl" }
%input.ofn-select2.fullwidth#enterprise_address_attributes_country_id{ name: 'enterprise[address_attributes][country_id]', type: 'number', data: 'countries', placeholder: t('admin.choose'), ng: { model: 'Enterprise.address.country_id' } }

View File

@@ -16,11 +16,11 @@
%td= link_to t(:edit), edit_admin_payment_method_path(payment_method)
%br
.row
.six.columns.alpha
.eight.columns
%a.button{ href: "#{admin_payment_methods_path}"}
= t('.manage')
%i.icon-arrow-right
.five.columns.omega.text-right
.eight.columns.text-right
%a.button{ href: "#{new_admin_payment_method_path}"}
= t('.create_button')
%i.icon-plus

View File

@@ -1,19 +1,17 @@
.row
.alpha.eleven.columns
.three.columns.alpha
= f.label :name, t('.name')
%span.required *
.eight.columns.omega
= f.text_field :name, { placeholder: t('.name_placeholder') }
.three.columns.alpha
= f.label :name, t('.name')
%span.required *
.eight.columns.omega
= f.text_field :name, { placeholder: t('.name_placeholder') }
- if @groups.present?
.row
.alpha.eleven.columns
.three.columns.alpha
= f.label :group_ids, t('.groups')
%div{'ofn-with-tip' => t('.groups_tip')}
%a= t('admin.whats_this')
.eight.columns.omega
= f.collection_select :group_ids, @groups, :id, :name, {}, class: "select2 fullwidth", multiple: true, placeholder: t('.groups_placeholder')
.three.columns.alpha
= f.label :group_ids, t('.groups')
%div{'ofn-with-tip' => t('.groups_tip')}
%a= t('admin.whats_this')
.eight.columns.omega
= f.collection_select :group_ids, @groups, :id, :name, {}, class: "select2 fullwidth", multiple: true, placeholder: t('.groups_placeholder')
.row
.three.columns.alpha
@@ -25,20 +23,19 @@
= f.label :is_primary_producer, t('.producer')
- if spree_current_user.admin?
.row
.alpha.eleven.columns
.three.columns.alpha
= f.label :sells, t('.sells')
%div{'ofn-with-tip' => t('.sells_tip')}
%a= t('admin.whats_this')
.two.columns
= f.radio_button :sells, "none", 'ng-model' => 'Enterprise.sells'
= f.label :sells, t('.none'), value: "none"
.two.columns
= f.radio_button :sells, "own", 'ng-model' => 'Enterprise.sells'
= f.label :sells, t('.own'), value: "own"
.four.columns.omega
= f.radio_button :sells, "any", 'ng-model' => 'Enterprise.sells'
= f.label :sells, t('.any'), value: "any"
.three.columns.alpha
= f.label :sells, t('.sells')
%div{'ofn-with-tip' => t('.sells_tip')}
%a= t('admin.whats_this')
.two.columns
= f.radio_button :sells, "none", 'ng-model' => 'Enterprise.sells'
= f.label :sells, t('.none'), value: "none"
.two.columns
= f.radio_button :sells, "own", 'ng-model' => 'Enterprise.sells'
= f.label :sells, t('.own'), value: "own"
.four.columns.omega
= f.radio_button :sells, "any", 'ng-model' => 'Enterprise.sells'
= f.label :sells, t('.any'), value: "any"
.row
.three.columns.alpha
%label= t('.visible_in_search')
@@ -56,7 +53,7 @@
= f.label :permalink, t('.permalink')
%div{'ofn-with-tip' => t('.permalink_tip', link: main_app.root_url)}
%a= t('admin.whats_this')
.six.columns
.eight.columns
= f.text_field :permalink, { 'ng-model' => "Enterprise.permalink", placeholder: "eg. your-shop-name", 'ng-model-options' => "{ updateOn: 'default blur', debounce: {'default': 300, 'blur': 0} }" }
.two.columns.omega
%div{ng: {show: "checking", cloak: true}, style: "width: 30px; height: 30px;"}

View File

@@ -15,11 +15,11 @@
%td= link_to t(:edit), edit_admin_shipping_method_path(shipping_method)
%br
.row
.six.columns.alpha
.eight.columns
%a.button{ href: "#{admin_shipping_methods_path}"}
= t('.manage')
%i.icon-arrow-right
.five.columns.omega.text-right
.eight.columns.text-right
%a.button{ href: "#{new_admin_shipping_method_path}"}
= t('.create_button')
%i.icon-plus

View File

@@ -1,104 +1,95 @@
.row
.alpha.eleven.columns
.three.columns.alpha
= f.label "enterprise_preferred_shopfront_message", t('.shopfront_message')
.eight.columns.omega
%text-angular{'ng-model' => 'Enterprise.preferred_shopfront_message', 'id' => 'enterprise_preferred_shopfront_message', 'name' => 'enterprise[preferred_shopfront_message]', 'class' => 'text-angular textangular-strip', 'ta-paste' => "stripFormatting($html)", "textangular-links-target-blank" => true,
'ta-toolbar' => "[['h1','h2','h3','h4','p'],['bold','italics','underline','clear'],['insertLink']]",
'placeholder' => t('.shopfront_message_placeholder')}
.three.columns.alpha
= f.label "enterprise_preferred_shopfront_message", t('.shopfront_message')
.eight.columns.omega
%text-angular{'ng-model' => 'Enterprise.preferred_shopfront_message', 'id' => 'enterprise_preferred_shopfront_message', 'name' => 'enterprise[preferred_shopfront_message]', 'class' => 'text-angular textangular-strip', 'ta-paste' => "stripFormatting($html)", "textangular-links-target-blank" => true,
'ta-toolbar' => "[['h1','h2','h3','h4','p'],['bold','italics','underline','clear'],['insertLink']]",
'placeholder' => t('.shopfront_message_placeholder')}
.row
.alpha.eleven.columns
.three.columns.alpha
= f.label "enterprise_preferred_shopfront_closed_message", t('.shopfront_closed_message')
.eight.columns.omega
%text-angular{'ng-model' => 'Enterprise.preferred_shopfront_closed_message', 'id' => 'enterprise_preferred_shopfront_closed_message', 'name' => 'enterprise[preferred_shopfront_closed_message]', 'class' => 'text-angular textangular-strip', 'ta-paste' => "stripFormatting($html)", "textangular-links-target-blank" => true,
'ta-toolbar' => "[['h1','h2','h3','h4','p'],['bold','italics','underline','clear'],['insertLink']]",
'placeholder' => t('.shopfront_closed_message_placeholder')}
.three.columns.alpha
= f.label "enterprise_preferred_shopfront_closed_message", t('.shopfront_closed_message')
.eight.columns.omega
%text-angular{'ng-model' => 'Enterprise.preferred_shopfront_closed_message', 'id' => 'enterprise_preferred_shopfront_closed_message', 'name' => 'enterprise[preferred_shopfront_closed_message]', 'class' => 'text-angular textangular-strip', 'ta-paste' => "stripFormatting($html)", "textangular-links-target-blank" => true,
'ta-toolbar' => "[['h1','h2','h3','h4','p'],['bold','italics','underline','clear'],['insertLink']]",
'placeholder' => t('.shopfront_closed_message_placeholder')}
.row
.alpha.eleven.columns
.three.columns.alpha
= f.label "enterprise_preferred_shopfront_taxon_order", t('.shopfront_category_ordering')
%br
= t('.shopfront_category_ordering_note')
.eight.columns.omega
%textarea.fullwidth{ id: 'enterprise_preferred_shopfront_taxon_order', name: 'enterprise[preferred_shopfront_taxon_order]', rows: 6, 'ng-model' => 'Enterprise.preferred_shopfront_taxon_order', 'ofn-taxon-autocomplete' => '', 'multiple-selection' => 'true', placeholder: 'Category' }
.three.columns.alpha
= f.label "enterprise_preferred_shopfront_taxon_order", t('.shopfront_category_ordering')
%br
= t('.shopfront_category_ordering_note')
.eight.columns.omega
%textarea.fullwidth{ id: 'enterprise_preferred_shopfront_taxon_order', name: 'enterprise[preferred_shopfront_taxon_order]', rows: 6, 'ng-model' => 'Enterprise.preferred_shopfront_taxon_order', 'ofn-taxon-autocomplete' => '', 'multiple-selection' => 'true', placeholder: 'Category' }
.row
.alpha.eleven.columns
.three.columns.alpha
= f.label "enterprise_preferred_shopfront_order_cycle_order", t(:sort_order_cycles_on_shopfront_by)
.three.columns
= radio_button :enterprise, :preferred_shopfront_order_cycle_order, :orders_open_at, { 'ng-model' => 'Enterprise.preferred_shopfront_order_cycle_order' }
= label :enterprise, :preferred_shopfront_order_cycle_order_orders_open_at, t('.open_date')
.five.columns.omega
= radio_button :enterprise, :preferred_shopfront_order_cycle_order, :orders_close_at, { 'ng-model' => 'Enterprise.preferred_shopfront_order_cycle_order' }
= label :enterprise, :preferred_shopfront_order_cycle_order_orders_close_at, t('.close_date')
.three.columns.alpha
= f.label "enterprise_preferred_shopfront_order_cycle_order", t(:sort_order_cycles_on_shopfront_by)
.three.columns
= radio_button :enterprise, :preferred_shopfront_order_cycle_order, :orders_open_at, { 'ng-model' => 'Enterprise.preferred_shopfront_order_cycle_order' }
= label :enterprise, :preferred_shopfront_order_cycle_order_orders_open_at, t('.open_date')
.five.columns.omega
= radio_button :enterprise, :preferred_shopfront_order_cycle_order, :orders_close_at, { 'ng-model' => 'Enterprise.preferred_shopfront_order_cycle_order' }
= label :enterprise, :preferred_shopfront_order_cycle_order_orders_close_at, t('.close_date')
.row
.alpha.eleven.columns
.three.columns.alpha
%label= t '.shopfront_requires_login'
%div{'ofn-with-tip' => t('.shopfront_requires_login_tip')}
%a= t 'admin.whats_this'
.three.columns
= f.radio_button :require_login, false, "ng-model" => "Enterprise.require_login", "ng-value" => "false"
= f.label :require_login, t('.shopfront_requires_login_false'), value: :false
.five.columns.omega
= f.radio_button :require_login, true, "ng-model" => "Enterprise.require_login", "ng-value" => "true"
= f.label :require_login, t('.shopfront_requires_login_true'), value: :true
.three.columns.alpha
%label= t '.shopfront_requires_login'
%div{'ofn-with-tip' => t('.shopfront_requires_login_tip')}
%a= t 'admin.whats_this'
.three.columns
= f.radio_button :require_login, false, "ng-model" => "Enterprise.require_login", "ng-value" => "false"
= f.label :require_login, t('.shopfront_requires_login_false'), value: :false
.five.columns.omega
= f.radio_button :require_login, true, "ng-model" => "Enterprise.require_login", "ng-value" => "true"
= f.label :require_login, t('.shopfront_requires_login_true'), value: :true
.row{ng: {if: "!Enterprise.require_login"}}
.alpha.eleven.columns
.three.columns.alpha
%label= t '.allow_guest_orders'
%div{'ofn-with-tip' => t('.allow_guest_orders_tip')}
%a= t 'admin.whats_this'
.eight.columns.omega
.row
.three.columns.alpha
= f.radio_button :allow_guest_orders, true, "ng-model" => "Enterprise.allow_guest_orders", "ng-value" => "true"
= f.label :allow_guest_orders, t('.allow_guest_orders_true'), value: :true
.five.columns.omega
= f.radio_button :allow_guest_orders, false, "ng-model" => "Enterprise.allow_guest_orders", "ng-value" => "false"
= f.label :allow_guest_orders, t('.allow_guest_orders_false'), value: :false
.row.warning{ng: {show: 'Enterprise.allow_guest_orders && Enterprise.allow_order_changes'}}
.eight.columns.alpha.omega
%i.icon-warning-sign
= t '.recommend_require_login'
.three.columns.alpha
%label= t '.allow_guest_orders'
%div{'ofn-with-tip' => t('.allow_guest_orders_tip')}
%a= t 'admin.whats_this'
.eight.columns.omega
.row
.three.columns.alpha
= f.radio_button :allow_guest_orders, true, "ng-model" => "Enterprise.allow_guest_orders", "ng-value" => "true"
= f.label :allow_guest_orders, t('.allow_guest_orders_true'), value: :true
.five.columns.omega
= f.radio_button :allow_guest_orders, false, "ng-model" => "Enterprise.allow_guest_orders", "ng-value" => "false"
= f.label :allow_guest_orders, t('.allow_guest_orders_false'), value: :false
.row.warning{ng: {show: 'Enterprise.allow_guest_orders && Enterprise.allow_order_changes'}}
.eight.columns.alpha.omega
%i.icon-warning-sign
= t '.recommend_require_login'
.row
.alpha.eleven.columns
.three.columns.alpha
%label= t '.allow_order_changes'
%div{'ofn-with-tip' => t('.allow_order_changes_tip')}
%a= t 'admin.whats_this'
.three.columns
= f.radio_button :allow_order_changes, false, "ng-model" => "Enterprise.allow_order_changes", "ng-value" => "false"
= f.label :allow_order_changes, t('.allow_order_changes_false'), value: :false
.five.columns.omega
= f.radio_button :allow_order_changes, true, "ng-model" => "Enterprise.allow_order_changes", "ng-value" => "true"
= f.label :allow_order_changes, t('.allow_order_changes_true'), value: :true
.three.columns.alpha
%label= t '.allow_order_changes'
%div{'ofn-with-tip' => t('.allow_order_changes_tip')}
%a= t 'admin.whats_this'
.three.columns
= f.radio_button :allow_order_changes, false, "ng-model" => "Enterprise.allow_order_changes", "ng-value" => "false"
= f.label :allow_order_changes, t('.allow_order_changes_false'), value: :false
.five.columns.omega
= f.radio_button :allow_order_changes, true, "ng-model" => "Enterprise.allow_order_changes", "ng-value" => "true"
= f.label :allow_order_changes, t('.allow_order_changes_true'), value: :true
.row
.alpha.eleven.columns
.three.columns.alpha
%label= t '.enable_subscriptions'
%div{'ofn-with-tip' => t('.enable_subscriptions_tip')}
%a= t 'admin.whats_this'
.three.columns
= f.radio_button :enable_subscriptions, true
= f.label :enable_subscriptions, t('.enable_subscriptions_true'), value: :true
.five.columns.omega
= f.radio_button :enable_subscriptions, false
= f.label :enable_subscriptions, t('.enable_subscriptions_false'), value: :false
.three.columns.alpha
%label= t '.enable_subscriptions'
%div{'ofn-with-tip' => t('.enable_subscriptions_tip')}
%a= t 'admin.whats_this'
.three.columns
= f.radio_button :enable_subscriptions, true
= f.label :enable_subscriptions, t('.enable_subscriptions_true'), value: :true
.five.columns.omega
= f.radio_button :enable_subscriptions, false
= f.label :enable_subscriptions, t('.enable_subscriptions_false'), value: :false
.row
.alpha.eleven.columns
.three.columns.alpha
%label= t '.customer_names_in_reports'
%div{'ofn-with-tip' => t('.customer_names_tip')}
%a= t 'admin.whats_this'
.three.columns
= radio_button :enterprise, :preferred_show_customer_names_to_suppliers, true
= label :enterprise_preferred_show_customer_names_to_suppliers, t('.customer_names_true'), value: :true
.five.columns.omega
= radio_button :enterprise, :preferred_show_customer_names_to_suppliers, false
= label :enterprise_preferred_show_customer_names_to_suppliers, t('.customer_names_false'), value: :false
.three.columns.alpha
%label= t '.customer_names_in_reports'
%div{'ofn-with-tip' => t('.customer_names_tip')}
%a= t 'admin.whats_this'
.three.columns
= radio_button :enterprise, :preferred_show_customer_names_to_suppliers, true
= label :enterprise_preferred_show_customer_names_to_suppliers, t('.customer_names_true'), value: :true
.five.columns.omega
= radio_button :enterprise, :preferred_show_customer_names_to_suppliers, false
= label :enterprise_preferred_show_customer_names_to_suppliers, t('.customer_names_false'), value: :false

View File

@@ -5,7 +5,8 @@
= "admin.enterprises"
- content_for :page_actions do
= render 'admin/shared/user_guide_link'
%li#user_guide_link
= render 'admin/shared/user_guide_link'
%li#new_product_link
- button_href = spree_current_user.can_own_more_enterprises? ? main_app.new_admin_enterprise_path : '#'

View File

@@ -2,14 +2,14 @@
.alpha.two.columns
= f.label :name, t('.name')
%span.required *
.six.columns.omega
.six.columns.omega.fullwidth_inputs
- if viewing_as_coordinator_of?(@order_cycle)
= f.text_field :name, 'ng-model' => 'order_cycle.name', 'required' => true, 'ng-disabled' => '!loaded()'
- else
{{ order_cycle.name }}
.two.columns
= f.label :orders_open_at, t('.orders_open')
.omega.six.columns
.omega.six.columns.fullwidth_inputs
- if viewing_as_coordinator_of?(@order_cycle)
= f.text_field :orders_open_at, 'datetimepicker' => 'order_cycle.orders_open_at', 'ng-model' => 'order_cycle.orders_open_at', 'ng-disabled' => '!loaded()', 'change-warning' => 'order_cycle'
- else
@@ -18,11 +18,11 @@
.row
.alpha.two.columns
= f.label :coordinator, t('.coordinator')
.six.columns.omega
.six.columns.omega.fullwidth_inputs
= @order_cycle.coordinator.name
.two.columns
= f.label :orders_close, t('.orders_close')
.six.columns.omega
.six.columns.omega.fullwidth_inputs
- if viewing_as_coordinator_of?(@order_cycle)
= f.text_field :orders_close_at, 'datetimepicker' => 'order_cycle.orders_close_at', 'ng-model' => 'order_cycle.orders_close_at', 'ng-disabled' => '!loaded()', 'change-warning' => 'order_cycle'
- else
@@ -33,7 +33,7 @@
.row
.two.columns.alpha
= f.label :schedule_ids, t('admin.order_cycles.index.schedules')
.twelve.columns
.six.columns
- if viewing_as_coordinator_of?(@order_cycle)
%input.fullwidth.ofn-select2#schedule_ids{ name: 'order_cycle[schedule_ids]',
data: 'schedules',
@@ -43,5 +43,3 @@
ng: { model: 'order_cycle.schedule_ids' } }
- else
%schedule-list{ 'order-cycle' => 'order_cycle' }
.two.columns.omega
&nbsp;

View File

@@ -4,14 +4,14 @@
.alpha.two.columns
= label_tag t('.ready_for')
%span.required *
.six.columns
= text_field_tag 'order_cycle_outgoing_exchange_0_pickup_time', '', 'id' => 'order_cycle_outgoing_exchange_0_pickup_time', 'required' => 'required', 'placeholder' => t('.ready_for_placeholder'), 'ng-model' => 'outgoing_exchange.pickup_time', 'size' => 30, 'maxlength' => 35
%span.icon-question-sign{'ofn-with-tip' => t('admin.order_cycles.exchange_form.pickup_time_tip')}
.six.columns.fullwidth_inputs
= text_field_tag 'order_cycle_outgoing_exchange_0_pickup_time', '', 'id' => 'order_cycle_outgoing_exchange_0_pickup_time', 'required' => 'required', 'placeholder' => t('.ready_for_placeholder'), 'ng-model' => 'outgoing_exchange.pickup_time', 'maxlength' => 35
.two.columns
= label_tag t('.customer_instructions')
.six.columns.omega
= text_field_tag 'order_cycle_outgoing_exchange_0_pickup_instructions', '', 'id' => 'order_cycle_outgoing_exchange_0_pickup_instructions', 'placeholder' => t('.customer_instructions_placeholder'), 'ng-model' => 'outgoing_exchange.pickup_instructions', 'size' => 30
%span.icon-question-sign{'ofn-with-tip' => t('admin.order_cycles.exchange_form.pickup_instructions_tip')}
.six.columns.omega.fullwidth_inputs
= text_field_tag 'order_cycle_outgoing_exchange_0_pickup_instructions', '', 'id' => 'order_cycle_outgoing_exchange_0_pickup_instructions', 'placeholder' => t('.customer_instructions_placeholder'), 'ng-model' => 'outgoing_exchange.pickup_instructions', 'size' => 30
= label_tag t('.products')
%table.exchanges

View File

@@ -2,7 +2,7 @@
%table#hidden-products{ ng: { show: 'filteredProducts.length > 0' } }
%col.producer{ width: "20%" }
%col.product{ width: "20%" }
%col.variant{ width: "30%" }
%col.variant{ width: "20%" }
%col.add{ width: "15%" }
%thead
%tr

View File

@@ -1,9 +1,9 @@
%table#new-products{ ng: { show: 'views.new.visible && filteredProducts.length > 0' } }
%col.producer{ width: "20%" }
%col.product{ width: "20%" }
%col.variant{ width: "30%" }
%col.add{ width: "15%" }
%col.hide{ width: "15%" }
%col.variant{ width: "20%" }
%col.add{ width: "10%" }
%col.hide{ width: "10%" }
%thead
%tr
%th.producer=t('admin.producer')

View File

@@ -4,6 +4,7 @@
= inject_saved_credit_cards
= form_for current_order,
url: order_path(current_order),
html: {name: "checkout",
id: "checkout_form",
novalidate: true,

View File

@@ -2,9 +2,6 @@
.row
%fieldset.no-border-bottom
%legend{align: "center"}= t("spree.general")
.field
= preference_field_tag("enable_mail_delivery", Spree::Config[:enable_mail_delivery], type: :boolean)
= label_tag :enable_mail_delivery, t("spree.enable_mail_delivery")
.field
= label_tag :mails_from, t("spree.send_mails_as")
%br/

View File

@@ -1,5 +1,5 @@
%div{"data-hook" => "admin_orders_index_search"}
= form_tag :orders, {name: "orders_form", "ng-submit" => "fetchResults()"} do
= form_tag :admin_orders, {name: "orders_form", "ng-submit" => "fetchResults()"} do
.field-block.alpha.four.columns
.date-range-filter.field
= label_tag nil, t(:date_range)

View File

@@ -4,7 +4,7 @@
= render :partial => "spree/admin/orders/shipment", :collection => @order.shipments, :locals => { :order => order }
= render :partial => "spree/admin/orders/_form/adjustments", :locals => { :adjustments => @order.price_adjustments, :title => t(".line_item_adjustments")}
= render :partial => "spree/admin/orders/_form/adjustments", :locals => { :adjustments => @order.line_item_adjustments, :title => t(".line_item_adjustments")}
= render :partial => "spree/admin/orders/_form/adjustments", :locals => { :adjustments => order_adjustments_for_display(@order), :title => t(".order_adjustments")}
- if order.line_items.exists?

View File

@@ -54,9 +54,8 @@
%td.actions
- if can? :update, shipment
= link_to '', '#', :class => 'save-method icon_link icon-ok no-text with-tip', :data => { 'shipment-number' => shipment.number, :action => 'save' }, title: I18n.t('actions.save')
= link_to '', '#', :class => 'cancel-method icon_link icon-cancel no-text with-tip', :data => { :action => 'cancel' }, :title => I18n.t('actions.cancel')
= link_to '', '', :class => 'save-method icon_link icon-ok no-text with-tip', :data => { 'shipment-number' => shipment.number, :action => 'save' }, title: I18n.t('actions.save')
= link_to '', '', :class => 'cancel-method icon_link icon-cancel no-text with-tip', :data => { :action => 'cancel' }, :title => I18n.t('actions.cancel')
%tr.show-method.total
%td{ :colspan => "4" }
- if shipment.adjustment.present?
@@ -73,7 +72,7 @@
- if shipment.adjustment.present? && !shipment.shipped?
%td.actions
- if can? :update, shipment
= link_to '', '#', :class => 'edit-method icon_link icon-edit no-text with-tip', :data => { :action => 'edit' }, :title => Spree.t('edit')
= link_to '', '', :class => 'edit-method icon_link icon-edit no-text with-tip', :data => { :action => 'edit' }, :title => Spree.t('edit')
%tr.edit-tracking.hidden.total
%td{ :colspan => "5" }
@@ -83,8 +82,8 @@
%td.actions
- if can? :update, shipment
= link_to '', '#', :class => 'save-tracking icon_link icon-ok no-text with-tip', :data => { 'shipment-number' => shipment.number, :action => 'save' }, :title => I18n.t('actions.save')
= link_to '', '#', :class => 'cancel-tracking icon_link icon-cancel no-text with-tip', :data => { :action => 'cancel' }, :title => I18n.t('actions.cancel')
= link_to '', '', :class => 'save-tracking icon_link icon-ok no-text with-tip', :data => { 'shipment-number' => shipment.number, :action => 'save' }, :title => I18n.t('actions.save')
= link_to '', '', :class => 'cancel-tracking icon_link icon-cancel no-text with-tip', :data => { :action => 'cancel' }, :title => I18n.t('actions.cancel')
%tr.show-tracking.total
%td{ :colspan => "5" }
@@ -97,4 +96,4 @@
%td.actions
- if can? :update, shipment
= link_to '', '#', :class => 'edit-tracking icon_link icon-edit no-text with-tip', :data => { :action => 'edit' }, :title => Spree.t('edit')
= link_to '', '', :class => 'edit-tracking icon_link icon-edit no-text with-tip', :data => { :action => 'edit' }, :title => Spree.t('edit')

View File

@@ -21,12 +21,12 @@
%label{ :for => 'start_date_filter' }
= t("admin.start_date")
%br
%input{ :class => "two columns alpha", :type => "text", :id => 'start_date_filter', 'ng-model' => 'startDate', 'datepicker' => "startDate", 'confirm-change' => "confirmRefresh()", 'ng-change' => 'refreshData()', 'ng-model-options' => '{ debounce: 1000 }' }
%input.fullwidth{ :type => "text", :id => 'start_date_filter', 'ng-model' => 'startDate', 'datepicker' => "startDate", 'confirm-change' => "confirmRefresh()", 'ng-change' => 'refreshData()', 'ng-model-options' => '{ debounce: 1000 }' }
.date_filter{ :class => "two columns" }
%label{ :for => 'end_date_filter' }
= t("admin.end_date")
%br
%input{ :class => "two columns alpha", :type => "text", :id => 'end_date_filter', 'ng-model' => 'endDate', 'datepicker' => "endDate", 'confirm-change' => "confirmRefresh()", 'ng-change' => 'refreshData()', 'ng-model-options' => '{ debounce: 1000 }' }
%input.fullwidth{ :type => "text", :id => 'end_date_filter', 'ng-model' => 'endDate', 'datepicker' => "endDate", 'confirm-change' => "confirmRefresh()", 'ng-change' => 'refreshData()', 'ng-model-options' => '{ debounce: 1000 }' }
.one.column &nbsp;
.filter_select{ :class => "three columns" }
%label{ :for => 'supplier_filter' }
@@ -98,9 +98,10 @@
.controls.sixteen.columns.alpha.omega{ ng: { hide: 'RequestMonitor.loading || line_items.length == 0' } }
%div.three.columns.alpha
%input.fullwidth{ :type => "text", :id => 'quick_search', 'ng-model' => 'quickSearch', :placeholder => 'Quick Search' }
= render 'admin/shared/bulk_actions_dropdown'
%div.seven.columns &nbsp;
%columns-dropdown{ action: "#{controller_name}_#{action_name}" }
%div.three.columns
= render 'admin/shared/bulk_actions_dropdown'
%div.ten.columns
%columns-dropdown{ action: "#{controller_name}_#{action_name}" }
%div.sixteen.columns.alpha#loading{ 'ng-if' => 'RequestMonitor.loading' }
= render partial: "components/spinner"

View File

@@ -7,13 +7,13 @@
= f.label :email, Spree.t(:email) + ':'
= f.email_field :email, :class => 'fullwidth'
.alpha.six.columns{"data-hook" => "bill_address_wrapper"}
.alpha.eight.columns{"data-hook" => "bill_address_wrapper"}
%fieldset.no-border-bottom
%legend{:align => "center"}= Spree.t(:billing_address)
= f.fields_for :bill_address do |ba_form|
= render :partial => 'address_form', :locals => { :f => ba_form, :name => Spree.t(:billing_address), :use_billing => false }
.omega.six.columns{"data-hook" => "ship_address_wrapper"}
.omega.eight.columns{"data-hook" => "ship_address_wrapper"}
%fieldset.no-border-bottom
%legend{:align => "center"}= Spree.t(:shipping_address)
= f.fields_for :ship_address do |sa_form|

View File

@@ -1,21 +1,21 @@
- color_class = @order_cycle_count > 0 ? "blue" : "orange"
- icon_class = @order_cycle_count > 0 ? "icon-ok-sign" : "icon-warning-sign"
%div.dashboard_item.seven.columns.omega#order_cycles
%div.header.seven.columns.alpha{class: color_class}
%h3.four.columns.alpha
%div.header.sixteen.columns.alpha{class: color_class}
%h3.ten.columns.alpha
= t ".order_cycles"
- if @order_cycle_count > 0
%a.three.columns.omega.icon-plus.button.blue{ href: main_app.new_admin_order_cycle_path }
%a.six.columns.omega.icon-plus.button.blue{ href: main_app.new_admin_order_cycle_path }
= t "spree_admin_enterprises_create_new"
- else
%a{ "ofn-with-tip" => t(".order_cycles_tip") }
= t "admin.whats_this"
%div.seven.columns.alpha.list
%div.seven.columns.alpha.list-item{class: color_class}
%span.six.columns.alpha
%div.sixteen.columns.alpha.list
%div.sixteen.columns.alpha.list-item{class: color_class}
%span.thirteen.columns.alpha
= t('.you_have_active', count: @order_cycle_count)
%span.one.column.omega
%span.three.columns.omega
%span{class: icon_class}
%a.seven.columns.alpha.button.bottom{ href: main_app.admin_order_cycles_path, class: color_class }
%a.sixteen.columns.alpha.button.bottom{ href: main_app.admin_order_cycles_path, class: color_class }
= t ".manage_order_cycles"
%span.icon-arrow-right

View File

@@ -1,29 +1,29 @@
%div.dashboard_item.seven.columns.alpha#products
%div.header.seven.columns.alpha{ :class => "#{@product_count > 0 ? "" : "red"}"}
%h3.four.columns.alpha
%div.header.sixteen.columns.alpha{ :class => "#{@product_count > 0 ? "" : "red"}"}
%h3.ten.columns.alpha
= t "products"
- if @product_count > 0
%a.three.columns.omega.icon-plus.button.blue{ href: "#{new_admin_product_path}" }
%a.six.columns.omega.icon-plus.button.blue{ href: "#{new_admin_product_path}" }
= t "spree_admin_enterprises_create_new"
- else
%a{ "ofn-with-tip" => "The products that you sell through the Open Food Network." }
= t "admin.whats_this"
%div.seven.columns.alpha.list
%div.sixteen.columns.alpha.list
- if @product_count > 0
%div.seven.columns.alpha.list-item
%span.six.columns.alpha
%div.sixteen.columns.alpha.list-item
%span.thirteen.columns.alpha
= t(".active_products", count: @product_count )
%span.one.column.omega
%span.three.columns.omega
%span.icon-ok-sign
%a.seven.columns.alpha.button.bottom.blue{ href: "#{admin_products_path}" }
%a.sixteen.columns.alpha.button.bottom.blue{ href: "#{admin_products_path}" }
= t "spree_admin_enterprises_producers_manage_products"
%span.icon-arrow-right
- else
%div.seven.columns.alpha.list-item.red
%span.six.columns.alpha
%div.sixteen.columns.alpha.list-item.red
%span.thirteen.columns.alpha
= t(".active_products", count: @product_count )
%span.one.column.omega
%span.three.columns.omega
%span.icon-remove-sign
%a.seven.columns.alpha.button.bottom.red{ href: "#{new_admin_product_path}" }
%a.eight.columns.alpha.button.bottom.red{ href: "#{new_admin_product_path}" }
= t "spree_admin_enterprises_create_new_product"
%span.icon-arrow-right

View File

@@ -34,7 +34,7 @@
%a.close{ href: "#" } ×
.row
.alpha.seven.columns.dashboard_item.single-ent#map
.alpha.eight.columns.dashboard_item.single-ent#map
.header
%h3
%span.icon-user
@@ -45,10 +45,8 @@
= @enterprise.name
= t "live"
%span.icon-arrow-right
.two.columns
&nbsp;
.seven.columns.omega.dashboard_item.single-ent#edit
.eight.columns.omega.dashboard_item.single-ent#edit
.header
%h3
%span.icon-edit
@@ -63,7 +61,7 @@
.row
- if can? :admin, Spree::Product
.seven.columns.alpha.dashboard_item.single-ent#products
.eight.columns.alpha.dashboard_item.single-ent#products
.header
%h3
%span.icon-th-large
@@ -73,11 +71,8 @@
= t "manage_products"
%span.icon-arrow-right
.two.columns
&nbsp;
- if can? :admin, OrderCycle
.seven.columns.omega.dashboard_item.single-ent#order_cycles
.eight.columns.omega.dashboard_item.single-ent#order_cycles
.header
%h3
%span.icon-shopping-cart

View File

@@ -1,5 +1,5 @@
%div{"data-hook" => "admin_product_form_fields"}
.left.eight.columns.alpha
.left.twelve.columns.alpha
= f.field_container :name do
= f.label :name, raw(t(:name) + content_tag(:span, ' *', :class => 'required'))
= f.text_field :name, :class => 'fullwidth title'

View File

@@ -1,13 +1,14 @@
- content_for :page_title do
= t(:listing_reports)
%table.index
%thead
%tr
%th= t(:name)
%th= t(:description)
%tbody
- @reports.each do |key, value|
.columns.twelve
%table.index
%thead
%tr
%td= link_to value[:name], value[:url]
%td= value[:description]
%th= t(:name)
%th= t(:description)
%tbody
- @reports.each do |key, value|
%tr
%td= link_to value[:name], value[:url]
%td= value[:description]

View File

@@ -1,27 +1,28 @@
- hubs_color = @hubs.count > 0 ? "blue" : "red"
- hubs_color = 'red' if (controller.action_name == 'create' || controller.action_name == 'update') && @object.errors.full_messages.include?(t(:hub_sidebar_at_least))
.sidebar_item.omega.four.columns#hubs
.four.columns.alpha.header{ class: "#{hubs_color}" }
.sixteen.columns.alpha.header{ class: "#{hubs_color}" }
%span.four.columns.alpha.centered
= t(:hub_sidebar_hubs)
.four.columns.alpha.list{ class: "#{hubs_color}" }
.sixteen.columns.alpha.list{ class: "#{hubs_color}" }
- if @hubs.count > 0
= hidden_field klass, :distributor_ids, :multiple => true, value: nil
- @hubs.each do |hub|
%span.four.columns.alpha.list-item{ class: "#{cycle('odd','even')}" }
%span.four.columns
%span.three.columns.alpha
%span.sixteen.columns.alpha.list-item{ class: "#{cycle('odd','even')}" }
%span.sixteen.columns
%span.fourteen.columns.alpha
%label
= check_box klass, :distributor_ids, { multiple: true }.merge(add_check_if_single(@hubs.count)), hub.id, nil
= hub.name
%a.one.column.omega{ href: "#{main_app.edit_admin_enterprise_path(hub)}" }
%a.two.columns.omega{ href: "#{main_app.edit_admin_enterprise_path(hub)}" }
%span.icon-arrow-right
- else
.four.columns.alpha.list-item
%span.three.columns.alpha
.sixteen.columns.alpha.list-item
%span.twelve.columns.alpha
= t(:hub_sidebar_none_available)
%span.one.column.omega
%span.four.column.omega
%span.icon-remove-sign
%a.four.columns.alpha.button{ href: "#{main_app.admin_enterprises_path}", class: "#{hubs_color}" }
%a.sixteen.columns.alpha.button{ href: "#{main_app.admin_enterprises_path}", class: "#{hubs_color}" }
= t(:hub_sidebar_manage)
%span.icon-arrow-right

View File

@@ -19,9 +19,9 @@
= render :partial => 'spree/layouts/admin/login_nav'
%nav#admin-menu{ data: { hook: '' }}
.container
.container.no-gutter
.sixteen.columns.main-menu-wrapper
%ul.inline-menu.fullwidth-menu{"data-hook" => "admin_tabs"}
%ul.inline-menu{"data-hook" => "admin_tabs"}
= render :partial => 'spree/admin/shared/tabs'
- if content_for?(:sub_menu)

View File

@@ -12,7 +12,7 @@
- if order.changes_allowed?
.columns.show-for-medium-up.medium-3 &nbsp;
.columns.small-12.medium-3
= link_to spree.cancel_order_path(@order), method: :put, :class => "button secondary expand", "confirm-link-click" => t('orders_confirm_cancel') do
= link_to cancel_order_path(@order), method: :put, :class => "button secondary expand", "confirm-link-click" => t('orders_confirm_cancel') do
%i.ofn-i_009-close
= t(:cancel_order)
.columns.small-12.medium-3

View File

@@ -41,7 +41,7 @@
= t(:orders_changeable_orders_alert_html, oc_close: l(order.order_cycle.orders_close_at, format: "%b %d, %Y %H:%M"))
%a.close{ "ng-click" => "close()" } &times;
= form_for order, html: {id: 'update-order', name: 'update_order_form' } do |order_form|
= form_for order, url: order_path(order), html: {id: 'update-order', name: 'update_order_form' } do |order_form|
- if order.changes_allowed?
= render 'spree/orders/form', order_form: order_form
-else

View File

@@ -1,7 +1,8 @@
- content_for :injection_data do
= inject_orders
= inject_shops
= inject_json_array("orders", @orders.all, Api::OrderSerializer)
= inject_json_array("shops", @shops.all, Api::ShopForOrdersSerializer)
= inject_saved_credit_cards
- if Stripe.publishable_key
:javascript
angular.module('Darkswarm').value("stripeObject", Stripe("#{Stripe.publishable_key}"))
@@ -22,14 +23,14 @@
.row.tabset-ctrl#account-tabs{ style: 'margin-bottom: 100px', navigate: 'true', selected: 'orders', prefix: 'account' }
.small.12.medium-3.columns.tab{ name: "orders" }
%a{ href: 'javascript:void(0)' }=t('.tabs.orders')
%a=t('.tabs.orders')
- if Spree::Config.stripe_connect_enabled && Stripe.publishable_key
.small.12.medium-3.columns.tab{ name: "cards" }
%a{ href: 'javascript:void(0)' }=t('.tabs.cards')
%a=t('.tabs.cards')
.small.12.medium-3.columns.tab{ name: "transactions" }
%a{ href: 'javascript:void(0)' }=t('.tabs.transactions')
%a=t('.tabs.transactions')
.small.12.medium-3.columns.tab{ name: "settings" }
%a{ href: 'javascript:void(0)' }=t('.tabs.settings')
%a=t('.tabs.settings')
.small-12.columns.tab-view
= render partial: "shared/footer"

View File

@@ -6,7 +6,7 @@
- separator = messages.values.any? ? ": " : ", "
- orders.each_with_index do |order, i|
%a{ href: spree.order_url(order) }>= order.number
%a{ href: order_url(order) }>= order.number
= separator if messages.values.any? || i < orders.count - 1
- if messages.values.any?
= messages[order.id] || t(".no_message_provided")
@@ -17,5 +17,5 @@
%h4= t(".other.title", count: orders.count)
%p= t(".other.explainer")
- orders.each_with_index do |order, i|
%a{ href: spree.order_url(order) }>= order.number
%a{ href: order_url(order) }>= order.number
= ", " if i < orders.count - 1

View File

@@ -6,7 +6,7 @@
- if @order.user.present?
= t("email_so_edit_false_html",
orders_close_at: l(@order.order_cycle.orders_close_at, format: mail_long_datetime_format),
order_url: spree.order_url(@order))
order_url: order_url(@order))
= t("email_so_contact_distributor_html", distributor: @order.distributor.name, email: @order.distributor.contact.email)
%p &nbsp;

View File

@@ -5,7 +5,7 @@
- if @order.user.present?
= t("email_so_edit_false_html",
orders_close_at: l(@order.order_cycle.orders_close_at, format: mail_long_datetime_format),
order_url: spree.order_url(@order))
order_url: order_url(@order))
= t("email_so_contact_distributor_html", distributor: @order.distributor.name, email: @order.distributor.contact.email)
- if @order.errors.any?

View File

@@ -8,7 +8,7 @@
- allow_changes = !!@order.distributor.allow_order_changes?
= t("email_so_edit_#{allow_changes}_html",
orders_close_at: l(@order.order_cycle.orders_close_at, format: mail_long_datetime_format),
order_url: spree.order_url(@order))
order_url: order_url(@order))
= t("email_so_contact_distributor_html", distributor: @order.distributor.name, email: @order.distributor.contact.email)
- else
= t("email_so_contact_distributor_to_change_order_html",

View File

@@ -0,0 +1,2 @@
require 'compass'
Sass.load_paths << Compass::Frameworks['compass'].stylesheets_directory

View File

@@ -2318,6 +2318,8 @@ ar:
payment_processing_failed: "لا يمكن معالجة الدفع ، يرجى التحقق من التفاصيل التي أدخلتها"
payment_method_not_supported: "طريقة الدفع هذه غير مدعومة. يرجى اختيار واحد آخر."
payment_updated: "تم تحديث الدفع"
cannot_perform_operation: "تعذر تحديث الدفع"
action_required: "الإجراء مطلوب"
inventory_settings: "إعدادات المخزون"
tag_rules: "قواعد الوسم"
shop_preferences: "تفضيلات المتجر"
@@ -2579,6 +2581,8 @@ ar:
processing: "قيد المعالجة"
void: "فارغ"
invalid: "غير صالحة"
quantity_adjusted: "مخزون غير كافٍ. تم تحديث البند إلى الكمية القصوى المتاحة."
quantity_unchanged: "الكمية لم تتغير عن المبلغ السابق."
resend_user_email_confirmation:
resend: "إعادة إرسال"
sending: "إعادة إرسال..."
@@ -3565,6 +3569,10 @@ ar:
subject: "تعليمات إعادة تعيين كلمة المرور"
confirmation_instructions:
subject: "يرجى تأكيد حسابك OFN"
payment_mailer:
authorize_payment:
subject: "يرجى تفويض الدفع الخاص بك إلى %{distributor} على OFN"
instructions: "يتطلب الدفع الخاص بك من %{amount} إلى %{distributor} مصادقة إضافية. الرجاء زيارة URL التالي لتفويض الدفع الخاص بك:"
shipment_mailer:
shipped_email:
dear_customer: "عزيزي العميل،"

File diff suppressed because it is too large Load Diff

View File

@@ -3117,6 +3117,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using
tax rate: "Tax Rates"
new_tax_rate: "New Tax Rate"
tax_category: "Tax Category"
tax_rates: "Tax Rates"
rate: "Rate"
tax_rate_amount_explanation: "Tax rates are a decimal amount to aid in calculations, (i.e. if the tax rate is 5% then enter 0.05)"
included_in_price: "Included in Price"

View File

@@ -2319,6 +2319,8 @@ en_FR:
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"
@@ -2587,6 +2589,8 @@ en_FR:
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..."
@@ -3478,6 +3482,10 @@ en_FR:
subject: "Reset password instructions"
confirmation_instructions:
subject: "Please confirm your OFN account"
payment_mailer:
authorize_payment:
subject: "Please authorize your payment to %{distributor} on CoopCircuits"
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,"

View File

@@ -2319,6 +2319,8 @@ en_GB:
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"
@@ -2593,6 +2595,8 @@ en_GB:
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..."
@@ -3484,6 +3488,10 @@ en_GB:
subject: "Reset password instructions"
confirmation_instructions:
subject: "Please confirm your OFN account"
payment_mailer:
authorize_payment:
subject: "Please authorise your payment to %{distributor} on OFN"
instructions: "Your payment of %{amount} to %{distributor} requires additional authentication. Please visit the following URL to authorise your payment:"
shipment_mailer:
shipped_email:
dear_customer: "Dear Customer,"

View File

@@ -2321,6 +2321,8 @@ fr:
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: "Catalogue boutique"
tag_rules: "Règles de tag"
shop_preferences: "Préférences boutique"
@@ -2615,6 +2617,8 @@ fr:
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: "Renvoi...."
@@ -3508,6 +3512,10 @@ fr:
subject: "Instructions de mise à jour du mot de passe"
confirmation_instructions:
subject: "Veuillez confirmer votre compte"
payment_mailer:
authorize_payment:
subject: "Veuillez autoriser votre paiement à %{distributor} sur CoopCircuits."
instructions: "Votre paiement de %{amount} à %{distributor} demande une autorisation additionnelle. Veuillez suivre ce lien afin d'autoriser votre paiement :"
shipment_mailer:
shipped_email:
dear_customer: "Cher Acheteur,"

View File

@@ -1,3 +1,11 @@
Openfoodnetwork::Application.routes.draw do
scope module: 'spree' do
resources :orders do
put :cancel, on: :member
end
end
end
# Overriding Devise routes to use our own controller
Spree::Core::Engine.routes.draw do
devise_for :spree_user,
@@ -159,12 +167,6 @@ Spree::Core::Engine.routes.draw do
resources :payment_methods
end
resources :orders do
get :clear, :on => :collection
get :order_cycle_expired, :on => :collection
put :cancel, on: :member
end
resources :products
# Used by spree_paypal_express

View File

@@ -0,0 +1,8 @@
class RemoveEnableMailDeliveryPreference < ActiveRecord::Migration
def up
Spree::Preference.delete_all("key ilike '%enable_mail_delivery%'")
end
def down
end
end

View File

@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20210115143738) do
ActiveRecord::Schema.define(version: 20210125123000) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"

View File

@@ -4,7 +4,6 @@ require 'yaml'
def set_mail_configuration
MailConfiguration.entries= {
enable_mail_delivery: true,
mail_host: ENV.fetch('MAIL_HOST'),
mail_domain: ENV.fetch('MAIL_DOMAIN'),
mail_port: ENV.fetch('MAIL_PORT'),

View File

@@ -12,13 +12,9 @@ module Spree
end
def override!
if Config.enable_mail_delivery
ActionMailer::Base.default_url_options[:host] ||= Config.site_url
ActionMailer::Base.smtp_settings = mail_server_settings
ActionMailer::Base.perform_deliveries = true
else
ActionMailer::Base.perform_deliveries = false
end
ActionMailer::Base.default_url_options[:host] ||= Config.site_url
ActionMailer::Base.smtp_settings = mail_server_settings
ActionMailer::Base.perform_deliveries = true
end
private

View File

@@ -6,6 +6,7 @@ require 'spree/i18n/base'
module Spree
extend ActionView::Helpers::TranslationHelper
extend ActionView::Helpers::TagHelper if ENV['DEPENDENCIES_NEXT']
class << self
# Add spree namespace and delegate to Rails TranslationHelper for some nice

View File

@@ -20,7 +20,7 @@ describe Admin::BulkLineItemsController, type: :controller do
before { allow(controller).to receive_messages spree_current_user: create(:user) }
it "should deny me access to the index action" do
spree_get :index, format: :json
get :index, format: :json
expect(response).to redirect_to unauthorized_path
end
end
@@ -32,7 +32,7 @@ describe Admin::BulkLineItemsController, type: :controller do
context "when no ransack params are passed in" do
before do
spree_get :index, format: :json
get :index, format: :json
end
it "retrieves a list of line_items with appropriate attributes, including line items with appropriate attributes" do
@@ -56,7 +56,7 @@ describe Admin::BulkLineItemsController, type: :controller do
context "when ransack params are passed in for line items" do
before do
spree_get :index, format: :json, q: { order_id_eq: order2.id }
get :index, format: :json, q: { order_id_eq: order2.id }
end
it "retrives a list of line items which match the criteria" do
@@ -66,7 +66,7 @@ describe Admin::BulkLineItemsController, type: :controller do
context "when ransack params are passed in for orders" do
before do
spree_get :index, format: :json, q: { order: { completed_at_gt: 2.hours.ago } }
get :index, format: :json, q: { order: { completed_at_gt: 2.hours.ago } }
end
it "retrives a list of line items whose orders match the criteria" do
@@ -90,7 +90,7 @@ describe Admin::BulkLineItemsController, type: :controller do
context "producer enterprise" do
before do
allow(controller).to receive_messages spree_current_user: supplier.owner
spree_get :index, format: :json
get :index, format: :json
end
it "does not display line items for which my enterprise is a supplier" do
@@ -101,7 +101,7 @@ describe Admin::BulkLineItemsController, type: :controller do
context "coordinator enterprise" do
before do
allow(controller).to receive_messages spree_current_user: coordinator.owner
spree_get :index, format: :json
get :index, format: :json
end
it "retrieves a list of line_items" do
@@ -113,7 +113,7 @@ describe Admin::BulkLineItemsController, type: :controller do
context "hub enterprise" do
before do
allow(controller).to receive_messages spree_current_user: distributor1.owner
spree_get :index, format: :json
get :index, format: :json
end
it "retrieves a list of line_items" do
@@ -130,7 +130,7 @@ describe Admin::BulkLineItemsController, type: :controller do
context "with pagination args" do
it "returns paginated results" do
spree_get :index, { page: 1, per_page: 2 }, format: :json
get :index, { page: 1, per_page: 2 }, format: :json
expect(line_item_ids).to eq [line_item1.id, line_item2.id]
expect(json_response['pagination']).to eq(
@@ -139,7 +139,7 @@ describe Admin::BulkLineItemsController, type: :controller do
end
it "returns paginated results for a second page" do
spree_get :index, { page: 2, per_page: 2 }, format: :json
get :index, { page: 2, per_page: 2 }, format: :json
expect(line_item_ids).to eq [line_item3.id, line_item4.id]
expect(json_response['pagination']).to eq(

View File

@@ -17,7 +17,7 @@ module Admin
end
it "returns an empty @collection" do
spree_get :index, format: :html
get :index, format: :html
expect(assigns(:collection)).to eq []
end
end
@@ -34,13 +34,13 @@ module Admin
let(:params) { { format: :json, enterprise_id: enterprise.id } }
it "scopes @collection to customers of that enterprise" do
spree_get :index, params
get :index, params
expect(assigns(:collection)).to eq [customer]
end
it "serializes the data" do
expect(ActiveModel::ArraySerializer).to receive(:new)
spree_get :index, params
get :index, params
end
context 'when the customer_balance feature is enabled' do
@@ -57,13 +57,13 @@ module Admin
expect(customers_with_balance).to receive(:query) { Customer.none }
spree_get :index, params
get :index, params
end
it 'serializes using CustomerWithBalanceSerializer' do
expect(Api::Admin::CustomerWithBalanceSerializer).to receive(:new)
spree_get :index, params
get :index, params
end
end
@@ -75,20 +75,20 @@ module Admin
it 'calls Customer.of' do
expect(Customer).to receive(:of).twice.with(enterprise) { Customer.none }
spree_get :index, params
get :index, params
end
it 'serializes calling the UserBalanceCalculator' do
expect(OpenFoodNetwork::UserBalanceCalculator)
.to receive(:new).with(customer.email, customer.enterprise) { calculator }
spree_get :index, params
get :index, params
end
end
context 'when the customer has no orders' do
it 'includes the customer balance in the response' do
spree_get :index, params
get :index, params
expect(json_response.first["balance"]).to eq("$0.00")
end
end
@@ -103,7 +103,7 @@ module Admin
end
it 'includes the customer balance in the response' do
spree_get :index, params
get :index, params
expect(json_response.first["balance"]).to eq("$-10.00")
end
end
@@ -124,7 +124,7 @@ module Admin
end
it 'includes the customer balance in the response' do
spree_get :index, params
get :index, params
expect(json_response.first["balance"]).to eq("$10.00")
end
end
@@ -134,7 +134,7 @@ module Admin
let!(:line_item) { create(:line_item, order: order, price: 10.0) }
it 'includes the customer balance in the response' do
spree_get :index, params
get :index, params
expect(json_response.first["balance"]).to eq("$0.00")
end
end
@@ -156,7 +156,7 @@ module Admin
it 'includes the customer balance in the response' do
expect(order.payment_total).to eq(0)
spree_get :index, params
get :index, params
expect(json_response.first["balance"]).to eq('$-10.00')
end
end
@@ -164,7 +164,7 @@ module Admin
context "and enterprise_id is not given in params" do
it "returns an empty collection" do
spree_get :index, format: :json
get :index, format: :json
expect(assigns(:collection)).to eq []
end
end
@@ -176,7 +176,7 @@ module Admin
end
it "returns an empty collection" do
spree_get :index, format: :json
get :index, format: :json
expect(assigns(:collection)).to eq []
end
end
@@ -276,7 +276,7 @@ module Admin
end
it "renders the customer as json" do
spree_get :show, format: :json, id: customer.id
get :show, format: :json, id: customer.id
expect(JSON.parse(response.body)["id"]).to eq customer.id
end
end
@@ -287,7 +287,7 @@ module Admin
end
it "prevents me from updating the customer" do
spree_get :show, format: :json, id: customer.id
get :show, format: :json, id: customer.id
expect(response).to redirect_to unauthorized_path
end
end

View File

@@ -457,28 +457,28 @@ describe Admin::EnterprisesController, type: :controller do
end
context "when no order_cycle or coordinator is provided in params" do
before { spree_get :for_order_cycle, format: :json }
before { get :for_order_cycle, format: :json }
it "initializes permissions with nil" do
expect(OpenFoodNetwork::OrderCyclePermissions).to have_received(:new).with(user, nil)
end
end
context "when an order_cycle_id is provided in params" do
before { spree_get :for_order_cycle, format: :json, order_cycle_id: 1 }
before { get :for_order_cycle, format: :json, order_cycle_id: 1 }
it "initializes permissions with the existing OrderCycle" do
expect(OpenFoodNetwork::OrderCyclePermissions).to have_received(:new).with(user, "existing OrderCycle")
end
end
context "when a coordinator is provided in params" do
before { spree_get :for_order_cycle, format: :json, coordinator_id: 1 }
before { get :for_order_cycle, format: :json, coordinator_id: 1 }
it "initializes permissions with a new OrderCycle" do
expect(OpenFoodNetwork::OrderCyclePermissions).to have_received(:new).with(user, "new OrderCycle")
end
end
context "when both an order cycle and a coordinator are provided in params" do
before { spree_get :for_order_cycle, format: :json, order_cycle_id: 1, coordinator_id: 1 }
before { get :for_order_cycle, format: :json, order_cycle_id: 1, coordinator_id: 1 }
it "initializes permissions with the existing OrderCycle" do
expect(OpenFoodNetwork::OrderCyclePermissions).to have_received(:new).with(user, "existing OrderCycle")
end
@@ -500,7 +500,7 @@ describe Admin::EnterprisesController, type: :controller do
it "uses permissions to determine which enterprises are visible and should be rendered" do
expect(controller).to receive(:render_as_json).with([visible_enterprise], ams_prefix: 'basic', spree_current_user: user).and_call_original
spree_get :visible, format: :json
get :visible, format: :json
end
end
@@ -518,14 +518,14 @@ describe Admin::EnterprisesController, type: :controller do
context "html" do
it "returns all enterprises" do
spree_get :index, format: :html
get :index, format: :html
expect(assigns(:collection)).to include enterprise1, enterprise2, enterprise3
end
end
context "json" do
it "returns all enterprises" do
spree_get :index, format: :json
get :index, format: :json
expect(assigns(:collection)).to include enterprise1, enterprise2, enterprise3
end
end
@@ -543,14 +543,14 @@ describe Admin::EnterprisesController, type: :controller do
context "html" do
it "returns an empty @collection" do
spree_get :index, format: :html
get :index, format: :html
expect(assigns(:collection)).to eq []
end
end
context "json" do
it "scopes @collection to enterprises editable by the user" do
spree_get :index, format: :json
get :index, format: :json
expect(assigns(:collection)).to include enterprise1, enterprise2
expect(assigns(:collection)).to_not include enterprise3
end

View File

@@ -20,7 +20,7 @@ module Admin
context "html" do
it "doesn't load any data" do
spree_get :index, format: :html
get :index, format: :html
expect(assigns(:collection)).to be_empty
end
end
@@ -28,7 +28,7 @@ module Admin
context "json" do
context "where ransack conditions are specified" do
it "loads order cycles that closed within the past month, and orders without a close_at date" do
spree_get :index, format: :json
get :index, format: :json
expect(assigns(:collection)).to_not include oc1, oc2
expect(assigns(:collection)).to include oc3, oc4
end
@@ -38,7 +38,7 @@ module Admin
let(:q) { { orders_close_at_gt: 45.days.ago } }
it "loads order cycles that closed after the specified date, and orders without a close_at date" do
spree_get :index, format: :json, q: q
get :index, format: :json, q: q
expect(assigns(:collection)).to_not include oc1
expect(assigns(:collection)).to include oc2, oc3, oc4
end
@@ -47,7 +47,7 @@ module Admin
before { q.merge!(id_not_in: [oc2.id, oc4.id]) }
it "loads order cycles that meet all conditions" do
spree_get :index, format: :json, q: q
get :index, format: :json, q: q
expect(assigns(:collection)).to_not include oc1, oc2, oc4
expect(assigns(:collection)).to include oc3
end
@@ -62,7 +62,7 @@ module Admin
let!(:distributor) { create(:distributor_enterprise, owner: distributor_owner) }
it "renders the new template" do
spree_get :new
get :new
expect(response).to render_template :new
end
end
@@ -73,21 +73,21 @@ module Admin
let!(:distributor3) { create(:distributor_enterprise) }
it "renders the set_coordinator template" do
spree_get :new
get :new
expect(response).to render_template :set_coordinator
end
describe "and a coordinator_id is submitted as part of the request" do
describe "when the user manages the enterprise" do
it "renders the new template" do
spree_get :new, coordinator_id: distributor1.id
get :new, coordinator_id: distributor1.id
expect(response).to render_template :new
end
end
describe "when the user does not manage the enterprise" do
it "renders the set_coordinator template and sets a flash error" do
spree_get :new, coordinator_id: distributor3.id
get :new, coordinator_id: distributor3.id
expect(response).to render_template :set_coordinator
expect(flash[:error]).to eq "You don't have permission to create an order cycle coordinated by that enterprise"
end
@@ -331,7 +331,7 @@ module Admin
describe "when an order cycle is deleteable" do
it "allows the order_cycle to be destroyed" do
spree_get :destroy, id: oc.id
get :destroy, id: oc.id
expect(OrderCycle.find_by(id: oc.id)).to be nil
end
end
@@ -340,7 +340,7 @@ module Admin
let!(:order) { create(:order, order_cycle: oc) }
it "displays an error message when we attempt to delete it" do
spree_get :destroy, id: oc.id
get :destroy, id: oc.id
expect(response).to redirect_to admin_order_cycles_path
expect(flash[:error]).to eq I18n.t('admin.order_cycles.destroy_errors.orders_present')
end
@@ -350,7 +350,7 @@ module Admin
let!(:schedule) { create(:schedule, order_cycles: [oc]) }
it "displays an error message when we attempt to delete it" do
spree_get :destroy, id: oc.id
get :destroy, id: oc.id
expect(response).to redirect_to admin_order_cycles_path
expect(flash[:error]).to eq I18n.t('admin.order_cycles.destroy_errors.schedule_present')
end

View File

@@ -42,7 +42,7 @@ describe Admin::ProxyOrdersController, type: :controller do
context "when cancellation succeeds" do
it 'renders the cancelled proxy_order as json' do
spree_get :cancel, params
get :cancel, params
json_response = JSON.parse(response.body)
expect(json_response['state']).to eq "canceled"
expect(json_response['id']).to eq proxy_order.id
@@ -54,7 +54,7 @@ describe Admin::ProxyOrdersController, type: :controller do
before { order_cycle.update(orders_close_at: 1.day.ago) }
it "shows an error" do
spree_get :cancel, params
get :cancel, params
json_response = JSON.parse(response.body)
expect(json_response['errors']).to eq ['Could not cancel the order']
end
@@ -111,7 +111,7 @@ describe Admin::ProxyOrdersController, type: :controller do
context "when resuming succeeds" do
it 'renders the resumed proxy_order as json' do
spree_get :resume, params
get :resume, params
json_response = JSON.parse(response.body)
expect(json_response['state']).to eq "resumed"
expect(json_response['id']).to eq proxy_order.id
@@ -123,7 +123,7 @@ describe Admin::ProxyOrdersController, type: :controller do
before { order_cycle.update(orders_close_at: 1.day.ago) }
it "shows an error" do
spree_get :resume, params
get :resume, params
json_response = JSON.parse(response.body)
expect(json_response['errors']).to eq ['Could not resume the order']
end

View File

@@ -21,13 +21,13 @@ describe Admin::SchedulesController, type: :controller do
let(:params) { { format: :json } }
it "scopes @collection to schedules containing order_cycles coordinated by enterprises I manage" do
spree_get :index, params
get :index, params
expect(assigns(:collection)).to eq [coordinated_schedule]
end
it "serializes the data" do
expect(ActiveModel::ArraySerializer).to receive(:new)
spree_get :index, params
get :index, params
end
context "and there is a schedule of an OC coordinated by _another_ enterprise I manage and the first enterprise is given" do
@@ -37,7 +37,7 @@ describe Admin::SchedulesController, type: :controller do
let(:params) { { format: :json, enterprise_id: managed_coordinator.id } }
it "scopes @collection to schedules containing order_cycles coordinated by the first enterprise" do
spree_get :index, params
get :index, params
expect(assigns(:collection)).to eq [coordinated_schedule]
end
end
@@ -45,7 +45,7 @@ describe Admin::SchedulesController, type: :controller do
context "where I dont manage an order cycle coordinator" do
it "returns an empty collection" do
spree_get :index, format: :json
get :index, format: :json
expect(assigns(:collection)).to be_nil
end
end

View File

@@ -15,7 +15,7 @@ describe Admin::StripeAccountsController, type: :controller do
end
it "redirects to Stripe Authorization url constructed OAuth" do
spree_get :connect, enterprise_id: 1 # A deterministic id results in a deterministic state JWT token
get :connect, enterprise_id: 1 # A deterministic id results in a deterministic state JWT token
expect(response).to redirect_to("https://connect.stripe.com/oauth/authorize?state=eyJhbGciOiJIUzI1NiJ9.eyJlbnRlcnByaXNlX2lkIjoiMSJ9.jSSFGn0bLhwuiQYK5ORmHWW7aay1l030bcfGwn1JbFg&scope=read_write&client_id=some_id&response_type=code")
end
@@ -98,7 +98,7 @@ describe Admin::StripeAccountsController, type: :controller do
end
it "redirects to unauthorized" do
spree_get :status, params
get :status, params
expect(response).to redirect_to unauthorized_path
end
end
@@ -110,7 +110,7 @@ describe Admin::StripeAccountsController, type: :controller do
context "when Stripe is not enabled" do
it "returns with a status of 'stripe_disabled'" do
spree_get :status, params
get :status, params
json_response = JSON.parse(response.body)
expect(json_response["status"]).to eq "stripe_disabled"
end
@@ -121,7 +121,7 @@ describe Admin::StripeAccountsController, type: :controller do
context "when no stripe account is associated with the specified enterprise" do
it "returns with a status of 'account_missing'" do
spree_get :status, params
get :status, params
json_response = JSON.parse(response.body)
expect(json_response["status"]).to eq "account_missing"
end
@@ -136,7 +136,7 @@ describe Admin::StripeAccountsController, type: :controller do
end
it "returns with a status of 'access_revoked'" do
spree_get :status, params
get :status, params
json_response = JSON.parse(response.body)
expect(json_response["status"]).to eq "access_revoked"
end
@@ -157,7 +157,7 @@ describe Admin::StripeAccountsController, type: :controller do
end
it "returns with a status of 'connected'" do
spree_get :status, params
get :status, params
json_response = JSON.parse(response.body)
expect(json_response["status"]).to eq "connected"
# serializes required attrs

View File

@@ -17,7 +17,7 @@ describe Admin::StripeConnectSettingsController, type: :controller do
before { allow(controller).to receive(:spree_current_user) { user } }
it "does not allow access" do
spree_get :edit
get :edit
expect(response).to redirect_to unauthorized_path
end
end
@@ -34,7 +34,7 @@ describe Admin::StripeConnectSettingsController, type: :controller do
end
it "sets the account status to :empty_api_key_error_html" do
spree_get :edit
get :edit
expect(assigns(:stripe_account)[:status]).to eq :empty_api_key_error_html
expect(assigns(:settings).stripe_connect_enabled).to be true
end
@@ -52,7 +52,7 @@ describe Admin::StripeConnectSettingsController, type: :controller do
end
it "sets the account status to :auth_fail_error" do
spree_get :edit
get :edit
expect(assigns(:stripe_account)[:status]).to eq :auth_fail_error
expect(assigns(:settings).stripe_connect_enabled).to be true
end
@@ -65,7 +65,7 @@ describe Admin::StripeConnectSettingsController, type: :controller do
end
it "sets the account status to :ok, loads settings into Struct" do
spree_get :edit
get :edit
expect(assigns(:stripe_account)[:status]).to eq :ok
expect(assigns(:obfuscated_secret_key)).to eq "sk_test_****xxxx"
expect(assigns(:settings).stripe_connect_enabled).to be true
@@ -82,7 +82,7 @@ describe Admin::StripeConnectSettingsController, type: :controller do
before { allow(controller).to receive(:spree_current_user) { user } }
it "does not allow access" do
spree_get :update, params
get :update, params
expect(response).to redirect_to unauthorized_path
end
end
@@ -95,7 +95,7 @@ describe Admin::StripeConnectSettingsController, type: :controller do
it "sets global config to the specified values" do
expect(Spree::Config.stripe_connect_enabled).to be true
spree_get :update, params
get :update, params
expect(Spree::Config.stripe_connect_enabled).to be false
end
end

View File

@@ -19,7 +19,7 @@ describe Admin::SubscriptionsController, type: :controller do
context 'as a regular user' do
it 'redirects to unauthorized' do
spree_get :index, params
get :index, params
expect(response).to redirect_to unauthorized_path
end
end
@@ -32,7 +32,7 @@ describe Admin::SubscriptionsController, type: :controller do
let!(:subscription) { create(:subscription, shop: shop) }
it 'renders the index page with appropriate data' do
spree_get :index, params
get :index, params
expect(response).to render_template 'index'
expect(assigns(:collection)).to eq [] # No collection loaded
expect(assigns(:shops)).to eq [shop] # Shops are loaded
@@ -41,7 +41,7 @@ describe Admin::SubscriptionsController, type: :controller do
context "where I don't manage a shop that is set up for subscriptions" do
it 'renders the setup_explanation page' do
spree_get :index, params
get :index, params
expect(response).to render_template 'setup_explanation'
expect(assigns(:collection)).to eq [] # No collection loaded
expect(assigns(:shop)).to eq shop # First SO enabled shop is loaded
@@ -56,7 +56,7 @@ describe Admin::SubscriptionsController, type: :controller do
context 'as a regular user' do
it 'redirects to unauthorized' do
spree_get :index, params
get :index, params
expect(response).to redirect_to unauthorized_path
end
end
@@ -67,7 +67,7 @@ describe Admin::SubscriptionsController, type: :controller do
let!(:subscription2) { create(:subscription, shop: shop2) }
it 'renders the collection as json' do
spree_get :index, params
get :index, params
json_response = JSON.parse(response.body)
expect(json_response.count).to be 2
expect(json_response.map{ |so| so['id'] }).to include subscription.id, subscription2.id
@@ -77,7 +77,7 @@ describe Admin::SubscriptionsController, type: :controller do
before { params.merge!(q: { shop_id_eq: shop2.id }) }
it "restricts the list of subscriptions" do
spree_get :index, params
get :index, params
json_response = JSON.parse(response.body)
expect(json_response.count).to be 1
ids = json_response.map{ |so| so['id'] }
@@ -99,7 +99,7 @@ describe Admin::SubscriptionsController, type: :controller do
it 'loads the preloads the necessary data' do
expect(controller).to receive(:load_form_data)
spree_get :new, subscription: { shop_id: shop.id }
get :new, subscription: { shop_id: shop.id }
expect(assigns(:subscription)).to be_a_new Subscription
expect(assigns(:subscription).shop).to eq shop
end
@@ -238,7 +238,7 @@ describe Admin::SubscriptionsController, type: :controller do
it 'loads the preloads the necessary data' do
expect(controller).to receive(:load_form_data)
spree_get :edit, id: subscription.id
get :edit, id: subscription.id
expect(assigns(:subscription)).to eq subscription
end
end

View File

@@ -19,7 +19,7 @@ module Api
end
it "lists customers associated with the current user" do
spree_get :index
get :index
expect(response.status).to eq 200
expect(json_response.length).to eq 1
expect(json_response.first[:id]).to eq customer1.id

View File

@@ -26,7 +26,7 @@ module Api
let(:products_relation) { Spree::Product.where("1=0") }
it "handles it gracefully" do
spree_get :index, exchange_id: exchange.id
get :index, exchange_id: exchange.id
expect(json_response["products"].length).to eq 0
end
end
@@ -36,7 +36,7 @@ module Api
describe "when an exchange id param is provided" do
it "uses exchange order_cycle, incoming and enterprise to fetch products" do
spree_get :index, exchange_id: exchange.id, order_cycle_id: 666, enterprise_id: 666, incoming: false
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
@@ -59,7 +59,7 @@ module Api
describe "when a specific page is requested" do
it "returns the requested page with paginated data" do
spree_get :index, exchange_id: exchange.id, page: 1
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
spree_get :index, exchange_id: exchange.id
get :index, exchange_id: exchange.id
expect(json_response["products"].size).to eq 2
expect(json_response["pagination"]).to be nil

View File

@@ -23,7 +23,7 @@ describe Api::ShopsController, type: :controller do
describe "#show" do
it "returns shopfront data for an enterprise" do
spree_get :show, id: producer.id
get :show, id: producer.id
expect(json_response['name']).to eq 'Shopfront Test Producer'
expect(json_response['hubs'][0]['name']).to eq 'Shopfront Test Hub'
@@ -33,7 +33,7 @@ describe Api::ShopsController, type: :controller do
describe "#closed_shops" do
it "returns data for all closed shops" do
spree_get :closed_shops, {}
get :closed_shops, {}
expect(json_response).not_to match hub.name

View File

@@ -9,21 +9,21 @@ module Api
describe "job queue status" do
it "returns alive when up to date" do
Spree::Config.last_job_queue_heartbeat_at = Time.now.in_time_zone
spree_get :job_queue
get :job_queue
expect(response).to be_success
expect(response.body).to eq({ alive: true }.to_json)
end
it "returns dead otherwise" do
Spree::Config.last_job_queue_heartbeat_at = 10.minutes.ago
spree_get :job_queue
get :job_queue
expect(response).to be_success
expect(response.body).to eq({ alive: false }.to_json)
end
it "returns dead when no heartbeat recorded" do
Spree::Config.last_job_queue_heartbeat_at = nil
spree_get :job_queue
get :job_queue
expect(response).to be_success
expect(response.body).to eq({ alive: false }.to_json)
end

View File

@@ -26,7 +26,7 @@ describe Api::VariantsController, type: :controller do
end
it "retrieves a list of variants with appropriate attributes" do
spree_get :index, format: :json
get :index, format: :json
keys = json_response.first.keys.map(&:to_sym)
expect(attributes.all?{ |attr| keys.include? attr }).to eq(true)

View File

@@ -101,7 +101,7 @@ describe BaseController, type: :controller do
end
it "redirects to home with message if order cycle is expired" do
expect(controller).to receive(:current_order_cycle).and_return(oc).twice
expect(controller).to receive(:current_order_cycle).and_return(oc)
expect(controller).to receive(:current_order).and_return(order).twice
expect(oc).to receive(:closed?).and_return(true)
expect(order).to receive(:empty!)
@@ -109,7 +109,6 @@ describe BaseController, type: :controller do
get :index
expect(session[:expired_order_cycle_id]).to eq oc.id
expect(response).to redirect_to root_url
expect(flash[:info]).to eq I18n.t('order_cycle_closed')
end

View File

@@ -82,7 +82,7 @@ describe CheckoutController, concurrency: true, type: :controller do
# see the order page. This is basically verifying a "double click"
# scenario.
expect(response.status).to eq(200)
expect(response.body).to eq({ path: spree.order_path(order) }.to_json)
expect(response.body).to eq({ path: order_path(order) }.to_json)
expect(order.payments.count).to eq 1
expect(order.completed?).to be true
end

View File

@@ -110,7 +110,7 @@ describe CheckoutController, type: :controller do
it "completes the order and redirects to the order confirmation page" do
get :edit, { payment_intent: "pi_123" }
expect(order.completed?).to be true
expect(response).to redirect_to spree.order_path(order)
expect(response).to redirect_to order_path(order)
end
end
end
@@ -242,7 +242,7 @@ describe CheckoutController, type: :controller do
spree_post :update, format: :json, order: {}
expect(response.status).to eq(200)
expect(response.body).to eq({ path: spree.order_path(order) }.to_json)
expect(response.body).to eq({ path: order_path(order) }.to_json)
end
it "returns an error on unexpected failure" do

View File

@@ -18,7 +18,7 @@ describe EnterprisesController, type: :controller do
end
it "sets the shop as the distributor on the order when shopping for the distributor" do
spree_get :shop, id: distributor
get :shop, id: distributor
expect(controller.current_distributor).to eq(distributor)
expect(controller.current_order.distributor).to eq(distributor)
@@ -29,7 +29,7 @@ describe EnterprisesController, type: :controller do
before { allow(controller).to receive(:spree_current_user) { user } }
it "sets the shop as the distributor on the order when shopping for the distributor" do
spree_get :shop, id: distributor
get :shop, id: distributor
expect(controller.current_distributor).to eq(distributor)
expect(controller.current_order.distributor).to eq(distributor)
@@ -39,11 +39,11 @@ describe EnterprisesController, type: :controller do
it "sorts order cycles by the distributor's preferred ordering attr" do
distributor.update_attribute(:preferred_shopfront_order_cycle_order, 'orders_close_at')
spree_get :shop, id: distributor
get :shop, id: distributor
expect(assigns(:order_cycles)).to eq([order_cycle1, order_cycle2].sort_by(&:orders_close_at))
distributor.update_attribute(:preferred_shopfront_order_cycle_order, 'orders_open_at')
spree_get :shop, id: distributor
get :shop, id: distributor
expect(assigns(:order_cycles)).to eq([order_cycle1, order_cycle2].sort_by(&:orders_open_at))
end
@@ -64,23 +64,23 @@ describe EnterprisesController, type: :controller do
preferred_exchange_tags: "wholesale",
preferred_matched_order_cycles_visibility: 'hidden')
spree_get :shop, id: distributor
get :shop, id: distributor
expect(assigns(:order_cycles)).to include order_cycle1, order_cycle2, order_cycle3
allow(controller).to receive(:spree_current_user) { user }
spree_get :shop, id: distributor
get :shop, id: distributor
expect(assigns(:order_cycles)).to include order_cycle1, order_cycle2, order_cycle3
oc3_exchange.update_attribute(:tag_list, "wholesale")
spree_get :shop, id: distributor
get :shop, id: distributor
expect(assigns(:order_cycles)).to include order_cycle1, order_cycle2
expect(assigns(:order_cycles)).not_to include order_cycle3
customer.update_attribute(:tag_list, ["wholesale"])
spree_get :shop, id: distributor
get :shop, id: distributor
expect(assigns(:order_cycles)).to include order_cycle1, order_cycle2, order_cycle3
end
end
@@ -89,7 +89,7 @@ describe EnterprisesController, type: :controller do
line_item = create(:line_item)
controller.current_order.line_items << line_item
spree_get :shop, id: distributor
get :shop, id: distributor
expect(controller.current_order.distributor).to eq(distributor)
expect(controller.current_order.order_cycle).to be_nil
@@ -97,7 +97,7 @@ describe EnterprisesController, type: :controller do
end
it "should not empty an order if returning to the same distributor" do
spree_get :shop, id: current_distributor
get :shop, id: current_distributor
expect(controller.current_order.distributor).to eq current_distributor
expect(controller.current_order.line_items.first.variant).to eq line_item.variant
@@ -117,7 +117,7 @@ describe EnterprisesController, type: :controller do
end
it "redirects to the cart" do
spree_get :shop, id: current_distributor
get :shop, id: current_distributor
expect(response).to redirect_to cart_path
end
@@ -129,7 +129,7 @@ describe EnterprisesController, type: :controller do
order.save
order_cycle1.update_attribute :orders_close_at, Time.zone.now
spree_get :shop, id: distributor
get :shop, id: distributor
expect(controller.current_order.distributor).to eq(distributor)
expect(controller.current_order.order_cycle).to eq(order_cycle2)
@@ -139,7 +139,7 @@ describe EnterprisesController, type: :controller do
it "sets order cycle if only one is available at the chosen distributor" do
order_cycle2.destroy
spree_get :shop, id: distributor
get :shop, id: distributor
expect(controller.current_order.distributor).to eq(distributor)
expect(controller.current_order.order_cycle).to eq(order_cycle1)
@@ -155,7 +155,7 @@ describe EnterprisesController, type: :controller do
end
it "responds with status of 409 when the permalink matches an existing route" do
# spree_get :check_permalink, { permalink: 'enterprise_permalink', format: :js }
# get :check_permalink, { permalink: 'enterprise_permalink', format: :js }
# expect(response.status).to be 409
xhr :get, :check_permalink, permalink: 'map', format: :js
expect(response.status).to be 409
@@ -166,7 +166,7 @@ describe EnterprisesController, type: :controller do
context "checking access on nonexistent enterprise" do
before do
spree_get :shop, id: "some_nonexistent_enterprise"
get :shop, id: "some_nonexistent_enterprise"
end
it "redirects to shops_path" do

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