Merge pull request #5548 from luisramos0/3-0-stable-jun-2
[Spree 2.1] Merge master into 3-0-stable
@@ -142,7 +142,6 @@ Layout/LineLength:
|
||||
- spec/controllers/api/product_images_controller_spec.rb
|
||||
- spec/controllers/api/products_controller_spec.rb
|
||||
- spec/controllers/api/promo_images_controller_spec.rb
|
||||
- spec/controllers/api/shipments_controller_spec.rb
|
||||
- spec/controllers/api/variants_controller_spec.rb
|
||||
- spec/controllers/cart_controller_spec.rb
|
||||
- spec/controllers/checkout_controller_spec.rb
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# Contributing
|
||||
We love pull requests from everyone. Any contribution is valuable, but there are two issue streams that we especially love people to work on:
|
||||
We love pull requests from everyone. Any contribution is valuable!
|
||||
|
||||
1) Our delivery backlog, is managed via a ZenHub board (ZenHub extensions are available for most major browsers). We use a Kanban-style approach, whereby devs pick issues from the top of the backlog which has been organised according to current priorities. If you have some time and are interested in working on some issues from the backlog, please make yourself known on the [#dev][slack-dev] channel on Slack and we can direct you to the most appropriate issue to pick up.
|
||||
If you have some time and are interested in working on some issues please make yourself known on the [#dev][slack-dev] channel on Slack.
|
||||
|
||||
2) Our list of bugs and other self-contained issues that we consider to be a good starting point for new contributors, or devs who aren’t able to commit to seeing a whole feature through. These issues are marked with the `# good first issue` label.
|
||||
We have curated all issues we consider to be a good starting point for new members of the community within the [Welcome New Developers project board][welcome-dev]. Have a look and pick the one you would prefer working on!
|
||||
|
||||
## Set up
|
||||
|
||||
@@ -19,10 +19,6 @@ If you want to run the whole test suite, we recommend using a free CI service to
|
||||
|
||||
bundle exec rspec spec
|
||||
|
||||
## Which issue to pick first?
|
||||
|
||||
We have curated all issues interesting for new members of the community within the [Welcome New Developers project board][welcome-dev]. Have a look and pick the one you would prefer working on!
|
||||
|
||||
## Internationalisation (i18n)
|
||||
|
||||
The locale `en` is maintained in the source code, but other locales are managed at [Transifex][ofn-transifex]. Read more about [internationalisation][i18n] in the developer wiki.
|
||||
|
||||
@@ -13,8 +13,8 @@ WORKDIR /usr/src/app
|
||||
COPY .ruby-version .
|
||||
|
||||
# Install Rbenv & Ruby
|
||||
RUN git clone https://github.com/rbenv/rbenv.git ${RBENV_ROOT} && \
|
||||
git clone https://github.com/rbenv/ruby-build.git ${RBENV_ROOT}/plugins/ruby-build && \
|
||||
RUN git clone --depth 1 --branch v1.1.2 https://github.com/rbenv/rbenv.git ${RBENV_ROOT} && \
|
||||
git clone --depth 1 --branch v20200520 https://github.com/rbenv/ruby-build.git ${RBENV_ROOT}/plugins/ruby-build && \
|
||||
${RBENV_ROOT}/plugins/ruby-build/install.sh && \
|
||||
echo 'eval "$(rbenv init -)"' >> /etc/profile.d/rbenv.sh && \
|
||||
rbenv install $(cat .ruby-version) && \
|
||||
@@ -43,4 +43,5 @@ RUN wget https://chromedriver.storage.googleapis.com/2.41/chromedriver_linux64.z
|
||||
|
||||
# Copy code and install app dependencies
|
||||
COPY . /usr/src/app/
|
||||
RUN bundle install
|
||||
# Run bundler install in parallel with the amount of available CPUs
|
||||
RUN bundle install --jobs="$(nproc)"
|
||||
|
||||
@@ -2,21 +2,17 @@
|
||||
|
||||
This is a general guide to setting up an Open Food Network development environment on your local machine.
|
||||
|
||||
The fastest way to make it work locally is to use Docker, see the [Docker setup guide](DOCKER.md).
|
||||
### Requirements
|
||||
|
||||
The following guides are located in the wiki and provide more OS-specific step-by-step instructions:
|
||||
|
||||
- [Ubuntu Setup Guide][ubuntu]
|
||||
- [macOS Sierra Setup Guide][sierra]
|
||||
- [OSX El Capitan Setup Guide][el-capitan]
|
||||
|
||||
### Dependencies
|
||||
|
||||
* Rails 3.2.x
|
||||
* Ruby 2.3.7
|
||||
The fastest way to make it work locally is to use Docker, you only need to setup git, see the [Docker setup guide](DOCKER.md).
|
||||
Otherwise, for a local setup you will need:
|
||||
* Ruby 2.3.7 and bundler
|
||||
* PostgreSQL database
|
||||
* PhantomJS (for testing)
|
||||
* See Gemfile for a list of gems required
|
||||
* Chrome (for testing)
|
||||
|
||||
The following guides will provide OS-specific step-by-step instructions to get these requirements installed:
|
||||
- [Ubuntu Setup Guide][ubuntu]
|
||||
- [OSX Setup Guide][osx]
|
||||
|
||||
If you are likely to need to manage multiple version of ruby on your local machine, we recommend version managers such as [rbenv](https://github.com/rbenv/rbenv) or [RVM](https://rvm.io/).
|
||||
|
||||
@@ -52,14 +48,12 @@ This will create the "ofn" user as superuser and allowing it to create databases
|
||||
|
||||
Once done, run `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.
|
||||
|
||||
If you run into any other issues getting your local environment up and running please consult [the wiki][wiki].
|
||||
|
||||
If still you get stuck do not hesitate to open an issue reporting the full output of the script.
|
||||
|
||||
Now, your dreams of spinning up a development server can be realised:
|
||||
|
||||
bundle exec rails server
|
||||
|
||||
Go to [http://localhost:3000](http://localhost:3000) to play around!
|
||||
|
||||
To login as the default user, use:
|
||||
|
||||
email: ofn@example.com
|
||||
@@ -79,7 +73,7 @@ The tests of all custom engines can be run with:
|
||||
|
||||
bundle exec rake ofn:specs:engines:rspec
|
||||
|
||||
Note: If your OS is not explicitly supported in the setup guides then not all tests may pass. However, you may still be able to develop. Get in touch with the [#dev][slack-dev] channel on Slack to troubleshoot issues and determine if they will preclude you from contributing to OFN.
|
||||
Note: If your OS is not explicitly supported in the setup guides then not all tests may pass. However, you may still be able to develop.
|
||||
|
||||
Note: The time zone on your machine should match the one defined in `config/application.yml`.
|
||||
|
||||
@@ -120,8 +114,7 @@ $ createdb open_food_network_test --owner=ofn
|
||||
If these commands succeed, you should be able to [continue the setup process](#get-it-running).
|
||||
|
||||
[developer-wiki]: https://github.com/openfoodfoundation/openfoodnetwork/wiki
|
||||
[sierra]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/Development-Environment-Setup%3A-macOS-%28Sierra%2C-HighSierra%2C-Mojave-and-Catalina%29
|
||||
[el-capitan]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/Development-Environment-Setup:-OS-X-(El-Capitan)
|
||||
[osx]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/Development-Environment-Setup:-OS-X
|
||||
[ubuntu]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/Development-Environment-Setup:-Ubuntu
|
||||
[wiki]: https://github.com/openfoodfoundation/openfoodnetwork/wiki
|
||||
[zeus]: https://github.com/burke/zeus
|
||||
|
||||
6
Gemfile
@@ -3,7 +3,7 @@ ruby "2.3.7"
|
||||
git_source(:github) { |repo_name| "https://github.com/#{repo_name}.git" }
|
||||
|
||||
gem 'i18n', '~> 0.6.11'
|
||||
gem 'i18n-js', '~> 3.6.0'
|
||||
gem 'i18n-js', '~> 3.7.0'
|
||||
gem 'rails', '~> 4.0.13'
|
||||
gem 'rails-i18n', '~> 4.0'
|
||||
gem 'rails_safe_tasks', '~> 1.0'
|
||||
@@ -161,11 +161,11 @@ group :test do
|
||||
end
|
||||
|
||||
group :development do
|
||||
gem 'byebug', '~> 11.0' # 11.1 requires ruby 2.4
|
||||
gem 'byebug', '~> 11.0.0' # 11.1 requires ruby 2.4
|
||||
gem 'debugger-linecache'
|
||||
gem "newrelic_rpm", "~> 3.0"
|
||||
gem "pry", "~> 0.12.0" # pry 0.13 is not compatible with pry-byebug 3.7
|
||||
gem 'pry-byebug', '~> 3.7' # 3.8 requires ruby 2.4
|
||||
gem 'pry-byebug', '~> 3.7.0' # 3.8 requires ruby 2.4
|
||||
gem 'rubocop'
|
||||
gem 'rubocop-rails'
|
||||
gem 'spring'
|
||||
|
||||
18
Gemfile.lock
@@ -207,7 +207,7 @@ GEM
|
||||
activerecord (>= 3.2.0, < 5.0)
|
||||
fog (~> 1.0)
|
||||
rails (>= 3.2.0, < 5.0)
|
||||
ddtrace (0.35.2)
|
||||
ddtrace (0.36.0)
|
||||
msgpack
|
||||
debugger-linecache (1.2.0)
|
||||
delayed_job (4.1.8)
|
||||
@@ -421,7 +421,7 @@ GEM
|
||||
mime-types (~> 3.0)
|
||||
multi_xml (>= 0.5.2)
|
||||
i18n (0.6.11)
|
||||
i18n-js (3.6.0)
|
||||
i18n-js (3.7.0)
|
||||
i18n (>= 0.6.6)
|
||||
immigrant (0.3.6)
|
||||
activerecord (>= 3.0)
|
||||
@@ -502,6 +502,7 @@ GEM
|
||||
pg (0.21.0)
|
||||
polyamorous (0.6.4)
|
||||
activerecord (>= 3.0)
|
||||
power_assert (1.2.0)
|
||||
pry (0.12.2)
|
||||
coderay (~> 1.1.0)
|
||||
method_source (~> 0.9.0)
|
||||
@@ -510,7 +511,7 @@ GEM
|
||||
pry (~> 0.10)
|
||||
public_suffix (4.0.3)
|
||||
rack (1.5.5)
|
||||
rack-mini-profiler (2.0.1)
|
||||
rack-mini-profiler (2.0.2)
|
||||
rack (>= 1.2.0)
|
||||
rack-protection (1.5.5)
|
||||
rack
|
||||
@@ -643,9 +644,10 @@ GEM
|
||||
sprockets (>= 2.8, < 4.0)
|
||||
state_machine (1.2.0)
|
||||
stringex (1.5.1)
|
||||
stripe (5.15.0)
|
||||
stripe (5.22.0)
|
||||
temple (0.8.2)
|
||||
test-unit (3.3.5)
|
||||
test-unit (3.3.6)
|
||||
power_assert
|
||||
thor (0.20.3)
|
||||
thread_safe (0.3.6)
|
||||
tilt (1.4.1)
|
||||
@@ -707,7 +709,7 @@ DEPENDENCIES
|
||||
aws-sdk (= 1.11.1)
|
||||
blockenspiel
|
||||
bugsnag
|
||||
byebug (~> 11.0)
|
||||
byebug (~> 11.0.0)
|
||||
cancan (~> 1.6.10)
|
||||
capybara (>= 2.18.0)
|
||||
catalog!
|
||||
@@ -741,7 +743,7 @@ DEPENDENCIES
|
||||
highline (= 1.6.18)
|
||||
httparty (~> 0.11)
|
||||
i18n (~> 0.6.11)
|
||||
i18n-js (~> 3.6.0)
|
||||
i18n-js (~> 3.7.0)
|
||||
immigrant
|
||||
jquery-migrate-rails
|
||||
jquery-rails (= 3.1.5)
|
||||
@@ -765,7 +767,7 @@ DEPENDENCIES
|
||||
paranoia (~> 2.0)
|
||||
pg (~> 0.21.0)
|
||||
pry (~> 0.12.0)
|
||||
pry-byebug (~> 3.7)
|
||||
pry-byebug (~> 3.7.0)
|
||||
rack-mini-profiler (< 3.0.0)
|
||||
rack-rewrite
|
||||
rack-ssl
|
||||
|
||||
|
Before Width: | Height: | Size: 107 KiB |
|
Before Width: | Height: | Size: 138 KiB |
|
Before Width: | Height: | Size: 105 KiB |
|
Before Width: | Height: | Size: 570 KiB |
|
Before Width: | Height: | Size: 206 KiB |
|
Before Width: | Height: | Size: 244 KiB |
|
Before Width: | Height: | Size: 195 KiB |
|
Before Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 123 KiB |
@@ -1,72 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 17.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="386.638px" height="320px" viewBox="-31.319 2 386.638 320" enable-background="new -31.319 2 386.638 320"
|
||||
xml:space="preserve">
|
||||
<g>
|
||||
<path fill="#ABDBD0" d="M331.518,159.254c-13.147,0-23.805,26.723-23.805,59.69c0,32.96,10.658,59.685,23.805,59.685
|
||||
c13.142,0,23.801-26.725,23.801-59.685C355.319,185.977,344.66,159.254,331.518,159.254z M332.114,255.185
|
||||
c-8.06,0-14.593-15.746-14.593-35.167s6.533-35.165,14.593-35.165c8.059,0,14.594,15.743,14.594,35.165
|
||||
S340.173,255.185,332.114,255.185z"/>
|
||||
<path fill="#ABDBD0" d="M304.557,219.468c0-36.244,11.718-65.623,26.171-65.623c2.107,0,4.154,0.642,6.116,1.823
|
||||
c-10.469-8.709-35.108-4.515-46.498-2.514c-2.139,3.216-3.572,6.079-4.237,7.624c-3.91,9.023-7.063,22.001-7.063,22.001
|
||||
l-11.863-0.291l11.689,55.666h-17.909c2.54,25.911,10.809,43.072,25.314,46.94c0,0,30.567,4.944,45.693-0.081
|
||||
c-0.414,0.046-0.828,0.081-1.243,0.081C316.273,285.091,304.557,255.707,304.557,219.468z"/>
|
||||
<path fill="#ABDBD0" d="M64.393,237.666c0-46.574,34.058-84.332,76.072-84.332c1.812,0,3.605,0.095,5.386,0.234
|
||||
c-5.466-1.08-11.117-1.655-16.903-1.655c-47.453,0-85.919,38.074-85.919,85.044c0,46.967,38.467,85.042,85.919,85.042
|
||||
c2.052,0,4.08-0.097,6.096-0.238C95.562,318.679,64.393,282.219,64.393,237.666z"/>
|
||||
<path fill="#ABDBD0" d="M122.02,149.109c44.188-2.104,67.371,17.402,79.829,34.057l3.027-2.314l4.452-5.008l28.39,7.793
|
||||
l10.02,52.325h27.275l-11.689-55.667l11.861,0.291c0,0,3.157-12.974,7.066-22c1.977-4.57,10.576-20.597,24.492-23.378
|
||||
c13.917-2.784,26.31,15.218,26.31,15.218l-6.824-19.114l-25.606-9.464l-7.794-42.304l11.689-7.236l-1.114-11.69l-64.57-23.38
|
||||
l-82.387,19.483V66.74l13.361,3.341l-8.908,25.608c0,0-23.709-3.198-47.031-1.02c-27.244,2.543-54.707,10.521-54.707,10.521
|
||||
l-7.365,14.434l-5.009,66.242l2.983,0.565l5.182-59.414l70.49-6.662L122.02,149.109L122.02,149.109z M65.958,118.276
|
||||
c-3.541,0.556-6.775-1.29-7.219-4.123c-0.446-2.835,2.065-5.583,5.606-6.139c3.543-0.556,6.776,1.288,7.22,4.124
|
||||
C72.011,114.972,69.5,117.719,65.958,118.276z M107.793,115.428c-4.711,0.741-9.011-1.713-9.603-5.483
|
||||
c-0.592-3.77,2.748-7.425,7.458-8.167c4.713-0.741,9.014,1.717,9.604,5.484C115.845,111.034,112.505,114.689,107.793,115.428z
|
||||
M225.388,109.481h-19.989L166.472,98.96l7.715-25.25l57.162-10.17L225.388,109.481z M252.39,181.723l-17.886-0.702l7.015-117.482
|
||||
l30.508,9.469l5.612,49.447L252.39,181.723z M282.025,122.017l-6.135-47.956l14.378,7.715l7.015,43.925L282.025,122.017z"/>
|
||||
<path fill="#ABDBD0" d="M147.008,91.476V57.053h-6.84V41.534c-0.001-8.57-6.945-15.515-15.517-15.519v6.314
|
||||
c5.083,0.008,9.198,4.123,9.206,9.204v15.519h-6.312v33.7C134.962,90.733,141.75,91.082,147.008,91.476z"/>
|
||||
<path fill="#ABDBD0" d="M-22.811,227.408c0-33.523,28.628-60.694,63.942-60.694c1.17,0,2.333,0.034,3.487,0.094l0.406-5.338
|
||||
c-2.084-0.176-4.193-0.274-6.325-0.274c-38.67-0.001-70.018,29.602-70.018,66.12c0,36.522,31.348,66.125,70.018,66.125
|
||||
c6.585,0,12.95-0.877,18.994-2.483c-1.019-1.387-1.98-2.814-2.918-4.26c-4.397,0.909-8.959,1.4-13.642,1.4
|
||||
C5.817,288.099-22.811,260.925-22.811,227.408z"/>
|
||||
<path fill="#ABDBD0" d="M10.539,226.003c0-18.358,16.222-33.24,36.233-33.24c2.119,0,4.189,0.176,6.207,0.497
|
||||
c0.214-0.435,0.437-0.864,0.675-1.295l-10.952-2.055l1.408-18.469c-1.078-0.059-2.159-0.087-3.249-0.087
|
||||
c-32.898,0-59.568,25.249-59.568,56.395c0,31.139,26.67,56.388,59.568,56.388c4.363,0,8.614-0.457,12.71-1.299
|
||||
c-4.71-7.248-8.31-15.242-10.552-23.764C24.771,257.346,10.539,243.2,10.539,226.003z"/>
|
||||
<g>
|
||||
<polygon fill="#ABDBD0" points="121.189,130.962 56.135,136.089 56.662,129.208 122.02,123.859 "/>
|
||||
<polygon fill="#ABDBD0" points="120.531,141.218 55.478,146.347 56.004,139.465 121.364,134.116 "/>
|
||||
<path fill="#ABDBD0" d="M120.311,143.455l-65.36,5.348l-0.526,6.882l50.139-3.953c4.875-1.368,9.922-2.336,15.109-2.83
|
||||
L120.311,143.455z"/>
|
||||
<path fill="#ABDBD0" d="M54.293,159.059l-0.527,6.883l24.851-1.96c4.491-3.131,9.296-5.842,14.364-8.088L54.293,159.059z"/>
|
||||
<path fill="#ABDBD0" d="M72.954,168.275l-19.187,1.571l-0.526,6.882l11.721-0.926C67.461,173.128,70.129,170.612,72.954,168.275z"
|
||||
/>
|
||||
<path fill="#ABDBD0" d="M52.847,179.313l-0.526,6.882l4.571-0.362c1.745-2.542,3.636-4.978,5.641-7.313L52.847,179.313z"/>
|
||||
</g>
|
||||
<circle fill="#ABDBD0" cx="140.958" cy="239.852" r="19.726"/>
|
||||
<ellipse fill="#ABDBD0" cx="328.491" cy="218.807" rx="4.487" ry="12.775"/>
|
||||
<g>
|
||||
<circle fill="#ABDBD0" cx="162.134" cy="223.81" r="2.781"/>
|
||||
<circle fill="#ABDBD0" cx="133.371" cy="215.827" r="2.781"/>
|
||||
<circle fill="#ABDBD0" cx="115.492" cy="239.462" r="2.781"/>
|
||||
<circle fill="#ABDBD0" cx="131.915" cy="265.616" r="2.781"/>
|
||||
<circle fill="#ABDBD0" cx="161.682" cy="255.915" r="2.783"/>
|
||||
</g>
|
||||
<path fill="#ABDBD0" d="M126.341,6.21c-9.103,0-16.483,7.379-16.483,16.482c0,2.76,0.686,5.357,1.886,7.641
|
||||
c-2.135-2.062-3.7-4.699-4.48-7.655l0,0c-0.538,0.587-1.051,1.203-1.509,1.884c-5.088,7.548-3.096,17.791,4.454,22.881
|
||||
c2.287,1.542,4.825,2.424,7.39,2.708c-4.22,0.898-8.783,0.158-12.644-2.444c-7.548-5.088-9.542-15.333-4.452-22.881
|
||||
c1.634-2.423,3.81-4.247,6.245-5.472c-0.014-0.289-0.046-0.574-0.046-0.869c0-3.665,1.211-7.038,3.233-9.775l-0.001,0.001
|
||||
c-0.855-0.185-1.731-0.312-2.642-0.312c-7.101,0-12.857,5.756-12.857,12.858c0,2.152,0.535,4.177,1.472,5.959
|
||||
c-2.421-2.337-3.933-5.611-3.933-9.241c0-7.101,5.756-12.857,12.856-12.857c2.414,0,4.663,0.675,6.591,1.833
|
||||
c-0.004,0.002-0.004,0.004-0.006,0.005C114.405,3.9,118.571,2,123.185,2c6.343,0,11.841,3.588,14.598,8.842
|
||||
C134.817,7.98,130.789,6.21,126.341,6.21z"/>
|
||||
<path fill="#ABDBD0" d="M188.32,300.982c-0.004,0-0.006,0.002-0.008,0.004c19.094-15.154,31.275-38.079,31.275-63.757
|
||||
c0-40.085-29.659-73.5-69.016-81.055c-1.782-0.134-3.574-0.227-5.385-0.227c-42.013,0-76.072,36.7-76.072,81.97
|
||||
c0,43.31,31.169,78.747,70.65,81.743c7.991-0.539,15.673-2.145,22.914-4.642L188.32,300.982z M144.663,286.068
|
||||
c-23.696,0-42.907-20.166-42.907-45.041c0-24.878,19.211-45.042,42.907-45.042c23.697,0,42.908,20.166,42.908,45.042
|
||||
C187.571,265.902,168.359,286.068,144.663,286.068z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 6.3 KiB |
@@ -105,6 +105,7 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout
|
||||
$scope.producerFilter = "0"
|
||||
$scope.categoryFilter = "0"
|
||||
$scope.importDateFilter = "0"
|
||||
$scope.fetchProducts()
|
||||
|
||||
$scope.$watch 'sortOptions', (sort) ->
|
||||
return unless sort && sort.predicate != ""
|
||||
|
||||
@@ -37,6 +37,7 @@ angular.module("admin.orders").controller "ordersCtrl", ($scope, $timeout, Reque
|
||||
'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.shipping_method_id,
|
||||
per_page: $scope.per_page,
|
||||
page: page
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ angular.module("admin.side_menu")
|
||||
items: []
|
||||
selected: null
|
||||
|
||||
|
||||
# Checks for path and uses it to set the view
|
||||
# If no path, loads first view
|
||||
init: =>
|
||||
@@ -31,11 +30,3 @@ angular.module("admin.side_menu")
|
||||
for item in @items when item.name is name
|
||||
return item
|
||||
null
|
||||
|
||||
hide_item_by_name: (name) =>
|
||||
item = @find_by_name(name)
|
||||
item.visible = false if item
|
||||
|
||||
show_item_by_name: (name) =>
|
||||
item = @find_by_name(name)
|
||||
item.visible = true if item
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
#= require angular-sanitize
|
||||
#= require angular-animate
|
||||
#= require angular-resource
|
||||
#= require autocomplete.min.js
|
||||
#= require leaflet-1.6.0.js
|
||||
#= require leaflet-providers.js
|
||||
#= require lodash.underscore.js
|
||||
# bluebird.js is a dependency of angular-google-maps.js 2.0.0
|
||||
#= require bluebird.js
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
Darkswarm.controller "GroupPageCtrl", ($scope, enterprises, Enterprises, MapConfiguration, OfnMap) ->
|
||||
Darkswarm.controller "GroupPageCtrl", ($scope, enterprises, Enterprises) ->
|
||||
$scope.Enterprises = Enterprises
|
||||
|
||||
$scope.map = angular.copy MapConfiguration.options
|
||||
$scope.mapMarkers = OfnMap.enterprise_markers enterprises
|
||||
$scope.embedded_layout = window.location.search.indexOf("embedded_shopfront=true") != -1
|
||||
|
||||
@@ -2,6 +2,5 @@ Darkswarm.controller "ProductNodeCtrl", ($scope, $modal, FilterSelectorsService)
|
||||
$scope.enterprise = $scope.product.supplier # For the modal, so it's consistent
|
||||
|
||||
$scope.triggerProductModal = ->
|
||||
$scope.productTaxonSelectors = FilterSelectorsService.createSelectors()
|
||||
$scope.productPropertySelectors = FilterSelectorsService.createSelectors()
|
||||
$modal.open(templateUrl: "product_modal.html", scope: $scope)
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
Darkswarm.directive 'ofnOpenStreetMap', ($window, Enterprises, EnterpriseModal, availableCountries, openStreetMapConfig) ->
|
||||
restrict: 'E'
|
||||
replace: true
|
||||
scope: true
|
||||
template: "<div></div>"
|
||||
|
||||
link: (scope, element, attrs, ctrl, transclude)->
|
||||
map = null
|
||||
markers = []
|
||||
enterpriseNames = []
|
||||
openStreetMapProviderName = openStreetMapConfig.open_street_map_provider_name
|
||||
openStreetMapProviderOptions = JSON.parse(openStreetMapConfig.open_street_map_provider_options)
|
||||
|
||||
average = (values) ->
|
||||
total = values.reduce (sum, value) ->
|
||||
sum = sum + value
|
||||
, 0
|
||||
total / values.length
|
||||
|
||||
averageAngle = (angleName) ->
|
||||
positiveAngles = []
|
||||
negativeAngles = []
|
||||
for enterprise in Enterprises.enterprises
|
||||
if enterprise.latitude? && enterprise.longitude?
|
||||
if enterprise[angleName] > 0
|
||||
positiveAngles.push(enterprise[angleName])
|
||||
else
|
||||
negativeAngles.push(enterprise[angleName])
|
||||
|
||||
averageNegativeAngle = average(negativeAngles)
|
||||
averagePositiveAngle = average(positiveAngles)
|
||||
|
||||
if negativeAngles.length == 0
|
||||
averagePositiveAngle
|
||||
else if positiveAngles.length == 0
|
||||
averageNegativeAngle
|
||||
else if averagePositiveAngle > averageNegativeAngle
|
||||
averagePositiveAngle - averageNegativeAngle
|
||||
else
|
||||
averageNegativeAngle - averagePositiveAngle
|
||||
|
||||
buildMarker = (enterprise, latlng, title) ->
|
||||
icon = L.icon
|
||||
iconUrl: enterprise.icon
|
||||
marker = L.marker latlng,
|
||||
draggable: true,
|
||||
icon: icon,
|
||||
riseOnHover: true,
|
||||
title: title
|
||||
marker.on "click", ->
|
||||
EnterpriseModal.open enterprise
|
||||
marker
|
||||
|
||||
enterpriseName = (enterprise) ->
|
||||
return enterprise.name + " (" + enterprise.address.address1 + ", " + enterprise.address.city + ", " + enterprise.address.state_name + ")";
|
||||
|
||||
goToEnterprise = (selectedEnterpriseName) ->
|
||||
enterprise = Enterprises.enterprises.find (enterprise) ->
|
||||
enterpriseName(enterprise) == selectedEnterpriseName
|
||||
map.setView([enterprise.latitude, enterprise.longitude], 12)
|
||||
|
||||
displayMap = ->
|
||||
setMapDimensions()
|
||||
averageLatitude = averageAngle("latitude")
|
||||
averageLongitude = averageAngle("longitude")
|
||||
zoomLevel = 6
|
||||
map = L.map('open-street-map')
|
||||
L.tileLayer.provider(openStreetMapProviderName, openStreetMapProviderOptions).addTo(map)
|
||||
map.setView([averageLatitude, averageLongitude], zoomLevel)
|
||||
|
||||
displayEnterprises = ->
|
||||
for enterprise in Enterprises.enterprises
|
||||
if enterprise.latitude? && enterprise.longitude?
|
||||
marker = buildMarker(enterprise, { lat: enterprise.latitude, lng: enterprise.longitude }, enterprise.name).addTo(map)
|
||||
enterpriseNames.push(enterpriseName(enterprise))
|
||||
markers.push(marker)
|
||||
|
||||
displaySearchField = () ->
|
||||
new Autocomplete('#open-street-map--search',
|
||||
onSubmit: goToEnterprise
|
||||
search: searchEnterprises
|
||||
)
|
||||
overwriteInlinePositionRelativeToPositionSearchField = ->
|
||||
$('#open-street-map--search').css("position", "absolute")
|
||||
overwriteInlinePositionRelativeToPositionSearchField()
|
||||
|
||||
searchEnterprises = (input) ->
|
||||
if input.length < 1
|
||||
return []
|
||||
enterpriseNames.filter (country) ->
|
||||
country.toLowerCase().includes input.toLowerCase()
|
||||
|
||||
setMapDimensions = ->
|
||||
height = $window.innerHeight - element.offset().top
|
||||
element.css "width", "100%"
|
||||
element.css "height", (height + "px")
|
||||
|
||||
displayMap()
|
||||
displayEnterprises()
|
||||
displaySearchField()
|
||||
@@ -21,8 +21,10 @@ Darkswarm.factory 'Checkout', ($injector, CurrentOrder, ShippingMethods, StripeE
|
||||
try
|
||||
@handle_checkout_error_response(response)
|
||||
catch error
|
||||
@loadFlash(error: t("checkout.failed")) # inform the user about the unexpected error
|
||||
throw error # generate a BugsnagJS alert
|
||||
try
|
||||
@loadFlash(error: t("checkout.failed")) # inform the user about the unexpected error
|
||||
finally
|
||||
throw error # generate a BugsnagJS alert
|
||||
|
||||
handle_checkout_error_response: (response) =>
|
||||
if response.data.path
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Darkswarm.factory 'Enterprises', (enterprises, ShopsResource, CurrentHub, Taxons, Dereferencer, Matcher, Geo, $rootScope) ->
|
||||
Darkswarm.factory 'Enterprises', (enterprises, ShopsResource, CurrentHub, Taxons, Dereferencer, Matcher, GmapsGeo, $rootScope) ->
|
||||
new class Enterprises
|
||||
enterprises: []
|
||||
enterprises_by_id: {}
|
||||
@@ -59,7 +59,7 @@ Darkswarm.factory 'Enterprises', (enterprises, ShopsResource, CurrentHub, Taxons
|
||||
false
|
||||
|
||||
calculateDistance: (query, firstMatching) ->
|
||||
if query?.length > 0 and Geo.OK
|
||||
if query?.length > 0 and GmapsGeo.OK
|
||||
if firstMatching?
|
||||
@setDistanceFrom firstMatching
|
||||
else
|
||||
@@ -68,9 +68,9 @@ Darkswarm.factory 'Enterprises', (enterprises, ShopsResource, CurrentHub, Taxons
|
||||
@resetDistance()
|
||||
|
||||
calculateDistanceGeo: (query) ->
|
||||
Geo.geocode query, (results, status) =>
|
||||
GmapsGeo.geocode query, (results, status) =>
|
||||
$rootScope.$apply =>
|
||||
if status == Geo.OK
|
||||
if status == GmapsGeo.OK
|
||||
#console.log "Geocoded #{query} -> #{results[0].geometry.location}."
|
||||
@setDistanceFrom results[0].geometry.location
|
||||
else
|
||||
@@ -79,7 +79,7 @@ Darkswarm.factory 'Enterprises', (enterprises, ShopsResource, CurrentHub, Taxons
|
||||
|
||||
setDistanceFrom: (locatable) ->
|
||||
for enterprise in @enterprises
|
||||
enterprise.distance = Geo.distanceBetween enterprise, locatable
|
||||
enterprise.distance = GmapsGeo.distanceBetween enterprise, locatable
|
||||
$rootScope.$broadcast 'enterprisesChanged'
|
||||
|
||||
resetDistance: ->
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Darkswarm.service "Geo", ->
|
||||
new class Geo
|
||||
Darkswarm.service "GmapsGeo", ->
|
||||
new class GmapsGeo
|
||||
OK: google?.maps?.GeocoderStatus?.OK
|
||||
|
||||
# Usage:
|
||||
@@ -1,6 +1,5 @@
|
||||
.row
|
||||
|
||||
.columns.small-12.large-6.product-header
|
||||
.columns.small-12.medium-6.large-6.product-header
|
||||
%h3{"ng-bind" => "::product.name"}
|
||||
%span
|
||||
%em {{'products_from' | t}}
|
||||
@@ -8,19 +7,14 @@
|
||||
|
||||
%br
|
||||
|
||||
.filter-shopfront.taxon-selectors.inline-block
|
||||
%filter-selector{ 'selector-set' => "productTaxonSelectors", objects: "[product] | taxonsOf" }
|
||||
|
||||
.filter-shopfront.property-selectors.inline-block
|
||||
%filter-selector{ 'selector-set' => "productPropertySelectors", objects: "[product] | propertiesWithValuesOf" }
|
||||
|
||||
%div{"ng-if" => "product.description_html"}
|
||||
%hr
|
||||
.product-description{"ng-if" => "product.description_html"}
|
||||
%p.text-small{"ng-bind-html" => "::product.description_html"}
|
||||
%hr
|
||||
|
||||
.columns.small-12.large-6
|
||||
%img.product-img{"ng-src" => "{{::product.largeImage}}", "ng-if" => "::product.largeImage"}
|
||||
%img.product-img.placeholder{ src: "/assets/noimage/large.png", "ng-if" => "::!product.largeImage"}
|
||||
.columns.small-12.medium-6.large-6.product-img
|
||||
%img{"ng-src" => "{{::product.largeImage}}", "ng-if" => "::product.largeImage"}
|
||||
%img.placeholder{ src: "/assets/noimage/large.png", "ng-if" => "::!product.largeImage"}
|
||||
|
||||
%ng-include{src: "'partials/close.html'"}
|
||||
|
||||
@@ -27,13 +27,11 @@
|
||||
|
||||
a, a.button {
|
||||
display: block;
|
||||
padding-top: 0.5rem;
|
||||
|
||||
@include border-radius(0.5em);
|
||||
|
||||
border: 1px solid $border-clr;
|
||||
padding: 0.5em 0.625em;
|
||||
font-size: 0.875em;
|
||||
color: $base-clr;
|
||||
font-size: 0.75em;
|
||||
background: white;
|
||||
|
||||
@@ -1,9 +1,30 @@
|
||||
.product-header {
|
||||
padding-left: 1.5rem;
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin: 0;
|
||||
margin: 0.2rem 1.5rem 0 0;
|
||||
}
|
||||
|
||||
hr {
|
||||
margin: 0.5em 0;
|
||||
span {
|
||||
color: $grey-500;
|
||||
}
|
||||
|
||||
.product-description {
|
||||
margin: 1rem 0.25rem 0.25rem 0;
|
||||
}
|
||||
|
||||
.property-selectors li {
|
||||
margin: 0 0.25rem 0.25rem 0;
|
||||
padding: 0.4rem 0 0;
|
||||
|
||||
a {
|
||||
border: 1px solid $grey-300;
|
||||
font-weight: normal;
|
||||
padding: 0.15rem 0.5rem;
|
||||
}
|
||||
|
||||
span {
|
||||
color: $grey-600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,6 +63,8 @@ ordercycle {
|
||||
|
||||
select {
|
||||
background-image: url('/assets/white-caret.svg');
|
||||
background-size: 30px auto;
|
||||
background-position-x: 102%;
|
||||
}
|
||||
|
||||
p {
|
||||
@@ -71,24 +73,27 @@ ordercycle {
|
||||
|
||||
select,
|
||||
p {
|
||||
width: inherit;
|
||||
display: inline-block;
|
||||
color: $white;
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
border-radius: 0 $radius-small $radius-small 0;
|
||||
margin-bottom: 0;
|
||||
padding: 0.5em 1.25em 0.5em 0.75em;
|
||||
font-size: 1em;
|
||||
line-height: 1.3em;
|
||||
padding: 0.5em 1.25em 0.5em 0.75em;
|
||||
height: 2.35em;
|
||||
background-size: 30px auto;
|
||||
border-radius: 0 $radius-small $radius-small 0;
|
||||
min-width: 13em;
|
||||
width: 200px;
|
||||
|
||||
@include breakpoint(mobile) {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
@media all and (min-width: 640px) and (max-width: 1024px), (min-width: 1200px) {
|
||||
width: 250px;
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
@@ -107,6 +112,7 @@ ordercycle {
|
||||
|
||||
@include breakpoint(mobile) {
|
||||
display: flex;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,7 +168,7 @@ shop ordercycle {
|
||||
|
||||
@include breakpoint(tablet) {
|
||||
float: none;
|
||||
padding: 0 0 10px;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
* and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
|
||||
* the top of the compiled file, but it's generally better to create a new file per style scope.
|
||||
|
||||
*= require autocomplete
|
||||
*= require leaflet
|
||||
|
||||
*= require_self
|
||||
*/
|
||||
@import 'variables';
|
||||
|
||||
@@ -143,8 +143,8 @@
|
||||
}
|
||||
|
||||
.reveal-modal-bg.in {
|
||||
filter: alpha(opacity = 50);
|
||||
opacity: 0.5;
|
||||
filter: alpha(opacity = 75);
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
.animate-repeat {
|
||||
|
||||
@@ -11,7 +11,7 @@ section {
|
||||
display: block;
|
||||
background: $white;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
z-index: 20;
|
||||
|
||||
.details {
|
||||
box-sizing: border-box;
|
||||
@@ -20,10 +20,6 @@ section {
|
||||
padding: 30px 0 0;
|
||||
position: relative;
|
||||
|
||||
select {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
img {
|
||||
display: block;
|
||||
height: 100px;
|
||||
|
||||
@@ -3,18 +3,22 @@
|
||||
@import "branding";
|
||||
|
||||
.product-img {
|
||||
padding: 5px;
|
||||
margin-bottom: 10px;
|
||||
outline: 1px solid #ccc;
|
||||
text-align: center;
|
||||
|
||||
@include box-shadow(0 1px 2px 1px rgba(0, 0, 0, 0.15));
|
||||
img {
|
||||
padding: 0.3rem;
|
||||
|
||||
// placeholder for when no product images
|
||||
&.placeholder {
|
||||
opacity: 0.35;
|
||||
// placeholder for when no product images
|
||||
&.placeholder {
|
||||
opacity: 0.35;
|
||||
|
||||
@include breakpoint(desktop) {
|
||||
display: none;
|
||||
@include breakpoint(desktop) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1024px) {
|
||||
margin: 0 0 0.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,10 +53,3 @@
|
||||
.producer-logo {
|
||||
max-width: 220px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1024px) {
|
||||
.product-img {
|
||||
margin-top: 2em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
.map-container {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
|
||||
map, .angular-google-map-container, google-map, .angular-google-map {
|
||||
display: block;
|
||||
@@ -38,6 +39,30 @@
|
||||
background: rgba(255, 255, 255, 1);
|
||||
}
|
||||
}
|
||||
|
||||
#open-street-map {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#open-street-map--search {
|
||||
top: 16px;
|
||||
left: 54px;
|
||||
width: 50%;
|
||||
z-index: 1000;
|
||||
|
||||
.autocomplete-input,
|
||||
.autocomplete-result-list {
|
||||
border: 2px solid $grey-500;
|
||||
|
||||
&:hover, &:active, &:focus {
|
||||
border-color: $clr-brick;
|
||||
}
|
||||
}
|
||||
|
||||
.autocomplete-result-list {
|
||||
border-top: 1px dotted $grey-500;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.map-footer {
|
||||
@@ -63,3 +88,8 @@
|
||||
left: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.tabs-content .map-footer {
|
||||
position: relative;
|
||||
bottom: 30px;
|
||||
}
|
||||
|
||||
@@ -5,8 +5,6 @@ dialog
|
||||
, .reveal-modal {
|
||||
border: none;
|
||||
outline: none;
|
||||
padding: 30px 20px 0 20px;
|
||||
border-bottom: 30px solid white;
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
min-height: 260px;
|
||||
@@ -18,23 +16,26 @@ dialog
|
||||
// Reveal.js break point:
|
||||
// @media only screen and (max-width: 40.063em)
|
||||
|
||||
// Small - when modal IS full screen
|
||||
// Small - smaller outside area
|
||||
@media only screen and (max-width: 640px) {
|
||||
left: 0;
|
||||
max-height: 100%;
|
||||
position: absolute !important;
|
||||
top: 0;
|
||||
left: 4%;
|
||||
max-height: 92%;
|
||||
max-width: 92%;
|
||||
padding: 15px 0 0;
|
||||
top: 4%;
|
||||
}
|
||||
|
||||
// Medium and up - when modal IS NOT full screen
|
||||
// Medium and up - larger outside area
|
||||
@media only screen and (min-width: 641px) {
|
||||
border-bottom: 30px solid $white;
|
||||
max-height: 90%;
|
||||
padding: 30px 20px 0 20px;
|
||||
top: 5%;
|
||||
}
|
||||
}
|
||||
|
||||
.reveal-modal-bg {
|
||||
background-color: rgba(0, 0, 0, 0.85);
|
||||
background-color: $black;
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
@@ -58,6 +59,10 @@ dialog
|
||||
dialog .close-reveal-modal
|
||||
, .reveal-modal .close-reveal-modal {
|
||||
@include close-button(0.25rem);
|
||||
|
||||
background-color: $grey-500;
|
||||
color: $white;
|
||||
font-size: 1.5rem;
|
||||
right: 0.25rem;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,12 @@
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 640px) {
|
||||
.tabbable {
|
||||
margin: 0 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 1025px) {
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
@import "mixins";
|
||||
|
||||
#registration-modal {
|
||||
@media only screen and (max-width: 640px) {
|
||||
margin: 0 15px;
|
||||
}
|
||||
|
||||
header {
|
||||
text-align: center;
|
||||
|
||||
|
||||
@@ -234,6 +234,7 @@ $sidebar-footer-height: 5em;
|
||||
.warning-sign {
|
||||
margin: 0 10px 0 5px;
|
||||
display: inline-block;
|
||||
line-height: 1.9rem;
|
||||
|
||||
strong {
|
||||
color: $grey-650;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
color: $dark-grey;
|
||||
box-shadow: $distributor-header-shadow;
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
|
||||
.columns {
|
||||
display: flex;
|
||||
|
||||
@@ -68,6 +68,10 @@ table.social {
|
||||
background-color: white !important;
|
||||
border: 1px solid #ebebeb;
|
||||
}
|
||||
|
||||
&.fullwidth {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
table.order-summary {
|
||||
|
||||
@@ -32,7 +32,8 @@ module Admin
|
||||
PreferenceSections::GroupSignupPageSection.new,
|
||||
PreferenceSections::MainLinksSection.new,
|
||||
PreferenceSections::FooterAndExternalLinksSection.new,
|
||||
PreferenceSections::UserGuideSection.new
|
||||
PreferenceSections::UserGuideSection.new,
|
||||
PreferenceSections::MapSection.new
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
@@ -145,7 +145,7 @@ module Admin
|
||||
preload(:schedules).
|
||||
ransack(params[:q]).
|
||||
result.
|
||||
accessible_by(spree_current_user)
|
||||
visible_by(spree_current_user)
|
||||
end
|
||||
|
||||
def load_data_for_index
|
||||
|
||||
@@ -65,7 +65,10 @@ class EnterprisesController < BaseController
|
||||
def reset_order
|
||||
order = current_order(true)
|
||||
|
||||
OrderCartReset.new(order, params[:id], try_spree_current_user, current_customer).call
|
||||
# reset_distributor must be called before any call to current_customer or current_distributor
|
||||
order_cart_reset = OrderCartReset.new(order, params[:id])
|
||||
order_cart_reset.reset_distributor
|
||||
order_cart_reset.reset_other!(try_spree_current_user, current_customer)
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
flash[:error] = I18n.t(:enterprise_shop_show_error)
|
||||
redirect_to shops_path
|
||||
|
||||
@@ -23,7 +23,7 @@ module Spree
|
||||
rescue StandardError => e
|
||||
flash[:error] = Spree.t('admin.mail_methods.testmail.error') % { e: e }
|
||||
ensure
|
||||
redirect_to edit_admin_mail_method_url
|
||||
redirect_to edit_admin_mail_methods_url
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -247,15 +247,17 @@ module Spree
|
||||
end
|
||||
|
||||
def suppliers_of_products_distributed_by(distributors)
|
||||
distributors.map { |d| Spree::Product.in_distributor(d).includes(:supplier).to_a }.
|
||||
flatten.map(&:supplier).uniq
|
||||
supplier_ids = Spree::Product.in_distributors(distributors).
|
||||
select('spree_products.supplier_id')
|
||||
|
||||
Enterprise.where(id: supplier_ids)
|
||||
end
|
||||
|
||||
# Load order cycles the current user has access to
|
||||
def my_order_cycles
|
||||
OrderCycle.
|
||||
active_or_complete.
|
||||
accessible_by(spree_current_user).
|
||||
visible_by(spree_current_user).
|
||||
order('orders_close_at DESC')
|
||||
end
|
||||
|
||||
|
||||
@@ -100,6 +100,10 @@ module InjectionHelper
|
||||
inject_json_ams "currencyConfig", {}, Api::CurrencyConfigSerializer
|
||||
end
|
||||
|
||||
def inject_open_street_map_config
|
||||
inject_json_ams "openStreetMapConfig", {}, Api::OpenStreetMapConfigSerializer
|
||||
end
|
||||
|
||||
def inject_spree_api_key
|
||||
render partial: "json/injection_ams", locals: { name: 'spreeApiKey', json: "'#{@spree_api_key}'" }
|
||||
end
|
||||
|
||||
@@ -17,6 +17,11 @@ class ContentConfiguration < Spree::Preferences::FileConfiguration
|
||||
preference :home_show_stats, :boolean, default: true
|
||||
has_attached_file :home_hero, default_url: "/assets/home/home.jpg"
|
||||
|
||||
# Map
|
||||
preference :open_street_map_enabled, :boolean, default: false
|
||||
preference :open_street_map_provider_name, :string, default: "OpenStreetMap.Mapnik"
|
||||
preference :open_street_map_provider_options, :text, default: "{}"
|
||||
|
||||
# Producer sign-up page
|
||||
# All the following defaults using I18n don't work.
|
||||
# https://github.com/openfoodfoundation/openfoodnetwork/issues/3816
|
||||
|
||||
@@ -70,7 +70,7 @@ class OrderCycle < ActiveRecord::Base
|
||||
}
|
||||
|
||||
# Return order cycles that user coordinates, sends to or receives from
|
||||
scope :accessible_by, lambda { |user|
|
||||
scope :visible_by, lambda { |user|
|
||||
if user.has_spree_role?('admin')
|
||||
where(nil)
|
||||
else
|
||||
|
||||
17
app/models/preference_sections/map_section.rb
Normal file
@@ -0,0 +1,17 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module PreferenceSections
|
||||
class MapSection
|
||||
def name
|
||||
I18n.t('admin.contents.edit.map')
|
||||
end
|
||||
|
||||
def preferences
|
||||
[
|
||||
:open_street_map_enabled,
|
||||
:open_street_map_provider_name,
|
||||
:open_street_map_provider_options
|
||||
]
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -39,7 +39,7 @@ class AbilityDecorator
|
||||
# OR if they manage a producer which is included in any order cycles
|
||||
def can_manage_order_cycles?(user)
|
||||
can_manage_orders?(user) ||
|
||||
OrderCycle.accessible_by(user).any?
|
||||
OrderCycle.visible_by(user).any?
|
||||
end
|
||||
|
||||
# Users can manage orders if they have a sells own/any enterprise.
|
||||
@@ -193,7 +193,7 @@ class AbilityDecorator
|
||||
|
||||
def add_order_cycle_management_abilities(user)
|
||||
can [:admin, :index, :read, :edit, :update, :incoming, :outgoing], OrderCycle do |order_cycle|
|
||||
OrderCycle.accessible_by(user).include? order_cycle
|
||||
OrderCycle.visible_by(user).include? order_cycle
|
||||
end
|
||||
can [:admin, :index, :create], Schedule
|
||||
can [:admin, :update, :destroy], Schedule do |schedule|
|
||||
|
||||
@@ -26,6 +26,7 @@ Spree::AppConfiguration.class_eval do
|
||||
preference :bugherd_api_key, :string, default: nil
|
||||
preference :matomo_url, :string, default: nil
|
||||
preference :matomo_site_id, :string, default: nil
|
||||
preference :matomo_tag_manager_url, :string, default: nil
|
||||
|
||||
# Invoices & Receipts
|
||||
preference :enable_invoices?, :boolean, default: true
|
||||
|
||||
@@ -13,7 +13,7 @@ module Spree
|
||||
end
|
||||
|
||||
def compute(object)
|
||||
min = preferred_minimal_amount.to_i
|
||||
min = preferred_minimal_amount.to_f
|
||||
order_amount = line_items_for(object).map { |x| x.price * x.quantity }.sum
|
||||
|
||||
if order_amount < min
|
||||
|
||||
@@ -79,6 +79,12 @@ Spree::Product.class_eval do
|
||||
select('distinct spree_products.*')
|
||||
}
|
||||
|
||||
scope :in_distributors, lambda { |distributors|
|
||||
with_order_cycles_outer.
|
||||
where('(o_exchanges.incoming = ? AND o_exchanges.receiver_id IN (?))', false, distributors).
|
||||
uniq
|
||||
}
|
||||
|
||||
# Products supplied by a given enterprise or distributed via that enterprise through an OC
|
||||
scope :in_supplier_or_distributor, lambda { |enterprise|
|
||||
enterprise = enterprise.respond_to?(:id) ? enterprise.id : enterprise.to_i
|
||||
@@ -153,18 +159,6 @@ Spree::Product.class_eval do
|
||||
self.class.in_order_cycle(order_cycle).include? self
|
||||
end
|
||||
|
||||
# overriding to check self.on_demand as well
|
||||
def has_stock?
|
||||
has_variants? ? variants.any?(&:in_stock?) : (on_demand || master.in_stock?)
|
||||
end
|
||||
|
||||
def has_stock_for_distribution?(order_cycle, distributor)
|
||||
# This product has stock for a distribution if it is available on-demand
|
||||
# or if one of its variants in the distribution is in stock
|
||||
(!has_variants? && on_demand) ||
|
||||
variants_distributed_by(order_cycle, distributor).any?(&:in_stock?)
|
||||
end
|
||||
|
||||
def variants_distributed_by(order_cycle, distributor)
|
||||
order_cycle.variants_distributed_by(distributor).where(product_id: self)
|
||||
end
|
||||
|
||||
21
app/serializers/api/open_street_map_config_serializer.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
class OpenStreetMapConfigSerializer < ActiveModel::Serializer
|
||||
attributes :open_street_map_enabled,
|
||||
:open_street_map_provider_name,
|
||||
:open_street_map_provider_options
|
||||
|
||||
def open_street_map_enabled
|
||||
ContentConfig.open_street_map_enabled
|
||||
end
|
||||
|
||||
def open_street_map_provider_name
|
||||
ContentConfig.open_street_map_provider_name
|
||||
end
|
||||
|
||||
def open_street_map_provider_options
|
||||
ContentConfig.open_street_map_provider_options.to_json
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -7,9 +7,8 @@ class BulkInvoiceService
|
||||
|
||||
def start_pdf_job(order_ids)
|
||||
pdf = CombinePDF.new
|
||||
orders = Spree::Order.where(id: order_ids)
|
||||
|
||||
orders.each do |order|
|
||||
orders_from(order_ids).each do |order|
|
||||
invoice = renderer.render_to_string(order)
|
||||
|
||||
pdf << CombinePDF.parse(invoice)
|
||||
@@ -29,6 +28,10 @@ class BulkInvoiceService
|
||||
|
||||
private
|
||||
|
||||
def orders_from(order_ids)
|
||||
Spree::Order.where(id: order_ids).order("completed_at DESC")
|
||||
end
|
||||
|
||||
def new_invoice_id
|
||||
Time.zone.now.to_i.to_s
|
||||
end
|
||||
|
||||
@@ -2,25 +2,12 @@
|
||||
|
||||
# Resets an order by verifying it's state and fixing any issues
|
||||
class OrderCartReset
|
||||
def initialize(order, distributor_id, current_user, current_customer)
|
||||
def initialize(order, distributor_id)
|
||||
@order = order
|
||||
@distributor ||= Enterprise.is_distributor.find_by(permalink: distributor_id) ||
|
||||
Enterprise.is_distributor.find(distributor_id)
|
||||
@current_user = current_user
|
||||
@current_customer = current_customer
|
||||
end
|
||||
|
||||
def call
|
||||
reset_distributor
|
||||
reset_user_and_customer if current_user
|
||||
reset_order_cycle
|
||||
order.save!
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :order, :distributor, :current_user, :current_customer
|
||||
|
||||
def reset_distributor
|
||||
if order.distributor && order.distributor != distributor
|
||||
order.empty!
|
||||
@@ -29,12 +16,24 @@ class OrderCartReset
|
||||
order.distributor = distributor
|
||||
end
|
||||
|
||||
def reset_user_and_customer
|
||||
def reset_other!(current_user, current_customer)
|
||||
reset_user_and_customer(current_user)
|
||||
reset_order_cycle(current_customer)
|
||||
order.save!
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :order, :distributor, :current_user
|
||||
|
||||
def reset_user_and_customer(current_user)
|
||||
return unless current_user
|
||||
|
||||
order.associate_user!(current_user) if order.user.blank? || order.email.blank?
|
||||
order.__send__(:associate_customer) if order.customer.nil? # Only associates existing customers
|
||||
end
|
||||
|
||||
def reset_order_cycle
|
||||
def reset_order_cycle(current_customer)
|
||||
listed_order_cycles = Shop::OrderCyclesList.new(distributor, current_customer).call
|
||||
|
||||
if order_cycle_not_listed?(order.order_cycle, listed_order_cycles)
|
||||
|
||||
@@ -24,13 +24,25 @@ class SearchOrders
|
||||
attr_reader :params, :current_user
|
||||
|
||||
def fetch_orders
|
||||
@search = ::Permissions::Order.new(current_user).editable_orders.ransack(params[:q])
|
||||
@search = search_query.ransack(params[:q])
|
||||
|
||||
return paginated_results if using_pagination?
|
||||
|
||||
@search.result(distinct: true)
|
||||
end
|
||||
|
||||
def search_query
|
||||
base_query = ::Permissions::Order.new(current_user).editable_orders
|
||||
return base_query unless params[:shipping_method_id]
|
||||
|
||||
base_query
|
||||
.joins(shipments: :shipping_rates)
|
||||
.where(spree_shipping_rates: {
|
||||
selected: true,
|
||||
shipping_method_id: params[:shipping_method_id]
|
||||
})
|
||||
end
|
||||
|
||||
def paginated_results
|
||||
@search.result(distinct: true)
|
||||
.page(params[:page])
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
= label_tag(:matomo_site_id, t('.matomo_site_id')) + tag(:br)
|
||||
= preference_field_tag("preferences[#{:matomo_site_id}]", Spree::Config[:matomo_site_id], type: Spree::Config.preference_type(:matomo_site_id))
|
||||
|
||||
.field
|
||||
= label_tag(:matomo_tag_manager_url, t('.matomo_tag_manager_url')) + tag(:br)
|
||||
= preference_field_tag("preferences[#{:matomo_tag_manager_url}]", Spree::Config[:matomo_tag_manager_url], type: Spree::Config.preference_type(:matomo_tag_manager_url))
|
||||
.warning.note= t('.config_instructions_tag_manager_html')
|
||||
|
||||
.form-buttons{"data-hook" => "buttons"}
|
||||
= button t(:update), 'icon-refresh'
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
= @group.logo.url
|
||||
|
||||
- content_for :injection_data do
|
||||
= inject_available_countries
|
||||
= inject_group_enterprises
|
||||
= inject_open_street_map_config
|
||||
|
||||
#group-page.row.pad-top.footer-pad{"ng-controller" => "GroupPageCtrl"}
|
||||
.small-12.columns.pad-top
|
||||
@@ -32,13 +34,8 @@
|
||||
%tab{heading: t(:label_map),
|
||||
active: "tabs.map.active",
|
||||
select: "select(\'map\')"}
|
||||
.map-container
|
||||
%map{"ng-if" => "(isActive(\'/map\') && (mapShowed = true)) || mapShowed"}
|
||||
%ui-gmap-google-map{options: "map.additional_options", center: "map.center", zoom: "map.zoom", styles: "map.styles", draggable: "true"}
|
||||
%map-osm-tiles
|
||||
%map-search
|
||||
%ui-gmap-markers{models: "mapMarkers", fit: "true",
|
||||
coords: "'self'", icon: "'icon'", click: "'reveal'"}
|
||||
%div{"ng-if" => "(isActive(\'/map\') && (mapShowed = true)) || mapShowed"}
|
||||
= render partial: "shared/map"
|
||||
|
||||
%tab{heading: t(:groups_about),
|
||||
active: "tabs.about.active",
|
||||
@@ -122,4 +119,4 @@
|
||||
%span
|
||||
= t 'title'
|
||||
|
||||
= render "shared/footer"
|
||||
= render "shared/footer"
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
|
||||
- if Spree::Config.matomo_tag_manager_url.present?
|
||||
:javascript
|
||||
var _mtm = _mtm || [];
|
||||
_mtm.push({'mtm.startTime': (new Date().getTime()), 'event': 'mtm.Start'});
|
||||
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
||||
var u="#{Spree::Config.matomo_tag_manager_url}";
|
||||
g.type='text/javascript'; g.async=true; g.defer=true; g.src=u; s.parentNode.insertBefore(g,s);
|
||||
|
||||
- if Spree::Config.matomo_url.present?
|
||||
:javascript
|
||||
var _paq = _paq || [];
|
||||
var _paq = window._paq || [];
|
||||
_paq.push(["setDocumentTitle", document.domain + "/" + document.title]);
|
||||
_paq.push(["setCookieDomain", "*.#{Spree::Config.site_url}"]);
|
||||
_paq.push(["setDomains", ["*.#{Spree::Config.site_url}"]]);
|
||||
@@ -8,8 +17,8 @@
|
||||
_paq.push(['enableLinkTracking']);
|
||||
(function() {
|
||||
var u="#{Spree::Config.matomo_url}";
|
||||
_paq.push(['setTrackerUrl', u+'piwik.php']);
|
||||
_paq.push(['setTrackerUrl', u+'matomo.php']);
|
||||
_paq.push(['setSiteId', '#{Spree::Config.matomo_site_id}']);
|
||||
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
||||
g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
|
||||
g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
|
||||
})();
|
||||
|
||||
@@ -39,7 +39,8 @@
|
||||
|
||||
= render "layouts/bugsnag_js"
|
||||
%script{:src => "https://js.stripe.com/v3/", :type => "text/javascript"}
|
||||
%script{src: "//maps.googleapis.com/maps/api/js?libraries=places,geometry#{ ENV['GOOGLE_MAPS_API_KEY'] ? '&key=' + ENV['GOOGLE_MAPS_API_KEY'] : ''} "}
|
||||
- if !ContentConfig.open_street_map_enabled
|
||||
%script{src: "//maps.googleapis.com/maps/api/js?libraries=places,geometry#{ ENV['GOOGLE_MAPS_API_KEY'] ? '&key=' + ENV['GOOGLE_MAPS_API_KEY'] : ''} "}
|
||||
= javascript_include_tag "darkswarm/all"
|
||||
= javascript_include_tag "web/all"
|
||||
= render "layouts/i18n_script"
|
||||
|
||||
@@ -2,15 +2,8 @@
|
||||
= t :label_map
|
||||
|
||||
- content_for :injection_data do
|
||||
= inject_available_countries
|
||||
= inject_enterprise_shopfront_list
|
||||
= inject_open_street_map_config
|
||||
|
||||
.map-container{"fill-vertical" => true}
|
||||
%map{"ng-controller" => "MapCtrl"}
|
||||
%ui-gmap-google-map{options: "map.additional_options", center: "map.center", zoom: "map.zoom", styles: "map.styles", draggable: "true"}
|
||||
%map-osm-tiles
|
||||
%map-search
|
||||
%ui-gmap-markers{models: "OfnMap.enterprises", fit: "true",
|
||||
coords: "'self'", icon: "'icon'", click: "'reveal'"}
|
||||
|
||||
.map-footer
|
||||
%a{:href => "http://www.openstreetmap.org/copyright"} © OpenStreetMap contributors
|
||||
= render partial: "shared/map"
|
||||
|
||||
19
app/views/shared/_map.html.haml
Normal file
@@ -0,0 +1,19 @@
|
||||
- if ContentConfig.open_street_map_enabled
|
||||
.map-container
|
||||
%ofn-open-street-map#open-street-map
|
||||
%div#open-street-map--search
|
||||
%input.autocomplete-input
|
||||
%ul.autocomplete-result-list
|
||||
|
||||
- else
|
||||
.map-container
|
||||
%map{"ng-controller" => "MapCtrl"}
|
||||
%ui-gmap-google-map{options: "map.additional_options", center: "map.center", zoom: "map.zoom",
|
||||
styles: "map.styles", draggable: "true"}
|
||||
%map-osm-tiles
|
||||
%map-search
|
||||
%ui-gmap-markers{models: "OfnMap.enterprises", fit: "true",
|
||||
coords: "'self'", icon: "'icon'", click: "'reveal'"}
|
||||
|
||||
.map-footer
|
||||
%a{:href => "http://www.openstreetmap.org/copyright"} © OpenStreetMap contributors
|
||||
@@ -1,3 +1,5 @@
|
||||
.content.footer-pad{ "darker-background" => true, "ng-controller" => "ProductsCtrl", "ng-show" => "order_cycle.order_cycle_id == null" }
|
||||
.select-oc-message
|
||||
= t '.select_oc_html'
|
||||
.row
|
||||
.small-12.columns
|
||||
.select-oc-message
|
||||
= t '.select_oc_html'
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
= render :partial => 'spree/admin/shared/order_tabs', :locals => { :current => 'Adjustments' }
|
||||
= render :partial => 'spree/admin/shared/order_page_title'
|
||||
= render :partial => 'spree/admin/shared/order_tabs', locals: { current: 'Adjustments' }
|
||||
|
||||
- content_for :page_title do
|
||||
%i.icon-arrow-right
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
= render :partial => 'spree/admin/shared/order_tabs', :locals => { :current => 'Adjustments' }
|
||||
= render partial: 'spree/admin/shared/order_page_title'
|
||||
= render partial: 'spree/admin/shared/order_tabs', locals: { current: 'Adjustments' }
|
||||
|
||||
- content_for :page_title do
|
||||
%i.icon-arrow-right
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
= render :partial => 'spree/admin/shared/order_tabs', :locals => { :current => 'Adjustments' }
|
||||
= render partial: 'spree/admin/shared/order_page_title'
|
||||
= render partial: 'spree/admin/shared/order_tabs', locals: { current: 'Adjustments' }
|
||||
|
||||
- content_for :page_title do
|
||||
%i.icon-arrow-right
|
||||
|
||||
@@ -15,15 +15,13 @@
|
||||
%colgroup
|
||||
%col{ style: "width: 5%" }/
|
||||
%col{ style: "width: 10%" }/
|
||||
- if @product.has_variants?
|
||||
%col{ style: "width: 25%" }/
|
||||
%col{ style: "width: 25%" }/
|
||||
%col{ style: "width: 45%" }/
|
||||
%col{ style: "width: 15%" }/
|
||||
%thead
|
||||
%tr
|
||||
%th{:colspan => "2"}= t('spree.thumbnail')
|
||||
- if @product.has_variants?
|
||||
%th= Spree::Variant.model_name.human
|
||||
%th= Spree::Variant.model_name.human
|
||||
%th= t('spree.alt_text')
|
||||
%th.actions
|
||||
%tbody
|
||||
@@ -35,8 +33,7 @@
|
||||
%span.handle
|
||||
%td
|
||||
= link_to image_tag(image.attachment.url(:mini)), image.attachment.url(:product)
|
||||
- if @product.has_variants?
|
||||
%td= options_text_for(image)
|
||||
%td= options_text_for(image)
|
||||
%td= image.alt
|
||||
%td.actions
|
||||
= link_to_with_icon 'icon-edit', t('spree.edit'), edit_admin_product_image_url(@product, image), no_text: true, data: { action: 'edit'}
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
|
||||
- content_for :page_actions do
|
||||
%li
|
||||
= link_to_with_icon 'icon-envelope-alt', t("spree.admin.mail_methods.send_testmail"), testmail_admin_mail_method_path, method: :post, title: t("spree.admin.mail_methods.send_testmail"), class: 'send_mail button no-text'
|
||||
= link_to_with_icon 'icon-envelope-alt', t("spree.admin.mail_methods.send_testmail"), testmail_admin_mail_methods_path, method: :post, title: t("spree.admin.mail_methods.send_testmail"), class: 'send_mail button no-text'
|
||||
|
||||
= render partial: 'spree/shared/error_messages', locals: { target: @mail_method }
|
||||
|
||||
= form_tag admin_mail_method_path, method: :put do |f|
|
||||
= form_tag admin_mail_methods_path, method: :put do |f|
|
||||
%fieldset.no-border-top
|
||||
= render partial: 'form', locals: { f: f }
|
||||
.form-buttons.filter-actions.actions= button t("spree.actions.update"), 'icon-refresh'
|
||||
|
||||
@@ -32,6 +32,11 @@
|
||||
%label
|
||||
= check_box_tag "q[completed_at_not_null]", 1, true, {'ng-model' => 'q.completed_at_not_null'}
|
||||
= t(:show_only_complete_orders)
|
||||
.field
|
||||
= label_tag nil, t(:shipping_method)
|
||||
= select_tag("shipping_method_id",
|
||||
options_for_select(Spree::ShippingMethod.managed_by(spree_current_user).collect {|s| [t("spree.shipping_method.#{s.name}"), s.id]}),
|
||||
{include_blank: true, class: 'select2', 'ng-model' => 'shipping_method_id'})
|
||||
.field-block.alpha.eight.columns
|
||||
= label_tag nil, t(:distributors)
|
||||
= select_tag("q[distributor_id_in]",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
= render :partial => 'spree/admin/shared/order_tabs', :locals => { :current => 'Customer Details' }
|
||||
= render partial: 'spree/admin/shared/order_page_title'
|
||||
= render partial: 'spree/admin/shared/order_tabs', locals: { current: 'Customer Details' }
|
||||
|
||||
= csrf_meta_tags
|
||||
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
- if can?(:admin, Spree::Order)
|
||||
%li= button_link_to t(:back_to_orders_list), admin_orders_path, :icon => 'icon-arrow-left'
|
||||
|
||||
= render :partial => 'spree/admin/shared/order_tabs', :locals => { :current => 'Order Details' }
|
||||
= render partial: "spree/admin/shared/order_page_title"
|
||||
= render partial: "spree/admin/shared/order_tabs", locals: { current: 'Order Details' }
|
||||
|
||||
%div{"data-hook" => "admin_order_edit_header"}
|
||||
-# Suppress errors when manually creating a new order - needs to proceed to edit page
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
- content_for :page_title do
|
||||
= t(:new)
|
||||
= t(:new_order)
|
||||
\#
|
||||
= @order.number
|
||||
|
||||
- content_for :page_actions do
|
||||
%li= button_link_to t(:back_to_orders_list), spree.admin_orders_path, :icon => 'icon-arrow-left'
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
- content_for :page_title do
|
||||
= t(:new)
|
||||
|
||||
- content_for :page_actions do
|
||||
%li= button_link_to t(:back_to_orders_list), spree.admin_orders_path, :icon => 'icon-arrow-left'
|
||||
|
||||
= admin_inject_shops(module: 'admin.orders')
|
||||
= admin_inject_order_cycles
|
||||
|
||||
- content_for :page_title do
|
||||
= t(:new_order)
|
||||
\#
|
||||
= @order.number
|
||||
|
||||
= render 'spree/admin/shared/order_tabs', :current => 'Order Details'
|
||||
|
||||
= csrf_meta_tags
|
||||
|
||||
@@ -1,42 +1,44 @@
|
||||
= admin_inject_payment_method
|
||||
= admin_inject_json_ams_array "admin.paymentMethods", "shops", @hubs, Api::Admin::BasicEnterpriseSerializer
|
||||
%div.alpha.eleven.columns{ "ng-app" => "admin.paymentMethods", "ng-controller" => "paymentMethodCtrl" }
|
||||
.alpha.eleven.columns{ "ng-app" => "admin.paymentMethods", "ng-controller" => "paymentMethodCtrl" }
|
||||
.row
|
||||
= t '.deactivation_warning'
|
||||
.row
|
||||
.alpha.three.columns
|
||||
= label_tag nil, t(:name)
|
||||
= label_tag nil, t('.name')
|
||||
.omega.eight.columns
|
||||
= text_field :payment_method, :name, class: 'fullwidth'
|
||||
.row
|
||||
.alpha.three.columns
|
||||
= label_tag nil, t(:description)
|
||||
= label_tag nil, t('.description')
|
||||
.omega.eight.columns
|
||||
= text_area :payment_method, :description, {cols: 60, rows: 6, class: 'fullwidth'}
|
||||
- if spree_current_user.admin?
|
||||
.row
|
||||
.alpha.three.columns
|
||||
= label_tag nil, t(:environment)
|
||||
= label_tag nil, t('.environment')
|
||||
.omega.eight.columns
|
||||
= collection_select(:payment_method, :environment, Rails.configuration.database_configuration.keys.sort, :to_s, :titleize, {}, {id: 'gtwy-env', class: 'select2 fullwidth'})
|
||||
.row
|
||||
.alpha.three.columns
|
||||
= label_tag nil, t(:display)
|
||||
.omega.eight.columns
|
||||
= select(:payment_method, :display_on, Spree::PaymentMethod::DISPLAY.collect { |display| [t(display), display == :both ? nil : display.to_s] }, {}, {class: 'select2 fullwidth'})
|
||||
.row
|
||||
.alpha.three.columns
|
||||
= label_tag nil, t(:active)
|
||||
= label_tag nil, t('.display')
|
||||
.omega.eight.columns
|
||||
= select(:payment_method, :display_on, Spree::PaymentMethod::DISPLAY.collect { |display| [t('.' + display.to_s), display == :both ? nil : display.to_s] }, {}, {class: 'select2 fullwidth'})
|
||||
.row
|
||||
.alpha.three.columns
|
||||
= label_tag nil, t('.active')
|
||||
.two.columns
|
||||
= radio_button :payment_method, :active, true
|
||||
|
||||
= label_tag nil, t(:say_yes)
|
||||
= label_tag nil, t('.active_yes')
|
||||
.omega.six.columns
|
||||
= radio_button :payment_method, :active, false
|
||||
|
||||
= label_tag nil, t(:say_no)
|
||||
= label_tag nil, t('.active_no')
|
||||
|
||||
.row
|
||||
.alpha.three.columns
|
||||
= label(:payment_method, :tags, t(:tags))
|
||||
= label(:payment_method, :tags, t('.tags'))
|
||||
.omega.eight.columns
|
||||
= hidden_field(:payment_method, :tag_list, "ng-value" => "paymentMethod.tag_list")
|
||||
%tags-with-translation#something{ object: "paymentMethod" }
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#provider-settings{ ng: { controller: "ProvidersCtrl" } }
|
||||
.row
|
||||
.alpha.three.columns
|
||||
= label :payment_method, :type, t(:provider)
|
||||
= label :payment_method, :type, t('.provider')
|
||||
.omega.eight.columns
|
||||
= collection_select(:payment_method, :type, @providers, :to_s, :clean_name, (!@object.persisted? ? { :selected => "Spree::PaymentMethod::Check"} : {}), { class: 'select2 fullwidth', 'provider-prefs-for' => "#{@object.id}"})
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
= @payment_method.name
|
||||
- content_for :page_actions do
|
||||
%li
|
||||
= button_link_to t(:new), spree.new_admin_payment_method_path, icon: 'icon-plus'
|
||||
= button_link_to t('.new'), spree.new_admin_payment_method_path, icon: 'icon-plus'
|
||||
%li
|
||||
= button_link_to t('.back_to_payment_methods_list'), spree.admin_payment_methods_path, icon: 'icon-arrow-left'
|
||||
= render partial: 'spree/shared/error_messages', locals: { target: @payment_method }
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
- content_for :page_title do
|
||||
= Spree.t(:payment_methods)
|
||||
= t('.payment_methods')
|
||||
|
||||
- content_for :page_actions do
|
||||
%li
|
||||
= button_link_to Spree.t(:new_payment_method), new_object_url, icon: 'icon-plus', id: 'admin_new_payment_methods_link'
|
||||
= button_link_to t('.new_payment_method'), new_object_url, icon: 'icon-plus', id: 'admin_new_payment_methods_link'
|
||||
|
||||
- if @payment_methods.any?
|
||||
%table#listing_payment_methods.index
|
||||
@@ -17,12 +17,12 @@
|
||||
%col{style: "width: 11%"}
|
||||
%thead
|
||||
%tr
|
||||
%th= Spree.t(:name)
|
||||
%th= t(:products_distributor)
|
||||
%th= Spree.t(:provider)
|
||||
%th= Spree.t(:environment)
|
||||
%th= Spree.t(:display)
|
||||
%th= Spree.t(:active)
|
||||
%th= t('.name')
|
||||
%th= t('.products_distributor')
|
||||
%th= t('.provider')
|
||||
%th= t('.environment')
|
||||
%th= t('.display')
|
||||
%th= t('.active')
|
||||
%th.actions
|
||||
%tbody
|
||||
- @payment_methods.each do |method|
|
||||
@@ -34,10 +34,10 @@
|
||||
%br/
|
||||
%td= method.type
|
||||
%td.align-center= method.environment.to_s.titleize
|
||||
%td.align-center= method.display_on.blank? ? Spree.t(:both) : Spree.t(method.display_on)
|
||||
%td.align-center= method.active ? Spree.t(:say_yes) : Spree.t(:say_no)
|
||||
%td.align-center= method.display_on.blank? ? t('.both') : t('.' + method.display_on.to_s)
|
||||
%td.align-center= method.active ? t('.active_yes') : t('.active_no')
|
||||
%td.actions
|
||||
= link_to_edit method, no_text: true
|
||||
= link_to_delete method, no_text: true
|
||||
- else
|
||||
.alpha.twelve.columns.no-objects-found= Spree.t(:no_payment_methods_found)
|
||||
.alpha.twelve.columns.no-objects-found= t('.no_payment_methods_found')
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
= render partial: 'spree/admin/shared/order_page_title'
|
||||
= render partial: 'spree/admin/shared/order_tabs', locals: { current: 'Payments' }
|
||||
|
||||
- content_for :page_actions do
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
= render partial: 'spree/admin/shared/order_page_title'
|
||||
= render partial: 'spree/admin/shared/order_tabs', locals: { current: 'Payments' }
|
||||
|
||||
- content_for :page_title do
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
= render partial: 'spree/admin/shared/order_page_title'
|
||||
= render partial: 'spree/admin/shared/order_tabs', locals: { current: 'Payments' }
|
||||
|
||||
- content_for :page_title do
|
||||
|
||||
@@ -43,37 +43,6 @@
|
||||
|
||||
.clear
|
||||
|
||||
- unless @product.has_variants?
|
||||
= f.field_container :sku do
|
||||
= f.label :sku, t(:sku)
|
||||
= f.text_field :sku, :size => 16
|
||||
|
||||
.alpha.two.columns
|
||||
= f.field_container :on_hand do
|
||||
= f.label :on_hand, t(:on_hand)
|
||||
= f.number_field :on_hand, :min => 0
|
||||
.omega.two.columns
|
||||
= f.field_container :on_demand, :class => ['checkbox'] do
|
||||
%label
|
||||
= f.check_box :on_demand
|
||||
= t(:on_demand)
|
||||
|
||||
.clear
|
||||
|
||||
%ul#shipping_specs
|
||||
%li#shipping_specs_weight_field.field.alpha.two.columns
|
||||
= f.label :weight, t(:weight)
|
||||
= f.text_field :weight, :size => 4
|
||||
%li#shipping_specs_height_field.field.omega.two.columns
|
||||
= f.label :height, t(:height)
|
||||
= f.text_field :height, :size => 4
|
||||
%li#shipping_specs_width_field.field.alpha.two.columns
|
||||
= f.label :width, t(:width)
|
||||
= f.text_field :width, :size => 4
|
||||
%li#shipping_specs_depth_field.field.omega.two.columns
|
||||
= f.label :depth, t(:depth)
|
||||
= f.text_field :depth, :size => 4
|
||||
|
||||
= f.field_container :shipping_categories do
|
||||
= f.label :shipping_category_id, t(:shipping_categories)
|
||||
= f.collection_select(:shipping_category_id, @shipping_categories, :id, :name, { :include_blank => 'None' }, { :class => 'select2' })
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
- if @return_authorization.can_cancel?
|
||||
= button_link_to t('actions.cancel'), fire_admin_order_return_authorization_url(@order, @return_authorization, e: 'cancel'), method: :put, data: { confirm: t('.are_you_sure') }, icon: 'icon-remove'
|
||||
|
||||
= render partial: 'spree/admin/shared/order_page_title'
|
||||
= render partial: 'spree/admin/shared/order_tabs', locals: { current: 'Return Authorizations' }
|
||||
|
||||
- content_for :page_title do
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
= render partial: 'spree/admin/shared/order_page_title'
|
||||
= render partial: 'spree/admin/shared/order_tabs', locals: { current: 'Return Authorizations' }
|
||||
|
||||
- content_for :page_actions do
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
= render partial: 'spree/admin/shared/order_page_title'
|
||||
= render partial: 'spree/admin/shared/order_tabs', locals: { current: 'Return Authorizations' }
|
||||
|
||||
- content_for :page_title do
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
%ul.sidebar
|
||||
= configurations_sidebar_menu_item Spree.t(:general_settings), edit_admin_general_settings_path
|
||||
- if Spree::Config[:override_actionmailer_config]
|
||||
= configurations_sidebar_menu_item Spree.t(:mail_method_settings), edit_admin_mail_method_path
|
||||
= configurations_sidebar_menu_item Spree.t(:mail_method_settings), edit_admin_mail_methods_path
|
||||
= configurations_sidebar_menu_item Spree.t(:image_settings), edit_admin_image_settings_path
|
||||
= configurations_sidebar_menu_item Spree.t(:tax_categories), admin_tax_categories_path
|
||||
= configurations_sidebar_menu_item Spree.t(:tax_rates), admin_tax_rates_path
|
||||
|
||||
4
app/views/spree/admin/shared/_order_page_title.html.haml
Normal file
@@ -0,0 +1,4 @@
|
||||
- content_for :page_title do
|
||||
= t(:order)
|
||||
\#
|
||||
= @order.number
|
||||
@@ -1,8 +1,3 @@
|
||||
- content_for :page_title do
|
||||
= t(:order)
|
||||
\#
|
||||
= @order.number
|
||||
|
||||
- if @order.bill_address.present?
|
||||
= @order.bill_address.firstname
|
||||
= @order.bill_address.lastname
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
= tab :order_cycles, url: main_app.admin_order_cycles_path, icon: 'icon-refresh'
|
||||
= tab :orders, :subscriptions, :customer_details, :adjustments, :payments, :return_authorizations, url: admin_orders_path('q[s]' => 'completed_at desc'), icon: 'icon-shopping-cart'
|
||||
= tab :reports, icon: 'icon-file'
|
||||
= tab :general_settings, :mail_method, :image_settings, :tax_categories, :tax_rates, :tax_settings, :zones, :countries, :states, :payment_methods, :taxonomies, :shipping_methods, :shipping_categories, :enterprise_fees, :contents, :invoice_settings, :matomo_settings, :stripe_connect_settings, label: 'configuration', icon: 'icon-wrench', url: edit_admin_general_settings_path
|
||||
= tab :general_settings, :mail_methods, :image_settings, :tax_categories, :tax_rates, :tax_settings, :zones, :countries, :states, :payment_methods, :taxonomies, :shipping_methods, :shipping_categories, :enterprise_fees, :contents, :invoice_settings, :matomo_settings, :stripe_connect_settings, label: 'configuration', icon: 'icon-wrench', url: edit_admin_general_settings_path
|
||||
= tab :enterprises, :enterprise_relationships, url: main_app.admin_enterprises_path
|
||||
= tab :customers, url: main_app.admin_customers_path
|
||||
= tab :enterprise_groups, url: main_app.admin_enterprise_groups_path, label: 'groups'
|
||||
|
||||
@@ -15,13 +15,12 @@
|
||||
.omega.eight.columns
|
||||
= f.text_area :description, class: 'fullwidth', rows: 2, placeholder: t(:spree_admin_eg_collect_your_order)
|
||||
= error_message_on :shipping_method, :description
|
||||
- if spree_current_user.admin?
|
||||
.row
|
||||
.alpha.three.columns
|
||||
= f.label :display_on, t(:display)
|
||||
.omega.eight.columns
|
||||
= select(:shipping_method, :display_on, [[t(".both"), nil], [t(".back_end"), "back_end"]], {}, {class: 'select2 fullwidth'})
|
||||
= error_message_on :shipping_method, :display_on
|
||||
.row
|
||||
.alpha.three.columns
|
||||
= f.label :display_on, t(:display)
|
||||
.omega.eight.columns
|
||||
= select(:shipping_method, :display_on, [[t(".both"), nil], [t(".back_end"), "back_end"]], {}, {class: 'select2 fullwidth'})
|
||||
= error_message_on :shipping_method, :display_on
|
||||
|
||||
.row
|
||||
.alpha.three.columns
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
<button class="add_variant no-text icon-plus icon_link with-tip" data-stock-location-id="{{variant.stock_location_id}}" title="Add" data-action="add"></button>
|
||||
</td>
|
||||
{{else}}
|
||||
<td><%= Spree.t(:out_of_stock) %></td>
|
||||
<td><%= t('.out_of_stock') %></td>
|
||||
<td>0</td>
|
||||
{{/if}}
|
||||
</tr>
|
||||
|
||||
@@ -3,40 +3,32 @@
|
||||
= render partial: 'spree/admin/shared/product_tabs', locals: {current: 'Variants'}
|
||||
|
||||
#new_variant
|
||||
- if @variants.any?
|
||||
%table.index.sortable{"data-sortable-link" => update_positions_admin_product_variants_path(@product)}
|
||||
%colgroup
|
||||
%col{style: "width: 5%"}/
|
||||
%col{style: "width: 25%"}/
|
||||
%col{style: "width: 20%"}/
|
||||
%col{style: "width: 20%"}/
|
||||
%col{style: "width: 15%"}/
|
||||
%col{style: "width: 15%"}/
|
||||
%thead
|
||||
%tr
|
||||
%th{colspan: "2"}= t('.options')
|
||||
%th= t('.price')
|
||||
%th= t('.sku')
|
||||
%th.actions
|
||||
%tbody
|
||||
- @variants.each do |variant|
|
||||
%tr{id: spree_dom_id(variant), class: cycle('odd', 'even'), style: "#{"color:red;" if variant.deleted? }" }
|
||||
%td.no-border
|
||||
%span.handle
|
||||
%td= variant.full_name
|
||||
%td.align-center= variant.display_price.to_html
|
||||
%td.align-center= variant.sku
|
||||
%td.actions
|
||||
= link_to_edit(variant, no_text: true) unless variant.deleted?
|
||||
= link_to_delete(variant, no_text: true) unless variant.deleted?
|
||||
- unless @product.has_variants?
|
||||
%tr
|
||||
%td{colspan: "5"}= t(:none)
|
||||
|
||||
- else
|
||||
.alpha.twelve.columns.no-objects-found
|
||||
= t('.no_results')
|
||||
\.
|
||||
%table.index.sortable{"data-sortable-link" => update_positions_admin_product_variants_path(@product)}
|
||||
%colgroup
|
||||
%col{style: "width: 5%"}/
|
||||
%col{style: "width: 25%"}/
|
||||
%col{style: "width: 20%"}/
|
||||
%col{style: "width: 20%"}/
|
||||
%col{style: "width: 15%"}/
|
||||
%col{style: "width: 15%"}/
|
||||
%thead
|
||||
%tr
|
||||
%th{colspan: "2"}= t('.options')
|
||||
%th= t('.price')
|
||||
%th= t('.sku')
|
||||
%th.actions
|
||||
%tbody
|
||||
- @variants.each do |variant|
|
||||
%tr{id: spree_dom_id(variant), class: cycle('odd', 'even'), style: "#{"color:red;" if variant.deleted? }" }
|
||||
%td.no-border
|
||||
%span.handle
|
||||
%td= variant.full_name
|
||||
%td.align-center= variant.display_price.to_html
|
||||
%td.align-center= variant.sku
|
||||
%td.actions
|
||||
= link_to_edit(variant, no_text: true) unless variant.deleted?
|
||||
= link_to_delete(variant, no_text: true) unless variant.deleted?
|
||||
|
||||
- if @product.empty_option_values?
|
||||
%p.first_add_option_types.no-objects-found
|
||||
|
||||
@@ -1,11 +1,29 @@
|
||||
%h3
|
||||
= t(".customer_greeting", name: @order.bill_address.firstname)
|
||||
%h4
|
||||
= t(".instructions")
|
||||
%span.clear
|
||||
%table.social.white-bg.fullwidth
|
||||
%table.column
|
||||
%tr
|
||||
%td
|
||||
%h3
|
||||
= t(".customer_greeting", name: @order.bill_address.firstname)
|
||||
%h4
|
||||
= t(".instructions_html", distributor: @order.distributor.name )
|
||||
%img{src: "#{@order.distributor.logo.url(:medium)}"}
|
||||
|
||||
%p.callout
|
||||
= t(".dont_cancel", email: @order.distributor.contact.email)
|
||||
|
||||
%p
|
||||
%h4
|
||||
= t(".order_summary_canceled_html", number: @order.number)
|
||||
%p
|
||||
= t(".details")
|
||||
|
||||
= t(".order_summary_canceled")
|
||||
= render 'order_summary'
|
||||
|
||||
%p
|
||||
- if @order.paid?
|
||||
= t(".paid_order", distributor: @order.distributor.name)
|
||||
- else
|
||||
= t(".unpaid_order")
|
||||
|
||||
= render 'signoff'
|
||||
= render 'shared/mailers/social_and_contact'
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
- if target && target.errors.any?
|
||||
#errorExplanation.errorExplanation
|
||||
%h2
|
||||
= Spree.t(:errors_prohibited_this_record_from_being_saved, count: target.errors.count)
|
||||
\:
|
||||
= t(".errors_prohibited_this_record_from_being_saved", count: target.errors.count)
|
||||
%p
|
||||
= Spree.t(:there_were_problems_with_the_following_fields)
|
||||
= t(".there_were_problems_with_the_following_fields")
|
||||
\:
|
||||
%ul
|
||||
- target.errors.full_messages.each do |msg|
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
%th.order3.show-for-large-up= t('.changes_allowed_until')
|
||||
%th.order4.show-for-large-up= t('.items')
|
||||
%th.order5.text-right= t('.total')
|
||||
%th.order6.text-right.show-for-large-up= t('.edit')
|
||||
%th.order7.text-right= t('.cancel')
|
||||
%th.order6.text-right= t('.edit')
|
||||
%th.order7.show-for-large-up.text-right= t('.cancel')
|
||||
%tbody.transaction-group{"ng-repeat" => "order in Orders.changeable", "ng-class-odd"=>"'odd'", "ng-class-even"=>"'even'"}
|
||||
%tr.order-row
|
||||
%td.order1
|
||||
@@ -18,7 +18,7 @@
|
||||
%td.order3.show-for-large-up{"ng-bind" => "::order.changes_allowed_until"}
|
||||
%td.order4.show-for-large-up{"ng-bind" => "::order.item_count"}
|
||||
%td.order5.text-right{"ng-class" => "{'credit' : order.total < 0, 'debit' : order.total > 0, 'paid' : order.total == 0}","ng-bind" => "::order.total | localizeCurrency"}
|
||||
%td.order6.text-right.show-for-large-up.brick
|
||||
%td.order6.text-right.brick
|
||||
%a{"ng-href" => "{{::order.path}}" }= t('.edit')
|
||||
%td.order7.text-right
|
||||
%td.order7.show-for-large-up.text-right
|
||||
= link_to t('.cancel'), "", method: :put, "ng-href" => "{{::order.cancel_path}}", "confirm-link-click" => t('orders_confirm_cancel')
|
||||
|
||||
@@ -5,6 +5,7 @@ defaults: &defaults
|
||||
host: <%= ENV.fetch('OFN_DB_HOST', 'localhost') %>
|
||||
username: <%= ENV.fetch('OFN_DB_USERNAME', 'ofn') %>
|
||||
password: <%= ENV.fetch('OFN_DB_PASSWORD', 'f00d') %>
|
||||
port: <%= ENV.fetch('OFN_DB_PORT', 5432) %>
|
||||
|
||||
development:
|
||||
<<: *defaults
|
||||
|
||||
@@ -363,7 +363,6 @@ ar:
|
||||
title: "إعدادات Matomo"
|
||||
matomo_url: "العنوان الالكتروني ل Matomo "
|
||||
matomo_site_id: "معرف موقع Matomo"
|
||||
info_html: "Matomo هو تحليلات الويب والجوال. يمكنك إما تنصيب Matomo محليًا أو استخدام خدمة استضافة سحابية. انظر <a href='http://matomo.org' target='_blank'>matomo.org</a> لمزيد من المعلومات."
|
||||
config_instructions_html: "هنا يمكنك تهيئة تكامل Matomo لشبكة الغذاء المفتوح. يجب أن يشير عنوان الالكتروني URL الخاص بـ Matomo أدناه إلى مثيل Matomo حيث سيتم إرسال معلومات تتبع المستخدم إلى ؛ إذا تم تركه فارغًا ، فسيتم تعطيل تتبع مستخدم Matomo. حقل معرف الموقع ليس إلزاميًا ولكنه مفيد إذا كنت تتعقب أكثر من موقع ويب على مثيل Matomo ؛ يمكن العثور عليه على وحدة تحكم مثيل Matomo."
|
||||
customers:
|
||||
index:
|
||||
@@ -398,6 +397,7 @@ ar:
|
||||
footer_and_external_links: تذييل والروابط الخارجية
|
||||
your_content: المحتوى الخاص بك
|
||||
user_guide: دليل المستخدم
|
||||
map: خريطة
|
||||
enterprise_fees:
|
||||
index:
|
||||
title: "رسوم الشركة"
|
||||
@@ -2752,6 +2752,8 @@ ar:
|
||||
new_payment: "دفعة جديد"
|
||||
capture: "إلتقاط"
|
||||
void: "فارغ"
|
||||
login: "تسجيل الدخول"
|
||||
password: "كلمه السر"
|
||||
configurations: "تهيئة"
|
||||
general_settings: "الاعدادات العامة"
|
||||
site_name: "اسم الموقع"
|
||||
@@ -2816,8 +2818,6 @@ ar:
|
||||
abbreviation: "الاختصار"
|
||||
new_state: "محافظة جديدة"
|
||||
payment_methods: "طرق الدفع"
|
||||
new_payment_method: "طريقة الدفع الجديدة"
|
||||
provider: "مزود"
|
||||
taxonomies: "التصنيفات"
|
||||
new_taxonomy: "تصنيف جديد"
|
||||
back_to_taxonomies_list: "العودة إلى قائمة التصنيفات"
|
||||
@@ -3024,10 +3024,23 @@ ar:
|
||||
categories: "التصنيفات"
|
||||
zones: "مناطق"
|
||||
payment_methods:
|
||||
index:
|
||||
payment_methods: "طريقة الدفع"
|
||||
new_payment_method: "طريقة الدفع الجديدة"
|
||||
name: "الاسم"
|
||||
products_distributor: "الموزع"
|
||||
provider: "مزود"
|
||||
environment: "بيئة"
|
||||
display: "عرض"
|
||||
active: "نشط"
|
||||
both: "على حد سواء"
|
||||
active_yes: "نعم"
|
||||
active_no: "لا"
|
||||
new:
|
||||
new_payment_method: "طريقة الدفع الجديدة"
|
||||
back_to_payment_methods_list: "العودة إلى قائمة طرق الدفع"
|
||||
edit:
|
||||
new: "جديد"
|
||||
editing_payment_method: "تحرير طريقة الدفع"
|
||||
back_to_payment_methods_list: "العودة إلى قائمة طرق الدفع"
|
||||
stripe_connect:
|
||||
@@ -3043,6 +3056,17 @@ ar:
|
||||
account_id: معرف الحساب
|
||||
business_name: الاسم التجاري
|
||||
charges_enabled: تم تمكين الدفع
|
||||
form:
|
||||
name: "الاسم"
|
||||
description: "وصف"
|
||||
environment: "بيئة"
|
||||
display: "عرض"
|
||||
active: "نشط"
|
||||
active_yes: "نعم"
|
||||
active_no: "لا"
|
||||
tags: "الاوسمة"
|
||||
providers:
|
||||
provider: "مزود"
|
||||
payments:
|
||||
source_forms:
|
||||
stripe:
|
||||
@@ -3143,6 +3167,7 @@ ar:
|
||||
display_as: "عرض ب"
|
||||
display_name: "اسم العرض"
|
||||
autocomplete:
|
||||
out_of_stock: "غير متوفر"
|
||||
producer_name: "المنتج"
|
||||
unit: "وحدة"
|
||||
shared:
|
||||
@@ -3207,9 +3232,6 @@ ar:
|
||||
invalid: غير صالحة
|
||||
order_mailer:
|
||||
cancel_email:
|
||||
customer_greeting: "مرحبًا %{name}!"
|
||||
instructions: "تم إلغاء طلبك. يرجى الاحتفاظ بمعلومات الإلغاء هذه بسجلاتك."
|
||||
order_summary_canceled: "ملخص الطلب [ملغى]"
|
||||
subject: "إلغاء الطلب"
|
||||
confirm_email:
|
||||
subject: "تأكيد الطلب"
|
||||
|
||||
@@ -368,8 +368,10 @@ ca:
|
||||
title: "Configuració de Matomo"
|
||||
matomo_url: "URL de Matomo"
|
||||
matomo_site_id: "Identificador de Matomo"
|
||||
info_html: "Matomo és un analitzador de webs i mòbils. Podeu allotjar Matomo de manera local o utilitzar un servei al núvol. Vegeu <a href='http://matomo.org' target='_blank'> matomo.org </a> per obtenir més informació."
|
||||
matomo_tag_manager_url: "URL de Matomo Tag Manager"
|
||||
info_html: "Matomo és una aplicació d'analytics web i mòbil. Podeu allotjar Matomo en local o bé utilitzar un servei allotjat al núvol. Consulteu <a href='http://matomo.org' target='_blank'>matomo.org</a> per obtenir més informació."
|
||||
config_instructions_html: "Aquí podeu configurar la integració Matomo OFN. L'URL de Matomo que us apareix a continuació ha d'indicar la instància de Matomo en la qual s'enviarà la informació de seguiment de l'usuari; si es deixa buit, el seguiment de l'usuari de Matomo estarà desactivat. El camp d'identificació del lloc no és obligatori, però és útil si fa un seguiment de més d'un lloc web en una sola instància de Matomo; es pot trobar a la consola d'instància de Matomo."
|
||||
config_instructions_tag_manager_html: "En configurar l'URL de Matomo Tag Manager s'activa Matomo Tag Manager. Aquesta eina us permet configurar esdeveniments d’analítica. L’URL de Matomo Tag Manager es copia de la secció Instal·lar codi de Matomo Tag Manager. Assegureu-vos de seleccionar el contenidor i l’entorn adequats ja que aquestes opcions canvien l’URL."
|
||||
customers:
|
||||
index:
|
||||
new_customer: "Nova consumidora"
|
||||
@@ -403,6 +405,7 @@ ca:
|
||||
footer_and_external_links: Peu de pàgina i enllaços externs
|
||||
your_content: El vostre contingut
|
||||
user_guide: Guia de l'usuari
|
||||
map: Mapa
|
||||
enterprise_fees:
|
||||
index:
|
||||
title: "Comissions de l'organització"
|
||||
@@ -687,6 +690,7 @@ ca:
|
||||
ofn_uid_tip: L'identificador únic que s’utilitza per identificar l'organització a Open Food Network.
|
||||
shipping_methods:
|
||||
name: "Nom"
|
||||
applies: "Actiu?"
|
||||
manage: "Gestiona els mètodes d'enviament"
|
||||
create_button: "Crea un nou mètode d'enviament"
|
||||
create_one_button: "Crea'n un ara"
|
||||
@@ -2811,6 +2815,14 @@ ca:
|
||||
new_payment: "Nou pagament"
|
||||
capture: "Captura"
|
||||
void: "Buit"
|
||||
login: "Inicia sessió"
|
||||
password: "Contrasenya"
|
||||
signature: "Signatura"
|
||||
solution: "Solució"
|
||||
landing_page: "Pàgina d'inici"
|
||||
server: "Servidor"
|
||||
test_mode: "Mode de prova"
|
||||
logourl: "URL del logo"
|
||||
configurations: "Configuracions"
|
||||
general_settings: "Configuració general"
|
||||
site_name: "Nom del lloc"
|
||||
@@ -2875,8 +2887,6 @@ ca:
|
||||
abbreviation: "Abreviatura"
|
||||
new_state: "Nou estat"
|
||||
payment_methods: "Mètodes de Pagament"
|
||||
new_payment_method: "Nou mètode de pagament"
|
||||
provider: "Proveïdor"
|
||||
taxonomies: "Taxonomies"
|
||||
new_taxonomy: "Nova taxonomia"
|
||||
back_to_taxonomies_list: "Torna a la llista de taxonomies"
|
||||
@@ -2929,6 +2939,12 @@ ca:
|
||||
options: "Opcions"
|
||||
actions:
|
||||
update: "Actualitzar"
|
||||
shared:
|
||||
error_messages:
|
||||
errors_prohibited_this_record_from_being_saved:
|
||||
one: "Un error va prohibir guardar aquest registre:"
|
||||
other: "%{count} errors han impedit guardar aquest registre:"
|
||||
there_were_problems_with_the_following_fields: "Hi ha hagut problemes amb els camps següents"
|
||||
errors:
|
||||
messages:
|
||||
blank: "no es pot deixar en blanc"
|
||||
@@ -3071,6 +3087,8 @@ ca:
|
||||
zone: "Zona"
|
||||
calculator: "Calculadora"
|
||||
display: "Mostra"
|
||||
both: "Ambdues, validació de comanda i administració"
|
||||
back_end: "Només pàgina administració (back office) "
|
||||
no_shipping_methods_found: "No s’han trobat mètodes d’enviament"
|
||||
new:
|
||||
new_shipping_method: "Nou mètode d'enviament"
|
||||
@@ -3083,11 +3101,29 @@ ca:
|
||||
categories: "Categories"
|
||||
zones: "Zones"
|
||||
both: "Comandes com administració"
|
||||
back_end: "Només pàgina administració (back office) "
|
||||
deactivation_warning: "Desactivar un mètode d'enviament pot fer que desaparegui de la teva llista. Pots ocultar-lo de la pàgina de validació de comanda configurant l'opció \"Mostrar\" a \"només a la pàgina d'administració\" (back end)."
|
||||
payment_methods:
|
||||
index:
|
||||
payment_methods: "Mètodes de Pagament"
|
||||
new_payment_method: "Nou mètode de pagament"
|
||||
name: "Nom"
|
||||
products_distributor: "Distribuïdora"
|
||||
provider: "Proveïdor"
|
||||
environment: "Ambient"
|
||||
display: "Mostra"
|
||||
active: "Actiu"
|
||||
both: "Ambdós"
|
||||
front_end: "Visible només per al comprador"
|
||||
back_end: "Només pàgina administració (back office) "
|
||||
active_yes: "Sí"
|
||||
active_no: "No"
|
||||
no_payment_methods_found: "No s'han trobat mètodes de pagament"
|
||||
new:
|
||||
new_payment_method: "Nou mètode de pagament"
|
||||
back_to_payment_methods_list: "Tornar a la llista de mètodes de pagament"
|
||||
edit:
|
||||
new: "Nou"
|
||||
editing_payment_method: "Edició del mètode de pagament"
|
||||
back_to_payment_methods_list: "Tornar a la llista de mètodes de pagament"
|
||||
stripe_connect:
|
||||
@@ -3103,6 +3139,21 @@ ca:
|
||||
account_id: Identificador del compte
|
||||
business_name: Nom de l'empresa
|
||||
charges_enabled: Càrrecs habilitats
|
||||
form:
|
||||
name: "Nom"
|
||||
description: "Descripció"
|
||||
environment: "Ambient"
|
||||
display: "Mostra"
|
||||
active: "Actiu"
|
||||
active_yes: "Sí"
|
||||
active_no: "No"
|
||||
both: "Ambdues, validació de comanda i administració"
|
||||
front_end: "Visible només per al comprador"
|
||||
back_end: "Només pàgina administració (back office) "
|
||||
tags: "Etiquetes"
|
||||
deactivation_warning: "Desactivar un mètode de pagament pot fer que el mètode de pagament desapareixi de la vostra llista. De forma alternativa, podeu amagar un mètode de pagament a la pàgina de compra configurant l'opció \"Mostrar\" a \"només a la pàgina d'administració\" (back end)."
|
||||
providers:
|
||||
provider: "Proveïdor"
|
||||
payments:
|
||||
source_forms:
|
||||
stripe:
|
||||
@@ -3205,6 +3256,7 @@ ca:
|
||||
display_as_placeholder: 'per exemple. 2 kg'
|
||||
display_name_placeholder: 'per exemple. Tomàquets'
|
||||
autocomplete:
|
||||
out_of_stock: "Fora d'existència"
|
||||
producer_name: "Productor"
|
||||
unit: "Unitat"
|
||||
shared:
|
||||
@@ -3242,6 +3294,7 @@ ca:
|
||||
format: '%d-% m-% Y'
|
||||
js_format: 'dd-mm-yy'
|
||||
orders:
|
||||
error_flash_for_unavailable_items: "Un ítem del teu carret ja no està disponible. Sis plau actualitza les quantitats seleccionades."
|
||||
edit:
|
||||
login_to_view_order: "Si us plau inicia sessió per veure la teva comanda."
|
||||
bought:
|
||||
@@ -3269,9 +3322,14 @@ ca:
|
||||
invalid: invàlid
|
||||
order_mailer:
|
||||
cancel_email:
|
||||
customer_greeting: "Hola %{name}!"
|
||||
instructions: "La teva comanda ha estat anul·lada. Conserva aquesta informació de cancel·lació per als teus registres."
|
||||
order_summary_canceled: "Resum de comanda [CANCEL·LADA]"
|
||||
customer_greeting: "Benvolgut/da,%{name}"
|
||||
instructions_html: "La teva comanda<strong> %{distributor}</strong> ha estat CANCEL·LADA"
|
||||
dont_cancel: "Si heu canviat d'opinió o no voleu cancel·lar aquesta comanda, poseu-vos en contacte amb %{email}"
|
||||
order_summary_canceled_html: "<strong>Resum de comanda # %{number} [CANCELAT]</strong>"
|
||||
details: "Aquí teniu els detalls del que vau demanar:"
|
||||
unpaid_order: "La vostra comanda no s'havia pagat, per la qual cosa no s'ha realitzat cap reemborsament"
|
||||
paid_order: "La vostra comanda s'havia pagat per la qual cosa %{distributor} ha reemborsat l'import complet"
|
||||
credit_order: "La vostra comanda s'havia pagat i per tant, s'ha abonat l'import al vostre compte"
|
||||
subject: "Cancel·lació de la comanda"
|
||||
confirm_email:
|
||||
subject: "Confirmació de la comanda"
|
||||
|
||||
@@ -367,7 +367,6 @@ de_DE:
|
||||
title: "Matomo-Einstellungen"
|
||||
matomo_url: "Matomo-URL"
|
||||
matomo_site_id: "Matomo-Site-ID"
|
||||
info_html: "Matomo ist eine Web- und Mobile Analytics. Sie können Matomo entweder lokal hosten oder einen von der Cloud gehosteten Dienst verwenden. Weitere Informationen finden Sie unter <a href='http://matomo.org' target='_blank'> matomo.org </a>."
|
||||
config_instructions_html: "Hier können Sie die OFN Matomo Integration konfigurieren. Die unten angegebene Matomo-URL sollte auf die Matomo-Instanz verweisen, an die die Benutzerverfolgungsinformationen gesendet werden. Wenn es leer bleibt, wird das Matomo-Benutzer-Tracking deaktiviert. Das Feld Site-ID ist nicht obligatorisch, aber nützlich, wenn Sie mehr als eine Website in einer einzelnen Matomo-Instanz verfolgen. Es kann auf der Matomo-Instanzkonsole gefunden werden."
|
||||
customers:
|
||||
index:
|
||||
@@ -402,6 +401,7 @@ de_DE:
|
||||
footer_and_external_links: Fußzeile und externe Links
|
||||
your_content: Ihr Inhalt
|
||||
user_guide: Benutzerhandbuch
|
||||
map: Karte
|
||||
enterprise_fees:
|
||||
index:
|
||||
title: "Unternehmensgebühren"
|
||||
@@ -2785,6 +2785,8 @@ de_DE:
|
||||
new_payment: "Neue Zahlung"
|
||||
capture: "Erfassung"
|
||||
void: "Leere"
|
||||
login: "Anmeldung"
|
||||
password: "Passwort"
|
||||
configurations: "Konfigurationen"
|
||||
general_settings: "Allgemeine Einstellungen"
|
||||
site_name: "Site-Name"
|
||||
@@ -2849,8 +2851,6 @@ de_DE:
|
||||
abbreviation: "Abkürzung"
|
||||
new_state: "Neuer Staat"
|
||||
payment_methods: "Zahlungsarten"
|
||||
new_payment_method: "Neue Zahlungsart"
|
||||
provider: "Anbieter"
|
||||
taxonomies: "Taxonomien"
|
||||
new_taxonomy: "Neue Taxonomie"
|
||||
back_to_taxonomies_list: "Zurück zur Taxonomieliste"
|
||||
@@ -3057,6 +3057,13 @@ de_DE:
|
||||
categories: "Kategorien"
|
||||
zones: "Zonen"
|
||||
payment_methods:
|
||||
index:
|
||||
payment_methods: "Zahlungsarten"
|
||||
name: "Name"
|
||||
products_distributor: "Verteiler"
|
||||
both: "Beide"
|
||||
active_yes: "Ja"
|
||||
active_no: "Nein"
|
||||
new:
|
||||
new_payment_method: "Neue Zahlungsart"
|
||||
back_to_payment_methods_list: "Zurück zur Liste der Zahlungsmethoden"
|
||||
@@ -3076,6 +3083,12 @@ de_DE:
|
||||
account_id: Konto-ID
|
||||
business_name: Geschäftsname
|
||||
charges_enabled: Gebühren aktiviert
|
||||
form:
|
||||
name: "Name"
|
||||
description: "Beschreibung"
|
||||
active_yes: "Ja"
|
||||
active_no: "Nein"
|
||||
tags: "Stichwörter"
|
||||
payments:
|
||||
source_forms:
|
||||
stripe:
|
||||
@@ -3236,9 +3249,6 @@ de_DE:
|
||||
invalid: ungültig
|
||||
order_mailer:
|
||||
cancel_email:
|
||||
customer_greeting: "Hallo %{name}!"
|
||||
instructions: "Ihre Bestellung wurde storniert. Bitte bewahren Sie diese Stornierungsinformationen für Ihre Unterlagen auf."
|
||||
order_summary_canceled: "Bestellübersicht [STORNIERT]"
|
||||
subject: "Stornierung der Bestellung"
|
||||
confirm_email:
|
||||
subject: "Bestellbestätigung"
|
||||
|
||||