mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-01 21:47:16 +00:00
Merge pull request #3164 from luisramos0/2-0-stable-dec-3rd
[Spree Upgrade] Merging master into 2-0-stable (first run in Dec2018)
This commit is contained in:
@@ -186,6 +186,9 @@ Lint/AssignmentInCondition:
|
||||
Metrics/AbcSize:
|
||||
Max: 15
|
||||
|
||||
Metrics/BlockLength:
|
||||
ExcludedMethods: ["describe", "context"]
|
||||
|
||||
Metrics/BlockNesting:
|
||||
Max: 3
|
||||
|
||||
|
||||
2
Gemfile
2
Gemfile
@@ -154,4 +154,6 @@ group :development do
|
||||
# While we don't require this gem directly, no dependents forced the upgrade to a version
|
||||
# greater than 1.0.9, so we just required the latest available version here.
|
||||
gem 'eventmachine', '>= 1.2.3'
|
||||
|
||||
gem 'rack-mini-profiler', '< 1.0.0'
|
||||
end
|
||||
|
||||
@@ -578,6 +578,8 @@ GEM
|
||||
rack (1.4.7)
|
||||
rack-cache (1.8.0)
|
||||
rack (>= 0.4)
|
||||
rack-mini-profiler (0.10.7)
|
||||
rack (>= 1.2.0)
|
||||
rack-rewrite (1.5.1)
|
||||
rack-ssl (1.3.4)
|
||||
rack
|
||||
@@ -683,7 +685,7 @@ GEM
|
||||
json (>= 1.8, < 3)
|
||||
simplecov-html (~> 0.10.0)
|
||||
simplecov-html (0.10.2)
|
||||
skylight (1.6.1)
|
||||
skylight (1.7.1)
|
||||
activesupport (>= 3.0.0)
|
||||
spinjs-rails (1.3)
|
||||
rails (>= 3.1)
|
||||
@@ -716,7 +718,7 @@ GEM
|
||||
unicorn (5.4.1)
|
||||
kgio (~> 2.6)
|
||||
raindrops (~> 0.7)
|
||||
unicorn-rails (1.1.0)
|
||||
unicorn-rails (2.2.1)
|
||||
rack
|
||||
unicorn
|
||||
uuidtools (2.1.5)
|
||||
@@ -809,6 +811,7 @@ DEPENDENCIES
|
||||
poltergeist (>= 1.16.0)
|
||||
pry-byebug (>= 3.4.3)
|
||||
rabl
|
||||
rack-mini-profiler (< 1.0.0)
|
||||
rack-rewrite
|
||||
rack-ssl
|
||||
rails (~> 3.2.22)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
angular.module('admin.enterpriseFees').directive 'spreeDeleteResource', ->
|
||||
(scope, element, attrs) ->
|
||||
if scope.enterprise_fee.id
|
||||
url = '/admin/enterprise_fees/' + scope.enterprise_fee.id
|
||||
url = '/api/enterprise_fees/' + scope.enterprise_fee.id
|
||||
html = '<a href="' + url + '" class="delete-resource icon_link icon-trash no-text" data-action="remove" data-confirm="' + t('are_you_sure') + '" url="' + url + '"></a>'
|
||||
#var html = '<a href="'+url+'" class="delete-resource" data-confirm="Are you sure?"><img alt="Delete" src="/assets/admin/icons/delete.png" /> Delete</a>';
|
||||
element.append html
|
||||
|
||||
@@ -1,25 +1,22 @@
|
||||
Darkswarm.controller "AccordionCtrl", ($scope, localStorageService, $timeout, $document, CurrentHub) ->
|
||||
key = "accordion_#{$scope.order.id}#{CurrentHub.hub.id}#{$scope.order.user_id}"
|
||||
value = if localStorageService.get(key) then {} else { details: true, billing: false, shipping: false, payment: false }
|
||||
localStorageService.bind $scope, "accordion", value, key
|
||||
$scope.accordionSections = ["details", "billing", "shipping", "payment"]
|
||||
# Scrolling is confused by our position:fixed top bar - add an offset to scroll
|
||||
# to the correct location, plus 5px buffer
|
||||
offset_height = $("nav.top-bar").height() + 5
|
||||
$scope.accordion = { details: true, billing: true, shipping: true, payment: true }
|
||||
|
||||
$scope.show = (section)->
|
||||
$scope.show = (section) ->
|
||||
$scope.accordion[section] = true
|
||||
# If we call scrollTo() directly after show(), when one of the accordions above the
|
||||
# scroll location is closed by show(), scrollTo() will scroll to the old location of
|
||||
# the element. Putting this in a 50 ms timeout is enough delay for the DOM to
|
||||
# have updated.
|
||||
$timeout ->
|
||||
$document.scrollTo($("##{section}"), offset_height, 500)
|
||||
, 50
|
||||
|
||||
$scope.scrollTo = (section) ->
|
||||
# Scrolling is confused by our position:fixed top bar - add an offset to scroll
|
||||
# to the correct location, plus 5px buffer
|
||||
offset_height = $("nav.top-bar").height() + 5
|
||||
$document.scrollTo($("##{section}"), offset_height, 400)
|
||||
|
||||
$scope.$on 'purchaseFormInvalid', (event, form) ->
|
||||
# Scroll to first invalid section
|
||||
for section in $scope.accordionSections
|
||||
if not form[section].$valid
|
||||
$scope.show section
|
||||
$timeout ->
|
||||
$scope.scrollTo(section)
|
||||
, 50
|
||||
break
|
||||
|
||||
@@ -5,7 +5,7 @@ Darkswarm.controller "BillingCtrl", ($scope, $timeout) ->
|
||||
|
||||
$scope.summary = ->
|
||||
[$scope.order.bill_address.address1,
|
||||
$scope.order.bill_address.city,
|
||||
$scope.order.bill_address.city,
|
||||
$scope.order.bill_address.zipcode]
|
||||
|
||||
$timeout $scope.onTimeout
|
||||
$timeout $scope.onTimeout
|
||||
|
||||
@@ -13,11 +13,11 @@ Darkswarm.controller "DetailsCtrl", ($scope, $timeout, $http, CurrentUser, Authe
|
||||
|
||||
$scope.summary = ->
|
||||
[$scope.fullName(),
|
||||
$scope.order.email,
|
||||
$scope.order.email,
|
||||
$scope.order.bill_address.phone]
|
||||
|
||||
$scope.fullName = ->
|
||||
[$scope.order.bill_address.firstname ? null,
|
||||
[$scope.order.bill_address.firstname ? null,
|
||||
$scope.order.bill_address.lastname ? null].join(" ").trim()
|
||||
|
||||
$timeout $scope.onTimeout
|
||||
$timeout $scope.onTimeout
|
||||
|
||||
@@ -2,11 +2,11 @@ window.FieldsetMixin = ($scope)->
|
||||
$scope.next = (event = false)->
|
||||
event.preventDefault() if event
|
||||
return unless $scope.nextPanel
|
||||
$scope.accordion[$scope.name] = false
|
||||
$scope.show $scope.nextPanel
|
||||
|
||||
$scope.onTimeout = ->
|
||||
if $scope[$scope.name].$valid
|
||||
$scope.next()
|
||||
$scope.accordion[$scope.name] = !$scope[$scope.name].$valid
|
||||
|
||||
$scope.valid = ->
|
||||
$scope.form().$valid
|
||||
|
||||
@@ -2,7 +2,6 @@ module Admin
|
||||
class EnterpriseFeesController < ResourceController
|
||||
before_filter :load_enterprise_fee_set, :only => :index
|
||||
before_filter :load_data
|
||||
before_filter :do_not_destroy_referenced_fees, :only => :destroy
|
||||
|
||||
|
||||
def index
|
||||
@@ -45,22 +44,6 @@ module Admin
|
||||
|
||||
private
|
||||
|
||||
def do_not_destroy_referenced_fees
|
||||
product_distribution = ProductDistribution.where(:enterprise_fee_id => @object).first
|
||||
if product_distribution
|
||||
p = product_distribution.product
|
||||
error = I18n.t(:enterprise_fees_destroy_error, id: p.id, name: p.name)
|
||||
|
||||
respond_with(@object) do |format|
|
||||
format.html do
|
||||
flash[:error] = error
|
||||
redirect_to collection_url
|
||||
end
|
||||
format.js { render text: error, status: 403 }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def load_enterprise_fee_set
|
||||
@enterprise_fee_set = EnterpriseFeeSet.new :collection => collection
|
||||
end
|
||||
|
||||
21
app/controllers/api/enterprise_fees_controller.rb
Normal file
21
app/controllers/api/enterprise_fees_controller.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
module Api
|
||||
class EnterpriseFeesController < BaseController
|
||||
respond_to :json
|
||||
|
||||
def destroy
|
||||
authorize! :destroy, enterprise_fee
|
||||
|
||||
if enterprise_fee.destroy
|
||||
render text: I18n.t(:successfully_removed), status: 204
|
||||
else
|
||||
render text: enterprise_fee.errors.full_messages.first, status: 403
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def enterprise_fee
|
||||
@enterprise_fee ||= EnterpriseFee.find_by_id params[:id]
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -55,7 +55,7 @@ module EnterprisesHelper
|
||||
if enterprise.sells == 'none'
|
||||
enterprise.producer_profile_only ? I18n.t(:profile) : I18n.t(:supplier_only)
|
||||
else
|
||||
"Has Shopfront"
|
||||
I18n.t(:has_shopfront)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ class EnterpriseFee < ActiveRecord::Base
|
||||
validates_presence_of :name
|
||||
|
||||
before_save :ensure_valid_tax_category_settings
|
||||
before_destroy :ensure_no_product_distributions
|
||||
|
||||
scope :for_enterprise, lambda { |enterprise| where(enterprise_id: enterprise) }
|
||||
scope :for_enterprises, lambda { |enterprises| where(enterprise_id: enterprises) }
|
||||
@@ -68,6 +69,15 @@ class EnterpriseFee < ActiveRecord::Base
|
||||
return true
|
||||
end
|
||||
|
||||
def ensure_no_product_distributions
|
||||
dependent_distribution = ProductDistribution.where(enterprise_fee_id: self).first
|
||||
return unless dependent_distribution
|
||||
product = dependent_distribution.product
|
||||
error = I18n.t(:enterprise_fees_destroy_error, id: product.id, name: product.name)
|
||||
errors.add(:base, error)
|
||||
false
|
||||
end
|
||||
|
||||
def refresh_products_cache
|
||||
OpenFoodNetwork::ProductsCache.enterprise_fee_changed self
|
||||
end
|
||||
|
||||
@@ -100,7 +100,8 @@ module ProductImport
|
||||
entries[entry.line_number] = {
|
||||
attributes: entry.displayable_attributes,
|
||||
validates_as: entry.validates_as,
|
||||
errors: entry.invalid_attributes
|
||||
errors: entry.invalid_attributes,
|
||||
product_validations: entry.product_validations
|
||||
}
|
||||
end
|
||||
entries.to_json
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
/ insert_before "[data-hook='admin_order_form_buttons']"
|
||||
|
||||
= render partial: 'spree/admin/orders/_form/distribution_fields'
|
||||
@@ -1,2 +0,0 @@
|
||||
add_to_attributes "table.index, [data-hook='admin_order_form_buttons']"
|
||||
attributes "ng-show" => "distributionChosen()"
|
||||
@@ -1,3 +0,0 @@
|
||||
/ replace "code[erb-loud]:contains('button t(:update)')"
|
||||
|
||||
= button t(:update_and_recalculate_fees), 'icon-refresh'
|
||||
@@ -1,3 +0,0 @@
|
||||
/ replace 'code[erb-loud]:contains(\'"(#{f.object.variant.options_text})"\')'
|
||||
|
||||
= "(#{f.object.full_name})"
|
||||
@@ -1,3 +0,0 @@
|
||||
/ replace 'code[erb-loud]:contains(\'f.object.variant.display_amount\')'
|
||||
|
||||
= f.object.single_money
|
||||
@@ -1,6 +0,0 @@
|
||||
/ insert_after "code[erb-loud]:contains('button_link_to t(:resend)')"
|
||||
|
||||
%li.links-dropdown#links-dropdown{ links: order_links(@order).to_json }
|
||||
|
||||
:coffee
|
||||
angular.bootstrap(document.getElementById("links-dropdown"),['admin.dropdown'])
|
||||
@@ -1,6 +0,0 @@
|
||||
/ replace "code[erb-loud]:contains(\'error_messages\')"
|
||||
|
||||
-# Suppress errors when manually creating a new order - needs to proceed to edit page
|
||||
-# without having line items (which otherwise gives a validation error)
|
||||
- unless params["suppress_error_msg"]
|
||||
= render partial: "spree/shared/error_messages", :locals => { :target => @order }
|
||||
@@ -1,3 +0,0 @@
|
||||
/ replace "[data-hook=admin_product_form_left] code[erb-loud]:contains('f.text_area :description')"
|
||||
%text-angular{'id' => 'product_description', 'name' => 'product[description]', 'class' => 'text-angular', 'textangular-strip' => true, 'ta-paste' => "stripFormatting($html)", 'ta-toolbar' => "[['bold','italics','clear']]"}
|
||||
= sanitize(@product.description)
|
||||
@@ -1,3 +0,0 @@
|
||||
/ insert_after "div[class='variant_units_form']"
|
||||
|
||||
= render 'spree/admin/products/primary_taxon_form', f: f
|
||||
@@ -1,6 +0,0 @@
|
||||
/ insert_before "code[erb-loud]:contains('f.field_container :price')"
|
||||
= f.field_container :supplier do
|
||||
= f.label :supplier, t(:spree_admin_supplier)
|
||||
%br
|
||||
= f.collection_select(:supplier_id, @producers, :id, :name, {:include_blank => true}, {:class => "select2"})
|
||||
= f.error_message_on :supplier
|
||||
@@ -1,17 +0,0 @@
|
||||
/ insert_top "[data-hook='admin_product_form_right']"
|
||||
|
||||
.variant_units_form{ 'ng-app' => 'admin.products', 'ng-controller' => 'editUnitsCtrl' }
|
||||
|
||||
= f.field_container :units do
|
||||
= f.label :variant_unit_with_scale, t(:spree_admin_variant_unit_scale)
|
||||
%select.select2.fullwidth{ id: 'product_variant_unit_with_scale', 'ng-model' => 'variant_unit_with_scale', 'ng-change' => 'setFields()', 'ng-options' => 'unit[1] as unit[0] for unit in variant_unit_options' }
|
||||
%option{'value' => ''}
|
||||
|
||||
= f.text_field :variant_unit, {'id' => 'variant_unit', 'ng-value' => 'product.variant_unit', 'hidden' => true}
|
||||
= f.text_field :variant_unit_scale, {'id' => 'variant_unit_scale', 'ng-value' => 'product.variant_unit_scale', 'hidden' => true}
|
||||
|
||||
.variant_unit_name{'ng-show' => 'product.variant_unit == "items"'}
|
||||
= f.field_container :variant_unit_name do
|
||||
= f.label :variant_unit_name, t(:spree_admin_variant_unit_name)
|
||||
= f.text_field :variant_unit_name, {placeholder: t('admin.products.unit_name_placeholder')}
|
||||
= f.error_message_on :variant_unit_name
|
||||
@@ -1,2 +0,0 @@
|
||||
remove "code[erb-loud]:contains('f.label :available_on')"
|
||||
closing_selector("code[erb-loud]:contains('f.text_field :available_on')")
|
||||
@@ -1,2 +0,0 @@
|
||||
remove "code[erb-loud]:contains('f.field_container :cost_currency')"
|
||||
closing_selector("code[erb-silent]:contains('end')")
|
||||
@@ -1,2 +0,0 @@
|
||||
remove "code[erb-loud]:contains('f.field_container :cost_price')"
|
||||
closing_selector("code[erb-silent]:contains('end')")
|
||||
@@ -1 +0,0 @@
|
||||
remove "div[data-hook='admin_product_form_meta']"
|
||||
@@ -1 +0,0 @@
|
||||
remove "div[class='twelve columns alpha omega']"
|
||||
@@ -1,2 +0,0 @@
|
||||
/ replace "[data-hook=admin_product_form_right] code[erb-loud]:contains('f.label :price')"
|
||||
= f.label :price, raw(t(:price) + content_tag(:span, ' *', :class => 'required'))
|
||||
@@ -1,5 +0,0 @@
|
||||
/ insert_bottom "[data-hook=admin_product_form_left]"
|
||||
= f.field_container :taxons do
|
||||
= f.label :taxon_ids, t(:taxons)
|
||||
%br
|
||||
= f.hidden_field :taxon_ids, :value => @product.taxon_ids.join(',')
|
||||
@@ -1,2 +0,0 @@
|
||||
add_to_attributes 'fieldset.no-border-top'
|
||||
attributes 'ng-app' => 'admin.products'
|
||||
@@ -1,3 +0,0 @@
|
||||
/ replace_contents "#new_product_link"
|
||||
|
||||
= button_link_to t(:new_product), new_object_url, {:icon => 'icon-plus', :id => 'admin_new_product' }
|
||||
@@ -1,3 +0,0 @@
|
||||
/ replace "code[erb-loud]:contains('button_link_to t(:back_to_products_list)')"
|
||||
|
||||
= button_link_to t('admin.products.back_to_products_list'), admin_products_path, :icon => 'icon-arrow-left'
|
||||
@@ -7,3 +7,5 @@
|
||||
( {{entry.attributes.display_name}} )
|
||||
%p.error{ng: {repeat: "(attribute, error) in entry.errors", show: "ignore_fields.indexOf(attribute) < 0" }}
|
||||
- {{error}}
|
||||
%p.error{ng: {repeat: "(attribute, error) in entry.product_validations"}}
|
||||
- {{error}}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
= render partial: "shopping_shared/details"
|
||||
|
||||
%accordion{"close-others" => "true"}
|
||||
%accordion{"close-others" => "false"}
|
||||
%checkout.row{"ng-controller" => "CheckoutCtrl"}
|
||||
.small-12.medium-8.large-9.columns
|
||||
- unless spree_current_user
|
||||
|
||||
17
app/views/spree/admin/orders/_add_product.html.haml
Normal file
17
app/views/spree/admin/orders/_add_product.html.haml
Normal file
@@ -0,0 +1,17 @@
|
||||
= render partial: "spree/admin/variants/autocomplete", formats: :js
|
||||
#add-line-item
|
||||
%fieldset
|
||||
%legend{align: "center"}
|
||||
= t(:add_product)
|
||||
.field.eight.columns.alpha
|
||||
= label_tag :add_product_name, t(:name_or_sku)
|
||||
= hidden_field_tag :add_variant_id, "", class: "variant_autocomplete fullwidth"
|
||||
.field.two.columns
|
||||
= label_tag :add_quantity, t(:qty)
|
||||
= number_field_tag :add_quantity, 1, min: 0
|
||||
.actions.two.columns.omega
|
||||
= link_to_with_icon 'icon-plus', t(:add), admin_order_line_items_url(@order),
|
||||
method: :post,
|
||||
id: 'add_line_item_to_order',
|
||||
class: 'button fullwidth',
|
||||
'data-update' => 'order-form-wrapper'
|
||||
68
app/views/spree/admin/orders/_form.html.haml
Normal file
68
app/views/spree/admin/orders/_form.html.haml
Normal file
@@ -0,0 +1,68 @@
|
||||
%div
|
||||
- if @line_item.try(:errors).present?
|
||||
= render partial: 'spree/shared/error_messages', locals: { target: @line_item }
|
||||
= form_for @order, url: admin_order_url(@order), method: :put do |f|
|
||||
%fieldset.no-border-top
|
||||
= f.hidden_field :number
|
||||
%table.index{"ng-show" => "distributionChosen()"}
|
||||
%colgroup
|
||||
%col{style: "width: 49%;"}/
|
||||
%col{style: "width: 14%;"}/
|
||||
%col{style: "width: 10%;"}/
|
||||
%col{style: "width: 14%;"}/
|
||||
%col{style: "width: 8%;"}/
|
||||
%thead#line-items
|
||||
%tr
|
||||
%th
|
||||
= t(:item_description)
|
||||
%th.price
|
||||
= t(:price)
|
||||
%th.qty
|
||||
= t(:qty)
|
||||
%th.total
|
||||
%span
|
||||
= t(:total)
|
||||
%th.orders-actions.actions
|
||||
%tbody
|
||||
= f.fields_for :line_items do |li_form|
|
||||
= render partial: 'spree/admin/orders/line_item', locals: { f: li_form }
|
||||
%tbody#subtotal.no-border-top
|
||||
%tr#subtotal-row
|
||||
%td{colspan: "3"}
|
||||
%b
|
||||
= t(:subtotal)
|
||||
\:
|
||||
%td.total.align-center
|
||||
%span
|
||||
= @order.display_item_total.to_html
|
||||
%td.actions
|
||||
%tbody#order-charges.no-border-top
|
||||
- @order.adjustments.eligible.each do |adjustment|
|
||||
%tr
|
||||
%td{colspan: "3"}
|
||||
%strong
|
||||
= adjustment.label
|
||||
\:
|
||||
%td.total.align-center
|
||||
%span= adjustment.display_amount.to_html
|
||||
%td.actions
|
||||
%tbody#order-total.grand-total.no-border-top
|
||||
%tr
|
||||
%td{colspan: "3"}
|
||||
%b
|
||||
= t(:order_total)
|
||||
\:
|
||||
%td.total.align-center
|
||||
%span#order_total
|
||||
= @order.display_total.to_html
|
||||
%td.actions
|
||||
|
||||
= render partial: 'spree/admin/orders/_form/distribution_fields'
|
||||
|
||||
.filter-actions.actions{"ng-show" => "distributionChosen()"}
|
||||
= button t(:update_and_recalculate_fees), 'icon-refresh'
|
||||
%span.or
|
||||
= t(:or)
|
||||
= link_to_with_icon 'button icon-arrow-left', t(:back), admin_orders_url
|
||||
= javascript_tag do
|
||||
= render partial: 'spree/admin/shared/update_order_state', handlers: [:js]
|
||||
12
app/views/spree/admin/orders/_line_item.html.haml
Normal file
12
app/views/spree/admin/orders/_line_item.html.haml
Normal file
@@ -0,0 +1,12 @@
|
||||
%tr{id: "#{spree_dom_id(f.object)}", class: "#{cycle('odd', 'even')}"}
|
||||
%td
|
||||
= f.object.variant.product.name
|
||||
= "(#{f.object.full_name})" unless f.object.variant.option_values.empty?
|
||||
%td.price.align-center
|
||||
= f.object.variant.display_amount
|
||||
%td.qty
|
||||
= f.number_field :quantity, min: 0, class: "qty"
|
||||
%td.total.align-center
|
||||
= f.object.single_money
|
||||
%td.actions
|
||||
= link_to_delete f.object, {url: admin_order_line_item_url(@order.number, f.object), no_text: true}
|
||||
@@ -3,6 +3,8 @@
|
||||
- content_for :page_actions do
|
||||
%li= event_links
|
||||
%li= button_link_to t(:resend), resend_admin_order_url(@order), method: :post, icon: 'icon-email'
|
||||
%li.links-dropdown#links-dropdown{ links: order_links(@order).to_json }
|
||||
|
||||
%li= button_link_to t(:back_to_orders_list), admin_orders_path, icon: 'icon-arrow-left'
|
||||
|
||||
= admin_inject_shops(module: 'admin.orders')
|
||||
@@ -10,15 +12,19 @@
|
||||
|
||||
= render 'spree/admin/shared/order_tabs', current: 'Order Details'
|
||||
|
||||
%div{"data-hook" => "admin_order_edit_header"}
|
||||
= render 'spree/shared/error_messages', target: @order
|
||||
%div
|
||||
- unless params["suppress_error_msg"]
|
||||
= render partial: "spree/shared/error_messages", :locals => { :target => @order }
|
||||
|
||||
%div{"ng-app" => "admin.orders", "ng-controller" => "orderCtrl", "ofn-distributor-id" => @order.distributor_id, "ofn-order-cycle-id" => @order.order_cycle_id}
|
||||
= render 'add_product'
|
||||
|
||||
%div{"data-hook" => "admin_order_edit_form"}
|
||||
%div
|
||||
#order-form-wrapper
|
||||
= render 'form', order: @order
|
||||
|
||||
- content_for :head do
|
||||
= javascript_tag 'var expand_variants = true;'
|
||||
|
||||
:coffee
|
||||
angular.bootstrap(document.getElementById("links-dropdown"),['admin.dropdown'])
|
||||
|
||||
106
app/views/spree/admin/products/_form.html.haml
Normal file
106
app/views/spree/admin/products/_form.html.haml
Normal file
@@ -0,0 +1,106 @@
|
||||
%div{"data-hook" => "admin_product_form_fields"}
|
||||
.left.eight.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'
|
||||
= f.error_message_on :name
|
||||
|
||||
= f.field_container :permalink do
|
||||
= f.label :permalink, raw(t(:permalink) + content_tag(:span, ' *', :class => "required"))
|
||||
= f.text_field :permalink, :class => 'fullwidth title'
|
||||
= f.error_message_on :permalink
|
||||
|
||||
= f.field_container :description do
|
||||
= f.label :description, t(:description)
|
||||
%text-angular{'id' => 'product_description', 'name' => 'product[description]', 'class' => 'text-angular', 'textangular-strip' => true, 'ta-paste' => "stripFormatting($html)", 'ta-toolbar' => "[['bold','italics','clear']]"}
|
||||
= sanitize(@product.description)
|
||||
= f.error_message_on :description
|
||||
|
||||
= f.field_container :taxons do
|
||||
= f.label :taxon_ids, t(:taxons)
|
||||
%br
|
||||
= f.hidden_field :taxon_ids, :value => @product.taxon_ids.join(',')
|
||||
|
||||
.right.four.columns.omega
|
||||
.variant_units_form{ 'ng-app' => 'admin.products', 'ng-controller' => 'editUnitsCtrl' }
|
||||
|
||||
= f.field_container :units do
|
||||
= f.label :variant_unit_with_scale, t(:spree_admin_variant_unit_scale)
|
||||
%select.select2.fullwidth{ id: 'product_variant_unit_with_scale', 'ng-model' => 'variant_unit_with_scale', 'ng-change' => 'setFields()', 'ng-options' => 'unit[1] as unit[0] for unit in variant_unit_options' }
|
||||
%option{'value' => ''}
|
||||
|
||||
= f.text_field :variant_unit, {'id' => 'variant_unit', 'ng-value' => 'product.variant_unit', 'hidden' => true}
|
||||
= f.text_field :variant_unit_scale, {'id' => 'variant_unit_scale', 'ng-value' => 'product.variant_unit_scale', 'hidden' => true}
|
||||
|
||||
.variant_unit_name{'ng-show' => 'product.variant_unit == "items"'}
|
||||
= f.field_container :variant_unit_name do
|
||||
= f.label :variant_unit_name, t(:spree_admin_variant_unit_name)
|
||||
= f.text_field :variant_unit_name, {placeholder: t('admin.products.unit_name_placeholder')}
|
||||
= f.error_message_on :variant_unit_name
|
||||
|
||||
= render 'spree/admin/products/primary_taxon_form', f: f
|
||||
|
||||
= f.field_container :supplier do
|
||||
= f.label :supplier, t(:spree_admin_supplier)
|
||||
%br
|
||||
= f.collection_select(:supplier_id, @producers, :id, :name, {:include_blank => true}, {:class => "select2"})
|
||||
= f.error_message_on :supplier
|
||||
|
||||
= f.field_container :price do
|
||||
= f.label :price, raw(t(:price) + content_tag(:span, ' *', :class => 'required'))
|
||||
= f.text_field :price, :value => number_to_currency(@product.price, :unit => '')
|
||||
= f.error_message_on :price
|
||||
|
||||
.clear
|
||||
|
||||
- unless @product.has_variants?
|
||||
= f.field_container :sku do
|
||||
= f.label :sku, t(:sku)
|
||||
= f.text_field :sku, :size => 16
|
||||
|
||||
- if Spree::Config[:track_inventory_levels]
|
||||
.alpha.two.columns
|
||||
= f.field_container :on_hand do
|
||||
= f.label :on_hand, t(:on_hand)
|
||||
= f.number_field :on_hand, :min => 0
|
||||
.omega.two.columns
|
||||
= f.field_container :on_demand, :class => ['checkbox'] do
|
||||
%label
|
||||
= f.check_box :on_demand
|
||||
= t(:on_demand)
|
||||
|
||||
.clear
|
||||
|
||||
%ul#shipping_specs
|
||||
%li#shipping_specs_weight_field.field.alpha.two.columns
|
||||
= f.label :weight, t(:weight)
|
||||
= f.text_field :weight, :size => 4
|
||||
%li#shipping_specs_height_field.field.omega.two.columns
|
||||
= f.label :height, t(:height)
|
||||
= f.text_field :height, :size => 4
|
||||
%li#shipping_specs_width_field.field.alpha.two.columns
|
||||
= f.label :width, t(:width)
|
||||
= f.text_field :width, :size => 4
|
||||
%li#shipping_specs_depth_field.field.omega.two.columns
|
||||
= f.label :depth, t(:depth)
|
||||
= f.text_field :depth, :size => 4
|
||||
|
||||
= f.field_container :shipping_categories do
|
||||
= f.label :shipping_category_id, t(:shipping_categories)
|
||||
= f.collection_select(:shipping_category_id, @shipping_categories, :id, :name, { :include_blank => 'None' }, { :class => 'select2' })
|
||||
= f.error_message_on :shipping_category
|
||||
|
||||
= f.field_container :tax_category do
|
||||
= f.label :tax_category_id, t(:tax_category)
|
||||
= f.collection_select(:tax_category_id, @tax_categories, :id, :name, { :include_blank => 'None' }, { :class => 'select2' })
|
||||
= f.error_message_on :tax_category
|
||||
|
||||
.clear
|
||||
|
||||
%div
|
||||
|
||||
.clear
|
||||
|
||||
- unless Rails.env.test?
|
||||
:javascript
|
||||
$('.select2-container').css({width: '20em'})
|
||||
14
app/views/spree/admin/products/edit.html.haml
Normal file
14
app/views/spree/admin/products/edit.html.haml
Normal file
@@ -0,0 +1,14 @@
|
||||
- content_for :page_actions do
|
||||
%li= button_link_to t('admin.products.back_to_products_list'), admin_products_path, :icon => 'icon-arrow-left'
|
||||
%li#new_product_link
|
||||
= button_link_to t(:new_product), new_object_url, { :icon => 'icon-plus', :id => 'admin_new_product' }
|
||||
|
||||
= render :partial => 'spree/admin/shared/product_sub_menu'
|
||||
|
||||
= render :partial => 'spree/admin/shared/product_tabs', :locals => { :current => 'Product Details' }
|
||||
= render :partial => 'spree/shared/error_messages', :locals => { :target => @product }
|
||||
|
||||
= form_for [:admin, @product], :method => :put, :html => { :multipart => true } do |f|
|
||||
%fieldset.no-border-top{'ng-app' => 'admin.products'}
|
||||
= render :partial => 'form', :locals => { :f => f }
|
||||
= render :partial => 'spree/admin/shared/edit_resource_links'
|
||||
75
app/views/spree/admin/shared/_order_tabs.html.haml
Normal file
75
app/views/spree/admin/shared/_order_tabs.html.haml
Normal file
@@ -0,0 +1,75 @@
|
||||
- content_for :page_title do
|
||||
= t(:order)
|
||||
\#
|
||||
= @order.number
|
||||
|
||||
- if @order.bill_address.present?
|
||||
= @order.bill_address.firstname
|
||||
= @order.bill_address.lastname
|
||||
\-
|
||||
|
||||
- content_for :sidebar_title do
|
||||
= t(:order_information)
|
||||
|
||||
- content_for :sidebar do
|
||||
%header#order_tab_summary
|
||||
%dl.additional-info
|
||||
%dt#order_status
|
||||
= t(:status)
|
||||
%dd
|
||||
- order_state_classes = "state #{@order.state}"
|
||||
%span{ class: order_state_classes }
|
||||
= t(@order.state, scope: :order_state)
|
||||
%dt
|
||||
= t(:total)
|
||||
\:
|
||||
%dd#order_total
|
||||
= @order.display_total.to_html
|
||||
|
||||
- if @order.completed?
|
||||
%dt
|
||||
= t(:shipment)
|
||||
\:
|
||||
%dd#shipment_status
|
||||
- shipment_state_classes = "state #{@order.shipment_state}"
|
||||
%span{ class: shipment_state_classes }
|
||||
= t(@order.shipment_state, scope: :shipment_states, default: [:missing, "none"])
|
||||
%dt
|
||||
= t(:payment)
|
||||
\:
|
||||
%dd#payment_status
|
||||
- payment_state_classes = "state #{@order.payment_state}"
|
||||
%span{ class: payment_state_classes }
|
||||
= t(@order.payment_state, scope: :payment_states, default: [:missing, "none"])
|
||||
%dt
|
||||
= t(:date_completed)
|
||||
\:
|
||||
%dd#date_complete
|
||||
= pretty_time(@order.completed_at)
|
||||
|
||||
%nav.menu
|
||||
%ul
|
||||
- order_details_classes = "active" if current == "Order Details"
|
||||
%li{ class: order_details_classes }
|
||||
= link_to_with_icon 'icon-edit', t(:order_details), edit_admin_order_url(@order)
|
||||
|
||||
- customer_details_classes = "active" if current == "Customer Details"
|
||||
%li{ class: customer_details_classes }
|
||||
= link_to_with_icon 'icon-user', t(:customer_details), admin_order_customer_url(@order)
|
||||
|
||||
- adjustments_classes = "active" if current == "Adjustments"
|
||||
%li{ class: adjustments_classes }
|
||||
= link_to_with_icon 'icon-cogs', t(:adjustments), admin_order_adjustments_url(@order)
|
||||
|
||||
- payments_classes = "active" if current == "Payments"
|
||||
%li{ class: payments_classes }
|
||||
= link_to_with_icon 'icon-credit-card', t(:payments), admin_order_payments_url(@order)
|
||||
|
||||
- shipments_classes = "active" if current == "Shipments"
|
||||
%li{ class: shipments_classes }
|
||||
= link_to_with_icon 'icon-road', t(:shipments), admin_order_shipments_url(@order)
|
||||
|
||||
- if @order.completed?
|
||||
- authorizations_classes = "active" if current == "Return Authorizations"
|
||||
%li{ class: authorizations_classes }
|
||||
= link_to_with_icon 'icon-share-alt', t(:return_authorizations), admin_order_return_authorizations_url(@order)
|
||||
@@ -1,11 +1,11 @@
|
||||
.row
|
||||
.alpha.five.columns
|
||||
= f.field_container :email do
|
||||
= f.label :email, Spree.t(:email)
|
||||
= f.label :email, t(".email")
|
||||
= f.email_field :email, class: "fullwidth"
|
||||
= error_message_on :user, :email
|
||||
.field
|
||||
= label_tag nil, Spree.t(:roles)
|
||||
= label_tag nil, t(".roles")
|
||||
%ul
|
||||
- @roles.each do |role|
|
||||
%li
|
||||
@@ -13,14 +13,14 @@
|
||||
= label_tag role.name
|
||||
= hidden_field_tag "user[spree_role_ids][]", ""
|
||||
= f.field_container :enterprise_limit do
|
||||
= f.label :enterprise_limit, t(:enterprise_limit)
|
||||
= f.label :enterprise_limit, t(".enterprise_limit")
|
||||
= f.text_field :enterprise_limit, class: "fullwidth"
|
||||
.omega.five.columns
|
||||
= f.field_container :password do
|
||||
= f.label :password, Spree.t(:password)
|
||||
= f.label :password, t(".password")
|
||||
= f.password_field :password, class: "fullwidth"
|
||||
= f.error_message_on :password
|
||||
= f.field_container :password do
|
||||
= f.label :password_confirmation, Spree.t(:confirm_password)
|
||||
= f.label :password_confirmation, t(".confirm_password")
|
||||
= f.password_field :password_confirmation, class: "fullwidth"
|
||||
= f.error_message_on :password_confirmation
|
||||
@@ -1,10 +1,10 @@
|
||||
- content_for :page_title do
|
||||
= Spree.t(:editing_user)
|
||||
= t(".editing_user")
|
||||
- content_for :page_actions do
|
||||
%li
|
||||
= button_link_to Spree.t(:back_to_users_list), spree.admin_users_path, icon: "icon-arrow-left"
|
||||
= button_link_to t(".back_to_users_list"), spree.admin_users_path, icon: "icon-arrow-left"
|
||||
%fieldset.alpha.ten.columns{"data-hook" => "admin_user_edit_general_settings"}
|
||||
%legend= Spree.t(:general_settings)
|
||||
%legend= t(".general_settings")
|
||||
%div{"data-hook" => "admin_user_edit_form_header"}
|
||||
= render partial: "spree/shared/error_messages", locals: { target: @user }
|
||||
%div{"data-hook" => "admin_user_edit_form"}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
- content_for :page_title do
|
||||
= Spree.t(:listing_users)
|
||||
= t(".listing_users")
|
||||
- content_for :page_actions do
|
||||
%li
|
||||
= button_link_to Spree.t(:new_user), new_object_url, icon: "icon-plus", id: "admin_new_user_link"
|
||||
= button_link_to t(".new_user"), new_object_url, icon: "icon-plus", id: "admin_new_user_link"
|
||||
|
||||
= render "admin/shared/users_sub_menu"
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
%col{ style: "width: 15%" }
|
||||
%thead
|
||||
%tr
|
||||
%th= sort_link @search,:email, Spree.t(:user), {}, {title: "users_email_title"}
|
||||
%th= sort_link @search,:enterprise_limit, t(:enterprise_limit)
|
||||
%th= sort_link @search,:email, t(".user"), {}, {title: "users_email_title"}
|
||||
%th= sort_link @search,:enterprise_limit, t(".enterprise_limit")
|
||||
%th.actions
|
||||
%tbody
|
||||
- @users.each do |user|
|
||||
@@ -28,13 +28,13 @@
|
||||
= link_to_delete user, no_text: true
|
||||
= paginate @users
|
||||
- content_for :sidebar_title do
|
||||
= Spree.t(:search)
|
||||
= t(".search")
|
||||
- content_for :sidebar do
|
||||
.box.align-center
|
||||
= search_form_for [:admin, @search] do |f|
|
||||
.field
|
||||
= f.label Spree.t(:email)
|
||||
= f.label t(".email")
|
||||
%br
|
||||
= f.text_field :email_cont, class: "fullwidth"
|
||||
%div
|
||||
= button Spree.t(:search), "icon-search"
|
||||
= button t(".search"), "icon-search"
|
||||
|
||||
@@ -209,7 +209,6 @@ en:
|
||||
distributors: Distributors
|
||||
distribution: Distribution
|
||||
order_cycles: Order Cycles
|
||||
enterprise_limit: Enterprise Limit
|
||||
bulk_order_management: Bulk Order Management
|
||||
enterprises: Enterprises
|
||||
enterprise_groups: Groups
|
||||
@@ -225,6 +224,7 @@ en:
|
||||
admin_and_handling: Admin & Handling
|
||||
profile: Profile
|
||||
supplier_only: Supplier Only
|
||||
has_shopfront: Has Shopfront
|
||||
weight: Weight
|
||||
volume: Volume
|
||||
items: Items
|
||||
@@ -252,6 +252,7 @@ en:
|
||||
password_confirmation: Password Confirmation
|
||||
reset_password_token: Reset password token
|
||||
expired: has expired, please request a new one
|
||||
back_to_payments_list: "Back to Payments List"
|
||||
|
||||
actions:
|
||||
create_and_add_another: "Create and Add Another"
|
||||
@@ -1941,7 +1942,6 @@ See the %{link} to find out more about %{sitename}'s features and to start using
|
||||
enterprise_long_desc: "Long Description"
|
||||
enterprise_long_desc_placeholder: "This is your opportunity to tell the story of your enterprise - what makes you different and wonderful? We'd suggest keeping your description to under 600 characters or 150 words."
|
||||
enterprise_long_desc_length: "%{num} characters / up to 600 recommended"
|
||||
enterprise_limit: Enterprise Limit
|
||||
enterprise_abn: "ABN"
|
||||
enterprise_abn_placeholder: "eg. 99 123 456 789"
|
||||
enterprise_acn: "ACN"
|
||||
@@ -2402,6 +2402,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using
|
||||
validation_msg_relationship_already_established: "^That relationship is already established."
|
||||
validation_msg_at_least_one_hub: "^At least one hub must be selected"
|
||||
validation_msg_product_category_cant_be_blank: "^Product Category cant be blank"
|
||||
validation_msg_tax: "^Tax Category is required"
|
||||
validation_msg_tax_category_cant_be_blank: "^Tax Category can't be blank"
|
||||
validation_msg_is_associated_with_an_exising_customer: "is associated with an existing customer"
|
||||
content_configuration_pricing_table: "(TODO: Pricing table)"
|
||||
@@ -2769,6 +2770,23 @@ See the %{link} to find out more about %{sitename}'s features and to start using
|
||||
bulk_coop_packing_sheets: 'Bulk Co-op - Packing Sheets'
|
||||
bulk_coop_customer_payments: 'Bulk Co-op - Customer Payments'
|
||||
users:
|
||||
index:
|
||||
listing_users: "Listing Users"
|
||||
new_user: "New User"
|
||||
user: "User"
|
||||
enterprise_limit: "Enterprise Limit"
|
||||
search: "Search"
|
||||
email: "Email"
|
||||
edit:
|
||||
editing_user: "Editing User"
|
||||
back_to_users_list: "Back To Users List"
|
||||
general_settings: "General Settings"
|
||||
form:
|
||||
email: "Email"
|
||||
roles: "Roles"
|
||||
enterprise_limit: "Enterprise Limit"
|
||||
confirm_password: "Confirm Password"
|
||||
password: "Password"
|
||||
email_confirmation:
|
||||
confirmation_pending: "Email confirmation is pending. We've sent a confirmation email to %{address}."
|
||||
variants:
|
||||
|
||||
@@ -111,6 +111,8 @@ Openfoodnetwork::Application.routes.draw do
|
||||
|
||||
resources :customers, only: [:index, :update]
|
||||
|
||||
resources :enterprise_fees, only: [:destroy]
|
||||
|
||||
post '/product_images/:product_id', to: 'product_images#update_product_image'
|
||||
end
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ Openfoodnetwork::Application.routes.draw do
|
||||
resources :enterprise_relationships
|
||||
resources :enterprise_roles
|
||||
|
||||
resources :enterprise_fees do
|
||||
resources :enterprise_fees, except: :destroy do
|
||||
collection do
|
||||
get :for_order_cycle
|
||||
post :bulk_update, :as => :bulk_update
|
||||
|
||||
42
db/migrate/20181123012635_associate_customers_to_users.rb
Normal file
42
db/migrate/20181123012635_associate_customers_to_users.rb
Normal file
@@ -0,0 +1,42 @@
|
||||
# When we introduced the Customer model, we didn't associate any existing
|
||||
# customers with users that have the same email address.
|
||||
# Later we decided to create that association when users sign up. But we didn't
|
||||
# update all the existing customers. We do that now for data consistency and to
|
||||
# solve several bugs.
|
||||
#
|
||||
# - https://github.com/openfoodfoundation/openfoodnetwork/pull/2084
|
||||
# - https://github.com/openfoodfoundation/openfoodnetwork/issues/2841
|
||||
class AssociateCustomersToUsers < ActiveRecord::Migration
|
||||
class Customer < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def up
|
||||
save_customers
|
||||
execute "UPDATE customers
|
||||
SET user_id = spree_users.id
|
||||
FROM spree_users
|
||||
WHERE customers.email = spree_users.email
|
||||
AND customers.user_id IS NULL;"
|
||||
end
|
||||
|
||||
def down
|
||||
customers = backed_up_customers
|
||||
Customer.where(id: customers).update_all(user_id: nil)
|
||||
end
|
||||
|
||||
def save_customers
|
||||
customers = Customer.
|
||||
joins("INNER JOIN spree_users ON customers.email = spree_users.email").
|
||||
where(user_id: nil).all
|
||||
|
||||
File.write(backup_file, YAML.dump(customers))
|
||||
end
|
||||
|
||||
def backed_up_customers
|
||||
YAML.load(File.read(backup_file))
|
||||
end
|
||||
|
||||
def backup_file
|
||||
File.join("log", "customers_without_user_association.log")
|
||||
end
|
||||
end
|
||||
@@ -11,7 +11,7 @@
|
||||
#
|
||||
# It's strongly recommended to check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(:version => 20181106162211) do
|
||||
ActiveRecord::Schema.define(:version => 20181123012635) do
|
||||
|
||||
create_table "account_invoices", :force => true do |t|
|
||||
t.integer "user_id", :null => false
|
||||
|
||||
34
spec/controllers/api/enterprise_fees_controller_spec.rb
Normal file
34
spec/controllers/api/enterprise_fees_controller_spec.rb
Normal file
@@ -0,0 +1,34 @@
|
||||
require 'spec_helper'
|
||||
|
||||
module Api
|
||||
describe EnterpriseFeesController, type: :controller do
|
||||
include AuthenticationWorkflow
|
||||
|
||||
let!(:unreferenced_fee) { create(:enterprise_fee) }
|
||||
let!(:referenced_fee) { create(:enterprise_fee) }
|
||||
let(:product) { create(:product) }
|
||||
let(:distributor) { create(:distributor_enterprise) }
|
||||
let!(:product_distribution) { create(:product_distribution, product: product, distributor: distributor, enterprise_fee: referenced_fee) }
|
||||
let(:current_user) { create(:admin_user) }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:spree_current_user) { current_user }
|
||||
end
|
||||
|
||||
describe "destroy" do
|
||||
it "removes the fee" do
|
||||
expect { spree_delete :destroy, id: unreferenced_fee.id, format: :json }
|
||||
.to change { EnterpriseFee.count }.by -1
|
||||
end
|
||||
|
||||
context "when the fee is referenced by a product distribution" do
|
||||
it "does not remove the fee" do
|
||||
spree_delete :destroy, id: referenced_fee.id, format: :json
|
||||
expect(response.status).to eq 403
|
||||
expect(response.body).to match(/That enterprise fee cannot be deleted/)
|
||||
expect(referenced_fee.reload).to eq(referenced_fee)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -90,7 +90,7 @@ describe Spree::Admin::LineItemsController, type: :controller do
|
||||
|
||||
it 'returns an HTML response with the order form' do
|
||||
spree_put :update, params
|
||||
expect(response.body).to match(/admin_order_form_fields/)
|
||||
expect(response.body).to match(/edit_order/)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -16,10 +16,10 @@ feature %q{
|
||||
let!(:producer_related) { create(:supplier_enterprise) }
|
||||
let!(:producer_unrelated) { create(:supplier_enterprise) }
|
||||
let!(:er1) { create(:enterprise_relationship, parent: producer, child: hub,
|
||||
permissions_list: [:create_variant_overrides])
|
||||
permissions_list: [:create_variant_overrides])
|
||||
}
|
||||
let!(:er2) { create(:enterprise_relationship, parent: producer_related, child: hub,
|
||||
permissions_list: [:create_variant_overrides])
|
||||
permissions_list: [:create_variant_overrides])
|
||||
}
|
||||
|
||||
context "as an enterprise user" do
|
||||
@@ -28,7 +28,7 @@ feature %q{
|
||||
|
||||
describe "selecting a hub" do
|
||||
let!(:er1) { create(:enterprise_relationship, parent: hub2, child: producer_managed,
|
||||
permissions_list: [:add_to_order_cycle])
|
||||
permissions_list: [:add_to_order_cycle])
|
||||
} # This er should not confer ability to create VOs for hub2
|
||||
|
||||
it "displays a list of hub choices (ie. only those managed by the user)" do
|
||||
@@ -338,7 +338,7 @@ feature %q{
|
||||
it "shows the overridden price" do
|
||||
targetted_select2_search product.name, from: '#add_variant_id', dropdown_css: '.select2-drop'
|
||||
click_link 'Add'
|
||||
expect(page).to have_selector("table.index tbody[data-hook='admin_order_form_line_items'] tr") # Wait for JS
|
||||
expect(page).to have_selector("table.index tbody tr") # Wait for JS
|
||||
expect(page).to have_content(product.variants.first.variant_overrides.first.price)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -65,19 +65,18 @@ feature "As a consumer I want to check out my cart", js: true, retry: 3 do
|
||||
let(:user) { create(:user) }
|
||||
|
||||
def fill_out_form
|
||||
toggle_shipping
|
||||
choose sm1.name
|
||||
toggle_payment
|
||||
choose pm1.name
|
||||
toggle_details
|
||||
|
||||
within "#details" do
|
||||
fill_in "First Name", with: "Will"
|
||||
fill_in "Last Name", with: "Marshall"
|
||||
fill_in "Email", with: "test@test.com"
|
||||
fill_in "Phone", with: "0468363090"
|
||||
end
|
||||
toggle_billing
|
||||
|
||||
check "Save as default billing address"
|
||||
|
||||
within "#billing" do
|
||||
fill_in "City", with: "Melbourne"
|
||||
fill_in "Postcode", with: "3066"
|
||||
@@ -86,7 +85,6 @@ feature "As a consumer I want to check out my cart", js: true, retry: 3 do
|
||||
select "Victoria", from: "State"
|
||||
end
|
||||
|
||||
toggle_shipping
|
||||
check "Shipping address same as billing address?"
|
||||
check "Save as default shipping address"
|
||||
end
|
||||
@@ -150,7 +148,6 @@ feature "As a consumer I want to check out my cart", js: true, retry: 3 do
|
||||
it "checks out successfully" do
|
||||
visit checkout_path
|
||||
choose sm2.name
|
||||
toggle_payment
|
||||
choose pm1.name
|
||||
|
||||
expect do
|
||||
@@ -193,7 +190,6 @@ feature "As a consumer I want to check out my cart", js: true, retry: 3 do
|
||||
|
||||
visit checkout_path
|
||||
fill_out_form
|
||||
toggle_payment
|
||||
choose stripe_pm.name
|
||||
end
|
||||
|
||||
@@ -229,7 +225,6 @@ feature "As a consumer I want to check out my cart", js: true, retry: 3 do
|
||||
end
|
||||
|
||||
it "shows a breakdown of the order price" do
|
||||
toggle_shipping
|
||||
choose sm2.name
|
||||
|
||||
page.should have_selector 'orderdetails .cart-total', text: with_currency(11.23)
|
||||
@@ -243,7 +238,6 @@ feature "As a consumer I want to check out my cart", js: true, retry: 3 do
|
||||
end
|
||||
|
||||
it "shows all shipping methods in order by name" do
|
||||
toggle_shipping
|
||||
within '#shipping' do
|
||||
expect(page).to have_selector "label", count: 4 # Three shipping methods + instructions label
|
||||
labels = page.all('label').map(&:text)
|
||||
@@ -255,7 +249,6 @@ feature "As a consumer I want to check out my cart", js: true, retry: 3 do
|
||||
|
||||
context "when shipping method requires an address" do
|
||||
before do
|
||||
toggle_shipping
|
||||
choose sm1.name
|
||||
end
|
||||
it "shows ship address forms when 'same as billing address' is unchecked" do
|
||||
@@ -270,7 +263,6 @@ feature "As a consumer I want to check out my cart", js: true, retry: 3 do
|
||||
|
||||
it "shows shipping methods allowed by the rule" do
|
||||
# No rules in effect
|
||||
toggle_shipping
|
||||
page.should have_content "Frogs"
|
||||
page.should have_content "Donkeys"
|
||||
page.should have_content "Local"
|
||||
@@ -316,7 +308,6 @@ feature "As a consumer I want to check out my cart", js: true, retry: 3 do
|
||||
before do
|
||||
visit checkout_path
|
||||
checkout_as_guest
|
||||
toggle_payment
|
||||
end
|
||||
|
||||
it "shows all available payment methods" do
|
||||
@@ -327,8 +318,6 @@ feature "As a consumer I want to check out my cart", js: true, retry: 3 do
|
||||
|
||||
describe "purchasing" do
|
||||
it "takes us to the order confirmation page when we submit a complete form" do
|
||||
toggle_details
|
||||
|
||||
within "#details" do
|
||||
fill_in "First Name", with: "Will"
|
||||
fill_in "Last Name", with: "Marshall"
|
||||
@@ -336,8 +325,6 @@ feature "As a consumer I want to check out my cart", js: true, retry: 3 do
|
||||
fill_in "Phone", with: "0468363090"
|
||||
end
|
||||
|
||||
toggle_billing
|
||||
|
||||
within "#billing" do
|
||||
fill_in "Address", with: "123 Your Face"
|
||||
select "Australia", from: "Country"
|
||||
@@ -346,15 +333,11 @@ feature "As a consumer I want to check out my cart", js: true, retry: 3 do
|
||||
fill_in "Postcode", with: "3066"
|
||||
end
|
||||
|
||||
toggle_shipping
|
||||
|
||||
within "#shipping" do
|
||||
choose sm2.name
|
||||
fill_in 'Any comments or special instructions?', with: "SpEcIaL NoTeS"
|
||||
end
|
||||
|
||||
toggle_payment
|
||||
|
||||
within "#payment" do
|
||||
choose pm1.name
|
||||
end
|
||||
@@ -383,18 +366,16 @@ feature "As a consumer I want to check out my cart", js: true, retry: 3 do
|
||||
|
||||
context "with basic details filled" do
|
||||
before do
|
||||
toggle_shipping
|
||||
choose sm1.name
|
||||
toggle_payment
|
||||
choose pm1.name
|
||||
toggle_details
|
||||
|
||||
within "#details" do
|
||||
fill_in "First Name", with: "Will"
|
||||
fill_in "Last Name", with: "Marshall"
|
||||
fill_in "Email", with: "test@test.com"
|
||||
fill_in "Phone", with: "0468363090"
|
||||
end
|
||||
toggle_billing
|
||||
|
||||
within "#billing" do
|
||||
fill_in "City", with: "Melbourne"
|
||||
fill_in "Postcode", with: "3066"
|
||||
@@ -402,7 +383,7 @@ feature "As a consumer I want to check out my cart", js: true, retry: 3 do
|
||||
select "Australia", from: "Country"
|
||||
select "Victoria", from: "State"
|
||||
end
|
||||
toggle_shipping
|
||||
|
||||
check "Shipping address same as billing address?"
|
||||
end
|
||||
|
||||
@@ -443,7 +424,6 @@ feature "As a consumer I want to check out my cart", js: true, retry: 3 do
|
||||
expect(page).to have_selector ".transaction-fee td", text: with_currency(0.00)
|
||||
expect(page).to have_selector ".total", text: with_currency(11.23)
|
||||
|
||||
toggle_payment
|
||||
choose "#{pm2.name} (#{with_currency(5.67)})"
|
||||
|
||||
expect(page).to have_selector ".transaction-fee td", text: with_currency(5.67)
|
||||
@@ -465,7 +445,6 @@ feature "As a consumer I want to check out my cart", js: true, retry: 3 do
|
||||
let!(:pm1) { create(:payment_method, distributors: [distributor], name: "Roger rabbit", type: gateway_type) }
|
||||
|
||||
it "takes us to the order confirmation page when submitted with a valid credit card" do
|
||||
toggle_payment
|
||||
fill_in 'Card Number', with: "4111111111111111"
|
||||
select 'February', from: 'secrets.card_month'
|
||||
select (Date.current.year+1).to_s, from: 'secrets.card_year'
|
||||
@@ -480,7 +459,6 @@ feature "As a consumer I want to check out my cart", js: true, retry: 3 do
|
||||
end
|
||||
|
||||
it "shows the payment processing failed message when submitted with an invalid credit card" do
|
||||
toggle_payment
|
||||
fill_in 'Card Number', with: "9999999988887777"
|
||||
select 'February', from: 'secrets.card_month'
|
||||
select (Date.current.year+1).to_s, from: 'secrets.card_year'
|
||||
|
||||
@@ -67,7 +67,6 @@ feature "Using embedded shopfront functionality", js: true do
|
||||
fill_in "Phone", with: "0456789012"
|
||||
end
|
||||
|
||||
toggle_billing
|
||||
within "#billing" do
|
||||
fill_in "Address", with: "123 Street"
|
||||
select "Australia", from: "Country"
|
||||
@@ -76,12 +75,10 @@ feature "Using embedded shopfront functionality", js: true do
|
||||
fill_in "Postcode", with: "3066"
|
||||
end
|
||||
|
||||
toggle_shipping
|
||||
within "#shipping" do
|
||||
find('input[type="radio"]').trigger 'click'
|
||||
end
|
||||
|
||||
toggle_payment
|
||||
within "#payment" do
|
||||
find('input[type="radio"]').trigger 'click'
|
||||
end
|
||||
|
||||
@@ -173,7 +173,6 @@ feature "shopping with variant overrides defined", js: true, retry: 3 do
|
||||
fill_in "Phone", with: "0456789012"
|
||||
end
|
||||
|
||||
toggle_billing
|
||||
within "#billing" do
|
||||
fill_in "Address", with: "123 Street"
|
||||
select "Australia", from: "Country"
|
||||
@@ -182,12 +181,10 @@ feature "shopping with variant overrides defined", js: true, retry: 3 do
|
||||
fill_in "Postcode", with: "3066"
|
||||
end
|
||||
|
||||
toggle_shipping
|
||||
within "#shipping" do
|
||||
choose sm.name
|
||||
end
|
||||
|
||||
toggle_payment
|
||||
within "#payment" do
|
||||
choose pm.name
|
||||
end
|
||||
@@ -201,5 +198,4 @@ feature "shopping with variant overrides defined", js: true, retry: 3 do
|
||||
wait_until_enabled 'li.cart a.button'
|
||||
first(:link, 'Checkout now').click
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -18,16 +18,4 @@ module CheckoutWorkflow
|
||||
def toggle_details
|
||||
toggle_accordion :details
|
||||
end
|
||||
|
||||
def toggle_billing
|
||||
toggle_accordion :billing
|
||||
end
|
||||
|
||||
def toggle_shipping
|
||||
toggle_accordion :shipping
|
||||
end
|
||||
|
||||
def toggle_payment
|
||||
toggle_accordion :payment
|
||||
end
|
||||
end
|
||||
|
||||
@@ -13,7 +13,7 @@ module ShopWorkflow
|
||||
end
|
||||
|
||||
def set_order(order)
|
||||
ApplicationController.any_instance.stub(:session).and_return({order_id: order.id, access_token: order.token})
|
||||
allow_any_instance_of(ApplicationController).to receive(:session).and_return({order_id: order.id, access_token: order.token})
|
||||
end
|
||||
|
||||
def add_product_to_cart(order, product, quantity: 1)
|
||||
|
||||
Reference in New Issue
Block a user