mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-27 01:43:22 +00:00
Compare commits
1 Commits
v4.2.37
...
10228-spli
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a8f88ba687 |
@@ -2,4 +2,3 @@
|
||||
.gitignore
|
||||
log/*
|
||||
tmp/*
|
||||
node_modules/
|
||||
|
||||
11
.gitattributes
vendored
11
.gitattributes
vendored
@@ -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
|
||||
3
.github/ISSUE_TEMPLATE/release.md
vendored
3
.github/ISSUE_TEMPLATE/release.md
vendored
@@ -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>
|
||||
|
||||
4
.github/dependabot.yml
vendored
4
.github/dependabot.yml
vendored
@@ -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
|
||||
|
||||
2
.github/workflows/brakeman-analysis.yml
vendored
2
.github/workflows/brakeman-analysis.yml
vendored
@@ -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
|
||||
|
||||
|
||||
14
.github/workflows/build.yml
vendored
14
.github/workflows/build.yml
vendored
@@ -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
|
||||
|
||||
8
.github/workflows/linters.yml
vendored
8
.github/workflows/linters.yml
vendored
@@ -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:
|
||||
|
||||
@@ -1 +1 @@
|
||||
14.21.2
|
||||
14.16.1
|
||||
|
||||
@@ -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:
|
||||
@@ -839,6 +850,7 @@ Rails/OutputSafety:
|
||||
- 'lib/reporting/queries/query_builder.rb'
|
||||
- 'lib/reporting/queries/query_interface.rb'
|
||||
- 'lib/spree/money.rb'
|
||||
- 'spec/system/admin/order_print_ticket_spec.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
|
||||
@@ -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} && \
|
||||
|
||||
@@ -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):
|
||||
|
||||
|
||||
18
Gemfile
18
Gemfile
@@ -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,15 +83,16 @@ 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
|
||||
gem 'geocoder'
|
||||
gem 'gmaps4rails'
|
||||
gem 'mimemagic', '> 0.3.5'
|
||||
gem 'paper_trail', '~> 12.1'
|
||||
gem 'paper_trail', '~> 12.1.0'
|
||||
gem 'rack-rewrite'
|
||||
gem 'rack-ssl', require: 'rack/ssl'
|
||||
gem 'roadie-rails'
|
||||
|
||||
gem 'hiredis'
|
||||
@@ -108,8 +109,8 @@ gem 'wicked_pdf'
|
||||
gem 'wkhtmltopdf-binary'
|
||||
|
||||
gem 'immigrant'
|
||||
gem 'roo' # read spreadsheets
|
||||
gem 'spreadsheet_architect' # write spreadsheets
|
||||
gem 'roo'
|
||||
gem 'spreadsheet_architect'
|
||||
|
||||
gem 'whenever', require: false
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -125,6 +126,8 @@ gem 'jquery-rails', '4.4.0'
|
||||
gem 'jquery-ui-rails', '~> 4.2'
|
||||
gem "select2-rails", github: "openfoodfoundation/select2-rails", branch: "v349_with_thor_v1"
|
||||
|
||||
gem 'ofn-qz', github: 'openfoodfoundation/ofn-qz', branch: 'ofn-rails-4'
|
||||
|
||||
gem 'good_migrations'
|
||||
|
||||
gem 'flipper'
|
||||
@@ -182,5 +185,6 @@ group :development do
|
||||
gem 'spring-commands-rspec'
|
||||
gem 'web-console'
|
||||
|
||||
|
||||
gem 'rack-mini-profiler', '< 3.0.0'
|
||||
end
|
||||
|
||||
342
Gemfile.lock
342
Gemfile.lock
@@ -8,6 +8,13 @@ GIT
|
||||
fog-core (~> 1.0)
|
||||
rails (>= 3.2.0, < 7.0)
|
||||
|
||||
GIT
|
||||
remote: https://github.com/openfoodfoundation/ofn-qz.git
|
||||
revision: 467f6ea1c44529c7c91cac4c8211bbd863588c0b
|
||||
branch: ofn-rails-4
|
||||
specs:
|
||||
ofn-qz (0.1.0)
|
||||
|
||||
GIT
|
||||
remote: https://github.com/openfoodfoundation/select2-rails.git
|
||||
revision: fc240e85fbdf1878ff3c39d972c0cd9a312f5ed4
|
||||
@@ -44,42 +51,42 @@ GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
Ascii85 (1.1.0)
|
||||
actioncable (6.1.7.2)
|
||||
actionpack (= 6.1.7.2)
|
||||
activesupport (= 6.1.7.2)
|
||||
actioncable (6.1.7)
|
||||
actionpack (= 6.1.7)
|
||||
activesupport (= 6.1.7)
|
||||
nio4r (~> 2.0)
|
||||
websocket-driver (>= 0.6.1)
|
||||
actionmailbox (6.1.7.2)
|
||||
actionpack (= 6.1.7.2)
|
||||
activejob (= 6.1.7.2)
|
||||
activerecord (= 6.1.7.2)
|
||||
activestorage (= 6.1.7.2)
|
||||
activesupport (= 6.1.7.2)
|
||||
actionmailbox (6.1.7)
|
||||
actionpack (= 6.1.7)
|
||||
activejob (= 6.1.7)
|
||||
activerecord (= 6.1.7)
|
||||
activestorage (= 6.1.7)
|
||||
activesupport (= 6.1.7)
|
||||
mail (>= 2.7.1)
|
||||
actionmailer (6.1.7.2)
|
||||
actionpack (= 6.1.7.2)
|
||||
actionview (= 6.1.7.2)
|
||||
activejob (= 6.1.7.2)
|
||||
activesupport (= 6.1.7.2)
|
||||
actionmailer (6.1.7)
|
||||
actionpack (= 6.1.7)
|
||||
actionview (= 6.1.7)
|
||||
activejob (= 6.1.7)
|
||||
activesupport (= 6.1.7)
|
||||
mail (~> 2.5, >= 2.5.4)
|
||||
rails-dom-testing (~> 2.0)
|
||||
actionpack (6.1.7.2)
|
||||
actionview (= 6.1.7.2)
|
||||
activesupport (= 6.1.7.2)
|
||||
actionpack (6.1.7)
|
||||
actionview (= 6.1.7)
|
||||
activesupport (= 6.1.7)
|
||||
rack (~> 2.0, >= 2.0.9)
|
||||
rack-test (>= 0.6.3)
|
||||
rails-dom-testing (~> 2.0)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
||||
actionpack-action_caching (1.2.2)
|
||||
actionpack (>= 4.0.0)
|
||||
actiontext (6.1.7.2)
|
||||
actionpack (= 6.1.7.2)
|
||||
activerecord (= 6.1.7.2)
|
||||
activestorage (= 6.1.7.2)
|
||||
activesupport (= 6.1.7.2)
|
||||
actiontext (6.1.7)
|
||||
actionpack (= 6.1.7)
|
||||
activerecord (= 6.1.7)
|
||||
activestorage (= 6.1.7)
|
||||
activesupport (= 6.1.7)
|
||||
nokogiri (>= 1.8.5)
|
||||
actionview (6.1.7.2)
|
||||
activesupport (= 6.1.7.2)
|
||||
actionview (6.1.7)
|
||||
activesupport (= 6.1.7)
|
||||
builder (~> 3.1)
|
||||
erubi (~> 1.4)
|
||||
rails-dom-testing (~> 2.0)
|
||||
@@ -91,19 +98,19 @@ GEM
|
||||
activemodel (>= 5.2.0)
|
||||
activestorage (>= 5.2.0)
|
||||
activesupport (>= 5.2.0)
|
||||
activejob (6.1.7.2)
|
||||
activesupport (= 6.1.7.2)
|
||||
activejob (6.1.7)
|
||||
activesupport (= 6.1.7)
|
||||
globalid (>= 0.3.6)
|
||||
activemerchant (1.123.0)
|
||||
activesupport (>= 4.2)
|
||||
builder (>= 2.1.2, < 4.0.0)
|
||||
i18n (>= 0.6.9)
|
||||
nokogiri (~> 1.4)
|
||||
activemodel (6.1.7.2)
|
||||
activesupport (= 6.1.7.2)
|
||||
activerecord (6.1.7.2)
|
||||
activemodel (= 6.1.7.2)
|
||||
activesupport (= 6.1.7.2)
|
||||
activemodel (6.1.7)
|
||||
activesupport (= 6.1.7)
|
||||
activerecord (6.1.7)
|
||||
activemodel (= 6.1.7)
|
||||
activesupport (= 6.1.7)
|
||||
activerecord-import (1.4.1)
|
||||
activerecord (>= 4.2)
|
||||
activerecord-postgresql-adapter (0.0.1)
|
||||
@@ -114,21 +121,21 @@ GEM
|
||||
multi_json (~> 1.11, >= 1.11.2)
|
||||
rack (>= 2.0.8, < 3)
|
||||
railties (>= 5.2.4.1)
|
||||
activestorage (6.1.7.2)
|
||||
actionpack (= 6.1.7.2)
|
||||
activejob (= 6.1.7.2)
|
||||
activerecord (= 6.1.7.2)
|
||||
activesupport (= 6.1.7.2)
|
||||
activestorage (6.1.7)
|
||||
actionpack (= 6.1.7)
|
||||
activejob (= 6.1.7)
|
||||
activerecord (= 6.1.7)
|
||||
activesupport (= 6.1.7)
|
||||
marcel (~> 1.0)
|
||||
mini_mime (>= 1.1.0)
|
||||
activesupport (6.1.7.2)
|
||||
activesupport (6.1.7)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 1.6, < 2)
|
||||
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)
|
||||
@@ -151,16 +158,16 @@ GEM
|
||||
awesome_nested_set (3.5.0)
|
||||
activerecord (>= 4.0.0, < 7.1)
|
||||
aws-eventstream (1.2.0)
|
||||
aws-partitions (1.711.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.1)
|
||||
aws-sdk-s3 (1.117.2)
|
||||
aws-sdk-core (~> 3, >= 3.165.0)
|
||||
aws-sdk-kms (~> 1)
|
||||
aws-sigv4 (~> 1.4)
|
||||
@@ -168,11 +175,11 @@ GEM
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
bcrypt (3.1.18)
|
||||
bigdecimal (3.0.2)
|
||||
bindata (2.4.15)
|
||||
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)
|
||||
@@ -214,7 +221,7 @@ GEM
|
||||
combine_pdf (1.0.22)
|
||||
matrix
|
||||
ruby-rc4 (>= 0.1.5)
|
||||
concurrent-ruby (1.2.2)
|
||||
concurrent-ruby (1.1.10)
|
||||
connection_pool (2.3.0)
|
||||
crack (0.4.5)
|
||||
rexml
|
||||
@@ -230,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)
|
||||
@@ -249,7 +253,7 @@ GEM
|
||||
warden (~> 1.2.3)
|
||||
devise-encryptable (0.2.0)
|
||||
devise (>= 2.1.0)
|
||||
devise-i18n (1.10.3)
|
||||
devise-i18n (1.10.2)
|
||||
devise (>= 4.8.0)
|
||||
devise-token_authenticatable (1.1.0)
|
||||
devise (>= 4.0.0, < 5.0.0)
|
||||
@@ -260,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)
|
||||
@@ -270,12 +274,12 @@ GEM
|
||||
factory_bot_rails (6.2.0)
|
||||
factory_bot (~> 6.2.0)
|
||||
railties (>= 5.0.0)
|
||||
faraday (2.7.4)
|
||||
faraday (2.6.0)
|
||||
faraday-net_http (>= 2.0, < 3.1)
|
||||
ruby2_keywords (>= 0.0.4)
|
||||
faraday-follow_redirects (0.3.0)
|
||||
faraday (>= 1, < 3)
|
||||
faraday-net_http (3.0.2)
|
||||
faraday-net_http (3.0.1)
|
||||
ferrum (0.13)
|
||||
addressable (~> 2.5)
|
||||
concurrent-ruby (~> 1.1)
|
||||
@@ -309,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.1.0)
|
||||
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)
|
||||
@@ -353,7 +361,7 @@ GEM
|
||||
jquery-ui-rails (4.2.1)
|
||||
railties (>= 3.2.16)
|
||||
json (2.6.3)
|
||||
json-jwt (1.16.3)
|
||||
json-jwt (1.16.0)
|
||||
activesupport (>= 4.2)
|
||||
aes_key_wrap
|
||||
bindata
|
||||
@@ -366,28 +374,22 @@ GEM
|
||||
rspec (>= 2.0, < 4.0)
|
||||
jsonapi-serializer (2.2.0)
|
||||
activesupport (>= 4.2)
|
||||
jwt (2.7.0)
|
||||
knapsack_pro (3.8.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)
|
||||
@@ -400,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)
|
||||
@@ -410,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.2.1)
|
||||
net-protocol (0.1.3)
|
||||
timeout
|
||||
net-smtp (0.3.3)
|
||||
net-smtp (0.3.2)
|
||||
net-protocol
|
||||
nio4r (2.5.8)
|
||||
nokogiri (1.14.2)
|
||||
nokogiri (1.13.10)
|
||||
mini_portile2 (~> 2.8.0)
|
||||
racc (~> 1.4)
|
||||
oauth2 (1.4.11)
|
||||
@@ -429,16 +426,13 @@ GEM
|
||||
multi_json (~> 1.3)
|
||||
multi_xml (~> 0.5)
|
||||
rack (>= 1.2, < 4)
|
||||
omniauth (2.1.1)
|
||||
omniauth (2.1.0)
|
||||
hashie (>= 3.4.6)
|
||||
rack (>= 2.2.3)
|
||||
rack-protection
|
||||
omniauth-rails_csrf_protection (1.0.1)
|
||||
actionpack (>= 4.2)
|
||||
omniauth (~> 2.0)
|
||||
omniauth_openid_connect (0.6.1)
|
||||
omniauth (>= 1.9, < 3)
|
||||
openid_connect (~> 1.1)
|
||||
openid_connect (1.4.2)
|
||||
activemodel
|
||||
attr_required (>= 1.0.0)
|
||||
@@ -453,13 +447,13 @@ GEM
|
||||
orm_adapter (0.5.0)
|
||||
pagy (5.10.1)
|
||||
activesupport
|
||||
paper_trail (12.3.0)
|
||||
paper_trail (12.1.0)
|
||||
activerecord (>= 5.2)
|
||||
request_store (~> 1.1)
|
||||
parallel (1.22.1)
|
||||
paranoia (2.6.1)
|
||||
activerecord (>= 5.1, < 7.1)
|
||||
parser (3.2.1.0)
|
||||
parser (3.1.3.0)
|
||||
ast (~> 2.4.1)
|
||||
paypal-sdk-core (0.3.4)
|
||||
multi_json (~> 1.0)
|
||||
@@ -477,12 +471,12 @@ GEM
|
||||
pry (0.13.1)
|
||||
coderay (~> 1.1)
|
||||
method_source (~> 1.0)
|
||||
public_suffix (5.0.1)
|
||||
puma (6.1.1)
|
||||
public_suffix (5.0.0)
|
||||
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)
|
||||
@@ -493,26 +487,28 @@ 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)
|
||||
rails (6.1.7.2)
|
||||
actioncable (= 6.1.7.2)
|
||||
actionmailbox (= 6.1.7.2)
|
||||
actionmailer (= 6.1.7.2)
|
||||
actionpack (= 6.1.7.2)
|
||||
actiontext (= 6.1.7.2)
|
||||
actionview (= 6.1.7.2)
|
||||
activejob (= 6.1.7.2)
|
||||
activemodel (= 6.1.7.2)
|
||||
activerecord (= 6.1.7.2)
|
||||
activestorage (= 6.1.7.2)
|
||||
activesupport (= 6.1.7.2)
|
||||
rails (6.1.7)
|
||||
actioncable (= 6.1.7)
|
||||
actionmailbox (= 6.1.7)
|
||||
actionmailer (= 6.1.7)
|
||||
actionpack (= 6.1.7)
|
||||
actiontext (= 6.1.7)
|
||||
actionview (= 6.1.7)
|
||||
activejob (= 6.1.7)
|
||||
activemodel (= 6.1.7)
|
||||
activerecord (= 6.1.7)
|
||||
activestorage (= 6.1.7)
|
||||
activesupport (= 6.1.7)
|
||||
bundler (>= 1.15.0)
|
||||
railties (= 6.1.7.2)
|
||||
railties (= 6.1.7)
|
||||
sprockets-rails (>= 2.0.0)
|
||||
rails-controller-testing (1.0.5)
|
||||
actionpack (>= 5.0.1.rc1)
|
||||
@@ -526,39 +522,37 @@ 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)
|
||||
railties (>= 6.0.0, < 8)
|
||||
rails_safe_tasks (1.0.0)
|
||||
railties (6.1.7.2)
|
||||
actionpack (= 6.1.7.2)
|
||||
activesupport (= 6.1.7.2)
|
||||
railties (6.1.7)
|
||||
actionpack (= 6.1.7)
|
||||
activesupport (= 6.1.7)
|
||||
method_source
|
||||
rake (>= 12.2)
|
||||
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)
|
||||
redis (4.8.1)
|
||||
redis-client (0.13.0)
|
||||
connection_pool
|
||||
regexp_parser (2.7.0)
|
||||
redcarpet (3.5.1)
|
||||
redis (4.8.0)
|
||||
regexp_parser (2.6.1)
|
||||
reline (0.3.2)
|
||||
io-console (~> 0.5)
|
||||
request_store (1.5.1)
|
||||
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)
|
||||
@@ -569,32 +563,32 @@ GEM
|
||||
rodf (1.2.0)
|
||||
builder (>= 3.0)
|
||||
rubyzip (>= 1.0)
|
||||
roo (2.10.0)
|
||||
roo (2.9.0)
|
||||
nokogiri (~> 1)
|
||||
rubyzip (>= 1.3.0, < 3.0.0)
|
||||
rspec (3.12.0)
|
||||
rspec-core (~> 3.12.0)
|
||||
rspec-expectations (~> 3.12.0)
|
||||
rspec-mocks (~> 3.12.0)
|
||||
rspec-core (3.12.1)
|
||||
rspec-support (~> 3.12.0)
|
||||
rspec-expectations (3.12.2)
|
||||
rspec (3.10.0)
|
||||
rspec-core (~> 3.10.0)
|
||||
rspec-expectations (~> 3.10.0)
|
||||
rspec-mocks (~> 3.10.0)
|
||||
rspec-core (3.10.2)
|
||||
rspec-support (~> 3.10.0)
|
||||
rspec-expectations (3.10.2)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.12.0)
|
||||
rspec-mocks (3.12.3)
|
||||
rspec-support (~> 3.10.0)
|
||||
rspec-mocks (3.10.2)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.12.0)
|
||||
rspec-rails (6.0.1)
|
||||
actionpack (>= 6.1)
|
||||
activesupport (>= 6.1)
|
||||
railties (>= 6.1)
|
||||
rspec-core (~> 3.11)
|
||||
rspec-expectations (~> 3.11)
|
||||
rspec-mocks (~> 3.11)
|
||||
rspec-support (~> 3.11)
|
||||
rspec-support (~> 3.10.0)
|
||||
rspec-rails (5.1.2)
|
||||
actionpack (>= 5.2)
|
||||
activesupport (>= 5.2)
|
||||
railties (>= 5.2)
|
||||
rspec-core (~> 3.10)
|
||||
rspec-expectations (~> 3.10)
|
||||
rspec-mocks (~> 3.10)
|
||||
rspec-support (~> 3.10)
|
||||
rspec-retry (0.6.2)
|
||||
rspec-core (> 3.3)
|
||||
rspec-support (3.12.0)
|
||||
rspec-support (3.10.3)
|
||||
rswag-api (2.8.0)
|
||||
railties (>= 3.1, < 7.1)
|
||||
rswag-specs (2.8.0)
|
||||
@@ -605,25 +599,25 @@ GEM
|
||||
rswag-ui (2.8.0)
|
||||
actionpack (>= 3.1, < 7.1)
|
||||
railties (>= 3.1, < 7.1)
|
||||
rubocop (1.47.0)
|
||||
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.26.0, < 2.0)
|
||||
rubocop-ast (>= 1.24.1, < 2.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (>= 2.4.0, < 3.0)
|
||||
rubocop-ast (1.27.0)
|
||||
parser (>= 3.2.1.0)
|
||||
rubocop-rails (2.18.0)
|
||||
unicode-display_width (>= 1.4.0, < 3.0)
|
||||
rubocop-ast (1.24.1)
|
||||
parser (>= 3.1.1.0)
|
||||
rubocop-rails (2.17.4)
|
||||
activesupport (>= 4.2.0)
|
||||
rack (>= 1.1)
|
||||
rubocop (>= 1.33.0, < 2.0)
|
||||
ruby-graphviz (1.2.5)
|
||||
rexml
|
||||
ruby-progressbar (1.12.0)
|
||||
ruby-progressbar (1.11.0)
|
||||
ruby-rc4 (0.1.5)
|
||||
ruby-vips (2.1.4)
|
||||
ffi (~> 1.12)
|
||||
@@ -642,14 +636,14 @@ GEM
|
||||
semantic_range (3.0.0)
|
||||
shoulda-matchers (5.3.0)
|
||||
activesupport (>= 5.2.0)
|
||||
sidekiq (7.0.6)
|
||||
concurrent-ruby (< 2)
|
||||
connection_pool (>= 2.3.0)
|
||||
rack (>= 2.2.4)
|
||||
redis-client (>= 0.11.0)
|
||||
sidekiq-scheduler (5.0.2)
|
||||
sidekiq (6.5.8)
|
||||
connection_pool (>= 2.2.5, < 3)
|
||||
rack (~> 2.0)
|
||||
redis (>= 4.5.0, < 5)
|
||||
sidekiq-scheduler (4.0.3)
|
||||
redis (>= 4.2.0)
|
||||
rufus-scheduler (~> 3.2)
|
||||
sidekiq (>= 6, < 8)
|
||||
sidekiq (>= 4, < 7)
|
||||
tilt (>= 1.4.0)
|
||||
simplecov (0.22.0)
|
||||
docile (~> 1.1)
|
||||
@@ -660,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)
|
||||
@@ -688,7 +682,7 @@ GEM
|
||||
railties (>= 5.2)
|
||||
redis
|
||||
stringex (2.8.5)
|
||||
stripe (8.3.0)
|
||||
stripe (8.0.0)
|
||||
swd (1.3.0)
|
||||
activesupport (>= 3)
|
||||
attr_required (>= 0.0.5)
|
||||
@@ -698,15 +692,15 @@ GEM
|
||||
power_assert
|
||||
thor (1.2.1)
|
||||
thread-local (1.1.0)
|
||||
tilt (2.1.0)
|
||||
tilt (2.0.11)
|
||||
timecop (0.9.6)
|
||||
timeout (0.3.2)
|
||||
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)
|
||||
@@ -716,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)
|
||||
@@ -738,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)
|
||||
@@ -755,7 +749,7 @@ GEM
|
||||
xml-simple (1.1.8)
|
||||
xpath (3.2.0)
|
||||
nokogiri (~> 1.8)
|
||||
zeitwerk (2.6.7)
|
||||
zeitwerk (2.6.6)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
@@ -768,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
|
||||
@@ -809,6 +803,7 @@ DEPENDENCIES
|
||||
foreman
|
||||
fuubar (~> 2.5.1)
|
||||
geocoder
|
||||
gitlab-omniauth-openid-connect
|
||||
gmaps4rails
|
||||
good_migrations
|
||||
haml
|
||||
@@ -830,15 +825,15 @@ 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)
|
||||
paper_trail (~> 12.1)
|
||||
paper_trail (~> 12.1.0)
|
||||
paranoia (~> 2.4)
|
||||
paypal-sdk-merchant (= 1.117.2)
|
||||
pdf-reader
|
||||
@@ -847,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
|
||||
@@ -898,4 +894,4 @@ RUBY VERSION
|
||||
ruby 3.0.3p157
|
||||
|
||||
BUNDLED WITH
|
||||
2.4.3
|
||||
2.1.4
|
||||
|
||||
@@ -33,7 +33,7 @@ We also have a [Super Admin Guide][super-admin-guide] to help with configuration
|
||||
|
||||
## Testing
|
||||
|
||||
If you'd like to help out with testing, please introduce yourself on the #testing channel on [Slack][slack-invite] and download the [ZenHub browser extension][zenhub] to view the development pipeline. Also, do have a look in our [Welcome New QAs board][welcome-qa] for some good first issues, both on manual and automated testing (RSpec/Capybara).
|
||||
If you'd like to help out with testing, please introduce yourself on the #testing channel on [Slack][slack-invite] and download the [ZenHub browser extension][zenhub] to view the development pipeline. Also, do have a look in our [Welcome New QAs board](https://github.com/orgs/openfoodfoundation/projects/1) for some good first issues, both on manual and automated testing (RSpec/Capybara).
|
||||
|
||||
We use [BrowserStack](https://www.browserstack.com/) as a manual testing tool. BrowserStack provides open source projects with unlimited and free of charge accounts. A big thanks to them!
|
||||
|
||||
@@ -52,6 +52,5 @@ Copyright (c) 2012 - 2022 Open Food Foundation, released under the AGPL licence.
|
||||
[ofn-handbook]: https://ofn-user-guide.gitbook.io/ofn-handbook/
|
||||
[ofn-install]: https://github.com/openfoodfoundation/ofn-install
|
||||
[super-admin-guide]: https://ofn-user-guide.gitbook.io/ofn-super-admin-guide
|
||||
[welcome-dev]: https://github.com/orgs/openfoodfoundation/projects/5
|
||||
[welcome-qa]: https://github.com/orgs/openfoodfoundation/projects/6
|
||||
[welcome-dev]: https://github.com/orgs/openfoodfoundation/projects/2
|
||||
[zenhub]: https://www.zenhub.com/extension
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -35,11 +35,7 @@ angular.module('admin.orderCycles')
|
||||
OrderCycle.removeExchangeFee(exchange, index)
|
||||
$scope.order_cycle_form.$dirty = true
|
||||
|
||||
$scope.setPickupTimeFieldDirty = (index, pickup_time) ->
|
||||
# if the pickup_time is already set we are in edit mode, so no need to set pickup_time field as dirty
|
||||
# to show it is required (it has a red border when set to dirty)
|
||||
return if pickup_time
|
||||
|
||||
$scope.setPickupTimeFieldDirty = (index) ->
|
||||
$timeout ->
|
||||
pickup_time_field_name = "order_cycle_outgoing_exchange_" + index + "_pickup_time"
|
||||
$scope.order_cycle_form[pickup_time_field_name].$setDirty()
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
angular.module("admin.orders").controller "bulkCancelCtrl", ($scope, $http, $timeout) ->
|
||||
|
||||
$scope.cancelOrder = (orderIds, sendEmailCancellation, restock_items) ->
|
||||
$http(
|
||||
method: 'post'
|
||||
url: "/admin/orders/bulk_cancel?order_ids=#{orderIds}&send_cancellation_email=#{sendEmailCancellation}&restock_items=#{restock_items}" ).then(->
|
||||
window.location.reload()
|
||||
)
|
||||
|
||||
$scope.cancelSelectedOrders = ->
|
||||
ofnCancelOrderAlert((confirm, sendEmailCancellation, restock_items) ->
|
||||
if confirm
|
||||
$scope.cancelOrder $scope.selected_orders, sendEmailCancellation, restock_items
|
||||
)
|
||||
@@ -7,12 +7,8 @@ angular.module('Darkswarm').controller "RegistrationFormCtrl", ($scope, Registra
|
||||
form.$valid
|
||||
|
||||
$scope.create = (form) ->
|
||||
if ($scope.valid(form))
|
||||
$scope.disableButton()
|
||||
EnterpriseRegistrationService.create().then(() ->
|
||||
$scope.enableButton()
|
||||
)
|
||||
end
|
||||
$scope.disableButton()
|
||||
EnterpriseRegistrationService.create($scope.enableButton) if $scope.valid(form)
|
||||
|
||||
$scope.update = (nextStep, form) ->
|
||||
EnterpriseRegistrationService.update(nextStep) if $scope.valid(form)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
5
app/assets/javascripts/iehack.js
Normal file
5
app/assets/javascripts/iehack.js
Normal file
@@ -0,0 +1,5 @@
|
||||
$( document ).ready(function() {
|
||||
$("#closeie").click(function() {
|
||||
$("#ie-warning").hide();
|
||||
});
|
||||
})
|
||||
9227
app/assets/javascripts/shared/jquery-1.8.0.js
vendored
Normal file
9227
app/assets/javascripts/shared/jquery-1.8.0.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,13 +1,11 @@
|
||||
.ofn-drop-down.ofn-drop-down-v2.right#columns-dropdown{ ng: { controller: 'ColumnsDropdownCtrl' } }
|
||||
.ofn-drop-down-label
|
||||
= " #{t('admin.columns')}".html_safe
|
||||
%span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" }
|
||||
.ofn-drop-down.right#columns-dropdown{ ng: { controller: 'ColumnsDropdownCtrl' } }
|
||||
%span{ :class => 'icon-reorder' }= " #{t('admin.columns')}".html_safe
|
||||
%span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" }
|
||||
%div.menu{ 'ng-show' => "expanded" }
|
||||
.menu_items
|
||||
.menu_item{ ng: { repeat: "column in columns", click: "toggle(column);" } }
|
||||
%input.redesigned-input{ type: "checkbox", ng: { checked: "column.visible" } }
|
||||
{{ column.name }}
|
||||
%hr
|
||||
%div.menu_item.text-center
|
||||
%input.fullwidth.orange{ type: "button", ng: { value: "saved() ? 'Saved': 'Saving'", show: "saved() || saving", disabled: "saved()" } }
|
||||
%input.fullwidth.red{ type: "button", :value => t('admin.column_save_as_default').html_safe, ng: { show: "!saved() && !saving", click: "saveColumnPreferences(action)"} }
|
||||
%div.menu_item{ ng: { repeat: "column in columns", click: "toggle(column)", class: "{selected: column.visible}" } }
|
||||
%span.check
|
||||
%span.name {{ column.name }}
|
||||
%hr
|
||||
%div.menu_item.text-center
|
||||
%input.fullwidth.orange{ type: "button", ng: { value: "saved() ? 'Saved': 'Saving'", show: "saved() || saving", disabled: "saved()" } }
|
||||
%input.fullwidth.red{ type: "button", :value => t('admin.column_save_as_default').html_safe, ng: { show: "!saved() && !saving", click: "saveColumnPreferences(action)"} }
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class ConfirmModalComponent < ModalComponent
|
||||
def initialize(id:, confirm_actions: nil, controllers: nil, message: nil)
|
||||
super(id: id, close_button: true)
|
||||
@confirm_actions = confirm_actions
|
||||
@controllers = controllers
|
||||
@message = message
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def close_button_class
|
||||
"secondary"
|
||||
end
|
||||
end
|
||||
@@ -1,10 +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
|
||||
|
||||
= render @message if @message
|
||||
|
||||
.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 }
|
||||
@@ -1,4 +0,0 @@
|
||||
.modal-actions {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -1,26 +1,18 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class ProductComponent < ViewComponentReflex::Component
|
||||
DATETIME_FORMAT = '%F %T'
|
||||
|
||||
def initialize(product:, columns:)
|
||||
super
|
||||
@product = product
|
||||
@image = @product.images[0] if product.images.any?
|
||||
@columns = columns.map do |c|
|
||||
@columns = columns.map { |c|
|
||||
{
|
||||
id: c[:value],
|
||||
value: column_value(c[:value])
|
||||
}
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
# This must be define when using ProductComponent.with_collection()
|
||||
def collection_key
|
||||
@product.id
|
||||
end
|
||||
|
||||
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength
|
||||
def column_value(column)
|
||||
case column
|
||||
when 'name'
|
||||
@@ -33,27 +25,6 @@ class ProductComponent < ViewComponentReflex::Component
|
||||
@product.supplier.name
|
||||
when 'category'
|
||||
@product.taxons.map(&:name).join(', ')
|
||||
when 'sku'
|
||||
@product.sku
|
||||
when 'on_hand'
|
||||
@product.on_hand || 0
|
||||
when 'on_demand'
|
||||
@product.on_demand
|
||||
when 'tax_category'
|
||||
@product.tax_category.name
|
||||
when 'inherits_properties'
|
||||
@product.inherits_properties
|
||||
when 'available_on'
|
||||
format_date(@product.available_on)
|
||||
when 'import_date'
|
||||
format_date(@product.import_date)
|
||||
end
|
||||
end
|
||||
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/MethodLength
|
||||
|
||||
private
|
||||
|
||||
def format_date(date)
|
||||
date&.strftime(DATETIME_FORMAT) || ''
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,37 +3,27 @@
|
||||
class ProductsTableComponent < ViewComponentReflex::Component
|
||||
include Pagy::Backend
|
||||
|
||||
SORTABLE_COLUMNS = ['name', 'import_date'].freeze
|
||||
SELECTABLE_COLUMNS = [
|
||||
{ label: I18n.t("admin.products_page.columns_selector.price"), value: "price" },
|
||||
{ label: I18n.t("admin.products_page.columns_selector.unit"), value: "unit" },
|
||||
{ label: I18n.t("admin.products_page.columns_selector.producer"), value: "producer" },
|
||||
{ label: I18n.t("admin.products_page.columns_selector.category"), value: "category" },
|
||||
{ label: I18n.t("admin.products_page.columns_selector.sku"), value: "sku" },
|
||||
{ label: I18n.t("admin.products_page.columns_selector.on_hand"), value: "on_hand" },
|
||||
{ label: I18n.t("admin.products_page.columns_selector.on_demand"), value: "on_demand" },
|
||||
{ label: I18n.t("admin.products_page.columns_selector.tax_category"), value: "tax_category" },
|
||||
{
|
||||
label: I18n.t("admin.products_page.columns_selector.inherits_properties"),
|
||||
value: "inherits_properties"
|
||||
},
|
||||
{ label: I18n.t("admin.products_page.columns_selector.available_on"), value: "available_on" },
|
||||
{ label: I18n.t("admin.products_page.columns_selector.import_date"), value: "import_date" }
|
||||
].sort do |a, b|
|
||||
SORTABLE_COLUMNS = ["name"].freeze
|
||||
SELECTABLE_COMUMNS = [{ label: I18n.t("admin.products_page.columns_selector.price"),
|
||||
value: "price" },
|
||||
{ label: I18n.t("admin.products_page.columns_selector.unit"),
|
||||
value: "unit" },
|
||||
{ label: I18n.t("admin.products_page.columns_selector.producer"),
|
||||
value: "producer" },
|
||||
{ label: I18n.t("admin.products_page.columns_selector.category"),
|
||||
value: "category" }].sort { |a, b|
|
||||
a[:label] <=> b[:label]
|
||||
end.freeze
|
||||
|
||||
}.freeze
|
||||
PER_PAGE_VALUE = [10, 25, 50, 100].freeze
|
||||
PER_PAGE = PER_PAGE_VALUE.map { |value| { label: value, value: value } }
|
||||
NAME_COLUMN = {
|
||||
label: I18n.t("admin.products_page.columns.name"), value: "name", sortable: true
|
||||
}.freeze
|
||||
NAME_COLUMN = { label: I18n.t("admin.products_page.columns.name"), value: "name",
|
||||
sortable: true }.freeze
|
||||
|
||||
def initialize(user:)
|
||||
super
|
||||
@user = user
|
||||
@selectable_columns = SELECTABLE_COLUMNS
|
||||
@columns_selected = ['unit', 'price', 'on_hand', 'category', 'import_date']
|
||||
@selectable_columns = SELECTABLE_COMUMNS
|
||||
@columns_selected = ["price", "unit"]
|
||||
@per_page = PER_PAGE
|
||||
@per_page_selected = [10]
|
||||
@categories = [{ label: "All", value: "all" }] +
|
||||
@@ -50,20 +40,16 @@ class ProductsTableComponent < ViewComponentReflex::Component
|
||||
@search_term = ""
|
||||
end
|
||||
|
||||
# any change on a "reflex_data_attributes" (defined in the template) will trigger a re render
|
||||
def before_render
|
||||
fetch_products
|
||||
refresh_columns
|
||||
end
|
||||
|
||||
# Element refers to the component the data is set on
|
||||
def search_term
|
||||
# Element is SearchInputComponent
|
||||
@search_term = element.dataset['value']
|
||||
end
|
||||
|
||||
def toggle_column
|
||||
# Element is SelectorComponent
|
||||
column = element.dataset['value']
|
||||
@columns_selected = if @columns_selected.include?(column)
|
||||
@columns_selected - [column]
|
||||
@@ -73,33 +59,26 @@ class ProductsTableComponent < ViewComponentReflex::Component
|
||||
end
|
||||
|
||||
def click_sort
|
||||
# Element is TableHeaderComponent
|
||||
@sort = {
|
||||
column: element.dataset['sort-value'],
|
||||
direction: element.dataset['sort-direction'] == "asc" ? "desc" : "asc"
|
||||
}
|
||||
@sort = { column: element.dataset['sort-value'],
|
||||
direction: element.dataset['sort-direction'] == "asc" ? "desc" : "asc" }
|
||||
end
|
||||
|
||||
def toggle_per_page
|
||||
# Element is SelectorComponent
|
||||
selected = element.dataset['value'].to_i
|
||||
@per_page_selected = [selected] if PER_PAGE_VALUE.include?(selected)
|
||||
end
|
||||
|
||||
def toggle_category
|
||||
# Element is SelectorWithFilterComponent
|
||||
category_clicked = element.dataset['value']
|
||||
@categories_selected = toggle_selector_with_filter(category_clicked, @categories_selected)
|
||||
end
|
||||
|
||||
def toggle_producer
|
||||
# Element is SelectorWithFilterComponent
|
||||
producer_clicked = element.dataset['value']
|
||||
@producers_selected = toggle_selector_with_filter(producer_clicked, @producers_selected)
|
||||
end
|
||||
|
||||
def change_page
|
||||
# Element is PaginationComponent
|
||||
page = element.dataset['page'].to_i
|
||||
@page = page if page > 0
|
||||
end
|
||||
@@ -107,13 +86,10 @@ class ProductsTableComponent < ViewComponentReflex::Component
|
||||
private
|
||||
|
||||
def refresh_columns
|
||||
@columns = @columns_selected.map do |column|
|
||||
{
|
||||
label: I18n.t("admin.products_page.columns.#{column}"),
|
||||
value: column,
|
||||
sortable: SORTABLE_COLUMNS.include?(column)
|
||||
}
|
||||
end.sort! { |a, b| a[:label] <=> b[:label] }
|
||||
@columns = @columns_selected.map { |column|
|
||||
{ label: I18n.t("admin.products_page.columns.#{column}"), value: column,
|
||||
sortable: SORTABLE_COLUMNS.include?(column) }
|
||||
}.sort! { |a, b| a[:label] <=> b[:label] }
|
||||
@columns.unshift(NAME_COLUMN)
|
||||
end
|
||||
|
||||
@@ -169,13 +145,8 @@ class ProductsTableComponent < ViewComponentReflex::Component
|
||||
def product_query_includes
|
||||
[
|
||||
master: [:images],
|
||||
variants: [
|
||||
:default_price,
|
||||
:stock_locations,
|
||||
:stock_items,
|
||||
:variant_overrides,
|
||||
{ option_values: :option_type }
|
||||
]
|
||||
variants: [:default_price, :stock_locations, :stock_items, :variant_overrides,
|
||||
{ option_values: :option_type }]
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -18,6 +18,7 @@ module Admin
|
||||
params.require(:preferences).permit(
|
||||
:enable_invoices?,
|
||||
:invoice_style2?,
|
||||
:enable_receipt_printing?,
|
||||
:enterprise_number_required_on_invoices?,
|
||||
)
|
||||
end
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -61,7 +61,7 @@ module Api
|
||||
def search_customers
|
||||
customers = visible_customers.includes(:bill_address, :ship_address)
|
||||
customers = customers.where(enterprise_id: params[:enterprise_id]) if params[:enterprise_id]
|
||||
customers.ransack(params[:q]).result.order(:id)
|
||||
customers.ransack(params[:q]).result
|
||||
end
|
||||
|
||||
def visible_customers
|
||||
|
||||
@@ -15,9 +15,7 @@ module CheckoutCallbacks
|
||||
prepend_before_action :require_distributor_chosen
|
||||
|
||||
before_action :load_order, :associate_user, :load_saved_addresses, :load_saved_credit_cards
|
||||
before_action :allowed_shipping_methods, if: -> {
|
||||
params[:step] == "details"
|
||||
}
|
||||
before_action :load_shipping_methods, if: -> { params[:step] == "details" }
|
||||
|
||||
before_action :ensure_order_not_completed
|
||||
before_action :ensure_checkout_allowed
|
||||
@@ -48,22 +46,8 @@ module CheckoutCallbacks
|
||||
@selected_card = nil
|
||||
end
|
||||
|
||||
def allowed_shipping_methods
|
||||
@allowed_shipping_methods ||= sorted_available_shipping_methods.filter(
|
||||
&method(:supports_all_products_shipping_categories?)
|
||||
)
|
||||
end
|
||||
|
||||
def sorted_available_shipping_methods
|
||||
available_shipping_methods.sort { |a, b| a.name.casecmp(b.name) }
|
||||
end
|
||||
|
||||
def supports_all_products_shipping_categories?(shipping_method)
|
||||
(products_shipping_categories - shipping_method.shipping_categories.pluck(:id)).empty?
|
||||
end
|
||||
|
||||
def products_shipping_categories
|
||||
@products_shipping_categories ||= @order.products.pluck(:shipping_category_id).uniq
|
||||
def load_shipping_methods
|
||||
@shipping_methods = available_shipping_methods.sort { |a, b| a.name.casecmp(b.name) }
|
||||
end
|
||||
|
||||
def redirect_to_shop?
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -4,11 +4,6 @@ class ErrorsController < ApplicationController
|
||||
layout "errors"
|
||||
|
||||
def not_found
|
||||
Bugsnag.notify("404") do |event|
|
||||
event.severity = "info"
|
||||
|
||||
event.add_metadata(:request, request.env)
|
||||
end
|
||||
render status: :not_found
|
||||
end
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ class SplitCheckoutController < ::BaseController
|
||||
check_step if params[:step]
|
||||
recalculate_tax if params[:step] == "summary"
|
||||
|
||||
flash_error_when_no_shipping_method_available if allowed_shipping_methods.none?
|
||||
flash_error_when_no_shipping_method_available if available_shipping_methods.none?
|
||||
end
|
||||
|
||||
def update
|
||||
@@ -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,61 +50,6 @@ class SplitCheckoutController < ::BaseController
|
||||
|
||||
private
|
||||
|
||||
def render_error
|
||||
flash.now[:error] ||= I18n.t(
|
||||
'split_checkout.errors.saving_failed',
|
||||
messages: order_error_messages
|
||||
)
|
||||
|
||||
render status: :unprocessable_entity, operations: cable_car.
|
||||
replace("#checkout", partial("split_checkout/checkout")).
|
||||
replace("#flashes", partial("shared/flashes", locals: { flashes: flash }))
|
||||
end
|
||||
|
||||
def order_error_messages
|
||||
# Remove ship_address.* errors if no shipping method is not selected
|
||||
remove_ship_address_errors if no_ship_address_needed?
|
||||
|
||||
# Reorder errors to make sure the most important ones are shown first
|
||||
# and finally, return the error messages to sentence
|
||||
reorder_errors.map(&:full_message).to_sentence
|
||||
end
|
||||
|
||||
def no_ship_address_needed?
|
||||
@order.errors[:shipping_method].present? || params[:ship_address_same_as_billing] == "1"
|
||||
end
|
||||
|
||||
def remove_ship_address_errors
|
||||
@order.errors.delete("ship_address.firstname")
|
||||
@order.errors.delete("ship_address.address1")
|
||||
@order.errors.delete("ship_address.city")
|
||||
@order.errors.delete("ship_address.phone")
|
||||
@order.errors.delete("ship_address.lastname")
|
||||
@order.errors.delete("ship_address.zipcode")
|
||||
end
|
||||
|
||||
def reorder_errors
|
||||
@order.errors.sort_by do |e|
|
||||
case e.attribute
|
||||
when /email/i then 0
|
||||
when /phone/i then 1
|
||||
when /bill_address/i then 2 + bill_address_error_order(e)
|
||||
else 20
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def bill_address_error_order(error)
|
||||
case error.attribute
|
||||
when /firstname/i then 0
|
||||
when /lastname/i then 1
|
||||
when /address1/i then 2
|
||||
when /city/i then 3
|
||||
when /zipcode/i then 4
|
||||
else 5
|
||||
end
|
||||
end
|
||||
|
||||
def flash_error_when_no_shipping_method_available
|
||||
flash[:error] = I18n.t('split_checkout.errors.no_shipping_methods_available')
|
||||
end
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -9,13 +9,15 @@ module Spree
|
||||
helper CheckoutHelper
|
||||
|
||||
before_action :load_order, only: [:edit, :update, :fire, :resend,
|
||||
:invoice, :print]
|
||||
:invoice, :print, :print_ticket]
|
||||
before_action :load_distribution_choices, only: [:new, :edit, :update]
|
||||
|
||||
# Ensure that the distributor is set for an order when
|
||||
before_action :ensure_distribution, only: :new
|
||||
before_action :require_distributor_abn, only: :invoice
|
||||
|
||||
content_security_policy false, only: :print_ticket
|
||||
|
||||
respond_to :html, :json
|
||||
|
||||
def new
|
||||
@@ -65,6 +67,18 @@ module Spree
|
||||
load_spree_api_key
|
||||
end
|
||||
|
||||
def bulk_cancel
|
||||
order_ids = params[:order_ids].split(',')
|
||||
|
||||
Spree::Order.where(id: order_ids).find_each do |order|
|
||||
order.send_cancellation_email = params[:send_cancellation_email] != "false"
|
||||
order.restock_items = params.fetch(:restock_items, "true") == "true"
|
||||
order.cancel
|
||||
end
|
||||
|
||||
flash[:success] = Spree.t(:order_updated)
|
||||
end
|
||||
|
||||
def fire
|
||||
event = params[:e]
|
||||
@order.send_cancellation_email = params[:send_cancellation_email] != "false"
|
||||
@@ -103,6 +117,10 @@ module Spree
|
||||
render_with_wicked_pdf InvoiceRenderer.new.args(@order)
|
||||
end
|
||||
|
||||
def print_ticket
|
||||
render template: "spree/admin/orders/ticket", layout: false
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def order_params
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -27,7 +27,7 @@ module Spree
|
||||
private
|
||||
|
||||
def complete_order_links
|
||||
[resend_confirmation_link] + invoice_links
|
||||
[resend_confirmation_link] + invoice_links + ticket_links
|
||||
end
|
||||
|
||||
def invoice_links
|
||||
@@ -52,6 +52,12 @@ module Spree
|
||||
end
|
||||
end
|
||||
|
||||
def ticket_links
|
||||
return [] unless Spree::Config[:enable_receipt_printing?]
|
||||
|
||||
[print_ticket_link, select_ticket_printer_link]
|
||||
end
|
||||
|
||||
def edit_order_link
|
||||
{ name: t(:edit_order),
|
||||
url: spree.edit_admin_order_path(@order),
|
||||
@@ -94,6 +100,20 @@ module Spree
|
||||
confirm: t(:must_have_valid_business_number, enterprise_name: @order.distributor.name) }
|
||||
end
|
||||
|
||||
def print_ticket_link
|
||||
{ name: t(:print_ticket),
|
||||
url: print_ticket_admin_order_path(@order),
|
||||
icon: 'icon-print',
|
||||
target: "_blank" }
|
||||
end
|
||||
|
||||
def select_ticket_printer_link
|
||||
{ name: t(:select_ticket_printer),
|
||||
url: "#{print_ticket_admin_order_path(@order)}#select-printer",
|
||||
icon: 'icon-print',
|
||||
target: "_blank" }
|
||||
end
|
||||
|
||||
def ship_order_link
|
||||
{ name: t(:ship_order),
|
||||
url: spree.fire_admin_order_path(@order, e: 'ship'),
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -1,6 +1,6 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class BulkInvoiceJob < ApplicationJob
|
||||
class BulkInvoiceJob < ActiveJob::Base
|
||||
def perform(order_ids, filepath)
|
||||
pdf = CombinePDF.new
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class OrderCycleClosingJob < ApplicationJob
|
||||
class OrderCycleClosingJob < ActiveJob::Base
|
||||
def perform
|
||||
return if recently_closed_order_cycles.empty?
|
||||
|
||||
|
||||
@@ -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|
|
||||
|
||||
@@ -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, mode: "wb")
|
||||
end
|
||||
|
||||
def read_result
|
||||
File.read(filename)
|
||||
ensure
|
||||
File.unlink(filename)
|
||||
end
|
||||
|
||||
def filename
|
||||
Rails.root.join("tmp/report-#{job_id}")
|
||||
end
|
||||
end
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -263,7 +263,7 @@ module Spree
|
||||
|
||||
def add_order_management_abilities(user)
|
||||
can [:index, :create], Spree::Order
|
||||
can [:read, :update, :fire, :resend, :invoice, :print], Spree::Order do |order|
|
||||
can [:read, :update, :fire, :resend, :invoice, :print, :print_ticket], Spree::Order do |order|
|
||||
# We allow editing orders with a nil distributor as this state occurs
|
||||
# during the order creation process from the admin backend
|
||||
order.distributor.nil? ||
|
||||
|
||||
@@ -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"
|
||||
@@ -123,9 +125,10 @@ module Spree
|
||||
preference :matomo_site_id, :string, default: nil
|
||||
preference :matomo_tag_manager_url, :string, default: nil
|
||||
|
||||
# Invoices
|
||||
# Invoices & Receipts
|
||||
preference :enable_invoices?, :boolean, default: true
|
||||
preference :invoice_style2?, :boolean, default: false
|
||||
preference :enable_receipt_printing?, :boolean, default: false
|
||||
preference :enterprise_number_required_on_invoices?, :boolean, default: true
|
||||
|
||||
# Stripe payments
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -665,7 +665,6 @@ module Spree
|
||||
|
||||
def after_cancel
|
||||
shipments.each(&:cancel!)
|
||||
payments.checkout.each(&:void!)
|
||||
|
||||
OrderMailer.cancel_email(id).deliver_later if send_cancellation_email
|
||||
update(payment_state: updater.update_payment_state)
|
||||
@@ -673,8 +672,6 @@ module Spree
|
||||
|
||||
def after_resume
|
||||
shipments.each(&:resume!)
|
||||
payments.void.each(&:resume!)
|
||||
|
||||
update(payment_state: updater.update_payment_state)
|
||||
end
|
||||
|
||||
|
||||
@@ -47,11 +47,9 @@ module Spree
|
||||
scope :with_state, ->(s) { where(state: s.to_s) }
|
||||
scope :completed, -> { with_state('completed') }
|
||||
scope :incomplete, -> { where(state: %w(checkout pending requires_authorization)) }
|
||||
scope :checkout, -> { with_state('checkout') }
|
||||
scope :pending, -> { with_state('pending') }
|
||||
scope :failed, -> { with_state('failed') }
|
||||
scope :valid, -> { where.not(state: %w(failed invalid)) }
|
||||
scope :void, -> { with_state('void') }
|
||||
scope :authorization_action_required, -> { where.not(cvv_response_message: nil) }
|
||||
scope :requires_authorization, -> { with_state("requires_authorization") }
|
||||
scope :with_payment_intent, ->(code) { where(response_code: code) }
|
||||
@@ -91,10 +89,6 @@ module Spree
|
||||
event :complete_authorization do
|
||||
transition from: [:requires_authorization], to: :completed
|
||||
end
|
||||
event :resume do
|
||||
transition from: [:void], to: :checkout
|
||||
end
|
||||
|
||||
|
||||
after_transition to: :completed, do: :set_captured_at
|
||||
end
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -415,8 +415,8 @@ module Spree
|
||||
# If the master cannot be saved, the Product object will get its errors
|
||||
# and will be destroyed
|
||||
rescue ActiveRecord::RecordInvalid
|
||||
master.errors.each do |error|
|
||||
errors.add error.attribute, error.message
|
||||
master.errors.each do |att, error|
|
||||
errors.add(att, error)
|
||||
end
|
||||
raise
|
||||
end
|
||||
|
||||
@@ -116,22 +116,7 @@ module Spree
|
||||
|
||||
# The call to Stock::Estimator below will replace the current shipping_method
|
||||
original_shipping_method_id = shipping_method.try(:id)
|
||||
|
||||
estimator = OrderManagement::Stock::Estimator.new(order)
|
||||
distributor_shipping_rates = estimator.shipping_rates(to_package)
|
||||
|
||||
if original_shipping_method_id.present? &&
|
||||
distributor_shipping_rates.map(&:shipping_method_id)
|
||||
.exclude?(original_shipping_method_id)
|
||||
cost = estimator.calculate_cost(shipping_method, to_package)
|
||||
unless cost.nil?
|
||||
original_shipping_rate = shipping_method.shipping_rates.new(cost: cost)
|
||||
self.shipping_rates = distributor_shipping_rates + [original_shipping_rate]
|
||||
self.selected_shipping_rate_id = original_shipping_rate.id
|
||||
end
|
||||
else
|
||||
self.shipping_rates = distributor_shipping_rates
|
||||
end
|
||||
self.shipping_rates = OrderManagement::Stock::Estimator.new(order).shipping_rates(to_package)
|
||||
|
||||
keep_original_shipping_method_selection(original_shipping_method_id)
|
||||
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class CancelOrdersReflex < ApplicationReflex
|
||||
def confirm(params)
|
||||
OrdersBulkCancelService.new(params).call
|
||||
cable_ready.dispatch_event(name: "modal:close")
|
||||
# flash[:success] = Spree.t(:order_updated)
|
||||
end
|
||||
end
|
||||
@@ -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
|
||||
@@ -3,8 +3,7 @@
|
||||
module Api
|
||||
module Admin
|
||||
class OrderSerializer < ActiveModel::Serializer
|
||||
attributes :id, :number, :user_id, :full_name, :email, :phone, :completed_at,
|
||||
:completed_at_utc_iso8601, :display_total,
|
||||
attributes :id, :number, :user_id, :full_name, :email, :phone, :completed_at, :display_total,
|
||||
:edit_path, :state, :payment_state, :shipment_state,
|
||||
:payments_path, :ready_to_ship, :ready_to_capture, :created_at,
|
||||
:distributor_name, :special_instructions, :display_outstanding_balance,
|
||||
@@ -74,10 +73,6 @@ module Api
|
||||
object.line_items.count
|
||||
end
|
||||
|
||||
def completed_at_utc_iso8601
|
||||
object.completed_at.blank? ? "" : object.completed_at.utc.iso8601
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def spree_routes_helper
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
class ContentSanitizer
|
||||
include ActionView::Helpers::SanitizeHelper
|
||||
|
||||
ALLOWED_TAGS = ["p", "b", "strong", "em", "i", "a", "u"].freeze
|
||||
ALLOWED_ATTRIBUTES = ["href", "target"].freeze
|
||||
FILTERED_CHARACTERS = {
|
||||
"&amp;" => "&",
|
||||
"&" => "&",
|
||||
@@ -22,7 +24,7 @@ class ContentSanitizer
|
||||
def sanitize_content(content)
|
||||
return unless content.present?
|
||||
|
||||
content = sanitize(content.to_s, scrubber: ContentScrubber.new)
|
||||
content = sanitize(content.to_s, tags: ALLOWED_TAGS, attributes: ALLOWED_ATTRIBUTES)
|
||||
|
||||
filter_characters(content)
|
||||
end
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class ContentScrubber < Rails::Html::PermitScrubber
|
||||
ALLOWED_TAGS = ["p", "b", "strong", "em", "i", "a", "u", "img"].freeze
|
||||
ALLOWED_ATTRIBUTES = ["href", "target", "src", "alt"].freeze
|
||||
|
||||
def initialize
|
||||
super
|
||||
self.tags = ALLOWED_TAGS
|
||||
self.attributes = ALLOWED_ATTRIBUTES
|
||||
end
|
||||
|
||||
def skip_node?(node)
|
||||
node.text?
|
||||
end
|
||||
end
|
||||
@@ -15,7 +15,7 @@ class DefaultAddressUpdater
|
||||
assign_bill_addresses
|
||||
assign_ship_addresses
|
||||
|
||||
customer&.save
|
||||
customer.save
|
||||
user&.save
|
||||
end
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -30,10 +30,8 @@ class OrderCycleForm
|
||||
order_cycle.schedule_ids = schedule_ids if parameter_specified?(:schedule_ids)
|
||||
order_cycle.save!
|
||||
apply_exchange_changes
|
||||
if can_update_selected_payment_or_shipping_methods?
|
||||
attach_selected_distributor_payment_methods
|
||||
attach_selected_distributor_shipping_methods
|
||||
end
|
||||
attach_selected_distributor_payment_methods
|
||||
attach_selected_distributor_shipping_methods
|
||||
sync_subscriptions
|
||||
true
|
||||
end
|
||||
@@ -63,33 +61,14 @@ class OrderCycleForm
|
||||
def attach_selected_distributor_payment_methods
|
||||
return if @selected_distributor_payment_method_ids.nil?
|
||||
|
||||
if distributor_only?
|
||||
payment_method_ids = order_cycle.selected_distributor_payment_method_ids
|
||||
payment_method_ids -= user_distributor_payment_method_ids
|
||||
payment_method_ids += user_only_selected_distributor_payment_method_ids
|
||||
order_cycle.selected_distributor_payment_method_ids = payment_method_ids
|
||||
else
|
||||
order_cycle.selected_distributor_payment_method_ids = selected_distributor_payment_method_ids
|
||||
end
|
||||
order_cycle.selected_distributor_payment_method_ids = selected_distributor_payment_method_ids
|
||||
order_cycle.save!
|
||||
end
|
||||
|
||||
def attach_selected_distributor_shipping_methods
|
||||
return if @selected_distributor_shipping_method_ids.nil?
|
||||
|
||||
if distributor_only?
|
||||
# A distributor can only update methods associated with their own
|
||||
# enterprise, so we load all previously selected methods, and replace
|
||||
# only the distributor's methods with their selection (not touching other
|
||||
# distributor's methods).
|
||||
shipping_method_ids = order_cycle.selected_distributor_shipping_method_ids
|
||||
shipping_method_ids -= user_distributor_shipping_method_ids
|
||||
shipping_method_ids += user_only_selected_distributor_shipping_method_ids
|
||||
order_cycle.selected_distributor_shipping_method_ids = shipping_method_ids
|
||||
else
|
||||
order_cycle.selected_distributor_shipping_method_ids = selected_distributor_shipping_method_ids
|
||||
end
|
||||
|
||||
order_cycle.selected_distributor_shipping_method_ids = selected_distributor_shipping_method_ids
|
||||
order_cycle.save!
|
||||
end
|
||||
|
||||
@@ -120,10 +99,6 @@ class OrderCycleForm
|
||||
@selected_distributor_payment_method_ids
|
||||
end
|
||||
|
||||
def user_only_selected_distributor_payment_method_ids
|
||||
user_distributor_payment_method_ids.intersection(selected_distributor_payment_method_ids)
|
||||
end
|
||||
|
||||
def selected_distributor_shipping_method_ids
|
||||
@selected_distributor_shipping_method_ids = (
|
||||
attachable_distributor_shipping_method_ids &
|
||||
@@ -137,10 +112,6 @@ class OrderCycleForm
|
||||
@selected_distributor_shipping_method_ids
|
||||
end
|
||||
|
||||
def user_only_selected_distributor_shipping_method_ids
|
||||
user_distributor_shipping_method_ids.intersection(selected_distributor_shipping_method_ids)
|
||||
end
|
||||
|
||||
def build_schedule_ids
|
||||
return unless parameter_specified?(:schedule_ids)
|
||||
|
||||
@@ -189,37 +160,4 @@ class OrderCycleForm
|
||||
def new_schedule_ids
|
||||
@order_cycle.schedule_ids - existing_schedule_ids
|
||||
end
|
||||
|
||||
def can_update_selected_payment_or_shipping_methods?
|
||||
@user.admin? || coordinator? || distributor?
|
||||
end
|
||||
|
||||
def coordinator?
|
||||
@user.enterprises.include?(@order_cycle.coordinator)
|
||||
end
|
||||
|
||||
def distributor?
|
||||
!user_distributors_ids.empty?
|
||||
end
|
||||
|
||||
def distributor_only?
|
||||
distributor? && !@user.admin? && !coordinator?
|
||||
end
|
||||
|
||||
def user_distributors_ids
|
||||
@user_distributors_ids ||= @user.enterprises.pluck(:id)
|
||||
.intersection(@order_cycle.distributors.pluck(:id))
|
||||
end
|
||||
|
||||
def user_distributor_payment_method_ids
|
||||
@user_distributor_payment_method_ids ||=
|
||||
DistributorPaymentMethod.where(distributor_id: user_distributors_ids)
|
||||
.pluck(:id)
|
||||
end
|
||||
|
||||
def user_distributor_shipping_method_ids
|
||||
@user_distributor_shipping_method_ids ||=
|
||||
DistributorShippingMethod.where(distributor_id: user_distributors_ids)
|
||||
.pluck(:id)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class OrderFeesHandler
|
||||
attr_reader :order
|
||||
|
||||
delegate :distributor, :order_cycle, to: :order
|
||||
attr_reader :order, :distributor, :order_cycle
|
||||
|
||||
def initialize(order)
|
||||
@order = order
|
||||
@distributor = order.distributor
|
||||
@order_cycle = order.order_cycle
|
||||
end
|
||||
|
||||
def recreate_all_fees!
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class OrdersBulkCancelService
|
||||
def initialize(params)
|
||||
@order_ids = params[:order_ids]
|
||||
@send_cancellation_email = params[:send_cancellation_email]
|
||||
@restock_items = params[:restock_items]
|
||||
end
|
||||
|
||||
def call
|
||||
Spree::Order.where(id: @order_ids).find_each do |order|
|
||||
order.send_cancellation_email = @send_cancellation_email
|
||||
order.restock_items = @restock_items
|
||||
order.cancel
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -38,5 +38,3 @@
|
||||
%tr
|
||||
%td{colspan: "4"}= t(:none)
|
||||
= f.submit t(:update)
|
||||
|
||||
= render partial: 'admin/shared/pagy_links', locals: { pagy: @pagy }
|
||||
|
||||
@@ -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") }
|
||||
|
||||
@@ -15,6 +15,11 @@
|
||||
= check_box_tag 'preferences[invoice_style2?]', '1', Spree::Config[:invoice_style2?]
|
||||
= label_tag nil, t('.invoice_style2?')
|
||||
|
||||
.field.align-center
|
||||
= hidden_field_tag 'preferences[enable_receipt_printing?]', '0'
|
||||
= check_box_tag 'preferences[enable_receipt_printing?]', '1', Spree::Config[:enable_receipt_printing?]
|
||||
= label_tag nil, t('.enable_receipt_printing?')
|
||||
|
||||
.field.align-center
|
||||
= hidden_field_tag 'preferences[enterprise_number_required_on_invoices?]', '0'
|
||||
= check_box_tag 'preferences[enterprise_number_required_on_invoices?]', '1', Spree::Config[:enterprise_number_required_on_invoices?]
|
||||
|
||||
@@ -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)"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
%td.tags.panel-toggle.text-center{ name: "tags", ng: { if: 'enterprises[exchange.enterprise_id].managed || order_cycle.viewing_as_coordinator' } }
|
||||
{{ exchange.tags.length }}
|
||||
%td.collection-details
|
||||
= text_field_tag 'order_cycle_outgoing_exchange_{{ $index }}_pickup_time', '', 'ng-init' => 'setPickupTimeFieldDirty($index, exchange.pickup_time)', 'id' => 'order_cycle_outgoing_exchange_{{ $index }}_pickup_time', 'required' => 'required', 'placeholder' => t('.pickup_time_placeholder'), 'ng-model' => 'exchange.pickup_time', 'ng-disabled' => '!enterprises[exchange.enterprise_id].managed && !order_cycle.viewing_as_coordinator', 'maxlength' => 35
|
||||
= text_field_tag 'order_cycle_outgoing_exchange_{{ $index }}_pickup_time', '', 'ng-init' => 'setPickupTimeFieldDirty($index)', 'id' => 'order_cycle_outgoing_exchange_{{ $index }}_pickup_time', 'required' => 'required', 'placeholder' => t('.pickup_time_placeholder'), 'ng-model' => 'exchange.pickup_time', 'ng-disabled' => '!enterprises[exchange.enterprise_id].managed && !order_cycle.viewing_as_coordinator', 'maxlength' => 35
|
||||
%span.icon-question-sign{'ofn-with-tip' => t('.pickup_time_tip')}
|
||||
%br/
|
||||
= text_field_tag 'order_cycle_outgoing_exchange_{{ $index }}_pickup_instructions', '', 'id' => 'order_cycle_outgoing_exchange_{{ $index }}_pickup_instructions', 'placeholder' => t('.pickup_instructions_placeholder'), 'ng-model' => 'exchange.pickup_instructions', 'ng-disabled' => '!enterprises[exchange.enterprise_id].managed && !order_cycle.viewing_as_coordinator'
|
||||
@@ -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 }
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) }
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
- content_for :page_title do
|
||||
= t :edit_order_cycle
|
||||
|
||||
= form_for [main_app, :admin, @order_cycle], html: { class: "order_cycle" , data: { controller: 'unsaved-changes', action: 'beforeunload@window->unsaved-changes#leavingPage', 'unsaved-changes-changed': "false" } } do |f|
|
||||
= form_for [main_app, :admin, @order_cycle], html: { class: "order_cycle" } do |f|
|
||||
|
||||
= render 'wizard_progress'
|
||||
|
||||
%fieldset.no-border-bottom
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
- report ||= @report
|
||||
|
||||
.report__table-container
|
||||
%table.report__table
|
||||
%thead
|
||||
|
||||
@@ -1,8 +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})
|
||||
@@ -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})
|
||||
@@ -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"
|
||||
|
||||
@@ -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} }}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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"} ×
|
||||
|
||||
31
app/views/shared/_ie_warning.html.haml
Normal file
31
app/views/shared/_ie_warning.html.haml
Normal 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: "#"} ×
|
||||
@@ -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)
|
||||
}
|
||||
});
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user