Compare commits

..

1 Commits

Author SHA1 Message Date
Maikel Linke
fddb76f002 Merge branch 'active-storage' into HEAD
Creating a seperate release off the master branch.
2022-06-08 12:05:56 +10:00
210 changed files with 3066 additions and 21691 deletions

13
.github/FUNDING.yml vendored
View File

@@ -1,13 +0,0 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: ofnusa
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

View File

@@ -10,6 +10,7 @@ assignees: ''
## Preparation on Thursday
- [ ] Merge pull requests in the [Ready To Go] column
- [ ] Merge [Transifex pull request]
- [ ] Include translations: `tx pull --force`
- [ ] [Draft new release]. Look at previous [releases] for inspiration.
- [ ] Notify [#instance-managers] of user-facing changes.

View File

@@ -10,14 +10,8 @@ on:
pull_request:
branches: [ "master" ]
permissions:
contents: read
jobs:
brakeman-scan:
permissions:
contents: read # for actions/checkout to fetch code
security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
name: Brakeman Scan
runs-on: ubuntu-latest
steps:

View File

@@ -12,9 +12,6 @@ env:
RSPEC_RETRY_RETRY_COUNT: 3
RAILS_ENV: test
permissions:
contents: read
jobs:
rspec:
runs-on: ubuntu-18.04

View File

@@ -1,5 +1,5 @@
name: 'Mayhem for API'
on: workflow_dispatch
on: [push]
jobs:
test:
if: ${{ github.repository_owner == 'openfoodfoundation' }}

View File

@@ -29,7 +29,6 @@ gem 'rails_safe_tasks', '~> 1.0'
gem "activerecord-import"
gem "db2fog", github: "openfoodfoundation/db2fog", branch: "rails-6"
gem "fog-aws", "~> 2.0" # db2fog does not support v3
gem "mime-types" # required by fog
gem "valid_email2"
@@ -70,6 +69,7 @@ gem 'rswag-api'
gem 'rswag-ui'
gem 'angularjs-rails', '1.8.0'
gem 'aws-sdk', '1.67.0'
gem 'bugsnag'
gem 'haml'
gem 'redcarpet'
@@ -104,7 +104,7 @@ gem 'wicked_pdf'
gem 'wkhtmltopdf-binary'
gem 'immigrant'
gem 'roo'
gem 'roo', github: "roo-rb/roo" # master is currently needed for Ruby 3.x (awaiting new release)
gem 'spreadsheet_architect'
gem 'whenever', require: false

View File

@@ -24,6 +24,14 @@ GIT
sass-rails
thor (>= 0.14)
GIT
remote: https://github.com/roo-rb/roo.git
revision: 709464c77623be2bc09b2103405d90ded7604a75
specs:
roo (2.8.3)
nokogiri (~> 1)
rubyzip (>= 1.3.0, < 3.0.0)
PATH
remote: engines/catalog
specs:
@@ -51,67 +59,67 @@ GEM
remote: https://rubygems.org/
specs:
Ascii85 (1.1.0)
actioncable (6.1.6.1)
actionpack (= 6.1.6.1)
activesupport (= 6.1.6.1)
actioncable (6.1.4.4)
actionpack (= 6.1.4.4)
activesupport (= 6.1.4.4)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
actionmailbox (6.1.6.1)
actionpack (= 6.1.6.1)
activejob (= 6.1.6.1)
activerecord (= 6.1.6.1)
activestorage (= 6.1.6.1)
activesupport (= 6.1.6.1)
actionmailbox (6.1.4.4)
actionpack (= 6.1.4.4)
activejob (= 6.1.4.4)
activerecord (= 6.1.4.4)
activestorage (= 6.1.4.4)
activesupport (= 6.1.4.4)
mail (>= 2.7.1)
actionmailer (6.1.6.1)
actionpack (= 6.1.6.1)
actionview (= 6.1.6.1)
activejob (= 6.1.6.1)
activesupport (= 6.1.6.1)
actionmailer (6.1.4.4)
actionpack (= 6.1.4.4)
actionview (= 6.1.4.4)
activejob (= 6.1.4.4)
activesupport (= 6.1.4.4)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0)
actionpack (6.1.6.1)
actionview (= 6.1.6.1)
activesupport (= 6.1.6.1)
actionpack (6.1.4.4)
actionview (= 6.1.4.4)
activesupport (= 6.1.4.4)
rack (~> 2.0, >= 2.0.9)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.2.0)
actionpack-action_caching (1.2.2)
actionpack (>= 4.0.0)
actiontext (6.1.6.1)
actionpack (= 6.1.6.1)
activerecord (= 6.1.6.1)
activestorage (= 6.1.6.1)
activesupport (= 6.1.6.1)
actiontext (6.1.4.4)
actionpack (= 6.1.4.4)
activerecord (= 6.1.4.4)
activestorage (= 6.1.4.4)
activesupport (= 6.1.4.4)
nokogiri (>= 1.8.5)
actionview (6.1.6.1)
activesupport (= 6.1.6.1)
actionview (6.1.4.4)
activesupport (= 6.1.4.4)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
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 (0.9.7)
activejob (>= 5.2.0)
activemodel (>= 5.2.0)
activestorage (>= 5.2.0)
activesupport (>= 5.2.0)
activejob (6.1.6.1)
activesupport (= 6.1.6.1)
activejob (6.1.4.4)
activesupport (= 6.1.4.4)
globalid (>= 0.3.6)
activemerchant (1.123.0)
activesupport (>= 4.2)
builder (>= 2.1.2, < 4.0.0)
i18n (>= 0.6.9)
nokogiri (~> 1.4)
activemodel (6.1.6.1)
activesupport (= 6.1.6.1)
activerecord (6.1.6.1)
activemodel (= 6.1.6.1)
activesupport (= 6.1.6.1)
activerecord-import (1.4.0)
activemodel (6.1.4.4)
activesupport (= 6.1.4.4)
activerecord (6.1.4.4)
activemodel (= 6.1.4.4)
activesupport (= 6.1.4.4)
activerecord-import (1.3.0)
activerecord (>= 4.2)
activerecord-postgresql-adapter (0.0.1)
pg
@@ -121,14 +129,14 @@ GEM
multi_json (~> 1.11, >= 1.11.2)
rack (>= 2.0.8, < 3)
railties (>= 5.2.4.1)
activestorage (6.1.6.1)
actionpack (= 6.1.6.1)
activejob (= 6.1.6.1)
activerecord (= 6.1.6.1)
activesupport (= 6.1.6.1)
marcel (~> 1.0)
activestorage (6.1.4.4)
actionpack (= 6.1.4.4)
activejob (= 6.1.4.4)
activerecord (= 6.1.4.4)
activesupport (= 6.1.4.4)
marcel (~> 1.0.0)
mini_mime (>= 1.1.0)
activesupport (6.1.6.1)
activesupport (6.1.4.4)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
@@ -141,49 +149,53 @@ GEM
addressable (2.8.0)
public_suffix (>= 2.0.2, < 5.0)
afm (0.2.2)
angular-rails-templates (1.2.0)
railties (>= 5.0, < 7.1)
angular-rails-templates (1.1.0)
railties (>= 4.2, < 7)
sprockets (>= 3.0, < 5)
sprockets-rails
tilt
angular_rails_csrf (4.5.0)
railties (>= 3, < 7)
angularjs-file-upload-rails (2.4.1)
angularjs-rails (1.8.0)
arel-helpers (2.14.0)
activerecord (>= 3.1.0, < 8)
arel-helpers (2.12.1)
activerecord (>= 3.1.0, < 7)
ast (2.4.2)
awesome_nested_set (3.5.0)
activerecord (>= 4.0.0, < 7.1)
awesome_nested_set (3.4.0)
activerecord (>= 4.0.0, < 7.0)
awesome_print (1.9.2)
aws-eventstream (1.2.0)
aws-partitions (1.601.0)
aws-sdk-core (3.131.2)
aws-partitions (1.570.0)
aws-sdk (1.67.0)
aws-sdk-v1 (= 1.67.0)
aws-sdk-core (3.130.0)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.525.0)
aws-sigv4 (~> 1.1)
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.57.0)
jmespath (~> 1.0)
aws-sdk-kms (1.55.0)
aws-sdk-core (~> 3, >= 3.127.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.114.0)
aws-sdk-s3 (1.113.0)
aws-sdk-core (~> 3, >= 3.127.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.4)
aws-sigv4 (1.5.0)
aws-sdk-v1 (1.67.0)
json (~> 1.4)
nokogiri (~> 1)
aws-sigv4 (1.4.0)
aws-eventstream (~> 1, >= 1.0.2)
axlsx_styler (1.1.0)
activesupport (>= 3.1)
caxlsx (>= 2.0.2)
bcrypt (3.1.18)
bcrypt (3.1.16)
bigdecimal (3.0.2)
bindex (0.8.1)
bootsnap (1.13.0)
bootsnap (1.10.1)
msgpack (~> 1.2)
bugsnag (6.24.2)
bugsnag (6.24.1)
concurrent-ruby (~> 1.0)
builder (3.2.4)
bullet (7.0.2)
bullet (6.1.5)
activesupport (>= 3.0.0)
uniform_notifier (~> 1.11)
byebug (11.1.3)
@@ -191,7 +203,7 @@ GEM
rails (>= 5.2)
thread-local (>= 1.1.0)
cancancan (1.15.0)
capybara (3.37.1)
capybara (3.36.0)
addressable
matrix
mini_mime (>= 0.1.3)
@@ -216,15 +228,14 @@ GEM
coffee-script-source
execjs
coffee-script-source (1.12.2)
combine_pdf (1.0.22)
matrix
combine_pdf (1.0.21)
ruby-rc4 (>= 0.1.5)
concurrent-ruby (1.1.10)
concurrent-ruby (1.1.9)
connection_pool (2.2.5)
crack (0.4.5)
rexml
crass (1.0.6)
css_parser (1.11.0)
css_parser (1.9.0)
addressable
cuprite (0.13)
capybara (>= 2.1, < 4)
@@ -240,7 +251,7 @@ GEM
msgpack
debase-ruby_core_source (0.10.12)
debugger-linecache (1.2.0)
devise (4.8.1)
devise (4.8.0)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 4.1.0)
@@ -248,20 +259,21 @@ GEM
warden (~> 1.2.3)
devise-encryptable (0.2.0)
devise (>= 2.1.0)
devise-i18n (1.10.2)
devise-i18n (1.10.0)
devise (>= 4.8.0)
devise-token_authenticatable (1.1.0)
devise (>= 4.0.0, < 5.0.0)
diff-lcs (1.5.0)
diff-lcs (1.4.4)
digest (3.1.0)
docile (1.4.0)
dotenv (2.8.1)
dotenv-rails (2.8.1)
dotenv (= 2.8.1)
dotenv (2.7.6)
dotenv-rails (2.7.6)
dotenv (= 2.7.6)
railties (>= 3.2)
dry-inflector (0.2.1)
erubi (1.11.0)
et-orbi (1.2.7)
e2mmap (0.1.0)
erubi (1.10.0)
et-orbi (1.2.4)
tzinfo
excon (0.81.0)
execjs (2.7.0)
@@ -270,16 +282,21 @@ 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 (1.4.1)
faraday-excon (~> 1.1)
faraday-net_http (~> 1.0)
faraday-net_http_persistent (~> 1.1)
multipart-post (>= 1.2, < 3)
ruby2_keywords (>= 0.0.4)
faraday-net_http (2.0.3)
faraday-excon (1.1.0)
faraday-net_http (1.0.1)
faraday-net_http_persistent (1.1.0)
ferrum (0.11)
addressable (~> 2.5)
cliver (~> 0.3)
concurrent-ruby (~> 1.1)
websocket-driver (>= 0.6, < 0.8)
ffaker (2.21.0)
ffaker (2.20.0)
ffi (1.15.5)
flipper (0.20.4)
flipper-active_record (0.20.4)
@@ -307,17 +324,17 @@ GEM
nokogiri (>= 1.5.11, < 2.0.0)
foreman (0.87.2)
formatador (0.2.5)
fugit (1.5.3)
et-orbi (~> 1, >= 1.2.7)
fugit (1.4.5)
et-orbi (~> 1.1, >= 1.1.8)
raabro (~> 1.4)
fuubar (2.5.1)
rspec-core (~> 3.0)
ruby-progressbar (~> 1.4)
geocoder (1.8.0)
geocoder (1.7.0)
globalid (1.0.0)
activesupport (>= 5.0)
gmaps4rails (2.1.2)
good_migrations (0.2.1)
good_migrations (0.1.0)
activerecord (>= 3.1)
railties (>= 3.1)
haml (5.2.2)
@@ -328,9 +345,9 @@ GEM
highline (2.0.3)
hiredis (0.6.3)
htmlentities (4.3.4)
i18n (1.12.0)
i18n (1.8.10)
concurrent-ruby (~> 1.0)
i18n-js (3.9.2)
i18n-js (3.9.0)
i18n (>= 0.6.6)
image_processing (1.12.2)
mini_magick (>= 4.9.5, < 5)
@@ -345,7 +362,7 @@ GEM
thor (>= 0.14, < 2.0)
jquery-ui-rails (4.2.1)
railties (>= 3.2.16)
json (2.6.2)
json (2.6.1)
json-schema (2.8.1)
addressable (>= 2.4)
json_spec (1.1.5)
@@ -353,18 +370,18 @@ GEM
rspec (>= 2.0, < 4.0)
jsonapi-serializer (2.2.0)
activesupport (>= 4.2)
jwt (2.4.1)
jwt (2.3.0)
knapsack (4.0.0)
rake
launchy (2.5.0)
addressable (~> 2.7)
letter_opener (1.8.1)
launchy (>= 2.2, < 3)
letter_opener (1.7.0)
launchy (~> 2.2)
libv8-node (15.14.0.1)
listen (3.7.1)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
loofah (2.18.0)
loofah (2.13.0)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mail (2.7.1)
@@ -372,9 +389,6 @@ GEM
marcel (1.0.2)
matrix (0.4.2)
method_source (1.0.0)
mime-types (3.4.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2021.0225)
mimemagic (0.4.3)
nokogiri (~> 1)
rake
@@ -383,20 +397,21 @@ GEM
mini_portile2 (2.8.0)
mini_racer (0.4.0)
libv8-node (~> 15.14.0.0)
minitest (5.16.2)
minitest (5.15.0)
monetize (1.12.0)
money (~> 6.12)
money (6.16.0)
i18n (>= 0.6.4, <= 2)
msgpack (1.5.4)
msgpack (1.4.2)
multi_json (1.15.0)
multi_xml (0.6.0)
multipart-post (2.1.1)
nio4r (2.5.8)
nokogiri (1.13.8)
nokogiri (1.13.3)
mini_portile2 (~> 2.8.0)
racc (~> 1.4)
oauth2 (1.4.10)
faraday (>= 0.17.3, < 3.0)
oauth2 (1.4.7)
faraday (>= 0.8, < 2.0)
jwt (>= 1.0, < 3.0)
multi_json (~> 1.3)
multi_xml (~> 0.5)
@@ -406,17 +421,17 @@ GEM
paper_trail (12.1.0)
activerecord (>= 5.2)
request_store (~> 1.1)
parallel (1.22.1)
paranoia (2.6.0)
activerecord (>= 5.1, < 7.1)
parser (3.1.2.0)
parallel (1.21.0)
paranoia (2.4.3)
activerecord (>= 4.0, < 6.2)
parser (3.1.0.0)
ast (~> 2.4.1)
paypal-sdk-core (0.3.4)
multi_json (~> 1.0)
xml-simple
paypal-sdk-merchant (1.117.2)
paypal-sdk-core (~> 0.3.0)
pdf-reader (2.10.0)
pdf-reader (2.5.0)
Ascii85 (~> 1.0)
afm (~> 0.2.1)
hashery (~> 2.0)
@@ -430,13 +445,13 @@ GEM
pry-byebug (3.9.0)
byebug (~> 11.0)
pry (~> 0.13.0)
public_suffix (4.0.7)
puma (5.6.4)
public_suffix (4.0.6)
puma (5.6.2)
nio4r (~> 2.0)
raabro (1.4.0)
racc (1.6.0)
rack (2.2.4)
rack-mini-profiler (2.3.4)
rack (2.2.3)
rack-mini-profiler (2.3.3)
rack (>= 1.2.0)
rack-protection (2.1.0)
rack
@@ -445,23 +460,23 @@ GEM
rack-rewrite (1.5.1)
rack-ssl (1.4.1)
rack
rack-test (2.0.2)
rack (>= 1.3)
rack-timeout (0.6.3)
rails (6.1.6.1)
actioncable (= 6.1.6.1)
actionmailbox (= 6.1.6.1)
actionmailer (= 6.1.6.1)
actionpack (= 6.1.6.1)
actiontext (= 6.1.6.1)
actionview (= 6.1.6.1)
activejob (= 6.1.6.1)
activemodel (= 6.1.6.1)
activerecord (= 6.1.6.1)
activestorage (= 6.1.6.1)
activesupport (= 6.1.6.1)
rack-test (1.1.0)
rack (>= 1.0, < 3)
rack-timeout (0.6.0)
rails (6.1.4.4)
actioncable (= 6.1.4.4)
actionmailbox (= 6.1.4.4)
actionmailer (= 6.1.4.4)
actionpack (= 6.1.4.4)
actiontext (= 6.1.4.4)
actionview (= 6.1.4.4)
activejob (= 6.1.4.4)
activemodel (= 6.1.4.4)
activerecord (= 6.1.4.4)
activestorage (= 6.1.4.4)
activesupport (= 6.1.4.4)
bundler (>= 1.15.0)
railties (= 6.1.6.1)
railties (= 6.1.4.4)
sprockets-rails (>= 2.0.0)
rails-controller-testing (1.0.5)
actionpack (>= 5.0.1.rc1)
@@ -470,17 +485,17 @@ GEM
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
rails-html-sanitizer (1.4.3)
rails-html-sanitizer (1.4.2)
loofah (~> 2.3)
rails-i18n (7.0.5)
rails-i18n (7.0.1)
i18n (>= 0.7, < 2)
railties (>= 6.0.0, < 8)
rails_safe_tasks (1.0.0)
railties (6.1.6.1)
actionpack (= 6.1.6.1)
activesupport (= 6.1.6.1)
railties (6.1.4.4)
actionpack (= 6.1.4.4)
activesupport (= 6.1.4.4)
method_source
rake (>= 12.2)
rake (>= 0.13)
thor (~> 1.0)
rainbow (3.1.1)
rake (13.0.6)
@@ -492,40 +507,37 @@ GEM
rb-inotify (0.10.1)
ffi (~> 1.0)
redcarpet (3.5.1)
redis (4.7.1)
regexp_parser (2.5.0)
redis (4.5.1)
regexp_parser (2.2.0)
request_store (1.5.0)
rack (>= 1.4)
responders (3.0.1)
actionpack (>= 5.0)
railties (>= 5.0)
rexml (3.2.5)
roadie (5.0.1)
roadie (4.0.0)
css_parser (~> 1.4)
nokogiri (~> 1.8)
roadie-rails (3.0.0)
railties (>= 5.1, < 7.1)
roadie (~> 5.0)
roadie-rails (2.2.0)
railties (>= 5.1, < 6.2)
roadie (>= 3.1, < 5.0)
rodf (1.1.1)
builder (>= 3.0)
dry-inflector (~> 0.1)
rubyzip (>= 1.0)
roo (2.9.0)
nokogiri (~> 1)
rubyzip (>= 1.3.0, < 3.0.0)
rspec (3.10.0)
rspec-core (~> 3.10.0)
rspec-expectations (~> 3.10.0)
rspec-mocks (~> 3.10.0)
rspec-core (3.10.2)
rspec-core (3.10.1)
rspec-support (~> 3.10.0)
rspec-expectations (3.10.2)
rspec-expectations (3.10.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.10.0)
rspec-mocks (3.10.2)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.10.0)
rspec-rails (5.1.2)
rspec-rails (5.0.2)
actionpack (>= 5.2)
activesupport (>= 5.2)
railties (>= 5.2)
@@ -535,29 +547,28 @@ GEM
rspec-support (~> 3.10)
rspec-retry (0.6.2)
rspec-core (> 3.3)
rspec-support (3.10.3)
rswag-api (2.5.1)
railties (>= 3.1, < 7.1)
rswag-specs (2.5.1)
activesupport (>= 3.1, < 7.1)
rspec-support (3.10.2)
rswag-api (2.4.0)
railties (>= 3.1, < 7.0)
rswag-specs (2.4.0)
activesupport (>= 3.1, < 7.0)
json-schema (~> 2.2)
railties (>= 3.1, < 7.1)
rswag-ui (2.5.1)
actionpack (>= 3.1, < 7.1)
railties (>= 3.1, < 7.1)
rubocop (1.32.0)
json (~> 2.3)
railties (>= 3.1, < 7.0)
rswag-ui (2.4.0)
actionpack (>= 3.1, < 7.0)
railties (>= 3.1, < 7.0)
rubocop (1.22.2)
parallel (~> 1.10)
parser (>= 3.1.0.0)
parser (>= 3.0.0.0)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.19.1, < 2.0)
rexml
rubocop-ast (>= 1.12.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 3.0)
rubocop-ast (1.19.1)
parser (>= 3.1.1.0)
rubocop-rails (2.15.2)
rubocop-ast (1.15.1)
parser (>= 3.0.1.1)
rubocop-rails (2.13.2)
activesupport (>= 4.2.0)
rack (>= 1.1)
rubocop (>= 1.7.0, < 2.0)
@@ -565,9 +576,9 @@ GEM
ruby-rc4 (0.1.5)
ruby-vips (2.1.4)
ffi (~> 1.12)
ruby2_keywords (0.0.5)
ruby2_keywords (0.0.4)
rubyzip (2.3.2)
rufus-scheduler (3.8.1)
rufus-scheduler (3.7.0)
fugit (~> 1.1, >= 1.1.6)
sass (3.4.25)
sass-rails (5.0.8)
@@ -577,22 +588,23 @@ GEM
sprockets-rails (>= 2.0, < 4.0)
tilt (>= 1.1, < 3)
sd_notify (0.1.1)
selenium-webdriver (4.3.0)
selenium-webdriver (4.0.3)
childprocess (>= 0.5, < 5.0)
rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 3.0)
websocket (~> 1.0)
rubyzip (>= 1.2.2)
semantic_range (3.0.0)
shoulda-matchers (5.1.0)
shoulda-matchers (5.0.0)
activesupport (>= 5.2.0)
sidekiq (6.5.1)
sidekiq (6.3.1)
connection_pool (>= 2.2.2)
rack (~> 2.0)
redis (>= 4.2.0)
sidekiq-scheduler (4.0.2)
redis (>= 4.2.0)
sidekiq-scheduler (3.1.0)
e2mmap
redis (>= 3, < 5)
rufus-scheduler (~> 3.2)
sidekiq (>= 4)
sidekiq (>= 3)
thwait
tilt (>= 1.4.0)
simplecov (0.21.2)
docile (~> 1.1)
@@ -604,7 +616,7 @@ GEM
axlsx_styler (>= 1.0.0, < 2)
caxlsx (>= 2.0.2, < 4)
rodf (>= 1.0.0, < 2)
spring (4.0.0)
spring (3.0.0)
spring-commands-rspec (1.0.4)
spring (>= 0.9.1)
sprockets (3.7.2)
@@ -624,32 +636,33 @@ GEM
stringex (2.8.5)
stripe (5.42.0)
temple (0.8.2)
test-prof (1.0.9)
test-unit (3.5.3)
test-prof (1.0.7)
test-unit (3.5.0)
power_assert
thor (1.2.1)
thread-local (1.1.0)
tilt (2.0.11)
timecop (0.9.5)
thwait (0.2.0)
e2mmap
tilt (2.0.10)
timecop (0.9.4)
ttfunk (1.7.0)
tzinfo (2.0.5)
tzinfo (2.0.4)
concurrent-ruby (~> 1.0)
uglifier (4.2.0)
execjs (>= 0.3.0, < 3)
unicode-display_width (2.2.0)
uniform_notifier (1.16.0)
valid_email2 (4.0.3)
unicode-display_width (2.1.0)
uniform_notifier (1.14.2)
valid_email2 (4.0.0)
activemodel (>= 3.2)
mail (~> 2.5)
view_component (2.64.0)
view_component (2.41.0)
activesupport (>= 5.0.0, < 8.0)
concurrent-ruby (~> 1.0)
method_source (~> 1.0)
view_component_storybook (0.11.1)
view_component_storybook (0.10.1)
view_component (>= 2.36)
warden (1.2.9)
rack (>= 2.0.9)
web-console (4.2.0)
web-console (4.1.0)
actionview (>= 6.0.0)
activemodel (>= 6.0.0)
bindex (>= 0.4.0)
@@ -658,7 +671,7 @@ GEM
nokogiri (~> 1.6)
rubyzip (>= 1.3.0)
selenium-webdriver (~> 4.0)
webmock (3.15.0)
webmock (3.14.0)
addressable (>= 2.8.0)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
@@ -667,19 +680,18 @@ GEM
rack-proxy (>= 0.6.1)
railties (>= 5.2)
semantic_range (>= 2.3.0)
websocket (1.2.9)
websocket-driver (0.7.5)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
whenever (1.0.0)
chronic (>= 0.6.3)
wicked_pdf (2.6.3)
wicked_pdf (2.1.0)
activesupport
wkhtmltopdf-binary (0.12.6.5)
xml-simple (1.1.8)
xpath (3.2.0)
nokogiri (~> 1.8)
zeitwerk (2.6.0)
zeitwerk (2.5.3)
PLATFORMS
ruby
@@ -701,6 +713,7 @@ DEPENDENCIES
arel-helpers (~> 2.12)
awesome_nested_set
awesome_print
aws-sdk (= 1.67.0)
aws-sdk-s3
bigdecimal (= 3.0.2)
bootsnap
@@ -752,7 +765,6 @@ DEPENDENCIES
knapsack
letter_opener (>= 1.4.1)
listen
mime-types
mimemagic (> 0.3.5)
mini_racer (= 0.4.0)
monetize (~> 1.11)
@@ -782,7 +794,7 @@ DEPENDENCIES
responders
rexml
roadie-rails
roo
roo!
rspec-rails (>= 3.5.2)
rspec-retry
rswag-api

