Compare commits

..

1 Commits

Author SHA1 Message Date
Jean-Baptiste Bellet
a8f88ba687 Workaround: bad interaction btw Turbo and stripe iframe
Found this workaround here: https://github.com/hotwired/turbo/issues/270#issuecomment-1068130327

This js hack persists the original iframe object downloaded from stripe in the new body sent by Turbo (instead of using the new one, in the new body)
2023-01-09 10:35:52 +01:00
232 changed files with 2167 additions and 4196 deletions

View File

@@ -2,4 +2,3 @@
.gitignore
log/*
tmp/*
node_modules/

11
.gitattributes vendored
View File

@@ -1,11 +0,0 @@
# Set default behavior to automatically normalize line endings.
* text=auto
# Set line endings to LF, even on Windows. Otherwise, execution within Docker fails.
# See https://docs.github.com/en/get-started/getting-started-with-git/configuring-git-to-handle-line-endings#per-repository-settings
*.sh text eol=lf
# Same thing for following files, but they don't have an sh extension
pre-commit eol=lf
webpack-dev-server eol=lf
install-bundler eol=lf

View File

@@ -23,7 +23,8 @@ assignees: ''
## Finish on Tuesday
- [ ] Publish and notify [#global-community] (this is automatically posted with a plugin)
- [ ] Publish and notify [#global-community]:
> The next release is ready: https://github.com/openfoodfoundation/openfoodnetwork/releases/latest
- [ ] Deploy the new release to all managed instances.
<details><summary>Command line instructions</summary>
<pre>

View File

@@ -6,12 +6,10 @@ updates:
schedule:
interval: "daily"
open-pull-requests-limit: 10
# Only specific requirements are specified in Gemfile, so don't touch it.
versioning-strategy: lockfile-only
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "daily"
# All versions are specified in package.json, so please update them.
versioning-strategy: increase
versioning-strategy: lockfile-only

View File

@@ -33,7 +33,7 @@ jobs:
- name: Setup Brakeman
env:
BRAKEMAN_VERSION: '5.4.0'
BRAKEMAN_VERSION: '4.10' # SARIF support is provided in Brakeman version 4.10+
run: |
gem install brakeman --version $BRAKEMAN_VERSION

View File

@@ -57,7 +57,7 @@ jobs:
- uses: actions/setup-node@v3
with:
node-version-file: .node-version
node-version: 16
- name: Install JS dependencies
run: yarn install --frozen-lockfile
@@ -126,7 +126,7 @@ jobs:
- uses: actions/setup-node@v3
with:
node-version-file: .node-version
node-version: 16
- name: Install JS dependencies
run: yarn install --frozen-lockfile
@@ -195,7 +195,7 @@ jobs:
- uses: actions/setup-node@v3
with:
node-version-file: .node-version
node-version: 16
- name: Install JS dependencies
run: yarn install --frozen-lockfile
@@ -273,7 +273,7 @@ jobs:
- uses: actions/setup-node@v3
with:
node-version-file: .node-version
node-version: 16
- name: Install JS dependencies
run: yarn install --frozen-lockfile
@@ -351,7 +351,7 @@ jobs:
- uses: actions/setup-node@v3
with:
node-version-file: .node-version
node-version: 16
- name: Install JS dependencies
run: yarn install --frozen-lockfile
@@ -429,7 +429,7 @@ jobs:
- uses: actions/setup-node@v3
with:
node-version-file: .node-version
node-version: 16
- name: Install JS dependencies
run: yarn install --frozen-lockfile
@@ -489,7 +489,7 @@ jobs:
- uses: actions/setup-node@v3
with:
node-version-file: .node-version
node-version: 16
- name: Install JS dependencies
run: yarn install --frozen-lockfile

View File

@@ -24,14 +24,6 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version-file: .node-version
- name: Install JS dependencies
run: yarn install --frozen-lockfile
- name: prettier
uses: EPMatt/reviewdog-action-prettier@v1
with:

View File

@@ -1 +1 @@
14.21.2
14.16.1

View File

@@ -684,6 +684,17 @@ Rails/ApplicationController:
Exclude:
- 'engines/dfc_provider/app/controllers/dfc_provider/base_controller.rb'
# Offense count: 6
# This cop supports unsafe autocorrection (--autocorrect-all).
Rails/ApplicationJob:
Exclude:
- 'app/jobs/bulk_invoice_job.rb'
- 'app/jobs/heartbeat_job.rb'
- 'app/jobs/order_cycle_closing_job.rb'
- 'app/jobs/order_cycle_notification_job.rb'
- 'app/jobs/subscription_confirm_job.rb'
- 'app/jobs/subscription_placement_job.rb'
# Offense count: 1
# This cop supports unsafe autocorrection (--autocorrect-all).
Rails/ApplicationMailer:

View File

@@ -35,10 +35,7 @@ ENV BUNDLE_PATH /bundles
ENV LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so
WORKDIR /usr/src/app
# trim spaces and line return from .ruby-version file
COPY .ruby-version .ruby-version.raw
RUN cat .ruby-version.raw | tr -d '\r\t ' > .ruby-version
COPY .ruby-version .
# Install Rbenv & Ruby
RUN git clone --depth 1 https://github.com/rbenv/rbenv.git ${RBENV_ROOT} && \

View File

@@ -11,9 +11,6 @@ Head to our wiki on [Learning Rails](https://github.com/openfoodfoundation/openf
The fastest way to make it work locally is to use Docker, you only need to setup git, see the [Docker setup guide](docker/README.md).
Otherwise, for a local setup you will need:
* Ruby and bundler (check current Ruby version in [.ruby-version](https://github.com/openfoodfoundation/openfoodnetwork/blob/master/.ruby-version) file)
- To manage versions, it's recommended to use [rbenv](https://github.com/rbenv/rbenv) or [RVM](https://rvm.io/)
* Node and yarn (check current Node version in [.node-version](https://github.com/openfoodfoundation/openfoodnetwork/blob/master/.node-version) file)
- [nodevn](https://github.com/nodenv/nodenv) is recommended.
* PostgreSQL database
* Redis (for background jobs)
* Chrome (for testing)
@@ -23,13 +20,15 @@ The following guides will provide OS-specific step-by-step instructions to get t
- [Debian Setup Guide][debian]
- [OSX Setup Guide][osx]
If you are likely to need to manage multiple version of ruby on your local machine, we recommend version managers such as [rbenv](https://github.com/rbenv/rbenv) or [RVM](https://rvm.io/).
For those new to Rails, the following tutorial will help get you up to speed with configuring a [Rails environment](http://guides.rubyonrails.org/getting_started.html).
### Get it
So you have set up your local environment according to the requirements listed above. If you're planning on contributing code to the project (which we [LOVE](CONTRIBUTING.md)), it is a good idea to begin by forking this repo using the `Fork` button in the top-right corner of this screen. You should then be able to use `git clone` to copy your fork onto your local machine:
git clone git@github.com:YOUR_GITHUB_USERNAME_HERE/openfoodnetwork.git
git clone https://github.com/YOUR_GITHUB_USERNAME_HERE/openfoodnetwork
Jump into your new local copy of the Open Food Network:
@@ -37,7 +36,7 @@ Jump into your new local copy of the Open Food Network:
And then add an `upstream` remote that points to the main repo:
git remote add upstream git@github.com:openfoodfoundation/openfoodnetwork.git
git remote add upstream https://github.com/openfoodfoundation/openfoodnetwork
Fetch the latest version of `master` from `upstream` (ie. the main repo):

View File

@@ -17,7 +17,7 @@ gem 'activemerchant', '>= 1.78.0'
gem 'rexml'
gem 'angular-rails-templates', '>= 0.3.0'
gem 'awesome_nested_set'
gem 'ransack', '~> 2.6.0'
gem 'ransack', '2.4.2'
gem 'responders'
gem 'webpacker', '~> 5'
@@ -69,7 +69,7 @@ gem 'pagy', '~> 5.1'
gem 'rswag-api'
gem 'rswag-ui'
gem 'omniauth_openid_connect'
gem 'gitlab-omniauth-openid-connect', require: 'omniauth_openid_connect'
gem 'openid_connect', '~> 1.3'
gem 'omniauth-rails_csrf_protection'
@@ -83,7 +83,7 @@ gem 'actionpack-action_caching'
# AMS is deprecated, we will introduce an alternative at some point
gem "active_model_serializers", "0.8.4"
gem 'activerecord-session_store'
gem 'acts-as-taggable-on'
gem 'acts-as-taggable-on', '~> 8.1'
gem 'angularjs-file-upload-rails', '~> 2.4.1'
gem 'bigdecimal', '3.0.2'
gem 'bootsnap', require: false
@@ -92,6 +92,7 @@ gem 'gmaps4rails'
gem 'mimemagic', '> 0.3.5'
gem 'paper_trail', '~> 12.1.0'
gem 'rack-rewrite'
gem 'rack-ssl', require: 'rack/ssl'
gem 'roadie-rails'
gem 'hiredis'
@@ -117,7 +118,7 @@ gem 'test-unit', '~> 3.5'
gem 'coffee-rails', '~> 5.0.0'
gem 'mini_racer'
gem 'mini_racer', '0.4.0'
gem 'angular_rails_csrf'

View File

@@ -134,8 +134,8 @@ GEM
minitest (>= 5.1)
tzinfo (~> 2.0)
zeitwerk (~> 2.3)
acts-as-taggable-on (9.0.1)
activerecord (>= 6.0, < 7.1)
acts-as-taggable-on (8.1.0)
activerecord (>= 5.0, < 6.2)
acts_as_list (1.0.4)
activerecord (>= 4.2)
addressable (2.8.1)
@@ -158,16 +158,16 @@ GEM
awesome_nested_set (3.5.0)
activerecord (>= 4.0.0, < 7.1)
aws-eventstream (1.2.0)
aws-partitions (1.701.0)
aws-sdk-core (3.170.0)
aws-partitions (1.669.0)
aws-sdk-core (3.168.2)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.5)
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.62.0)
aws-sdk-kms (1.60.0)
aws-sdk-core (~> 3, >= 3.165.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.119.0)
aws-sdk-s3 (1.117.2)
aws-sdk-core (~> 3, >= 3.165.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.4)
@@ -177,9 +177,9 @@ GEM
bigdecimal (3.0.2)
bindata (2.4.12)
bindex (0.8.1)
bootsnap (1.16.0)
bootsnap (1.15.0)
msgpack (~> 1.2)
bugsnag (6.25.2)
bugsnag (6.25.0)
concurrent-ruby (~> 1.0)
builder (3.2.4)
bullet (7.0.7)
@@ -221,7 +221,7 @@ GEM
combine_pdf (1.0.22)
matrix
ruby-rc4 (>= 0.1.5)
concurrent-ruby (1.2.0)
concurrent-ruby (1.1.10)
connection_pool (2.3.0)
crack (0.4.5)
rexml
@@ -237,13 +237,10 @@ GEM
activerecord (>= 5.a)
database_cleaner-core (~> 2.0.0)
database_cleaner-core (2.0.1)
date (3.3.3)
ddtrace (1.9.0)
debase-ruby_core_source (>= 0.10.16, <= 3.2.0)
libdatadog (~> 1.0.1.1.0)
libddwaf (~> 1.5.1.0.0)
ddtrace (0.54.1)
debase-ruby_core_source (= 0.10.12)
msgpack
debase-ruby_core_source (3.2.0)
debase-ruby_core_source (0.10.12)
debug (1.7.1)
irb (>= 1.5.0)
reline (>= 0.3.1)
@@ -267,7 +264,7 @@ GEM
dotenv-rails (2.8.1)
dotenv (= 2.8.1)
railties (>= 3.2)
erubi (1.12.0)
erubi (1.11.0)
et-orbi (1.2.7)
tzinfo
excon (0.81.0)
@@ -316,14 +313,18 @@ GEM
nokogiri (>= 1.5.11, < 2.0.0)
foreman (0.87.2)
formatador (0.2.5)
fugit (1.8.1)
fugit (1.7.1)
et-orbi (~> 1, >= 1.2.7)
raabro (~> 1.4)
fuubar (2.5.1)
rspec-core (~> 3.0)
ruby-progressbar (~> 1.4)
geocoder (1.8.1)
globalid (1.0.1)
gitlab-omniauth-openid-connect (0.10.0)
addressable (~> 2.7)
omniauth (>= 1.9, < 3)
openid_connect (~> 1.2)
globalid (1.0.0)
activesupport (>= 5.0)
gmaps4rails (2.1.2)
good_migrations (0.2.1)
@@ -373,28 +374,22 @@ GEM
rspec (>= 2.0, < 4.0)
jsonapi-serializer (2.2.0)
activesupport (>= 4.2)
jwt (2.7.0)
jwt (2.6.0)
knapsack_pro (3.7.0)
rake
launchy (2.5.0)
addressable (~> 2.7)
letter_opener (1.8.1)
launchy (>= 2.2, < 3)
libdatadog (1.0.1.1.0)
libddwaf (1.5.1.0.0)
ffi (~> 1.0)
libv8-node (16.10.0.0)
listen (3.8.0)
libv8-node (15.14.0.1)
listen (3.7.1)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
loofah (2.19.1)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mail (2.8.1)
mail (2.7.1)
mini_mime (>= 0.1.1)
net-imap
net-pop
net-smtp
marcel (1.0.2)
matrix (0.4.2)
method_source (1.0.0)
@@ -407,8 +402,8 @@ GEM
mini_magick (4.11.0)
mini_mime (1.1.2)
mini_portile2 (2.8.1)
mini_racer (0.6.3)
libv8-node (~> 16.10.0.0)
mini_racer (0.4.0)
libv8-node (~> 15.14.0.0)
minitest (5.17.0)
monetize (1.12.0)
money (~> 6.12)
@@ -417,17 +412,12 @@ GEM
msgpack (1.6.0)
multi_json (1.15.0)
multi_xml (0.6.0)
net-imap (0.3.4)
date
net-protocol
net-pop (0.1.2)
net-protocol
net-protocol (0.1.3)
timeout
net-smtp (0.3.2)
net-protocol
nio4r (2.5.8)
nokogiri (1.14.1)
nokogiri (1.13.10)
mini_portile2 (~> 2.8.0)
racc (~> 1.4)
oauth2 (1.4.11)
@@ -443,9 +433,6 @@ GEM
omniauth-rails_csrf_protection (1.0.1)
actionpack (>= 4.2)
omniauth (~> 2.0)
omniauth_openid_connect (0.6.0)
omniauth (>= 1.9, < 3)
openid_connect (~> 1.1)
openid_connect (1.4.2)
activemodel
attr_required (>= 1.0.0)
@@ -466,7 +453,7 @@ GEM
parallel (1.22.1)
paranoia (2.6.1)
activerecord (>= 5.1, < 7.1)
parser (3.2.0.0)
parser (3.1.3.0)
ast (~> 2.4.1)
paypal-sdk-core (0.3.4)
multi_json (~> 1.0)
@@ -485,11 +472,11 @@ GEM
coderay (~> 1.1)
method_source (~> 1.0)
public_suffix (5.0.0)
puma (6.0.2)
puma (5.6.5)
nio4r (~> 2.0)
raabro (1.4.0)
racc (1.6.2)
rack (2.2.6.2)
racc (1.6.1)
rack (2.2.4)
rack-mini-profiler (2.3.4)
rack (>= 1.2.0)
rack-oauth2 (1.21.3)
@@ -500,9 +487,11 @@ GEM
rack (>= 2.1.0)
rack-protection (2.1.0)
rack
rack-proxy (0.7.6)
rack-proxy (0.7.0)
rack
rack-rewrite (1.5.1)
rack-ssl (1.4.1)
rack
rack-test (2.0.2)
rack (>= 1.3)
rack-timeout (0.6.3)
@@ -533,7 +522,7 @@ GEM
activesupport (>= 4.2)
choice (~> 0.2.0)
ruby-graphviz (~> 1.2)
rails-html-sanitizer (1.5.0)
rails-html-sanitizer (1.4.4)
loofah (~> 2.19, >= 2.19.1)
rails-i18n (7.0.6)
i18n (>= 0.7, < 2)
@@ -547,23 +536,23 @@ GEM
thor (~> 1.0)
rainbow (3.1.1)
rake (13.0.6)
ransack (2.6.0)
activerecord (>= 6.0.4)
activesupport (>= 6.0.4)
ransack (2.4.2)
activerecord (>= 5.2.4)
activesupport (>= 5.2.4)
i18n
rb-fsevent (0.11.2)
rb-fsevent (0.11.0)
rb-inotify (0.10.1)
ffi (~> 1.0)
redcarpet (3.6.0)
redcarpet (3.5.1)
redis (4.8.0)
regexp_parser (2.6.2)
regexp_parser (2.6.1)
reline (0.3.2)
io-console (~> 0.5)
request_store (1.5.0)
rack (>= 1.4)
responders (3.1.0)
actionpack (>= 5.2)
railties (>= 5.2)
responders (3.0.1)
actionpack (>= 5.0)
railties (>= 5.0)
rexml (3.2.5)
roadie (5.0.1)
css_parser (~> 1.4)
@@ -610,16 +599,16 @@ GEM
rswag-ui (2.8.0)
actionpack (>= 3.1, < 7.1)
railties (>= 3.1, < 7.1)
rubocop (1.44.1)
rubocop (1.42.0)
json (~> 2.3)
parallel (~> 1.10)
parser (>= 3.2.0.0)
parser (>= 3.1.2.1)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.24.1, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
unicode-display_width (>= 1.4.0, < 3.0)
rubocop-ast (1.24.1)
parser (>= 3.1.1.0)
rubocop-rails (2.17.4)
@@ -651,9 +640,10 @@ GEM
connection_pool (>= 2.2.5, < 3)
rack (~> 2.0)
redis (>= 4.5.0, < 5)
sidekiq-scheduler (5.0.1)
sidekiq-scheduler (4.0.3)
redis (>= 4.2.0)
rufus-scheduler (~> 3.2)
sidekiq (>= 4, < 8)
sidekiq (>= 4, < 7)
tilt (>= 1.4.0)
simplecov (0.22.0)
docile (~> 1.1)
@@ -664,7 +654,7 @@ GEM
spreadsheet_architect (5.0.0)
caxlsx (>= 3.3.0, < 4)
rodf (>= 1.0.0, < 2)
spring (4.1.1)
spring (4.1.0)
spring-commands-rspec (1.0.4)
spring (>= 0.9.1)
sprockets (3.7.2)
@@ -706,11 +696,11 @@ GEM
timecop (0.9.6)
timeout (0.3.0)
ttfunk (1.7.0)
tzinfo (2.0.6)
tzinfo (2.0.5)
concurrent-ruby (~> 1.0)
unicode-display_width (2.4.2)
unicode-display_width (2.3.0)
uniform_notifier (1.16.0)
valid_email2 (4.0.5)
valid_email2 (4.0.4)
activemodel (>= 3.2)
mail (~> 2.5)
validate_email (0.1.6)
@@ -720,7 +710,7 @@ GEM
activemodel (>= 3.0.0)
public_suffix
vcr (6.1.0)
view_component (2.82.0)
view_component (2.80.0)
activesupport (>= 5.2.0, < 8.0)
concurrent-ruby (~> 1.0)
method_source (~> 1.0)
@@ -742,7 +732,7 @@ GEM
addressable (>= 2.8.0)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
webpacker (5.4.4)
webpacker (5.4.3)
activesupport (>= 5.2)
rack-proxy (>= 0.6.1)
railties (>= 5.2)
@@ -772,7 +762,7 @@ DEPENDENCIES
activerecord-import
activerecord-postgresql-adapter
activerecord-session_store
acts-as-taggable-on
acts-as-taggable-on (~> 8.1)
acts_as_list (= 1.0.4)
angular-rails-templates (>= 0.3.0)
angular_rails_csrf
@@ -813,6 +803,7 @@ DEPENDENCIES
foreman
fuubar (~> 2.5.1)
geocoder
gitlab-omniauth-openid-connect
gmaps4rails
good_migrations
haml
@@ -834,12 +825,11 @@ DEPENDENCIES
mime-types
mimemagic (> 0.3.5)
mini_portile2 (~> 2.8)
mini_racer
mini_racer (= 0.4.0)
monetize (~> 1.11)
oauth2 (~> 1.4.7)
ofn-qz!
omniauth-rails_csrf_protection
omniauth_openid_connect
openid_connect (~> 1.3)
order_management!
pagy (~> 5.1)
@@ -852,13 +842,14 @@ DEPENDENCIES
puma
rack-mini-profiler (< 3.0.0)
rack-rewrite
rack-ssl
rack-timeout
rails (>= 6.1.4)
rails-controller-testing
rails-erd
rails-i18n
rails_safe_tasks (~> 1.0)
ransack (~> 2.6.0)
ransack (= 2.4.2)
redcarpet
redis (>= 4.0)
responders
@@ -903,4 +894,4 @@ RUBY VERSION
ruby 3.0.3p157
BUNDLED WITH
2.4.3
2.1.4

View File

@@ -9,41 +9,41 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
$scope.sharedResource = false
$scope.columns = Columns.columns
$scope.sorting = SortOptions
$scope.pagination = LineItems.pagination
$scope.per_page_options = [
{id: 15, name: t('js.admin.orders.index.per_page', results: 15)},
{id: 50, name: t('js.admin.orders.index.per_page', results: 50)},
{id: 100, name: t('js.admin.orders.index.per_page', results: 100)}
]
$scope.page = 1
$scope.per_page = $scope.per_page_options[0].id
$scope.confirmRefresh = ->
LineItems.allSaved() || confirm(t("unsaved_changes_warning"))
$scope.initStartAndEnDate = ->
$scope.startDate = moment().startOf('day').subtract(7, 'days').format('YYYY-MM-DD')
$scope.endDate = moment().startOf('day').format('YYYY-MM-DD')
$scope.resetFilters = ->
$scope.distributorFilter = ''
$scope.supplierFilter = ''
$scope.orderCycleFilter = ''
$scope.quickSearch = ''
$scope.startDate = undefined
$scope.endDate = undefined
event = new CustomEvent('flatpickr:clear')
$scope.initStartAndEnDate()
event = new CustomEvent('flatpickr:change', {
detail: {
startDate: $scope.startDate,
endDate: $scope.endDate
}
})
window.dispatchEvent(event)
$scope.resetSelectFilters = ->
$scope.resetFilters()
$scope.refreshData()
$scope.fetchResults = ->
# creates indirection in order to factorize the code between orders and bulk orders
# used in app/views/admin/shared/_angular_per_page_controls.html.haml
$scope.refreshData()
$scope.refreshData = ->
$scope.formattedStartDate = moment($scope.startDate).format()
$scope.formattedEndDate = moment($scope.endDate).add(1,'day').format()
return unless moment($scope.formattedStartDate).isValid() and moment($scope.formattedEndDate).isValid()
return "cancel" unless $scope.confirmRefresh()
$scope.loadOrders()
$scope.loadLineItems()
unless $scope.initialized
@@ -51,14 +51,33 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
$scope.dereferenceLoadedData()
$scope.setOrderCycleDateRange = ->
start_date = OrderCycles.byID[$scope.orderCycleFilter].orders_open_at
end_date = OrderCycles.byID[$scope.orderCycleFilter].orders_close_at
format = "YYYY-MM-DD HH:mm:ss Z"
$scope.startDate = moment(start_date, format).format('YYYY-MM-DD')
$scope.endDate = moment(end_date, format).startOf('day').format('YYYY-MM-DD')
# throw a flatpickr:change event to change the date back in the datepicker
event = new CustomEvent('flatpickr:change', {
detail: {
startDate: $scope.startDate,
endDate: $scope.endDate
}
})
window.dispatchEvent(event)
$scope.loadOrders = ->
RequestMonitor.load $scope.orders = Orders.index(
"q[id_in][]": $scope.line_items.map((line_item) -> line_item.order.id)
"q[state_not_eq]": "canceled",
"q[shipment_state_not_eq]": "shipped",
"q[completed_at_not_null]": "true",
"q[distributor_id_eq]": $scope.distributorFilter,
"q[order_cycle_id_eq]": $scope.orderCycleFilter,
"q[completed_at_gteq]": $scope.formattedStartDate,
"q[completed_at_lt]": $scope.formattedEndDate
)
$scope.loadLineItems = ->
[formattedStartDate, formattedEndDate] = $scope.formatDates($scope.startDate, $scope.endDate)
RequestMonitor.load LineItems.index(
"q[order_state_not_eq]": "canceled",
"q[order_shipment_state_not_eq]": "shipped",
@@ -66,32 +85,23 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
"q[order_distributor_id_eq]": $scope.distributorFilter,
"q[variant_product_supplier_id_eq]": $scope.supplierFilter,
"q[order_order_cycle_id_eq]": $scope.orderCycleFilter,
"q[order_completed_at_gteq]": if formattedStartDate then formattedStartDate else undefined,
"q[order_completed_at_lt]": if formattedEndDate then formattedEndDate else undefined,
"page": $scope.page,
"per_page": $scope.per_page
"q[order_completed_at_gteq]": $scope.formattedStartDate,
"q[order_completed_at_lt]": $scope.formattedEndDate
)
$scope.formatDates = (startDate, endDate) ->
formattedStartDate = moment(startDate).format('YYYY-MM-DD') if startDate
formattedEndDate = moment(endDate).add(1,'day').format('YYYY-MM-DD') if endDate
return [formattedStartDate, formattedEndDate]
$scope.loadAssociatedData = ->
RequestMonitor.load $scope.distributors = Enterprises.index(action: "visible", ams_prefix: "basic", "q[sells_in][]": ["own", "any"])
RequestMonitor.load $scope.orderCycles = OrderCycles.index(ams_prefix: "basic", as: "distributor", "q[orders_close_at_gt]": "#{moment().subtract(90,'days').format()}")
RequestMonitor.load $scope.suppliers = Enterprises.index(action: "visible", ams_prefix: "basic", "q[is_primary_producer_eq]": "true")
$scope.dereferenceLoadedData = ->
RequestMonitor.load $q.all([$scope.distributors.$promise, $scope.orderCycles.$promise, $scope.suppliers.$promise, $scope.line_items.$promise]).then ->
RequestMonitor.load $q.all([$scope.orders.$promise, $scope.distributors.$promise, $scope.orderCycles.$promise, $scope.suppliers.$promise, $scope.line_items.$promise]).then ->
Dereferencer.dereferenceAttr $scope.orders, "distributor", Enterprises.byID
Dereferencer.dereferenceAttr $scope.orders, "order_cycle", OrderCycles.byID
Dereferencer.dereferenceAttr $scope.line_items, "supplier", Enterprises.byID
$scope.loadOrders()
RequestMonitor.load $q.all([$scope.orders.$promise]).then ->
Dereferencer.dereferenceAttr $scope.line_items, "order", Orders.byID
Dereferencer.dereferenceAttr $scope.orders, "distributor", Enterprises.byID
Dereferencer.dereferenceAttr $scope.orders, "order_cycle", OrderCycles.byID
$scope.bulk_order_form.$setPristine()
StatusMessage.clear()
Dereferencer.dereferenceAttr $scope.line_items, "order", Orders.byID
$scope.bulk_order_form.$setPristine()
StatusMessage.clear()
unless $scope.initialized
$scope.initialized = true
@@ -209,7 +219,7 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
$scope.getGroupBySizeFormattedValueWithUnitName = (value, unitsProduct, unitsVariant) ->
scale = $scope.getScale(unitsProduct, unitsVariant)
if scale && value
if scale
value = value / scale if scale != 28.35 && scale != 1 && scale != 453.6 # divide by scale if not smallest unit
$scope.getFormattedValueWithUnitName(value, unitsProduct, unitsVariant, scale)
else
@@ -253,8 +263,4 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
lineItem.final_weight_volume = LineItems.pristineByID[lineItem.id].final_weight_volume * lineItem.quantity / LineItems.pristineByID[lineItem.id].quantity
$scope.weightAdjustedPrice(lineItem)
$scope.changePage = (newPage) ->
$scope.page = newPage
$scope.refreshData()
$scope.resetSelectFilters()

View File

@@ -17,12 +17,9 @@ angular.module('Darkswarm').directive "ofnFlash", (flash, $timeout, RailsFlashLo
# Callback when a new flash message is pushed to flash service
show = (message, type)=>
return unless message
# if same message already exists, don't add it again
return if $scope.flashes.some((flash) -> flash.message == message)
$scope.flashes.push({message: message, type: typePairings[type]})
$timeout($scope.delete, 10000)
if message
$scope.flashes.push({message: message, type: typePairings[type]})
$timeout($scope.delete, 10000)
$scope.delete = ->
$scope.flashes.shift()

View File

@@ -1,4 +1,4 @@
angular.module('Darkswarm').directive "ofnOnHand", (StockQuantity, Messages) ->
angular.module('Darkswarm').directive "ofnOnHand", (StockQuantity) ->
restrict: 'A'
require: "ngModel"
scope: true
@@ -16,7 +16,7 @@ angular.module('Darkswarm').directive "ofnOnHand", (StockQuantity, Messages) ->
ngModel.$parsers.push (viewValue) ->
available_quantity = scope.available_quantity()
if parseInt(viewValue) > available_quantity
Messages.flash({error: t("js.insufficient_stock", {on_hand: available_quantity})})
alert t("js.insufficient_stock", {on_hand: available_quantity})
viewValue = available_quantity
ngModel.$setViewValue viewValue
ngModel.$render()

View File

@@ -0,0 +1,5 @@
$( document ).ready(function() {
$("#closeie").click(function() {
$("#ie-warning").hide();
});
})

View File

@@ -1,15 +0,0 @@
# frozen_string_literal: true
class ConfirmModalComponent < ModalComponent
def initialize(id:, confirm_actions: nil, controllers: nil)
super(id: id, close_button: true)
@confirm_actions = confirm_actions
@controllers = controllers
end
private
def close_button_class
"secondary"
end
end

View File

@@ -1,8 +0,0 @@
%div{ id: @id, "data-controller": "modal #{@controllers}", "data-action": "keyup@document->modal#closeIfEscapeKey" }
.reveal-modal-bg.fade{ "data-modal-target": "background", "data-action": "click->modal#close" }
.reveal-modal.fade.tiny.help-modal{ "data-modal-target": "modal" }
= content
.modal-actions
%input{ class: "button icon-plus #{close_button_class}", type: 'button', value: t('js.admin.modals.cancel'), "data-action": "click->modal#close" }
%input{ class: "button icon-plus primary", type: 'button', value: t('js.admin.modals.confirm'), "data-action": @confirm_actions }

View File

@@ -1,4 +0,0 @@
.modal-actions {
display: flex;
justify-content: space-around;
}

View File

@@ -1,7 +1,26 @@
# frozen_string_literal: true
class HelpModalComponent < ModalComponent
class HelpModalComponent < ViewComponent::Base
def initialize(id:, close_button: true)
super(id: id, close_button: close_button)
@id = id
@close_button = close_button
end
private
def close_button_class
if namespace == "admin"
"red"
else
"primary"
end
end
def close_button?
!!@close_button
end
def namespace
helpers.controller_path.split("/").first
end
end

View File

@@ -1,26 +0,0 @@
# frozen_string_literal: true
class ModalComponent < ViewComponent::Base
def initialize(id:, close_button: true)
@id = id
@close_button = close_button
end
private
def close_button_class
if namespace == "admin"
"red"
else
"primary"
end
end
def close_button?
!!@close_button
end
def namespace
helpers.controller_path.split("/").first
end
end

View File

@@ -3,16 +3,11 @@
require "open_food_network/feature_toggle"
class FeatureToggleConstraint
def initialize(feature_name, negate: false)
def initialize(feature_name)
@feature = feature_name
@negate = negate
end
def matches?(request)
enabled?(request) ^ @negate
end
def enabled?(request)
OpenFoodNetwork::FeatureToggle.enabled?(@feature, current_user(request))
end

View File

@@ -8,12 +8,12 @@ module Admin
class EnterprisesController < Admin::ResourceController
include GeocodeEnterpriseAddress
include CablecarResponses
include Pagy::Backend
# These need to run before #load_resource so that @object is initialised with sanitised values
prepend_before_action :override_owner, only: :create
prepend_before_action :override_sells, only: :create
before_action :load_enterprise_set, only: :index
before_action :load_countries, except: [:index, :register, :check_permalink]
before_action :load_methods_and_fees, only: [:edit, :update]
before_action :load_groups, only: [:new, :edit, :update, :create]
@@ -33,8 +33,6 @@ module Admin
include OrderCyclesHelper
def index
load_enterprise_set_on_index
respond_to do |format|
format.html
format.json {
@@ -102,8 +100,7 @@ module Admin
end
def bulk_update
load_enterprise_set_with_params(bulk_params)
@enterprise_set = Sets::EnterpriseSet.new(collection, bulk_params)
if @enterprise_set.save
flash[:success] = I18n.t(:enterprise_bulk_update_success_notice)
@@ -151,15 +148,8 @@ module Admin
private
def load_enterprise_set_on_index
return unless spree_current_user.admin?
load_enterprise_set_with_params
end
def load_enterprise_set_with_params(params = {})
@pagy, @paginated_collection = pagy(@collection)
@enterprise_set = Sets::EnterpriseSet.new(@paginated_collection, params)
def load_enterprise_set
@enterprise_set = Sets::EnterpriseSet.new(collection) if spree_current_user.admin?
end
def load_countries

View File

@@ -19,22 +19,22 @@ module Admin
end
def show
@report = report_class.new(spree_current_user, params, render: render_data?)
@report = report_class.new(spree_current_user, params, request)
if report_format.present?
export_report
else
show_report
render_report
end
end
private
def export_report
send_data render_report_as(report_format), filename: report_filename
send_data @report.render_as(report_format, controller: self), filename: report_filename
end
def show_report
def render_report
assign_view_data
render "show"
end
@@ -43,29 +43,13 @@ module Admin
@report_type = report_type
@report_subtypes = report_subtypes
@report_subtype = report_subtype
@report_title = report_title
@report_title = if report_subtype
report_subtype_title
else
I18n.t(:name, scope: [:admin, :reports, @report_type])
end
@rendering_options = rendering_options
@table = render_report_as(:html) if render_data?
@data = Reporting::FrontendData.new(spree_current_user)
end
def render_data?
request.post?
end
def render_report_as(format)
if OpenFoodNetwork::FeatureToggle.enabled?(:background_reports, spree_current_user)
job = ReportJob.new
JobProcessor.perform_forked(
job,
report_class, spree_current_user, params, format
)
# This result has been rendered by Rails in safe mode already.
job.result.html_safe # rubocop:disable Rails/OutputSafety
else
@report.render_as(format)
end
end
end
end

View File

@@ -39,14 +39,6 @@ module ReportsActions
params[:report_subtype] || report_subtypes_codes.first
end
def report_title
if report_subtype
report_subtype_title
else
I18n.t(:name, scope: [:admin, :reports, report_type])
end
end
def report_subtype_title
report_subtypes.select { |_name, key| key.to_sym == report_subtype.to_sym }.first[0]
end

View File

@@ -36,7 +36,11 @@ class SplitCheckoutController < ::BaseController
advance_order_state
redirect_to_step
else
render_error
flash.now[:error] ||= I18n.t('split_checkout.errors.global')
render status: :unprocessable_entity, operations: cable_car.
replace("#checkout", partial("split_checkout/checkout")).
replace("#flashes", partial("shared/flashes", locals: { flashes: flash }))
end
rescue Spree::Core::GatewayError => e
flash[:error] = I18n.t(:spree_gateway_error_flash_for_checkout, error: e.message)
@@ -46,17 +50,6 @@ class SplitCheckoutController < ::BaseController
private
def render_error
flash.now[:error] ||= I18n.t(
'split_checkout.errors.saving_failed',
messages: @order.errors.full_messages.to_sentence
)
render status: :unprocessable_entity, operations: cable_car.
replace("#checkout", partial("split_checkout/checkout")).
replace("#flashes", partial("shared/flashes", locals: { flashes: flash }))
end
def flash_error_when_no_shipping_method_available
flash[:error] = I18n.t('split_checkout.errors.no_shipping_methods_available')
end

View File

@@ -6,6 +6,7 @@ module Spree
def edit
@preferences_general = [:site_name, :default_seo_title, :default_meta_keywords,
:default_meta_description, :site_url]
@preferences_security = [:allow_ssl_in_production, :allow_ssl_in_staging]
@preferences_currency = [:display_currency, :hide_cents]
end

View File

@@ -11,7 +11,6 @@ module CheckoutHelper
def checkout_adjustments_for(order, opts = {})
exclude = opts[:exclude] || {}
reject_zero_amount = opts.fetch(:reject_zero_amount, true)
adjustments = order.all_adjustments.eligible.to_a
@@ -33,10 +32,6 @@ module CheckoutHelper
}
end
if reject_zero_amount
adjustments.reject! { |a| a.amount == 0 }
end
adjustments
end

View File

@@ -26,12 +26,6 @@ module ReportsHelper
end.uniq
end
def customer_email_options(order_customers)
order_customers.map do |customer|
[customer&.email, customer&.id]
end
end
def currency_symbol
Spree::Money.currency_symbol
end

View File

@@ -12,16 +12,6 @@ module TaxHelper
end
end
def display_line_items_taxes(line_item, display_zero: true)
if line_item.included_tax.positive?
Spree::Money.new(line_item.included_tax, currency: line_item.currency)
elsif line_item.added_tax.positive?
Spree::Money.new(line_item.added_tax, currency: line_item.currency)
elsif display_zero
Spree::Money.new(0.00, currency: line_item.currency)
end
end
def display_total_with_tax(taxable)
total = taxable.amount + taxable.additional_tax_total
Spree::Money.new(total, currency: taxable.currency)

View File

@@ -1,10 +0,0 @@
# frozen_string_literal: true
# Rails standard class for common job code.
class ApplicationJob < ActiveJob::Base
# Automatically retry jobs that encountered a deadlock
# retry_on ActiveRecord::Deadlocked
# Most jobs are safe to ignore if the underlying records are no longer available
# discard_on ActiveJob::DeserializationError
end

View File

@@ -1,6 +1,6 @@
# frozen_string_literal: true
class BulkInvoiceJob < ApplicationJob
class BulkInvoiceJob < ActiveJob::Base
def perform(order_ids, filepath)
pdf = CombinePDF.new

View File

@@ -1,6 +1,6 @@
# frozen_string_literal: true
class HeartbeatJob < ApplicationJob
class HeartbeatJob < ActiveJob::Base
def perform
Spree::Config.last_job_queue_heartbeat_at = Time.now.in_time_zone
end

View File

@@ -1,6 +1,6 @@
# frozen_string_literal: true
class OrderCycleClosingJob < ApplicationJob
class OrderCycleClosingJob < ActiveJob::Base
def perform
return if recently_closed_order_cycles.empty?

View File

@@ -1,7 +1,7 @@
# frozen_string_literal: true
# Delivers an email with a report of the order cycle to each of its suppliers
class OrderCycleNotificationJob < ApplicationJob
class OrderCycleNotificationJob < ActiveJob::Base
def perform(order_cycle_id)
order_cycle = OrderCycle.find(order_cycle_id)
order_cycle.suppliers.each do |supplier|

View File

@@ -1,34 +0,0 @@
# frozen_string_literal: true
# Renders a report and saves it to a temporary file.
class ReportJob < ActiveJob::Base
def perform(report_class, user, params, format)
report = report_class.new(user, params, render: true)
result = report.render_as(format)
write(result)
end
def done?
@done ||= File.file?(filename)
end
def result
@result ||= read_result
end
private
def write(result)
File.write(filename, result)
end
def read_result
File.read(filename)
ensure
File.unlink(filename)
end
def filename
Rails.root.join("tmp/report-#{job_id}")
end
end

View File

@@ -3,7 +3,7 @@
require 'order_management/subscriptions/summarizer'
# Confirms orders of unconfirmed proxy orders in recently closed Order Cycles
class SubscriptionConfirmJob < ApplicationJob
class SubscriptionConfirmJob < ActiveJob::Base
def perform
confirm_proxy_orders!
end

View File

@@ -2,7 +2,7 @@
require 'order_management/subscriptions/summarizer'
class SubscriptionPlacementJob < ApplicationJob
class SubscriptionPlacementJob < ActiveJob::Base
def perform
proxy_orders.each do |proxy_order|
place_order_for(proxy_order)

View File

@@ -7,6 +7,7 @@ module Calculator
extend Spree::LocalizedNumber
preference :amount, :decimal, default: 0
preference :currency, :string, default: Spree::Config[:currency]
localize_number :preferred_amount

View File

@@ -9,6 +9,7 @@ module Calculator
preference :first_item, :decimal, default: 0.0
preference :additional_item, :decimal, default: 0.0
preference :max_items, :integer, default: 0
preference :currency, :string, default: Spree::Config[:currency]
localize_number :preferred_first_item,
:preferred_additional_item

View File

@@ -1,13 +0,0 @@
# frozen_string_literal: false
module Calculator
class None < Spree::Calculator
def self.description
I18n.t(:none)
end
def compute(_object = nil)
0
end
end
end

View File

@@ -7,6 +7,7 @@ module Calculator
extend Spree::LocalizedNumber
preference :amount, :decimal, default: 0
preference :currency, :string, default: Spree::Config[:currency]
localize_number :preferred_amount

View File

@@ -9,6 +9,7 @@ module Calculator
preference :minimal_amount, :decimal, default: 0
preference :normal_amount, :decimal, default: 0
preference :discount_amount, :decimal, default: 0
preference :currency, :string, default: Spree::Config[:currency]
localize_number :preferred_minimal_amount,
:preferred_normal_amount,

View File

@@ -33,6 +33,8 @@ module Spree
preference :allow_backorder_shipping, :boolean, default: false
preference :allow_checkout_on_gateway_error, :boolean, default: false
preference :allow_guest_checkout, :boolean, default: true
preference :allow_ssl_in_production, :boolean, default: true
preference :allow_ssl_in_staging, :boolean, default: true
# Replace with the name of a zone if you would like to limit the countries
preference :checkout_zone, :string, default: nil
preference :currency, :string, default: "USD"

View File

@@ -186,10 +186,6 @@ module Spree
adjustments.tax.inclusive.sum(:amount)
end
def added_tax
adjustments.tax.additional.sum(:amount)
end
def tax_rates
product.tax_category&.tax_rates || []
end

View File

@@ -13,7 +13,7 @@ module Spree
include SetUnusedAddressFields
searchable_attributes :number, :state, :shipment_state, :payment_state, :distributor_id,
:order_cycle_id, :email, :total, :customer_id
:order_cycle_id, :email, :total
searchable_associations :shipping_method, :bill_address
searchable_scopes :complete, :incomplete

View File

@@ -113,7 +113,7 @@ module Spree
end
def init
self.calculator ||= ::Calculator::None.new
self.calculator ||= ::Calculator::FlatRate.new(preferred_amount: 0)
end
def has_distributor?(distributor)

View File

@@ -32,8 +32,6 @@ module Spree
validate :at_least_one_shipping_category
validates :display_on, inclusion: { in: DISPLAY_ON_OPTIONS.values }, allow_nil: true
after_initialize :init
after_save :touch_distributors
scope :managed_by, lambda { |user|
@@ -69,6 +67,10 @@ module Spree
tracking_url.gsub(/:tracking/, tracking) unless tracking.blank? || tracking_url.blank?
end
def self.calculators
spree_calculators.__send__ model_name_without_spree_namespace
end
# Some shipping methods are only meant to be set via backend
def frontend?
display_on != "back_end"
@@ -108,10 +110,6 @@ module Spree
where(display_on: [nil, ""])
end
def init
self.calculator ||= ::Calculator::None.new if new_record?
end
private
def no_active_or_upcoming_order_cycle_distributors_with_only_one_shipping_method?

View File

@@ -16,11 +16,4 @@ class ApplicationReflex < StimulusReflex::Reflex
#
# For code examples, considerations and caveats, see:
# https://docs.stimulusreflex.com/rtfm/patterns#internationalization
include CanCan::ControllerAdditions
delegate :current_user, to: :connection
def current_ability
Spree::Ability.new(current_user)
end
end

View File

@@ -1,13 +0,0 @@
# frozen_string_literal: true
class ResendConfirmationEmailReflex < ApplicationReflex
def confirm(order_ids)
Spree::Order.where(id: order_ids).find_each do |o|
Spree::OrderMailer.confirm_email_for_customer(o.id, true).deliver_later if can? :resend, o
end
flash[:success] = I18n.t("admin.resend_confirmation_emails_feedback", count: order_ids.count)
cable_ready.dispatch_event(name: "modal:close")
morph "#flashes", render(partial: "shared/flashes", locals: { flashes: flash })
end
end

View File

@@ -1,29 +0,0 @@
# frozen_string_literal: true
# Forks into a separate process to contain memory usage and timeout errors.
class JobProcessor
def self.perform_forked(job, *args)
# Reports should abort when puma threads are killed to avoid wasting
# resources. Nobody would be collecting the result. We still need to
# implement a way to email or download reports later.
timeout = ENV.fetch("RACK_TIMEOUT_WAIT_TIMEOUT", "30").to_i
child = fork do
Process.setproctitle("Job worker #{job.job_id}")
Timeout.timeout(timeout) do
job.perform(*args)
end
# Exit is not a good idea within a Rails process but Rubocop doesn't know
# that we are in a forked process.
exit # rubocop:disable Rails/Exit
end
# Wait for the forked child process to exit.
Process.waitpid(child)
ensure
# If this Puma thread is interrupted then we need to detach the child
# process to avoid it becoming a zombie.
Process.detach(child)
end
end

View File

@@ -4,7 +4,7 @@ module PermittedAttributes
class Calculator
def self.attributes
[
:id, :preferred_amount, :preferred_flat_percent,
:id, :preferred_currency, :preferred_amount, :preferred_flat_percent,
:preferred_minimal_amount, :preferred_normal_amount, :preferred_discount_amount,
:preferred_unit_from_list, :preferred_per_unit, :preferred_first_item,
:preferred_additional_item, :preferred_max_items

View File

@@ -56,7 +56,7 @@ module VariantUnits
def option_value_value_unit_scaled
unit_scale, unit_name = scale_for_unit_value
value = (@variant.unit_value / unit_scale).to_d.truncate(2)
value = BigDecimal(@variant.unit_value / unit_scale, 6)
[value, unit_name]
end

View File

@@ -38,5 +38,3 @@
%tr
%td{colspan: "4"}= t(:none)
= f.submit t(:update)
= render partial: 'admin/shared/pagy_links', locals: { pagy: @pagy }

View File

@@ -1,12 +1,6 @@
.row
= t(:required_fields)
(
%span.required *
)
.row
.three.columns.alpha
= bf.label :company, t(".company_legal_name")
%span.required *
%i.text-big.icon-question-sign{ "data-controller": "help-modal-link", "data-action": "click->help-modal-link#open", "data-help-modal-link-target-value": "business_address_info_modal" }
.eight.columns.omega
= bf.text_field :company, { placeholder: t(".company_placeholder") }
@@ -14,7 +8,6 @@
.row
.three.columns.alpha
= bf.label :address1, t('.address1')
%span.required *
%i.text-big.icon-question-sign{ "data-controller": "help-modal-link", "data-action": "click->help-modal-link#open", "data-help-modal-link-target-value": "business_address_info_modal" }
.eight.columns.omega
= bf.text_field :address1, { placeholder: t(".address1_placeholder") }
@@ -26,10 +19,8 @@
.row
.three.columns.alpha
= bf.label :city, t(:city)
%span.required *
\/
= bf.label :zipcode, t(:postcode)
%span.required *
.four.columns
= bf.text_field :city, { placeholder: t(:city_placeholder) }
.four.columns.omega
@@ -37,10 +28,8 @@
.row{"data-controller": "dependent-select", "data-dependent-select-options-value": countries_with_states }
.three.columns.alpha
= bf.label :country_id, t(:country)
%span.required *
\/
= bf.label :state_id, t(:state)
%span.required *
.four.columns
= bf.select :country_id, options_for_select(available_countries.map { |c| [c.name, c.id] }, @enterprise.business_address.country_id), {}, { "data-controller": "tom-select", "data-dependent-select-target": "source", "data-action": "dependent-select#handleSelectChange", class: "primary" }
.four.columns.omega
@@ -50,7 +39,6 @@
.row
.three.columns.alpha
= bf.label :phone, t(".legal_phone_number")
%span.required *
%i.text-big.icon-question-sign{ "data-controller": "help-modal-link", "data-action": "click->help-modal-link#open", "data-help-modal-link-target-value": "business_address_info_modal" }
.eight.columns.omega
= bf.text_field :phone, { placeholder: t(".phone_placeholder") }

View File

@@ -3,4 +3,4 @@
{{ enterprise.name }}
= "{{ enterprise.issues_summary_#{type} ? '('+enterprise.issues_summary_#{type}+')' : '' }}"
= f.submit t(".add_#{type}"), 'ng-click' => "add#{type.capitalize}($event)", 'ng-disabled' => "!new_#{type}_id || !OrderCycle.novel#{type.capitalize}(new_#{type}_id)", "class": "secondary"
= f.submit t(".add_#{type}"), 'ng-click' => "add#{type.capitalize}($event)", 'ng-disabled' => "!new_#{type}_id || !OrderCycle.novel#{type.capitalize}(new_#{type}_id)"

View File

@@ -26,16 +26,15 @@
= f.submit t('.add_fee'), 'ng-click' => 'addExchangeFee($event, exchange)', 'ng-hide' => '!enterprises[exchange.enterprise_id].managed && !order_cycle.viewing_as_coordinator'
%td.actions
.flex
%a{'ng-click' => 'removeExchange($event, exchange)', :class => "icon-trash no-text remove-exchange"}
%a{'ng-click' => 'removeExchange($event, exchange)', :class => "icon-trash no-text remove-exchange"}
- if type == 'supplier'
%tr.panel-row{ object: "exchange",
panels: "{products: 'exchange_products_supplied'}",
locals: "$index,exchangeTotalVariants,order_cycle,exchange,enterprises,setExchangeVariants,selectAllVariants,suppliedVariants,removeDistributionOfVariant,initializeExchangeProductsPanel,loadMoreExchangeProducts,loadAllExchangeProducts,productsLoading",
colspan: if feature?(:admin_style_v2, spree_current_user) then 5 else 4 end }
colspan: 4 }
- if type == 'distributor'
%tr.panel-row{ object: "exchange",
panels: "{products: 'exchange_products_distributed', tags: 'exchange_tags'}",
locals: "$index,exchangeTotalVariants,order_cycle,exchange,enterprises,setExchangeVariants,incomingExchangeVariantsFor,variantSuppliedToOrderCycle,initializeExchangeProductsPanel,loadMoreExchangeProducts,loadAllExchangeProducts,productsLoading",
colspan: if feature?(:admin_style_v2, spree_current_user) then 6 else 5 end }
colspan: 5 }

View File

@@ -1,16 +1,16 @@
%colgroup
%col{ ng: { show: 'columns.name.visible' } }
%col{ ng: { show: 'columns.schedules.visible' } }
%col{ ng: { show: 'columns.open.visible' } }
%col{ ng: { show: 'columns.close.visible' } }
%col{ ng: { show: 'columns.open.visible' }, style: 'width: 20%;' }
%col{ ng: { show: 'columns.close.visible' }, style: 'width: 20%;' }
- unless simple_index
%col{ ng: { show: 'columns.producers.visible' } }
%col{ ng: { show: 'columns.coordinator.visible' } }
%col{ ng: { show: 'columns.shops.visible' } }
%col{ ng: { show: 'columns.products.visible' } }
%col
%col
%col
%col{ style: 'width: 5%;' }
%col{ style: 'width: 5%;' }
%col{ style: 'width: 5%;' }
%thead
%tr
@@ -32,3 +32,5 @@
%th{ ng: { show: 'columns.products.visible' } }
=t :products
%th.actions
%th.actions
%th.actions

View File

@@ -32,9 +32,8 @@
= t('.variants')
%td.actions
.flex
%a.edit-order-cycle.icon-edit.no-text{ ng: { href: '{{orderCycle.edit_path}}'}, 'ofn-with-tip' => t(:edit) }
%div{ ng: { if: 'orderCycle.viewing_as_coordinator' } }
%a.clone-order-cycle.icon-copy.no-text{ ng: { href: '{{orderCycle.clone_path}}'}, 'ofn-with-tip' => t(:clone) }
%div{ ng: { if: 'orderCycle.deletable && orderCycle.viewing_as_coordinator' }}
%a.delete-order-cycle.icon-trash.no-text{ ng: { href: '{{orderCycle.delete_path}}'}, data: { method: 'delete', confirm: t(:are_you_sure) }, 'ofn-with-tip' => t(:remove) }
%a.edit-order-cycle.icon-edit.no-text{ ng: { href: '{{orderCycle.edit_path}}'}, 'ofn-with-tip' => t(:edit) }
%td.actions{ ng: { if: 'orderCycle.viewing_as_coordinator' } }
%a.clone-order-cycle.icon-copy.no-text{ ng: { href: '{{orderCycle.clone_path}}'}, 'ofn-with-tip' => t(:clone) }
%td.actions{ ng: { if: 'orderCycle.deletable && orderCycle.viewing_as_coordinator' }}
%a.delete-order-cycle.icon-trash.no-text{ ng: { href: '{{orderCycle.delete_path}}'}, data: { method: 'delete', confirm: t(:are_you_sure) }, 'ofn-with-tip' => t(:remove) }

View File

@@ -1,5 +1,5 @@
%ul{style: "margin-left: 12pt"}
- report_subtypes.each do |report_subtype|
%li
- url = main_app.admin_report_path(report_type: report_type, report_subtype: report_subtype[1])
- url = main_app.admin_report_url(report_type: report_type, report_subtype: report_subtype[1])
= link_to report_subtype[0], url

View File

@@ -1,3 +1,5 @@
- report ||= @report
.report__table-container
%table.report__table
%thead

View File

@@ -1,13 +0,0 @@
.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})
.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})
.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})

View File

@@ -1,12 +1,10 @@
- content_for :page_title do
= @report_title
= form_for @report.search, :url => url_for do |f|
= form_for @report.search, :url => url_for(only_path: false) do |f|
%fieldset.no-border-bottom.print-hidden
%legend{ align: 'center'}= t(:report_filters)
= render partial: "admin/reports/filters/#{@report_type}", locals: { f: f }
- if @report_subtype && lookup_context.exists?(@report_subtype, "admin/reports/filters/", true)
= render partial: "admin/reports/filters/#{@report_subtype}", locals: { f: f }
%fieldset.print-hidden
%legend{ align: 'center'}= t(:report_render_options)
@@ -21,4 +19,7 @@
- if request.post?
%button.btn-print.icon-print{ onclick: "window.print()"}= t(:report_print)
= @table
/ We don't want to render data unless search params are supplied.
/ Compiling data can take a long time.
- if request.post?
= render "table"

View File

@@ -1,7 +0,0 @@
- position ||= ""
.per-page{'ng-show' => "!RequestMonitor.loading && #{model}.length > 0", class: ("right" if position == "right") }
%input.per-page-select.ofn-select2{type: 'number', data: 'per_page_options', 'min-search' => 999, 'ng-model' => 'per_page', 'ng-change' => 'fetchResults()'}
%span.per-page-feedback
{{ "spree.admin.#{model}.index.results_found" | t:{number: pagination.results} }}
{{ 'spree.admin.#{model}.index.viewing' | t:{start: ((pagination.page -1) * pagination.per_page) +1, end: ((pagination.page -1) * pagination.per_page) + #{model}.length} }}

View File

@@ -9,7 +9,7 @@
= t :checkout_cart_total
%td.cart-total.text-right= display_checkout_subtotal(@order)
- checkout_adjustments_for(current_order, exclude: [:shipping, :payment, :line_item]).each do |adjustment|
- checkout_adjustments_for(current_order, exclude: [:shipping, :payment, :line_item]).reject{ |a| a.amount == 0 }.each do |adjustment|
%tr.adjustment
%th= adjustment.label
%td.text-right= adjustment.display_amount.to_html

View File

@@ -36,6 +36,10 @@
= action_cable_meta_tag
%body{ class: body_classes, "body-scroll": "true", "data-turbo": "false" }
/ [if lte IE 8]
= render partial: "shared/ie_warning"
= javascript_include_tag "iehack"
.off-canvas-wrap{ offcanvas: true }
.fixed.off-canvas-fixed
= render "shared/menu/menu" unless @hide_menu

View File

@@ -19,6 +19,10 @@
= csrf_meta_tags
%body.off-canvas{ style: "background-image: url(#{image_pack_path('tile-wide.png')})", "data-turbo": "false" }
/ [if lte IE 8]
= render partial: "shared/ie_warning"
= javascript_include_tag "iehack"
.off-canvas-wrap{offcanvas: true}
.inner-wrap

View File

@@ -2,6 +2,6 @@
- if defined? flashes
- flashes.each do |type, msg|
%alert.animate-show{"data-controller": "flash"}
.flash{type: "#{type}", class: "alert-box #{type == 'error' ? 'alert' : type}"}
%div{type: "#{type}", class: "alert-box #{type == 'error' ? 'alert' : type}"}
%span= msg
%a.small.close{"data-action": "click->flash#close"} ×

View File

@@ -0,0 +1,31 @@
.alert-box.alert#ie-warning{"data-alert" => ""}
.row.ie-msg
.small-4.large-2.columns
%i.ofn-i_012-warning
.small-8.large-10.columns
%h3
= t :ie_warning_headline
%p
= t :ie_warning_text
.row
.small-4.columns.browserbtn
%a.browserlogo{href: "https://www.google.com/intl/en_au/chrome/browser/", target: "_blank"}
%img{src: image_pack_path("browser-logos/chrome.png") }
%a{href: "https://www.google.com/intl/en_au/chrome/browser/", target: "_blank"}
= t :ie_warning_chrome
.small-4.columns.browserbtn
%a.browserlogo{href: "http://www.mozilla.org/en-US/firefox/new/", target: "_blank"}
%img{src: image_pack_path("browser-logos/firefox.png") }
%a{href: "http://www.mozilla.org/en-US/firefox/new/", target: "_blank"}
= t :ie_warning_firefox
.small-4.columns.browserbtn
%a.browserlogo{href: "http://windows.microsoft.com/en-AU/internet-explorer/download-ie", target: "_blank"}
%img{src: image_pack_path("browser-logos/internet-explorer.png") }
%a{href: "http://windows.microsoft.com/en-AU/internet-explorer/download-ie", target: "_blank"}
= t :ie_warning_ie
.row.ie-msg
.small-12.large-12.columns
.text-center
%em
= t :ie_warning_other
%a#closeie.close{href: "#"} ×

View File

@@ -3,3 +3,13 @@
= raw render file: "spec/support/fixtures/stripejs-mock.js"
- else
%script{src: "https://js.stripe.com/v3/", type: "text/javascript"}
:javascript
// persist initial stripe iFrame DOM Object across turbo AJAX page requests
let stripeIFrameQuery = 'iframe[src^="https://js.stripe.com"]';
document.addEventListener('turbo:before-render', function (event) {
const stripeIFrame = document.querySelector(stripeIFrameQuery);
const newStripeIFrame = event.detail.newBody.querySelector(stripeIFrameQuery);
if (stripeIFrame && !newStripeIFrame){
event.detail.newBody.appendChild(stripeIFrame)
}
});

View File

@@ -1,3 +1,3 @@
.already-ordered
.panel
.panel.medium-6
= t("split_checkout.already_ordered.message_html", cart: link_to(t('split_checkout.already_ordered.cart'), "#{main_app.cart_path}#bought-products"))

View File

@@ -1,4 +1,5 @@
%checkout.row#checkout
.small-12.medium-12.columns
= render partial: "split_checkout/tabs"
= render partial: "split_checkout/already_ordered" if show_bought_items? && checkout_step?(:summary)
= render partial: "split_checkout/form"

View File

@@ -89,7 +89,7 @@
"data-action": "toggle#toggle shippingmethod#selectShippingMethod",
"data-toggle-show": shipping_method.require_ship_address
= shipping_method_form.label shipping_method.id, shipping_method.name, {for: "shipping_method_" + shipping_method.id.to_s }
%em.fees= payment_or_shipping_price(shipping_method, @order)
%em= payment_or_shipping_price(shipping_method, @order)
- display_ship_address = display_ship_address || (ship_method_is_selected && shipping_method.require_ship_address)
%div.checkout-input{"data-shippingmethod-target": "shippingMethodDescription", "data-shippingmethodid": shipping_method.id , style: "display: #{ship_method_is_selected ? 'block' : 'none'}" }
#distributor_address.panel

View File

@@ -1,7 +1,7 @@
- content_for :injection_data do
= inject_saved_credit_cards
%div.checkout-step{"class": if checkout_step?(:summary) then "checkout-summary" end}
%div.checkout-step
= form_with url: checkout_update_path(checkout_step), model: @order, method: :put,
data: { remote: "true" } do |form|

View File

@@ -12,12 +12,12 @@
name: "order[payments_attributes][][payment_method_id]",
checked: (payment_method.id == selected_payment_method),
"data-action": "paymentmethod#selectPaymentMethod",
"data-paymentmethod-id": "#{payment_method.id}",
"data-paymentmethod-id": "paymentmethod#{payment_method.id}",
"data-paymentmethod-target": "input"
= f.label :payment_method_id, "#{payment_method.name}", for: "payment_method_#{payment_method.id}"
%em.fees=payment_or_shipping_price(payment_method, @order)
%em=payment_or_shipping_price(payment_method, @order)
.paymentmethod-container{"data-paymentmethod-id": "#{payment_method.id}", style: "display: #{payment_method.id == selected_payment_method ? "block" : "none"}"}
.paymentmethod-container{"data-paymentmethod-id": "paymentmethod#{payment_method.id}", style: "display: #{payment_method.id == selected_payment_method ? "block" : "none"}"}
- if payment_method.description && !payment_method.description.empty?
.paymentmethod-description.panel
#{payment_method.description}

View File

@@ -1,95 +1,81 @@
.summary-main
= render partial: "split_checkout/already_ordered" if show_bought_items? && checkout_step?(:summary)
.checkout-substep
.checkout-title
= t("split_checkout.step3.delivery_details.title")
%a.summary-edit{href: main_app.checkout_step_path(:details)}
= t("split_checkout.step3.delivery_details.edit")
.medium-10
%div.checkout-substep
%div.checkout-title
= t("split_checkout.step3.your_details.title")
.summary-subtitle
= @order.shipping_method.name
%em.fees= payment_or_shipping_price(@order.shipping_method, @order)
.two-columns
%div
.summary-subtitle
= t("split_checkout.step3.delivery_details.address")
%span
= @order.bill_address.firstname
= @order.bill_address.lastname
%div
= @order.bill_address.phone
%div
= @order.user.email if @order.user
%br
%div
= @order.bill_address.address1
- unless @order.bill_address.address2.blank?
%div
= @order.bill_address.address2
%div
= @order.bill_address.city
%div
= @order.bill_address.state
%div
= @order.bill_address.zipcode
%div
= @order.bill_address.country
- if @order.shipping_method.description.present?
%div
.summary-subtitle
= t("split_checkout.step3.delivery_details.instructions")
%div
= @order.shipping_method.description
%div.summary
%span.summary-label
= t("split_checkout.step1.billing_address.first_name.label")
%span.summary-value
= @order.bill_address.firstname
%div.summary
%span.summary-label
= t("split_checkout.step1.billing_address.last_name.label")
%span.summary-value
= @order.bill_address.lastname
%div.summary
%span.summary-label
= t("split_checkout.step1.contact_information.email.label")
%span.summary-value
= @order.user ? @order.user.email : "Change me"
%hr
%div.summary
%span.summary-label
= t("split_checkout.step1.contact_information.phone.label")
%span.summary-value
= @order.bill_address.phone
.checkout-substep
.checkout-title
%div.checkout-substep
%div.checkout-title
= t("split_checkout.step3.billing_address.title")
= render "summary_address", address: @order.bill_address
%div.checkout-substep
%div.checkout-title
= t("split_checkout.step3.shipping_address.title")
= render "summary_address", address: @order.shipping_address
%div.checkout-substep
%div.checkout-title
= t("split_checkout.step3.delivery_info.title")
%div.summary
%span.summary-label
= t("split_checkout.step1.shipping_info.title")
%span.summary-value
= @order.shipping_method.name
%div.summary-description
= @order.shipping_method.description
%a.summary-edit{href: main_app.checkout_step_path(:details)}
= t("split_checkout.step3.your_details.edit")
%div.checkout-substep
%div.checkout-title
= t("split_checkout.step3.payment_method.title")
%div.summary
%span.summary-value
= last_payment_method(@order)&.name
%div.summary-description
= last_payment_method(@order)&.description
%a.summary-edit{href: main_app.checkout_step_path(:payment)}
= t("split_checkout.step3.payment_method.edit")
.two-columns
%div
- payment_method = last_payment_method(@order)
= payment_method&.name
%em.fees=payment_or_shipping_price(payment_method, @order)
- if payment_method&.description.present?
%div
.summary-subtitle
= t("split_checkout.step3.payment_method.instructions")
%div
= last_payment_method(@order)&.description
%div.checkout-substep
%div.checkout-title
= t("split_checkout.step3.order.title")
%a.summary-edit{href: main_app.cart_path}
= t("split_checkout.step3.order.edit")
= render 'spree/orders/summary', order: @order, display_footer: false
= render 'spree/orders/summary', order: @order
.summary-right{ "data-controller": "sticky", "data-sticky-target": "container" }
.summary-right-line.total
.summary-right-line-label= t :order_total_price
.summary-right-line-value#order_total= @order.display_total.to_html
.summary-right-line
.summary-right-line-label= t :order_produce
.summary-right-line-value= display_checkout_subtotal(@order)
- checkout_adjustments_for(@order, exclude: [:line_item]).reverse_each do |adjustment|
.summary-right-line
.summary-right-line-label= adjustment.label
.summary-right-line-value= adjustment.display_amount.to_html
- if @order.total_tax > 0
.summary-right-line
.summary-right-line-label= t :order_includes_tax
.summary-right-line-value#tax-row= display_checkout_tax_total(@order)
.checkout-submit
- if any_terms_required?(@order.distributor)
= render partial: "terms_and_conditions", locals: { f: f }
= f.submit t("split_checkout.step3.submit"), name: "confirm_order", class: "button primary", disabled: @terms_and_conditions_accepted == false || @platform_tos_accepted == false
.checkout-step3{"data-controller": "sticky", "data-sticky-target": "container"}
- if any_terms_required?(@order.distributor)
= render partial: "terms_and_conditions", locals: { f: f }
.medium-6
.checkout-submit
= f.submit t("split_checkout.step3.submit"), name: "confirm_order", class: "button primary", disabled: @terms_and_conditions_accepted == false || @platform_tos_accepted == false
%a.button.cancel{href: main_app.checkout_step_path(:payment)}
= t("split_checkout.step3.cancel")

View File

@@ -0,0 +1,36 @@
%div.summary
%span.summary-label
= t("split_checkout.step1.address.address1.label")
%span.summary-value
= address.address1
- unless @order.bill_address.address2.blank?
%div.summary
%span.summary-label
= t("split_checkout.step1.address.address2.label")
%span.summary-value
= address.address2
%div.summary
%span.summary-label
= t("split_checkout.step1.address.city.label")
%span.summary-value
= address.city
%div.summary
%span.summary-label
= t("split_checkout.step1.address.state_id.label")
%span.summary-value
= address.state
%div.summary
%span.summary-label
= t("split_checkout.step1.address.zipcode.label")
%span.summary-value
= address.zipcode
%div.summary
%span.summary-label
= t("split_checkout.step1.address.country_id.label")
%span.summary-value
= address.country

View File

@@ -1,4 +1,4 @@
%div.checkout-substep
%div.checkout-substep.medium-6
%div.checkout-input
- if platform_terms_required? && distributor_terms_required?
= f.check_box :accept_terms, { name: "accept_terms", checked: all_terms_and_conditions_already_accepted? }, 1, nil
@@ -14,3 +14,6 @@
= t('split_checkout.step3.terms_and_conditions.message_html', terms_and_conditions_link: link_to( t("split_checkout.step3.terms_and_conditions.link_text"), @order.distributor.terms_and_conditions, target: '_blank'))
= f.error_message_on :terms_and_conditions, standalone: true
%div.checkout-input
= t("split_checkout.step3.agree")

View File

@@ -1,4 +1,4 @@
%div{"data-controller": "stripe-cards", "data-paymentmethod-id": "#{payment_method.id}" }
%div{"data-controller": "stripe-cards"}
- if @saved_credit_cards.any?
.checkout-input
%label

View File

@@ -17,6 +17,14 @@
.row
.alpha.six.columns
%fieldset.security.no-border-bottom
%legend{:align => "center"}= Spree.t(:security_settings)
- @preferences_security.each do |key|
- type = Spree::Config.preference_type(key)
.field
= label_tag(key, Spree.t(key) + ': ') + tag(:br) if type != :boolean
= preference_field_tag(key, Spree::Config[key], :type => type)
= label_tag(key, Spree.t(key)) + tag(:br) if type == :boolean
%fieldset.legal.no-border-bottom
%legend{:align => "center"}= t('.legal_settings')
.field

View File

@@ -20,11 +20,11 @@
%td{:align => "right"}
= item.quantity
%td{:align => "right"}
= display_line_items_taxes(item)
= item.included_tax > 0 ? item.display_included_tax : ""
%td{:align => "right"}
= item.display_amount_with_adjustments
- checkout_adjustments_for(@order, exclude: [:line_item]).reverse_each do |adjustment|
- checkout_adjustments_for(@order, exclude: [:line_item]).reject{ |a| a.amount == 0 }.reverse_each do |adjustment|
- taxable = adjustment.adjustable_type == "Spree::Shipment" ? adjustment.adjustable : adjustment
%tr
%td

View File

@@ -30,7 +30,7 @@
%td{:align => "right"}
= display_line_item_tax_rates(item)
- checkout_adjustments_for(@order, exclude: [:line_item]).reverse_each do |adjustment|
- checkout_adjustments_for(@order, exclude: [:line_item]).reject{ |a| a.amount == 0 }.reverse_each do |adjustment|
%tr
%td
%strong= "#{raw(adjustment.label)}"

View File

@@ -0,0 +1,7 @@
- position ||= ""
.per-page{'ng-show' => '!RequestMonitor.loading && orders.length > 0', class: ("right" if position == "right") }
%input.per-page-select.ofn-select2{type: 'number', data: 'per_page_options', 'min-search' => 999, 'ng-model' => 'per_page', 'ng-change' => 'fetchResults()'}
%span.per-page-feedback
{{ 'spree.admin.orders.index.results_found' | t:{number: pagination.results} }}
{{ 'spree.admin.orders.index.viewing' | t:{start: ((pagination.page -1) * pagination.per_page) +1, end: ((pagination.page -1) * pagination.per_page) + orders.length} }}

View File

@@ -32,7 +32,7 @@
%label{ :for => 'order_cycle_filter' }
= t("admin.order_cycle")
%br
%input#order_cycle_filter.ofn-select2.fullwidth{ type: 'number', 'min-search' => 5, data: 'orderCycles', placeholder: "#{t(:all)}", blank: "{ id: '', name: '#{t(:all)}' }", on: { selecting: "confirmRefresh" }, ng: { model: 'orderCycleFilter' } }
%input#order_cycle_filter.ofn-select2.fullwidth{ type: 'number', 'min-search' => 5, data: 'orderCycles', placeholder: "#{t(:all)}", blank: "{ id: '', name: '#{t(:all)}' }", on: { selecting: "confirmRefresh" }, ng: { model: 'orderCycleFilter', change: "setOrderCycleDateRange()" } }
.date_filter{class: "four columns"}
%label
= t("date_range")
@@ -94,20 +94,14 @@
= t("admin.orders.bulk_management.variants_without_unit_value")
%hr.divider.sixteen.columns.alpha.omega
.clear
%div{ ng: { hide: 'RequestMonitor.loading || line_items.length == 0' }, style: "display: flex; justify-content: flex-start; column-gap: 10px; margin-bottom: 15px" }
%div{ style: "flex-grow: 1" }
.controls.sixteen.columns.alpha.omega{ ng: { hide: 'RequestMonitor.loading || line_items.length == 0' } }
%div.three.columns.alpha
%input.fullwidth{ :type => "text", :id => 'quick_search', 'ng-model' => 'quickSearch', :placeholder => 'Quick Search' }
-# This -20px is a hack to make the dropdowns align properly
%div{ style: "margin-right: -20px;" }
%div.three.columns
= render 'admin/shared/bulk_actions_dropdown'
%div
%div.ten.columns
%columns-dropdown{ action: "#{controller_name}_#{action_name}" }
%div{ style: "flex-grow: 1"}
%div{ style: "float: right;"}
= render partial: 'admin/shared/angular_per_page_controls', locals: { position: "right", model: "line_items" }
%div.sixteen.columns.alpha#loading{ 'ng-if' => 'RequestMonitor.loading' }
= render partial: "components/admin_spinner"
@@ -190,7 +184,4 @@
%td.actions
%a{ 'ng-click' => "deleteLineItem(line_item)", :class => "delete-line-item icon-trash no-text" }
%div{'ng-show' => "!RequestMonitor.loading && line_items.length > 0" }
= render partial: 'admin/shared/angular_pagination'
= render 'spree/admin/shared/custom-confirm'

View File

@@ -30,17 +30,15 @@
="#{t('admin.actions')}".html_safe
%span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" }
%div.menu{ 'ng-show' => "expanded" }
%div.menu_item
%span.name{ "data-controller": "modal-link", "data-action": "click->modal-link#open", "data-modal-link-target-value": "resend_confirmation" }
= t('.resend_confirmation')
%div.menu_item
%span.name.invoices-modal{'ng-controller' => 'bulkInvoiceCtrl', 'ng-click' => 'createBulkInvoice()' }
= t('.print_invoices')
%div.menu_item
%span.name{'ng-controller' => 'bulkCancelCtrl', 'ng-click' => 'cancelSelectedOrders()' }
= t('.cancel_orders')
= render partial: 'admin/shared/angular_per_page_controls', locals: { position: "right", model: "orders" }
= render partial: 'per_page_controls', locals: { position: "right" }
%table#listing_orders.index.responsive{width: "100%", 'ng-init' => 'initialise()', 'ng-show' => "!RequestMonitor.loading && orders.length > 0" }
%colgroup
@@ -65,7 +63,7 @@
%tbody
%tr{ng: {repeat: 'order in orders track by order.id', class: {even: "'even'", odd: "'odd'"}}, 'ng-class' => "{'state-{{order.state}}': true, 'row-loading': rowStatus[order.id] == 'loading'}"}
%td.align-center
%input{type: 'checkbox', 'ng-model' => 'checkboxes[order.id]', 'ng-change' => 'toggleSelection(order.id)', value: '{{order.id}}', name: 'order_ids[]'}
%input{type: 'checkbox', 'ng-model' => 'checkboxes[order.id]', 'ng-change' => 'toggleSelection(order.id)'}
%td.align-center
{{order.distributor_name}}
%td.align-center
@@ -120,7 +118,3 @@
= t('.no_orders_found')
= render 'spree/admin/shared/custom-confirm'
= render ConfirmModalComponent.new(id: "resend_confirmation", confirm_actions: "click->resend-confirmation-email#confirm", controllers: "resend-confirmation-email") do
.margin-bottom-30
= t('.resend_confirmation_confirm_html')

View File

@@ -43,7 +43,7 @@
j(line_item.display_amount_with_adjustments.format(symbol: false, with_currency: false))] }
.join('" + \'\x0A\' + "')}",
'\x0A',
"#{checkout_adjustments_for(@order, exclude: [:line_item], reject_zero_amount: false)
"#{checkout_adjustments_for(@order, exclude: [:line_item])
.reject{ |a| a.amount == 0 }
.reverse.map { |adjustment| '%5s %-27.27s%8.8s' %
["",

View File

@@ -11,8 +11,6 @@
- if flash[:success]
.flash.success= flash[:success]
= render partial: "shared/flashes"
= render partial: "spree/layouts/admin/progress_spinner"
%header#header{"data-hook" => ""}

View File

@@ -40,7 +40,7 @@
= t :email_order_summary_subtotal
%td{align: "right"}
= display_checkout_subtotal(@order)
- checkout_adjustments_for(@order, exclude: [:line_item]).reverse_each do |adjustment|
- checkout_adjustments_for(@order, exclude: [:line_item]).reject{ |a| a.amount == 0 }.reverse_each do |adjustment|
%tr
%td{align: "right", colspan: "3"}
= "#{raw(adjustment.label)}:"

View File

@@ -31,7 +31,7 @@
%span.order-total.item-total= display_checkout_subtotal(@order)
%td
- checkout_adjustments_for(@order, exclude: [:line_item]).reverse_each do |adjustment|
- checkout_adjustments_for(@order, exclude: [:line_item]).reject{ |a| a.amount == 0 }.reverse_each do |adjustment|
%tr.order-adjustment
%td.text-right{:colspan => "3"}
= adjustment.label

View File

@@ -1,5 +1,3 @@
- display_footer = true if display_footer.nil?
%table#line-items{"data-hook" => "order_details"}
%col{valign: "middle"}/
%col{halign: "center", valign: "middle", width: "5%"}/
@@ -28,4 +26,36 @@
%td.text-right.total{"data-hook" => "order_item_total"}
%span= item.display_amount_with_adjustments.to_html
= render partial: "spree/orders/totals_footer", locals: { order: order } if display_footer
%tfoot
#subtotal{"data-hook" => "order_details_subtotal"}
%tr#subtotal-row.total
%td.text-right{colspan: "3"}
%strong
= t :order_produce
%td.text-right.total
%span= display_checkout_subtotal(order)
#order-charges{"data-hook" => "order_details_adjustments"}
- checkout_adjustments_for(order, exclude: [:line_item]).reject{ |a| a.amount == 0 }.reverse_each do |adjustment|
%tr.total
%td.text-right{:colspan => "3"}
%strong
= adjustment.label
%td.text-right.total
%span= adjustment.display_amount.to_html
#order-total{"data-hook" => "order_details_total"}
%tr.total
%td.text-right{colspan: "3"}
%h5
= t :order_total_price
%td.text-right.total
%h5#order_total= order.display_total.to_html
- if order.total_tax > 0
#tax{"data-hook" => "order_details_tax"}
%tr#tax-row.total
%td.text-right{colspan: "3"}
= t :order_includes_tax
%td.text-right.total
%span= display_checkout_tax_total(order)

View File

@@ -1,33 +0,0 @@
%tfoot
#subtotal{"data-hook" => "order_details_subtotal"}
%tr#subtotal-row.total
%td.text-right{colspan: "3"}
%strong
= t :order_produce
%td.text-right.total
%span= display_checkout_subtotal(order)
#order-charges{"data-hook" => "order_details_adjustments"}
- checkout_adjustments_for(order, exclude: [:line_item]).reverse_each do |adjustment|
%tr.total
%td.text-right{:colspan => "3"}
%strong
= adjustment.label
%td.text-right.total
%span= adjustment.display_amount.to_html
#order-total{"data-hook" => "order_details_total"}
%tr.total
%td.text-right{colspan: "3"}
%h5
= t :order_total_price
%td.text-right.total
%h5#order_total= order.display_total.to_html
- if order.total_tax > 0
#tax{"data-hook" => "order_details_tax"}
%tr#tax-row.total
%td.text-right{colspan: "3"}
= t :order_includes_tax
%td.text-right.total
%span= display_checkout_tax_total(order)

View File

@@ -5,6 +5,15 @@ document.addEventListener("turbolinks:before-cache", () =>
);
export default class extends Controller {
connect() {
setTimeout(this.fadeout.bind(this), 3000);
}
fadeout() {
this.element.classList.add("animate-hide-500");
setTimeout(this.close.bind(this), 500);
}
close() {
this.element.remove();
}

View File

@@ -55,7 +55,6 @@ export default class extends Flatpickr {
mode,
};
window.addEventListener("flatpickr:change", this.onChangeEvent.bind(this));
window.addEventListener("flatpickr:clear", this.clear.bind(this));
}
clear(e) {

View File

@@ -1,10 +1,33 @@
import { Controller } from "stimulus";
import { useOpenAndCloseAsAModal } from "./mixins/useOpenAndCloseAsAModal";
export default class extends Controller {
static targets = ["background", "modal"];
connect() {
useOpenAndCloseAsAModal(this);
open() {
this.backgroundTarget.style.display = "block";
this.modalTarget.style.display = "block";
setTimeout(() => {
this.modalTarget.classList.add("in");
this.backgroundTarget.classList.add("in");
document.querySelector("body").classList.add("modal-open");
});
}
close() {
this.modalTarget.classList.remove("in");
this.backgroundTarget.classList.remove("in");
document.querySelector("body").classList.remove("modal-open");
setTimeout(() => {
this.backgroundTarget.style.display = "none";
this.modalTarget.style.display = "none";
}, 200);
}
closeIfEscapeKey(e) {
if (e.code == "Escape") {
this.close();
}
}
}

View File

@@ -1,7 +1,15 @@
import ModalLinkController from "./modal_link_controller";
import { Controller } from "stimulus";
export default class extends ModalLinkController {
getIdentifier() {
return "help-modal";
export default class extends Controller {
static values = { target: String };
open() {
let helpModal = document.getElementById(this.targetValue);
let helpModalController =
this.application.getControllerForElementAndIdentifier(
helpModal,
"help-modal"
);
helpModalController.open();
}
}

View File

@@ -1,31 +0,0 @@
export const useOpenAndCloseAsAModal = (controller) => {
Object.assign(controller, {
open: function () {
this.backgroundTarget.style.display = "block";
this.modalTarget.style.display = "block";
setTimeout(() => {
this.modalTarget.classList.add("in");
this.backgroundTarget.classList.add("in");
document.querySelector("body").classList.add("modal-open");
});
}.bind(controller),
close: function () {
this.modalTarget.classList.remove("in");
this.backgroundTarget.classList.remove("in");
document.querySelector("body").classList.remove("modal-open");
setTimeout(() => {
this.backgroundTarget.style.display = "none";
this.modalTarget.style.display = "none";
}, 200);
}.bind(controller),
closeIfEscapeKey: function (e) {
if (e.code == "Escape") {
this.close();
}
}.bind(controller),
});
};

View File

@@ -1,15 +0,0 @@
import { Controller } from "stimulus";
import { useOpenAndCloseAsAModal } from "./mixins/useOpenAndCloseAsAModal";
export default class extends Controller {
static targets = ["background", "modal"];
connect() {
useOpenAndCloseAsAModal(this);
window.addEventListener("modal:close", this.close.bind(this));
}
disconnect() {
window.removeEventListener("modal:close", this.close);
}
}

View File

@@ -1,18 +0,0 @@
import { Controller } from "stimulus";
export default class extends Controller {
static values = { target: String };
open() {
let modal = document.getElementById(this.targetValue);
let modalController = this.application.getControllerForElementAndIdentifier(
modal,
this.getIdentifier()
);
modalController.open();
}
getIdentifier() {
return "modal";
}
}

View File

@@ -12,12 +12,17 @@ export default class extends Controller {
selectPaymentMethod(event) {
this.setPaymentMethod(event.target.dataset.paymentmethodId);
// Send an event to the right (ie. the one with the same paymentmethodId)
// StripeCardsController to initialize the form elements with the selected card
const customEvent = new CustomEvent("stripecards:initSelectedCard", {
detail: event.target.dataset.paymentmethodId,
});
document.dispatchEvent(customEvent);
const stripeCardSelector =
this.application.getControllerForElementAndIdentifier(
document
.querySelector(
`[data-paymentmethod-id="${event.target.dataset.paymentmethodId}"]`
)
.querySelector('[data-controller="stripe-cards"]'),
"stripe-cards"
);
stripeCardSelector?.initSelectedCard();
}
setPaymentMethod(paymentMethodContainerId) {

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