Compare commits

..

68 Commits

Author SHA1 Message Date
Matt-Yorkley
b1bfac5144 Update all locales with the latest Transifex translations 2021-06-01 19:10:58 +01:00
Pau Pérez Fabregat
01f8aff3e0 Merge pull request #7716 from coopdevs/pick-up-site-name-from-env
Allow :site_name to be picked up from ENV vars
2021-06-01 13:50:36 +02:00
Matt-Yorkley
7f9179193e Merge pull request #7713 from openfoodfoundation/dependabot/npm_and_yarn/ws-7.4.6
Bump ws from 7.4.4 to 7.4.6
2021-05-31 16:07:05 +02:00
Pau Perez
3be0e1c13a Allow :site_name to be picked up from ENV vars
This mimics what we did in 6377736f4. This way provisioning an instance
from scratch doesn't require configuring things from the backoffice,
which will simplify the roll out of
https://github.com/openfoodfoundation/ofn-install/pull/734.
2021-05-31 15:50:54 +02:00
Pau Pérez Fabregat
18c020535a Merge pull request #7711 from Matt-Yorkley/sidekiq
Sidekiq!
2021-05-31 15:11:45 +02:00
Matt-Yorkley
8d1fcc06fd Remove logfile config
This setting was removed in Sidekiq 6.0, logs are handled a bit differently now. The logging works though 👍
2021-05-31 10:46:43 +01:00
Matt-Yorkley
2b6a72ffb4 Remove DelayedJob web UI 2021-05-31 10:10:36 +01:00
Pau Pérez Fabregat
157d86c94f Merge pull request #7714 from openfoodfoundation/dependabot/bundler/test-unit-3.4.2
Bump test-unit from 3.4.1 to 3.4.2
2021-05-31 11:04:42 +02:00
Pau Pérez Fabregat
d41de06809 Merge pull request #7707 from openfoodfoundation/transifex
Transifex
2021-05-31 10:59:04 +02:00
Transifex-Openfoodnetwork
d730f21dc7 Updating translations for config/locales/en_GB.yml 2021-05-31 17:54:39 +10:00
dependabot[bot]
49dfaa20ab Bump test-unit from 3.4.1 to 3.4.2
Bumps [test-unit](https://github.com/test-unit/test-unit) from 3.4.1 to 3.4.2.
- [Release notes](https://github.com/test-unit/test-unit/releases)
- [Commits](https://github.com/test-unit/test-unit/compare/3.4.1...3.4.2)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-31 05:38:26 +00:00
dependabot[bot]
bfeb892cab Bump ws from 7.4.4 to 7.4.6
Bumps [ws](https://github.com/websockets/ws) from 7.4.4 to 7.4.6.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/7.4.4...7.4.6)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-30 21:28:21 +00:00
Matt-Yorkley
4b56422abd Add network timeouts
In rare cases where Redis is being updated/restarted while a job is running, this should add some flexibility.
2021-05-29 21:07:36 +01:00
Matt-Yorkley
53e3e2b66d Remove outdated Job test helpers
This logic around testing jobs is already handled by integrations with ActiveJob since Rails 4.2
2021-05-29 16:37:06 +01:00
Matt-Yorkley
834140f0a2 Don't dump massive binary PDF data into the job queue
Here we were rendering an entire PDF, then passing that PDF into the job queue as an *argument* containing the entire binary of the PDF in a massive string. This means the job object itself would contain that entire PDF. That's bad queueing!

We now create the PDF *during* the job (not before it), and pass simple arguments.
2021-05-29 16:06:29 +01:00
Matt-Yorkley
0d95d83ef9 Add sidekiq-scheduler to web UI 2021-05-29 13:12:33 +01:00
Matt-Yorkley
54d373c963 Enqueue scheduled jobs with sidekick-scheduler 2021-05-29 13:12:33 +01:00
Matt-Yorkley
1dfd68c691 Add sidekiq-scheduler 2021-05-29 13:12:33 +01:00
Matt-Yorkley
df9213e812 Bump port for new caching instance 2021-05-29 13:12:33 +01:00
Matt-Yorkley
03a078a3a0 Remove namespacing in cache config 2021-05-29 13:11:59 +01:00
Matt-Yorkley
11da025247 Add Sidekiq web interface 2021-05-29 13:11:59 +01:00
Matt-Yorkley
07a9da901f Switch queue adapter to Sidekiq 2021-05-29 13:11:59 +01:00
Matt-Yorkley
4ac3853be9 Configure Sidekiq 2021-05-29 13:11:59 +01:00
Transifex-Openfoodnetwork
eae7a9978c Updating translations for config/locales/de_DE.yml 2021-05-29 18:47:49 +10:00
Transifex-Openfoodnetwork
bdd8572fbf Updating translations for config/locales/en_US.yml 2021-05-29 02:59:45 +10:00
Matt-Yorkley
07422dac29 Add sidekiq gem 2021-05-28 16:58:26 +01:00
jibees
088ae496cc Merge pull request #7664 from shen-sat/7626-fix-unknown-currency-error
7626 fix unknown currency error
2021-05-28 16:18:04 +02:00
Pau Pérez Fabregat
c83a619082 Merge pull request #7705 from openfoodfoundation/transifex
Transifex
2021-05-28 15:45:58 +02:00
Transifex-Openfoodnetwork
ca7d1b111a Updating translations for config/locales/ru.yml 2021-05-28 21:35:53 +10:00
Pau Pérez Fabregat
3c507c1727 Merge pull request #7696 from openfoodfoundation/transifex
Transifex
2021-05-28 13:28:39 +02:00
Jean-Baptiste Bellet
b111d24488 Update all locales with the latest Transifex translations 2021-05-28 09:12:42 +02:00
Andy Brett
4dc8b44e81 Merge pull request #7695 from coopdevs/fix-ruby-installation-dockerfile
Fix Rbenv and ruby-build installation to get Ruby 2.5.9
2021-05-27 11:30:31 -07:00
Andy Brett
27a9ad7bcb Merge pull request #7698 from Matt-Yorkley/remove-eventmachine
Remove eventmachine gem
2021-05-27 11:30:14 -07:00
Pau Perez
fbd4d512d5 Add libssl as required by Ruby 2.5.9
This is a more recent libssl version in Ubuntu 20. Not related to the
libssl1.0 hack required by older Ruby versions.
2021-05-27 17:50:22 +02:00
Pau Perez
0f85db6d36 Fix Rbenv and ruby-build installation to get 2.5.9
This newer Ruby version can't be found on that ruby-build's branch that
we were installing. The `docker-compose build` command works again.
2021-05-27 17:50:22 +02:00
Pau Pérez Fabregat
0f78b5b315 Merge pull request #7616 from jibees/7602-unit-price-not-displaying-when-comma-is-the-decimal-separator
Backoffice: Unit price not displaying when comma is the decimal separator
2021-05-27 17:45:19 +02:00
Matt-Yorkley
78e3bb1acd Remove eventmachine gem
This was a dependency of a dependency a long time ago...
2021-05-27 15:57:17 +01:00
Transifex-Openfoodnetwork
c5e1c057ae Updating translations for config/locales/es.yml 2021-05-28 00:17:47 +10:00
Transifex-Openfoodnetwork
f34a3c3c02 Updating translations for config/locales/ca.yml 2021-05-28 00:17:29 +10:00
Transifex-Openfoodnetwork
546a32e97a Updating translations for config/locales/en_FR.yml 2021-05-27 22:47:27 +10:00
Transifex-Openfoodnetwork
abd269949d Updating translations for config/locales/fr.yml 2021-05-27 22:47:09 +10:00
Pau Pérez Fabregat
0d5f76b19e Merge pull request #7621 from jibees/7534-upload-logo-and-promo-image-for-enterprise
Upload enterprise image (logo and promo): force content type to "text/plain"
2021-05-27 11:33:56 +02:00
Pau Pérez Fabregat
bfa77baae1 Merge pull request #7542 from jibees/6359-add-payment-method-description-to-invoice
Add payment method description to invoice
2021-05-27 11:01:07 +02:00
Pau Pérez Fabregat
a2a1aac384 Merge pull request #7604 from coopdevs/compile-with-jemalloc
Compile Ruby with jemalloc
2021-05-27 08:30:51 +02:00
Pau Perez
43ede7ba26 Remove libssl1.0 from Dockerfile
We recently removed it from production in
bd9e382fba.
2021-05-27 08:09:51 +02:00
Andy Brett
883e9fdf62 Merge pull request #7690 from Matt-Yorkley/ruby-259
Bump Ruby to 2.5.9
2021-05-26 08:41:15 -07:00
Matt-Yorkley
c625766af1 Bump Ruby to 2.5.9 2021-05-26 09:36:28 +01:00
Andy Brett
23730ab28f Merge pull request #7683 from openfoodfoundation/dependabot/bundler/view_component-2.32.0
Bump view_component from 2.31.1 to 2.32.0
2021-05-25 07:36:25 -07:00
Jean-Baptiste Bellet
0c8bfea2f7 Add feature tests for upload images on enterprise registration
For both logo and promo images
2021-05-25 15:30:35 +02:00
Jean-Baptiste Bellet
0306732a3d Add test for enterprise logo and promo image uploading
- Add a fixture image to do the upload thanks to `fixture_file_upload`
 - Check the response status, the content type and the response body for both logo image and promo image
2021-05-25 15:30:29 +02:00
Jean-Baptiste Bellet
6842cbfda4 Force content type to "text/html"
- Force the content type to be `text/html` (instead of `application/json`)
2021-05-25 15:30:21 +02:00
Matt-Yorkley
ecb4cb31ad Merge pull request #7599 from Matt-Yorkley/cart-rendering
Move line item rendering to a collection in cart page
2021-05-25 13:37:50 +02:00
Jean-Baptiste Bellet
dd47430f19 Improve unlocalizeCurrency filter to handle many cases
- Complete the unit test to handle all these cases.
2021-05-25 13:14:53 +02:00
Jean-Baptiste Bellet
afe97bcc96 Add tests for creating/editing product/variant cases with decimal price 2021-05-24 10:55:05 +02:00
Jean-Baptiste Bellet
8af6fedf8a Factorize js:true as a common configuration around all tests 2021-05-24 10:55:05 +02:00
Jean-Baptiste Bellet
d8042b25e4 Add test for unlocalize currency filter
- Test that comma is well handle in both cases where comma is the default decimal separator or not.
2021-05-24 10:55:05 +02:00
Jean-Baptiste Bellet
f97e71d054 Add test for decimal price separated by point or comma 2021-05-24 10:55:05 +02:00
Jean-Baptiste Bellet
d066f0b94d Enable displayable unit price for price with comma as decimal separator
Retrieve the current decimal separator used to display price (`I18n.toCurrency()`), and check if number is formatted with only if this is `,`. If so, remplace comma by point, to pass the check `!isNaN`, and format unit price
2021-05-24 10:55:05 +02:00
dependabot[bot]
e9d389e4f1 Bump view_component from 2.31.1 to 2.32.0
Bumps [view_component](https://github.com/github/view_component) from 2.31.1 to 2.32.0.
- [Release notes](https://github.com/github/view_component/releases)
- [Changelog](https://github.com/github/view_component/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/view_component/compare/v2.31.1...v2.32.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-24 05:51:25 +00:00
Jean-Baptiste Bellet
325b97b683 Add tests around invoice printing in PDF
- use PDF Reader to read pdf and get its content
 - check with we print the payment description information section with the right value
2021-05-19 11:55:46 +02:00
Jean-Baptiste Bellet
7ab065e8cd Add section at the bottom of invoice: Payment Description at Checkout
- If there is any payments, we use the last one to retrieve the payment method description
Use the first completed payment to display payment description
Completed is state = "checkout" or state = "completed"
Squash w/ "Add section at the bottom of invoice: Payment Description at Checkout"

Squash w "Add section at the bottom of invoice: Payment Description a"
2021-05-19 11:55:38 +02:00
Jean-Baptiste Bellet
aea0670268 Add method payment_method to get the payment method from a payment
- Method `payment_method_name` now use `payment_method`
2021-05-19 11:55:38 +02:00
Shen Sat
cb914e4729 Change wording in create_admin_user to be more descriptive 2021-05-19 08:45:40 +01:00
Shen Sat
ab027d6af6 Change money initializer to use ENV vars instead of Spree::Config 2021-05-19 08:44:55 +01:00
Shen Sat
6a8ee544e8 Change readme to strong encourage running setup script 2021-05-19 08:44:10 +01:00
Pau Perez
ed6b7f1ab4 Split apt packages list into a name per line
This super long line was hard to read.
2021-05-10 19:57:24 +02:00
Pau Perez
4453123944 Compile Ruby with jemalloc 2021-05-10 19:31:04 +02:00
Matt-Yorkley
122ba385f7 Move line item rendering to collection in cart page
Improvement from upstream Spree commit. Brings a big performance boost to rendering, especially with larger numbers of items in the cart. 50%+ reduction in rendering times reported.
2021-05-10 11:50:31 +01:00
48 changed files with 500 additions and 198 deletions

View File

@@ -1 +1 @@
2.5.8
2.5.9

View File

@@ -7,7 +7,23 @@ RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN echo "deb http://security.ubuntu.com/ubuntu bionic-security main" >> /etc/apt/sources.list
# Install all the requirements
RUN apt-get update && apt-get install -y curl git build-essential software-properties-common wget zlib1g-dev libssl1.0-dev libreadline-dev libyaml-dev libffi-dev libxml2-dev libxslt1-dev wait-for-it imagemagick unzip
RUN apt-get update && apt-get install -y \
curl \
git \
build-essential \
software-properties-common \
wget \
zlib1g-dev \
libreadline-dev \
libyaml-dev \
libffi-dev \
libxml2-dev \
libxslt1-dev \
wait-for-it \
imagemagick \
unzip \
libjemalloc-dev \
libssl-dev
# Setup ENV variables
ENV PATH /usr/local/src/rbenv/shims:/usr/local/src/rbenv/bin:$PATH
@@ -19,11 +35,10 @@ WORKDIR /usr/src/app
COPY .ruby-version .
# Install Rbenv & Ruby
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 && \
RUN git clone --depth 1 https://github.com/rbenv/rbenv.git ${RBENV_ROOT} && \
git clone --depth 1 https://github.com/rbenv/ruby-build.git ${RBENV_ROOT}/plugins/ruby-build && \
echo 'eval "$(rbenv init -)"' >> /etc/profile.d/rbenv.sh && \
rbenv install $(cat .ruby-version) && \
RUBY_CONFIGURE_OPTS=--with-jemalloc rbenv install $(cat .ruby-version) && \
rbenv global $(cat .ruby-version) && \
gem install bundler --version=1.17.3

View File

@@ -47,7 +47,11 @@ $ sudo -u postgres psql -c "CREATE USER ofn WITH SUPERUSER CREATEDB PASSWORD 'f0
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.
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.
Next, it is _strongly recommended_ to run the setup script.
```sh
$ 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.
Now, your dreams of spinning up a development server can be realised:

11
Gemfile
View File

@@ -1,7 +1,7 @@
# frozen_string_literal: true
source 'https://rubygems.org'
ruby "2.5.8"
ruby "2.5.9"
git_source(:github) { |repo_name| "https://github.com/#{repo_name}.git" }
gem 'rails', '~> 5.2'
@@ -52,7 +52,6 @@ gem 'oauth2', '~> 1.4.7' # Used for Stripe Connect
gem 'daemons'
gem 'delayed_job_active_record'
gem 'delayed_job_web'
gem 'kaminari', '~> 1.2.1'
@@ -84,6 +83,8 @@ gem 'roadie-rails', '~> 2.2.0'
gem 'redis', '>= 4.0', require: ['redis', 'redis/connection/hiredis']
gem 'hiredis'
gem 'sidekiq'
gem 'sidekiq-scheduler'
gem 'combine_pdf'
gem 'wicked_pdf'
@@ -155,6 +156,7 @@ group :test do
gem 'test-prof'
gem 'webmock'
gem 'rails-controller-testing'
gem 'pdf-reader'
# See spec/spec_helper.rb for instructions
# gem 'perftools.rb'
end
@@ -171,10 +173,5 @@ group :development do
gem "view_component_storybook", require: "view_component/storybook/engine"
# 1.0.9 fixed openssl issues on macOS https://github.com/eventmachine/eventmachine/issues/602
# While we don't require this gem directly, no dependents forced the upgrade to a version
# greater than 1.0.9, so we just required the latest available version here.
gem 'eventmachine', '>= 1.2.3'
gem 'rack-mini-profiler', '< 3.0.0'
end

View File

@@ -47,6 +47,7 @@ PATH
GEM
remote: https://rubygems.org/
specs:
Ascii85 (1.1.0)
actioncable (5.2.6)
actionpack (= 5.2.6)
nio4r (~> 2.0)
@@ -113,6 +114,7 @@ GEM
activerecord (>= 4.2)
addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0)
afm (0.2.2)
andand (1.3.3)
angular-rails-templates (1.1.0)
railties (>= 4.2, < 7)
@@ -184,6 +186,7 @@ GEM
sass-rails (< 5.1)
sprockets (< 4.0)
concurrent-ruby (1.1.8)
connection_pool (2.2.5)
crack (0.4.5)
rexml
crass (1.0.6)
@@ -201,11 +204,6 @@ GEM
delayed_job_active_record (4.1.6)
activerecord (>= 3.0, < 6.2)
delayed_job (>= 3.0, < 5)
delayed_job_web (1.4.4)
activerecord (> 3.0.0)
delayed_job (> 2.0.3)
rack-protection (>= 1.5.5)
sinatra (>= 1.4.4)
devise (4.8.0)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
@@ -218,8 +216,10 @@ GEM
devise (>= 4.0.0, < 5.0.0)
diff-lcs (1.4.4)
docile (1.3.5)
e2mmap (0.1.0)
erubi (1.10.0)
eventmachine (1.2.7)
et-orbi (1.2.4)
tzinfo
excon (0.79.0)
execjs (2.7.0)
factory_bot (6.2.0)
@@ -267,6 +267,9 @@ GEM
foundation-rails (5.5.2.1)
railties (>= 3.1.0)
sass (>= 3.3.0, < 3.5)
fugit (1.4.5)
et-orbi (~> 1.1, >= 1.1.8)
raabro (~> 1.4)
fuubar (2.5.1)
rspec-core (~> 3.0)
ruby-progressbar (~> 1.4)
@@ -283,6 +286,7 @@ GEM
temple (>= 0.8.0)
tilt
hashdiff (1.0.1)
hashery (2.1.2)
highline (2.0.3)
hiredis (0.6.3)
i18n (1.8.10)
@@ -352,8 +356,6 @@ GEM
multi_json (1.15.0)
multi_xml (0.6.0)
multipart-post (2.1.1)
mustermann (1.1.1)
ruby2_keywords (~> 0.0.1)
nio4r (2.5.7)
nokogiri (1.11.4)
mini_portile2 (~> 2.5.0)
@@ -384,6 +386,12 @@ GEM
xml-simple
paypal-sdk-merchant (1.117.2)
paypal-sdk-core (~> 0.3.0)
pdf-reader (2.4.2)
Ascii85 (~> 1.0)
afm (~> 0.2.1)
hashery (~> 2.0)
ruby-rc4
ttfunk
pg (1.2.3)
power_assert (2.0.0)
pry (0.13.1)
@@ -393,6 +401,7 @@ GEM
byebug (~> 11.0)
pry (~> 0.13.0)
public_suffix (4.0.6)
raabro (1.4.0)
racc (1.5.2)
rack (2.2.3)
rack-mini-profiler (2.3.2)
@@ -519,6 +528,8 @@ GEM
ruby-rc4 (0.1.5)
ruby2_keywords (0.0.2)
rubyzip (2.3.0)
rufus-scheduler (3.7.0)
fugit (~> 1.1, >= 1.1.6)
sass (3.4.25)
sass-rails (5.0.7)
railties (>= 4.0.0, < 6)
@@ -534,17 +545,23 @@ GEM
rubyzip (>= 1.2.2)
shoulda-matchers (4.5.1)
activesupport (>= 4.2.0)
sidekiq (6.2.1)
connection_pool (>= 2.2.2)
rack (~> 2.0)
redis (>= 4.2.0)
sidekiq-scheduler (3.0.1)
e2mmap
redis (>= 3, < 5)
rufus-scheduler (~> 3.2)
sidekiq (>= 3)
thwait
tilt (>= 1.4.0)
simplecov (0.21.2)
docile (~> 1.1)
simplecov-html (~> 0.11)
simplecov_json_formatter (~> 0.1)
simplecov-html (0.12.3)
simplecov_json_formatter (0.1.2)
sinatra (2.1.0)
mustermann (~> 1.0)
rack (~> 2.2)
rack-protection (= 2.1.0)
tilt (~> 2.0)
spring (2.1.1)
spring-commands-rspec (1.0.4)
spring (>= 0.9.1)
@@ -566,12 +583,15 @@ GEM
stripe (5.30.0)
temple (0.8.2)
test-prof (1.0.5)
test-unit (3.4.1)
test-unit (3.4.2)
power_assert
thor (0.20.3)
thread_safe (0.3.6)
thwait (0.2.0)
e2mmap
tilt (2.0.10)
timecop (0.9.4)
ttfunk (1.7.0)
tzinfo (1.2.9)
thread_safe (~> 0.1)
uglifier (4.2.0)
@@ -587,7 +607,7 @@ GEM
get_process_mem (~> 0)
unicorn (>= 4, < 7)
uniform_notifier (1.14.1)
view_component (2.31.1)
view_component (2.32.0)
activesupport (>= 5.0.0, < 7.0)
view_component_storybook (0.8.0)
view_component (>= 2.2)
@@ -651,12 +671,10 @@ DEPENDENCIES
ddtrace
debugger-linecache
delayed_job_active_record
delayed_job_web
devise
devise-encryptable
devise-token_authenticatable
dfc_provider!
eventmachine (>= 1.2.3)
factory_bot_rails (= 6.2.0)
ffaker
figaro
@@ -695,6 +713,7 @@ DEPENDENCIES
paperclip (~> 3.4.1)
paranoia (~> 2.4)
paypal-sdk-merchant (= 1.117.2)
pdf-reader
pg (~> 1.2.3)
pry
pry-byebug
@@ -721,6 +740,8 @@ DEPENDENCIES
select2-rails (~> 3.4.7)
selenium-webdriver
shoulda-matchers
sidekiq
sidekiq-scheduler
simplecov
spring
spring-commands-rspec
@@ -743,7 +764,7 @@ DEPENDENCIES
wkhtmltopdf-binary
RUBY VERSION
ruby 2.5.8p224
ruby 2.5.9p229
BUNDLED WITH
1.17.3

View File

@@ -1,6 +1,7 @@
angular.module("admin.products").factory "UnitPrices", (VariantUnitManager, localizeCurrencyFilter) ->
angular.module("admin.products").factory "UnitPrices", (VariantUnitManager, localizeCurrencyFilter, unlocalizeCurrencyFilter) ->
class UnitPrices
@displayableUnitPrice: (price, scale, unit_type, unit_value, variant_unit_name) ->
price = unlocalizeCurrencyFilter(price)
if price && !isNaN(price) && unit_type && unit_value
value = localizeCurrencyFilter(UnitPrices.price(price, scale, unit_type, unit_value, variant_unit_name))
unit = UnitPrices.unit(scale, unit_type, variant_unit_name)
@@ -29,4 +30,4 @@ angular.module("admin.products").factory "UnitPrices", (VariantUnitManager, loca
else if unit_type == "weight"
"kg"
else if unit_type == "volume"
"L"
"L"

View File

@@ -0,0 +1,15 @@
angular.module("admin.utils").filter "unlocalizeCurrency", ()->
# Convert string to number using injected currency configuration.
(price) ->
# used decimal and thousands separators from currency configuration
decimal_separator = I18n.toCurrency(.1, {precision: 1, unit: ''}).substring(1,2)
thousands_separator = I18n.toCurrency(1000, {precision: 1, unit: ''}).substring(1,2)
if (price.length > 4)
# remove configured thousands separator if price is greater than 999
price = price.replaceAll(thousands_separator, '')
if (decimal_separator == ",")
price = price.replace(",", ".")
return parseFloat(price)

View File

@@ -44,9 +44,9 @@ module Api
authorize! :update, @enterprise
if params[:logo] && @enterprise.update( logo: params[:logo] )
render plain: @enterprise.logo.url(:medium), status: :ok
render html: @enterprise.logo.url(:medium), status: :ok
elsif params[:promo] && @enterprise.update( promo_image: params[:promo] )
render plain: @enterprise.promo_image.url(:medium), status: :ok
render html: @enterprise.promo_image.url(:medium), status: :ok
else
invalid_resource!(@enterprise)
end

View File

@@ -81,9 +81,7 @@ module Spree
end
def invoice
pdf = InvoiceRenderer.new.render_to_string(@order)
Spree::OrderMailer.invoice_email(@order.id, pdf).deliver_later
Spree::OrderMailer.invoice_email(@order.id).deliver_later
flash[:success] = t('admin.orders.invoice_email_sent')
respond_with(@order) { |format|

View File

@@ -1,9 +1,13 @@
module Spree
module PaymentMethodsHelper
def payment_method_name(payment)
def payment_method(payment)
# hack to allow us to retrieve the name of a "deleted" payment method
id = payment.payment_method_id
Spree::PaymentMethod.find_with_destroyed(id).name
Spree::PaymentMethod.find_with_destroyed(id)
end
def payment_method_name(payment)
payment_method(payment).name
end
end
end

View File

@@ -49,8 +49,10 @@ module Spree
end
end
def invoice_email(order_or_order_id, pdf)
def invoice_email(order_or_order_id)
@order = find_order(order_or_order_id)
pdf = InvoiceRenderer.new.render_to_string(@order)
attach_file("invoice-#{@order.number}.pdf", pdf)
I18n.with_locale valid_locale(@order.user) do
mail(to: @order.email,

View File

@@ -17,8 +17,7 @@
%th.cart-item-delete-header
%tbody#line_items{"data-hook" => ""}
= order_form.fields_for :line_items do |item_form|
= render :partial => 'line_item', :locals => { :variant => item_form.object.variant, :line_item => item_form.object, :item_form => item_form }
= render partial: 'line_item', collection: order_form.object.line_items, locals: {order_form: order_form}
= render 'bought' if show_bought_items? && @order.cart?

View File

@@ -1,37 +1,39 @@
%tr.line-item{class: "variant-#{variant.id}"}
%td.cart-item-description{'data-hook' => "cart_item_description"}
- variant = line_item.variant
= order_form.fields_for :line_items, line_item do |item_form|
%tr.line-item{class: "variant-#{variant.id}"}
%td.cart-item-description{'data-hook' => "cart_item_description"}
%div.item-thumb-image{"data-hook" => "cart_item_image"}
= render 'spree/shared/variant_thumbnail', variant: variant
%div.item-thumb-image{"data-hook" => "cart_item_image"}
= render 'spree/shared/variant_thumbnail', variant: variant
= render 'spree/shared/line_item_name', line_item: line_item
= render 'spree/shared/line_item_name', line_item: line_item
- if @insufficient_stock_lines.andand.include? line_item
%span.out-of-stock
= variant.in_stock? ? t(".insufficient_stock", :on_hand => variant.on_hand) : t(".out_of_stock")
%br/
- if @insufficient_stock_lines.andand.include? line_item
%span.out-of-stock
= variant.in_stock? ? t(".insufficient_stock", :on_hand => variant.on_hand) : t(".out_of_stock")
%br/
- if @unavailable_order_variants.andand.include? line_item.variant
%span.out-of-stock
= t(".unavailable_item")
%br/
- if @unavailable_order_variants.andand.include? line_item.variant
%span.out-of-stock
= t(".unavailable_item")
%br/
%td.text-right.cart-item-price{"data-hook" => "cart_item_price"}
= line_item.single_display_amount_with_adjustments.to_html
- if feature? :unit_price, spree_current_user
%br
%span.unit-price
= line_item.unit_price_price_and_unit
%td.text-center.cart-item-quantity{"data-hook" => "cart_item_quantity"}
- finalized_quantity = @order.completed? ? line_item.quantity : 0
= item_form.number_field :quantity,
:min => 0, "ofn-on-hand" => "#{variant.on_demand && 9999 || variant.on_hand}",
"finalizedquantity" => finalized_quantity, :class => "line_item_quantity", :size => 5,
"ng-model" => "line_item_#{line_item.id}",
"validate-stock-quantity" => true
%td.cart-item-total.text-right{"data-hook" => "cart_item_total"}
= line_item.display_amount_with_adjustments.to_html unless line_item.quantity.nil?
%td.text-right.cart-item-price{"data-hook" => "cart_item_price"}
= line_item.single_display_amount_with_adjustments.to_html
- if feature? :unit_price, spree_current_user
%br
%span.unit-price
= line_item.unit_price_price_and_unit
%td.text-center.cart-item-quantity{"data-hook" => "cart_item_quantity"}
- finalized_quantity = @order.completed? ? line_item.quantity : 0
= item_form.number_field :quantity,
:min => 0, "ofn-on-hand" => "#{variant.on_demand && 9999 || variant.on_hand}",
"finalizedquantity" => finalized_quantity, :class => "line_item_quantity", :size => 5,
"ng-model" => "line_item_#{line_item.id}",
"validate-stock-quantity" => true
%td.cart-item-total.text-right{"data-hook" => "cart_item_total"}
= line_item.display_amount_with_adjustments.to_html unless line_item.quantity.nil?
%td.cart-item-delete.text-center{"data-hook" => "cart_item_delete"}
%a.delete{href: "#", id: "delete_#{dom_id(line_item)}"}
%i.delete.ofn-i_026-trash
%td.cart-item-delete.text-center{"data-hook" => "cart_item_delete"}
%a.delete{href: "#", id: "delete_#{dom_id(line_item)}"}
%i.delete.ofn-i_026-trash

View File

@@ -13,3 +13,8 @@
= t :email_payment_summary
- if @order.payments.any?
= render partial: 'spree/shared/payments_list', locals: { payments: @order.payments }
- if last_payment_method(@order).present?
%p.callout{style: "margin-top: 40px"}
%strong
= t :email_payment_description
%p{style: "margin: 5px"}= last_payment_method(@order).description

View File

@@ -189,7 +189,7 @@ module Openfoodnetwork
config.active_support.escape_html_entities_in_json = true
config.active_job.queue_adapter = :delayed_job
config.active_job.queue_adapter = :sidekiq
config.action_controller.include_all_helpers = false

View File

@@ -15,7 +15,6 @@ Openfoodnetwork::Application.configure do
config.cache_store = :redis_cache_store, {
driver: :hiredis,
url: ENV.fetch("OFN_REDIS_URL", "redis://localhost:6379/0"),
namespace: "cache",
expires_in: 90.minutes
}
end

View File

@@ -44,8 +44,7 @@ Openfoodnetwork::Application.configure do
# Use a different cache store in production
config.cache_store = :redis_cache_store, {
driver: :hiredis,
url: ENV.fetch("OFN_REDIS_URL", "redis://localhost:6379/0"),
namespace: "cache",
url: ENV.fetch("OFN_REDIS_URL", "redis://localhost:6380/0"),
reconnect_attempts: 1
}

View File

@@ -44,8 +44,7 @@ Openfoodnetwork::Application.configure do
# Use a different cache store in production
config.cache_store = :redis_cache_store, {
driver: :hiredis,
url: ENV.fetch("OFN_REDIS_URL", "redis://localhost:6379/0"),
namespace: "cache",
url: ENV.fetch("OFN_REDIS_URL", "redis://localhost:6380/0"),
reconnect_attempts: 1
}

View File

@@ -1,2 +1,2 @@
Money.rounding_mode = BigDecimal::ROUND_HALF_EVEN
Money.default_currency = Money::Currency.new(Spree::Config[:currency])
Money.default_currency = Money::Currency.new(ENV.fetch('CURRENCY'))

View File

@@ -0,0 +1,11 @@
if Rails.env.production? || Rails.env.staging?
redis_jobs_url = ENV.fetch("OFN_REDIS_JOBS_URL", "redis://localhost:6381/0")
Sidekiq.configure_server do |config|
config.redis = { url: redis_jobs_url, network_timeout: 5 }
end
Sidekiq.configure_client do |config|
config.redis = { url: redis_jobs_url, network_timeout: 5 }
end
end

View File

@@ -19,6 +19,7 @@ end
Spree.config do |config|
config.site_url = ENV['SITE_URL'] if ENV['SITE_URL']
config.site_name = ENV['SITE_NAME'] if ENV['SITE_NAME']
config.shipping_instructions = true
config.address_requires_state = true
config.admin_interface_logo = '/default_images/ofn-logo.png'

View File

@@ -1571,6 +1571,7 @@ ca:
email_order_summary_includes_tax: "(inclou impostos):"
email_payment_paid: PAGAT
email_payment_not_paid: 'NO PAGAT '
email_payment_description: Descripció del pagament de la comanda
email_payment_summary: Resum del pagament
email_payment_method: "Pagament a través de:"
email_so_placement_intro_html: "Tens una nova comanda amb <strong> %{distributor}</strong>"

View File

@@ -50,7 +50,7 @@ de_DE:
variant_override:
count_on_hand:
using_producer_stock_settings_but_count_on_hand_set: "muss leer sein, da die Einstellungen des Produzentenbestands verwendet werden"
on_demand_but_count_on_hand_set: "muss leer sein, wenn die Produktion auf Anfrage erfolgt"
on_demand_but_count_on_hand_set: "muss leer sein, wenn unbegrenzt verfügbar oder die Produktion auf Bestellung erfolgt"
limited_stock_but_no_count_on_hand: "muss angegeben werden, da nur begrenzte Lagerbestände verfügbar sind"
activemodel:
attributes:
@@ -347,8 +347,8 @@ de_DE:
ends_on: Endet am
name: Name
on_hand: Verfügbar
on_demand: Auf Anfrage
on_demand?: Auf Anfrage?
on_demand: Unbegrenzt/auf Bestellung
on_demand?: Unbegrenzt/auf Bestellung
order_cycle: Bestellzyklus
payment: Zahlung
payment_method: Zahlungsart
@@ -986,7 +986,7 @@ de_DE:
add: Koordinatorgebühr hinzufügen
filters:
search_by_order_cycle_name: "Suche nach Name des Bestellzyklus ..."
involving: "Betrifft"
involving: "Unternehmen"
any_enterprise: "Alle Unternehmen"
any_schedule: "Alle Zeitpläne"
form:
@@ -1369,7 +1369,7 @@ de_DE:
country: Land
unauthorized: Nicht autorisiert
terms_of_service: "AGB"
on_demand: Auf Anfrage
on_demand: Unbegrenzt/auf Bestellung
none: Keine
not_allowed: Nicht erlaubt
no_shipping: keine Lieferoptionen
@@ -1570,6 +1570,7 @@ de_DE:
email_order_summary_includes_tax: "(inkl. Steuern):"
email_payment_paid: BEZAHLT
email_payment_not_paid: NICHT BEZAHLT
email_payment_description: 'Hinweise zur Zahlung '
email_payment_summary: Zahlungsübersicht
email_payment_method: "Zahlungsart:"
email_so_placement_intro_html: "Sie haben eine neue Bestellung bei <strong>%{distributor}</strong> erhalten!"
@@ -2729,7 +2730,7 @@ de_DE:
unit_price_tooltip: "Grundpreis: Er ermöglicht einen einfachen Preisvergleich von Produkten, unabhängig von Packungsgröße und -gewicht."
variants:
on_demand:
'yes': "Auf Anfrage"
'yes': "Unbegrenzt/auf Bestellung"
variant_overrides:
on_demand:
use_producer_settings: "Einstellungen des Produzentenbestands verwenden"
@@ -3021,7 +3022,7 @@ de_DE:
location: "Ort"
count_on_hand: "Verfügbar"
quantity: "Menge"
on_demand: "Unbegrenzt"
on_demand: "Unbegrenzt/auf Bestellung"
on_hand: "Verfügbar"
package_from: "Paket von"
item_description: "Artikelbeschreibung"
@@ -3465,7 +3466,7 @@ de_DE:
unit_price: "Grundpreis"
unit_price_legend: "Berechnet aus Preis und Menge."
on_hand: "Verfügbar"
on_demand: "Unbegrenzt"
on_demand: "Unbegrenzt/auf Bestellung"
product_description: "Produktbeschreibung"
image: "Bild"
or: "oder"

View File

@@ -1669,6 +1669,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using
email_order_summary_includes_tax: "(includes tax):"
email_payment_paid: PAID
email_payment_not_paid: NOT PAID
email_payment_description: Payment Description at Checkout
email_payment_summary: Payment summary
email_payment_method: "Paying via:"
email_so_placement_intro_html: "You have a new order with <strong>%{distributor}</strong>"

View File

@@ -1568,6 +1568,7 @@ en_FR:
email_order_summary_includes_tax: "(includes tax):"
email_payment_paid: PAID
email_payment_not_paid: NOT PAID
email_payment_description: Payment Description at Checkout
email_payment_summary: Payment summary
email_payment_method: "Paying via:"
email_so_placement_intro_html: "You have a new order with <strong>%{distributor}</strong>"

View File

@@ -1568,6 +1568,7 @@ en_GB:
email_order_summary_includes_tax: "(includes tax):"
email_payment_paid: PAID
email_payment_not_paid: NOT PAID
email_payment_description: Payment Description at Checkout
email_payment_summary: Payment summary
email_payment_method: "Paying via:"
email_so_placement_intro_html: "You have a new order with <strong>%{distributor}</strong>"

View File

@@ -1568,6 +1568,7 @@ en_US:
email_order_summary_includes_tax: "(includes tax):"
email_payment_paid: PAID
email_payment_not_paid: NOT PAID
email_payment_description: Payment Description at Checkout
email_payment_summary: Payment summary
email_payment_method: "Paying via:"
email_so_placement_intro_html: "You have a new order with <strong>%{distributor}</strong>"

View File

@@ -1570,6 +1570,7 @@ es:
email_order_summary_includes_tax: "(incluye impuestos):"
email_payment_paid: PAGADO
email_payment_not_paid: NO PAGADO
email_payment_description: Descripción de pago de la compra
email_payment_summary: Resumen de pago
email_payment_method: "Pagando con:"
email_so_placement_intro_html: "Tiene un nuevo pedido con <strong> %{distributor} </strong>"

View File

@@ -1570,6 +1570,7 @@ fr:
email_order_summary_includes_tax: "(dont TVA)"
email_payment_paid: RÉGLÉ
email_payment_not_paid: NON RÉGLÉ
email_payment_description: Informations concernant le mode de paiement
email_payment_summary: Résumé du paiement
email_payment_method: "Payer via :"
email_so_placement_intro_html: "Une nouvelle commande automatique a été passée pour vous chez <strong>%{distributor}</strong>"

View File

@@ -121,11 +121,23 @@ pt_BR:
send_instructions: "Você receberá um e-mail com instruções sobre como confirmar sua conta em alguns minutos."
home_page_alert_html: "HTML de alerta da página"
item_description: "Descrição do item"
menu_1_icon_name: "Nome do ícone do Menu 1"
menu_2_icon_name: "Nome do ícone do Menu 2"
menu_3_icon_name: "Nome do ícone do Menu 3"
menu_4_icon_name: "Nome do ícone do Menu 4"
menu_5_icon_name: "Nome do ícone do Menu 5"
menu_6_icon_name: "Nome do ícone do Menu 6"
menu_7_icon_name: "Nome do ícone do Menu 7"
models:
order_cycle:
cloned_order_cycle_name: "COPIA DO %{order_cycle}"
tax_rate:
included_in_price: "Incluso no preço"
open_street_map_enabled: "Open Street Map ativado"
open_street_map_default_latitude: "Latitude padrão do Open Street Map"
open_street_map_default_longitude: "Longitude padrão do Open Street Map"
open_street_map_provider_name: "Nome do provedor do Open Street Map"
open_street_map_provider_options: "Opções do provedor do Open Street Map"
resume_order: "Retomar pedido"
sku: "SKU"
subtotal: "Subtotal"
@@ -1328,6 +1340,12 @@ pt_BR:
address2: Complemento
city: Cidade
city_placeholder: 'ex: República'
latitude: Latitude
latitude_placeholder: ex. -13.51772776
latitude_longitude_tip: A Latitude e Longitude são necessárias para mostrar sua iniciativa no mapa.
longitude: Longitude
longitude_placeholder: ex. 46.40625
use_geocoder: 'Calcular latitude e longitude automaticamente a partir do endereço? '
postcode: CEP
postcode_placeholder: 'ex: 05429-130'
suburb: Cidade
@@ -1536,6 +1554,7 @@ pt_BR:
email_order_summary_includes_tax: "(inclui taxa):"
email_payment_paid: PAGO
email_payment_not_paid: NÃO PAGO
email_payment_description: Descrição do Pagamento no Checkout
email_payment_summary: Resumo do pagamento
email_payment_method: "Pagando com:"
email_so_placement_intro_html: "Você tem um novo pedido com <strong>%{distributor}</strong>"
@@ -1881,6 +1900,11 @@ pt_BR:
state_field_error: "Estado requerido"
country_field: "País:"
country_field_error: "Por favor, selecione um país"
map_location: "Localização no Mapa"
locate_address: "Localizar endereço no mapa"
drag_pin: "Arraste e solte o marcador na localização correta, caso ele não esteja no lugar certo"
confirm_address: "Eu confirmo que a localização da iniciativa no mapa está correta."
drag_map_marker: "Ajude-nos a entender melhor onde você está localizado arrastando o marcador no mapa acima para uma localização mais precisa, com base no seu conhecimento."
contact:
title: "Contato"
who_is_managing_enterprise: "Quem é responsável por gerenciar %{enterprise}? "
@@ -3730,6 +3754,9 @@ pt_BR:
other: Pagamentos
datetime:
distance_in_words:
about_x_hours:
one: cerca de 1 hora
other: cerca de %{count}horas
about_x_months:
one: cerca de 1 mês
other: cerca de %{count}mês

View File

@@ -1238,7 +1238,7 @@ ru:
mailers:
powered_by:
open_food_network: "Открытая Сеть Продуктов"
powered_html: "Ваш опыт покупок обеспечивается %{open_food_network}."
powered_html: "Ваш опыт покупок обеспечивает %{open_food_network}."
menu:
cart:
cart: "Корзина"
@@ -1368,7 +1368,7 @@ ru:
suburb: Город
state: Область
country: Страна
unauthorized: На разрешено
unauthorized: Неавторизованный
terms_of_service: "Условия Сервиса"
on_demand: По запросу
none: Ничего
@@ -1571,6 +1571,7 @@ ru:
email_order_summary_includes_tax: "(включает налог):"
email_payment_paid: ОПЛАЧЕН
email_payment_not_paid: НЕ ОПЛАЧЕН
email_payment_description: Описание Платежа при Оформлении Заказа
email_payment_summary: Статус оплаты
email_payment_method: "Тип оплаты:"
email_so_placement_intro_html: "У Вас есть новый заказ с <strong>%{distributor}</strong>"

View File

@@ -1,9 +1,12 @@
require 'sidekiq/web'
require 'sidekiq-scheduler/web'
Openfoodnetwork::Application.routes.draw do
namespace :admin do
authenticated :spree_user, -> user { user.admin? } do
mount DelayedJobWeb, at: '/delayed_job'
mount Flipper::UI.app(Flipper) => '/feature-toggle'
mount Sidekiq::Web, at: "/sidekiq"
end
resources :bulk_line_items

View File

@@ -9,7 +9,6 @@ env "MAILTO", app_config["SCHEDULE_NOTIFICATIONS"] if app_config["SCHEDULE_NOTIF
# If we use -e with a file containing specs, rspec interprets it and filters out our examples
job_type :run_file, "cd :path; :environment_variable=:environment bundle exec script/rails runner :task :output"
job_type :enqueue_job, "cd :path; :environment_variable=:environment bundle exec script/enqueue :task :priority :output"
every 1.month, at: '4:30am' do
rake 'ofn:data:remove_transient_data'
@@ -22,9 +21,3 @@ end
every 4.hours do
rake 'db2fog:backup' if app_config['S3_BACKUPS_BUCKET']
end
every 5.minutes do
enqueue_job 'HeartbeatJob', priority: 0
enqueue_job 'SubscriptionPlacementJob', priority: 0
enqueue_job 'SubscriptionConfirmJob', priority: 0
end

16
config/sidekiq.yml Normal file
View File

@@ -0,0 +1,16 @@
---
:verbose: false
:concurrency: 5
:queues:
- default
- mailers
:schedule:
HeartbeatJob:
every: "5m"
SubscriptionPlacementJob:
every: "5m"
SubscriptionConfirmJob:
every: "5m"

View File

@@ -62,7 +62,7 @@ def create_admin_user
role = Spree::Role.find_or_create_by(name: 'admin')
admin.spree_roles << role
admin.save
say "Done!"
say "New admin user persisted!"
else
say "There was some problems with persisting new admin user:"
admin.errors.full_messages.each do |error|

View File

@@ -75,15 +75,24 @@ describe Api::V0::EnterprisesController, type: :controller do
end
describe "submitting a valid image" do
let!(:logo) { fixture_file_upload("files/logo.png", "image/png") }
before do
allow(Enterprise)
.to receive(:find_by).with({ permalink: enterprise.id.to_s }) { enterprise }
allow(enterprise).to receive(:update).and_return(true)
end
it "I can update enterprise image" do
api_post :update_image, logo: 'a logo', id: enterprise.id
it "I can update enterprise logo image" do
api_post :update_image, logo: logo, id: enterprise.id
expect(response.status).to eq 200
expect(response.content_type).to eq "text/html"
expect(response.body).to match %r{/images/enterprises/logos/\d*/medium/logo\.png\?\d*}
end
it "I can update enterprise promo image" do
api_post :update_image, promo: logo, id: enterprise.id
expect(response.status).to eq 200
expect(response.content_type).to eq "text/html"
expect(response.body).to match %r{/images/enterprises/promo_images/\d*/medium/logo\.jpg\?\d*}
end
end
end

View File

@@ -36,10 +36,8 @@ describe UserPasswordsController, type: :controller do
it "renders Darkswarm" do
setup_email
clear_jobs
user.send_reset_password_instructions
flush_jobs # Send the reset password instructions
user.reload
spree_get :edit, reset_password_token: user.reset_password_token

View File

@@ -0,0 +1,103 @@
# frozen_string_literal: true
require "spec_helper"
feature '
As an administrator
I want to print a invoice as PDF
', js: false do
include WebHelper
include AuthenticationHelper
let(:user) { create(:user) }
let(:product) { create(:simple_product) }
let(:distributor) { create(:distributor_enterprise, owner: user, charges_sales_tax: true) }
let(:order_cycle) do
create(:simple_order_cycle, name: 'One', distributors: [distributor],
variants: [product.variants.first])
end
let(:order) do
create(:order_with_totals_and_distribution, user: user, distributor: distributor,
order_cycle: order_cycle, state: 'complete',
payment_state: 'balance_due')
end
describe "that contains right Payment Description at Checkout information" do
let!(:payment_method1) do
create(:stripe_sca_payment_method, distributors: [distributor], description: "description1")
end
let!(:payment_method2) do
create(:stripe_sca_payment_method, distributors: [distributor], description: "description2")
end
context "with no payment" do
it "do not display the payment description information" do
login_as_admin_and_visit spree.print_admin_order_path(order)
convert_pdf_to_page
expect(page).to have_no_content 'Payment Description at Checkout'
end
end
context "with one payment" do
let!(:payment1) do
create(:payment, order: order, state: 'completed', payment_method: payment_method1)
end
before do
order.save!
end
it "display the payment description section" do
login_as_admin_and_visit spree.print_admin_order_path(order)
convert_pdf_to_page
expect(page).to have_content 'Payment Description at Checkout'
expect(page).to have_content 'description1'
end
end
context "with two payments, and one that failed" do
before do
order.update payments: []
order.payments << create(:payment, order: order, state: 'completed',
payment_method: payment_method1, created_at: 1.day.ago)
order.payments << create(:payment, order: order, state: 'failed',
payment_method: payment_method2, created_at: 2.days.ago)
order.save!
end
it "display the payment description section and use the one from the completed payment" do
login_as_admin_and_visit spree.print_admin_order_path(order)
convert_pdf_to_page
expect(page).to have_content 'Payment Description at Checkout'
expect(page).to have_content 'description1'
end
end
context "with two completed payments" do
before do
order.update payments: []
order.payments << create(:payment, order: order, state: 'completed',
payment_method: payment_method1, created_at: 2.days.ago)
order.payments << create(:payment, order: order, state: 'completed',
payment_method: payment_method2, created_at: 1.day.ago)
order.save!
end
it "display the payment description section and use the one from the last payment" do
login_as_admin_and_visit spree.print_admin_order_path(order)
convert_pdf_to_page
expect(page).to have_content 'Payment Description at Checkout'
expect(page).to have_content 'description2'
end
end
end
end
def convert_pdf_to_page
temp_pdf = Tempfile.new('pdf')
temp_pdf << page.source.force_encoding('UTF-8')
reader = PDF::Reader.new(temp_pdf)
pdf_text = reader.pages.map(&:text)
temp_pdf.close
page.driver.response.instance_variable_set('@body', pdf_text)
end

View File

@@ -5,36 +5,36 @@ require 'spec_helper'
feature '
As an admin
I want to check the unit price of my products/variants
' do
', js: true do
include AuthenticationHelper
include WebHelper
let!(:stock_location) { create(:stock_location, backorderable_default: false) }
before do
allow(OpenFoodNetwork::FeatureToggle).to receive(:enabled?).with(:unit_price, anything) { true }
end
describe "product", js: true do
describe "product" do
scenario "creating a new product" do
login_as_admin_and_visit spree.admin_products_path
click_link 'New Product'
select "Weight (kg)", from: 'product_variant_unit_with_scale'
fill_in 'Value', with: '1'
fill_in 'Price', with: '1'
expect(find_field("Unit Price", disabled: true).value).to eq "$1.00 / kg"
end
end
describe "variant", js: true do
describe "variant" do
scenario "creating a new variant" do
product = create(:simple_product, variant_unit: "weight", variant_unit_scale: "1")
login_as_admin_and_visit spree.admin_product_variants_path product
click_link 'New Variant'
fill_in 'Weight (g)', with: '1'
fill_in 'Price', with: '1'
expect(find_field("Unit Price", disabled: true).value).to eq '$1,000.00 / kg'
end
@@ -43,8 +43,42 @@ feature '
variant = product.variants.first
variant.update(price: 1.0)
login_as_admin_and_visit spree.edit_admin_product_variant_path(product, variant)
expect(find_field("Unit Price", disabled: true).value).to eq '$1,000.00 / kg'
end
end
describe "when admin use es as default language (and comma as decimal separator)", :debug do
scenario "creating a new product with a comma separated decimal price" do
login_as_admin_and_visit spree.admin_dashboard_path(locale: 'es')
visit spree.admin_products_path
click_link 'Nuevo producto'
select "Peso (kg)", from: 'product_variant_unit_with_scale'
fill_in 'Valor', with: '1'
fill_in 'Precio', with: '1,5'
expect(find_field("Precio por unidad", disabled: true).value).to eq "1,50 $ / kg"
end
scenario "creating a new variant with a comma separated decimal price" do
product = create(:simple_product, variant_unit: "weight", variant_unit_scale: "1")
login_as_admin_and_visit spree.admin_dashboard_path(locale: 'es')
visit spree.admin_product_variants_path product
click_link 'Nueva Variante'
fill_in 'Peso (g)', with: '1'
fill_in 'Precio', with: '1,5'
expect(find_field("Precio por unidad", disabled: true).value).to eq '1.500,00 $ / kg'
end
scenario "editing a variant with a comma separated decimal price" do
product = create(:simple_product, variant_unit: "weight", variant_unit_scale: "1")
variant = product.variants.first
variant.update(price: 1.5)
login_as_admin_and_visit spree.admin_dashboard_path(locale: 'es')
visit spree.edit_admin_product_variant_path(product, variant)
expect(find_field("Precio por unidad", disabled: true).value).to eq '1.500,00 $ / kg'
end
end
end

View File

@@ -100,10 +100,20 @@ feature "Registration", js: true do
expect(e.charges_sales_tax).to be true
# Images
# Upload logo image
attach_file "image-select", Rails.root.join("spec/fixtures/files/logo.png"), visible: false
expect(page).to have_no_css('#image-placeholder .loading')
expect(page.find('#image-placeholder img')['src']).to_not be_empty
# Move from logo page
click_button "Continue"
expect(page).to have_content 'Step 3. Select Promo Image'
# Upload promo image
attach_file "image-select", Rails.root.join("spec/fixtures/files/promo.png"), visible: false
expect(page).to have_no_css('#image-placeholder .loading')
expect(page.find('#image-placeholder img')['src']).to_not be_empty
# Move from promo page
click_button "Continue"
expect(page).to have_content 'How can people find My Awesome Enterprise online?'

BIN
spec/fixtures/files/logo.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

BIN
spec/fixtures/files/promo.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@@ -0,0 +1,91 @@
describe 'convert string to number with configurated currency', ->
filter = null
beforeEach ->
module 'ofn.admin'
inject ($filter) ->
filter = $filter('unlocalizeCurrency')
describe "with point as decimal separator and comma as thousands separator for I18n service", ->
beforeEach ->
spyOn(I18n,'toCurrency').and.callFake (arg) ->
if (arg == 0.1)
return "0.1"
else if (arg == 1000)
return "1,000"
it "handle point as decimal separator", ->
expect(filter("1.00")).toEqual 1.0
it "handle point as decimal separator", ->
expect(filter("1.000")).toEqual 1.0
it "also handle comma as decimal separator", ->
expect(filter("1,00")).toEqual 1.0
it "handle point as decimal separator and comma as thousands separator", ->
expect(filter("1,000,000.00")).toEqual 1000000
it "handle integer number", ->
expect(filter("10")).toEqual 10
it "handle integer number with comma as thousands separator", ->
expect(filter("1,000")).toEqual 1000
it "handle integer number with no thousands separator", ->
expect(filter("1000")).toEqual 1000
describe "with comma as decimal separator and final point as thousands separator for I18n service", ->
beforeEach ->
spyOn(I18n,'toCurrency').and.callFake (arg) ->
if (arg == 0.1)
return "0,1"
else if (arg == 1000)
return "1.000"
it "handle comma as decimal separator", ->
expect(filter("1,00")).toEqual 1.0
it "also handle point as decimal separator", ->
expect(filter("1.00")).toEqual 1.0
it "handle point as decimal separator and final point as thousands separator", ->
expect(filter("1.000.000,00")).toEqual 1000000
it "handle integer number", ->
expect(filter("10")).toEqual 10
it "handle integer number with final point as thousands separator", ->
expect(filter("1.000")).toEqual 1000
it "handle integer number with no thousands separator", ->
expect(filter("1000")).toEqual 1000
describe "with comma as decimal separator and space as thousands separator for I18n service", ->
beforeEach ->
spyOn(I18n,'toCurrency').and.callFake (arg) ->
if (arg == 0.1)
return "0,1"
else if (arg == 1000)
return "1 000"
it "handle comma as decimal separator", ->
expect(filter("1,00")).toEqual 1.0
it "also handle final point as decimal separator", ->
expect(filter("1.00")).toEqual 1.0
it "handle point as decimal separator and space as thousands separator", ->
expect(filter("1 000 000,00")).toEqual 1000000
it "handle integer number", ->
expect(filter("10")).toEqual 10
it "handle integer number with space as thousands separator", ->
expect(filter("1 000")).toEqual 1000
it "handle integer number with no thousands separator", ->
expect(filter("1000")).toEqual 1000

View File

@@ -138,3 +138,19 @@ describe "UnitPrices service", ->
unit_value = 453.6
expect(UnitPrices.price(price, scale, unit_type, unit_value)).toEqual 1
expect(UnitPrices.unit(scale, unit_type)).toEqual "lb"
describe "get unit price when price is a decimal string", ->
unit_type = "weight"
it "with price: '1,0'", ->
price = '1,0'
scale = 1
unit_value = 1
expect(UnitPrices.displayableUnitPrice(price, scale, unit_type, unit_value)).toEqual "$1,000.00 / kg"
it "with price: '1.0'", ->
price = '1.0'
scale = 1
unit_value = 1
expect(UnitPrices.displayableUnitPrice(price, scale, unit_type, unit_value)).toEqual "$1,000.00 / kg"

View File

@@ -13,16 +13,8 @@ describe HeartbeatJob do
end
it "updates the last_job_queue_heartbeat_at config var" do
run_job
HeartbeatJob.perform_now
expect(Time.parse(Spree::Config.last_job_queue_heartbeat_at).in_time_zone).to eq(run_time)
end
end
private
def run_job
clear_jobs
HeartbeatJob.perform_now
flush_jobs ignore_exceptions: false
end
end

View File

@@ -199,7 +199,6 @@ RSpec.configure do |config|
config.include OpenFoodNetwork::DistributionHelper
config.include OpenFoodNetwork::HtmlHelper
config.include ActionView::Helpers::DateHelper
config.include OpenFoodNetwork::DelayedJobHelper
config.include OpenFoodNetwork::PerformanceHelper
config.include DownloadsHelper, type: :feature
config.include ActiveJob::TestHelper

View File

@@ -1,70 +0,0 @@
# frozen_string_literal: true
module OpenFoodNetwork
module DelayedJobHelper
# Process all pending Delayed jobs, keeping in mind jobs could spawn new
# delayed job (so things might be added to the queue while processing)
def flush_jobs(options = {})
options[:ignore_exceptions] ||= false
Delayed::Worker.new.work_off(100)
unless options[:ignore_exceptions]
Delayed::Job.all.each do |job|
if job.last_error.present?
throw "There was an error in a delayed job: #{job.last_error}"
end
end
end
end
def clear_jobs
Delayed::Job.delete_all
end
# expect { foo }.to enqueue_job MyJob, field1: 'foo', field2: 'bar'
RSpec::Matchers.define :enqueue_job do |klass, options = {}|
match do |event_proc|
last_job_id_before = Delayed::Job.last.andand.id || 0
begin
event_proc.call
rescue StandardError => e
@exception = e
raise e
end
@jobs_created = Delayed::Job.where('id > ?', last_job_id_before)
@jobs_created.any? do |job|
job = job.payload_object
match = true
match &= (job.class == klass)
options.each_pair do |k, v|
begin
match &= (job[k] == v)
rescue NameError
match = false
end
end
match
end
end
failure_message do |_event_proc|
@exception || "expected #{klass} to be enqueued matching #{options.inspect} (#{@jobs_created.count} others enqueued)"
end
failure_message_when_negated do |_event_proc|
@exception || "expected #{klass} to not be enqueued matching #{options.inspect}"
end
def supports_block_expectations?
true
end
end
end
end

View File

@@ -9255,9 +9255,9 @@ write-file-atomic@^3.0.0:
typedarray-to-buffer "^3.1.5"
ws@~7.4.2:
version "7.4.4"
resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.4.tgz#383bc9742cb202292c9077ceab6f6047b17f2d59"
integrity sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw==
version "7.4.6"
resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c"
integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==
xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1:
version "4.0.2"