mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-27 01:43:22 +00:00
Merge branch 'openfoodfoundation:master' into master
This commit is contained in:
3
.github/ISSUE_TEMPLATE/release.md
vendored
3
.github/ISSUE_TEMPLATE/release.md
vendored
@@ -28,7 +28,7 @@ assignees: ''
|
||||
<pre>
|
||||
git checkout master # same version as the release draft
|
||||
git fetch upstream
|
||||
git diff upstream master -- config/locales/en.yml
|
||||
git diff upstream/master -- config/locales/en.yml
|
||||
tx pull --force # if no changes or only additions in the locale
|
||||
git checkout --detach # if we need to commit new translations
|
||||
git commit -a -m "Update translations"
|
||||
@@ -43,7 +43,6 @@ assignees: ''
|
||||
<pre>
|
||||
cd ofn-install
|
||||
git pull
|
||||
(cd ../ofn-secrets && git pull)
|
||||
ansible-playbook --limit all-prod --extra-vars "git_version=vx.y.z" playbooks/deploy.yml
|
||||
</pre>
|
||||
</details>
|
||||
|
||||
@@ -1 +1 @@
|
||||
2.7.3
|
||||
3.0.3
|
||||
|
||||
5
Gemfile
5
Gemfile
@@ -1,7 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
source 'https://rubygems.org'
|
||||
ruby "2.7.3"
|
||||
ruby "3.0.3"
|
||||
git_source(:github) { |repo_name| "https://github.com/#{repo_name}.git" }
|
||||
|
||||
gem 'dotenv-rails', require: 'dotenv/rails-now' # Load ENV vars before other gems
|
||||
@@ -9,6 +9,7 @@ gem 'dotenv-rails', require: 'dotenv/rails-now' # Load ENV vars before other gem
|
||||
gem 'rails', '>= 6.1.4'
|
||||
|
||||
gem 'activemerchant', '>= 1.78.0'
|
||||
gem 'rexml'
|
||||
gem 'angular-rails-templates', '>= 0.3.0'
|
||||
gem 'awesome_nested_set'
|
||||
gem 'ransack', '2.4.2'
|
||||
@@ -94,7 +95,7 @@ gem 'wicked_pdf'
|
||||
gem 'wkhtmltopdf-binary'
|
||||
|
||||
gem 'immigrant'
|
||||
gem 'roo', '~> 2.8.3'
|
||||
gem 'roo', github: "roo-rb/roo" # master is currently needed for Ruby 3.x (awaiting new release)
|
||||
gem 'spreadsheet_architect'
|
||||
|
||||
gem 'whenever', require: false
|
||||
|
||||
53
Gemfile.lock
53
Gemfile.lock
@@ -24,6 +24,14 @@ GIT
|
||||
sass-rails
|
||||
thor (>= 0.14)
|
||||
|
||||
GIT
|
||||
remote: https://github.com/roo-rb/roo.git
|
||||
revision: 709464c77623be2bc09b2103405d90ded7604a75
|
||||
specs:
|
||||
roo (2.8.3)
|
||||
nokogiri (~> 1)
|
||||
rubyzip (>= 1.3.0, < 3.0.0)
|
||||
|
||||
PATH
|
||||
remote: engines/catalog
|
||||
specs:
|
||||
@@ -106,8 +114,8 @@ GEM
|
||||
activerecord (6.1.4.4)
|
||||
activemodel (= 6.1.4.4)
|
||||
activesupport (= 6.1.4.4)
|
||||
activerecord-import (1.2.0)
|
||||
activerecord (>= 3.2)
|
||||
activerecord-import (1.3.0)
|
||||
activerecord (>= 4.2)
|
||||
activerecord-postgresql-adapter (0.0.1)
|
||||
pg
|
||||
activerecord-session_store (2.0.0)
|
||||
@@ -161,8 +169,8 @@ GEM
|
||||
bcrypt (3.1.16)
|
||||
bigdecimal (3.0.2)
|
||||
bindex (0.8.1)
|
||||
bootsnap (1.9.1)
|
||||
msgpack (~> 1.0)
|
||||
bootsnap (1.10.1)
|
||||
msgpack (~> 1.2)
|
||||
bugsnag (6.24.1)
|
||||
concurrent-ruby (~> 1.0)
|
||||
builder (3.2.4)
|
||||
@@ -220,9 +228,10 @@ GEM
|
||||
activerecord (>= 5.a)
|
||||
database_cleaner-core (~> 2.0.0)
|
||||
database_cleaner-core (2.0.1)
|
||||
ddtrace (0.53.0)
|
||||
ffi (~> 1.0)
|
||||
ddtrace (0.54.1)
|
||||
debase-ruby_core_source (= 0.10.12)
|
||||
msgpack
|
||||
debase-ruby_core_source (0.10.12)
|
||||
debugger-linecache (1.2.0)
|
||||
devise (4.8.0)
|
||||
bcrypt (~> 3.0)
|
||||
@@ -269,7 +278,7 @@ GEM
|
||||
concurrent-ruby (~> 1.1)
|
||||
websocket-driver (>= 0.6, < 0.8)
|
||||
ffaker (2.20.0)
|
||||
ffi (1.15.4)
|
||||
ffi (1.15.5)
|
||||
flipper (0.20.4)
|
||||
flipper-active_record (0.20.4)
|
||||
activerecord (>= 5.0, < 7)
|
||||
@@ -344,7 +353,7 @@ GEM
|
||||
letter_opener (1.7.0)
|
||||
launchy (~> 2.2)
|
||||
libv8-node (15.14.0.1)
|
||||
listen (3.7.0)
|
||||
listen (3.7.1)
|
||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||
rb-inotify (~> 0.9, >= 0.9.10)
|
||||
loofah (2.13.0)
|
||||
@@ -366,9 +375,9 @@ GEM
|
||||
mini_racer (0.4.0)
|
||||
libv8-node (~> 15.14.0.0)
|
||||
minitest (5.15.0)
|
||||
monetize (1.11.0)
|
||||
monetize (1.12.0)
|
||||
money (~> 6.12)
|
||||
money (6.14.1)
|
||||
money (6.16.0)
|
||||
i18n (>= 0.6.4, <= 2)
|
||||
msgpack (1.4.2)
|
||||
multi_json (1.15.0)
|
||||
@@ -398,7 +407,7 @@ GEM
|
||||
parallel (1.21.0)
|
||||
paranoia (2.4.3)
|
||||
activerecord (>= 4.0, < 6.2)
|
||||
parser (3.0.2.0)
|
||||
parser (3.1.0.0)
|
||||
ast (~> 2.4.1)
|
||||
paypal-sdk-core (0.3.4)
|
||||
multi_json (~> 1.0)
|
||||
@@ -461,9 +470,9 @@ GEM
|
||||
nokogiri (>= 1.6)
|
||||
rails-html-sanitizer (1.4.2)
|
||||
loofah (~> 2.3)
|
||||
rails-i18n (6.0.0)
|
||||
rails-i18n (7.0.1)
|
||||
i18n (>= 0.7, < 2)
|
||||
railties (>= 6.0.0, < 7)
|
||||
railties (>= 6.0.0, < 8)
|
||||
rails_safe_tasks (1.0.0)
|
||||
railties (6.1.4.4)
|
||||
actionpack (= 6.1.4.4)
|
||||
@@ -471,7 +480,7 @@ GEM
|
||||
method_source
|
||||
rake (>= 0.13)
|
||||
thor (~> 1.0)
|
||||
rainbow (3.0.0)
|
||||
rainbow (3.1.1)
|
||||
rake (13.0.6)
|
||||
ransack (2.4.2)
|
||||
activerecord (>= 5.2.4)
|
||||
@@ -482,7 +491,7 @@ GEM
|
||||
ffi (~> 1.0)
|
||||
redcarpet (3.5.1)
|
||||
redis (4.5.1)
|
||||
regexp_parser (2.1.1)
|
||||
regexp_parser (2.2.0)
|
||||
request_store (1.5.0)
|
||||
rack (>= 1.4)
|
||||
responders (3.0.1)
|
||||
@@ -499,9 +508,6 @@ GEM
|
||||
builder (>= 3.0)
|
||||
dry-inflector (~> 0.1)
|
||||
rubyzip (>= 1.0)
|
||||
roo (2.8.3)
|
||||
nokogiri (~> 1)
|
||||
rubyzip (>= 1.3.0, < 3.0.0)
|
||||
rspec (3.10.0)
|
||||
rspec-core (~> 3.10.0)
|
||||
rspec-expectations (~> 3.10.0)
|
||||
@@ -547,9 +553,9 @@ GEM
|
||||
rubocop-ast (>= 1.12.0, < 2.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (>= 1.4.0, < 3.0)
|
||||
rubocop-ast (1.12.0)
|
||||
rubocop-ast (1.15.1)
|
||||
parser (>= 3.0.1.1)
|
||||
rubocop-rails (2.12.4)
|
||||
rubocop-rails (2.13.2)
|
||||
activesupport (>= 4.2.0)
|
||||
rack (>= 1.1)
|
||||
rubocop (>= 1.7.0, < 2.0)
|
||||
@@ -613,7 +619,7 @@ GEM
|
||||
activerecord (>= 5.1)
|
||||
state_machines-activemodel (>= 0.8.0)
|
||||
stringex (2.8.5)
|
||||
stripe (5.39.0)
|
||||
stripe (5.42.0)
|
||||
temple (0.8.2)
|
||||
test-prof (1.0.7)
|
||||
test-unit (3.5.0)
|
||||
@@ -767,8 +773,9 @@ DEPENDENCIES
|
||||
redcarpet
|
||||
redis (>= 4.0)
|
||||
responders
|
||||
rexml
|
||||
roadie-rails
|
||||
roo (~> 2.8.3)
|
||||
roo!
|
||||
rspec-rails (>= 3.5.2)
|
||||
rspec-retry
|
||||
rswag
|
||||
@@ -804,7 +811,7 @@ DEPENDENCIES
|
||||
wkhtmltopdf-binary
|
||||
|
||||
RUBY VERSION
|
||||
ruby 2.7.3p183
|
||||
ruby 3.0.3p157
|
||||
|
||||
BUNDLED WITH
|
||||
2.1.4
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
#= require jsuri
|
||||
|
||||
class window.Spree
|
||||
# Helper function to take a URL and add query parameters to it
|
||||
@url: (uri, query) ->
|
||||
if uri.path == undefined
|
||||
uri = new Uri(uri)
|
||||
if query
|
||||
$.each query, (key, value) ->
|
||||
uri.addQueryParam(key, value)
|
||||
@url: (uri) ->
|
||||
if uri.pathname == undefined
|
||||
uri = new URL(uri.toString())
|
||||
if Spree.api_key
|
||||
uri.addQueryParam('token', Spree.api_key)
|
||||
params = new URLSearchParams(uri.search)
|
||||
params.append('token', Spree.api_key)
|
||||
|
||||
return uri
|
||||
|
||||
@@ -2,10 +2,9 @@ root = exports ? this
|
||||
|
||||
root.taxon_tree_menu = (obj, context) ->
|
||||
|
||||
base_url = Spree.url(Spree.routes.taxonomy_taxons_path)
|
||||
admin_base_url = Spree.url(Spree.routes.admin_taxonomy_taxons_path)
|
||||
edit_url = admin_base_url.clone()
|
||||
edit_url.setPath(edit_url.path() + '/' + obj.attr("id") + "/edit");
|
||||
base_url = Spree.url(Spree.routes.taxonomy_taxons)
|
||||
admin_base_url = Spree.url(Spree.routes.admin_taxonomy_taxons)
|
||||
edit_url = Spree.url(Spree.routes.admin_taxonomy_taxons + '/' + obj.attr("id") + "/edit");
|
||||
|
||||
create:
|
||||
label: "<i class='icon-plus'></i> " + Spree.translations.add,
|
||||
|
||||
@@ -9,7 +9,7 @@ handle_move = (e, data) ->
|
||||
new_parent = data.rslt.np
|
||||
|
||||
url = Spree.url(base_url).clone()
|
||||
url.setPath url.path() + '/' + node.attr("id")
|
||||
url.pathname = url.pathname + '/' + node.attr("id")
|
||||
$.ajax
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
@@ -41,7 +41,7 @@ handle_rename = (e, data) ->
|
||||
name = data.rslt.new_name
|
||||
|
||||
url = Spree.url(base_url).clone()
|
||||
url.setPath(url.path() + '/' + node.attr("id"))
|
||||
url.pathname = url.pathname + '/' + node.attr("id")
|
||||
|
||||
$.ajax
|
||||
type: "POST",
|
||||
@@ -70,10 +70,10 @@ root = exports ? this
|
||||
root.setup_taxonomy_tree = (taxonomy_id) ->
|
||||
if taxonomy_id != undefined
|
||||
# this is defined within admin/taxonomies/edit
|
||||
root.base_url = Spree.url(Spree.routes.taxonomy_taxons_path)
|
||||
root.base_url = Spree.url(Spree.routes.taxonomy_taxons)
|
||||
|
||||
$.ajax
|
||||
url: base_url.path().replace("/taxons", "/jstree"),
|
||||
url: base_url.pathname.replace("/taxons", "/jstree"),
|
||||
success: (taxonomy) ->
|
||||
last_rollback = null
|
||||
|
||||
@@ -82,7 +82,7 @@ root.setup_taxonomy_tree = (taxonomy_id) ->
|
||||
data: taxonomy,
|
||||
ajax:
|
||||
url: (e) ->
|
||||
base_url.path() + '/' + e.attr('id') + '/jstree'
|
||||
base_url.pathname + '/' + e.attr('id') + '/jstree'
|
||||
themes:
|
||||
theme: "apple",
|
||||
url: "/assets/jquery.jstree/themes/apple/style.css"
|
||||
|
||||
@@ -3,3 +3,9 @@ angular.module('Darkswarm').directive 'auth', (AuthenticationService) ->
|
||||
link: (scope, elem, attrs) ->
|
||||
elem.bind "click", ->
|
||||
AuthenticationService.open '/' + attrs.auth
|
||||
|
||||
window.addEventListener "login:modal:open", ->
|
||||
AuthenticationService.open '/login'
|
||||
|
||||
scope.$on "$destroy", ->
|
||||
window.removeEventListener "login:modal:open"
|
||||
|
||||
@@ -8,6 +8,7 @@ class SplitCheckoutController < ::BaseController
|
||||
include OrderStockCheck
|
||||
include Spree::BaseHelper
|
||||
include CheckoutCallbacks
|
||||
include OrderCompletion
|
||||
include CablecarResponses
|
||||
|
||||
helper 'terms_and_conditions'
|
||||
@@ -16,16 +17,10 @@ class SplitCheckoutController < ::BaseController
|
||||
helper OrderHelper
|
||||
|
||||
def edit
|
||||
return redirect_to_step unless params[:step]
|
||||
|
||||
return redirect_to_guest if !spree_current_user &&
|
||||
!@order.distributor.allow_guest_orders? &&
|
||||
params[:step] != "guest"
|
||||
redirect_to_step unless params[:step]
|
||||
end
|
||||
|
||||
def update
|
||||
return redirect_to_guest if !spree_current_user && !@order.distributor.allow_guest_orders?
|
||||
|
||||
if confirm_order || update_order
|
||||
clear_invalid_payments
|
||||
advance_order_state
|
||||
@@ -33,10 +28,9 @@ class SplitCheckoutController < ::BaseController
|
||||
else
|
||||
flash.now[:error] = I18n.t('split_checkout.errors.global')
|
||||
|
||||
render operations: cable_car.
|
||||
render status: :unprocessable_entity, operations: cable_car.
|
||||
replace("#checkout", partial("split_checkout/checkout")).
|
||||
replace("#flashes", partial("shared/flashes", locals: { flashes: flash })),
|
||||
status: :unprocessable_entity
|
||||
replace("#flashes", partial("shared/flashes", locals: { flashes: flash }))
|
||||
end
|
||||
end
|
||||
|
||||
@@ -47,10 +41,12 @@ class SplitCheckoutController < ::BaseController
|
||||
end
|
||||
|
||||
def confirm_order
|
||||
return unless @order.confirmation? && params[:confirm_order]
|
||||
return unless summary_step? && @order.confirmation?
|
||||
return unless validate_summary! && @order.errors.empty?
|
||||
|
||||
@order.customer.touch :terms_and_conditions_accepted_at
|
||||
@order.confirm!
|
||||
order_completion_reset @order
|
||||
end
|
||||
|
||||
def update_order
|
||||
@@ -58,17 +54,27 @@ class SplitCheckoutController < ::BaseController
|
||||
|
||||
@order.select_shipping_method(params[:shipping_method_id])
|
||||
@order.update(order_params)
|
||||
send("validate_#{params[:step]}!")
|
||||
|
||||
validate_current_step!
|
||||
|
||||
@order.errors.empty?
|
||||
end
|
||||
|
||||
def summary_step?
|
||||
params[:step] == "summary"
|
||||
end
|
||||
|
||||
def advance_order_state
|
||||
return if @order.complete?
|
||||
|
||||
OrderWorkflow.new(@order).advance_checkout(raw_params.slice(:shipping_method_id))
|
||||
end
|
||||
|
||||
def validate_current_step!
|
||||
step = ([params[:step]] & ["details", "payment", "summary"]).first
|
||||
send("validate_#{step}!")
|
||||
end
|
||||
|
||||
def validate_details!
|
||||
return true if params[:shipping_method_id].present?
|
||||
|
||||
@@ -83,6 +89,7 @@ class SplitCheckoutController < ::BaseController
|
||||
|
||||
def validate_summary!
|
||||
return true if params[:accept_terms]
|
||||
return true unless TermsOfService.required?(@order.distributor)
|
||||
|
||||
@order.errors.add(:terms_and_conditions, t("split_checkout.errors.terms_not_accepted"))
|
||||
end
|
||||
@@ -91,13 +98,7 @@ class SplitCheckoutController < ::BaseController
|
||||
@order_params ||= Checkout::Params.new(@order, params).call
|
||||
end
|
||||
|
||||
def redirect_to_guest
|
||||
redirect_to checkout_step_path(:guest)
|
||||
end
|
||||
|
||||
def redirect_to_step
|
||||
return redirect_to_guest if !spree_current_user && !params[:step]
|
||||
|
||||
case @order.state
|
||||
when "cart", "address", "delivery"
|
||||
redirect_to checkout_step_path(:details)
|
||||
|
||||
@@ -6,7 +6,7 @@ module Spree
|
||||
module ReportsHelper
|
||||
def report_payment_method_options(orders)
|
||||
orders.map do |order|
|
||||
payment_method = order.payments.first&.payment_method
|
||||
payment_method = order.payments.last&.payment_method
|
||||
|
||||
next unless payment_method
|
||||
|
||||
|
||||
@@ -7,21 +7,25 @@ module TermsAndConditionsHelper
|
||||
end
|
||||
|
||||
def render_terms_and_conditions
|
||||
if platform_terms_required? && terms_and_conditions_activated?
|
||||
if platform_terms_required? && distributor_terms_required?
|
||||
render("checkout/all_terms_and_conditions")
|
||||
elsif platform_terms_required?
|
||||
render "checkout/platform_terms_of_service"
|
||||
elsif terms_and_conditions_activated?
|
||||
elsif distributor_terms_required?
|
||||
render "checkout/terms_and_conditions"
|
||||
end
|
||||
end
|
||||
|
||||
def platform_terms_required?
|
||||
Spree::Config.shoppers_require_tos
|
||||
def any_terms_required?(distributor)
|
||||
TermsOfService.required?(distributor)
|
||||
end
|
||||
|
||||
def terms_and_conditions_activated?
|
||||
current_order.distributor.terms_and_conditions.file?
|
||||
def platform_terms_required?
|
||||
TermsOfService.platform_terms_required?
|
||||
end
|
||||
|
||||
def distributor_terms_required?
|
||||
TermsOfService.distributor_terms_required?(current_order.distributor)
|
||||
end
|
||||
|
||||
def all_terms_and_conditions_already_accepted?
|
||||
|
||||
@@ -30,7 +30,7 @@ module Spree
|
||||
go_to_state :complete
|
||||
end
|
||||
|
||||
attr_accessor :use_billing, :checkout_processing
|
||||
attr_accessor :use_billing, :checkout_processing, :save_bill_address, :save_ship_address
|
||||
|
||||
token_resource
|
||||
|
||||
@@ -104,6 +104,8 @@ module Spree
|
||||
before_save :update_shipping_fees!, if: :complete?
|
||||
before_save :update_payment_fees!, if: :complete?
|
||||
|
||||
after_save_commit DefaultAddressUpdater
|
||||
|
||||
# -- Scopes
|
||||
scope :not_empty, -> {
|
||||
left_outer_joins(:line_items).where.not(spree_line_items: { id: nil })
|
||||
|
||||
@@ -24,6 +24,7 @@ module Checkout
|
||||
def apply_strong_parameters
|
||||
@order_params = params.require(:order).permit(
|
||||
:email, :shipping_method_id, :special_instructions, :existing_card_id,
|
||||
:save_bill_address, :save_ship_address,
|
||||
bill_address_attributes: ::PermittedAttributes::Address.attributes,
|
||||
ship_address_attributes: ::PermittedAttributes::Address.attributes,
|
||||
payments_attributes: [
|
||||
|
||||
42
app/services/default_address_updater.rb
Normal file
42
app/services/default_address_updater.rb
Normal file
@@ -0,0 +1,42 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class DefaultAddressUpdater
|
||||
def self.after_commit(order)
|
||||
return unless order.save_bill_address || order.save_ship_address
|
||||
|
||||
new(order).call
|
||||
end
|
||||
|
||||
def initialize(order)
|
||||
@order = order
|
||||
end
|
||||
|
||||
def call
|
||||
assign_bill_addresses
|
||||
assign_ship_addresses
|
||||
|
||||
customer.save
|
||||
user&.save
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :order
|
||||
|
||||
delegate :save_ship_address, :save_bill_address, :customer, :user,
|
||||
:bill_address_id, :ship_address_id, to: :order
|
||||
|
||||
def assign_bill_addresses
|
||||
return unless save_bill_address
|
||||
|
||||
customer.bill_address_id = bill_address_id
|
||||
user&.bill_address_id = bill_address_id
|
||||
end
|
||||
|
||||
def assign_ship_addresses
|
||||
return unless save_ship_address
|
||||
|
||||
customer.ship_address_id = ship_address_id
|
||||
user&.ship_address_id = ship_address_id
|
||||
end
|
||||
end
|
||||
@@ -10,4 +10,16 @@ class TermsOfService
|
||||
TermsOfServiceFile.updated_at
|
||||
end
|
||||
end
|
||||
|
||||
def self.required?(distributor)
|
||||
platform_terms_required? || distributor_terms_required?(distributor)
|
||||
end
|
||||
|
||||
def self.platform_terms_required?
|
||||
Spree::Config.shoppers_require_tos
|
||||
end
|
||||
|
||||
def self.distributor_terms_required?(distributor)
|
||||
distributor.terms_and_conditions.file?
|
||||
end
|
||||
end
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
.columns.small-12.fat
|
||||
%div{"ng-if" => "::producer.name"}
|
||||
%label
|
||||
= t :producers_buy_at_html, {enterprise: '<span class="turquoise" ng-bind="::producer.name"></span>'.html_safe}
|
||||
= t :producers_buy_at_html, enterprise: '<span class="turquoise" ng-bind="::producer.name"></span>'.html_safe
|
||||
%div.show-for-medium-up{"ng-if" => "::!producer.name"}
|
||||
|
||||
.row.cta-container
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
%checkout.row#checkout
|
||||
.small-12.medium-12.columns
|
||||
= render partial: "split_checkout/tabs" unless checkout_step?(:guest)
|
||||
= render partial: "split_checkout/tabs"
|
||||
= render partial: "split_checkout/form"
|
||||
|
||||
@@ -60,8 +60,8 @@
|
||||
|
||||
- if spree_current_user||true
|
||||
%div.checkout-input
|
||||
= f.check_box :checkout_default_bill_address
|
||||
= f.label :checkout_default_bill_address, t(:checkout_default_bill_address)
|
||||
= f.check_box :save_bill_address
|
||||
= f.label :save_bill_address, t(:checkout_default_bill_address)
|
||||
|
||||
%div.checkout-substep{ "data-controller": "toggle shippingmethod" }
|
||||
- selected_shipping_method = @order.shipping_method&.id || params[:shipping_method_id]
|
||||
@@ -136,8 +136,8 @@
|
||||
|
||||
- if spree_current_user
|
||||
%div.checkout-input{ "data-toggle-target": "content", style: "display: none" }
|
||||
= f.check_box :default_ship_address, { id: "default_ship_address", name: "default_ship_address" }
|
||||
= f.label :default_ship_address, t(:checkout_default_ship_address), { for: "default_ship_address" }
|
||||
= f.check_box :save_ship_address
|
||||
= f.label :save_ship_address, t(:checkout_default_ship_address)
|
||||
|
||||
.div.checkout-input
|
||||
= f.label :special_instructions, t(:checkout_instructions)
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
.medium-10
|
||||
%div.checkout-guest-title
|
||||
= t :checkout_headline
|
||||
.checkout-step
|
||||
.medium-10
|
||||
%div.checkout-guest-title
|
||||
= t :checkout_headline
|
||||
|
||||
%div.checkout-submit{ class: "#{@order.distributor.allow_guest_orders? ? 'checkout-submit-inline' : 'medium-6' }" }
|
||||
%a.primary.button{href: main_app.login_path}
|
||||
= t :label_login
|
||||
-if @order.distributor.allow_guest_orders?
|
||||
%span.checkout-submit-or
|
||||
or
|
||||
%a.button.cancel{href: main_app.checkout_step_path(:details)}
|
||||
= t :checkout_as_guest
|
||||
%div.checkout-submit{ class: "#{@order.distributor.allow_guest_orders? ? 'checkout-submit-inline' : 'medium-6' }" }
|
||||
%button.button.primary{ "data-action": "click->guest-checkout#login" }
|
||||
= t :label_login
|
||||
-if @order.distributor.allow_guest_orders?
|
||||
%span.checkout-submit-or
|
||||
or
|
||||
%button.button.cancel{ "data-action": "click->guest-checkout#guestSelected" }
|
||||
= t :checkout_as_guest
|
||||
|
||||
@@ -71,15 +71,16 @@
|
||||
|
||||
= render 'spree/orders/summary', order: @order
|
||||
|
||||
%div.checkout-substep.medium-6
|
||||
%div.checkout-input
|
||||
= f.check_box :accept_terms, { id: "accept_terms", name: "accept_terms", "checked": "#{all_terms_and_conditions_already_accepted?}" }, 1, nil
|
||||
= f.label :accept_terms, t('split_checkout.step3.terms_and_conditions.message_html', terms_and_conditions_link: link_to( t("split_checkout.step3.terms_and_conditions.link_text"), @order.distributor.terms_and_conditions.url, target: '_blank'), tos_link: link_to_platform_terms), { for: "accept_terms" }
|
||||
- if any_terms_required?(@order.distributor)
|
||||
%div.checkout-substep.medium-6
|
||||
%div.checkout-input
|
||||
= f.check_box :accept_terms, { id: "accept_terms", name: "accept_terms", "checked": "#{all_terms_and_conditions_already_accepted?}" }, 1, nil
|
||||
= f.label :accept_terms, t('split_checkout.step3.terms_and_conditions.message_html', terms_and_conditions_link: link_to( t("split_checkout.step3.terms_and_conditions.link_text"), @order.distributor.terms_and_conditions.url, target: '_blank'), tos_link: link_to_platform_terms), { for: "accept_terms" }
|
||||
|
||||
= f.error_message_on :terms_and_conditions, standalone: true
|
||||
= f.error_message_on :terms_and_conditions, standalone: true
|
||||
|
||||
%div.checkout-input
|
||||
= t("split_checkout.step3.agree")
|
||||
%div.checkout-input
|
||||
= t("split_checkout.step3.agree")
|
||||
|
||||
%div.checkout-submit.medium-6
|
||||
= f.submit t("split_checkout.step3.submit"), name: "confirm_order", class: "button primary", disabled: @terms_and_conditions_accepted == false || @platform_tos_accepted == false
|
||||
|
||||
@@ -19,6 +19,12 @@
|
||||
.sub-header.show-for-medium-down
|
||||
= render partial: "shopping_shared/order_cycles"
|
||||
|
||||
= render partial: "checkout"
|
||||
.row{ "data-controller": "guest-checkout", "data-guest-checkout-distributor-value": @order.distributor.id }
|
||||
%div{ style: "display: #{spree_current_user ? 'block' : 'none'}", "data-guest-checkout-target": "checkout" }
|
||||
= render partial: "checkout"
|
||||
|
||||
- unless spree_current_user
|
||||
%div{ style: "display: block", "data-guest-checkout-target": "guest" }
|
||||
= render partial: "guest"
|
||||
|
||||
= render partial: "shared/footer"
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
- if @line_item.try(:errors).present?
|
||||
= render :partial => 'spree/shared/error_messages', :locals => { :target => @line_item }
|
||||
|
||||
- if !@order.completed? && @order.insufficient_stock_lines.any?
|
||||
= render 'spree/admin/orders/insufficient_stock_lines', insufficient_stock_lines: @order.insufficient_stock_lines
|
||||
|
||||
= render :partial => "spree/admin/orders/shipment", :collection => @order.shipments, :locals => { :order => order }
|
||||
|
||||
= render :partial => "spree/admin/orders/_form/adjustments", :locals => { :adjustments => @order.line_item_adjustments, :title => t(".line_item_adjustments")}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
%div.insufficient-stock-items
|
||||
%fieldset.no-border-bottom
|
||||
%legend
|
||||
= t("spree.orders.line_item.out_of_stock")
|
||||
|
||||
%table
|
||||
%colgroup
|
||||
%col{ :style => "width: 10%;" }
|
||||
%col{ :style => "width: 30%;" }
|
||||
%col{ :style => "width: 15%;" }
|
||||
%col{ :style => "width: 15%;" }
|
||||
%col{ :style => "width: 15%;" }
|
||||
%col{ :style => "width: 15%;" }
|
||||
|
||||
%thead
|
||||
%th{ :colspan => "2" }
|
||||
= Spree.t(:item_description)
|
||||
%th
|
||||
= Spree.t(:price)
|
||||
%th
|
||||
= Spree.t(:quantity)
|
||||
%th
|
||||
= Spree.t(:total)
|
||||
%th.orders-actions.actions
|
||||
|
||||
- insufficient_stock_lines.each do |line_item|
|
||||
%tr.insufficient-stock-item
|
||||
%td
|
||||
= render 'spree/shared/variant_thumbnail', variant: line_item.variant
|
||||
%td
|
||||
= line_item.variant.product_and_full_name
|
||||
%td.align-center
|
||||
= line_item.single_money.to_html
|
||||
%td.align-center
|
||||
= line_item.quantity
|
||||
%td.align-center
|
||||
= line_item.money.to_html
|
||||
%td.actions
|
||||
= link_to_delete line_item, { url: main_app.admin_bulk_line_item_path(line_item), no_text: true }
|
||||
@@ -6,9 +6,9 @@
|
||||
Spree.routes = {}
|
||||
}
|
||||
Spree.routes = <%== {
|
||||
:variants_search => spree.admin_search_variants_path(:format => 'json'),
|
||||
:taxons_search => main_app.api_v0_taxons_path(:format => 'json'),
|
||||
:orders_api => main_app.api_v0_orders_path,
|
||||
:states_search => main_app.api_v0_states_path(:format => 'json')
|
||||
:variants_search => spree.admin_search_variants_url(:format => 'json'),
|
||||
:taxons_search => main_app.api_v0_taxons_url(:format => 'json'),
|
||||
:orders_api => main_app.api_v0_orders_url,
|
||||
:states_search => main_app.api_v0_states_url(:format => 'json')
|
||||
}.to_json %>;
|
||||
</script>
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
= label_tag nil, t("spree.tree")
|
||||
%br/
|
||||
:javascript
|
||||
Spree.routes.taxonomy_taxons_path = "#{main_app.api_v0_taxonomy_taxons_path(@taxonomy)}";
|
||||
Spree.routes.admin_taxonomy_taxons_path = "#{spree.admin_taxonomy_taxons_path(@taxonomy)}";
|
||||
Spree.routes.taxonomy_taxons = "#{main_app.api_v0_taxonomy_taxons_url(@taxonomy)}";
|
||||
Spree.routes.admin_taxonomy_taxons = "#{spree.admin_taxonomy_taxons_url(@taxonomy)}";
|
||||
#taxonomy_tree.tree
|
||||
#progress{style: "display:none;"}
|
||||
= image_pack_tag 'select2-spinner.gif', title: 'Spinner', style: "vertical-align:bottom;"
|
||||
|
||||
35
app/webpacker/controllers/guest_checkout_controller.js
Normal file
35
app/webpacker/controllers/guest_checkout_controller.js
Normal file
@@ -0,0 +1,35 @@
|
||||
import { Controller } from "stimulus"
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = ["checkout", "guest"];
|
||||
static values = {
|
||||
distributor: String,
|
||||
session: { type: String, default: "guest-checkout" }
|
||||
};
|
||||
|
||||
connect() {
|
||||
if(!this.hasGuestTarget) { return }
|
||||
|
||||
if(this.usingGuestCheckout()) {
|
||||
this.showCheckout();
|
||||
}
|
||||
}
|
||||
|
||||
login() {
|
||||
window.dispatchEvent(new Event("login:modal:open"))
|
||||
}
|
||||
|
||||
showCheckout() {
|
||||
this.checkoutTarget.style.display = "block";
|
||||
this.guestTarget.style.display = "none";
|
||||
}
|
||||
|
||||
guestSelected() {
|
||||
this.showCheckout();
|
||||
sessionStorage.setItem(this.sessionValue, this.distributorValue);
|
||||
}
|
||||
|
||||
usingGuestCheckout() {
|
||||
return sessionStorage.getItem(this.sessionValue) === this.distributorValue
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
.insufficient-stock-items {
|
||||
legend {
|
||||
color: $color-error;
|
||||
}
|
||||
|
||||
table tr:last-child th {
|
||||
border-bottom: 1px solid $admin-table-border;
|
||||
}
|
||||
}
|
||||
|
||||
// Customize orduct add fieldset
|
||||
#add-line-item {
|
||||
fieldset {
|
||||
|
||||
@@ -1353,6 +1353,7 @@ de_DE:
|
||||
terms_and_conditions: "Allgemeinen Geschäftsbedingungen (AGB)"
|
||||
failed: "Der Bestellabschluss ist fehlgeschlagen. Bitte geben Sie uns Bescheid, damit wir Ihre Bestellung dennoch bearbeiten können."
|
||||
payment_cancelled_due_to_stock: "Zahlung storniert: Der Bestellabschluss konnte aufgrund von Problemen mit dem Lagerbestand nicht abgeschlossen werden."
|
||||
order_not_loaded: "Keine gültige Bestellung für den Bestellabschluss gefunden."
|
||||
shops:
|
||||
hubs:
|
||||
show_closed_shops: "Geschlossene Läden anzeigen"
|
||||
@@ -3215,7 +3216,6 @@ de_DE:
|
||||
notice_messages:
|
||||
variant_deleted: "Produktvariante wurde gelöscht"
|
||||
or: "oder"
|
||||
order_processed_successfully: "Ihre Bestellung wurde erfolgreich verarbeitet."
|
||||
payment_method_not_supported: "Zahlungsart wird nicht unterstützt"
|
||||
resend_authorization_email: "Autorisierungs-E-Mail erneut senden"
|
||||
rma_credit: "Gutschrift aus Retour"
|
||||
|
||||
@@ -1351,6 +1351,7 @@ en_FR:
|
||||
terms_and_conditions: "Terms and Conditions"
|
||||
failed: "The checkout failed. Please let us know so that we can process your order."
|
||||
payment_cancelled_due_to_stock: "Payment cancelled: the checkout could not be completed due to stock issues."
|
||||
order_not_loaded: "No valid order found for checkout processing"
|
||||
shops:
|
||||
hubs:
|
||||
show_closed_shops: "Show closed shops"
|
||||
@@ -3206,7 +3207,6 @@ en_FR:
|
||||
notice_messages:
|
||||
variant_deleted: "Variant deleted"
|
||||
or: "Or"
|
||||
order_processed_successfully: "Order processed successfully"
|
||||
payment_method_not_supported: "Payment method not supported"
|
||||
resend_authorization_email: "Resend authorization email"
|
||||
rma_credit: "RMA credit"
|
||||
|
||||
@@ -1353,6 +1353,7 @@ fr:
|
||||
terms_and_conditions: "CGU & CGV"
|
||||
failed: "La validation du paiement a échoué. Contactez-nous afin de finaliser votre commande."
|
||||
payment_cancelled_due_to_stock: "Paiement annulé : la commande n'a pas été finalisée car un ou plusieurs articles ne sont plus en stock."
|
||||
order_not_loaded: "Aucune commande n'a été trouvée pour poursuivre le parcours d'achat."
|
||||
shops:
|
||||
hubs:
|
||||
show_closed_shops: "Afficher les boutiques fermées"
|
||||
@@ -3235,7 +3236,6 @@ fr:
|
||||
notice_messages:
|
||||
variant_deleted: "Variante supprimée"
|
||||
or: "Ou"
|
||||
order_processed_successfully: "Commande traitée avec succès"
|
||||
payment_method_not_supported: "Mode de paiement non pris en charge"
|
||||
resend_authorization_email: "Renvoyer l'e-mail d'autorisation"
|
||||
rma_credit: "Crédit ARM"
|
||||
|
||||
@@ -72,6 +72,44 @@ ru:
|
||||
missing: "У клиента нет карты, с которой начисляется оплата."
|
||||
processing_error: "Произошла ошибка при обработке карты."
|
||||
rate_limit: "Произошла ошибка из-за того, что запросы попали в API слишком быстро. Сообщите нам, если вы постоянно сталкиваетесь с этой ошибкой."
|
||||
authentication_required: "Карта была отклонена, так как транзакция требует аутентификации."
|
||||
approve_with_id: "Платеж не может быть авторизован."
|
||||
call_issuer: "Карта была отклонена по неизвестной причине."
|
||||
card_not_supported: "Карта не поддерживает этот тип покупки."
|
||||
card_velocity_exceeded: "Клиент превысил баланс или кредитный лимит, доступный на его карте."
|
||||
currency_not_supported: "Карта не поддерживает указанную валюту."
|
||||
do_not_honor: "Карта была отклонена по неизвестной причине."
|
||||
do_not_try_again: "Карта была отклонена по неизвестной причине."
|
||||
duplicate_transaction: "Слишком часто была отправлена транзакция с одинаковой суммой и данными кредитной карты."
|
||||
fraudulent: "Платеж был отклонен, так как Stripe подозревает, что это мошенничество."
|
||||
generic_decline: "Карта была отклонена по неизвестной причине."
|
||||
incorrect_pin: "Введен неверный PIN-код. Этот код отклонения применяется только к платежам, совершенным с помощью устройства для чтения карт."
|
||||
insufficient_funds: "На карте недостаточно средств для совершения покупки."
|
||||
invalid_account: "Карта или счет, к которому привязана карта, недействительны."
|
||||
invalid_amount: "Сумма платежа недействительна или превышает допустимую сумму."
|
||||
invalid_pin: "Введен неверный PIN-код. Этот код отклонения применяется только к платежам, совершенным с помощью устройства для чтения карт."
|
||||
issuer_not_available: "Не удалось связаться с эмитентом карты, поэтому платеж не мог быть авторизован."
|
||||
lost_card: "Платеж был отклонен, поскольку заявлено, что карта утеряна."
|
||||
merchant_blacklist: "Платеж был отклонен, поскольку пользователь Stripe в черном списке."
|
||||
new_account_information_available: "Карта или счет, к которому привязана карта, недействительны."
|
||||
no_action_taken: "Карта была отклонена по неизвестной причине."
|
||||
not_permitted: "Оплата не разрешена."
|
||||
offline_pin_required: "Карта была отклонена, так как требует PIN-код."
|
||||
online_or_offline_pin_required: "Карта была отклонена, так как требует PIN-код."
|
||||
pickup_card: "Карту нельзя использовать для этого платежа (возможно, она была утеряна или украдена)."
|
||||
pin_try_exceeded: "Превышено допустимое количество попыток ввода PIN-кода."
|
||||
reenter_transaction: "Платеж не может быть обработан эмитентом по неизвестной причине."
|
||||
restricted_card: "Карту нельзя использовать для этого платежа (возможно, она была утеряна или украдена)."
|
||||
revocation_of_all_authorizations: "Карта была отклонена по неизвестной причине."
|
||||
revocation_of_authorization: "Карта была отклонена по неизвестной причине."
|
||||
security_violation: "Карта была отклонена по неизвестной причине."
|
||||
service_not_allowed: "Карта была отклонена по неизвестной причине."
|
||||
stolen_card: "Платеж был отклонен, поскольку карта была украдена."
|
||||
stop_payment_order: "Карта была отклонена по неизвестной причине."
|
||||
testmode_decline: "Был использован номер тестовой карты Stripe."
|
||||
transaction_not_allowed: "Карта была отклонена по неизвестной причине."
|
||||
try_again_later: "Карта была отклонена по неизвестной причине."
|
||||
withdrawal_count_limit_exceeded: "Клиент превысил баланс или кредитный лимит, доступный на его карте."
|
||||
activemodel:
|
||||
attributes:
|
||||
order_management/reports/enterprise_fee_summary/parameters:
|
||||
@@ -138,6 +176,9 @@ ru:
|
||||
already_registered: "Этот адрес электронной почты уже зарегистрирован. Пожалуйста, войдите, чтобы продолжить, или вернитесь и используйте другой адрес электронной почты."
|
||||
success:
|
||||
logged_in_succesfully: "Вы успешно вошли"
|
||||
sessions:
|
||||
signed_out: "Выполнен выход."
|
||||
already_signed_out: "Выполнен выход."
|
||||
user_passwords:
|
||||
spree_user:
|
||||
updated_not_active: "Ваш пароль был сброшен, но ваш адрес электронной почты еще не подтвержден."
|
||||
@@ -1313,6 +1354,7 @@ ru:
|
||||
terms_and_conditions: "Условия и Положения"
|
||||
failed: "Оформить заказ не удалось. Сообщите нам, чтобы мы могли обработать ваш заказ."
|
||||
payment_cancelled_due_to_stock: "Платеж отменен: оформление заказа не может быть выполнено из-за проблем на складе."
|
||||
order_not_loaded: "Не найден действительный заказ для оформления"
|
||||
shops:
|
||||
hubs:
|
||||
show_closed_shops: "Показать закрытые магазины"
|
||||
@@ -3221,7 +3263,6 @@ ru:
|
||||
notice_messages:
|
||||
variant_deleted: "Вариант удален"
|
||||
or: "Или"
|
||||
order_processed_successfully: "Заказ успешно обработан"
|
||||
payment_method_not_supported: "Способ оплаты не поддерживается"
|
||||
resend_authorization_email: "Повторно отправить письмо для авторизации"
|
||||
rma_credit: "Кредит RMA"
|
||||
|
||||
@@ -87,7 +87,7 @@ Openfoodnetwork::Application.routes.draw do
|
||||
constraints SplitCheckoutConstraint.new do
|
||||
get '/checkout', to: 'split_checkout#edit'
|
||||
|
||||
constraints step: /(guest|details|payment|summary)/ do
|
||||
constraints step: /(details|payment|summary)/ do
|
||||
get '/checkout/:step', to: 'split_checkout#edit', as: :checkout_step
|
||||
put '/checkout/:step', to: 'split_checkout#update', as: :checkout_update
|
||||
end
|
||||
|
||||
@@ -8,7 +8,7 @@ module OrderManagement
|
||||
private
|
||||
|
||||
def i18n_translate(translation_key, options = {})
|
||||
I18n.t("order_management.reports.enterprise_fee_summary.#{translation_key}", options)
|
||||
I18n.t("order_management.reports.enterprise_fee_summary.#{translation_key}", **options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -678,7 +678,7 @@ describe OrderManagement::Reports::EnterpriseFeeSummary::ReportService do
|
||||
# Helper methods for example group
|
||||
|
||||
def i18n_translate(translation_key, options = {})
|
||||
I18n.t("order_management.reports.enterprise_fee_summary.#{translation_key}", options)
|
||||
I18n.t("order_management.reports.enterprise_fee_summary.#{translation_key}", **options)
|
||||
end
|
||||
|
||||
def expect_total_attributes(total, expected_attribute_list)
|
||||
|
||||
@@ -94,7 +94,7 @@ module OpenFoodNetwork
|
||||
order.email,
|
||||
ba&.phone,
|
||||
order.shipping_method&.name,
|
||||
order.payments.first&.payment_method&.name,
|
||||
order.payments.last&.payment_method&.name,
|
||||
order.total,
|
||||
balance(order)]
|
||||
end
|
||||
|
||||
@@ -38,7 +38,7 @@ describe Api::V0::BaseController do
|
||||
context "cannot make a request to the API" do
|
||||
it "with an invalid API key" do
|
||||
request.headers["X-Spree-Token"] = "fake_key"
|
||||
get :index, {}
|
||||
get :index, params: {}
|
||||
expect(json_response).to eq( "error" => "Invalid API key (fake_key) specified." )
|
||||
expect(response.status).to eq(401)
|
||||
end
|
||||
|
||||
198
spec/controllers/split_checkout_controller_spec.rb
Normal file
198
spec/controllers/split_checkout_controller_spec.rb
Normal file
@@ -0,0 +1,198 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe SplitCheckoutController, type: :controller do
|
||||
let(:user) { order.user }
|
||||
let(:address) { create(:address) }
|
||||
let(:distributor) { create(:distributor_enterprise, with_payment_and_shipping: true) }
|
||||
let(:order_cycle) { create(:order_cycle, distributors: [distributor]) }
|
||||
let(:exchange) { order_cycle.exchanges.outgoing.first }
|
||||
let(:order) {
|
||||
create(:order_with_line_items, line_items_count: 1, distributor: distributor,
|
||||
order_cycle: order_cycle)
|
||||
}
|
||||
let(:payment_method) { distributor.payment_methods.first }
|
||||
let(:shipping_method) { distributor.shipping_methods.first }
|
||||
|
||||
before do
|
||||
allow(Flipper).to receive(:enabled?).with(:split_checkout) { true }
|
||||
allow(Flipper).to receive(:enabled?).with(:split_checkout, anything) { true }
|
||||
|
||||
exchange.variants << order.line_items.first.variant
|
||||
allow(controller).to receive(:current_order) { order }
|
||||
allow(controller).to receive(:spree_current_user) { user }
|
||||
end
|
||||
|
||||
describe "#edit" do
|
||||
it "renders the checkout" do
|
||||
get :edit, params: { step: "details" }
|
||||
expect(response.status).to eq 200
|
||||
end
|
||||
|
||||
it "redirects to current step if no step is given" do
|
||||
get :edit
|
||||
expect(response).to redirect_to checkout_step_path(:details)
|
||||
end
|
||||
|
||||
context "when line items in the cart are not valid" do
|
||||
before { allow(controller).to receive(:valid_order_line_items?) { false } }
|
||||
|
||||
it "redirects to cart" do
|
||||
get :edit
|
||||
expect(response).to redirect_to cart_path
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#update" do
|
||||
let(:checkout_params) { {} }
|
||||
let(:params) { { step: step }.merge(checkout_params) }
|
||||
|
||||
context "details step" do
|
||||
let(:step) { "details" }
|
||||
|
||||
context "with incomplete data" do
|
||||
let(:checkout_params) { { order: { email: user.email } } }
|
||||
|
||||
it "returns 422 and some feedback" do
|
||||
put :update, params: params
|
||||
|
||||
expect(response.status).to eq 422
|
||||
expect(flash[:error]).to eq "Saving failed, please update the highlighted fields."
|
||||
expect(order.reload.state).to eq "cart"
|
||||
end
|
||||
end
|
||||
|
||||
context "with complete data" do
|
||||
let(:checkout_params) do
|
||||
{
|
||||
order: {
|
||||
email: user.email,
|
||||
bill_address_attributes: address.to_param,
|
||||
ship_address_attributes: address.to_param
|
||||
},
|
||||
shipping_method_id: shipping_method.id
|
||||
}
|
||||
end
|
||||
|
||||
it "updates and redirects to payment step" do
|
||||
put :update, params: params
|
||||
|
||||
expect(response).to redirect_to checkout_step_path(:payment)
|
||||
expect(order.reload.state).to eq "payment"
|
||||
end
|
||||
|
||||
describe "saving default addresses" do
|
||||
it "updates default bill address on user and customer" do
|
||||
put :update, params: params.merge({ order: { save_bill_address: true } })
|
||||
|
||||
expect(order.customer.bill_address).to eq(order.bill_address)
|
||||
expect(order.user.bill_address).to eq(order.bill_address)
|
||||
end
|
||||
|
||||
it "updates default ship address on user and customer" do
|
||||
put :update, params: params.merge({ order: { save_ship_address: true } })
|
||||
|
||||
expect(order.customer.ship_address).to eq(order.ship_address)
|
||||
expect(order.user.ship_address).to eq(order.ship_address)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "payment step" do
|
||||
let(:step) { "payment" }
|
||||
|
||||
before do
|
||||
order.bill_address = address
|
||||
order.ship_address = address
|
||||
order.select_shipping_method shipping_method.id
|
||||
OrderWorkflow.new(order).advance_to_payment
|
||||
end
|
||||
|
||||
context "with incomplete data" do
|
||||
let(:checkout_params) { { order: { email: user.email } } }
|
||||
|
||||
it "returns 422 and some feedback" do
|
||||
put :update, params: params
|
||||
|
||||
expect(response.status).to eq 422
|
||||
expect(flash[:error]).to eq "Saving failed, please update the highlighted fields."
|
||||
expect(order.reload.state).to eq "payment"
|
||||
end
|
||||
end
|
||||
|
||||
context "with complete data" do
|
||||
let(:checkout_params) do
|
||||
{
|
||||
order: {
|
||||
payments_attributes: [
|
||||
{ payment_method_id: payment_method.id }
|
||||
]
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
it "updates and redirects to payment step" do
|
||||
put :update, params: params
|
||||
|
||||
expect(response).to redirect_to checkout_step_path(:summary)
|
||||
expect(order.reload.state).to eq "confirmation"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "summary step" do
|
||||
let(:step) { "summary" }
|
||||
|
||||
before do
|
||||
order.bill_address = address
|
||||
order.ship_address = address
|
||||
order.select_shipping_method shipping_method.id
|
||||
OrderWorkflow.new(order).advance_to_payment
|
||||
|
||||
order.payments << build(:payment, amount: order.total, payment_method: payment_method)
|
||||
order.next
|
||||
end
|
||||
|
||||
describe "confirming the order" do
|
||||
it "completes the order and redirects to order confirmation" do
|
||||
put :update, params: params
|
||||
|
||||
expect(response).to redirect_to order_path(order)
|
||||
expect(order.reload.state).to eq "complete"
|
||||
end
|
||||
end
|
||||
|
||||
context "when accepting T&Cs is required" do
|
||||
before do
|
||||
allow(TermsOfService).to receive(:platform_terms_required?) { true }
|
||||
end
|
||||
|
||||
describe "submitting without accepting the T&Cs" do
|
||||
let(:checkout_params) { {} }
|
||||
|
||||
it "returns 422 and some feedback" do
|
||||
put :update, params: params
|
||||
|
||||
expect(response.status).to eq 422
|
||||
expect(flash[:error]).to eq "Saving failed, please update the highlighted fields."
|
||||
expect(order.reload.state).to eq "confirmation"
|
||||
end
|
||||
end
|
||||
|
||||
describe "submitting and accepting the T&Cs" do
|
||||
let(:checkout_params) { { accept_terms: true } }
|
||||
|
||||
it "completes the order and redirects to order confirmation" do
|
||||
put :update, params: params
|
||||
|
||||
expect(response).to redirect_to order_path(order)
|
||||
expect(order.reload.state).to eq "complete"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -11,6 +11,39 @@ FactoryBot.define do
|
||||
completed_at { nil }
|
||||
email { user&.email || customer.email }
|
||||
|
||||
factory :order_ready_for_details do
|
||||
distributor { create(:distributor_enterprise, with_payment_and_shipping: true) }
|
||||
order_cycle { create(:order_cycle, distributors: [distributor]) }
|
||||
|
||||
after(:create) do |order|
|
||||
order.line_items << build(:line_item, order: order)
|
||||
order.updater.update_totals_and_states
|
||||
|
||||
order.order_cycle.exchanges.outgoing.first.variants << order.line_items.first.variant
|
||||
end
|
||||
|
||||
factory :order_ready_for_payment do
|
||||
bill_address
|
||||
ship_address
|
||||
|
||||
after(:create) do |order, evaluator|
|
||||
order.select_shipping_method evaluator.shipping_method.id
|
||||
OrderWorkflow.new(order).advance_to_payment
|
||||
end
|
||||
|
||||
factory :order_ready_for_confirmation do
|
||||
transient do
|
||||
payment_method { create(:payment_method, distributors: [distributor]) }
|
||||
end
|
||||
|
||||
after(:create) do |order, evaluator|
|
||||
order.payments << build(:payment, amount: order.total, payment_method: evaluator.payment_method)
|
||||
order.next!
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
factory :order_with_totals do
|
||||
after(:create) do |order|
|
||||
create(:line_item, order: order)
|
||||
|
||||
@@ -7,7 +7,7 @@ describe Spree::ReportsHelper, type: :helper do
|
||||
let(:order_with_payments) { create(:order_ready_to_ship) }
|
||||
let(:order_without_payments) { create(:order_with_line_items) }
|
||||
let(:orders) { [order_with_payments, order_without_payments] }
|
||||
let(:payment_method) { order_with_payments.payments.first.payment_method }
|
||||
let(:payment_method) { order_with_payments.payments.last.payment_method }
|
||||
|
||||
it "returns payment method select options for given orders" do
|
||||
select_options = helper.report_payment_method_options([order_with_payments])
|
||||
|
||||
@@ -462,6 +462,27 @@ describe '
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when an incomplete order has some line items with insufficient stock" do
|
||||
let(:incomplete_order) do
|
||||
create(:order_with_line_items, user: user, distributor: distributor,
|
||||
order_cycle: order_cycle)
|
||||
end
|
||||
|
||||
it "displays the out of stock line items and they can be deleted from the order" do
|
||||
incomplete_order.line_items.first.variant.update!(on_demand: false, on_hand: 0)
|
||||
|
||||
visit spree.edit_admin_order_path(incomplete_order)
|
||||
|
||||
within ".insufficient-stock-items" do
|
||||
expect(page).to have_content incomplete_order.products.first.name
|
||||
accept_alert 'Are you sure?' do
|
||||
find("a.delete-resource").click
|
||||
end
|
||||
expect(page).to_not have_content incomplete_order.products.first.name
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "creating an order with distributor and order cycle" do
|
||||
|
||||
@@ -8,7 +8,7 @@ describe "As a consumer, I want to checkout my order", js: true do
|
||||
|
||||
let!(:zone) { create(:zone_with_member) }
|
||||
let(:supplier) { create(:supplier_enterprise) }
|
||||
let(:distributor) { create(:distributor_enterprise, charges_sales_tax: true, allow_guest_orders: false) }
|
||||
let(:distributor) { create(:distributor_enterprise, charges_sales_tax: true) }
|
||||
let(:product) {
|
||||
create(:taxed_product, supplier: supplier, price: 10, zone: zone, tax_rate_amount: 0.1)
|
||||
}
|
||||
@@ -19,7 +19,8 @@ describe "As a consumer, I want to checkout my order", js: true do
|
||||
}
|
||||
let(:order) {
|
||||
create(:order, order_cycle: order_cycle, distributor: distributor, bill_address_id: nil,
|
||||
ship_address_id: nil, state: "cart")
|
||||
ship_address_id: nil, state: "cart",
|
||||
line_items: [create(:line_item, variant: variant)])
|
||||
}
|
||||
|
||||
let(:fee_tax_rate) { create(:tax_rate, amount: 0.10, zone: zone, included_in_price: true) }
|
||||
@@ -45,7 +46,6 @@ describe "As a consumer, I want to checkout my order", js: true do
|
||||
|
||||
add_enterprise_fee enterprise_fee
|
||||
set_order order
|
||||
add_product_to_cart order, product
|
||||
|
||||
distributor.shipping_methods << free_shipping
|
||||
distributor.shipping_methods << shipping_with_fee
|
||||
@@ -53,37 +53,28 @@ describe "As a consumer, I want to checkout my order", js: true do
|
||||
|
||||
context "guest checkout when distributor doesn't allow guest orders" do
|
||||
before do
|
||||
visit checkout_path
|
||||
distributor.update_columns allow_guest_orders: false
|
||||
visit checkout_step_path(:details)
|
||||
end
|
||||
|
||||
it "should display the split checkout login page" do
|
||||
expect(page).to have_content distributor.name
|
||||
expect(page).to have_content("Ok, ready to checkout?")
|
||||
expect(page).to have_content("Login")
|
||||
expect(page).to have_no_content("Checkout as guest")
|
||||
end
|
||||
|
||||
it "should be redirected if user enter the url" do
|
||||
order.update(state: "payment")
|
||||
get checkout_step_path(:details)
|
||||
expect(response).to have_http_status(:redirect)
|
||||
expect(page).to have_content("Ok, ready to checkout?")
|
||||
end
|
||||
|
||||
it "should redirect to the login page when clicking the login button" do
|
||||
it "should show the login modal when clicking the login button" do
|
||||
click_on "Login"
|
||||
expect(page).to have_content("Login")
|
||||
expect(page).to have_selector ".login-modal"
|
||||
end
|
||||
end
|
||||
|
||||
context "as a guest user" do
|
||||
before do
|
||||
distributor.update!(allow_guest_orders: true)
|
||||
order.update!(distributor_id: distributor.id)
|
||||
visit checkout_path
|
||||
end
|
||||
|
||||
it "should display the split checkout login/guest page" do
|
||||
it "should display the split checkout login/guest form" do
|
||||
expect(page).to have_content distributor.name
|
||||
expect(page).to have_content("Ok, ready to checkout?")
|
||||
expect(page).to have_content("Login")
|
||||
@@ -126,7 +117,7 @@ describe "As a consumer, I want to checkout my order", js: true do
|
||||
it "should allow visit '/checkout/details'" do
|
||||
order.update(state: "payment")
|
||||
visit checkout_step_path(:details)
|
||||
expect(page).to have_button("Next - Payment method")
|
||||
expect(page).to have_current_path("/checkout/details")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -230,14 +221,35 @@ describe "As a consumer, I want to checkout my order", js: true do
|
||||
expect(page).to have_content("Select a shipping method")
|
||||
end
|
||||
end
|
||||
|
||||
context "summary step" do
|
||||
let(:order) { create(:order_ready_for_confirmation, distributor: distributor) }
|
||||
|
||||
describe "completing the checkout" do
|
||||
it "keeps the distributor selected for the current user after completion" do
|
||||
visit checkout_step_path(:summary)
|
||||
|
||||
expect(page).to have_content "Shopping @ #{distributor.name}"
|
||||
|
||||
click_on "Complete order"
|
||||
|
||||
expect(page).to have_content "Back To Store"
|
||||
expect(order.reload.state).to eq "complete"
|
||||
|
||||
expect(page).to have_content "Shopping @ #{distributor.name}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when I have an out of stock product in my cart" do
|
||||
before do
|
||||
variant.update!(on_demand: false, on_hand: 0)
|
||||
end
|
||||
|
||||
it "returns me to the cart with an error message" do
|
||||
visit checkout_path
|
||||
|
||||
expect(page).not_to have_selector 'closing', text: "Checkout now"
|
||||
expect(page).to have_selector 'closing', text: "Your shopping cart"
|
||||
expect(page).to have_content "An item in your cart has become unavailable"
|
||||
|
||||
@@ -22,21 +22,76 @@ describe "spree/admin/orders/edit.html.haml" do
|
||||
end
|
||||
|
||||
allow(view).to receive_messages spree_current_user: create(:user)
|
||||
|
||||
order = create(:completed_order_with_fees)
|
||||
order.distributor = create(:distributor_enterprise)
|
||||
assign(:order, order)
|
||||
assign(:shops, [order.distributor])
|
||||
assign(:order_cycles, [])
|
||||
end
|
||||
|
||||
describe "order values" do
|
||||
it "displays order shipping costs, transaction fee and order total" do
|
||||
render
|
||||
context "when order is complete" do
|
||||
let(:order) { create(:completed_order_with_fees) }
|
||||
|
||||
expect(rendered).to have_content("Shipping Method\nUPS Ground $6.00")
|
||||
expect(rendered).to have_content("Transaction fee:\n\n$10.00")
|
||||
expect(rendered).to have_content("Order Total\n$36.00")
|
||||
before do
|
||||
order.distributor = create(:distributor_enterprise)
|
||||
assign(:order, order)
|
||||
assign(:shops, [order.distributor])
|
||||
assign(:order_cycles, [])
|
||||
end
|
||||
|
||||
describe "order values" do
|
||||
it "displays order shipping costs, transaction fee and order total" do
|
||||
render
|
||||
|
||||
expect(rendered).to have_content("Shipping Method\nUPS Ground $6.00")
|
||||
expect(rendered).to have_content("Transaction fee:\n\n$10.00")
|
||||
expect(rendered).to have_content("Order Total\n$36.00")
|
||||
end
|
||||
end
|
||||
|
||||
context "when some line items are out of stock" do
|
||||
let!(:out_of_stock_line_item) do
|
||||
line_item = order.line_items.first
|
||||
line_item.variant.update!(on_demand: false, on_hand: 0)
|
||||
line_item
|
||||
end
|
||||
|
||||
it "doesn't display a table of out of stock line items" do
|
||||
render
|
||||
|
||||
expect(rendered).to_not have_content "Out of Stock"
|
||||
expect(rendered).to_not have_selector ".insufficient-stock-items",
|
||||
text: out_of_stock_line_item.variant.display_name
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when order is incomplete" do
|
||||
let(:order) { create(:order_with_line_items) }
|
||||
|
||||
before do
|
||||
assign(:order, order)
|
||||
assign(:shops, [order.distributor])
|
||||
assign(:order_cycles, [])
|
||||
end
|
||||
|
||||
context "when some line items are out of stock" do
|
||||
let!(:out_of_stock_line_item) do
|
||||
line_item = order.line_items.first
|
||||
line_item.variant.update!(on_demand: false, on_hand: 0)
|
||||
line_item
|
||||
end
|
||||
|
||||
it "displays a table of out of stock line items" do
|
||||
render
|
||||
|
||||
expect(rendered).to have_content "Out of Stock"
|
||||
expect(rendered).to have_selector ".insufficient-stock-items",
|
||||
text: out_of_stock_line_item.variant.display_name
|
||||
end
|
||||
end
|
||||
|
||||
context "when all line items are in stock" do
|
||||
it "doesn't display a table of out of stock line items" do
|
||||
render
|
||||
|
||||
expect(rendered).to_not have_content "Out of Stock"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
2
vendor/assets/javascripts/jsuri.js
vendored
2
vendor/assets/javascripts/jsuri.js
vendored
@@ -1,2 +0,0 @@
|
||||
/*! jsUri v1.1.1 | https://github.com/derek-watson/jsUri */
|
||||
var Query=function(a){"use strict";var b=function(a){var b=[],c,d,e,f;if(typeof a=="undefined"||a===null||a==="")return b;a.indexOf("?")===0&&(a=a.substring(1)),d=a.toString().split(/[&;]/);for(c=0;c<d.length;c++)e=d[c],f=e.split("="),b.push([f[0],f[1]]);return b},c=b(a),d=function(){var a="",b,d;for(b=0;b<c.length;b++)d=c[b],a.length>0&&(a+="&"),a+=d.join("=");return a.length>0?"?"+a:a},e=function(a){a=decodeURIComponent(a),a=a.replace("+"," ");return a},f=function(a){var b,d;for(d=0;d<c.length;d++){b=c[d];if(e(a)===e(b[0]))return b[1]}},g=function(a){var b=[],d,f;for(d=0;d<c.length;d++)f=c[d],e(a)===e(f[0])&&b.push(f[1]);return b},h=function(a,b){var d=[],f,g,h,i;for(f=0;f<c.length;f++)g=c[f],h=e(g[0])===e(a),i=e(g[1])===e(b),(arguments.length===1&&!h||arguments.length===2&&!h&&!i)&&d.push(g);c=d;return this},i=function(a,b,d){arguments.length===3&&d!==-1?(d=Math.min(d,c.length),c.splice(d,0,[a,b])):arguments.length>0&&c.push([a,b]);return this},j=function(a,b,d){var f=-1,g,j;if(arguments.length===3){for(g=0;g<c.length;g++){j=c[g];if(e(j[0])===e(a)&&decodeURIComponent(j[1])===e(d)){f=g;break}}h(a,d).addParam(a,b,f)}else{for(g=0;g<c.length;g++){j=c[g];if(e(j[0])===e(a)){f=g;break}}h(a),i(a,b,f)}return this};return{getParamValue:f,getParamValues:g,deleteParam:h,addParam:i,replaceParam:j,toString:d}},Uri=function(a){"use strict";var b=!1,c=function(a){var c={strict:/^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,loose:/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/},d=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],e={name:"queryKey",parser:/(?:^|&)([^&=]*)=?([^&]*)/g},f=c[b?"strict":"loose"].exec(a),g={},h=14;while(h--)g[d[h]]=f[h]||"";g[e.name]={},g[d[12]].replace(e.parser,function(a,b,c){b&&(g[e.name][b]=c)});return g},d=c(a||""),e=new Query(d.query),f=function(a){typeof a!="undefined"&&(d.protocol=a);return d.protocol},g=null,h=function(a){typeof a!="undefined"&&(g=a);return g===null?d.source.indexOf("//")!==-1:g},i=function(a){typeof a!="undefined"&&(d.userInfo=a);return d.userInfo},j=function(a){typeof a!="undefined"&&(d.host=a);return d.host},k=function(a){typeof a!="undefined"&&(d.port=a);return d.port},l=function(a){typeof a!="undefined"&&(d.path=a);return d.path},m=function(a){typeof a!="undefined"&&(e=new Query(a));return e},n=function(a){typeof a!="undefined"&&(d.anchor=a);return d.anchor},o=function(a){f(a);return this},p=function(a){h(a);return this},q=function(a){i(a);return this},r=function(a){j(a);return this},s=function(a){k(a);return this},t=function(a){l(a);return this},u=function(a){m(a);return this},v=function(a){n(a);return this},w=function(a){return m().getParamValue(a)},x=function(a){return m().getParamValues(a)},y=function(a,b){arguments.length===2?m().deleteParam(a,b):m().deleteParam(a);return this},z=function(a,b,c){arguments.length===3?m().addParam(a,b,c):m().addParam(a,b);return this},A=function(a,b,c){arguments.length===3?m().replaceParam(a,b,c):m().replaceParam(a,b);return this},B=function(){var a="",b=function(a){return a!==null&&a!==""};b(f())?(a+=f(),f().indexOf(":")!==f().length-1&&(a+=":"),a+="//"):h()&&b(j())&&(a+="//"),b(i())&&b(j())&&(a+=i(),i().indexOf("@")!==i().length-1&&(a+="@")),b(j())&&(a+=j(),b(k())&&(a+=":"+k())),b(l())?a+=l():b(j())&&(b(m().toString())||b(n()))&&(a+="/"),b(m().toString())&&(m().toString().indexOf("?")!==0&&(a+="?"),a+=m().toString()),b(n())&&(n().indexOf("#")!==0&&(a+="#"),a+=n());return a},C=function(){return new Uri(B())};return{protocol:f,hasAuthorityPrefix:h,userInfo:i,host:j,port:k,path:l,query:m,anchor:n,setProtocol:o,setHasAuthorityPrefix:p,setUserInfo:q,setHost:r,setPort:s,setPath:t,setQuery:u,setAnchor:v,getQueryParamValue:w,getQueryParamValues:x,deleteQueryParam:y,addQueryParam:z,replaceQueryParam:A,toString:B,clone:C}},jsUri=Uri;
|
||||
131
yarn.lock
131
yarn.lock
@@ -5144,15 +5144,10 @@ data-urls@^2.0.0:
|
||||
whatwg-mimetype "^2.3.0"
|
||||
whatwg-url "^8.0.0"
|
||||
|
||||
date-format@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/date-format/-/date-format-2.1.0.tgz#31d5b5ea211cf5fd764cd38baf9d033df7e125cf"
|
||||
integrity sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA==
|
||||
|
||||
date-format@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/date-format/-/date-format-3.0.0.tgz#eb8780365c7d2b1511078fb491e6479780f3ad95"
|
||||
integrity sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w==
|
||||
date-format@^4.0.3:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/date-format/-/date-format-4.0.3.tgz#f63de5dc08dc02efd8ef32bf2a6918e486f35873"
|
||||
integrity sha512-7P3FyqDcfeznLZp2b+OMitV9Sz2lUnsT87WaTat9nVwqsBkTzPG3lPLNwW3en6F4pHUiWzr6vb8CLhjdK9bcxQ==
|
||||
|
||||
debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0:
|
||||
version "2.6.9"
|
||||
@@ -5161,10 +5156,10 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0:
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@4, debug@~4.3.2:
|
||||
version "4.3.2"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b"
|
||||
integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==
|
||||
debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.3, debug@~4.3.1, debug@~4.3.2:
|
||||
version "4.3.3"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664"
|
||||
integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==
|
||||
dependencies:
|
||||
ms "2.1.2"
|
||||
|
||||
@@ -5175,13 +5170,6 @@ debug@^3.0.0, debug@^3.1.1, debug@^3.2.6:
|
||||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
debug@^4.1.0, debug@^4.1.1, debug@~4.3.1:
|
||||
version "4.3.1"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
|
||||
integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==
|
||||
dependencies:
|
||||
ms "2.1.2"
|
||||
|
||||
decamelize@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
|
||||
@@ -6131,15 +6119,10 @@ flatpickr@^4.6.9:
|
||||
resolved "https://registry.yarnpkg.com/flatpickr/-/flatpickr-4.6.9.tgz#9a13383e8a6814bda5d232eae3fcdccb97dc1499"
|
||||
integrity sha512-F0azNNi8foVWKSF+8X+ZJzz8r9sE1G4hl06RyceIaLvyltKvDl6vqk9Lm/6AUUCi5HWaIjiUbk7UpeE/fOXOpw==
|
||||
|
||||
flatted@^2.0.1:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138"
|
||||
integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==
|
||||
|
||||
flatted@^3.2.2:
|
||||
version "3.2.2"
|
||||
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.2.tgz#64bfed5cb68fe3ca78b3eb214ad97b63bedce561"
|
||||
integrity sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==
|
||||
flatted@^3.2.2, flatted@^3.2.4:
|
||||
version "3.2.4"
|
||||
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.4.tgz#28d9969ea90661b5134259f312ab6aa7929ac5e2"
|
||||
integrity sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==
|
||||
|
||||
flatten@^1.0.2:
|
||||
version "1.0.3"
|
||||
@@ -6250,14 +6233,14 @@ fs-extra@^0.30.0:
|
||||
path-is-absolute "^1.0.0"
|
||||
rimraf "^2.2.8"
|
||||
|
||||
fs-extra@^8.1.0:
|
||||
version "8.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
|
||||
integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
|
||||
fs-extra@^10.0.0:
|
||||
version "10.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.0.tgz#9ff61b655dde53fb34a82df84bb214ce802e17c1"
|
||||
integrity sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==
|
||||
dependencies:
|
||||
graceful-fs "^4.2.0"
|
||||
jsonfile "^4.0.0"
|
||||
universalify "^0.1.0"
|
||||
jsonfile "^6.0.1"
|
||||
universalify "^2.0.0"
|
||||
|
||||
fs-extra@^9.0.0, fs-extra@^9.0.1:
|
||||
version "9.1.0"
|
||||
@@ -6541,11 +6524,16 @@ good-listener@^1.2.2:
|
||||
dependencies:
|
||||
delegate "^3.1.2"
|
||||
|
||||
graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6:
|
||||
graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.9, graceful-fs@^4.2.4, graceful-fs@^4.2.6:
|
||||
version "4.2.6"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee"
|
||||
integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==
|
||||
|
||||
graceful-fs@^4.1.6, graceful-fs@^4.2.0:
|
||||
version "4.2.9"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96"
|
||||
integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==
|
||||
|
||||
handle-thing@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e"
|
||||
@@ -8209,13 +8197,6 @@ jsonfile@^2.1.0:
|
||||
optionalDependencies:
|
||||
graceful-fs "^4.1.6"
|
||||
|
||||
jsonfile@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
|
||||
integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=
|
||||
optionalDependencies:
|
||||
graceful-fs "^4.1.6"
|
||||
|
||||
jsonfile@^6.0.1:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae"
|
||||
@@ -8438,15 +8419,15 @@ lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
|
||||
log4js@^6.3.0:
|
||||
version "6.3.0"
|
||||
resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.3.0.tgz#10dfafbb434351a3e30277a00b9879446f715bcb"
|
||||
integrity sha512-Mc8jNuSFImQUIateBFwdOQcmC6Q5maU0VVvdC2R6XMb66/VnT+7WS4D/0EeNMZu1YODmJe5NIn2XftCzEocUgw==
|
||||
version "6.4.0"
|
||||
resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.4.0.tgz#3f63ccfc8033c83cd617a4d2d50e48be5944eae9"
|
||||
integrity sha512-ysc/XUecZJuN8NoKOssk3V0cQ29xY4fra6fnigZa5VwxFsCsvdqsdnEuAxNN89LlHpbE4KUD3zGcn+kFqonSVQ==
|
||||
dependencies:
|
||||
date-format "^3.0.0"
|
||||
debug "^4.1.1"
|
||||
flatted "^2.0.1"
|
||||
rfdc "^1.1.4"
|
||||
streamroller "^2.2.4"
|
||||
date-format "^4.0.3"
|
||||
debug "^4.3.3"
|
||||
flatted "^3.2.4"
|
||||
rfdc "^1.3.0"
|
||||
streamroller "^3.0.2"
|
||||
|
||||
loglevel@^1.6.8:
|
||||
version "1.7.1"
|
||||
@@ -8928,9 +8909,9 @@ nan@^2.12.1:
|
||||
integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==
|
||||
|
||||
nanoid@^3.1.23:
|
||||
version "3.1.30"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.30.tgz#63f93cc548d2a113dc5dfbc63bfa09e2b9b64362"
|
||||
integrity sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c"
|
||||
integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==
|
||||
|
||||
nanomatch@^1.2.9:
|
||||
version "1.2.13"
|
||||
@@ -8983,9 +8964,11 @@ no-case@^3.0.4:
|
||||
tslib "^2.0.3"
|
||||
|
||||
node-fetch@^2.6.1:
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
|
||||
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
|
||||
version "2.6.7"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"
|
||||
integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==
|
||||
dependencies:
|
||||
whatwg-url "^5.0.0"
|
||||
|
||||
node-forge@^0.10.0:
|
||||
version "0.10.0"
|
||||
@@ -11070,7 +11053,7 @@ reusify@^1.0.4:
|
||||
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
|
||||
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
|
||||
|
||||
rfdc@^1.1.4:
|
||||
rfdc@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b"
|
||||
integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==
|
||||
@@ -11749,14 +11732,14 @@ stream-shift@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d"
|
||||
integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==
|
||||
|
||||
streamroller@^2.2.4:
|
||||
version "2.2.4"
|
||||
resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-2.2.4.tgz#c198ced42db94086a6193608187ce80a5f2b0e53"
|
||||
integrity sha512-OG79qm3AujAM9ImoqgWEY1xG4HX+Lw+yY6qZj9R1K2mhF5bEmQ849wvrb+4vt4jLMLzwXttJlQbOdPOQVRv7DQ==
|
||||
streamroller@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-3.0.2.tgz#30418d0eee3d6c93ec897f892ed098e3a81e68b7"
|
||||
integrity sha512-ur6y5S5dopOaRXBuRIZ1u6GC5bcEXHRZKgfBjfCglMhmIf+roVCECjvkEYzNQOXIN2/JPnkMPW/8B3CZoKaEPA==
|
||||
dependencies:
|
||||
date-format "^2.1.0"
|
||||
date-format "^4.0.3"
|
||||
debug "^4.1.1"
|
||||
fs-extra "^8.1.0"
|
||||
fs-extra "^10.0.0"
|
||||
|
||||
strict-uri-encode@^1.0.0:
|
||||
version "1.1.0"
|
||||
@@ -12232,6 +12215,11 @@ tr46@^2.1.0:
|
||||
dependencies:
|
||||
punycode "^2.1.1"
|
||||
|
||||
tr46@~0.0.3:
|
||||
version "0.0.3"
|
||||
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
|
||||
integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=
|
||||
|
||||
trim-trailing-lines@^1.0.0:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz#bd4abbec7cc880462f10b2c8b5ce1d8d1ec7c2c0"
|
||||
@@ -12489,7 +12477,7 @@ unist-util-visit@2.0.3, unist-util-visit@^2.0.0:
|
||||
unist-util-is "^4.0.0"
|
||||
unist-util-visit-parents "^3.0.0"
|
||||
|
||||
universalify@^0.1.0, universalify@^0.1.2:
|
||||
universalify@^0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
|
||||
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
|
||||
@@ -12766,6 +12754,11 @@ web-namespaces@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.4.tgz#bc98a3de60dadd7faefc403d1076d529f5e030ec"
|
||||
integrity sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==
|
||||
|
||||
webidl-conversions@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
|
||||
integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=
|
||||
|
||||
webidl-conversions@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff"
|
||||
@@ -12949,6 +12942,14 @@ whatwg-mimetype@^2.3.0:
|
||||
resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf"
|
||||
integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==
|
||||
|
||||
whatwg-url@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
|
||||
integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0=
|
||||
dependencies:
|
||||
tr46 "~0.0.3"
|
||||
webidl-conversions "^3.0.0"
|
||||
|
||||
whatwg-url@^8.0.0, whatwg-url@^8.5.0:
|
||||
version "8.7.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77"
|
||||
|
||||
Reference in New Issue
Block a user