mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
Compare commits
304 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
076244ee1c | ||
|
|
2e2488a25e | ||
|
|
bf950d7c69 | ||
|
|
257959448a | ||
|
|
ba4e7e440d | ||
|
|
cb83069101 | ||
|
|
456355da79 | ||
|
|
2dc3c472c1 | ||
|
|
dfec0c3caf | ||
|
|
73596308ab | ||
|
|
b736db0d7b | ||
|
|
3ff1cd0793 | ||
|
|
b93f6dfdad | ||
|
|
9ba0695652 | ||
|
|
df42a88150 | ||
|
|
8b73660d75 | ||
|
|
f214c1f14f | ||
|
|
0eff4d3906 | ||
|
|
84831266f1 | ||
|
|
5e1d4892b1 | ||
|
|
7260bf1041 | ||
|
|
01a907de9f | ||
|
|
5e0a08d99b | ||
|
|
7b5debb76b | ||
|
|
32fb898962 | ||
|
|
df8fd88682 | ||
|
|
68b2e48fb3 | ||
|
|
0202bb40cf | ||
|
|
f7c62dfe45 | ||
|
|
1c185c2ca4 | ||
|
|
883f01e3e6 | ||
|
|
8ccc88d770 | ||
|
|
133512e4f4 | ||
|
|
86b4570fc2 | ||
|
|
3c996fdfb3 | ||
|
|
8048dc2c8b | ||
|
|
0f9f4b07a8 | ||
|
|
a6fdefff08 | ||
|
|
6a28918654 | ||
|
|
d544233bac | ||
|
|
d577d60de6 | ||
|
|
473a35f330 | ||
|
|
2fd8ffa413 | ||
|
|
bbf400a83b | ||
|
|
d1cd1fdefe | ||
|
|
df868d88d8 | ||
|
|
da61fdbc2c | ||
|
|
54b0554bb4 | ||
|
|
2652bc086a | ||
|
|
f72e040a4d | ||
|
|
1546619718 | ||
|
|
1c17c37915 | ||
|
|
063e424bc0 | ||
|
|
b53faceebb | ||
|
|
aebf84b53f | ||
|
|
9ce1c536e4 | ||
|
|
edb2645af1 | ||
|
|
d797ef2b3a | ||
|
|
d46105ea90 | ||
|
|
151e71b4d9 | ||
|
|
b6bc4c66a2 | ||
|
|
b8b50fa165 | ||
|
|
4d23113265 | ||
|
|
f909b742ce | ||
|
|
5a4727138c | ||
|
|
fe05d17078 | ||
|
|
9f9d8020c1 | ||
|
|
14955ac8ca | ||
|
|
06c6853323 | ||
|
|
4e0b206c7b | ||
|
|
3d003a735f | ||
|
|
e16c8661a2 | ||
|
|
eaa6e9bc18 | ||
|
|
91652ba792 | ||
|
|
4bf640f0c4 | ||
|
|
cf489e809f | ||
|
|
35bb539271 | ||
|
|
b3020a5573 | ||
|
|
250b9bc3c0 | ||
|
|
e58add6af0 | ||
|
|
3447959a06 | ||
|
|
41440af533 | ||
|
|
826b1e95ef | ||
|
|
6cabbee1a2 | ||
|
|
11bc5c775c | ||
|
|
788093c7cf | ||
|
|
f44228eef7 | ||
|
|
62935f65a2 | ||
|
|
e8425c5805 | ||
|
|
31cde7e06e | ||
|
|
f467efc42b | ||
|
|
faa8888e2a | ||
|
|
84f488917e | ||
|
|
00c57fa06c | ||
|
|
c4748104a0 | ||
|
|
46bbf1b1ec | ||
|
|
d12e99e363 | ||
|
|
85c8a0ac35 | ||
|
|
0e9869c4d3 | ||
|
|
a3416bcb80 | ||
|
|
bf206dc4e6 | ||
|
|
55ef4dfe0d | ||
|
|
3489f08ec5 | ||
|
|
4a7ac45dba | ||
|
|
df925d6412 | ||
|
|
84bf38ce4d | ||
|
|
490c5afc59 | ||
|
|
367f77f477 | ||
|
|
892a020bcc | ||
|
|
1f5281ac1a | ||
|
|
3c9b7a10f4 | ||
|
|
e2441cdcf6 | ||
|
|
6dec80aaaf | ||
|
|
1c349049d1 | ||
|
|
edc667a336 | ||
|
|
02787e668f | ||
|
|
830a7c8f1d | ||
|
|
cd43bd4522 | ||
|
|
9dbc9f7272 | ||
|
|
da9a4803ff | ||
|
|
732ebd8457 | ||
|
|
39e567d386 | ||
|
|
4740c2b0db | ||
|
|
ee70ab8adb | ||
|
|
936a96bd6c | ||
|
|
b3492981d3 | ||
|
|
167ce0e53c | ||
|
|
8f47d2b2be | ||
|
|
e873771f18 | ||
|
|
627b8af37b | ||
|
|
eb72ec8e13 | ||
|
|
7458dccea6 | ||
|
|
3e24b7ba6b | ||
|
|
62cd507fb9 | ||
|
|
beba3c7684 | ||
|
|
f5bd23b4d8 | ||
|
|
2c14aecf4f | ||
|
|
4e6d64c0a1 | ||
|
|
5718f9f00c | ||
|
|
5423c1c02e | ||
|
|
ee8454bd2c | ||
|
|
45c23a76ff | ||
|
|
5a1d9013c6 | ||
|
|
3a68e237de | ||
|
|
87ed23211e | ||
|
|
48e18b016a | ||
|
|
da851079f4 | ||
|
|
1d265d19ce | ||
|
|
9e4bd23332 | ||
|
|
fdc362cb44 | ||
|
|
8d3845508c | ||
|
|
952b6039f9 | ||
|
|
053af8416b | ||
|
|
955b84ae6f | ||
|
|
2455ecabde | ||
|
|
71037022ec | ||
|
|
7ffd4669be | ||
|
|
2b7b83ba37 | ||
|
|
fc79612f26 | ||
|
|
de28027623 | ||
|
|
755107ec9f | ||
|
|
b40cd579bc | ||
|
|
8e45b758ba | ||
|
|
c4de247dd9 | ||
|
|
a244b34627 | ||
|
|
dabe37ebcb | ||
|
|
2fcbe437f2 | ||
|
|
642938afe0 | ||
|
|
7b96a1fb5b | ||
|
|
0ca86344d2 | ||
|
|
980f004b83 | ||
|
|
c0ee72319f | ||
|
|
3d26b76d17 | ||
|
|
7772c01e16 | ||
|
|
04921aeed4 | ||
|
|
c71c5054e0 | ||
|
|
4015413d1d | ||
|
|
b3059bbdbc | ||
|
|
a35fab5e1f | ||
|
|
c22f6cb805 | ||
|
|
f00aeb006e | ||
|
|
66c3ba3bba | ||
|
|
b322df8515 | ||
|
|
617164684c | ||
|
|
b36fae1bbb | ||
|
|
3a5f263fb5 | ||
|
|
d5c3edc8fa | ||
|
|
ec65e4dcaa | ||
|
|
c83eb5d5dc | ||
|
|
9a40329bd7 | ||
|
|
bf74612892 | ||
|
|
eae7d96b30 | ||
|
|
96c6f58ba2 | ||
|
|
6a8c7b15dc | ||
|
|
955492bfdd | ||
|
|
0000faab91 | ||
|
|
e3f157ebdd | ||
|
|
f8af84d9d4 | ||
|
|
bddbb36813 | ||
|
|
78b73c988e | ||
|
|
cd641cc5d6 | ||
|
|
50555a3fe9 | ||
|
|
7c6e220bf7 | ||
|
|
3496b57942 | ||
|
|
bc805d94d8 | ||
|
|
1596649034 | ||
|
|
81461684f3 | ||
|
|
d33cdd1327 | ||
|
|
daaff2f7e8 | ||
|
|
4de0b9ad11 | ||
|
|
14a258c661 | ||
|
|
3b3f9a7513 | ||
|
|
3e1b66fd01 | ||
|
|
9da6f862cd | ||
|
|
3eb597bff4 | ||
|
|
46fde6bd40 | ||
|
|
590a09f069 | ||
|
|
1d9fbbf69e | ||
|
|
b378d7655f | ||
|
|
617a417dc2 | ||
|
|
bfbdb5f44b | ||
|
|
e02de2b17d | ||
|
|
ae84dfe3cd | ||
|
|
8a6874326a | ||
|
|
68de510c4e | ||
|
|
230afd5024 | ||
|
|
41e696282c | ||
|
|
e655d5b188 | ||
|
|
7d15baef9d | ||
|
|
312f2544dd | ||
|
|
157bdd9f3d | ||
|
|
b4e041c7e9 | ||
|
|
23e2d28488 | ||
|
|
0f9ebfe34a | ||
|
|
b7adc5f551 | ||
|
|
7bb7391634 | ||
|
|
e5a136801d | ||
|
|
addd2ea9ac | ||
|
|
7b0ce3272a | ||
|
|
5bbbe4b67a | ||
|
|
4705d306b5 | ||
|
|
2082404c87 | ||
|
|
c9a7230fe2 | ||
|
|
1f329e85bc | ||
|
|
b2c778794d | ||
|
|
80eef9c302 | ||
|
|
f40b569a4a | ||
|
|
1f161bee1f | ||
|
|
4140e3d153 | ||
|
|
db70c47a31 | ||
|
|
cd71233163 | ||
|
|
6ef0e04c18 | ||
|
|
87274bccc6 | ||
|
|
981c306977 | ||
|
|
82e38d7b91 | ||
|
|
5894246474 | ||
|
|
058a45f4e5 | ||
|
|
e5ccee42cc | ||
|
|
38f145549a | ||
|
|
f551bea00b | ||
|
|
f5ebc797c4 | ||
|
|
263b36d1d9 | ||
|
|
ea76615763 | ||
|
|
e076e23064 | ||
|
|
a272479483 | ||
|
|
6ec3e7ee0c | ||
|
|
ec4d091c2e | ||
|
|
eec117e769 | ||
|
|
eb621cae35 | ||
|
|
73f55ae776 | ||
|
|
19584ce6e0 | ||
|
|
8942d3d17b | ||
|
|
ddfbcacd83 | ||
|
|
c3a7acf9ad | ||
|
|
fb0d922d73 | ||
|
|
5c83a3277e | ||
|
|
c6332ab306 | ||
|
|
6b7030a6a8 | ||
|
|
b1fd6d9541 | ||
|
|
d73d6dcdb6 | ||
|
|
792d6d9569 | ||
|
|
1137e6890b | ||
|
|
52e934ec2b | ||
|
|
bc26a3aa07 | ||
|
|
01c477f2cb | ||
|
|
8335594351 | ||
|
|
44db511e66 | ||
|
|
8b89c901ef | ||
|
|
7b57f2358c | ||
|
|
b297299838 | ||
|
|
52843de1da | ||
|
|
77e644e3d4 | ||
|
|
72df2867d4 | ||
|
|
0cc8349c71 | ||
|
|
47ac118cf7 | ||
|
|
95d68b98a9 | ||
|
|
47a43163d8 | ||
|
|
52c6f5a222 | ||
|
|
b582b61414 | ||
|
|
6ead127b5c | ||
|
|
22cf05ad94 | ||
|
|
a2e68026e5 | ||
|
|
c9419d3437 | ||
|
|
c1f34bc680 |
@@ -1 +1,2 @@
|
||||
defaults
|
||||
IE 11
|
||||
|
||||
@@ -6,3 +6,6 @@ STRIPE_SECRET_TEST_API_KEY="bogus_key"
|
||||
STRIPE_CUSTOMER="bogus_customer"
|
||||
|
||||
SITE_URL="test.host"
|
||||
|
||||
OPENID_APP_ID="test-provider"
|
||||
OPENID_APP_SECRET="12345"
|
||||
|
||||
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,6 +1,6 @@
|
||||
#### What? Why?
|
||||
|
||||
Closes # <!-- Insert issue number here. -->
|
||||
- Closes # <!-- Insert issue number here. -->
|
||||
|
||||
<!-- Explain why this change is needed and the solution you propose.
|
||||
Provide context for others to understand it. -->
|
||||
|
||||
6
.github/workflows/brakeman-analysis.yml
vendored
6
.github/workflows/brakeman-analysis.yml
vendored
@@ -23,11 +23,11 @@ jobs:
|
||||
steps:
|
||||
# Checkout the repository to the GitHub Actions runner
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# Customize the ruby version depending on your needs
|
||||
- name: Setup Ruby
|
||||
uses: actions/setup-ruby@v1
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: '2.7'
|
||||
|
||||
@@ -45,6 +45,6 @@ jobs:
|
||||
|
||||
# Upload the SARIF file generated in the previous step
|
||||
- name: Upload SARIF
|
||||
uses: github/codeql-action/upload-sarif@v1
|
||||
uses: github/codeql-action/upload-sarif@v2
|
||||
with:
|
||||
sarif_file: output.sarif.json
|
||||
|
||||
27
.github/workflows/build.yml
vendored
27
.github/workflows/build.yml
vendored
@@ -3,13 +3,14 @@ name: Build
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches-ignore:
|
||||
- 'dependabot/**'
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
DISABLE_KNAPSACK: true
|
||||
TIMEZONE: UTC
|
||||
COVERAGE: true
|
||||
RSPEC_RETRY_RETRY_COUNT: 3
|
||||
RAILS_ENV: test
|
||||
|
||||
permissions:
|
||||
@@ -46,16 +47,21 @@ jobs:
|
||||
- "engines/*/spec"
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup redis
|
||||
uses: supercharge/redis-github-action@1.4.0
|
||||
with:
|
||||
redis-version: 6
|
||||
|
||||
- name: Set up Ruby
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
||||
|
||||
- uses: actions/setup-node@v2
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '14.15.5'
|
||||
node-version: 16
|
||||
|
||||
- name: Install JS dependencies
|
||||
run: yarn install --frozen-lockfile
|
||||
@@ -70,7 +76,7 @@ jobs:
|
||||
|
||||
- name: Archive failed tests screenshots
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: failed-tests-screenshots
|
||||
path: tmp/capybara/screenshots/*.png
|
||||
@@ -93,16 +99,21 @@ jobs:
|
||||
POSTGRES_USER: ofn
|
||||
POSTGRES_PASSWORD: f00d
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup redis
|
||||
uses: supercharge/redis-github-action@1.4.0
|
||||
with:
|
||||
redis-version: 6
|
||||
|
||||
- name: Set up Ruby
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
||||
|
||||
- uses: actions/setup-node@v2
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '14.15.5'
|
||||
node-version: 16
|
||||
|
||||
- name: Install JS dependencies
|
||||
run: yarn install --frozen-lockfile
|
||||
|
||||
2
.github/workflows/linters.yml
vendored
2
.github/workflows/linters.yml
vendored
@@ -23,7 +23,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: prettier
|
||||
uses: EPMatt/reviewdog-action-prettier@v1
|
||||
with:
|
||||
|
||||
6
.github/workflows/mapi.yml
vendored
6
.github/workflows/mapi.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: true
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- run: docker/build
|
||||
- run: docker-compose up --detach
|
||||
- run: until curl -f -s http://localhost:3000; do echo "waiting for api server"; sleep 1; done
|
||||
@@ -39,13 +39,13 @@ jobs:
|
||||
|
||||
# Archive HTML report
|
||||
- name: Archive Mayhem for API report
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: mapi-report
|
||||
path: mapi.html
|
||||
|
||||
# Upload SARIF file (only available on public repos or github enterprise)
|
||||
- name: Upload SARIF file
|
||||
uses: github/codeql-action/upload-sarif@v1
|
||||
uses: github/codeql-action/upload-sarif@v2
|
||||
with:
|
||||
sarif_file: mapi.sarif
|
||||
|
||||
@@ -478,6 +478,7 @@ Metrics/ClassLength:
|
||||
- 'app/serializers/api/enterprise_shopfront_serializer.rb'
|
||||
- 'app/services/cart_service.rb'
|
||||
- 'app/services/order_syncer.rb'
|
||||
- 'app/services/order_cycle_form.rb'
|
||||
- 'engines/order_management/app/services/order_management/order/updater.rb'
|
||||
- 'lib/open_food_network/enterprise_fee_calculator.rb'
|
||||
- 'lib/open_food_network/order_cycle_form_applicator.rb'
|
||||
|
||||
15
Gemfile
15
Gemfile
@@ -69,6 +69,10 @@ gem 'pagy', '~> 5.1'
|
||||
gem 'rswag-api'
|
||||
gem 'rswag-ui'
|
||||
|
||||
gem 'gitlab-omniauth-openid-connect', require: 'omniauth_openid_connect'
|
||||
gem 'openid_connect', '~> 1.3'
|
||||
gem 'omniauth-rails_csrf_protection'
|
||||
|
||||
gem 'angularjs-rails', '1.8.0'
|
||||
gem 'bugsnag'
|
||||
gem 'haml'
|
||||
@@ -116,7 +120,6 @@ gem 'coffee-rails', '~> 5.0.0'
|
||||
|
||||
gem 'mini_racer', '0.4.0'
|
||||
|
||||
|
||||
gem 'angular_rails_csrf'
|
||||
|
||||
gem 'jquery-rails', '4.4.0'
|
||||
@@ -147,10 +150,10 @@ group :test, :development do
|
||||
gem "factory_bot_rails", '6.2.0', require: false
|
||||
gem 'fuubar', '~> 2.5.1'
|
||||
gem 'json_spec', '~> 1.1.4'
|
||||
gem 'knapsack'
|
||||
gem 'knapsack', require: false
|
||||
gem 'letter_opener', '>= 1.4.1'
|
||||
gem 'rspec-rails', ">= 3.5.2"
|
||||
gem 'rspec-retry'
|
||||
gem 'rspec-retry', require: false
|
||||
gem 'rswag-specs'
|
||||
gem 'shoulda-matchers'
|
||||
gem 'timecop'
|
||||
@@ -161,9 +164,9 @@ group :test do
|
||||
gem 'pdf-reader'
|
||||
gem 'rails-controller-testing'
|
||||
gem 'simplecov', require: false
|
||||
gem 'test-prof'
|
||||
gem 'vcr'
|
||||
gem 'webmock'
|
||||
gem 'test-prof', require: false
|
||||
gem 'vcr', require: false
|
||||
gem 'webmock', require: false
|
||||
# See spec/spec_helper.rb for instructions
|
||||
# gem 'perftools.rb'
|
||||
end
|
||||
|
||||
144
Gemfile.lock
144
Gemfile.lock
@@ -93,7 +93,7 @@ GEM
|
||||
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
||||
active_model_serializers (0.8.4)
|
||||
activemodel (>= 3.0)
|
||||
active_storage_validations (0.9.8)
|
||||
active_storage_validations (1.0.3)
|
||||
activejob (>= 5.2.0)
|
||||
activemodel (>= 5.2.0)
|
||||
activestorage (>= 5.2.0)
|
||||
@@ -111,7 +111,7 @@ GEM
|
||||
activerecord (6.1.7)
|
||||
activemodel (= 6.1.7)
|
||||
activesupport (= 6.1.7)
|
||||
activerecord-import (1.4.0)
|
||||
activerecord-import (1.4.1)
|
||||
activerecord (>= 4.2)
|
||||
activerecord-postgresql-adapter (0.0.1)
|
||||
pg
|
||||
@@ -140,6 +140,7 @@ GEM
|
||||
activerecord (>= 4.2)
|
||||
addressable (2.8.1)
|
||||
public_suffix (>= 2.0.2, < 6.0)
|
||||
aes_key_wrap (1.1.0)
|
||||
afm (0.2.2)
|
||||
angular-rails-templates (1.2.0)
|
||||
railties (>= 5.0, < 7.1)
|
||||
@@ -153,29 +154,31 @@ GEM
|
||||
arel-helpers (2.14.0)
|
||||
activerecord (>= 3.1.0, < 8)
|
||||
ast (2.4.2)
|
||||
attr_required (1.0.1)
|
||||
awesome_nested_set (3.5.0)
|
||||
activerecord (>= 4.0.0, < 7.1)
|
||||
aws-eventstream (1.2.0)
|
||||
aws-partitions (1.601.0)
|
||||
aws-sdk-core (3.131.2)
|
||||
aws-partitions (1.651.0)
|
||||
aws-sdk-core (3.165.1)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
aws-partitions (~> 1, >= 1.525.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
aws-partitions (~> 1, >= 1.651.0)
|
||||
aws-sigv4 (~> 1.5)
|
||||
jmespath (~> 1, >= 1.6.1)
|
||||
aws-sdk-kms (1.57.0)
|
||||
aws-sdk-core (~> 3, >= 3.127.0)
|
||||
aws-sdk-kms (1.59.0)
|
||||
aws-sdk-core (~> 3, >= 3.165.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
aws-sdk-s3 (1.114.0)
|
||||
aws-sdk-core (~> 3, >= 3.127.0)
|
||||
aws-sdk-s3 (1.117.0)
|
||||
aws-sdk-core (~> 3, >= 3.165.0)
|
||||
aws-sdk-kms (~> 1)
|
||||
aws-sigv4 (~> 1.4)
|
||||
aws-sigv4 (1.5.0)
|
||||
aws-sigv4 (1.5.2)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
axlsx_styler (1.1.0)
|
||||
activesupport (>= 3.1)
|
||||
caxlsx (>= 2.0.2)
|
||||
bcrypt (3.1.18)
|
||||
bigdecimal (3.0.2)
|
||||
bindata (2.4.12)
|
||||
bindex (0.8.1)
|
||||
bootsnap (1.13.0)
|
||||
msgpack (~> 1.2)
|
||||
@@ -242,7 +245,7 @@ GEM
|
||||
debase-ruby_core_source (= 0.10.12)
|
||||
msgpack
|
||||
debase-ruby_core_source (0.10.12)
|
||||
debug (1.6.2)
|
||||
debug (1.6.3)
|
||||
irb (>= 1.3.6)
|
||||
reline (>= 0.3.1)
|
||||
debugger-linecache (1.2.0)
|
||||
@@ -276,10 +279,12 @@ GEM
|
||||
factory_bot_rails (6.2.0)
|
||||
factory_bot (~> 6.2.0)
|
||||
railties (>= 5.0.0)
|
||||
faraday (2.3.0)
|
||||
faraday-net_http (~> 2.0)
|
||||
faraday (2.6.0)
|
||||
faraday-net_http (>= 2.0, < 3.1)
|
||||
ruby2_keywords (>= 0.0.4)
|
||||
faraday-net_http (2.0.3)
|
||||
faraday-follow_redirects (0.3.0)
|
||||
faraday (>= 1, < 3)
|
||||
faraday-net_http (3.0.1)
|
||||
ferrum (0.11)
|
||||
addressable (~> 2.5)
|
||||
cliver (~> 0.3)
|
||||
@@ -313,13 +318,17 @@ GEM
|
||||
nokogiri (>= 1.5.11, < 2.0.0)
|
||||
foreman (0.87.2)
|
||||
formatador (0.2.5)
|
||||
fugit (1.5.3)
|
||||
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)
|
||||
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)
|
||||
@@ -331,9 +340,11 @@ GEM
|
||||
tilt
|
||||
hashdiff (1.0.1)
|
||||
hashery (2.1.2)
|
||||
hashie (5.0.0)
|
||||
highline (2.0.3)
|
||||
hiredis (0.6.3)
|
||||
htmlentities (4.3.4)
|
||||
httpclient (2.8.3)
|
||||
i18n (1.12.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
i18n-js (3.9.2)
|
||||
@@ -345,7 +356,7 @@ GEM
|
||||
activerecord (>= 3.0)
|
||||
io-console (0.5.11)
|
||||
ipaddress (0.8.3)
|
||||
irb (1.4.1)
|
||||
irb (1.4.2)
|
||||
reline (>= 0.3.0)
|
||||
jmespath (1.6.1)
|
||||
jquery-rails (4.4.0)
|
||||
@@ -355,8 +366,14 @@ GEM
|
||||
jquery-ui-rails (4.2.1)
|
||||
railties (>= 3.2.16)
|
||||
json (2.6.2)
|
||||
json-schema (2.8.1)
|
||||
addressable (>= 2.4)
|
||||
json-jwt (1.16.0)
|
||||
activesupport (>= 4.2)
|
||||
aes_key_wrap
|
||||
bindata
|
||||
faraday (~> 2.0)
|
||||
faraday-follow_redirects
|
||||
json-schema (3.0.0)
|
||||
addressable (>= 2.8)
|
||||
json_spec (1.1.5)
|
||||
multi_json (~> 1.0)
|
||||
rspec (>= 2.0, < 4.0)
|
||||
@@ -373,7 +390,7 @@ GEM
|
||||
listen (3.7.1)
|
||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||
rb-inotify (~> 0.9, >= 0.9.10)
|
||||
loofah (2.18.0)
|
||||
loofah (2.19.0)
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.5.9)
|
||||
mail (2.7.1)
|
||||
@@ -400,16 +417,38 @@ GEM
|
||||
msgpack (1.5.4)
|
||||
multi_json (1.15.0)
|
||||
multi_xml (0.6.0)
|
||||
net-protocol (0.1.3)
|
||||
timeout
|
||||
net-smtp (0.3.2)
|
||||
net-protocol
|
||||
nio4r (2.5.8)
|
||||
nokogiri (1.13.8)
|
||||
nokogiri (1.13.9)
|
||||
mini_portile2 (~> 2.8.0)
|
||||
racc (~> 1.4)
|
||||
oauth2 (1.4.10)
|
||||
oauth2 (1.4.11)
|
||||
faraday (>= 0.17.3, < 3.0)
|
||||
jwt (>= 1.0, < 3.0)
|
||||
multi_json (~> 1.3)
|
||||
multi_xml (~> 0.5)
|
||||
rack (>= 1.2, < 3)
|
||||
rack (>= 1.2, < 4)
|
||||
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)
|
||||
openid_connect (1.4.2)
|
||||
activemodel
|
||||
attr_required (>= 1.0.0)
|
||||
json-jwt (>= 1.15.0)
|
||||
net-smtp
|
||||
rack-oauth2 (~> 1.21)
|
||||
swd (~> 1.3)
|
||||
tzinfo
|
||||
validate_email
|
||||
validate_url
|
||||
webfinger (~> 1.2)
|
||||
orm_adapter (0.5.0)
|
||||
pagy (5.10.1)
|
||||
activesupport
|
||||
@@ -426,7 +465,7 @@ GEM
|
||||
xml-simple
|
||||
paypal-sdk-merchant (1.117.2)
|
||||
paypal-sdk-core (~> 0.3.0)
|
||||
pdf-reader (2.10.0)
|
||||
pdf-reader (2.11.0)
|
||||
Ascii85 (~> 1.0)
|
||||
afm (~> 0.2.1)
|
||||
hashery (~> 2.0)
|
||||
@@ -445,6 +484,12 @@ GEM
|
||||
rack (2.2.4)
|
||||
rack-mini-profiler (2.3.4)
|
||||
rack (>= 1.2.0)
|
||||
rack-oauth2 (1.21.3)
|
||||
activesupport
|
||||
attr_required
|
||||
httpclient
|
||||
json-jwt (>= 1.11.0)
|
||||
rack (>= 2.1.0)
|
||||
rack-protection (2.1.0)
|
||||
rack
|
||||
rack-proxy (0.7.0)
|
||||
@@ -505,7 +550,7 @@ GEM
|
||||
ffi (~> 1.0)
|
||||
redcarpet (3.5.1)
|
||||
redis (4.8.0)
|
||||
regexp_parser (2.5.0)
|
||||
regexp_parser (2.6.0)
|
||||
reline (0.3.1)
|
||||
io-console (~> 0.5)
|
||||
request_store (1.5.0)
|
||||
@@ -550,28 +595,29 @@ GEM
|
||||
rspec-retry (0.6.2)
|
||||
rspec-core (> 3.3)
|
||||
rspec-support (3.10.3)
|
||||
rswag-api (2.6.0)
|
||||
rswag-api (2.7.0)
|
||||
railties (>= 3.1, < 7.1)
|
||||
rswag-specs (2.6.0)
|
||||
rswag-specs (2.7.0)
|
||||
activesupport (>= 3.1, < 7.1)
|
||||
json-schema (~> 2.2)
|
||||
json-schema (>= 2.2, < 4.0)
|
||||
railties (>= 3.1, < 7.1)
|
||||
rswag-ui (2.6.0)
|
||||
rspec-core (>= 2.14)
|
||||
rswag-ui (2.7.0)
|
||||
actionpack (>= 3.1, < 7.1)
|
||||
railties (>= 3.1, < 7.1)
|
||||
rubocop (1.36.0)
|
||||
rubocop (1.38.0)
|
||||
json (~> 2.3)
|
||||
parallel (~> 1.10)
|
||||
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.20.1, < 2.0)
|
||||
rubocop-ast (>= 1.23.0, < 2.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (>= 1.4.0, < 3.0)
|
||||
rubocop-ast (1.21.0)
|
||||
rubocop-ast (1.23.0)
|
||||
parser (>= 3.1.1.0)
|
||||
rubocop-rails (2.16.1)
|
||||
rubocop-rails (2.17.2)
|
||||
activesupport (>= 4.2.0)
|
||||
rack (>= 1.1)
|
||||
rubocop (>= 1.33.0, < 2.0)
|
||||
@@ -583,7 +629,7 @@ GEM
|
||||
ffi (~> 1.12)
|
||||
ruby2_keywords (0.0.5)
|
||||
rubyzip (2.3.2)
|
||||
rufus-scheduler (3.8.1)
|
||||
rufus-scheduler (3.8.2)
|
||||
fugit (~> 1.1, >= 1.1.6)
|
||||
sass (3.4.25)
|
||||
sass-rails (5.0.8)
|
||||
@@ -600,10 +646,10 @@ GEM
|
||||
connection_pool (>= 2.2.5)
|
||||
rack (~> 2.0)
|
||||
redis (>= 4.5.0, < 5)
|
||||
sidekiq-scheduler (4.0.2)
|
||||
sidekiq-scheduler (4.0.3)
|
||||
redis (>= 4.2.0)
|
||||
rufus-scheduler (~> 3.2)
|
||||
sidekiq (>= 4)
|
||||
sidekiq (>= 4, < 7)
|
||||
tilt (>= 1.4.0)
|
||||
simplecov (0.21.2)
|
||||
docile (~> 1.1)
|
||||
@@ -644,14 +690,19 @@ GEM
|
||||
redis
|
||||
stringex (2.8.5)
|
||||
stripe (7.1.0)
|
||||
swd (1.3.0)
|
||||
activesupport (>= 3)
|
||||
attr_required (>= 0.0.5)
|
||||
httpclient (>= 2.4)
|
||||
temple (0.8.2)
|
||||
test-prof (1.0.10)
|
||||
test-prof (1.0.11)
|
||||
test-unit (3.5.5)
|
||||
power_assert
|
||||
thor (1.2.1)
|
||||
thread-local (1.1.0)
|
||||
tilt (2.0.11)
|
||||
timecop (0.9.5)
|
||||
timeout (0.3.0)
|
||||
ttfunk (1.7.0)
|
||||
tzinfo (2.0.5)
|
||||
concurrent-ruby (~> 1.0)
|
||||
@@ -660,11 +711,14 @@ GEM
|
||||
valid_email2 (4.0.4)
|
||||
activemodel (>= 3.2)
|
||||
mail (~> 2.5)
|
||||
validate_email (0.1.6)
|
||||
activemodel (>= 3.0)
|
||||
mail (>= 2.2.5)
|
||||
validate_url (1.0.15)
|
||||
activemodel (>= 3.0.0)
|
||||
public_suffix
|
||||
vcr (6.1.0)
|
||||
activesupport (>= 5.0.0, < 8.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
method_source (~> 1.0)
|
||||
view_component (2.74.0)
|
||||
view_component (2.74.1)
|
||||
activesupport (>= 5.0.0, < 8.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
method_source (~> 1.0)
|
||||
@@ -677,6 +731,9 @@ GEM
|
||||
activemodel (>= 6.0.0)
|
||||
bindex (>= 0.4.0)
|
||||
railties (>= 6.0.0)
|
||||
webfinger (1.2.0)
|
||||
activesupport
|
||||
httpclient (>= 2.4)
|
||||
webmock (3.18.1)
|
||||
addressable (>= 2.8.0)
|
||||
crack (>= 0.3.2)
|
||||
@@ -697,7 +754,7 @@ GEM
|
||||
xml-simple (1.1.8)
|
||||
xpath (3.2.0)
|
||||
nokogiri (~> 1.8)
|
||||
zeitwerk (2.6.0)
|
||||
zeitwerk (2.6.1)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
@@ -751,6 +808,7 @@ DEPENDENCIES
|
||||
foreman
|
||||
fuubar (~> 2.5.1)
|
||||
geocoder
|
||||
gitlab-omniauth-openid-connect
|
||||
gmaps4rails
|
||||
good_migrations
|
||||
haml
|
||||
@@ -775,6 +833,8 @@ DEPENDENCIES
|
||||
monetize (~> 1.11)
|
||||
oauth2 (~> 1.4.7)
|
||||
ofn-qz!
|
||||
omniauth-rails_csrf_protection
|
||||
openid_connect (~> 1.3)
|
||||
order_management!
|
||||
pagy (~> 5.1)
|
||||
paper_trail (~> 12.1.0)
|
||||
|
||||
@@ -22,24 +22,6 @@
|
||||
//= require angular-rails-templates
|
||||
//= require lodash.underscore.js
|
||||
|
||||
// datetimepicker (fil, nb)
|
||||
//= require flatpickr/dist/flatpickr.min
|
||||
//= require flatpickr/dist/l10n/ar
|
||||
//= require flatpickr/dist/l10n/cat
|
||||
//= require flatpickr/dist/l10n/cy
|
||||
//= require flatpickr/dist/l10n/de
|
||||
//= require flatpickr/dist/l10n/es
|
||||
//= require flatpickr/dist/l10n/fr
|
||||
//= require flatpickr/dist/l10n/it
|
||||
//= require flatpickr/dist/l10n/nl
|
||||
//= require flatpickr/dist/l10n/pl
|
||||
//= require flatpickr/dist/l10n/pt
|
||||
//= require flatpickr/dist/l10n/ru
|
||||
//= require flatpickr/dist/l10n/sv
|
||||
//= require flatpickr/dist/l10n/tr
|
||||
//= require shortcut-buttons-flatpickr/dist/shortcut-buttons-flatpickr.min
|
||||
//= require flatpickr/dist/plugins/labelPlugin/labelPlugin
|
||||
|
||||
// spree
|
||||
//= require admin/spree/spree
|
||||
//= require admin/spree/spree-select2
|
||||
|
||||
@@ -261,7 +261,8 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout
|
||||
product = BulkProducts.find product.id
|
||||
variant.unit_value = parseFloat(match[1].replace(",", "."))
|
||||
variant.unit_value = null if isNaN(variant.unit_value)
|
||||
variant.unit_value *= product.variant_unit_scale if variant.unit_value && product.variant_unit_scale
|
||||
if variant.unit_value && product.variant_unit_scale
|
||||
variant.unit_value = parseFloat(window.bigDecimal.multiply(variant.unit_value, product.variant_unit_scale, 2))
|
||||
variant.unit_description = match[3]
|
||||
|
||||
$scope.incrementLimit = ->
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
angular.module("admin.enterprises")
|
||||
.controller "enterpriseCtrl", ($scope, $http, $window, NavigationCheck, enterprise, Enterprises, EnterprisePaymentMethods, SideMenu, StatusMessage, RequestMonitor) ->
|
||||
.controller "enterpriseCtrl", ($scope, $http, $window, NavigationCheck, enterprise, Enterprises, SideMenu, StatusMessage, RequestMonitor) ->
|
||||
$scope.Enterprise = enterprise
|
||||
$scope.Enterprises = Enterprises
|
||||
$scope.PaymentMethods = EnterprisePaymentMethods.paymentMethods
|
||||
$scope.navClear = NavigationCheck.clear
|
||||
$scope.menu = SideMenu
|
||||
$scope.newManager = { id: null, email: (t('add_manager')) }
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
angular.module("admin.enterprises")
|
||||
.factory "EnterprisePaymentMethods", (enterprise, PaymentMethods) ->
|
||||
new class EnterprisePaymentMethods
|
||||
paymentMethods: PaymentMethods.all
|
||||
|
||||
constructor: ->
|
||||
for payment_method in @paymentMethods
|
||||
payment_method.selected = payment_method.id in enterprise.payment_method_ids
|
||||
|
||||
displayColor: ->
|
||||
if @paymentMethods.length > 0 && @selectedCount() > 0
|
||||
"blue"
|
||||
else
|
||||
"red"
|
||||
|
||||
selectedCount: ->
|
||||
@paymentMethods.reduce (count, payment_method) ->
|
||||
count++ if payment_method.selected
|
||||
count
|
||||
, 0
|
||||
@@ -25,6 +25,10 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
|
||||
$scope.resetFilters()
|
||||
$scope.refreshData()
|
||||
|
||||
$scope.$watchCollection "[startDate, endDate]", (newValues, oldValues) ->
|
||||
if newValues != oldValues
|
||||
$scope.refreshData()
|
||||
|
||||
$scope.refreshData = ->
|
||||
unless !$scope.orderCycleFilter? || $scope.orderCycleFilter == ''
|
||||
$scope.setOrderCycleDateRange()
|
||||
|
||||
@@ -18,7 +18,8 @@ angular.module('admin.orderCycles')
|
||||
OrderCycle.exchangeDirection(exchange)
|
||||
|
||||
$scope.enterprisesWithFees = ->
|
||||
$scope.enterprises[id] for id in [OrderCycle.participatingEnterpriseIds()..., [OrderCycle.order_cycle.coordinator_id]...] when $scope.enterpriseFeesForEnterprise(id).length > 0
|
||||
ids = [OrderCycle.participatingEnterpriseIds()..., [OrderCycle.order_cycle.coordinator_id]...]
|
||||
$scope.enterprises[id] for id in Array.from(new Set(ids)) when $scope.enterpriseFeesForEnterprise(id).length > 0
|
||||
|
||||
$scope.removeExchange = ($event, exchange) ->
|
||||
$event.preventDefault()
|
||||
|
||||
@@ -1,21 +1,4 @@
|
||||
angular.module('admin.orderCycles', ['ngTagsInput', 'admin.indexUtils', 'admin.enterprises'])
|
||||
.directive 'datetimepicker', ($timeout, $parse) ->
|
||||
require: "ngModel"
|
||||
link: (scope, element, attrs, ngModel) ->
|
||||
$timeout ->
|
||||
fp = flatpickr(element, Object.assign({},
|
||||
window.FLATPICKR_DATETIME_DEFAULT, {
|
||||
onOpen: (selectedDates, dateStr, instance) ->
|
||||
instance.setDate(ngModel.$modelValue)
|
||||
instance.input.dispatchEvent(new Event('focus', { bubbles: true }));
|
||||
}));
|
||||
fp.minuteElement.addEventListener "keyup", (e) ->
|
||||
if !isNaN(event.target.value)
|
||||
fp.setDate(fp.selectedDates[0].setMinutes(e.target.value), true)
|
||||
fp.hourElement.addEventListener "keyup", (e) ->
|
||||
if !isNaN(event.target.value)
|
||||
fp.setDate(fp.selectedDates[0].setHours(e.target.value), true)
|
||||
|
||||
.directive 'ofnOnChange', ->
|
||||
(scope, element, attrs) ->
|
||||
element.bind 'change', ->
|
||||
|
||||
@@ -93,9 +93,9 @@ angular.module('admin.orderCycles').factory 'OrderCycle', ($resource, $window, $
|
||||
variant_ids
|
||||
|
||||
participatingEnterpriseIds: ->
|
||||
suppliers = (exchange.enterprise_id for exchange in this.order_cycle.incoming_exchanges)
|
||||
distributors = (exchange.enterprise_id for exchange in this.order_cycle.outgoing_exchanges)
|
||||
jQuery.unique(suppliers.concat(distributors)).sort()
|
||||
suppliers = (parseInt(exchange.enterprise_id) for exchange in this.order_cycle.incoming_exchanges)
|
||||
distributors = (parseInt(exchange.enterprise_id) for exchange in this.order_cycle.outgoing_exchanges)
|
||||
Array.from(new Set([suppliers..., distributors...]))
|
||||
|
||||
exchangesByDirection: (direction) ->
|
||||
if direction == 'incoming'
|
||||
|
||||
@@ -29,6 +29,8 @@ angular.module("admin.orders").controller "ordersCtrl", ($scope, $timeout, Reque
|
||||
$scope.q = {
|
||||
completed_at_not_null: true
|
||||
}
|
||||
e = new CustomEvent("flatpickr_clear");
|
||||
window.dispatchEvent(e)
|
||||
|
||||
$scope.clearFilters = () ->
|
||||
KeyValueMapStore.clearKeyValueMap()
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
angular.module("admin.paymentMethods").controller "paymentMethodsCtrl", ($scope, PaymentMethods) ->
|
||||
$scope.findPaymentMethodByID = (id) ->
|
||||
$scope.PaymentMethod = PaymentMethods.byID[id]
|
||||
@@ -65,7 +65,8 @@ angular.module("ofn.admin").factory "BulkProducts", (ProductResource, dataFetche
|
||||
variantUnitValue: (product, variant) ->
|
||||
if variant.unit_value?
|
||||
if product.variant_unit_scale
|
||||
@divideAsInteger variant.unit_value, product.variant_unit_scale
|
||||
variant_unit_value = @divideAsInteger variant.unit_value, product.variant_unit_scale
|
||||
parseFloat(window.bigDecimal.round(variant_unit_value, 2))
|
||||
else
|
||||
variant.unit_value
|
||||
else
|
||||
|
||||
@@ -1,70 +1,4 @@
|
||||
$(document).ready(function() {
|
||||
var onClickButtons = function(index, fp) {
|
||||
var date;
|
||||
// Memorize index used for the 'Close' button
|
||||
// (currently it has index of 1)
|
||||
var closeButtonIndex = 1;
|
||||
switch (index) {
|
||||
case 0:
|
||||
date = new Date();
|
||||
break;
|
||||
case closeButtonIndex:
|
||||
fp.close();
|
||||
break;
|
||||
}
|
||||
// Set the date unless clicked button was the 'Close' one
|
||||
if (index != closeButtonIndex) {
|
||||
fp.setDate(date, true);
|
||||
}
|
||||
}
|
||||
window.FLATPICKR_DATE_DEFAULT = {
|
||||
altInput: true,
|
||||
altFormat: Spree.translations.flatpickr_date_format,
|
||||
dateFormat: "Y-m-d",
|
||||
locale: I18n.base_locale,
|
||||
plugins: [
|
||||
ShortcutButtonsPlugin({
|
||||
button: [
|
||||
{
|
||||
label: Spree.translations.today
|
||||
},
|
||||
{
|
||||
label: Spree.translations.close
|
||||
}
|
||||
],
|
||||
label: "or",
|
||||
onClick: onClickButtons
|
||||
}),
|
||||
labelPlugin({})
|
||||
]
|
||||
}
|
||||
window.FLATPICKR_DATETIME_DEFAULT = Object.assign(
|
||||
{},
|
||||
window.FLATPICKR_DATE_DEFAULT,
|
||||
{
|
||||
altInput: true,
|
||||
altFormat: Spree.translations.flatpickr_datetime_format,
|
||||
dateFormat: "Y-m-d H:i",
|
||||
enableTime: true,
|
||||
time_24hr: true,
|
||||
plugins: [
|
||||
ShortcutButtonsPlugin({
|
||||
button: [
|
||||
{
|
||||
label: Spree.translations.now
|
||||
},
|
||||
{
|
||||
label: Spree.translations.close
|
||||
}
|
||||
],
|
||||
label: "or",
|
||||
onClick: onClickButtons
|
||||
}),
|
||||
labelPlugin({})
|
||||
]
|
||||
}
|
||||
);
|
||||
flatpickr(".datetimepicker", window.FLATPICKR_DATETIME_DEFAULT);
|
||||
$('a.close').click(function(event){
|
||||
event.preventDefault();
|
||||
$(this).parent().slideUp(250);
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
angular.module("admin.utils").directive "datepicker", ($window, $timeout) ->
|
||||
require: "ngModel"
|
||||
link: (scope, element, attrs, ngModel) ->
|
||||
$timeout ->
|
||||
flapickrInstance = flatpickr(element, Object.assign(
|
||||
{},
|
||||
$window.FLATPICKR_DATE_DEFAULT, {
|
||||
onOpen: (selectedDates, dateStr, instance) ->
|
||||
instance.setDate(ngModel.$modelValue)
|
||||
}
|
||||
));
|
||||
ngModel.$render = () ->
|
||||
newValue = ngModel.$viewValue;
|
||||
flapickrInstance?.setDate(newValue)
|
||||
9
app/components/multiple_checked_select_component.rb
Normal file
9
app/components/multiple_checked_select_component.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class MultipleCheckedSelectComponent < ViewComponent::Base
|
||||
def initialize(name:, options:, selected:)
|
||||
@name = name
|
||||
@options = options.map { |option| [option[0], option[1].to_sym] }
|
||||
@selected = selected.nil? ? [] : selected.map(&:to_sym)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,13 @@
|
||||
.ofn-drop-down.ofn-drop-down-v2{ data: { controller: "multiple-checked-select" } }
|
||||
%div.ofn-drop-down-label{ "data-multiple-checked-select-target": "button" }
|
||||
%span{class: "label"}= t('admin.columns')
|
||||
%span{ class: "icon-caret-down", "data-multiple-checked-select-target": "caret" }
|
||||
%div.menu{ class: "hidden", "data-multiple-checked-select-target": "options" }
|
||||
%div.filter
|
||||
%input{ type: "text", "data-multiple-checked-select-target": "filter", placeholder: I18n.t('components.multiple_checked_select.filter_placeholder') }
|
||||
%hr
|
||||
%div.menu_items
|
||||
- @options.each do |option|
|
||||
%label.menu_item{ "data-multiple-checked-select-target": "option", "data-value": option[1], "data-label": option[0] }
|
||||
%input.redesigned-input{ type: "checkbox", checked: @selected.include?(option[1]), name: "#{@name}[]", value: option[1] }
|
||||
= option[0]
|
||||
15
app/constraints/feature_toggle_constraint.rb
Normal file
15
app/constraints/feature_toggle_constraint.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class FeatureToggleConstraint
|
||||
def initialize(feature_name)
|
||||
@feature = feature_name
|
||||
end
|
||||
|
||||
def matches?(request)
|
||||
OpenFoodNetwork::FeatureToggle.enabled?(@feature, current_user(request))
|
||||
end
|
||||
|
||||
def current_user(request)
|
||||
request.env['warden'].user
|
||||
end
|
||||
end
|
||||
@@ -1,11 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class SplitCheckoutConstraint
|
||||
def matches?(request)
|
||||
OpenFoodNetwork::FeatureToggle.enabled? :split_checkout, current_user(request)
|
||||
end
|
||||
|
||||
def current_user(request)
|
||||
request.env['warden'].user
|
||||
end
|
||||
end
|
||||
@@ -6,6 +6,7 @@ module Admin
|
||||
class EnterpriseFeesController < Admin::ResourceController
|
||||
before_action :load_enterprise_fee_set, only: :index
|
||||
before_action :load_data
|
||||
before_action :check_enterprise_fee_input, only: [:bulk_update]
|
||||
|
||||
def index
|
||||
@include_calculators = params[:include_calculators].present?
|
||||
@@ -35,13 +36,6 @@ module Admin
|
||||
end
|
||||
|
||||
def bulk_update
|
||||
@flat_percent_value = enterprise_fee_bulk_params.dig('collection_attributes', '0', 'calculator_attributes', 'preferred_flat_percent')
|
||||
|
||||
unless @flat_percent_value.nil? || Float(@flat_percent_value, exception: false)
|
||||
flash[:error] = I18n.t(:calculator_preferred_value_error)
|
||||
return redirect_to redirect_path
|
||||
end
|
||||
|
||||
@enterprise_fee_set = Sets::EnterpriseFeeSet.new(enterprise_fee_bulk_params)
|
||||
|
||||
if @enterprise_fee_set.save
|
||||
@@ -105,5 +99,25 @@ module Admin
|
||||
]
|
||||
)
|
||||
end
|
||||
|
||||
def check_enterprise_fee_input
|
||||
enterprise_fee_bulk_params['collection_attributes'].each do |_, fee_row|
|
||||
enterprise_fees = fee_row['calculator_attributes']&.slice(
|
||||
:preferred_flat_percent, :preferred_amount,
|
||||
:preferred_first_item, :preferred_additional_item,
|
||||
:preferred_minimal_amount, :preferred_normal_amount,
|
||||
:preferred_discount_amount, :preferred_per_unit
|
||||
)
|
||||
|
||||
next unless enterprise_fees
|
||||
|
||||
enterprise_fees.each do |_, enterprise_amount|
|
||||
unless enterprise_amount.nil? || Float(enterprise_amount, exception: false)
|
||||
flash[:error] = I18n.t(:calculator_preferred_value_error)
|
||||
return redirect_to redirect_path
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
7
app/controllers/admin/oidc_settings_controller.rb
Normal file
7
app/controllers/admin/oidc_settings_controller.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Admin
|
||||
class OidcSettingsController < Spree::Admin::BaseController
|
||||
def index; end
|
||||
end
|
||||
end
|
||||
@@ -43,17 +43,19 @@ module Admin
|
||||
@report_type = report_type
|
||||
@report_subtypes = report_subtypes
|
||||
@report_subtype = report_subtype
|
||||
@report_title = if report_subtype
|
||||
report_subtype_title
|
||||
else
|
||||
I18n.t(:name, scope: [:admin, :reports, @report_type])
|
||||
end
|
||||
|
||||
# Initialize data
|
||||
params[:display_summary_row] = true if request.get?
|
||||
if OpenFoodNetwork::FeatureToggle.enabled?(:report_inverse_columns_logic,
|
||||
spree_current_user)
|
||||
@params_fields_to_show = if request.get?
|
||||
@report.columns.keys
|
||||
else
|
||||
params[:fields_to_show]
|
||||
end
|
||||
end
|
||||
@params_fields_to_show = if request.get?
|
||||
@report.columns.keys - @report.fields_to_hide
|
||||
else
|
||||
params[:fields_to_show]
|
||||
end
|
||||
|
||||
@data = Reporting::FrontendData.new(spree_current_user)
|
||||
end
|
||||
|
||||
@@ -40,7 +40,7 @@ module Api
|
||||
end
|
||||
|
||||
def restrict_feature
|
||||
not_found unless Flipper.enabled?(:api_v1, @current_api_user)
|
||||
not_found unless OpenFoodNetwork::FeatureToggle.enabled?(:api_v1, @current_api_user)
|
||||
end
|
||||
|
||||
def current_ability
|
||||
|
||||
@@ -22,12 +22,8 @@ class BaseController < ApplicationController
|
||||
end
|
||||
|
||||
# Default to the only order cycle if there's only one
|
||||
#
|
||||
# Here we need to use @order_cycles.size not @order_cycles.count
|
||||
# because OrderCyclesList returns a modified ActiveRecord::Relation
|
||||
# and these modifications are not seen if it is reloaded with count
|
||||
def set_order_cycle
|
||||
return if @order_cycles.size != 1
|
||||
return if @order_cycles.count != 1
|
||||
|
||||
current_order(true).set_order_cycle! @order_cycles.first
|
||||
end
|
||||
|
||||
@@ -50,7 +50,9 @@ module OrderCompletion
|
||||
end
|
||||
|
||||
def order_invalid!
|
||||
Bugsnag.notify("Notice: invalid order loaded during checkout", order: @order)
|
||||
Bugsnag.notify("Notice: invalid order loaded during checkout") do |payload|
|
||||
payload.add_metadata :order, @order
|
||||
end
|
||||
|
||||
flash[:error] = t('checkout.order_not_loaded')
|
||||
redirect_to main_app.shop_path
|
||||
@@ -81,7 +83,9 @@ module OrderCompletion
|
||||
end
|
||||
|
||||
def processing_failed(error = RuntimeError.new(order_processing_error))
|
||||
Bugsnag.notify(error, order: @order)
|
||||
Bugsnag.notify(error) do |payload|
|
||||
payload.add_metadata :order, @order
|
||||
end
|
||||
flash[:error] = order_processing_error if flash.blank?
|
||||
Checkout::PostCheckoutActions.new(@order).failure
|
||||
end
|
||||
|
||||
@@ -21,7 +21,9 @@ module OrderStockCheck
|
||||
def check_order_cycle_expiry
|
||||
return unless current_order_cycle&.closed?
|
||||
|
||||
Bugsnag.notify("Notice: order cycle closed during checkout completion", order: current_order)
|
||||
Bugsnag.notify("Notice: order cycle closed during checkout completion") do |payload|
|
||||
payload.add_metadata :order, current_order
|
||||
end
|
||||
current_order.empty!
|
||||
current_order.set_order_cycle! nil
|
||||
|
||||
@@ -39,7 +41,7 @@ module OrderStockCheck
|
||||
end
|
||||
|
||||
def reset_order_to_cart
|
||||
return if Flipper.enabled? :split_checkout, spree_current_user
|
||||
return if OpenFoodNetwork::FeatureToggle.enabled? :split_checkout, spree_current_user
|
||||
|
||||
OrderCheckoutRestart.new(@order).call
|
||||
end
|
||||
|
||||
@@ -39,6 +39,10 @@ module ReportsActions
|
||||
params[:report_subtype] || report_subtypes_codes.first
|
||||
end
|
||||
|
||||
def report_subtype_title
|
||||
report_subtypes.select { |_name, key| key.to_sym == report_subtype.to_sym }.first[0]
|
||||
end
|
||||
|
||||
def ransack_params
|
||||
raw_params[:q]
|
||||
end
|
||||
|
||||
16
app/controllers/omniauth_callbacks_controller.rb
Normal file
16
app/controllers/omniauth_callbacks_controller.rb
Normal file
@@ -0,0 +1,16 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
||||
def openid_connect
|
||||
spree_current_user.link_from_omniauth(request.env["omniauth.auth"])
|
||||
|
||||
redirect_to admin_oidc_settings_path
|
||||
end
|
||||
|
||||
def failure
|
||||
error_message = request.env["omniauth.error"].to_s
|
||||
flash[:error] = t("devise.oidc.failure", error: error_message)
|
||||
|
||||
super
|
||||
end
|
||||
end
|
||||
@@ -227,10 +227,10 @@ module Spree
|
||||
|
||||
def notify_bugsnag(error, product, variant)
|
||||
Bugsnag.notify(error) do |report|
|
||||
report.add_tab(:product, product.attributes)
|
||||
report.add_tab(:product_error, product.errors.first) unless product.valid?
|
||||
report.add_tab(:variant, variant.attributes)
|
||||
report.add_tab(:variant_error, variant.errors.first) unless variant.valid?
|
||||
report.add_metadata(:product, product.attributes)
|
||||
report.add_metadata(:product_error, product.errors.first) unless product.valid?
|
||||
report.add_metadata(:variant, variant.attributes)
|
||||
report.add_metadata(:variant_error, variant.errors.first) unless variant.valid?
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -95,11 +95,20 @@ module Spree
|
||||
end
|
||||
|
||||
def check_shipping_fee_input
|
||||
shipping_amount = permitted_resource_params.dig('calculator_attributes', 'preferred_amount')
|
||||
shipping_fees = permitted_resource_params['calculator_attributes']&.slice(
|
||||
:preferred_flat_percent, :preferred_amount,
|
||||
:preferred_first_item, :preferred_additional_item,
|
||||
:preferred_minimal_amount, :preferred_normal_amount,
|
||||
:preferred_discount_amount, :preferred_per_unit
|
||||
)
|
||||
|
||||
unless shipping_amount.nil? || Float(shipping_amount, exception: false)
|
||||
flash[:error] = I18n.t(:calculator_preferred_value_error)
|
||||
return redirect_to location_after_save
|
||||
return unless shipping_fees
|
||||
|
||||
shipping_fees.each do |_, shipping_amount|
|
||||
unless shipping_amount.nil? || Float(shipping_amount, exception: false)
|
||||
flash[:error] = I18n.t(:calculator_preferred_value_error)
|
||||
return redirect_to location_after_save
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -32,7 +32,7 @@ module Spree
|
||||
def load_object
|
||||
@user ||= find_user
|
||||
if @user
|
||||
authorize! params[:action].to_sym, @user
|
||||
authorize! :update, @user
|
||||
else
|
||||
redirect_to main_app.login_path
|
||||
end
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "spree/core/controller_helpers/auth"
|
||||
require "spree/core/controller_helpers/common"
|
||||
require "spree/core/controller_helpers/order"
|
||||
|
||||
module Spree
|
||||
class UserRegistrationsController < Devise::RegistrationsController
|
||||
helper 'spree/base'
|
||||
|
||||
include Spree::Core::ControllerHelpers::Auth
|
||||
include Spree::Core::ControllerHelpers::Common
|
||||
include Spree::Core::ControllerHelpers::Order
|
||||
|
||||
before_action :check_permissions, only: [:edit, :update]
|
||||
skip_before_action :require_no_authentication
|
||||
|
||||
# GET /resource/edit
|
||||
def edit
|
||||
super
|
||||
end
|
||||
|
||||
# PUT /resource
|
||||
def update
|
||||
super
|
||||
end
|
||||
|
||||
# DELETE /resource
|
||||
def destroy
|
||||
super
|
||||
end
|
||||
|
||||
# GET /resource/cancel
|
||||
# Forces the session data which is usually expired after sign
|
||||
# in to be expired now. This is useful if the user wants to
|
||||
# cancel oauth signing in/up in the middle of the process,
|
||||
# removing all OAuth session data.
|
||||
def cancel
|
||||
super
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def check_permissions
|
||||
authorize!(:create, resource)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,13 +1,23 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'open_food_network/error_logger'
|
||||
require "spree/core/controller_helpers/auth"
|
||||
require "spree/core/controller_helpers/common"
|
||||
require "spree/core/controller_helpers/order"
|
||||
|
||||
class UserRegistrationsController < Spree::UserRegistrationsController
|
||||
class UserRegistrationsController < Devise::RegistrationsController
|
||||
I18N_SCOPE = 'devise.user_registrations.spree_user'
|
||||
|
||||
before_action :set_checkout_redirect, only: :create
|
||||
helper 'spree/base'
|
||||
|
||||
include Spree::Core::ControllerHelpers::Auth
|
||||
include Spree::Core::ControllerHelpers::Common
|
||||
include Spree::Core::ControllerHelpers::Order
|
||||
include I18nHelper
|
||||
|
||||
skip_before_action :require_no_authentication
|
||||
|
||||
before_action :set_checkout_redirect, only: :create
|
||||
before_action :set_locale
|
||||
|
||||
# POST /resource/sign_up
|
||||
|
||||
@@ -32,25 +32,9 @@ module CheckoutHelper
|
||||
}
|
||||
end
|
||||
|
||||
enterprise_fee_adjustments = adjustments.select { |a|
|
||||
a.originator_type == 'EnterpriseFee' && a.adjustable_type != 'Spree::LineItem'
|
||||
}
|
||||
adjustments.reject! { |a|
|
||||
a.originator_type == 'EnterpriseFee' && a.adjustable_type != 'Spree::LineItem'
|
||||
}
|
||||
unless exclude.include? :admin_and_handling
|
||||
adjustments << Spree::Adjustment.new(
|
||||
label: I18n.t(:orders_form_admin), amount: enterprise_fee_adjustments.sum(&:amount)
|
||||
)
|
||||
end
|
||||
|
||||
adjustments
|
||||
end
|
||||
|
||||
def display_line_item_fees_total_for(order)
|
||||
Spree::Money.new order.adjustments.enterprise_fee.sum(:amount), currency: order.currency
|
||||
end
|
||||
|
||||
def checkout_line_item_fees(order)
|
||||
order.line_item_adjustments.enterprise_fee
|
||||
end
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'open_food_network/available_payment_method_filter'
|
||||
|
||||
module EnterprisesHelper
|
||||
def current_distributor
|
||||
@current_distributor ||= current_order(false)&.distributor
|
||||
@@ -18,18 +16,7 @@ module EnterprisesHelper
|
||||
end
|
||||
|
||||
def available_payment_methods
|
||||
return [] if current_distributor.blank?
|
||||
|
||||
payment_methods = current_distributor.payment_methods.available(:both).to_a
|
||||
|
||||
filter = OpenFoodNetwork::AvailablePaymentMethodFilter.new
|
||||
filter.filter!(payment_methods)
|
||||
|
||||
applicator = OpenFoodNetwork::TagRuleApplicator.new(current_distributor,
|
||||
"FilterPaymentMethods", current_customer&.tag_list)
|
||||
applicator.filter!(payment_methods)
|
||||
|
||||
payment_methods
|
||||
OrderAvailablePaymentMethods.new(current_order, current_customer).to_a
|
||||
end
|
||||
|
||||
def managed_enterprises
|
||||
|
||||
@@ -55,7 +55,9 @@ class SubscriptionConfirmJob < ActiveJob::Base
|
||||
if order.errors.any?
|
||||
send_failed_payment_email(order)
|
||||
else
|
||||
Bugsnag.notify(e, order: order)
|
||||
Bugsnag.notify(e) do |payload|
|
||||
payload.add_metadata :order, order
|
||||
end
|
||||
send_failed_payment_email(order, e.message)
|
||||
end
|
||||
end
|
||||
@@ -106,6 +108,9 @@ class SubscriptionConfirmJob < ActiveJob::Base
|
||||
record_and_log_error(:failed_payment, order, error_message)
|
||||
SubscriptionMailer.failed_payment_email(order).deliver_now
|
||||
rescue StandardError => e
|
||||
Bugsnag.notify(e, order: order, error_message: error_message)
|
||||
Bugsnag.notify(e) do |payload|
|
||||
payload.add_metadata :order, order
|
||||
payload.add_metadata :error_message, error_message
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,16 +2,18 @@
|
||||
|
||||
module Spree
|
||||
class ShipmentMailer < BaseMailer
|
||||
def shipped_email(shipment, resend = false)
|
||||
def shipped_email(shipment, delivery:)
|
||||
@shipment = shipment.respond_to?(:id) ? shipment : Spree::Shipment.find(shipment)
|
||||
subject = (resend ? "[#{Spree.t(:resend).upcase}] " : '') + base_subject
|
||||
@delivery = delivery
|
||||
subject = base_subject
|
||||
mail(to: @shipment.order.email, from: from_address, subject: subject)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def base_subject
|
||||
"#{@shipment.order.distributor.name} #{default_i18n_subject} ##{@shipment.order.number}"
|
||||
default_subject = !@delivery ? t('.picked_up_subject') : default_i18n_subject
|
||||
"#{@shipment.order.distributor.name} #{default_subject} ##{@shipment.order.number}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -9,9 +9,9 @@ module PaymentMethodDistributors
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
has_and_belongs_to_many :distributors, join_table: 'distributors_payment_methods',
|
||||
class_name: 'Enterprise',
|
||||
foreign_key: 'payment_method_id',
|
||||
association_foreign_key: 'distributor_id'
|
||||
has_many :distributor_payment_methods, dependent: :destroy
|
||||
has_many :distributors, through: :distributor_payment_methods,
|
||||
class_name: 'Enterprise',
|
||||
foreign_key: 'distributor_id'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,20 +6,12 @@ module ProductStock
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def on_demand
|
||||
if variants?
|
||||
raise 'Cannot determine product on_demand value of product with multiple variants' if variants.size > 1
|
||||
raise 'Cannot determine product on_demand value of product with multiple variants' if variants.size > 1
|
||||
|
||||
variants.first.on_demand
|
||||
else
|
||||
master.on_demand
|
||||
end
|
||||
variants.first.on_demand
|
||||
end
|
||||
|
||||
def on_hand
|
||||
if variants?
|
||||
variants.map(&:on_hand).reduce(:+)
|
||||
else
|
||||
master.on_hand
|
||||
end
|
||||
variants.map(&:on_hand).reduce(:+)
|
||||
end
|
||||
end
|
||||
|
||||
7
app/models/distributor_payment_method.rb
Normal file
7
app/models/distributor_payment_method.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class DistributorPaymentMethod < ApplicationRecord
|
||||
self.table_name = "distributors_payment_methods"
|
||||
belongs_to :payment_method, class_name: "Spree::PaymentMethod", touch: true
|
||||
belongs_to :distributor, class_name: "Enterprise", touch: true
|
||||
end
|
||||
@@ -16,6 +16,19 @@ class Enterprise < ApplicationRecord
|
||||
large: { resize_to_fill: [1200, 260] },
|
||||
}.freeze
|
||||
|
||||
self.ignored_columns = %i(terms_and_conditions_file_name
|
||||
terms_and_conditions_content_type
|
||||
terms_and_conditions_file_size
|
||||
terms_and_conditions_updated_at
|
||||
logo_file_name
|
||||
logo_content_type
|
||||
logo_file_size
|
||||
logo_updated_at
|
||||
promo_image_file_name
|
||||
promo_image_content_type
|
||||
promo_image_file_size
|
||||
promo_image_updated_at)
|
||||
|
||||
searchable_attributes :sells, :is_primary_producer
|
||||
searchable_associations :properties
|
||||
searchable_scopes :is_primary_producer, :is_distributor, :is_hub, :activated, :visible,
|
||||
@@ -56,10 +69,9 @@ class Enterprise < ApplicationRecord
|
||||
has_many :users, through: :enterprise_roles
|
||||
belongs_to :owner, class_name: 'Spree::User',
|
||||
inverse_of: :owned_enterprises
|
||||
has_and_belongs_to_many :payment_methods, join_table: 'distributors_payment_methods',
|
||||
class_name: 'Spree::PaymentMethod',
|
||||
foreign_key: 'distributor_id'
|
||||
has_many :distributor_payment_methods, foreign_key: :distributor_id
|
||||
has_many :distributor_shipping_methods, foreign_key: :distributor_id
|
||||
has_many :payment_methods, through: :distributor_payment_methods
|
||||
has_many :shipping_methods, through: :distributor_shipping_methods
|
||||
has_many :customers
|
||||
has_many :inventory_items
|
||||
@@ -197,15 +209,14 @@ class Enterprise < ApplicationRecord
|
||||
joins(:enterprise_roles).where('enterprise_roles.user_id = ?', user.id)
|
||||
end
|
||||
}
|
||||
scope :relatives_of_one_union_others, lambda { |one, others|
|
||||
|
||||
scope :parents_of_one_union_others, lambda { |one, others|
|
||||
where("
|
||||
enterprises.id IN
|
||||
(SELECT child_id FROM enterprise_relationships WHERE enterprise_relationships.parent_id=?)
|
||||
OR enterprises.id IN
|
||||
(SELECT parent_id FROM enterprise_relationships WHERE enterprise_relationships.child_id=?)
|
||||
OR enterprises.id IN
|
||||
(?)
|
||||
", one, one, others)
|
||||
", one, others)
|
||||
}
|
||||
|
||||
def business_address_empty?(attributes)
|
||||
@@ -260,9 +271,9 @@ class Enterprise < ApplicationRecord
|
||||
", id, id)
|
||||
end
|
||||
|
||||
def plus_relatives_and_oc_producers(order_cycles)
|
||||
def plus_parents_and_order_cycle_producers(order_cycles)
|
||||
oc_producer_ids = Exchange.in_order_cycle(order_cycles).incoming.pluck :sender_id
|
||||
Enterprise.not_hidden.is_primary_producer.relatives_of_one_union_others(id, oc_producer_ids | [id])
|
||||
Enterprise.not_hidden.is_primary_producer.parents_of_one_union_others(id, oc_producer_ids | [id])
|
||||
end
|
||||
|
||||
def relatives_including_self
|
||||
@@ -388,7 +399,7 @@ class Enterprise < ApplicationRecord
|
||||
end
|
||||
|
||||
def ready_for_checkout?
|
||||
shipping_methods.frontend.any? && payment_methods.available.any?
|
||||
shipping_methods.frontend.any? && payment_methods.available.any?(&:configured?)
|
||||
end
|
||||
|
||||
def self.find_available_permalink(test_permalink)
|
||||
|
||||
@@ -5,6 +5,15 @@ require 'open_food_network/locking'
|
||||
class EnterpriseGroup < ApplicationRecord
|
||||
include PermalinkGenerator
|
||||
|
||||
self.ignored_columns = %i(logo_file_name
|
||||
logo_content_type
|
||||
logo_file_size
|
||||
logo_updated_at
|
||||
promo_image_file_name
|
||||
promo_image_content_type
|
||||
promo_image_file_size
|
||||
promo_image_updated_at)
|
||||
|
||||
acts_as_list
|
||||
|
||||
has_and_belongs_to_many :enterprises, join_table: 'enterprise_groups_enterprises'
|
||||
|
||||
@@ -24,6 +24,9 @@ class OrderCycle < ApplicationRecord
|
||||
has_many :distributors, -> { distinct }, source: :receiver, through: :cached_outgoing_exchanges
|
||||
has_many :order_cycle_schedules
|
||||
has_many :schedules, through: :order_cycle_schedules
|
||||
has_and_belongs_to_many :selected_distributor_payment_methods,
|
||||
class_name: 'DistributorPaymentMethod',
|
||||
join_table: 'order_cycles_distributor_payment_methods'
|
||||
has_and_belongs_to_many :selected_distributor_shipping_methods,
|
||||
class_name: 'DistributorShippingMethod',
|
||||
join_table: 'order_cycles_distributor_shipping_methods'
|
||||
@@ -152,12 +155,10 @@ class OrderCycle < ApplicationRecord
|
||||
]
|
||||
end
|
||||
|
||||
def attachable_payment_methods
|
||||
Spree::PaymentMethod.available(:both).
|
||||
joins("INNER JOIN distributors_payment_methods
|
||||
ON payment_method_id = spree_payment_methods.id").
|
||||
where("distributor_id IN (?)", distributor_ids).
|
||||
distinct
|
||||
def attachable_distributor_payment_methods
|
||||
DistributorPaymentMethod.joins(:payment_method).
|
||||
merge(Spree::PaymentMethod.available).
|
||||
where("distributor_id IN (?)", distributor_ids)
|
||||
end
|
||||
|
||||
def attachable_distributor_shipping_methods
|
||||
@@ -167,21 +168,7 @@ class OrderCycle < ApplicationRecord
|
||||
end
|
||||
|
||||
def clone!
|
||||
oc = dup
|
||||
oc.name = I18n.t("models.order_cycle.cloned_order_cycle_name", order_cycle: oc.name)
|
||||
oc.orders_open_at = oc.orders_close_at = oc.mails_sent = oc.processed_at = nil
|
||||
oc.coordinator_fee_ids = coordinator_fee_ids
|
||||
# rubocop:disable Layout/LineLength
|
||||
oc.preferred_product_selection_from_coordinator_inventory_only = preferred_product_selection_from_coordinator_inventory_only
|
||||
# rubocop:enable Layout/LineLength
|
||||
oc.schedule_ids = schedule_ids
|
||||
oc.save!
|
||||
exchanges.each { |e| e.clone!(oc) }
|
||||
oc.selected_distributor_shipping_method_ids = (
|
||||
attachable_distributor_shipping_methods.map(&:id) & selected_distributor_shipping_method_ids
|
||||
)
|
||||
sync_subscriptions
|
||||
oc.reload
|
||||
OrderCycleClone.new(self).create
|
||||
end
|
||||
|
||||
def variants
|
||||
@@ -293,6 +280,18 @@ class OrderCycle < ApplicationRecord
|
||||
items.each { |li| scoper.scope(li.variant) }
|
||||
end
|
||||
|
||||
def distributor_payment_methods
|
||||
if simple? || selected_distributor_payment_methods.none?
|
||||
attachable_distributor_payment_methods
|
||||
else
|
||||
attachable_distributor_payment_methods.where(
|
||||
"distributors_payment_methods.id IN (?) OR distributor_id NOT IN (?)",
|
||||
selected_distributor_payment_methods.map(&:id),
|
||||
selected_distributor_payment_methods.map(&:distributor_id)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def distributor_shipping_methods
|
||||
if simple? || selected_distributor_shipping_methods.none?
|
||||
attachable_distributor_shipping_methods
|
||||
|
||||
@@ -177,6 +177,8 @@ module Spree
|
||||
end
|
||||
|
||||
can [:admin, :create], :manager_invitation
|
||||
|
||||
can [:admin, :index], :oidc_setting
|
||||
end
|
||||
|
||||
def add_product_management_abilities(user)
|
||||
|
||||
@@ -9,6 +9,13 @@ module Spree
|
||||
large: { resize_to_limit: [600, 600] },
|
||||
}.freeze
|
||||
|
||||
self.ignored_columns = %i(attachment_file_name
|
||||
attachment_content_type
|
||||
attachment_file_size
|
||||
attachment_updated_at
|
||||
attachment_width
|
||||
attachment_height)
|
||||
|
||||
has_one_attached :attachment
|
||||
|
||||
validates :attachment, attached: true, content_type: %r{\Aimage/(png|jpeg|gif|jpg|svg\+xml|webp)\Z}
|
||||
|
||||
@@ -25,7 +25,7 @@ module Spree
|
||||
order.payment_required?
|
||||
}
|
||||
go_to_state :confirmation, if: ->(order) {
|
||||
Flipper.enabled? :split_checkout, order.created_by
|
||||
OpenFoodNetwork::FeatureToggle.enabled? :split_checkout, order.created_by
|
||||
}
|
||||
go_to_state :complete
|
||||
end
|
||||
@@ -311,7 +311,7 @@ module Spree
|
||||
# Creates new tax charges if there are any applicable rates. If prices already
|
||||
# include taxes then price adjustments are created instead.
|
||||
def create_tax_charge!
|
||||
return if state.in?(["cart", "address", "delivery"]) && Flipper.enabled?(:split_checkout)
|
||||
return if state.in?(["cart", "address", "delivery"]) && OpenFoodNetwork::FeatureToggle.enabled?(:split_checkout)
|
||||
|
||||
clear_legacy_taxes!
|
||||
|
||||
@@ -376,10 +376,6 @@ module Spree
|
||||
payment_state == 'paid' || payment_state == 'credit_owed'
|
||||
end
|
||||
|
||||
def available_payment_methods
|
||||
@available_payment_methods ||= PaymentMethod.available(:both)
|
||||
end
|
||||
|
||||
# "Checkout" is the initial state and, for card payments, "pending" is the state after auth
|
||||
# These are both valid states to process the payment
|
||||
def pending_payments
|
||||
@@ -540,9 +536,9 @@ module Spree
|
||||
# And the shipping fee is already up-to-date when this error occurs.
|
||||
# https://github.com/openfoodfoundation/openfoodnetwork/issues/3924
|
||||
Bugsnag.notify(e) do |report|
|
||||
report.add_tab(:order, attributes)
|
||||
report.add_tab(:shipment, shipment.attributes)
|
||||
report.add_tab(:shipment_in_db, Spree::Shipment.find_by(id: shipment.id).attributes)
|
||||
report.add_metadata(:order, attributes)
|
||||
report.add_metadata(:shipment, shipment.attributes)
|
||||
report.add_metadata(:shipment_in_db, Spree::Shipment.find_by(id: shipment.id).attributes)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ module Spree
|
||||
|
||||
after_initialize :init
|
||||
|
||||
scope :inactive_or_backend, -> { where("active = false OR display_on = 'back_end'") }
|
||||
|
||||
scope :production, -> { where(environment: 'production') }
|
||||
|
||||
scope :managed_by, lambda { |user|
|
||||
@@ -57,6 +59,10 @@ module Spree
|
||||
Rails.application.config.spree.payment_methods
|
||||
end
|
||||
|
||||
def configured?
|
||||
!stripe? || stripe_configured?
|
||||
end
|
||||
|
||||
def provider_class
|
||||
raise 'You must implement provider_class method for this gateway.'
|
||||
end
|
||||
@@ -71,6 +77,10 @@ module Spree
|
||||
nil
|
||||
end
|
||||
|
||||
def frontend?
|
||||
active? && display_on != "back_end"
|
||||
end
|
||||
|
||||
# The class that will process payments for this payment type, used for @payment.source
|
||||
# e.g. CreditCard in the case of a the Gateway payment type
|
||||
# nil means the payment method doesn't require a source e.g. check
|
||||
@@ -120,5 +130,17 @@ module Spree
|
||||
def distributor_validation
|
||||
validates_with DistributorsValidator
|
||||
end
|
||||
|
||||
def stripe?
|
||||
type.ends_with?("StripeSCA")
|
||||
end
|
||||
|
||||
def stripe_configured?
|
||||
Spree::Config.stripe_connect_enabled &&
|
||||
Stripe.publishable_key &&
|
||||
preferred_enterprise_id.present? &&
|
||||
preferred_enterprise_id > 0 &&
|
||||
stripe_account_id.present?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -251,11 +251,6 @@ module Spree
|
||||
permalink.present? ? permalink : (permalink_was || UrlGenerator.to_url(name))
|
||||
end
|
||||
|
||||
# the master variant is not a member of the variants array
|
||||
def variants?
|
||||
variants.any?
|
||||
end
|
||||
|
||||
def tax_category
|
||||
if self[:tax_category_id].nil?
|
||||
TaxCategory.find_by(is_default: true)
|
||||
|
||||
@@ -343,7 +343,8 @@ module Spree
|
||||
end
|
||||
|
||||
def send_shipped_email
|
||||
ShipmentMailer.shipped_email(id).deliver_later
|
||||
delivery = !!shipping_method.require_ship_address
|
||||
ShipmentMailer.shipped_email(id, delivery: delivery).deliver_later
|
||||
end
|
||||
|
||||
def update_adjustments
|
||||
|
||||
@@ -7,8 +7,10 @@ module Spree
|
||||
searchable_attributes :email
|
||||
|
||||
devise :database_authenticatable, :token_authenticatable, :registerable, :recoverable,
|
||||
:rememberable, :trackable, :validatable,
|
||||
:encryptable, :confirmable, encryptor: 'authlogic_sha512', reconfirmable: true
|
||||
:rememberable, :trackable, :validatable, :omniauthable,
|
||||
:encryptable, :confirmable,
|
||||
encryptor: 'authlogic_sha512', reconfirmable: true,
|
||||
omniauth_providers: [:openid_connect]
|
||||
|
||||
has_many :orders
|
||||
belongs_to :ship_address, class_name: 'Spree::Address'
|
||||
@@ -44,6 +46,8 @@ module Spree
|
||||
after_create :associate_customers, :associate_orders
|
||||
|
||||
validate :limit_owned_enterprises
|
||||
validates :uid, uniqueness: true, if: lambda { uid.present? }
|
||||
validates_email :uid, if: lambda { uid.present? }
|
||||
|
||||
class DestroyWithOrdersError < StandardError; end
|
||||
|
||||
@@ -51,6 +55,10 @@ module Spree
|
||||
User.admin.count > 0
|
||||
end
|
||||
|
||||
def link_from_omniauth(auth)
|
||||
update!(provider: auth.provider, uid: auth.uid)
|
||||
end
|
||||
|
||||
# Whether a user has a role or not.
|
||||
def has_spree_role?(role_in_question)
|
||||
spree_roles.where(name: role_in_question.to_s).any?
|
||||
|
||||
@@ -5,6 +5,11 @@ class TermsOfServiceFile < ApplicationRecord
|
||||
|
||||
validates :attachment, attached: true
|
||||
|
||||
self.ignored_columns = %i(attachment_file_name
|
||||
attachment_content_type
|
||||
attachment_file_size
|
||||
attachment_updated_at)
|
||||
|
||||
# The most recently uploaded file is the current one.
|
||||
def self.current
|
||||
order(:id).last
|
||||
|
||||
@@ -54,7 +54,7 @@ module Api
|
||||
|
||||
def producers
|
||||
ActiveModel::ArraySerializer.new(
|
||||
enterprise.plus_relatives_and_oc_producers(
|
||||
enterprise.plus_parents_and_order_cycle_producers(
|
||||
OrderCycle.not_closed.with_distributor(enterprise)
|
||||
),
|
||||
each_serializer: Api::EnterpriseThinSerializer
|
||||
@@ -63,7 +63,7 @@ module Api
|
||||
|
||||
def hubs
|
||||
ActiveModel::ArraySerializer.new(
|
||||
enterprise.distributors, each_serializer: Api::EnterpriseThinSerializer
|
||||
enterprise.distributors.not_hidden, each_serializer: Api::EnterpriseThinSerializer
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
37
app/services/order_available_payment_methods.rb
Normal file
37
app/services/order_available_payment_methods.rb
Normal file
@@ -0,0 +1,37 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class OrderAvailablePaymentMethods
|
||||
attr_reader :order, :customer
|
||||
|
||||
delegate :distributor,
|
||||
:order_cycle,
|
||||
to: :order
|
||||
|
||||
def initialize(order, customer = nil)
|
||||
@order, @customer = order, customer
|
||||
end
|
||||
|
||||
def to_a
|
||||
return [] if distributor.blank?
|
||||
|
||||
payment_methods = payment_methods_before_tag_rules_applied
|
||||
|
||||
applicator = OpenFoodNetwork::TagRuleApplicator.new(distributor,
|
||||
"FilterPaymentMethods", customer&.tag_list)
|
||||
applicator.filter!(payment_methods)
|
||||
|
||||
payment_methods.uniq
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def payment_methods_before_tag_rules_applied
|
||||
if order_cycle.nil? || order_cycle.simple?
|
||||
distributor.payment_methods
|
||||
else
|
||||
distributor.payment_methods.where(
|
||||
id: order_cycle.distributor_payment_methods.select(:payment_method_id)
|
||||
)
|
||||
end.available.select(&:configured?)
|
||||
end
|
||||
end
|
||||
45
app/services/order_cycle_clone.rb
Normal file
45
app/services/order_cycle_clone.rb
Normal file
@@ -0,0 +1,45 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'order_management/subscriptions/proxy_order_syncer'
|
||||
|
||||
class OrderCycleClone
|
||||
def initialize(order_cycle)
|
||||
@original_order_cycle = order_cycle
|
||||
end
|
||||
|
||||
def create
|
||||
oc = @original_order_cycle.dup
|
||||
oc.name = I18n.t("models.order_cycle.cloned_order_cycle_name", order_cycle: oc.name)
|
||||
oc.orders_open_at = oc.orders_close_at = oc.mails_sent = oc.processed_at = nil
|
||||
oc.coordinator_fee_ids = @original_order_cycle.coordinator_fee_ids
|
||||
oc.preferred_product_selection_from_coordinator_inventory_only =
|
||||
@original_order_cycle.preferred_product_selection_from_coordinator_inventory_only
|
||||
oc.schedule_ids = @original_order_cycle.schedule_ids
|
||||
oc.save!
|
||||
@original_order_cycle.exchanges.each { |e| e.clone!(oc) }
|
||||
oc.selected_distributor_payment_method_ids = selected_distributor_payment_method_ids
|
||||
oc.selected_distributor_shipping_method_ids = selected_distributor_shipping_method_ids
|
||||
sync_subscriptions
|
||||
oc.reload
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def selected_distributor_payment_method_ids
|
||||
@original_order_cycle.attachable_distributor_payment_methods.map(&:id) &
|
||||
@original_order_cycle.selected_distributor_payment_method_ids
|
||||
end
|
||||
|
||||
def selected_distributor_shipping_method_ids
|
||||
@original_order_cycle.attachable_distributor_shipping_methods.map(&:id) &
|
||||
@original_order_cycle.selected_distributor_shipping_method_ids
|
||||
end
|
||||
|
||||
def sync_subscriptions
|
||||
return unless @original_order_cycle.schedule_ids.any?
|
||||
|
||||
OrderManagement::Subscriptions::ProxyOrderSyncer.new(
|
||||
Subscription.where(schedule_id: @original_order_cycle.schedule_ids)
|
||||
).sync!
|
||||
end
|
||||
end
|
||||
@@ -12,6 +12,9 @@ class OrderCycleForm
|
||||
@user = user
|
||||
@permissions = OpenFoodNetwork::Permissions.new(user)
|
||||
@schedule_ids = order_cycle_params.delete(:schedule_ids)
|
||||
@selected_distributor_payment_method_ids = order_cycle_params.delete(
|
||||
:selected_distributor_payment_method_ids
|
||||
)
|
||||
@selected_distributor_shipping_method_ids = order_cycle_params.delete(
|
||||
:selected_distributor_shipping_method_ids
|
||||
)
|
||||
@@ -27,6 +30,7 @@ class OrderCycleForm
|
||||
order_cycle.schedule_ids = schedule_ids if parameter_specified?(:schedule_ids)
|
||||
order_cycle.save!
|
||||
apply_exchange_changes
|
||||
attach_selected_distributor_payment_methods
|
||||
attach_selected_distributor_shipping_methods
|
||||
sync_subscriptions
|
||||
true
|
||||
@@ -49,16 +53,29 @@ class OrderCycleForm
|
||||
return if exchanges_unchanged?
|
||||
|
||||
OpenFoodNetwork::OrderCycleFormApplicator.new(order_cycle, user).go!
|
||||
|
||||
# reload so outgoing exchanges are up-to-date for shipping/payment method validations
|
||||
order_cycle.reload
|
||||
end
|
||||
|
||||
def attach_selected_distributor_payment_methods
|
||||
return if @selected_distributor_payment_method_ids.nil?
|
||||
|
||||
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?
|
||||
|
||||
order_cycle.reload # so outgoing exchanges are up-to-date for shipping method validations
|
||||
order_cycle.selected_distributor_shipping_method_ids = selected_distributor_shipping_method_ids
|
||||
order_cycle.save!
|
||||
end
|
||||
|
||||
def attachable_distributor_payment_method_ids
|
||||
@attachable_distributor_payment_method_ids ||= order_cycle.attachable_distributor_payment_methods.map(&:id)
|
||||
end
|
||||
|
||||
def attachable_distributor_shipping_method_ids
|
||||
@attachable_distributor_shipping_method_ids ||= order_cycle.attachable_distributor_shipping_methods.map(&:id)
|
||||
end
|
||||
@@ -69,6 +86,19 @@ class OrderCycleForm
|
||||
end
|
||||
end
|
||||
|
||||
def selected_distributor_payment_method_ids
|
||||
@selected_distributor_payment_method_ids = (
|
||||
attachable_distributor_payment_method_ids &
|
||||
@selected_distributor_payment_method_ids.reject(&:blank?).map(&:to_i)
|
||||
)
|
||||
|
||||
if attachable_distributor_payment_method_ids.sort == @selected_distributor_payment_method_ids.sort
|
||||
@selected_distributor_payment_method_ids = []
|
||||
end
|
||||
|
||||
@selected_distributor_payment_method_ids
|
||||
end
|
||||
|
||||
def selected_distributor_shipping_method_ids
|
||||
@selected_distributor_shipping_method_ids = (
|
||||
attachable_distributor_shipping_method_ids &
|
||||
|
||||
@@ -17,7 +17,8 @@ module PermittedAttributes
|
||||
:name, :orders_open_at, :orders_close_at, :coordinator_id,
|
||||
:preferred_product_selection_from_coordinator_inventory_only,
|
||||
:automatic_notifications,
|
||||
{ schedule_ids: [], selected_distributor_shipping_method_ids: [], coordinator_fee_ids: [] }
|
||||
{ schedule_ids: [], selected_distributor_payment_method_ids: [],
|
||||
selected_distributor_shipping_method_ids: [], coordinator_fee_ids: [] }
|
||||
]
|
||||
end
|
||||
|
||||
|
||||
@@ -24,7 +24,9 @@ class PlaceProxyOrder
|
||||
send_placement_email
|
||||
rescue StandardError => e
|
||||
summarizer.record_and_log_error(:processing, order, e.message)
|
||||
Bugsnag.notify(e, order: order)
|
||||
Bugsnag.notify(e) do |payload|
|
||||
payload.add_metadata :order, order
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
@@ -54,7 +56,10 @@ class PlaceProxyOrder
|
||||
|
||||
true
|
||||
rescue StandardError => e
|
||||
Bugsnag.notify(e, subscription: subscription, proxy_order: proxy_order)
|
||||
Bugsnag.notify(e) do |payload|
|
||||
payload.add_metadata :subscription, subscription
|
||||
payload.add_metadata :proxy_order, proxy_order
|
||||
end
|
||||
false
|
||||
end
|
||||
|
||||
|
||||
@@ -47,10 +47,9 @@ module Sets
|
||||
end
|
||||
|
||||
def update_product(product, attributes)
|
||||
original_supplier = product.supplier_id
|
||||
return false unless update_product_only_attributes(product, attributes)
|
||||
|
||||
ExchangeVariantDeleter.new.delete(product) if original_supplier != product.supplier_id
|
||||
ExchangeVariantDeleter.new.delete(product) if product.saved_change_to_supplier_id?
|
||||
|
||||
update_product_variants(product, attributes) &&
|
||||
update_product_master(product, attributes)
|
||||
@@ -110,6 +109,8 @@ module Sets
|
||||
end
|
||||
|
||||
def create_variant(product, variant_attributes)
|
||||
return if variant_attributes.blank?
|
||||
|
||||
on_hand = variant_attributes.delete(:on_hand)
|
||||
on_demand = variant_attributes.delete(:on_demand)
|
||||
|
||||
@@ -131,11 +132,11 @@ module Sets
|
||||
|
||||
def notify_bugsnag(error, product, variant, variant_attributes)
|
||||
Bugsnag.notify(error) do |report|
|
||||
report.add_tab(:product, product.attributes)
|
||||
report.add_tab(:product_error, product.errors.first) unless product.valid?
|
||||
report.add_tab(:variant_attributes, variant_attributes)
|
||||
report.add_tab(:variant, variant.attributes)
|
||||
report.add_tab(:variant_error, variant.errors.first) unless variant.valid?
|
||||
report.add_metadata(:product, product.attributes)
|
||||
report.add_metadata(:product_error, product.errors.first) unless product.valid?
|
||||
report.add_metadata(:variant_attributes, variant_attributes)
|
||||
report.add_metadata(:variant, variant.attributes)
|
||||
report.add_metadata(:variant_error, variant.errors.first) unless variant.valid?
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -8,9 +8,11 @@ module Shop
|
||||
end
|
||||
|
||||
def self.ready_for_checkout_for(distributor, customer)
|
||||
return OrderCycle.none unless distributor.ready_for_checkout?
|
||||
|
||||
new(distributor, customer).call
|
||||
new(distributor, customer).call.select do |order_cycle|
|
||||
order = Spree::Order.new(distributor: distributor, order_cycle: order_cycle)
|
||||
OrderAvailablePaymentMethods.new(order, customer).to_a.any? &&
|
||||
OrderAvailableShippingMethods.new(order, customer).to_a.any?
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(distributor, customer)
|
||||
|
||||
@@ -87,16 +87,16 @@
|
||||
= af.text_field :city, { placeholder: t(:city_placeholder)}
|
||||
.five.columns.omega
|
||||
= af.text_field :zipcode, { placeholder: t(:postcode_placeholder)}
|
||||
%div{"data-controller": "dependant-select", "data-dependant-select-options-value": countries_with_states }
|
||||
%div{"data-controller": "dependent-select", "data-dependent-select-options-value": countries_with_states }
|
||||
.row
|
||||
.three.columns.alpha
|
||||
= af.label :state_id, t(:state)
|
||||
\/
|
||||
= af.label :country_id, t(:country)
|
||||
.four.columns
|
||||
= af.select :country_id, available_countries.map { |c| [c.name, c.id] }, {}, { "data-controller": "tom-select", "data-dependant-select-target": "source", "data-action": "dependant-select#handleSelectChange", class: "primary" }
|
||||
= af.select :country_id, available_countries.map { |c| [c.name, c.id] }, {}, { "data-controller": "tom-select", "data-dependent-select-target": "source", "data-action": "dependent-select#handleSelectChange", class: "primary" }
|
||||
.five.columns.omega
|
||||
= af.select :state_id, @enterprise.address.country.states.map { |s| [s.name, s.id] }, {}, { "data-controller": "tom-select", "data-dependant-select-target": "select", class: "primary" }
|
||||
= af.select :state_id, @enterprise.address.country.states.map { |s| [s.name, s.id] }, {}, { "data-controller": "tom-select", "data-dependent-select-target": "select", class: "primary" }
|
||||
.row
|
||||
.three.columns.alpha
|
||||
= af.label :latitude, t(:latitude)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
.three.columns.alpha
|
||||
= bf.label :address1, t('.address1')
|
||||
%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") }
|
||||
.row
|
||||
.alpha.three.columns
|
||||
@@ -24,16 +25,16 @@
|
||||
= bf.text_field :city, { placeholder: t(:city_placeholder) }
|
||||
.four.columns.omega
|
||||
= bf.text_field :zipcode, { placeholder: t(:postcode_placeholder) }
|
||||
.row
|
||||
.row{"data-controller": "dependent-select", "data-dependent-select-options-value": countries_with_states }
|
||||
.three.columns.alpha
|
||||
= bf.label :country_id, t(:country)
|
||||
\/
|
||||
= bf.label :state_id, t(:state)
|
||||
%div{"data-controller": "dependant-select", "data-dependant-select-options-value": countries_with_states }
|
||||
.four.columns
|
||||
= bf.select :country_id, available_countries.map { |c| [c.name, c.id] }, {}, { "data-controller": "tom-select", "data-dependant-select-target": "source", "data-action": "dependant-select#handleSelectChange", class: "primary" }
|
||||
.four.columns.omega
|
||||
= bf.select :state_id, @enterprise.address.country.states.map { |s| [s.name, s.id] }, {}, { "data-controller": "tom-select", "data-dependant-select-target": "select", class: "primary" }
|
||||
.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
|
||||
- states = @enterprise.business_address.country.present? ? @enterprise.business_address.country&.states&.map { |s| [s.name, s.id] } : []
|
||||
= bf.select :state_id, states, {}, { "data-controller": "tom-select", "data-dependent-select-target": "select", class: "primary" }
|
||||
|
||||
.row
|
||||
.three.columns.alpha
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
%th
|
||||
%tbody
|
||||
- @payment_methods.each do |payment_method|
|
||||
%tr{ ng: { controller: 'paymentMethodsCtrl', init: "findPaymentMethodByID(#{payment_method.id})" } }
|
||||
%tr
|
||||
%td= payment_method.name
|
||||
%td= f.check_box :payment_method_ids, { multiple: true, 'ng-model' => 'PaymentMethod.selected' }, payment_method.id, nil
|
||||
%td= f.check_box :payment_method_ids, { multiple: true }, payment_method.id, nil
|
||||
%td= link_to t(:edit), edit_admin_payment_method_path(payment_method)
|
||||
%br
|
||||
.row
|
||||
|
||||
25
app/views/admin/oidc_settings/index.html.haml
Normal file
25
app/views/admin/oidc_settings/index.html.haml
Normal file
@@ -0,0 +1,25 @@
|
||||
- content_for :page_title do
|
||||
= t(".title")
|
||||
|
||||
= render 'admin/shared/enterprises_sub_menu'
|
||||
|
||||
%div
|
||||
%h2= t(".connect")
|
||||
%br
|
||||
|
||||
- if spree_current_user.provider == 'openid_connect' && spree_current_user.uid.present?
|
||||
= t(".already_connected")
|
||||
= spree_current_user.uid
|
||||
%br
|
||||
%br
|
||||
|
||||
= t(".view_account")
|
||||
= link_to t(".les_communs_link"), "#{ Devise.omniauth_configs[:openid_connect].options[:issuer] }/account"
|
||||
|
||||
- else
|
||||
= t(".link_your_account")
|
||||
%br
|
||||
%br
|
||||
= button_to t(".link_account_button"),
|
||||
Spree::Core::Engine.routes.url_helpers.spree_user_openid_connect_omniauth_authorize_path(auth_type: "login"),
|
||||
method: :post
|
||||
@@ -11,7 +11,7 @@
|
||||
= f.label :orders_open_at, t('.orders_open')
|
||||
.omega.six.columns.fullwidth_inputs
|
||||
- if viewing_as_coordinator_of?(@order_cycle)
|
||||
= f.text_field :orders_open_at, 'datetimepicker' => 'order_cycle.orders_open_at', 'ng-model' => 'order_cycle.orders_open_at', 'ng-if' => 'loaded()', 'change-warning' => 'order_cycle', class: "datetimepicker"
|
||||
= f.text_field :orders_open_at, data: { controller: "flatpickr", "flatpickr-enable-time-value": true }, 'ng-model' => 'order_cycle.orders_open_at', 'ng-if' => 'loaded()', 'change-warning' => 'order_cycle', class: "datetimepicker"
|
||||
- else
|
||||
{{ order_cycle.orders_open_at }}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
= f.label :orders_close, t('.orders_close')
|
||||
.six.columns.omega.fullwidth_inputs
|
||||
- if viewing_as_coordinator_of?(@order_cycle)
|
||||
= f.text_field :orders_close_at, 'datetimepicker' => 'order_cycle.orders_close_at', 'ng-model' => 'order_cycle.orders_close_at', 'ng-if' => 'loaded()', 'change-warning' => 'order_cycle', class: "datetimepicker"
|
||||
= f.text_field :orders_close_at, data: { controller: "flatpickr", "flatpickr-enable-time-value": true }, 'ng-model' => 'order_cycle.orders_close_at', 'ng-if' => 'loaded()', 'change-warning' => 'order_cycle', class: "datetimepicker"
|
||||
- else
|
||||
{{ order_cycle.orders_close_at }}
|
||||
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
{{ schedule.name + ($last ? '' : ',') }}
|
||||
%span{ ng: { show: 'orderCycle.schedules.length == 0'}} None
|
||||
%td.orders_open_at{ ng: { show: 'columns.open.visible' } }
|
||||
%input.datetimepicker{ id: 'oc{{::orderCycle.id}}_orders_open_at', name: 'oc{{::orderCycle.id}}[orders_open_at]', type: 'text', ng: { if: 'orderCycle.viewing_as_coordinator', model: 'orderCycle.orders_open_at' }, datetimepicker: 'orderCycle.orders_open_at', 'change-warning' => 'orderCycle' }
|
||||
%input.datetimepicker{ id: 'oc{{::orderCycle.id}}_orders_open_at', name: 'oc{{::orderCycle.id}}[orders_open_at]', type: 'text', ng: { if: 'orderCycle.viewing_as_coordinator', model: 'orderCycle.orders_open_at' }, data: { controller: "flatpickr", "flatpickr-enable-time-value": true }, 'change-warning' => 'orderCycle' }
|
||||
%input{ id: 'oc{{::orderCycle.id}}_orders_open_at', name: 'oc{{::orderCycle.id}}[orders_open_at]', type: 'text', ng: { if: '!orderCycle.viewing_as_coordinator', model: 'orderCycle.orders_open_at'}, disabled: true }
|
||||
%td.orders_close_at{ ng: { show: 'columns.close.visible' } }
|
||||
%input.datetimepicker{ id: 'oc{{::orderCycle.id}}_orders_close_at', name: 'oc{{::orderCycle.id}}[orders_close_at]', type: 'text', ng: { if: 'orderCycle.viewing_as_coordinator', model: 'orderCycle.orders_close_at' }, datetimepicker: 'orderCycle.orders_close_at', 'change-warning' => 'orderCycle' }
|
||||
%input.datetimepicker{ id: 'oc{{::orderCycle.id}}_orders_close_at', name: 'oc{{::orderCycle.id}}[orders_close_at]', type: 'text', ng: { if: 'orderCycle.viewing_as_coordinator', model: 'orderCycle.orders_close_at' }, data: { controller: "flatpickr", "flatpickr-enable-time-value": true }, 'change-warning' => 'orderCycle' }
|
||||
%input{ id: 'oc{{::orderCycle.id}}_orders_close_at', name: 'oc{{::orderCycle.id}}[orders_close_at]', type: 'text', ng: { if: '!orderCycle.viewing_as_coordinator', model: 'orderCycle.orders_close_at'}, disabled: true }
|
||||
|
||||
- unless simple_index
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
%fieldset.no-border-bottom
|
||||
%legend{ align: 'center'}= t('.checkout_options')
|
||||
|
||||
= hidden_field_tag "order_cycle[selected_distributor_shipping_method_ids][]", ""
|
||||
|
||||
.row
|
||||
.three.columns
|
||||
|
||||
@@ -19,10 +17,12 @@
|
||||
%table.checkout-options
|
||||
%thead
|
||||
%tr
|
||||
%th{ colspan: 2 }= t('.shipping_methods')
|
||||
%th{ colspan: 2 }
|
||||
= t('.shipping_methods')
|
||||
= hidden_field_tag "order_cycle[selected_distributor_shipping_method_ids][]", ""
|
||||
- @order_cycle.distributors.each do |distributor|
|
||||
- distributor_shipping_methods = @order_cycle.attachable_distributor_shipping_methods.where("distributor_id = ?", distributor.id).includes(:shipping_method)
|
||||
%tr{ "data-controller": "select-all" }
|
||||
%tr{ class: "distributor-#{distributor.id}-shipping-methods", "data-controller": "select-all" }
|
||||
%td.text-center
|
||||
- if distributor_shipping_methods.many?
|
||||
%label
|
||||
@@ -48,17 +48,36 @@
|
||||
%p
|
||||
= t('.no_shipping_methods')
|
||||
%tr
|
||||
%th{ colspan: 2 }= t('.payment_methods')
|
||||
%tr
|
||||
%td
|
||||
%td
|
||||
- if @order_cycle.attachable_payment_methods.available(:both).any?
|
||||
%ul
|
||||
- @order_cycle.attachable_payment_methods.available(:both).each do |payment_method|
|
||||
%li= payment_method.name
|
||||
- else
|
||||
%p
|
||||
= t('.no_payment_methods')
|
||||
%th{ colspan: 2 }
|
||||
= t('.payment_methods')
|
||||
= hidden_field_tag "order_cycle[selected_distributor_payment_method_ids][]", ""
|
||||
- @order_cycle.distributors.each do |distributor|
|
||||
- distributor_payment_methods = @order_cycle.attachable_distributor_payment_methods.where("distributor_id = ?", distributor.id).includes(:payment_method)
|
||||
%tr{ class: "distributor-#{distributor.id}-payment-methods", "data-controller": "select-all" }
|
||||
%td.text-center
|
||||
- if distributor_payment_methods.many?
|
||||
%label
|
||||
= check_box_tag nil, nil, nil, { "data-action": "change->select-all#toggleAll", "data-select-all-target": "all" }
|
||||
= t(".select_all")
|
||||
%td
|
||||
%em= distributor.name
|
||||
- distributor_payment_methods.each do |distributor_payment_method|
|
||||
%p
|
||||
%label{ class: ("disabled" if distributor_payment_methods.one? || !distributor_payment_method.payment_method.frontend?) }
|
||||
= check_box_tag "order_cycle[selected_distributor_payment_method_ids][]",
|
||||
distributor_payment_method.id,
|
||||
@order_cycle.distributor_payment_methods.include?(distributor_payment_method),
|
||||
id: "order_cycle_selected_distributor_payment_method_ids_#{distributor_payment_method.id}",
|
||||
data: ({ "action" => "change->select-all#toggleCheckbox", "select-all-target" => "checkbox" } if distributor_payment_method.payment_method.frontend?)
|
||||
= distributor_payment_method.payment_method.name
|
||||
- distributor.payment_methods.inactive_or_backend.each do |payment_method|
|
||||
%label.disabled
|
||||
= check_box_tag nil, nil, false, disabled: true
|
||||
= payment_method.name
|
||||
= "(#{t('.back_end')})"
|
||||
- if distributor.payment_methods.available.none?
|
||||
%p
|
||||
= t('.no_payment_methods')
|
||||
|
||||
%div#save-bar
|
||||
%div.container
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
.row.date-range-filter
|
||||
.alpha.two.columns= label_tag nil, t(:date_range)
|
||||
.omega.fourteen.columns
|
||||
= f.text_field "#{field}_gt", :class => 'datetimepicker datepicker-from', :placeholder => t(:start)
|
||||
= f.text_field "#{field}_gt", :class => 'datetimepicker datepicker-from', :placeholder => t(:start), data: { controller: "flatpickr", "flatpickr-enable-time-value": true }
|
||||
%span.range-divider
|
||||
%i.icon-arrow-right
|
||||
= f.text_field "#{field}_lt", :class => 'datetimepicker datepicker-to', :placeholder => t(:stop)
|
||||
= f.text_field "#{field}_lt", :class => 'datetimepicker datepicker-to', :placeholder => t(:stop), data: { controller: "flatpickr", "flatpickr-enable-time-value": true }
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
- if @report_subtypes.present? && @report_subtypes.count > 1
|
||||
- if feature?(:report_inverse_columns_logic, spree_current_user)
|
||||
%input{type: 'hidden', name: 'report_subtype', value: @report_subtype}
|
||||
- else
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, t(:report_type)
|
||||
.omega.fourteen.columns
|
||||
= select_tag(:report_subtype, options_for_select(@report_subtypes, @report_subtype))
|
||||
%input{type: 'hidden', name: 'report_subtype', value: @report_subtype}
|
||||
|
||||
.row.rendering-options{ "data-controller": "csv-select" }
|
||||
.alpha.two.columns
|
||||
@@ -31,13 +25,7 @@
|
||||
|
||||
- if @report.available_headers.present?
|
||||
.row
|
||||
- if feature? :report_inverse_columns_logic, spree_current_user
|
||||
.alpha.two.columns= label_tag nil, t(:report_columns)
|
||||
.omega.fourteen.columns
|
||||
= select_tag(:fields_to_show, options_for_select(@report.available_headers, @params_fields_to_show),
|
||||
class: "select2 fullwidth", multiple: true)
|
||||
- else
|
||||
.alpha.two.columns= label_tag nil, t(:report_hide_columns)
|
||||
.omega.fourteen.columns
|
||||
= select_tag(:fields_to_hide, options_for_select(@report.available_headers, params[:fields_to_hide]),
|
||||
class: "select2 fullwidth", multiple: true)
|
||||
.alpha.two.columns= label_tag nil, t(:report_columns)
|
||||
.omega.fourteen.columns
|
||||
= render MultipleCheckedSelectComponent.new(name: "fields_to_show", options: @report.available_headers, selected: @params_fields_to_show)
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
.fourteen.columns.omega= number_field_tag :initial_invoice_number, params[:initial_invoice_number]
|
||||
.row
|
||||
.two.columns.alpha= label_tag :invoice_date, t(:invoice_date)
|
||||
.fourteen.columns.omega= text_field_tag :invoice_date, params[:invoice_date], class: 'datetimepicker'
|
||||
.fourteen.columns.omega= text_field_tag :invoice_date, params[:invoice_date], class: 'datetimepicker', data: { controller: "flatpickr", "flatpickr-enable-time-value": true }
|
||||
.row
|
||||
.two.columns.alpha= label_tag :due_date, t(:due_date)
|
||||
.fourteen.columns.omega= text_field_tag :due_date, params[:due_date], class: 'datetimepicker'
|
||||
.fourteen.columns.omega= text_field_tag :due_date, params[:due_date], class: 'datetimepicker', data: { controller: "flatpickr", "flatpickr-enable-time-value": true }
|
||||
.row
|
||||
.two.columns.alpha= label_tag :account_code, t(:account_code)
|
||||
.fourteen.columns.omega= text_field_tag :account_code, params[:account_code]
|
||||
|
||||
@@ -11,13 +11,9 @@
|
||||
- @reports.each do |report_type, report_subtypes|
|
||||
%tr
|
||||
%td
|
||||
- name = I18n.t(:name, scope: [:admin, :reports, report_type])
|
||||
- url = main_app.admin_report_url(report_type: report_type)
|
||||
= link_to name, url
|
||||
= I18n.t(:name, scope: [:admin, :reports, report_type])
|
||||
%td
|
||||
- begin
|
||||
= I18n.t!(:description, scope: [:admin, :reports, report_type])
|
||||
- if feature? :report_inverse_columns_logic, spree_current_user
|
||||
= render partial: "report_subtype", locals: { report_subtypes: report_subtypes, report_type: report_type }
|
||||
- rescue I18n::MissingTranslationData
|
||||
= render partial: "report_subtype", locals: { report_subtypes: report_subtypes, report_type: report_type }
|
||||
- if report_subtypes.empty?
|
||||
- name = I18n.t(:name, scope: [:admin, :reports, report_type])
|
||||
- report_subtypes = [[name, nil]]
|
||||
= render partial: "report_subtype", locals: { report_subtypes: report_subtypes, report_type: report_type }
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
- content_for :page_title do
|
||||
= @report_title
|
||||
|
||||
= form_for @report.search, :url => url_for(only_path: false) do |f|
|
||||
%fieldset.no-border-bottom.print-hidden
|
||||
%legend{ align: 'center'}= t(:report_filters)
|
||||
|
||||
@@ -2,3 +2,5 @@
|
||||
%ul#sub_nav.inline-menu{"data-hook" => "admin_enterprise_sub_tabs"}
|
||||
= tab :enterprises, url: main_app.admin_enterprises_path
|
||||
= tab :enterprise_relationships, url: main_app.admin_enterprise_relationships_path
|
||||
- if ENV["OPENID_APP_ID"].present? && ENV["OPENID_APP_SECRET"].present?
|
||||
= tab :oidc_settings, url: main_app.admin_oidc_settings_path
|
||||
|
||||
@@ -34,11 +34,11 @@
|
||||
.row
|
||||
.seven.columns.alpha.field
|
||||
%label{ for: 'begins_at'}= t('admin.begins_at')
|
||||
%input.fullwidth#begins_at{ name: 'begins_at', type: 'text', placeholder: "#{t('.begins_at_placeholder')}", datepicker: 'subscription.begins_at', required: true, ng: { model: 'subscription.begins_at' } }
|
||||
%input.fullwidth#begins_at{ name: 'begins_at', type: 'text', placeholder: "#{t('.begins_at_placeholder')}", data: { controller: "flatpickr" }, required: true, ng: { model: 'subscription.begins_at' } }
|
||||
.error{ ng: { show: 'subscription_form.$submitted && subscription_details_form.begins_at.$error.required' } }= t(:error_required)
|
||||
.error{ ng: { repeat: 'error in errors.begins_at', show: 'subscription_details_form.begins_at.$pristine' } } {{ error }}
|
||||
.two.columns
|
||||
.seven.columns.omega.field
|
||||
%label{ for: 'ends_at'}= t('admin.ends_at')
|
||||
%input.fullwidth#ends_at{ name: 'ends_at', type: 'text', placeholder: "#{t('.ends_at_placeholder')}", datepicker: 'subscription.begins_at', ng: { model: 'subscription.ends_at' } }
|
||||
%input.fullwidth#ends_at{ name: 'ends_at', type: 'text', placeholder: "#{t('.ends_at_placeholder')}", data: { controller: "flatpickr" }, ng: { model: 'subscription.ends_at' } }
|
||||
.error{ ng: { repeat: 'error in errors.ends_at', show: 'subscription_details_form.ends_at.$pristine' } } {{ error }}
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
|
||||
= form_with url: "/admin/subscriptions/new", method: :get do |f|
|
||||
.text-left.margin-bottom-30
|
||||
= select_tag "subscription[shop_id]", options_from_collection_for_select(@shops, "id", "name"), { "data-controller": "tom-select", "data-dependant-select-target": "source", "data-action": "dependant-select#handleSelectChange", class: "primary" }
|
||||
= select_tag "subscription[shop_id]", options_from_collection_for_select(@shops, "id", "name"), { "data-controller": "tom-select", "data-dependent-select-target": "source", "data-action": "dependent-select#handleSelectChange", class: "primary" }
|
||||
.text-center
|
||||
= f.submit "Continue", class: "button red icon-plus"
|
||||
= f.submit "Continue", class: "button red icon-plus"
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
%p
|
||||
%input{ type: "checkbox", id: "accept_terms", ng: { model: "platform_tos_accepted", init: "platform_tos_accepted = #{platform_tos_already_accepted?}" } }
|
||||
%label.small{for: "platform_tos_accepted"}
|
||||
%input{ type: "checkbox",
|
||||
id: "accept_terms",
|
||||
ng: {
|
||||
model: "platform_tos_accepted",
|
||||
init: "platform_tos_accepted = #{platform_tos_already_accepted?}"
|
||||
}
|
||||
}
|
||||
%label.small{for: "accept_terms"}
|
||||
= t(".message_html", tos_link: link_to_platform_terms)
|
||||
|
||||
19
app/views/devise/shared/_links.html.erb
Normal file
19
app/views/devise/shared/_links.html.erb
Normal file
@@ -0,0 +1,19 @@
|
||||
<%- if controller_name != 'sessions' %>
|
||||
<%= link_to t(".sign_in"), new_session_path(resource_name) %><br />
|
||||
<% end %>
|
||||
|
||||
<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
|
||||
<%= link_to t(".sign_up"), new_registration_path(resource_name) %><br />
|
||||
<% end %>
|
||||
|
||||
<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
|
||||
<%= link_to t(".forgot_your_password"), new_password_path(resource_name) %><br />
|
||||
<% end %>
|
||||
|
||||
<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
|
||||
<%= link_to t('.didn_t_receive_confirmation_instructions'), new_confirmation_path(resource_name) %><br />
|
||||
<% end %>
|
||||
|
||||
<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
|
||||
<%= link_to t('.didn_t_receive_unlock_instructions'), new_unlock_path(resource_name) %><br />
|
||||
<% end %>
|
||||
@@ -50,16 +50,16 @@
|
||||
= bill_address.text_field :zipcode, { placeholder: t("split_checkout.step1.address.zipcode.placeholder") }
|
||||
= f.error_message_on "bill_address.zipcode"
|
||||
|
||||
%div{ "data-controller": "dependant-select", "data-dependant-select-options-value": countries_with_states }
|
||||
%div{ "data-controller": "dependent-select", "data-dependent-select-options-value": countries_with_states }
|
||||
- bill_address_country = @order.bill_address.country || DefaultCountry.country
|
||||
|
||||
%div.checkout-input
|
||||
= bill_address.label :country_id, t("split_checkout.step1.address.country_id.label")
|
||||
= bill_address.select :country_id, countries, { selected: bill_address_country.id }, { "data-dependant-select-target": "source", "data-action": "dependant-select#handleSelectChange" }
|
||||
= bill_address.select :country_id, countries, { selected: bill_address_country.id }, { "data-dependent-select-target": "source", "data-action": "dependent-select#handleSelectChange" }
|
||||
|
||||
%div.checkout-input
|
||||
= bill_address.label :state_id, t("split_checkout.step1.address.state_id.label")
|
||||
= bill_address.select :state_id, states_for_country(bill_address_country), { selected: @order.bill_address&.state_id }, { "data-dependant-select-target": "select" }
|
||||
= bill_address.select :state_id, states_for_country(bill_address_country), { selected: @order.bill_address&.state_id }, { "data-dependent-select-target": "select" }
|
||||
|
||||
- if spree_current_user
|
||||
%div.checkout-input
|
||||
@@ -130,16 +130,16 @@
|
||||
= ship_address.text_field :zipcode, { placeholder: t("split_checkout.step1.address.zipcode.placeholder") }
|
||||
= f.error_message_on "ship_address.zipcode"
|
||||
|
||||
%div{ "data-controller": "dependant-select", "data-dependant-select-options-value": countries_with_states }
|
||||
%div{ "data-controller": "dependent-select", "data-dependent-select-options-value": countries_with_states }
|
||||
- ship_address_country = @order.ship_address.country || DefaultCountry.country
|
||||
|
||||
%div.checkout-input
|
||||
= ship_address.label :country_id, t("split_checkout.step1.address.country_id.label")
|
||||
= ship_address.select :country_id, countries, { selected: ship_address_country.id }, { "data-dependant-select-target": "source", "data-action": "dependant-select#handleSelectChange" }
|
||||
= ship_address.select :country_id, countries, { selected: ship_address_country.id }, { "data-dependent-select-target": "source", "data-action": "dependent-select#handleSelectChange" }
|
||||
|
||||
%div.checkout-input
|
||||
= ship_address.label :state_id, t("split_checkout.step1.address.state_id.label")
|
||||
= ship_address.select :state_id, states_for_country(ship_address_country), { selected: @order.ship_address&.state_id }, { "data-dependant-select-target": "select" }
|
||||
= ship_address.select :state_id, states_for_country(ship_address_country), { selected: @order.ship_address&.state_id }, { "data-dependent-select-target": "select" }
|
||||
|
||||
- if spree_current_user
|
||||
%div.checkout-input{ "data-toggle-target": "content", style: "display: #{display_ship_address ? 'block' : 'none'}" }
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
= form_for [:admin, @product, @image], url: admin_product_image_path(@product, @image, @url_filters), html: { multipart: true } do |f|
|
||||
%fieldset
|
||||
%legend{align: "center"}= @image.attachment_file_name
|
||||
%legend{align: "center"}= @image.attachment.filename
|
||||
.field.alpha.three.columns.align-center
|
||||
= f.label t('spree.thumbnail')
|
||||
%br/
|
||||
|
||||
@@ -3,11 +3,10 @@
|
||||
.field-block.alpha.four.columns
|
||||
.date-range-filter.field
|
||||
= label_tag nil, t(:date_range)
|
||||
.date-range-fields
|
||||
= text_field_tag "q[completed_at_gteq]", nil, class: 'datepicker', datepicker: 'q.completed_at_gteq', 'ng-model' => 'q.completed_at_gteq', :placeholder => t(:start)
|
||||
%span.range-divider
|
||||
%i.icon-arrow-right
|
||||
= text_field_tag "q[completed_at_lteq]", nil, class: 'datepicker', datepicker: 'q.completed_at_lteq', 'ng-model' => 'q.completed_at_lteq', :placeholder => t(:stop)
|
||||
.date-range-fields{ data: { controller: "flatpickr", "flatpickr-mode-value": "range", "flatpickr-default-date": "{{ [q.completed_at_gteq, q.completed_at_lteq] }}" } }
|
||||
= text_field_tag nil, nil, class: "datepicker", data: { "flatpickr-target": "instance", action: "flatpickr_clear@window->flatpickr#clear" }
|
||||
= text_field_tag "q[completed_at_gteq]", nil, "ng-model": "q.completed_at_gteq", data: { "flatpickr-target": "start" }, style: "display: none"
|
||||
= text_field_tag "q[completed_at_lteq]", nil, "ng-model": "q.completed_at_lteq", data: { "flatpickr-target": "end" }, style: "display: none"
|
||||
.field
|
||||
= label_tag nil, t(:status)
|
||||
%select2-watch-ng-model{'ng-model': 'q.state_eq'}
|
||||
|
||||
@@ -17,16 +17,14 @@
|
||||
%input.red{ type: "button", value: "Save Changes", ng: { click: "submit()", disabled: "!bulk_order_form.$dirty" } }
|
||||
|
||||
.filters{ :class => "sixteen columns alpha" }
|
||||
.date_filter{ :class => "two columns alpha" }
|
||||
%label{ :for => 'start_date_filter' }
|
||||
= t("admin.start_date")
|
||||
.date_filter{class: "four columns"}
|
||||
%label
|
||||
= t("date_range")
|
||||
%br
|
||||
%input.fullwidth.datepicker{ :type => "text", :id => 'start_date_filter', 'ng-model' => 'startDate', 'datepicker' => "startDate", 'confirm-change' => "confirmRefresh()", 'ng-change' => 'refreshData()', 'ng-model-options' => '{ debounce: 1000 }' }
|
||||
.date_filter{ :class => "two columns" }
|
||||
%label{ :for => 'end_date_filter' }
|
||||
= t("admin.end_date")
|
||||
%br
|
||||
%input.fullwidth.datepicker{ :type => "text", :id => 'end_date_filter', 'ng-model' => 'endDate', 'datepicker' => "endDate", 'confirm-change' => "confirmRefresh()", 'ng-change' => 'refreshData()', 'ng-model-options' => '{ debounce: 1000 }' }
|
||||
%div{ data: { controller: "flatpickr", "flatpickr-mode-value": "range", "flatpickr-default-date": "{{ [startDate, endDate] }}" } }
|
||||
%input.datepicker.fullwidth{ class: "datepicker", data: { "flatpickr-target": "instance" } }
|
||||
%input{ type: "text", id: 'start_date_filter', 'ng-model': "startDate", data: { "flatpickr-target": "start" }, style: "display: none;", "confirm-change": "confirmRefresh()" }
|
||||
%input{ type: "text", id: 'end_date_filter', 'ng-model': "endDate", data: { "flatpickr-target": "end" }, style: "display: none;", "confirm-change": "confirmRefresh()"}
|
||||
.one.column
|
||||
.filter_select{ :class => "three columns" }
|
||||
%label{ :for => 'supplier_filter' }
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
= t(".active_products", count: @product_count )
|
||||
%span.three.columns.omega
|
||||
%span.icon-remove-sign
|
||||
%a.eight.columns.alpha.button.bottom.red{ href: "#{new_admin_product_path}" }
|
||||
%a.sixteen.columns.alpha.button.bottom.red{ href: "#{new_admin_product_path}" }
|
||||
= t "spree_admin_enterprises_create_new_product"
|
||||
%span.icon-arrow-right
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
= f.field_container :primary_taxon_id do
|
||||
= f.field_container :primary_taxon do
|
||||
= f.label :primary_taxon_id, t('.product_category')
|
||||
%span.required *
|
||||
%br
|
||||
= f.collection_select(:primary_taxon_id, Spree::Taxon.order(:name), :id, :name, {:include_blank => true}, {:class => "select2 fullwidth"})
|
||||
= f.error_message_on :primary_taxon_id
|
||||
= f.error_message_on :primary_taxon
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
= f.field_container :tax_category_id do
|
||||
= f.label :tax_category_id, t(:tax_category)
|
||||
%span.required *
|
||||
%br
|
||||
= f.collection_select(:tax_category_id, Spree::TaxCategory.all, :id, :name, {:include_blank => Spree::Config.products_require_tax_category ? false : t(:none)}, {:class => "select2 fullwidth"})
|
||||
= f.error_message_on :tax_category_id
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
.eight.columns.alpha
|
||||
= f.field_container :supplier do
|
||||
= f.label :supplier_id, t(".supplier")
|
||||
%span.required *
|
||||
= f.select :supplier_id, options_from_collection_for_select(@producers, :id, :name, @product.supplier_id), {}, { "data-controller": "tom-select", class: "primary" }
|
||||
= f.error_message_on :supplier
|
||||
.eight.columns.omega
|
||||
@@ -22,13 +21,14 @@
|
||||
= f.error_message_on :name
|
||||
.sixteen.columns.alpha
|
||||
.eight.columns.alpha
|
||||
= f.field_container :units do
|
||||
= f.field_container :variant_unit do
|
||||
= f.label :variant_unit_with_scale, t(".units")
|
||||
%span.required *
|
||||
%select{id: 'product_variant_unit_with_scale', 'ng-model' => 'product.variant_unit_with_scale', 'ng-options' => 'unit[1] as unit[0] for unit in variant_unit_options',"data-controller": "tom-select", class: "primary"}
|
||||
%select{id: 'product_variant_unit_with_scale', 'ng-model' => 'product.variant_unit_with_scale', 'ng-options' => 'unit[1] as unit[0] for unit in variant_unit_options', "data-controller": "tom-select","data-tom-select-options-value": '{"allowEmptyOption":false}', class: "primary"}
|
||||
%option{'value' => '', 'ng-hide' => "hasUnit(product)"}
|
||||
%input{ type: 'hidden', 'ng-value': 'product.variant_unit', "ng-init": "product.variant_unit='#{@product.variant_unit}'", name: 'product[variant_unit]' }
|
||||
%input{ type: 'hidden', 'ng-value': 'product.variant_unit_scale', "ng-init": "product.variant_unit_scale='#{@product.variant_unit_scale}'", name: 'product[variant_unit_scale]' }
|
||||
= f.error_message_on :variant_unit
|
||||
.two.columns
|
||||
= f.field_container :unit_value do
|
||||
= f.label :unit_value_with_description, t(".value"), 'ng-disabled' => "!hasUnit(product)"
|
||||
@@ -36,6 +36,7 @@
|
||||
%input.fullwidth{ id: 'product_unit_value_with_description', 'ng-model' => 'product.master.unit_value_with_description', :type => 'text', placeholder: "eg. 2", 'ng-disabled' => "!hasUnit(product)" }
|
||||
%input{ type: 'hidden', 'ng-value': 'product.master.unit_value', "ng-init": "product.master.unit_value='#{@product.master.unit_value}'", name: 'product[unit_value]' }
|
||||
%input{ type: 'hidden', 'ng-value': 'product.master.unit_description', "ng-init": "product.master.unit_description='#{@product.master.unit_description}'", name: 'product[unit_description]' }
|
||||
= f.error_message_on :unit_value
|
||||
= render 'display_as', f: f
|
||||
.six.columns.omega{ 'ng-show' => "product.variant_unit_with_scale == 'items'" }
|
||||
= f.field_container :unit_name do
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
= tab :orders, :subscriptions, :customer_details, :adjustments, :payments, :return_authorizations, url: admin_orders_path('q[s]' => 'completed_at desc'), icon: 'icon-shopping-cart'
|
||||
= tab :reports, url: main_app.admin_reports_path, icon: 'icon-file'
|
||||
= tab :general_settings, :mail_methods, :tax_categories, :tax_rates, :tax_settings, :zones, :countries, :states, :payment_methods, :taxonomies, :shipping_methods, :shipping_categories, :enterprise_fees, :contents, :invoice_settings, :matomo_settings, :stripe_connect_settings, label: 'configuration', icon: 'icon-wrench', url: edit_admin_general_settings_path
|
||||
= tab :enterprises, :enterprise_relationships, url: main_app.admin_enterprises_path
|
||||
= tab :enterprises, :enterprise_relationships, :oidc_settings, url: main_app.admin_enterprises_path
|
||||
= tab :customers, url: main_app.admin_customers_path
|
||||
= tab :enterprise_groups, url: main_app.admin_enterprise_groups_path, label: 'groups'
|
||||
- if can? :admin, Spree::User
|
||||
|
||||
@@ -30,15 +30,8 @@
|
||||
%td.text-right
|
||||
%span.order-total.item-total= display_checkout_subtotal(@order)
|
||||
%td
|
||||
-if display_line_item_fees_total_for(@order) != Spree::Money.new(0 , currency: @order.currency)
|
||||
%tr
|
||||
%td.text-right{colspan:"3"}
|
||||
= t :orders_form_admin
|
||||
%td.text-right
|
||||
%span.order-total.distribution-total= display_line_item_fees_total_for(@order)
|
||||
%td
|
||||
|
||||
- checkout_adjustments_for(@order, exclude: [:line_item, :admin_and_handling]).reject{ |a| a.amount == 0 }.reverse_each do |adjustment|
|
||||
- checkout_adjustments_for(@order, exclude: [:line_item]).reject{ |a| a.amount == 0 }.reverse_each do |adjustment|
|
||||
%tr.order-adjustment
|
||||
%td.text-right{:colspan => "3"}
|
||||
= adjustment.label
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
%h3
|
||||
= t('.dear_customer')
|
||||
%p.lead
|
||||
= t('.instructions', distributor: @shipment.order.distributor.name)
|
||||
|
||||
- if @delivery
|
||||
%p.lead
|
||||
= t('.instructions', distributor: @shipment.order.distributor.name)
|
||||
- else
|
||||
%p.lead
|
||||
= t('.picked_up_instructions', distributor: @shipment.order.distributor.name)
|
||||
|
||||
%p
|
||||
%strong
|
||||
|
||||
121
app/webpacker/controllers/flatpickr_controller.js
Normal file
121
app/webpacker/controllers/flatpickr_controller.js
Normal file
@@ -0,0 +1,121 @@
|
||||
// import Flatpickr
|
||||
import Flatpickr from "stimulus-flatpickr";
|
||||
import { ar } from "flatpickr/dist/l10n/ar";
|
||||
import { cat } from "flatpickr/dist/l10n/cat";
|
||||
import { cy } from "flatpickr/dist/l10n/cy";
|
||||
import { de } from "flatpickr/dist/l10n/de";
|
||||
import { fr } from "flatpickr/dist/l10n/fr";
|
||||
import { it } from "flatpickr/dist/l10n/it";
|
||||
import { nl } from "flatpickr/dist/l10n/nl";
|
||||
import { pl } from "flatpickr/dist/l10n/pl";
|
||||
import { pt } from "flatpickr/dist/l10n/pt";
|
||||
import { ru } from "flatpickr/dist/l10n/ru";
|
||||
import { sv } from "flatpickr/dist/l10n/sv";
|
||||
import { tr } from "flatpickr/dist/l10n/tr";
|
||||
import { en } from "flatpickr/dist/l10n/default.js";
|
||||
import ShortcutButtonsPlugin from "shortcut-buttons-flatpickr";
|
||||
import labelPlugin from "flatpickr/dist/plugins/labelPlugin/labelPlugin";
|
||||
|
||||
export default class extends Flatpickr {
|
||||
static values = { enableTime: Boolean, mode: String };
|
||||
static targets = ["start", "end"];
|
||||
locales = {
|
||||
ar: ar,
|
||||
cat: cat,
|
||||
cy: cy,
|
||||
de: de,
|
||||
fr: fr,
|
||||
it: it,
|
||||
nl: nl,
|
||||
pl: pl,
|
||||
pt: pt,
|
||||
ru: ru,
|
||||
sv: sv,
|
||||
tr: tr,
|
||||
en: en,
|
||||
};
|
||||
|
||||
initialize() {
|
||||
const datetimepicker = this.enableTimeValue == true;
|
||||
const mode = this.modeValue == "range" ? "range" : "single";
|
||||
// sets your language (you can also set some global setting for all time pickers)
|
||||
this.config = {
|
||||
altInput: true,
|
||||
altFormat: datetimepicker
|
||||
? Spree.translations.flatpickr_datetime_format
|
||||
: Spree.translations.flatpickr_date_format,
|
||||
dateFormat: datetimepicker ? "Y-m-d H:i" : "Y-m-d",
|
||||
enableTime: datetimepicker,
|
||||
time_24hr: datetimepicker,
|
||||
locale: I18n.base_locale,
|
||||
plugins: this.plugins(mode, datetimepicker),
|
||||
mode,
|
||||
};
|
||||
}
|
||||
|
||||
clear(e) {
|
||||
this.fp.setDate(null);
|
||||
}
|
||||
|
||||
open() {
|
||||
this.fp.element.dispatchEvent(new Event("focus"));
|
||||
}
|
||||
|
||||
change(selectedDates, dateStr, instance) {
|
||||
if (this.hasStartTarget && this.hasEndTarget && this.modeValue == "range") {
|
||||
this.startTarget.value = selectedDates[0]
|
||||
? this.fp.formatDate(selectedDates[0], this.config.dateFormat)
|
||||
: "";
|
||||
this.endTarget.value = selectedDates[1]
|
||||
? this.fp.formatDate(selectedDates[1], this.config.dateFormat)
|
||||
: "";
|
||||
// Also, send event to be sure that ng-model is well updated
|
||||
// Send event only if range il valid, ie. start and end are not empty
|
||||
if (this.startTarget.value && this.endTarget.value) {
|
||||
this.startTarget.dispatchEvent(new Event("change"));
|
||||
this.endTarget.dispatchEvent(new Event("change"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
close() {
|
||||
// Send a change event to the input element to trigger the ng-change
|
||||
this.hasEndTarget && this.endTarget.dispatchEvent(new Event("change"));
|
||||
}
|
||||
|
||||
// private
|
||||
|
||||
plugins = (mode, datetimepicker) => {
|
||||
const buttons = [{ label: Spree.translations.close }];
|
||||
if (mode == "single") {
|
||||
buttons.unshift({
|
||||
label: datetimepicker
|
||||
? Spree.translations.now
|
||||
: Spree.translations.today,
|
||||
});
|
||||
}
|
||||
return [
|
||||
ShortcutButtonsPlugin({
|
||||
button: buttons,
|
||||
onClick: this.onClickButtons,
|
||||
}),
|
||||
labelPlugin({}),
|
||||
];
|
||||
};
|
||||
|
||||
onClickButtons = (index, fp) => {
|
||||
// Memorize index used for the 'Close' and 'Today|Now' buttons
|
||||
// it has index of 1 in case of single mode (ie. can set Today or Now date)
|
||||
// it has index of 0 in case of range mode (no Today or Now button)
|
||||
const closeButtonIndex = this.modeValue == "range" ? 0 : 1;
|
||||
const todayButtonIndex = this.modeValue == "range" ? null : 0;
|
||||
switch (index) {
|
||||
case todayButtonIndex:
|
||||
fp.setDate(new Date(), true);
|
||||
break;
|
||||
case closeButtonIndex:
|
||||
fp.close();
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import { Controller } from "stimulus";
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = ["button", "caret", "options", "option", "filter"];
|
||||
|
||||
connect() {
|
||||
this.buttonTarget.addEventListener("click", this.toggleOptions);
|
||||
document.addEventListener("click", this.closeOptions);
|
||||
this.filterTarget.addEventListener("input", this.filterOptions);
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
document.removeEventListener("click", this.closeOptions);
|
||||
}
|
||||
|
||||
// private methods
|
||||
|
||||
filterOptions = (e) => {
|
||||
const filter = e.target.value.toLowerCase();
|
||||
this.optionTargets.forEach((option) => {
|
||||
if (option.dataset["label"].toLowerCase().includes(filter)) {
|
||||
option.classList.remove("hidden");
|
||||
} else {
|
||||
option.classList.add("hidden");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
toggleOptions = () => {
|
||||
this.optionsTarget.classList.toggle("hidden");
|
||||
this.caretTarget.classList.toggle("icon-caret-down");
|
||||
this.caretTarget.classList.toggle("icon-caret-up");
|
||||
};
|
||||
|
||||
closeOptions = (e) => {
|
||||
if (!this.element.contains(e.target)) {
|
||||
this.optionsTarget.classList.add("hidden");
|
||||
this.caretTarget.classList.remove("icon-caret-up");
|
||||
this.caretTarget.classList.add("icon-caret-down");
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Controller } from "stimulus";
|
||||
import TomSelect from "tom-select";
|
||||
import TomSelect from "tom-select/dist/esm/tom-select.complete";
|
||||
|
||||
export default class extends Controller {
|
||||
static values = { options: Object };
|
||||
|
||||
@@ -1,15 +1,5 @@
|
||||
// scss-lint:disable QualifyingElement
|
||||
|
||||
.date-range-filter {
|
||||
.range-divider {
|
||||
padding: 0;
|
||||
margin-left: 5px;
|
||||
}
|
||||
input.datepicker {
|
||||
width: 96px !important;
|
||||
}
|
||||
}
|
||||
|
||||
input.datetimepicker {
|
||||
min-width: 12.9em;
|
||||
}
|
||||
|
||||
@@ -8,3 +8,34 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
input[type='checkbox'].redesigned-input {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
-moz-appearance:none;
|
||||
-webkit-appearance:none;
|
||||
-o-appearance:none;
|
||||
appearance: none;
|
||||
outline: none;
|
||||
content: none;
|
||||
cursor: pointer;
|
||||
|
||||
&:before {
|
||||
font-family: "FontAwesome";
|
||||
content: "\f00c";
|
||||
font-size: 15px;
|
||||
color: transparent !important;
|
||||
background: transparent !important;
|
||||
display: block;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
border: 1px solid #809cb1;
|
||||
margin-right: 7px;
|
||||
}
|
||||
|
||||
&:checked:before {
|
||||
color: #5498DA !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user