mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-14 18:56:49 +00:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b17d3e447c | ||
|
|
2ae4234015 | ||
|
|
20874dec98 | ||
|
|
288cd367bc | ||
|
|
68902021ab | ||
|
|
7f9c578fca | ||
|
|
782c9150a2 | ||
|
|
447b040020 |
@@ -5,17 +5,9 @@
|
||||
#
|
||||
# cp .env.development .env.local
|
||||
|
||||
VERBOSE_QUERY_LOGS=true
|
||||
|
||||
SECRET_TOKEN="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
|
||||
OFN_REDIS_URL="redis://localhost:6379/1"
|
||||
OFN_REDIS_JOBS_URL="redis://localhost:6379/2"
|
||||
|
||||
SITE_URL="0.0.0.0:3000"
|
||||
|
||||
# Deactivate rack-timeout in development.
|
||||
# https://github.com/zombocom/rack-timeout#configuring
|
||||
RACK_TIMEOUT_SERVICE_TIMEOUT="0"
|
||||
RACK_TIMEOUT_WAIT_TIMEOUT="0"
|
||||
RACK_TIMEOUT_WAIT_OVERTIME="0"
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/release.md
vendored
2
.github/ISSUE_TEMPLATE/release.md
vendored
@@ -40,7 +40,7 @@ The full process is described at https://github.com/openfoodfoundation/openfoodn
|
||||
|
||||
[Ready To Go]: #zenhub
|
||||
[Transifex pull request]: https://github.com/openfoodfoundation/openfoodnetwork/pulls?utf8=%E2%9C%93&q=is%3Apr+is%3Aopen+head%3Atransifex
|
||||
[Draft new release]: https://github.com/openfoodfoundation/openfoodnetwork/releases/new?tag=v&title=v+Code+Name&body=Congrats%0A%0ADescription%0A%0A%23%23+User+facing+changes+:eyes:%0A%0A%0A%23%23%23+Experimental+features+for+testing+:sunglasses:%0A%0A%0A%23%23+Technical+changes+:wrench:%0A%0A
|
||||
[Draft new release]: https://github.com/openfoodfoundation/openfoodnetwork/releases/new?tag=v&title=v+Code+Name&body=Congrats%0A%0ADescription%0A%0A%23%23+User+facing+changes+:eyes:%0A%0A%0A%0A%23%23+Technical+changes+:wrench:%0A%0A
|
||||
[releases]: https://github.com/openfoodfoundation/openfoodnetwork/releases
|
||||
[#instance-managers]: https://app.slack.com/client/T02G54U79/CG7NJ966B
|
||||
[#testing]: https://openfoodnetwork.slack.com/app_redirect?channel=C02TZ6X00
|
||||
|
||||
1
.github/workflows/brakeman-analysis.yml
vendored
1
.github/workflows/brakeman-analysis.yml
vendored
@@ -41,7 +41,6 @@ jobs:
|
||||
- name: Scan
|
||||
continue-on-error: true
|
||||
run: |
|
||||
git show --no-patch # the commit being tested (which is often a merge due to actions/checkout@v3)
|
||||
brakeman -f sarif -o output.sarif.json .
|
||||
|
||||
# Upload the SARIF file generated in the previous step
|
||||
|
||||
17
.github/workflows/build.yml
vendored
17
.github/workflows/build.yml
vendored
@@ -18,7 +18,7 @@ permissions:
|
||||
|
||||
jobs:
|
||||
knapsack_rspec_controllers:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-20.04
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:10
|
||||
@@ -68,6 +68,7 @@ jobs:
|
||||
bundle exec rake db:schema:load
|
||||
|
||||
- name: Run tests
|
||||
|
||||
env:
|
||||
KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC: 864ef557d85ea8e603e086c0387d5154
|
||||
KNAPSACK_PRO_CI_NODE_TOTAL: ${{ matrix.ci_node_total }}
|
||||
@@ -81,12 +82,12 @@ jobs:
|
||||
# https://knapsackpro.com/faq/question/how-to-split-slow-rspec-test-files-by-test-examples-by-individual-it
|
||||
#KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES: true
|
||||
KNAPSACK_PRO_TEST_FILE_PATTERN: "{spec/controllers/**/*_spec.rb}"
|
||||
|
||||
run: |
|
||||
git show --no-patch # the commit being tested (which is often a merge due to actions/checkout@v3)
|
||||
bundle exec rake knapsack_pro:rspec
|
||||
|
||||
knapsack_rspec_models:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-20.04
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:10
|
||||
@@ -155,7 +156,7 @@ jobs:
|
||||
bundle exec rake knapsack_pro:rspec
|
||||
|
||||
knapsack_rspec_system_admin:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-20.04
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:10
|
||||
@@ -233,7 +234,7 @@ jobs:
|
||||
if-no-files-found: ignore
|
||||
|
||||
knapsack_rspec_system_consumer:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-20.04
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:10
|
||||
@@ -311,7 +312,7 @@ jobs:
|
||||
if-no-files-found: ignore
|
||||
|
||||
knapsack_rspec_engines:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-20.04
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:10
|
||||
@@ -389,7 +390,7 @@ jobs:
|
||||
if-no-files-found: ignore
|
||||
|
||||
knapsack_rspec_test_the_rest:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-20.04
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:10
|
||||
@@ -459,7 +460,7 @@ jobs:
|
||||
bundle exec rake knapsack_pro:rspec
|
||||
|
||||
non_knapsack_jest_karma:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-20.04
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:10
|
||||
|
||||
6
.github/workflows/linters.yml
vendored
6
.github/workflows/linters.yml
vendored
@@ -9,11 +9,7 @@ jobs:
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v1
|
||||
|
||||
- uses: ruby/setup-ruby@v1
|
||||
|
||||
- run: git show --no-patch # the commit being tested (which is often a merge due to actions/checkout@v3)
|
||||
|
||||
- name: rubocop
|
||||
uses: reviewdog/action-rubocop@v2
|
||||
with:
|
||||
@@ -36,8 +32,6 @@ jobs:
|
||||
- name: Install JS dependencies
|
||||
run: yarn install --frozen-lockfile
|
||||
|
||||
- run: git show --no-patch # the commit being tested (which is often a merge due to actions/checkout@v3)
|
||||
|
||||
- name: prettier
|
||||
uses: EPMatt/reviewdog-action-prettier@v1
|
||||
with:
|
||||
|
||||
62
.github/workflows/stage.yml
vendored
62
.github/workflows/stage.yml
vendored
@@ -1,62 +0,0 @@
|
||||
name: "Deploy to Staging"
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [labeled]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
server:
|
||||
description: "Staging Server"
|
||||
type: choice
|
||||
required: true
|
||||
options:
|
||||
- staging.openfoodnetwork.org.uk
|
||||
- staging.openfoodnetwork.org.au
|
||||
- staging.coopcircuits.fr
|
||||
|
||||
jobs:
|
||||
deploy_pr:
|
||||
if: contains(fromJSON('["pr-staged-uk", "pr-staged-au", "pr-staged-fr"]'), github.event.label.name)
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: "Check user has write access"
|
||||
uses: "lannonbr/repo-permission-check-action@2.0.2"
|
||||
with:
|
||||
permission: "write"
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Configure deployment key
|
||||
if: success()
|
||||
run: |
|
||||
install -m 600 -D /dev/null ~/.ssh/id_rsa
|
||||
echo "${{ secrets.DEPLOYMENT_KEY }}" > ~/.ssh/id_rsa
|
||||
echo "${{ secrets.DEPLOYMENT_HOSTS }}" > ~/.ssh/known_hosts
|
||||
|
||||
- name: Deploy to Staging
|
||||
if: success()
|
||||
run: |
|
||||
ssh ofn-deploy@${{ github.event.label.description }} -o LogLevel=ERROR "pull-request-${{ github.event.pull_request.number }} ."
|
||||
|
||||
deploy_branch:
|
||||
if: ${{ inputs.server }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: "Check user has write access"
|
||||
uses: "lannonbr/repo-permission-check-action@2.0.2"
|
||||
with:
|
||||
permission: "write"
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Configure deployment key
|
||||
if: success()
|
||||
run: |
|
||||
install -m 600 -D /dev/null ~/.ssh/id_rsa
|
||||
echo "${{ secrets.DEPLOYMENT_KEY }}" > ~/.ssh/id_rsa
|
||||
echo "${{ secrets.DEPLOYMENT_HOSTS }}" > ~/.ssh/known_hosts
|
||||
|
||||
- name: Deploy to Staging
|
||||
if: success()
|
||||
run: |
|
||||
ssh ofn-deploy@${{ inputs.server }} -o LogLevel=ERROR "$GITHUB_REF_NAME $GITHUB_SHA"
|
||||
@@ -1 +1 @@
|
||||
17.9.1
|
||||
14.21.2
|
||||
|
||||
@@ -1,26 +1,17 @@
|
||||
# Ignore a lot of things, but we should enable where it can be helpful.
|
||||
|
||||
# Basically, ignore everythings expect app/webpacker/controllers/*.js and app/webpacker/packs/*.js
|
||||
*.css
|
||||
*.scss
|
||||
# Except v2
|
||||
!/app/webpacker/css/admin/v2/**/*.scss
|
||||
*.md
|
||||
*.yml
|
||||
*.yaml
|
||||
*.json
|
||||
*.html
|
||||
|
||||
# JS
|
||||
# Enabled: app/webpacker/controllers/*.js and app/webpacker/packs/*.js
|
||||
babel.config.js
|
||||
postcss.config.js
|
||||
|
||||
# SCSS
|
||||
# Enabled: most of admin
|
||||
/app/webpacker/css/admin/globals/
|
||||
/app/webpacker/css/admin/shared/
|
||||
/app/webpacker/css/admin_v3/globals/variables.scss
|
||||
/app/webpacker/css/darkswarm/
|
||||
/app/webpacker/css/mail/
|
||||
/app/webpacker/css/shared/
|
||||
|
||||
# More
|
||||
/app/assets/
|
||||
/config/
|
||||
/coverage/
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
{
|
||||
"printWidth": 100
|
||||
}
|
||||
{}
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
#
|
||||
# These are the rules we agreed upon and we work towards.
|
||||
AllCops:
|
||||
NewCops: enable
|
||||
NewCops: disable
|
||||
SuggestExtensions: false
|
||||
TargetRailsVersion: 5.0
|
||||
Exclude:
|
||||
- 'bin/**/*'
|
||||
- 'db/**/*'
|
||||
@@ -40,13 +41,9 @@ Metrics/BlockLength:
|
||||
"resources",
|
||||
"scenario",
|
||||
"shared_examples",
|
||||
"shared_examples_for",
|
||||
"xdescribe",
|
||||
]
|
||||
|
||||
Metrics/ParameterLists:
|
||||
CountKeywordArgs: false
|
||||
|
||||
Rails/ApplicationRecord:
|
||||
Exclude:
|
||||
# Migrations should not contain application code:
|
||||
|
||||
1498
.rubocop_todo.yml
1498
.rubocop_todo.yml
File diff suppressed because it is too large
Load Diff
@@ -1 +1 @@
|
||||
3.1.4
|
||||
3.0.3
|
||||
|
||||
@@ -57,7 +57,6 @@ TL;DR:
|
||||
* Maintain a clean commit history
|
||||
* Use a style consistent with the rest of the codebase
|
||||
* Before submitting, [rebase your work][rebase] on the current master branch
|
||||
* After submitting, be sure to check the [CI test results](ci). Click on a ❌ result to view the logged results and investigate.
|
||||
|
||||
From here, your pull request will progress through the [Review, Test, Merge & Deploy process][process].
|
||||
|
||||
@@ -71,5 +70,4 @@ From here, your pull request will progress through the [Review, Test, Merge & De
|
||||
[slack-dev]: https://openfoodnetwork.slack.com/messages/C2GQ45KNU
|
||||
[ofn-transifex]: https://www.transifex.com/open-food-foundation/open-food-network/
|
||||
[i18n]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/Internationalisation-%28i18n%29
|
||||
[welcome-dev]: https://github.com/orgs/openfoodfoundation/projects/5
|
||||
[ci]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/Continuous-Integration
|
||||
[welcome-dev]: https://github.com/orgs/openfoodfoundation/projects/2
|
||||
|
||||
20
Dockerfile
20
Dockerfile
@@ -28,9 +28,8 @@ RUN apt-get update && apt-get install -y \
|
||||
gnupg
|
||||
|
||||
# Setup ENV variables
|
||||
ENV PATH /usr/local/src/rbenv/shims:/usr/local/src/rbenv/bin:/usr/local/src/nodenv/shims:/usr/local/src/nodenv/bin:$PATH
|
||||
ENV PATH /usr/local/src/rbenv/shims:/usr/local/src/rbenv/bin:$PATH
|
||||
ENV RBENV_ROOT /usr/local/src/rbenv
|
||||
ENV NODENV_ROOT /usr/local/src/nodenv
|
||||
ENV CONFIGURE_OPTS --disable-install-doc
|
||||
ENV BUNDLE_PATH /bundles
|
||||
ENV LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so
|
||||
@@ -54,19 +53,10 @@ RUN sh -c "echo 'deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-
|
||||
apt-get update && \
|
||||
apt-get install -yqq --no-install-recommends postgresql-client-10 libpq-dev
|
||||
|
||||
|
||||
# trim spaces and line return from .node-version file
|
||||
COPY .node-version .node-version.raw
|
||||
RUN cat .node-version.raw | tr -d '\r\t ' > .node-version
|
||||
|
||||
# Install Node and Yarn with Nodenv
|
||||
RUN git clone --depth 1 https://github.com/nodenv/nodenv.git ${NODENV_ROOT} && \
|
||||
git clone --depth 1 https://github.com/nodenv/node-build.git ${NODENV_ROOT}/plugins/node-build && \
|
||||
git clone --depth 1 https://github.com/pine/nodenv-yarn-install.git ${NODENV_ROOT}/plugins/nodenv-yarn-install && \
|
||||
git clone --depth 1 https://github.com/nodenv/nodenv-package-rehash.git ${NODENV_ROOT}/plugins/nodenv-package-rehash && \
|
||||
echo 'eval "$(nodenv init -)"' >> /etc/profile.d/nodenv.sh && \
|
||||
nodenv install $(cat .node-version) && \
|
||||
nodenv global $(cat .node-version)
|
||||
# Install NodeJs and yarn
|
||||
RUN curl -sL https://deb.nodesource.com/setup_14.x | bash - \
|
||||
&& apt-get install --no-install-recommends -y nodejs \
|
||||
&& npm install -g yarn
|
||||
|
||||
# Install Chrome
|
||||
RUN wget --quiet -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \
|
||||
|
||||
@@ -48,14 +48,14 @@ Fetch the latest version of `master` from `upstream` (ie. the main repo):
|
||||
First, you need to create the database user the app will use by manually typing the following in your terminal:
|
||||
|
||||
```sh
|
||||
sudo --login --user=postgres psql -c "CREATE USER ofn WITH SUPERUSER CREATEDB PASSWORD 'f00d'"
|
||||
$ sudo -u postgres psql -c "CREATE USER ofn WITH SUPERUSER CREATEDB PASSWORD 'f00d'"
|
||||
```
|
||||
|
||||
This will create the "ofn" user as superuser and allowing it to create databases. If this command fails, check the [troubleshooting section](#creating-the-database) for an alternative.
|
||||
|
||||
Next, it is _strongly recommended_ to run the setup script.
|
||||
```sh
|
||||
./script/setup
|
||||
$ script/setup
|
||||
```
|
||||
If the script succeeds you're ready to start developing. If not, take a look at the output as it should be informative enough to help you troubleshoot.
|
||||
|
||||
@@ -114,13 +114,13 @@ Below are fixes to potential issues that can happen during the installation proc
|
||||
|
||||
#### Creating the database
|
||||
|
||||
If the `sudo -u postgres psql -c "CREATE USER ofn WITH SUPERUSER CREATEDB PASSWORD 'f00d'"` command doesn't work, you can run the following commands instead:
|
||||
If the ```$ sudo -u postgres psql -c "CREATE USER ofn WITH SUPERUSER CREATEDB PASSWORD 'f00d'"``` command doesn't work, you can run the following commands instead:
|
||||
```
|
||||
createuser --superuser --pwprompt ofn
|
||||
# Enter password for new role: f00d
|
||||
# Enter it again: f00d
|
||||
createdb open_food_network_dev --owner=ofn
|
||||
createdb open_food_network_test --owner=ofn
|
||||
$ createuser --superuser --pwprompt ofn
|
||||
Enter password for new role: f00d
|
||||
Enter it again: f00d
|
||||
$ createdb open_food_network_dev --owner=ofn
|
||||
$ createdb open_food_network_test --owner=ofn
|
||||
```
|
||||
If these commands succeed, you should be able to [continue the setup process](#get-it-running).
|
||||
|
||||
|
||||
31
Gemfile
31
Gemfile
@@ -1,13 +1,12 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
source 'https://rubygems.org'
|
||||
ruby "3.0.3"
|
||||
git_source(:github) { |repo_name| "https://github.com/#{repo_name}.git" }
|
||||
|
||||
ruby File.read('.ruby-version').chomp
|
||||
|
||||
gem 'dotenv-rails', require: 'dotenv/rails-now' # Load ENV vars before other gems
|
||||
|
||||
gem 'rails'
|
||||
gem 'rails', '>= 6.1.4'
|
||||
|
||||
# Active Storage
|
||||
gem "active_storage_validations"
|
||||
@@ -15,11 +14,11 @@ gem "aws-sdk-s3", require: false
|
||||
gem "image_processing"
|
||||
|
||||
gem 'activemerchant', '>= 1.78.0'
|
||||
gem 'rexml'
|
||||
gem 'angular-rails-templates', '>= 0.3.0'
|
||||
gem 'awesome_nested_set'
|
||||
gem 'ransack', '~> 2.6.0'
|
||||
gem 'responders'
|
||||
gem 'rexml'
|
||||
gem 'webpacker', '~> 5'
|
||||
|
||||
gem 'i18n'
|
||||
@@ -28,7 +27,7 @@ gem 'rails-i18n'
|
||||
gem 'rails_safe_tasks', '~> 1.0'
|
||||
|
||||
gem "activerecord-import"
|
||||
gem "db2fog", github: "openfoodfoundation/db2fog", branch: "rails-7"
|
||||
gem "db2fog", github: "openfoodfoundation/db2fog", branch: "rails-6"
|
||||
gem "fog-aws", "~> 2.0" # db2fog does not support v3
|
||||
gem "mime-types" # required by fog
|
||||
|
||||
@@ -64,7 +63,6 @@ gem 'devise-token_authenticatable'
|
||||
gem 'jwt', '~> 2.3'
|
||||
gem 'oauth2', '~> 1.4.7' # Used for Stripe Connect
|
||||
|
||||
gem 'datafoodconsortium-connector'
|
||||
gem 'jsonapi-serializer'
|
||||
gem 'pagy', '~> 5.1'
|
||||
|
||||
@@ -72,8 +70,8 @@ gem 'rswag-api'
|
||||
gem 'rswag-ui'
|
||||
|
||||
gem 'omniauth_openid_connect'
|
||||
gem 'omniauth-rails_csrf_protection'
|
||||
gem 'openid_connect', '~> 1.3'
|
||||
gem 'omniauth-rails_csrf_protection'
|
||||
|
||||
gem 'angularjs-rails', '1.8.0'
|
||||
gem 'bugsnag'
|
||||
@@ -94,7 +92,6 @@ gem 'gmaps4rails'
|
||||
gem 'mimemagic', '> 0.3.5'
|
||||
gem 'paper_trail', '~> 12.1'
|
||||
gem 'rack-rewrite'
|
||||
gem 'rack-timeout'
|
||||
gem 'roadie-rails'
|
||||
|
||||
gem 'hiredis'
|
||||
@@ -103,8 +100,8 @@ gem 'redis', '>= 4.0', require: ['redis', 'redis/connection/hiredis']
|
||||
gem 'sidekiq'
|
||||
gem 'sidekiq-scheduler'
|
||||
|
||||
gem "cable_ready", "5.0.0.rc2"
|
||||
gem "stimulus_reflex", "3.5.0.rc2"
|
||||
gem "cable_ready", "5.0.0.pre9"
|
||||
gem "stimulus_reflex", "3.5.0.pre9"
|
||||
|
||||
gem 'combine_pdf'
|
||||
gem 'wicked_pdf'
|
||||
@@ -116,8 +113,12 @@ gem 'spreadsheet_architect' # write spreadsheets
|
||||
|
||||
gem 'whenever', require: false
|
||||
|
||||
gem 'test-unit', '~> 3.5'
|
||||
|
||||
gem 'coffee-rails', '~> 5.0.0'
|
||||
|
||||
gem 'mini_racer'
|
||||
|
||||
gem 'angular_rails_csrf'
|
||||
|
||||
gem 'jquery-rails', '4.4.0'
|
||||
@@ -135,10 +136,9 @@ gem 'view_component_reflex', '3.1.14.pre9'
|
||||
|
||||
gem 'mini_portile2', '~> 2.8'
|
||||
|
||||
gem "faraday"
|
||||
gem "private_address_check"
|
||||
|
||||
group :production, :staging do
|
||||
gem 'ddtrace'
|
||||
gem 'rack-timeout'
|
||||
gem 'sd_notify' # For better Systemd process management. Used by Puma.
|
||||
end
|
||||
|
||||
@@ -147,7 +147,6 @@ group :test, :development do
|
||||
gem 'capybara'
|
||||
gem 'cuprite'
|
||||
gem 'database_cleaner', require: false
|
||||
gem 'debug', '>= 1.0.0'
|
||||
gem "factory_bot_rails", '6.2.0', require: false
|
||||
gem 'fuubar', '~> 2.5.1'
|
||||
gem 'json_spec', '~> 1.1.4'
|
||||
@@ -158,6 +157,7 @@ group :test, :development do
|
||||
gem 'rswag-specs'
|
||||
gem 'shoulda-matchers'
|
||||
gem 'timecop'
|
||||
gem 'debug', '>= 1.0.0'
|
||||
end
|
||||
|
||||
group :test do
|
||||
@@ -172,11 +172,10 @@ end
|
||||
|
||||
group :development do
|
||||
gem 'debugger-linecache'
|
||||
gem 'rails-erd'
|
||||
gem 'foreman'
|
||||
gem 'listen'
|
||||
gem 'pry', '~> 0.13.0'
|
||||
gem 'query_count'
|
||||
gem 'rails-erd'
|
||||
gem 'rubocop'
|
||||
gem 'rubocop-rails'
|
||||
gem 'spring'
|
||||
|
||||
389
Gemfile.lock
389
Gemfile.lock
@@ -1,12 +1,12 @@
|
||||
GIT
|
||||
remote: https://github.com/openfoodfoundation/db2fog.git
|
||||
revision: 6e88c0ab9eeb23d7ad9964b27becb1c04a83141f
|
||||
branch: rails-7
|
||||
revision: 5b63343847452f52aa42f7fc169d6ab3af57cda3
|
||||
branch: rails-6
|
||||
specs:
|
||||
db2fog (0.9.2)
|
||||
activerecord (>= 3.2.0)
|
||||
activerecord (>= 3.2.0, < 7.0)
|
||||
fog-core (~> 1.0)
|
||||
rails (>= 3.2.0)
|
||||
rails (>= 3.2.0, < 7.0)
|
||||
|
||||
GIT
|
||||
remote: https://github.com/openfoodfoundation/select2-rails.git
|
||||
@@ -44,73 +44,66 @@ GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
Ascii85 (1.1.0)
|
||||
actioncable (7.0.6)
|
||||
actionpack (= 7.0.6)
|
||||
activesupport (= 7.0.6)
|
||||
actioncable (6.1.7.2)
|
||||
actionpack (= 6.1.7.2)
|
||||
activesupport (= 6.1.7.2)
|
||||
nio4r (~> 2.0)
|
||||
websocket-driver (>= 0.6.1)
|
||||
actionmailbox (7.0.6)
|
||||
actionpack (= 7.0.6)
|
||||
activejob (= 7.0.6)
|
||||
activerecord (= 7.0.6)
|
||||
activestorage (= 7.0.6)
|
||||
activesupport (= 7.0.6)
|
||||
actionmailbox (6.1.7.2)
|
||||
actionpack (= 6.1.7.2)
|
||||
activejob (= 6.1.7.2)
|
||||
activerecord (= 6.1.7.2)
|
||||
activestorage (= 6.1.7.2)
|
||||
activesupport (= 6.1.7.2)
|
||||
mail (>= 2.7.1)
|
||||
net-imap
|
||||
net-pop
|
||||
net-smtp
|
||||
actionmailer (7.0.6)
|
||||
actionpack (= 7.0.6)
|
||||
actionview (= 7.0.6)
|
||||
activejob (= 7.0.6)
|
||||
activesupport (= 7.0.6)
|
||||
actionmailer (6.1.7.2)
|
||||
actionpack (= 6.1.7.2)
|
||||
actionview (= 6.1.7.2)
|
||||
activejob (= 6.1.7.2)
|
||||
activesupport (= 6.1.7.2)
|
||||
mail (~> 2.5, >= 2.5.4)
|
||||
net-imap
|
||||
net-pop
|
||||
net-smtp
|
||||
rails-dom-testing (~> 2.0)
|
||||
actionpack (7.0.6)
|
||||
actionview (= 7.0.6)
|
||||
activesupport (= 7.0.6)
|
||||
rack (~> 2.0, >= 2.2.4)
|
||||
actionpack (6.1.7.2)
|
||||
actionview (= 6.1.7.2)
|
||||
activesupport (= 6.1.7.2)
|
||||
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 (7.0.6)
|
||||
actionpack (= 7.0.6)
|
||||
activerecord (= 7.0.6)
|
||||
activestorage (= 7.0.6)
|
||||
activesupport (= 7.0.6)
|
||||
globalid (>= 0.6.0)
|
||||
actiontext (6.1.7.2)
|
||||
actionpack (= 6.1.7.2)
|
||||
activerecord (= 6.1.7.2)
|
||||
activestorage (= 6.1.7.2)
|
||||
activesupport (= 6.1.7.2)
|
||||
nokogiri (>= 1.8.5)
|
||||
actionview (7.0.6)
|
||||
activesupport (= 7.0.6)
|
||||
actionview (6.1.7.2)
|
||||
activesupport (= 6.1.7.2)
|
||||
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 (1.0.4)
|
||||
active_storage_validations (1.0.3)
|
||||
activejob (>= 5.2.0)
|
||||
activemodel (>= 5.2.0)
|
||||
activestorage (>= 5.2.0)
|
||||
activesupport (>= 5.2.0)
|
||||
activejob (7.0.6)
|
||||
activesupport (= 7.0.6)
|
||||
activejob (6.1.7.2)
|
||||
activesupport (= 6.1.7.2)
|
||||
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 (7.0.6)
|
||||
activesupport (= 7.0.6)
|
||||
activerecord (7.0.6)
|
||||
activemodel (= 7.0.6)
|
||||
activesupport (= 7.0.6)
|
||||
activemodel (6.1.7.2)
|
||||
activesupport (= 6.1.7.2)
|
||||
activerecord (6.1.7.2)
|
||||
activemodel (= 6.1.7.2)
|
||||
activesupport (= 6.1.7.2)
|
||||
activerecord-import (1.4.1)
|
||||
activerecord (>= 4.2)
|
||||
activerecord-postgresql-adapter (0.0.1)
|
||||
@@ -121,23 +114,24 @@ GEM
|
||||
multi_json (~> 1.11, >= 1.11.2)
|
||||
rack (>= 2.0.8, < 3)
|
||||
railties (>= 5.2.4.1)
|
||||
activestorage (7.0.6)
|
||||
actionpack (= 7.0.6)
|
||||
activejob (= 7.0.6)
|
||||
activerecord (= 7.0.6)
|
||||
activesupport (= 7.0.6)
|
||||
activestorage (6.1.7.2)
|
||||
actionpack (= 6.1.7.2)
|
||||
activejob (= 6.1.7.2)
|
||||
activerecord (= 6.1.7.2)
|
||||
activesupport (= 6.1.7.2)
|
||||
marcel (~> 1.0)
|
||||
mini_mime (>= 1.1.0)
|
||||
activesupport (7.0.6)
|
||||
activesupport (6.1.7.2)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 1.6, < 2)
|
||||
minitest (>= 5.1)
|
||||
tzinfo (~> 2.0)
|
||||
zeitwerk (~> 2.3)
|
||||
acts-as-taggable-on (9.0.1)
|
||||
activerecord (>= 6.0, < 7.1)
|
||||
acts_as_list (1.0.4)
|
||||
activerecord (>= 4.2)
|
||||
addressable (2.8.4)
|
||||
addressable (2.8.1)
|
||||
public_suffix (>= 2.0.2, < 6.0)
|
||||
aes_key_wrap (1.1.0)
|
||||
afm (0.2.2)
|
||||
@@ -157,17 +151,17 @@ GEM
|
||||
awesome_nested_set (3.5.0)
|
||||
activerecord (>= 4.0.0, < 7.1)
|
||||
aws-eventstream (1.2.0)
|
||||
aws-partitions (1.780.0)
|
||||
aws-sdk-core (3.175.0)
|
||||
aws-partitions (1.711.0)
|
||||
aws-sdk-core (3.170.0)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
aws-partitions (~> 1, >= 1.651.0)
|
||||
aws-sigv4 (~> 1.5)
|
||||
jmespath (~> 1, >= 1.6.1)
|
||||
aws-sdk-kms (1.67.0)
|
||||
aws-sdk-core (~> 3, >= 3.174.0)
|
||||
aws-sdk-kms (1.62.0)
|
||||
aws-sdk-core (~> 3, >= 3.165.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
aws-sdk-s3 (1.126.0)
|
||||
aws-sdk-core (~> 3, >= 3.174.0)
|
||||
aws-sdk-s3 (1.119.1)
|
||||
aws-sdk-core (~> 3, >= 3.165.0)
|
||||
aws-sdk-kms (~> 1)
|
||||
aws-sigv4 (~> 1.4)
|
||||
aws-sigv4 (1.5.2)
|
||||
@@ -184,14 +178,16 @@ GEM
|
||||
bullet (7.0.7)
|
||||
activesupport (>= 3.0.0)
|
||||
uniform_notifier (~> 1.11)
|
||||
cable_ready (5.0.0.rc2)
|
||||
cable_ready (5.0.0.pre9)
|
||||
actioncable (>= 5.2)
|
||||
actionpack (>= 5.2)
|
||||
actionview (>= 5.2)
|
||||
activerecord (>= 5.2)
|
||||
activesupport (>= 5.2)
|
||||
railties (>= 5.2)
|
||||
thread-local (>= 1.1.0)
|
||||
cancancan (1.15.0)
|
||||
capybara (3.39.2)
|
||||
capybara (3.38.0)
|
||||
addressable
|
||||
matrix
|
||||
mini_mime (>= 0.1.3)
|
||||
@@ -215,11 +211,11 @@ GEM
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.12.2)
|
||||
combine_pdf (1.0.23)
|
||||
combine_pdf (1.0.22)
|
||||
matrix
|
||||
ruby-rc4 (>= 0.1.5)
|
||||
concurrent-ruby (1.2.2)
|
||||
connection_pool (2.4.1)
|
||||
connection_pool (2.3.0)
|
||||
crack (0.4.5)
|
||||
rexml
|
||||
crass (1.0.6)
|
||||
@@ -228,20 +224,24 @@ GEM
|
||||
cuprite (0.14.3)
|
||||
capybara (~> 3.0)
|
||||
ferrum (~> 0.13.0)
|
||||
database_cleaner (2.0.2)
|
||||
database_cleaner-active_record (>= 2, < 3)
|
||||
database_cleaner-active_record (2.1.0)
|
||||
database_cleaner (2.0.1)
|
||||
database_cleaner-active_record (~> 2.0.0)
|
||||
database_cleaner-active_record (2.0.0)
|
||||
activerecord (>= 5.a)
|
||||
database_cleaner-core (~> 2.0.0)
|
||||
database_cleaner-core (2.0.1)
|
||||
datafoodconsortium-connector (1.0.0.pre.alpha.6)
|
||||
virtual_assembly-semantizer (~> 1.0, >= 1.0.4)
|
||||
date (3.3.3)
|
||||
debug (1.8.0)
|
||||
ddtrace (1.10.1)
|
||||
debase-ruby_core_source (>= 0.10.16, <= 3.2.0)
|
||||
libdatadog (~> 2.0.0.1.0)
|
||||
libddwaf (~> 1.6.2.0.0)
|
||||
msgpack
|
||||
debase-ruby_core_source (3.2.0)
|
||||
debug (1.7.1)
|
||||
irb (>= 1.5.0)
|
||||
reline (>= 0.3.1)
|
||||
debugger-linecache (1.2.0)
|
||||
devise (4.9.2)
|
||||
devise (4.8.1)
|
||||
bcrypt (~> 3.0)
|
||||
orm_adapter (~> 0.1)
|
||||
railties (>= 4.1.0)
|
||||
@@ -249,8 +249,8 @@ GEM
|
||||
warden (~> 1.2.3)
|
||||
devise-encryptable (0.2.0)
|
||||
devise (>= 2.1.0)
|
||||
devise-i18n (1.11.0)
|
||||
devise (>= 4.9.0)
|
||||
devise-i18n (1.10.3)
|
||||
devise (>= 4.8.0)
|
||||
devise-token_authenticatable (1.1.0)
|
||||
devise (>= 4.0.0, < 5.0.0)
|
||||
diff-lcs (1.5.0)
|
||||
@@ -270,7 +270,7 @@ GEM
|
||||
factory_bot_rails (6.2.0)
|
||||
factory_bot (~> 6.2.0)
|
||||
railties (>= 5.0.0)
|
||||
faraday (2.7.10)
|
||||
faraday (2.7.4)
|
||||
faraday-net_http (>= 2.0, < 3.1)
|
||||
ruby2_keywords (>= 0.0.4)
|
||||
faraday-follow_redirects (0.3.0)
|
||||
@@ -283,17 +283,15 @@ GEM
|
||||
websocket-driver (>= 0.6, < 0.8)
|
||||
ffaker (2.21.0)
|
||||
ffi (1.15.5)
|
||||
flipper (0.26.2)
|
||||
concurrent-ruby (< 2)
|
||||
flipper-active_record (0.26.2)
|
||||
activerecord (>= 4.2, < 8)
|
||||
flipper (~> 0.26.2)
|
||||
flipper-ui (0.26.2)
|
||||
flipper (0.20.4)
|
||||
flipper-active_record (0.20.4)
|
||||
activerecord (>= 5.0, < 7)
|
||||
flipper (~> 0.20.4)
|
||||
flipper-ui (0.20.4)
|
||||
erubi (>= 1.0.0, < 2.0.0)
|
||||
flipper (~> 0.26.2)
|
||||
flipper (~> 0.20.4)
|
||||
rack (>= 1.4, < 3)
|
||||
rack-protection (>= 1.5.3, <= 4.0.0)
|
||||
sanitize (< 7)
|
||||
rack-protection (>= 1.5.3, < 2.2.0)
|
||||
fog-aws (2.0.1)
|
||||
fog-core (~> 1.38)
|
||||
fog-json (~> 1.0)
|
||||
@@ -317,7 +315,7 @@ GEM
|
||||
fuubar (2.5.1)
|
||||
rspec-core (~> 3.0)
|
||||
ruby-progressbar (~> 1.4)
|
||||
geocoder (1.8.2)
|
||||
geocoder (1.8.1)
|
||||
globalid (1.1.0)
|
||||
activesupport (>= 5.0)
|
||||
gmaps4rails (2.1.2)
|
||||
@@ -334,7 +332,7 @@ GEM
|
||||
hiredis (0.6.3)
|
||||
htmlentities (4.3.4)
|
||||
httpclient (2.8.3)
|
||||
i18n (1.14.1)
|
||||
i18n (1.12.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
i18n-js (3.9.2)
|
||||
i18n (>= 0.6.6)
|
||||
@@ -345,7 +343,7 @@ GEM
|
||||
activerecord (>= 3.0)
|
||||
io-console (0.6.0)
|
||||
ipaddress (0.8.3)
|
||||
irb (1.6.4)
|
||||
irb (1.6.2)
|
||||
reline (>= 0.3.0)
|
||||
jmespath (1.6.2)
|
||||
jquery-rails (4.4.0)
|
||||
@@ -355,20 +353,12 @@ GEM
|
||||
jquery-ui-rails (4.2.1)
|
||||
railties (>= 3.2.16)
|
||||
json (2.6.3)
|
||||
json-canonicalization (0.3.1)
|
||||
json-jwt (1.16.3)
|
||||
activesupport (>= 4.2)
|
||||
aes_key_wrap
|
||||
bindata
|
||||
faraday (~> 2.0)
|
||||
faraday-follow_redirects
|
||||
json-ld (3.2.3)
|
||||
htmlentities (~> 4.3)
|
||||
json-canonicalization (~> 0.3)
|
||||
link_header (~> 0.0, >= 0.0.8)
|
||||
multi_json (~> 1.15)
|
||||
rack (~> 2.2)
|
||||
rdf (~> 3.2, >= 3.2.9)
|
||||
json-schema (3.0.0)
|
||||
addressable (>= 2.8)
|
||||
json_spec (1.1.5)
|
||||
@@ -376,21 +366,23 @@ GEM
|
||||
rspec (>= 2.0, < 4.0)
|
||||
jsonapi-serializer (2.2.0)
|
||||
activesupport (>= 4.2)
|
||||
jwt (2.7.1)
|
||||
knapsack_pro (5.1.2)
|
||||
jwt (2.7.0)
|
||||
knapsack_pro (3.8.0)
|
||||
rake
|
||||
language_server-protocol (3.17.0.3)
|
||||
launchy (2.5.0)
|
||||
addressable (~> 2.7)
|
||||
letter_opener (1.8.1)
|
||||
launchy (>= 2.2, < 3)
|
||||
link_header (0.0.8)
|
||||
libdatadog (2.0.0.1.0)
|
||||
libddwaf (1.6.2.0.0)
|
||||
ffi (~> 1.0)
|
||||
libv8-node (16.10.0.0)
|
||||
listen (3.8.0)
|
||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||
rb-inotify (~> 0.9, >= 0.9.10)
|
||||
loofah (2.21.3)
|
||||
loofah (2.19.1)
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.12.0)
|
||||
nokogiri (>= 1.5.9)
|
||||
mail (2.8.1)
|
||||
mini_mime (>= 0.1.1)
|
||||
net-imap
|
||||
@@ -407,16 +399,18 @@ GEM
|
||||
rake
|
||||
mini_magick (4.11.0)
|
||||
mini_mime (1.1.2)
|
||||
mini_portile2 (2.8.2)
|
||||
minitest (5.18.1)
|
||||
mini_portile2 (2.8.1)
|
||||
mini_racer (0.6.3)
|
||||
libv8-node (~> 16.10.0.0)
|
||||
minitest (5.17.0)
|
||||
monetize (1.12.0)
|
||||
money (~> 6.12)
|
||||
money (6.16.0)
|
||||
i18n (>= 0.6.4, <= 2)
|
||||
msgpack (1.7.1)
|
||||
msgpack (1.6.1)
|
||||
multi_json (1.15.0)
|
||||
multi_xml (0.6.0)
|
||||
net-imap (0.3.6)
|
||||
net-imap (0.3.4)
|
||||
date
|
||||
net-protocol
|
||||
net-pop (0.1.2)
|
||||
@@ -425,9 +419,9 @@ GEM
|
||||
timeout
|
||||
net-smtp (0.3.3)
|
||||
net-protocol
|
||||
nio4r (2.5.9)
|
||||
nokogiri (1.15.3)
|
||||
mini_portile2 (~> 2.8.2)
|
||||
nio4r (2.5.8)
|
||||
nokogiri (1.14.2)
|
||||
mini_portile2 (~> 2.8.0)
|
||||
racc (~> 1.4)
|
||||
oauth2 (1.4.11)
|
||||
faraday (>= 0.17.3, < 3.0)
|
||||
@@ -462,12 +456,11 @@ GEM
|
||||
paper_trail (12.3.0)
|
||||
activerecord (>= 5.2)
|
||||
request_store (~> 1.1)
|
||||
parallel (1.23.0)
|
||||
paranoia (2.6.2)
|
||||
parallel (1.22.1)
|
||||
paranoia (2.6.1)
|
||||
activerecord (>= 5.1, < 7.1)
|
||||
parser (3.2.2.3)
|
||||
parser (3.2.1.1)
|
||||
ast (~> 2.4.1)
|
||||
racc
|
||||
paypal-sdk-core (0.3.4)
|
||||
multi_json (~> 1.0)
|
||||
xml-simple
|
||||
@@ -480,19 +473,16 @@ GEM
|
||||
ruby-rc4
|
||||
ttfunk
|
||||
pg (1.2.3)
|
||||
private_address_check (0.5.0)
|
||||
power_assert (2.0.2)
|
||||
pry (0.13.1)
|
||||
coderay (~> 1.1)
|
||||
method_source (~> 1.0)
|
||||
public_suffix (5.0.1)
|
||||
puma (6.3.0)
|
||||
puma (6.1.1)
|
||||
nio4r (~> 2.0)
|
||||
query_count (1.1.1)
|
||||
activerecord (>= 4.2)
|
||||
railties (>= 4.2)
|
||||
raabro (1.4.0)
|
||||
racc (1.7.1)
|
||||
rack (2.2.7)
|
||||
racc (1.6.2)
|
||||
rack (2.2.6.3)
|
||||
rack-mini-profiler (2.3.4)
|
||||
rack (>= 1.2.0)
|
||||
rack-oauth2 (1.21.3)
|
||||
@@ -501,55 +491,53 @@ GEM
|
||||
httpclient
|
||||
json-jwt (>= 1.11.0)
|
||||
rack (>= 2.1.0)
|
||||
rack-protection (3.0.5)
|
||||
rack-protection (2.1.0)
|
||||
rack
|
||||
rack-proxy (0.7.6)
|
||||
rack
|
||||
rack-rewrite (1.5.1)
|
||||
rack-test (2.1.0)
|
||||
rack-test (2.0.2)
|
||||
rack (>= 1.3)
|
||||
rack-timeout (0.6.3)
|
||||
rails (7.0.6)
|
||||
actioncable (= 7.0.6)
|
||||
actionmailbox (= 7.0.6)
|
||||
actionmailer (= 7.0.6)
|
||||
actionpack (= 7.0.6)
|
||||
actiontext (= 7.0.6)
|
||||
actionview (= 7.0.6)
|
||||
activejob (= 7.0.6)
|
||||
activemodel (= 7.0.6)
|
||||
activerecord (= 7.0.6)
|
||||
activestorage (= 7.0.6)
|
||||
activesupport (= 7.0.6)
|
||||
rails (6.1.7.2)
|
||||
actioncable (= 6.1.7.2)
|
||||
actionmailbox (= 6.1.7.2)
|
||||
actionmailer (= 6.1.7.2)
|
||||
actionpack (= 6.1.7.2)
|
||||
actiontext (= 6.1.7.2)
|
||||
actionview (= 6.1.7.2)
|
||||
activejob (= 6.1.7.2)
|
||||
activemodel (= 6.1.7.2)
|
||||
activerecord (= 6.1.7.2)
|
||||
activestorage (= 6.1.7.2)
|
||||
activesupport (= 6.1.7.2)
|
||||
bundler (>= 1.15.0)
|
||||
railties (= 7.0.6)
|
||||
railties (= 6.1.7.2)
|
||||
sprockets-rails (>= 2.0.0)
|
||||
rails-controller-testing (1.0.5)
|
||||
actionpack (>= 5.0.1.rc1)
|
||||
actionview (>= 5.0.1.rc1)
|
||||
activesupport (>= 5.0.1.rc1)
|
||||
rails-dom-testing (2.1.1)
|
||||
activesupport (>= 5.0.0)
|
||||
minitest
|
||||
rails-dom-testing (2.0.3)
|
||||
activesupport (>= 4.2.0)
|
||||
nokogiri (>= 1.6)
|
||||
rails-erd (1.7.2)
|
||||
activerecord (>= 4.2)
|
||||
activesupport (>= 4.2)
|
||||
choice (~> 0.2.0)
|
||||
ruby-graphviz (~> 1.2)
|
||||
rails-html-sanitizer (1.6.0)
|
||||
loofah (~> 2.21)
|
||||
nokogiri (~> 1.14)
|
||||
rails-i18n (7.0.7)
|
||||
rails-html-sanitizer (1.5.0)
|
||||
loofah (~> 2.19, >= 2.19.1)
|
||||
rails-i18n (7.0.6)
|
||||
i18n (>= 0.7, < 2)
|
||||
railties (>= 6.0.0, < 8)
|
||||
rails_safe_tasks (1.0.0)
|
||||
railties (7.0.6)
|
||||
actionpack (= 7.0.6)
|
||||
activesupport (= 7.0.6)
|
||||
railties (6.1.7.2)
|
||||
actionpack (= 6.1.7.2)
|
||||
activesupport (= 6.1.7.2)
|
||||
method_source
|
||||
rake (>= 12.2)
|
||||
thor (~> 1.0)
|
||||
zeitwerk (~> 2.5)
|
||||
rainbow (3.1.1)
|
||||
rake (13.0.6)
|
||||
ransack (2.6.0)
|
||||
@@ -559,14 +547,12 @@ GEM
|
||||
rb-fsevent (0.11.2)
|
||||
rb-inotify (0.10.1)
|
||||
ffi (~> 1.0)
|
||||
rdf (3.2.9)
|
||||
link_header (~> 0.0, >= 0.0.8)
|
||||
redcarpet (3.6.0)
|
||||
redis (4.8.1)
|
||||
redis-client (0.14.1)
|
||||
redis-client (0.13.0)
|
||||
connection_pool
|
||||
regexp_parser (2.8.1)
|
||||
reline (0.3.3)
|
||||
regexp_parser (2.7.0)
|
||||
reline (0.3.2)
|
||||
io-console (~> 0.5)
|
||||
request_store (1.5.1)
|
||||
rack (>= 1.4)
|
||||
@@ -590,49 +576,48 @@ GEM
|
||||
rspec-core (~> 3.12.0)
|
||||
rspec-expectations (~> 3.12.0)
|
||||
rspec-mocks (~> 3.12.0)
|
||||
rspec-core (3.12.2)
|
||||
rspec-core (3.12.1)
|
||||
rspec-support (~> 3.12.0)
|
||||
rspec-expectations (3.12.3)
|
||||
rspec-expectations (3.12.2)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.12.0)
|
||||
rspec-mocks (3.12.5)
|
||||
rspec-mocks (3.12.3)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.12.0)
|
||||
rspec-rails (6.0.3)
|
||||
rspec-rails (6.0.1)
|
||||
actionpack (>= 6.1)
|
||||
activesupport (>= 6.1)
|
||||
railties (>= 6.1)
|
||||
rspec-core (~> 3.12)
|
||||
rspec-expectations (~> 3.12)
|
||||
rspec-mocks (~> 3.12)
|
||||
rspec-support (~> 3.12)
|
||||
rspec-core (~> 3.11)
|
||||
rspec-expectations (~> 3.11)
|
||||
rspec-mocks (~> 3.11)
|
||||
rspec-support (~> 3.11)
|
||||
rspec-retry (0.6.2)
|
||||
rspec-core (> 3.3)
|
||||
rspec-support (3.12.0)
|
||||
rswag-api (2.9.0)
|
||||
rswag-api (2.8.0)
|
||||
railties (>= 3.1, < 7.1)
|
||||
rswag-specs (2.9.0)
|
||||
rswag-specs (2.8.0)
|
||||
activesupport (>= 3.1, < 7.1)
|
||||
json-schema (>= 2.2, < 4.0)
|
||||
railties (>= 3.1, < 7.1)
|
||||
rspec-core (>= 2.14)
|
||||
rswag-ui (2.9.0)
|
||||
rswag-ui (2.8.0)
|
||||
actionpack (>= 3.1, < 7.1)
|
||||
railties (>= 3.1, < 7.1)
|
||||
rubocop (1.54.1)
|
||||
rubocop (1.48.1)
|
||||
json (~> 2.3)
|
||||
language_server-protocol (>= 3.17.0)
|
||||
parallel (~> 1.10)
|
||||
parser (>= 3.2.2.3)
|
||||
parser (>= 3.2.0.0)
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
regexp_parser (>= 1.8, < 3.0)
|
||||
rexml (>= 3.2.5, < 4.0)
|
||||
rubocop-ast (>= 1.28.0, < 2.0)
|
||||
rubocop-ast (>= 1.26.0, < 2.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (>= 2.4.0, < 3.0)
|
||||
rubocop-ast (1.29.0)
|
||||
rubocop-ast (1.27.0)
|
||||
parser (>= 3.2.1.0)
|
||||
rubocop-rails (2.20.2)
|
||||
rubocop-rails (2.18.0)
|
||||
activesupport (>= 4.2.0)
|
||||
rack (>= 1.1)
|
||||
rubocop (>= 1.33.0, < 2.0)
|
||||
@@ -646,9 +631,6 @@ GEM
|
||||
rubyzip (2.3.2)
|
||||
rufus-scheduler (3.8.2)
|
||||
fugit (~> 1.1, >= 1.1.6)
|
||||
sanitize (6.0.2)
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.12.0)
|
||||
sass (3.4.25)
|
||||
sass-rails (5.0.8)
|
||||
railties (>= 5.2.0)
|
||||
@@ -660,12 +642,12 @@ GEM
|
||||
semantic_range (3.0.0)
|
||||
shoulda-matchers (5.3.0)
|
||||
activesupport (>= 5.2.0)
|
||||
sidekiq (7.1.2)
|
||||
sidekiq (7.0.6)
|
||||
concurrent-ruby (< 2)
|
||||
connection_pool (>= 2.3.0)
|
||||
rack (>= 2.2.4)
|
||||
redis-client (>= 0.14.0)
|
||||
sidekiq-scheduler (5.0.3)
|
||||
redis-client (>= 0.11.0)
|
||||
sidekiq-scheduler (5.0.2)
|
||||
rufus-scheduler (~> 3.2)
|
||||
sidekiq (>= 6, < 8)
|
||||
tilt (>= 1.4.0)
|
||||
@@ -688,41 +670,43 @@ GEM
|
||||
actionpack (>= 5.2)
|
||||
activesupport (>= 5.2)
|
||||
sprockets (>= 3.0.0)
|
||||
state_machines (0.6.0)
|
||||
state_machines-activemodel (0.9.0)
|
||||
activemodel (>= 6.0)
|
||||
state_machines (>= 0.6.0)
|
||||
state_machines-activerecord (0.9.0)
|
||||
activerecord (>= 6.0)
|
||||
state_machines-activemodel (>= 0.9.0)
|
||||
stimulus_reflex (3.5.0.rc2)
|
||||
actioncable (>= 5.2, < 8)
|
||||
actionpack (>= 5.2, < 8)
|
||||
actionview (>= 5.2, < 8)
|
||||
activesupport (>= 5.2, < 8)
|
||||
cable_ready (>= 5.0.0.rc2)
|
||||
nokogiri (~> 1.0)
|
||||
rack (>= 2, < 4)
|
||||
railties (>= 5.2, < 8)
|
||||
redis (>= 4.0, < 6.0)
|
||||
stringex (2.8.6)
|
||||
stripe (8.5.0)
|
||||
state_machines (0.5.0)
|
||||
state_machines-activemodel (0.8.0)
|
||||
activemodel (>= 5.1)
|
||||
state_machines (>= 0.5.0)
|
||||
state_machines-activerecord (0.8.0)
|
||||
activerecord (>= 5.1)
|
||||
state_machines-activemodel (>= 0.8.0)
|
||||
stimulus_reflex (3.5.0.pre9)
|
||||
actioncable (>= 5.2)
|
||||
actionpack (>= 5.2)
|
||||
actionview (>= 5.2)
|
||||
activesupport (>= 5.2)
|
||||
cable_ready (>= 5.0.0.pre9)
|
||||
nokogiri
|
||||
rack
|
||||
railties (>= 5.2)
|
||||
redis
|
||||
stringex (2.8.5)
|
||||
stripe (8.3.0)
|
||||
swd (1.3.0)
|
||||
activesupport (>= 3)
|
||||
attr_required (>= 0.0.5)
|
||||
httpclient (>= 2.4)
|
||||
temple (0.8.2)
|
||||
thor (1.2.2)
|
||||
test-unit (3.5.7)
|
||||
power_assert
|
||||
thor (1.2.1)
|
||||
thread-local (1.1.0)
|
||||
tilt (2.1.0)
|
||||
timecop (0.9.6)
|
||||
timeout (0.4.0)
|
||||
timeout (0.3.2)
|
||||
ttfunk (1.7.0)
|
||||
tzinfo (2.0.6)
|
||||
concurrent-ruby (~> 1.0)
|
||||
unicode-display_width (2.4.2)
|
||||
uniform_notifier (1.16.0)
|
||||
valid_email2 (4.0.6)
|
||||
valid_email2 (4.0.5)
|
||||
activemodel (>= 3.2)
|
||||
mail (~> 2.5)
|
||||
validate_email (0.1.6)
|
||||
@@ -731,8 +715,8 @@ GEM
|
||||
validate_url (1.0.15)
|
||||
activemodel (>= 3.0.0)
|
||||
public_suffix
|
||||
vcr (6.2.0)
|
||||
view_component (3.3.0)
|
||||
vcr (6.1.0)
|
||||
view_component (2.82.0)
|
||||
activesupport (>= 5.2.0, < 8.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
method_source (~> 1.0)
|
||||
@@ -740,8 +724,6 @@ GEM
|
||||
rails (>= 5.2, < 8.0)
|
||||
stimulus_reflex (>= 3.5.0.pre2)
|
||||
view_component (>= 2.28.0)
|
||||
virtual_assembly-semantizer (1.0.4)
|
||||
json-ld (~> 3.2, >= 3.2.3)
|
||||
warden (1.2.9)
|
||||
rack (>= 2.0.9)
|
||||
web-console (4.2.0)
|
||||
@@ -773,7 +755,7 @@ GEM
|
||||
xml-simple (1.1.8)
|
||||
xpath (3.2.0)
|
||||
nokogiri (~> 1.8)
|
||||
zeitwerk (2.6.8)
|
||||
zeitwerk (2.6.7)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
@@ -799,7 +781,7 @@ DEPENDENCIES
|
||||
bootsnap
|
||||
bugsnag
|
||||
bullet
|
||||
cable_ready (= 5.0.0.rc2)
|
||||
cable_ready (= 5.0.0.pre9)
|
||||
cancancan (~> 1.15.0)
|
||||
capybara
|
||||
catalog!
|
||||
@@ -807,8 +789,8 @@ DEPENDENCIES
|
||||
combine_pdf
|
||||
cuprite
|
||||
database_cleaner
|
||||
datafoodconsortium-connector
|
||||
db2fog!
|
||||
ddtrace
|
||||
debug (>= 1.0.0)
|
||||
debugger-linecache
|
||||
devise
|
||||
@@ -819,7 +801,6 @@ DEPENDENCIES
|
||||
digest
|
||||
dotenv-rails
|
||||
factory_bot_rails (= 6.2.0)
|
||||
faraday
|
||||
ffaker
|
||||
flipper
|
||||
flipper-active_record
|
||||
@@ -849,6 +830,7 @@ DEPENDENCIES
|
||||
mime-types
|
||||
mimemagic (> 0.3.5)
|
||||
mini_portile2 (~> 2.8)
|
||||
mini_racer
|
||||
monetize (~> 1.11)
|
||||
oauth2 (~> 1.4.7)
|
||||
omniauth-rails_csrf_protection
|
||||
@@ -861,14 +843,12 @@ DEPENDENCIES
|
||||
paypal-sdk-merchant (= 1.117.2)
|
||||
pdf-reader
|
||||
pg (~> 1.2.3)
|
||||
private_address_check
|
||||
pry (~> 0.13.0)
|
||||
puma
|
||||
query_count
|
||||
rack-mini-profiler (< 3.0.0)
|
||||
rack-rewrite
|
||||
rack-timeout
|
||||
rails
|
||||
rails (>= 6.1.4)
|
||||
rails-controller-testing
|
||||
rails-erd
|
||||
rails-i18n
|
||||
@@ -897,9 +877,10 @@ DEPENDENCIES
|
||||
spring
|
||||
spring-commands-rspec
|
||||
state_machines-activerecord
|
||||
stimulus_reflex (= 3.5.0.rc2)
|
||||
stimulus_reflex (= 3.5.0.pre9)
|
||||
stringex (~> 2.8.5)
|
||||
stripe
|
||||
test-unit (~> 3.5)
|
||||
timecop
|
||||
valid_email2
|
||||
vcr
|
||||
@@ -914,7 +895,7 @@ DEPENDENCIES
|
||||
wkhtmltopdf-binary
|
||||
|
||||
RUBY VERSION
|
||||
ruby 3.1.4p223
|
||||
ruby 3.0.3p157
|
||||
|
||||
BUNDLED WITH
|
||||
2.4.3
|
||||
|
||||
4
Procfile
4
Procfile
@@ -1,5 +1,5 @@
|
||||
# Foreman Procfile. Start all dev server processes with: `foreman start`
|
||||
|
||||
rails: DEV_CACHING=true bundle exec rails s -p 3000
|
||||
rails: bundle exec rails s -p 3000
|
||||
webpack: ./bin/webpack-dev-server
|
||||
sidekiq: DEV_CACHING=true bundle exec sidekiq -q mailers -q default
|
||||
sidekiq: bundle exec sidekiq -q mailers -q default
|
||||
|
||||
@@ -12,6 +12,5 @@ angular.module("ofn.admin", [
|
||||
"admin.orders"
|
||||
]).config ($httpProvider, $locationProvider, $qProvider) ->
|
||||
$httpProvider.defaults.headers.common["Accept"] = "application/json, text/javascript, */*"
|
||||
# for the next line, you should also probably check file: app/assets/javascripts/admin/utils/utils.js.coffee
|
||||
$locationProvider.hashPrefix('')
|
||||
$qProvider.errorOnUnhandledRejections(false)
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
// jquery and angular
|
||||
//= require jquery2
|
||||
//= require jquery_ujs
|
||||
//= require jquery.ui.all
|
||||
//= require jquery.powertip
|
||||
//= require jquery.cookie
|
||||
@@ -68,6 +69,25 @@
|
||||
//= require textAngular.min.js
|
||||
//= require i18n/translations
|
||||
//= require darkswarm/i18n.translate.js
|
||||
//= require moment/min/moment.min.js
|
||||
//= require moment/locale/ar.js
|
||||
//= require moment/locale/ca.js
|
||||
//= require moment/locale/de.js
|
||||
//= require moment/locale/en-gb.js
|
||||
//= require moment/locale/es.js
|
||||
//= require moment/locale/fil.js
|
||||
//= require moment/locale/fr.js
|
||||
//= require moment/locale/it.js
|
||||
//= require moment/locale/nb.js
|
||||
//= require moment/locale/nl-be.js
|
||||
//= require moment/locale/pt-br.js
|
||||
//= require moment/locale/pt.js
|
||||
//= require moment/locale/ru.js
|
||||
//= require moment/locale/sv.js
|
||||
//= require moment/locale/tr.js
|
||||
//= require moment/locale/pl.js
|
||||
|
||||
//= require js-big-decimal/dist/web/js-big-decimal.min.js
|
||||
|
||||
// foundation
|
||||
//= require ../shared/mm-foundation-tpls-0.9.0-20180826174721.min.js
|
||||
|
||||
@@ -113,7 +113,7 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout
|
||||
(DirtyProducts.count() > 0 and confirm(t("unsaved_changes_confirmation"))) or (DirtyProducts.count() == 0)
|
||||
|
||||
editProductUrl = (product, variant) ->
|
||||
"/admin/products/" + product.id + ((if variant then "/variants/" + variant.id else "")) + "/edit"
|
||||
"/admin/products/" + product.permalink_live + ((if variant then "/variants/" + variant.id else "")) + "/edit"
|
||||
|
||||
$scope.editWarn = (product, variant) ->
|
||||
if confirm_unsaved_changes()
|
||||
@@ -162,7 +162,7 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout
|
||||
if confirm(t("are_you_sure"))
|
||||
$http(
|
||||
method: "DELETE"
|
||||
url: "/api/v0/products/" + product.id + "/variants/" + variant.id
|
||||
url: "/api/v0/products/" + product.permalink_live + "/variants/" + variant.id
|
||||
).then (response) ->
|
||||
$scope.removeVariant(product, variant)
|
||||
else
|
||||
@@ -352,6 +352,9 @@ filterSubmitProducts = (productsToFilter) ->
|
||||
if product.hasOwnProperty("inherits_properties")
|
||||
filteredProduct.inherits_properties = product.inherits_properties
|
||||
hasUpdatableProperty = true
|
||||
if product.hasOwnProperty("available_on")
|
||||
filteredProduct.available_on = product.available_on
|
||||
hasUpdatableProperty = true
|
||||
if filteredMaster?
|
||||
filteredProduct.master_attributes = filteredMaster
|
||||
hasUpdatableProperty = true
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
angular.module("admin.dropdown").directive "linksDropdown", ($window)->
|
||||
restrict: "C"
|
||||
scope:
|
||||
links: "="
|
||||
templateUrl: "admin/links_dropdown.html"
|
||||
@@ -61,6 +61,9 @@ angular.module("admin.enterprises")
|
||||
$scope.removePromoImage = ->
|
||||
$scope.performEnterpriseAction("removePromoImage", "immediate_promo_image_removal_warning", "removed_promo_image_successfully")
|
||||
|
||||
$scope.removeTermsAndConditions = ->
|
||||
$scope.performEnterpriseAction("removeTermsAndConditions", "immediate_terms_and_conditions_removal_warning", "removed_terms_and_conditions_successfully")
|
||||
|
||||
$scope.performEnterpriseAction = (enterpriseActionName, warning_message_key, success_message_key) ->
|
||||
return unless confirm($scope.translation(warning_message_key))
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
angular.module("admin.enterprises").directive 'termsAndConditionsWarning', ($rootScope, $compile, $templateCache, DialogDefaults, $timeout) ->
|
||||
restrict: 'A'
|
||||
scope: true
|
||||
|
||||
link: (scope, element, attr) ->
|
||||
# This file input click handler will hold the browser file input dialog and show a warning modal
|
||||
scope.hold_file_input_and_show_warning_modal = (event) ->
|
||||
event.preventDefault()
|
||||
scope.template = $compile($templateCache.get('admin/modals/terms_and_conditions_warning.html'))(scope)
|
||||
if scope.template.dialog
|
||||
scope.template.dialog(DialogDefaults)
|
||||
scope.template.dialog('open')
|
||||
$rootScope.$evalAsync()
|
||||
|
||||
element.bind 'click', scope.hold_file_input_and_show_warning_modal
|
||||
|
||||
# When the user presses continue in the warning modal, we open the browser file input dialog
|
||||
scope.continue = ->
|
||||
scope.template.dialog('close')
|
||||
$rootScope.$evalAsync()
|
||||
|
||||
# unbind warning modal handler and click file input again to open the browser file input dialog
|
||||
element.unbind('click').trigger('click')
|
||||
# afterwards, bind warning modal handler again so that the warning is shown the next time
|
||||
$timeout ->
|
||||
element.bind 'click', scope.hold_file_input_and_show_warning_modal
|
||||
return
|
||||
|
||||
scope.close = ->
|
||||
scope.template.dialog('close')
|
||||
$rootScope.$evalAsync()
|
||||
return
|
||||
@@ -11,6 +11,5 @@ angular.module("admin.indexUtils").factory 'SortOptions', ->
|
||||
sortingExpr
|
||||
|
||||
toggle: (predicate) ->
|
||||
# predicate is a string or an array of strings
|
||||
@reverse = (JSON.stringify(@predicate) == JSON.stringify(predicate)) && !@reverse
|
||||
@reverse = (@predicate == predicate) && !@reverse
|
||||
@predicate = predicate
|
||||
|
||||
@@ -9,7 +9,6 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
|
||||
$scope.sharedResource = false
|
||||
$scope.columns = Columns.columns
|
||||
$scope.sorting = SortOptions
|
||||
$scope.sorting.toggle("order_date")
|
||||
$scope.pagination = LineItems.pagination
|
||||
$scope.per_page_options = [
|
||||
{id: 15, name: t('js.admin.orders.index.per_page', results: 15)},
|
||||
@@ -18,16 +17,7 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
|
||||
]
|
||||
$scope.page = 1
|
||||
$scope.per_page = $scope.per_page_options[0].id
|
||||
$scope.filterByVariantId = null
|
||||
searchThrough = ["order_distributor_name",
|
||||
"order_bill_address_phone",
|
||||
"order_bill_address_firstname",
|
||||
"order_bill_address_lastname",
|
||||
"order_bill_address_full_name",
|
||||
"variant_product_supplier_name",
|
||||
"order_email",
|
||||
"order_number",
|
||||
"product_name"].join("_or_") + "_cont"
|
||||
|
||||
|
||||
$scope.confirmRefresh = ->
|
||||
LineItems.allSaved() || confirm(t("unsaved_changes_warning"))
|
||||
@@ -36,7 +26,7 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
|
||||
$scope.distributorFilter = ''
|
||||
$scope.supplierFilter = ''
|
||||
$scope.orderCycleFilter = ''
|
||||
$scope.query = ''
|
||||
$scope.quickSearch = ''
|
||||
$scope.startDate = undefined
|
||||
$scope.endDate = undefined
|
||||
event = new CustomEvent('flatpickr:clear')
|
||||
@@ -62,8 +52,6 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
|
||||
$scope.dereferenceLoadedData()
|
||||
|
||||
$scope.loadOrders = ->
|
||||
return $scope.orders = [] unless $scope.line_items.length
|
||||
|
||||
RequestMonitor.load $scope.orders = Orders.index(
|
||||
"q[id_in][]": $scope.line_items.map((line_item) -> line_item.order.id)
|
||||
)
|
||||
@@ -72,8 +60,6 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
|
||||
[formattedStartDate, formattedEndDate] = $scope.formatDates($scope.startDate, $scope.endDate)
|
||||
|
||||
RequestMonitor.load LineItems.index(
|
||||
"q[#{searchThrough}]": $scope.query,
|
||||
"q[variant_id_eq]": $scope.filterByVariantId if $scope.filterByVariantId,
|
||||
"q[order_state_not_eq]": "canceled",
|
||||
"q[order_shipment_state_not_eq]": "shipped",
|
||||
"q[order_completed_at_not_null]": "true",
|
||||
@@ -82,7 +68,6 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
|
||||
"q[order_order_cycle_id_eq]": $scope.orderCycleFilter,
|
||||
"q[order_completed_at_gteq]": if formattedStartDate then formattedStartDate else undefined,
|
||||
"q[order_completed_at_lt]": if formattedEndDate then formattedEndDate else undefined,
|
||||
"q[s]": "order_completed_at desc",
|
||||
"page": $scope.page,
|
||||
"per_page": $scope.per_page
|
||||
)
|
||||
@@ -126,16 +111,16 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
|
||||
else
|
||||
StatusMessage.display 'failure', t "unsaved_changes_error"
|
||||
|
||||
$scope.cancelOrder = (order, sendEmailCancellation, restock_items) ->
|
||||
$scope.cancelOrder = (order, sendEmailCancellation) ->
|
||||
return $http(
|
||||
method: 'GET'
|
||||
url: "/admin/orders/#{order.number}/fire?e=cancel&send_cancellation_email=#{sendEmailCancellation}&restock_items=#{restock_items}")
|
||||
url: "/admin/orders/#{order.number}/fire?e=cancel&send_cancellation_email=#{sendEmailCancellation}")
|
||||
|
||||
$scope.deleteLineItem = (lineItem) ->
|
||||
if lineItem.order.item_count == 1
|
||||
ofnCancelOrderAlert((confirm, sendEmailCancellation, restock_items) ->
|
||||
ofnCancelOrderAlert((confirm, sendEmailCancellation) ->
|
||||
if confirm
|
||||
$scope.cancelOrder(lineItem.order, sendEmailCancellation, restock_items).then(->
|
||||
$scope.cancelOrder(lineItem.order, sendEmailCancellation).then(->
|
||||
$scope.refreshData()
|
||||
)
|
||||
else
|
||||
@@ -157,11 +142,11 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
|
||||
willCancelOrders = true if (order.item_count == itemsPerOrder.get(order).length)
|
||||
|
||||
if willCancelOrders
|
||||
ofnCancelOrderAlert((confirm, sendEmailCancellation, restock_items) ->
|
||||
ofnCancelOrderAlert((confirm, sendEmailCancellation) ->
|
||||
if confirm
|
||||
itemsPerOrder.forEach (items, order) =>
|
||||
if order.item_count == items.length
|
||||
$scope.cancelOrder(order, sendEmailCancellation, restock_items).then(-> $scope.refreshData())
|
||||
$scope.cancelOrder(order, sendEmailCancellation).then(-> $scope.refreshData())
|
||||
else
|
||||
Promise.all(LineItems.delete(item) for item in items).then(-> $scope.refreshData())
|
||||
, "js.admin.deleting_item_will_cancel_order")
|
||||
@@ -183,17 +168,6 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
|
||||
$scope.setSelectedUnitsVariant = (unitsProduct,unitsVariant) ->
|
||||
$scope.selectedUnitsProduct = unitsProduct
|
||||
$scope.selectedUnitsVariant = unitsVariant
|
||||
$scope.filterByVariantId = unitsVariant.id
|
||||
$scope.page = 1
|
||||
$scope.refreshData()
|
||||
|
||||
$scope.resetSelectedUnitsVariant = ->
|
||||
$scope.selectedUnitsProduct = { }
|
||||
$scope.selectedUnitsVariant = { }
|
||||
$scope.filterByVariantId = null
|
||||
$scope.sharedResource = false
|
||||
$scope.page = 1
|
||||
$scope.refreshData()
|
||||
|
||||
$scope.getLineItemScale = (lineItem) ->
|
||||
if lineItem.units_product && lineItem.units_variant && (lineItem.units_product.variant_unit == "weight" || lineItem.units_product.variant_unit == "volume")
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
angular.module("admin.lineItems").filter "variantFilter", ->
|
||||
return (lineItems,selectedUnitsProduct,selectedUnitsVariant,sharedResource) ->
|
||||
filtered = []
|
||||
filtered.push lineItem for lineItem in lineItems when (angular.equals(selectedUnitsProduct,{}) ||
|
||||
(lineItem.units_product.id == selectedUnitsProduct.id && (sharedResource || lineItem.units_variant.id == selectedUnitsVariant.id ) ) )
|
||||
filtered
|
||||
@@ -18,6 +18,7 @@ angular.module('admin.orderCycles')
|
||||
|
||||
$scope.submit = ($event, destination) ->
|
||||
$event.preventDefault()
|
||||
NavigationCheck.clear()
|
||||
StatusMessage.display 'progress', t('js.saving')
|
||||
OrderCycle.update(destination, $scope.order_cycle_form)
|
||||
|
||||
|
||||
@@ -33,11 +33,9 @@ angular.module("admin.orderCycles").controller "OrderCyclesCtrl", ($scope, $q, C
|
||||
StatusMessage.display 'notice', "You have unsaved changes" if newVal
|
||||
|
||||
$scope.showMore = (days) ->
|
||||
orderCycles = OrderCycles.index(ams_prefix: "index",
|
||||
"q[orders_close_at_gt]": "#{daysFromToday($scope.ordersCloseAtLimit - days)}",
|
||||
"q[orders_close_at_lteq]": "#{daysFromToday($scope.ordersCloseAtLimit)}"
|
||||
)
|
||||
$scope.ordersCloseAtLimit -= days
|
||||
existingIDs = Object.keys(OrderCycles.byID)
|
||||
orderCycles = OrderCycles.index(ams_prefix: "index", "q[orders_close_at_gt]": "#{daysFromToday($scope.ordersCloseAtLimit)}", "q[id_not_in][]": existingIDs)
|
||||
orderCycles.$promise.then ->
|
||||
$scope.orderCycles.push(orderCycle) for orderCycle in orderCycles
|
||||
compileData()
|
||||
|
||||
@@ -33,4 +33,6 @@ angular.module('admin.orderCycles').factory('Enterprise', ($resource) ->
|
||||
variantsOf: (product) ->
|
||||
if product.variants.length > 0
|
||||
variant.id for variant in product.variants
|
||||
else
|
||||
[product.master_id]
|
||||
})
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
angular.module("admin.orders").controller "bulkInvoiceCtrl", ($scope, $http, $timeout) ->
|
||||
$scope.createBulkInvoice = ->
|
||||
$scope.invoice_id = null
|
||||
$scope.poll = 1
|
||||
$scope.loading = true
|
||||
$scope.message = null
|
||||
$scope.error = null
|
||||
$scope.poll_wait = 5 # 5 Seconds between each check
|
||||
$scope.poll_retries = 80 # Maximum checks before stopping
|
||||
|
||||
$http.post('/admin/orders/invoices', {order_ids: $scope.selected_orders}).then (response) ->
|
||||
$scope.invoice_id = response.data
|
||||
$scope.pollBulkInvoice()
|
||||
|
||||
$scope.pollBulkInvoice = ->
|
||||
$timeout($scope.nextPoll, $scope.poll_wait * 1000)
|
||||
|
||||
$scope.nextPoll = ->
|
||||
$http.get('/admin/orders/invoices/'+$scope.invoice_id+'/poll').then (response) ->
|
||||
$scope.loading = false
|
||||
$scope.message = t('js.admin.orders.index.bulk_invoice_created')
|
||||
|
||||
.catch (response) ->
|
||||
$scope.poll++
|
||||
|
||||
if $scope.poll > $scope.poll_retries
|
||||
$scope.loading = false
|
||||
$scope.error = t('js.admin.orders.index.bulk_invoice_failed')
|
||||
return
|
||||
|
||||
$scope.pollBulkInvoice()
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
angular.module("admin.orders").controller "ordersCtrl", ($scope, $timeout, RequestMonitor, Orders, SortOptions, $window, $filter, $location, KeyValueMapStore) ->
|
||||
$scope.RequestMonitor = RequestMonitor
|
||||
$scope.pagination = Orders.pagination
|
||||
$scope.orders = Orders.all
|
||||
$scope.sortOptions = SortOptions
|
||||
$scope.per_page_options = [
|
||||
{id: 15, name: t('js.admin.orders.index.per_page', results: 15)},
|
||||
{id: 50, name: t('js.admin.orders.index.per_page', results: 50)},
|
||||
{id: 100, name: t('js.admin.orders.index.per_page', results: 100)}
|
||||
]
|
||||
$scope.selected_orders = []
|
||||
$scope.checkboxes = {}
|
||||
$scope.selected = false
|
||||
$scope.select_all = false
|
||||
$scope.poll = 0
|
||||
$scope.rowStatus = {}
|
||||
|
||||
KeyValueMapStore.localStorageKey = 'ordersFilters'
|
||||
KeyValueMapStore.storableKeys = ["q", "sorting", "page", "per_page"]
|
||||
|
||||
$scope.initialise = ->
|
||||
unless KeyValueMapStore.restoreValues($scope)
|
||||
$scope.setDefaults()
|
||||
|
||||
$scope.fetchResults()
|
||||
|
||||
$scope.setDefaults = ->
|
||||
$scope.per_page = 15
|
||||
$scope.q = {
|
||||
completed_at_not_null: true
|
||||
}
|
||||
e = new CustomEvent("flatpickr_clear");
|
||||
window.dispatchEvent(e)
|
||||
|
||||
$scope.clearFilters = () ->
|
||||
KeyValueMapStore.clearKeyValueMap()
|
||||
$scope.setDefaults()
|
||||
$scope.fetchResults()
|
||||
|
||||
$scope.fetchResults = (page=1) ->
|
||||
startDateWithTime = $scope.appendStringIfNotEmpty($scope.q?.completed_at_gteq, ' 00:00:00')
|
||||
endDateWithTime = $scope.appendStringIfNotEmpty($scope.q?.completed_at_lteq, ' 23:59:59')
|
||||
|
||||
$scope.resetSelected()
|
||||
params = {
|
||||
'q[completed_at_gteq]': startDateWithTime,
|
||||
'q[completed_at_lteq]': endDateWithTime,
|
||||
'q[state_eq]': $scope.q?.state_eq,
|
||||
'q[number_cont]': $scope.q?.number_cont,
|
||||
'q[email_cont]': $scope.q?.email_cont,
|
||||
'q[bill_address_firstname_start]': $scope.q?.bill_address_firstname_start,
|
||||
'q[bill_address_lastname_start]': $scope.q?.bill_address_lastname_start,
|
||||
# Set default checkbox values to null. See: https://github.com/openfoodfoundation/openfoodnetwork/pull/3076#issuecomment-440010498
|
||||
'q[completed_at_not_null]': $scope.q?.completed_at_not_null || null,
|
||||
'q[distributor_id_in][]': $scope.q?.distributor_id_in,
|
||||
'q[order_cycle_id_in][]': $scope.q?.order_cycle_id_in,
|
||||
'q[s]': $scope.sorting || 'completed_at desc',
|
||||
shipping_method_id: $scope.q?.shipping_method_id,
|
||||
per_page: $scope.per_page,
|
||||
page: page
|
||||
}
|
||||
KeyValueMapStore.setStoredValues($scope)
|
||||
RequestMonitor.load(Orders.index(params).$promise)
|
||||
|
||||
$scope.appendStringIfNotEmpty = (baseString, stringToAppend) ->
|
||||
return baseString unless baseString
|
||||
return baseString if baseString.endsWith(stringToAppend)
|
||||
|
||||
baseString + stringToAppend
|
||||
|
||||
$scope.resetSelected = ->
|
||||
$scope.selected_orders.length = 0
|
||||
$scope.selected = false
|
||||
$scope.select_all = false
|
||||
$scope.checkboxes = {}
|
||||
|
||||
$scope.toggleSelection = (id) ->
|
||||
index = $scope.selected_orders.indexOf(id)
|
||||
|
||||
if index == -1
|
||||
$scope.selected_orders.push(id)
|
||||
else
|
||||
$scope.selected_orders.splice(index, 1)
|
||||
|
||||
$scope.toggleAll = ->
|
||||
$scope.selected_orders.length = 0
|
||||
$scope.orders.forEach (order) ->
|
||||
$scope.checkboxes[order.id] = $scope.select_all
|
||||
$scope.selected_orders.push order.id if $scope.select_all
|
||||
|
||||
$scope.$watch 'sortOptions', (sort) ->
|
||||
return unless sort && sort.predicate != ""
|
||||
|
||||
$scope.sorting = sort.getSortingExpr()
|
||||
$scope.fetchResults()
|
||||
, true
|
||||
|
||||
$scope.capturePayment = (order) ->
|
||||
$scope.rowAction('capture', order)
|
||||
|
||||
$scope.shipOrder = (order) ->
|
||||
$scope.rowAction('ship', order)
|
||||
|
||||
$scope.rowAction = (action, order) ->
|
||||
$scope.rowStatus[order.id] = "loading"
|
||||
|
||||
Orders[action](order).$promise.then (data) ->
|
||||
$scope.rowStatus[order.id] = "success"
|
||||
$timeout(->
|
||||
$scope.rowStatus[order.id] = null
|
||||
, 1500)
|
||||
, (error) ->
|
||||
$scope.rowStatus[order.id] = "error"
|
||||
|
||||
$scope.changePage = (newPage) ->
|
||||
$scope.page = newPage
|
||||
$scope.fetchResults(newPage)
|
||||
@@ -0,0 +1,5 @@
|
||||
angular.module("admin.orders").directive "invoicesModal", ($modal) ->
|
||||
restrict: 'C'
|
||||
link: (scope, elem, attrs, ctrl) ->
|
||||
elem.on "click", (ev) =>
|
||||
scope.uploadModal = $modal.open(templateUrl: 'admin/modals/bulk_invoice.html', controller: ctrl, scope: scope, windowClass: 'simple-modal')
|
||||
@@ -14,4 +14,7 @@ angular.module("admin.resources").factory 'EnterpriseResource', ($resource) ->
|
||||
'removePromoImage':
|
||||
url: '/api/v0/enterprises/:id/promo_image.json'
|
||||
method: 'DELETE'
|
||||
'removeTermsAndConditions':
|
||||
url: '/api/v0/enterprises/:id/terms_and_conditions.json'
|
||||
method: 'DELETE'
|
||||
})
|
||||
|
||||
@@ -63,3 +63,4 @@ angular.module("admin.resources").factory 'Enterprises', ($q, $filter, Enterpris
|
||||
|
||||
removeLogo: performActionOnEnterpriseResource(EnterpriseResource.removeLogo)
|
||||
removePromoImage: performActionOnEnterpriseResource(EnterpriseResource.removePromoImage)
|
||||
removeTermsAndConditions: performActionOnEnterpriseResource(EnterpriseResource.removeTermsAndConditions)
|
||||
|
||||
15
app/assets/javascripts/admin/spree/images/index.js.coffee
Normal file
15
app/assets/javascripts/admin/spree/images/index.js.coffee
Normal file
@@ -0,0 +1,15 @@
|
||||
$ ->
|
||||
($ '#new_image_link').click (event) ->
|
||||
event.preventDefault()
|
||||
|
||||
($ '.no-objects-found').hide()
|
||||
|
||||
($ this).hide()
|
||||
$.ajax
|
||||
type: 'GET'
|
||||
url: @href
|
||||
data: (
|
||||
authenticity_token: AUTH_TOKEN
|
||||
)
|
||||
success: (r) ->
|
||||
($ '#images').html r
|
||||
7
app/assets/javascripts/admin/spree/images/new.js.coffee
Normal file
7
app/assets/javascripts/admin/spree/images/new.js.coffee
Normal file
@@ -0,0 +1,7 @@
|
||||
($ '#cancel_link').click (event) ->
|
||||
event.preventDefault()
|
||||
|
||||
($ '.no-objects-found').show()
|
||||
|
||||
($ '#new_image_link').show()
|
||||
($ '#images').html('')
|
||||
@@ -15,7 +15,7 @@ $(document).ready(function() {
|
||||
console.log(msg);
|
||||
});
|
||||
}
|
||||
$('.admin-order-edit-form a.ship').click(handle_ship_click);
|
||||
$('[data-hook=admin_order_edit_form] a.ship').click(handle_ship_click);
|
||||
|
||||
//handle shipping method edit click
|
||||
$('a.edit-method').click(toggleMethodEdit);
|
||||
@@ -37,7 +37,7 @@ $(document).ready(function() {
|
||||
console.log(msg);
|
||||
});
|
||||
}
|
||||
$('.admin-order-edit-form a.save-method').click(handle_shipping_method_save);
|
||||
$('[data-hook=admin_order_edit_form] a.save-method').click(handle_shipping_method_save);
|
||||
|
||||
//handle tracking info edit/delete
|
||||
|
||||
@@ -64,8 +64,8 @@ $(document).ready(function() {
|
||||
return Spree.url( Spree.routes.orders_api + "/" + order_number + "/shipments/" + shipmentNumber + ".json");
|
||||
}
|
||||
|
||||
$('.admin-order-edit-form a.save-tracking').click(saveTrackingInfo);
|
||||
$('.admin-order-edit-form a.delete-tracking').click(deleteTrackingInfo);
|
||||
$('[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
|
||||
|
||||
@@ -96,8 +96,8 @@ $(document).ready(function() {
|
||||
});
|
||||
}
|
||||
|
||||
$('.admin-order-edit-form a.save-note').click(saveNote);
|
||||
$('.admin-order-edit-form a.delete-note').click(deleteNote);
|
||||
$('[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) {
|
||||
|
||||
@@ -4,8 +4,7 @@ $(document).ready(function() {
|
||||
|
||||
initAlert()
|
||||
initConfirm()
|
||||
initButtonCancel()
|
||||
initLinkCancel()
|
||||
initCancelOrder()
|
||||
|
||||
if ($('#variant_autocomplete_template').length > 0) {
|
||||
window.variantTemplate = Handlebars.compile($('#variant_autocomplete_template').text());
|
||||
@@ -100,7 +99,6 @@ adjustItems = function(shipment_number, variant_id, quantity, restock_item){
|
||||
doAdjustItems(shipment_number, variant_id, quantity, inventory_units, restock_item, () => {
|
||||
var redirectTo = new URL(Spree.routes.cancel_order.toString());
|
||||
redirectTo.searchParams.append("send_cancellation_email", sendEmailCancellation);
|
||||
redirectTo.searchParams.append("restock_item", restock_item);
|
||||
window.location.href = redirectTo.toString();
|
||||
});
|
||||
}
|
||||
@@ -278,23 +276,17 @@ ofnConfirm = function(callback) {
|
||||
$('#custom-confirm').show();
|
||||
}
|
||||
|
||||
initCancelAction = function(e){
|
||||
ofnCancelOrderAlert((confirm, sendEmailCancellation, restock_items) => {
|
||||
if (confirm) {
|
||||
var redirectTo = new URL(Spree.routes.cancel_order.toString());
|
||||
redirectTo.searchParams.append("send_cancellation_email", sendEmailCancellation);
|
||||
redirectTo.searchParams.append("restock_items", restock_items);
|
||||
window.location.href = redirectTo.toString();
|
||||
}
|
||||
initCancelOrder = function() {
|
||||
$('#cancel_order_form').submit(function(e){
|
||||
ofnCancelOrderAlert((confirm, sendEmailCancellation, restock_items) => {
|
||||
if (confirm) {
|
||||
var redirectTo = new URL(Spree.routes.cancel_order.toString());
|
||||
redirectTo.searchParams.append("send_cancellation_email", sendEmailCancellation);
|
||||
redirectTo.searchParams.append("restock_items", restock_items);
|
||||
window.location.href = redirectTo.toString();
|
||||
}
|
||||
});
|
||||
e.preventDefault();
|
||||
return false;
|
||||
});
|
||||
e.preventDefault();
|
||||
return false;
|
||||
};
|
||||
|
||||
initButtonCancel = function() {
|
||||
$('#cancel_order_form').submit(initCancelAction)
|
||||
}
|
||||
|
||||
initLinkCancel = function() {
|
||||
$('#links-dropdown a[href$="cancel"]').click(initCancelAction);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ handle_move = (e, data) ->
|
||||
node = data.rslt.o
|
||||
new_parent = data.rslt.np
|
||||
|
||||
url = new URL(Spree.routes.admin_taxonomy_taxons)
|
||||
url = new URL(base_url)
|
||||
url.pathname = url.pathname + '/' + node.attr("id")
|
||||
data = {
|
||||
_method: "put",
|
||||
|
||||
@@ -10,12 +10,6 @@ angular.module("admin.utils").directive "variantAutocomplete", ($timeout) ->
|
||||
element.select2
|
||||
placeholder: t('admin.orders.select_variant')
|
||||
minimumInputLength: 3
|
||||
formatInputTooShort: ->
|
||||
t('admin.select2.minimal_search_length', count: 3)
|
||||
formatSearching: ->
|
||||
t('admin.select2.searching')
|
||||
formatNoMatches: ->
|
||||
t('admin.select2.no_matches')
|
||||
ajax:
|
||||
url: Spree.routes.variants_search
|
||||
datatype: "json"
|
||||
|
||||
@@ -5,8 +5,8 @@ angular.module("admin.utils").factory "StatusMessage", ->
|
||||
alert: {style: {color: 'grey'}}
|
||||
notice: {style: {color: 'grey'}}
|
||||
success: {style: {color: '#9fc820'}}
|
||||
failure: {style: {color: '#C85136'}}
|
||||
error: {style: {color: '#C85136'}}
|
||||
failure: {style: {color: '#da5354'}}
|
||||
error: {style: {color: '#da5354'}}
|
||||
|
||||
statusMessage:
|
||||
text: ""
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
angular.module("admin.utils", ["templates", "ngSanitize"]).config ($httpProvider, $locationProvider) ->
|
||||
# for the next line, you should also probably check file: app/assets/javascripts/admin/admin_ofn.js.coffee
|
||||
$locationProvider.hashPrefix('')
|
||||
$httpProvider.defaults.headers.common["Accept"] = "application/json, text/javascript, */*"
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
// This is a manifest file that'll be compiled into including all the files listed below.
|
||||
// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
|
||||
// be included in the compiled file accessible from http://example.com/assets/application.js
|
||||
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
||||
// the compiled file.
|
||||
//
|
||||
|
||||
//= require jquery2
|
||||
//= require admin/spree/spree-select2
|
||||
//= require admin/spree/handlebar_extensions
|
||||
|
||||
//= require i18n/translations
|
||||
//= require darkswarm/i18n.translate.js
|
||||
|
||||
window.angular = { module: function(noop){ return { value: function(){} } } }
|
||||
@@ -29,6 +29,24 @@
|
||||
#
|
||||
#= require angular-flash.min.js
|
||||
#
|
||||
#= require moment/min/moment.min.js
|
||||
#= require moment/locale/ar.js
|
||||
#= require moment/locale/ca.js
|
||||
#= require moment/locale/de.js
|
||||
#= require moment/locale/en-gb.js
|
||||
#= require moment/locale/es.js
|
||||
#= require moment/locale/fil.js
|
||||
#= require moment/locale/fr.js
|
||||
#= require moment/locale/it.js
|
||||
#= require moment/locale/nb.js
|
||||
#= require moment/locale/nl-be.js
|
||||
#= require moment/locale/pt-br.js
|
||||
#= require moment/locale/pt.js
|
||||
#= require moment/locale/ru.js
|
||||
#= require moment/locale/sv.js
|
||||
#= require moment/locale/tr.js
|
||||
#= require moment/locale/pl.js
|
||||
#
|
||||
#= require modernizr
|
||||
#
|
||||
#= require foundation-sites/js/foundation.js
|
||||
@@ -49,3 +67,11 @@ document.addEventListener "turbo:before-render", ->
|
||||
rootscope = null
|
||||
window.injector = null
|
||||
true
|
||||
|
||||
document.addEventListener "ajax:beforeSend", (event) =>
|
||||
window.Turbo.navigator.adapter.progressBar.setValue(0)
|
||||
window.Turbo.navigator.adapter.progressBar.show()
|
||||
|
||||
document.addEventListener "ajax:complete", (event) =>
|
||||
window.Turbo.navigator.adapter.progressBar.setValue(100)
|
||||
window.Turbo.navigator.adapter.progressBar.hide()
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
angular.module('Darkswarm').controller "AccordionCtrl", ($scope, localStorageService, $timeout, $document, CurrentHub) ->
|
||||
$scope.accordionSections = ["details", "billing", "shipping", "payment"]
|
||||
$scope.accordion = { details: true, billing: true, shipping: true, payment: true }
|
||||
|
||||
$scope.show = (section) ->
|
||||
$scope.accordion[section] = true
|
||||
|
||||
$scope.scrollTo = (section) ->
|
||||
# Scrolling is confused by our position:fixed top bar - add an offset to scroll
|
||||
# to the correct location, plus 5px buffer
|
||||
offset_height = $("nav.top-bar").height() + 5
|
||||
$document.scrollTo($("##{section}"), offset_height, 400)
|
||||
|
||||
$scope.$on 'purchaseFormInvalid', (event, form) ->
|
||||
# Scroll to first invalid section
|
||||
for section in $scope.accordionSections
|
||||
if not form[section].$valid
|
||||
$scope.show section
|
||||
$timeout ->
|
||||
$scope.scrollTo(section)
|
||||
, 50
|
||||
break
|
||||
@@ -0,0 +1,12 @@
|
||||
angular.module('Darkswarm').controller "BillingCtrl", ($scope, $timeout, $controller) ->
|
||||
angular.extend this, $controller('FieldsetMixin', {$scope: $scope})
|
||||
|
||||
$scope.name = "billing"
|
||||
$scope.nextPanel = "shipping"
|
||||
|
||||
$scope.summary = ->
|
||||
[$scope.order.bill_address.address1,
|
||||
$scope.order.bill_address.city,
|
||||
$scope.order.bill_address.zipcode]
|
||||
|
||||
$timeout $scope.onTimeout
|
||||
@@ -0,0 +1,43 @@
|
||||
angular.module('Darkswarm').controller "CheckoutCtrl", ($scope, localStorageService, Checkout, CurrentUser, CurrentHub, $http) ->
|
||||
$scope.Checkout = Checkout
|
||||
$scope.submitted = false
|
||||
|
||||
# Bind to local storage
|
||||
$scope.fieldsToBind = ["bill_address", "email", "payment_method_id", "shipping_method_id", "ship_address"]
|
||||
prefix = "order_#{Checkout.order.id}#{CurrentUser.id or ""}#{CurrentHub.hub.id}"
|
||||
|
||||
for field in $scope.fieldsToBind
|
||||
localStorageService.bind $scope, "Checkout.order.#{field}", Checkout.order[field], "#{prefix}_#{field}"
|
||||
|
||||
localStorageService.bind $scope, "Checkout.ship_address_same_as_billing", true, "#{prefix}_sameasbilling"
|
||||
localStorageService.bind $scope, "Checkout.default_bill_address", false, "#{prefix}_defaultasbilladdress"
|
||||
localStorageService.bind $scope, "Checkout.default_ship_address", false, "#{prefix}_defaultasshipaddress"
|
||||
|
||||
$scope.order = Checkout.order # Ordering is important
|
||||
$scope.secrets = Checkout.secrets
|
||||
|
||||
$scope.enabled = !!CurrentUser.id?
|
||||
|
||||
$scope.purchase = (event, form) ->
|
||||
event.preventDefault()
|
||||
$scope.formdata = form
|
||||
$scope.submitted = true
|
||||
|
||||
if CurrentUser.id
|
||||
$scope.validateForm(form)
|
||||
else
|
||||
$scope.ensureUserIsGuest()
|
||||
|
||||
$scope.validateForm = ->
|
||||
if $scope.formdata.$valid
|
||||
$scope.Checkout.purchase()
|
||||
else
|
||||
$scope.$broadcast 'purchaseFormInvalid', $scope.formdata
|
||||
|
||||
$scope.ensureUserIsGuest = (callback = null) ->
|
||||
$http.post("/user/registered_email", {email: $scope.order.email})
|
||||
.then (response)->
|
||||
window.CableReady.perform(response.data)
|
||||
.catch ->
|
||||
$scope.validateForm() if $scope.submitted
|
||||
callback() if callback
|
||||
@@ -0,0 +1,8 @@
|
||||
angular.module('Darkswarm').controller "CountryCtrl", ($scope, availableCountries) ->
|
||||
|
||||
$scope.countries = availableCountries
|
||||
|
||||
$scope.countriesById = $scope.countries.reduce (obj, country) ->
|
||||
obj[country.id] = country
|
||||
obj
|
||||
, {}
|
||||
@@ -0,0 +1,24 @@
|
||||
angular.module('Darkswarm').controller "DetailsCtrl", ($scope, $timeout, $http, CurrentUser, SpreeUser, $controller) ->
|
||||
angular.extend this, $controller('FieldsetMixin', {$scope: $scope})
|
||||
|
||||
$scope.name = "details"
|
||||
$scope.nextPanel = "billing"
|
||||
|
||||
$scope.login_or_next = (event) ->
|
||||
event.preventDefault()
|
||||
unless CurrentUser.id
|
||||
$scope.ensureUserIsGuest($scope.next)
|
||||
return
|
||||
|
||||
$scope.next()
|
||||
|
||||
$scope.summary = ->
|
||||
[$scope.fullName(),
|
||||
$scope.order.email,
|
||||
$scope.order.bill_address.phone]
|
||||
|
||||
$scope.fullName = ->
|
||||
[$scope.order.bill_address.firstname ? null,
|
||||
$scope.order.bill_address.lastname ? null].join(" ").trim()
|
||||
|
||||
$timeout $scope.onTimeout
|
||||
@@ -0,0 +1,19 @@
|
||||
angular.module('Darkswarm').controller "PaymentCtrl", ($scope, $timeout, savedCreditCards, Dates, $controller) ->
|
||||
angular.extend this, $controller('FieldsetMixin', {$scope: $scope})
|
||||
|
||||
$scope.savedCreditCards = savedCreditCards
|
||||
$scope.name = "payment"
|
||||
$scope.months = Dates.months
|
||||
$scope.years = Dates.years
|
||||
|
||||
$scope.secrets.card_month = "1"
|
||||
$scope.secrets.card_year = moment().year()
|
||||
|
||||
for card in savedCreditCards when card.is_default
|
||||
$scope.secrets.selected_card = card.id
|
||||
break
|
||||
|
||||
$scope.summary = ->
|
||||
[$scope.Checkout.paymentMethod()?.name]
|
||||
|
||||
$timeout $scope.onTimeout
|
||||
@@ -0,0 +1,11 @@
|
||||
angular.module('Darkswarm').controller "ShippingCtrl", ($scope, $timeout, ShippingMethods, $controller) ->
|
||||
angular.extend this, $controller('FieldsetMixin', {$scope: $scope})
|
||||
|
||||
$scope.ShippingMethods = ShippingMethods
|
||||
$scope.name = "shipping"
|
||||
$scope.nextPanel = "payment"
|
||||
|
||||
$scope.summary = ->
|
||||
[$scope.Checkout.shippingMethod()?.name]
|
||||
|
||||
$timeout $scope.onTimeout
|
||||
@@ -25,8 +25,6 @@ angular.module('Darkswarm').controller "OrderCycleChangeCtrl", ($scope, $rootSco
|
||||
Cart.reloadFinalisedLineItems()
|
||||
ChangeableOrdersAlert.reload()
|
||||
$rootScope.$broadcast 'orderCycleSelected'
|
||||
event = new CustomEvent('orderCycleSelected')
|
||||
window.dispatchEvent(event)
|
||||
|
||||
$scope.closesInLessThan3Months = () ->
|
||||
moment().diff(moment(OrderCycle.orders_close_at(), "YYYY-MM-DD HH:mm:SS Z"), 'days') > -75
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
angular.module('Darkswarm').controller "PageSelectionCtrl", ($scope, $rootScope, $location) ->
|
||||
$scope.selectedPage = ->
|
||||
# The path looks like `/contact` for the URL `https://ofn.org/shop#/contact`.
|
||||
# We remove the slash at the beginning.
|
||||
page = $location.path()[1..]
|
||||
|
||||
return $scope.whitelist[0] unless page
|
||||
|
||||
# If the path points to an unrelated path like `/login`, stay where we were.
|
||||
return $scope.lastPage unless page in $scope.whitelist
|
||||
|
||||
$scope.lastPage = page
|
||||
page
|
||||
|
||||
$scope.whitelistPages = (pages) ->
|
||||
$scope.whitelist = pages
|
||||
$scope.lastPage = pages[0]
|
||||
|
||||
# when an order cycle is changed, ensure the shop tab is active to save a click
|
||||
$rootScope.$on "orderCycleSelected", ->
|
||||
if $scope.selectedPage() != "shop"
|
||||
$location.path("shop")
|
||||
@@ -2,7 +2,6 @@ angular.module('Darkswarm').factory "EnterpriseModal", ($modal, $rootScope, $htt
|
||||
# Build a modal popup for an enterprise.
|
||||
new class EnterpriseModal
|
||||
open: (enterprise)->
|
||||
return if enterprise.visible == 'hidden'
|
||||
scope = $rootScope.$new(true) # Spawn an isolate to contain the enterprise
|
||||
scope.embedded_layout = window.location.search.indexOf("embedded_shopfront=true") != -1
|
||||
|
||||
|
||||
@@ -55,10 +55,6 @@ angular.module('Darkswarm').factory "EnterpriseRegistrationService", ($http, Reg
|
||||
).catch((response) ->
|
||||
Loading.clear()
|
||||
alert(t('failed_to_update_enterprise_unknown'))
|
||||
if response.data.errors.instagram
|
||||
igErr = document.querySelector("#instagram-error")
|
||||
igErr.style.display = 'block'
|
||||
igErr.textContent = response.data.errors.instagram[0]
|
||||
)
|
||||
|
||||
prepare: =>
|
||||
|
||||
@@ -33,9 +33,9 @@ angular.module('Darkswarm').factory 'Products', (OrderCycleResource, OrderCycle,
|
||||
prices = (v.price for v in product.variants)
|
||||
product.price = Math.min.apply(null, prices)
|
||||
product.hasVariants = product.variants?.length > 0
|
||||
product.primaryImage = product.image?.small_url if product.image
|
||||
product.primaryImage = product.images[0]?.small_url if product.images
|
||||
product.primaryImageOrMissing = product.primaryImage || "/noimage/small.png"
|
||||
product.largeImage = product.image?.large_url if product.image
|
||||
product.largeImage = product.images[0]?.large_url if product.images
|
||||
|
||||
dereference: ->
|
||||
for product in @fetched_products
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
.ofn-drop-down
|
||||
%span
|
||||
%i.icon-check
|
||||
{{ 'admin.actions' | t }}
|
||||
%i{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" }
|
||||
%div.menu{ 'ng-show' => "expanded" }
|
||||
%a.menu_item{ 'ng-repeat' => "link in links", href: '{{link.url}}', target: "{{link.target || '_self'}}", data: { method: "{{ link.method || 'get' }}", confirm: "{{link.confirm}}" } }
|
||||
%span
|
||||
%i{ ng: { class: "link.icon" } }
|
||||
%span {{ link.name }}
|
||||
@@ -0,0 +1,14 @@
|
||||
%div
|
||||
.margin-bottom-30.text-center
|
||||
.text-big
|
||||
{{ 'js.admin.modals.terms_and_conditions_warning.title' | t }}
|
||||
.margin-bottom-30
|
||||
%p
|
||||
{{ 'js.admin.modals.terms_and_conditions_warning.message_1' | t }}
|
||||
.margin-bottom-30
|
||||
%p
|
||||
{{ 'js.admin.modals.terms_and_conditions_warning.message_2' | t }}
|
||||
|
||||
.text-center
|
||||
%input.button.red{ type: 'button', value: t('js.admin.modals.close'), ng: { click: 'close()' } }
|
||||
%input.button.red{ type: 'button', value: t('js.admin.modals.continue'), ng: { click: 'continue()' } }
|
||||
@@ -3,7 +3,7 @@
|
||||
.seven.columns.alpha
|
||||
%h5#status-message{ ng: { show: "StatusMessage.invalidMessage == ''", style: 'StatusMessage.statusMessage.style' } }
|
||||
{{ StatusMessage.statusMessage.text || " " }}
|
||||
%h5#status-message{ ng: { show: "StatusMessage.invalidMessage !== ''" }, style: 'color: #C85136' }
|
||||
%h5#status-message{ ng: { show: "StatusMessage.invalidMessage !== ''" }, style: 'color: #da5354' }
|
||||
{{ StatusMessage.invalidMessage || " " }}
|
||||
.nine.columns.omega.text-right{ ng: { transclude: true } }
|
||||
|
||||
|
||||
@@ -15,6 +15,6 @@
|
||||
|
||||
.columns.small-12.medium-6.large-6.product-img
|
||||
%img{"ng-src" => "{{::product.largeImage}}", "ng-if" => "::product.largeImage"}
|
||||
%img.placeholder{ src: Spree::Image.default_image_url(:large), "ng-if" => "::!product.largeImage"}
|
||||
%img.placeholder{ src: "/noimage/large.png", "ng-if" => "::!product.largeImage"}
|
||||
|
||||
%ng-include{src: "'partials/close.html'"}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class ScopedChannel < ApplicationCable::Channel
|
||||
class << self
|
||||
def for_id(id)
|
||||
"ScopedChannel:#{id}"
|
||||
end
|
||||
end
|
||||
|
||||
def subscribed
|
||||
stream_from "ScopedChannel:#{params[:id]}"
|
||||
end
|
||||
end
|
||||
@@ -1,13 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class SessionChannel < ApplicationCable::Channel
|
||||
def self.for_request(request)
|
||||
"SessionChannel:#{request.session.id}"
|
||||
end
|
||||
|
||||
def subscribed
|
||||
return reject if current_user.nil?
|
||||
|
||||
stream_from "SessionChannel:#{session_id}"
|
||||
end
|
||||
end
|
||||
@@ -1,12 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class ConfirmModalComponent < ModalComponent
|
||||
def initialize(id:, confirm_actions: nil, reflex: nil, controller: nil, message: nil, confirm_reflexes: nil)
|
||||
def initialize(id:, confirm_actions: nil, controllers: nil, message: nil)
|
||||
super(id: id, close_button: true)
|
||||
@confirm_actions = confirm_actions
|
||||
@reflex = reflex
|
||||
@confirm_reflexes = confirm_reflexes
|
||||
@controller = controller
|
||||
@controllers = controllers
|
||||
@message = message
|
||||
end
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
%div{ id: @id, "data-controller": "modal #{@controller}", "data-action": "keyup@document->modal#closeIfEscapeKey", "data-#{@controller}-reflex-value": @reflex }
|
||||
%div{ id: @id, "data-controller": "modal #{@controllers}", "data-action": "keyup@document->modal#closeIfEscapeKey" }
|
||||
.reveal-modal-bg.fade{ "data-modal-target": "background", "data-action": "click->modal#close" }
|
||||
.reveal-modal.fade.tiny.help-modal{ "data-modal-target": "modal" }
|
||||
= content
|
||||
@@ -7,4 +7,4 @@
|
||||
|
||||
.modal-actions
|
||||
%input{ class: "button icon-plus #{close_button_class}", type: 'button', value: t('js.admin.modals.cancel'), "data-action": "click->modal#close" }
|
||||
%input{ class: "button icon-plus primary", type: 'button', value: t('js.admin.modals.confirm'), "data-action": @confirm_actions, "data-reflex": @confirm_reflexes }
|
||||
%input{ class: "button icon-plus primary", type: 'button', value: t('js.admin.modals.confirm'), "data-action": @confirm_actions }
|
||||
|
||||
@@ -6,7 +6,7 @@ class ProductComponent < ViewComponentReflex::Component
|
||||
def initialize(product:, columns:)
|
||||
super
|
||||
@product = product
|
||||
@image = @product.image if product.image.present?
|
||||
@image = @product.images[0] if product.images.any?
|
||||
@columns = columns.map do |c|
|
||||
{
|
||||
id: c[:value],
|
||||
@@ -28,7 +28,7 @@ class ProductComponent < ViewComponentReflex::Component
|
||||
when 'price'
|
||||
@product.price
|
||||
when 'unit'
|
||||
"#{@product.variants.first.unit_value} #{@product.variant_unit}"
|
||||
"#{@product.unit_value} #{@product.variant_unit}"
|
||||
when 'producer'
|
||||
@product.supplier.name
|
||||
when 'category'
|
||||
@@ -43,6 +43,8 @@ class ProductComponent < ViewComponentReflex::Component
|
||||
@product.tax_category.name
|
||||
when 'inherits_properties'
|
||||
@product.inherits_properties
|
||||
when 'available_on'
|
||||
format_date(@product.available_on)
|
||||
when 'import_date'
|
||||
format_date(@product.import_date)
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%tr
|
||||
- @columns.each do |column|
|
||||
%td.products_column{class: column[:id]}
|
||||
- if column[:id] == "name" && @image&.attachment.present?
|
||||
- if column[:id] == "name" && @image
|
||||
= image_tag @image.url(:mini)
|
||||
= column[:value]
|
||||
|
||||
@@ -17,6 +17,7 @@ class ProductsTableComponent < ViewComponentReflex::Component
|
||||
label: I18n.t("admin.products_page.columns_selector.inherits_properties"),
|
||||
value: "inherits_properties"
|
||||
},
|
||||
{ label: I18n.t("admin.products_page.columns_selector.available_on"), value: "available_on" },
|
||||
{ label: I18n.t("admin.products_page.columns_selector.import_date"), value: "import_date" }
|
||||
].sort do |a, b|
|
||||
a[:label] <=> b[:label]
|
||||
@@ -167,12 +168,13 @@ class ProductsTableComponent < ViewComponentReflex::Component
|
||||
|
||||
def product_query_includes
|
||||
[
|
||||
:image,
|
||||
master: [:images],
|
||||
variants: [
|
||||
:default_price,
|
||||
:stock_locations,
|
||||
:stock_items,
|
||||
:variant_overrides
|
||||
:variant_overrides,
|
||||
{ option_values: :option_type }
|
||||
]
|
||||
]
|
||||
end
|
||||
|
||||
@@ -11,8 +11,9 @@ module Admin
|
||||
|
||||
@line_items = order_permissions.
|
||||
editable_line_items.where(order_id: orders).
|
||||
includes(:variant).
|
||||
ransack(params[:q]).result.order(:id)
|
||||
includes(variant: { option_values: :option_type }).
|
||||
ransack(params[:q]).result.
|
||||
reorder('spree_line_items.order_id ASC, spree_line_items.id ASC')
|
||||
|
||||
@pagy, @line_items = pagy(@line_items) if pagination_required?
|
||||
|
||||
@@ -34,8 +35,7 @@ module Admin
|
||||
# and https://www.postgresql.org/docs/current/static/sql-select.html#SQL-FOR-UPDATE-SHARE
|
||||
order.with_lock do
|
||||
if order.contents.update_item(@line_item, line_item_params)
|
||||
# No Content, does not trigger ng resource auto-update
|
||||
render body: nil, status: :no_content
|
||||
render body: nil, status: :no_content # No Content, does not trigger ng resource auto-update
|
||||
else
|
||||
render json: { errors: @line_item.errors }, status: :precondition_failed
|
||||
end
|
||||
|
||||
@@ -18,8 +18,6 @@ module Admin
|
||||
end
|
||||
end
|
||||
|
||||
ContentConfig.updated_at = Time.zone.now
|
||||
|
||||
flash[:success] =
|
||||
t(:successfully_updated, resource: I18n.t('admin.contents.edit.your_content'))
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
require 'open_food_network/address_finder'
|
||||
|
||||
# rubocop:disable Metrics/ClassLength
|
||||
module Admin
|
||||
class CustomersController < Admin::ResourceController
|
||||
before_action :load_managed_shops, only: :index, if: :html_request?
|
||||
@@ -36,10 +35,8 @@ module Admin
|
||||
end
|
||||
|
||||
def create
|
||||
@customer = Customer.find_or_initialize_by(customer_params.slice(:email, :enterprise_id))
|
||||
|
||||
@customer = Customer.new(customer_params)
|
||||
if user_can_create_customer?
|
||||
@customer.created_manually = true
|
||||
if @customer.save
|
||||
tag_rule_mapping = TagRule.mapping_for(Enterprise.where(id: @customer.enterprise))
|
||||
render_as_json @customer, tag_rule_mapping: tag_rule_mapping
|
||||
@@ -70,7 +67,7 @@ module Admin
|
||||
|
||||
def collection
|
||||
if json_request? && params[:enterprise_id].present?
|
||||
CustomersWithBalance.new(customers).query.
|
||||
CustomersWithBalance.new(managed_enterprise_id).query.
|
||||
includes(
|
||||
:enterprise,
|
||||
{ bill_address: [:state, :country] },
|
||||
@@ -82,15 +79,6 @@ module Admin
|
||||
end
|
||||
end
|
||||
|
||||
def customers
|
||||
return @customers if @customers.present?
|
||||
|
||||
@customers = Customer.visible.managed_by(spree_current_user)
|
||||
return @customers if params[:enterprise_id].blank?
|
||||
|
||||
@customers = @customers.where(enterprise_id: params[:enterprise_id])
|
||||
end
|
||||
|
||||
def managed_enterprise_id
|
||||
@managed_enterprise_id ||= Enterprise.managed_by(spree_current_user).
|
||||
select('enterprises.id').find_by(id: params[:enterprise_id])
|
||||
@@ -132,4 +120,3 @@ module Admin
|
||||
end
|
||||
end
|
||||
end
|
||||
# rubocop:enable Metrics/ClassLength
|
||||
|
||||
@@ -7,7 +7,6 @@ module Admin
|
||||
before_action :load_enterprise_fee_set, only: :index
|
||||
before_action :load_data
|
||||
before_action :check_enterprise_fee_input, only: [:bulk_update]
|
||||
before_action :check_calculators_compatibility_with_taxes, only: [:bulk_update]
|
||||
|
||||
def index
|
||||
@include_calculators = params[:include_calculators].present?
|
||||
@@ -25,6 +24,7 @@ module Admin
|
||||
format.json {
|
||||
render_as_json @collection, controller: self, include_calculators: @include_calculators
|
||||
}
|
||||
# format.json { @presented_collection = @collection.each_with_index.map { |ef, i| EnterpriseFeePresenter.new(self, ef, i) } }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -62,7 +62,7 @@ module Admin
|
||||
when :for_order_cycle
|
||||
order_cycle = OrderCycle.find_by(id: params[:order_cycle_id]) if params[:order_cycle_id]
|
||||
coordinator = Enterprise.find_by(id: params[:coordinator_id]) if params[:coordinator_id]
|
||||
order_cycle ||= OrderCycle.new(coordinator: coordinator) if coordinator.present?
|
||||
order_cycle = OrderCycle.new(coordinator: coordinator) if order_cycle.nil? && coordinator.present?
|
||||
enterprises = OpenFoodNetwork::OrderCyclePermissions.new(spree_current_user,
|
||||
order_cycle).visible_enterprises
|
||||
EnterpriseFee.for_enterprises(enterprises).order('enterprise_id', 'fee_type', 'name')
|
||||
@@ -119,17 +119,5 @@ module Admin
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def check_calculators_compatibility_with_taxes
|
||||
enterprise_fee_bulk_params['collection_attributes'].each do |_, enterprise_fee|
|
||||
next unless enterprise_fee['inherits_tax_category'] == "true"
|
||||
next unless EnterpriseFee::PER_ORDER_CALCULATORS.include?(enterprise_fee['calculator_type'])
|
||||
|
||||
flash[:error] = I18n.t(
|
||||
'activerecord.errors.models.enterprise_fee.inherit_tax_requires_per_item_calculator'
|
||||
)
|
||||
return redirect_to redirect_path
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -16,8 +16,7 @@ module Admin
|
||||
@enterprise_relationship = EnterpriseRelationship.new enterprise_relationship_params
|
||||
|
||||
if @enterprise_relationship.save
|
||||
render plain: Api::Admin::EnterpriseRelationshipSerializer
|
||||
.new(@enterprise_relationship).to_json
|
||||
render plain: Api::Admin::EnterpriseRelationshipSerializer.new(@enterprise_relationship).to_json
|
||||
else
|
||||
render status: :bad_request,
|
||||
json: { errors: @enterprise_relationship.errors.full_messages.join(', ') }
|
||||
|
||||
@@ -29,6 +29,7 @@ module Admin
|
||||
|
||||
after_action :geocode_address_if_use_geocoder, only: [:create, :update]
|
||||
|
||||
helper 'spree/products'
|
||||
include OrderCyclesHelper
|
||||
|
||||
def index
|
||||
@@ -46,11 +47,10 @@ module Admin
|
||||
def edit
|
||||
@object = Enterprise.where(permalink: params[:id]).
|
||||
includes(users: [:ship_address, :bill_address]).first
|
||||
@object.build_custom_tab if @object.custom_tab.nil?
|
||||
if params[:stimulus]
|
||||
@enterprise.is_primary_producer = params[:is_primary_producer]
|
||||
@enterprise.sells = params[:enterprise_sells]
|
||||
render cable_ready: cable_car.morph("#side_menu", partial("admin/shared/side_menu"))
|
||||
render operations: cable_car.morph("#side_menu", partial("admin/shared/side_menu"))
|
||||
.morph("#permalink", partial("admin/enterprises/form/permalink"))
|
||||
end
|
||||
end
|
||||
@@ -64,8 +64,6 @@ module Admin
|
||||
update_tag_rules(tag_rules_attributes) if tag_rules_attributes.present?
|
||||
update_enterprise_notifications
|
||||
|
||||
delete_custom_tab if params[:custom_tab] == 'false'
|
||||
|
||||
if @object.update(enterprise_params)
|
||||
flash[:success] = flash_message_for(@object, :successfully_updated)
|
||||
respond_with(@object) do |format|
|
||||
@@ -121,12 +119,8 @@ module Admin
|
||||
def for_order_cycle
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
render(
|
||||
json: @collection,
|
||||
each_serializer: Api::Admin::ForOrderCycle::EnterpriseSerializer,
|
||||
order_cycle: @order_cycle,
|
||||
spree_current_user: spree_current_user
|
||||
)
|
||||
render json: @collection,
|
||||
each_serializer: Api::Admin::ForOrderCycle::EnterpriseSerializer, order_cycle: @order_cycle, spree_current_user: spree_current_user
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -142,11 +136,6 @@ module Admin
|
||||
|
||||
protected
|
||||
|
||||
def delete_custom_tab
|
||||
@object.custom_tab.destroy if @object.custom_tab.present?
|
||||
enterprise_params.delete(:custom_tab_attributes)
|
||||
end
|
||||
|
||||
def build_resource
|
||||
enterprise = super
|
||||
enterprise.address ||= Spree::Address.new
|
||||
@@ -182,7 +171,7 @@ module Admin
|
||||
when :for_order_cycle
|
||||
@order_cycle = OrderCycle.find_by(id: params[:order_cycle_id]) if params[:order_cycle_id]
|
||||
coordinator = Enterprise.find_by(id: params[:coordinator_id]) if params[:coordinator_id]
|
||||
@order_cycle ||= OrderCycle.new(coordinator: coordinator) if coordinator.present?
|
||||
@order_cycle = OrderCycle.new(coordinator: coordinator) if @order_cycle.nil? && coordinator.present?
|
||||
|
||||
enterprises = OpenFoodNetwork::OrderCyclePermissions.new(spree_current_user, @order_cycle)
|
||||
.visible_enterprises
|
||||
@@ -190,7 +179,7 @@ module Admin
|
||||
if enterprises.present?
|
||||
enterprises.includes(
|
||||
supplied_products:
|
||||
[:supplier, :variants, :image]
|
||||
[:supplier, { master: [:images], variants: { option_values: :option_type } }]
|
||||
)
|
||||
end
|
||||
when :index
|
||||
@@ -199,8 +188,7 @@ module Admin
|
||||
editable_enterprises.
|
||||
order('is_primary_producer ASC, name')
|
||||
elsif json_request?
|
||||
OpenFoodNetwork::Permissions.new(spree_current_user)
|
||||
.editable_enterprises.ransack(params[:q]).result
|
||||
OpenFoodNetwork::Permissions.new(spree_current_user).editable_enterprises.ransack(params[:q]).result
|
||||
else
|
||||
Enterprise.where("1=0")
|
||||
end
|
||||
@@ -208,6 +196,7 @@ module Admin
|
||||
OpenFoodNetwork::Permissions.new(spree_current_user).visible_enterprises
|
||||
.includes(:shipping_methods, :payment_methods).ransack(params[:q]).result
|
||||
else
|
||||
# TODO was ordered with is_distributor DESC as well, not sure why or how we want to sort this now
|
||||
OpenFoodNetwork::Permissions.new(spree_current_user).
|
||||
editable_enterprises.
|
||||
order('is_primary_producer ASC, name')
|
||||
@@ -328,9 +317,7 @@ module Admin
|
||||
:producer_properties_attributes).nil?
|
||||
names = Spree::Property.pluck(:name)
|
||||
enterprise_params[:producer_properties_attributes].each do |key, property|
|
||||
unless names.include? property[:property_name]
|
||||
enterprise_params[:producer_properties_attributes].delete key
|
||||
end
|
||||
enterprise_params[:producer_properties_attributes].delete key unless names.include? property[:property_name]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -37,14 +37,8 @@ module Admin
|
||||
end
|
||||
|
||||
def reset_absent_products
|
||||
@importer = ProductImport::ProductImporter.new(
|
||||
File.new(file_path),
|
||||
spree_current_user,
|
||||
import_into: params[:import_into],
|
||||
enterprises_to_reset: params[:enterprises_to_reset],
|
||||
updated_ids: params[:updated_ids],
|
||||
settings: params[:settings]
|
||||
)
|
||||
@importer = ProductImport::ProductImporter.new(File.new(params[:filepath]),
|
||||
spree_current_user, import_into: params[:import_into], enterprises_to_reset: params[:enterprises_to_reset], updated_ids: params[:updated_ids], settings: params[:settings])
|
||||
|
||||
if params.key?(:enterprises_to_reset) && params.key?(:updated_ids)
|
||||
@importer.reset_absent(params[:updated_ids])
|
||||
@@ -62,13 +56,8 @@ module Admin
|
||||
end
|
||||
|
||||
def process_data(method)
|
||||
@importer = ProductImport::ProductImporter.new(
|
||||
File.new(file_path),
|
||||
spree_current_user,
|
||||
start: params[:start],
|
||||
end: params[:end],
|
||||
settings: params[:settings]
|
||||
)
|
||||
@importer = ProductImport::ProductImporter.new(File.new(params[:filepath]),
|
||||
spree_current_user, start: params[:start], end: params[:end], settings: params[:settings])
|
||||
|
||||
begin
|
||||
@importer.public_send("#{method}_entries")
|
||||
@@ -123,25 +112,5 @@ module Admin
|
||||
def model_class
|
||||
ProductImport::ProductImporter
|
||||
end
|
||||
|
||||
def file_path
|
||||
@file_path ||= validate_file_path(sanitize_file_path(params[:filepath]))
|
||||
end
|
||||
|
||||
def sanitize_file_path(file_path)
|
||||
FilePathSanitizer.new.sanitize(file_path, on_error: method(:raise_invalid_file_path))
|
||||
end
|
||||
|
||||
def validate_file_path(file_path)
|
||||
return file_path if file_path.to_s.match?(TEMP_FILE_PATH_REGEX)
|
||||
|
||||
raise_invalid_file_path
|
||||
end
|
||||
|
||||
def raise_invalid_file_path
|
||||
redirect_to '/admin/product_import', notice: I18n.t(:product_import_no_data_in_spreadsheet_notice)
|
||||
raise 'Invalid File Path'
|
||||
end
|
||||
TEMP_FILE_PATH_REGEX = %r{^/tmp/product_import[A-Za-z0-9-]*/import\.csv$}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Admin
|
||||
class ProductsV3Controller < Spree::Admin::BaseController
|
||||
def index; end
|
||||
end
|
||||
end
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
module Admin
|
||||
class ReportsController < Spree::Admin::BaseController
|
||||
include ActiveStorage::SetCurrent
|
||||
include ReportsActions
|
||||
helper ReportsHelper
|
||||
|
||||
@@ -22,14 +21,7 @@ module Admin
|
||||
def show
|
||||
@report = report_class.new(spree_current_user, params, render: render_data?)
|
||||
|
||||
@background_reports = OpenFoodNetwork::FeatureToggle
|
||||
.enabled?(:background_reports, spree_current_user)
|
||||
|
||||
if @background_reports && request.post?
|
||||
return background(report_format)
|
||||
end
|
||||
|
||||
if params[:report_format].present?
|
||||
if report_format.present?
|
||||
export_report
|
||||
else
|
||||
show_report
|
||||
@@ -39,12 +31,11 @@ module Admin
|
||||
private
|
||||
|
||||
def export_report
|
||||
send_data @report.render_as(report_format), filename: report_filename
|
||||
send_data render_report_as(report_format), filename: report_filename
|
||||
end
|
||||
|
||||
def show_report
|
||||
assign_view_data
|
||||
@table = @report.render_as(:html) if render_data?
|
||||
render "show"
|
||||
end
|
||||
|
||||
@@ -54,6 +45,7 @@ module Admin
|
||||
@report_subtype = report_subtype
|
||||
@report_title = report_title
|
||||
@rendering_options = rendering_options
|
||||
@table = render_report_as(:html) if render_data?
|
||||
@data = Reporting::FrontendData.new(spree_current_user)
|
||||
end
|
||||
|
||||
@@ -61,24 +53,19 @@ module Admin
|
||||
request.post?
|
||||
end
|
||||
|
||||
def background(format)
|
||||
cable_ready[ScopedChannel.for_id(params[:uuid])]
|
||||
.inner_html(
|
||||
selector: "#report-table",
|
||||
html: render_to_string(partial: "admin/reports/loading")
|
||||
).scroll_into_view(
|
||||
selector: "#report-table",
|
||||
block: "start"
|
||||
).broadcast
|
||||
def render_report_as(format)
|
||||
if OpenFoodNetwork::FeatureToggle.enabled?(:background_reports, spree_current_user)
|
||||
job = ReportJob.new
|
||||
JobProcessor.perform_forked(
|
||||
job,
|
||||
report_class, spree_current_user, params, format
|
||||
)
|
||||
|
||||
blob = ReportBlob.create_for_upload_later!(report_filename)
|
||||
|
||||
ReportJob.perform_later(
|
||||
report_class: report_class, user: spree_current_user, params: params,
|
||||
format: format, blob: blob, channel: ScopedChannel.for_id(params[:uuid]),
|
||||
)
|
||||
|
||||
head :no_content
|
||||
# This result has been rendered by Rails in safe mode already.
|
||||
job.result.html_safe # rubocop:disable Rails/OutputSafety
|
||||
else
|
||||
@report.render_as(format)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -40,11 +40,8 @@ module Admin
|
||||
def index
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
render_as_json(
|
||||
@collection,
|
||||
ams_prefix: params[:ams_prefix],
|
||||
editable_schedule_ids: permissions.editable_schedules.pluck(:id)
|
||||
)
|
||||
render_as_json @collection, ams_prefix: params[:ams_prefix],
|
||||
editable_schedule_ids: permissions.editable_schedules.pluck(:id)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -122,8 +119,7 @@ module Admin
|
||||
.pluck(:id)
|
||||
result = @existing_order_cycle_ids
|
||||
result |= (requested & permitted) # add any requested & permitted ids
|
||||
# remove any existing and permitted ids that were not specifically requested
|
||||
result -= ((result & permitted) - requested)
|
||||
result -= ((result & permitted) - requested) # remove any existing and permitted ids that were not specifically requested
|
||||
result
|
||||
end
|
||||
|
||||
|
||||
@@ -16,10 +16,8 @@ module Admin
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
if view_context.subscriptions_setup_complete?(@shops)
|
||||
@order_cycles = OrderCycle.joins(:schedules).managed_by(spree_current_user)
|
||||
.includes([:distributors, :cached_incoming_exchanges])
|
||||
@payment_methods = Spree::PaymentMethod.managed_by(spree_current_user)
|
||||
.includes(:taggings)
|
||||
@order_cycles = OrderCycle.joins(:schedules).managed_by(spree_current_user).includes([:distributors, :cached_incoming_exchanges])
|
||||
@payment_methods = Spree::PaymentMethod.managed_by(spree_current_user).includes(:taggings)
|
||||
@payment_method_tags = payment_method_tags_by_id
|
||||
@shipping_methods = Spree::ShippingMethod.managed_by(spree_current_user)
|
||||
else
|
||||
@@ -27,10 +25,7 @@ module Admin
|
||||
render :setup_explanation
|
||||
end
|
||||
end
|
||||
format.json {
|
||||
render_as_json @collection, ams_prefix: params[:ams_prefix],
|
||||
payment_method_tags: payment_method_tags_by_id
|
||||
}
|
||||
format.json { render_as_json @collection, ams_prefix: params[:ams_prefix], payment_method_tags: payment_method_tags_by_id }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -101,8 +96,7 @@ module Admin
|
||||
end
|
||||
|
||||
def load_shops
|
||||
@shops = Enterprise.managed_by(spree_current_user)
|
||||
.is_distributor.where(enable_subscriptions: true)
|
||||
@shops = Enterprise.managed_by(spree_current_user).is_distributor.where(enable_subscriptions: true)
|
||||
end
|
||||
|
||||
def load_form_data
|
||||
@@ -141,9 +135,7 @@ module Admin
|
||||
@open_orders_to_keep = @subscription.proxy_orders.placed_and_open.pluck(:id)
|
||||
return if @open_orders_to_keep.empty? || params[:open_orders] == 'keep'
|
||||
|
||||
render json: {
|
||||
errors: { open_orders: t('admin.subscriptions.confirm_cancel_open_orders_msg') }
|
||||
},
|
||||
render json: { errors: { open_orders: t('admin.subscriptions.confirm_cancel_open_orders_msg') } },
|
||||
status: :conflict
|
||||
end
|
||||
|
||||
@@ -151,9 +143,7 @@ module Admin
|
||||
return if params[:canceled_orders] == 'notified'
|
||||
return if @subscription.proxy_orders.active.canceled.empty?
|
||||
|
||||
render json: {
|
||||
errors: { canceled_orders: t('admin.subscriptions.resume_canceled_orders_msg') }
|
||||
},
|
||||
render json: { errors: { canceled_orders: t('admin.subscriptions.resume_canceled_orders_msg') } },
|
||||
status: :conflict
|
||||
end
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ module Admin
|
||||
|
||||
options = [{ id: '0', name: 'All' }]
|
||||
import_dates.collect(&:import_date).map { |i|
|
||||
options.push(id: i.to_date, name: i.to_date.to_fs(:long))
|
||||
options.push(id: i.to_date, name: i.to_date.to_formatted_s(:long))
|
||||
}
|
||||
|
||||
options
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Admin
|
||||
class VouchersController < ResourceController
|
||||
before_action :load_enterprise
|
||||
|
||||
def new
|
||||
@voucher = Voucher.new
|
||||
end
|
||||
|
||||
def create
|
||||
voucher_params = permitted_resource_params.merge(enterprise: @enterprise)
|
||||
@voucher = Voucher.create(voucher_params)
|
||||
|
||||
if @voucher.save
|
||||
redirect_to(
|
||||
"#{edit_admin_enterprise_path(@enterprise)}#vouchers_panel",
|
||||
flash: { success: flash_message_for(@voucher, :successfully_created) }
|
||||
)
|
||||
else
|
||||
flash[:error] = @voucher.errors.full_messages.to_sentence
|
||||
render :new
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_enterprise
|
||||
@enterprise = OpenFoodNetwork::Permissions
|
||||
.new(spree_current_user)
|
||||
.editable_enterprises
|
||||
.find_by(permalink: params[:enterprise_id])
|
||||
end
|
||||
|
||||
def permitted_resource_params
|
||||
params.require(:voucher).permit(:code, :amount)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -6,7 +6,7 @@ module Api
|
||||
skip_authorization_check only: :index
|
||||
|
||||
def index
|
||||
@customers = current_api_user.customers.visible
|
||||
@customers = current_api_user.customers
|
||||
render json: @customers, each_serializer: CustomerSerializer
|
||||
end
|
||||
|
||||
|
||||
@@ -80,12 +80,8 @@ module Api
|
||||
end
|
||||
|
||||
def permitted_ransack_params
|
||||
[
|
||||
"#{[:name, :meta_keywords, :variants_display_as,
|
||||
:variants_display_name, :supplier_name]
|
||||
.join('_or_')}_cont",
|
||||
:with_properties, :primary_taxon_id_in_any
|
||||
]
|
||||
[:name_or_meta_keywords_or_variants_display_as_or_variants_display_name_or_supplier_name_cont,
|
||||
:with_properties, :primary_taxon_id_in_any]
|
||||
end
|
||||
|
||||
def distributor
|
||||
|
||||
@@ -47,15 +47,17 @@ module Api
|
||||
def capture
|
||||
authorize! :admin, order
|
||||
|
||||
payment_capture = OrderCaptureService.new(order)
|
||||
pending_payment = order.pending_payments.first
|
||||
|
||||
if payment_capture.call
|
||||
return payment_capture_failed unless order.payment_required? && pending_payment
|
||||
|
||||
if pending_payment.capture!
|
||||
render json: order.reload, serializer: Api::Admin::OrderSerializer, status: :ok
|
||||
elsif payment_capture.gateway_error.present?
|
||||
error_during_processing(payment_capture.gateway_error)
|
||||
else
|
||||
payment_capture_failed
|
||||
end
|
||||
rescue Spree::Core::GatewayError => e
|
||||
error_during_processing(e)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -9,9 +9,9 @@ module Api
|
||||
product = Spree::Product.find(params[:product_id])
|
||||
authorize! :update, product
|
||||
|
||||
image = product.image || Spree::Image.new(
|
||||
viewable_id: product.id,
|
||||
viewable_type: 'Spree::Product'
|
||||
image = product.images.first || Spree::Image.new(
|
||||
viewable_id: product.master.id,
|
||||
viewable_type: 'Spree::Variant'
|
||||
)
|
||||
|
||||
success_status = image.persisted? ? :ok : :created
|
||||
|
||||
@@ -10,6 +10,8 @@ module Api
|
||||
respond_to :json
|
||||
DEFAULT_PER_PAGE = 15
|
||||
|
||||
before_action :set_default_available_on, only: :create
|
||||
|
||||
skip_authorization_check only: [:show, :bulk_products, :overridable]
|
||||
|
||||
def show
|
||||
@@ -21,10 +23,15 @@ module Api
|
||||
authorize! :create, Spree::Product
|
||||
@product = Spree::Product.new(product_params)
|
||||
|
||||
if @product.save
|
||||
render json: @product, serializer: Api::Admin::ProductSerializer, status: :created
|
||||
else
|
||||
invalid_resource!(@product)
|
||||
begin
|
||||
if @product.save
|
||||
render json: @product, serializer: Api::Admin::ProductSerializer, status: :created
|
||||
else
|
||||
invalid_resource!(@product)
|
||||
end
|
||||
rescue ActiveRecord::RecordNotUnique
|
||||
@product.permalink = nil
|
||||
retry
|
||||
end
|
||||
end
|
||||
|
||||
@@ -89,6 +96,8 @@ module Api
|
||||
private
|
||||
|
||||
def find_product(id)
|
||||
product_scope.find_by!(permalink: id.to_s)
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
product_scope.find(id)
|
||||
end
|
||||
|
||||
@@ -107,8 +116,9 @@ module Api
|
||||
|
||||
def product_query_includes
|
||||
[
|
||||
image: { attachment_attachment: :blob },
|
||||
variants: [:default_price, :stock_locations, :stock_items, :variant_overrides]
|
||||
master: [:images],
|
||||
variants: [:default_price, :stock_locations, :stock_items, :variant_overrides,
|
||||
{ option_values: :option_type }]
|
||||
]
|
||||
end
|
||||
|
||||
@@ -143,6 +153,10 @@ module Api
|
||||
@product_params ||=
|
||||
params.permit(product: PermittedAttributes::Product.attributes)[:product].to_h
|
||||
end
|
||||
|
||||
def set_default_available_on
|
||||
product_params[:available_on] ||= Time.zone.now
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -21,9 +21,7 @@ module Api
|
||||
@shipment.refresh_rates
|
||||
@shipment.save!
|
||||
|
||||
OrderWorkflow.new(@order).advance_to_payment if @order.line_items.any?
|
||||
|
||||
render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok
|
||||
render json: @shipment.reload, serializer: Api::ShipmentSerializer, status: :ok
|
||||
end
|
||||
|
||||
def update
|
||||
@@ -34,7 +32,7 @@ module Api
|
||||
@shipment.fee_adjustment.fire_events(:open)
|
||||
|
||||
if @shipment.update(shipment_params)
|
||||
@order.update_totals_and_states
|
||||
@order.updater.update_totals_and_states
|
||||
end
|
||||
|
||||
@shipment.fee_adjustment.close
|
||||
|
||||
@@ -9,12 +9,12 @@ module Api
|
||||
before_action :product
|
||||
|
||||
def index
|
||||
@variants = scope.ransack(params[:q]).result
|
||||
@variants = scope.includes(option_values: :option_type).ransack(params[:q]).result
|
||||
render json: @variants, each_serializer: Api::VariantSerializer
|
||||
end
|
||||
|
||||
def show
|
||||
@variant = scope.find(params[:id])
|
||||
@variant = scope.includes(option_values: :option_type).find(params[:id])
|
||||
render json: @variant, serializer: Api::VariantSerializer
|
||||
end
|
||||
|
||||
@@ -50,15 +50,15 @@ module Api
|
||||
private
|
||||
|
||||
def product
|
||||
@product ||= Spree::Product.find(params[:product_id]) if params[:product_id]
|
||||
@product ||= Spree::Product.find_by(permalink: params[:product_id]) if params[:product_id]
|
||||
end
|
||||
|
||||
def scope
|
||||
if @product
|
||||
variants = if current_api_user.has_spree_role?("admin") || params[:show_deleted]
|
||||
@product.variants.with_deleted
|
||||
@product.variants_including_master.with_deleted
|
||||
else
|
||||
@product.variants
|
||||
@product.variants_including_master
|
||||
end
|
||||
else
|
||||
variants = Spree::Variant.where(nil)
|
||||
|
||||
@@ -106,9 +106,7 @@ module Api
|
||||
end
|
||||
|
||||
def json_api_error(message, **options)
|
||||
error_options = options.delete(:error_options) || {}
|
||||
|
||||
{ errors: [{ detail: message }.merge(error_options)] }.merge(options)
|
||||
{ errors: [{ detail: message }] }.merge(options)
|
||||
end
|
||||
|
||||
def json_api_invalid(message, errors)
|
||||
|
||||
@@ -6,17 +6,11 @@ module Api
|
||||
module V1
|
||||
class CustomersController < Api::V1::BaseController
|
||||
include AddressTransformation
|
||||
include ExtraFields
|
||||
|
||||
skip_authorization_check only: :index
|
||||
|
||||
before_action :authorize_action, only: [:show, :update, :destroy]
|
||||
|
||||
# Query parameters
|
||||
before_action only: [:index] do
|
||||
@extra_customer_fields = extra_fields :customer, [:balance]
|
||||
end
|
||||
|
||||
def index
|
||||
@pagy, customers = pagy(search_customers, pagy_options)
|
||||
|
||||
@@ -29,8 +23,7 @@ module Api
|
||||
|
||||
def create
|
||||
authorize! :update, Enterprise.find(customer_params[:enterprise_id])
|
||||
customer = Customer.find_or_initialize_by(customer_params.slice(:email, :enterprise_id))
|
||||
customer.assign_attributes(customer_params)
|
||||
customer = Customer.new(customer_params)
|
||||
|
||||
if customer.save
|
||||
render json: Api::V1::CustomerSerializer.new(customer), status: :created
|
||||
@@ -58,11 +51,7 @@ module Api
|
||||
private
|
||||
|
||||
def customer
|
||||
@customer ||= if action_name == "show"
|
||||
CustomersWithBalance.new(Customer.where(id: params[:id])).query.first!
|
||||
else
|
||||
Customer.find(params[:id])
|
||||
end
|
||||
@customer ||= Customer.find(params[:id])
|
||||
end
|
||||
|
||||
def authorize_action
|
||||
@@ -72,16 +61,13 @@ module Api
|
||||
def search_customers
|
||||
customers = visible_customers.includes(:bill_address, :ship_address)
|
||||
customers = customers.where(enterprise_id: params[:enterprise_id]) if params[:enterprise_id]
|
||||
|
||||
if @extra_customer_fields.include?(:balance)
|
||||
customers = CustomersWithBalance.new(customers).query
|
||||
end
|
||||
|
||||
customers.ransack(params[:q]).result.order(:id)
|
||||
end
|
||||
|
||||
def visible_customers
|
||||
Customer.visible.managed_by(current_api_user)
|
||||
current_api_user.customers.or(
|
||||
Customer.where(enterprise_id: editable_enterprises)
|
||||
)
|
||||
end
|
||||
|
||||
def customer_params
|
||||
@@ -97,7 +83,6 @@ module Api
|
||||
]
|
||||
).to_h
|
||||
|
||||
attributes.merge!(created_manually: true)
|
||||
attributes.merge!(tag_list: params[:tags]) if params.key?(:tags)
|
||||
|
||||
transform_address!(attributes, :billing_address, :bill_address)
|
||||
@@ -106,6 +91,10 @@ module Api
|
||||
attributes
|
||||
end
|
||||
|
||||
def editable_enterprises
|
||||
OpenFoodNetwork::Permissions.new(current_api_user).editable_enterprises.select(:id)
|
||||
end
|
||||
|
||||
def include_options
|
||||
fields = [params.fetch(:include, [])].flatten
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ require 'spree/core/controller_helpers/common'
|
||||
require 'open_food_network/referer_parser'
|
||||
|
||||
class ApplicationController < ActionController::Base
|
||||
include CablecarResponses
|
||||
include Pagy::Backend
|
||||
include RequestTimeouts
|
||||
|
||||
|
||||
184
app/controllers/checkout_controller.rb
Normal file
184
app/controllers/checkout_controller.rb
Normal file
@@ -0,0 +1,184 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'open_food_network/address_finder'
|
||||
|
||||
class CheckoutController < ::BaseController
|
||||
include OrderStockCheck
|
||||
include OrderCompletion
|
||||
|
||||
layout 'darkswarm'
|
||||
|
||||
helper 'terms_and_conditions'
|
||||
helper 'checkout'
|
||||
|
||||
# We need pessimistic locking to avoid race conditions.
|
||||
# Otherwise we fail on duplicate indexes or end up with negative stock.
|
||||
prepend_around_action CurrentOrderLocker, only: [:edit, :update]
|
||||
|
||||
prepend_before_action :check_hub_ready_for_checkout
|
||||
prepend_before_action :check_order_cycle_expiry
|
||||
prepend_before_action :require_order_cycle
|
||||
prepend_before_action :require_distributor_chosen
|
||||
|
||||
before_action :load_order
|
||||
|
||||
before_action :handle_insufficient_stock
|
||||
|
||||
before_action :associate_user
|
||||
before_action :check_authorization
|
||||
|
||||
helper 'spree/orders'
|
||||
|
||||
def edit; end
|
||||
|
||||
def update
|
||||
params_adapter = Checkout::FormDataAdapter.new(permitted_params, @order, spree_current_user)
|
||||
return action_failed unless @order.update(params_adapter.params[:order] || {})
|
||||
|
||||
checkout_workflow(params_adapter.shipping_method_id)
|
||||
rescue Spree::Core::GatewayError => e
|
||||
gateway_error(e)
|
||||
action_failed(e)
|
||||
rescue StandardError => e
|
||||
flash[:error] = I18n.t("checkout.failed")
|
||||
action_failed(e)
|
||||
ensure
|
||||
@order.update_order!
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def check_authorization
|
||||
authorize!(:edit, current_order, session[:access_token])
|
||||
end
|
||||
|
||||
def load_order
|
||||
load_checkout_order
|
||||
|
||||
return handle_invalid_stock unless valid_order_line_items?
|
||||
|
||||
before_address
|
||||
setup_for_current_state
|
||||
end
|
||||
|
||||
def handle_invalid_stock
|
||||
reset_order_to_cart
|
||||
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
redirect_to main_app.cart_path
|
||||
end
|
||||
|
||||
format.json do
|
||||
render json: { path: main_app.cart_path }, status: :bad_request
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def setup_for_current_state
|
||||
method_name = :"before_#{@order.state}"
|
||||
__send__(method_name) if respond_to?(method_name, true)
|
||||
end
|
||||
|
||||
def before_address
|
||||
associate_user
|
||||
|
||||
finder = OpenFoodNetwork::AddressFinder.new(@order.email, @order.customer, spree_current_user)
|
||||
|
||||
@order.bill_address = finder.bill_address
|
||||
@order.ship_address = finder.ship_address
|
||||
end
|
||||
|
||||
def before_payment
|
||||
current_order.payments.destroy_all if request.put?
|
||||
end
|
||||
|
||||
def checkout_workflow(shipping_method_id)
|
||||
while @order.state != "complete"
|
||||
if @order.state == "payment"
|
||||
update_payment_total
|
||||
return if redirect_to_payment_gateway
|
||||
|
||||
return action_failed if @order.errors.any?
|
||||
return action_failed unless @order.process_payments!
|
||||
end
|
||||
|
||||
next if OrderWorkflow.new(@order).next({ "shipping_method_id" => shipping_method_id })
|
||||
|
||||
return action_failed
|
||||
end
|
||||
|
||||
update_response
|
||||
end
|
||||
|
||||
def update_payment_total
|
||||
@order.updater.update_totals
|
||||
@order.updater.update_pending_payment
|
||||
end
|
||||
|
||||
def redirect_to_payment_gateway
|
||||
return unless selected_payment_method.external_gateway?
|
||||
return unless (redirect_url = selected_payment_method.external_payment_url(order: @order))
|
||||
|
||||
render json: { path: redirect_url }, status: :ok
|
||||
true
|
||||
end
|
||||
|
||||
def selected_payment_method
|
||||
@selected_payment_method ||= Spree::PaymentMethod.find(
|
||||
params.dig(:order, :payments_attributes, 0, :payment_method_id)
|
||||
)
|
||||
end
|
||||
|
||||
def update_response
|
||||
if order_complete?
|
||||
processing_succeeded
|
||||
update_succeeded_response
|
||||
else
|
||||
action_failed(RuntimeError.new("Order not complete after the checkout workflow"))
|
||||
end
|
||||
end
|
||||
|
||||
def order_complete?
|
||||
@order.state == "complete" || @order.completed?
|
||||
end
|
||||
|
||||
def update_succeeded_response
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
respond_with(@order, location: order_completion_route)
|
||||
end
|
||||
format.json do
|
||||
render json: { path: order_completion_route }, status: :ok
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def action_failed(error = RuntimeError.new(order_processing_error))
|
||||
processing_failed(error)
|
||||
action_failed_response
|
||||
end
|
||||
|
||||
def action_failed_response
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
render :edit
|
||||
end
|
||||
format.json do
|
||||
discard_flash_errors
|
||||
render json: { errors: @order.errors, flash: flash.to_hash }.to_json, status: :bad_request
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def permitted_params
|
||||
PermittedAttributes::Checkout.new(params).call
|
||||
end
|
||||
|
||||
def discard_flash_errors
|
||||
# Marks flash errors for deletion after the current action has completed.
|
||||
# This ensures flash errors generated during XHR requests are not persisted in the
|
||||
# session for longer than expected.
|
||||
flash.discard(:error)
|
||||
end
|
||||
end
|
||||
@@ -15,7 +15,9 @@ module CheckoutCallbacks
|
||||
prepend_before_action :require_distributor_chosen
|
||||
|
||||
before_action :load_order, :associate_user, :load_saved_addresses, :load_saved_credit_cards
|
||||
before_action :load_shipping_methods, if: -> { params[:step] == "details" }
|
||||
before_action :allowed_shipping_methods, if: -> {
|
||||
params[:step] == "details"
|
||||
}
|
||||
|
||||
before_action :ensure_order_not_completed
|
||||
before_action :ensure_checkout_allowed
|
||||
@@ -30,8 +32,6 @@ module CheckoutCallbacks
|
||||
@order.manual_shipping_selection = true
|
||||
@order.checkout_processing = true
|
||||
|
||||
@voucher_adjustment = @order.voucher_adjustments.first
|
||||
|
||||
redirect_to(main_app.shop_path) && return if redirect_to_shop?
|
||||
redirect_to_cart_path && return unless valid_order_line_items?
|
||||
end
|
||||
@@ -48,8 +48,22 @@ module CheckoutCallbacks
|
||||
@selected_card = nil
|
||||
end
|
||||
|
||||
def load_shipping_methods
|
||||
@shipping_methods = available_shipping_methods.sort { |a, b| a.name.casecmp(b.name) }
|
||||
def allowed_shipping_methods
|
||||
@allowed_shipping_methods ||= sorted_available_shipping_methods.filter(
|
||||
&method(:supports_all_products_shipping_categories?)
|
||||
)
|
||||
end
|
||||
|
||||
def sorted_available_shipping_methods
|
||||
available_shipping_methods.sort { |a, b| a.name.casecmp(b.name) }
|
||||
end
|
||||
|
||||
def supports_all_products_shipping_categories?(shipping_method)
|
||||
(products_shipping_categories - shipping_method.shipping_categories.pluck(:id)).empty?
|
||||
end
|
||||
|
||||
def products_shipping_categories
|
||||
@products_shipping_categories ||= @order.products.pluck(:shipping_category_id).uniq
|
||||
end
|
||||
|
||||
def redirect_to_shop?
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# To be included in api controllers for handeling query params
|
||||
module ExtraFields
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def invalid_query_param(name, status, msg)
|
||||
render status: status, json: json_api_error(msg, error_options:
|
||||
{
|
||||
title: I18n.t("api.query_param.error.title"),
|
||||
source: { parameter: name },
|
||||
status: status,
|
||||
code: Rack::Utils::SYMBOL_TO_STATUS_CODE[status]
|
||||
})
|
||||
end
|
||||
|
||||
def extra_fields(type, available_fields)
|
||||
fields = params.dig(:extra_fields, type)&.split(',')&.compact&.map(&:to_sym)
|
||||
return [] if fields.blank?
|
||||
|
||||
unknown_fields = fields - available_fields
|
||||
|
||||
if unknown_fields.present?
|
||||
invalid_query_param(
|
||||
"extra_fields[#{type}]", :unprocessable_entity,
|
||||
I18n.t("api.query_param.error.extra_fields", fields: unknown_fields.join(', '))
|
||||
)
|
||||
end
|
||||
|
||||
fields
|
||||
end
|
||||
end
|
||||
@@ -9,10 +9,12 @@ module ManagerInvitations
|
||||
new_user.reset_password_token = Devise.friendly_token
|
||||
# Same time as used in Devise's lib/devise/models/recoverable.rb.
|
||||
new_user.reset_password_sent_at = Time.now.utc
|
||||
if new_user.save
|
||||
enterprise.users << new_user
|
||||
EnterpriseMailer.manager_invitation(enterprise, new_user).deliver_later
|
||||
end
|
||||
new_user.save
|
||||
|
||||
return new_user unless new_user.valid? # Return early if user is invalid.
|
||||
|
||||
enterprise.users << new_user
|
||||
EnterpriseMailer.manager_invitation(@enterprise, new_user).deliver_later
|
||||
|
||||
new_user
|
||||
end
|
||||
|
||||
@@ -41,8 +41,8 @@ module OrderCompletion
|
||||
main_app.order_path(@order, order_token: @order.token)
|
||||
end
|
||||
|
||||
def order_failed_route(step: 'details')
|
||||
main_app.checkout_step_path(step:)
|
||||
def order_failed_route
|
||||
main_app.checkout_path
|
||||
end
|
||||
|
||||
def order_invalid_for_checkout?
|
||||
@@ -60,8 +60,8 @@ module OrderCompletion
|
||||
|
||||
def process_payment_completion!
|
||||
unless @order.process_payments!
|
||||
payment_failed
|
||||
return redirect_to order_failed_route(step: 'payment')
|
||||
processing_failed
|
||||
return redirect_to order_failed_route
|
||||
end
|
||||
|
||||
if OrderWorkflow.new(@order).next && @order.complete?
|
||||
@@ -82,20 +82,12 @@ module OrderCompletion
|
||||
order_completion_reset(@order)
|
||||
end
|
||||
|
||||
def payment_failed
|
||||
notify_failure
|
||||
end
|
||||
|
||||
def processing_failed
|
||||
notify_failure
|
||||
Checkout::PostCheckoutActions.new(@order).failure
|
||||
end
|
||||
|
||||
def notify_failure(error = RuntimeError.new(order_processing_error))
|
||||
def processing_failed(error = RuntimeError.new(order_processing_error))
|
||||
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
|
||||
|
||||
def order_processing_error
|
||||
|
||||
@@ -13,6 +13,8 @@ module OrderStockCheck
|
||||
def handle_insufficient_stock
|
||||
return if sufficient_stock?
|
||||
|
||||
reset_order_to_cart
|
||||
|
||||
flash[:error] = Spree.t(:inventory_error_flash_for_insufficient_quantity)
|
||||
redirect_to main_app.cart_path
|
||||
end
|
||||
@@ -29,7 +31,7 @@ module OrderStockCheck
|
||||
flash[:info] = I18n.t('order_cycle_closed')
|
||||
respond_to do |format|
|
||||
format.cable_ready {
|
||||
render status: :see_other, cable_ready: cable_car.redirect_to(url: main_app.shop_path)
|
||||
render status: :see_other, operations: cable_car.redirect_to(url: main_app.shop_path)
|
||||
}
|
||||
format.json { render json: { path: main_app.shop_path }, status: :see_other }
|
||||
format.html { redirect_to main_app.shop_path, status: :see_other }
|
||||
@@ -41,4 +43,10 @@ module OrderStockCheck
|
||||
def sufficient_stock?
|
||||
@sufficient_stock ||= @order.insufficient_stock_lines.blank?
|
||||
end
|
||||
|
||||
def reset_order_to_cart
|
||||
return if OpenFoodNetwork::FeatureToggle.enabled? :split_checkout, spree_current_user
|
||||
|
||||
OrderCheckoutRestart.new(@order).call
|
||||
end
|
||||
end
|
||||
|
||||
@@ -56,7 +56,7 @@ module ReportsActions
|
||||
end
|
||||
|
||||
def report_format
|
||||
params[:report_format].presence || "html"
|
||||
params[:report_format]
|
||||
end
|
||||
|
||||
def report_filename
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module WhiteLabel
|
||||
extend ActiveSupport::Concern
|
||||
include EnterprisesHelper
|
||||
|
||||
def hide_ofn_navigation(distributor = current_distributor)
|
||||
# if the distributor has the hide_ofn_navigation preference set to true
|
||||
# then we should hide the OFN navigation
|
||||
@hide_ofn_navigation = distributor.hide_ofn_navigation
|
||||
|
||||
# if the distributor has the hide_ofn_navigation preference
|
||||
# set to false, there is no need to check the white_label_logo preference
|
||||
return unless @hide_ofn_navigation
|
||||
|
||||
@white_label_logo = distributor.white_label_logo
|
||||
@white_label_distributor = distributor
|
||||
end
|
||||
end
|
||||
@@ -4,9 +4,9 @@ require 'open_food_network/enterprise_injection_data'
|
||||
|
||||
class EnterprisesController < BaseController
|
||||
layout "darkswarm"
|
||||
helper Spree::ProductsHelper
|
||||
include OrderCyclesHelper
|
||||
include SerializerHelper
|
||||
include WhiteLabel
|
||||
|
||||
protect_from_forgery except: :check_permalink
|
||||
|
||||
@@ -14,7 +14,6 @@ class EnterprisesController < BaseController
|
||||
prepend_before_action :set_order_cycles, :require_distributor_chosen, :reset_order, only: :shop
|
||||
|
||||
before_action :clean_permalink, only: :check_permalink
|
||||
before_action :hide_ofn_navigation, only: :shop
|
||||
|
||||
respond_to :js, only: :permalink_checker
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user