mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-03-01 02:03:22 +00:00
Compare commits
92 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b455755bfc | ||
|
|
619ecf9432 | ||
|
|
4f152a9151 | ||
|
|
8d7252f078 | ||
|
|
08399e753d | ||
|
|
8d721ccac8 | ||
|
|
b7a1b39c1a | ||
|
|
e276fb0386 | ||
|
|
f86eb3fb82 | ||
|
|
0d46a3bc2e | ||
|
|
0418163ad7 | ||
|
|
2e67899bcc | ||
|
|
e2536ffe71 | ||
|
|
2c6b758f66 | ||
|
|
fb0f379c43 | ||
|
|
7a4aa9dcb1 | ||
|
|
4e8d37b0b5 | ||
|
|
616de3a9c0 | ||
|
|
16b3da66c2 | ||
|
|
691995eeaa | ||
|
|
045482e07d | ||
|
|
62f25d4d31 | ||
|
|
618c7028e2 | ||
|
|
13cec27f6b | ||
|
|
5b925517f0 | ||
|
|
167099badf | ||
|
|
40d8839bc4 | ||
|
|
da1e1a9859 | ||
|
|
43ad7654b6 | ||
|
|
15d83724ea | ||
|
|
47652e9d25 | ||
|
|
b5315c2123 | ||
|
|
97ce4eaccd | ||
|
|
8814427677 | ||
|
|
4b69e192ec | ||
|
|
9c99f4868c | ||
|
|
39d59c3a5f | ||
|
|
ad9a12da0e | ||
|
|
9968776726 | ||
|
|
d99a88817d | ||
|
|
1b36cce816 | ||
|
|
4b157abd4d | ||
|
|
dc494bb0f9 | ||
|
|
b3e7b12b86 | ||
|
|
b69e6827cc | ||
|
|
340f459912 | ||
|
|
33a96d5a0f | ||
|
|
93d6db9d44 | ||
|
|
c1068af0ba | ||
|
|
482c2a4a6e | ||
|
|
2557a4de39 | ||
|
|
ab1f43f1ac | ||
|
|
f921524588 | ||
|
|
5cbd507c1e | ||
|
|
532bfaaa2d | ||
|
|
70b31a4212 | ||
|
|
9da3b0ea01 | ||
|
|
51df612c51 | ||
|
|
3be0cca230 | ||
|
|
283d13eb35 | ||
|
|
b21224d5ff | ||
|
|
4744d7b741 | ||
|
|
ac1dd74e23 | ||
|
|
970f486ec0 | ||
|
|
8c244e8b56 | ||
|
|
c3cc01c677 | ||
|
|
c63e60d782 | ||
|
|
11e8c9456d | ||
|
|
860a21f86f | ||
|
|
d24af18ff4 | ||
|
|
33b191f439 | ||
|
|
a690d39864 | ||
|
|
7c0586db7b | ||
|
|
461fd00ccd | ||
|
|
f872201fef | ||
|
|
162c58ac39 | ||
|
|
02d47d0a0d | ||
|
|
e86bf441ab | ||
|
|
f9617b8156 | ||
|
|
4650e30c09 | ||
|
|
2749965e73 | ||
|
|
e87965bda0 | ||
|
|
9dcb3ec748 | ||
|
|
90c23d0245 | ||
|
|
99e238d92d | ||
|
|
8eb9709a04 | ||
|
|
5f31baa022 | ||
|
|
b58834b11f | ||
|
|
d4811648f1 | ||
|
|
77fe1fa6f9 | ||
|
|
03b7c07495 | ||
|
|
a3c08ceb7c |
8
.github/workflows/build.yml
vendored
8
.github/workflows/build.yml
vendored
@@ -46,7 +46,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup redis
|
||||
uses: supercharge/redis-github-action@1.4.0
|
||||
uses: supercharge/redis-github-action@1.8.1
|
||||
with:
|
||||
redis-version: 6
|
||||
|
||||
@@ -124,7 +124,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup redis
|
||||
uses: supercharge/redis-github-action@1.4.0
|
||||
uses: supercharge/redis-github-action@1.8.1
|
||||
with:
|
||||
redis-version: 6
|
||||
|
||||
@@ -211,7 +211,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup redis
|
||||
uses: supercharge/redis-github-action@1.4.0
|
||||
uses: supercharge/redis-github-action@1.8.1
|
||||
with:
|
||||
redis-version: 6
|
||||
|
||||
@@ -290,7 +290,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup redis
|
||||
uses: supercharge/redis-github-action@1.4.0
|
||||
uses: supercharge/redis-github-action@1.8.1
|
||||
with:
|
||||
redis-version: 6
|
||||
|
||||
|
||||
92
Gemfile.lock
92
Gemfile.lock
@@ -112,7 +112,7 @@ GEM
|
||||
rails-html-sanitizer (~> 1.6)
|
||||
active_model_serializers (0.8.4)
|
||||
activemodel (>= 3.0)
|
||||
active_storage_validations (3.0.2)
|
||||
active_storage_validations (3.0.3)
|
||||
activejob (>= 6.1.4)
|
||||
activemodel (>= 6.1.4)
|
||||
activestorage (>= 6.1.4)
|
||||
@@ -210,12 +210,12 @@ GEM
|
||||
bigdecimal (3.3.1)
|
||||
bindata (2.5.1)
|
||||
bindex (0.8.1)
|
||||
bootsnap (1.19.0)
|
||||
bootsnap (1.22.0)
|
||||
msgpack (~> 1.2)
|
||||
bugsnag (6.28.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
builder (3.3.0)
|
||||
bullet (8.0.8)
|
||||
bullet (8.1.0)
|
||||
activesupport (>= 3.0.0)
|
||||
uniform_notifier (~> 1.11)
|
||||
cable_ready (5.0.6)
|
||||
@@ -242,7 +242,7 @@ GEM
|
||||
marcel (~> 1.0)
|
||||
nokogiri (~> 1.10, >= 1.10.4)
|
||||
rubyzip (>= 1.3.0, < 3)
|
||||
cgi (0.5.0)
|
||||
cgi (0.5.1)
|
||||
childprocess (5.0.0)
|
||||
choice (0.2.0)
|
||||
chronic (0.10.2)
|
||||
@@ -257,7 +257,7 @@ GEM
|
||||
combine_pdf (1.0.31)
|
||||
matrix
|
||||
ruby-rc4 (>= 0.1.5)
|
||||
concurrent-ruby (1.3.5)
|
||||
concurrent-ruby (1.3.6)
|
||||
connection_pool (2.5.5)
|
||||
cookiejar (0.3.4)
|
||||
crack (1.0.1)
|
||||
@@ -278,7 +278,7 @@ GEM
|
||||
database_cleaner-core (2.0.1)
|
||||
datafoodconsortium-connector (1.2.0)
|
||||
virtual_assembly-semantizer (~> 1.0, >= 1.0.5)
|
||||
date (3.5.0)
|
||||
date (3.5.1)
|
||||
debug (1.11.0)
|
||||
irb (~> 1.10)
|
||||
reline (>= 0.3.8)
|
||||
@@ -326,19 +326,21 @@ GEM
|
||||
factory_bot_rails (6.2.0)
|
||||
factory_bot (~> 6.2.0)
|
||||
railties (>= 5.0.0)
|
||||
faraday (2.9.0)
|
||||
faraday-net_http (>= 2.0, < 3.2)
|
||||
faraday (2.14.1)
|
||||
faraday-net_http (>= 2.0, < 3.5)
|
||||
json
|
||||
logger
|
||||
faraday-follow_redirects (0.4.0)
|
||||
faraday (>= 1, < 3)
|
||||
faraday-net_http (3.1.1)
|
||||
net-http
|
||||
faraday-net_http (3.4.2)
|
||||
net-http (~> 0.5)
|
||||
ferrum (0.14)
|
||||
addressable (~> 2.5)
|
||||
concurrent-ruby (~> 1.1)
|
||||
webrick (~> 1.7)
|
||||
websocket-driver (>= 0.6, < 0.8)
|
||||
ffaker (2.25.0)
|
||||
ffi (1.17.2)
|
||||
ffi (1.17.3)
|
||||
flipper (1.3.6)
|
||||
concurrent-ruby (< 2)
|
||||
flipper-active_record (1.3.6)
|
||||
@@ -396,7 +398,8 @@ GEM
|
||||
sysexits (~> 1.1)
|
||||
hashdiff (1.2.1)
|
||||
hashery (2.1.2)
|
||||
hashie (5.0.0)
|
||||
hashie (5.1.0)
|
||||
logger
|
||||
highline (3.1.2)
|
||||
reline
|
||||
htmlentities (4.4.2)
|
||||
@@ -425,10 +428,11 @@ GEM
|
||||
activerecord (>= 3.0)
|
||||
invisible_captcha (2.3.0)
|
||||
rails (>= 5.2)
|
||||
io-console (0.8.1)
|
||||
io-console (0.8.2)
|
||||
ipaddress (0.8.3)
|
||||
irb (1.15.3)
|
||||
irb (1.17.0)
|
||||
pp (>= 0.6.0)
|
||||
prism (>= 1.3.0)
|
||||
rdoc (>= 4.0.0)
|
||||
reline (>= 0.4.2)
|
||||
jmespath (1.6.2)
|
||||
@@ -438,7 +442,7 @@ GEM
|
||||
thor (>= 0.14, < 2.0)
|
||||
jquery-ui-rails (4.2.1)
|
||||
railties (>= 3.2.16)
|
||||
json (2.15.2)
|
||||
json (2.18.1)
|
||||
json-canonicalization (1.0.0)
|
||||
json-jwt (1.17.0)
|
||||
activesupport (>= 4.2)
|
||||
@@ -464,7 +468,7 @@ GEM
|
||||
activesupport (>= 4.2)
|
||||
jwt (2.10.2)
|
||||
base64
|
||||
knapsack_pro (8.4.0)
|
||||
knapsack_pro (9.2.2)
|
||||
rake
|
||||
language_server-protocol (3.17.0.5)
|
||||
launchy (3.0.0)
|
||||
@@ -474,11 +478,12 @@ GEM
|
||||
launchy (>= 2.2, < 4)
|
||||
link_header (0.0.8)
|
||||
lint_roller (1.1.0)
|
||||
listen (3.9.0)
|
||||
listen (3.10.0)
|
||||
logger
|
||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||
rb-inotify (~> 0.9, >= 0.9.10)
|
||||
logger (1.7.0)
|
||||
loofah (2.24.1)
|
||||
loofah (2.25.0)
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.12.0)
|
||||
mail (2.9.0)
|
||||
@@ -501,7 +506,8 @@ GEM
|
||||
logger
|
||||
mini_mime (1.1.5)
|
||||
mini_portile2 (2.8.6)
|
||||
minitest (5.26.2)
|
||||
minitest (6.0.1)
|
||||
prism (~> 1.5)
|
||||
monetize (1.13.0)
|
||||
money (~> 6.12)
|
||||
money (6.16.0)
|
||||
@@ -510,8 +516,8 @@ GEM
|
||||
multi_json (1.17.0)
|
||||
multi_xml (0.6.0)
|
||||
mutex_m (0.3.0)
|
||||
net-http (0.7.0)
|
||||
uri
|
||||
net-http (0.9.1)
|
||||
uri (>= 0.11.1)
|
||||
net-imap (0.5.12)
|
||||
date
|
||||
net-protocol
|
||||
@@ -523,7 +529,8 @@ GEM
|
||||
net-protocol
|
||||
newrelic_rpm (9.24.0)
|
||||
nio4r (2.7.5)
|
||||
nokogiri (1.18.10)
|
||||
nokogiri (1.19.0)
|
||||
mini_portile2 (~> 2.8.2)
|
||||
racc (~> 1.4)
|
||||
nokogiri-html5-inference (0.3.0)
|
||||
nokogiri (~> 1.14)
|
||||
@@ -539,7 +546,7 @@ GEM
|
||||
logger
|
||||
rack (>= 2.2.3)
|
||||
rack-protection
|
||||
omniauth-rails_csrf_protection (1.0.2)
|
||||
omniauth-rails_csrf_protection (2.0.1)
|
||||
actionpack (>= 4.2)
|
||||
omniauth (~> 2.0)
|
||||
omniauth_openid_connect (0.8.0)
|
||||
@@ -568,7 +575,7 @@ GEM
|
||||
parallel (1.27.0)
|
||||
paranoia (2.6.4)
|
||||
activerecord (>= 5.1, < 7.2)
|
||||
parser (3.3.10.0)
|
||||
parser (3.3.10.2)
|
||||
ast (~> 2.4.1)
|
||||
racc
|
||||
paypal-sdk-core (0.3.4)
|
||||
@@ -586,11 +593,12 @@ GEM
|
||||
pp (0.6.3)
|
||||
prettyprint
|
||||
prettyprint (0.2.0)
|
||||
prism (1.7.0)
|
||||
prism (1.9.0)
|
||||
private_address_check (0.5.0)
|
||||
pry (0.15.2)
|
||||
pry (0.16.0)
|
||||
coderay (~> 1.1)
|
||||
method_source (~> 1.0)
|
||||
reline (>= 0.6.0)
|
||||
psych (5.3.1)
|
||||
date
|
||||
stringio
|
||||
@@ -610,7 +618,7 @@ GEM
|
||||
railties (>= 4.2)
|
||||
raabro (1.4.0)
|
||||
racc (1.8.1)
|
||||
rack (2.2.21)
|
||||
rack (2.2.22)
|
||||
rack-mini-profiler (2.3.4)
|
||||
rack (>= 1.2.0)
|
||||
rack-oauth2 (2.3.0)
|
||||
@@ -684,7 +692,7 @@ GEM
|
||||
activesupport (>= 6.1.5)
|
||||
i18n
|
||||
rb-fsevent (0.11.2)
|
||||
rb-inotify (0.10.1)
|
||||
rb-inotify (0.11.1)
|
||||
ffi (~> 1.0)
|
||||
rdf (3.3.4)
|
||||
bcp47_spec (~> 0.2)
|
||||
@@ -693,7 +701,7 @@ GEM
|
||||
logger (~> 1.5)
|
||||
ostruct (~> 0.6)
|
||||
readline (~> 0.0)
|
||||
rdoc (7.0.1)
|
||||
rdoc (7.2.0)
|
||||
erb
|
||||
psych (>= 4.0.0)
|
||||
tsort
|
||||
@@ -709,9 +717,9 @@ GEM
|
||||
io-console (~> 0.5)
|
||||
request_store (1.7.0)
|
||||
rack (>= 1.4)
|
||||
responders (3.1.1)
|
||||
actionpack (>= 5.2)
|
||||
railties (>= 5.2)
|
||||
responders (3.2.0)
|
||||
actionpack (>= 7.0)
|
||||
railties (>= 7.0)
|
||||
rexml (3.4.4)
|
||||
roadie (5.2.1)
|
||||
css_parser (~> 1.4)
|
||||
@@ -766,7 +774,7 @@ GEM
|
||||
rswag-ui (2.17.0)
|
||||
actionpack (>= 5.2, < 8.2)
|
||||
railties (>= 5.2, < 8.2)
|
||||
rubocop (1.81.7)
|
||||
rubocop (1.84.2)
|
||||
json (~> 2.3)
|
||||
language_server-protocol (~> 3.17.0.2)
|
||||
lint_roller (~> 1.1.0)
|
||||
@@ -774,25 +782,25 @@ GEM
|
||||
parser (>= 3.3.0.2)
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
regexp_parser (>= 2.9.3, < 3.0)
|
||||
rubocop-ast (>= 1.47.1, < 2.0)
|
||||
rubocop-ast (>= 1.49.0, < 2.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (>= 2.4.0, < 4.0)
|
||||
rubocop-ast (1.48.0)
|
||||
rubocop-ast (1.49.0)
|
||||
parser (>= 3.3.7.2)
|
||||
prism (~> 1.4)
|
||||
prism (~> 1.7)
|
||||
rubocop-capybara (2.22.1)
|
||||
lint_roller (~> 1.1)
|
||||
rubocop (~> 1.72, >= 1.72.1)
|
||||
rubocop-factory_bot (2.28.0)
|
||||
lint_roller (~> 1.1)
|
||||
rubocop (~> 1.72, >= 1.72.1)
|
||||
rubocop-rails (2.34.2)
|
||||
rubocop-rails (2.34.3)
|
||||
activesupport (>= 4.2.0)
|
||||
lint_roller (~> 1.1)
|
||||
rack (>= 1.1)
|
||||
rubocop (>= 1.75.0, < 2.0)
|
||||
rubocop-ast (>= 1.44.0, < 2.0)
|
||||
rubocop-rspec (3.8.0)
|
||||
rubocop-rspec (3.9.0)
|
||||
lint_roller (~> 1.1)
|
||||
rubocop (~> 1.81)
|
||||
rubocop-rspec_rails (2.32.0)
|
||||
@@ -844,7 +852,7 @@ GEM
|
||||
caxlsx (<= 4.0)
|
||||
csv
|
||||
rodf
|
||||
spring (4.4.0)
|
||||
spring (4.4.2)
|
||||
spring-commands-rspec (1.0.4)
|
||||
spring (>= 0.9.1)
|
||||
spring-commands-rubocop (0.4.0)
|
||||
@@ -889,10 +897,10 @@ GEM
|
||||
temple (0.10.4)
|
||||
terminal-table (4.0.0)
|
||||
unicode-display_width (>= 1.1.1, < 4)
|
||||
thor (1.4.0)
|
||||
thor (1.5.0)
|
||||
thread-local (1.1.0)
|
||||
tilt (2.6.1)
|
||||
timeout (0.4.4)
|
||||
timeout (0.6.0)
|
||||
tsort (0.2.0)
|
||||
ttfunk (1.8.0)
|
||||
bigdecimal (~> 3.1)
|
||||
@@ -914,7 +922,7 @@ GEM
|
||||
unicode-display_width (3.2.0)
|
||||
unicode-emoji (~> 4.1)
|
||||
unicode-emoji (4.2.0)
|
||||
uniform_notifier (1.17.0)
|
||||
uniform_notifier (1.18.0)
|
||||
uri (1.1.1)
|
||||
valid_email2 (5.2.3)
|
||||
activemodel (>= 3.2)
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class SearchableDropdownComponent < ViewComponent::Base
|
||||
REMOVED_SEARCH_PLUGIN = { 'tom-select-options-value': '{ "plugins": [] }' }.freeze
|
||||
MINIMUM_OPTIONS_FOR_SEARCH_FIELD = 11 # at least 11 options are required for the search field
|
||||
|
||||
def initialize(
|
||||
form:,
|
||||
name:,
|
||||
options:,
|
||||
selected_option:,
|
||||
placeholder_value:,
|
||||
form: nil,
|
||||
placeholder_value: '',
|
||||
include_blank: false,
|
||||
aria_label: '',
|
||||
multiple: false,
|
||||
remote_url: nil,
|
||||
other_attrs: {}
|
||||
)
|
||||
@f = form
|
||||
@@ -21,13 +22,15 @@ class SearchableDropdownComponent < ViewComponent::Base
|
||||
@placeholder_value = placeholder_value
|
||||
@include_blank = include_blank
|
||||
@aria_label = aria_label
|
||||
@multiple = multiple
|
||||
@remote_url = remote_url
|
||||
@other_attrs = other_attrs
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :f, :name, :options, :selected_option, :placeholder_value, :include_blank,
|
||||
:aria_label, :other_attrs
|
||||
:aria_label, :multiple, :remote_url, :other_attrs
|
||||
|
||||
def classes
|
||||
"fullwidth #{'no-input' if remove_search_plugin?}"
|
||||
@@ -36,11 +39,33 @@ class SearchableDropdownComponent < ViewComponent::Base
|
||||
def data
|
||||
{
|
||||
controller: "tom-select",
|
||||
'tom-select-placeholder-value': placeholder_value
|
||||
}.merge(remove_search_plugin? ? REMOVED_SEARCH_PLUGIN : {})
|
||||
'tom-select-placeholder-value': placeholder_value,
|
||||
'tom-select-options-value': tom_select_options_value,
|
||||
'tom-select-remote-url-value': remote_url,
|
||||
}
|
||||
end
|
||||
|
||||
def tom_select_options_value
|
||||
plugins = []
|
||||
plugins << 'virtual_scroll' if @remote_url.present?
|
||||
plugins << 'dropdown_input' unless remove_search_plugin?
|
||||
plugins << 'remove_button' if multiple
|
||||
|
||||
{
|
||||
plugins:,
|
||||
maxItems: multiple ? nil : 1,
|
||||
}
|
||||
end
|
||||
|
||||
def uses_form_builder?
|
||||
f.present?
|
||||
end
|
||||
|
||||
def remove_search_plugin?
|
||||
@remove_search_plugin ||= options.count < MINIMUM_OPTIONS_FOR_SEARCH_FIELD
|
||||
# Remove the search plugin when:
|
||||
# - the select is multiple (it already includes a search field), or
|
||||
# - there is no remote URL and the options are below the search threshold
|
||||
@remove_search_plugin ||= multiple ||
|
||||
(@remote_url.nil? && options.count < MINIMUM_OPTIONS_FOR_SEARCH_FIELD)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1 +1,4 @@
|
||||
= f.select name, options_for_select(options, selected_option), { include_blank: }, class: classes, data:, 'aria-label': aria_label, **other_attrs
|
||||
- if uses_form_builder?
|
||||
= f.select name, options, { selected: selected_option, include_blank:, multiple: }, class: classes, data:, 'aria-label': aria_label, **other_attrs
|
||||
- else
|
||||
= select_tag name, options_for_select(options, selected_option), include_blank:, multiple:, class: classes, data:, 'aria-label': aria_label, **other_attrs
|
||||
|
||||
@@ -4,6 +4,7 @@ module Admin
|
||||
class ReportsController < Spree::Admin::BaseController
|
||||
include ActiveStorage::SetCurrent
|
||||
include ReportsActions
|
||||
include Reports::AjaxSearch
|
||||
|
||||
helper ReportsHelper
|
||||
|
||||
|
||||
108
app/controllers/concerns/reports/ajax_search.rb
Normal file
108
app/controllers/concerns/reports/ajax_search.rb
Normal file
@@ -0,0 +1,108 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Reports
|
||||
module AjaxSearch
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def search_enterprise_fees
|
||||
report = report_class.new(spree_current_user, params, render: false)
|
||||
fee_ids = enterprise_fee_ids(report.search.result)
|
||||
query = EnterpriseFee.where(id: fee_ids)
|
||||
|
||||
render json: build_search_response(query)
|
||||
end
|
||||
|
||||
def search_enterprise_fee_owners
|
||||
report = report_class.new(spree_current_user, params, render: false)
|
||||
owner_ids = enterprise_fee_owner_ids(report.search.result)
|
||||
query = Enterprise.where(id: owner_ids)
|
||||
|
||||
render json: build_search_response(query)
|
||||
end
|
||||
|
||||
def search_distributors
|
||||
query = frontend_data.distributors
|
||||
|
||||
render json: build_search_response(query)
|
||||
end
|
||||
|
||||
def search_order_cycles
|
||||
query = frontend_data.order_cycles
|
||||
|
||||
render json: build_search_response(query)
|
||||
end
|
||||
|
||||
def search_order_customers
|
||||
query = frontend_data.order_customers
|
||||
|
||||
render json: build_search_response(query)
|
||||
end
|
||||
|
||||
def search_suppliers
|
||||
query = frontend_data.orders_suppliers
|
||||
|
||||
render json: build_search_response(query)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def build_search_response(query)
|
||||
page = (params[:page] || 1).to_i
|
||||
per_page = 30
|
||||
|
||||
filtered_query = apply_search_filter(query)
|
||||
total_count = filtered_query.size
|
||||
items = paginated_items(filtered_query, page, per_page)
|
||||
results = format_results(items)
|
||||
|
||||
{ results: results, pagination: { more: (page * per_page) < total_count } }
|
||||
end
|
||||
|
||||
def apply_search_filter(query)
|
||||
search_term = params[:q]
|
||||
return query if search_term.blank?
|
||||
|
||||
escaped_search_term = ActiveRecord::Base.sanitize_sql_like(search_term)
|
||||
pattern = "%#{escaped_search_term}%"
|
||||
|
||||
# Handle different model types
|
||||
if query.model == OrderCycle
|
||||
query.where("order_cycles.name ILIKE ?", pattern)
|
||||
elsif query.model == Customer
|
||||
query.where("customers.email ILIKE ?", pattern)
|
||||
else
|
||||
query.where("name ILIKE ?", pattern)
|
||||
end
|
||||
end
|
||||
|
||||
def paginated_items(query, page, per_page)
|
||||
if query.model == Customer
|
||||
query.order(:email).offset((page - 1) * per_page).limit(per_page).pluck(:email, :id)
|
||||
elsif query.model == OrderCycle
|
||||
query.order('order_cycles.orders_close_at DESC')
|
||||
.offset((page - 1) * per_page)
|
||||
.limit(per_page).pluck(
|
||||
:name, :id
|
||||
)
|
||||
else
|
||||
query.order(:name).offset((page - 1) * per_page).limit(per_page).pluck(:name, :id)
|
||||
end
|
||||
end
|
||||
|
||||
def format_results(items)
|
||||
items.map { |label, value| { value:, label: } }
|
||||
end
|
||||
|
||||
def frontend_data
|
||||
@frontend_data ||= Reporting::FrontendData.new(spree_current_user)
|
||||
end
|
||||
|
||||
def enterprise_fee_owner_ids(orders)
|
||||
EnterpriseFee.where(id: enterprise_fee_ids(orders)).select(:enterprise_id)
|
||||
end
|
||||
|
||||
def enterprise_fee_ids(orders)
|
||||
Spree::Adjustment.enterprise_fee.where(order_id: orders.select(:id)).select(:originator_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -138,7 +138,7 @@ module Spree
|
||||
|
||||
providers.delete("Spree::Gateway::StripeSCA") unless show_stripe?
|
||||
|
||||
providers.map(&:constantize)
|
||||
providers
|
||||
end
|
||||
|
||||
# Show Stripe as an option if enabled, or if the
|
||||
|
||||
@@ -95,8 +95,7 @@ module Spree
|
||||
private
|
||||
|
||||
def load_payment_source
|
||||
if @payment.payment_method.is_a?(Spree::Gateway) &&
|
||||
@payment.payment_method.payment_profiles_supported? &&
|
||||
if @payment.payment_method.is_a?(Gateway::StripeSCA) &&
|
||||
params[:card].present? &&
|
||||
(params[:card] != 'new')
|
||||
@payment.source = CreditCard.find_by(id: params[:card])
|
||||
|
||||
@@ -34,29 +34,8 @@ module ReportsHelper
|
||||
end
|
||||
end
|
||||
|
||||
def fee_name_options(orders)
|
||||
EnterpriseFee.where(id: enterprise_fee_ids(orders))
|
||||
.pluck(:name, :id)
|
||||
end
|
||||
|
||||
def fee_owner_options(orders)
|
||||
Enterprise.where(id: enterprise_fee_owner_ids(orders))
|
||||
.pluck(:name, :id)
|
||||
end
|
||||
|
||||
delegate :currency_symbol, to: :'Spree::Money'
|
||||
|
||||
def enterprise_fee_owner_ids(orders)
|
||||
EnterpriseFee.where(id: enterprise_fee_ids(orders))
|
||||
.pluck(:enterprise_id)
|
||||
end
|
||||
|
||||
def enterprise_fee_ids(orders)
|
||||
Spree::Adjustment.enterprise_fee
|
||||
.where(order_id: orders.map(&:id))
|
||||
.pluck(:originator_id)
|
||||
end
|
||||
|
||||
def datepicker_time(datetime)
|
||||
datetime = Time.zone.parse(datetime) if datetime.is_a? String
|
||||
datetime.strftime('%Y-%m-%d %H:%M')
|
||||
|
||||
18
app/helpers/spree/admin/payment_methods_helper.rb
Normal file
18
app/helpers/spree/admin/payment_methods_helper.rb
Normal file
@@ -0,0 +1,18 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Spree
|
||||
module Admin
|
||||
module PaymentMethodsHelper
|
||||
def payment_method_type_name(class_name)
|
||||
scope = "spree.admin.payment_methods.providers"
|
||||
key = class_name.demodulize.downcase
|
||||
|
||||
I18n.t(key, scope:)
|
||||
end
|
||||
|
||||
def payment_method_type_options(providers)
|
||||
providers.map { |p| [payment_method_type_name(p), p] }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -6,6 +6,11 @@ module Spree
|
||||
class Ability
|
||||
include CanCan::Ability
|
||||
|
||||
REPORTS_SEARCH_ACTIONS = [
|
||||
:search_enterprise_fees, :search_enterprise_fee_owners, :search_distributors,
|
||||
:search_suppliers, :search_order_cycles, :search_order_customers
|
||||
].freeze
|
||||
|
||||
def initialize(user)
|
||||
clear_aliased_actions
|
||||
|
||||
@@ -260,7 +265,8 @@ module Spree
|
||||
can [:admin, :index, :import], ::Admin::DfcProductImportsController
|
||||
|
||||
# Reports page
|
||||
can [:admin, :index, :show, :create], ::Admin::ReportsController
|
||||
can [:admin, :index, :show, :create, *REPORTS_SEARCH_ACTIONS],
|
||||
::Admin::ReportsController
|
||||
can [:admin, :show, :create, :customers, :orders_and_distributors, :group_buys, :payments,
|
||||
:orders_and_fulfillment, :products_and_inventory, :order_cycle_management,
|
||||
:packing, :enterprise_fee_summary, :bulk_coop, :suppliers], :report
|
||||
@@ -392,7 +398,7 @@ module Spree
|
||||
end
|
||||
|
||||
# Reports page
|
||||
can [:admin, :index, :show, :create], ::Admin::ReportsController
|
||||
can [:admin, :index, :show, :create, *REPORTS_SEARCH_ACTIONS], ::Admin::ReportsController
|
||||
can [:admin, :customers, :group_buys, :sales_tax, :payments,
|
||||
:orders_and_distributors, :orders_and_fulfillment, :products_and_inventory,
|
||||
:order_cycle_management, :xero_invoices, :enterprise_fee_summary, :bulk_coop], :report
|
||||
|
||||
@@ -5,7 +5,7 @@ module Spree
|
||||
acts_as_taggable
|
||||
include PaymentMethodDistributors
|
||||
|
||||
delegate :authorize, :purchase, :capture, :void, :credit, to: :provider
|
||||
delegate :authorize, :purchase, :capture, :void, :credit, :refund, to: :provider
|
||||
|
||||
validates :name, :type, presence: true
|
||||
|
||||
@@ -35,6 +35,10 @@ module Spree
|
||||
end
|
||||
|
||||
def method_missing(method, *)
|
||||
message = "Deprecated delegation of Gateway##{method}"
|
||||
Alert.raise(message)
|
||||
raise message if Rails.env.local?
|
||||
|
||||
if @provider.nil? || !@provider.respond_to?(method)
|
||||
super
|
||||
else
|
||||
@@ -42,10 +46,6 @@ module Spree
|
||||
end
|
||||
end
|
||||
|
||||
def payment_profiles_supported?
|
||||
false
|
||||
end
|
||||
|
||||
def method_type
|
||||
'gateway'
|
||||
end
|
||||
|
||||
@@ -35,10 +35,6 @@ module Spree
|
||||
ActiveMerchant::Billing::StripePaymentIntentsGateway
|
||||
end
|
||||
|
||||
def payment_profiles_supported?
|
||||
true
|
||||
end
|
||||
|
||||
def stripe_account_id
|
||||
StripeAccount.find_by(enterprise_id: preferred_enterprise_id)&.stripe_user_id
|
||||
end
|
||||
@@ -84,7 +80,7 @@ module Spree
|
||||
end
|
||||
|
||||
# NOTE: this method is required by Spree::Payment::Processing
|
||||
def void(payment_intent_id, _creditcard, gateway_options)
|
||||
def void(payment_intent_id, gateway_options)
|
||||
payment_intent_response = Stripe::PaymentIntent.retrieve(
|
||||
payment_intent_id, stripe_account: stripe_account_id
|
||||
)
|
||||
@@ -101,7 +97,13 @@ module Spree
|
||||
end
|
||||
|
||||
# NOTE: this method is required by Spree::Payment::Processing
|
||||
def credit(money, _creditcard, payment_intent_id, gateway_options)
|
||||
def credit(money, payment_intent_id, gateway_options)
|
||||
gateway_options[:stripe_account] = stripe_account_id
|
||||
provider.refund(money, payment_intent_id, gateway_options)
|
||||
end
|
||||
|
||||
# NOTE: this method is required by Spree::Payment::Processing
|
||||
def refund(money, payment_intent_id, gateway_options)
|
||||
gateway_options[:stripe_account] = stripe_account_id
|
||||
provider.refund(money, payment_intent_id, gateway_options)
|
||||
end
|
||||
|
||||
@@ -34,7 +34,7 @@ module Spree
|
||||
|
||||
# invalidate previously entered payments
|
||||
after_create :invalidate_old_payments
|
||||
after_save :create_payment_profile, if: :profiles_supported?
|
||||
after_save :create_payment_profile
|
||||
|
||||
# update the order totals, etc.
|
||||
after_save :ensure_correct_adjustment, :update_order
|
||||
@@ -217,18 +217,13 @@ module Spree
|
||||
errors.blank?
|
||||
end
|
||||
|
||||
def profiles_supported?
|
||||
payment_method.respond_to?(:payment_profiles_supported?) &&
|
||||
payment_method.payment_profiles_supported?
|
||||
end
|
||||
|
||||
def create_payment_profile
|
||||
return unless source.is_a?(CreditCard)
|
||||
return unless source.try(:save_requested_by_customer?)
|
||||
return unless source.number || source.gateway_payment_profile_id
|
||||
return unless source.gateway_customer_profile_id.nil?
|
||||
|
||||
payment_method.create_profile(self)
|
||||
payment_method.try(:create_profile, self)
|
||||
rescue ActiveMerchant::ConnectionError => e
|
||||
gateway_error e
|
||||
end
|
||||
|
||||
@@ -58,16 +58,7 @@ module Spree
|
||||
protect_from_connection_error do
|
||||
check_environment
|
||||
|
||||
response = if payment_method.payment_profiles_supported?
|
||||
# Gateways supporting payment profiles will need access to credit
|
||||
# card object because this stores the payment profile information
|
||||
# so supply the authorization itself as well as the credit card,
|
||||
# rather than just the authorization code
|
||||
payment_method.void(response_code, source, gateway_options)
|
||||
else
|
||||
# Standard ActiveMerchant void usage
|
||||
payment_method.void(response_code, gateway_options)
|
||||
end
|
||||
response = payment_method.void(response_code, gateway_options)
|
||||
|
||||
record_response(response)
|
||||
|
||||
@@ -86,20 +77,11 @@ module Spree
|
||||
|
||||
credit_amount = calculate_refund_amount(credit_amount)
|
||||
|
||||
response = if payment_method.payment_profiles_supported?
|
||||
payment_method.credit(
|
||||
(credit_amount * 100).round,
|
||||
source,
|
||||
response_code,
|
||||
gateway_options
|
||||
)
|
||||
else
|
||||
payment_method.credit(
|
||||
(credit_amount * 100).round,
|
||||
response_code,
|
||||
gateway_options
|
||||
)
|
||||
end
|
||||
response = payment_method.credit(
|
||||
(credit_amount * 100).round,
|
||||
response_code,
|
||||
gateway_options
|
||||
)
|
||||
|
||||
record_response(response)
|
||||
|
||||
@@ -125,20 +107,11 @@ module Spree
|
||||
|
||||
refund_amount = calculate_refund_amount(refund_amount)
|
||||
|
||||
response = if payment_method.payment_profiles_supported?
|
||||
payment_method.refund(
|
||||
(refund_amount * 100).round,
|
||||
source,
|
||||
response_code,
|
||||
gateway_options
|
||||
)
|
||||
else
|
||||
payment_method.refund(
|
||||
(refund_amount * 100).round,
|
||||
response_code,
|
||||
gateway_options
|
||||
)
|
||||
end
|
||||
response = payment_method.refund(
|
||||
(refund_amount * 100).round,
|
||||
response_code,
|
||||
gateway_options
|
||||
)
|
||||
|
||||
record_response(response)
|
||||
|
||||
|
||||
@@ -93,10 +93,6 @@ module Spree
|
||||
unscoped { find(*) }
|
||||
end
|
||||
|
||||
def payment_profiles_supported?
|
||||
false
|
||||
end
|
||||
|
||||
def source_required?
|
||||
true
|
||||
end
|
||||
@@ -113,11 +109,6 @@ module Spree
|
||||
distributors.include?(distributor)
|
||||
end
|
||||
|
||||
def self.clean_name
|
||||
scope = "spree.admin.payment_methods.providers"
|
||||
I18n.t(name.demodulize.downcase, scope:)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def distributor_validation
|
||||
|
||||
@@ -251,7 +251,7 @@ module Spree
|
||||
transaction do
|
||||
ExchangeVariant.
|
||||
where(exchange_variants: { variant_id: variants.with_deleted.
|
||||
select(:id) }).destroy_all
|
||||
select(:id) }).destroy_all
|
||||
|
||||
yield
|
||||
end
|
||||
|
||||
@@ -35,8 +35,8 @@ module Spree
|
||||
taxons
|
||||
.pluck('spree_taxons.id, enterprises.id AS enterprise_id')
|
||||
.each_with_object({}) do |(taxon_id, enterprise_id), collection|
|
||||
collection[enterprise_id.to_i] ||= Set.new
|
||||
collection[enterprise_id.to_i] << taxon_id
|
||||
collection[enterprise_id.to_i] ||= Set.new
|
||||
collection[enterprise_id.to_i] << taxon_id
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -167,8 +167,8 @@ module Spree
|
||||
# In Rails 3, merging two scopes on the same column will consider only the last scope.
|
||||
def self.in_distributor(distributor)
|
||||
where(id: ExchangeVariant.select(:variant_id).
|
||||
joins(:exchange).
|
||||
where('exchanges.incoming = ? AND exchanges.receiver_id = ?', false, distributor))
|
||||
joins(:exchange).
|
||||
where('exchanges.incoming = ? AND exchanges.receiver_id = ?', false, distributor))
|
||||
end
|
||||
|
||||
def self.indexed
|
||||
@@ -179,11 +179,11 @@ module Spree
|
||||
# "where(id:" is necessary so that the returned relation has no includes
|
||||
# The relation without includes will not be readonly and allow updates on it
|
||||
where(spree_variants: { id: joins(:prices).
|
||||
where(deleted_at: nil).
|
||||
where('spree_prices.currency' =>
|
||||
where(deleted_at: nil).
|
||||
where('spree_prices.currency' =>
|
||||
currency || CurrentConfig.get(:currency)).
|
||||
where.not(spree_prices: { amount: nil }).
|
||||
select("spree_variants.id") })
|
||||
where.not(spree_prices: { amount: nil }).
|
||||
select("spree_variants.id") })
|
||||
end
|
||||
|
||||
def self.linked_to(semantic_id)
|
||||
|
||||
@@ -60,8 +60,8 @@ class ProductScopeQuery
|
||||
|
||||
def product_query_includes
|
||||
[
|
||||
image: { attachment_attachment: :blob },
|
||||
variants: [:default_price, :stock_items, :variant_overrides]
|
||||
{ image: { attachment_attachment: :blob },
|
||||
variants: [:default_price, :stock_items, :variant_overrides] }
|
||||
]
|
||||
end
|
||||
|
||||
|
||||
@@ -42,10 +42,10 @@ class DfcCatalogImporter
|
||||
.includes(:semantic_links).references(:semantic_links)
|
||||
.where.not(semantic_links: { semantic_id: present_ids })
|
||||
.select do |variant|
|
||||
# Variants that were in the same catalog before:
|
||||
variant.semantic_links.map(&:semantic_id).any? do |semantic_id|
|
||||
FdcUrlBuilder.new(semantic_id).catalog_url == catalog_url
|
||||
end
|
||||
# Variants that were in the same catalog before:
|
||||
variant.semantic_links.map(&:semantic_id).any? do |semantic_id|
|
||||
FdcUrlBuilder.new(semantic_id).catalog_url == catalog_url
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -51,8 +51,8 @@ class LineItemSyncer
|
||||
def destroy_obsolete_items(order)
|
||||
order.line_items.
|
||||
where(variant_id: subscription_line_items.
|
||||
select(&:marked_for_destruction?).
|
||||
map(&:variant_id)).
|
||||
select(&:marked_for_destruction?).
|
||||
map(&:variant_id)).
|
||||
destroy_all
|
||||
end
|
||||
|
||||
|
||||
@@ -130,12 +130,11 @@ module Orders
|
||||
|
||||
def order_cycle_fees
|
||||
return @order_cycle_fees if defined? @order_cycle_fees
|
||||
return [] unless order_cycle && distributor
|
||||
|
||||
@order_cycle_fees = begin
|
||||
fees = []
|
||||
|
||||
return fees unless order_cycle && distributor
|
||||
|
||||
order_cycle.exchanges.supplying_to(distributor).each do |exchange|
|
||||
exchange.enterprise_fees.per_item.each do |enterprise_fee|
|
||||
fee_value = FeeValue.new(fee: enterprise_fee, role: exchange.role)
|
||||
|
||||
@@ -14,12 +14,12 @@ module PermittedAttributes
|
||||
|
||||
def self.attributes
|
||||
basic_permitted_attributes + [
|
||||
group_ids: [], user_ids: [],
|
||||
shipping_method_ids: [], payment_method_ids: [],
|
||||
address_attributes: PermittedAttributes::Address.attributes,
|
||||
business_address_attributes: PermittedAttributes::BusinessAddress.attributes,
|
||||
producer_properties_attributes: [:id, :property_name, :value, :_destroy],
|
||||
custom_tab_attributes: PermittedAttributes::CustomTab.attributes,
|
||||
{ group_ids: [], user_ids: [],
|
||||
shipping_method_ids: [], payment_method_ids: [],
|
||||
address_attributes: PermittedAttributes::Address.attributes,
|
||||
business_address_attributes: PermittedAttributes::BusinessAddress.attributes,
|
||||
producer_properties_attributes: [:id, :property_name, :value, :_destroy],
|
||||
custom_tab_attributes: PermittedAttributes::CustomTab.attributes },
|
||||
]
|
||||
end
|
||||
|
||||
|
||||
@@ -25,8 +25,8 @@ module PermittedAttributes
|
||||
private
|
||||
|
||||
def attributes
|
||||
self.class.basic_attributes + [incoming_exchanges: permitted_exchange_attributes,
|
||||
outgoing_exchanges: permitted_exchange_attributes]
|
||||
self.class.basic_attributes + [{ incoming_exchanges: permitted_exchange_attributes,
|
||||
outgoing_exchanges: permitted_exchange_attributes }]
|
||||
end
|
||||
|
||||
def permitted_exchange_attributes
|
||||
|
||||
@@ -26,11 +26,11 @@ module PermittedAttributes
|
||||
|
||||
def other_permitted_attributes
|
||||
[
|
||||
subscription_line_items_attributes: [
|
||||
:id, :quantity, :variant_id, :price_estimate, :_destroy
|
||||
],
|
||||
bill_address_attributes: PermittedAttributes::Address.attributes,
|
||||
ship_address_attributes: PermittedAttributes::Address.attributes
|
||||
{ subscription_line_items_attributes: [
|
||||
:id, :quantity, :variant_id, :price_estimate, :_destroy
|
||||
],
|
||||
bill_address_attributes: PermittedAttributes::Address.attributes,
|
||||
ship_address_attributes: PermittedAttributes::Address.attributes }
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,23 +1,50 @@
|
||||
- search_url_query = {report_type: :enterprise_fee_summary, report_subtype: :enterprise_fees_with_tax_report_by_order}
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_hubs)
|
||||
.omega.fourteen.columns= f.collection_select(:distributor_id_in, @data.distributors, :id, :name, {}, {class: "select2 fullwidth", multiple: true})
|
||||
.omega.fourteen.columns
|
||||
= render(SearchableDropdownComponent.new(form: f,
|
||||
name: :distributor_id_in,
|
||||
options: [],
|
||||
selected_option: params.dig(:q, :distributor_id_in),
|
||||
multiple: true,
|
||||
remote_url: admin_reports_search_distributors_url))
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_customers_cycle)
|
||||
.omega.fourteen.columns
|
||||
= f.select(:order_cycle_id_in, report_order_cycle_options(@data.order_cycles), {selected: params.dig(:q, :order_cycle_id_in)}, {class: "select2 fullwidth", multiple: true})
|
||||
= render(SearchableDropdownComponent.new(form: f,
|
||||
name: :order_cycle_id_in,
|
||||
options: [],
|
||||
selected_option: params.dig(:q, :order_cycle_id_in),
|
||||
multiple: true,
|
||||
remote_url: admin_reports_search_order_cycles_url))
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:fee_name)
|
||||
.omega.fourteen.columns
|
||||
= f.select(:enterprise_fee_id_in, fee_name_options(@report.search.result), {selected: params.dig(:q, :enterprise_fee_id_in)}, {class: "select2 fullwidth", multiple: true})
|
||||
= render(SearchableDropdownComponent.new(form: f,
|
||||
name: :enterprise_fee_id_in,
|
||||
options: [],
|
||||
selected_option: params.dig(:q, :enterprise_fee_id_in),
|
||||
multiple: true,
|
||||
remote_url: admin_reports_search_enterprise_fees_url(search_url_query)))
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:fee_owner)
|
||||
.omega.fourteen.columns
|
||||
= f.select(:enterprise_fee_owner_id_in, fee_owner_options(@report.search.result), {selected: params.dig(:q, :enterprise_fee_owner_id_in)}, {class: "select2 fullwidth", multiple: true})
|
||||
= render(SearchableDropdownComponent.new(form: f,
|
||||
name: :enterprise_fee_owner_id_in,
|
||||
options: [],
|
||||
selected_option: params.dig(:q, :enterprise_fee_owner_id_in),
|
||||
multiple: true,
|
||||
remote_url: admin_reports_search_enterprise_fee_owners_url(search_url_query)))
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_customers)
|
||||
.omega.fourteen.columns
|
||||
= f.select(:customer_id_in, customer_email_options(@data.order_customers), {selected: params.dig(:q, :customer_id_in)}, {class: "select2 fullwidth", multiple: true})
|
||||
= render(SearchableDropdownComponent.new(form: f,
|
||||
name: :customer_id_in,
|
||||
options: [],
|
||||
selected_option: params.dig(:q, :customer_id_in),
|
||||
multiple: true,
|
||||
remote_url: admin_reports_search_order_customers_url))
|
||||
|
||||
@@ -1,27 +1,57 @@
|
||||
- search_url_query = {report_type: :enterprise_fee_summary, report_subtype: :enterprise_fees_with_tax_report_by_producer}
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_hubs)
|
||||
.omega.fourteen.columns= f.collection_select(:distributor_id_in, @data.distributors, :id, :name, {}, {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.omega.fourteen.columns
|
||||
= render(SearchableDropdownComponent.new(form: f,
|
||||
name: :distributor_id_in,
|
||||
options: [],
|
||||
selected_option: params.dig(:q, :distributor_id_in),
|
||||
multiple: true,
|
||||
remote_url: admin_reports_search_distributors_url))
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_producers)
|
||||
.omega.fourteen.columns= select_tag(:supplier_id_in, options_from_collection_for_select(@data.orders_suppliers, :id, :name, params[:supplier_id_in]), {class: "select2 fullwidth", multiple: true})
|
||||
.omega.fourteen.columns
|
||||
= render(SearchableDropdownComponent.new(name: :supplier_id_in,
|
||||
options: [],
|
||||
selected_option: params.dig(:supplier_id_in),
|
||||
multiple: true,
|
||||
remote_url: admin_reports_search_suppliers_url))
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_customers_cycle)
|
||||
.omega.fourteen.columns
|
||||
= f.select(:order_cycle_id_in, report_order_cycle_options(@data.order_cycles), {selected: params.dig(:q, :order_cycle_id_in)}, {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
= render(SearchableDropdownComponent.new(form: f,
|
||||
name: :order_cycle_id_in,
|
||||
options: [],
|
||||
selected_option: params.dig(:q, :order_cycle_id_in),
|
||||
multiple: true,
|
||||
remote_url: admin_reports_search_order_cycles_url))
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:fee_name)
|
||||
.omega.fourteen.columns
|
||||
= f.select(:enterprise_fee_id_in, fee_name_options(@report.search.result), {selected: params.dig(:q, :enterprise_fee_id_in)}, {class: "select2 fullwidth", multiple: true})
|
||||
= render(SearchableDropdownComponent.new(form: f,
|
||||
name: :enterprise_fee_id_in,
|
||||
options: [],
|
||||
selected_option: params.dig(:q, :enterprise_fee_id_in),
|
||||
multiple: true,
|
||||
remote_url: admin_reports_search_enterprise_fees_url(search_url_query)))
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:fee_owner)
|
||||
.omega.fourteen.columns
|
||||
= f.select(:enterprise_fee_owner_id_in, fee_owner_options(@report.search.result), {selected: params.dig(:q, :enterprise_fee_owner_id_in)}, {class: "select2 fullwidth", multiple: true})
|
||||
= render(SearchableDropdownComponent.new(form: f,
|
||||
name: :enterprise_fee_owner_id_in,
|
||||
options: [],
|
||||
selected_option: params.dig(:q, :enterprise_fee_owner_id_in),
|
||||
multiple: true,
|
||||
remote_url: admin_reports_search_enterprise_fee_owners_url(search_url_query)))
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_customers)
|
||||
.omega.fourteen.columns
|
||||
= f.select(:customer_id_in, customer_email_options(@data.order_customers), {selected: params.dig(:q, :customer_id_in)}, {class: "select2 fullwidth", multiple: true})
|
||||
= render(SearchableDropdownComponent.new(form: f,
|
||||
name: :customer_id_in,
|
||||
options: [],
|
||||
selected_option: params.dig(:q, :customer_id_in),
|
||||
multiple: true,
|
||||
remote_url: admin_reports_search_order_customers_url))
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
.alpha.four.columns
|
||||
= label :payment_method, :type, t('.provider')
|
||||
.omega.twelve.columns
|
||||
= collection_select(:payment_method, :type, @providers, :to_s, :clean_name, {}, { class: 'select2 fullwidth', 'provider-prefs-for' => "#{@object.id}"})
|
||||
= select(:payment_method, :type, payment_method_type_options(@providers), {}, { class: 'select2 fullwidth', required: true, placeholder: t("admin.choose"), 'provider-prefs-for' => "#{@object.id}"})
|
||||
|
||||
%div{"ng-include" => "include_html" }
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
- method.distributors.each do |distributor|
|
||||
= distributor.name
|
||||
%br/
|
||||
%td= method.class.clean_name
|
||||
%td= payment_method_type_name(method.class.name)
|
||||
- if spree_current_user.admin?
|
||||
%td.align-center= method.environment.to_s.titleize
|
||||
%td.align-center= method.display_on.blank? ? t('.both') : t('.' + method.display_on.to_s)
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
import { Controller } from "stimulus";
|
||||
import TomSelect from "tom-select/dist/esm/tom-select.complete";
|
||||
import showHttpError from "../../webpacker/js/services/show_http_error";
|
||||
|
||||
export default class extends Controller {
|
||||
static values = { options: Object, placeholder: String };
|
||||
static values = {
|
||||
options: Object,
|
||||
placeholder: String,
|
||||
remoteUrl: String,
|
||||
};
|
||||
|
||||
connect(options = {}) {
|
||||
this.control = new TomSelect(this.element, {
|
||||
let tomSelectOptions = {
|
||||
maxItems: 1,
|
||||
maxOptions: null,
|
||||
plugins: ["dropdown_input"],
|
||||
@@ -16,7 +21,13 @@ export default class extends Controller {
|
||||
},
|
||||
...this.optionsValue,
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
if (this.remoteUrlValue) {
|
||||
this.#addRemoteOptions(tomSelectOptions);
|
||||
}
|
||||
|
||||
this.control = new TomSelect(this.element, tomSelectOptions);
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
@@ -29,4 +40,78 @@ export default class extends Controller {
|
||||
const optionsArray = [...this.element.options];
|
||||
return optionsArray.find((option) => [null, ""].includes(option.value))?.text;
|
||||
}
|
||||
|
||||
#buildUrl(query, page = 1) {
|
||||
const url = new URL(this.remoteUrlValue, window.location.origin);
|
||||
url.searchParams.set("q", query);
|
||||
url.searchParams.set("page", page);
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
#fetchOptions(query, callback) {
|
||||
const url = this.control.getUrl(query);
|
||||
|
||||
fetch(url)
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
showHttpError(response.status);
|
||||
throw response;
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then((json) => {
|
||||
/**
|
||||
* Expected API shape:
|
||||
* {
|
||||
* results: [{ value, label }],
|
||||
* pagination: { more: boolean }
|
||||
* }
|
||||
*/
|
||||
if (json.pagination?.more) {
|
||||
const currentUrl = new URL(url);
|
||||
const currentPage = parseInt(currentUrl.searchParams.get("page") || "1");
|
||||
const nextUrl = this.#buildUrl(query, currentPage + 1);
|
||||
this.control.setNextUrl(query, nextUrl);
|
||||
}
|
||||
|
||||
callback(json.results || []);
|
||||
})
|
||||
.catch((error) => {
|
||||
callback();
|
||||
console.error(error);
|
||||
});
|
||||
}
|
||||
|
||||
#addRemoteOptions(options) {
|
||||
this.openedByClick = false;
|
||||
|
||||
options.firstUrl = (query) => {
|
||||
return this.#buildUrl(query, 1);
|
||||
};
|
||||
|
||||
options.load = this.#fetchOptions.bind(this);
|
||||
|
||||
options.onFocus = function () {
|
||||
this.control.load("", () => {});
|
||||
}.bind(this);
|
||||
|
||||
options.onDropdownOpen = function () {
|
||||
this.openedByClick = true;
|
||||
}.bind(this);
|
||||
|
||||
options.onType = function () {
|
||||
this.openedByClick = false;
|
||||
}.bind(this);
|
||||
|
||||
// As per TomSelect source code, Loading state is shown on the UI when this function returns true.
|
||||
// By default it shows loading state only when there is some input in the search box.
|
||||
// We want to show loading state on focus as well (when there is no input) to indicate that options are being loaded.
|
||||
options.shouldLoad = function (query) {
|
||||
return this.openedByClick || query.length > 0;
|
||||
}.bind(this);
|
||||
|
||||
options.valueField = "value";
|
||||
options.labelField = "label";
|
||||
options.searchField = "label";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,16 +2,27 @@ require_relative 'spree'
|
||||
|
||||
Rails.application.reloader.to_prepare do
|
||||
# See: https://github.com/openfoodfoundation/db2fog
|
||||
DB2Fog.config = {
|
||||
if ENV['S3_BACKUPS_HOST'].present?
|
||||
DB2Fog.config = {
|
||||
aws_access_key_id: ENV['S3_BACKUPS_ACCESS_KEY'],
|
||||
aws_secret_access_key: ENV['S3_BACKUPS_SECRET'],
|
||||
directory: ENV['S3_BACKUPS_BUCKET'],
|
||||
provider: 'AWS',
|
||||
scheme: ENV['S3_BACKUPS_SCHEME'],
|
||||
host: ENV['S3_BACKUPS_HOST']
|
||||
}
|
||||
else
|
||||
DB2Fog.config = {
|
||||
:aws_access_key_id => Spree::Config[:s3_access_key],
|
||||
:aws_secret_access_key => Spree::Config[:s3_secret],
|
||||
:directory => ENV['S3_BACKUPS_BUCKET'],
|
||||
:provider => 'AWS'
|
||||
}
|
||||
}
|
||||
|
||||
region = ENV['S3_BACKUPS_REGION'] || ENV['S3_REGION']
|
||||
region = ENV['S3_BACKUPS_REGION'] || ENV['S3_REGION']
|
||||
|
||||
# If no region is defined we leave this config key undefined (instead of nil),
|
||||
# so that db2fog correctly applies it's default
|
||||
DB2Fog.config[:region] = region if region
|
||||
# If no region is defined we leave this config key undefined (instead of nil),
|
||||
# so that db2fog correctly applies it's default
|
||||
DB2Fog.config[:region] = region if region
|
||||
end
|
||||
end
|
||||
|
||||
@@ -246,6 +246,9 @@ en_CA:
|
||||
disconnect_failure: "Failed to disconnecct Stripe."
|
||||
success_code:
|
||||
disconnected: "Stripe account disconnected."
|
||||
taler:
|
||||
order_status:
|
||||
claimed: "The payment request expired. Please try again."
|
||||
activemodel:
|
||||
errors:
|
||||
messages:
|
||||
@@ -3358,6 +3361,8 @@ en_CA:
|
||||
payment_processing_failed: "Payment could not be processed, please check the details you entered."
|
||||
payment_method_not_supported: "That payment method is unsupported. Please choose another one."
|
||||
payment_updated: "Payment Updated"
|
||||
payment_method_taler:
|
||||
order_summary: "Open Food Network order"
|
||||
cannot_perform_operation: "Could not update the payment"
|
||||
action_required: "Action required"
|
||||
tag_rules: "Tag Rules"
|
||||
@@ -4171,6 +4176,7 @@ en_CA:
|
||||
alt_text: "Alternative Text"
|
||||
thumbnail: "Thumbnail"
|
||||
back_to_images_list: "Back to Images List"
|
||||
backend_url: "Backend URL"
|
||||
api_key: "API key"
|
||||
email: Email
|
||||
account_updated: "Account updated!"
|
||||
@@ -4490,6 +4496,7 @@ en_CA:
|
||||
check: "Cash/EFT/Bank Transfer etc. (payments for which automatic validation is not required)"
|
||||
paypalexpress: "PayPal Express"
|
||||
stripesca: "Stripe SCA"
|
||||
taler: "Taler"
|
||||
payments:
|
||||
source_forms:
|
||||
stripe:
|
||||
|
||||
@@ -115,6 +115,67 @@ en_GB:
|
||||
blank: "can't be blank"
|
||||
too_short: "is too short (minimum is %{count} characters)"
|
||||
errors:
|
||||
messages:
|
||||
content_type_invalid:
|
||||
one: "has an invalid content type (authorised content type is %{authorized_human_content_types})"
|
||||
other: "has an invalid content type (authorised content types are\n%{authorized_human_content_types})"
|
||||
content_type_spoofed:
|
||||
one: "has a content type that is not equivalent to the one that is detected through its content (authorised content type is %{authorized_human_content_types})"
|
||||
other: "has a content type that is not equivalent to the one that is detected through its content (authorised content types are %{authorized_human_content_types})"
|
||||
file_size_not_less_than: "file size must be less than %{max} (current size is %{file_size})"
|
||||
file_size_not_less_than_or_equal_to: "file size must be less than or equal to %{max} (current size is %{file_size})"
|
||||
file_size_not_greater_than: "file size must be greater than %{min} (current size is %{file_size})"
|
||||
file_size_not_greater_than_or_equal_to: "file size must be greater than or equal to %{min} (current size is %{file_size})"
|
||||
file_size_not_between: "file size must be between %{min} and %{max} (current size is %{file_size})"
|
||||
file_size_not_equal_to: "file size must be equal to %{exact} (current size is %{file_size})"
|
||||
total_file_size_not_less_than: "total file size must be less than %{max} (current size is %{total_file_size})"
|
||||
total_file_size_not_less_than_or_equal_to: "total file size must be less than or equal to %{max} (current size is %{total_file_size})"
|
||||
total_file_size_not_greater_than: "total file size must be greater than %{min} (current size is %{total_file_size})"
|
||||
total_file_size_not_greater_than_or_equal_to: "total file size must be greater than or equal to %{min} (current size is %{total_file_size})"
|
||||
total_file_size_not_between: "total file size must be between %{min} and %{max} (current size is %{total_file_size})"
|
||||
total_file_size_not_equal_to: "total file size must be equal to %{exact} (current size is %{total_file_size})"
|
||||
duration_not_less_than: "duration must be less than %{max} (current duration is %{duration})"
|
||||
duration_not_less_than_or_equal_to: "duration must be less than or equal to %{max} (current duration is %{duration})"
|
||||
duration_not_greater_than: "duration must be greater than %{min} (current duration is %{duration})"
|
||||
duration_not_greater_than_or_equal_to: "duration must be greater than or equal to %{min} (current duration is %{duration})"
|
||||
duration_not_between: "duration must be between %{min} and %{max} (current duration is %{duration})"
|
||||
duration_not_equal_to: "duration must be equal to %{exact} (current duration is %{duration})"
|
||||
limit_out_of_range:
|
||||
zero: "no files attached (must have between %{min} and %{max}files)"
|
||||
one: "only 1 file attached (must have between %{min} and %{max}files)"
|
||||
other: "total number of files must be between %{min} and %{max} files (there are %{count}files attached)"
|
||||
limit_min_not_reached:
|
||||
zero: "no files attached (must have at least %{min} files)"
|
||||
one: "only 1 file attached (must have at least %{min} files)"
|
||||
other: "%{count} files attached (must have at least %{min} files)"
|
||||
limit_max_exceeded:
|
||||
zero: "no files attached (maximum is %{max} files)"
|
||||
one: "too many files attached (maximum is %{max} files, got %{count})"
|
||||
other: "too many files attached (maximum is %{max} files, got %{count})"
|
||||
attachment_missing: "is missing its attachment"
|
||||
media_metadata_missing: "is not a valid media file"
|
||||
dimension_min_not_included_in: "must be greater than or equal to %{width} x %{height} pixels"
|
||||
dimension_max_not_included_in: "must be less than or equal to %{width} x %{height} pixels"
|
||||
dimension_width_not_included_in: "width is not included between %{min} and %{max} pixels"
|
||||
dimension_height_not_included_in: "height is not included between %{min} and %{max} pixels"
|
||||
dimension_width_not_greater_than_or_equal_to: "width must be greater than or equal to %{length} pixels"
|
||||
dimension_height_not_greater_than_or_equal_to: "height must be greater than or equal to %{length} pixels"
|
||||
dimension_width_not_less_than_or_equal_to: "width must be less than or equal to %{length} pixels"
|
||||
dimension_height_not_less_than_or_equal_to: "height must be less than or equal to %{length} pixels"
|
||||
dimension_width_not_equal_to: "width must be equal to %{length} pixels"
|
||||
dimension_height_not_equal_to: "height must be equal to %{length} pixels"
|
||||
aspect_ratio_not_square: "must be square (current file is %{width}x%{height}px)"
|
||||
aspect_ratio_not_portrait: "must be portrait (current file is %{width}x%{height}px)"
|
||||
aspect_ratio_not_landscape: "must be landscape (current file is %{width}x%{height}px)"
|
||||
aspect_ratio_not_x_y: "must be %{authorized_aspect_ratios} (current file is %{width}x%{height}px)"
|
||||
aspect_ratio_invalid: "has an invalid aspect ratio (valid aspect ratios are %{authorized_aspect_ratios})"
|
||||
file_not_processable: "is not identified as a valid media file"
|
||||
pages_not_less_than: "page count must be less than %{max} (current page count is %{pages})"
|
||||
pages_not_less_than_or_equal_to: "page count must be less than or equal to %{max} (current page count is %{pages})"
|
||||
pages_not_greater_than: "page count must be greater than %{min} (current page count is %{pages})"
|
||||
pages_not_greater_than_or_equal_to: "page count must be greater than or equal to %{min} (current page count is %{pages})"
|
||||
pages_not_between: "page count must be between %{min} and %{max} (current page count is %{pages})"
|
||||
pages_not_equal_to: "page count must be equal to %{exact} (current page count is %{pages})"
|
||||
not_found:
|
||||
title: "The page you were looking for doesn't exist (404)"
|
||||
message_html: "<b>Please try again</b> <p>This might be a temporary problem. Please click the back button to return to the previous screen or go back to <a href='/'>Home</a> and try again.</p> <b>Contact support</b> <p>If the problem persists or is urgent, please tell us about it. Find our contact details from the global <a href='https://openfoodnetwork.org/ofn-local/' target='blank'>Open Food Network Local page</a>.</p> <p>It really helps us if you can give as much detail as possible about what the missing page is about.</p>"
|
||||
@@ -185,6 +246,9 @@ en_GB:
|
||||
disconnect_failure: "Failed to disconnect Stripe."
|
||||
success_code:
|
||||
disconnected: "Stripe account disconnected."
|
||||
taler:
|
||||
order_status:
|
||||
claimed: "The payment request expired. Please try again."
|
||||
activemodel:
|
||||
errors:
|
||||
messages:
|
||||
@@ -520,6 +584,7 @@ en_GB:
|
||||
errors:
|
||||
vine_api: "There was an error communicating with the API, please try again later."
|
||||
invalid_voucher: "The voucher is not valid"
|
||||
expired: "The voucher has expired"
|
||||
not_found_voucher: "Sorry, we couldn't find that voucher, please check the code."
|
||||
vine_voucher_redeemer_service:
|
||||
errors:
|
||||
@@ -934,6 +999,10 @@ en_GB:
|
||||
clone:
|
||||
success: Successfully cloned the product
|
||||
error: Unable to clone the product
|
||||
tag_rules:
|
||||
rules_per_tag:
|
||||
one: "%{tag} has 1 rule"
|
||||
other: "%{tag} has %{count} rules"
|
||||
product_import:
|
||||
title: Product Import
|
||||
file_not_found: File not found or could not be opened
|
||||
@@ -2374,9 +2443,9 @@ en_GB:
|
||||
order_includes_tax: (includes tax)
|
||||
order_payment_paypal_successful: Your payment via PayPal has been processed successfully.
|
||||
order_hub_info: Hub info
|
||||
order_back_to_store: Back To Store
|
||||
order_back_to_cart: Back To Cart
|
||||
order_back_to_website: Back To Website
|
||||
order_back_to_store: Back to shop
|
||||
order_back_to_cart: Back to cart
|
||||
order_back_to_website: Back to website
|
||||
checkout_details_title: Checkout Details
|
||||
checkout_payment_title: Checkout Payment
|
||||
checkout_summary_title: Checkout Summary
|
||||
@@ -3292,11 +3361,13 @@ en_GB:
|
||||
payment_processing_failed: "Payment could not be processed, please check the details you entered"
|
||||
payment_method_not_supported: "That payment method is unsupported. Please choose another one."
|
||||
payment_updated: "Payment Updated"
|
||||
payment_method_taler:
|
||||
order_summary: "Open Food Network order"
|
||||
cannot_perform_operation: "Could not update the payment"
|
||||
action_required: "Action required"
|
||||
tag_rules: "Tag Rules"
|
||||
enterprise_fee_whole_order: Whole order
|
||||
enterprise_fee_by_name: "%{name} fee by %{role}%{enterprise_name}"
|
||||
enterprise_fee_by_name: "%{name} fee by %{role} %{enterprise_name}"
|
||||
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_tax_category_cant_be_blank: "^Tax Category can't be blank"
|
||||
@@ -3337,6 +3408,7 @@ en_GB:
|
||||
order_cycles_no_permission_to_coordinate_error: "None of your enterprises have permission to coordinate an order cycle"
|
||||
order_cycles_no_permission_to_create_error: "You don't have permission to create an order cycle coordinated by that enterprise"
|
||||
order_cycle_closed: "The order cycle you've selected has just closed."
|
||||
order_cycle_closed_next_steps: "The order cycle you've selected has just closed. Please contact us to complete your order #\n%{order_number}!"
|
||||
back_to_orders_list: "Back To Orders List"
|
||||
no_orders_found: "No Orders Found"
|
||||
order_information: "Order Information"
|
||||
@@ -3911,6 +3983,8 @@ en_GB:
|
||||
destroy:
|
||||
success: Webhook endpoint successfully deleted
|
||||
error: Webhook endpoint failed to delete
|
||||
test:
|
||||
success: Some test data will be sent to the webhook url
|
||||
spree:
|
||||
order_updated: "Order Updated"
|
||||
cannot_perform_operation: "Can not perform this operation"
|
||||
@@ -4017,6 +4091,7 @@ en_GB:
|
||||
logourl: "Logo url"
|
||||
are_you_sure_delete: "Are you sure you want to delete this record?"
|
||||
confirm_delete: "Confirm Deletion"
|
||||
tag_rule: "Tag Rule"
|
||||
voucher: "Voucher"
|
||||
configurations: "Configurations"
|
||||
general_settings: "General Settings"
|
||||
@@ -4108,6 +4183,7 @@ en_GB:
|
||||
alt_text: "Alternative Text"
|
||||
thumbnail: "Thumbnail"
|
||||
back_to_images_list: "Back To Images List"
|
||||
backend_url: "Backend URL"
|
||||
api_key: "API key"
|
||||
email: Email
|
||||
account_updated: "Account updated!"
|
||||
@@ -4427,6 +4503,7 @@ en_GB:
|
||||
check: "Cash/EFT/etc. (payments for which automatic validation is not required)"
|
||||
paypalexpress: "PayPal Express"
|
||||
stripesca: "Stripe SCA "
|
||||
taler: "Taler"
|
||||
payments:
|
||||
source_forms:
|
||||
stripe:
|
||||
@@ -4883,6 +4960,7 @@ en_GB:
|
||||
order_cycle_tagged_bottom: "are:"
|
||||
inventory_tagged_top: "Inventory variants tagged"
|
||||
inventory_tagged_bottom: "are:"
|
||||
variant_tagged_top: "Variants tagged"
|
||||
variant_tagged_bottom: "are:"
|
||||
visible: VISIBLE
|
||||
not_visible: NOT VISIBLE
|
||||
@@ -4898,6 +4976,8 @@ en_GB:
|
||||
create_placeholder: Enter the URL of the remote webhook endpoint
|
||||
event_types:
|
||||
order_cycle_opened: Order Cycle Opened
|
||||
payment_status_changed: Post webhook on Payment status change
|
||||
test_endpoint: Test webhook endpoint
|
||||
invisible_captcha:
|
||||
sentence_for_humans: "Please leave empty"
|
||||
timestamp_error_message: "Please try again after 5 seconds."
|
||||
|
||||
@@ -18,7 +18,7 @@ fi:
|
||||
phone: "Puhelinnumero"
|
||||
firstname: "Etunimi"
|
||||
lastname: "Sukunimi"
|
||||
zipcode: "Toimituspostinumero"
|
||||
zipcode: "Toimitusosoitteen postinumero"
|
||||
spree/order/bill_address:
|
||||
address1: "Laskutusosoite (Katu ja talonumero)"
|
||||
zipcode: "Laskutuspostinumero"
|
||||
@@ -115,6 +115,67 @@ fi:
|
||||
blank: "ei voi olla tyhjä"
|
||||
too_short: "on liian lyhyt (vähintään %{count} merkkiä)"
|
||||
errors:
|
||||
messages:
|
||||
content_type_invalid:
|
||||
one: "sisältää virheellisen sisältötyypin (valtuutettu sisältötyyppi on %{authorized_human_content_types} )"
|
||||
other: "sisältää virheellisen sisältötyypin (valtuutetut sisältötyypit ovat %{authorized_human_content_types} )"
|
||||
content_type_spoofed:
|
||||
one: "sisältötyyppi ei vastaa sisällöstä havaittua tyyppiä (valtuutettu sisältötyyppi on %{authorized_human_content_types} )"
|
||||
other: "sisältötyyppi ei vastaa sisällöstä havaittua tyyppiä (valtuutetut sisältötyypit ovat %{authorized_human_content_types} )"
|
||||
file_size_not_less_than: "tiedoston koko on oltava pienempi kuin %{max} (nykyinen koko on %{file_size} )"
|
||||
file_size_not_less_than_or_equal_to: "tiedoston koko on oltava pienempi tai yhtä suuri kuin %{max} (nykyinen koko on %{file_size} )"
|
||||
file_size_not_greater_than: "tiedoston koko on oltava suurempi kuin %{min} (nykyinen koko on %{file_size} )"
|
||||
file_size_not_greater_than_or_equal_to: "tiedoston koko on oltava suurempi tai yhtä suuri kuin %{min} (nykyinen koko on %{file_size} )"
|
||||
file_size_not_between: "koko on oltava %{min} ja %{max} välillä (nykyinen koko on %{file_size} )"
|
||||
file_size_not_equal_to: "tiedoston koko on oltava yhtä suuri kuin %{exact} (nykyinen koko on %{file_size} )"
|
||||
total_file_size_not_less_than: "yhteensä tiedoston koko on oltava pienempi kuin %{max} (nykyinen koko on %{total_file_size} )"
|
||||
total_file_size_not_less_than_or_equal_to: "yhteensä tiedoston koko on oltava pienempi tai yhtä suuri kuin %{max} (nykyinen koko on %{total_file_size} )"
|
||||
total_file_size_not_greater_than: "yhteensä tiedoston koko on oltava suurempi kuin %{min} (nykyinen koko on %{total_file_size} )"
|
||||
total_file_size_not_greater_than_or_equal_to: "yhteensä tiedoston koko on oltava suurempi tai yhtä suuri kuin %{min} (nykyinen koko on %{total_file_size} )"
|
||||
total_file_size_not_between: "yhteensä tiedoston koko on oltava %{min} ja %{max} välillä (nykyinen koko on %{total_file_size} )"
|
||||
total_file_size_not_equal_to: "yhteensä tiedoston koko on oltava yhtä suuri kuin %{exact} (nykyinen koko on %{total_file_size} )"
|
||||
duration_not_less_than: "keston on oltava pienempi kuin %{max} (nykyinen kesto on %{duration} )"
|
||||
duration_not_less_than_or_equal_to: "keston on oltava pienempi tai yhtä suuri kuin %{max} (nykyinen kesto on %{duration} )"
|
||||
duration_not_greater_than: "keston on oltava suurempi kuin %{min} (nykyinen kesto on %{duration} )"
|
||||
duration_not_greater_than_or_equal_to: "keston on oltava suurempi tai yhtä suuri kuin %{min} (nykyinen kesto on %{duration} )"
|
||||
duration_not_between: "keston on oltava välillä %{min} ja %{max} (nykyinen kesto on %{duration} )"
|
||||
duration_not_equal_to: "keston on oltava yhtä suuri kuin %{exact} (nykyinen kesto on %{duration} )"
|
||||
limit_out_of_range:
|
||||
zero: "ei liitettyjä tiedostoja (tiedostojen on oltava %{min} ja %{max} välillä)"
|
||||
one: "vain yksi liitetty tiedosto (tiedostojen on oltava %{min} ja %{max} välillä)"
|
||||
other: "Tiedostojen yhteensä on oltava %{min} ja %{max} välillä (liitteenä on %{count} tiedostot)"
|
||||
limit_min_not_reached:
|
||||
zero: "ei liitettyjä tiedostoja (tiedostoissa on oltava vähintään %{min} )"
|
||||
one: "vain yksi tiedosto liitettynä (tiedostojen on oltava vähintään %{min} )"
|
||||
other: "%{count} tiedostot liitteenä (vähintään %{min} tiedostoja on oltava)"
|
||||
limit_max_exceeded:
|
||||
zero: "ei liitettyjä tiedostoja (enintään %{max} tiedostoja)"
|
||||
one: "liian monta tiedostoa liitettynä (suurin sallittu määrä on %{max} , sain tulokseksi %{count} )"
|
||||
other: "liian monta tiedostoa liitettynä (suurin sallittu määrä on %{max} , sain tulokseksi %{count} )"
|
||||
attachment_missing: "puuttuu sen liite"
|
||||
media_metadata_missing: "ei ole kelvollinen mediatiedosto"
|
||||
dimension_min_not_included_in: "on oltava suurempi tai yhtä suuri kuin %{width} x %{height} pikseliä"
|
||||
dimension_max_not_included_in: "on oltava pienempi tai yhtä suuri kuin %{width} x %{height} pikseliä"
|
||||
dimension_width_not_included_in: "Leveys ei sisälly %{min} ja %{max} pikselien väliin"
|
||||
dimension_height_not_included_in: "Korkeutta ei ole %{min} ja %{max} pikselien välillä."
|
||||
dimension_width_not_greater_than_or_equal_to: "leveyden on oltava suurempi tai yhtä suuri kuin %{length} pikseliä"
|
||||
dimension_height_not_greater_than_or_equal_to: "korkeuden on oltava suurempi tai yhtä suuri kuin %{length} pikseliä"
|
||||
dimension_width_not_less_than_or_equal_to: "leveyden on oltava pienempi tai yhtä suuri kuin %{length} pikseliä"
|
||||
dimension_height_not_less_than_or_equal_to: "korkeuden on oltava pienempi tai yhtä suuri kuin %{length} pikseliä"
|
||||
dimension_width_not_equal_to: "leveyden on oltava yhtä suuri kuin %{length} pikseliä"
|
||||
dimension_height_not_equal_to: "korkeuden on oltava yhtä suuri kuin %{length} pikselit"
|
||||
aspect_ratio_not_square: "on oltava neliön muotoinen (nykyinen tiedosto on %{width} x %{height} px)"
|
||||
aspect_ratio_not_portrait: "tiedoston on oltava pystysuuntainen (nykyinen tiedosto on %{width} x %{height} px)"
|
||||
aspect_ratio_not_landscape: "tiedoston on oltava vaakasuuntainen (nykyinen tiedosto on %{width} x %{height} px)"
|
||||
aspect_ratio_not_x_y: "tiedoston on oltava %{authorized_aspect_ratios} (nykyinen tiedosto on %{width} x %{height} px)"
|
||||
aspect_ratio_invalid: "kuvasuhde on virheellinen (kelvolliset kuvasuhteet ovat %{authorized_aspect_ratios} )"
|
||||
file_not_processable: "ei ole tunnistettu kelvolliseksi mediatiedostoksi"
|
||||
pages_not_less_than: "sivumäärän on oltava pienempi kuin %{max} (nykyinen sivumäärä on %{pages} )"
|
||||
pages_not_less_than_or_equal_to: "sivumäärän on oltava pienempi tai yhtä suuri kuin %{max} (nykyinen sivumäärä on %{pages} )"
|
||||
pages_not_greater_than: "sivumäärän on oltava suurempi kuin %{min} (nykyinen sivumäärä on %{pages} )"
|
||||
pages_not_greater_than_or_equal_to: "sivumäärän on oltava suurempi tai yhtä suuri kuin %{min} (nykyinen sivumäärä on %{pages} )"
|
||||
pages_not_between: "sivumäärän on oltava välillä %{min} ja %{max} (nykyinen sivumäärä on %{pages} )"
|
||||
pages_not_equal_to: "sivumäärän on oltava yhtä suuri kuin %{exact} (nykyinen sivumäärä on %{pages} )"
|
||||
not_found:
|
||||
title: "Etsimääsi sivua ei löytynyt (404)"
|
||||
message_html: "<b>Yritä uudelleen</b> <p>Tämä voi olla tilapäinen ongelma. Palaa edelliselle sivulle tai <a href='/'>etusivulle</a> ja yritä uudelleen.</p> <b>Ota yhteyttä tukeen</b> <p>Jos ongelma jatkuu tai on kiireellinen, kerro siitä meille. Löydä yhteystiedot globaalilta <a href='https://openfoodnetwork.org/ofn-local/' target='blank'>Open Food Network Local -sivulta</a>.</p> <p>Autat meitä paljon, jos annat mahdollisimman paljon yksityiskohtia puuttuvasta sivusta.</p>"
|
||||
@@ -185,6 +246,9 @@ fi:
|
||||
disconnect_failure: "Stripe-tilin irrottaminen epäonnistui."
|
||||
success_code:
|
||||
disconnected: "Stripe-tili irrotettu."
|
||||
taler:
|
||||
order_status:
|
||||
claimed: "Maksupyyntö vanheni. Yritä uudelleen."
|
||||
activemodel:
|
||||
errors:
|
||||
messages:
|
||||
@@ -518,6 +582,7 @@ fi:
|
||||
errors:
|
||||
vine_api: "API-yhteydessä tapahtui virhe, yritä myöhemmin uudelleen."
|
||||
invalid_voucher: "Alennuskuponki ei ole kelvollinen"
|
||||
expired: "Kuponki on vanhentunut"
|
||||
not_found_voucher: "Anteeksi, emme löytäneet tätä alennuskuponkia, tarkista koodi."
|
||||
vine_voucher_redeemer_service:
|
||||
errors:
|
||||
@@ -932,6 +997,10 @@ fi:
|
||||
clone:
|
||||
success: Tuote kloonattiin onnistuneesti
|
||||
error: Tuotteen kloonaaminen epäonnistui
|
||||
tag_rules:
|
||||
rules_per_tag:
|
||||
one: "%{tag} llä on 1 sääntö"
|
||||
other: "%{tag} llä on %{count} säännöt."
|
||||
product_import:
|
||||
title: Tuontituotteet
|
||||
file_not_found: Tiedostoa ei löytynyt tai sitä ei voitu avata
|
||||
@@ -1326,6 +1395,9 @@ fi:
|
||||
add_new_button: '+ Lisää uusi oletussääntö'
|
||||
no_tags_yet: Tähän yritykseen ei vielä liity tägejä
|
||||
add_new_tag: '+ Lisää uusi tägi'
|
||||
show_hide_variants: 'Näytä tai Piilota variantit myymälästäni'
|
||||
show_hide_shipping: 'Näytä tai piilota toimitustavat kassalla'
|
||||
show_hide_payment: 'Näytä tai Piilota maksutavat kassalla'
|
||||
show_hide_order_cycles: 'Näytä tai piilota tilausjaksot verkkokaupassani'
|
||||
users:
|
||||
legend: "Käyttäjät"
|
||||
@@ -1479,6 +1551,10 @@ fi:
|
||||
invite_manager:
|
||||
user_already_exists: "Käyttäjä on jo olemassa"
|
||||
error: "Jotain meni pieleen"
|
||||
tag_rules:
|
||||
not_supported_type: tägi -sääntötyyppiä ei tueta
|
||||
confirm_delete: Haluatko varmasti poistaa tämän säännön?
|
||||
destroy_error: tägi -säännön poistamisessa oli ongelma.
|
||||
order_cycles:
|
||||
loading_flash:
|
||||
loading_order_cycles: LADATAAN TILAUSJAKSOJA
|
||||
@@ -1702,6 +1778,8 @@ fi:
|
||||
not_visible: "%{enterprise} ei ole näkyvissä, joten sitä ei löydy kartalta tai hauista"
|
||||
reports:
|
||||
none: ei yhtään
|
||||
metadata:
|
||||
report_title: Ilmianna otsikko
|
||||
deprecated: "Tämä raportti on vanhentunut ja se poistetaan tulevasta julkaisusta."
|
||||
hidden_field: "< Piilotettu >"
|
||||
unitsize: YKSIKKÖKOKO
|
||||
@@ -1804,6 +1882,7 @@ fi:
|
||||
display: Näyttö
|
||||
summary_row: Yhteenvetorivi
|
||||
header_row: Otsikkorivi
|
||||
metadata_rows: Metadata-rivit
|
||||
raw_data: Raakadata
|
||||
formatted_data: Muotoiltu data
|
||||
packing:
|
||||
@@ -2379,8 +2458,15 @@ fi:
|
||||
email_confirmed: "Kiitos sähköpostiosoitteesi vahvistamisesta."
|
||||
email_confirmation_activate_account: "Ennen kuin voimme aktivoida uuden tilisi, meidän on vahvistettava sähköpostiosoitteesi."
|
||||
email_confirmation_greeting: "Hei, %{contact} !"
|
||||
email_confirmation_profile_created: >
|
||||
Profiili käyttäjälle %{name} on luotu onnistuneesti! Profiilisi aktivoimiseksi
|
||||
meidän on vahvistettava tämä sähköpostiosoite.
|
||||
email_confirmation_click_link: "Vahvista sähköpostiosoitteesi ja jatka profiilisi luomista napsauttamalla alla olevaa linkkiä."
|
||||
email_confirmation_link_label: "Vahvista tämä sähköpostiosoite »"
|
||||
email_confirmation_help_html: >
|
||||
Kun olet vahvistanut sähköpostiosoitteesi, voit käyttää ylläpitäjän tiliäsi
|
||||
tässä yrityksessä. Katso %{link} saadaksesi about %{sitename} :n ominaisuuksista
|
||||
ja aloittaaksesi profiilisi tai verkkokauppasi käytön.
|
||||
email_confirmation_notice_unexpected: "Sait tämän viestin, koska rekisteröidyit palvelussa %{sitename} tai joku luultavasti tuntemasi henkilö kutsui sinut rekisteröitymään. Jos et ymmärrä, miksi saat tämän sähköpostin, kirjoita osoitteeseen %{contact} ."
|
||||
email_social: "Ota yhteyttä:"
|
||||
email_contact: "Lähetä meille sähköpostia:"
|
||||
@@ -3276,6 +3362,8 @@ fi:
|
||||
payment_processing_failed: "Payment could not be processed, please check the details you entered"
|
||||
payment_method_not_supported: "Maksutapaa ei tueta. Valitse toinen."
|
||||
payment_updated: "Maksu päivitetty"
|
||||
payment_method_taler:
|
||||
order_summary: "Open Food Network tilaus"
|
||||
cannot_perform_operation: "Maksua ei voitu päivittää"
|
||||
action_required: "Toimenpide vaaditaan"
|
||||
tag_rules: "Tägisäännöt"
|
||||
@@ -3321,6 +3409,7 @@ fi:
|
||||
order_cycles_no_permission_to_coordinate_error: "Yhdelläkään yritykselläsi ei ole lupaa koordinoida tilauskiertoa."
|
||||
order_cycles_no_permission_to_create_error: "Sinulla ei ole oikeutta luoda kyseisen yrityksen koordinoimaa tilausjaksoa."
|
||||
order_cycle_closed: "Valitsemasi tilausjakso on juuri päättynyt. Yritä uudelleen!"
|
||||
order_cycle_closed_next_steps: "Valitsemasi tilausjakso on juuri sulkeutunut. Ota meihin yhteyttä täydentääksesi tilaustasi# %{order_number} !"
|
||||
back_to_orders_list: "Takaisin tilauslistaan"
|
||||
no_orders_found: "Ei tilaukset löytynyt"
|
||||
order_information: "Tilaustiedot"
|
||||
@@ -3888,6 +3977,8 @@ fi:
|
||||
destroy:
|
||||
success: Webhook-päätepiste poistettu onnistuneesti
|
||||
error: Webhook-päätepisteen poistaminen epäonnistui
|
||||
test:
|
||||
success: Joitakin testitietoja lähetetään webhookin URL-osoitteeseen
|
||||
spree:
|
||||
order_updated: "Tilaus päivitetty"
|
||||
cannot_perform_operation: "Tätä toimintoa ei voida suorittaa"
|
||||
@@ -3994,6 +4085,7 @@ fi:
|
||||
logourl: "Logourl"
|
||||
are_you_sure_delete: "Haluatko varmasti poistaa tämän tietueen?"
|
||||
confirm_delete: "Vahvista poisto"
|
||||
tag_rule: "tägi Rule"
|
||||
voucher: "Alennuskuponki"
|
||||
configurations: "Asetukset"
|
||||
general_settings: "Yleiset asetukset"
|
||||
@@ -4085,6 +4177,8 @@ fi:
|
||||
alt_text: "Vaihtoehtoinen teksti"
|
||||
thumbnail: "Pienoiskuva"
|
||||
back_to_images_list: "Takaisin kuvaluetteloon"
|
||||
backend_url: "Taustapalvelun URL-osoite"
|
||||
api_key: "API-avain"
|
||||
email: Sähköposti
|
||||
account_updated: "Tili päivitetty!"
|
||||
email_updated: "Tili päivitetään, kun uusi sähköpostiosoite on vahvistettu."
|
||||
@@ -4403,6 +4497,7 @@ fi:
|
||||
check: "Käteinen/sähköinen maksu/jne. (maksut, joille ei vaadita automaattista vahvistusta)"
|
||||
paypalexpress: "PayPal Express"
|
||||
stripesca: "Stripe SCA"
|
||||
taler: "Taleri"
|
||||
payments:
|
||||
source_forms:
|
||||
stripe:
|
||||
@@ -4852,13 +4947,31 @@ fi:
|
||||
tag_rule_form:
|
||||
tag_rules:
|
||||
shipping_method_tagged_top: "Toimitustavat merkitty tägillä"
|
||||
shipping_method_tagged_bottom: "ovat:"
|
||||
payment_method_tagged_top: "Maksutavat merkitty tägillä"
|
||||
payment_method_tagged_bottom: "ovat:"
|
||||
order_cycle_tagged_top: "Tilausjaksot merkitty tägillä"
|
||||
order_cycle_tagged_bottom: "ovat:"
|
||||
inventory_tagged_top: "Tägätyt varastomuunnelmat"
|
||||
inventory_tagged_bottom: "ovat:"
|
||||
variant_tagged_top: "Variantit -tunnisteella"
|
||||
variant_tagged_bottom: "ovat:"
|
||||
visible: NÄKYVÄ
|
||||
not_visible: EI NÄKYVÄ
|
||||
tag_rule_group_form:
|
||||
for_customers_tagged: 'Asiakkaille, jotka on tägätty:'
|
||||
add_new_rule: '+ Lisää uusi sääntö'
|
||||
no_rules_yet: Tähän tägiin ei vielä sovelleta sääntöjä
|
||||
add_tag_rule_modal:
|
||||
select_rule_type: "Valitse säännön tyyppi:"
|
||||
add_rule: "lisää sääntö"
|
||||
webhook_endpoint_form:
|
||||
url:
|
||||
create_placeholder: Anna etäwebhook-päätepisteen URL-osoite
|
||||
event_types:
|
||||
order_cycle_opened: Tilausjakso avattu
|
||||
payment_status_changed: Lähetä webhook maksun tilan muutoksesta
|
||||
test_endpoint: Testaa webhookin päätepiste
|
||||
invisible_captcha:
|
||||
sentence_for_humans: "Jätä tyhjäksi"
|
||||
timestamp_error_message: "Yritä uudelleen 5 sekunnin kuluttua."
|
||||
|
||||
@@ -2945,7 +2945,7 @@ fr:
|
||||
shipping_method_destroy_error: "Cette méthode de livraison ne peut pas être supprimée car elle est référencée dans une commande : %{number}."
|
||||
fees: "Frais"
|
||||
fee_name: "Nom de la marge/commission"
|
||||
fee_owner: "Propriétaire des droits"
|
||||
fee_owner: "Propriétaire de la marge/commission"
|
||||
item_cost: "Coût du produit"
|
||||
bulk: "Vrac"
|
||||
shop_variant_quantity_min: "min"
|
||||
|
||||
@@ -115,6 +115,69 @@ fr_CA:
|
||||
blank: "Champ obligatoire"
|
||||
too_short: "est trop court (minimum %{count} caractère)"
|
||||
errors:
|
||||
messages:
|
||||
content_type_invalid:
|
||||
one: "a un contenu invalide (le type de contenu autorisé est %{authorized_human_content_types})"
|
||||
many: "a un contenu invalide (les types de contenus autorisés sont %{authorized_human_content_types})"
|
||||
other: "a un contenu invalide (les types de contenus autorisés sont %{authorized_human_content_types})"
|
||||
content_type_spoofed:
|
||||
one: "a un type de contenu qui n'est pas équivalent avec celui détecté (le type de contenu autorisé est %{authorized_human_content_types})"
|
||||
many: "a un type de contenu qui n'est pas équivalent avec celui détecté (les types de contenus autorisés sont %{authorized_human_content_types})"
|
||||
other: "a un type de contenu qui n'est pas équivalent avec celui détecté (les types de contenus autorisés sont %{authorized_human_content_types})"
|
||||
file_size_not_less_than: "la taille du fichier doit être inférieure à %{max} (la taille actuelle est %{file_size})"
|
||||
file_size_not_less_than_or_equal_to: "la taille du fichier doit être inférieure ou égale à %{max} (la taille actuelle est %{file_size})"
|
||||
file_size_not_greater_than: "la taille du fichier doit être supérieure à %{min} (la taille actuelle est%{file_size})"
|
||||
file_size_not_greater_than_or_equal_to: "la taille du fichier doit être supérieure ou égale à %{min} (la taille actuelle est %{file_size})"
|
||||
file_size_not_between: "la taille du fichier doit être comprise entre%{min} et %{max} (la taille actuelle est %{file_size})"
|
||||
file_size_not_equal_to: "la taille du fichier doit être égale à %{exact} (la taille actuelle est %{file_size})"
|
||||
total_file_size_not_less_than: "La taille totale du fichier doit être inférieure à %{max} (la taille actuelle est%{total_file_size})"
|
||||
total_file_size_not_less_than_or_equal_to: "La taille totale du fichier doit être inférieure ou égale à %{max} (la taille actuelle est %{total_file_size})"
|
||||
total_file_size_not_greater_than: "La taille totale du fichier doit être supérieure à %{min} (la taille actuelle est%{total_file_size})"
|
||||
total_file_size_not_greater_than_or_equal_to: "La taille totale du fichier doit être supérieure ou égale à %{min} (la taille actuelle est %{total_file_size})"
|
||||
total_file_size_not_between: "La taille totale du fichier doit être comprise entre %{min} et %{max} (la taille actuelle est %{total_file_size})"
|
||||
total_file_size_not_equal_to: "La taille totale du fichier doit être égale à %{exact} (la taille actuelle est%{total_file_size})"
|
||||
duration_not_less_than: "La durée doit être inférieure à %{max} (la durée actuelle est %{duration})"
|
||||
duration_not_less_than_or_equal_to: "La durée doit être inférieure ou égale à %{max} (la durée actuelle est%{duration})"
|
||||
duration_not_greater_than: "La durée doit être supérieure à %{min} (la durée actuelle est %{duration})"
|
||||
duration_not_greater_than_or_equal_to: "La durée doit être supérieure ou égale à %{min} (la durée actuelle est%{duration})"
|
||||
duration_not_between: "La durée doit être comprise entre %{min} et %{max} (la durée actuelle est %{duration})"
|
||||
duration_not_equal_to: "La durée doit être égale à %{exact} (la durée actuelle est %{duration})"
|
||||
limit_out_of_range:
|
||||
zero: "Aucun fichier joint (doit contenir entre %{min} et %{max} fichiers)"
|
||||
one: "Seulement 1 fichier joint (doit contenir entre%{min} et %{max} fichiers)"
|
||||
other: "Le nombre total de fichiers doit être compris entre %{min} et %{max} fichiers (il y a %{count} fichiers joints)"
|
||||
limit_min_not_reached:
|
||||
zero: "Aucun fichier joint (doit contenir au moins %{min} fichiers)"
|
||||
one: "Seulement 1 fichier joint (doit contenir au moins %{min} fichiers)"
|
||||
other: "%{count} Aucun fichier joint (doit contenir au moins %{min} fichiers)"
|
||||
limit_max_exceeded:
|
||||
zero: "Aucun fichier joint (au maximum %{max} fichiers)"
|
||||
one: "Trop de fichiers joints (le maximum est %{max} fichiers, il y en a %{count})"
|
||||
other: "Trop de fichiers joints (le maximum est %{max} fichiers, il y en a%{count})"
|
||||
attachment_missing: "une pièce jointe est manquante"
|
||||
media_metadata_missing: "n'est pas un fichier multimédia valide"
|
||||
dimension_min_not_included_in: "doit être plus grand ou égal à %{width} x %{height} pixels"
|
||||
dimension_max_not_included_in: "doit être plus petit ou égal à %{width} x %{height} pixels"
|
||||
dimension_width_not_included_in: "la largeur n'est pas comprise entre %{min} et %{max} pixels"
|
||||
dimension_height_not_included_in: "la hauteur n'est pas comprise entre %{min} et %{max} pixels"
|
||||
dimension_width_not_greater_than_or_equal_to: "la largeur doit être supérieure ou égale à %{length} pixels"
|
||||
dimension_height_not_greater_than_or_equal_to: "la hauteur doit être supérieure ou égale à %{length} pixels"
|
||||
dimension_width_not_less_than_or_equal_to: "la largeur doit être inférieure ou égale à %{length} pixels"
|
||||
dimension_height_not_less_than_or_equal_to: "la hauteur doit être inférieure ou égale à %{length} pixels"
|
||||
dimension_width_not_equal_to: "la largeur doit être égale à %{length} pixels"
|
||||
dimension_height_not_equal_to: "La hauteur doit être égale à %{length} pixels"
|
||||
aspect_ratio_not_square: "doit être carré (le fichier actuel est %{width}x%{height}px)"
|
||||
aspect_ratio_not_portrait: "doit être au format portrait (le fichier actuel mesure %{width}x%{height}px)"
|
||||
aspect_ratio_not_landscape: "doit être au format paysage (le fichier actuel mesure %{width}x%{height}px)"
|
||||
aspect_ratio_not_x_y: "doit être %{authorized_aspect_ratios} (le fichier actuel est %{width}x%{height}px)"
|
||||
aspect_ratio_invalid: "possède un ratio d'image invalide (les ratios d'image valides sont %{authorized_aspect_ratios})"
|
||||
file_not_processable: "n'est pas identifié comme un fichier multimédia valide"
|
||||
pages_not_less_than: "La durée doit être inférieure à %{max} (la durée actuelle est %{pages})"
|
||||
pages_not_less_than_or_equal_to: "La durée doit être inférieure ou égale à %{max} (la durée actuelle est %{pages})"
|
||||
pages_not_greater_than: "La durée doit être supérieure à %{min}(la durée actuelle est %{pages})"
|
||||
pages_not_greater_than_or_equal_to: "La durée doit être supérieure ou égale à %{min} (la durée actuelle %{pages})"
|
||||
pages_not_between: "La durée doit être comprise entre %{min} et %{max} (la durée actuelle est %{pages})"
|
||||
pages_not_equal_to: "La durée doit être égale à %{exact} (la durée actuelle est %{pages})"
|
||||
not_found:
|
||||
title: "La page que vous recherchez n'existe pas (erreur 404)"
|
||||
message_html: "<b>Veuillez essayer à nouveau </b> <p> Il s'agit peut-être d'un problème temporaire. Veuillez cliquer sur le bouton retour de votre navigateur ou retourner à l'<a href='/'> Accueil </a> et recommencez. <b> Contacter notre support </b> <p> Si le problème persiste ou si c'est urgent, veuillez nous contacter. </p>"
|
||||
@@ -185,6 +248,9 @@ fr_CA:
|
||||
disconnect_failure: "Déconnecter Stripe a échoué."
|
||||
success_code:
|
||||
disconnected: "Le compte Stripe est déconnecté."
|
||||
taler:
|
||||
order_status:
|
||||
claimed: "La demande de paiement a expiré. Merci d'essayer à nouveau."
|
||||
activemodel:
|
||||
errors:
|
||||
messages:
|
||||
@@ -520,6 +586,7 @@ fr_CA:
|
||||
errors:
|
||||
vine_api: "There was an error communicating with the API, please try again later."
|
||||
invalid_voucher: "The voucher is not valid"
|
||||
expired: "Le bon de réduction a expiré."
|
||||
not_found_voucher: "Désolé, nous n'avons pas trouvé ce bon de réduction. Merci de vérifier le code qui vous a été transmis."
|
||||
vine_voucher_redeemer_service:
|
||||
errors:
|
||||
@@ -3305,6 +3372,8 @@ fr_CA:
|
||||
payment_processing_failed: "Le paiement n'a pas pu être traité, veuillez vérifier les informations saisies"
|
||||
payment_method_not_supported: "Cette méthode de paiement n'est pas maintenue. Veuillez en sélectionner une autre."
|
||||
payment_updated: "Paiement mis à jour"
|
||||
payment_method_taler:
|
||||
order_summary: "Commande Open Food Network"
|
||||
cannot_perform_operation: "Le paiement n'a pas pu être mis à jour."
|
||||
action_required: "Une action est requise"
|
||||
tag_rules: "Règles de tag"
|
||||
@@ -3965,6 +4034,8 @@ fr_CA:
|
||||
destroy:
|
||||
success: Le webhook a bien été supprimé.
|
||||
error: Le webhook n'a pas pu être supprimé.
|
||||
test:
|
||||
success: Des données test vont être envoyées à l'URL du webhook
|
||||
spree:
|
||||
order_updated: "La commande a été mise à jour"
|
||||
cannot_perform_operation: "Cette opération ne peut pas être réalisée"
|
||||
@@ -4071,6 +4142,7 @@ fr_CA:
|
||||
logourl: "URL du logo"
|
||||
are_you_sure_delete: "Etes-vous certain de vouloir supprimer cet élément ?"
|
||||
confirm_delete: "Confirmer la suppression"
|
||||
tag_rule: "Règle de tag"
|
||||
voucher: "Bon de réduction"
|
||||
configurations: "Configurations"
|
||||
general_settings: "Configurations générales"
|
||||
@@ -4162,6 +4234,7 @@ fr_CA:
|
||||
alt_text: "Texte alternatif"
|
||||
thumbnail: "Miniature"
|
||||
back_to_images_list: "Retour à la liste des images"
|
||||
backend_url: "URL du backend"
|
||||
api_key: "Clé API"
|
||||
email: Email
|
||||
account_updated: "Compte mis à jour!"
|
||||
@@ -4481,6 +4554,7 @@ fr_CA:
|
||||
check: "Espèces / chèques / virements / autres "
|
||||
paypalexpress: "PayPal Express"
|
||||
stripesca: "Stripe SCA"
|
||||
taler: "Taler"
|
||||
payments:
|
||||
source_forms:
|
||||
stripe:
|
||||
@@ -4967,6 +5041,8 @@ fr_CA:
|
||||
create_placeholder: Entrez l'URL du point de terminaison du webhook
|
||||
event_types:
|
||||
order_cycle_opened: Cycle de vente ouvert
|
||||
payment_status_changed: Poster webhook sur le changement du statut de paiement
|
||||
test_endpoint: Tester le point de terminaison du webhook
|
||||
invisible_captcha:
|
||||
sentence_for_humans: "Merci de laisser ce champ libre"
|
||||
timestamp_error_message: "S'il vous plaît réessayez après 5 secondes."
|
||||
|
||||
@@ -136,7 +136,15 @@ Openfoodnetwork::Application.routes.draw do
|
||||
put :resume, on: :member, format: :json
|
||||
end
|
||||
|
||||
get '/reports', to: 'reports#index', as: :reports
|
||||
scope :reports, as: :reports do
|
||||
get '/', to: 'reports#index'
|
||||
get '/search_enterprise_fees', to: 'reports#search_enterprise_fees', as: :search_enterprise_fees
|
||||
get '/search_enterprise_fee_owners', to: 'reports#search_enterprise_fee_owners', as: :search_enterprise_fee_owners
|
||||
get '/search_distributors', to: 'reports#search_distributors', as: :search_distributors
|
||||
get '/search_suppliers', to: 'reports#search_suppliers', as: :search_suppliers
|
||||
get '/search_order_cycles', to: 'reports#search_order_cycles', as: :search_order_cycles
|
||||
get '/search_order_customers', to: 'reports#search_order_customers', as: :search_order_customers
|
||||
end
|
||||
match '/reports/:report_type(/:report_subtype)', to: 'reports#show', via: :get, as: :report
|
||||
match '/reports/:report_type(/:report_subtype)', to: 'reports#create', via: :post
|
||||
end
|
||||
|
||||
@@ -36,7 +36,7 @@ RSpec.describe "CatalogItems", swagger_doc: "dfc.yaml" do
|
||||
|
||||
get "List CatalogItems" do
|
||||
produces "application/json"
|
||||
security [oidc_token: []]
|
||||
security [{ oidc_token: [] }]
|
||||
|
||||
response "404", "not found" do
|
||||
context "as platform user" do
|
||||
|
||||
@@ -35,7 +35,7 @@ RSpec.describe "ProductGroups", swagger_doc: "dfc.yaml" do
|
||||
|
||||
get "Show ProductGroup" do
|
||||
produces "application/json"
|
||||
security [oidc_token: []]
|
||||
security [{ oidc_token: [] }]
|
||||
|
||||
response "200", "success" do
|
||||
let(:id) { product.id }
|
||||
|
||||
@@ -179,7 +179,7 @@ module.exports = {
|
||||
// transform: { "\\.[jt]sx?$": "babel-jest" },
|
||||
|
||||
// An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation
|
||||
transformIgnorePatterns: ["/node_modules/(?!stimulus)/"],
|
||||
transformIgnorePatterns: ["/node_modules/(?!(stimulus.+|tom-select)/)"],
|
||||
|
||||
// An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them
|
||||
// unmockedModulePathPatterns: undefined,
|
||||
|
||||
@@ -46,7 +46,7 @@ module Reporting
|
||||
end
|
||||
|
||||
def order_customers
|
||||
Customer.where(id: visible_order_customer_ids).select("customers.id, customers.email")
|
||||
Customer.where(id: visible_order_customer_ids_query).select("customers.id, customers.email")
|
||||
end
|
||||
|
||||
private
|
||||
@@ -57,8 +57,8 @@ module Reporting
|
||||
@permissions ||= OpenFoodNetwork::Permissions.new(current_user)
|
||||
end
|
||||
|
||||
def visible_order_customer_ids
|
||||
Permissions::Order.new(current_user).visible_orders.pluck(:customer_id)
|
||||
def visible_order_customer_ids_query
|
||||
Permissions::Order.new(current_user).visible_orders.select(:customer_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -15,7 +15,7 @@ module Reporting
|
||||
@orders ||= search_orders
|
||||
end
|
||||
|
||||
def list(line_item_includes = [variant: [:supplier, :product]])
|
||||
def list(line_item_includes = [{ variant: [:supplier, :product] }])
|
||||
line_items = order_permissions.visible_line_items.in_orders(orders.result)
|
||||
.order(
|
||||
"supplier.name",
|
||||
|
||||
@@ -10,10 +10,10 @@ module Reporting
|
||||
.complete.not_state(:canceled)
|
||||
.order(:id))
|
||||
.group_by do |order|
|
||||
{
|
||||
customer_id: order.customer_id || order.email,
|
||||
hub_id: order.distributor_id,
|
||||
}
|
||||
{
|
||||
customer_id: order.customer_id || order.email,
|
||||
hub_id: order.distributor_id,
|
||||
}
|
||||
end.values
|
||||
end
|
||||
|
||||
|
||||
@@ -44,11 +44,11 @@ module Reporting
|
||||
.filter(&method(:filter_enterprise_fee_by_id))
|
||||
.filter(&method(:filter_enterprise_fee_by_owner))
|
||||
.map do |enterprise_fee_id, enterprise_fee_adjustment_ids|
|
||||
{
|
||||
enterprise_fee_id:,
|
||||
enterprise_fee_adjustment_ids:,
|
||||
order:
|
||||
}
|
||||
{
|
||||
enterprise_fee_id:,
|
||||
enterprise_fee_adjustment_ids:,
|
||||
order:
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
296
spec/javascripts/stimulus/tom_select_controller_test.js
Normal file
296
spec/javascripts/stimulus/tom_select_controller_test.js
Normal file
@@ -0,0 +1,296 @@
|
||||
/**
|
||||
* @jest-environment jsdom
|
||||
*/
|
||||
|
||||
import { Application } from "stimulus";
|
||||
import { fireEvent, waitFor } from "@testing-library/dom";
|
||||
import tom_select_controller from "controllers/tom_select_controller";
|
||||
import showHttpError from "js/services/show_http_error";
|
||||
|
||||
jest.mock("js/services/show_http_error", () => ({
|
||||
__esModule: true,
|
||||
default: jest.fn(),
|
||||
}));
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
* Helpers
|
||||
* ------------------------------------------------------------------ */
|
||||
|
||||
const buildResults = (count, start = 1) =>
|
||||
Array.from({ length: count }, (_, i) => ({
|
||||
value: String(start + i),
|
||||
label: `Option ${start + i}`,
|
||||
}));
|
||||
|
||||
const setupDOM = (html) => {
|
||||
document.body.innerHTML = html;
|
||||
};
|
||||
|
||||
const getSelect = () => document.getElementById("select");
|
||||
const getTomSelect = () => getSelect().tomselect;
|
||||
|
||||
const openDropdown = () => fireEvent.click(document.getElementById("select-ts-control"));
|
||||
|
||||
const mockRemoteFetch = (...responses) => {
|
||||
responses.forEach((response) => {
|
||||
fetch.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
json: async () => response,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const mockDropdownScroll = (
|
||||
dropdown,
|
||||
{ scrollHeight = 1000, clientHeight = 300, scrollTop = 700 } = {},
|
||||
) => {
|
||||
Object.defineProperty(dropdown, "scrollHeight", {
|
||||
configurable: true,
|
||||
value: scrollHeight,
|
||||
});
|
||||
|
||||
Object.defineProperty(dropdown, "clientHeight", {
|
||||
configurable: true,
|
||||
value: clientHeight,
|
||||
});
|
||||
|
||||
Object.defineProperty(dropdown, "scrollTop", {
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: scrollTop,
|
||||
});
|
||||
|
||||
fireEvent.scroll(dropdown);
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
* Expectation helpers
|
||||
* ------------------------------------------------------------------ */
|
||||
|
||||
const expectOptionsCount = (count) => {
|
||||
expect(document.querySelectorAll('.ts-dropdown-content [role="option"]').length).toBe(count);
|
||||
};
|
||||
|
||||
const expectDropdownToContain = (text) => {
|
||||
expect(document.querySelector(".ts-dropdown-content")?.textContent).toContain(text);
|
||||
};
|
||||
|
||||
const expectDropdownWithNoResults = () => {
|
||||
expect(document.querySelector(".ts-dropdown-content")?.textContent).toBe("No results found");
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
* Specs
|
||||
* ------------------------------------------------------------------ */
|
||||
|
||||
describe("TomSelectController", () => {
|
||||
let application;
|
||||
|
||||
beforeAll(() => {
|
||||
application = Application.start();
|
||||
application.register("tom-select", tom_select_controller);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
global.fetch = jest.fn();
|
||||
global.I18n = { t: (key) => key };
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
document.body.innerHTML = "";
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
describe("connect()", () => {
|
||||
beforeEach(() => {
|
||||
setupDOM(`
|
||||
<select id="select" data-controller="tom-select">
|
||||
<option value="">Default Option</option>
|
||||
<option value="1">Option 1</option>
|
||||
<option value="2">Option 2</option>
|
||||
</select>
|
||||
`);
|
||||
});
|
||||
|
||||
it("initializes TomSelect with default options", () => {
|
||||
const settings = getTomSelect().settings;
|
||||
|
||||
expect(settings.placeholder).toBe("Default Option");
|
||||
expect(settings.maxItems).toBe(1);
|
||||
expect(settings.plugins).toEqual(["dropdown_input"]);
|
||||
expect(settings.allowEmptyOption).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("connect() with custom values", () => {
|
||||
beforeEach(() => {
|
||||
setupDOM(`
|
||||
<select
|
||||
id="select"
|
||||
data-controller="tom-select"
|
||||
data-tom-select-placeholder-value="Choose an option"
|
||||
data-tom-select-options-value='{"maxItems": 3, "plugins": ["remove_button"]}'
|
||||
>
|
||||
<option value="1">Option 1</option>
|
||||
<option value="2">Option 2</option>
|
||||
</select>
|
||||
`);
|
||||
});
|
||||
|
||||
it("applies custom placeholder and options", () => {
|
||||
const settings = getTomSelect().settings;
|
||||
|
||||
expect(settings.placeholder).toBe("Choose an option");
|
||||
expect(settings.maxItems).toBe(3);
|
||||
expect(settings.plugins).toEqual(["remove_button"]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("connect() with remoteUrl", () => {
|
||||
beforeEach(() => {
|
||||
setupDOM(`
|
||||
<select
|
||||
id="select"
|
||||
data-controller="tom-select"
|
||||
data-tom-select-options-value='{"plugins":["virtual_scroll"]}'
|
||||
data-tom-select-remote-url-value="https://ofn-tests.com/api/search"
|
||||
></select>
|
||||
`);
|
||||
});
|
||||
|
||||
it("configures remote loading callbacks", () => {
|
||||
const settings = getTomSelect().settings;
|
||||
|
||||
expect(settings.valueField).toBe("value");
|
||||
expect(settings.labelField).toBe("label");
|
||||
expect(settings.searchField).toBe("label");
|
||||
expect(settings.load).toEqual(expect.any(Function));
|
||||
expect(settings.firstUrl).toEqual(expect.any(Function));
|
||||
expect(settings.onFocus).toEqual(expect.any(Function));
|
||||
});
|
||||
|
||||
it("fetches page 1 on focus", async () => {
|
||||
mockRemoteFetch({
|
||||
results: buildResults(1),
|
||||
pagination: { more: false },
|
||||
});
|
||||
|
||||
openDropdown();
|
||||
|
||||
await waitFor(() => expect(fetch).toHaveBeenCalledTimes(1));
|
||||
|
||||
expect(fetch).toHaveBeenCalledWith(expect.stringContaining("q=&page=1"));
|
||||
|
||||
await waitFor(() => {
|
||||
expectOptionsCount(1);
|
||||
expectDropdownToContain("Option 1");
|
||||
});
|
||||
});
|
||||
|
||||
it("fetches remote options using search query", async () => {
|
||||
const appleOption = { value: "apple", label: "Apple" };
|
||||
mockRemoteFetch({
|
||||
results: [...buildResults(1), appleOption],
|
||||
pagination: { more: false },
|
||||
});
|
||||
|
||||
openDropdown();
|
||||
|
||||
await waitFor(() => {
|
||||
expectOptionsCount(2);
|
||||
});
|
||||
|
||||
mockRemoteFetch({
|
||||
results: [appleOption],
|
||||
pagination: { more: false },
|
||||
});
|
||||
|
||||
fireEvent.input(document.getElementById("select-ts-control"), {
|
||||
target: { value: "apple" },
|
||||
});
|
||||
|
||||
await waitFor(() =>
|
||||
expect(fetch).toHaveBeenCalledWith(expect.stringContaining("q=apple&page=1")),
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expectOptionsCount(1);
|
||||
expectDropdownToContain("Apple");
|
||||
});
|
||||
});
|
||||
|
||||
it("loads next page on scroll (infinite scroll)", async () => {
|
||||
mockRemoteFetch(
|
||||
{
|
||||
results: buildResults(30),
|
||||
pagination: { more: true },
|
||||
},
|
||||
{
|
||||
results: buildResults(1, 31),
|
||||
pagination: { more: false },
|
||||
},
|
||||
);
|
||||
|
||||
openDropdown();
|
||||
|
||||
await waitFor(() => {
|
||||
expectOptionsCount(30);
|
||||
});
|
||||
|
||||
const dropdown = document.querySelector(".ts-dropdown-content");
|
||||
mockDropdownScroll(dropdown);
|
||||
|
||||
await waitFor(() => {
|
||||
expectOptionsCount(31);
|
||||
});
|
||||
|
||||
expect(fetch).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it("handles fetch errors gracefully", async () => {
|
||||
fetch.mockRejectedValueOnce(new Error("Fetch error"));
|
||||
|
||||
openDropdown();
|
||||
|
||||
await waitFor(() => {
|
||||
expectDropdownWithNoResults();
|
||||
});
|
||||
|
||||
expect(showHttpError).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("displays HTTP error on failure", async () => {
|
||||
fetch.mockResolvedValueOnce({
|
||||
ok: false,
|
||||
status: 500,
|
||||
json: async () => ({}),
|
||||
});
|
||||
|
||||
openDropdown();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(showHttpError).toHaveBeenCalledWith(500);
|
||||
});
|
||||
|
||||
expectDropdownWithNoResults();
|
||||
});
|
||||
|
||||
it("controls loading behavior based on user interaction", () => {
|
||||
const settings = getTomSelect().settings;
|
||||
|
||||
// Initial state: openedByClick is false, query is empty
|
||||
expect(settings.shouldLoad("")).toBe(false);
|
||||
|
||||
// Simulating opening the dropdown
|
||||
settings.onDropdownOpen();
|
||||
expect(settings.shouldLoad("")).toBe(true);
|
||||
|
||||
// Simulating typing
|
||||
settings.onType();
|
||||
expect(settings.shouldLoad("")).toBe(false);
|
||||
|
||||
// Query present
|
||||
expect(settings.shouldLoad("a")).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -109,7 +109,7 @@ RSpec.describe Spree::Gateway::StripeSCA, :vcr, :stripe_version do
|
||||
end
|
||||
|
||||
it "refunds the payment" do
|
||||
response = subject.void(payment_intent.id, nil, {})
|
||||
response = subject.void(payment_intent.id, {})
|
||||
|
||||
expect(response.success?).to eq true
|
||||
end
|
||||
@@ -131,7 +131,7 @@ RSpec.describe Spree::Gateway::StripeSCA, :vcr, :stripe_version do
|
||||
end
|
||||
|
||||
it "void the payment" do
|
||||
response = subject.void(payment_intent.id, nil, {})
|
||||
response = subject.void(payment_intent.id, {})
|
||||
|
||||
expect(response.success?).to eq true
|
||||
end
|
||||
@@ -162,7 +162,7 @@ RSpec.describe Spree::Gateway::StripeSCA, :vcr, :stripe_version do
|
||||
stripe_account: stripe_test_account
|
||||
)
|
||||
|
||||
response = subject.credit(1000, nil, payment_intent.id, {})
|
||||
response = subject.credit(1000, payment_intent.id, {})
|
||||
|
||||
expect(response.success?).to eq true
|
||||
end
|
||||
|
||||
@@ -14,8 +14,14 @@ RSpec.describe Spree::Gateway do
|
||||
end
|
||||
|
||||
it "passes through all arguments on a method_missing call" do
|
||||
expect(Rails.env).to receive(:local?).and_return(false)
|
||||
gateway = test_gateway.new
|
||||
expect(gateway.provider).to receive(:imaginary_method).with('foo')
|
||||
gateway.imaginary_method('foo')
|
||||
end
|
||||
|
||||
it "raises an error in test env" do
|
||||
gateway = test_gateway.new
|
||||
expect { gateway.imaginary_method('foo') }.to raise_error StandardError
|
||||
end
|
||||
end
|
||||
|
||||
@@ -86,11 +86,11 @@ RSpec.describe Spree::Order do
|
||||
|
||||
(Spree::Shipment.state_machine.states.keys - [:pending, :backorder, :ready])
|
||||
.each do |shipment_state|
|
||||
it "should be false if shipment_state is #{shipment_state}" do
|
||||
allow(order).to receive_messages completed?: true
|
||||
order.shipment_state = shipment_state
|
||||
expect(order.can_cancel?).to be_falsy
|
||||
end
|
||||
it "should be false if shipment_state is #{shipment_state}" do
|
||||
allow(order).to receive_messages completed?: true
|
||||
order.shipment_state = shipment_state
|
||||
expect(order.can_cancel?).to be_falsy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -131,13 +131,6 @@ RSpec.describe Spree::PaymentMethod do
|
||||
expect(pm.errors.to_a).to eq(["Name can't be blank", "At least one hub must be selected"])
|
||||
end
|
||||
|
||||
it "generates a clean name for known Payment Method types" do
|
||||
expect(Spree::PaymentMethod::Check.clean_name)
|
||||
.to eq('Cash/EFT/etc. (payments for which automatic validation is not required)')
|
||||
expect(Spree::Gateway::PayPalExpress.clean_name).to eq('PayPal Express')
|
||||
expect(Spree::Gateway::StripeSCA.clean_name).to eq('Stripe SCA')
|
||||
end
|
||||
|
||||
it "computes the amount of fees" do
|
||||
order = create(:order)
|
||||
|
||||
|
||||
@@ -345,24 +345,6 @@ RSpec.describe Spree::Payment do
|
||||
allow(payment_method).to receive(:void).and_return(success_response)
|
||||
end
|
||||
|
||||
context "when profiles are supported" do
|
||||
it "should call payment_enterprise.void with the payment's response_code" do
|
||||
allow(payment_method).to receive(:payment_profiles_supported) { true }
|
||||
expect(payment_method).to receive(:void).with('123', card,
|
||||
anything).and_return(success_response)
|
||||
payment.void_transaction!
|
||||
end
|
||||
end
|
||||
|
||||
context "when profiles are not supported" do
|
||||
it "should call payment_gateway.void with the payment's response_code" do
|
||||
allow(payment_method).to receive(:payment_profiles_supported) { false }
|
||||
expect(payment_method).to receive(:void).with('123', card,
|
||||
anything).and_return(success_response)
|
||||
payment.void_transaction!
|
||||
end
|
||||
end
|
||||
|
||||
it "should log the response" do
|
||||
payment.void_transaction!
|
||||
expect(payment).to have_received(:record_response)
|
||||
@@ -437,7 +419,7 @@ RSpec.describe Spree::Payment do
|
||||
end
|
||||
|
||||
it "should call credit on the gateway with the credit amount and response_code" do
|
||||
expect(payment_method).to receive(:credit).with(1000, card, '123',
|
||||
expect(payment_method).to receive(:credit).with(1000, '123',
|
||||
anything).and_return(success_response)
|
||||
payment.credit!
|
||||
end
|
||||
@@ -463,7 +445,7 @@ RSpec.describe Spree::Payment do
|
||||
|
||||
it "should call credit on the gateway with the credit amount and response_code" do
|
||||
expect(payment_method).to receive(:credit).with(
|
||||
amount_in_cents, card, '123', anything
|
||||
amount_in_cents, '123', anything
|
||||
).and_return(success_response)
|
||||
payment.credit!
|
||||
end
|
||||
@@ -476,7 +458,7 @@ RSpec.describe Spree::Payment do
|
||||
|
||||
it "should call credit on the gateway with original payment amount and response_code" do
|
||||
expect(payment_method).to receive(:credit).with(
|
||||
amount_in_cents.to_f, card, '123', anything
|
||||
amount_in_cents.to_f, '123', anything
|
||||
).and_return(success_response)
|
||||
payment.credit!
|
||||
end
|
||||
@@ -658,7 +640,6 @@ RSpec.describe Spree::Payment do
|
||||
|
||||
context "when profiles are supported" do
|
||||
before do
|
||||
allow(payment_method).to receive(:payment_profiles_supported?) { true }
|
||||
allow(payment.source).to receive(:has_payment_profile?) { false }
|
||||
end
|
||||
|
||||
@@ -700,26 +681,6 @@ RSpec.describe Spree::Payment do
|
||||
end
|
||||
end
|
||||
|
||||
context "when profiles are not supported" do
|
||||
before do
|
||||
allow(payment_method).to receive(:payment_profiles_supported?) { false }
|
||||
end
|
||||
|
||||
it "should not create a payment profile" do
|
||||
payment_method.name = 'Gateway'
|
||||
payment_method.distributors << create(:distributor_enterprise)
|
||||
payment_method.save!
|
||||
|
||||
expect(payment_method).not_to receive :create_profile
|
||||
payment = Spree::Payment.create(
|
||||
amount: 100,
|
||||
order: create(:order),
|
||||
source: card,
|
||||
payment_method:
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the payment was completed but now void' do
|
||||
let(:payment) { create(:payment, :completed, amount: 100, order:) }
|
||||
|
||||
@@ -877,23 +838,6 @@ RSpec.describe Spree::Payment do
|
||||
end
|
||||
end
|
||||
|
||||
describe "performing refunds" do
|
||||
before do
|
||||
allow(payment).to receive(:calculate_refund_amount) { 123 }
|
||||
expect(payment.payment_method).to receive(:refund).and_return(success)
|
||||
end
|
||||
|
||||
it "performs the refund without payment profiles" do
|
||||
allow(payment.payment_method).to receive(:payment_profiles_supported?) { false }
|
||||
payment.refund!
|
||||
end
|
||||
|
||||
it "performs the refund with payment profiles" do
|
||||
allow(payment.payment_method).to receive(:payment_profiles_supported?) { true }
|
||||
payment.refund!
|
||||
end
|
||||
end
|
||||
|
||||
it "records the response" do
|
||||
allow(payment).to receive(:calculate_refund_amount) { 123 }
|
||||
allow(payment.payment_method).to receive(:refund).and_return(success)
|
||||
|
||||
@@ -17,7 +17,7 @@ RSpec.describe Spree::User do
|
||||
bill_address_attributes: new_bill_address.dup.attributes.merge(
|
||||
'id' => old_bill_address.id
|
||||
)
|
||||
.except!('created_at', 'updated_at')
|
||||
.except!('created_at', 'updated_at')
|
||||
)
|
||||
|
||||
expect(user.bill_address.id).to eq old_bill_address.id
|
||||
|
||||
@@ -10,7 +10,7 @@ RSpec.describe OutstandingBalanceQuery do
|
||||
let(:normalized_sql_statement) { normalize(query.statement) }
|
||||
|
||||
it 'returns the CASE statement necessary to compute the order balance' do
|
||||
expect(normalized_sql_statement).to eq(normalize(<<-SQL.squish))
|
||||
expect(normalized_sql_statement).to eq(normalize(<<~SQL.squish))
|
||||
CASE WHEN "spree_orders"."state" IN ('canceled', 'returned') THEN "spree_orders"."payment_total"
|
||||
WHEN "spree_orders"."state" IS NOT NULL THEN "spree_orders"."payment_total" - "spree_orders"."total"
|
||||
ELSE 0 END
|
||||
|
||||
328
spec/requests/admin/reports_ajax_api_spec.rb
Normal file
328
spec/requests/admin/reports_ajax_api_spec.rb
Normal file
@@ -0,0 +1,328 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe "Admin Reports AJAX Search API" do
|
||||
let(:bill_address) { create(:address) }
|
||||
let(:ship_address) { create(:address) }
|
||||
let(:instructions) { "pick up on thursday please" }
|
||||
let(:coordinator1) { create(:distributor_enterprise) }
|
||||
let(:supplier1) { create(:supplier_enterprise) }
|
||||
let(:supplier2) { create(:supplier_enterprise) }
|
||||
let(:supplier3) { create(:supplier_enterprise) }
|
||||
let(:distributor1) { create(:distributor_enterprise) }
|
||||
let(:distributor2) { create(:distributor_enterprise) }
|
||||
let(:product1) { create(:product, price: 12.34, supplier_id: supplier1.id) }
|
||||
let(:product2) { create(:product, price: 23.45, supplier_id: supplier2.id) }
|
||||
let(:product3) { create(:product, price: 34.56, supplier_id: supplier3.id) }
|
||||
|
||||
let(:enterprise_fee1) { create(:enterprise_fee, name: "Delivery Fee", enterprise: distributor1) }
|
||||
let(:enterprise_fee2) { create(:enterprise_fee, name: "Admin Fee", enterprise: distributor2) }
|
||||
|
||||
let(:ocA) {
|
||||
create(:simple_order_cycle, coordinator: coordinator1,
|
||||
distributors: [distributor1, distributor2],
|
||||
suppliers: [supplier1, supplier2, supplier3],
|
||||
variants: [product1.variants.first, product3.variants.first])
|
||||
}
|
||||
let(:ocB) {
|
||||
create(:simple_order_cycle, coordinator: coordinator1,
|
||||
distributors: [distributor1, distributor2],
|
||||
suppliers: [supplier1, supplier2, supplier3],
|
||||
variants: [product2.variants.first])
|
||||
}
|
||||
|
||||
let(:orderA1) do
|
||||
order = create(:order, distributor: distributor1, bill_address:,
|
||||
ship_address:, special_instructions: instructions,
|
||||
order_cycle: ocA)
|
||||
order.line_items << create(:line_item, variant: product1.variants.first)
|
||||
order.line_items << create(:line_item, variant: product3.variants.first)
|
||||
order.finalize!
|
||||
order.save
|
||||
order
|
||||
end
|
||||
|
||||
let(:orderA2) do
|
||||
order = create(:order, distributor: distributor2, bill_address:,
|
||||
ship_address:, special_instructions: instructions,
|
||||
order_cycle: ocA)
|
||||
order.line_items << create(:line_item, variant: product2.variants.first)
|
||||
order.finalize!
|
||||
order.save
|
||||
order
|
||||
end
|
||||
|
||||
let(:orderB1) do
|
||||
order = create(:order, distributor: distributor1, bill_address:,
|
||||
ship_address:, special_instructions: instructions,
|
||||
order_cycle: ocB)
|
||||
order.line_items << create(:line_item, variant: product1.variants.first)
|
||||
order.line_items << create(:line_item, variant: product3.variants.first)
|
||||
order.finalize!
|
||||
order.save
|
||||
order
|
||||
end
|
||||
|
||||
let(:base_params) do
|
||||
{
|
||||
report_type: :enterprise_fee_summary,
|
||||
report_subtype: :enterprise_fees_with_tax_report_by_order
|
||||
}
|
||||
end
|
||||
|
||||
def create_adjustment(order, fee, amount)
|
||||
order.adjustments.create!(
|
||||
originator: fee,
|
||||
label: fee.name,
|
||||
amount:,
|
||||
state: "finalized",
|
||||
order:
|
||||
)
|
||||
end
|
||||
|
||||
context "when user is an admin" do
|
||||
before do
|
||||
login_as create(:admin_user)
|
||||
create_adjustment(orderA1, enterprise_fee1, 5.0)
|
||||
create_adjustment(orderB1, enterprise_fee2, 3.0)
|
||||
end
|
||||
|
||||
describe "GET /admin/reports/search_enterprise_fees" do
|
||||
it "returns enterprise fees sorted alphabetically by name" do
|
||||
get "/admin/reports/search_enterprise_fees", params: base_params
|
||||
|
||||
expect(response).to have_http_status(:ok)
|
||||
json_response = response.parsed_body
|
||||
|
||||
expect(json_response["results"].pluck("label")).to eq(['Admin Fee', 'Delivery Fee'])
|
||||
expect(json_response["pagination"]["more"]).to be false
|
||||
end
|
||||
|
||||
context "with more than 30 records" do
|
||||
before do
|
||||
create_list(:enterprise_fee, 35, enterprise: distributor1) do |fee, i|
|
||||
index = (i + 1).to_s.rjust(2, "0")
|
||||
fee.update!(name: "Fee #{index}")
|
||||
create_adjustment(orderA1, fee, 1.0)
|
||||
end
|
||||
end
|
||||
|
||||
it "returns first page with 30 results and more flag as true" do
|
||||
get "/admin/reports/search_enterprise_fees", params: base_params.merge(page: 1)
|
||||
|
||||
json_response = response.parsed_body
|
||||
expect(json_response["results"].length).to eq(30)
|
||||
expect(json_response["pagination"]["more"]).to be true
|
||||
end
|
||||
|
||||
it "returns remaining results on second page with more flag as false" do
|
||||
get "/admin/reports/search_enterprise_fees", params: base_params.merge(page: 2)
|
||||
|
||||
json_response = response.parsed_body
|
||||
expect(json_response["results"].length).to eq(7)
|
||||
expect(json_response["pagination"]["more"]).to be false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /admin/reports/search_enterprise_fee_owners" do
|
||||
it "returns unique enterprise fee owners sorted alphabetically by name" do
|
||||
distributor1.update!(name: "Zebra Farm")
|
||||
distributor2.update!(name: "Alpha Market")
|
||||
|
||||
get "/admin/reports/search_enterprise_fee_owners", params: base_params
|
||||
|
||||
expect(response).to have_http_status(:ok)
|
||||
json_response = response.parsed_body
|
||||
|
||||
expect(json_response["results"].pluck("label")).to eq(['Alpha Market', 'Zebra Farm'])
|
||||
expect(json_response["pagination"]["more"]).to be false
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /admin/reports/search_order_customers" do
|
||||
let!(:customer1) { create(:customer, email: "alice@example.com", enterprise: distributor1) }
|
||||
let!(:customer2) { create(:customer, email: "bob@example.com", enterprise: distributor1) }
|
||||
|
||||
before do
|
||||
orderA1.update!(customer: customer1)
|
||||
orderA2.update!(customer: customer2)
|
||||
end
|
||||
|
||||
it "returns all customers sorted by email" do
|
||||
get "/admin/reports/search_order_customers", params: base_params
|
||||
|
||||
json_response = response.parsed_body
|
||||
expect(json_response["results"].pluck("label")).to eq(["alice@example.com",
|
||||
"bob@example.com"])
|
||||
expect(json_response["pagination"]["more"]).to be false
|
||||
end
|
||||
|
||||
it "filters customers by email query" do
|
||||
get "/admin/reports/search_order_customers", params: base_params.merge(q: "alice")
|
||||
|
||||
json_response = response.parsed_body
|
||||
expect(json_response["results"].pluck("label")).to eq(["alice@example.com"])
|
||||
expect(json_response["pagination"]["more"]).to be false
|
||||
end
|
||||
|
||||
context "with more than 30 customers" do
|
||||
before do
|
||||
create_list(:customer, 35, enterprise: distributor1) do |customer, i|
|
||||
customer.update!(email: "customer#{(i + 1).to_s.rjust(2, '0')}@example.com")
|
||||
order = create(:order, distributor: distributor1, order_cycle: ocA, customer:)
|
||||
order.line_items << create(:line_item, variant: product1.variants.first)
|
||||
order.finalize!
|
||||
end
|
||||
end
|
||||
|
||||
it "returns first page with 30 results and more flag as true" do
|
||||
get "/admin/reports/search_order_customers", params: base_params.merge(page: 1)
|
||||
|
||||
json_response = response.parsed_body
|
||||
expect(json_response["results"].length).to eq(30)
|
||||
expect(json_response["pagination"]["more"]).to be true
|
||||
end
|
||||
|
||||
it "returns remaining results on second page with more flag as false" do
|
||||
get "/admin/reports/search_order_customers", params: base_params.merge(page: 2)
|
||||
|
||||
json_response = response.parsed_body
|
||||
expect(json_response["results"].length).to eq(7)
|
||||
expect(json_response["pagination"]["more"]).to be false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /admin/reports/search_order_cycles" do
|
||||
before do
|
||||
ocA.update!(name: "Winter Market")
|
||||
ocB.update!(name: "Summer Market")
|
||||
end
|
||||
|
||||
it "returns order cycles sorted by close date" do
|
||||
get "/admin/reports/search_order_cycles", params: base_params
|
||||
|
||||
json_response = response.parsed_body
|
||||
expect(json_response["results"].pluck("label")).to eq(["Summer Market", "Winter Market"])
|
||||
expect(json_response["pagination"]["more"]).to be false
|
||||
end
|
||||
|
||||
it "filters order cycles by name query" do
|
||||
get "/admin/reports/search_order_cycles", params: base_params.merge(q: "Winter")
|
||||
|
||||
json_response = response.parsed_body
|
||||
expect(json_response["results"].pluck("label")).to eq(["Winter Market"])
|
||||
expect(json_response["pagination"]["more"]).to be false
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /admin/reports/search_distributors" do
|
||||
before do
|
||||
distributor1.update!(name: "Alpha Farm")
|
||||
distributor2.update!(name: "Beta Market")
|
||||
end
|
||||
|
||||
it "filters distributors by name query" do
|
||||
get "/admin/reports/search_distributors", params: base_params.merge(q: "Alpha")
|
||||
|
||||
json_response = response.parsed_body
|
||||
expect(json_response["results"].pluck("label")).to eq(["Alpha Farm"])
|
||||
expect(json_response["pagination"]["more"]).to be false
|
||||
end
|
||||
|
||||
context "with more than 30 distributors" do
|
||||
before { create_list(:distributor_enterprise, 35) }
|
||||
|
||||
it "returns first page with 30 results and more flag as true" do
|
||||
get "/admin/reports/search_distributors", params: base_params.merge(page: 1)
|
||||
|
||||
json_response = response.parsed_body
|
||||
expect(json_response["results"].length).to eq(30)
|
||||
expect(json_response["pagination"]["more"]).to be true
|
||||
end
|
||||
|
||||
it "returns remaining results on subsequent pages with more flag as false" do
|
||||
get "/admin/reports/search_distributors", params: base_params.merge(page: 2)
|
||||
|
||||
json_response = response.parsed_body
|
||||
expect(json_response["results"].length).to be > 0
|
||||
expect(json_response["pagination"]["more"]).to be false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when user is not an admin" do
|
||||
before do
|
||||
login_as distributor1.users.first
|
||||
create_adjustment(orderA1, enterprise_fee1, 5.0)
|
||||
create_adjustment(orderA2, enterprise_fee2, 3.0)
|
||||
end
|
||||
|
||||
describe "GET /admin/reports/search_enterprise_fees" do
|
||||
it "returns only enterprise fees for user's managed enterprises" do
|
||||
get "/admin/reports/search_enterprise_fees", params: base_params
|
||||
|
||||
expect(response).to have_http_status(:ok)
|
||||
json_response = response.parsed_body
|
||||
|
||||
expect(json_response["results"].pluck("label")).to eq(['Delivery Fee'])
|
||||
expect(json_response["pagination"]["more"]).to be false
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /admin/reports/search_enterprise_fee_owners" do
|
||||
it "returns only enterprise fee owners for user's managed enterprises" do
|
||||
get "/admin/reports/search_enterprise_fee_owners", params: base_params
|
||||
|
||||
expect(response).to have_http_status(:ok)
|
||||
json_response = response.parsed_body
|
||||
|
||||
expect(json_response["results"].pluck("label")).to eq([distributor1.name])
|
||||
expect(json_response["pagination"]["more"]).to be false
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /admin/reports/search_order_customers" do
|
||||
it "returns only customers from user's managed enterprises" do
|
||||
customer1 = create(:customer, email: "alice@example.com", enterprise: distributor1)
|
||||
customer2 = create(:customer, email: "bob@example.com", enterprise: distributor1)
|
||||
orderA1.update!(customer: customer1)
|
||||
orderA2.update!(customer: customer2)
|
||||
|
||||
get "/admin/reports/search_order_customers", params: base_params
|
||||
|
||||
json_response = response.parsed_body
|
||||
expect(json_response["results"].pluck("label")).to eq(["alice@example.com"])
|
||||
expect(json_response["pagination"]["more"]).to be false
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /admin/reports/search_order_cycles" do
|
||||
it "returns only order cycles accessible to user's managed enterprises" do
|
||||
ocA.update!(name: "Winter Market")
|
||||
ocB.update!(name: "Summer Market")
|
||||
create(:simple_order_cycle, name: 'Autumn Market', coordinator: coordinator1,
|
||||
distributors: [distributor2],
|
||||
suppliers: [supplier1, supplier2, supplier3],
|
||||
variants: [product2.variants.first])
|
||||
|
||||
get "/admin/reports/search_order_cycles", params: base_params
|
||||
|
||||
json_response = response.parsed_body
|
||||
expect(json_response["results"].pluck("label")).to eq(["Summer Market", "Winter Market"])
|
||||
expect(json_response["pagination"]["more"]).to be false
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /admin/reports/search_distributors" do
|
||||
it "returns only user's managed distributors" do
|
||||
get "/admin/reports/search_distributors", params: base_params
|
||||
|
||||
json_response = response.parsed_body
|
||||
expect(json_response["results"].pluck("label")).to eq([distributor1.name])
|
||||
expect(json_response["pagination"]["more"]).to be false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -38,8 +38,8 @@ RSpec.shared_examples "attribute changes - tax total changes" do |boolean, type,
|
||||
create(:order_with_taxes, product_price: 110, tax_rate_amount: 0.1,
|
||||
included_in_price: included_boolean)
|
||||
.tap do |order|
|
||||
order.create_tax_charge!
|
||||
order.update_shipping_fees!
|
||||
order.create_tax_charge!
|
||||
order.update_shipping_fees!
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -92,9 +92,7 @@ RSpec::Matchers.define :have_select2 do |id, options = {}|
|
||||
end
|
||||
|
||||
def selected_option_is(from, text)
|
||||
within find(from) do
|
||||
find("a.select2-choice").text == text
|
||||
end
|
||||
find("#{from} a.select2-choice", text:)
|
||||
end
|
||||
|
||||
def with_select2_open(from)
|
||||
|
||||
@@ -144,7 +144,7 @@ module StripeStubs
|
||||
customer_id = options[:customer_id] || "cus_A123"
|
||||
{ status: 200,
|
||||
body: JSON.generate(id: customer_id,
|
||||
sources: { data: [id: customer_id] }) }
|
||||
sources: { data: [{ id: customer_id }] }) }
|
||||
end
|
||||
|
||||
def payment_successful_refund_mock
|
||||
|
||||
@@ -69,8 +69,6 @@ module WebHelper
|
||||
.find(:css, '.select2-drop-active .select2-result-label',
|
||||
text: options[:select_text] || value)
|
||||
.click
|
||||
|
||||
expect(page).to have_select2 options[:from], selected: options[:select_text] || value
|
||||
end
|
||||
|
||||
def open_select2(selector)
|
||||
|
||||
@@ -152,7 +152,7 @@ RSpec.describe '
|
||||
click_link 'Adjustments'
|
||||
page.find('tr', text: 'Extra Adjustment').find('a.icon-edit').click
|
||||
|
||||
expect(page).to have_select2 :adjustment_tax_category_id, selected: []
|
||||
expect(page).to have_select2 :adjustment_tax_category_id, selected: "None"
|
||||
|
||||
# When I edit the adjustment, setting a tax rate
|
||||
select2_select 'GST', from: :adjustment_tax_category_id
|
||||
|
||||
@@ -1044,10 +1044,10 @@ RSpec.describe '
|
||||
page.driver
|
||||
.dismiss_modal :confirm,
|
||||
text: "Unsaved changes exist and will be lost if you continue." do
|
||||
within "tr#li_#{li1.id}" do
|
||||
fill_in "quantity", with: (li1.quantity + 1)
|
||||
find("a.edit-order").click
|
||||
end
|
||||
within "tr#li_#{li1.id}" do
|
||||
fill_in "quantity", with: (li1.quantity + 1)
|
||||
find("a.edit-order").click
|
||||
end
|
||||
end
|
||||
|
||||
# So we save the changes
|
||||
|
||||
@@ -20,7 +20,11 @@ RSpec.describe '
|
||||
click_link 'Payment Methods'
|
||||
click_link 'New Payment Method'
|
||||
|
||||
expect(page).to have_select2 "payment_method_type", selected: "Choose..."
|
||||
|
||||
fill_in 'payment_method_name', with: 'Cheque payment method'
|
||||
cash_name = "Cash/EFT/etc. (payments for which automatic validation is not required)"
|
||||
select2_select cash_name, from: "payment_method_type"
|
||||
|
||||
check "payment_method_distributor_ids_#{@distributors[0].id}"
|
||||
click_button 'Create'
|
||||
@@ -243,6 +247,9 @@ RSpec.describe '
|
||||
it "creates payment methods" do
|
||||
visit spree.new_admin_payment_method_path
|
||||
fill_in 'payment_method_name', with: 'Cheque payment method'
|
||||
cash_name = "Cash/EFT/etc. (payments for which automatic validation is not required)"
|
||||
select2_select cash_name, from: "payment_method_type"
|
||||
|
||||
expect(page).to have_field 'payment_method_description'
|
||||
expect(page).to have_select 'payment_method_display_on'
|
||||
|
||||
|
||||
@@ -296,11 +296,8 @@ RSpec.describe "Enterprise Summary Fee with Tax Report By Producer" do
|
||||
end
|
||||
|
||||
it "should filter by distributor and order cycle" do
|
||||
page.find("#s2id_autogen1").click
|
||||
find('li', text: distributor.name).click # selects Distributor
|
||||
|
||||
page.find("#s2id_q_order_cycle_id_in").click
|
||||
find('li', text: order_cycle.name).click
|
||||
tomselect_multiselect distributor.name, from: 'q[distributor_id_in][]'
|
||||
tomselect_multiselect order_cycle.name, from: 'q[order_cycle_id_in][]'
|
||||
|
||||
run_report
|
||||
expect(page.find("table.report__table thead tr")).to have_content(table_header)
|
||||
@@ -455,9 +452,6 @@ RSpec.describe "Enterprise Summary Fee with Tax Report By Producer" do
|
||||
}
|
||||
|
||||
context "filtering" do
|
||||
let(:fee_name_selector){ "#s2id_q_enterprise_fee_id_in" }
|
||||
let(:fee_owner_selector){ "#s2id_q_enterprise_fee_owner_id_in" }
|
||||
|
||||
let(:summary_row_after_filtering_by_fee_name){
|
||||
[cost_of_produce1, "TOTAL", "120.0", "4.8", "124.8"].join(" ")
|
||||
}
|
||||
@@ -471,11 +465,8 @@ RSpec.describe "Enterprise Summary Fee with Tax Report By Producer" do
|
||||
end
|
||||
|
||||
it "should filter by distributor and order cycle" do
|
||||
page.find("#s2id_autogen1").click
|
||||
find('li', text: distributor.name).click # selects Distributor
|
||||
|
||||
page.find("#s2id_q_order_cycle_id_in").click
|
||||
find('li', text: order_cycle3.name).click
|
||||
tomselect_multiselect distributor.name, from: 'q[distributor_id_in][]'
|
||||
tomselect_multiselect order_cycle3.name, from: 'q[order_cycle_id_in][]'
|
||||
|
||||
run_report
|
||||
expect(page.find("table.report__table thead tr")).to have_content(table_header)
|
||||
@@ -504,8 +495,7 @@ RSpec.describe "Enterprise Summary Fee with Tax Report By Producer" do
|
||||
end
|
||||
|
||||
it "should filter by producer" do
|
||||
page.find("#s2id_supplier_id_in").click
|
||||
find('li', text: supplier2.name).click
|
||||
tomselect_multiselect supplier2.name, from: 'supplier_id_in[]'
|
||||
|
||||
run_report
|
||||
expect(page.find("table.report__table thead tr")).to have_content(table_header)
|
||||
@@ -528,8 +518,7 @@ RSpec.describe "Enterprise Summary Fee with Tax Report By Producer" do
|
||||
end
|
||||
|
||||
it "should filter by fee name" do
|
||||
page.find(fee_name_selector).click
|
||||
find('li', text: supplier_fees.name).click
|
||||
tomselect_multiselect supplier_fees.name, from: 'q[enterprise_fee_id_in][]'
|
||||
|
||||
run_report
|
||||
|
||||
@@ -557,8 +546,7 @@ RSpec.describe "Enterprise Summary Fee with Tax Report By Producer" do
|
||||
end
|
||||
|
||||
it "should filter by fee owner" do
|
||||
page.find(fee_owner_selector).click
|
||||
find('li', text: supplier.name).click
|
||||
tomselect_multiselect supplier.name, from: 'q[enterprise_fee_owner_id_in][]'
|
||||
|
||||
run_report
|
||||
expect(page.find("table.report__table thead tr")).to have_content(table_header)
|
||||
|
||||
@@ -360,10 +360,10 @@ RSpec.describe "As a consumer, I want to checkout my order" do
|
||||
# And fake the payment status to avoid user interaction.
|
||||
allow_any_instance_of(Taler::Client)
|
||||
.to receive(:fetch_order) do
|
||||
payment = Spree::Payment.last
|
||||
url = payment_gateways_confirm_taler_path(payment_id: payment.id)
|
||||
payment = Spree::Payment.last
|
||||
url = payment_gateways_confirm_taler_path(payment_id: payment.id)
|
||||
|
||||
{ "order_status_url" => url, "order_status" => "paid" }
|
||||
{ "order_status_url" => url, "order_status" => "paid" }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
302
yarn.lock
302
yarn.lock
@@ -13,34 +13,34 @@
|
||||
"@csstools/css-tokenizer" "^3.0.3"
|
||||
lru-cache "^10.4.3"
|
||||
|
||||
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.27.1", "@babel/code-frame@^7.28.6":
|
||||
version "7.28.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.28.6.tgz#72499312ec58b1e2245ba4a4f550c132be4982f7"
|
||||
integrity sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==
|
||||
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.27.1", "@babel/code-frame@^7.28.6", "@babel/code-frame@^7.29.0":
|
||||
version "7.29.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.29.0.tgz#7cd7a59f15b3cc0dcd803038f7792712a7d0b15c"
|
||||
integrity sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==
|
||||
dependencies:
|
||||
"@babel/helper-validator-identifier" "^7.28.5"
|
||||
js-tokens "^4.0.0"
|
||||
picocolors "^1.1.1"
|
||||
|
||||
"@babel/compat-data@^7.27.7", "@babel/compat-data@^7.28.6":
|
||||
version "7.28.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.28.6.tgz#103f466803fa0f059e82ccac271475470570d74c"
|
||||
integrity sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg==
|
||||
"@babel/compat-data@^7.28.6", "@babel/compat-data@^7.29.0":
|
||||
version "7.29.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.29.0.tgz#00d03e8c0ac24dd9be942c5370990cbe1f17d88d"
|
||||
integrity sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==
|
||||
|
||||
"@babel/core@^7.23.9", "@babel/core@^7.27.4", "@babel/core@^7.28.5":
|
||||
version "7.28.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.28.6.tgz#531bf883a1126e53501ba46eb3bb414047af507f"
|
||||
integrity sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==
|
||||
version "7.29.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.29.0.tgz#5286ad785df7f79d656e88ce86e650d16ca5f322"
|
||||
integrity sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.28.6"
|
||||
"@babel/generator" "^7.28.6"
|
||||
"@babel/code-frame" "^7.29.0"
|
||||
"@babel/generator" "^7.29.0"
|
||||
"@babel/helper-compilation-targets" "^7.28.6"
|
||||
"@babel/helper-module-transforms" "^7.28.6"
|
||||
"@babel/helpers" "^7.28.6"
|
||||
"@babel/parser" "^7.28.6"
|
||||
"@babel/parser" "^7.29.0"
|
||||
"@babel/template" "^7.28.6"
|
||||
"@babel/traverse" "^7.28.6"
|
||||
"@babel/types" "^7.28.6"
|
||||
"@babel/traverse" "^7.29.0"
|
||||
"@babel/types" "^7.29.0"
|
||||
"@jridgewell/remapping" "^2.3.5"
|
||||
convert-source-map "^2.0.0"
|
||||
debug "^4.1.0"
|
||||
@@ -48,13 +48,13 @@
|
||||
json5 "^2.2.3"
|
||||
semver "^6.3.1"
|
||||
|
||||
"@babel/generator@^7.27.5", "@babel/generator@^7.28.6":
|
||||
version "7.28.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.28.6.tgz#48dcc65d98fcc8626a48f72b62e263d25fc3c3f1"
|
||||
integrity sha512-lOoVRwADj8hjf7al89tvQ2a1lf53Z+7tiXMgpZJL3maQPDxh0DgLMN62B2MKUOFcoodBHLMbDM6WAbKgNy5Suw==
|
||||
"@babel/generator@^7.27.5", "@babel/generator@^7.29.0":
|
||||
version "7.29.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.29.1.tgz#d09876290111abbb00ef962a7b83a5307fba0d50"
|
||||
integrity sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==
|
||||
dependencies:
|
||||
"@babel/parser" "^7.28.6"
|
||||
"@babel/types" "^7.28.6"
|
||||
"@babel/parser" "^7.29.0"
|
||||
"@babel/types" "^7.29.0"
|
||||
"@jridgewell/gen-mapping" "^0.3.12"
|
||||
"@jridgewell/trace-mapping" "^0.3.28"
|
||||
jsesc "^3.0.2"
|
||||
@@ -110,6 +110,17 @@
|
||||
lodash.debounce "^4.0.8"
|
||||
resolve "^1.22.10"
|
||||
|
||||
"@babel/helper-define-polyfill-provider@^0.6.6":
|
||||
version "0.6.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.6.tgz#714dfe33d8bd710f556df59953720f6eeb6c1a14"
|
||||
integrity sha512-mOAsxeeKkUKayvZR3HeTYD/fICpCPLJrU5ZjelT/PA6WHtNDBOE436YiaEUvHN454bRM3CebhDsIpieCc4texA==
|
||||
dependencies:
|
||||
"@babel/helper-compilation-targets" "^7.28.6"
|
||||
"@babel/helper-plugin-utils" "^7.28.6"
|
||||
debug "^4.4.3"
|
||||
lodash.debounce "^4.0.8"
|
||||
resolve "^1.22.11"
|
||||
|
||||
"@babel/helper-globals@^7.28.0":
|
||||
version "7.28.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-globals/-/helper-globals-7.28.0.tgz#b9430df2aa4e17bc28665eadeae8aa1d985e6674"
|
||||
@@ -123,7 +134,7 @@
|
||||
"@babel/traverse" "^7.28.5"
|
||||
"@babel/types" "^7.28.5"
|
||||
|
||||
"@babel/helper-module-imports@^7.27.1", "@babel/helper-module-imports@^7.28.6":
|
||||
"@babel/helper-module-imports@^7.28.6":
|
||||
version "7.28.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz#60632cbd6ffb70b22823187201116762a03e2d5c"
|
||||
integrity sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==
|
||||
@@ -131,7 +142,7 @@
|
||||
"@babel/traverse" "^7.28.6"
|
||||
"@babel/types" "^7.28.6"
|
||||
|
||||
"@babel/helper-module-transforms@^7.27.1", "@babel/helper-module-transforms@^7.28.3", "@babel/helper-module-transforms@^7.28.6":
|
||||
"@babel/helper-module-transforms@^7.27.1", "@babel/helper-module-transforms@^7.28.6":
|
||||
version "7.28.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz#9312d9d9e56edc35aeb6e95c25d4106b50b9eb1e"
|
||||
integrity sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==
|
||||
@@ -147,21 +158,11 @@
|
||||
dependencies:
|
||||
"@babel/types" "^7.27.1"
|
||||
|
||||
"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.27.1", "@babel/helper-plugin-utils@^7.28.6":
|
||||
"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.27.1", "@babel/helper-plugin-utils@^7.28.6", "@babel/helper-plugin-utils@^7.8.0":
|
||||
version "7.28.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz#6f13ea251b68c8532e985fd532f28741a8af9ac8"
|
||||
integrity sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==
|
||||
|
||||
"@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.8.0":
|
||||
version "7.27.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz#ddb2f876534ff8013e6c2b299bf4d39b3c51d44c"
|
||||
integrity sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==
|
||||
|
||||
"@babel/helper-plugin-utils@^7.14.5":
|
||||
version "7.21.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.21.5.tgz#345f2377d05a720a4e5ecfa39cbf4474a4daed56"
|
||||
integrity sha512-0WDaIlXKOX/3KfBK/dwP1oQGiPh6rjMkT7HIRv7i5RR2VUMwrx5ZL0dwBkKx7+SW1zwNdgjHd34IMk5ZjTeHVg==
|
||||
|
||||
"@babel/helper-remap-async-to-generator@^7.27.1":
|
||||
version "7.27.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz#4601d5c7ce2eb2aea58328d43725523fcd362ce6"
|
||||
@@ -220,12 +221,12 @@
|
||||
"@babel/template" "^7.28.6"
|
||||
"@babel/types" "^7.28.6"
|
||||
|
||||
"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.28.6":
|
||||
version "7.28.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.6.tgz#f01a8885b7fa1e56dd8a155130226cd698ef13fd"
|
||||
integrity sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==
|
||||
"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.28.6", "@babel/parser@^7.29.0":
|
||||
version "7.29.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.0.tgz#669ef345add7d057e92b7ed15f0bac07611831b6"
|
||||
integrity sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==
|
||||
dependencies:
|
||||
"@babel/types" "^7.28.6"
|
||||
"@babel/types" "^7.29.0"
|
||||
|
||||
"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.28.5":
|
||||
version "7.28.5"
|
||||
@@ -306,14 +307,7 @@
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.28.6"
|
||||
|
||||
"@babel/plugin-syntax-import-attributes@^7.24.7":
|
||||
version "7.27.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz#34c017d54496f9b11b61474e7ea3dfd5563ffe07"
|
||||
integrity sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.27.1"
|
||||
|
||||
"@babel/plugin-syntax-import-attributes@^7.28.6":
|
||||
"@babel/plugin-syntax-import-attributes@^7.24.7", "@babel/plugin-syntax-import-attributes@^7.28.6":
|
||||
version "7.28.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz#b71d5914665f60124e133696f17cd7669062c503"
|
||||
integrity sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==
|
||||
@@ -419,14 +413,14 @@
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.27.1"
|
||||
|
||||
"@babel/plugin-transform-async-generator-functions@^7.28.6":
|
||||
version "7.28.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.6.tgz#80cb86d3eaa2102e18ae90dd05ab87bdcad3877d"
|
||||
integrity sha512-9knsChgsMzBV5Yh3kkhrZNxH3oCYAfMBkNNaVN4cP2RVlFPe8wYdwwcnOsAbkdDoV9UjFtOXWrWB52M8W4jNeA==
|
||||
"@babel/plugin-transform-async-generator-functions@^7.29.0":
|
||||
version "7.29.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.29.0.tgz#63ed829820298f0bf143d5a4a68fb8c06ffd742f"
|
||||
integrity sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.28.6"
|
||||
"@babel/helper-remap-async-to-generator" "^7.27.1"
|
||||
"@babel/traverse" "^7.28.6"
|
||||
"@babel/traverse" "^7.29.0"
|
||||
|
||||
"@babel/plugin-transform-async-to-generator@^7.28.6":
|
||||
version "7.28.6"
|
||||
@@ -510,10 +504,10 @@
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.27.1"
|
||||
|
||||
"@babel/plugin-transform-duplicate-named-capturing-groups-regex@^7.28.6":
|
||||
version "7.28.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.28.6.tgz#e0c59ba54f1655dd682f2edf5f101b5910a8f6f3"
|
||||
integrity sha512-5suVoXjC14lUN6ZL9OLKIHCNVWCrqGqlmEp/ixdXjvgnEl/kauLvvMO/Xw9NyMc95Joj1AeLVPVMvibBgSoFlA==
|
||||
"@babel/plugin-transform-duplicate-named-capturing-groups-regex@^7.29.0":
|
||||
version "7.29.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.29.0.tgz#8014b8a6cfd0e7b92762724443bf0d2400f26df1"
|
||||
integrity sha512-zBPcW2lFGxdiD8PUnPwJjag2J9otbcLQzvbiOzDxpYXyCuYX9agOwMPGn1prVH0a4qzhCKu24rlH4c1f7yA8rw==
|
||||
dependencies:
|
||||
"@babel/helper-create-regexp-features-plugin" "^7.28.5"
|
||||
"@babel/helper-plugin-utils" "^7.28.6"
|
||||
@@ -608,15 +602,15 @@
|
||||
"@babel/helper-module-transforms" "^7.28.6"
|
||||
"@babel/helper-plugin-utils" "^7.28.6"
|
||||
|
||||
"@babel/plugin-transform-modules-systemjs@^7.28.5":
|
||||
version "7.28.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.28.5.tgz#7439e592a92d7670dfcb95d0cbc04bd3e64801d2"
|
||||
integrity sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==
|
||||
"@babel/plugin-transform-modules-systemjs@^7.29.0":
|
||||
version "7.29.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.0.tgz#e458a95a17807c415924106a3ff188a3b8dee964"
|
||||
integrity sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ==
|
||||
dependencies:
|
||||
"@babel/helper-module-transforms" "^7.28.3"
|
||||
"@babel/helper-plugin-utils" "^7.27.1"
|
||||
"@babel/helper-module-transforms" "^7.28.6"
|
||||
"@babel/helper-plugin-utils" "^7.28.6"
|
||||
"@babel/helper-validator-identifier" "^7.28.5"
|
||||
"@babel/traverse" "^7.28.5"
|
||||
"@babel/traverse" "^7.29.0"
|
||||
|
||||
"@babel/plugin-transform-modules-umd@^7.27.1":
|
||||
version "7.27.1"
|
||||
@@ -626,13 +620,13 @@
|
||||
"@babel/helper-module-transforms" "^7.27.1"
|
||||
"@babel/helper-plugin-utils" "^7.27.1"
|
||||
|
||||
"@babel/plugin-transform-named-capturing-groups-regex@^7.27.1":
|
||||
version "7.27.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz#f32b8f7818d8fc0cc46ee20a8ef75f071af976e1"
|
||||
integrity sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==
|
||||
"@babel/plugin-transform-named-capturing-groups-regex@^7.29.0":
|
||||
version "7.29.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.29.0.tgz#a26cd51e09c4718588fc4cce1c5d1c0152102d6a"
|
||||
integrity sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==
|
||||
dependencies:
|
||||
"@babel/helper-create-regexp-features-plugin" "^7.27.1"
|
||||
"@babel/helper-plugin-utils" "^7.27.1"
|
||||
"@babel/helper-create-regexp-features-plugin" "^7.28.5"
|
||||
"@babel/helper-plugin-utils" "^7.28.6"
|
||||
|
||||
"@babel/plugin-transform-new-target@^7.27.1":
|
||||
version "7.27.1"
|
||||
@@ -720,10 +714,10 @@
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.27.1"
|
||||
|
||||
"@babel/plugin-transform-regenerator@^7.28.6":
|
||||
version "7.28.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.6.tgz#6ca2ed5b76cff87980f96eaacfc2ce833e8e7a1b"
|
||||
integrity sha512-eZhoEZHYQLL5uc1gS5e9/oTknS0sSSAtd5TkKMUp3J+S/CaUjagc0kOUPsEbDmMeva0nC3WWl4SxVY6+OBuxfw==
|
||||
"@babel/plugin-transform-regenerator@^7.29.0":
|
||||
version "7.29.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.29.0.tgz#dec237cec1b93330876d6da9992c4abd42c9d18b"
|
||||
integrity sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.28.6"
|
||||
|
||||
@@ -743,12 +737,12 @@
|
||||
"@babel/helper-plugin-utils" "^7.27.1"
|
||||
|
||||
"@babel/plugin-transform-runtime@^7.28.5":
|
||||
version "7.28.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.28.5.tgz#ae3e21fbefe2831ebac04dfa6b463691696afe17"
|
||||
integrity sha512-20NUVgOrinudkIBzQ2bNxP08YpKprUkRTiRSd2/Z5GOdPImJGkoN4Z7IQe1T5AdyKI1i5L6RBmluqdSzvaq9/w==
|
||||
version "7.29.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.29.0.tgz#a5fded13cc656700804bfd6e5ebd7fffd5266803"
|
||||
integrity sha512-jlaRT5dJtMaMCV6fAuLbsQMSwz/QkvaHOHOSXRitGGwSpR1blCY4KUKoyP2tYO8vJcqYe8cEj96cqSztv3uF9w==
|
||||
dependencies:
|
||||
"@babel/helper-module-imports" "^7.27.1"
|
||||
"@babel/helper-plugin-utils" "^7.27.1"
|
||||
"@babel/helper-module-imports" "^7.28.6"
|
||||
"@babel/helper-plugin-utils" "^7.28.6"
|
||||
babel-plugin-polyfill-corejs2 "^0.4.14"
|
||||
babel-plugin-polyfill-corejs3 "^0.13.0"
|
||||
babel-plugin-polyfill-regenerator "^0.6.5"
|
||||
@@ -822,11 +816,11 @@
|
||||
"@babel/helper-plugin-utils" "^7.28.6"
|
||||
|
||||
"@babel/preset-env@^7.28.5":
|
||||
version "7.28.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.28.6.tgz#b4586bb59d8c61be6c58997f4912e7ea6bd17178"
|
||||
integrity sha512-GaTI4nXDrs7l0qaJ6Rg06dtOXTBCG6TMDB44zbqofCIC4PqC7SEvmFFtpxzCDw9W5aJ7RKVshgXTLvLdBFV/qw==
|
||||
version "7.29.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.29.0.tgz#c55db400c515a303662faaefd2d87e796efa08d0"
|
||||
integrity sha512-fNEdfc0yi16lt6IZo2Qxk3knHVdfMYX33czNb4v8yWhemoBhibCpQK/uYHtSKIiO+p/zd3+8fYVXhQdOVV608w==
|
||||
dependencies:
|
||||
"@babel/compat-data" "^7.28.6"
|
||||
"@babel/compat-data" "^7.29.0"
|
||||
"@babel/helper-compilation-targets" "^7.28.6"
|
||||
"@babel/helper-plugin-utils" "^7.28.6"
|
||||
"@babel/helper-validator-option" "^7.27.1"
|
||||
@@ -840,7 +834,7 @@
|
||||
"@babel/plugin-syntax-import-attributes" "^7.28.6"
|
||||
"@babel/plugin-syntax-unicode-sets-regex" "^7.18.6"
|
||||
"@babel/plugin-transform-arrow-functions" "^7.27.1"
|
||||
"@babel/plugin-transform-async-generator-functions" "^7.28.6"
|
||||
"@babel/plugin-transform-async-generator-functions" "^7.29.0"
|
||||
"@babel/plugin-transform-async-to-generator" "^7.28.6"
|
||||
"@babel/plugin-transform-block-scoped-functions" "^7.27.1"
|
||||
"@babel/plugin-transform-block-scoping" "^7.28.6"
|
||||
@@ -851,7 +845,7 @@
|
||||
"@babel/plugin-transform-destructuring" "^7.28.5"
|
||||
"@babel/plugin-transform-dotall-regex" "^7.28.6"
|
||||
"@babel/plugin-transform-duplicate-keys" "^7.27.1"
|
||||
"@babel/plugin-transform-duplicate-named-capturing-groups-regex" "^7.28.6"
|
||||
"@babel/plugin-transform-duplicate-named-capturing-groups-regex" "^7.29.0"
|
||||
"@babel/plugin-transform-dynamic-import" "^7.27.1"
|
||||
"@babel/plugin-transform-explicit-resource-management" "^7.28.6"
|
||||
"@babel/plugin-transform-exponentiation-operator" "^7.28.6"
|
||||
@@ -864,9 +858,9 @@
|
||||
"@babel/plugin-transform-member-expression-literals" "^7.27.1"
|
||||
"@babel/plugin-transform-modules-amd" "^7.27.1"
|
||||
"@babel/plugin-transform-modules-commonjs" "^7.28.6"
|
||||
"@babel/plugin-transform-modules-systemjs" "^7.28.5"
|
||||
"@babel/plugin-transform-modules-systemjs" "^7.29.0"
|
||||
"@babel/plugin-transform-modules-umd" "^7.27.1"
|
||||
"@babel/plugin-transform-named-capturing-groups-regex" "^7.27.1"
|
||||
"@babel/plugin-transform-named-capturing-groups-regex" "^7.29.0"
|
||||
"@babel/plugin-transform-new-target" "^7.27.1"
|
||||
"@babel/plugin-transform-nullish-coalescing-operator" "^7.28.6"
|
||||
"@babel/plugin-transform-numeric-separator" "^7.28.6"
|
||||
@@ -878,7 +872,7 @@
|
||||
"@babel/plugin-transform-private-methods" "^7.28.6"
|
||||
"@babel/plugin-transform-private-property-in-object" "^7.28.6"
|
||||
"@babel/plugin-transform-property-literals" "^7.27.1"
|
||||
"@babel/plugin-transform-regenerator" "^7.28.6"
|
||||
"@babel/plugin-transform-regenerator" "^7.29.0"
|
||||
"@babel/plugin-transform-regexp-modifiers" "^7.28.6"
|
||||
"@babel/plugin-transform-reserved-words" "^7.27.1"
|
||||
"@babel/plugin-transform-shorthand-properties" "^7.27.1"
|
||||
@@ -891,10 +885,10 @@
|
||||
"@babel/plugin-transform-unicode-regex" "^7.27.1"
|
||||
"@babel/plugin-transform-unicode-sets-regex" "^7.28.6"
|
||||
"@babel/preset-modules" "0.1.6-no-external-plugins"
|
||||
babel-plugin-polyfill-corejs2 "^0.4.14"
|
||||
babel-plugin-polyfill-corejs3 "^0.13.0"
|
||||
babel-plugin-polyfill-regenerator "^0.6.5"
|
||||
core-js-compat "^3.43.0"
|
||||
babel-plugin-polyfill-corejs2 "^0.4.15"
|
||||
babel-plugin-polyfill-corejs3 "^0.14.0"
|
||||
babel-plugin-polyfill-regenerator "^0.6.6"
|
||||
core-js-compat "^3.48.0"
|
||||
semver "^6.3.1"
|
||||
|
||||
"@babel/preset-modules@0.1.6-no-external-plugins":
|
||||
@@ -925,23 +919,23 @@
|
||||
"@babel/parser" "^7.28.6"
|
||||
"@babel/types" "^7.28.6"
|
||||
|
||||
"@babel/traverse@^7.27.1", "@babel/traverse@^7.28.5", "@babel/traverse@^7.28.6":
|
||||
version "7.28.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.28.6.tgz#871ddc79a80599a5030c53b1cc48cbe3a5583c2e"
|
||||
integrity sha512-fgWX62k02qtjqdSNTAGxmKYY/7FSL9WAS1o2Hu5+I5m9T0yxZzr4cnrfXQ/MX0rIifthCSs6FKTlzYbJcPtMNg==
|
||||
"@babel/traverse@^7.27.1", "@babel/traverse@^7.28.5", "@babel/traverse@^7.28.6", "@babel/traverse@^7.29.0":
|
||||
version "7.29.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.29.0.tgz#f323d05001440253eead3c9c858adbe00b90310a"
|
||||
integrity sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.28.6"
|
||||
"@babel/generator" "^7.28.6"
|
||||
"@babel/code-frame" "^7.29.0"
|
||||
"@babel/generator" "^7.29.0"
|
||||
"@babel/helper-globals" "^7.28.0"
|
||||
"@babel/parser" "^7.28.6"
|
||||
"@babel/parser" "^7.29.0"
|
||||
"@babel/template" "^7.28.6"
|
||||
"@babel/types" "^7.28.6"
|
||||
"@babel/types" "^7.29.0"
|
||||
debug "^4.3.1"
|
||||
|
||||
"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.28.2", "@babel/types@^7.28.5", "@babel/types@^7.28.6", "@babel/types@^7.4.4":
|
||||
version "7.28.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.6.tgz#c3e9377f1b155005bcc4c46020e7e394e13089df"
|
||||
integrity sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==
|
||||
"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.28.2", "@babel/types@^7.28.5", "@babel/types@^7.28.6", "@babel/types@^7.29.0", "@babel/types@^7.4.4":
|
||||
version "7.29.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.29.0.tgz#9f5b1e838c446e72cf3cd4b918152b8c605e37c7"
|
||||
integrity sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==
|
||||
dependencies:
|
||||
"@babel/helper-string-parser" "^7.27.1"
|
||||
"@babel/helper-validator-identifier" "^7.28.5"
|
||||
@@ -2639,13 +2633,13 @@ babel-plugin-jest-hoist@30.2.0:
|
||||
dependencies:
|
||||
"@types/babel__core" "^7.20.5"
|
||||
|
||||
babel-plugin-polyfill-corejs2@^0.4.14:
|
||||
version "0.4.14"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz#8101b82b769c568835611542488d463395c2ef8f"
|
||||
integrity sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==
|
||||
babel-plugin-polyfill-corejs2@^0.4.14, babel-plugin-polyfill-corejs2@^0.4.15:
|
||||
version "0.4.15"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.15.tgz#808fa349686eea4741807cfaaa2aa3aa57ce120a"
|
||||
integrity sha512-hR3GwrRwHUfYwGfrisXPIDP3JcYfBrW7wKE7+Au6wDYl7fm/ka1NEII6kORzxNU556JjfidZeBsO10kYvtV1aw==
|
||||
dependencies:
|
||||
"@babel/compat-data" "^7.27.7"
|
||||
"@babel/helper-define-polyfill-provider" "^0.6.5"
|
||||
"@babel/compat-data" "^7.28.6"
|
||||
"@babel/helper-define-polyfill-provider" "^0.6.6"
|
||||
semver "^6.3.1"
|
||||
|
||||
babel-plugin-polyfill-corejs3@^0.13.0:
|
||||
@@ -2656,12 +2650,20 @@ babel-plugin-polyfill-corejs3@^0.13.0:
|
||||
"@babel/helper-define-polyfill-provider" "^0.6.5"
|
||||
core-js-compat "^3.43.0"
|
||||
|
||||
babel-plugin-polyfill-regenerator@^0.6.5:
|
||||
version "0.6.5"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz#32752e38ab6f6767b92650347bf26a31b16ae8c5"
|
||||
integrity sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==
|
||||
babel-plugin-polyfill-corejs3@^0.14.0:
|
||||
version "0.14.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.14.0.tgz#65b06cda48d6e447e1e926681f5a247c6ae2b9cf"
|
||||
integrity sha512-AvDcMxJ34W4Wgy4KBIIePQTAOP1Ie2WFwkQp3dB7FQ/f0lI5+nM96zUnYEOE1P9sEg0es5VCP0HxiWu5fUHZAQ==
|
||||
dependencies:
|
||||
"@babel/helper-define-polyfill-provider" "^0.6.5"
|
||||
"@babel/helper-define-polyfill-provider" "^0.6.6"
|
||||
core-js-compat "^3.48.0"
|
||||
|
||||
babel-plugin-polyfill-regenerator@^0.6.5, babel-plugin-polyfill-regenerator@^0.6.6:
|
||||
version "0.6.6"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.6.tgz#69f5dd263cab933c42fe5ea05e83443b374bd4bf"
|
||||
integrity sha512-hYm+XLYRMvupxiQzrvXUj7YyvFFVfv5gI0R71AJzudg1g2AI2vyCPPIFEBjk162/wFzti3inBHo7isWFuEVS/A==
|
||||
dependencies:
|
||||
"@babel/helper-define-polyfill-provider" "^0.6.6"
|
||||
|
||||
babel-preset-current-node-syntax@^1.2.0:
|
||||
version "1.2.0"
|
||||
@@ -2775,7 +2777,7 @@ braces@^3.0.2, braces@^3.0.3, braces@~3.0.2:
|
||||
dependencies:
|
||||
fill-range "^7.1.1"
|
||||
|
||||
browserslist@^4.0.0, browserslist@^4.24.0, browserslist@^4.27.0, browserslist@^4.28.0, browserslist@^4.28.1:
|
||||
browserslist@^4.0.0, browserslist@^4.24.0, browserslist@^4.27.0, browserslist@^4.28.1:
|
||||
version "4.28.1"
|
||||
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.28.1.tgz#7f534594628c53c63101079e27e40de490456a95"
|
||||
integrity sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==
|
||||
@@ -3075,12 +3077,12 @@ cookie@~0.7.1, cookie@~0.7.2:
|
||||
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.2.tgz#556369c472a2ba910f2979891b526b3436237ed7"
|
||||
integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==
|
||||
|
||||
core-js-compat@^3.43.0:
|
||||
version "3.47.0"
|
||||
resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.47.0.tgz#698224bbdbb6f2e3f39decdda4147b161e3772a3"
|
||||
integrity sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ==
|
||||
core-js-compat@^3.43.0, core-js-compat@^3.48.0:
|
||||
version "3.48.0"
|
||||
resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.48.0.tgz#7efbe1fc1cbad44008190462217cc5558adaeaa6"
|
||||
integrity sha512-OM4cAF3D6VtH/WkLtWvyNC56EZVXsZdU3iqaMG2B4WvYrlqU831pc4UtG5yp0sE9z8Y02wVN7PjW5Zf9Gt0f1Q==
|
||||
dependencies:
|
||||
browserslist "^4.28.0"
|
||||
browserslist "^4.28.1"
|
||||
|
||||
core-util-is@~1.0.0:
|
||||
version "1.0.3"
|
||||
@@ -3297,7 +3299,7 @@ debug@2.6.9:
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.4, debug@^4.4.1:
|
||||
debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.4, debug@^4.4.1, debug@^4.4.3:
|
||||
version "4.4.3"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a"
|
||||
integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==
|
||||
@@ -3511,13 +3513,13 @@ engine.io@~6.6.0:
|
||||
engine.io-parser "~5.2.1"
|
||||
ws "~8.17.1"
|
||||
|
||||
enhanced-resolve@^5.17.4:
|
||||
version "5.18.4"
|
||||
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.18.4.tgz#c22d33055f3952035ce6a144ce092447c525f828"
|
||||
integrity sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==
|
||||
enhanced-resolve@^5.19.0:
|
||||
version "5.19.0"
|
||||
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz#6687446a15e969eaa63c2fa2694510e17ae6d97c"
|
||||
integrity sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==
|
||||
dependencies:
|
||||
graceful-fs "^4.2.4"
|
||||
tapable "^2.2.0"
|
||||
tapable "^2.3.0"
|
||||
|
||||
ent@~2.2.0:
|
||||
version "2.2.2"
|
||||
@@ -4003,9 +4005,9 @@ hasown@^2.0.2:
|
||||
function-bind "^1.1.2"
|
||||
|
||||
hotkeys-js@*:
|
||||
version "3.13.15"
|
||||
resolved "https://registry.yarnpkg.com/hotkeys-js/-/hotkeys-js-3.13.15.tgz#2d394bd6bd78857d4b24dc86bdba2fa1cf7012fc"
|
||||
integrity sha512-gHh8a/cPTCpanraePpjRxyIlxDFrIhYqjuh01UHWEwDpglJKCnvLW8kqSx5gQtOuSsJogNZXLhOdbSExpgUiqg==
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/hotkeys-js/-/hotkeys-js-4.0.0.tgz#75336c0ac610ad384d286c61c519909dcd4bdf6b"
|
||||
integrity sha512-gIoeqMWYqPIItc4HaseVbtTRpEpBbeufZMUcoWtN62JZdDq3KadS1ijN6wpaDjTzRK7PjT3QOPUcx+yNT0rrZQ==
|
||||
|
||||
hpack.js@^2.1.6:
|
||||
version "2.1.6"
|
||||
@@ -6078,9 +6080,9 @@ qjobs@^1.2.0:
|
||||
integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==
|
||||
|
||||
qs@~6.14.0:
|
||||
version "6.14.1"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.14.1.tgz#a41d85b9d3902f31d27861790506294881871159"
|
||||
integrity sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==
|
||||
version "6.14.2"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.14.2.tgz#b5634cf9d9ad9898e31fba3504e866e8efb6798c"
|
||||
integrity sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==
|
||||
dependencies:
|
||||
side-channel "^1.1.0"
|
||||
|
||||
@@ -6239,7 +6241,7 @@ resolve-from@^5.0.0:
|
||||
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69"
|
||||
integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==
|
||||
|
||||
resolve@^1.1.7, resolve@^1.22.10, resolve@^1.9.0:
|
||||
resolve@^1.1.7, resolve@^1.22.10, resolve@^1.22.11, resolve@^1.9.0:
|
||||
version "1.22.11"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.11.tgz#aad857ce1ffb8bfa9b0b1ac29f1156383f68c262"
|
||||
integrity sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==
|
||||
@@ -6428,9 +6430,9 @@ sass-embedded@^1.96.0:
|
||||
sass-embedded-win32-x64 "1.97.3"
|
||||
|
||||
sass-loader@^16.0.6:
|
||||
version "16.0.6"
|
||||
resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-16.0.6.tgz#913b05607d06c386bc37870494e1e3a3e091fd3b"
|
||||
integrity sha512-sglGzId5gmlfxNs4gK2U3h7HlVRfx278YK6Ono5lwzuvi1jxig80YiuHkaDBVsYIKFhx8wN7XSCI0M2IDS/3qA==
|
||||
version "16.0.7"
|
||||
resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-16.0.7.tgz#d1f8723b795805831d41b5825e3d9cd72cb939e7"
|
||||
integrity sha512-w6q+fRHourZ+e+xA1kcsF27iGM6jdB8teexYCfdUw0sYgcDNeZESnDNT9sUmmPm3ooziwUJXGwZJSTF3kOdBfA==
|
||||
dependencies:
|
||||
neo-async "^2.6.2"
|
||||
|
||||
@@ -6987,7 +6989,7 @@ synckit@^0.11.8:
|
||||
dependencies:
|
||||
"@pkgr/core" "^0.2.9"
|
||||
|
||||
tapable@^2.2.0, tapable@^2.2.1, tapable@^2.3.0:
|
||||
tapable@^2.2.1, tapable@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.3.0.tgz#7e3ea6d5ca31ba8e078b560f0d83ce9a14aa8be6"
|
||||
integrity sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==
|
||||
@@ -7062,9 +7064,9 @@ toidentifier@1.0.1, toidentifier@~1.0.1:
|
||||
integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==
|
||||
|
||||
tom-select@*:
|
||||
version "2.4.3"
|
||||
resolved "https://registry.yarnpkg.com/tom-select/-/tom-select-2.4.3.tgz#1daa4131cd317de691f39eb5bf41148265986c1f"
|
||||
integrity sha512-MFFrMxP1bpnAMPbdvPCZk0KwYxLqhYZso39torcdoefeV/NThNyDu8dV96/INJ5XQVTL3O55+GqQ78Pkj5oCfw==
|
||||
version "2.5.1"
|
||||
resolved "https://registry.yarnpkg.com/tom-select/-/tom-select-2.5.1.tgz#8c8d3f11e5c1780b5f26c9e90f4e650842ff9596"
|
||||
integrity sha512-63D5/Qf6bb6kLSgksEuas/60oawDcuUHrD90jZofeOpF6bkQFYriKrvtpJBQQ4xIA5dUGcjhBbk/yrlfOQsy3g==
|
||||
dependencies:
|
||||
"@orchidjs/sifter" "^1.1.0"
|
||||
"@orchidjs/unicode-variants" "^1.1.2"
|
||||
@@ -7261,10 +7263,10 @@ walker@^1.0.8:
|
||||
dependencies:
|
||||
makeerror "1.0.12"
|
||||
|
||||
watchpack@^2.4.4:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.5.0.tgz#fa115d5ccaa4bf3aa594f586257c0bc4768939fd"
|
||||
integrity sha512-e6vZvY6xboSwLz2GD36c16+O/2Z6fKvIf4pOXptw2rY9MVwE/TXc6RGqxD3I3x0a28lwBY7DE+76uTPSsBrrCA==
|
||||
watchpack@^2.5.1:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.5.1.tgz#dd38b601f669e0cbf567cb802e75cead82cde102"
|
||||
integrity sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==
|
||||
dependencies:
|
||||
glob-to-regexp "^0.4.1"
|
||||
graceful-fs "^4.1.2"
|
||||
@@ -7374,9 +7376,9 @@ webpack-sources@^3.3.3:
|
||||
integrity sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==
|
||||
|
||||
webpack@^5.104.0:
|
||||
version "5.104.1"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.104.1.tgz#94bd41eb5dbf06e93be165ba8be41b8260d4fb1a"
|
||||
integrity sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA==
|
||||
version "5.105.1"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.105.1.tgz#c05cb3621196c76fa3b3a9bea446d14616b83778"
|
||||
integrity sha512-Gdj3X74CLJJ8zy4URmK42W7wTZUJrqL+z8nyGEr4dTN0kb3nVs+ZvjbTOqRYPD7qX4tUmwyHL9Q9K6T1seW6Yw==
|
||||
dependencies:
|
||||
"@types/eslint-scope" "^3.7.7"
|
||||
"@types/estree" "^1.0.8"
|
||||
@@ -7388,7 +7390,7 @@ webpack@^5.104.0:
|
||||
acorn-import-phases "^1.0.3"
|
||||
browserslist "^4.28.1"
|
||||
chrome-trace-event "^1.0.2"
|
||||
enhanced-resolve "^5.17.4"
|
||||
enhanced-resolve "^5.19.0"
|
||||
es-module-lexer "^2.0.0"
|
||||
eslint-scope "5.1.1"
|
||||
events "^3.2.0"
|
||||
@@ -7401,7 +7403,7 @@ webpack@^5.104.0:
|
||||
schema-utils "^4.3.3"
|
||||
tapable "^2.3.0"
|
||||
terser-webpack-plugin "^5.3.16"
|
||||
watchpack "^2.4.4"
|
||||
watchpack "^2.5.1"
|
||||
webpack-sources "^3.3.3"
|
||||
|
||||
websocket-driver@>=0.5.1, websocket-driver@^0.7.4:
|
||||
|
||||
Reference in New Issue
Block a user