View File

@@ -39,7 +39,7 @@ We use [BrowserStack](https://www.browserstack.com/) as a manual testing tool. B
## Licence
Copyright (c) 2012 - 2022 Open Food Foundation, released under the AGPL licence.
Copyright (c) 2012 - 2021 Open Food Foundation, released under the AGPL licence.
[survey]: https://docs.google.com/a/eaterprises.com.au/forms/d/1zxR5vSiU9CigJ9cEaC8-eJLgYid8CR8er7PPH9Mc-30/edit#
[slack-invite]: https://join.slack.com/t/openfoodnetwork/shared_invite/zt-9sjkjdlu-r02kUMP1zbrTgUhZhYPF~A

View File

@@ -10,7 +10,6 @@
scope.$emit "offClick"
element.click (event) ->
return if event.target.closest(".ofn-drop-down").classList.contains "disabled" || event.target.classList.contains "disabled"
if !scope.expanded
event.stopPropagation()
scope.deregistrationCallback = scope.$on "offClick", ->

View File

@@ -166,18 +166,12 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
$scope.sumUnitValues = ->
sum = $scope.filteredLineItems?.reduce (sum, lineItem) ->
if lineItem.units_product.variant_unit == "items"
sum + lineItem.quantity
else
sum + $scope.roundToThreeDecimals(lineItem.final_weight_volume / $scope.getLineItemScale(lineItem))
sum + $scope.roundToThreeDecimals(lineItem.final_weight_volume / $scope.getLineItemScale(lineItem))
, 0
$scope.sumMaxUnitValues = ->
sum = $scope.filteredLineItems?.reduce (sum,lineItem) ->
if lineItem.units_product.variant_unit == "items"
sum + lineItem.max_quantity
else
sum + lineItem.max_quantity * $scope.roundToThreeDecimals(lineItem.units_variant.unit_value / $scope.getLineItemScale(lineItem))
sum + lineItem.max_quantity * $scope.roundToThreeDecimals(lineItem.units_variant.unit_value / $scope.getLineItemScale(lineItem))
, 0
$scope.roundToThreeDecimals = (value) ->
@@ -191,8 +185,6 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
$scope.getScale = (unitsProduct, unitsVariant) ->
if unitsProduct.hasOwnProperty("variant_unit") && (unitsProduct.variant_unit == "weight" || unitsProduct.variant_unit == "volume")
unitsProduct.variant_unit_scale
else if unitsProduct.hasOwnProperty("variant_unit") && unitsProduct.variant_unit == "items"
1
else
null
@@ -217,11 +209,11 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
$scope.fulfilled = (sumOfUnitValues) ->
# A Units Variant is an API object which holds unit properies of a variant
if $scope.selectedUnitsProduct.hasOwnProperty("group_buy_unit_size")&& $scope.selectedUnitsProduct.group_buy_unit_size > 0 &&
$scope.selectedUnitsProduct.hasOwnProperty("variant_unit")
if $scope.selectedUnitsProduct.variant_unit == "weight" || $scope.selectedUnitsProduct.variant_unit == "volume"
scale = $scope.selectedUnitsProduct.variant_unit_scale
sumOfUnitValues = sumOfUnitValues * scale unless scale == 28.35 || scale == 453.6
if $scope.selectedUnitsProduct.hasOwnProperty("group_buy_unit_size") && $scope.selectedUnitsProduct.group_buy_unit_size > 0 &&
$scope.selectedUnitsProduct.hasOwnProperty("variant_unit") &&
( $scope.selectedUnitsProduct.variant_unit == "weight" || $scope.selectedUnitsProduct.variant_unit == "volume" )
scale = $scope.selectedUnitsProduct.variant_unit_scale
sumOfUnitValues = sumOfUnitValues * scale unless scale == 28.35 || scale == 453.6
$scope.roundToThreeDecimals(sumOfUnitValues / $scope.selectedUnitsProduct.group_buy_unit_size)
else
''

View File

@@ -20,7 +20,7 @@ angular.module("admin.orders").controller "orderCtrl", ($scope, shops, orderCycl
$scope.distributor_id && $scope.order_cycle_id
for oc in $scope.orderCycles
oc.name_and_status = "#{oc.name} (#{t("admin.order_cycles.status.#{oc.status}")})"
oc.name_and_status = "#{oc.name} (#{oc.status})"
for shop in $scope.shops
shop.disabled = !$scope.distributorHasOrderCycles(shop)

View File

@@ -0,0 +1,62 @@
angular.module("admin.orders").directive 'customerSearchOverride', ->
restrict: 'C'
scope:
distributorId: '@'
link: (scope, element, attr) ->
if $('#customer_autocomplete_template').length > 0
customerTemplate = Handlebars.compile($('#customer_autocomplete_template').text())
formatCustomerResult = (customer) ->
customerTemplate
customer: customer
bill_address: customer.bill_address
ship_address: customer.ship_address
element.select2
placeholder: Spree.translations.choose_a_customer
minimumInputLength: 3
ajax:
url: '/admin/search/customers.json'
datatype: 'json'
data: (term, page) ->
{
q: term
distributor_id: scope.distributorId # modified
}
results: (data, page) ->
{ results: data }
dropdownCssClass: 'customer_search'
formatResult: formatCustomerResult
formatSelection: (customer) ->
_.each [
'bill_address'
'ship_address'
], (address) ->
data = customer[address]
address_parts = [
'firstname'
'lastname'
'company'
'address1'
'address2'
'city'
'zipcode'
'phone'
]
attribute_wrapper = '#order_' + address + '_attributes_'
if data # modified
_.each address_parts, (part) ->
$(attribute_wrapper + part).val data[part]
return
$(attribute_wrapper + 'state_id').select2 'val', data['state_id']
$(attribute_wrapper + 'country_id').select2 'val', data['country_id']
else
_.each address_parts, (part) ->
$(attribute_wrapper + part).val ''
return
$(attribute_wrapper + 'state_id').select2 'val', ''
$(attribute_wrapper + 'country_id').select2 'val', ''
return
$('#order_email').val customer.email
$('#user_id').val customer.user_id # modified
customer.email

View File

@@ -8,7 +8,7 @@ angular.module("admin.products")
$scope.processVariantUnitWithScale()
$scope.processUnitValueWithDescription()
$scope.processUnitPrice()
$scope.placeholder_text = new OptionValueNamer($scope.product.master).name() if $scope.product.variant_unit_scale
$scope.placeholder_text = new OptionValueNamer($scope.product.master).name()
$scope.variant_unit_options = VariantUnitManager.variantUnitOptions()
@@ -21,8 +21,6 @@ angular.module("admin.products")
else
$scope.product.variant_unit = $scope.product.variant_unit_with_scale
$scope.product.variant_unit_scale = null
else if $scope.product.variant_unit && $scope.product.variant_unit_scale
$scope.product.variant_unit_with_scale = VariantUnitManager.getUnitWithScale($scope.product.variant_unit, parseFloat($scope.product.variant_unit_scale))
else
$scope.product.variant_unit = $scope.product.variant_unit_scale = null
@@ -34,10 +32,6 @@ angular.module("admin.products")
$scope.product.master.unit_value = null if isNaN($scope.product.master.unit_value)
$scope.product.master.unit_value *= $scope.product.variant_unit_scale if $scope.product.master.unit_value && $scope.product.variant_unit_scale
$scope.product.master.unit_description = match[3]
else
value = $scope.product.master.unit_value
value /= $scope.product.variant_unit_scale if $scope.product.master.unit_value && $scope.product.variant_unit_scale
$scope.product.master.unit_value_with_description = value + " " + $scope.product.master.unit_description
$scope.processUnitPrice = ->
price = $scope.product.price

View File

@@ -13,9 +13,3 @@ angular.module("ofn.admin").factory "ProductImageService", (FileUploader, SpreeA
@imageUploader.onSuccessItem = (image, response) =>
product.thumb_url = response.thumb_url
product.image_url = response.image_url
@imageUploader.onErrorItem = (image, response) =>
if Array.isArray(response.errors)
message = response.errors.join("\n")
else
message = response.error.toString()
alert(message)

View File

@@ -27,22 +27,16 @@ angular.module("admin.products").factory "VariantUnitManager", (availableUnits)
1000.0:
name: 'kL'
system: 'metric'
'items':
1:
name: 'items'
@variantUnitOptions: ->
available = availableUnits.split(",")
options = for unit_type, _ of @units
for scale in @unitScales(unit_type, available)
name = @getUnitName(scale, unit_type)
["#{I18n.t(unit_type)} (#{name})", @getUnitWithScale(unit_type, scale)]
["#{I18n.t(unit_type)} (#{name})", "#{unit_type}_#{scale}"]
options.push [[I18n.t('items'), 'items']]
options = [].concat options...
@getUnitWithScale: (unit_type, scale) ->
"#{unit_type}_#{scale}"
@getUnitName: (scale, unitType) ->
if @units[unitType][scale]
@units[unitType][scale]['name']

View File

@@ -25,12 +25,13 @@ $(document).ready(function() {
var link = $(this);
var shipment_number = link.data('shipment-number');
var selected_shipping_rate_id = link.parents('tbody').find("select#selected_shipping_rate_id[data-shipment-number='" + shipment_number + "']").val();
var unlock = link.parents('tbody').find("input[name='open_adjustment'][data-shipment-number='" + shipment_number + "']:checked").val();
var url = Spree.url( Spree.routes.orders_api + "/" + order_number + "/shipments/" + shipment_number + ".json");
$.ajax({
type: "PUT",
url: url,
data: { shipment: { selected_shipping_rate_id: selected_shipping_rate_id } }
data: { shipment: { selected_shipping_rate_id: selected_shipping_rate_id, unlock: unlock } }
}).done(function( msg ) {
window.location.reload();
}).error(function( msg ) {
@@ -39,94 +40,25 @@ $(document).ready(function() {
}
$('[data-hook=admin_order_edit_form] a.save-method').click(handle_shipping_method_save);
//handle tracking info edit/delete
// Show the input field to edit the tracking info
// And hide the input field when cancel is clicked
//handle tracking edit click
$('a.edit-tracking').click(toggleTrackingEdit);
$('a.cancel-tracking').click(toggleTrackingEdit);
saveTrackingInfo = function(){
let shipmentNumber = $(this).data('shipment-number');
let tracking = document.getElementById('tracking').value
handle_tracking_save = function(){
var link = $(this);
var shipment_number = link.data('shipment-number');
var tracking = link.parents('tbody').find('input#tracking').val();
var url = Spree.url( Spree.routes.orders_api + "/" + order_number + "/shipments/" + shipment_number + ".json");
makeApiCall(trackingUrl(shipmentNumber), { shipment: { tracking: tracking } } )
}
deleteTrackingInfo = function(){
let shipmentNumber = $(this).data('shipment-number');
let tracking = ''
confirmDelete(trackingUrl(shipmentNumber), { shipment: { tracking: tracking } })
}
trackingUrl = function(shipmentNumber){
return Spree.url( Spree.routes.orders_api + "/" + order_number + "/shipments/" + shipmentNumber + ".json");
}
$('[data-hook=admin_order_edit_form] a.save-tracking').click(saveTrackingInfo);
$('[data-hook=admin_order_edit_form] a.delete-tracking').click(deleteTrackingInfo);
// handle note edit/delete
// Show the input field to edit the note
// And hide the input field when cancel is clicked
$('a.edit-note.icon-edit').click(toggleNoteEdit);
$('a.cancel-note').click(toggleNoteEdit);
saveNote = function(){
let note = document.getElementById('note').value
makeApiCall(getNoteUrl(), { note: note })
}
deleteNote = function(){
let note = ''
confirmDelete(getNoteUrl(), { note: note })
}
getNoteUrl = function(){
return Spree.url( Spree.routes.orders_api + "/" + order_number);
}
confirmDelete = function(url, params){
displayDeleteAlert(function(confirmation) {
if (confirmation) {
makeApiCall(url, params)
}
});
}
$('[data-hook=admin_order_edit_form] a.save-note').click(saveNote);
$('[data-hook=admin_order_edit_form] a.delete-note').click(deleteNote);
// Makes API call for notes/tracking info
makeApiCall = function(url, params) {
$.ajax({
type: "PUT",
url: url,
data: params
data: { shipment: { tracking: tracking } }
}).done(function( msg ) {
window.location.reload();
}).error(function( msg ) {
console.log(msg);
});
}
displayDeleteAlert = function(callback) {
i18nKey = "are_you_sure";
$('#custom-confirm .message').html(
` ${t(i18nKey)}
<div class="form">
</div>`);
$('#custom-confirm button.confirm').unbind( "click" ).click(() => {
$('#custom-confirm').hide();
callback(true);
});
$('#custom-confirm button.cancel').click(() => {
$('#custom-confirm').hide();
callback(false)
});
$('#custom-confirm').show();
}
$('[data-hook=admin_order_edit_form] a.save-tracking').click(handle_tracking_save);
});

View File

@@ -141,26 +141,8 @@ doAdjustItems = function(shipment_number, variant_id, quantity, inventory_units,
toggleTrackingEdit = function(){
var link = $(this);
var parent_node = link.parents('tbody')
let input = parent_node.find('#tracking')[0]
parent_node.find('tr.edit-tracking').toggle();
// Set focus on input and
// put cursor at it's end
input.focus()
input.setSelectionRange(-1, -1)
parent_node.find('tr.show-tracking').toggle();
}
toggleNoteEdit = function(){
var link = $(this);
var parent_node = link.parents('tbody')
let input = parent_node.find('#note')[0]
parent_node.find('tr.edit-note').toggle();
// Set focus on input and
// put cursor at it's end
input.focus()
input.setSelectionRange(-1, -1)
parent_node.find('tr.show-note').toggle();
link.parents('tbody').find('tr.edit-tracking').toggle();
link.parents('tbody').find('tr.show-tracking').toggle();
}
toggleMethodEdit = function(){

View File

@@ -8,18 +8,13 @@ handle_move = (e, data) ->
node = data.rslt.o
new_parent = data.rslt.np
url = new URL(base_url)
url.pathname = url.pathname + '/' + node.attr("id")
data = {
_method: "put",
"taxon[position]": position,
"taxon[parent_id]": if !isNaN(new_parent.attr("id")) then new_parent.attr("id") else undefined
}
url = Spree.url(base_url).clone()
url.pathname = url.pathname + '/' + node.attr("id")
$.ajax
type: "POST",
dataType: "json",
url: url.toString(),
data: data,
data: ({_method: "put", "taxon[parent_id]": new_parent.attr("id"), "taxon[position]": position }),
error: handle_ajax_error
true
@@ -31,16 +26,11 @@ handle_create = (e, data) ->
position = data.rslt.position
new_parent = data.rslt.parent
data = {
"taxon[name]": name,
"taxon[position]": position
"taxon[parent_id]": if !isNaN(new_parent.attr("id")) then new_parent.attr("id") else undefined
}
$.ajax
type: "POST",
dataType: "json",
url: base_url.toString(),
data: data,
data: ({"taxon[name]": name, "taxon[parent_id]": new_parent.attr("id"), "taxon[position]": position }),
error: handle_ajax_error,
success: (data,result) ->
node.attr('id', data.id)
@@ -49,10 +39,8 @@ handle_rename = (e, data) ->
last_rollback = data.rlbk
node = data.rslt.obj
name = data.rslt.new_name
# change the name inside the main input field as well if taxon is the root one
document.getElementById("taxonomy_name").value = name if node.parents("[id]").attr("id") == "taxonomy_tree"
url = new URL(base_url)
url = Spree.url(base_url).clone()
url.pathname = url.pathname + '/' + node.attr("id")
$.ajax
@@ -65,8 +53,8 @@ handle_rename = (e, data) ->
handle_delete = (e, data) ->
last_rollback = data.rlbk
node = data.rslt.obj
delete_url = new URL(base_url)
delete_url.pathname = delete_url.pathname + '/' + node.attr("id")
delete_url = base_url.clone()
delete_url.setPath delete_url.path() + '/' + node.attr("id")
if confirm(Spree.translations.are_you_sure_delete)
$.ajax
type: "POST",

View File

@@ -3,7 +3,6 @@ angular.module("admin.utils").directive "tagsWithTranslation", ($timeout) ->
templateUrl: "admin/tags_input.html"
scope:
object: "="
form: "="
tagsAttr: "@?"
tagListAttr: "@?"
findTags: "&"
@@ -19,15 +18,7 @@ angular.module("admin.utils").directive "tagsWithTranslation", ($timeout) ->
scope.limitReached = scope.object[scope.tagsAttr].length >= scope.max if scope.max != undefined
scope.object[scope.tagListAttr] = (tag.text for tag in scope.object[scope.tagsAttr]).join(",")
scope.$watch "object", (newObject) ->
scope.object = newObject
init()
$timeout ->
init()
init = ->
return unless scope.object
# Initialize properties if necessary
scope.tagsAttr ||= "tags"
scope.tagListAttr ||= "tag_list"

View File

@@ -5,16 +5,15 @@ angular.module("admin.utils").factory "ErrorsParser", ->
return defaultContent unless errors?
errorsString = ""
if Array.isArray(errors)
if errors.length > 0
# it is an array of errors
errorsString = errors.join("\n") + "\n"
else if typeof errors == "object"
else
# it is a hash of errors
keys = Object.keys(errors)
for key in keys
errorsString += errors[key].join("\n") + "\n"
else # string
errorsString = errors
this.defaultIfEmpty(errorsString, defaultContent)
defaultIfEmpty: (content, defaultContent) =>

View File

@@ -26,8 +26,4 @@ angular.module('mm.foundation.offcanvas').directive 'offCanvasWrap', ($window) -
# Bind hiding of the off-canvas that only happens when screen width is over 1024px.
win.bind 'resize.body', ->
isolatedScope.hide() if $(window).width() > 1024
win.bind 'click.body', (e) ->
if e.target.closest(".left-off-canvas-menu") == null && e.target.closest(".left-off-canvas-toggle") == null
isolatedScope.hide()
}

View File

@@ -1,12 +1,8 @@
%div.contact-container
%div.modal-centered{"ng-if" => "::enterprise.email_address || enterprise.website || enterprise.phone || enterprise.whatsapp_phone"}
%div.modal-centered{"ng-if" => "::enterprise.email_address || enterprise.website || enterprise.phone"}
%p.modal-header {{'contact' | t}}
%p{"ng-if" => "::enterprise.phone", "ng-bind" => "::enterprise.phone"}
%p{"ng-if" => "::enterprise.whatsapp_phone"}
%img{ src: image_path("/map_icons/social-logos/whatsapp.svg") }
%a{"ng-href" => "{{::enterprise.whatsapp_url}}", target: "_blank", "ng-bind" => "::enterprise.whatsapp_phone"}
%p{"ng-if" => "::enterprise.email_address"}
%a{"ng-href" => "{{::enterprise.email_address | stripUrl}}", target: "_blank", mailto: true}
%span.obfuscatedEmail.email{"ng-bind" => "::enterprise.email_address | stripUrl"}

View File

@@ -9,19 +9,19 @@
%span{"ng-bind" => "::'item_cost' | t"}
%li{"ng-if" => "::variant.fees.admin"}
.right {{ ::variant.fees.admin | localizeCurrency }}
%span{"ng-bind" => "::variant.fees_name.admin"}
%span{"ng-bind" => "::'admin_fee' | t"}
%li{"ng-if" => "::variant.fees.sales"}
.right {{ ::variant.fees.sales | localizeCurrency }}
%span{"ng-bind" => "::variant.fees_name.sales"}
%span{"ng-bind" => "::'sales_fee' | t"}
%li{"ng-if" => "::variant.fees.packing"}
.right {{ ::variant.fees.packing | localizeCurrency }}
%span{"ng-bind" => "::variant.fees_name.packing"}
%span{"ng-bind" => "::'packing_fee' | t"}
%li{"ng-if" => "::variant.fees.transport"}
.right {{ ::variant.fees.transport | localizeCurrency }}
%span{"ng-bind" => "::variant.fees_name.transport"}
%span{"ng-bind" => "::'transport_fee' | t"}
%li{"ng-if" => "::variant.fees.fundraising"}
.right {{ ::variant.fees.fundraising | localizeCurrency }}
%span{"ng-bind" => "::variant.fees_name.fundraising"}
%span{"ng-bind" => "::'fundraising_fee' | t"}
%li
%strong
.right = {{ ::variant.price_with_fees | localizeCurrency }}

View File

@@ -19,7 +19,6 @@ module Admin
:enable_invoices?,
:invoice_style2?,
:enable_receipt_printing?,
:enterprise_number_required_on_invoices?,
)
end
end

View File

@@ -46,14 +46,6 @@ module Admin
# 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
@data = Reporting::FrontendData.new(spree_current_user)
end

View File

@@ -26,13 +26,6 @@ module Api
}
end
def update
authorize! :admin, order
order.update!(order_params)
render json: order, serializer: Api::OrderDetailedSerializer, current_order: order
end
def ship
authorize! :admin, order
@@ -79,10 +72,6 @@ module Api
includes(line_items: { variant: [:product, :stock_items, :default_price] }).
first!
end
def order_params
params.permit(:note)
end
end
end
end

View File

@@ -6,21 +6,20 @@ module Api
respond_to :json
def update_product_image
product = Spree::Product.find(params[:product_id])
authorize! :update, product
@product = Spree::Product.find(params[:product_id])
authorize! :update, @product
image = product.images.first || Spree::Image.new(
viewable_id: product.master.id,
viewable_type: 'Spree::Variant'
)
success_status = image.persisted? ? :ok : :created
if image.update(attachment: params[:file])
render json: image, serializer: ImageSerializer, status: success_status
if @product.images.first.nil?
@image = Spree::Image.create(
attachment: params[:file],
viewable_id: @product.master.id,
viewable_type: 'Spree::Variant'
)
render json: @image, serializer: ImageSerializer, status: :created
else
error_json = { errors: image.errors.full_messages }
render json: error_json, status: :unprocessable_entity
@image = @product.images.first
@image.update(attachment: params[:file])
render json: @image, serializer: ImageSerializer, status: :ok
end
end
end

View File

@@ -28,14 +28,19 @@ module Api
authorize! :read, Spree::Shipment
@shipment = @order.shipments.find_by!(number: params[:id])
params[:shipment] ||= []
unlock = params[:shipment].delete(:unlock)
@shipment.fee_adjustment.fire_events(:open)
if unlock == 'yes'
@shipment.fee_adjustment.fire_events(:open)
end
if @shipment.update(shipment_params)
@order.updater.update_totals_and_states
end
@shipment.fee_adjustment.close
if unlock == 'yes'
@shipment.fee_adjustment.close
end
render json: @shipment.reload, serializer: Api::ShipmentSerializer, status: :ok
end

View File

@@ -73,7 +73,7 @@ module Api
def taxon_params
return if params[:taxon].blank?
params.require(:taxon).permit([:name, :parent_id, :position])
params.require(:taxon).permit([:name, :parent_id])
end
end
end

View File

@@ -5,10 +5,9 @@ require 'open_food_network/permissions'
module Api
module V1
class CustomersController < Api::V1::BaseController
include AddressTransformation
skip_authorization_check only: :index
before_action :set_customer, only: [:show, :update, :destroy]
before_action :authorize_action, only: [:show, :update, :destroy]
def index
@@ -18,44 +17,44 @@ module Api
end
def show
render json: Api::V1::CustomerSerializer.new(customer, include_options)
render json: Api::V1::CustomerSerializer.new(@customer, include_options)
end
def create
authorize! :update, Enterprise.find(customer_params[:enterprise_id])
customer = Customer.new(customer_params)
@customer = Customer.new(customer_params)
if customer.save
render json: Api::V1::CustomerSerializer.new(customer), status: :created
if @customer.save
render json: Api::V1::CustomerSerializer.new(@customer), status: :created
else
invalid_resource! customer
invalid_resource! @customer
end
end
def update
if customer.update(customer_params)
render json: Api::V1::CustomerSerializer.new(customer)
if @customer.update(customer_params)
render json: Api::V1::CustomerSerializer.new(@customer)
else
invalid_resource! customer
invalid_resource! @customer
end
end
def destroy
if customer.destroy
render json: Api::V1::CustomerSerializer.new(customer)
if @customer.destroy
render json: Api::V1::CustomerSerializer.new(@customer)
else
invalid_resource! customer
invalid_resource! @customer
end
end
private
def customer
@customer ||= Customer.find(params[:id])
def set_customer
@customer = Customer.find(params[:id])
end
def authorize_action
authorize! action_name.to_sym, customer
authorize! action_name.to_sym, @customer
end
def search_customers
@@ -78,8 +77,7 @@ module Api
:phone, :latitude, :longitude,
:first_name, :last_name,
:street_address_1, :street_address_2,
:postal_code, :locality,
{ region: [:name, :code], country: [:name, :code] },
:postal_code, :locality, :region, :country,
]
).to_h
@@ -91,6 +89,39 @@ module Api
attributes
end
def transform_address!(attributes, from, to)
return unless attributes.key?(from)
address = attributes.delete(from)
if address.nil?
attributes[to] = nil
return
end
address.transform_keys! do |key|
{
phone: :phone, latitude: :latitude, longitude: :longitude,
first_name: :firstname, last_name: :lastname,
street_address_1: :address1, street_address_2: :address2,
postal_code: :zipcode,
locality: :city,
region: :state_name,
country: :country,
}.with_indifferent_access[key]
end
if address[:state_name].present?
address[:state] = Spree::State.find_by(name: address[:state_name])
end
if address[:country].present?
address[:country] = Spree::Country.find_by(name: address[:country])
end
attributes["#{to}_attributes"] = address
end
def editable_enterprises
OpenFoodNetwork::Permissions.new(current_api_user).editable_enterprises.select(:id)
end

View File

@@ -39,7 +39,6 @@ class ApplicationController < ActionController::Base
include Spree::Core::ControllerHelpers::Common
before_action :set_cache_headers # prevent cart emptying via cache when using back button #1213
before_action :check_disabled_user, if: :spree_user_signed_in?
before_action :set_after_login_url
include RawParams
@@ -160,14 +159,6 @@ class ApplicationController < ActionController::Base
response.headers["Pragma"] = "no-cache"
response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT"
end
def check_disabled_user
return unless current_spree_user.disabled
flash[:success] = nil
flash.now[:error] = I18n.t("devise.failure.disabled")
sign_out current_spree_user
end
end
require 'spree/i18n/initializer'

View File

@@ -1,48 +0,0 @@
# frozen_string_literal: true
# Our internal data structures are different to the API data strurctures.
module AddressTransformation
extend ActiveSupport::Concern
def transform_address!(attributes, from, to)
return unless attributes.key?(from)
address = attributes.delete(from)
if address.nil?
attributes[to] = nil
return
end
address.transform_keys! do |key|
{
phone: :phone, latitude: :latitude, longitude: :longitude,
first_name: :firstname, last_name: :lastname,
street_address_1: :address1, street_address_2: :address2,
postal_code: :zipcode,
locality: :city,
region: :state,
country: :country,
}.with_indifferent_access[key]
end
address[:state] = find_state(address) if address[:state].present?
address[:country] = find_country(address) if address[:country].present?
attributes["#{to}_attributes"] = address
end
private
def find_state(address)
Spree::State.find_by("LOWER(abbr) = ? OR LOWER(name) = ?",
address.dig(:state, :code)&.downcase,
address.dig(:state, :name)&.downcase)
end
def find_country(address)
Spree::Country.find_by("LOWER(iso) = ? OR LOWER(name) = ?",
address.dig(:country, :code)&.downcase,
address.dig(:country, :name)&.downcase)
end
end

View File

@@ -42,10 +42,6 @@ module Spree
@order.update_order!
end
if params[:set_distribution_step] && @order.update(order_params)
return redirect_to spree.admin_order_customer_path(@order)
end
unless order_params.present? && @order.update(order_params) && @order.line_items.present?
if @order.line_items.empty? && !params[:suppress_error_msg]
@order.errors.add(:line_items, Spree.t('errors.messages.blank'))
@@ -59,7 +55,7 @@ module Spree
redirect_to spree.edit_admin_order_path(@order)
else
# Jump to next step if order is not complete
redirect_to spree.admin_order_payments_path(@order)
redirect_to spree.admin_order_customer_path(@order)
end
end
@@ -130,7 +126,7 @@ module Spree
end
def require_distributor_abn
return if @order.distributor.can_invoice?
return if @order.distributor.abn.present?
flash[:error] = t(:must_have_valid_business_number,
enterprise_name: @order.distributor.name)

View File

@@ -30,11 +30,12 @@ module Spree
@object.attributes = permitted_resource_params
if @object.save
flash[:success] = flash_message_for(@object, :successfully_created)
redirect_after_save
if params[:button] == "add_another"
redirect_to spree.new_admin_product_path
else
redirect_to spree.admin_products_path
end
else
# Re-fill the form with deleted params on product
@on_hand = request.params[:product][:on_hand]
@on_demand = request.params[:product][:on_demand]
render :new
end
end
@@ -137,14 +138,6 @@ module Spree
private
def redirect_after_save
if params[:button] == "add_another"
redirect_to spree.new_admin_product_path
else
redirect_to spree.admin_products_path
end
end
def product_set_from_params
collection_hash = Hash[products_bulk_params[:products].each_with_index.map { |p, i|
[i, p]

View File

@@ -4,8 +4,6 @@ module Spree
class OrdersController < ::BaseController
include OrderCyclesHelper
include Rails.application.routes.url_helpers
include CablecarResponses
layout 'darkswarm'
@@ -101,8 +99,7 @@ module Spree
else
flash[:error] = I18n.t(:orders_could_not_cancel)
end
render status: :found,
operations: cable_car.redirect_to(url: request.referer || main_app.order_path(@order))
redirect_to request.referer || main_app.order_path(@order)
end
private

View File

@@ -44,14 +44,6 @@ module Spree
end
end
def print_invoice_link
if @order.distributor.can_invoice?
print_invoice_link_with_url
else
notify_about_required_enterprise_number
end
end
def ticket_links
return [] unless Spree::Config[:enable_receipt_printing?]
@@ -86,20 +78,13 @@ module Spree
confirm: t(:must_have_valid_business_number, enterprise_name: @order.distributor.name) }
end
def print_invoice_link_with_url
def print_invoice_link
{ name: t(:print_invoice),
url: spree.print_admin_order_path(@order),
icon: 'icon-print',
target: "_blank" }
end
def notify_about_required_enterprise_number
{ name: t(:print_invoice),
url: "#",
icon: 'icon-print',
confirm: t(:must_have_valid_business_number, enterprise_name: @order.distributor.name) }
end
def print_ticket_link
{ name: t(:print_ticket),
url: print_ticket_admin_order_path(@order),

View File

@@ -41,8 +41,8 @@ class CustomerSchema < JsonApiSchema
street_address_2: "",
postal_code: "1234",
locality: "Melbourne",
region: { code: "Vic", name: "Victoria" },
country: { code: "AU", name: "Australia" },
region: "Victoria",
country: "Australia",
}
end

View File

@@ -10,7 +10,7 @@ class Customer < ApplicationRecord
belongs_to :enterprise
belongs_to :user, class_name: "Spree::User"
has_many :orders, class_name: "Spree::Order"
before_destroy :update_orders_and_delete_canceled_subscriptions
before_destroy :check_for_orders
belongs_to :bill_address, class_name: "Spree::Address"
alias_attribute :billing_address, :bill_address
@@ -52,12 +52,10 @@ class Customer < ApplicationRecord
self.user = user || Spree::User.find_by(email: email)
end
def update_orders_and_delete_canceled_subscriptions
if Subscription.where(customer_id: id).not_canceled.any?
errors.add(:base, I18n.t('admin.customers.destroy.has_associated_subscriptions'))
throw :abort
end
Subscription.where(customer_id: id).destroy_all
orders.update_all(customer_id: nil)
def check_for_orders
return true unless orders.any?
errors.add(:base, I18n.t('admin.customers.destroy.has_associated_orders'))
throw :abort
end
end

View File

@@ -84,8 +84,8 @@ class Enterprise < ApplicationRecord
has_one_attached :promo_image
has_one_attached :terms_and_conditions
validates :logo, content_type: %r{\Aimage/(png|jpeg|gif|jpg|svg\+xml|webp)\Z}
validates :promo_image, content_type: %r{\Aimage/(png|jpeg|gif|jpg|svg\+xml|webp)\Z}
validates :logo, content_type: %r{\Aimage/.*\Z}
validates :promo_image, content_type: %r{\Aimage/.*\Z}
validates :terms_and_conditions, content_type: {
in: "application/pdf",
message: I18n.t(:enterprise_terms_and_conditions_type_error),
@@ -312,10 +312,6 @@ class Enterprise < ApplicationRecord
correct_instagram_url self[:instagram]
end
def whatsapp_url
correct_whatsapp_url self[:whatsapp_phone]
end
def inventory_variants
if prefers_product_selection_from_inventory_only?
Spree::Variant.visible_for(self)
@@ -412,8 +408,6 @@ class Enterprise < ApplicationRecord
end
def can_invoice?
return true unless Spree::Config.enterprise_number_required_on_invoices?
abn.present?
end
@@ -452,10 +446,6 @@ class Enterprise < ApplicationRecord
url&.sub(%r{(https?://)?}, '')
end
def correct_whatsapp_url(phone_number)
phone_number && "https://wa.me/" + phone_number.tr('+ ', '')
end
def correct_instagram_url(url)
url && strip_url(url).sub(%r{www.instagram.com/}, '').delete("@")
end

View File

@@ -28,8 +28,8 @@ class EnterpriseGroup < ApplicationRecord
has_one_attached :logo
has_one_attached :promo_image
validates :logo, content_type: %r{\Aimage/(png|jpeg|gif|jpg|svg\+xml|webp)\Z}
validates :promo_image, content_type: %r{\Aimage/(png|jpeg|gif|jpg|svg\+xml|webp)\Z}
validates :logo, content_type: %r{\Aimage/.*\Z}
validates :promo_image, content_type: %r{\Aimage/.*\Z}
scope :by_position, -> { order('position ASC') }
scope :on_front_page, -> { where(on_front_page: true) }

View File

@@ -5,7 +5,7 @@
# This reduces the need to keep Orders in sync with their parent Subscriptions
class ProxyOrder < ApplicationRecord
belongs_to :order, class_name: 'Spree::Order'
belongs_to :order, class_name: 'Spree::Order', dependent: :destroy
belongs_to :subscription
belongs_to :order_cycle

View File

@@ -129,7 +129,6 @@ module Spree
preference :enable_invoices?, :boolean, default: true
preference :invoice_style2?, :boolean, default: false
preference :enable_receipt_printing?, :boolean, default: false
preference :enterprise_number_required_on_invoices?, :boolean, default: true
# Stripe payments
preference :stripe_connect_enabled, :boolean, default: false

View File

@@ -11,19 +11,15 @@ module Spree
has_one_attached :attachment
validates :attachment, attached: true, content_type: %r{\Aimage/(png|jpeg|gif|jpg|svg\+xml|webp)\Z}
validates :attachment, attached: true, content_type: %r{\Aimage/.*\Z}
validate :no_attachment_errors
def variant(name)
if attachment.variable?
attachment.variant(SIZES[name])
else
attachment
end
attachment.variant(SIZES[name])
end
def url(size)
return unless attachment.attached?
return unless attachment.variable?
Rails.application.routes.url_helpers.url_for(variant(size))
end

View File

@@ -433,7 +433,7 @@ module Spree
all_adjustments.destroy_all
payments.clear
shipments.destroy_all
restart_checkout_flow if state.in?(["payment", "confirmation"])
restart_checkout_flow if state == "payment"
end
def state_changed(name)

View File

@@ -41,7 +41,7 @@ module Spree
accepts_nested_attributes_for :bill_address
accepts_nested_attributes_for :ship_address
after_create :associate_customers, :associate_orders
after_create :associate_customers
validate :limit_owned_enterprises
@@ -113,12 +113,6 @@ module Spree
self.customers = Customer.where(email: email)
end
def associate_orders
Spree::Order.where(customer: customers).find_each do |order|
order.associate_user!(self)
end
end
def can_own_more_enterprises?
owned_enterprises.reload.size < enterprise_limit
end
@@ -150,14 +144,6 @@ module Spree
"#{self.class.name};#{id}"
end
def disabled
disabled_at.present?
end
def disabled=(value)
self.disabled_at = value == '1' ? Time.zone.now : nil
end
protected
def password_required?

View File

@@ -172,11 +172,6 @@ module Spree
OpenFoodNetwork::EnterpriseFeeCalculator.new(distributor, order_cycle).fees_by_type_for self
end
def fees_name_by_type_for(distributor, order_cycle)
OpenFoodNetwork::EnterpriseFeeCalculator.new(distributor,
order_cycle).fees_name_by_type_for self
end
def option_value(opt_name)
option_values.detect { |o| o.option_type.name == opt_name }.try(:presentation)
end

View File

@@ -17,9 +17,9 @@ class Subscription < ApplicationRecord
belongs_to :payment_method, class_name: 'Spree::PaymentMethod'
belongs_to :bill_address, class_name: "Spree::Address"
belongs_to :ship_address, class_name: "Spree::Address"
has_many :subscription_line_items, inverse_of: :subscription, dependent: :destroy
has_many :subscription_line_items, inverse_of: :subscription
has_many :order_cycles, through: :schedule
has_many :proxy_orders, dependent: :destroy
has_many :proxy_orders
has_many :orders, through: :proxy_orders
alias_attribute :billing_address, :bill_address

View File

@@ -14,9 +14,9 @@ module Api
attributes :name, :id, :description, :latitude, :longitude,
:long_description, :website, :instagram, :linkedin, :twitter,
:facebook, :is_primary_producer, :is_distributor, :phone, :whatsapp_phone,
:whatsapp_url, :visible, :email_address, :hash, :logo, :promo_image, :path, :pickup,
:delivery, :icon, :icon_font, :producer_icon_font, :category
:facebook, :is_primary_producer, :is_distributor, :phone, :visible,
:email_address, :hash, :logo, :promo_image, :path, :pickup, :delivery,
:icon, :icon_font, :producer_icon_font, :category
attributes :taxons, :supplied_taxons

View File

@@ -7,9 +7,9 @@ module Api
attributes :name, :id, :description, :latitude, :longitude, :long_description, :website,
:instagram, :linkedin, :twitter, :facebook, :is_primary_producer, :is_distributor,
:phone, :whatsapp_phone, :whatsapp_url, :visible, :email_address, :hash, :logo,
:promo_image, :path, :category, :active, :producers, :orders_close_at, :hubs,
:taxons, :supplied_taxons, :pickup, :delivery, :preferred_product_low_stock_display
:phone, :visible, :email_address, :hash, :logo, :promo_image, :path, :category,
:active, :producers, :orders_close_at, :hubs, :taxons, :supplied_taxons, :pickup,
:delivery, :preferred_product_low_stock_display
has_one :address, serializer: Api::AddressSerializer
has_many :supplied_properties, serializer: Api::PropertySerializer

View File

@@ -11,18 +11,8 @@ module Api
attribute :street_address_2, &:address2
attribute :postal_code, &:zipcode
attribute :locality, &:city
attribute :region do |object|
{
name: object.state.name,
code: object.state.abbr,
}
end
attribute :country do |object|
{
name: object.country.name,
code: object.country.iso,
}
end
attribute :region, &:state_name
attribute :country, ->(object, _) { object.country.name }
end
end
end

View File

@@ -4,8 +4,7 @@ class Api::VariantSerializer < ActiveModel::Serializer
attributes :id, :is_master, :product_name, :sku,
:options_text, :unit_value, :unit_description, :unit_to_display,
:display_as, :display_name, :name_to_display,
:price, :on_demand, :on_hand,
:fees, :fees_name, :price_with_fees,
:price, :on_demand, :on_hand, :fees, :price_with_fees,
:tag_list, :thumb_url,
:unit_price_price, :unit_price_unit
@@ -16,10 +15,6 @@ class Api::VariantSerializer < ActiveModel::Serializer
object.fees_by_type_for(options[:current_distributor], options[:current_order_cycle])
end
def fees_name
object.fees_name_by_type_for(options[:current_distributor], options[:current_order_cycle])
end
def price_with_fees
if options[:enterprise_fee_calculator]
object.price + options[:enterprise_fee_calculator].indexed_fees_for(object)

View File

@@ -25,10 +25,10 @@ module PermittedAttributes
def self.basic_permitted_attributes
[
:id, :name, :visible, :permalink, :owner_id, :contact_name, :email_address, :phone,
:whatsapp_phone, :is_primary_producer, :sells, :website, :facebook, :instagram, :linkedin,
:twitter, :description, :long_description, :logo, :promo_image, :terms_and_conditions,
:allow_guest_orders, :allow_order_changes, :require_login, :enable_subscriptions, :abn,
:acn, :charges_sales_tax, :display_invoice_logo, :invoice_text,
:is_primary_producer, :sells, :website, :facebook, :instagram, :linkedin, :twitter,
:description, :long_description, :logo, :promo_image, :terms_and_conditions,
:allow_guest_orders, :allow_order_changes, :require_login, :enable_subscriptions,
:abn, :acn, :charges_sales_tax, :display_invoice_logo, :invoice_text,
:preferred_product_selection_from_inventory_only, :preferred_shopfront_message,
:preferred_shopfront_closed_message, :preferred_shopfront_taxon_order,
:preferred_shopfront_producer_order, :preferred_shopfront_order_cycle_order,

View File

@@ -15,7 +15,7 @@ module PermittedAttributes
private
def permitted_attributes
[:email, :password, :password_confirmation, :disabled]
[:email, :password, :password_confirmation]
end
end
end

View File

@@ -97,7 +97,6 @@ module Sets
variants_attributes.each do |attributes|
create_or_update_variant(product, attributes)
end
product.errors.empty?
end
def create_or_update_variant(product, variant_attributes)
@@ -115,11 +114,6 @@ module Sets
variant = product.variants.create(variant_attributes)
if variant.errors.present?
product.errors.merge!(variant.errors)
return false
end
begin
variant.on_demand = on_demand if on_demand.present?
variant.on_hand = on_hand.to_i if on_hand.present?

View File

@@ -15,13 +15,6 @@
= f.label :phone, t('.phone')
.omega.eight.columns
= f.text_field :phone, { placeholder: t('.phone_placeholder') }
.row
.alpha.three.columns
= f.label :whatsapp_phone, t('.whatsapp_phone')
%div{'ofn-with-tip' => t('.whatsapp_phone_tip')}
%a= t('admin.whats_this')
.omega.eight.columns
= f.text_field :whatsapp_phone, { placeholder: t('.whatsapp_phone_placeholder') }
.row
.alpha.three.columns
= f.label :website, t('.website')

View File

@@ -20,10 +20,5 @@
= check_box_tag 'preferences[enable_receipt_printing?]', '1', Spree::Config[:enable_receipt_printing?]
= label_tag nil, t('.enable_receipt_printing?')
.field.align-center
= hidden_field_tag 'preferences[enterprise_number_required_on_invoices?]', '0'
= check_box_tag 'preferences[enterprise_number_required_on_invoices?]', '1', Spree::Config[:enterprise_number_required_on_invoices?]
= label_tag nil, t('.enterprise_number_required_on_invoices?')
.form-buttons{"data-hook" => "buttons"}
= button t(:update), 'icon-refresh'

View File

@@ -19,10 +19,6 @@
%tr.products
%td{ ng: { include: "'admin/panels/exchange_products_simple.html'" } }
%br
= label_tag t('.tags')
%tags-with-translation{ object: 'order_cycle.outgoing_exchanges[0]', form: 'order_cycle_form' }
%br/
= label_tag t('.fees')
= render 'coordinator_fees', f: f

View File

@@ -1,12 +1,8 @@
- 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))
.row
.alpha.two.columns= label_tag nil, t(:report_type)
.omega.fourteen.columns
= select_tag(:report_subtype, options_for_select(@report_subtypes, @report_subtype))
- if @report.header_option? || @report.summary_row_option?
.row
@@ -23,16 +19,10 @@
- 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_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)
.row.rendering-options
.alpha.two.columns

View File

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

View File

@@ -17,7 +17,9 @@
%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 }
%ul{style: "margin-left: 12pt"}
- report_subtypes.each do |report_subtype|
%li
- url = main_app.admin_report_url(report_type: report_type, report_subtype: report_subtype[1])
= link_to report_subtype[0], url

View File

@@ -14,6 +14,6 @@
= t(".using_default_terms_html", tos_link: link_to_platform_terms)
= form_for [main_app, :admin, @new_file] do |f|
= f.label :attachment, t(".attachment")
= f.label :attachment
= f.file_field :attachment
= f.submit t(".create_terms_of_service")
= f.submit

View File

@@ -1,7 +1,7 @@
- if Spree::Config.matomo_tag_manager_url.present?
:javascript
var _mtm = window._mtm = window._mtm || [];
var _mtm = _mtm || [];
_mtm.push({'mtm.startTime': (new Date().getTime()), 'event': 'mtm.Start'});
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
var u="#{Spree::Config.matomo_tag_manager_url}";

View File

@@ -14,7 +14,6 @@
= favicon_link_tag "/favicon-staging.ico"
%link{href: "https://fonts.googleapis.com/css?family=Roboto:400,300italic,400italic,300,700,700italic|Oswald:300,400,700", rel: "stylesheet", type: "text/css"}
%link{href: asset_pack_path("media/fonts/OFN-v2.woff"), rel: "preload", as: "font", crossorigin: "anonymous"}
= render "layouts/matomo_tag"
= language_meta_tags
= stylesheet_pack_tag "darkswarm", "data-turbo-track": "reload"
@@ -58,5 +57,6 @@
= inject_currency_config
= yield :injection_data
= render "layouts/matomo_tag"
= render "layouts/login_modal"

View File

@@ -38,11 +38,6 @@
= t :producers_contact_phone
%span{"ng-bind" => "::producer.phone"}
%p.word-wrap{"ng-if" => "::producer.whatsapp_phone"}
%a{"ng-href" => "{{::producer.whatsapp_url}}", target: "_blank"}
%img{ src: image_pack_path("social-logos/whatsapp.svg") }
%span{"ng-bind" => "::producer.whatsapp_phone"}
%p.word-wrap{"ng-if" => "::producer.email_address"}
%a{"ng-href" => "{{::producer.email_address | stripUrl}}", target: "_blank", mailto: true}
%span.obfuscatedEmail.email{"ng-bind" => "::producer.email_address | stripUrl"}

View File

@@ -24,10 +24,6 @@
.small-12.columns.field
%label{ for: 'enterprise_phone' }= t(".phone_field")+":"
%input.chunky.small-12.columns{ id: 'enterprise_phone', name: 'phone', placeholder: "{{'registration.steps.contact.phone_field_placeholder' | t}}", ng: { model: 'enterprise.phone' } }
.row
.small-12.columns.field
%label{ "for" => 'enterprise_whatsapp_phone', 'data-toggle' => "tooltip", 'title' => "{{'registration.steps.contact.whatsapp_phone_tooltip' | t}}" }= t(".whatsapp_phone_field")+":"
%input.chunky.small-12.columns{ id: 'enterprise_whatsapp_phone', name: 'whatsapp_phone', placeholder: "{{'registration.steps.contact.whatsapp_phone_field_placeholder' | t}}", ng: { model: 'enterprise.whatsapp_phone' } }
.small-12.medium-12.large-5.hide-for-small-only
.row.buttons

View File

@@ -18,7 +18,7 @@
= current_distributor.address.zipcode
.small-12.large-4.columns
- if current_distributor.website || current_distributor.email_address || current_distributor.phone || current_distributor.whatsapp_phone
- if current_distributor.website || current_distributor.email_address || current_distributor.phone
%div.center
.header
= t :shopping_contact_web
@@ -26,11 +26,6 @@
- if current_distributor.phone.present?
= current_distributor.phone
%br
- if current_distributor.whatsapp_phone.present?
%a{href: current_distributor.whatsapp_url, target: "_blank" }
%img{ src: image_pack_path("social-logos/whatsapp.svg") }
= current_distributor.whatsapp_phone
%br
- if current_distributor.website.present?
%a{href: "http://#{current_distributor.website}", target: "_blank" }
= current_distributor.website

View File

@@ -6,8 +6,6 @@
= render 'spree/admin/orders/insufficient_stock_lines', insufficient_stock_lines: @order.insufficient_stock_lines
= render :partial => "spree/admin/orders/shipment", :collection => @order.shipments, :locals => { :order => order }
- if order.line_items.exists?
= render partial: "spree/admin/orders/note", locals: { order: @order }
= render :partial => "spree/admin/orders/_form/adjustments", :locals => { :adjustments => @order.line_item_adjustments, :title => t(".line_item_adjustments")}
= render :partial => "spree/admin/orders/_form/adjustments", :locals => { :adjustments => order_adjustments_for_display(@order), :title => t(".order_adjustments")}

View File

@@ -1,26 +0,0 @@
%table.index.edit-note-table
%tr.edit-note.hidden.total
%td{ colspan: "5", data: { controller: "input-char-count" }, style: "position: relative;" }
%label
= t(".note_label")
= text_field_tag :note, @order.note, { maxLength: 280, data: { "input-char-count-target": "input" } }
%span.edit-note-count{ data: { "input-char-count-target": "count" }, style: "position: absolute; right: 7px; top: 7px; font-size: 11px;" }
%td.actions
= link_to '', '', class: 'save-note icon_link icon-ok no-text with-tip', data: { action: 'save' }, title: I18n.t('actions.save')
= link_to '', '', class: 'cancel-note icon_link icon-cancel no-text with-tip', data: { action: 'cancel' }, title: I18n.t('actions.cancel')
%tr.show-note.total
%td{ :colspan => "5" }
- if order.note.present?
%strong
= t(".note_label")
= order.note
- else
= t(".no_note_present")
%td.actions
= link_to '', '', class: 'edit-note icon_link icon-edit no-text with-tip', data: { action: 'edit' }, title: Spree.t('edit')
- if @order.note.present?
= link_to '', '', class: 'delete-note icon_link icon-trash no-text with-tip', data: { action: 'remove' }, title: Spree.t('delete')

View File

@@ -1,5 +1,4 @@
- position ||= ""
.per-page{'ng-show' => '!RequestMonitor.loading && orders.length > 0', class: ("right" if position == "right") }
.per-page{'ng-show' => '!RequestMonitor.loading && orders.length > 0'}
%input.per-page-select.ofn-select2{type: 'number', data: 'per_page_options', 'min-search' => 999, 'ng-model' => 'per_page', 'ng-change' => 'fetchResults()'}
%span.per-page-feedback

View File

@@ -40,6 +40,18 @@
= label_tag 'selected_shipping_rate_id', Spree.t(:shipping_method)
= select_tag :selected_shipping_rate_id, options_for_select(shipment.shipping_rates.backend.map { |sr| ["#{sr.name} #{sr.display_price}", sr.id] }, shipment.selected_shipping_rate_id), { :class => 'select2 fullwidth', :data => { 'shipment-number' => shipment.number } }
- if shipment.fee_adjustment&.closed?
%div.field.omega.four.columns
%label
= Spree.t(:associated_adjustment_closed)
%ul
%li
= radio_button_tag :open_adjustment, 'yes', false, :data => { 'shipment-number' => shipment.number }
= "Yes"
%li
= radio_button_tag :open_adjustment, 'no', true, :data => {'shipment-number' => shipment.number }
= "No"
%td.actions
- if can? :update, shipment
= link_to '', '', :class => 'save-method icon_link icon-ok no-text with-tip', :data => { 'shipment-number' => shipment.number, :action => 'save' }, title: I18n.t('actions.save')
@@ -85,5 +97,3 @@
%td.actions
- if can?(:update, shipment) && shipment.can_modify?
= link_to '', '', :class => 'edit-tracking icon_link icon-edit no-text with-tip', :data => { :action => 'edit' }, :title => Spree.t('edit')
- if shipment.tracking.present?
= link_to '', '', :class => 'delete-tracking icon_link icon-trash no-text with-tip', :data => { 'shipment-number' => shipment.number, :action => 'remove' }, :title => Spree.t('delete')

View File

@@ -0,0 +1,19 @@
<script type='text/template' id='customer_autocomplete_template'>
<div class='customer-autocomplete-item'>
<div class='customer-details'>
<h5>{{customer.email}}</h5>
{{#if bill_address.firstname }}
<strong>{{t 'bill_address' }}</strong>
{{bill_address.firstname}} {{bill_address.lastname}}<br>
{{bill_address.address1}}, {{bill_address.address2}}<br>
{{bill_address.city}}<br>
{{#if bill_address.state_id }}
{{bill_address.state.name}}
{{else}}
{{bill_address.state_name}}
{{/if}}
{{bill_address.country.name}}
{{/if}}
</div>
</div>
</script>

View File

@@ -17,8 +17,8 @@
%legend{:align => "center"}= Spree.t(:customer_search)
- content_for :main_ng_app_name do
= "admin.orders"
%label{for: "customer_search_override"}= Spree.t(:choose_a_customer)
%select{name: "customer_search_override", "data-controller": "select-customer", "data-select-customer-distributor-value": @order.distributor_id, class: "primary", placeholder: Spree.t(:choose_a_customer) }
= hidden_field_tag :customer_search_override, nil, distributor_id: @order.distributor_id, :class => 'fullwidth title customer-search-override'
= render :partial => "spree/admin/orders/customer_details/autocomplete", :formats => :js
= render :partial => 'spree/shared/error_messages', :locals => { :target => @order }

View File

@@ -20,22 +20,11 @@
= render partial: 'filters'
.row.index-controls{'ng-show' => '!RequestMonitor.loading && orders.length > 0'}
%div{style: "display: flex; justify-content: space-between;"}
- if Spree::Config[:enable_invoices?]
.ofn-drop-down-with-prepend
.ofn-drop-down-prepend{"ng-class": "selected_orders.length == 0 ? 'disabled' : ''"}
{{ "spree.admin.orders.index.selected" | t:{count: selected_orders.length} }}
.ofn-drop-down{"ng-class": "selected_orders.length == 0 ? 'disabled' : ''"}
%span{ :class => 'icon-reorder' }
="#{t('admin.actions')}".html_safe
%span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" }
%div.menu{ 'ng-show' => "expanded" }
%div.menu_item
%span.name.invoices-modal{'ng-controller' => 'bulkInvoiceCtrl', 'ng-click' => 'createBulkInvoice()' }
= t('.print_invoices')
= render partial: 'per_page_controls'
= render partial: 'per_page_controls', locals: { position: "right" }
- if Spree::Config[:enable_invoices?]
%button.invoices-modal{'ng-controller' => 'bulkInvoiceCtrl', 'ng-click' => 'createBulkInvoice()', 'ng-disabled' => 'selected_orders.length == 0'}
= t('.print_invoices')
%table#listing_orders.index.responsive{width: "100%", 'ng-init' => 'initialise()', 'ng-show' => "!RequestMonitor.loading && orders.length > 0" }
%colgroup

View File

@@ -8,7 +8,7 @@
= t :tax_invoice
- if @order.distributor.display_invoice_logo? && @order.distributor.logo.variable?
%td{ :align => "right", rowspan: 2 }
= wicked_pdf_image_tag @order.distributor.logo_url(:small)
= wicked_pdf_image_tag @order.distributor.logo.variant(resize_to_limit: [150, 150])
%tr{ valign: "top" }
%td{ :align => "left" }
- if @order.distributor.business_address.blank?

View File

@@ -9,7 +9,7 @@
\#
= @order.number
= render 'spree/admin/shared/order_tabs', :current => 'Customer Details'
= render 'spree/admin/shared/order_tabs', :current => 'Order Details'
= csrf_meta_tags
@@ -21,7 +21,6 @@
= render 'spree/admin/orders/_form/distribution_fields'
-# This param passed to stop validation error in next page due to no line items in order yet:
= hidden_field_tag 'suppress_error_msg', "true"
= hidden_field_tag "set_distribution_step", "true"
= button_tag :class => 'secondary radius expand small', :id => 'update-button' do
%i.icon-arrow-right
= t(:next)

View File

@@ -1,4 +1,4 @@
.six.columns.omega{ "ng-if" => "product.variant_unit_with_scale != 'items'" }
= f.field_container :display_as do
= f.label :product_display_as, t('.display_as')
%input#product_display_as.fullwidth{name: "product[display_as]", placeholder: "{{ placeholder_text }}", type: "text", value: @product.master.display_as}
%input#product_display_as.fullwidth{name: "product[display_as]", placeholder: "{{ placeholder_text }}", type: "text"}

View File

@@ -11,7 +11,7 @@
= 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.collection_select(:supplier_id, @producers, :id, :name, {:include_blank => true, :selected => select_only_item(@producers)}, {:class => "select2 fullwidth"})
= f.error_message_on :supplier
.eight.columns.omega
= f.field_container :name do
@@ -25,17 +25,17 @@
= f.field_container :units 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.select2.fullwidth{ 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' }
%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]' }
%input{ type: 'hidden', 'ng-value' => 'product.variant_unit', name: 'product[variant_unit]' }
%input{ type: 'hidden', 'ng-value' => 'product.variant_unit_scale', name: 'product[variant_unit_scale]' }
.two.columns
= f.field_container :unit_value do
= f.label :unit_value_with_description, t(".value"), 'ng-disabled' => "!hasUnit(product)"
%span.required *
%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]' }
%input{ type: 'hidden', 'ng-value' => 'product.master.unit_value', name: 'product[unit_value]' }
%input{ type: 'hidden', 'ng-value' => 'product.master.unit_description', name: 'product[unit_description]' }
= render 'display_as', f: f
.six.columns.omega{ 'ng-show' => "product.variant_unit_with_scale == 'items'" }
= f.field_container :unit_name do
@@ -50,7 +50,7 @@
= f.label :price, t(".price")
%span.required *
%br/
= f.text_field :price, { "class": "fullwidth", "ng-model": "product.price", "ng-value": "'#{@product.price}'" }
= f.text_field :price, { "class" => "fullwidth", "ng-model" => "product.price" }
= f.error_message_on :price
.four.columns{ ng: { app: 'ofn.admin'}}
= f.field_container :unit_price do
@@ -77,20 +77,20 @@
= f.field_container :on_hand do
= f.label :on_hand, t(".on_hand")
%br/
= f.text_field :on_hand, class: 'fullwidth', value: @on_hand
= f.text_field :on_hand, class: 'fullwidth'
= f.error_message_on :on_hand
.three.columns.omega
= f.field_container :on_demand do
= f.label :on_demand, t(".on_demand")
%br/
= f.check_box :on_demand, value: '1', checked: @on_demand == '1'
= f.check_box :on_demand
= f.error_message_on :on_demand
.sixteen.columns.alpha
= f.field_container :description do
= f.label :product_description, t(".product_description")
%br/
%text-angular{'id' => 'product_description', 'name' => 'product[description]', 'class' => 'text-angular', "textangular-links-target-blank" => true, 'ta-toolbar' => "[['bold','italics','underline','clear'],['insertLink']]", "ng-model": "product.description"}
%text-angular{'id' => 'product_description', 'name' => 'product[description]', 'class' => 'text-angular', "textangular-links-target-blank" => true, 'ta-toolbar' => "[['bold','italics','underline','clear'],['insertLink']]"}
= sanitize(@product.description)
= f.error_message_on :description
.four.columns.omega{ style: "text-align: center" }

View File

@@ -1,5 +1,5 @@
%fieldset#calculator_fields.no-border-bottom
%legend{align: "center"}= t(:fees)
%legend{align: "center"}= t(:calculator)
#preference-settings
.row
.alpha.four.columns

View File

@@ -44,22 +44,22 @@
%nav.menu
%ul
- customer_details_classes = "active" if current == "Customer Details"
%li{ class: customer_details_classes }
= link_to_with_icon 'icon-user', t(:customer_details), spree.admin_order_customer_url(@order)
- order_details_classes = "active" if current == "Order Details"
%li{ class: order_details_classes }
= link_to_with_icon 'icon-edit', t(:order_details), spree.edit_admin_order_url(@order)
- payments_classes = "active" if current == "Payments"
%li{ class: payments_classes }
= link_to_with_icon 'icon-credit-card', t(:payments), spree.admin_order_payments_url(@order)
- customer_details_classes = "active" if current == "Customer Details"
%li{ class: customer_details_classes }
= link_to_with_icon 'icon-user', t(:customer_details), spree.admin_order_customer_url(@order)
- adjustments_classes = "active" if current == "Adjustments"
%li{ class: adjustments_classes }
= link_to_with_icon 'icon-cogs', t(:adjustments), spree.admin_order_adjustments_url(@order)
- payments_classes = "active" if current == "Payments"
%li{ class: payments_classes }
= link_to_with_icon 'icon-credit-card', t(:payments), spree.admin_order_payments_url(@order)
- if @order.completed?
- authorizations_classes = "active" if current == "Return Authorizations"
%li{ class: authorizations_classes }

View File

@@ -27,7 +27,7 @@
-# The 'Category' label here is just a logical descriptor for the data we are trying to collect for 'requires_ship_address'
-# and does not relate to shipping categories in any way.
= f.label :require_ship_address, t(:category)
.three.columns
.two.columns
= f.radio_button :require_ship_address, true
&nbsp;
= f.label :delivery, t(:delivery)

View File

@@ -18,13 +18,9 @@
.omega.five.columns
= f.field_container :password do
= f.label :password, t(".password")
= f.password_field :password, class: "fullwidth", autocomplete: "new-password"
= f.password_field :password, class: "fullwidth"
= f.error_message_on :password
= f.field_container :password do
= f.label :password_confirmation, t(".confirm_password")
= f.password_field :password_confirmation, class: "fullwidth"
= f.error_message_on :password_confirmation
= f.field_container :disabled do
= f.label :disabled, t(".disabled")
= f.check_box :disabled
= f.error_message_on :disabled
= f.error_message_on :password_confirmation

View File

@@ -10,7 +10,7 @@
= t(:order_back_to_store)
.columns.small-12.medium-6
- if @order.distributor.website.present?
= link_to_service "https://", @order.distributor.website, class: "button expand" do
= link_to_service "https://", current_order.distributor.website, class: "button expand" do
= t(:order_back_to_website)
- else
&nbsp;

View File

@@ -1 +1,6 @@
= image_tag(variant.product.images.first&.url(:mini) || "/noimage/mini.png")
- if variant.product.images.length == 0
= image_tag("/noimage/mini.png")
- else
- # A Rails bug makes it necessary to call `main_app.url_for` here.
- # https://github.com/rails/rails/issues/31325
= image_tag(main_app.url_for(variant.product.images.first.variant(:mini)))

View File

@@ -14,7 +14,7 @@
= item.variant.options_text
%br
- if @shipment.tracking.present?
- if @shipment.tracking
%p.lead
= t('.track_information', tracking: @shipment.tracking)

View File

@@ -11,7 +11,8 @@
%th.order7.show-for-large-up.text-right= t('.cancel')
%tbody.transaction-group{"ng-repeat" => "order in Orders.changeable", "ng-class-odd"=>"'odd'", "ng-class-even"=>"'even'"}
%tr.order-row
%td.order1{"ng-bind" => "::order.number"}
%td.order1
%a{"ng-href" => "{{::order.path}}", "ng-bind" => "::order.number"}
%td.order2
%a{"ng-href" => "{{::Orders.shopsByID[order.shop_id].hash}}#{main_app.shop_path}", "ng-bind" => "::Orders.shopsByID[order.shop_id].name"}
%td.order3.show-for-large-up{"ng-bind" => "::order.changes_allowed_until"}

View File

@@ -8,16 +8,16 @@
%th.order4.show-for-large-up= t('.items')
%th.order5.text-right= t('.total')
%th.order6.text-right.show-for-large-up= t('.paid?')
%th.order7.text-right= t('.status')
%th.order7.text-right= t('.view')
%tbody.transaction-group{"ng-repeat" => "order in Orders.all | filter:{changes_allowed:false} as pastOrders", "ng-class-odd"=>"'odd'", "ng-class-even"=>"'even'"}
%tr.order-row
%td.order1{"ng-bind" => "::order.number"}
%td.order1
%a{"ng-href" => "{{::order.path}}", "ng-bind" => "::order.number"}
%td.order2
%a{"ng-href" => "{{::Orders.shopsByID[order.shop_id].hash}}#{main_app.shop_path}", "ng-bind" => "::Orders.shopsByID[order.shop_id].name"}
%td.order3.show-for-large-up{"ng-bind" => "::order.completed_at"}
%td.order4.show-for-large-up{"ng-bind" => "::order.item_count"}
%td.order5.text-right{"ng-class" => "{'debit': order.payment_state != 'paid', 'credit': order.payment_state == 'paid'}","ng-bind" => "::order.total | localizeCurrency"}
%td.order6.text-right.show-for-large-up{"ng-class" => "{'debit': order.payment_state != 'paid', 'credit': order.payment_state == 'paid'}", "ng-bind" => "::(order.payment_state == 'paid' ? 'say_yes' : 'say_no') | t"}
%td.order7.text-right{ "ng-switch" => "::order.state" }
%a{ "ng-switch-when" => "complete", "ng-href" => "{{::order.path}}" }= t('.completed')
%span{ "ng-switch-when" => "canceled" }= t('.cancelled')
%td.order7.text-right
%a{"ng-href" => "{{::order.path}}" }= t('.view')

View File

@@ -12,7 +12,7 @@
%tr
%td{:align => "right"}
- if @shop.logo.variable?
= image_tag @shop.logo_url(:medium), class: "float-right"
= image_tag @shop.logo_variant(:medium), class: "float-right"
%span.clear
= render 'summary_overview', summary: @summary

View File

@@ -1,21 +0,0 @@
import { Controller } from "stimulus";
export default class extends Controller {
static targets = ["count", "input"];
connect() {
this.inputTarget.addEventListener("keyup", this.countCharacters.bind(this));
this.countCharacters();
}
countCharacters() {
this.displayCount(
this.inputTarget.value.length,
this.inputTarget.maxLength
);
}
displayCount(count, max) {
this.countTarget.textContent = `${count}/${max}`;
}
}

View File

@@ -1,50 +0,0 @@
export const useRenderCustomer = (controller) => {
Object.assign(controller, {
renderOption(item, escape) {
if (!item.bill_address) {
return this.renderWithNoBillAddress(item, escape);
}
return `<div class='customer-autocomplete-item'>
<div class='customer-details'>
<h5>${escape(item.email)}</h5>
${
item.bill_address.firstname
? `<strong>${I18n.t("bill_address")}</strong>
${item.bill_address.firstname} ${
item.bill_address.lastname
}<br>
${item.bill_address.address1}, ${
item.bill_address.address2
}<br>
${item.bill_address.city}
<br>
${
item.bill_address.state_id &&
item.bill_address.state &&
item.bill_address.state.name
? item.bill_address.state.name
: item.bill_address.state_name
}
${
item.bill_address.country &&
item.bill_address.country.name
? item.bill_address.country.name
: item.bill_address.country_name
}
`
: ""
}
</div>
</div>`;
},
renderWithNoBillAddress(item, escape) {
return `<div class='customer-autocomplete-item'>
<div class='customer-details'><h5>${escape(
item.email
)}</h5></div>
</div>`;
},
});
};

View File

@@ -1,22 +0,0 @@
export const useSearchCustomer = (controller) => {
Object.assign(controller, {
load: function (query, callback) {
var params = {
q: query,
distributor_id: this.distributorValue,
};
fetch("/admin/search/customers.json?" + new URLSearchParams(params))
.then((response) => response.json())
.then((json) => {
this.items = json;
callback(json);
})
.catch((error) => {
this.items = [];
console.log(error);
callback();
});
},
});
};

View File

@@ -1,66 +0,0 @@
import TomSelectController from "./tom_select_controller";
import { useSearchCustomer } from "./mixins/useSearchCustomer";
import { useRenderCustomer } from "./mixins/useRenderCustomer";
export default class extends TomSelectController {
static values = { options: Object, distributor: Number };
connect() {
useSearchCustomer(this);
useRenderCustomer(this);
const options = {
valueField: "id",
labelField: "email",
searchField: ["email", "full_name", "last_name"],
load: this.load.bind(this),
shouldLoad: (query) => query.length > 2,
render: {
option: this.renderOption.bind(this),
},
};
super.connect(options);
this.control.on("item_add", this.onItemSelect.bind(this));
this.items = [];
}
onItemSelect(id, item) {
const customer = this.items.find((item) => item.id == id);
["bill_address", "ship_address"].forEach((address) => {
const data = customer[address];
const address_parts = [
"firstname",
"lastname",
"address1",
"address2",
"city",
"zipcode",
"phone",
];
const attribute_wrapper = "#order_" + address + "_attributes_";
address_parts.forEach((part) => {
document.querySelector(attribute_wrapper + part).value = data
? data[part]
: "";
});
this.setValueOnTomSelectController(
document.querySelector(attribute_wrapper + "state_id"),
data ? data.state_id : ""
);
this.setValueOnTomSelectController(
document.querySelector(attribute_wrapper + "country_id"),
data ? data.country_id : ""
);
});
$("#order_email").val(customer.email);
$("#user_id").val(customer.user_id);
}
setValueOnTomSelectController = (element, value) => {
if (!value) {
return;
}
this.application
.getControllerForElementAndIdentifier(element, "tom-select")
.control.setValue(value, true);
};
}

View File

@@ -1,24 +1,22 @@
import { Controller } from "stimulus";
import TomSelect from "tom-select";
import { Controller } from "stimulus"
import TomSelect from "tom-select"
export default class extends Controller {
static values = { options: Object };
static values = { options: Object }
static defaults = {
maxItems: 1,
maxOptions: null,
plugins: ["dropdown_input"],
allowEmptyOption: true,
};
allowEmptyOption: true
}
connect(options = {}) {
this.control = new TomSelect(this.element, {
...this.constructor.defaults,
...this.optionsValue,
...options,
});
connect() {
this.control = new TomSelect(
this.element, { ...this.constructor.defaults, ...this.optionsValue }
)
}
disconnect() {
if (this.control) this.control.destroy();
if (this.control) this.control.destroy()
}
}

View File

@@ -1,17 +1,6 @@
.per-page {
float: left;
&.right {
display: flex;
flex-direction: row-reverse;
align-items: center;
.per-page-feedback {
margin-right: 1em;
margin-left: 0;
}
}
.per-page-feedback {
margin-left: 1em;
}

View File

@@ -11,12 +11,14 @@
color: #575757;
}
@mixin ofn-drop-down-style {
.ofn-drop-down {
padding: 7px 15px;
border-radius: 3px;
border: 1px solid #d4d4d4;
background-color: #f5f5f5;
position: relative;
display: block;
float: left;
color: #828282;
cursor: pointer;
-moz-user-select: none;
@@ -27,47 +29,6 @@
text-align: center;
margin-right: 10px;
&.disabled {
opacity: 0.5;
&:hover {
cursor: default;
border-color: #d4d4d4;
color: #828282;
}
}
}
.ofn-drop-down-with-prepend {
display: flex;
&.right {
float: right;
}
.ofn-drop-down {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.ofn-drop-down-prepend {
@include ofn-drop-down-style;
border-right: none;
margin-left: 0;
margin-right: 0;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
cursor: default;
}
}
.ofn-drop-down {
@include ofn-drop-down-style;
position: relative;
float: left;
&.right {
float: right;
margin-right: 0px;

View File

@@ -82,12 +82,6 @@ div#group_buy_calculation {
}
}
// Changing placeholder text colour
.items-placeholder::placeholder {
color: $white;
opacity: 1;
}
th.actions {
white-space: nowrap;
}
@@ -96,18 +90,6 @@ table.index td.actions {
text-align: left;
}
table.edit-note-table {
margin-top: -15px;
tr:first-child th, tr:first-child td {
border-top: none;
}
td.actions {
width: 15%;
}
}
.index-controls {
button {

View File

@@ -1,2 +0,0 @@
<!--https://icon-sets.iconify.design/fa/whatsapp/-->
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" width="0.96em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 1536 1600"><path fill="currentColor" d="M985 878q13 0 97.5 44t89.5 53q2 5 2 15q0 33-17 76q-16 39-71 65.5T984 1158q-57 0-190-62q-98-45-170-118T476 793q-72-107-71-194v-8q3-91 74-158q24-22 52-22q6 0 18 1.5t19 1.5q19 0 26.5 6.5T610 448q8 20 33 88t25 75q0 21-34.5 57.5T599 715q0 7 5 15q34 73 102 137q56 53 151 101q12 7 22 7q15 0 54-48.5t52-48.5zm-203 530q127 0 243.5-50t200.5-134t134-200.5t50-243.5t-50-243.5T1226 336t-200.5-134T782 152t-243.5 50T338 336T204 536.5T154 780q0 203 120 368l-79 233l242-77q158 104 345 104zm0-1382q153 0 292.5 60T1315 247t161 240.5t60 292.5t-60 292.5t-161 240.5t-240.5 161t-292.5 60q-195 0-365-94L0 1574l136-405Q28 991 28 780q0-153 60-292.5T249 247T489.5 86T782 26z"/></svg>

Before

Width:  |  Height:  |  Size: 897 B

View File

@@ -1,5 +1,9 @@
#!/usr/bin/env ruby
load File.expand_path("spring", __dir__)
begin
load File.expand_path('../spring', __FILE__)
rescue LoadError => e
raise unless e.message.include?('spring')
end
APP_PATH = File.expand_path('../config/application', __dir__)
require_relative '../config/boot'
require 'rails/commands'

View File

@@ -1,5 +1,9 @@
#!/usr/bin/env ruby
load File.expand_path("spring", __dir__)
begin
load File.expand_path('../spring', __FILE__)
rescue LoadError => e
raise unless e.message.include?('spring')
end
require_relative '../config/boot'
require 'rake'
Rake.application.run

View File

@@ -1,4 +1,8 @@
#!/usr/bin/env ruby
load File.expand_path("spring", __dir__)
begin
load File.expand_path('../spring', __FILE__)
rescue LoadError => e
raise unless e.message.include?('spring')
end
require 'bundler/setup'
load Gem.bin_path('rspec-core', 'rspec')

View File

@@ -1,14 +1,17 @@
#!/usr/bin/env ruby
# This file loads Spring without using loading other gems in the Gemfile, in order to be fast.
# This file loads Spring without using Bundler, in order to be fast.
# It gets overwritten when you run the `spring binstub` command.
if !defined?(Spring) && [nil, "development", "test"].include?(ENV["RAILS_ENV"])
require "bundler"
unless defined?(Spring)
require 'rubygems'
require 'bundler'
Bundler.locked_gems.specs.find { |spec| spec.name == "spring" }&.tap do |spring|
lockfile = Bundler::LockfileParser.new(Bundler.default_lockfile.read)
spring = lockfile.specs.detect { |spec| spec.name == 'spring' }
if spring
Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path
gem "spring", spring.version
require "spring/binstub"
gem 'spring', spring.version
require 'spring/binstub'
end
end

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